Refactor project name from "Open Claude Design" to "Open Design" (#1)

* Refactor project name from "Open Claude Design" to "Open Design"

- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.

* Add contributing guidelines in English and Chinese

- Introduced CONTRIBUTING.md and CONTRIBUTING.zh-CN.md to provide clear instructions for contributors.
- Outlined contribution types, local setup instructions, and merging criteria for skills and design systems.
- Enhanced README files to reference the new contributing guidelines.
This commit is contained in:
Tom Huang
2026-04-28 16:03:35 +08:00
committed by GitHub
parent a98096a042
commit 6f6bf31dd2
131 changed files with 2560 additions and 650 deletions
+18 -18
View File
@@ -2,7 +2,7 @@
**Parent:** [`spec.md`](spec.md) · **Siblings:** [`architecture.md`](architecture.md) · [`skills-protocol.md`](skills-protocol.md) · [`modes.md`](modes.md)
The adapter layer is OCD's most load-bearing design decision. We delegate the **entire agent loop** — model calls, tool use, context management, permission handling, resume, cancel — to the user's existing code agent CLI. OCD's job is to detect it, feed it a skill + prompt + working directory, and stream its output back to the web UI.
The adapter layer is OD's most load-bearing design decision. We delegate the **entire agent loop** — model calls, tool use, context management, permission handling, resume, cancel — to the user's existing code agent CLI. OD's job is to detect it, feed it a skill + prompt + working directory, and stream its output back to the web UI.
> **Thesis:** The code agent space has already converged on a few strong implementations (Claude Code, Codex, Cursor Agent, Gemini CLI, OpenCode, OpenClaw). Reimplementing a 7th is worse than just talking to all of them.
>
@@ -70,7 +70,7 @@ type AgentEvent =
## 2. Detection strategy
Run all adapters' `detect()` in parallel on daemon start, then cache results in `~/.open-claude-design/agents.json` with a 24h TTL. Re-detect on daemon `SIGHUP`.
Run all adapters' `detect()` in parallel on daemon start, then cache results in `~/.open-design/agents.json` with a 24h TTL. Re-detect on daemon `SIGHUP`.
Each adapter uses **two signals**:
@@ -98,7 +98,7 @@ If both signals agree, detection is confident. If only one signal fires, we mark
Skills travel into each agent via one of three strategies, in order of preference:
### 4.1 Native skill loading (preferred)
Agent scans its own `~/.<agent>/skills/` on launch. We symlink OCD's skill into that dir (see [`skills-protocol.md`](skills-protocol.md) §3) and let the agent pick it up natively. Zero prompt overhead.
Agent scans its own `~/.<agent>/skills/` on launch. We symlink OD's skill into that dir (see [`skills-protocol.md`](skills-protocol.md) §3) and let the agent pick it up natively. Zero prompt overhead.
- **Works for:** Claude Code. Codex (version-dependent). OpenCode.
@@ -131,10 +131,10 @@ The adapter declares which strategy to use via `capabilities().nativeSkillLoadin
- Invocation: direct Anthropic Messages API with `stream: true`.
- Skill loading: prompt injection only — read the skill dir, inline everything.
- Tool use: we register `Read/Write/Edit` as tools, implement them in the daemon against the artifact cwd, and run the loop ourselves. This is the one place OCD does own the loop — because the user has no agent at all. Keep it as dumb as possible.
- Tool use: we register `Read/Write/Edit` as tools, implement them in the daemon against the artifact cwd, and run the loop ourselves. This is the one place OD does own the loop — because the user has no agent at all. Keep it as dumb as possible.
- Surgical edits: approximated by regenerating the whole target file with "only change X" in the prompt.
- Model: Claude Sonnet 4.6 default; Opus 4.7 behind a flag.
- **Why ship this at all?** Topology C requires it (no daemon available in a pure-Vercel deploy). Also, users trying OCD for the first time without a CLI installed still get a working experience.
- **Why ship this at all?** Topology C requires it (no daemon available in a pure-Vercel deploy). Also, users trying OD for the first time without a CLI installed still get a working experience.
### 5.3 Codex
@@ -173,7 +173,7 @@ The web UI reads `agents.capabilities()` and disables features that the active a
| Comment mode (click to refine) | `surgicalEdit: true` | Hidden; show tooltip explaining why |
| Streaming tool-call feed | `streaming: true` | Show a spinner only |
| Resume interrupted run | `resume: true` | "Cancel + restart" only |
| Skill picker shows skill with `ocd.capabilities_required` | all listed caps | Skill greyed out with reason |
| Skill picker shows skill with `od.capabilities_required` | all listed caps | Skill greyed out with reason |
This is how we avoid "works on my Claude Code, breaks on your Gemini" — we detect, degrade, and document.
@@ -192,7 +192,7 @@ Switching mid-run is not allowed (cancel first). The artifact is agent-agnostic;
## 8. Fallback chain
If the user's preferred agent fails (crash, auth, timeout), OCD offers a one-click fallback in this order:
If the user's preferred agent fails (crash, auth, timeout), OD offers a one-click fallback in this order:
1. User's preferred agent (e.g. Cursor Agent)
2. Any other detected agent (Claude Code, if installed)
@@ -206,14 +206,14 @@ First run:
```
$ pnpm dev
[ocd] daemon starting on :7431
[ocd] detecting agents…
[ocd] ✓ claude-code v0.6.3 (auth: ok, skills dir linked)
[ocd] ✓ codex v0.8.1 (auth: ok)
[ocd] ✗ cursor-agent (not installed)
[ocd] ✗ gemini-cli (installed but not authenticated; run `gemini auth login`)
[ocd] ✓ api-fallback (ANTHROPIC_API_KEY found)
[ocd] daemon ready; 3 agents available
[od] daemon starting on :7431
[od] detecting agents…
[od] ✓ claude-code v0.6.3 (auth: ok, skills dir linked)
[od] ✓ codex v0.8.1 (auth: ok)
[od] ✗ cursor-agent (not installed)
[od] ✗ gemini-cli (installed but not authenticated; run `gemini auth login`)
[od] ✓ api-fallback (ANTHROPIC_API_KEY found)
[od] daemon ready; 3 agents available
```
Web UI mirrors this in an agent-selector dropdown, with unauthenticated agents shown greyed out with a fix-it tooltip.
@@ -222,8 +222,8 @@ Web UI mirrors this in an agent-selector dropdown, with unauthenticated agents s
We inherit the underlying agent's permission model rather than building our own. This means:
- **Claude Code** respects its own `--allowed-tools` and `--permission-mode` flags. OCD passes through user preferences.
- **Codex / Cursor** sandbox by workspace; OCD always sets cwd to the artifact dir so nothing outside is visible by default.
- **Claude Code** respects its own `--allowed-tools` and `--permission-mode` flags. OD passes through user preferences.
- **Codex / Cursor** sandbox by workspace; OD always sets cwd to the artifact dir so nothing outside is visible by default.
- **API fallback** is the one case we own. We implement a whitelist: only `Read`, `Write`, `Edit` tools, all rooted at the artifact cwd. Network access is off.
The daemon never grants more authority to an agent than it had on its own. We don't run the agent in a privileged mode "for convenience."
@@ -253,6 +253,6 @@ Each adapter is a separate module so community contributions can add new ones wi
## 12. Open questions
- **Nested agents.** What if Claude Code's agent itself spawns a subagent? We receive events from the outer process only. v1 policy: surface only top-level events; summarize subagent activity as "sub-task" placeholder.
- **Billing awareness.** Some agents bill per message, some per token. OCD doesn't track cost in MVP; v1 adds an optional "usage" event from adapters that expose it.
- **Billing awareness.** Some agents bill per message, some per token. OD doesn't track cost in MVP; v1 adds an optional "usage" event from adapters that expose it.
- **Windows support.** PATH scanning and `spawn` semantics differ on Windows. v1 targets macOS and Linux; Windows is best-effort.
- **Docker-contained agents.** Some users run Claude Code in a container. Adapter needs a "remote" mode — probably same interface but talks over SSH. Phase 2+.
+24 -24
View File
@@ -13,7 +13,7 @@ This doc describes the system topology, runtime modes, data flow, and file layou
## 1. Three deployment topologies
OCD is a web app plus a local daemon. The split means the same UI can run in three shapes:
OD is a web app plus a local daemon. The split means the same UI can run in three shapes:
### Topology A — Fully local (the default)
@@ -24,7 +24,7 @@ OCD is a web app plus a local daemon. The split means the same UI can run in thr
│ │ │
│ │ ws://localhost:7431 │
│ ▼ │
│ ocd daemon (Node, long-running) │
│ od daemon (Node, long-running) │
│ │ │
│ ▼ │
│ spawns: claude / codex / cursor / … │
@@ -36,22 +36,22 @@ One `pnpm dev` starts both the Next.js app and the daemon (via a predev script).
### Topology B — Web on Vercel + daemon on user's machine
```
browser ──► ocd.yourdomain.com (Vercel)
browser ──► od.yourdomain.com (Vercel)
│ ws(s):// user-provided URL (e.g. cloudflared tunnel)
ocd daemon on user's laptop
od daemon on user's laptop
spawns: claude / codex / …
```
The user runs `ocd daemon --expose` which prints a tunnel URL; they paste the URL into the deployed web app's "Connect daemon" screen. Daemon holds secrets; Vercel holds nothing sensitive.
The user runs `od daemon --expose` which prints a tunnel URL; they paste the URL into the deployed web app's "Connect daemon" screen. Daemon holds secrets; Vercel holds nothing sensitive.
### Topology C — Web on Vercel + direct API (no daemon)
```
browser ──► ocd.yourdomain.com (Vercel serverless)
browser ──► od.yourdomain.com (Vercel serverless)
Anthropic Messages API (BYOK stored in browser)
@@ -91,8 +91,8 @@ The three topologies share the same web bundle; the difference is which transpor
│ │
▼ ▼
┌─ agent CLIs ─┐ ┌─ filesystem ─┐
│ claude │ │ ./.ocd/ │
│ codex │ │ ~/.ocd/ │
│ claude │ │ ./.od/ │
│ codex │ │ ~/.od/ │
│ cursor-agent │ │ skills/ │
│ gemini │ │ DESIGN.md │
│ opencode │ └──────────────┘
@@ -107,10 +107,10 @@ The three topologies share the same web bundle; the difference is which transpor
- **Why Next.js, not Vite SPA?** We want SSR for the marketing landing page + serverless routes for Topology C's direct-API path + Vercel deployment as a first-class citizen. An SPA would need a separate server for any of that.
- **State:** Zustand for session/artifact stores. Browser-side only; hydrated from daemon on connect.
- **Iframe preview:** Vendored React 18 + Babel standalone for JSX artifacts, following [Open CoDesign][ocod]'s approach. HTML artifacts load raw. See [§5](#5-preview-renderer).
- **Comment mode:** Click captures `[data-ocd-id]` on preview DOM, opens a popover, sends `{artifact_id, element_id, note}` to daemon → agent gets a surgical edit instruction.
- **Comment mode:** Click captures `[data-od-id]` on preview DOM, opens a popover, sends `{artifact_id, element_id, note}` to daemon → agent gets a surgical edit instruction.
- **Slider UI:** When an agent emits a "tweak parameter" tool call (see [`skills-protocol.md`](skills-protocol.md) §4.2), the web app renders a live-update control that re-sends parameterized prompts without round-tripping the chat.
### 3.2 Local daemon (`ocd daemon`)
### 3.2 Local daemon (`od daemon`)
Single binary via `pkg` or a thin Node script distributed over npm. Responsibilities:
@@ -155,7 +155,7 @@ Conflicts resolve by priority (higher wins). Each skill parsed once; watched for
Plain files on disk. Conventional layout per project:
```
./.ocd/
./.od/
├── config.json # project-level daemon config
├── artifacts/
│ ├── 2026-04-24T10-03-12-landing/
@@ -169,8 +169,8 @@ Plain files on disk. Conventional layout per project:
```
Rationale:
- **Plain files** → users can `git add ./.ocd/artifacts/` and review designs in PRs.
- **`artifact.json` metadata** → OCD can reconstruct the artifact tree without a DB.
- **Plain files** → users can `git add ./.od/artifacts/` and review designs in PRs.
- **`artifact.json` metadata** → OD can reconstruct the artifact tree without a DB.
- **`history.jsonl` not SQLite** → append-only, git-friendly, greppable. [Open CoDesign][ocod] uses SQLite; we deliberately don't.
- **Sessions separate from artifacts** → sessions are ephemeral UI state; artifacts are durable.
@@ -195,7 +195,7 @@ Rationale:
3. Daemon:
a. picks active skill (prototype-skill)
b. loads design-system (DESIGN.md)
c. materializes a new artifact dir under ./.ocd/artifacts/<slug>/
c. materializes a new artifact dir under ./.od/artifacts/<slug>/
d. invokes agent adapter with:
- system: skill's SKILL.md contents + DESIGN.md
- user: original prompt
@@ -242,9 +242,9 @@ Rationale:
| File | Purpose |
|---|---|
| `~/.open-claude-design/config.toml` | daemon-global: default agent preference, keys (optional, BYOK), telemetry opt-in (default off) |
| `~/.open-claude-design/agents.json` | cached agent detection results |
| `./.ocd/config.json` | project-local: active design system, preferred skills, preferred mode |
| `~/.open-design/config.toml` | daemon-global: default agent preference, keys (optional, BYOK), telemetry opt-in (default off) |
| `~/.open-design/agents.json` | cached agent detection results |
| `./.od/config.json` | project-local: active design system, preferred skills, preferred mode |
| `./skills/<skill>/SKILL.md` | skill manifest (standard Claude Code format) |
| `./DESIGN.md` | active design system ([awesome-claude-design][acd] format) |
@@ -288,35 +288,35 @@ pnpm dev # starts daemon on :7431, next on :3000
services:
daemon:
image: openclaudedesign/daemon
volumes: [ "~/.open-claude-design:/root/.open-claude-design", "./:/workspace" ]
volumes: [ "~/.open-design:/root/.open-design", "./:/workspace" ]
ports: ["7431:7431"]
web:
image: openclaudedesign/web
ports: ["3000:3000"]
environment: [ "OCD_DAEMON_URL=ws://daemon:7431" ]
environment: [ "OD_DAEMON_URL=ws://daemon:7431" ]
```
### Vercel + local daemon (Topology B)
```sh
vercel deploy # web only
ocd daemon --expose # user runs locally; prints tunnel URL
od daemon --expose # user runs locally; prints tunnel URL
# user pastes URL into /connect UI
```
### Vercel direct (Topology C)
```sh
vercel deploy # same bundle
# flip VERCEL env flag OCD_MODE=direct to hide daemon-connect UI
# flip VERCEL env flag OD_MODE=direct to hide daemon-connect UI
```
## 9. Security model
| Surface | Threat | Mitigation |
|---|---|---|
| Daemon WebSocket | Arbitrary local process talks to daemon | Token handshake; token printed on `ocd daemon` start, required in WS URL |
| Daemon WebSocket | Arbitrary local process talks to daemon | Token handshake; token printed on `od daemon` start, required in WS URL |
| Artifact code in preview | XSS/cookie theft from host | `<iframe sandbox="allow-scripts">`, no `allow-same-origin` |
| Agent running on user's machine | Agent reads/writes outside project | Adapter sets `cwd` to artifact dir; relies on agent's own permission system (Claude Code's `--allowed-tools` etc.) |
| User secrets | Leak to cloud | BYOK stored only in daemon's `config.toml` (mode 0600) or browser `localStorage` in Topology C, never sent to OCD's own servers (we don't have any) |
| User secrets | Leak to cloud | BYOK stored only in daemon's `config.toml` (mode 0600) or browser `localStorage` in Topology C, never sent to OD's own servers (we don't have any) |
| Skill from untrusted source | Malicious skill in `~/.claude/skills/` | Install-time warning; skills run under the agent's permission model, not ours |
| Vercel web bundle | Compromised build | Standard Vercel integrity; bundle has zero secrets |
@@ -326,7 +326,7 @@ We inherit the agent's permission model on purpose — we don't invent our own s
- Daemon startup: < 500 ms (lazy adapter init).
- Agent detection: < 200 ms (parallel PATH probes).
- First generation latency: dominated by agent model time; OCD overhead should be < 50 ms.
- First generation latency: dominated by agent model time; OD overhead should be < 50 ms.
- Preview reload: debounced 100 ms on artifact file writes.
- Skill index: cold scan < 100 ms for ~50 skills; watched with `chokidar`.
+381
View File
@@ -0,0 +1,381 @@
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Open Design — cover</title>
<link rel='preconnect' href='https://fonts.googleapis.com'>
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>
<link href='https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,300;0,9..144,500;0,9..144,700;1,9..144,500;1,9..144,700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500&display=swap' rel='stylesheet'>
<style>
:root {
--bg: #0d0a06;
--bg-2: #14100a;
--ink: #f3ead8;
--muted: #9b8f78;
--rule: #4a3f2c;
--accent: #f0833f;
--accent-2: #e85a2c;
--paper: #f6efdd;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
width: 1920px;
height: 1080px;
background: var(--bg);
color: var(--ink);
font-family: 'Inter', -apple-system, system-ui, sans-serif;
overflow: hidden;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
background:
radial-gradient(1200px 700px at 78% 22%, rgba(240,131,63,0.12), transparent 70%),
radial-gradient(900px 600px at 12% 80%, rgba(232,90,44,0.06), transparent 70%),
linear-gradient(180deg, #0e0b07 0%, #0a0805 100%);
padding: 56px 72px;
display: flex;
flex-direction: column;
}
.mono {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 12px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
header {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
padding-bottom: 22px;
border-bottom: 1px solid var(--rule);
}
header .l { text-align: left; }
header .r { text-align: right; }
header .center {
font-family: 'Fraunces', serif;
font-style: italic;
font-weight: 500;
font-size: 22px;
color: var(--ink);
letter-spacing: 0.01em;
}
header .center .dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent);
margin: 0 8px 4px 0;
vertical-align: middle;
}
main {
flex: 1;
display: grid;
grid-template-columns: 1.05fr 1fr;
column-gap: 64px;
padding-top: 56px;
align-items: stretch;
}
.left {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.eyebrow {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 28px;
}
.eyebrow .pill {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
letter-spacing: 0.22em;
color: #f6e9d4;
background: rgba(240,131,63,0.16);
border: 1px solid rgba(240,131,63,0.45);
padding: 6px 12px;
border-radius: 999px;
text-transform: uppercase;
}
.eyebrow .pill.alt {
color: var(--muted);
background: transparent;
border-color: var(--rule);
}
h1 {
font-family: 'Fraunces', serif;
font-weight: 500;
font-size: 116px;
line-height: 0.94;
letter-spacing: -0.025em;
color: var(--ink);
margin: 0 0 36px 0;
}
h1 em {
font-style: italic;
color: var(--accent);
font-weight: 500;
}
h1 .small {
font-size: 96px;
}
.lede {
font-family: 'Fraunces', serif;
font-weight: 300;
font-size: 22px;
line-height: 1.5;
color: #d8cdb6;
max-width: 640px;
margin: 0 0 32px 0;
}
.lede b {
font-weight: 500;
color: #f3ead8;
}
.meta {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0;
border-top: 1px solid var(--rule);
padding-top: 22px;
}
.meta .cell {
border-right: 1px solid var(--rule);
padding-right: 18px;
}
.meta .cell:last-child { border-right: none; }
.meta .num {
font-family: 'Fraunces', serif;
font-weight: 500;
font-size: 42px;
line-height: 1;
color: var(--ink);
letter-spacing: -0.01em;
}
.meta .num em {
font-style: italic;
color: var(--accent);
font-weight: 500;
}
.meta .lbl {
margin-top: 10px;
font-family: 'JetBrains Mono', monospace;
font-size: 10.5px;
letter-spacing: 0.18em;
color: var(--muted);
text-transform: uppercase;
line-height: 1.4;
}
/* right artifact collage */
.right {
position: relative;
}
.stage {
position: absolute;
inset: 0;
}
.card {
position: absolute;
border-radius: 18px;
overflow: hidden;
background: #1a140d;
box-shadow:
0 1px 0 rgba(255,255,255,0.04) inset,
0 24px 60px rgba(0,0,0,0.55),
0 6px 18px rgba(0,0,0,0.45);
border: 1px solid rgba(255,255,255,0.06);
}
.card img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.card .tag {
position: absolute;
top: 14px;
left: 14px;
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: #ffd9b6;
background: rgba(20, 14, 8, 0.7);
padding: 6px 10px;
border-radius: 6px;
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
border: 1px solid rgba(255,217,182,0.18);
}
/* arrange three artifacts as an editorial collage */
.card.a { /* gamified-app — back-left */
width: 540px;
height: 320px;
top: 70px;
right: 280px;
transform: rotate(-3.5deg);
}
.card.b { /* digital-eguide — front-right hero */
width: 620px;
height: 360px;
top: 220px;
right: 0;
transform: rotate(2.5deg);
z-index: 3;
}
.card.c { /* dating-web — bottom-left */
width: 520px;
height: 300px;
top: 460px;
right: 230px;
transform: rotate(-1.5deg);
z-index: 2;
}
/* decorative marks */
.mark-circle {
position: absolute;
top: 36px;
right: 24px;
width: 86px;
height: 86px;
border-radius: 50%;
background: radial-gradient(circle at 35% 30%, #ffb37a, var(--accent-2) 80%);
color: #2a1408;
font-family: 'Fraunces', serif;
font-style: italic;
font-weight: 700;
font-size: 14px;
line-height: 1.15;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
transform: rotate(8deg);
box-shadow: 0 14px 30px rgba(232,90,44,0.45);
z-index: 5;
}
.mark-circle span { padding: 0 10px; }
footer {
margin-top: 48px;
padding-top: 22px;
border-top: 1px solid var(--rule);
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
}
footer .l { text-align: left; }
footer .r { text-align: right; }
footer .c {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
letter-spacing: 0.28em;
color: var(--muted);
text-transform: uppercase;
}
.underline-accent {
position: relative;
display: inline-block;
}
.underline-accent::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: -6px;
height: 6px;
background: var(--accent);
border-radius: 4px;
opacity: 0.85;
}
</style>
</head>
<body>
<header>
<div class='mono l'>Open Design · Manifesto · 2026 Edition</div>
<div class='center'><span class='dot'></span>open.design</div>
<div class='mono r'>Cover · 01 / 08 · OSS Alternative</div>
</header>
<main>
<section class='left'>
<div>
<div class='eyebrow'>
<span class='pill'>· APACHE 2.0</span>
<span class='pill alt'>Local-first · BYOK</span>
</div>
<h1>
Design with the<br/>
<em>agent</em> already<br/>
<span class='small'>on your <span class='underline-accent'>laptop</span>.</span>
</h1>
<p class='lede'>
Open Design is the open-source alternative to Claude Design.
Your existing coding agent — <b>Claude Code · Codex · Cursor · Gemini · OpenCode · Qwen</b>
becomes the design engine, driven by 19 composable Skills and 71 brand-grade Design Systems.
</p>
</div>
<div class='meta'>
<div class='cell'>
<div class='num'>71</div>
<div class='lbl'>Design<br/>Systems</div>
</div>
<div class='cell'>
<div class='num'>19</div>
<div class='lbl'>Composable<br/>Skills</div>
</div>
<div class='cell'>
<div class='num'>06</div>
<div class='lbl'>Coding<br/>Agents</div>
</div>
<div class='cell'>
<div class='num'><em>0</em></div>
<div class='lbl'>Lock-in /<br/>Vendor Cloud</div>
</div>
</div>
</section>
<section class='right'>
<div class='stage'>
<div class='card a'>
<span class='tag'>· Hi-Fi Prototype · iPhone</span>
<img src='../../screenshots/skills/gamified-app.png' alt=''>
</div>
<div class='card b'>
<span class='tag'>· Digital E-guide · 64pp</span>
<img src='../../screenshots/skills/digital-eguide.png' alt=''>
</div>
<div class='card c'>
<span class='tag'>· Dating App · Web</span>
<img src='../../screenshots/skills/dating-web.png' alt=''>
</div>
<div class='mark-circle'><span>OPEN<br/>SOURCE</span></div>
</div>
</section>
</main>
<footer>
<div class='mono l'>BYOK at every layer · No cloud lock-in</div>
<div class='c'>· pnpm dev · vercel deploy · npm start ·</div>
<div class='mono r'>github.com/open-design</div>
</footer>
</body>
</html>
+520
View File
@@ -0,0 +1,520 @@
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>71 Design Systems — cover</title>
<link rel='preconnect' href='https://fonts.googleapis.com'>
<link rel='preconnect' href='https://fonts.gstatic.com' crossorigin>
<link href='https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;0,9..144,700;1,9..144,500;1,9..144,700&family=JetBrains+Mono:wght@400;500&family=Inter:wght@400;500&display=swap' rel='stylesheet'>
<style>
:root {
--surface: #d9c3bd;
--surface-2: #e6d2cc;
--paper: #f5ecd9;
--paper-edge: #e8dcc4;
--ink: #1c1814;
--ink-soft: #4d4339;
--muted: #8a7e70;
--rule: #c8b9a1;
--accent: #c44a3a;
--accent-2: #d4593f;
}
* { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
width: 1920px;
height: 1080px;
background: var(--surface);
color: var(--ink);
font-family: 'Inter', -apple-system, system-ui, sans-serif;
overflow: hidden;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
background:
radial-gradient(1100px 700px at 28% 12%, var(--surface-2), transparent 70%),
radial-gradient(900px 600px at 88% 90%, #cab1aa, transparent 70%),
var(--surface);
padding: 60px 80px;
display: flex;
gap: 56px;
align-items: stretch;
}
.page {
background: var(--paper);
flex: 1;
border-radius: 4px;
padding: 56px 60px;
box-shadow:
0 0 0 1px var(--paper-edge),
0 30px 60px rgba(60, 30, 24, 0.18),
0 8px 22px rgba(60, 30, 24, 0.12);
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
}
.page::before {
content: '';
position: absolute;
inset: 0;
pointer-events: none;
background:
linear-gradient(180deg, rgba(28,24,20,0.04), transparent 8%, transparent 92%, rgba(28,24,20,0.05));
}
.mono {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 11px;
letter-spacing: 0.22em;
color: var(--muted);
text-transform: uppercase;
}
.pageHead {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 14px;
border-bottom: 1px solid var(--rule);
}
.dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent);
margin-right: 8px;
vertical-align: middle;
transform: translateY(-1px);
}
/* ---------- LEFT (cover) page ---------- */
.cover h1 {
font-family: 'Fraunces', serif;
font-weight: 500;
font-size: 96px;
line-height: 0.94;
letter-spacing: -0.02em;
color: var(--ink);
margin: 64px 0 32px 0;
}
.cover h1 em {
font-style: italic;
color: var(--accent);
font-weight: 500;
}
.cover .tagline {
font-family: 'Fraunces', serif;
font-style: italic;
font-weight: 400;
font-size: 22px;
line-height: 1.45;
color: var(--ink-soft);
max-width: 480px;
margin: 0 0 36px 0;
}
.byline {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
letter-spacing: 0.22em;
color: var(--muted);
text-transform: uppercase;
padding: 14px 0;
border-top: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
margin-bottom: 36px;
}
.stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0;
margin-bottom: 44px;
}
.stats .cell { padding-right: 16px; }
.stats .cell + .cell { border-left: 1px solid var(--rule); padding-left: 24px; }
.stats .num {
font-family: 'Fraunces', serif;
font-weight: 500;
font-size: 64px;
line-height: 1;
color: var(--ink);
letter-spacing: -0.02em;
}
.stats .num em { font-style: italic; color: var(--accent); }
.stats .lbl {
margin-top: 10px;
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
letter-spacing: 0.22em;
color: var(--muted);
text-transform: uppercase;
line-height: 1.4;
}
.toc-title {
font-family: 'Fraunces', serif;
font-weight: 500;
font-size: 32px;
margin: 8px 0 18px 0;
color: var(--ink);
}
.toc-title em { font-style: italic; color: var(--accent); }
.toc {
display: flex;
flex-direction: column;
gap: 10px;
}
.toc-row {
display: flex;
align-items: baseline;
font-family: 'Fraunces', serif;
font-size: 17px;
color: var(--ink);
}
.toc-row .name { flex: 0 0 auto; }
.toc-row .dots {
flex: 1;
border-bottom: 1px dotted #b6a487;
margin: 0 10px;
transform: translateY(-4px);
}
.toc-row .pg {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
letter-spacing: 0.18em;
color: var(--muted);
}
.cover .footer {
margin-top: auto;
display: flex;
justify-content: space-between;
border-top: 1px solid var(--rule);
padding-top: 14px;
}
/* ---------- RIGHT (index) page ---------- */
.index .h2 {
font-family: 'Fraunces', serif;
font-weight: 500;
font-size: 56px;
line-height: 1;
letter-spacing: -0.02em;
color: var(--ink);
margin: 32px 0 12px 0;
}
.index .h2 em {
font-style: italic;
color: var(--accent);
font-weight: 500;
}
.index .sub {
font-family: 'Fraunces', serif;
font-style: italic;
font-weight: 400;
font-size: 18px;
color: var(--ink-soft);
line-height: 1.5;
max-width: 540px;
margin: 0 0 28px 0;
}
.drop {
float: left;
font-family: 'Fraunces', serif;
font-weight: 500;
font-size: 76px;
line-height: 0.85;
color: var(--accent);
margin: 8px 12px -4px 0;
}
.drop + p {
font-family: 'Fraunces', serif;
font-size: 16px;
line-height: 1.5;
color: var(--ink-soft);
margin: 0 0 18px 0;
}
.columns {
display: grid;
grid-template-columns: 1fr 1fr;
column-gap: 36px;
row-gap: 6px;
margin: 18px 0 12px 0;
border-top: 1px solid var(--rule);
border-bottom: 1px solid var(--rule);
padding: 14px 0;
}
.item {
display: grid;
grid-template-columns: 26px 1fr auto;
align-items: baseline;
gap: 10px;
padding: 6px 0;
font-family: 'Fraunces', serif;
font-size: 16px;
color: var(--ink);
}
.item .n {
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
letter-spacing: 0.12em;
color: var(--muted);
}
.item .swatch {
width: 14px;
height: 14px;
border-radius: 3px;
display: inline-block;
transform: translateY(2px);
margin-right: 6px;
box-shadow: 0 0 0 1px rgba(0,0,0,0.08) inset;
}
.item .name { font-weight: 500; }
.item .tag {
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
}
.item.featured .name { color: var(--accent); font-style: italic; }
.spotlight {
display: grid;
grid-template-columns: 110px 1fr;
gap: 18px;
align-items: center;
background: #f0e3c8;
border: 1px solid var(--rule);
border-radius: 6px;
padding: 18px 20px;
margin-top: 18px;
}
.spotlight .swatches {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 6px;
}
.spotlight .sw {
height: 28px;
border-radius: 4px;
box-shadow: 0 0 0 1px rgba(0,0,0,0.06) inset;
}
.spotlight .label {
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
letter-spacing: 0.18em;
color: var(--muted);
text-transform: uppercase;
margin-bottom: 4px;
}
.spotlight h3 {
font-family: 'Fraunces', serif;
font-weight: 500;
font-style: italic;
font-size: 22px;
margin: 0 0 6px 0;
color: var(--ink);
}
.spotlight h3 em { color: var(--accent); }
.spotlight p {
font-family: 'Fraunces', serif;
font-size: 14px;
line-height: 1.5;
color: var(--ink-soft);
margin: 0;
}
.index .footer {
margin-top: auto;
display: flex;
justify-content: space-between;
border-top: 1px solid var(--rule);
padding-top: 14px;
}
.stamp {
position: absolute;
top: 56px;
right: 56px;
width: 88px;
height: 88px;
border-radius: 50%;
background: var(--accent);
color: #fff5e9;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
transform: rotate(8deg);
font-family: 'Fraunces', serif;
font-weight: 500;
font-style: italic;
font-size: 13px;
line-height: 1.15;
box-shadow: 0 12px 28px rgba(196,74,58,0.35);
z-index: 2;
}
</style>
</head>
<body>
<!-- LEFT PAGE: cover -->
<article class='page cover'>
<div class='pageHead'>
<div class='mono'><span class='dot'></span>Style &amp; Format Guide for Designers</div>
<div class='mono'>2026 Edition</div>
</div>
<h1>The <em>71</em><br/>Systems<br/>Library.</h1>
<p class='tagline'>
Linear, Stripe, Vercel, Airbnb, Tesla, Notion, Anthropic, Apple, Cursor, Supabase, Figma —
seventy-one brand-grade systems, one open library, zero lock-in.
</p>
<div class='byline'>By Open Design · Maintained on GitHub · 19 / 04 / 2026</div>
<div class='stats'>
<div class='cell'>
<div class='num'>71</div>
<div class='lbl'>Design<br/>Systems</div>
</div>
<div class='cell'>
<div class='num'>19</div>
<div class='lbl'>Composable<br/>Skills</div>
</div>
<div class='cell'>
<div class='num'><em>1</em></div>
<div class='lbl'>Library, zero<br/>vendor cloud</div>
</div>
</div>
<h2 class='toc-title'>What's <em>inside</em>.</h2>
<div class='toc'>
<div class='toc-row'><span class='name'>Tokens, palettes, motion</span><span class='dots'></span><span class='pg'>04</span></div>
<div class='toc-row'><span class='name'>Pick a direction</span><span class='dots'></span><span class='pg'>12</span></div>
<div class='toc-row'><span class='name'>Tone &amp; typography</span><span class='dots'></span><span class='pg'>18</span></div>
<div class='toc-row'><span class='name'>71 systems index</span><span class='dots'></span><span class='pg'>24</span></div>
<div class='toc-row'><span class='name'>Bring-your-own-key</span><span class='dots'></span><span class='pg'>40</span></div>
<div class='toc-row'><span class='name'>The anti-AI-slop checklist</span><span class='dots'></span><span class='pg'>52</span></div>
</div>
<div class='footer'>
<div class='mono'>Tokens, palettes &amp; type</div>
<div class='mono'>01 / 64</div>
</div>
</article>
<!-- RIGHT PAGE: index -->
<article class='page index'>
<div class='pageHead'>
<div class='mono'><span class='dot'></span>Chapter 02 · Index</div>
<div class='mono'>71 entries · A → Z</div>
</div>
<h2 class='h2'>All systems —<br/><em>one library.</em></h2>
<p class='sub'>
Every system ships a deterministic OKLch palette, a font stack, and a tone profile.
Pick one tile and the agent inherits the whole brand.
</p>
<p>
<span class='drop'>S</span>
eventy-one product systems, two hand-authored starters, five visual directions. Imported and curated
from awesome-design-md, hand-tuned for Open Design's discovery loop. Drop one in,
every artifact downstream changes accordingly — no model freestyle.
</p>
<div class='columns'>
<div class='item featured'>
<span class='n'>03</span>
<span><span class='swatch' style='background:#5e6ad2'></span><span class='name'>Linear</span></span>
<span class='tag'>· graphite · violet</span>
</div>
<div class='item'>
<span class='n'>07</span>
<span><span class='swatch' style='background:#635bff'></span><span class='name'>Stripe</span></span>
<span class='tag'>· payments · indigo</span>
</div>
<div class='item'>
<span class='n'>09</span>
<span><span class='swatch' style='background:#000000'></span><span class='name'>Vercel</span></span>
<span class='tag'>· void · grayscale</span>
</div>
<div class='item'>
<span class='n'>14</span>
<span><span class='swatch' style='background:#ff385c'></span><span class='name'>Airbnb</span></span>
<span class='tag'>· rausch · rounded</span>
</div>
<div class='item'>
<span class='n'>18</span>
<span><span class='swatch' style='background:#cc0000'></span><span class='name'>Tesla</span></span>
<span class='tag'>· red · industrial</span>
</div>
<div class='item'>
<span class='n'>22</span>
<span><span class='swatch' style='background:#000000'></span><span class='name'>Notion</span></span>
<span class='tag'>· paper · serif</span>
</div>
<div class='item'>
<span class='n'>27</span>
<span><span class='swatch' style='background:#cc785c'></span><span class='name'>Anthropic</span></span>
<span class='tag'>· clay · serif</span>
</div>
<div class='item'>
<span class='n'>31</span>
<span><span class='swatch' style='background:#a8a8a8'></span><span class='name'>Apple</span></span>
<span class='tag'>· chrome · sf pro</span>
</div>
<div class='item'>
<span class='n'>34</span>
<span><span class='swatch' style='background:#1a1a1a'></span><span class='name'>Cursor</span></span>
<span class='tag'>· terminal · mono</span>
</div>
<div class='item'>
<span class='n'>41</span>
<span><span class='swatch' style='background:#3ecf8e'></span><span class='name'>Supabase</span></span>
<span class='tag'>· emerald · rounded</span>
</div>
<div class='item'>
<span class='n'>48</span>
<span><span class='swatch' style='background:#0acf83'></span><span class='name'>Figma</span></span>
<span class='tag'>· spectrum · canvas</span>
</div>
<div class='item'>
<span class='n'>57</span>
<span><span class='swatch' style='background:#000000'></span><span class='name'>OpenAI</span></span>
<span class='tag'>· void · sober</span>
</div>
</div>
<div class='spotlight'>
<div class='swatches'>
<span class='sw' style='background:#1c1816'></span>
<span class='sw' style='background:#5e6ad2'></span>
<span class='sw' style='background:#9b9bd6'></span>
<span class='sw' style='background:#f3ead8'></span>
</div>
<div>
<div class='label'>Spotlight · Linear · 03 / 71</div>
<h3>Graphite + electric <em>violet.</em></h3>
<p>IBM Plex Sans · Inter Display · 4-step OKLch palette · 16/24 grid · square radius. The agent inherits the full token tree the moment you tap the tile.</p>
</div>
</div>
<div class='footer'>
<div class='mono'>Chapter 02 · Index</div>
<div class='mono'>24 / 64</div>
</div>
<div class='stamp'><span>71<br/>SYSTEMS</span></div>
</article>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 87 KiB

+43
View File
@@ -0,0 +1,43 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2400 800" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Hero banner placeholder">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FBF7EF"/>
<stop offset="100%" stop-color="#EFE7D7"/>
</linearGradient>
</defs>
<rect width="2400" height="800" fill="url(#bg)"/>
<rect x="32" y="32" width="2336" height="736" rx="28" ry="28"
fill="none" stroke="#C2532D" stroke-width="3" stroke-dasharray="16 12" opacity="0.85"/>
<g transform="translate(1200 340)" stroke="#1F1B16" stroke-width="6"
stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.9">
<rect x="-110" y="-72" width="220" height="144" rx="18"/>
<rect x="-36" y="-94" width="72" height="26" rx="8"/>
<circle r="42"/>
<circle r="18"/>
</g>
<text x="1200" y="430" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="34" font-weight="600" letter-spacing="6" fill="#C2532D">
OPEN DESIGN
</text>
<text x="1200" y="510" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="56" font-weight="700" fill="#1F1B16">
Hero banner
</text>
<text x="1200" y="575" text-anchor="middle"
font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
font-size="26" fill="#6B6258">
docs/assets/banner.svg
</text>
<text x="1200" y="640" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="24" fill="#6B6258">
Replace with a wide product screenshot or marketing illustration.
</text>
<text x="1200" y="744" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="20" letter-spacing="4" fill="#6B6258" opacity="0.85">
SCREENSHOT PENDING · 截图占位
</text>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 79 KiB

+43
View File
@@ -0,0 +1,43 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1600 900" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Design Systems library placeholder">
<defs>
<linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FBF7EF"/>
<stop offset="100%" stop-color="#EFE7D7"/>
</linearGradient>
</defs>
<rect width="1600" height="900" fill="url(#bg)"/>
<rect x="32" y="32" width="1536" height="836" rx="28" ry="28"
fill="none" stroke="#C2532D" stroke-width="3" stroke-dasharray="16 12" opacity="0.85"/>
<g transform="translate(800 390)" stroke="#1F1B16" stroke-width="6"
stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.9">
<rect x="-110" y="-72" width="220" height="144" rx="18"/>
<rect x="-36" y="-94" width="72" height="26" rx="8"/>
<circle r="42"/>
<circle r="18"/>
</g>
<text x="800" y="480" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="34" font-weight="600" letter-spacing="6" fill="#C2532D">
71 DESIGN SYSTEMS
</text>
<text x="800" y="560" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="56" font-weight="700" fill="#1F1B16">
Design Systems library
</text>
<text x="800" y="625" text-anchor="middle"
font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
font-size="26" fill="#6B6258">
docs/assets/design-systems-library.svg
</text>
<text x="800" y="690" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="24" fill="#6B6258">
Replace with a screenshot of the design-system browser.
</text>
<text x="800" y="844" text-anchor="middle"
font-family="ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif"
font-size="20" letter-spacing="4" fill="#6B6258" opacity="0.85">
SCREENSHOT PENDING · 截图占位
</text>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File
+4 -4
View File
@@ -8,7 +8,7 @@ triggers:
- "saas landing"
- "marketing page"
- "product landing"
ocd:
od:
mode: prototype
preview:
type: html
@@ -83,7 +83,7 @@ Output a single self-contained `index.html` with:
- System font fallbacks if DESIGN.md fonts aren't loadable from Google Fonts etc.
- No external JS.
- Semantic HTML (`<header>`, `<main>`, `<section>`, `<footer>`).
- Each editable element tagged with `data-ocd-id="<unique-slug>"` so the host app's comment mode can target it.
- Each editable element tagged with `data-od-id="<unique-slug>"` so the host app's comment mode can target it.
## 5. Self-check
@@ -112,9 +112,9 @@ saas-landing-skill/
```
Things to notice:
- The `ocd:` front-matter block is optional for Claude-Code-only compatibility, but adding it lights up OCD's typed inputs, sliders, preview metadata, and capability gating.
- The `od:` front-matter block is optional for Claude-Code-only compatibility, but adding it lights up OD's typed inputs, sliders, preview metadata, and capability gating.
- The workflow below the front-matter is plain Markdown that the agent reads as its system prompt.
- DESIGN.md is treated as a collaborator, not an override. The skill gives the agent authority to override when the brief conflicts, but never to invent new tokens.
- `data-ocd-id` tagging is how we wire elements to comment mode. Skills that want comment-mode compatibility must annotate their output.
- `data-od-id` tagging is how we wire elements to comment mode. Skills that want comment-mode compatibility must annotate their output.
See [`../../skills-protocol.md`](../../skills-protocol.md) for the full protocol.
+5 -5
View File
@@ -2,7 +2,7 @@
**Parent:** [`spec.md`](spec.md) · **Siblings:** [`architecture.md`](architecture.md) · [`skills-protocol.md`](skills-protocol.md) · [`agent-adapters.md`](agent-adapters.md)
OCD exposes four user-facing modes. Modes are not arbitrary; each maps to a distinct **skill type** (see [`skills-protocol.md`](skills-protocol.md) §4) and a distinct **workflow shape**. Keeping them separate lets us tune UI affordances, export pipelines, and default skills per mode.
OD exposes four user-facing modes. Modes are not arbitrary; each maps to a distinct **skill type** (see [`skills-protocol.md`](skills-protocol.md) §4) and a distinct **workflow shape**. Keeping them separate lets us tune UI affordances, export pipelines, and default skills per mode.
| Mode | What you get | Time to first result | Skill type |
|---|---|---|---|
@@ -24,14 +24,14 @@ One high-fidelity screen or flow. User brief → working HTML/JSX in a sandboxed
```
[ mode picker: Prototype ]
[ skill picker: saas-landing | dashboard | login-flow | … ]
[ inputs form (if skill declares ocd.inputs) ]
[ inputs form (if skill declares od.inputs) ]
[ free-text prompt box ]
[ generate ]
[ streaming tool-call feed · artifact tree · preview iframe ]
[ comment mode (if adapter supports surgicalEdit) ]
[ parameter sliders (if skill declares ocd.parameters) ]
[ parameter sliders (if skill declares od.parameters) ]
[ export: html · pdf · zip ]
```
@@ -54,7 +54,7 @@ One high-fidelity screen or flow. User brief → working HTML/JSX in a sandboxed
### Refinement surfaces
- **Chat:** free-text "move the CTA above the fold."
- **Comment mode:** click an element → popover → "make this card glassmorphic." Only available if `capabilities.surgicalEdit === true`.
- **Sliders:** any `ocd.parameters` the skill declared. Slider movements re-prompt with the parameter value only; no full regeneration.
- **Sliders:** any `od.parameters` the skill declared. Slider movements re-prompt with the parameter value only; no full regeneration.
### Default v1 skills
- `saas-landing`
@@ -82,7 +82,7 @@ Same as Prototype, but:
- Export adds `pptx` and `pdf` as first-class options
### Inputs
- Slide count (skill usually declares `ocd.inputs.slide_count`)
- Slide count (skill usually declares `od.inputs.slide_count`)
- Topic / outline (free text or structured)
- Theme preset (skill-defined enum; e.g. `editorial | minimal | brutalist`)
- DESIGN.md (optional — many deck skills don't need one because they have their own theme system)
+7 -7
View File
@@ -11,7 +11,7 @@ Every external project this spec leans on. Three questions per entry: what is it
### [Anthropic Claude Design][cd]
- **URL:** [claude.ai/design][cd] · [release announcement](https://www.infoq.cn/article/TH0QVHpvVGZ7VP3hAEmm) · [ifanr review](https://www.ifanr.com/1662860)
[cd]: https://www.anthropic.com/news/claude-design
[cd]: https://x.com/claudeai/status/2045156267690213649
- **What it is:** Anthropic's closed-source AI design product. Released 2026-04-17. Powered by Opus 4.7. Web-only (claude.ai). Generates prototypes, wireframes, decks, marketing pages, complex prototypes with voice/video/3D/shaders.
- **Why it matters to us:** Defines the category. Its viral moment (~60M X impressions week 1) proves the market.
- **What we borrow:** The high-level value prop — "natural language → editable visual design." Feature inspiration for modes (prototype, deck, marketing). UI ideas around inline editing and custom sliders.
@@ -74,8 +74,8 @@ Every external project this spec leans on. Three questions per entry: what is it
- **Related URLs:** claude.ai/design, getdesign.md, Discord community
- **Why it matters:** Defines the de-facto portable design-system format for AI agents.
- **What we borrow:**
- **The entire `DESIGN.md` format, unchanged.** We adopt their 9-section schema as OCD's canonical design-system format.
- Ecosystem compatibility: any of their 68 DESIGN.md files works as an OCD active design system out of the box.
- **The entire `DESIGN.md` format, unchanged.** We adopt their 9-section schema as OD's canonical design-system format.
- Ecosystem compatibility: any of their 68 DESIGN.md files works as an OD active design system out of the box.
- **What we don't:**
- Their curated list itself — we don't fork their 68 files; we reference upstream.
- Their Discord / community layer — not our product.
@@ -87,10 +87,10 @@ Every external project this spec leans on. Three questions per entry: what is it
- **What it is:** A Claude Code skill producing magazine-style, horizontal-swipe web decks. Structure: `SKILL.md` + `assets/template.html` + `references/{components,layouts,themes,checklist}.md`. 6-step workflow. Single-file HTML output with embedded CSS/WebGL. Keyboard/scroll/touch navigation.
- **Why it matters:** Reference implementation of a high-quality Claude skill, and our default deck skill.
- **What we borrow:**
- **The whole skill, unmodified.** It's our default v1 `deck-skill`. A user runs `ocd skill add https://github.com/op7418/guizang-ppt-skill` and it works.
- **The whole skill, unmodified.** It's our default v1 `deck-skill`. A user runs `od skill add https://github.com/op7418/guizang-ppt-skill` and it works.
- Skill directory convention (`assets/` + `references/` + `SKILL.md`) as the pattern we document for skill authors.
- The "6-step workflow + quality-checklist rubric" pattern for authoring new skills.
- **What we don't:** Nothing — this is pure reuse. We add an `ocd:` block to its front-matter only if we want to expose theme sliders; the skill works without it.
- **What we don't:** Nothing — this is pure reuse. We add an `od:` block to its front-matter only if we want to expose theme sliders; the skill works without it.
---
@@ -111,7 +111,7 @@ Every external project this spec leans on. Three questions per entry: what is it
## Compatibility & differentiation matrix
| Dimension | [Claude Design][cd] | [Open CoDesign][ocod] | [multica][multica] | [cc-switch][ccsw] | **OCD** |
| Dimension | [Claude Design][cd] | [Open CoDesign][ocod] | [multica][multica] | [cc-switch][ccsw] | **OD** |
|---|---|---|---|---|---|
| Open source | ❌ | ✅ | ✅ | ✅ | ✅ |
| Primary form factor | Web (hosted) | Electron | Web + Go daemon | Tauri | **Next.js web + Node daemon** |
@@ -125,7 +125,7 @@ Every external project this spec leans on. Three questions per entry: what is it
| Template gallery | ✅ | ✅ (15) | ❌ | ❌ | **✅** |
| Design-system authoring mode | ❌ | ❌ | ❌ | ❌ | **✅** |
The two empty-column crossings where OCD lights up and others don't: **Vercel-deployable + design-system authoring**, and **uses existing code agent + first-class DESIGN.md**. That's the niche.
The two empty-column crossings where OD lights up and others don't: **Vercel-deployable + design-system authoring**, and **uses existing code agent + first-class DESIGN.md**. That's the niche.
---
+11 -11
View File
@@ -12,7 +12,7 @@ Phased plan from "spec-only today" to "usable MVP" to "published v1." All estima
**Deliverables:**
- [x] `README.md` + `docs/spec.md` + architecture / protocol / adapter / modes / references docs (this repo, as of now)
- [ ] `docs/schemas/skill-manifest.json` — JSON Schema for the `ocd:` front-matter block
- [ ] `docs/schemas/skill-manifest.json` — JSON Schema for the `od:` front-matter block
- [ ] `docs/schemas/design-system.md` — formal spec of the 9-section `DESIGN.md`
- [ ] `docs/schemas/protocol.md` — JSON-RPC method signatures
- [ ] `docs/schemas/adapter.md` — adapter interface in TypeScript, printed out
@@ -65,7 +65,7 @@ Phased plan from "spec-only today" to "usable MVP" to "published v1." All estima
- PDF / PPTX export
- Topology B (Vercel + tunneled local daemon)
- Docker compose file
- Skill tests (`ocd skill test`)
- Skill tests (`od skill test`)
- Auth / multi-user
### Week-by-week breakdown
@@ -78,7 +78,7 @@ Phased plan from "spec-only today" to "usable MVP" to "published v1." All estima
| 4 | API-fallback adapter | Anthropic Messages streaming; minimal tool loop (Read/Write/Edit rooted to artifact cwd); integration with skill prompt injection |
| 5 | Web UI — chat + artifact tree | Zustand session store; WS client; chat pane; artifact tree reflects filesystem; skill picker |
| 6 | Web UI — preview + export | sandboxed iframe with hot reload; JSX → vendored React/Babel runtime; export ZIP; export self-contained HTML (inline CSS) |
| 7 | Default skills | port `guizang-ppt-skill` (no modifications; add `ocd:` extension block); write `saas-landing` skill; write 12 DESIGN.md examples; docs for skill authors |
| 7 | Default skills | port `guizang-ppt-skill` (no modifications; add `od:` extension block); write `saas-landing` skill; write 12 DESIGN.md examples; docs for skill authors |
| 8 | Polish + dogfood | end-to-end dogfooding; performance pass (daemon <500ms cold start, first generation overhead <50ms); bug-fixing; first publishable alpha |
### MVP exit criteria
@@ -87,8 +87,8 @@ Phased plan from "spec-only today" to "usable MVP" to "published v1." All estima
2. With Claude Code installed: prototype + deck generation works end-to-end.
3. Without Claude Code installed: API-fallback produces prototypes (not decks — guizang-ppt-skill needs native skill loading).
4. A user can drop a DESIGN.md into the project root and subsequent generations respect it.
5. A third party can publish a skill repo; `ocd skill add <url>` installs it and it works.
6. Artifacts are plain files; `git add ./.ocd/artifacts/` and `git log` tell a sensible story.
5. A third party can publish a skill repo; `od skill add <url>` installs it and it works.
6. Artifacts are plain files; `git add ./.od/artifacts/` and `git log` tell a sensible story.
7. No Electron, no Tauri, no desktop packaging anywhere in the repo.
---
@@ -107,7 +107,7 @@ Phased plan from "spec-only today" to "usable MVP" to "published v1." All estima
**UI:**
- **Comment mode** (click element → surgical edit; only when `capabilities.surgicalEdit`)
- **Slider parameters** (live-tweak `ocd.parameters`)
- **Slider parameters** (live-tweak `od.parameters`)
- **Multi-frame preview** (desktop / tablet / phone)
- **Template gallery** UI with thumbnails
- **Design System editor** (split view: markdown ↔ sample-components preview)
@@ -129,18 +129,18 @@ Phased plan from "spec-only today" to "usable MVP" to "published v1." All estima
**Deployment:**
- Docker compose file
- Topology B: Vercel web + tunneled local daemon
- Ship a helper subcommand: `ocd daemon --expose` using `cloudflared` (opt-in, documented)
- Ship a helper subcommand: `od daemon --expose` using `cloudflared` (opt-in, documented)
**Dev experience:**
- `ocd skill test` with cheap-model runs
- Skill author starter template: `ocd skill scaffold`
- `od skill test` with cheap-model runs
- Skill author starter template: `od skill scaffold`
### v1 exit criteria
1. All four modes fully functional.
2. Three adapters working (Claude Code, Codex, Cursor Agent); fallback chain shipping.
3. PDF + PPTX export working for at least the `magazine-web-ppt` + `pitch-deck` skills.
4. Deployed example at `demo.open-claude-design.dev` (Topology C).
4. Deployed example at `demo.open-design.dev` (Topology C).
5. Skill author docs published; at least one third-party skill submitted.
6. Documentation site rebuilt from these spec docs.
@@ -176,7 +176,7 @@ v2 isn't promised. It's the direction if v1 lands.
| `guizang-ppt-skill` or similar upstream skill changes format | default deck skill breaks | pin git SHA in our default install; monitor upstream |
| DESIGN.md format evolves in awesome-claude-design | incompatibility | track upstream; adopt changes; our resolver is tolerant of missing sections |
| Anthropic ships an open-source Claude Design | differentiation collapses | our moat is the "uses user's existing agent" angle; Anthropic is unlikely to ship that |
| Skill security (malicious skill via `ocd skill add`) | user machine compromise | install-time warning; rely on agent's own permission model; document best practices |
| Skill security (malicious skill via `od skill add`) | user machine compromise | install-time warning; rely on agent's own permission model; document best practices |
---
Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

+41 -41
View File
@@ -2,9 +2,9 @@
**Parent:** [`spec.md`](spec.md) · **Siblings:** [`architecture.md`](architecture.md) · [`agent-adapters.md`](agent-adapters.md) · [`modes.md`](modes.md)
A **Skill** is the atomic unit of design capability in OCD. We adopt Claude Code's `SKILL.md` convention verbatim as the base format, then add optional fields for design-specific features (preview type, input schema, slider parameters). A skill written for plain Claude Code runs in OCD. An OCD skill that doesn't use our extensions runs in plain Claude Code.
A **Skill** is the atomic unit of design capability in OD. We adopt Claude Code's `SKILL.md` convention verbatim as the base format, then add optional fields for design-specific features (preview type, input schema, slider parameters). A skill written for plain Claude Code runs in OD. An OD skill that doesn't use our extensions runs in plain Claude Code.
> **Compatibility promise:** A skill like [`guizang-ppt-skill`](https://github.com/op7418/guizang-ppt-skill) works in OCD **without modification**. It just drops into `~/.claude/skills/` and OCD discovers it.
> **Compatibility promise:** A skill like [`guizang-ppt-skill`](https://github.com/op7418/guizang-ppt-skill) works in OD **without modification**. It just drops into `~/.claude/skills/` and OD discovers it.
---
@@ -40,11 +40,11 @@ triggers:
Body is free-form Markdown that describes the workflow the agent should follow — typically a numbered step list plus principles. This is what [guizang-ppt-skill](https://github.com/op7418/guizang-ppt-skill) does.
**OCD reads all of this as-is.** No changes required.
**OD reads all of this as-is.** No changes required.
## 2. OCD extensions (optional)
## 2. OD extensions (optional)
Skills can declare additional front-matter fields to unlock OCD-specific UI. All fields are optional; absent fields fall back to sensible defaults.
Skills can declare additional front-matter fields to unlock OD-specific UI. All fields are optional; absent fields fall back to sensible defaults.
```yaml
---
@@ -52,9 +52,9 @@ name: magazine-web-ppt
description: …
triggers: […]
# --- OCD extensions below this line ---
# --- OD extensions below this line ---
ocd:
od:
mode: deck # one of: prototype | deck | template | design-system
preview:
type: html # html | jsx | pptx | markdown
@@ -94,21 +94,21 @@ ocd:
---
```
### 2.1 What OCD uses each field for
### 2.1 What OD uses each field for
| Field | Used by |
|---|---|
| `ocd.mode` | routing (which mode picker the skill shows up under) |
| `ocd.preview.type` | picking the right iframe renderer |
| `ocd.design_system.requires` | whether to inject `DESIGN.md` |
| `ocd.design_system.sections` | pruning the injected DESIGN.md to relevant sections only (token savings) |
| `ocd.inputs` | rendering a typed form in the sidebar instead of only free-text |
| `ocd.parameters` | rendering live sliders that re-prompt on change |
| `ocd.outputs.primary` | which file the iframe loads |
| `ocd.outputs.secondary` | which files export pipelines read (e.g. `slides.json` for PPTX) |
| `ocd.capabilities_required` | gating: if the active agent lacks surgical edit, comment mode is disabled for this skill |
| `od.mode` | routing (which mode picker the skill shows up under) |
| `od.preview.type` | picking the right iframe renderer |
| `od.design_system.requires` | whether to inject `DESIGN.md` |
| `od.design_system.sections` | pruning the injected DESIGN.md to relevant sections only (token savings) |
| `od.inputs` | rendering a typed form in the sidebar instead of only free-text |
| `od.parameters` | rendering live sliders that re-prompt on change |
| `od.outputs.primary` | which file the iframe loads |
| `od.outputs.secondary` | which files export pipelines read (e.g. `slides.json` for PPTX) |
| `od.capabilities_required` | gating: if the active agent lacks surgical edit, comment mode is disabled for this skill |
### 2.2 If a skill omits `ocd:` entirely
### 2.2 If a skill omits `od:` entirely
Defaults:
- `mode`: inferred from name/description (best-effort keyword match) or "prototype"
@@ -133,15 +133,15 @@ Conflicts by `name` resolve to the higher-priority version. All locations are wa
### Symlink strategy (borrowed from [cc-switch](https://github.com/farion1231/cc-switch))
`cc-switch` maintains a central skill dir at `~/.cc-switch/skills/` and symlinks it into each agent's expected location (`~/.claude/skills/`, `~/.codex/skills/`, etc.). OCD can opt into the same model:
`cc-switch` maintains a central skill dir at `~/.cc-switch/skills/` and symlinks it into each agent's expected location (`~/.claude/skills/`, `~/.codex/skills/`, etc.). OD can opt into the same model:
```
~/.open-claude-design/skills/
~/.open-design/skills/
magazine-web-ppt/ (canonical location)
~/.claude/skills/
magazine-web-ppt → ~/.open-claude-design/skills/magazine-web-ppt
magazine-web-ppt → ~/.open-design/skills/magazine-web-ppt
~/.codex/skills/
magazine-web-ppt → ~/.open-claude-design/skills/magazine-web-ppt
magazine-web-ppt → ~/.open-design/skills/magazine-web-ppt
```
One install → every agent sees the skill. This is optional; users who only use one agent don't need it.
@@ -181,17 +181,17 @@ Each mode expects a slightly different skill shape. The required outputs and exp
- **Preview:** `markdown` (render the resulting DESIGN.md with a sample-components preview).
- **Primary output:** `DESIGN.md`.
- **Typical workflow:** analyze input → draft 9 sections per awesome-claude-design schema → generate sample component preview → finalize.
- **Post-run:** OCD prompts the user to set this DESIGN.md as the project's active design system.
- **Post-run:** OD prompts the user to set this DESIGN.md as the project's active design system.
## 5. The DESIGN.md as skill context
Every nondesign-system skill (modes 13) can consume the active `DESIGN.md`. OCD injects it as:
Every nondesign-system skill (modes 13) can consume the active `DESIGN.md`. OD injects it as:
1. **System-prompt prefix** (required sections only, per `ocd.design_system.sections`).
1. **System-prompt prefix** (required sections only, per `od.design_system.sections`).
2. **File available in CWD** named `DESIGN.md` — skills can `Read` it directly via their agent.
3. **Template variable** `{{ design_system }}` if the skill body references it in Mustache-style.
The 9-section DESIGN.md format is **not invented by OCD**; it's the [awesome-claude-design](https://github.com/VoltAgent/awesome-claude-design) convention, reproduced here for convenience:
The 9-section DESIGN.md format is **not invented by OD**; it's the [awesome-claude-design](https://github.com/VoltAgent/awesome-claude-design) convention, reproduced here for convenience:
```markdown
# <Brand Name>
@@ -212,27 +212,27 @@ Full schema and examples: [`schemas/design-system.md`](schemas/design-system.md)
## 6. Skill installation
```sh
ocd skill add https://github.com/op7418/guizang-ppt-skill
# → clones into ~/.open-claude-design/skills/magazine-web-ppt
od skill add https://github.com/op7418/guizang-ppt-skill
# → clones into ~/.open-design/skills/magazine-web-ppt
# → symlinks into ~/.claude/skills/ (and any other active agent dirs)
# → re-indexes registry
ocd skill add ./path/to/my-skill
od skill add ./path/to/my-skill
# → symlinks local dir (no copy) into skills registry
ocd skill list
od skill list
# → table: name, mode, source, agent compatibility
ocd skill remove <name>
od skill remove <name>
# → unlinks; does not delete the source
```
## 7. Worked example — running `guizang-ppt-skill` under OCD
## 7. Worked example — running `guizang-ppt-skill` under OD
The skill is unchanged. Here's the full path:
1. User: `ocd skill add https://github.com/op7418/guizang-ppt-skill`
2. Registry indexes it. No `ocd:` block in front-matter → defaults applied:
1. User: `od skill add https://github.com/op7418/guizang-ppt-skill`
2. Registry indexes it. No `od:` block in front-matter → defaults applied:
- `mode`: inferred from body mentioning "PPT" → `deck`.
- `preview.type`: sniffed from `assets/template.html``html`.
- `preview.entry`: `index.html` (convention).
@@ -241,12 +241,12 @@ The skill is unchanged. Here's the full path:
4. User types "给我做一份杂志风 8 页投资人 PPT".
5. Daemon dispatches to active agent (Claude Code) with:
- system message: skill's `SKILL.md` body
- cwd: `./.ocd/artifacts/2026-04-24-pitch-deck/`
- cwd: `./.od/artifacts/2026-04-24-pitch-deck/`
- files already placed in cwd: `template.html` (from skill's `assets/`)
6. Agent runs its 6-step workflow (clarify → copy template → populate → self-check → preview → refine).
7. OCD streams the agent's tool calls as UI events; artifact dir grows.
7. OD streams the agent's tool calls as UI events; artifact dir grows.
8. Agent signals done; daemon sets preview iframe to `index.html`.
9. User clicks "Export PPTX" — export pipeline notices the skill has no `slides.json` output (the upstream skill doesn't produce one). OCD falls back to "print to PDF then page-to-slide PPTX," which is uglier but works. This is a known limitation documented per-skill.
9. User clicks "Export PPTX" — export pipeline notices the skill has no `slides.json` output (the upstream skill doesn't produce one). OD falls back to "print to PDF then page-to-slide PPTX," which is uglier but works. This is a known limitation documented per-skill.
## 8. Writing a new skill — minimal example
@@ -266,7 +266,7 @@ description: |
triggers:
- "saas landing"
- "marketing page"
ocd:
od:
mode: prototype
preview:
type: html
@@ -303,7 +303,7 @@ ocd:
## 9. Testing skills
A skill ships with optional test inputs that OCD uses for CI:
A skill ships with optional test inputs that OD uses for CI:
```
<skill-root>/
@@ -313,10 +313,10 @@ A skill ships with optional test inputs that OCD uses for CI:
└── basic.expected.regex.txt # text regex assertions against the primary output
```
`ocd skill test <name>` runs the skill against each case using a cheap model (e.g. Haiku 4.5) and asserts on the manifest + regex. Low-fidelity but catches structural regressions.
`od skill test <name>` runs the skill against each case using a cheap model (e.g. Haiku 4.5) and asserts on the manifest + regex. Low-fidelity but catches structural regressions.
## 10. Open questions
- **Skill signing.** Can we verify a skill hasn't been tampered with between publish and install? Simplest answer: `ocd skill add` records the git commit SHA; reinstall-on-update warns on signature change. Deferred to v1.
- **Skill signing.** Can we verify a skill hasn't been tampered with between publish and install? Simplest answer: `od skill add` records the git commit SHA; reinstall-on-update warns on signature change. Deferred to v1.
- **Skill composition.** Can a `prototype-skill` call a `deck-skill` for a sub-artifact? Not in v1; skills are leaf-level. Composition would require a meta-skill concept, which is speculative.
- **Parameter stability.** When sliders change, should the agent re-plan or just re-render? Lean: re-render (fast path), with an "also re-plan" button for larger changes.
+12 -12
View File
@@ -1,9 +1,9 @@
# Open Claude Design — Product Spec
# Open Design — Product Spec
**Status:** Draft v0.1 · 2026-04-24
**Scope:** Product definition, scenarios, non-goals, high-level modules, and positioning against both [Anthropic's Claude Design][cd] and the existing open-source alternative ([Open CoDesign][ocod]).
[cd]: https://www.anthropic.com/news/claude-design
[cd]: https://x.com/claudeai/status/2045156267690213649
[ocod]: https://github.com/OpenCoworkAI/open-codesign
[guizang]: https://github.com/op7418/guizang-ppt-skill
[multica]: https://github.com/multica-ai/multica
@@ -27,7 +27,7 @@ Other docs:
## 2. Core bets (and why they're different)
| # | Bet | [Anthropic Claude Design][cd] | [Open CoDesign][ocod] | OCD |
| # | Bet | [Anthropic Claude Design][cd] | [Open CoDesign][ocod] | OD |
|---|---|---|---|---|
| 1 | Where the product runs | claude.ai only | Local Electron app | **Next.js web app**`pnpm dev`, `vercel deploy`, or `docker compose up` |
| 2 | Who owns the agent loop | Anthropic, closed | [Open CoDesign][ocod] itself, via [`pi-ai`][piai] | **The user's existing code agent CLI** (Claude Code, Codex, Cursor Agent, Gemini CLI, OpenCode, OpenClaw); direct Anthropic API as fallback |
@@ -47,16 +47,16 @@ The differentiation is not "yet another design generator." It is **an integratio
## 4. User scenarios
### S1 — "Give me a prototype"
User opens the web app, types *"Airbnb-style search page, use our internal design system"*, OCD picks the `prototype-skill`, resolves the user's `DESIGN.md`, dispatches to Claude Code with both files plus the brief, streams tool calls into the UI, and renders the resulting HTML in an iframe preview. User clicks an element, drops a comment, the agent rewrites just that region.
User opens the web app, types *"Airbnb-style search page, use our internal design system"*, OD picks the `prototype-skill`, resolves the user's `DESIGN.md`, dispatches to Claude Code with both files plus the brief, streams tool calls into the UI, and renders the resulting HTML in an iframe preview. User clicks an element, drops a comment, the agent rewrites just that region.
### S2 — "Make me a deck"
User says *"8-slide magazine-style pitch deck for my seed round"*. OCD routes to `deck-skill` (a fork of [`guizang-ppt-skill`][guizang]). Output is a single-file HTML deck; preview is the deck itself with arrow-key navigation; export is PDF/PPTX.
User says *"8-slide magazine-style pitch deck for my seed round"*. OD routes to `deck-skill` (a fork of [`guizang-ppt-skill`][guizang]). Output is a single-file HTML deck; preview is the deck itself with arrow-key navigation; export is PDF/PPTX.
### S3 — "Start from a template"
User picks "SaaS landing — Stripe-ish" from a gallery. Template is a pre-filled artifact bundle plus a `DESIGN.md` reference. Agent only fills content; structure is already there. This is the fastest mode — useful for users who don't want to prompt at all.
### S4 — "Set up our design system"
User uploads a screenshot, brand guide PDF, or Figma link. OCD runs `design-system-skill` which produces a `DESIGN.md` following the 9-section format. That file is then referenced by every subsequent generation — prototypes, decks, templates all pick up the tokens.
User uploads a screenshot, brand guide PDF, or Figma link. OD runs `design-system-skill` which produces a `DESIGN.md` following the 9-section format. That file is then referenced by every subsequent generation — prototypes, decks, templates all pick up the tokens.
These four scenarios map 1:1 to the four modes in [`modes.md`](modes.md).
@@ -69,7 +69,7 @@ These four scenarios map 1:1 to the four modes in [`modes.md`](modes.md).
└────────────┬─────────────────────────────────┬───────────────────┘
│ WebSocket (JSON-RPC) │ HTTPS (BYOK direct)
┌────────────▼──────────────────┐ ┌────────▼─────────────────┐
│ Local Daemon (ocd daemon) │ │ Anthropic Messages API │
│ Local Daemon (od daemon) │ │ Anthropic Messages API │
│ · agent detection │ │ (fallback when no CLI) │
│ · skill registry │ └──────────────────────────┘
│ · artifact store │
@@ -88,7 +88,7 @@ Module responsibilities:
- **Daemon** — long-running local process. Detects agents, registers skills, manages artifacts on disk, resolves the active design system, and brokers WebSocket sessions.
- **Agent adapters** — one adapter per supported CLI; see [`agent-adapters.md`](agent-adapters.md).
- **Skill registry** — scans `~/.claude/skills/`, `./skills/`, and `./.claude/skills/`; merges and exposes a typed catalog.
- **Artifact store** — project-scoped folder (default `./.ocd/`) holding generated files, version snapshots (git-friendly), and per-artifact metadata.
- **Artifact store** — project-scoped folder (default `./.od/`) holding generated files, version snapshots (git-friendly), and per-artifact metadata.
- **Design-system resolver** — loads the active `DESIGN.md`, injects it as skill context.
- **Preview renderer** — sandboxed iframe with vendored React + Babel for JSX artifacts; plain iframe for HTML; PDF via the daemon's headless Chrome.
- **Export pipeline** — HTML (inlined), PDF, PPTX, ZIP, Markdown.
@@ -122,20 +122,20 @@ We are **not** trying to out-feature [Claude Design][cd]. Claude Design has Anth
- **Skills as files.** Version them in git. Fork them. Ship them to teammates as a repo. Run your team's branded deck skill without rebuilding a product.
- **Design systems as files.** A `DESIGN.md` is an artifact you can review in a PR. Claude Design's "design system" lives in an ephemeral chat.
In short: Claude Design is a product; OCD is a **substrate**.
In short: Claude Design is a product; OD is a **substrate**.
## 9. Success criteria for v1
- One developer can `git clone && pnpm install && pnpm dev`, point at their Claude Code install, and produce a prototype in under 5 minutes.
- A third party can author a skill in a separate git repo, publish it, and have a user install it by running `ocd skill add <git-url>` without touching OCD's source.
- A design system author can write a `DESIGN.md`, point OCD at it, and have the style propagate across prototype / deck / template outputs.
- A third party can author a skill in a separate git repo, publish it, and have a user install it by running `od skill add <git-url>` without touching OD's source.
- A design system author can write a `DESIGN.md`, point OD at it, and have the style propagate across prototype / deck / template outputs.
- Deploying to Vercel with a local daemon works end-to-end (the daemon is reachable via localhost tunnel or a user-provided URL).
- Swapping the underlying agent from Claude Code to Codex requires zero skill changes.
## 10. Open questions (to resolve before coding)
- **Daemon ↔ Vercel bridge.** Do we ship a reverse-tunnel helper (like `cloudflared`), require the user to set one up, or punt to "run locally for now"? My current lean: punt for MVP, helper in v1.
- **Artifact versioning.** Git, or SQLite, or both? [Open CoDesign][ocod] uses SQLite; that's easier but less reviewable. Lean: write artifacts as plain files + a `.ocd/history.jsonl` log. Git is the user's business.
- **Artifact versioning.** Git, or SQLite, or both? [Open CoDesign][ocod] uses SQLite; that's easier but less reviewable. Lean: write artifacts as plain files + a `.od/history.jsonl` log. Git is the user's business.
- **Comment mode on non-Claude-Code agents.** Claude Code supports surgical edits via its tool loop. Codex and Gemini CLI are less graceful. Do we degrade to "regenerate whole file" for weaker agents? Lean: yes, document clearly in the adapter table.
- **Skill trust model.** Skills can shell out via the agent. We should at minimum warn on install, and probably sandbox the agent's cwd to the project directory. Claude Code's permission mode handles this for us if we use it; Codex is looser. Needs a per-adapter note.