Repository navigation
Releases: SimaAlexandru99/agentscan
Release list
v1.4.0 — Copilot settings hooks and MCP credential check
Closes two coverage gaps left after the 2026-09-02 re-verification, then ships everything that sat in Unreleased: the seven false-positive corrections, plan 038 content hashes and verbatim fixtures, and #13 Windsurf Cascade hooks / skills. 103 checks, 532 tests. Still offline on check.
Install
npx @chimix/agentscan@latest
npx skills add SimaAlexandru99/agentscanGitHub Action:
- uses: SimaAlexandru99/agentscan@v1
with:
fail-on: errorSkill: https://skills.sh/simaalexandru99/agentscan/agentscan
Added
- Copilot CLI inline
hooksin.github/copilot/settings.jsonand.github/copilot/settings.local.json(alwayscopilot-cli, sourcecopilot-settings). User$COPILOT_HOME/settings.jsonor~/.copilot/settings.jsonunder--global. Same-event hooks from settings and.github/hookscoexist.$COPILOT_HOMEis honored for user hook files too..claude/settings.jsonstays on the Claude profile. Policy and plugin hook files stay unread. mcp.literal-credential(security, warning): secret-named string values under MCPheaders,http_headers, orauththat are not interpolation. Field paths only; values never echoed. Grok{{var}}, Gemini%VAR%, and the existing${VAR}/${env:}/${input:}forms are interpolation. Token-shaped literals still firesecurity.hardcoded-secretfirst.bun run spec:checkhashes the prose of every source page inscripts/spec-surfaces.ts(35 unique URLs) and compares againstscripts/spec-hashes.json.bun run spec:recordrewrites the baseline after a human has re-read the page. Page text is never stored.- Conformance fixtures carry the vendors' own examples verbatim, with a minimum fact count per fixture so a discovery regression cannot keep a fixture green.
Fixed
commandcode.mcp.invalid-transportno longer fires on"type": "streamable-http"in a shared.mcp.json, or onssein Command Code-only files.agent-skills.skill.invalid-nameaccepts lowercase letters from any script (résumé-builder).copilot.hook.command-without-commandaccepts the documentedexec(+args) form.copilot.hook.unknown-eventaccepts PascalCase spellings of Copilot-only events inversion: 1files:SessionEnd,PostToolUseFailure,ErrorOccurred,PermissionRequest.mcp.literal-envtreats Gemini CLI's Windows%VAR_NAME%form as interpolation.commandcode.agent.invalid-permission-modeacceptsinherit.
Changed
- Spec captures re-read on 2026-09-02;
spec:checknow also diffs Copilot PascalCase aliases and exits 1 when a source page's content hash has moved.
From #13 — true findings and Windsurf Cascade hooks / skills
.agentscan-rootstops walk-up. FencedSKILL.mdexamples, unclosed YAML, invalid Windsurf rule YAML,node ./".", and outbound skill-directory symlinks no longer produce false findings.- Windsurf Cascade hooks:
.windsurf/hooks.jsonand--global~/.codeium/windsurf/hooks.json. - Windsurf Cascade skills:
.windsurf/skillsand--global~/.codeium/windsurf/skills.
v1.3.0 — Windsurf, Grok Build, Codex user MCP
Native Windsurf / Cascade coverage. Also ships 1.2.0 (Grok Build provider) and 1.2.1 (Codex user MCP under --global) — those trains were never published as their own npm versions. 99 checks, 457 tests. Still offline on check.
Install
npx @chimix/agentscan@latest
npx skills add SimaAlexandru99/agentscanGitHub Action:
- uses: SimaAlexandru99/agentscan@v1
with:
fail-on: errorSkill: https://skills.sh/simaalexandru99/agentscan/agentscan
Native Windsurf / Cascade coverage against 2026-08-31 official docs.
99 checks, 457 tests.
Added
- Spec captures
docs/spec/windsurf-rules.md,windsurf-agents-md.md,
windsurf-mcp.md. - Workspace rules:
.devin/rules/*.md(preferred),.windsurf/rules/*.md
(fallback), subdirectory-scoped trees, legacy.windsurfrules.
.devinis a scan-root signal. - Character budgets:
windsurf.rule.too-large(12,000) and
windsurf.rule.global-too-large(6,000). Nevercursor.rule.too-large. windsurf.rule.missing-triggeron workspace.devin/.windsurfrules
that omit frontmattertrigger. Not on.windsurfrules,
global_rules.md, orAGENTS.md.- Portable lowercase
agents.md(samesourceProvider: unknownas
AGENTS.md). --globalCascade MCP at~/.codeium/windsurf/mcp_config.json
(windsurf-json). Launch iscommandorserverUrlorurl.
windsurf.mcp.no-launchwhen none are set. Never
claude.mcp.url-without-type.--global~/.codeium/windsurf/memories/global_rules.mdonly. Other
files in that memories directory stay unread.
Unread (intentional)
- Devin Local CLI MCP (no published path).
- Auto-generated memories other than
global_rules.md. - System / enterprise rule directories.
- Project MCP (none quoted).
- Marketplace, admin allowlists, OAuth stores.
Also in this npm version
1.2.1 — 2026-08-31
Codex user MCP under --global. 95 checks, 441 tests.
Added
$CODEX_HOME/config.toml(default~/.codex/config.toml) is opened only
with--global. Samecodex-tomlshape as project.codex/config.toml.- Same-name user and project servers both stay in the inventory. The
published page does not quote a replace-entirely rule, so this scanner
does not inventcodexEffective. - Spec recapture
docs/spec/codex-mcp.md(user path,CODEX_HOME, unread
system / managed / requirements / profiles / plugins / trust /auth.json).
Unread (intentional)
- System
/etc/codex/config.toml, managed preferences,requirements.toml,
profile files, plugin MCP,trust_level. - User-file
project_doc_*knobs. - Claude global settings; Command Code
projects/{slug}/mcp.json.
1.2.0 — 2026-08-31
Native Grok Build provider against 2026-08-31 official docs. 95 checks,
435 tests. Compatibility with Claude or Cursor is not schema identity.
Added
- Spec captures
docs/spec/grok-mcp.md,grok-hooks.md,grok-skills.md,
grok-rules.md,grok-agents.md. - Profiles:
grok-tomlMCP,grokhook and skill schemas.
inferHookSchemaProfile("grok")is"grok", not"claude". - Project
.grok/config.tomlwalk-up (cwd → scan boundary). User
$GROK_HOME/config.tomlor~/.grok/config.tomlunder--global.
Same-name project replaces user; closer project file wins.
grok.mcp.no-launchwhen neithercommandnorurlis set. Never
claude.mcp.url-without-typeongrok-toml. .grok/hooks/*.jsonand user hooks under--global. Fourteen events;
handlerscommand/http. Copilotversion: 1remap is not applied..grok/skills(and user skills under--global). Frontmatter required;
name/descriptionoptional. Agent Skills directory-match and Claude
listing-budget checks do not run..grok/rules/*.mdwith no size cap.Agents.mdandAGENT.mdas Grok
instruction files besideAGENTS.md.- Conformance fixture
tests/fixtures/conformance/grok-toml/. spec:checkdrifts Grok hook event names against the live hooks page.
Unread (intentional)
- Managed / requirements TOML, plugins, marketplaces, personas, LSP,
sandbox.toml,pager.toml. [skills] paths(no quoted resolution base)..grok/agents/(directory named, no filename pattern).- Claude / Cursor /
.mcp.jsonas Grok-consumed. .gitignoreskip for instruction files.- Credential files (
auth.json,mcp_credentials.json).
v1.1.0 — Command Code and correctness pass
Native Command Code provider, then a correctness pass over every registered check against 2026-08-31 official docs. Includes 1.0.1. 87 checks, 420 tests. Still offline on check.
Install
npx @chimix/agentscan@latest
npx skills add SimaAlexandru99/agentscanGitHub Action:
- uses: SimaAlexandru99/agentscan@v1
with:
fail-on: errorSkill: https://skills.sh/simaalexandru99/agentscan/agentscan
check against 2026-08-31 official docs. Includes 1.0.1. 87 checks, 420
tests.
Added
- Hook schema profiles:
claude|vscode-native|copilot-cli|
commandcode..github/hookswithversion: 1is Copilot CLI. - Claude hook schema: required
type(not inferred fromcommand/url);
mcp_toolneedsserver+tool;prompt/agentneedprompt;
documented event/handler compatibility; nested matcher groups only. - Copilot CLI: camelCase events mapped onto VS Code names;
bash/
powershell/command;cwd;timeoutSecthentimeout. Prompt
hooks only onsessionStart. User~/.copilot/hooksunder--global. - Agent Skills optional constrained fields:
compatibility1..500,
metadatamap<string,string>,allowed-toolsstring. Info for
SKILL.md>500 lines. File references resolve from the skill root only. - Claude skill listing budget: 1% context window, 8000-character fallback,
per-entry cap 1536, listing text is description (or first markdown
paragraph) pluswhen_to_use. First paragraph satisfies missing
description. - OpenCode V2: local
commandmust be an argv array
(opencode.mcp.command-not-array). - Continue standalone YAML blocks require
name/version/schema
(continue.mcp.missing-block-metadata). Copied JSON is not checked. - Gemini underscore alias warning (
gemini.mcp.underscore-alias). - Claude reserved MCP names including
workspace
(claude.mcp.reserved-name). - Codex chain knobs:
AGENTS.override.md>AGENTS.md>
project_doc_fallback_filenames; one file per directory; root→cwd;
project_doc_max_bytes;project_root_markers. - Coverage matrix uses five dimensions (project discovery, global
discovery, schema, precedence, conformance) instead offull/
partial. - Conformance fixture
tests/fixtures/conformance/copilot-hooks/. - Spec capture
docs/spec/copilot-hooks.md. Alias
claude.hook.mcp-tool-without-name→
claude.hook.mcp-tool-without-server-or-tool.
Changed
- Nested
<dir>/.commandcode/AGENTS.mdis Command Code memory when that
directory has noAGENTS.md(official memory table). - Native VS Code remains command-only with its documented eight events.
vscode.hook.http-without-urlandvscode.hook.mcp-tool-without-name
are removed. - Claude agent names: lowercase letters and hyphens (no digits); filename
is not compared toname. skill.description-budgetprovenance is vendor-recommendation, not a
16000-byte heuristic.
Added (Command Code provider)
- Provider
commandcodefrom official pages underdocs/spec/commandcode-*.md
(read 2026-08-31). Unknown stays skip: no invented local-project MCP slug,
no bundled-skill scan, no--skillflags, no model-id list, no mods
execution. - Skills:
.commandcode/skillsonly at the Command Code project root
(Agent Skills contract),.agents/skillswalk-up (max 10 hops from cwd,
stopping at home), extra dirs from the highest-precedence settings
skillsarray (replace, not merge; relative paths resolve against the git
root). User~/.commandcode/skillsand~/.agents/skillsunder
--global. - Memory: per directory, first existing of
AGENTS.mdor
.commandcode/AGENTS.md(project and nested). User
~/.commandcode/AGENTS.mdunder--global. Unresolved@pathis not a
hard error. Codex's instruction chain excludes.commandcode/AGENTS.md. - Agents:
<project>/.commandcode/agents/*.mdat the Command Code project
root only (git root, or cwd outside a git repo); filename supplies
name; noclaude.agent.*on these files. Checks:
commandcode.agent.reserved-name(explore/plan/review/
general),invalid-permission-mode,invalid-field-typecovering every
documented custom-agent typed field (reasoningEffortis not one of them).
maxTurnsmust be a positive integer. - Hooks: four events (
PreToolUse,PostToolUse,Stop,SessionStart);
nestedhooksarray required;typemust be the string"command";
commandmust be a string (not an argv array);matchermust be a string
when present. Timeout 0–600. A matcher onStop/SessionStartis
runtime-dead, not a schema error. Project and user hooks for the same event
coexist; only an exact duplicate command string is deduplicated (project
wins).settings.local.jsonfollows settings merge (an event array
replaces the project array for that event).COMMANDCODE_PROJECT_DIRand
COMMANDCODE_CWDexpand against the Command Code project root. - Settings: Command Code project root is the git root (a child
.cursor
does not hide<git-root>/.commandcode/).modelinventoried, not
validated. Inlinemcp.servers(array or object map; unnamed array items
are inventory-only). User~/.commandcode/mcp.jsonunder--global.
Spec/runtime checks skip shadowed lower-precedence definitions; security
checks still inspect every readable MCP file. - Slash commands: inventory
.commandcode/commandsat the project root and
the user dir — no required-field checks. - Mods: inventory
mods.paths— never execute or import TypeScript. - Conformance fixture
tests/fixtures/conformance/commandcode/. spec:checktracks captured surfaces and diffs Claude, VS Code, Copilot
CLI, and Command Code hook events against live pages.
Also changed
- Default
skillPathsincludes.commandcode/skills. --global/includeGlobalalso scans~/.commandcode/skills,
~/.agents/skills, user Command Code agents, MCP, memory, Copilot user
hooks, and Codex global AGENTS files.- Shared
.mcp.jsonismcp-json, not Claude-only.
1.0.1 (shared .mcp.json is mcp-json, not Claude-only) ships inside this package version; see CHANGELOG.md.
v1.0.0 — first stable release
First stable release. 59 checks, 345 tests. Offline on check. The coverage matrix in the README is the honesty contract: full only where discovery, spec-required fields, and a conformance fixture (or equivalent tests) all exist.
Install
npx @chimix/agentscan@latest
npx skills add SimaAlexandru99/agentscanGitHub Action:
- uses: SimaAlexandru99/agentscan@v1
with:
fail-on: errorSkill: https://skills.sh/simaalexandru99/agentscan/agentscan
Added
- Portable Agent Skills required fields (
name,description, directory match) for.agents/skills, nested Cursor.cursor/skills, and.codex/skills. - Path-keyed MCP parsers: VS Code
servers, Cursor, AntigravityserverUrl, Codex TOML, Geminicommand/url/httpUrl, OpenCode V1 and V2, Continueconfig.yamlplus.continue/mcpServers/*. - Nested / walk-up
AGENTS.mdwith nearest-wins; Codex instruction budget uses the effective per-directory file andproject_doc_max_bytes. - Walk-up
.claude/agents; VS Code.github/agentswithout Claude missing-name errors. - VS Code
.github/hooks/*.json(eight events) and per-provider hook event sets. - Cursor
.cursor/rules/**/*.mdc500-line recommendation (cursor.rule.too-large, info). Claude rules are inventoried only. - Official-shaped fixtures under
tests/fixtures/conformance/. spec:checktracks 21 captured surfaces, not only Claude hook events.- Launch
cwdandwindows/linux/osxoverrides on hooks and MCP. - GitHub Action pin
@v1.
Changed
- Product copy describes what 1.0.0 actually implements. Heuristics stay at
infoand are labeled in the registry. --globalalso scans~/.codex/skillsunder the Agent Skills contract.- In a monorepo, each
skills-lock.jsongoverns only the skills under its directory (nearest lock wins).
Fixed
- Nested
SKILL.mdtrees are one skill, not a missing-md folder. - Codex instruction chain: at most one file per directory; honour
project_doc_max_bytes. - Interpreter argv (
node script.js), MCPcommandarrays, and OS overrides are path-checked.--inline code (node -e) is not a path. - JSONC (comments and trailing commas) parses via
jsonc-parser; the published bundle imports the ESM entry so Node can loaddist/cli.js. - Scan boundary stays at Git/workspace. A child
.cursordoes not hide parent Claude or Codex. uses:is a launch only on Continue. Other profiles treat a uses-only entry as non-launchable.- OpenCode V2 requires
typeplus the matching launch field. V1 enabled-only overrides that inherit externally do not emit a hard error. - Windows drive / UNC cwd values and OS-specific script paths (
scripts\format.ps1) are not joined as POSIX relative paths when the scanner runs on Linux or macOS. - Old 0.7 rule ids still work in
ignoreRulesandexplain.
0.9.0 was planned as a separate train and shipped inside this release.
v0.4.0 — colour, a face, and Node support
Colour, a face, and a report that reads at a glance.
┌─────┐ 40/100 broken · touchagency
│ ✕ ✕ │ ██████████░░░░░░░░░░░░░░░
│ ⌒ │ 6 warn · 4 info hidden
└─────┘
Since v0.1.0
Runs on Node. npx @chimix/agentscan@latest works without Bun
installed. The published bin is one bundled file, 4 files and 92 kB in
the tarball, no install-time dependencies.
Bare invocation scans. No subcommand means check the current
directory, so the quick start shows findings instead of a usage screen.
Repeated findings group. Six dead hooks printed the same sentence
six times; now one header with ×6 and one line per occurrence. Paths
are shown relative to the scanned project.
A score you can read. 40/100 broken — the word comes from the same
thresholds as the face and the colour, so they cannot disagree.
Colour on a terminal, never anywhere else. Piped output is
byte-identical to the uncoloured report, --json and --output prompt
are never coloured, and --copy puts plain text on the clipboard.
--no-color and NO_COLOR are honoured.
The YAML rule engine is gone. 709 lines producing 9 info findings
across 21 projects, with an extension point nobody had used. Its five
rules are code now, with byte-identical output.
Install
npx @chimix/agentscan@latest # in any project
bun add -d @chimix/agentscan # then: agentscan checkScoped because npm rejects the bare name as too close to an unrelated
agent-scan. The command stays agentscan.
Still alpha
23 checks, each written against a published spec line recorded in
docs/spec/ with its source URL and date. 195 tests. No network on the
check path; nothing is written to the tree being scanned.
v0.1.0 — first alpha
First alpha. A deterministic, offline CLI that finds broken agent
configuration — hooks whose scripts are gone, MCP servers that can never
start, credentials pasted into config, skills that disagree with their
lockfile.
What it does
bunx agentscan check # text report
bunx agentscan check --output prompt # paste-ready handoff for a fixing agent
bunx agentscan check --fail-on error # CI gate23 checks, each one written against a published spec line recorded in
docs/spec/ with its source URL and the date it was read — not against
what happens to appear in real projects. That distinction is the whole
point of this release: an earlier build reported 37 findings across 17
projects of which 25 were false, because two checks were written
from observation. Both were deleted.
Score
score = max(0, 100 - 10 × errors - 3 × warnings)
Published deliberately. Measured across 21 projects it spans 40–100, and
it does not penalise a project for being large: an 85-skill project with
one warning scores 97, while a 54-skill one with six dead hooks scores
40. Coverage-ratio scoring was built, measured, and rejected for
inverting exactly that.
Requires Bun
Bun 1.1+. Not a Node build — import.meta.dir and Bun.which are used
directly. check never touches the network and never writes to the tree
being scanned; the only subprocess in the tool is the optional --copy
clipboard write.
Known limits
- Alpha. The finding-id format is a contract but the check set will move.
- Published as
@chimix/agentscan— npm rejects the bareagentscanas
too close to an unrelatedagent-scan. The command staysagentscan.