Skip to main content

Development

See AGENTS.md for additional guidelines.

Setup

This monorepo uses Bun for development commands; avoid npm/yarn/pnpm except for npm registry publishing. Run package scripts from the monorepo root or package directory with Bun, for example:
Atomic keeps the caller’s current working directory when launched from development wrappers.

Forking / Rebranding

Configure via package.json:
Change name, configDir, and the bin field for your fork. The app-specific <appName>Config key is preferred; legacy piConfig remains a backwards-compatible shim. Atomic sets these to atomic, .atomic, and the atomic executable. Affects CLI banner, config paths, and environment variable names.

Path Resolution

Three execution modes: package-manager install, standalone binary, and source checkout. Always use src/config.ts for package assets:
Never use __dirname directly for package assets.

Debug Command

/debug (hidden) writes to ~/.atomic/agent/atomic-debug.log:
  • Rendered TUI lines with ANSI codes
  • Last messages sent to the LLM

Startup timing probes

Set ATOMIC_TIMING=1 when profiling startup. Normal interactive launches print the initial startup group before interactiveMode.run() starts the TUI loop, so marks reached later in the interactive lifecycle are not printed during ordinary sessions. Use ATOMIC_STARTUP_BENCHMARK=1 for first-frame/deferred-startup probes; it initializes interactive mode, explicitly completes deferred startup work, emits marks such as time-to-first-frame, startup-input-raw-mode-enabled, startup-input-first-raw-key, and deferred-extension-load when reached, then exits without submitting a prompt. During normal startup, built-in commands and lightweight bundled extension command metadata are available for autocomplete immediately, while heavy extension implementations load only when an extension command or another extension-aware action is invoked. Targeted tests/probes can also assert later interactive marks such as interactive-input-handler-ready and interactive-first-submit.

Testing

The file-length gate scans tracked .ts, .tsx, .js, .jsx, .mjs, .cjs, and .rs files via git ls-files, falls back to a recursive walk outside Git, and counts physical lines with a no-final-newline correction. Only generated/vendored path globs (node_modules, dist, target, binaries, .git, vendor, minified bundles, and the bundled third-party packages/workflows/skills/impeccable/** skill) plus first-five-line generated markers are excluded.

Deterministic installs

@bastani/atomic ships packages/coding-agent/npm-shrinkwrap.json so package-manager installs resolve the same dependency tree every time. Contributors working from a source checkout can validate that the checked-in shrinkwrap is up to date with:

Release security boundary

Atomic’s release bases remain at the 0.0.0 placeholder. scripts/cut-release.ts stamps the real version only on a detached tagged release commit. Tag creation runs an inert signal workflow; a separate workflow_run publisher loaded from protected main validates the exact upstream repository, source workflow/event/run, tag/SHA, immutable release-base trailers, and deterministic release tree. The privileged trigger checks out only protected workflow code: it treats the tag tree as data, exports it only after deterministic verification, and makes every read-only build verify the protected job’s source checksum instead of checking out tag-selected code. Same-run artifact transport failures receive at most one retry after partial-download cleanup and still fail explicitly on the second error; verified source archives are streamed to tar over stdin for portable Windows drive-letter handling. Preparation restores the digest-verified source after documentation validation before producing artifacts. Release-source jobs configure no dependency cache, npm publication has OIDC without repository write, and GitHub Release creation has repository write without OIDC. Never move or recreate a failed release tag or dispatch the privileged publisher. See the repository’s CI/CD pipeline for trusted-publisher configuration.

Project Structure