Project structure
An agent-bundle project is an ordinary Node package with one extra file at the root and a
conventional src/ tree. Nothing here is mandatory: conventions fill the config in when it is
silent, and config always wins when both describe the same thing.
The layout
What each root means
Route and package entry conventions match .ts and .tsx files exactly; the state convention
is specifically src/state.ts. Discovered entries carry provenance.kind: 'conventional' in the
normalized model, so agent-bundle inspect tells you whether a file was picked up by convention
or claimed by config.
Config versus conventions
The config holds what no single file can own — project identity, target selection, and policy:
Add an explicit declaration only when you need something the convention cannot express — a different path, a target restriction, or an opt-out:
Source validation reports informational nudges — never errors — when a project shows a
pre-convention pattern: AB4730 for a self-connecting stdio entry that a default-exported
factory would upgrade to the framework lifecycle shell, and AB4731 / AB4732 / AB4733 when
src/cli.ts, src/index.ts, or src/mcp/<server-id>.ts exists but explicit configuration
shadows it. The bin: false and lib: false opt-outs stay silent.
Where output lands
agent-bundle build writes two independent things.
Host artifacts
One directory per selected target under the artifact root. The CLI defaults that root to
artifact/, so it never collides with the package build below; output.distPath or --output
moves it:
Per-host layouts are available as the claude, codex, cursor, and portable targets.
agent-bundle.manifest.json sits at the artifact root beside the target directories and records
every emitted file with its SHA-256, so artifact validation is content-addressed rather than a guess.
output.distPath moves the artifact root; it never changes the framework-owned layout inside
each target. Precedence is the CLI --output, then output.distPath, then the default —
artifact for agent-bundle build, which also emits the package build, and dist for the
programmatic build() without packageOutputs. Values must be non-empty, project-root-contained
relative POSIX paths.
The npm package build
When the project declares bin/lib — or provides them by convention — the same build also
writes the node-consumable package build under dist/:
dist is a mandatory-ignored directory: package outputs never enter project source snapshots or
Skill and asset discovery. The two outputs must not overlap: pointing output.distPath or
--output at dist on a project with package entries is AB4706. The default already keeps
them apart, and spelling it out is harmless:
Next steps
- Configuration model — the full config surface.
- Skills, Hooks, MCP servers and Apps — one page per surface.
- Scripts and assets and Package entries — the rest of the build output.