npm install # install deps
npm run build # tsc + copy dashboard public + git build-info
npm run typecheck # tsc --noEmit (fastest feedback)
npm test # fast deterministic suite (unit/component + deploy logic)
npm run test:watch # vitest (watch mode)
npm run test:integration # integration tests (needs abmind)
npm run test:e2e # critical end-to-end smoke/recovery tests
npm run test:extended # integration/process/E2E tests
npm run test:all # every Vitest test
npm run dev # node --import tsx src/main.ts
npm run bundle # esbuild single ESM bundle → bundle/Run npm run typecheck before committing. It catches strict-mode errors (noUnusedLocals, noUnusedParameters, noUncheckedIndexedAccess).
- Entry:
src/main.ts→src/bridge-app.ts→ boot phases (src/boot/phase-*.ts) - Boot phases run sequentially in a pipeline defined in
bridge-app.ts. Each phase sets exactly one field onBootCtx(src/boot/context.ts). - Platforms:
src/platforms/{telegram,discord,agent-api}/— adapters for chat input/output. - Transport:
src/components/transport/— bridges to agent CLI (tmux, ACP, or direct API). - Capabilities:
src/capabilities/{hotskills,sleep}/— self-contained feature modules. Browser work is an externalcloakCLI plus managed B-session routing. Registry auto-generated by esbuild plugin atsrc/capabilities/_registry.generated.ts. - Components:
src/components/— core subsystems (memory, tasks, pipeline, sessions, secrets, etc.).
All LLM calls go through spin.spin(spec) — the single async method in
src/components/spin.ts. Per-type behavior is driven by the SessionProfile
registry (src/components/spin-profiles.ts); adding a new SessionType means
adding a row, not a new method or branch.
- Use
spin({ type, ...spec, await: true })for new code. dispatch/dispatchAwait/sendUserToOrcare deprecated thin wrappers.dispatchBackground(opts)is the entry for non-user-facing one-shots (e.g. compaction summary, system maintenance).grep-invariant test(src/components/spin-invariant.test.ts) enforces: noruntime.complete(or caller-turn.sendPrompt(outside an allowlist. The allowlist is the chokepoint itself + transport machinery + the defensive fallback inopenai-compat-routes.ts.
abmind is a separate repo at ../abmind/ (sibling to abtars). It provides the memory system (MemoryManager).
vitest.config.tsaliasesabmind→../abmind/dist/src/index.jstsconfig.jsonpathsabmind→../abmind/dist/src/index.d.ts- You must build abmind first (
cd ../abmind && npm run build) before abmind-dependent tests pass. npm run check-importsenforces: no runtime imports fromabmind/*. Onlyimport typeandsrc/utils/abmind-lazy.tsare permitted.
- Unit tests live next to source files (
*.test.ts). - Integration tests live in
src/tests/integration/and use a harness (src/tests/integration/harness.ts) that creates a realMemoryManagerin a tmpdir. - Smoke/e2e tests in
src/tests/verify full bridge lifecycle with mock transport/adapter. - Tests use
vi.mock()for transport, adapter, and soul-loader. Real memory when possible.
The default npm test intentionally excludes tests under src/tests/integration/,
src/tests/e2e/, files named *integration.test.ts or *e2e.test.ts, and the
recovery redesign E2E test. Those tests are covered by npm run test:extended.
Deterministic deploy/rollback tests outside those groups remain part of the fast
suite. Use npm run test:all before a release when the complete local portfolio is
required.
dist/— tsc output (used bynpm start)bundle/— esbuild bundle (used by CLI bins:abtars,abtars-cli,abtars-restart). Generated bynpm run bundle.src/capabilities/_registry.generated.ts— auto-generated, do not edit manually..gitignoreexcludesdist/,bundle/,src/capabilities/_registry.generated.ts.
./boot/env.jsmust be the first import inmain.ts— dotenv must load before any transitiveprocess.envreads.process.umask(0o077)runs immediately after env load — all runtime files get 600 perms, dirs 700.bridge.lockis the single source of truth for running instances — never delete it.- Exit code 0 from
startBridge()means "restart requested"; non-zero means "die". - When
SUPERVISIONenv is set, the internal restart loop is disabled — OS supervisor handles restarts. esbuild.config.jsexternalizesbetter-sqlite3,abmind,pdf-parse,jimp,youtube-transcript,rettiwt-api— they must be available at runtime but are not bundled.
This repo is governed by abproject (../abproject/ — private repo github.com/aksika/abproject).
- Ways of working (planning tiers, approval gates, branching, deployment, commit discipline):
abproject/steering/ - Backlog:
abproject/backlog.db— SQLite, source of truth for all tickets - Specs:
abproject/specs/NNN/(Tier 3) andabproject/docs/plans/NNN-slug.md(legacy)
Read abproject/steering/000-start-here.md first when onboarding.