All notable changes to agentmap are documented here. Format: Keep a Changelog.
First release of the agentmap-php fork (forked from upstream
agentmap v0.9.0). Adds first-class
PHP and Laravel support via tree-sitter-php while preserving every existing
TS/JS capability. 194/194 tests pass (159 inherited TS/JS + 35 new PHP/Laravel/mixed).
- Modular
src/Core/architecture — extracted the monolithicagentmap.mjs(~1831 lines) into composable modules (language-parser,PhpParser,LaravelParser,EnhancedLaravelParser,map-builder,graph,rank,cache,cli,utils,vue,constants) behind aLanguageParserplugin interface.agentmap.mjsre-exports the surface area unchanged — no behavioral change for existing TS/JS users.
- tree-sitter-php parser — AST extraction for classes, interfaces, traits, enums, functions, and namespaces. No PHP runtime required.
- Import resolution —
use/require/includeresolved to import-graph edges. - PSR-4 namespace resolution via
composer.jsonautoload.psr-4. - PHP symbols in PageRank — PHP symbols flow through the existing personalized PageRank + identifier-graph ranking pipeline.
- All commands work with PHP —
--any,--map,--digest,--relates,--find,--hub,--symbolssurface PHP results alongside TS/JS. No new flags; PHP is just another language to the existing commands.
- Facade resolution — 33 standard Laravel facades (
Cache,DB,Route,Auth,Schema, …) resolved to their underlyingIlluminate\Support\Facades\*classes. - Eloquent relations —
hasOne/hasMany/belongsTo/belongsToMany/morphTo/… traced as graph edges between models. - Route → controller links —
routes/web.phpandapi.phpparsed;Route::get/post/resource(...)linked to controller handlers. - Service providers — provider classes and their bindings recognized.
- Unified TS/JS + PHP graph — repos with both languages parse into a single ranked graph.
- Cross-language references — Inertia links between TS/JS pages and PHP controllers detected as cross-language edges.
- Blade templates —
.blade.phpdirective extraction;@extends/@include/@componentresolved to target view files. - Livewire —
@livewire('comp')components andwire:model/wire:clickbindings traced. - DDD / pattern detection — Action, Domain, Repository, Service, DTO, Policy, Job, Event, Listener, … detected by naming convention.
- Artisan commands —
$signatureparsed into command name, arguments, options. - Middleware tracing —
->middleware()/Route::middleware()chains. - Migration parsing —
Schema::create('table')table schemas, column types, foreign keys. - Static analysis — declared property/parameter/return type extraction; controller→service→repository method-call tracing (shallow caller→callee pairs).
- Added
tree-sitter@^0.22.4andtree-sitter-php@^0.22.6(compatible pinned versions).ts-morph@28.0.0retained for TS/JS — no PHP runtime needed.
- All existing CLI flags and output formats are unchanged. TS/JS behavior is identical to upstream v0.9.0.
- This fork ships from GitHub (
dstwn/agentmap-php), not npm. The package name remains@raymondchins/agentmapto preserve upstream attribution. - The
npx --no-install @raymondchins/agentmappost-commit fallback resolves the upstream TS/JS-only package — keep a repo-localagentmap.mjsfor PHP support.
--install-skillplatform expansion (#6, #12, @muhajirdev) —codex,opencode,gemini,antigravity,copilotwith paths aligned to each platform's documented skill directories. Also merges always-onGEMINI.md/AGENTS.mdblocks, Gemini CLIBeforeToolhooks, and OpenCode plugin (same--install-skillcommand — no separate flag).
--platform alldefault set — now installs claude, cursor, codex, opencode, gemini, antigravity, copilot. Legacyagentsis opt-in (--platform agents). Globalallno longer writes~/.agents/skills/by default; useantigravity(~/.gemini/config/skills/) or explicitagentsfor v0.7.0~/.agents/behavior.
- Monorepo tsconfig path aliases (#9, @muhajirdev) —
--relatesno longer undercounts dependents when a repo imports through tsconfigpathsaliases (@/*,#/*,~/*) defined at a non-root package config. Alias-config discovery now also followsextends, so a package tsconfig that onlyextendsa shared base (Turborepotsconfig.base.jsonholding allpaths) still contributes its inheritedbaseUrl/paths. Recursive, depth-capped, child overrides parent. - Windows Gemini docs path — global
GEMINI.mdnow routes to~/.agents/GEMINI.mdon Windows (mirroring the skill destination) instead of the POSIX-only~/.gemini/GEMINI.md, so the always-on guidance lands where Gemini CLI reads it.
--hook-status(#5, @muhajirdev) — a read-only command that reports whether agentmap's git-hook wiring is installed: thepost-commithook (and whether it's agentmap's vs a foreign hook), thePreToolUsenudge file, thePreToolUse(Grep)PreToolUse(Bash)wiring in.claude/settings.json, and the.gitignoreentry. Detection is a substring marker scan, so a chainedpost-commit(agentmap sharing one hook with another tool) is correctly reported as installed.
--install-skill(#4, @muhajirdev) — install packaged agent-guidance assets so coding agents are steered to agentmap before falling back to grep: ships a Claude Code / Codex / OpenCodeSKILL.mdand a Cursor always-on rule. Flags:--platform claude|cursor|agents|all(defaultall),--project(default) or--global, and--dry-run. Writes are atomic and whitelisted to fixed, agentmap-namespaced paths. The installer is lazy-imported so it never loads on the warm--any/--findquery hot path.
- Graceful degradation: the per-file parse loop now wraps each file in try/catch — a single pathological source (e.g. a malformed import specifier that makes ts-morph throw) is skipped with a stderr warning instead of aborting the entire map build.
- Path aliases for dynamic edges: tsconfig/jsconfig
baseUrl/pathsaliases (@/x,~/x) now resolve for side-effect imports, dynamicimport(), andrequire()too — previously only static imports formed edges. - Symbol ranking: re-export barrels (
export { X } from './y') are no longer counted as references toX, so heavily re-exported symbols are not over-ranked in barrel-heavy repos (file-level dependency edges are unchanged). - Dirty-tree detection:
git statusrename parsing is gated on the porcelain status code, so a plain file whose name contains" -> "is no longer mis-parsed (which could serve a stale cache as fresh). --maptiny budgets: partial-recovery now tests down to a single symbol, so a very small--tokensvalue still emits the top file instead of nothing.- Non-git fingerprint walk: per-directory try/catch (a permission-denied subdir no longer empties the fingerprint and disables caching) plus a recursion depth cap; mirrored in the non-git Vue walk.
- Clarified that the
--anycontent fallback is case-insensitive by design (matches--find); matches are printed verbatim so true casing is visible.
0.4.0 - 2026-06-14
- Retrieval-accuracy eval (
eval/eval.mjs,npm run eval,EVAL.md). Scores whether agentmap returns the correct results, not just fewer tokens — complements the token-efficiency benchmark. Ground truth is derived live from real cloned repos (zod, zustand, hono) via an independent regex + import-resolver (not agentmap's own graph, so the comparison isn't circular), and scope is aligned both ways (test files and type-only edges excluded from both sides) so neither tool is unfairly scored. Measures symbol-definition top-1/top-3 hit rate and dependents precision/recall vs a naivegit grepbaseline. Network-only; excluded from CI. Clones land in gitignoredtmp/eval/.
- Untracked-secret exclusion in content search.
--anylive content search no longer returns matches from untracked files such as a local.env— secrets that live only on disk (never committed) are excluded from results, so a query that happens to match a secret value surfaces the source-code match but never the credential file. - Post-commit hook hardening against local-script execution. The git
post-commithook now trusts only the repo-root./agentmap.mjs(the unusual./scripts/agentmap.mjspath a malicious PR could add for arbitrary code execution on a victim's next commit was removed) and adds anAGENTMAP_HOOK_NO_LOCAL=1escape hatch to skip even./agentmap.mjsand rely solely on the installed binary / npx — for CI or when reviewing untrusted branches.
--install-hooksPreToolUse hook path now resolves under an npx install. The nudge is copied into the project at.claude/hooks/agentmap-nudge.mjsand wired vianode "$CLAUDE_PROJECT_DIR/.claude/hooks/agentmap-nudge.mjs", instead of referencingnode_modules/@raymondchins/agentmap/...which does not exist after annpxinstall (the hook silently never fired).- JSONC-tolerant settings parse.
--install-hooksnow parses a project.claude/settings.jsonthat contains comments (strict JSON first, then a comment-stripping retry) before surfacing a clear error. - Symlink-loop guard in source enumeration / cache traversal.
- Cache moved to
.claude/agentmap/(namespaced dir) with migration from the legacy single-file location;.gitignorenow ignores.claude/agentmap/. --install-hooks --dry-runprints the files it would create/overwrite and writes nothing.
- Token-cost methodology disclosure — benchmark numbers now state the
chars/4token approximation and document the Scenario-F benchmark so readers can reproduce the before/after counts. - New
SECURITY.md— supported versions, private reporting channel, and the threat model for the post-commit hook + content search.
- Added security gates to
.github/workflows/ci.yml:npm audit(--audit-level=high), CodeQL analysis,npm pack --dry-runmanifest validation, and a Gitleaks secret scan.
- Synced
package-lock.json(it was stale at0.2.0).
0.3.0 - 2026-06-14
-
Bash-searcher coverage for the
PreToolUsenudge hook.hooks/agentmap-nudge.mjspreviously only watched theGreptool, so any search run as rawgrep/rg/egrep/fgrep/ag/ackvia the Bash tool bypassed the nudge entirely — the exact gap that let an agent forget agentmap and fall back to manualRead/sed/awk. The hook now also handlestool_name === "Bash"with an identical fire/silence heuristic, plus a new multi-hump PascalCase symbol rule (ProviderCard,TopProviders) that catches bare identifier hunts the Grep branch never sees. The Bash branch only fires when the searcher is the primary command (at the start of the string, or after;/&&) — piped filters likeps aux | grep nodestay silent. The--install-hookscommand now wires both aGrepand aBashmatcher into.claude/settings.json(idempotent, merge-safe). -
New test file
test/nudge-hook.test.mjs(36 cases) drives the hook directly as a subprocess, covering Grep fires/silence, Bash fires/silence, PascalCase symbol detection, output shape validation, and injection safety.
--install-hooksnow writes twoPreToolUseentries —matcher: "Grep"andmatcher: "Bash"— both pointing at the sameagentmap-nudge.mjs. The hook dispatches internally ontool_name, so a single file covers both surfaces with no duplication of logic.- The TS-generic denylist (
<Promise<,<Record<string,<Array<, …) is no longer^-anchored — it now suppresses a generic wherever it appears. This fixes a spurious fire on the Bash branch (which tests the whole command, e.g.rg "<Promise<Foo>") and on mid-pattern Grep generics (e.g.useState<Promise>). A\bafter the type name keeps real components such as<PromiseCard/<MapViewfiring.
0.2.3 - 2026-06-14
- Docs only — no code change since 0.2.2. README restructured to lead with the benchmark (now a before/after table of real per-task token counts: reading files vs agentmap) and the agent-loop differentiator, with plain-language section intros. CI actions bumped to v5 (Node 24). Published to sync the npm package page with the GitHub README.
0.2.2 - 2026-06-13
--install-hooksnow auto-wires thePreToolUse(Grep)nudge into the project's.claude/settings.json(merge-safe + idempotent) instead of only printing the snippet — so the "agent is forced to use the map" enforcement is on by default after install, with no manual copy-paste step.
- Lazy-load
ts-morph. Its ~105 ms compiler init now fires only on a cold rebuild; warm cache queries (the common case on a clean tree) skip it entirely viacreateRequire, making them ~2× faster — measured 217 ms → 105 ms median (−52%) on a clean-tree fixture. Cold-build time is unchanged.
0.2.1 - 2026-06-13
- License simplified to MIT-only. Removed
LICENSE-APACHEfrom the repo and the npm tarball. agentmap's PageRank / symbol ranking is an independent JavaScript reimplementation of a public algorithm (Aider callsnetworkx; no Aider source is copied), so it is not a derivative work and carries no Apache-2.0 obligation. Aider remains credited inNOTICEand the README as the origin of the ranking approach. Fixes GitHub showing an "Unknown" license.
0.2.0 - 2026-06-13
- New CLI flags:
--help/-h,--version/-v,--json(global output modifier),--install-hooks,--mcp— full spec in README. --jsonstructured output for all query commands (--hubs,--features,--feature,--find,--relates,--map,--symbols,--any,--print, bare build); enables machine-readable consumption by MCP clients and CI scripts.- MCP server (
mcp.mjs) — stdio MCP transport wrapping all query commands; launched viaagentmap --mcpor directly. Ships in the npm tarball. - Hooks shipped in tarball —
hooks/directory (post-commit auto-refresh +agentmap-nudge.mjsPreToolUse hook for Claude Code) now listed inpackage.jsonfiles; installed into a repo viaagentmap --install-hooks. - Apache-2.0 attribution —
LICENSE-APACHEandNOTICEadded to credit Aider's PageRank / identifier-graph algorithm that agentmap ports. - Test suite —
test/directory withnode --testrunner;npm testentry point added topackage.json. - CI — GitHub Actions workflow running tests and a dry-run
npm packon every push.
- Corrected all npm-fetch references to use the scoped name
@raymondchins/agentmap(the bare nameagentmapon npm is an unrelated tool). - Stale-cache robustness: cache invalidation now detects monorepo roots, path aliases, symlinked node_modules, spaces in paths, and large repos (>10 k files).
--printJSON output now includes top-levelfileCount.- Unknown flags now print to stderr and exit 2 instead of silently rebuilding.
- Exit codes formalized: 0 = success, 1 = zero-result query, 2 = usage error.
- Internal rename: entry file
repomap.mjs→agentmap.mjs, cache file.claude/repomap.json→.claude/agentmap.json, and PreToolUse nudge hookrepomap-nudge.mjs→agentmap-nudge.mjs— aligns all internal filenames with the published binary name. package.jsonfilesallowlist expanded from["agentmap.mjs"]to includemcp.mjs,hooks/,LICENSE-APACHE, andNOTICE..npmignoreremoved — thefilesallowlist fully governs the tarball.
- Faster cold builds:
skipFileDependencyResolutionplusgit ls-files-based source enumeration (replacing an expensive full-tree FS glob) make a full build net faster than v0.1.0 while indexing the same-or-more files.