Archbird for JavaScript
Map codebases. Verify architecture. Plan and apply structural changes.
Archbird scans a repository and builds a deterministic map of its files, symbols, dependencies, public interfaces, tests, build routes, and components. Use it to understand unfamiliar code, give coding agents focused context, enforce reviewed architecture constraints in CI, compare ports or frontends, and check that coordinated changes produced the required structural result.
npm install --save-dev archbird
npx archbird map . # map the current repository
npx archbird serve # explore it in the local web application
Stages
| Stage | Question | Output |
|---|---|---|
| Map | What exists, and how is it connected? | Searchable files, symbols, dependencies, tests, and build routes |
| Query | Which exact evidence matters for this task? | Focused, ranked context with source witnesses |
| Path | How are two explicit architecture entities connected? | Bounded shortest witnesses with typed relations, evidence, and completeness |
| Verify | Does the code follow the architecture constraints? | Constraint status, violations, code locations, and unknowns |
| Plan | What structural change follows from current evidence, and what remains unknown? | An editable language-neutral Plan with objectives, operators, applicability, and acceptance constraints |
| Act | How does that Plan ground into exact repository changes, and does its after-state pass? | An accepted, sealed Act bound to exact transitions plus fresh Map and Verification evidence |
Map builds the canonical repository IR. Architecture is normally scattered across source languages, packages, public interfaces, native/frontend bridges, tests, build systems, and generated artifacts. Map joins those facts once so every later stage works from the same files, symbols, relationships, and source locations. Provider-specific lexical, syntax, host-AST, and SCIP facts are normalized into this language-neutral intermediate representation without discarding their provenance or uncertainty.
Query and Path evaluate projections over the Map IR. Query selects, traverses, and ranks the small neighborhood relevant to one task. Path answers a narrower question: whether two explicit entities are connected and which relationships form the connection. They share typed projection and graph indexes, but neither operation rewrites the Map or promotes an uncertain relationship into a confirmed one.
Verify checks architectural intent against the complete relevant model. Each constraint compiles into exhaustive projections over the Map IR plus a predicate such as required symbols, allowed dependencies, acyclicity, parity, or a numeric bound. Verify never uses a ranked or truncated Query result. Its Verification artifact records pass, failure, or unknown together with the exact operands and source locations responsible.
Plan describes a structural transition. Archbird can derive a Plan from the Map IR, current Verification findings, and a requested goal, but a developer or agent may also author or edit one directly. The language-neutral Plan records ordered objectives, applicable transformation operators, acceptance constraints, source identities, and explicitly manual work; it does not contain unreviewed guessed code.
Act grounds and checks the Plan. Act combines the reviewed Plan with exact source bytes and executor input, produces candidate file transitions, and evaluates their isolated after-state through a fresh Map and Verify run. A passing result can be sealed as an accepted Act without touching the worktree. Apply is the only mutating operation: it revalidates every source lock and replays that accepted Act.
The stages therefore form one traceable pipeline:
providers ───────────────→ Map IR ──→ projections ──→ Query / Path
│
└─────→ constraints ──→ Verification
│
Map IR + Verification + intent ──────────┴──→ Plan (derived or authored)
│
source + executor input ───────────────────────────┴──→ Act candidate
│
fresh Map + Verify
│
accepted Act → Apply
Every output retains its source and configuration links. Missing, conflicting, incomplete, and stale information remains visible instead of being guessed away.
Command-line workflow
The CLI follows the product stages directly. Run it from the repository root;
archbird.json is discovered automatically when present.
Map a repository
npx archbird map .
npx archbird map . --view architecture \
--group-by component --level file --relations imports,calls
npx archbird map . --view tests --group-by directory
npx archbird map . --view evidence --detail full
Map scans the configured or discovered scope and builds the reusable repository model. The default Markdown is an architecture-first overview. Canonical JSON is exhaustive; views, grouping, relation filters, and detail only change its presentation.
Query focused context
npx archbird query . --symbol 'src/runtime.c:runtime_start' \
--depth 1 --test-depth 1 --max-chars 12000 --check
npx archbird query . --search 'provider registry' \
--search-limit 8 --max-chars 12000 --check
npx archbird impact . --path src/runtime.c --depth 2 --check
npx archbird query . --symbol 'src/runtime.c:runtime_start' \
--view source --detail standard --max-chars 12000 --check
npx archbird query . --path src/runtime.c --dump --check
Query selects and ranks a task-sized neighborhood from the Map. Search supplies advisory lexical seeds when an exact identity is unknown; it is not semantic or natural-language search. Switch to a typed selector once the target is known.
--search KEYWORDS is deterministic lexical retrieval, not natural-language
or semantic search. Use concise repository vocabulary such as
provider registry; every candidate records the matched field and match type.
Prefer a typed selector such as --symbol or --path once the target is known.
query --view changes presents the same complete Query artifact as a coding
packet. It groups change seeds, affected code, strongest routes, ranked tests,
packages/builds/artifacts, uncertainty, and collapsed evidence without
inventing an edit or changing canonical JSON.
--git-diff REVISION converts Git’s tracked name/status output into a typed
change set. Current paths seed Query; deletions and paths outside the Map stay
explicit. External diff/text-conversion commands are disabled, and untracked
files require an explicit --path.
--verification-result PATH adds overlapping subject-side architecture constraints
and findings, including requirement IDs and freshness. It does not rerun
verification or infer relevance from prose, reference-only facts, or constraints
without exact source-path evidence.
The default is an architecture-first overview. Canonical JSON contains every selected file and mapped fact; Markdown is only a human projection:
npx archbird map --view overview --detail compact
npx archbird map --view architecture \
--group-by component --level file --relations imports,calls
npx archbird map --view tests --group-by directory
npx archbird map --view evidence --detail full
npx archbird query --symbol runtime_start --view source
npx archbird query --symbol runtime_start --dump
--view chooses an overview, architecture, tests, or evidence preset.
--group-by independently organizes entities by directory, configured
component, layer, or language; --level selects component, file, or symbol
nodes; and repeatable comma-separated --relations overrides the preset.
These semantic axes compile to one exhaustive graph ProjectionPlan shared with
the application. --detail changes presentation density only; --compact and
--full are aliases, and --max-chars is a final rendering guard. Compact and
standard Markdown rank structural groups, aggregated provider-to-consumer
dependency flows, and file landmarks while accounting for presentation
omissions. File landmarks use separate bounded production/API, test/fixture,
and build/artifact shortlists, followed by an unresolved-import frontier.
Classification consults the Map’s file-role evidence first and then
conservative repository-path conventions. Build outputs/tooling and
third-party/generated candidates take precedence over test candidates, while
participation metadata such as artifact-input does not by itself demote
production source. Visible relation, degree, and symbol counts are orientation
signals rather than correctness claims. Standard dependency rows show at most
eight relation kinds and disclose the omitted and total counts. Diagnostics
retain their exact canonical cause count; recognized Tree-sitter recovery and
missing node messages are additionally summarized by language and parser
action. Full detail enumerates the exhaustive selected records.
Graph completeness is distinct from repository coverage. Unsupported, ignored, or oversized inputs remain an explicit coverage frontier without falsely making a fully evaluated selected graph incomplete.
--view source materializes hash-checked source bytes for the Map or Query
selection. Compact detail is a declaration outline. Standard detail expands
exact symbol matches and complete directly selected paths while leaving
related files as outlines. Full detail returns every selected file; --dump
is an alias for --view source --detail full and cannot be combined with
--max-chars. Saved Maps do not contain source bytes, so use
--root CHECKOUT with a saved-Map source view. Archbird rejects changed bytes,
does not guess missing declaration extents, and does not embed non-UTF-8 or
terminal-control bytes in Markdown. Valid concrete-syntax boundaries outrank
semantic-AST boundaries for source rendering; alternate provider boundaries
remain recorded as merge variations.
Query context separately uses the exact, change, architecture, and
audit profiles plus per-kind quotas, route provenance/confidence, and
candidate/conservative policy. --progress auto updates one terminal line for
long interactive runs and stays silent when output is piped; use always or
never to override it.
direct, candidate, and conservative are static evidence strengths, not
claims that a test ran. Use project-runner observations for executed routes.
Find a connection with Path
npx archbird path 'src/cli.c' 'src/runtime.c' --root . \
--relation calls --direction downstream
path SOURCE TARGET searches the Map’s exhaustive typed graph for bounded
shortest witnesses. It preserves relation kind, direction, evidence state,
semantic resolution, provenance, and completeness. found requires a current,
source-evidenced route; candidate-only connectivity remains unknown and
fails --check.
Add --check when automation specifically requires a proven found result.
Repository-dependent examples omit it because an honest unknown is valid.
Verify architecture
Reviewed architecture policy belongs in the constraints collection of the
same archbird.json that defines project structure. Typed constraints infer
their exhaustive Map projections; primitive assertions can use inline literals,
observations, or named/inline projections. The project configuration described
below therefore needs no second suite file.
For a first check in an unfamiliar repository, configuration may contain only the reviewed constraint; discovery supplies the project model and layers:
npx archbird verify --config - --check <<'JSON'
{
"constraints": {
"NO-LARGE-SOURCE": {
"kind": "max_file_bytes",
"include": ["src/**"],
"max": 1048576,
"owner": "architecture",
"rationale": "Keep source files reviewable."
}
}
}
JSON
The same fragment can be saved unchanged as archbird.json. Explicit
project-model sections replace discovery; omitted sections inherit it.
# Run one saved Query plan or an ad-hoc query.
npx archbird query public-api-impact
npx archbird query --symbol demo_open --direction upstream
# Evaluate the whole reviewed policy or one named constraint.
npx archbird verify --check
npx archbird verify CORE-PUBLIC-API --check
# Preserve exhaustive repository-inventory operands when verifying a saved Map.
npx archbird verify --map .archbird/map.json \
--resolution .archbird/resolution.json --check
# Emit CI-native reports from the same constraints.
npx archbird verify --format sarif --output .archbird/architecture.sarif --check
npx archbird verify --format junit --output .archbird/architecture.junit.xml --check
# Freeze reviewed existing debt and coverage as a ratchet.
npx archbird verify --freeze .archbird/architecture.baseline.json \
--freeze-owner architecture \
--freeze-rationale "Reviewed starting point"
verify without IDs evaluates every configured constraint. Positional IDs
select an explicit subset and the Verification artifact records configured,
requested, evaluated, and omitted counts; a successful subset is never reported
as whole-policy compliance. Unknown IDs are errors. The CLI defaults to a
human-readable Markdown verdict; use --format json when saving the canonical
Verification artifact. Repository selection is
execution context: run in the project root or use --root PATH; an external
configuration uses --config CONFIG --root PROJECT. Query and Impact also
accept an unambiguous path-shaped positional root, such as
npx archbird query . --symbol demo_open.
npx archbird impact ../project --path src/api.c works similarly. A bare
positional token remains a saved query ID; use ./project rather than
project when selecting a relative repository path.
A saved Map contains mapped facts, not the complete discovery inventory.
Pass its matching config show artifact with --resolution when constraints
depend on ignored, unsupported, oversized, or forbidden repository paths.
Archbird validates the Map/resolution identities and rejects a mismatched pair.
Live verify derives both from one repository state automatically.
Common typed constraints cover required/forbidden paths and symbols, file-size bounds, symbol cardinality, component membership and cycles, allowed/forbidden/ required component or file edges, package entrypoints, bridges, test routes, and provider surfaces. They require no projection boilerplate. General predicates cover set/value equality, mapped equality, directional subsets, cardinality, numeric bounds, graph edges, acyclicity, minimum test routes, and observation equality.
provider_surface normally treats configured providers as one combined
declaration surface. Set require_all_providers: true when every capability
must appear in every configured provider. Verify then reports the exact
missing provider witnesses.
A projection result is exhaustive for its declared Map domain. If discovery, provider, resource, freshness, or source-lock evidence prevents a complete answer, the operand is partial or unknown and cannot make a constraint pass. Query may rank and bound context; Verify may not. Derived Map facts, asserted literals/mappings/waivers, and observed runner evidence retain distinct provenance.
Named projections are useful when several constraints or queries share a selection. One-off primitive operands stay inline:
{
"constraints": {
"API-SIZE": {
"assert": "cardinality",
"actual": {
"projection": {
"select": "symbols",
"paths": ["include/**"],
"public_only": true
}
},
"max": 30,
"owner": "core",
"rationale": "Keep the supported native surface reviewable."
}
}
}
Constraint-owned waivers require an ID, owner, rationale, an exact finding
fingerprint or comparison/key pair, and an expiry date or input-digest boundary.
Baselines classify new, known, reintroduced, and resolved findings while
ratcheting covered facts. Cross-repository constraints receive explicitly named
saved Maps with --map-input ID=PATH; behavioral parity receives reviewed
artifacts with --observation ID=PATH. Similar names alone never establish
semantic equivalence.
Every constraint has a stable ID, owner, rationale, optional requirement IDs, tags and severity. Findings cite exact evidence and separately record comparison, evidence state, applicability, disposition, baseline state, and a stable fingerprint. JSON, Markdown, SARIF, and JUnit are views of the same canonical Verification result.
Add observed test evidence
Run each case in isolation with V8 or Istanbul coverage, then convert the project-owned reports without rerunning the project:
npx archbird observe . --map .archbird/map.json \
--request .archbird/coverage-request.json \
--output .archbird/test-symbols.json
compileTestObservations(map, request, { repository, requestDirectory })
provides the same Node operation. Node also accepts isolated LLVM and gcov
JSON. Aggregate reports without exact per-test identity are rejected; use the
Python host for coverage.py dynamic contexts.
Plan, Act, and Apply
plan evaluates the complete current policy and produces one editable
language-neutral artifact. act grounds its operators through native language
executors, rebuilds the isolated after-state, and emits only an accepted Act
without writing. apply revalidates and replays that Act without reevaluating
the Plan or rerunning an executor.
An exact missing symbol or test route whose code is not derivable remains a
structured non-executable add_symbol or add_test_route operation. Plan can
order implementation before declaration and tests; Act still refuses the Plan
until a reviewed executor or agent supplies the unresolved semantics.
Supply reviewed full-file content for one exact add_symbol destination, or
for an add_test_route item with one exact mapped test file, with repeatable
act --submit ITEM=FILE. The symbol destination may already exist or may be
absent. This is Act executor input, not a Plan rewrite: native Act observes the
destination, emits an exact create or replace transition, records the executor
ledger, builds one isolated after-Map, and accepts only when fresh Verify
closes every item constraint and preserves the rest of the policy.
plan --format markdown renders the canonical Plan as a review packet.
Absent or ambiguous test locations remain manual.
An exact missing required_file_edge becomes a neutral add_dependency
objective over its source, target, relation, and optional name. Submit reviewed
source-file content with the same --submit interface; fresh Map and Verify
must observe the requested edge before Act is accepted. Its exhaustive
source-scoped file_edges delta permits only that one addition.
An exact current forbidden_file_edges violation between mapped files becomes
the symmetric neutral remove_dependency objective. Reviewed source bytes
must remove the relation from the fresh after-Map. Act rejects any unrelated
edge addition or removal even when Verify passes. Component edges, incomplete
evidence, and external or unmapped targets remain redirect/manual work.
npx archbird plan --format markdown
npx archbird plan --output .archbird/plan.json
npx archbird plan CORE-PUBLIC-API --output .archbird/plan.json
npx archbird plan CORE-PUBLIC-API --rename oldApi=newApi \
--output .archbird/plan.json
npx archbird plan FFI-SURFACE --git-diff HEAD \
--output .archbird/plan.json
npx archbird map --format json --output .archbird/before-map.json
# Or, after saving an explicit Map before a partial migration:
npx archbird plan FFI-SURFACE --before-map .archbird/before-map.json \
--output .archbird/plan.json
npx archbird act .archbird/plan.json
npx archbird act .archbird/plan.json \
--submit IMPLEMENT_ITEM=reviewed-module.js \
--submit TEST_ITEM=reviewed-test.js
npx archbird act .archbird/plan.json --format patch
npx archbird act .archbird/plan.json --format json \
--output .archbird/act.json
npx archbird apply .archbird/act.json
The neutral redirect_dependency operator stores an exhaustive edge
ProjectionPlan, the relation and symbol identities, and affected source paths.
It stores no source ranges or replacement text. Act reevaluates the projection
once and dispatches its typed evidence by mapped source language. The native C
executor resolves exact declaration, definition, include, and call evidence.
The native Python executor requires one exact imported binding, exact
CPython-AST call evidence, and an already observed import-module spelling for
the replacement; it preserves explicit local aliases. The native ECMAScript
executor supports JavaScript, TypeScript, and TSX named imports when
Tree-sitter proves each binding and this frontend’s TypeScript provider proves
every redirected call. It uses a replacement module spelling already observed
from the same source directory and preserves explicit aliases, including
self-aliases. Incomplete evidence, ambiguous definitions, missing observed
include/import routes, multi-name imports, non-call references, and non-unique
calls block execution.
Older exact replace_range, delete_file, move_file,
edit_json_pointer, and source-bound file deletion operations remain
available for bounded developer- or agent-authored edits. They are not the
model for derived Plan operators. An exact required_paths issue becomes a
path-only, input-required create_file objective; pass reviewed bytes through
act --submit ITEM=FILE, not through Plan. add_dependency and
remove_dependency follow the same input-required boundary for one exact
existing source file. An asserted
edit_json_pointer operation changes one reviewed
manifest/export-table value under an exact source hash, RFC 6901 pointer, and
expected old JSON value without reformatting the complete file. A derived
one-extra/one-missing rename candidate is review evidence, not intent; it
remains non-executable until --rename OLD=NEW is supplied. The reviewed Plan
stores only the language-independent symbol objective, exhaustive
symbol_occurrences ProjectionPlan identity, and repository-relative source
scope. Act reevaluates the same complete evidence. Tree-sitter establishes
ECMAScript declarations and import/export bindings; the TypeScript compiler
must establish reference targets while preserving aliased local names.
Qualified identities may rename only their terminal identifier while
preserving the same enclosing identity. Unrelated same-name declarations
outside the selected projection scope are not renamed. Public alias and
CommonJS assignment targets are separate reviewed surface identities, not
internal declaration occurrences. Candidate or unresolved calls, duplicate
targets, and unsupported inputs block Act instead of producing a partial
rename.
For a provider_surface issue, Plan can add a uniquely missing Make
registration, C header declaration, or bounded C/N-API export registration,
or use a reviewed rename to replace one stale Make registration with a
uniquely resolved surface member. Plan emits a neutral provider objective and
configured provider identity. Act validates the current configuration and Map.
Act/Make derives the source spelling and requires one direct token match.
Act/C requires one effective mapped C file, one mapped
napi_<capability> wrapper, syntax-clean source, and a mapped
DECLARE_NAPI_METHOD or descriptor peer. Multi-file, ambiguous, duplicate,
unresolved, or structurally unsupported provider cases remain manual or block
Act.
If the replacement capability is already registered, Plan emits removal of
the stale old capability rather than a duplicate registration.
Supplying --before-map allows the native compiler to finish one exact
observed provider-surface rename without a separate --rename. The old member
must have resolved uniquely before; exactly one new current member must retain
the same implementation paths and use ledger; and both declaration and
implementation signatures must differ only at the identifier. Both Maps must
share project, configuration, and producer identities. Incompatible,
diagnostic-bearing, signature-poor, or ambiguous histories remain
non-executable.
--git-diff REVISION builds the before Map from one Git commit through an
isolated raw-object snapshot and the ordinary discovery/provider pipeline. It
uses the current project configuration, does not run checkout filters or
mutate the source worktree, removes the temporary snapshot after mapping, and
reuses content-addressed provider facts. Revision ranges, saved-current-Map
mode, and simultaneous --before-map are rejected.
A required_symbols constraint naming one exact C header can derive
the language-neutral declare_symbol objective from one unique implementation
that establishes a bounded same-language evidence scope. Plan stores only the
symbol, destination, and exact source paths the executor may read. Act/C then
requires a declaration/definition peer, rederives the exact single-line
implementation source and placement, and rejects source-closure drift, globs,
ambiguous or internal implementations, and unproven header decoration. The
declaration and a derived Make registration can be accepted and applied
together.
If the constraint itself requires an implemented and used surface member that
is not registered, Plan can derive add_provider_capability without an extra
flag for each supported exact provider. Act/Make derives the direct or
leading-underscore convention from current source. Act/C can clone one mapped
C-header or N-API peer. Each executor selects one unique editable anchor by
canonical-name locality. The item is derived; incomplete, ambiguous,
duplicate, multi-file, or anchorless evidence stays manual or blocks Act.
Several missing members in the same Make provider remain separate Plan obligations but materialize as one source-locked file transition. Only distinct insertions sharing the same variable, anchor, and side compose; tokens are ordered canonically. Byte-identical edits from separate Plan obligations compose once and retain every item ID; incompatible overlaps remain conflicts.
Plan can also derive removal of one unresolved, unused Make registration when the Map proves zero candidates, zero uses, one exact declaration, and another uniquely resolved declaration from the same provider. It will not empty a configured provider, treat two stale entries as proof for each other, or turn a mixed replacement into an inferred deletion.
The Plan operations are add_provider_capability,
remove_provider_capability, and rename_provider_capability; they contain
no Make token, anchor, byte range, replacement text, or source hash. The
native Act/Make and Act/C executors own those details and preserve assignments,
comments, continuations, whitespace, line endings, and unrelated source.
--format patch renders the accepted Act as a unified diff; it does not
create another artifact.
An exact missing npm package entrypoint becomes a neutral
set_package_entrypoint Plan operation when one package and a literal
package-relative target are proven. Native Act grounds direct main,
exports, and existing-object bin routes through the lossless JSON editor.
The target must be an existing regular file but need not be mapped, so
extensionless npm executables work. Its exact state is sealed as a read-only
Act source lock. Conditional or nested exports, ambiguous packages, and
missing targets remain manual.
Existing transition sources and every read-only executor input use SHA-256
locks; ranges use UTF-8 byte offsets and include expected text. Manual items
expose missing transformation inputs and block Act instead of inventing code.
Act evaluates the complete prepared file set
through Project.withSourceOverlay(), deriving a fresh Map and every
source-policy constraint before the first write. Incomplete relation evidence
blocks destructive generation. Failed, unknown, or unsatisfied fresh
acceptance writes nothing; only a satisfied after-state emits an accepted
Act. Apply then advances through source-lock revalidation and transactional
replay. Plan input is bounded to
64 MiB, collections and touched files to 4,096, individual source files and
patches to 64 MiB, and aggregate touched source and patch output to 256 MiB.
Project compilers and tests remain external; their reviewed observations can
participate in Verify.
Explore the live repository
Run the local application while source changes:
npx archbird serve
serve prints a loopback URL immediately, analyzes in a worker, publishes only
valid generations, and retains the last good Map when a later candidate fails.
Live Map, projection, Query, Verify, and source work runs in the native Node
host; the page receives typed ProjectionResults and does not load browser Wasm.
Normal exploration does not download the canonical Map; saving it is explicit.
Reuse saved evidence safely
Save complete evidence when subsequent operations must use the exact same repository state:
mkdir -p .archbird
npx archbird map . --format json --pretty \
--output .archbird/map.json --check
npx archbird config show . --pretty \
--output .archbird/resolution.json --check
npx archbird query --map .archbird/map.json \
--symbol 'src/runtime.c:runtime_start' --depth 1 --max-chars 12000
npx archbird query --map .archbird/map.json \
--search 'provider registry' --search-limit 8
npx archbird impact --map .archbird/map.json \
--path src/runtime.c --depth 2
npx archbird path 'src/cli.c' 'src/runtime.c' \
--map .archbird/map.json --relation calls --direction downstream
npx archbird query --map .archbird/map.json \
--symbol 'src/runtime.c:runtime_start' \
--view changes --detail compact --check
npx archbird query --git-diff HEAD \
--view changes --detail compact --check
npx archbird query --git-diff HEAD --view changes \
--verification-result .archbird/verify.json --check
Archbird excludes .archbird/** by default, so saving generated artifacts
there does not change repository discovery or freshness. Use
--no-default-excludes only when that tool-output tree is intentionally part
of the analyzed scope.
Unchecked saved-Map queries accept supported older producers. Add --check
when the result will drive a decision; the shared core then requires the saved
producer digest to match the active core. Run freshness before treating the
saved source/config evidence as current:
npx archbird freshness --root . --snapshot .archbird/map.json --check
JavaScript APIs
Node
const {
Project,
auditMapFreshness,
compilePlan,
renderPlanMarkdown,
} = require("archbird");
const project = Project.fromRepository(".");
try {
const mapJson = project.mapJson({ pretty: true });
console.log(project.mapMarkdown({ maxChars: 12000 }).toString("utf8"));
console.log(project.queryMarkdown({
symbols: ["src/runtime.c:runtime_start"],
depth: 1,
context: { profile: "change" },
}).toString("utf8"));
const selectionJson = project.queryJson({
symbols: ["src/runtime.c:runtime_start"],
depth: 0,
});
console.log(project.sourceMarkdown({
artifactJson: selectionJson,
}).toString("utf8"));
console.log(auditMapFreshness(mapJson, project.mapJson()).toString("utf8"));
if (project.verificationConfigured) {
const verificationJson = project.verifyJson();
const planJson = compilePlan(
project,
project.mapJson(),
verificationJson,
);
console.log(renderPlanMarkdown(planJson).toString("utf8"));
}
} finally {
project.dispose();
}
Project.fromRepository() applies discovery, project configuration, and
explicit options. Project.fromConfig() requires one reviewed configuration.
Canonical JSON methods return stable artifact bytes; Markdown and graph outputs
are presentation views.
compilePlan() delegates Plan derivation to the native core. Its optional
beforeMapJson input enables identity-checked residual planning; Node performs
no Map comparison or action inference.
renderPlanMarkdown() presents the same validated Plan as a concise task
packet; it does not create or modify an artifact.
materializeAct() produces exact binary-safe transitions from a Plan. Its
optional executorSubmissionsJson option supplies reviewed full-file content
for exact unresolved symbol, test-route, required-path, or dependency items;
the corresponding planSourceRequirements() option asks the host for the
exact state required by each objective. Native Act then chooses create or
replace where the objective permits either. Submissions are ephemeral executor
input and never mutate Plan.
acceptAct() seals them only after callers supply the fresh isolated
after-Map and Verification. preflightActApply() returns ready or
already_satisfied after comparing newly observed sources with the complete
sealed before/after states; partial application and unrelated drift fail. The
explicit filesystem helpers observePlanSources(),
actOverlay(), runActGates(), renderAct(), and applyAcceptedAct()
provide that host transport. Reviewed gates from archbird.json execute as
direct argument arrays over the copied after-state; the native core rejects
incomplete or non-passing result ledgers before acceptance. All Plan
interpretation, edit materialization, gate-result validation, and acceptance
remain in the native core.
| Area | Public names |
| — | — |
| Repository model | Project, Source, Workspace |
| Map, Query, and Path | analyzeWorkspace, auditMapFreshness, diffMaps, exportGraph, pathMap, pathMapMarkdown, queryMap, queryMapMarkdown, renderMapMarkdown, renderPathMarkdown, renderSourceMarkdown, resolveDiscovery |
| Projection and policy | compileProjectConfiguration, compileQueryPlan, evaluateConstraints, evaluateProjection, freezeConstraints, reportConstraints |
| Plan and Act | acceptAct, actOverlay, actSourceRequirements, applyAcceptedAct, compilePlan, materializeAct, observeActSources, observePlanSources, planSourceRequirements, preflightActApply, renderAct, renderPlanMarkdown, runActGates, validateAct, validatePlan |
| Observations and OKF | analyzeOkfSource, compileTestObservations, publishOkfBundle |
| Runtime and planning | defaultProviderCacheDir, defaultProviderCacheMaxBytes, discoveryPlan, jsonCanonicalize |
| Runtime metadata | ENGINE, IMPLEMENTATION_SHA256, NATIVE_ABI_VERSION, PATTERN_CONTRACT, PATTERN_CONTRACT_VERSION, PATTERN_ENGINE, PATTERN_OPTIONS, PATTERN_UNICODE, PROVIDER_SUPPORT, VERSION |
The inventory above is checked against Object.keys(require("archbird")).
Node and Python expose parallel stage operations while retaining host-specific
runtime, cache, schema, OKF, and observation helpers.
Browser and package entrypoints
const { createBrowserArchbird } = require("archbird/browser");
const archbird = await createBrowserArchbird();
const project = archbird.Project.fromFiles([
new archbird.Source(
"src/index.ts",
new TextEncoder().encode("export function answer() { return 42; }\n"),
),
]);
try {
console.log(project.map());
const selectionJson = project.queryJson({ symbols: ["answer"], depth: 0 });
console.log(JSON.parse(selectionJson.toString("utf8")));
console.log(project.sourceMarkdown({
artifactJson: selectionJson,
}).toString("utf8"));
} finally {
project.dispose();
}
Browser input is supplied bytes; it has no filesystem discovery. The resolved facade is:
Project, Source, auditMapFreshness, ENGINE, NATIVE_ABI_VERSION,
PATTERN_CONTRACT, PATTERN_CONTRACT_VERSION, VERSION, and core.
The core property is the advanced raw Wasm facade.
Package entrypoints are archbird, archbird/browser, archbird/schema/*,
archbird/serve, archbird/wasm, archbird/wasm-sync, and
archbird/worker.
The direct browser API runs in the caller; the worker entrypoint and application isolate analysis in a Web Worker.
Agent workflow
Copy this compact policy into a project’s AGENTS.md, CLAUDE.md, or
equivalent agent instructions:
Use Archbird before broad source exploration.
- Start with `npx archbird map . --view overview --detail standard --max-chars
12000 --check`.
- When an exact identity is known, use `npx archbird query . --symbol
'PATH:SYMBOL' --depth 1 --test-depth 1 --max-chars 12000 --check`.
- When the identity is unknown, use `npx archbird query . --search 'CONCISE
REPOSITORY TERMS' --max-chars 12000 --check`. Search is lexical and advisory.
- Read an exact declaration with `npx archbird query . --symbol 'PATH:SYMBOL'
--view source --detail standard --max-chars 12000 --check`. Read one complete
file with `npx archbird query . --path PATH --dump --check`; do not combine
`--dump` with `--max-chars`.
- Use `npx archbird path SOURCE TARGET --check` for explicit connection
questions. Candidate-only or incomplete connectivity remains `unknown`.
- Run `npx archbird verify --root . --check` before and after
architecture-sensitive work. Treat static test routes as navigation, not
proof of execution.
- Check `npx archbird freshness --root . --snapshot .archbird/map.json
--check` before reusing a saved Map.
- Review generated Plans and accepted Acts. Never run `npx archbird apply`
unless repository mutation is explicitly authorized and the exact Act was
reviewed.
- If Archbird disagrees with source, inspect source directly and report a
general reproducer; never hide uncertainty or manufacture observed evidence.
Configuration
Archbird works without config. Add archbird.json when names and boundaries
are reviewed project intent. CLI arguments override project config, which
overrides versioned discovery defaults.
npx archbird config show . --pretty
npx archbird config init . --output archbird.json
config init is a review candidate, not architecture truth.
For monorepos, discovery follows explicit npm/Yarn workspaces and uv
[tool.uv.workspace] member patterns (including uv exclusions). It also probes
a direct-child Python pyproject.toml only when inventoried Python source exists
below that directory. The native resolver requests exact regular manifest files;
each request is limited to 256 KiB, with at most 128 npm and 32 Python
candidates. config show exposes the request ledger, limits, provenance, and
overlap/truncation/conflict diagnostics. Authored project, layers, and
packages fields still take precedence over every inferred candidate.
At the repository root, the same bounded request protocol reads at most one
setup.cfg and one CMakeLists.txt. Literal setuptools metadata can contribute
a source-backed Python package/import root; one literal lexical-root CMake
project() call can contribute project identity. Archbird does not evaluate
setuptools directives, interpolation, CMake variables, includes, macros, or
conditional/function bodies. It distinguishes modules, regular packages, and
namespace-package discovery, rejects unsupported include/exclude ambiguity,
and rejects a CMake identity if project is redefined or unreachable after a
root return(). Rejected identity is omitted from the project model and
recorded as a warning: discovery-manifest-invalid for malformed or ambiguous
input, and discovery-manifest-identity-unsupported for valid CMake or
setup.cfg that this reader cannot resolve statically. npm/PEP 621/setup.cfg/R/
Autoconf identity keeps priority over the CMake fallback; CLI and authored
project identity remain authoritative over all of them.
{
"project": "demo",
"layers": [
{
"name": "core",
"role": "core",
"language": "c",
"globs": ["include/**/*.h", "src/**/*.c"],
"public_headers": ["include/demo.h"]
},
{
"name": "javascript",
"role": "frontend",
"language": "typescript",
"globs": ["js/src/**/*.ts"]
}
],
"components": [
{"name": "native-core", "paths": ["include/**", "src/**"]},
{"name": "javascript-api", "paths": ["js/src/**"]}
]
}
That first file changes only Map construction. Add a reusable projection, a named Query, and a constraint when the project is ready to persist reviewed architecture policy:
{
"projections": {
"public-core-api": {
"select": "symbols",
"paths": ["include/demo.h"],
"public_only": true
}
},
"queries": {
"public-api-impact": {
"projection": "public-core-api",
"direction": "upstream",
"depth": 1
}
},
"constraints": {
"CORE-PUBLIC-API": {
"assert": "required_subset",
"expected": {"literal": ["demo_close", "demo_open"]},
"actual": {"projection": "public-core-api"},
"severity": "error",
"owner": "core",
"rationale": "Supported native entrypoints must remain public."
}
}
}
These are top-level members of the same archbird.json. The complete field
inventory is:
| Section | Purpose |
| — | — |
| project, description | optional stable project identity and human context |
| exclude, discovery | project-level selection and explicit discovery policy |
| layers, components | selected source/provider groups and reviewed architecture groupings |
| packages, builds, artifacts | manifests, public entrypoints, compilation-database/Autoconf/Make/npm routes, logical outputs and loaders |
| bridges | declared/used/implemented ABI, binding, or message surfaces |
| tests | static cases, reviewed case routes, and generated-source relations |
| named_entries, parity | configured entrypoint protocols and reviewed surface relationships |
| indexes | one or more SCIP indexes with prefixes, position encoding, and build variants |
| projections, queries, constraints | reusable derivations, saved Query plans, and reviewed architecture policy |
| gates | reviewed build or test commands that must pass in Act’s isolated after-state |
| limits | bounded Map analysis policy |
Selectors are segment-aware: src/*.c matches immediate children and
src/**/*.c is recursive. Components group selected files; they do not discover
new files. route_to is broad asserted intent; case_routes is case-specific.
Patterns use the pinned archbird-pcre2-v1 contract rather than JavaScript
RegExp.
Root compile_commands.json and index.scip files are consumed automatically
in zero-config mode. Multiple compiler outputs can be named and kept separate:
{
"builds": [
{"name": "wasm-db", "kind": "compile_commands", "path": "build/wasm/compile_commands.json", "variant": "wasm"}
],
"indexes": [
{"name": "wasm-scip", "format": "scip", "path": "build/wasm/index.scip", "variant": "wasm"}
]
}
Archbird consumes compiler outputs but never invokes a compiler or indexer. Build routes expose repository source paths, compiler basenames, and command digests without leaking absolute build-machine paths. SCIP facts retain their variant, producer, source anchoring, coverage, and freshness.
Map uses repository-local C/C++ include search paths from compilation databases in compiler order. Each translation unit’s context follows its literal includes through reached headers, and variants must agree on one selected target. Resolved edges cite only the repository-relative database path; external roots and absolute machine paths remain private.
The embedded config is mirrored by examples/minimal.archbird.json; the
complete multi-language form is examples/quickstart.archbird.json in the
source distribution.
The npm package exports the versioned JSON schemas for offline editors and
agents. For example,
require.resolve("archbird/schema/archbird.schema.json") locates the exact
project-configuration schema shipped with the installed engine. The native
configuration compiler remains authoritative for relational invariants that
standard JSON Schema cannot express.
Runtime and language evidence
The npm package has no install or postinstall compiler hook. It uses a matching
Linux x64 glibc Node-API prebuild when available and otherwise the bundled Wasm
core. Its content-hashed C snapshot stays compressed during normal installation;
npm run build:native verifies and expands it only for an explicit offline
source build. Select or inspect the engine with:
ARCHBIRD_ENGINE=native npx archbird support --pretty
ARCHBIRD_ENGINE=wasm npx archbird map . --check
| Language | npm/Node provider | Browser provider |
|---|---|---|
| JavaScript/TypeScript/TSX | TypeScript compiler + Tree-sitter + lexical | TypeScript compiler + Tree-sitter + lexical |
| C/C++ | Tree-sitter + lexical | Tree-sitter + lexical |
| Python | Tree-sitter + lexical | Tree-sitter + lexical |
| R | Tree-sitter + lexical | Tree-sitter + lexical |
For CPython-AST evidence, use the PyPI host. Tree-sitter recovery is fact-local; SCIP retains producer, document coverage, source anchoring, and freshness. Provider conflicts, ambiguity, and unresolved targets remain explicit.
Node’s per-file provider facts and materialized complete unchanged Maps are
content-addressed and revalidated against the native/Wasm core, configuration,
selected source bytes, and provider implementations. Both tiers share a 1 GiB
budget and evict the oldest entries;
--cache-max-bytes or ARCHBIRD_CACHE_MAX_BYTES changes it, --cache-dir
selects the root, and --no-cache disables it. Active and unverifiable cache
temporaries are preserved; abandoned same-execution-domain writes are removed
on the next use. Ownership includes the boot and PID-namespace domain where
available. A full cache warns without changing canonical output.
Visualization, interchange, and commands
npx archbird export json --map .archbird/map.json --view components \
--output .archbird/components.json
npx archbird export graphml --map .archbird/map.json \
--output .archbird/architecture.graphml
npx archbird export mermaid --map .archbird/map.json \
--output .archbird/architecture.mmd
Canonical Archbird JSON is authoritative. Graph-view JSON drives the app; GraphML and Mermaid are deterministic projections. Node exposes normalized OKF publication primitives, but the filesystem OKF CLI is Python-only. SCIP is an input evidence provider. Verification results can render SARIF or JUnit. Plan and Act remain canonical JSON artifacts; Plan additionally has a native Markdown task-packet view.
The CLI command names are map, config, query, impact, path, diff,
observe, freshness, workspace, verify, plan, act, apply, export,
serve, and support.
config provides show|init; export provides
json|graphml|mermaid. Use
npx archbird COMMAND --help for flags. Exit status is 0 for success, 1 when
requested --check blocks, and 2 for invalid input or configuration.
Guarantees and limits
- Identical selected source, config, provider implementations, and supplied evidence produce byte-identical canonical output under the same Archbird implementation.
- Source providers do not import or execute analyzed packages; Verify evaluates typed predicates rather than asking a model to judge architectural truth.
- Static routes are navigation evidence, not runtime execution or coverage.
- Lexical/syntax evidence is not whole-program semantic resolution.
- Dynamic dispatch/reflection, C preprocessing, complete Make evaluation, ABI layout, and arbitrary generated code need stronger supplied evidence or remain unknown.
- Archbird is pre-1 software; schemas and ABI can evolve under semantic versioning without a 1.x compatibility promise.
Requires Node 18+. Archbird is Apache-2.0 licensed. Content-hashed JSON schemas ship in the npm package; the C/Python hosts are included in the source repository. This README is the complete npm/Node/browser usage contract.