feat: add experimental tree command with agent index - #3005
Draft
kanoru3101 wants to merge 120 commits into
Draft
Conversation
Dynamic imports inside the test body made vitest transform the whole untransformed dependency subtree within the test, exceeding the 5000ms per-test budget when istanbul coverage is enabled. Static top-level imports move that cost to the file-load phase, which has no timeout.
Add the `treeview` language to the example code fences in tree.md (matching eject.md / translate.md house style) to satisfy markdownlint MD040. Stop tracking the internal agentic planning/spec docs under docs/superpowers/: they were accidentally committed into the published documentation and caused all vale and linkcheck failures plus most markdownlint errors. Nothing references them; they remain available locally but are no longer published.
The absolute-ref to node-id rule, the codepoint sort comparator, and the operation-method set each had duplicate copies across build-graph.ts and build-structure.ts. Move them to node-id.ts as the single source so the two graph builders cannot drift. Also fix build-graph's edge-refs sort to use the codepoint comparator (was the default .sort()), matching the determinism the module documents, and drop a redundant narrating comment in build-structure. No behavior change: 58 tree unit tests and 11 e2e snapshots pass unchanged.
…iants, duplicate e2e snapshot)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What/Why/How?
Adds the experimental
treecommand — one command that shows an API description's structure to humans and serves it as a navigable index to LLM agents.Humans get quick orientation and impact analysis in multi-file descriptions ("what breaks if I change this schema?"); agents get a way to work with descriptions too large for a context window, borrowing the retrieval loop from PageIndex: build a small hierarchical index, let the model reason over it, and fetch only what it needs — fully deterministic here, since an API description already carries its structure and summaries (no AI calls, no keys).
Everything is powered by one new
api-graphmodule in@redocly/openapi-core: a single walk of the ORIGINAL resolved files (lint pattern, no bundling) produces a dependency graph plus index metadata, and the CLI renders views over it:Selection is typed —
--tag,--path,--webhook,--operation(method or operationId),--component+--name,--file— so no id syntax has to be learned or explained; the up-front agent instruction measured 85 tokens.The default view is a bounded top-level tree (tags with counts, webhook names, component sections); every listing entry is card-shaped — the same structure as a single card (coordinates + typed
refs+usedBy), uniform for tooling.Every result carries a JSON pointer, the defining
file, andstart_line/end_line, so an agent can follow up with plain file reads; cards list one-hop typedrefs(outgoing) andusedBy(incoming).--with-depsreturns a self-contained slice (the selection plus everything it transitively references, in dependency order, 64 KB cap with an explicittruncatedmarker);--used-byreturns the transitively affected operations and components, each with the shortestviareference chain — a machine answer for "what breaks if I change this schema".Unresolvable
$refs render as ❌ nodes with stderr warnings; stdout stays clean JSON in machine formats;--formatisstylishorjsonfor every view.v1 scope: full OpenAPI 2.0–3.2; AsyncAPI/Arazzo render their
$refdependency tree (typed selectors are OpenAPI-only for now).Architecture note for review: the engine lives in core on purpose — the CLI is one of several planned surfaces; an MCP server and portal-side index generation would consume the same module directly.
Measured end to end on GitHub's own 10.0 MB REST API description (
github/rest-api-description, used unmodified), with a BPE tokenizer over real command output — task: "create a repository for the authenticated user":--operationslisting (card-shaped, the largest single view)--tag=repos→ card--with-depsThis is the case the hierarchy exists for: at 1.9M tokens the file is ten 200k windows — bounded drill-down is the only way an agent can touch it; the chain lands at ~13× less than the file (~14× on the split layout over 2,842 files), a deliberate trade: listing entries carry their one-hop
refs/usedByso every view shares one uniform card structure.Per-step numbers and real JSON output are in the benchmark guide.
Docs
Reference
treedraft (feat(cli): addtreecommand #2869)Testing
api-graphunit tests — graph building, selection lookups, views (overview/listings/cards), used-by reports withviachains, retrieval slices, deps closure, webhook classification, outside-cwd path normalization, callback exclusion, split-alias canonical ids.Screenshots (optional)
Check yourself
Security