You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+76-10Lines changed: 76 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,7 +29,7 @@ This file is the single source of truth for agents entering this repository. Rea
29
29
## Inactive or placeholder directories
30
30
31
31
-`apps/nextjs` and `packages/shared` have been removed; do not recreate or reference them.
32
-
-`.od/`, `.tmp/`, Playwright reports, and agent scratch directories are local runtime data and must stay out of git.
32
+
-Local runtime data, `.tmp/`, Playwright reports, and agent scratch directories must stay out of git. For daemon-managed data paths, read and follow **Daemon data directory contract** below; do not restate or improvise path conventions elsewhere.
33
33
34
34
# Development workflow
35
35
@@ -55,6 +55,81 @@ This file is the single source of truth for agents entering this repository. Rea
55
55
- Ports are governed by `tools-dev` flags: `--daemon-port` and `--web-port`.
56
56
-`tools-dev` exports `OD_PORT` for the web proxy target and `OD_WEB_PORT` for the web listener; do not use `NEXT_PORT`.
57
57
58
+
## Daemon data directory contract
59
+
60
+
This section is the only repository-wide source of truth for daemon-managed
61
+
data paths. Every README, guide, deployment note, and operational handoff that
62
+
mentions daemon data paths must point here instead of restating the rules.
63
+
64
+
This boundary is strict. Do not introduce concrete filesystem examples for the
65
+
daemon data directory, recommended data directory, shared data directory,
66
+
deployment mount, or example data directory. If existing code exposes a legacy
67
+
fallback, treat it as implementation detail or a known escape candidate, not as
68
+
a documentation pattern to copy. If a change needs a data-path rule that is not
69
+
covered here, request a core-maintainer decision in the PR instead of inventing
70
+
a new convention.
71
+
72
+
The daemon has one active data-root truth source:
73
+
74
+
- On daemon startup, `apps/daemon/src/server.ts` resolves `OD_DATA_DIR` into
75
+
`RUNTIME_DATA_DIR`.
76
+
- All daemon-owned data paths must derive from `RUNTIME_DATA_DIR` or from a
77
+
constant derived from it, such as `PROJECTS_DIR` or `ARTIFACTS_DIR`.
78
+
-`PROJECTS_DIR` is the managed-project root. Imported-folder projects are the
79
+
explicit exception: they use `metadata.baseDir` for the user-selected
-`tools-dev --namespace <name>` does not, by itself, define daemon data
93
+
isolation.
94
+
- A development run that needs an isolated daemon data root must pass
95
+
`OD_DATA_DIR` into the daemon process environment. After that, the daemon
96
+
resolves it once and all daemon data paths flow from `RUNTIME_DATA_DIR`.
97
+
98
+
Packaged propagation:
99
+
100
+
-`tools-pack` / `apps/packaged` own packaged channel and namespace layout.
101
+
- Packaged code resolves the final namespace-scoped daemon data root before
102
+
spawning the daemon.
103
+
- The packaged daemon receives that final data root as `OD_DATA_DIR`; daemon
104
+
code must not infer packaged data paths from app names, Electron `userData`,
105
+
ports, channel names, or namespace names.
106
+
107
+
Sanctioned exceptions:
108
+
109
+
-`OD_MEDIA_CONFIG_DIR` is a narrow override for `media-config.json` only. It
110
+
is not a second daemon data root.
111
+
-`OD_LEGACY_DATA_DIR` is a migration source for legacy data import only. It is
112
+
not an active daemon data root.
113
+
- External tool homes such as `CODEX_HOME` are integration inputs, not daemon
114
+
data roots. The daemon must not describe them as Open Design runtime data.
115
+
- Agent/project-cwd skill staging aliases are not daemon data roots.
116
+
- Manifest metadata keys and CSS identifiers are semantic namespaces, not
117
+
filesystem path conventions.
118
+
119
+
Known escape candidates that must not be reused:
120
+
121
+
- Module-level defaults that point at a cwd-relative legacy data directory.
122
+
- Helper defaults such as `defaultRegistryRoots()` that recompute a data root
123
+
from `process.env.OD_DATA_DIR` or a cwd fallback instead of receiving
124
+
`RUNTIME_DATA_DIR`.
125
+
-`openDatabase(projectRoot)` calls that rely on its fallback instead of
126
+
passing the resolved data root.
127
+
- Script help text or examples that suggest concrete legacy data directories.
128
+
129
+
Do not extend these escape patterns. When a fix is obvious, route the path
130
+
through `RUNTIME_DATA_DIR` or an explicit data-root argument. When it is not
131
+
obvious, block the PR and request core-maintainer guidance.
132
+
58
133
## Root command boundary
59
134
60
135
- Keep root scripts reserved for true repo-level checks and tools control-plane entrypoints: `pnpm guard`, `pnpm typecheck`, `pnpm tools-dev`, `pnpm tools-pack`, and `pnpm tools-serve`.
@@ -266,15 +341,6 @@ Desktop queries runtime status through sidecar IPC. The web URL comes from `tool
266
341
267
342
`@open-design/sidecar-proto` owns Open Design app/mode/source constants, namespace validation, stamp fields/flags, IPC message schema, status shapes, and error semantics. `@open-design/sidecar` provides only generic bootstrap, IPC transport, path/runtime resolution, launch env, and JSON runtime files. `@open-design/platform` provides only generic OS process stamp serialization, command parsing, and process matching/search primitives, consuming the proto descriptor.
268
343
269
-
## Where is data written?
270
-
271
-
The daemon writes `.od/` by default: SQLite at `.od/app.sqlite`, agent CWDs under `.od/projects/<id>/`, saved renders under `.od/artifacts/`, and credentials at `.od/media-config.json`. Two env vars override the storage root, in order:
272
-
273
-
1.`OD_DATA_DIR=<dir>` β relocates *all* daemon runtime data to `<dir>` (used by Playwright for test isolation, and by the packaged daemon and the Home Manager / NixOS modules to point the daemon at a writable directory when the install root is read-only). The path is resolved with `~/` expansion and relative paths anchored to `<projectRoot>`.
274
-
2.`OD_MEDIA_CONFIG_DIR=<dir>` β narrower override that relocates *only*`media-config.json`. Same resolution semantics. Most installs do not need this; it exists for setups that want to keep API credentials in a different location from the rest of the runtime data.
275
-
276
-
Default precedence is OD_MEDIA_CONFIG_DIR > OD_DATA_DIR > `<projectRoot>/.od`.
277
-
278
344
## When is `pnpm install` required?
279
345
280
346
Run `pnpm install` after changing package manifests, workspace layout, command entrypoints, bin/link-related content, or after adding/removing workspace packages.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -453,11 +453,11 @@ A memory-plus-UI release: **auto-memory store** carries agent context across run
453
453
-**`od plugin events snapshot/stats` + tail filters (Phase 4).** Extends Β§3.II1 with: `GET /api/plugins/events/snapshot` for non-SSE one-shot reads (dashboards that don't want a live connection); `GET /api/plugins/events/stats` returns a `summarisePluginEvents()` rollup (counts byKind, byPluginId β skipping empty ids β plus oldest/newest at + id range); `--kind <k>` and `--plugin-id <id>` filter flags work on both `od plugin events tail` (client-side post-render) and the new `od plugin events snapshot` subcommand. CLI pretty-prints the stats rollup with sorted-key counts for byte-determinism.
454
454
-**More plugin event producer hooks (Phase 4).** Extends Β§3.II1 with: `installPlugin` accepts `eventKind: 'installed' | 'upgraded'` so the upgrade route distinguishes the operation in the live tail; `POST /api/plugins/:id/trust` emits `plugin.trust-changed`; `POST /api/applied-plugins/prune` emits `plugin.snapshot-pruned` when anything was actually removed; `POST /api/marketplaces/:id/refresh` emits `plugin.marketplace-refreshed`. Each hook is best-effort and never blocks the underlying mutation if the ring buffer throws.
455
455
-**Plugin event ring buffer + SSE tail (Phase 4).** New `apps/daemon/src/plugins/events.ts` ships an in-memory FIFO ring buffer (capped at 1000 entries, monotonic ids, fan-out subscribers) for plugin lifecycle events: `plugin.installed` / `.upgraded` / `.uninstalled` / `.trust-changed` / `.applied` / `.snapshot-pruned` / `.marketplace-refreshed`. Producer hooks landed on the installer (install + uninstall). New `GET /api/plugins/events` SSE route emits the backlog on connect (with optional `?since=<id>` trim) then forwards live events. CLI: `od plugin events tail [-f] [--since <id>] [--json]` β non-follow mode drains backlog + exits; `-f` keeps the stream open for ops dashboards.
456
-
-**`od plugin doctor --strict` + verify strict propagation (Phase 4).** New `--strict` flag on `od plugin doctor` promotes warnings to failures (exit 4 distinguishes 'strict failed' from doctor errors at exit 1). The `verifyPlugin()` orchestrator gains a matching `strict: true` config knob that flows through `.od-verify.json` so plugins can lock 'no warnings allowed' as a one-line CI policy.
456
+
-**`od plugin doctor --strict` + verify strict propagation (Phase 4).** New `--strict` flag on `od plugin doctor` promotes warnings to failures (exit 4 distinguishes 'strict failed' from doctor errors at exit 1). The `verifyPlugin()` orchestrator gains a matching `strict: true` config knob that flows through the plugin verify config file so plugins can lock 'no warnings allowed' as a one-line CI policy.
457
457
-**`od daemon db verify` SQLite integrity check (Phase 5).** New `verifySqliteIntegrity()` pure helper wraps PRAGMA `integrity_check` (or `quick_check` with `--quick`) + PRAGMA `foreign_key_check`. Returns a structured `{ ok, mode, issues[], elapsedMs, generatedAt }` report with issues tagged `kind='integrity' | 'foreign_key'`. Loopback-only `POST /api/daemon/db/verify` route + `od daemon db verify [--quick]` CLI subcommand β exit 0 on ok=true, 4 on any issue, so CI can wire it into a pre-deploy check.
458
458
-**`od daemon db vacuum` (Phase 5).** New loopback-only `POST /api/daemon/db/vacuum` runs SQLite VACUUM and reports before/after sizes + reclaimed bytes + elapsed ms. Useful after large delete batches (snapshot prune, plugin uninstall) shrink rows but leave space allocated to the file. CLI: `od daemon db vacuum [--json]`.
459
459
-**`od daemon db status` SQLite inventory (Phase 5).** New `inspectSqliteDatabase()` pure helper + `GET /api/daemon/db` route returns a structured report: `kind` ('sqlite'), file location, size on disk (primary + WAL + SHM), schema version (`user_version` PRAGMA), and per-table row counts (system tables excluded, lexicographic order). CLI: `od daemon db status [--json]` lets ops sanity-check deployments at a glance + compare expected-vs-actual table rosters across daemon upgrades.
460
-
-**`od plugin verify <id>` CI meta-command (Phase 4).** New `verifyPlugin()` pure orchestrator aggregates `doctor` + `simulate` + `canon --check` into one pass/fail report. Reads `<plugin-folder>/.od-verify.json` (or `--config <path>`) so plugin authors commit their CI checks into their repo. Each check resolves to `passed | failed | skipped | unsupported`; aggregate passes iff every enabled check is passed or skipped (`unsupported` bubbles up as a fail to keep CI honest). One-liner CI workflow: `od plugin verify my-plugin` β exit 0 on pass, 4 on fail, 2 on CLI/config error.
460
+
-**`od plugin verify <id>` CI meta-command (Phase 4).** New `verifyPlugin()` pure orchestrator aggregates `doctor` + `simulate` + `canon --check` into one pass/fail report. Reads the pluginverify config file (or `--config <path>`) so plugin authors commit their CI checks into their repo. Each check resolves to `passed | failed | skipped | unsupported`; aggregate passes iff every enabled check is passed or skipped (`unsupported` bubbles up as a fail to keep CI honest). One-liner CI workflow: `od plugin verify my-plugin` β exit 0 on pass, 4 on fail, 2 on CLI/config error.
461
461
-**`od plugin simulate <id>` pipeline dry-run (Phase 4).** New `simulatePipeline({ pipeline, signals, iterationCap? })` pure helper walks every stage in a plugin's pipeline against caller-supplied signals (constant snapshot OR per-iteration generator function) and reports `outcome β { single | converged | cap | unparsable }` per stage plus aggregate `outcome β { all-converged | all-single | mixed | cap-hit | unparsable }`. Companion `parseSignalKv()` parses repeatable `-s key=value` CLI flags into the closed `UntilSignals` vocabulary with typo guards. CLI: `od plugin simulate <pluginId> [-s key=value ...] [--cap <n>] [--json]` β exit 4 on cap-hit/unparsable so CI can hook this into a pipeline check.
462
462
-**`od plugin stats` inventory health report (Phase 4).** New `pluginInventoryStats()` + `snapshotInventoryStats()` pure helpers aggregate installed-plugin counts (by `sourceKind` / `trust` / `taskKind`, bundled vs. third-party split, plugins with elevated capabilities β `fs:write` / `subprocess` / `bash` / `network` / `connector:*`) and snapshot health (status breakdown, project / run linkage, oldest / newest applied timestamps). New `GET /api/plugins/stats` route + `od plugin stats [--json]` CLI subcommand for at-a-glance fleet audit.
463
463
-**`od plugin canon --check <expected-file>` byte-equality fixtures (Phase 4).** New `--check` mode on `od plugin canon` compares the canon output against an on-disk fixture and exits 4 on mismatch with a per-line diff preview. Lets plugin authors commit `renderPluginBlock()` regression fixtures into their own `tests/` without writing a fresh test harness.
@@ -649,7 +649,7 @@ A connectivity-and-iteration release: Open Design becomes a fully bidirectional
649
649
650
650
#### MCP & connectors
651
651
- MCP install snippet survives daemon port changes. ([#846])
652
-
- Pin `OD_DATA_DIR`in `/api/mcp/install-info` env so the macOS-packaged MCP server stops EPERM'ing on `.od/projects`. ([#857])
652
+
- Pin the daemon data directory in `/api/mcp/install-info` env so the macOS-packaged MCP server stops failing on managed project storage. ([#857])
653
653
- Reserve clearance for the MCP server Copy button so it stops overlapping the snippet. ([#847])
654
654
- Give the MCP server Copy button a solid surface so it reads against the code block. ([#840])
655
655
- Stable curated tool count in the connector card badge. ([#767])
@@ -866,7 +866,7 @@ A minor release focused on iteration: live-data dashboards graduate to a first-c
866
866
867
867
### Documentation
868
868
869
-
- Documented `OD_DATA_DIR` and migration from `.od/` to the Desktop app. ([#570])
869
+
- Documented daemon data directory migration to the Desktop app. ([#570])
870
870
- Added Chinese (Simplified) QUICKSTART. ([#578])
871
871
- Backported missing zh-TW README sections from the English README. ([#586])
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -244,7 +244,7 @@ Beyond that:
244
244
## Commits & pull requests
245
245
246
246
-**One concern per PR.** Adding a skill + refactoring the parser + bumping a dep is three PRs.
247
-
-**Title is imperative + scope.**`add dating-web skill`, `fix daemon SSE backpressure when CLI hangs`, `docs: clarify .od layout`.
247
+
-**Title is imperative + scope.**`add dating-web skill`, `fix daemon SSE backpressure when CLI hangs`, `docs: clarify storage contract`.
248
248
-**Use the PR template.** Fill every section of [`.github/pull_request_template.md`](.github/pull_request_template.md) β Why, What users will see, Surface area, Screenshots (if UI), Bug fix verification (if bug fix), Validation. Empty sections earn a "please fill in" reply.
249
249
-**Body explains the why.** "What does this do" is usually obvious from the diff; "why does this need to exist" rarely is.
250
250
-**Reference an issue** if there is one. If there isn't and the PR is non-trivial, open one first so we can agree the change is wanted before you spend the time.
Before documenting, changing, or choosing any persistent daemon storage path,
157
+
you MUST read the root `AGENTS.md` section **Daemon data directory contract**.
158
+
This Quickstart MUST NOT restate that contract or define storage paths.
175
159
176
160
---
177
161
@@ -198,7 +182,7 @@ For the desktop shell and all managed sidecars in the background:
198
182
pnpm tools-dev # starts daemon + web + desktop in the background
199
183
```
200
184
201
-
On first load, the app detects your installed code-agent CLI (Claude Code / Codex / Devin for Terminal / Gemini / OpenCode / Cursor Agent / Qwen / Qoder CLI), picks it automatically, and defaults to `web-prototype` skill + `Neutral Modern` design system. Type a prompt and hit **Send**. The agent streams into the left pane; the `<artifact>` tag is parsed out and the HTML renders live on the right. When it finishes, click **Save to disk** to persist the artifact under `./.od/artifacts/<timestamp>-<slug>/index.html`.
185
+
On first load, the app detects your installed code-agent CLI (Claude Code / Codex / Devin for Terminal / Gemini / OpenCode / Cursor Agent / Qwen / Qoder CLI), picks it automatically, and defaults to `web-prototype` skill + `Neutral Modern` design system. Type a prompt and hit **Send**. The agent streams into the left pane; the `<artifact>` tag is parsed out and the HTML renders live on the right. Before documenting or changing any artifact storage path, you MUST read `AGENTS.md` β **Daemon data directory contract**.
202
186
203
187
The **Design system** dropdown ships with 71 built-in systems β 2 hand-authored starters (Neutral Modern, Warm Editorial) and 69 product systems imported from [`awesome-design-md`](https://github.com/VoltAgent/awesome-design-md), grouped by category (AI & LLM, Developer Tools, Productivity, Backend, Design Tools, Fintech, E-Commerce, Media, Automotive). Pick one to skin every prototype in that brand's aesthetic, and another set of 57 design skills sourced from [`awesome-design-skills`](https://github.com/bergside/awesome-design-skills).
204
188
@@ -357,10 +341,6 @@ open-design/
357
341
β βββ β¦129 systems # 2 starters Β· 70 product systems Β· 57 design skills
358
342
βββ scripts/sync-design-systems.ts # re-import from upstream getdesign tarball
359
343
βββ docs/ # product vision + spec
360
-
βββ .od/ # runtime data (gitignored, auto-created)
0 commit comments