Files
zernie__vigiles/package.json
Claude 0b79d4825a ci: replace the hand-rolled path classifier with dorny/paths-filter
The `changes` job was a shell script: one `gh api` call for the changed-file
list, two `grep -qvE`, and a fallback for every way that list can come back
unusable — empty, failed call, a push whose `before` is all zeros. Every one of
those branches is something `dorny/paths-filter` already does, and the edge
cases were exactly the half we were maintaining by hand.

This is `prefer-existing-solutions` applied to the place it had not been:
BUILD was never justified here, it was just what got written first.

THE COST, stated because it is real and it is the only one: on a `push` the
action diffs with git and therefore needs a checkout, while the old classifier
needed none and finished in ~3s. On a `pull_request` it reads the REST API and
still needs nothing. `push` in this workflow only ever means a merge into main,
so the checkout is paid once per merge and the job still rounds to the same
single billable minute.

🔴 `predicate-quantifier: some-with-excludes` IS LOAD-BEARING. Read out of the
action's own filter.ts before writing the filters, not assumed: the default is
`some`, i.e. `patterns.some(...)`, under which a file beneath site/ matches the
`'**'` pattern and sets root=true for a site-only diff — the exact hole the
filter exists to prevent, silently. `some-with-excludes` makes a negated pattern
a final exclusion ("included by >=1 pattern AND excluded by 0").

Also verified against the action's source rather than guessed: it calls
picomatch with `{ dot: true }`. Without that, `**` would not match `.claude/…`
and an agent-config-only diff would skip the root jobs.

WHAT THE TEST CAN AND CANNOT DO NOW. It could previously re-run the rule by
shelling out to `grep` with the workflow's own pattern. With an action it does
the nearest honest thing: reads the filters with a YAML parser and evaluates
them with the SAME matcher library the action uses, through a transcription of
the action's predicate. That transcription is the one copied thing, and its risk
is bounded two ways — the action is PINNED to `@v4.0.3` (a test fails on a
floating major), and the setting the predicate depends on is asserted
separately, because a transcription cannot catch its own premise being absent.

The conservative fallback is no longer ours to test, and that is most of the
point: the action documents that "all files are considered as added if there is
no common ancestor with base branch or no previous commit" — a new branch or a
shallow history runs everything.

Mutation-proven, each failing exactly its own assertion:
  - delete `predicate-quantifier`        -> `declares predicate-quantifier: …`
  - unpin `@v4.0.3` to `@v4`             -> `pins the action to an exact version`
  - break `!site/**` to `!nosuch/**`     -> `skips the root jobs for a site-only change`

`picomatch` + `@types/picomatch` become explicit devDependencies. picomatch was
already in the tree transitively; a test resting on an undeclared transitive
dependency is a landmine, so it is declared.

Gates: npm run check 18/18 · coverage 3975 passed, 0 failed. The 99.94%
statement gate fails locally on src/mock-model.ts (untouched; 25 tests skip
locally), green on CI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 23:54:53 +00:00

153 lines
4.5 KiB
JSON

