@chimix/agentscan 1.1.0 → 2.0.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/CHANGELOG.md +391 -0
- package/README.md +377 -154
- package/dist/cli.js +6422 -5421
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -5,19 +5,19 @@
|
|
|
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-143-111111?style=flat-square" alt="143 checks">
|
|
9
|
+
<img src="https://img.shields.io/badge/tests-647%20passing-111111?style=flat-square" alt="647 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">
|
|
13
13
|
<img src="https://img.shields.io/npm/v/@chimix/agentscan?style=flat-square&color=111111&label=npm" alt="npm version">
|
|
14
14
|
<img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
|
|
15
|
-
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-
|
|
15
|
+
<a href="CHANGELOG.md"><img src="https://img.shields.io/badge/changelog-2.0.0-111111?style=flat-square" alt="Changelog"></a>
|
|
16
16
|
</p>
|
|
17
17
|
|
|
18
18
|
<p align="center">
|
|
19
|
-
<strong>
|
|
20
|
-
<sub>An offline linter for Claude Code, Command Code, portable Agent Skills, nested AGENTS.md, Copilot CLI hooks, and the MCP / hooks / rules surfaces
|
|
19
|
+
<strong>143 checks · offline · 0 network calls on <code>check</code> · provenance on every rule</strong><br>
|
|
20
|
+
<sub>An offline linter for Claude Code, Command Code, Grok Build, Windsurf, Kiro, Cline, Roo, Kilo, Junie, portable Agent Skills, nested AGENTS.md, Copilot CLI hooks (including inline settings), and the MCP / hooks / rules surfaces the registry actually implements. Spec-required checks cite a published line in <a href="docs/spec/">docs/spec/</a>. Heuristics stay at <code>info</code> and say so. The coverage matrix below is the honesty contract — five dimensions, and a documented global location that is not scanned stays unread.</sub>
|
|
21
21
|
</p>
|
|
22
22
|
|
|
23
23
|
---
|
|
@@ -63,9 +63,9 @@ of the filesystem**, where nothing else in your stack will ever tell you.
|
|
|
63
63
|
No AI, no network on `check`. Read the config, read the disk, compare:
|
|
64
64
|
|
|
65
65
|
```
|
|
66
|
-
1. Discover .claude/ .commandcode/ .agents/ .vscode/ .cursor/ .codex/ .gemini/ .github/ .continue/ AGENTS.md skills-lock.json
|
|
66
|
+
1. Discover .claude/ .commandcode/ .grok/ .agents/ .vscode/ .cursor/ .codex/ .gemini/ .github/ .continue/ AGENTS.md skills-lock.json
|
|
67
67
|
2. Extract immutable facts — never re-read during checking
|
|
68
|
-
3. Check
|
|
68
|
+
3. Check 143 checks, each labeled spec-required, vendor-recommendation,
|
|
69
69
|
security, internal-consistency, or heuristic
|
|
70
70
|
4. Report text · --json · --output prompt (handoff for a fixing agent)
|
|
71
71
|
```
|
|
@@ -116,8 +116,8 @@ too close to an unrelated `agent-scan`. The command you type stays `agentscan`.
|
|
|
116
116
|
bun add -d @chimix/agentscan # then: bunx agentscan check
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
Point it at a project that actually has agent config — a `.claude
|
|
120
|
-
`.commandcode/` directory, an `.mcp.json`, an `AGENTS.md`. A directory with
|
|
119
|
+
Point it at a project that actually has agent config — a `.claude/`,
|
|
120
|
+
`.commandcode/`, or `.grok/` directory, an `.mcp.json`, an `AGENTS.md`. A directory with
|
|
121
121
|
agent config and no `package.json` is still scannable. On a directory with
|
|
122
122
|
neither it exits with a clear error.
|
|
123
123
|
|
|
@@ -164,7 +164,7 @@ bunx agentscan check # text report (cwd)
|
|
|
164
164
|
bunx agentscan check ./my-app # explicit root
|
|
165
165
|
bunx agentscan check --json # machine-readable
|
|
166
166
|
bunx agentscan check --quiet # summary only
|
|
167
|
-
bunx agentscan check --verbose # include
|
|
167
|
+
bunx agentscan check --verbose # include info findings and each finding's id
|
|
168
168
|
bunx agentscan check --fail-on warning
|
|
169
169
|
bunx agentscan check --global # also scan global skill dirs
|
|
170
170
|
|
|
@@ -183,10 +183,10 @@ Flags for `check`:
|
|
|
183
183
|
| `--copy` | Also copy the report to the system clipboard |
|
|
184
184
|
| `--no-color` | Never colour, even on a terminal (`NO_COLOR=1` does the same) |
|
|
185
185
|
| `--quiet` | Summary line only |
|
|
186
|
-
| `--verbose` | Show
|
|
186
|
+
| `--verbose` | Show info-severity findings, and print each finding's id |
|
|
187
187
|
| `--fail-on <level>` | `never` (default) · `warning` · `error` |
|
|
188
188
|
| `--fail-under <0-100>` | Fail when the score drops below this floor |
|
|
189
|
-
| `--global` | Also scan `~/.claude/skills`, `~/.codex/skills`, `~/.commandcode/skills`, and `~/.agents/skills` (see below) |
|
|
189
|
+
| `--global` | Also scan user skills (`$CLAUDE_CONFIG_DIR/skills` or `~/.claude/skills`, `~/.codex/skills`, `~/.commandcode/skills`, `~/.agents/skills`, `$GROK_HOME/skills`, `~/.codeium/windsurf/skills`), Claude user settings / agents / `CLAUDE.md` / rules / commands and `$CLAUDE_CONFIG_DIR/.claude.json` or `~/.claude.json` (user + matching local `mcpServers`), Copilot `$COPILOT_HOME` / `~/.copilot/hooks` and `settings.json`, Codex `$CODEX_HOME` / `~/.codex/hooks.json` and `config.toml` (MCP plus inline `[hooks]`), Grok `$GROK_HOME` / `~/.grok` (hooks + `config.toml`), Command Code user MCP/agents/memory, Antigravity `~/.gemini/config/hooks.json`, `rules/`, and `skills/`, plus `~/.gemini/AGENTS.md` and `GEMINI.md`, Kiro `~/.kiro/agents`, and Windsurf `~/.codeium/windsurf` MCP + `global_rules.md` + `hooks.json` (see below) |
|
|
190
190
|
| `--config <path>` | Config file path |
|
|
191
191
|
|
|
192
192
|
**v1 does not write the tree** — no `apply`, no skill delete/install. Findings may *suggest* shell commands; you run them yourself.
|
|
@@ -199,7 +199,7 @@ Flags for `check`:
|
|
|
199
199
|
│ ⌒ │ 6 error · 2 warning · 11 info hidden (--verbose)
|
|
200
200
|
└─────┘
|
|
201
201
|
|
|
202
|
-
agentscan
|
|
202
|
+
agentscan v2.0.0 — touchagency
|
|
203
203
|
|
|
204
204
|
Scanned: 46 deps · 108 skills · 1 mcp · 2 agents · packageManager=bun
|
|
205
205
|
|
|
@@ -231,7 +231,7 @@ JSON shape (abridged):
|
|
|
231
231
|
|
|
232
232
|
```json
|
|
233
233
|
{
|
|
234
|
-
"version": "
|
|
234
|
+
"version": "2.0.0",
|
|
235
235
|
"root": "/path/to/project",
|
|
236
236
|
"factsSummary": {
|
|
237
237
|
"packageManager": "bun",
|
|
@@ -259,14 +259,27 @@ Same tree → same sorted findings, with stable unique `id`s.
|
|
|
259
259
|
|
|
260
260
|
### `--global`
|
|
261
261
|
|
|
262
|
-
Adds
|
|
263
|
-
`~/.agents/skills
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
262
|
+
Adds user skill dirs (`$CLAUDE_CONFIG_DIR/skills` or `~/.claude/skills`, `~/.codex/skills`,
|
|
263
|
+
`~/.commandcode/skills`, `~/.agents/skills`, `$GROK_HOME/skills` or
|
|
264
|
+
`~/.grok/skills`), Claude user settings / agents / `CLAUDE.md` / rules /
|
|
265
|
+
commands and `~/.claude.json` (top-level user `mcpServers` plus local
|
|
266
|
+
`projects.<scanned-path>.mcpServers`), Copilot `~/.copilot/hooks`, Codex `$CODEX_HOME` /
|
|
267
|
+
`~/.codex` (`hooks.json`, `config.toml` MCP and inline `[hooks]`, plus `AGENTS.override.md` / `AGENTS.md`),
|
|
268
|
+
Grok `$GROK_HOME` / `~/.grok` (hooks + `config.toml`), Antigravity
|
|
269
|
+
`~/.gemini/config/hooks.json`, `rules/`, and `skills/`, plus
|
|
270
|
+
`~/.gemini/AGENTS.md` and `GEMINI.md`, Kiro `~/.kiro/agents`, Command Code user
|
|
271
|
+
agents / MCP / memory, and Windsurf `~/.codeium/windsurf/mcp_config.json`,
|
|
272
|
+
`memories/global_rules.md`, `hooks.json`, and `skills` to the structural checks: a `SKILL.md` that
|
|
273
|
+
is malformed is malformed wherever it lives, and those findings carry a
|
|
274
|
+
`source: global` evidence entry so you can tell them apart. Codex and
|
|
275
|
+
Command Code skills use the Agent Skills contract (`name` and `description`
|
|
276
|
+
required). Grok skills do not — `name` and `description` are optional. It
|
|
277
|
+
never opens `auth.json`, `mcp-tokens.json`, Codex `auth.json`, or Grok
|
|
278
|
+
`auth.json` / `mcp_credentials.json`. A `~/.claude.json` without user or
|
|
279
|
+
matching local `mcpServers` is skipped, not reported as unreadable.
|
|
280
|
+
`CLAUDE_CONFIG_DIR` relocates the `~/.claude` directory and, when set,
|
|
281
|
+
`~/.claude.json` to `$CLAUDE_CONFIG_DIR/.claude.json`. Unset, that file
|
|
282
|
+
stays in the home directory.
|
|
270
283
|
|
|
271
284
|
Lockfile checks stay project-scoped — a project lockfile cannot pin a skill that
|
|
272
285
|
lives in your home directory, so reporting one as "not in the lockfile" could
|
|
@@ -346,7 +359,7 @@ Optional `.agentscanrc.json` (create with `agentscan init`):
|
|
|
346
359
|
|
|
347
360
|
```json
|
|
348
361
|
{
|
|
349
|
-
"skillPaths": [".agents/skills", ".claude/skills", "skills", ".cursor/skills", ".codex/skills", ".commandcode/skills"],
|
|
362
|
+
"skillPaths": [".agents/skills", ".claude/skills", "skills", ".cursor/skills", ".codex/skills", ".commandcode/skills", ".grok/skills", ".windsurf/skills"],
|
|
350
363
|
"mcpPaths": [".mcp.json", ".claude/mcp.json", "mcp.json", ".vscode/mcp.json", ".cursor/mcp.json", ".agents/mcp_config.json", ".codex/config.toml", ".gemini/settings.json", "opencode.json", "opencode.jsonc", ".opencode/opencode.json", ".opencode/opencode.jsonc", ".continue/config.yaml", ".continue/mcpServers"],
|
|
351
364
|
"policyFiles": ["AGENTS.md", "CLAUDE.md"],
|
|
352
365
|
"ignoreSkills": [],
|
|
@@ -423,101 +436,181 @@ Every check lives in `src/checks/` and runs on every `check`. `agentscan rules`
|
|
|
423
436
|
lists all of them with their ids; `agentscan explain <id>` details any finding.
|
|
424
437
|
|
|
425
438
|
Most validate one discovered item against its own file on disk. Budget and
|
|
426
|
-
hygiene checks are **info** (hidden unless `--verbose`).
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
|
454
|
-
|
|
455
|
-
| `
|
|
456
|
-
| `
|
|
457
|
-
| `
|
|
458
|
-
| `
|
|
459
|
-
| `
|
|
460
|
-
| `
|
|
461
|
-
| `
|
|
462
|
-
| `
|
|
463
|
-
| `
|
|
464
|
-
| `claude.hook.
|
|
465
|
-
| `claude.hook.
|
|
466
|
-
| `claude.hook.
|
|
467
|
-
| `claude.hook.
|
|
468
|
-
| `
|
|
469
|
-
| `
|
|
470
|
-
| `
|
|
471
|
-
| `
|
|
472
|
-
| `
|
|
473
|
-
| `
|
|
474
|
-
| `copilot.hook.
|
|
475
|
-
| `copilot.hook.
|
|
476
|
-
| `copilot.hook.
|
|
477
|
-
| `copilot.hook.
|
|
478
|
-
| `
|
|
479
|
-
| `
|
|
480
|
-
| `
|
|
481
|
-
| `
|
|
482
|
-
| `
|
|
483
|
-
| `
|
|
484
|
-
| `
|
|
485
|
-
| `
|
|
486
|
-
| `
|
|
487
|
-
| `
|
|
488
|
-
| `
|
|
489
|
-
| `
|
|
490
|
-
| `
|
|
491
|
-
| `
|
|
492
|
-
| `
|
|
493
|
-
| `skill.
|
|
494
|
-
| `
|
|
495
|
-
| `
|
|
496
|
-
| `
|
|
497
|
-
| `
|
|
498
|
-
| `agent
|
|
499
|
-
| `agent
|
|
500
|
-
| `agent-
|
|
501
|
-
| `agent-
|
|
502
|
-
| `agent
|
|
503
|
-
| `
|
|
504
|
-
| `
|
|
505
|
-
| `
|
|
506
|
-
| `
|
|
507
|
-
| `
|
|
508
|
-
| `
|
|
509
|
-
| `
|
|
510
|
-
| `
|
|
511
|
-
| `
|
|
512
|
-
| `
|
|
513
|
-
| `
|
|
514
|
-
| `
|
|
515
|
-
| `
|
|
516
|
-
| `
|
|
517
|
-
| `
|
|
518
|
-
| `
|
|
519
|
-
|
|
520
|
-
|
|
439
|
+
hygiene checks are **info** (hidden unless `--verbose`).
|
|
440
|
+
|
|
441
|
+
Every rule states where its assertion comes from, and every report says so:
|
|
442
|
+
a `provenance` label (spec-required, vendor-recommendation, security,
|
|
443
|
+
internal-consistency, or heuristic) and either the vendor page it was read
|
|
444
|
+
from, with the date, or an explicit note that no vendor page states it.
|
|
445
|
+
|
|
446
|
+
```
|
|
447
|
+
ERROR rule:cursor.hook.unknown-event
|
|
448
|
+
"bogusEventName" is not a hook event that gets dispatched
|
|
449
|
+
bogusEventName @ .cursor/hooks.json · sessionStart, sessionEnd, ...
|
|
450
|
+
spec-required · cursor.com/docs/hooks · read 2026-09-03
|
|
451
|
+
|
|
452
|
+
ERROR rule:cursor.hook.missing-script
|
|
453
|
+
Hook points at a script that does not exist
|
|
454
|
+
afterFileEdit @ .cursor/hooks.json · ./hooks/format.sh
|
|
455
|
+
internal-consistency · no vendor page · agentscan inference
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
`agentscan rules` lists every rule with its severity, provenance and source;
|
|
459
|
+
`agentscan rules --json` adds the full URL and the `docs/spec` capture holding
|
|
460
|
+
the quoted lines; `agentscan explain <id>` prints both for one finding, and
|
|
461
|
+
`--json` carries them on every finding. Every cited page is one
|
|
462
|
+
`bun run spec:check` re-fetches and hash-compares, so a vendor rewriting it
|
|
463
|
+
fails CI instead of quietly turning a quoted rule into a false positive.
|
|
464
|
+
|
|
465
|
+
<!-- rules:start -->
|
|
466
|
+
| id | Severity | Provenance | Source | Catches |
|
|
467
|
+
|----|----------|------------|--------|---------|
|
|
468
|
+
| `config.unreadable` | error | internal-consistency | _parser result_ | Config file is not valid JSON or cannot be read |
|
|
469
|
+
| `scan.truncated` | info | internal-consistency | _scan cap_ | File is larger than the scan cap, so body checks read only a prefix of it |
|
|
470
|
+
| `claude.hook.unknown-event` | error | spec-required | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Hook registered under an event name that is never dispatched |
|
|
471
|
+
| `claude.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Hook points at a script that does not exist, so it never runs |
|
|
472
|
+
| `vscode.hook.unknown-event` | error | spec-required | [code.visualstudio.com/docs/agents/reference/hooks-reference](https://code.visualstudio.com/docs/agents/reference/hooks-reference) | VS Code hook registered under an event name that is never dispatched |
|
|
473
|
+
| `vscode.hook.missing-script` | error | internal-consistency | _agentscan inference_ | VS Code hook points at a script that does not exist, so it never runs |
|
|
474
|
+
| `claude.hook.invalid-group` | error | internal-consistency | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Claude hook group has a matcher but no hooks array |
|
|
475
|
+
| `claude.hook.command-without-command` | error | spec-required | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Claude command hook is missing the command field |
|
|
476
|
+
| `claude.hook.http-without-url` | error | spec-required | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Claude http hook is missing the url field |
|
|
477
|
+
| `claude.hook.mcp-tool-without-server-or-tool` | error | spec-required | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Claude MCP tool hook is missing required server and tool fields |
|
|
478
|
+
| `claude.hook.unknown-handler-type` | error | spec-required | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Claude hook uses a handler type that is not command, http, mcp_tool, prompt, or agent, or omits the required type |
|
|
479
|
+
| `claude.hook.prompt-without-prompt` | error | spec-required | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Claude prompt or agent hook is missing the required prompt field |
|
|
480
|
+
| `claude.hook.incompatible-handler` | error | spec-required | [code.claude.com/docs/en/hooks](https://code.claude.com/docs/en/hooks) | Claude hook handler type is not valid for its event |
|
|
481
|
+
| `vscode.hook.invalid-group` | error | internal-consistency | [code.visualstudio.com/docs/agents/reference/hooks-reference](https://code.visualstudio.com/docs/agents/reference/hooks-reference) | VS Code hook group has a matcher but no hooks array |
|
|
482
|
+
| `vscode.hook.command-without-command` | error | spec-required | [code.visualstudio.com/docs/agents/reference/hooks-reference](https://code.visualstudio.com/docs/agents/reference/hooks-reference) | VS Code command hook is missing the command field |
|
|
483
|
+
| `vscode.hook.unknown-handler-type` | error | spec-required | [code.visualstudio.com/docs/agents/reference/hooks-reference](https://code.visualstudio.com/docs/agents/reference/hooks-reference) | VS Code hook uses a handler type other than the required type command |
|
|
484
|
+
| `copilot.hook.unknown-event` | error | spec-required | [docs.github.com/en/copilot/reference/hooks-reference](https://docs.github.com/en/copilot/reference/hooks-reference) | Copilot CLI hook registered under an event name that is never dispatched |
|
|
485
|
+
| `copilot.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Copilot CLI hook points at a script that does not exist, so it never runs |
|
|
486
|
+
| `copilot.hook.command-without-command` | error | spec-required | [docs.github.com/en/copilot/reference/hooks-reference](https://docs.github.com/en/copilot/reference/hooks-reference) | Copilot CLI command hook declares none of bash, powershell, command, or exec |
|
|
487
|
+
| `copilot.hook.http-without-url` | error | spec-required | [docs.github.com/en/copilot/reference/hooks-reference](https://docs.github.com/en/copilot/reference/hooks-reference) | Copilot CLI http hook is missing the url field |
|
|
488
|
+
| `copilot.hook.prompt-without-prompt` | error | spec-required | [docs.github.com/en/copilot/reference/hooks-reference](https://docs.github.com/en/copilot/reference/hooks-reference) | Copilot CLI prompt hook is missing the prompt field |
|
|
489
|
+
| `copilot.hook.unknown-handler-type` | error | spec-required | [docs.github.com/en/copilot/reference/hooks-reference](https://docs.github.com/en/copilot/reference/hooks-reference) | Copilot CLI hook uses a handler type that is not command, http, or prompt |
|
|
490
|
+
| `copilot.hook.incompatible-handler` | error | spec-required | [docs.github.com/en/copilot/reference/hooks-reference](https://docs.github.com/en/copilot/reference/hooks-reference) | Copilot CLI prompt hook is registered on an event other than sessionStart |
|
|
491
|
+
| `skill.missing-skill-md` | warning | internal-consistency | [agentskills.io/specification](https://agentskills.io/specification) | Skill directory has no SKILL.md |
|
|
492
|
+
| `claude.skill.missing-frontmatter` | warning | spec-required | [code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills) | SKILL.md has no YAML frontmatter block |
|
|
493
|
+
| `claude.skill.missing-description` | info | vendor-recommendation | [code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills) | SKILL.md frontmatter has no description and no first markdown paragraph |
|
|
494
|
+
| `agent-skills.skill.missing-frontmatter` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill SKILL.md has no YAML frontmatter block |
|
|
495
|
+
| `agent-skills.skill.missing-name` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill frontmatter has no required name |
|
|
496
|
+
| `agent-skills.skill.missing-description` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill frontmatter has no required description |
|
|
497
|
+
| `agent-skills.skill.invalid-name` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill name is not a valid identifier |
|
|
498
|
+
| `agent-skills.skill.name-does-not-match-directory` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill name does not match its directory |
|
|
499
|
+
| `agent-skills.skill.name-too-long` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill name exceeds 64 characters |
|
|
500
|
+
| `agent-skills.skill.description-too-long` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill description exceeds 1024 characters |
|
|
501
|
+
| `agent-skills.skill.invalid-compatibility` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill compatibility is not a string of 1–500 characters |
|
|
502
|
+
| `agent-skills.skill.invalid-metadata` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill metadata is not a map of string to string |
|
|
503
|
+
| `agent-skills.skill.invalid-allowed-tools` | error | spec-required | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill allowed-tools is not a string |
|
|
504
|
+
| `agent-skills.skill.body-too-large` | info | vendor-recommendation | [agentskills.io/specification](https://agentskills.io/specification) | Portable skill SKILL.md exceeds the 500-line recommendation |
|
|
505
|
+
| `skill.not-in-lock` | info | heuristic | _lockfile hygiene, not a requirement_ | Skill on disk is not tracked by skills-lock.json |
|
|
506
|
+
| `skill.locked-not-installed` | warning | internal-consistency | _agentscan inference_ | skills-lock.json pins a skill that is not installed |
|
|
507
|
+
| `skill.broken-reference` | warning | internal-consistency | [agentskills.io/specification](https://agentskills.io/specification) | SKILL.md points at a bundled file that does not exist |
|
|
508
|
+
| `skill.duplicate-description` | info | heuristic | _selection hint, not a requirement_ | Two or more skills share an identical description |
|
|
509
|
+
| `skill.description-budget` | info | vendor-recommendation | [code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills) | Claude skill names + descriptions exceed the listing character budget |
|
|
510
|
+
| `skill.no-lockfile` | info | heuristic | _lockfile hygiene, not a requirement_ | Skills present with no skills-lock.json (requireLock only) |
|
|
511
|
+
| `claude.agent.missing-frontmatter` | error | spec-required | [code.claude.com/docs/en/sub-agents](https://code.claude.com/docs/en/sub-agents) | Agent definition has no YAML frontmatter block |
|
|
512
|
+
| `claude.agent.missing-description` | error | spec-required | [code.claude.com/docs/en/sub-agents](https://code.claude.com/docs/en/sub-agents) | Agent frontmatter has no description |
|
|
513
|
+
| `claude.agent.missing-name` | error | spec-required | [code.claude.com/docs/en/sub-agents](https://code.claude.com/docs/en/sub-agents) | Agent frontmatter has no name |
|
|
514
|
+
| `claude.agent.duplicate-name` | error | spec-required | [code.claude.com/docs/en/sub-agents](https://code.claude.com/docs/en/sub-agents) | Agent names are duplicated |
|
|
515
|
+
| `claude.agent.invalid-name` | warning/error | spec-required | [code.claude.com/docs/en/sub-agents](https://code.claude.com/docs/en/sub-agents) | Agent frontmatter name is not a valid identifier |
|
|
516
|
+
| `claude.mcp.no-launch` | error | spec-required | [code.claude.com/docs/en/mcp](https://code.claude.com/docs/en/mcp) | MCP server declares neither command nor url |
|
|
517
|
+
| `vscode.mcp.no-launch` | error | spec-required | [code.visualstudio.com/docs/agents/reference/mcp-configuration](https://code.visualstudio.com/docs/agents/reference/mcp-configuration) | VS Code MCP server declares neither command nor url |
|
|
518
|
+
| `cursor.mcp.no-launch` | error | spec-required | [cursor.com/docs/context/mcp](https://cursor.com/docs/context/mcp) | Cursor MCP server declares neither command nor url |
|
|
519
|
+
| `antigravity.mcp.no-launch` | error | spec-required | [antigravity.google/docs/mcp](https://antigravity.google/docs/mcp) | Antigravity MCP server declares neither command, serverUrl, nor url |
|
|
520
|
+
| `antigravity.hook.unknown-event` | error | spec-required | [antigravity.google/docs/hooks](https://antigravity.google/docs/hooks) | Antigravity hook registered under an event name that is never dispatched |
|
|
521
|
+
| `antigravity.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Antigravity hook points at a script that does not exist, so it never runs |
|
|
522
|
+
| `antigravity.hook.invalid-group` | error | spec-required | [antigravity.google/docs/hooks](https://antigravity.google/docs/hooks) | Antigravity hook group is missing a hooks array, or matcher is not a string |
|
|
523
|
+
| `antigravity.hook.command-without-command` | error | spec-required | [antigravity.google/docs/hooks](https://antigravity.google/docs/hooks) | Antigravity command hook declares no command |
|
|
524
|
+
| `antigravity.hook.unknown-handler-type` | error | spec-required | [antigravity.google/docs/hooks](https://antigravity.google/docs/hooks) | Antigravity hook handler type is not command |
|
|
525
|
+
| `codex.mcp.no-launch` | error | spec-required | [learn.chatgpt.com/docs/extend/mcp](https://learn.chatgpt.com/docs/extend/mcp) | Codex MCP server declares neither command nor url |
|
|
526
|
+
| `gemini.mcp.no-launch` | error | spec-required | [github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md) | Gemini MCP server declares neither command, url, nor httpUrl |
|
|
527
|
+
| `gemini.mcp.underscore-alias` | warning | vendor-recommendation | [github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md](https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md) | Gemini MCP server alias contains an underscore, which can make policies fail silently |
|
|
528
|
+
| `opencode.mcp.no-launch` | error | spec-required | [opencode.ai/v2/docs/mcp-servers](https://opencode.ai/v2/docs/mcp-servers) | OpenCode MCP server declares neither command nor url |
|
|
529
|
+
| `opencode.mcp.missing-type` | error | spec-required | [opencode.ai/v2/docs/mcp-servers](https://opencode.ai/v2/docs/mcp-servers) | OpenCode MCP server is missing type local or remote |
|
|
530
|
+
| `opencode.mcp.local-without-command` | error | spec-required | [opencode.ai/v2/docs/mcp-servers](https://opencode.ai/v2/docs/mcp-servers) | OpenCode local MCP server declares no command |
|
|
531
|
+
| `opencode.mcp.remote-without-url` | error | spec-required | [opencode.ai/v2/docs/mcp-servers](https://opencode.ai/v2/docs/mcp-servers) | OpenCode remote MCP server declares no url |
|
|
532
|
+
| `opencode.mcp.invalid-launch-for-type` | error | spec-required | [opencode.ai/v2/docs/mcp-servers](https://opencode.ai/v2/docs/mcp-servers) | OpenCode MCP server launch field does not match its type |
|
|
533
|
+
| `opencode.mcp.command-not-array` | error | spec-required | [opencode.ai/v2/docs/mcp-servers](https://opencode.ai/v2/docs/mcp-servers) | OpenCode V2 local MCP command is not an argv array |
|
|
534
|
+
| `continue.mcp.no-launch` | error | spec-required | [docs.continue.dev/customize/deep-dives/mcp](https://docs.continue.dev/customize/deep-dives/mcp) | Continue MCP server declares neither command, url, nor uses |
|
|
535
|
+
| `continue.mcp.missing-block-metadata` | error | spec-required | [docs.continue.dev/customize/deep-dives/mcp](https://docs.continue.dev/customize/deep-dives/mcp) | Standalone Continue YAML MCP block is missing name, version, or schema |
|
|
536
|
+
| `commandcode.mcp.no-launch` | error | spec-required | [commandcode.ai/docs/mcp](https://commandcode.ai/docs/mcp) | Command Code MCP server declares neither command nor url |
|
|
537
|
+
| `commandcode.mcp.invalid-transport` | error | spec-required | [commandcode.ai/docs/mcp](https://commandcode.ai/docs/mcp) | Command Code MCP transport is not http or stdio |
|
|
538
|
+
| `commandcode.mcp.http-without-url` | error | spec-required | [commandcode.ai/docs/mcp](https://commandcode.ai/docs/mcp) | Command Code HTTP MCP server declares no url |
|
|
539
|
+
| `commandcode.mcp.stdio-without-command` | error | spec-required | [commandcode.ai/docs/mcp](https://commandcode.ai/docs/mcp) | Command Code stdio MCP server declares no command |
|
|
540
|
+
| `commandcode.hook.unknown-event` | error | spec-required | [commandcode.ai/docs/hooks](https://commandcode.ai/docs/hooks) | Command Code hook registered under an event that is never dispatched |
|
|
541
|
+
| `commandcode.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Command Code hook points at a script that does not exist, so it never runs |
|
|
542
|
+
| `commandcode.hook.invalid-group` | error | spec-required | [commandcode.ai/docs/hooks](https://commandcode.ai/docs/hooks) | Command Code hook group is missing the required nested hooks array, or matcher is not a string |
|
|
543
|
+
| `commandcode.hook.command-without-command` | error | spec-required | [commandcode.ai/docs/hooks](https://commandcode.ai/docs/hooks) | Command Code command hook is missing the command field |
|
|
544
|
+
| `commandcode.hook.unknown-handler-type` | error | spec-required | [commandcode.ai/docs/hooks](https://commandcode.ai/docs/hooks) | Command Code hook uses a handler type other than the required string "command" |
|
|
545
|
+
| `commandcode.hook.timeout-out-of-bounds` | error | spec-required | [commandcode.ai/docs/hooks](https://commandcode.ai/docs/hooks) | Command Code hook timeout is outside 0–600 seconds |
|
|
546
|
+
| `commandcode.agent.reserved-name` | error | spec-required | [commandcode.ai/docs/agents](https://commandcode.ai/docs/agents) | Command Code custom agent uses a reserved name and is ignored |
|
|
547
|
+
| `commandcode.agent.invalid-permission-mode` | error | spec-required | [commandcode.ai/docs/agents](https://commandcode.ai/docs/agents) | Command Code agent permissionMode is not a documented value |
|
|
548
|
+
| `commandcode.agent.invalid-field-type` | error | spec-required | [commandcode.ai/docs/agents](https://commandcode.ai/docs/agents) | Command Code agent field has a type the spec does not accept |
|
|
549
|
+
| `grok.mcp.no-launch` | error | spec-required | [docs.x.ai/build/features/mcp-servers](https://docs.x.ai/build/features/mcp-servers) | Grok MCP server declares neither command nor url |
|
|
550
|
+
| `grok.hook.unknown-event` | error | spec-required | [docs.x.ai/build/features/hooks](https://docs.x.ai/build/features/hooks) | Grok hook registered under an event that is never dispatched |
|
|
551
|
+
| `grok.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Grok hook points at a script that does not exist, so it never runs |
|
|
552
|
+
| `grok.hook.invalid-group` | error | spec-required | [docs.x.ai/build/features/hooks](https://docs.x.ai/build/features/hooks) | Grok hook group is missing the required nested hooks array, or matcher is not a string |
|
|
553
|
+
| `grok.hook.command-without-command` | error | spec-required | [docs.x.ai/build/features/hooks](https://docs.x.ai/build/features/hooks) | Grok command hook is missing the command field |
|
|
554
|
+
| `grok.hook.http-without-url` | error | spec-required | [docs.x.ai/build/features/hooks](https://docs.x.ai/build/features/hooks) | Grok http hook is missing the url field |
|
|
555
|
+
| `grok.hook.unknown-handler-type` | error | spec-required | [docs.x.ai/build/features/hooks](https://docs.x.ai/build/features/hooks) | Grok hook uses a handler type other than command or http, or omits the required type |
|
|
556
|
+
| `grok.skill.missing-frontmatter` | error | spec-required | [docs.x.ai/build/features/skills-plugins-marketplaces](https://docs.x.ai/build/features/skills-plugins-marketplaces) | Grok SKILL.md has no YAML frontmatter block |
|
|
557
|
+
| `mcp.command-missing` | error | internal-consistency | _cross-provider path assertion; docs/spec/mcp.md calls it internal-consistency_ | MCP server command is a path that does not exist on disk |
|
|
558
|
+
| `claude.mcp.url-without-type` | error | spec-required | [code.claude.com/docs/en/mcp](https://code.claude.com/docs/en/mcp) | Remote MCP server has a url but no transport type |
|
|
559
|
+
| `claude.mcp.reserved-name` | error | spec-required | [code.claude.com/docs/en/mcp](https://code.claude.com/docs/en/mcp) | Claude MCP server uses a reserved name that Claude skips at load |
|
|
560
|
+
| `security.hardcoded-secret` | error | security | _cross-provider token-shape judgement, not a quoted rule_ | MCP config contains a token-shaped literal |
|
|
561
|
+
| `mcp.literal-env` | warning | security | [code.claude.com/docs/en/mcp](https://code.claude.com/docs/en/mcp) | MCP env value is a literal secret-shaped key instead of interpolation |
|
|
562
|
+
| `mcp.literal-credential` | warning | security | _cross-provider header judgement; no single vendor page states it_ | MCP headers, http_headers, or auth value is a literal secret instead of interpolation |
|
|
563
|
+
| `budget.agents-md` | info | heuristic | _size hint, not a requirement_ | AGENTS.md longer than the heuristic line budget (>150 lines) |
|
|
564
|
+
| `budget.claude-md` | info | vendor-recommendation | [code.claude.com/docs/en/memory](https://code.claude.com/docs/en/memory) | CLAUDE.md longer than the documented size target (~200 lines) |
|
|
565
|
+
| `budget.agents` | info | heuristic | _size hint, not a requirement_ | More agent definitions than a focused set (>8 files in .claude/agents) |
|
|
566
|
+
| `budget.mcp` | info | heuristic | _size hint, not a requirement_ | Project MCP server count above the point where tool selection may degrade |
|
|
567
|
+
| `codex.budget.instructions` | info | vendor-recommendation | [learn.chatgpt.com/docs/agent-configuration/agents-md](https://learn.chatgpt.com/docs/agent-configuration/agents-md) | Codex AGENTS.md chain exceeds project_doc_max_bytes (32 KiB default) |
|
|
568
|
+
| `cursor.rule.too-large` | info | vendor-recommendation | [cursor.com/docs/rules](https://cursor.com/docs/rules) | Cursor project rule exceeds the 500-line recommendation |
|
|
569
|
+
| `windsurf.rule.too-large` | info | vendor-recommendation | [docs.windsurf.com/windsurf/cascade/memories](https://docs.windsurf.com/windsurf/cascade/memories) | Windsurf workspace rule exceeds the 12,000-character limit |
|
|
570
|
+
| `windsurf.rule.global-too-large` | info | vendor-recommendation | [docs.windsurf.com/windsurf/cascade/memories](https://docs.windsurf.com/windsurf/cascade/memories) | Windsurf global_rules.md exceeds the 6,000-character limit |
|
|
571
|
+
| `windsurf.rule.missing-trigger` | warning | spec-required | [docs.windsurf.com/windsurf/cascade/memories](https://docs.windsurf.com/windsurf/cascade/memories) | Windsurf workspace rule is missing frontmatter trigger |
|
|
572
|
+
| `antigravity.rule.missing-trigger` | warning | spec-required | [antigravity.google/docs/rules](https://antigravity.google/docs/rules) | Antigravity modular rule is missing a frontmatter trigger |
|
|
573
|
+
| `antigravity.rule.invalid-trigger` | warning | spec-required | [antigravity.google/docs/rules](https://antigravity.google/docs/rules) | Antigravity modular rule trigger is not always_on, model_decision, glob, or manual |
|
|
574
|
+
| `antigravity.rule.missing-description` | warning | spec-required | [antigravity.google/docs/rules](https://antigravity.google/docs/rules) | Antigravity model_decision rule is missing a description |
|
|
575
|
+
| `antigravity.rule.missing-globs` | warning | spec-required | [antigravity.google/docs/rules](https://antigravity.google/docs/rules) | Antigravity glob rule is missing globs |
|
|
576
|
+
| `antigravity.rule.too-large` | warning | spec-required | [antigravity.google/docs/rules](https://antigravity.google/docs/rules) | Antigravity rule exceeds 24,000 bytes |
|
|
577
|
+
| `windsurf.mcp.no-launch` | error | spec-required | [docs.windsurf.com/windsurf/cascade/mcp](https://docs.windsurf.com/windsurf/cascade/mcp) | Windsurf MCP server declares neither command, serverUrl, nor url |
|
|
578
|
+
| `devin.mcp.no-launch` | error | spec-required | [docs.devin.ai/cli/extensibility/mcp/configuration](https://docs.devin.ai/cli/extensibility/mcp/configuration) | Devin MCP server declares neither command nor url |
|
|
579
|
+
| `windsurf.hook.unknown-event` | error | spec-required | [docs.devin.ai/desktop/cascade/hooks](https://docs.devin.ai/desktop/cascade/hooks) | Windsurf hook registered under an event name that is never dispatched |
|
|
580
|
+
| `windsurf.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Windsurf hook points at a script that does not exist, so it never runs |
|
|
581
|
+
| `windsurf.hook.command-without-command` | error | spec-required | [docs.devin.ai/desktop/cascade/hooks](https://docs.devin.ai/desktop/cascade/hooks) | Windsurf hook declares neither command nor powershell |
|
|
582
|
+
| `devin.hook.unknown-event` | error | spec-required | [docs.devin.ai/cli/extensibility/hooks/overview](https://docs.devin.ai/cli/extensibility/hooks/overview) | Devin hook registered under an event name that is never dispatched |
|
|
583
|
+
| `devin.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Devin hook points at a script that does not exist, so it never runs |
|
|
584
|
+
| `devin.hook.invalid-group` | error | spec-required | [docs.devin.ai/cli/extensibility/hooks/overview](https://docs.devin.ai/cli/extensibility/hooks/overview) | Devin hook group is missing a hooks array |
|
|
585
|
+
| `devin.hook.command-without-command` | error | spec-required | [docs.devin.ai/cli/extensibility/hooks/overview](https://docs.devin.ai/cli/extensibility/hooks/overview) | Devin command hook declares no command |
|
|
586
|
+
| `devin.hook.prompt-without-prompt` | error | spec-required | [docs.devin.ai/cli/extensibility/hooks/overview](https://docs.devin.ai/cli/extensibility/hooks/overview) | Devin prompt hook declares no prompt |
|
|
587
|
+
| `devin.hook.unknown-handler-type` | error | spec-required | [docs.devin.ai/cli/extensibility/hooks/overview](https://docs.devin.ai/cli/extensibility/hooks/overview) | Devin hook handler type is not command or prompt |
|
|
588
|
+
| `codex.hook.unknown-event` | error | spec-required | [learn.chatgpt.com/docs/hooks](https://learn.chatgpt.com/docs/hooks) | Codex hook registered under an event name that is never dispatched |
|
|
589
|
+
| `codex.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Codex hook points at a script that does not exist, so it never runs |
|
|
590
|
+
| `codex.hook.invalid-group` | error | spec-required | [learn.chatgpt.com/docs/hooks](https://learn.chatgpt.com/docs/hooks) | Codex hook group is missing a hooks array, or matcher is not a string |
|
|
591
|
+
| `codex.hook.command-without-command` | error | spec-required | [learn.chatgpt.com/docs/hooks](https://learn.chatgpt.com/docs/hooks) | Codex command hook declares no command |
|
|
592
|
+
| `codex.hook.mcp-tool-without-server-or-tool` | error | spec-required | [learn.chatgpt.com/docs/hooks](https://learn.chatgpt.com/docs/hooks) | Codex MCP tool hook declares no server or tool |
|
|
593
|
+
| `codex.hook.unknown-handler-type` | error | spec-required | [learn.chatgpt.com/docs/hooks](https://learn.chatgpt.com/docs/hooks) | Codex hook handler type is not command, mcp_tool, prompt, or agent |
|
|
594
|
+
| `codex.hook.incompatible-handler` | error | spec-required | [learn.chatgpt.com/docs/hooks](https://learn.chatgpt.com/docs/hooks) | Codex prompt or agent handler is parsed but skipped, or SessionEnd uses mcp_tool |
|
|
595
|
+
| `codex.hook.timeout-out-of-bounds` | error | spec-required | [learn.chatgpt.com/docs/hooks](https://learn.chatgpt.com/docs/hooks) | Codex SessionEnd or Interrupt hook timeout is outside 1–3 seconds |
|
|
596
|
+
| `gemini.hook.unknown-event` | error | spec-required | [geminicli.com/docs/hooks](https://geminicli.com/docs/hooks/) | Gemini hook registered under an event that is never dispatched |
|
|
597
|
+
| `gemini.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Gemini hook points at a script that does not exist, so it never runs |
|
|
598
|
+
| `gemini.hook.invalid-group` | error | spec-required | [geminicli.com/docs/hooks](https://geminicli.com/docs/hooks/) | Gemini hook group is missing the required nested hooks array, or matcher is not a string |
|
|
599
|
+
| `gemini.hook.command-without-command` | error | spec-required | [geminicli.com/docs/hooks](https://geminicli.com/docs/hooks/) | Gemini command hook is missing the command field |
|
|
600
|
+
| `gemini.hook.unknown-handler-type` | error | spec-required | [geminicli.com/docs/hooks](https://geminicli.com/docs/hooks/) | Gemini hook omits the required type or uses a value other than command |
|
|
601
|
+
| `cursor.hook.unknown-event` | error | spec-required | [cursor.com/docs/hooks](https://cursor.com/docs/hooks) | Cursor hook registered under an event that is never dispatched |
|
|
602
|
+
| `cursor.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Cursor hook points at a script that does not exist, so it never runs |
|
|
603
|
+
| `cursor.hook.command-without-command` | error | spec-required | [cursor.com/docs/hooks](https://cursor.com/docs/hooks) | Cursor hook is missing the required command field |
|
|
604
|
+
| `cursor.hook.unknown-handler-type` | error | spec-required | [cursor.com/docs/hooks](https://cursor.com/docs/hooks) | Cursor hook declares a type other than command or prompt |
|
|
605
|
+
| `kiro.hook.unknown-event` | error | spec-required | [kiro.dev/docs/ide/whats-new-v1/hooks](https://kiro.dev/docs/ide/whats-new-v1/hooks/) | Kiro hook registered under a trigger that is never dispatched |
|
|
606
|
+
| `kiro.hook.missing-script` | error | internal-consistency | _agentscan inference_ | Kiro command hook points at a script that does not exist, so it never runs |
|
|
607
|
+
| `kiro.hook.command-without-command` | error | spec-required | [kiro.dev/docs/hooks](https://kiro.dev/docs/hooks/) | Kiro command hook is missing the command field |
|
|
608
|
+
| `kiro.hook.prompt-without-prompt` | error | spec-required | [kiro.dev/docs/hooks](https://kiro.dev/docs/hooks/) | Kiro agent hook is missing the required prompt field |
|
|
609
|
+
| `kiro.hook.unknown-handler-type` | error | spec-required | [kiro.dev/docs/hooks](https://kiro.dev/docs/hooks/) | Kiro hook action type is missing or is not command or agent |
|
|
610
|
+
| `kiro.hook.invalid-group` | error | spec-required | [kiro.dev/docs/hooks](https://kiro.dev/docs/hooks/) | Kiro hook file is missing version v1 or a hooks array |
|
|
611
|
+
<!-- rules:end -->
|
|
612
|
+
|
|
613
|
+
### Coverage in 2.0.0
|
|
521
614
|
|
|
522
615
|
Each cell is one coverage dimension. There is no `full` / `partial` label: a
|
|
523
616
|
documented global or static location that is not opened stays **unread**.
|
|
@@ -532,29 +625,28 @@ Dimensions:
|
|
|
532
625
|
|
|
533
626
|
| Ecosystem | project discovery | global discovery | schema | precedence | conformance |
|
|
534
627
|
|-----------|-------------------|------------------|--------|------------|-------------|
|
|
535
|
-
| Agent Skills | `.agents/skills` (and Cursor / Codex / Command Code skill trees) | `--global` `~/.agents/skills`, `~/.codex/skills` | required `name` / `description` plus optional `compatibility` / `metadata` / `allowed-tools`; 500-line info | n/a | `agent-skills` fixture |
|
|
628
|
+
| Agent Skills | `.agents/skills` (and Cursor / Codex / Command Code skill trees). Default `skills/` uses the Claude schema, not this contract | `--global` `~/.agents/skills`, `~/.codex/skills` | required `name` / `description` plus optional `compatibility` / `metadata` / `allowed-tools`; 500-line info | n/a | `agent-skills` fixture |
|
|
536
629
|
| AGENTS.md | nested walk-up | n/a | no required fields | nearest-wins | tests |
|
|
537
|
-
| Claude Code | project settings, skills, agents, `CLAUDE.md`, `.mcp.json` / `.claude/mcp.json` |
|
|
630
|
+
| Claude Code | project settings, skills, agents, commands, `CLAUDE.md`, `.mcp.json` / `.claude/mcp.json`; in-tree plugin hooks / skills / agents / commands / `.mcp.json` | `--global` `$CLAUDE_CONFIG_DIR` or `~/.claude` (skills, settings, agents, `CLAUDE.md`, rules, commands) and `$CLAUDE_CONFIG_DIR/.claude.json` or `~/.claude.json` (user + matching local `mcpServers`); unread managed policy, marketplace plugins, other projects' local MCP | 33 events; required handler `type`; MCP reserved names; first-paragraph skill description; listing budget | walk-up `CLAUDE.md` / `.claude/agents` / `.claude/commands`; user+project+local layers inventoried | `claude-json` fixture |
|
|
538
631
|
| Command Code | git-root project files; per-directory `AGENTS.md` else `.commandcode/AGENTS.md` | `--global` `~/.commandcode/*`; unread `projects/{slug}/mcp.json` | 4 events; command handlers; Agent Skills; MCP `transport` / `type` | settings merge; project+user hooks coexist; skill/MCP shadow | `commandcode` fixture |
|
|
539
|
-
| Codex | `.codex/config.toml
|
|
540
|
-
| VS Code | `.github/hooks` without `version: 1
|
|
541
|
-
| Copilot CLI | `.github/hooks` with `version: 1` | `--global` `~/.copilot/hooks` with `version: 1
|
|
542
|
-
| Cursor | nested `.cursor/skills
|
|
543
|
-
| Grok |
|
|
544
|
-
| Antigravity | `.agents/mcp_config.json` |
|
|
545
|
-
| Gemini | `.gemini/settings.json` |
|
|
546
|
-
| Windsurf |
|
|
547
|
-
|
|
|
548
|
-
|
|
|
549
|
-
|
|
|
550
|
-
|
|
|
632
|
+
| Codex | `.codex/hooks.json` and inline `[hooks]` in `.codex/config.toml` on the ancestor walk; `.codex/skills`; AGENTS chain | `--global` `$CODEX_HOME` / `~/.codex` `hooks.json` and `config.toml` (MCP and `[hooks]`); `AGENTS.override.md` then `AGENTS.md`; unread system, managed, requirements, profiles, plugins, trust | 14 hook events; `command` / `mcp_tool`; `prompt` and `agent` parsed but skipped; SessionEnd rejects `mcp_tool`; SessionEnd and Interrupt timeout 1–3; TOML MCP; `project_doc_max_bytes`; Agent Skills | both hook files in a layer are inventoried; trust is not modeled; override > `AGENTS.md` > fallbacks; one file per dir; root→cwd; `project_root_markers`; MCP user+project both inventoried | `codex-hooks`, `codex-toml` fixtures |
|
|
633
|
+
| VS Code | `.github/hooks` without `version: 1` (legacy Local), instruction files, `.github/agents` (frontmatter hooks as vscode-native), `.vscode/mcp.json` `servers` | `--global` `~/.copilot/hooks` without `version: 1`; unread policy dirs; unread marketplace plugin `hooks.json` (install path unpublished) | 8 PascalCase events; command-only. New Copilot hooks are the Copilot row | workspace over user | `vscode-hooks`, `vscode-json` |
|
|
634
|
+
| Copilot CLI | `.github/hooks` with `version: 1`; inline `hooks` in `.github/copilot/settings.json` and `settings.local.json` | `--global` `$COPILOT_HOME` / `~/.copilot/hooks` with `version: 1`, `settings.json`, and `mcp-config.json` (`mcpServers`); unread `/etc/github-copilot/policy.d` | camelCase + PascalCase map; `bash` / `powershell` / `command` / `exec` / `http`; `cwd`; `timeoutSec`; prompt on `sessionStart`; user MCP `command` / `url` | documented sources coexist; policy unread; Copilot also reads `.claude/settings.json` but this scanner lints that file as Claude. Workspace `.mcp.json` stays the shared profile | `copilot-hooks` fixture |
|
|
635
|
+
| Cursor | nested `.cursor/skills`; `.cursor/mcp.json`, `.cursor/hooks.json` and `.cursor/rules` on the ancestor walk only (not descendant package trees from repo root) | `--global` `~/.cursor/hooks.json` and `~/.cursor/mcp.json`; unread MDM/team hooks; unread `~/.cursor/skills/` until a page quotes that directory; unread third-party Claude import as Cursor schema | Agent Skills; MCP launch; 500-line rules; 21 hook events, optional `type` (`command` / `prompt`), required `command`. Missing `version` is not a finding | n/a | `cursor-json` fixture |
|
|
636
|
+
| Grok | `.grok/config.toml` walk-up; `.grok/hooks/*.json`; `.grok/skills`; `.grok/rules/*.md`; `Agents.md` / `AGENT.md` | `--global` `$GROK_HOME` or `~/.grok` config/hooks/skills; unread managed, requirements, plugins, `[skills] paths`, agents, credentials | `command` / `url` MCP (no `type`); 14 events; command/http; frontmatter required, name/description optional; no rules cap | closer project wins; project same-name replaces user | `grok-toml` fixture |
|
|
637
|
+
| Antigravity | `.agents/mcp_config.json`; `.agents/hooks.json`, `GEMINI.md`, `.agents/GEMINI.md`, `.agents/rules/*.md`, and legacy `.agent/rules/*.md` on the ancestor walk. Workspace `AGENTS.md` stays the AGENTS.md row. `.agents/skills` stays the Agent Skills row | `--global` `~/.gemini/config` `mcp_config.json`, `hooks.json`, `rules/*.md`, `skills/`, `AGENTS.md`, and `GEMINI.md`, plus `~/.gemini/AGENTS.md` and `GEMINI.md`. Unread plugin hooks, plugin rules, plugin skills, `~/.gemini/antigravity-cli/settings.json`, `~/.gemini/antigravity-cli/skills/`, `~/.gemini/skills/`, and `~/.gemini/antigravity/skills/` | `command` / `serverUrl` (`url` is an alias; `httpUrl` is not a launch field); 6 hook events; direct handlers or matcher groups; `type` defaults to `command`; modular rule `trigger`; 24,000-byte rule limit | n/a | `antigravity-json`, `antigravity-hooks` fixtures |
|
|
638
|
+
| Gemini | `.gemini/settings.json` — MCP and `hooks` | `--global` `~/.gemini/settings.json` (hooks and MCP together); unread `/etc/gemini-cli/settings.json`, extension hooks, and `mcp-oauth-tokens.json` | `command` / `url` / `httpUrl`; underscore-alias warning; 11 hook events, required `type` (`command` only), nested groups, `$GEMINI_PROJECT_DIR` | n/a | `gemini-json` fixture |
|
|
639
|
+
| Windsurf | `.devin/rules/*.md` (preferred), `.windsurf/rules/*.md` (fallback), `.windsurfrules`; `.windsurf/hooks.json`; `.windsurf/skills`; portable `AGENTS.md` / `agents.md` | `--global` `~/.codeium/windsurf/mcp_config.json`, `memories/global_rules.md`, `hooks.json`, and `skills`; unread auto memories, system rules/hooks/skills, JetBrains `~/.codeium/hooks.json` | 12k / 6k character rules; workspace `trigger`; MCP `command` / `serverUrl` / `url` (no `type`); 12 snake_case hook events; `command` / `powershell`; Agent Skills on `.windsurf/skills` | n/a (no project MCP on this row; both rule trees inventoried). Devin CLI hooks and MCP are the next row | `windsurf-rules` fixture |
|
|
640
|
+
| Devin CLI | `.devin/hooks.v1.json`; `"hooks"` in `.devin/config.json` and `config.local.json`; `.devin/mcp_config.json` and `mcp_config.local.json`; `mcpServers` left in those config files; `.devin/skills` | `--global` `~/.config/devin/config.json`, `mcp_config.json`, and `skills`; unread Windows `%APPDATA%\devin` | 8 events (`PostCompaction`, not `PostCompact`); `command` / `prompt`; MCP `command` / `url` (`transport` `http` or `sse` is not a check); Agent Skills | Claude settings Devin also loads stay Claude findings | unit tests |
|
|
641
|
+
| Kiro | `.kiro/hooks/*.json`, `.kiro/skills`, `.kiro/agents/**/*.json` and `*.md` on the ancestor walk | `--global` `~/.kiro/hooks/`, `~/.kiro/skills`, `~/.kiro/agents/` | 13 PascalCase triggers, including `SessionEnd`, `PreCompact`, `PostCompact`; `command` / `agent`; Agent Skills. Agents are inventory only: the name is the relative path without the extension, and no field is required | nearer workspace agent shadows a farther one and a global one with the same name | unit tests |
|
|
642
|
+
| Cline | `.cline/skills` | `--global` `~/.cline/skills`; unread hooks (no quoted event list), unread agents | Agent Skills | n/a | unit tests |
|
|
643
|
+
| Roo | `.roo/skills` | `--global` `~/.roo/skills` | Agent Skills | n/a | unit tests |
|
|
644
|
+
| Kilo | `.kilo/skills` | `--global` `~/.kilo/skills`; unread extra paths in `kilo.jsonc` | Agent Skills | n/a | unit tests |
|
|
551
645
|
| OpenCode | `opencode.json(c)` V1 and V2 | none | V2 local `command` must be an argv array | n/a | `opencode-json` fixture |
|
|
552
|
-
| Junie |
|
|
646
|
+
| Junie | `.junie/skills` | `--global` `~/.junie/skills`; unread `--skill-location` / extension skills | Agent Skills with optional `description`; `name` need not match the folder | n/a | unit tests |
|
|
553
647
|
| Continue | `.continue/config.yaml`, `.continue/mcpServers/*` | none | launch `command` / `url` / `uses`; standalone YAML `name` / `version` / `schema` | n/a | `continue-yaml`, `continue-mcpservers` |
|
|
554
648
|
|
|
555
|
-
Cursor project rules (`.cursor/rules/**/*.mdc`) are a separate surface: discovery plus `cursor.rule.too-large` at info. Claude `.claude/rules/**/*.md` is inventoried and has no published line budget.
|
|
556
|
-
|
|
557
|
-
Old 0.7 rule ids still work in `ignoreRules` and `explain` (for example `hook.missing-script` aliases `claude.hook.missing-script`).
|
|
649
|
+
Cursor project rules (`.cursor/rules/**/*.mdc`) are a separate surface: discovery plus `cursor.rule.too-large` at info. Claude `.claude/rules/**/*.md` is inventoried and has no published line budget. Windsurf workspace rules use a 12,000-character budget (`windsurf.rule.too-large`); do not apply the Cursor 500-line check. Antigravity modular rules require `trigger` and a raw file over 24,000 bytes is `antigravity.rule.too-large`. Portable `AGENTS.md` / `agents.md` stay `sourceProvider: unknown` — this scanner does not claim exclusive Windsurf or Antigravity ownership.
|
|
558
650
|
|
|
559
651
|
Agent definitions are checked for structure only. A Claude agent's frontmatter
|
|
560
652
|
`name` is not compared to the filename; it must be lowercase letters and
|
|
@@ -575,19 +667,32 @@ illustration, not a pointer.
|
|
|
575
667
|
### Where it looks for hooks
|
|
576
668
|
|
|
577
669
|
The Claude hooks reference lists seven places a hook can be registered. agentscan
|
|
578
|
-
reads the
|
|
579
|
-
|
|
670
|
+
reads the project settings files, in-tree plugin and command-file hooks,
|
|
671
|
+
`~/.claude/settings.json` (or `$CLAUDE_CONFIG_DIR/settings.json`)
|
|
672
|
+
under `--global`, plus VS Code workspace hooks and Command Code settings hooks:
|
|
580
673
|
|
|
581
674
|
| Registered in | Script paths resolve against |
|
|
582
675
|
|---|---|
|
|
583
676
|
| `.claude/settings.json` · `.claude/settings.local.json` | project root, `${CLAUDE_PROJECT_DIR}` |
|
|
677
|
+
| `~/.claude/settings.json` (or `$CLAUDE_CONFIG_DIR/settings.json`) under `--global` | scanned project root, `${CLAUDE_PROJECT_DIR}` |
|
|
584
678
|
| A plugin's `hooks/hooks.json` (a directory with `.claude-plugin/plugin.json`, or the scan root itself) | the plugin root, `${CLAUDE_PLUGIN_ROOT}` |
|
|
585
|
-
| `SKILL.md` frontmatter | the skill's own directory, then the project root |
|
|
679
|
+
| `SKILL.md` frontmatter (including in-tree plugin skills) | the skill's own directory, then the project root |
|
|
680
|
+
| `.claude/commands/*.md` frontmatter | the command file's directory, then the project root |
|
|
586
681
|
| `.claude/agents/*.md` frontmatter | the agent file's directory, then the project root |
|
|
587
682
|
| `.github/hooks/*.json` without `version: 1` (native VS Code) | project root and the hooks directory |
|
|
588
683
|
| `.github/hooks/*.json` with `version: 1` (Copilot CLI) | project root, `cwd`, host `bash` / `powershell` / `command` |
|
|
589
|
-
|
|
|
684
|
+
| `.github/copilot/settings.json` · `.github/copilot/settings.local.json` (Copilot CLI inline) | project root and the settings directory; always `copilot-cli` |
|
|
685
|
+
| `~/.copilot/hooks` and `~/.copilot/settings.json` (or `$COPILOT_HOME/…`) under `--global` | same Copilot CLI / native VS Code split on hook files; settings hooks are always `copilot-cli` |
|
|
590
686
|
| `.commandcode/settings.json` · `.commandcode/settings.local.json` (and user settings under `--global`) | Command Code project root (git root, or cwd outside a git repo), `$COMMANDCODE_PROJECT_DIR`, `$COMMANDCODE_CWD` |
|
|
687
|
+
| `.grok/hooks/*.json` | project root and the hooks directory |
|
|
688
|
+
| `$GROK_HOME/hooks` or `~/.grok/hooks` under `--global` | same Grok 14-event / command-or-http split |
|
|
689
|
+
| `.github/agents/*.agent.md` frontmatter | vscode-native (command-only); project root and the agent file's directory |
|
|
690
|
+
| `.kiro/hooks/*.json` | project root; array-of-hooks, not Claude event-keyed objects |
|
|
691
|
+
| `~/.kiro/hooks/` under `--global` | scanned project root |
|
|
692
|
+
| `.cursor/hooks.json` | project root |
|
|
693
|
+
| `~/.cursor/hooks.json` under `--global` | scanned project root |
|
|
694
|
+
| `.gemini/settings.json` `hooks` | project root, `$GEMINI_PROJECT_DIR` |
|
|
695
|
+
| `~/.gemini/settings.json` `hooks` under `--global` | scanned project root, `$GEMINI_PROJECT_DIR` |
|
|
591
696
|
|
|
592
697
|
`${CLAUDE_PLUGIN_ROOT}` is expanded **only** for a hook that came from a plugin.
|
|
593
698
|
In a settings file it names nothing, so the path is skipped rather than guessed
|
|
@@ -623,35 +728,117 @@ first.
|
|
|
623
728
|
should add a `next-*` skill". That needed a hand-maintained registry, and the
|
|
624
729
|
version that existed fired on none of the 17 projects measured, so it was
|
|
625
730
|
removed. Skill provenance comes from `skills-lock.json` instead.
|
|
626
|
-
- **No
|
|
627
|
-
the `computedHash` in `skills-lock.json` is the obvious
|
|
731
|
+
- **No skill-content hash check.** Comparing a skill's content against
|
|
732
|
+
the `computedHash` in `skills-lock.json` is the obvious source of one; the
|
|
628
733
|
hash algorithm used by the installing tool is not documented here, and it is
|
|
629
734
|
not reproducible from `SKILL.md` bytes alone, so it is not implemented.
|
|
630
735
|
- **Runtime split.** Source development and the composite Action use Bun; the
|
|
631
736
|
published `dist/cli.js` runs on Node 20.11+ or Bun. The source entrypoint uses
|
|
632
737
|
Bun's `import.meta.dir` / `import.meta.main` and is not the Node entrypoint.
|
|
738
|
+
- **Grok compatibility and unpublished surfaces are unread.** Managed
|
|
739
|
+
(`~/.grok/managed_config.toml`, `/etc/grok/managed_config.toml`) and
|
|
740
|
+
requirements TOML are not opened. Plugins, marketplaces, personas, and
|
|
741
|
+
`[skills] paths` (no quoted resolution base) stay unread. `.grok/agents/`
|
|
742
|
+
is unread because the page names the directory but not a filename pattern
|
|
743
|
+
or required fields. Claude / Cursor / `.mcp.json` files keep their own
|
|
744
|
+
schemas — this scanner does not add `consumedBy: grok` to them. Grok’s
|
|
745
|
+
“skip gitignored instruction files” is unread: agentscan does not honor
|
|
746
|
+
`.gitignore`. `auth.json` and `mcp_credentials.json` are never opened.
|
|
747
|
+
Spec/runtime Grok MCP checks skip shadowed same-name servers; secrets
|
|
748
|
+
still inspect every readable MCP file.
|
|
749
|
+
- **Codex admin and profile layers are unread.** System `/etc/codex/config.toml`,
|
|
750
|
+
managed preferences, `requirements.toml`, `$CODEX_HOME/<name>.config.toml`
|
|
751
|
+
profiles, plugin hooks and MCP, and `trust_level` are not opened. Project
|
|
752
|
+
`.codex/hooks.json` and inline `[hooks]` in `.codex/config.toml` are
|
|
753
|
+
inventoried on the ancestor walk even when that layer is untrusted. The
|
|
754
|
+
same two files under `$CODEX_HOME` (or `~/.codex`) are opened only with
|
|
755
|
+
`--global`. `auth.json` is never opened. Same-name user and project MCP
|
|
756
|
+
servers are both inventoried — the published page does not quote a
|
|
757
|
+
replace-entirely rule. User-file `project_doc_*` knobs are not applied.
|
|
758
|
+
Relative hook commands resolve against the scanned directory, not the git
|
|
759
|
+
root. SessionEnd and Interrupt timeouts outside 1–3 seconds are findings;
|
|
760
|
+
other events have no quoted maximum.
|
|
633
761
|
- **Command Code local MCP is unread.** `~/.commandcode/projects/{project}/mcp.json`
|
|
634
762
|
is keyed by a working-directory slug that the sessions page does not publish.
|
|
635
763
|
Until it does, that path is skipped rather than guessed. Bundled Command Code
|
|
636
764
|
skills and `--skill` launch flags are not project files and are not scanned.
|
|
637
|
-
`mods
|
|
765
|
+
Command Code `mods` settings are not read, and mod TypeScript is never
|
|
766
|
+
executed or imported.
|
|
638
767
|
`auth.json` and `mcp-tokens.json` are never opened. Command Code project
|
|
639
768
|
root is the git root (or cwd outside a git repo); a child `.cursor` does
|
|
640
769
|
not hide `<git-root>/.commandcode/`. Spec/runtime Command Code checks skip
|
|
641
770
|
shadowed lower-precedence definitions; secrets still inspect every readable
|
|
642
771
|
MCP file.
|
|
643
|
-
- **
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
missing script, is not reported.
|
|
772
|
+
- **Two Claude hook locations stay unread.** Managed policy settings and
|
|
773
|
+
installed marketplace plugins under `~/.claude/plugins` sit outside the
|
|
774
|
+
scanned project, and the docs say a plugin's install directory changes
|
|
775
|
+
on every update. A hook registered in one of those, pointing at a
|
|
776
|
+
missing script, is not reported. User settings, skills, agents,
|
|
777
|
+
`CLAUDE.md`, rules, and commands under `$CLAUDE_CONFIG_DIR` or
|
|
778
|
+
`~/.claude` are scanned only under `--global`. User `~/.claude.json`
|
|
779
|
+
MCP is scanned only under `--global`: top-level `mcpServers` and
|
|
780
|
+
`projects.<scanned-path>.mcpServers`. Other projects' local servers
|
|
781
|
+
are skipped. A file without those keys is skipped, not
|
|
782
|
+
`config.unreadable`. In-tree plugin skills, agents, commands, and
|
|
783
|
+
`.mcp.json` are read; plugin agent frontmatter hooks are ignored
|
|
784
|
+
because Claude skips them.
|
|
785
|
+
- **Default `skills/` is Claude schema.** A repo-root `skills/` directory is
|
|
786
|
+
discovered, but `name` / directory-match from the Agent Skills spec are not
|
|
787
|
+
applied there. `.agents/skills`, `.cursor/skills`, `.codex/skills`,
|
|
788
|
+
`.commandcode/skills`, `.kiro/skills`, `.cline/skills`, `.roo/skills`,
|
|
789
|
+
`.kilo/skills`, and `.junie/skills` use the Agent Skills contract. Junie
|
|
790
|
+
does not require `description` and does not require `name` to match the
|
|
791
|
+
folder.
|
|
648
792
|
- **Copilot CLI policy hooks are unread.** `/etc/github-copilot/policy.d` and the
|
|
649
793
|
Windows policy directory are machine-wide admin files. User
|
|
650
|
-
`~/.copilot/hooks`
|
|
651
|
-
`.
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
794
|
+
`~/.copilot/hooks` and `~/.copilot/settings.json` (or `$COPILOT_HOME/…`)
|
|
795
|
+
are scanned only under `--global`. Plugin `hooks.json` stays unread.
|
|
796
|
+
Copilot also reads repository `.claude/settings.json`; this scanner still
|
|
797
|
+
lints that file as Claude (required nested groups and required `type`).
|
|
798
|
+
Copilot-only event names there stay `claude.hook.unknown-event`.
|
|
799
|
+
- **Gemini system settings are unread.** `~/.gemini/settings.json` (hooks and
|
|
800
|
+
MCP together) is scanned only under `--global`. `/etc/gemini-cli/settings.json`
|
|
801
|
+
and extension-provided hooks stay unread. `mcp-oauth-tokens.json` is never
|
|
802
|
+
opened.
|
|
803
|
+
- **Cursor managed hooks are unread.** `~/.cursor/hooks.json` is scanned only
|
|
804
|
+
under `--global`. MDM paths (`/etc/cursor/hooks.json` and the macOS /
|
|
805
|
+
Windows equivalents) and dashboard-synced team hooks stay unread. Cursor's
|
|
806
|
+
third-party import of Claude hook files stays on the Claude profile.
|
|
807
|
+
- **Antigravity global files.** `~/.gemini/config/mcp_config.json`,
|
|
808
|
+
`hooks.json`, `rules/*.md`, `skills/`, `AGENTS.md`, and `GEMINI.md`, plus
|
|
809
|
+
`~/.gemini/AGENTS.md` and `~/.gemini/GEMINI.md`, are scanned only under
|
|
810
|
+
`--global`. Project `.agents/mcp_config.json`, `.agents/hooks.json`,
|
|
811
|
+
`GEMINI.md`, `.agents/GEMINI.md`, `.agents/rules/*.md`, and legacy
|
|
812
|
+
`.agent/rules/*.md` are read on the ancestor walk. Workspace `AGENTS.md`
|
|
813
|
+
stays the portable policy file, so the 24,000-byte rule check does not
|
|
814
|
+
apply to it. That check counts raw bytes, before `@[label](path)`
|
|
815
|
+
expansion, and the 20,000-token aggregate is not checked. `rules.json`
|
|
816
|
+
paths are not followed. `url` is an alias of `serverUrl`. `httpUrl` alone
|
|
817
|
+
is still not a launch field. Plugin hooks, plugin rules, plugin skills,
|
|
818
|
+
`~/.gemini/antigravity-cli/settings.json`,
|
|
819
|
+
`~/.gemini/antigravity-cli/skills/`, `~/.gemini/skills/`, and
|
|
820
|
+
`~/.gemini/antigravity/skills/` stay unread. Hook `timeout` has no quoted
|
|
821
|
+
range, so it is not checked. Global skills use the Agent Skills contract,
|
|
822
|
+
which requires `name` even though the Antigravity skills page says `name`
|
|
823
|
+
defaults to the folder.
|
|
824
|
+
- **Cline hooks stay unread.** Cline's hooks page did not quote an event
|
|
825
|
+
identifier table. Cline agents are unread for the same reason. Kiro agents
|
|
826
|
+
are inventoried from `.kiro/agents/**/*.json` and `*.md` on the ancestor
|
|
827
|
+
walk, and from `~/.kiro/agents/` under `--global`. The name is the path
|
|
828
|
+
relative to the agents directory without the extension. A nearer workspace
|
|
829
|
+
agent shadows a farther one and a global one with the same name. No field
|
|
830
|
+
is required, so there is no `kiro.agent.*` check.
|
|
831
|
+
- **VS Code marketplace plugin hooks are unread.** In-tree Claude plugins
|
|
832
|
+
stay Claude. VS Code's `hooks.json` / `hooks/hooks.json` inside an
|
|
833
|
+
installed plugin package is not a project path.
|
|
834
|
+
- **Windsurf Devin CLI MCP and auto memories are unread.** Cascade MCP is
|
|
835
|
+
global-only (`~/.codeium/windsurf/mcp_config.json`, `--global`). The Devin
|
|
836
|
+
Local agent uses unpublished CLI config files — that path is not guessed.
|
|
837
|
+
Auto-generated files under `~/.codeium/windsurf/memories/` other than
|
|
838
|
+
`global_rules.md` are not opened. System / enterprise rule, hook, and
|
|
839
|
+
skill directories (`/etc/devin/rules`, `/etc/windsurf/rules`,
|
|
840
|
+
`/etc/windsurf/hooks.json`, `/etc/windsurf/skills/`) stay unread. There
|
|
841
|
+
is no quoted project MCP path. JetBrains `~/.codeium/hooks.json` is unread.
|
|
655
842
|
- **Bounded reads.** A `SKILL.md` is read to 64 KB and a policy file to 100 KB,
|
|
656
843
|
so `skill.broken-reference` and `policyLines` see only that much of a larger
|
|
657
844
|
file. This is reported — `scan.truncated`, at `info` — rather than left
|
|
@@ -665,6 +852,40 @@ Notes for every published version are in [CHANGELOG.md](CHANGELOG.md).
|
|
|
665
852
|
GitHub already has pages for [v0.1.0](https://github.com/SimaAlexandru99/agentscan/releases/tag/v0.1.0)
|
|
666
853
|
and [v0.4.0](https://github.com/SimaAlexandru99/agentscan/releases/tag/v0.4.0).
|
|
667
854
|
|
|
855
|
+
**2.0.0** (12 November 2026) is breaking for configs that still name the 0.7
|
|
856
|
+
rule ids or the old threshold keys. `ignoreRules`, `ignoreFindings`, and
|
|
857
|
+
`explain` accept only the printed ids. `thresholds.skillDescriptionBytes`
|
|
858
|
+
and `thresholds.skills` are rejected; the listing budget is
|
|
859
|
+
`thresholds.skillListingChars`. It also ships the November 2026 vendor
|
|
860
|
+
contracts: Kiro agents, Antigravity rules, skills, and hooks, Codex hooks,
|
|
861
|
+
Cursor user MCP, Devin CLI hooks / MCP / skills, and the Copilot user MCP
|
|
862
|
+
file. **143 checks**, **647 tests**.
|
|
863
|
+
|
|
864
|
+
**1.4.0** (2 September 2026) closes two coverage gaps and ships the
|
|
865
|
+
2026-09-02 re-verification: Copilot CLI inline `hooks` in
|
|
866
|
+
`.github/copilot/settings.json` / `settings.local.json` and `--global`
|
|
867
|
+
`$COPILOT_HOME` / `~/.copilot/settings.json`; `mcp.literal-credential` on
|
|
868
|
+
MCP `headers` / `http_headers` / `auth` (field paths only). Also the
|
|
869
|
+
seven false-positive corrections, spec content hashes, verbatim
|
|
870
|
+
conformance fixtures, and Windsurf Cascade hooks / skills from #13.
|
|
871
|
+
**103 checks**, **532 tests**. Policy hooks, plugin `hooks.json`, and
|
|
872
|
+
`.claude/settings.json` as Copilot stay unread.
|
|
873
|
+
|
|
874
|
+
**1.3.0** (31 August 2026) adds native Windsurf / Cascade coverage: workspace
|
|
875
|
+
`.devin/rules` and `.windsurf/rules`, portable `agents.md`, and `--global`
|
|
876
|
+
`mcp_config.json` plus `global_rules.md`. Devin CLI MCP, auto memories,
|
|
877
|
+
system rules, and a project MCP path stay unread.
|
|
878
|
+
|
|
879
|
+
**1.2.1** (31 August 2026) opens Codex user MCP (`$CODEX_HOME/config.toml`
|
|
880
|
+
or `~/.codex/config.toml`) under `--global`. Same-name user and project
|
|
881
|
+
servers are both inventoried. System, managed, requirements, profiles,
|
|
882
|
+
plugins, and `trust_level` stay unread. `auth.json` is never opened.
|
|
883
|
+
|
|
884
|
+
**1.2.0** (31 August 2026) adds a native Grok Build provider: project
|
|
885
|
+
`.grok/*` plus `$GROK_HOME` / `~/.grok/*` under `--global`. Compatibility
|
|
886
|
+
with Claude or Cursor is not schema identity. Agents, managed/requirements
|
|
887
|
+
TOML, plugins, `[skills] paths`, and `.gitignore` skip stay unread.
|
|
888
|
+
|
|
668
889
|
**1.1.0** (31 August 2026) adds a native Command Code provider and finishes the
|
|
669
890
|
correctness pass across registered checks: hook schema profiles, Agent Skills
|
|
670
891
|
optional fields, Claude listing budget, Codex chain knobs, and Copilot CLI
|
|
@@ -703,7 +924,9 @@ Before publishing a release:
|
|
|
703
924
|
|
|
704
925
|
1. Confirm `package.json` and `src/version.ts` contain the same version.
|
|
705
926
|
2. Run `bun run build`, then verify `node dist/cli.js --version` prints it.
|
|
706
|
-
3. Run `bun run typecheck`, `bun test`, and `bun run spec:check`.
|
|
927
|
+
3. Run `bun run typecheck`, `bun test`, and `bun run spec:check`. If a page
|
|
928
|
+
hash changed, re-read that page, update its `docs/spec/` capture and the
|
|
929
|
+
conformance fixture, then `bun run spec:record`.
|
|
707
930
|
4. Refresh the test-count badge and version examples above from that release run.
|
|
708
931
|
5. Add a section to [CHANGELOG.md](CHANGELOG.md) for the version, then publish
|
|
709
932
|
the GitHub release from that text.
|