NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Compact PHP repository symbol maps for coding-agent navigation.
Last release today
06 Oct 2026
Ships fairly regularly
a new release about every 8 days
Nearly every release is documented
notes for 46 of 46 stable releases
Nothing withdrawn
no release was ever pulled
2 months old
46 releases · first in 2026
One column per month.
method_rename_plan, class_rename_plan and method_removal_plan carry an optional non_php_references block that lists Markdown and Twig / Smarty / Blade
method_rename_plan, class_rename_plan and method_removal_plan carry an optional non_php_references block that lists Markdown and Twig / Smarty / Blade template mentions of the planned symbol, with a confidence grade, exact byte ranges and a historical flag for changelog-style files. It is residue evidence for a separate cleanup stage and never changes plan status, edits, blind spots or blockers; a symbol without mentions produces no key. See docs/stability.md.Make class_removal_plan@1.0 reject top-level declare statements with statement bodies when proving whole-file ownership, so executable work in block/c
class_removal_plan@1.0 reject top-level declare statements with statement bodies when proving whole-file ownership, so executable work in block/colon-form declare syntax cannot be silently deleted with the class file.Add class_removal_plan@1.0: a PHPStan-backed, fail-closed plan for deleting one unused namespaced class only when it exclusively owns its source file;
class_removal_plan@1.0: a PHPStan-backed, fail-closed plan for deleting one unused namespaced class only when it exclusively owns its source file; live type evidence blocks, while class PHPDoc, class attributes and exact string/PHPDoc references require review.Method, property and class-constant removal now take the declaration range, including its PHPDoc comment and attributes, from voku/simple-php-code-par
voku/simple-php-code-parser (AstNodeInspector::ownedRange(), 0.22.12) instead of reconstructing it from the AST in three places. Removal plans and their byte ranges are unchanged; a node without source positions now fails closed with a clear error. Requires voku/simple-php-code-parser ^0.22.12.Keep AST-only attribute extraction source-bound when process-global constants exist, consuming the upstream voku/simple-php-code-parser 0.22.7 fix ins
voku/simple-php-code-parser 0.22.7 fix instead of leaking runtime constant values into repository maps.voku/simple-php-code-parser ^0.22.7 for the AST-only constant-expression and array-key correctness fixes.Add SearchIndexStore::openReadOnly() as the owner boundary for querying an existing Search index without creating directories, migrating schema, or pr
SearchIndexStore::openReadOnly() as the owner boundary for querying an existing Search index without creating directories, migrating schema, or producing SQLite WAL/SHM sidecars; legacy WAL snapshots are rejected with an explicit refresh requirement (#117).voku/agent-graph 0.2.3 through GraphStore::openReadOnly() when opening/verifying the derived graph, so read-only Map inspection no longer mutates graph storage (#118).DELETE journal mode so a published Search snapshot can be consumed read-only without hidden sidecar state (#117).MapReadiness::$searchRecoveryCommand exposes the owner's Search recovery command (agent-map search-index build|refresh ...) from SearchReadinessInspec
MapReadiness::$searchRecoveryCommand exposes the owner's Search recovery command (agent-map search-index build|refresh ...) from SearchReadinessInspector, so hosts show the owner's action instead of composing their own recovery prose (#96).Add the typed SearchReadinessInspector owner projection for fail-closed Search capability, currentness, metadata recovery, and non-empty-index readine
SearchReadinessInspector owner projection for fail-closed Search capability, currentness, metadata recovery, and non-empty-index readiness checks.Add the typed SearchMaintenanceRequest -> SearchMaintenanceService::refreshIfPresent() -> SearchMaintenanceResult owner boundary for optional Search r
SearchMaintenanceRequest -> SearchMaintenanceService::refreshIfPresent() -> SearchMaintenanceResult owner boundary for optional Search reconciliation. Consumers can observe absent, unavailable, refused, stale, failed, refreshed, and current states without reconstructing Search storage, chunk, snapshot, or pruning semantics.Preserve the bounded preparation request in owner-produced recovery commands, including excludes, scan paths, output format, backend, and PHPStan conf
Add MapPreparationService::prepare() for bounded consumer preparation: it builds a missing map, refreshes an existing map with its recorded reproducib
MapPreparationService::prepare() for bounded consumer preparation: it builds a missing map, refreshes an existing map with its recorded reproducible backend, and returns a typed MapPreparationException with an executable recovery command when the state cannot be prepared safely.Add the typed Map preparation owner boundary MapPreparationRequest -> MapPreparationService::refresh() -> MapPreparationResult. The CLI now delegates
MapPreparationRequest -> MapPreparationService::refresh() -> MapPreparationResult. The CLI now delegates map refresh/currentness semantics to this PHP API, including stored semantic scope reuse, changed/new/removed file reconciliation, structural-only removal pruning, PHPStan full-scope refresh, semantic input drift, backend compatibility, and index persistence (#96, #97).voku/simple-php-code-parser ^0.22.4, the first release that provides the ParserOptions::astOnly() API used by Map's structural extractor (#98, #99).release: prepare voku/agent-map 0.14.0
release: prepare voku/agent-map 0.14.0
SimplePhpParserSymbolExtractor and AgentMapBuilder: uncached files are extracted concurrently across available CPU cores via pcntl_fork (when available) or proc_open child workers, dramatically reducing indexing wall-clock time.extract-worker subcommand in AgentMapApplication to support multi-process batch extraction across process boundaries and environments without pcntl.ParserOptions::astOnly() from upstream voku/simple-php-code-parser 0.22.4, restricting symbol extraction strictly to source file declarations and eliminating vendor reflection, parent class autoloading, and inherited member explosion (18x-280x extraction speedup).IndexReader static cache with LRU eviction to MAX_CACHE_ENTRIES (4) to prevent unbounded memory growth during repeated index queries.Make missing polyglot definition providers actionable: DefinitionEvidence and DefinitionCapabilityReport project missing_executables (list of missing
DefinitionEvidence and DefinitionCapabilityReport project missing_executables (list of missing binary names) and next_action (manual_setup_required) so coding agents and callers can self-diagnose and resolve missing toolchains without string scraping (#95).process-timeout to 900 seconds so full test suites with static analysis dogfood pass without hitting the default 300s process timeout in composer ci.feat(tests): add test discovery and intelligent symbol resolution sug…
feat(tests): add test discovery and intelligent symbol resolution sug…
tests command (agent-map tests <target>) discovers direct test callers (via incoming calls and instantiates relations), companion test files, and synthesized runner commands across PHPUnit and Codeception. Supports methods, classes, source files, and keywords with text, json, markdown, and toon output formats.scope or resolveMethod, agent-map suggests similar symbol names ("Did you mean: ...") and lists available methods on the matched class to enable fast self-correction for coding agents.WorkflowReport: tests referencing templates are now partitioned into a dedicated testSymbols section instead of cluttering production controllers and views.likelyTestFiles() recognizes Codeception conventions (_UnitCest, _ApiCest, _AcceptanceCest) in addition to PHPUnit *Test classes.callers, callees, related) via currentIndexForRead.feat(discovery): reverse-link templates and views for ajax handlers a…
feat(discovery): reverse-link templates and views for ajax handlers a…
WorkflowDiscovery reverse-links templates and entrypoint views when querying AJAX handler classes (xajax_*) or form action targets.fix(discovery): exclude hidden directories and worktrees in TemplateS…
fix(discovery): exclude hidden directories and worktrees in TemplateS…
TemplateScanner ignores hidden directory hierarchies (e.g. .agent-loop-runner, .git, .idea) avoiding duplicate templates from temporary worktrees or cache dirs.workflow command discovers full web workflows across PHP controllers, Smarty/Twig/Blade templates, form actions, and AJAX handlers. Traces bidirection
workflow command discovers full web workflows across PHP controllers, Smarty/Twig/Blade templates, form actions, and AJAX handlers. Traces bidirectional workflow chains between PHP views and templates with text, json, markdown, and toon output formatting.ScopeAstVisitor detects and resolves templates across render_with_data, render_only_data, display_string, fetch_string, method returns ($this->getTemplate*()), class constants, local variables, named arguments, and inline Smarty templates.definition-capabilities command reporting operational routing readiness (#92).scope and context bring a stale index current before answering, when that is safe. A stale index used to end the conversation: scope threw Agent map i
scope and context bring a stale index current before answering, when that is safe. A stale index used to end the conversation: scope threw Agent map is stale. Rebuild it before inspecting a scope. with no index path, no stale count and no command, so the host had to remember stale -> refresh -> re-issue the original question. Editing an unrelated Markdown file was enough to trigger it, and a tool that answers a maintenance errand instead of the question loses to text search, which has no freshness concept and always answers something. Repair is deliberately narrow: it runs only when the index and the current run resolve the same backend, which is the guard refresh already applies before merging, so PHPStan evidence is never quietly downgraded to structural-only; and it builds against the scope the index recorded rather than the files that happened to change, so a repair cannot shrink indexed coverage to whatever was edited last. Currentness means the same thing a refresh means by it: source hashes, and for a PHPStan-backed index also its configuration and composer.lock, because those move while every indexed file's hash stays identical and the callers and types a read reports would otherwise belong to the previous observation envelope. The repair always uses the scope the index recorded and never this command's --paths, --exclude or --scan: those flags exist so build and refresh can change what is observed, and a question must not smuggle a reconfiguration into persistent derived state. Every observation input comes from the index: its recorded root, scope, excludes and scan directories, for both backends. --root is the directory the question was asked from, so a stale read issued elsewhere would otherwise rebuild the index against the wrong project - and because the repair quietly did nothing in exactly that case, scope still refused a stale map and the suite still passed. The serialization the index is written in is preserved through IndexReader::detectFormat() rather than guessed from the filename, so a TOON index living under a .json name is not silently converted. A deleted file counts as stale in the announcement. A repair that fails reports why - a parse failure, a PHPStan failure and an I/O failure are different problems - instead of collapsing every fault into the same maintenance errand. It is never silent - the note goes to STDERR before the work starts, because a PHPStan-backed repair re-analyses the recorded semantic scope and can take tens of seconds. That is the same work a manual refresh would do, so the cost is unchanged; only the round trip disappears. Anything the repair cannot do safely still fails closed, and now names the index it judged, how many files are stale, and the exact command to run. Reported as #86.refresh --index=<path> writes the refreshed map back to that index. It resolved its output to the artifact root's default filename instead, so a project whose index is not named php-symbols.json had every refresh written to a second file while the named index stayed stale: the command reported Refreshed 1 changed ... file(s) and the next run read the same unchanged source again. An explicit --out still wins, and a .toon index keeps the TOON serializer without being told twice.AgentMapBuilder::backend() reports the backend identity a build by that instance would write, so a caller can test an index for mergeability before attempting an incremental merge rather than reading it out of the exception afterwards.--backend=structural - instead of prose describing that a full build is needed. The refusal already knew every argument; a host following the prescribed next action literally would otherwise loop refresh -> refusal -> refresh forever. The command rebuilds the scope the index recorded rather than the wider search scope a refresh uses, keeps a structural-only index structural-only, and quotes any value that would not survive being copied into a shell. Reported as voku/agent-loop#404.ImpactAnalyzer::forFile() answers what can notice a change to one indexed file, returning a typed FileImpactReport. Impact was reachable only from a s
ImpactAnalyzer::forFile() answers what can notice a change to one indexed file, returning a typed FileImpactReport. Impact was reachable only from a single method or node id, so a consumer holding a path - a Contract scope entry, a changed file - had to pick one declaration out of the file and accept a narrower answer, or union several traversals itself and get the shared bound and the uncertainty composition wrong. Every declaration in the file seeds one traversal, the node bound applies to their union, and the file's own declarations are excluded because changing a file is not something that file notices.Declare nikic/php-parser:^5.0 as a direct runtime dependency because agent-map production code directly consumes php-parser 5 APIs. Lowest-dependency
nikic/php-parser:^5.0 as a direct runtime dependency because agent-map production code directly consumes php-parser 5 APIs. Lowest-dependency consumers can no longer resolve php-parser 4.x and then type-error in class move/rename planning despite satisfying the published Composer metadata.--prefer-lowest dependency-floor check that asserts php-parser 5.x and exercises the class-move and class-rename planner regressions. Exact-head PHP 8.2, 8.3, 8.4 and 8.5 composer ci, structural/temporal checks, and rename/removal/class-move dogfood are green.Make incremental search-index refresh preserve the same deterministic duplicate canonical-chunk winner as a clean full build. When a refresh introduce
search-index refresh preserve the same deterministic duplicate canonical-chunk winner as a clean full build. When a refresh introduces an earlier path while a later duplicate claimant remains in the existing index, the retained row no longer wins merely because it survived the partial delete. Refresh now compares retained and incoming paths using the existing path-ordered first-wins rule, removes a later retained claimant together with its external FTS row inside the existing transaction when necessary, and otherwise skips the later incoming duplicate. The one-sided refresh regression verifies identical searchable results and chunk_id@content_sha256 state against a clean rebuild while preserving deleted-path pruning, transaction rollback, schema, and chunk-id semantics.Cache parsed AgentMapIndex instances in IndexReader across repetitive queries within a process when mtime and filesize are unchanged, avoiding duplica
AgentMapIndex instances in IndexReader across repetitive queries within a process when mtime and filesize are unchanged, avoiding duplicate JSON decoding and object hydration.IndexReader::read(), pre-filter unneeded top-level sections (such as diagnostics, local_bindings, local_exits) before invoking AgentMapIndex::fromArray(), avoiding construction of thousands of diagnostic and entry objects during partial section reads.IndexReader cache and PHP stat cache in IndexWriter::write() to maintain immediate read-after-write consistency.Stop search-index refresh aborting on a canonical symbol id that is declared more than once in the repository. A full build deletes every row before i
search-index refresh aborting on a canonical symbol id that is declared more than once in the repository. A full build deletes every row before inserting, so the only duplicates it can meet are inside its own batch, which it resolves by keeping the first and reporting a skipped count. A refresh deletes only the paths it replaces, so a row belonging to an untouched file could still hold a chunk id the incoming batch was about to insert, and the whole transaction died on UNIQUE constraint failed: code_chunks.chunk_id. Repositories with any duplicated canonical symbol id - legacy duplication, fixtures, vendored copies - could therefore build a search index but never refresh one. replaceChunks() now seeds its seen set from the ids that survived the delete, so a refresh skips exactly what a build skips.SearchIndexStore::semanticProvider(), the typed way to obtain the embedding provider an index's vectors were actually written with, and SearchIndexStore::storeEmbeddingState() to record it. Restoration was previously implemented only in a private CLI method reading the store's own metadata keys, so an embedding host that wanted the semantic channel had to reproduce which key holds the fitted weighting, how it is shaped, and what makes it valid - a second definition of the vector space living outside the package that owns it. The factory refuses rather than refits: it returns null when sqlite-vec is unavailable, when nothing is embedded, when the recorded state is unusable, or when the restored model no longer matches the fingerprint the stored vectors belong to. The CLI and the navigation-replay dogfood are now callers of it rather than second copies of it.MapReadinessInspector::inspect(MapArtifactPaths $artifacts, bool $loadRelations = true) so callers inspecting map file freshness can avoid parsing relations payloads.Add local semantic understanding inside methods and functions (#61):
LocalSemanticFrame capturing ordered execution checkpoints (LocalBindingCheckpoint, LocalGuardCheckpoint, LocalUseCheckpoint, LocalExitCheckpoint).startFilePos, endFilePos) across relations, variable bindings, and exit statements.Assign, AssignOp, AssignRef, Foreach_, Catch_) and exit points (Return_, Throw_).local_bindings and local_exits in companion relations file with backward compatibility.LocalSemanticFrameBuilder extracting variable narrowing (e.g. excludes false, excludes null, instanceof), semantic method/property uses on locals, and exit reasons.ScopeInspector, ScopeInspection, EditContextPlanner, EditContextPlan, and CLI scope command output.target_id property and output key to MethodMovePlan, MethodCopyPlan, MethodScaffoldPlan, ClassScaffoldPlan and their planners.rename, removal, move, copy, scaffold) in tests/PlanContractShapeTest.php.docs/stability.md classifying all 14 plan contracts as stable at contract version 1.0 with exit code 1 on blocked.voku/agent-graph ^0.2.0 and consume graph relation contracts and SQLite runtime (#63, #65, #71, #73).Reading a split index whose relations companion is missing now fails loudly instead of returning an empty relation graph. An incomplete copy was indis
map history diff reported
every relation on the other side as newly added against an unchanged tree. A
renamed symbols file beside the companion it names now resolves it; legacy
single-file indexes are unaffected.Makefile.agent-map.mk to resources/make/agent-map.mk, and move THIRD_PARTY_NOTICES.md to docs/reference/third-party-notices.md following the shared repository layout convention. Introduce PackageResources as the single owner of package-shipped asset paths.php-symbols.json or .toon) and a companion relations file (php-relations.json or .toon). This decouples large call/override relation graphs (often 80-90% of index size) from core symbol definitions, enabling direct fast reads (~60ms vs 1.4s) for file, symbol, stats, and changed lookups while preserving full relations on-demand or transparently via IndexReader::read().changed and stats CLI commands to use IndexReader::readSections(['files']) instead of a full read(). This skips decoding >70MB (87% of the index payload) of relations data when only file hashes, file metadata, and symbol counts are needed, reducing command execution time from >1.1s to ~0.4s and significantly lowering peak memory usage on large indexes.Add typed consumer accessors to MapArtifactPaths for the canonical index, relations, graph, search, temporal, source-cache, and lock artifacts.
MapArtifactPaths for the canonical index, relations, graph, search, temporal, source-cache, and lock artifacts.GraphIndexStore so graph-specific storage and validation details remain owner-owned.Publish the versioned, read-only class_constant_removal_plan@1.0 contract for provably unused private class constants with typed provenance, exact has
class_constant_removal_plan@1.0 contract for provably unused private class constants with typed provenance, exact hash-bound deletion edits, blockers, review-required evidence, stale evidence, and explicit non-observable boundaries.constant(), dynamic constant names, inherited or late-static lookup, and source outside the indexed map remain explicit non-observable boundaries rather than being presented as detected evidence.40e8ee8678dde9185ad7de99163a18209ab0152d before squash merge to f6f27e112d16ad96af7854a8ede3da5867d5500c.Publish the versioned, read-only property_removal_plan@1.0 contract for provably unused private properties with typed provenance, exact hash-bound del
property_removal_plan@1.0 contract for provably unused private properties with typed provenance, exact hash-bound deletion edits, blockers, review-required evidence, stale evidence, and explicit non-observable boundaries.29dfcb86bc0bfa9e8b9cbc4fa81e9e24c855ed1f before squash merge to 2e9e83902b4812e2ba36836a7a8650e38e514f9a.Publish the versioned, read-only method_removal_plan@1.0 contract for unused private methods with typed provenance, exact hash-bound deletion edits, b
method_removal_plan@1.0 contract for unused private methods with typed provenance, exact hash-bound deletion edits, blockers, review-required evidence, stale evidence, and explicit non-observable boundaries.--index paths follow the configured project root, while text output preserves provenance, stale evidence, and observability limits.c21f1b80b9abca508a672757d44ac11e26fffc2a before squash merge to 02adb3358eac3a1efbcd43111b541d82da455c88.Publish versioned, read-only rename plans for functions, private properties, same-namespace classes, and class constants, each with exact precondition
THIRD_PARTY_NOTICES.md.Publish method rename planning as an explicit versioned contract. Plans now carry complete map provenance (map digest, effective backend, and analysis
rename-plan evidence, status, observation, and mutation-host validation boundary.1.0, collect evidence identity under provenance, and always publish typed stale_evidence. The pre-0.9 top-level backend and digest fields remain compatibility aliases; blocked plans continue to publish no edits.Record the exact Composer package reference used by PHPStan-backed maps in AnalysisFingerprint; structural-only maps record none, while historical fin
AnalysisFingerprint; structural-only maps record none, while historical fingerprints without the field remain explicitly unknown.agent-loop builds today, and agent-map's existing
exact surfaces, under both the structural and PHPStan backends
(docs/dogfood/map-navigation-evidence.md, harness and raw reports in tools/dogfood/).AnalysisFingerprint so PHPStan provenance no longer has to be reconstructed later.composer install --no-dev structural build, and CodeRabbit with no actionable comments.Add explicit semantic-backend selection so embedders can choose auto, structural, or phpstan without treating PHPStan availability as an implicit inst
auto, structural, or phpstan without treating PHPStan availability as an implicit install-time requirement.Added immutable MapReadiness and MapReadinessInspector owner boundaries so embedders can consume current map freshness, source snapshot identity, and
MapReadiness and MapReadinessInspector owner boundaries so
embedders can consume current map freshness, source snapshot identity, and derived
Search compatibility without reconstructing agent-map policy from artifact presence.composer ci is green on PHP 8.2, 8.3, 8.4, and 8.5, and the temporal self-dogfood
job is green for the exact implementation candidate.Add graph-backed impact traversal and source materialization contracts.
Add typed map/search projection contracts for downstream consumers.
Add incremental map freshness and changed-path inspection support.
Add persisted code-search chunks, lexical search, and optional semantic vector projection.
Load stop words from voku/stop-words instead of copying the package data into source. The package already caches its per-language arrays in process; k
voku/stop-words instead of copying the package data into source. The package already caches its per-language arrays in process; keeping a second 1,300-word source constant added maintenance cost without avoiding runtime work. The code-domain additions remain local and lookups use a hash set rather than a linear in_array() scan.Add the initial hybrid search-index surface with canonical chunk identities and FTS-backed lexical search.
agent-map refresh re-analyses only the files whose hash moved plus the ones that appeared since the last build, and patches them into the existing ind
agent-map refresh re-analyses only the files whose hash moved plus the ones that appeared since the last build, and patches them into the existing index;
deleted files drop out. agent-map build --merge does the same for an
explicit --paths scope. Keeping a large map current no longer means paying
for a full rebuild.--scan=<dirs> maps to PHPStan's scanDirectories, so a scope that
references classes living outside it resolves their types instead of failing
with "Class X was not found ... discovering symbols is probably not
configured properly".voku/simple-php-code-parser resolves {@inheritdoc} parents through
class_exists($parent, true), so in a project whose autoloader maps class
names onto procedural legacy files, "parse one file" used to include and
execute that parent - rendering pages, opening database connections - and
then indexed the reflected parent as a symbol of the child file. On a real
code base that accounted for roughly half of all declares_method relations
and 19 000 bogus structural_only_method diagnostics.--exclude is set. PHPStan disables its
result cache completely when only files are passed ("Result cache not used
because only files were passed as analysed paths"), which made every rebuild
a cold rebuild; a no-change rebuild of a 3 300-file project dropped from over
15 minutes to under a minute.IndexWriter starts every top-level section on its own line (the output is
still ordinary JSON), and IndexReader::readSections() decodes only the
sections a command needs. file, query, stale, and summary now skip
the relation list - the largest section by far - which took their runtime on
a 66 MB index from ~6.7 s to ~2 s at 75 MB instead of >1 GB peak memory.SemanticAnalyzer::analyse() takes two additional optional parameters
($analyseDirectories, $scanDirectories). Custom implementations must
extend their signature.Added --phpstan-memory-limit to agent-map build, forwarding the bounded value to the PHPStan semantic-export child process.
--phpstan-memory-limit to agent-map build, forwarding the bounded
value to the PHPStan semantic-export child process.EditContextPolicy, allowing
consumers to send a surgical primary-source excerpt instead of a large
method while retaining the full target if no literal matches.PHPStan 2.2 semantic collection for resolved PHPDoc types, generics, call targets, instantiations, prototypes, and referenced types.
voku/simple-php-code-parser structural facts and PHPStan semantic facts, including explicit diagnostics and conflict states.callers, callees, and context commands for exact Class::method targets.scope now enriches syntax-derived calls with persisted PHPStan targets, resolution states, and inferred receiver/result types while retaining AST-only SQL-table and template hints.EditContextPlan generation with contracts, callers, caller tests, callees, type definitions, blind spots, source hashes, and bounded source slices.build --format=toon.^2.2 is a runtime dependency while voku/simple-php-code-parser remains the independent structural cross-check.scope rejects stale maps rather than combining current source with outdated semantic ranges.related's likely_tests, same_namespace, and mentions sections now render as bare file paths (with an "N more symbol(s)" count when applicable) instead
related's likely_tests, same_namespace, and mentions sections now
render as bare file paths (with an "N more symbol(s)" count when
applicable) instead of a full per-file symbol/method dump. Those sections
are context around the query, not the answer to it, and dumping full
detail on top of primary (which keeps it) made a default related call
far larger than a focused query for the same term. primary's detail
level is unchanged.Initial agent-map CLI: builds a compact JSON symbol index of a PHP repository and answers related, file, and changed queries.
agent-map CLI: builds a compact JSON symbol index of a PHP
repository and answers related, file, and changed queries.MagoAstBackend::parseMany to terminate
in-flight mago child processes on interrupt.mago/token-scanner AST backends with a single extractor built
on voku/simple-php-code-parser (nikic/php-parser under the hood), removing
the separate parallel-process backend, token backend, and their scanner
hacks in favor of one in-process parse per file.voku/simple-php-code-parser to ^0.22, which adds native
endLine/traitUses to its model, replacing the token-scan pass this
project previously used to backfill closing-brace lines and trait use
names.query now combines literal and separator-normalized hits, ranks them, and
limits method-only hits to the matched method. related now derives likely
tests and namespace peers from several top source candidates instead of only
the first result.src/Backend/* (AstBackend, AstResult, MagoAstBackend,
ParallelAstBackend, TokenAstBackend) and
src/Extract/PhpTokenSymbolExtractor.php.Your coding agent can read these notes before it upgrades. Set up the MCP server →