acp-runtime
AgentThe ACP runtime is the domain service that serves the ACP API contract. It owns the host-scoped dependencies needed to run…
- `src/core/services/app-db/node/schema.ts` - `src/main/db/initialize.ts` - `drizzle/`
`src/main/db/initialize.ts`
completion markers only for imported projects' destination hosts so subsequent Host backfill registers the imported records without replaying unrelated hosts.
All dev and test infrastructure lives in `tooling/` inside `apps/emdash-desktop/`. Nothing in `tooling/` is part of the production Electron bundle — the `@tooling` alias only exists in `vitest.config.ts`, not in `electron.vite.config.ts`.
tooling/
├── fixtures/ committed SQLite snapshots (empty.db, baseline.db)
├── node-deps/ isolated better-sqlite3 compiled for system Node
├── seeds/ seed functions that populate fixtures
├── generate-fixtures.ts fixture generator script (run via vitest)
└── utils/
└── db.ts openFixture() helper for migration testsPoint `EMDASH_DB_FILE` at a scratch path instead of using the default database when working on migrations, so schema experiments cannot corrupt your real app data. `pnpm run db:reset` wipes the default dev databases.
EMDASH_DB_FILE=/tmp/emdash-scratch.db pnpm run dev # start app with isolated dev database pnpm run db:reset # wipe the dev databases and start fresh
Two committed SQLite snapshots live in `tooling/fixtures/`:
Regenerate after any schema change:
pnpm run db:fixtures # writes .db files — no rebuild needed
`db:fixtures` and `test:migrations` use an isolated copy of `better-sqlite3` installed under `tooling/node-deps/` (compiled for system Node). The app's `node_modules/better-sqlite3` stays Electron-compiled at all times.
1. **Isolate your dev DB**: run the app with `EMDASH_DB_FILE` pointing at a scratch path so you're not working against your personal emdash database
2. **Snapshot the pre-migration baseline**:
cp tooling/fixtures/baseline.db tooling/fixtures/pre-XXXX.db
Commit this snapshot. It is the starting state your migration test will run against.
3. **Write the migration**: edit `src/core/services/app-db/node/schema.ts`, then generate the SQL:
pnpm run db:generate
4. **Write a migration test** in `src/main/db/tests/migrations/` using `openFixture('pre-XXXX')`. See `example.test.ts` in that directory for the pattern.
5. **Regenerate fixtures** so `baseline.db` and `empty.db` include the new schema:
pnpm run db:fixtures
6. **Run migration tests**:
pnpm run test:migrations
7. **Commit everything together**: migration SQL (`drizzle/`), `drizzle/meta/`, `pre-XXXX.db`, updated `tooling/fixtures/*.db`, the migration test.
Some `text()` columns store structured JSON that may evolve across app versions. These columns use `versionedJsonColumn()` — a Drizzle `customType` that transparently handles version detection, upgrade chains, and serialization.
import { versionedJsonColumn } from '@core/services/app-db/node/versioned-column';
import { myConfig } from '@core/primitives/my-domain/api/my-config';
export const myTable = sqliteTable('my_table', {
col: versionedJsonColumn(myConfig)('col'),
// inferred type: MyConfig | null
});Drizzle's `fromDriver` runs the full upgrade chain on read. `toDriver` always serializes the latest version on write. No `JSON.parse` or `JSON.stringify` is needed at call sites.
Versioned schema definitions live in the owning `src/core/primitives/<domain>/api/` slice. See `agents/conventions/versioned-schemas.md` for the full guide including the `defineVersionedSchema()` builder API, upgrade function patterns, and testing guidance.
| Column | Schema file | |--------|-------------| | `workspaces.config` | `src/core/primitives/workspaces/api/workspace-config.ts` | | `conversations.config` | `src/core/primitives/conversations/api/conversation-config.ts` | | `tasks.task_config` | `src/core/primitives/tasks/api/task-config.ts` | | `tasks.linked_issue` | `src/core/primitives/linked-issues/api/linked-issue.ts` | | `automations.trigger_config` | `src/core/primitives/automations/api/config.ts` | | `automations.conversation_config` | `src/core/primitives/automations/api/config.ts` | | `automations.task_config` | `src/core/primitives/automations/api/config.ts` | | `ssh_connections.metadata` | `src/core/primitives/ssh/api/ssh-connection-metadata.ts` |
`versionedJsonColumn` only hooks into ORM-level reads and writes. Columns written via raw SQL in automation run snapshots bypass `fromDriver`/`toDriver`. Those columns remain `text()` — call `schema.parseJson(row.col)` explicitly on read and `JSON.stringify` on write.
Emdash is the Open-Source Agentic Development Environment (🧡 YC W26). Run multiple coding agents in parallel. Use any provider.
The ACP runtime is the domain service that serves the ACP API contract. It owns the host-scoped dependencies needed to run…
This page defines the target organization of `packages/core/src/`. Core is organized by module type so that shared domain APIs…
Git is split into a transport contract and a host-scoped runtime. Renderer, desktop, and workspace-server code share the Wire…
The main process is organized into domain modules under `src/main/core/`. Each domain typically has a `controller.ts` (RPC…
`@emdash/core/primitives/path/api` is the source of truth for portable file identity and lexical path operations. The detailed…
Validates project structure against co-location and architecture patterns defined in AGENTS.md
Deprecated placeholder. Do not use; follow root AGENTS.md and package instructions instead.
Use this agent when you need to create or update technical documentation that helps developers understand the deep patterns,…
Orchestration patterns learned from experience. Review at startup and before heartbeat responses.