{
"name": "vigiles",
"version": "0.0.0-semantically-released",
"description": "Audit, test and measure the harness your AI agent runs on — grade your CLAUDE.md / AGENTS.md, skills, subagents and hooks, run them against a scripted model, and measure whether they actually fire.",
"keywords": [
"claude-code",
"codex",
"agents",
"agentic",
"ai",
"llm",
"harness",
"hooks",
"skills",
"claude",
"agents-md",
"eval",
"testing",
"linter"
],
"homepage": "https://github.com/zernie/vigiles#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/zernie/vigiles.git"
},
"bugs": {
"url": "https://github.com/zernie/vigiles/issues"
},
"license": "MIT",
"workspaces": [
"packages/*",
"report",
"site"
],
"bin": {
"vigiles": "dist/cli.js"
},
"main": "./dist/test.js",
"types": "./dist/test.d.ts",
"exports": {
".": "./dist/test.js",
"./spec": "./dist/core/spec.js",
"./eval": "./dist/eval-surface.js",
"./linting": "./dist/linting.js",
"./hook": "./dist/hook.js",
"./claude-code": "./dist/claude-code.js",
"./codex": "./dist/codex.js",
"./adapter": "./dist/adapter.js",
"./vitest": {
"types": "./dist/vitest.d.mts",
"default": "./dist/vitest.mjs"
},
"./jest": "./dist/jest.js"
},
"files": [
"dist/**/*.js",
"dist/**/*.mjs",
"dist/**/*.d.ts",
"dist/**/*.d.mts",
"dist/audit-report.template.html",
"!dist/**/*.test.js",
"!dist/**/*.test.d.ts",
"action.yml",
"plugin.json",
".claude-plugin",
"hooks",
"skills",
"!skills/**/*.spec.ts",
"README.md",
"LICENSE"
],
"scripts": {
"build": "tsc && node scripts/build-report.mjs",
"build:core": "tsc",
"test": "npm run build && vitest run",
"coverage": "npm run build && vitest run --coverage",
"lint": "eslint src/",
"fmt": "prettier --write .",
"fmt:check": "prettier --check .",
"test:unit": "npm run build && vitest run --project unit",
"test:integration": "npm run build && vitest run --project integration",
"test:e2e": "npm run build && vitest run --project e2e",
"test:cli-e2e": "bash test/e2e/run.sh",
"test:harness": "npm run build && node dist/cli.js test",
"test:eval": "npm run build && node dist/cli.js eval --all",
"test:vitest": "npm run build && vitest run --project runners",
"test:jest": "npm run build && jest",
"test:types": "npm run build && tsc --noEmit -p test/types/tsconfig.json",
"api:report": "npm run build && node scripts/api-extractor.mjs --local",
"api:check": "npm run build && node scripts/api-extractor.mjs",
"check": "node scripts/check.mjs",
"docs:check": "npm run build && node scripts/check-doc-imports.mjs . docs README.md",
"exports:check": "npm run build && node scripts/check-export-prefixes.mjs .",
"internal:check": "npm run api:check && node scripts/check-internal-tag.mjs",
"docs:api": "typedoc"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@jackchuka/mdschema": "^0.12.8",
"@microsoft/api-extractor": "^7.58.9",
"@semantic-release/commit-analyzer": "^13.0.1",
"@types/js-yaml": "^4.0.9",
"@types/markdown-it": "^14.1.2",
"@types/minimatch": "^5.1.2",
"@types/node": "^20.19.39",
"@types/picomatch": "^4.0.2",
"@typescript-eslint/eslint-plugin": "^8.58.0",
"@typescript-eslint/parser": "^8.58.0",
"@vitest/coverage-v8": "^4.1.8",
"conventional-changelog-conventionalcommits": "^10.3.0",
"eslint": "^10.1.0",
"eslint-import-resolver-typescript": "^4.4.5",
"eslint-plugin-boundaries": "^6.0.2",
"eslint-plugin-sonarjs": "^4.0.2",
"globals": "^17.4.0",
"jest": "^30.4.2",
"picomatch": "^4.0.4",
"prettier": "^3.8.1",
"tsx": "^4.21.0",
"typedoc": "^0.28.19",
"typescript": "^5.9.3",
"vitest": "^4.1.8"
},
"peerDependencies": {
"jest": ">=28",
"vitest": ">=1"
},
"peerDependenciesMeta": {
"jest": {
"optional": true
},
"vitest": {
"optional": true
}
},
"dependencies": {
"@ast-grep/lang-python": "^0.0.6",
"@ast-grep/lang-ruby": "^0.0.7",
"@ast-grep/lang-rust": "^0.0.7",
"@ast-grep/napi": "^0.43.0",
"@iarna/toml": "^2.2.5",
"ci-info": "^4.4.0",
"cosmiconfig": "^9.0.1",
"glob": "^13.0.6",
"js-yaml": "^4.1.0",
"markdown-it": "^14.3.0",
"minimatch": "^10.0.1",
"mvdan-sh": "^0.10.1",
"ts-essentials": "^10.2.1",
"typescript": "^5.9.3"
}
}