@chimix/agentscan 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -40
- package/dist/cli.js +1161 -776
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<img src="https://img.shields.io/badge/checks-
|
|
9
|
-
<img src="https://img.shields.io/badge/tests-
|
|
8
|
+
<img src="https://img.shields.io/badge/checks-26-111111?style=flat-square" alt="26 checks">
|
|
9
|
+
<img src="https://img.shields.io/badge/tests-226%20passing-111111?style=flat-square" alt="226 tests">
|
|
10
10
|
<img src="https://img.shields.io/badge/network-none-111111?style=flat-square" alt="No network">
|
|
11
11
|
<img src="https://img.shields.io/badge/writes-none-111111?style=flat-square" alt="Writes nothing">
|
|
12
12
|
<img src="https://img.shields.io/badge/runs%20on-node%20%C2%B7%20bun-111111?style=flat-square" alt="Node or Bun">
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
<p align="center">
|
|
18
|
-
<strong>
|
|
18
|
+
<strong>26 checks · 4.1k lines · 0 network calls · every check sourced to a published spec line</strong><br>
|
|
19
19
|
<sub>Alpha. An earlier build reported 37 findings across 17 real projects of which <strong>25 were false</strong> — two checks had been written from what real projects looked like instead of from the spec. Both were deleted, and every check that survived is recorded in <a href="docs/spec/">docs/spec/</a> with the URL it came from and the date it was read. That story is the reason this tool exists in its current shape.</sub>
|
|
20
20
|
</p>
|
|
21
21
|
|
|
@@ -47,12 +47,11 @@ think you have has silently not existed for six weeks.
|
|
|
47
47
|
```console
|
|
48
48
|
$ agentscan check
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
evidence: hook PreToolUse @ …/.claude/settings.json
|
|
50
|
+
ERROR rule:hook.missing-script
|
|
51
|
+
PreToolUse hook points at a script that does not exist: .claude/hooks/guard-destructive-bash.js
|
|
52
|
+
PreToolUse @ .claude/settings.json · .claude/hooks/guard-destructive-bash.js
|
|
54
53
|
|
|
55
|
-
Summary:
|
|
54
|
+
Summary: 1 error · score 90/100
|
|
56
55
|
```
|
|
57
56
|
|
|
58
57
|
That is the whole category: **a config file asserting something that is not true
|
|
@@ -65,7 +64,7 @@ No AI, no network, no heuristics. Read the config, read the disk, compare:
|
|
|
65
64
|
```
|
|
66
65
|
1. Discover .claude/ .agents/ .mcp.json AGENTS.md skills-lock.json
|
|
67
66
|
2. Extract immutable facts — never re-read during checking
|
|
68
|
-
3. Check
|
|
67
|
+
3. Check 26 checks, each against one published spec line
|
|
69
68
|
4. Report text · --json · --output prompt (handoff for a fixing agent)
|
|
70
69
|
```
|
|
71
70
|
|
|
@@ -84,8 +83,16 @@ A check here has to point at a spec line. If it cannot, it does not ship.
|
|
|
84
83
|
|
|
85
84
|
## Try it in 30 seconds
|
|
86
85
|
|
|
87
|
-
Run
|
|
88
|
-
|
|
86
|
+
No project handy? Run the built-in demo — it builds a throwaway fixture with the
|
|
87
|
+
killer case (a `PreToolUse` hook pointing at a missing script), prints the human
|
|
88
|
+
report, and deletes the fixture:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx @chimix/agentscan@latest demo
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Against a real project, it reads that tree, writes nothing, and never leaves
|
|
95
|
+
your machine:
|
|
89
96
|
|
|
90
97
|
```bash
|
|
91
98
|
cd ~/your-project
|
|
@@ -104,8 +111,9 @@ bun add -d @chimix/agentscan # then: bunx agentscan check
|
|
|
104
111
|
```
|
|
105
112
|
|
|
106
113
|
Point it at a project that actually has agent config — a `.claude/` directory,
|
|
107
|
-
an `.mcp.json`, an `AGENTS.md`.
|
|
108
|
-
|
|
114
|
+
an `.mcp.json`, an `AGENTS.md`. A directory with agent config and no
|
|
115
|
+
`package.json` is still scannable. On a directory with neither it exits with a
|
|
116
|
+
clear error.
|
|
109
117
|
|
|
110
118
|
```bash
|
|
111
119
|
# what it could possibly report, before you run it
|
|
@@ -152,6 +160,7 @@ bunx agentscan check --verbose # include KEEP and info-severity findings
|
|
|
152
160
|
bunx agentscan check --fail-on warning
|
|
153
161
|
bunx agentscan check --global # also scan global skill dirs
|
|
154
162
|
|
|
163
|
+
bunx agentscan demo # one-shot fixture (no project required)
|
|
155
164
|
bunx agentscan explain <findingId> # detail one finding
|
|
156
165
|
bunx agentscan rules # every check + rule id that can fire
|
|
157
166
|
bunx agentscan init # write .agentscanrc.json
|
|
@@ -164,6 +173,7 @@ Flags for `check`:
|
|
|
164
173
|
| `--json` | JSON report (alias for `--output json`) |
|
|
165
174
|
| `--output <format>` | `human` (default) · `json` · `prompt` |
|
|
166
175
|
| `--copy` | Also copy the report to the system clipboard |
|
|
176
|
+
| `--no-color` | Never colour, even on a terminal (`NO_COLOR=1` does the same) |
|
|
167
177
|
| `--quiet` | Summary line only |
|
|
168
178
|
| `--verbose` | Show KEEP + info-severity findings |
|
|
169
179
|
| `--fail-on <level>` | `never` (default) · `warning` · `error` |
|
|
@@ -176,28 +186,39 @@ Flags for `check`:
|
|
|
176
186
|
## Sample output
|
|
177
187
|
|
|
178
188
|
```text
|
|
179
|
-
|
|
189
|
+
┌─────┐ 40/100 broken · touchagency
|
|
190
|
+
│ ✕ ✕ │ ██████████░░░░░░░░░░░░░░░
|
|
191
|
+
│ ⌒ │ 6 error · 4 info hidden (--verbose)
|
|
192
|
+
└─────┘
|
|
193
|
+
|
|
194
|
+
agentscan v0.5.0 — touchagency
|
|
180
195
|
|
|
181
196
|
Scanned: 46 deps · 54 skills · 1 mcp · 2 agents · packageManager=bun
|
|
182
197
|
|
|
183
|
-
|
|
184
|
-
|
|
198
|
+
ERROR rule:hook.missing-script ×6
|
|
199
|
+
Hook points at a script that does not exist
|
|
185
200
|
PostToolUse @ .claude/settings.json · .claude/hooks/notify-related-tests.js
|
|
186
201
|
PreToolUse @ .claude/settings.json · .claude/hooks/guard-destructive-bash.js
|
|
187
202
|
PreToolUse @ .claude/settings.json · .claude/hooks/protect-artists-json.js
|
|
188
203
|
PreToolUse @ .claude/settings.json · .claude/hooks/protect-env.js
|
|
189
204
|
|
|
190
|
-
Summary: 6
|
|
205
|
+
Summary: 6 error · 4 info hidden (--verbose) · score 40/100 broken
|
|
191
206
|
```
|
|
192
207
|
|
|
193
|
-
|
|
194
|
-
|
|
208
|
+
On a terminal the header is coloured green, yellow or red and the face tracks
|
|
209
|
+
the score. Redirect or pipe it and you get exactly the text above, with no
|
|
210
|
+
escape sequences — the header box is dropped too, so `--json`, `--output
|
|
211
|
+
prompt`, CI logs and `--copy` are unchanged by any of this.
|
|
212
|
+
|
|
213
|
+
The `Scanned:` line is orientation only — which project, how big. The summary
|
|
214
|
+
lists severities (error / warning / info); a clean project prints
|
|
215
|
+
`Summary: no findings`. Score and `--fail-on` still use severity under the hood.
|
|
195
216
|
|
|
196
217
|
JSON shape (abridged):
|
|
197
218
|
|
|
198
219
|
```json
|
|
199
220
|
{
|
|
200
|
-
"version": "0.
|
|
221
|
+
"version": "0.5.0",
|
|
201
222
|
"root": "/path/to/project",
|
|
202
223
|
"factsSummary": {
|
|
203
224
|
"packageManager": "bun",
|
|
@@ -381,7 +402,7 @@ Every check lives in `src/checks/` and runs on every `check`. `agentscan rules`
|
|
|
381
402
|
lists all of them with their ids; `agentscan explain <id>` details any finding.
|
|
382
403
|
|
|
383
404
|
Most validate one discovered item against its own file on disk. The five
|
|
384
|
-
`budget.*`
|
|
405
|
+
`budget.*` entries at the bottom judge aggregate size instead —
|
|
385
406
|
they are all **info**, they are sourced to `docs/spec/thresholds.md`, and they
|
|
386
407
|
are retuned through `thresholds` in `.agentscanrc.json` rather than switched
|
|
387
408
|
off.
|
|
@@ -391,10 +412,14 @@ off.
|
|
|
391
412
|
| `config.unreadable` | error | A config file that is not valid JSON, so whatever it declares is silently not in effect |
|
|
392
413
|
| `hook.missing-script` | error | A registered hook whose script does not exist — it never runs |
|
|
393
414
|
| `hook.unknown-event` | error | A hook registered under an event name that is never dispatched |
|
|
394
|
-
| `agent.missing-frontmatter` |
|
|
395
|
-
| `agent.missing-description` |
|
|
396
|
-
| `
|
|
397
|
-
| `
|
|
415
|
+
| `agent.missing-frontmatter` | error | An agent definition with no `---` block |
|
|
416
|
+
| `agent.missing-description` | error | Agent frontmatter has no `description` |
|
|
417
|
+
| `agent.missing-name` | error | Agent frontmatter has no `name` |
|
|
418
|
+
| `agent.invalid-name` | error | Agent name is not lowercase letters, numbers, and hyphens |
|
|
419
|
+
| `agent.duplicate-name` | error | Multiple agent files declare the same name |
|
|
420
|
+
| `mcp.no-launch` | error | An MCP server with neither `command` nor `url` — unlaunchable by schema |
|
|
421
|
+
| `mcp.command-missing` | error | An MCP `command` that is a path-like value whose file does not exist on disk |
|
|
422
|
+
| `mcp.url-without-type` | error | A remote MCP server with a `url` but no `type` — read as stdio, misconfigured by schema, and skipped |
|
|
398
423
|
| `mcp.hardcoded-secret` | error | A token-shaped literal in MCP config (the value is never echoed back) |
|
|
399
424
|
| `mcp.literal-env` | warning | Long literal `env` values that should be `${VAR}` |
|
|
400
425
|
| `skill.missing-skill-md` | warning | A directory under a skill path with no `SKILL.md` |
|
|
@@ -408,9 +433,8 @@ off.
|
|
|
408
433
|
| `skill.no-lockfile` | info | Skills present with no lockfile at all (only with `requireLock`) |
|
|
409
434
|
|
|
410
435
|
Agent definitions are checked for structure only. An agent's frontmatter `name`
|
|
411
|
-
is
|
|
412
|
-
|
|
413
|
-
and a test guards against re-adding that check. Model identifiers and tool names
|
|
436
|
+
is not compared to the filename; it must simply be a valid lowercase identifier
|
|
437
|
+
and unique. Model identifiers and tool names
|
|
414
438
|
are likewise not validated: both would need a hardcoded list, which is the shape
|
|
415
439
|
that already shipped a false error. See [plans/003](plans/003-validate-agent-definitions.md).
|
|
416
440
|
|
|
@@ -422,13 +446,14 @@ references measured across 17 projects, 1645 resolved skill-relative and 12 only
|
|
|
422
446
|
at the root. Fenced code blocks are stripped first: a path in an example is
|
|
423
447
|
illustration, not a pointer.
|
|
424
448
|
|
|
425
|
-
`hook.missing-script`
|
|
426
|
-
|
|
427
|
-
(`a && b`, `$(...)`, pipes)
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
`$CLAUDE_PROJECT_DIR` is expanded — other variables are left alone rather
|
|
431
|
-
guessed at.
|
|
449
|
+
`hook.missing-script` and `mcp.command-missing` are deliberately conservative.
|
|
450
|
+
A value is only resolved when it is path-like and the answer is certain; shell
|
|
451
|
+
programs (`a && b`, `$(...)`, pipes), bare PATH binaries (`npx`, `uvx`), and
|
|
452
|
+
unresolved env vars are skipped. A false "broken" on a working `npx` server
|
|
453
|
+
would be worse than silence. `node -e "<code>"` is never treated as a path.
|
|
454
|
+
Only `$CLAUDE_PROJECT_DIR` is expanded — other variables are left alone rather
|
|
455
|
+
than guessed at. Schema checks judge misconfiguration, not whether a correctly
|
|
456
|
+
shaped entry will start at runtime.
|
|
432
457
|
|
|
433
458
|
Checks are written against the published specs, not against what happens to
|
|
434
459
|
appear in real projects. Two that were written the other way round shipped as
|
|
@@ -450,7 +475,9 @@ When adding a check, add its spec line there first.
|
|
|
450
475
|
the `computedHash` in `skills-lock.json` is the obvious `refresh` source; the
|
|
451
476
|
hash algorithm used by the installing tool is not documented here, and it is
|
|
452
477
|
not reproducible from `SKILL.md` bytes alone, so it is not implemented.
|
|
453
|
-
- **
|
|
478
|
+
- **Runtime split.** Source development and the composite Action use Bun; the
|
|
479
|
+
published `dist/cli.js` runs on Node 20.11+ or Bun. The source entrypoint uses
|
|
480
|
+
Bun's `import.meta.dir` / `import.meta.main` and is not the Node entrypoint.
|
|
454
481
|
- Policy files are read up to 100 KB, so `policyLines` undercounts past that.
|
|
455
482
|
|
|
456
483
|
## Development
|
|
@@ -469,14 +496,34 @@ bun run src/cli.ts check tests/fixtures/lock-drift
|
|
|
469
496
|
| `test` | `bun test` |
|
|
470
497
|
| `check` | `bun run src/cli.ts check` |
|
|
471
498
|
|
|
499
|
+
### Release checklist
|
|
500
|
+
|
|
501
|
+
Before publishing a release:
|
|
502
|
+
|
|
503
|
+
1. Confirm `package.json` and `src/version.ts` contain the same version.
|
|
504
|
+
2. Run `bun run build`, then verify `node dist/cli.js --version` prints it.
|
|
505
|
+
3. Run `bun run typecheck`, `bun test`, and `bun run spec:check`.
|
|
506
|
+
4. Refresh the test-count badge and version examples above from that release run.
|
|
507
|
+
|
|
472
508
|
## Design docs
|
|
473
509
|
|
|
474
510
|
**This README is the source of truth for current behavior.** The documents under
|
|
475
511
|
`docs/superpowers/specs/` are the original design and are **superseded** —
|
|
476
|
-
several decisions changed while building: Bun-only runtime
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
(`plans/010`). Read
|
|
512
|
+
several decisions changed while building: the original Bun-only runtime claim was
|
|
513
|
+
superseded by a Node-compatible published bundle, the dep-to-skill map and its
|
|
514
|
+
"orphan" heuristic dropped in favour of `skills-lock.json`, budget checks added,
|
|
515
|
+
structural checks added, and the YAML rule engine deleted (`plans/010`). Read
|
|
516
|
+
them as history, not as behavior.
|
|
517
|
+
|
|
518
|
+
## Skill
|
|
519
|
+
|
|
520
|
+
A Cursor / Agent Skills file lives at [`skills/agentscan/SKILL.md`](skills/agentscan/SKILL.md). Copy the folder so the agent runs the audit before it edits hooks or claims a guard is in place:
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
cp -R skills/agentscan .cursor/skills/agentscan
|
|
524
|
+
# or: .agents/skills/agentscan
|
|
525
|
+
# or: .claude/skills/agentscan
|
|
526
|
+
```
|
|
480
527
|
|
|
481
528
|
## License
|
|
482
529
|
|