@chimix/agentscan 0.7.0 → 1.1.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.
Files changed (4) hide show
  1. package/CHANGELOG.md +368 -0
  2. package/README.md +250 -88
  3. package/dist/cli.js +6863 -833
  4. package/package.json +6 -2
package/CHANGELOG.md ADDED
@@ -0,0 +1,368 @@
1
+ # Changelog
2
+
3
+ Notable changes to `@chimix/agentscan`. Dates are UTC publish days from git
4
+ and the existing GitHub releases. The `check` path stays offline and
5
+ read-only in every version below.
6
+
7
+ GitHub already has release pages for [v0.1.0](https://github.com/SimaAlexandru99/agentscan/releases/tag/v0.1.0)
8
+ and [v0.4.0](https://github.com/SimaAlexandru99/agentscan/releases/tag/v0.4.0).
9
+ 0.9.0 was planned as a separate train and shipped inside 1.0.0.
10
+ 1.0.1 is the shared-MCP hotfix; it is documented below and ships inside 1.1.0
11
+ (the published package version). A separate 1.0.1 npm tag would need an
12
+ intermediate commit that this train does not cut.
13
+
14
+ ## 1.1.0 — 2026-08-31
15
+
16
+ Native Command Code provider, then a correctness pass over every registered
17
+ check against 2026-08-31 official docs. Includes 1.0.1. **87 checks**, **420
18
+ tests**.
19
+
20
+ ### Added
21
+
22
+ - Hook schema profiles: `claude` | `vscode-native` | `copilot-cli` |
23
+ `commandcode`. `.github/hooks` with `version: 1` is Copilot CLI.
24
+ - Claude hook schema: required `type` (not inferred from `command`/`url`);
25
+ `mcp_tool` needs `server` + `tool`; `prompt`/`agent` need `prompt`;
26
+ documented event/handler compatibility; nested matcher groups only.
27
+ - Copilot CLI: camelCase events mapped onto VS Code names; `bash` /
28
+ `powershell` / `command`; `cwd`; `timeoutSec` then `timeout`. Prompt
29
+ hooks only on `sessionStart`. User `~/.copilot/hooks` under `--global`.
30
+ - Agent Skills optional constrained fields: `compatibility` 1..500,
31
+ `metadata` map<string,string>, `allowed-tools` string. Info for
32
+ `SKILL.md` >500 lines. File references resolve from the skill root only.
33
+ - Claude skill listing budget: 1% context window, 8000-character fallback,
34
+ per-entry cap 1536, listing text is description (or first markdown
35
+ paragraph) plus `when_to_use`. First paragraph satisfies missing
36
+ description.
37
+ - OpenCode V2: local `command` must be an argv array
38
+ (`opencode.mcp.command-not-array`).
39
+ - Continue standalone YAML blocks require `name` / `version` / `schema`
40
+ (`continue.mcp.missing-block-metadata`). Copied JSON is not checked.
41
+ - Gemini underscore alias warning (`gemini.mcp.underscore-alias`).
42
+ - Claude reserved MCP names including `workspace`
43
+ (`claude.mcp.reserved-name`).
44
+ - Codex chain knobs: `AGENTS.override.md` > `AGENTS.md` >
45
+ `project_doc_fallback_filenames`; one file per directory; root→cwd;
46
+ `project_doc_max_bytes`; `project_root_markers`.
47
+ - Coverage matrix uses five dimensions (project discovery, global
48
+ discovery, schema, precedence, conformance) instead of `full` /
49
+ `partial`.
50
+ - Conformance fixture `tests/fixtures/conformance/copilot-hooks/`.
51
+ - Spec capture `docs/spec/copilot-hooks.md`. Alias
52
+ `claude.hook.mcp-tool-without-name` →
53
+ `claude.hook.mcp-tool-without-server-or-tool`.
54
+
55
+ ### Changed
56
+
57
+ - Nested `<dir>/.commandcode/AGENTS.md` is Command Code memory when that
58
+ directory has no `AGENTS.md` (official memory table).
59
+ - Native VS Code remains command-only with its documented eight events.
60
+ `vscode.hook.http-without-url` and `vscode.hook.mcp-tool-without-name`
61
+ are removed.
62
+ - Claude agent names: lowercase letters and hyphens (no digits); filename
63
+ is not compared to `name`.
64
+ - `skill.description-budget` provenance is vendor-recommendation, not a
65
+ 16000-byte heuristic.
66
+
67
+ ### Added (Command Code provider)
68
+
69
+ - Provider `commandcode` from official pages under `docs/spec/commandcode-*.md`
70
+ (read 2026-08-31). Unknown stays skip: no invented local-project MCP slug,
71
+ no bundled-skill scan, no `--skill` flags, no model-id list, no mods
72
+ execution.
73
+ - Skills: `.commandcode/skills` only at the Command Code project root
74
+ (Agent Skills contract), `.agents/skills` walk-up (max 10 hops from cwd,
75
+ stopping at home), extra dirs from the highest-precedence settings
76
+ `skills` array (replace, not merge; relative paths resolve against the git
77
+ root). User `~/.commandcode/skills` and `~/.agents/skills` under
78
+ `--global`.
79
+ - Memory: per directory, first existing of `AGENTS.md` or
80
+ `.commandcode/AGENTS.md` (project and nested). User
81
+ `~/.commandcode/AGENTS.md` under `--global`. Unresolved `@path` is not a
82
+ hard error. Codex's instruction chain excludes `.commandcode/AGENTS.md`.
83
+ - Agents: `<project>/.commandcode/agents/*.md` at the Command Code project
84
+ root only (git root, or cwd outside a git repo); filename supplies
85
+ `name`; no `claude.agent.*` on these files. Checks:
86
+ `commandcode.agent.reserved-name` (`explore` / `plan` / `review` /
87
+ `general`), `invalid-permission-mode`, `invalid-field-type` covering every
88
+ documented custom-agent typed field (`reasoningEffort` is not one of them).
89
+ `maxTurns` must be a positive integer.
90
+ - Hooks: four events (`PreToolUse`, `PostToolUse`, `Stop`, `SessionStart`);
91
+ nested `hooks` array required; `type` must be the string `"command"`;
92
+ `command` must be a string (not an argv array); `matcher` must be a string
93
+ when present. Timeout 0–600. A matcher on `Stop` / `SessionStart` is
94
+ runtime-dead, not a schema error. Project and user hooks for the same event
95
+ coexist; only an exact duplicate command string is deduplicated (project
96
+ wins). `settings.local.json` follows settings merge (an event array
97
+ replaces the project array for that event). `COMMANDCODE_PROJECT_DIR` and
98
+ `COMMANDCODE_CWD` expand against the Command Code project root.
99
+ - Settings: Command Code project root is the git root (a child `.cursor`
100
+ does not hide `<git-root>/.commandcode/`). `model` inventoried, not
101
+ validated. Inline `mcp.servers` (array or object map; unnamed array items
102
+ are inventory-only). User `~/.commandcode/mcp.json` under `--global`.
103
+ Spec/runtime checks skip shadowed lower-precedence definitions; security
104
+ checks still inspect every readable MCP file.
105
+ - Slash commands: inventory `.commandcode/commands` at the project root and
106
+ the user dir — no required-field checks.
107
+ - Mods: inventory `mods.paths` — never execute or import TypeScript.
108
+ - Conformance fixture `tests/fixtures/conformance/commandcode/`.
109
+ - `spec:check` tracks captured surfaces and diffs Claude, VS Code, Copilot
110
+ CLI, and Command Code hook events against live pages.
111
+
112
+ ### Also changed
113
+
114
+ - Default `skillPaths` includes `.commandcode/skills`.
115
+ - `--global` / `includeGlobal` also scans `~/.commandcode/skills`,
116
+ `~/.agents/skills`, user Command Code agents, MCP, memory, Copilot user
117
+ hooks, and Codex global AGENTS files.
118
+ - Shared `.mcp.json` is `mcp-json`, not Claude-only.
119
+
120
+ ## 1.0.1 — 2026-08-31
121
+
122
+ Shared `.mcp.json` is not Claude-only. Command Code writes it for `--scope
123
+ project` with `transport` (and `type` as an alias). A Claude-keyed
124
+ `url`-without-`type` check on that path is a false positive on valid
125
+ Command Code HTTP config.
126
+
127
+ ### Fixed
128
+
129
+ - `.mcp.json` uses schema profile `mcp-json`, `consumedBy: ["claude",
130
+ "commandcode"]`, `sourceProvider: "unknown"`. `.claude/mcp.json` and
131
+ project `mcp.json` stay `claude-json`.
132
+ - Parse `transport` first; `type` is an alias. Store which field was
133
+ present.
134
+ - `claude.mcp.url-without-type` on `mcp-json` fires only when `url` is set
135
+ and transport is unset. On `claude-json` it still fires when the field is
136
+ `transport` or missing. `{ "transport": "http", "url": "…" }` does not
137
+ emit this.
138
+ - Command Code transport defects on `mcp-json` and `commandcode-json`:
139
+ `commandcode.mcp.invalid-transport`, `http-without-url`,
140
+ `stdio-without-command`. Valid transports are `http` and `stdio`. Claude
141
+ `sse` / `ws` on shared `.mcp.json` is not a Command Code invalid-transport.
142
+ - Empty launch on `mcp-json` still emits `claude.mcp.no-launch` (both
143
+ consumers need a launch field). `commandcode-json` empty launch emits
144
+ `commandcode.mcp.no-launch`.
145
+ - `looksLikeServerEntry` recognises `transport`. Absolute MCP paths under
146
+ `--global` are not joined as relative.
147
+
148
+ ### Security
149
+
150
+ - Never open `~/.commandcode/auth.json` or `mcp-tokens.json`.
151
+ - Local `~/.commandcode/projects/{project}/mcp.json` is unread: the slug
152
+ encoding is unpublished. Prefer skip over inventing it.
153
+
154
+ ## 1.0.0 — 2026-08-30
155
+
156
+ First stable release. 59 checks, 345 tests. The coverage matrix in the
157
+ README is the honesty contract: `full` only where discovery, spec-required
158
+ fields, and a conformance fixture (or equivalent tests) all exist.
159
+
160
+ ### Added
161
+
162
+ - Portable Agent Skills required fields (`name`, `description`, directory
163
+ match) for `.agents/skills`, nested Cursor `.cursor/skills`, and
164
+ `.codex/skills`.
165
+ - Path-keyed MCP parsers: VS Code `servers`, Cursor, Antigravity
166
+ `serverUrl`, Codex TOML, Gemini `command` / `url` / `httpUrl`, OpenCode
167
+ V1 and V2, Continue `config.yaml` plus `.continue/mcpServers/*`.
168
+ - Nested / walk-up `AGENTS.md` with nearest-wins; Codex instruction budget
169
+ uses the effective per-directory file and `project_doc_max_bytes`.
170
+ - Walk-up `.claude/agents`; VS Code `.github/agents` without Claude
171
+ missing-name errors.
172
+ - VS Code `.github/hooks/*.json` (eight events) and per-provider hook
173
+ event sets.
174
+ - Cursor `.cursor/rules/**/*.mdc` 500-line recommendation
175
+ (`cursor.rule.too-large`, info). Claude rules are inventoried only.
176
+ - Official-shaped fixtures under `tests/fixtures/conformance/`.
177
+ - `spec:check` tracks 21 captured surfaces, not only Claude hook events.
178
+ - Launch `cwd` and `windows` / `linux` / `osx` overrides on hooks and MCP.
179
+ - GitHub Action pin `@v1`.
180
+
181
+ ### Changed
182
+
183
+ - Product copy describes what 1.0.0 actually implements. Heuristics stay
184
+ at `info` and are labeled in the registry.
185
+ - `--global` also scans `~/.codex/skills` under the Agent Skills contract.
186
+ - In a monorepo, each `skills-lock.json` governs only the skills under
187
+ its directory (nearest lock wins).
188
+
189
+ ### Fixed
190
+
191
+ - Nested `SKILL.md` trees are one skill, not a missing-md folder.
192
+ - Codex instruction chain: at most one file per directory; honour
193
+ `project_doc_max_bytes`.
194
+ - Interpreter argv (`node script.js`), MCP `command` arrays, and OS
195
+ overrides are path-checked. `--` inline code (`node -e`) is not a path.
196
+ - JSONC (comments and trailing commas) parses via `jsonc-parser`; the
197
+ published bundle imports the ESM entry so Node can load `dist/cli.js`.
198
+ - Scan boundary stays at Git/workspace. A child `.cursor` does not hide
199
+ parent Claude or Codex.
200
+ - `uses:` is a launch only on Continue. Other profiles treat a uses-only
201
+ entry as non-launchable.
202
+ - OpenCode V2 requires `type` plus the matching launch field. V1
203
+ enabled-only overrides that inherit externally do not emit a hard error.
204
+ - Windows drive / UNC cwd values and OS-specific script paths
205
+ (`scripts\format.ps1`) are not joined as POSIX relative paths when the
206
+ scanner runs on Linux or macOS. Those launches are inventoried;
207
+ `scriptExists` / `commandExists` stay unset. Host-matching and
208
+ platform-neutral launches stay fully checked. `C:foo` is unresolved,
209
+ not absolute.
210
+ - Old 0.7 rule ids still work in `ignoreRules` and `explain`.
211
+
212
+ ## 0.8.0 — 2026-08-30
213
+
214
+ Honesty pass after the multi-provider audit. 38 checks, 267 tests.
215
+
216
+ ### Added
217
+
218
+ - Agent Skills profile on `.agents/skills` (required `name` /
219
+ `description`).
220
+ - MCP profile parsers for VS Code `.vscode/mcp.json` (`servers`), Cursor
221
+ `.cursor/mcp.json`, Antigravity `serverUrl`, and Codex
222
+ `[mcp_servers.*]` TOML.
223
+ - Nearest-signal project root: a child `.cursor` / `.claude` wins over a
224
+ parent `package.json`.
225
+ - Provenance on every registry entry (`spec-required`,
226
+ `vendor-recommendation`, `security`, `internal-consistency`,
227
+ `heuristic`).
228
+ - First coverage matrix (full / partial / none) for the surfaces this
229
+ version actually implemented.
230
+
231
+ ### Changed
232
+
233
+ - Claude check ids are namespaced (`claude.hook.missing-script`, …).
234
+ `ignoreRules` and `explain` accept the old 0.7 ids as aliases.
235
+ - README no longer claims every check is spec-sourced or that there are
236
+ no heuristics. Size opinions and installer policy stay at `info`.
237
+ - `budget.claude-md` quotes the official “target under 200 lines”
238
+ recommendation instead of an unsourced 150–200 / 50-token story.
239
+
240
+ ## 0.7.0 — 2026-08-24
241
+
242
+ 27 checks, 250 tests.
243
+
244
+ ### Added
245
+
246
+ - Hooks from in-tree plugin `hooks/hooks.json` and from skill / subagent
247
+ frontmatter, not only the two settings files.
248
+ `${CLAUDE_PLUGIN_ROOT}` expands only for a plugin-sourced hook.
249
+
250
+ ### Changed
251
+
252
+ - `engines.bun` is `>=1.4.0`. The repo ships the text `bun.lock`
253
+ (lockfileVersion 1); Bun 1.1 wrote `bun.lockb` and cannot read it, so
254
+ the old `>=1.1.0` floor was false. `engines.node` stays `>=20.11.0`.
255
+ - CI pins Bun; `Bun.YAML` is rejected in favour of the `yaml` package.
256
+
257
+ ## 0.6.0 — 2026-08-24
258
+
259
+ Stop reporting valid config as broken. 27 checks, 235 tests.
260
+
261
+ ### Added
262
+
263
+ - `scan.truncated` (info): a file past the 64 KB skill or 100 KB policy
264
+ cap is parsed from its prefix. The finding is about this scanner’s
265
+ reach, not about the file being invalid.
266
+
267
+ ### Changed
268
+
269
+ - `skill.duplicate-description` and `skill.description-budget` group by
270
+ the directory that owns the skill, so two apps in a monorepo no longer
271
+ look like a collision.
272
+ - `agent.invalid-name` drops from error to warning. The subagent
273
+ reference specifies the name format but documents a load failure only
274
+ for `:`.
275
+ - `--verbose` prints each finding’s id so the value `explain` and
276
+ `ignoreFindings` take can be copied out of the report.
277
+
278
+ ### Fixed
279
+
280
+ - A `SKILL.md` over the scan cap is no longer `config.unreadable` at
281
+ error. Claude Code still loads that file; the frontmatter sits in the
282
+ first 300 bytes.
283
+ - The Action’s `GITHUB_OUTPUT` heredoc delimiter is randomised.
284
+
285
+ Measured on the three projects that reproduced the defects: touchagency
286
+ 0 → 34, kronstadt-ehs-2026 40 → 94, optimad 0 → 85.
287
+
288
+ ## 0.5.0 — 2026-08-12
289
+
290
+ 26 checks.
291
+
292
+ ### Added
293
+
294
+ - `agentscan demo`: throwaway fixture with the killer missing-hook case,
295
+ human report, then delete.
296
+ - Trees with agent config and no `package.json` are scannable.
297
+ - `mcp.command-missing`: path-like `command` values are compared to
298
+ disk. Bare PATH binaries, shell compounds, and unresolved env vars
299
+ are skipped.
300
+
301
+ ### Changed
302
+
303
+ - Severity labels and neutral multi-event group headlines in the text
304
+ report.
305
+ - Public check count synced to 26.
306
+
307
+ ## 0.4.0 — 2026-08-09
308
+
309
+ Colour, a face, and a report that reads at a glance. 23 checks, 195
310
+ tests. [GitHub release](https://github.com/SimaAlexandru99/agentscan/releases/tag/v0.4.0).
311
+
312
+ ### Added
313
+
314
+ - Terminal header with score, face, and bar. Piped output stays
315
+ byte-identical to the uncoloured report. `--json`, `--output prompt`,
316
+ and `--copy` are never coloured. `--no-color` and `NO_COLOR` are
317
+ honoured.
318
+
319
+ ### Changed
320
+
321
+ - The YAML rule engine is gone (709 lines, 9 info findings across 21
322
+ projects, unused extension point). Its five rules are code, with
323
+ byte-identical output.
324
+
325
+ ## 0.3.0 — 2026-08-09
326
+
327
+ ### Changed
328
+
329
+ - Repeated findings group: six dead hooks print one header with `×6`
330
+ and one line per occurrence.
331
+ - Paths are shown relative to the scanned project.
332
+ - The score word (`broken`, …) comes from the same thresholds as the
333
+ face and the colour, so they cannot disagree.
334
+
335
+ ## 0.2.1 — 2026-08-09
336
+
337
+ ### Changed
338
+
339
+ - Bare invocation (`npx @chimix/agentscan`) scans the current
340
+ directory. The quick start shows findings instead of a usage screen.
341
+
342
+ ## 0.2.0 — 2026-08-09
343
+
344
+ ### Added
345
+
346
+ - Published `dist/cli.js` runs on Node 20.11+ as well as Bun. `npx
347
+ @chimix/agentscan@latest` works without Bun installed. One bundled
348
+ file, no install-time dependencies.
349
+
350
+ ## 0.1.0 — 2026-08-09
351
+
352
+ First alpha. [GitHub release](https://github.com/SimaAlexandru99/agentscan/releases/tag/v0.1.0).
353
+ 23 checks, each written against a published spec line in `docs/spec/`.
354
+
355
+ ### Added
356
+
357
+ - Deterministic offline CLI: broken hooks, unlaunchable MCP, credentials
358
+ pasted into config, skills that disagree with their lockfile.
359
+ - `check`, `--output prompt`, `--fail-on`, `--json`.
360
+ - Published score: `max(0, 100 - 10 × errors - 3 × warnings)`.
361
+ Coverage-ratio scoring was built, measured, and rejected.
362
+ - Published as `@chimix/agentscan` — npm rejects the bare name as too
363
+ close to an unrelated `agent-scan`. The command stays `agentscan`.
364
+
365
+ An earlier build reported 37 findings across 17 projects of which 25
366
+ were false, because two checks were written from observation. Both were
367
+ deleted before this release. Requires Bun for source development; `check`
368
+ never opens a socket and never writes the scanned tree.