|
| 1 | +# Project Consensus |
| 2 | + |
| 3 | +The single source of truth for what we agreed on, what is shipped, what is open, and how a new contributor (human or AI) gets going. |
| 4 | + |
| 5 | +Last updated: 2026-04-18 |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## 1. Product north star |
| 10 | + |
| 11 | +open-codesign is a **desktop AI design tool**. The user types a prompt, the app produces an HTML / PDF / PPTX / asset bundle. It is the open-source counterpart to Anthropic's [Claude Design](https://www.anthropic.com/news/claude-design-anthropic-labs). |
| 12 | + |
| 13 | +- Form factor: **Electron desktop** (Mac / Win / Linux) |
| 14 | +- Model layer: **`@mariozechner/pi-ai`** (multi-provider — Anthropic, OpenAI, Gemini, OpenRouter, DeepSeek, Ollama, …) |
| 15 | +- Auth: **BYOK only** (no proxy, no cloud account) |
| 16 | +- Storage: **local-first** (SQLite + TOML config) |
| 17 | +- Design language: **aligned with [open-cowork](https://github.com/OpenCoworkAI/open-cowork)** (warm beige Claude-style) |
| 18 | +- License: **Apache-2.0** |
| 19 | + |
| 20 | +The full vision is in [`docs/VISION.md`](./docs/VISION.md). The eight killer demos we committed to replicate are listed there. |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## 2. Hard constraints (non-negotiable, every PR is checked) |
| 25 | + |
| 26 | +1. Install size **≤ 80 MB** |
| 27 | +2. Prod dep count **≤ 30** |
| 28 | +3. **No bundled model runtimes** (no Ollama / Python / browser binaries) |
| 29 | +4. **Apache-2.0 compatible deps only** (reject GPL / AGPL / SSPL / proprietary) |
| 30 | +5. **Lazy-load every heavy feature** (PPTX, web capture, codebase scan, …) |
| 31 | +6. **No silent fallbacks** — errors throw with a structured `code` and surface in UI |
| 32 | +7. **All UI uses `packages/ui` tokens** — no hardcoded colors / fonts / px |
| 33 | +8. **Schema-version everything that lives on disk** (config, SQLite, IPC, exports) |
| 34 | +9. **`§5b`**: every PR description marks ✅ on Compatible / Upgradeable / No-bloat / Elegant |
| 35 | +10. **DCO sign-off** on every commit (`git commit -s`) |
| 36 | + |
| 37 | +Full text: [`docs/PRINCIPLES.md`](./docs/PRINCIPLES.md). |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +## 3. Locked technical stack |
| 42 | + |
| 43 | +| Layer | Choice | Why | |
| 44 | +|---|---|---| |
| 45 | +| Package manager | pnpm + Turborepo | Workspaces + cache | |
| 46 | +| Lint + format | Biome (single tool) | Replaces ESLint + Prettier | |
| 47 | +| TypeScript | strict, `verbatimModuleSyntax`, `noUncheckedIndexedAccess` | No `any`, bracket notation for index access | |
| 48 | +| Tests | Vitest unit + Playwright E2E | Mock at `core` boundary, never SDK level | |
| 49 | +| Versioning | Changesets | Don't hand-edit `CHANGELOG.md` | |
| 50 | +| Node | 22 LTS (`.nvmrc`) | | |
| 51 | +| UI framework | React 19 + Vite 6 | Matches what AI generates natively | |
| 52 | +| Styles | Tailwind v4 + CSS variables | Tokens in `packages/ui/src/tokens.css` | |
| 53 | +| State | Zustand | Don't introduce Redux / MobX | |
| 54 | +| Components | Radix primitives + custom shadcn-style | Lucide icons only | |
| 55 | +| Sandbox renderer | Electron iframe `srcdoc` + esbuild-wasm + import maps | Chosen over Sandpack / WebContainers in [research/03](./docs/research/03-sandbox-runtime.md) | |
| 56 | +| PPTX export | `pptxgenjs` + `dom-to-pptx` (Tier 2) — Tier 1 is text-only | [research/04](./docs/research/04-pptx-export.md) | |
| 57 | +| Electron | latest stable, **NOT 41.x** (cross-origin isolation regression) | | |
| 58 | +| Persistent storage | `better-sqlite3` for history; TOML for config (no electron-store blob) | | |
| 59 | +| Credential storage | Electron `safeStorage` → `~/.config/open-codesign/config.toml` | | |
| 60 | +| i18n | `i18next` + `react-i18next` (en + zh-CN) — landing in #2 | | |
| 61 | + |
| 62 | +--- |
| 63 | + |
| 64 | +## 4. Repository layout |
| 65 | + |
| 66 | +``` |
| 67 | +apps/ |
| 68 | + desktop/ Electron shell (main + preload + renderer) |
| 69 | +packages/ |
| 70 | + core/ Generation orchestration (prompt → artifact) |
| 71 | + providers/ pi-ai wrapper + missing-capability layer |
| 72 | + runtime/ Sandbox iframe + overlay script |
| 73 | + ui/ Design tokens + Wordmark + base components |
| 74 | + artifacts/ Streaming <artifact> tag parser + zod schemas |
| 75 | + exporters/ HTML (live), PDF/PPTX/ZIP (stubbed in main) |
| 76 | + templates/ Built-in demo prompts + system prompts |
| 77 | + shared/ Types, zod schemas (ChatMessage, ModelRef, etc.) |
| 78 | + i18n/ en + zh-CN translations (landing in #2) |
| 79 | +website/ VitePress marketing site (en + zh) |
| 80 | +docs/ |
| 81 | + VISION.md |
| 82 | + PRINCIPLES.md |
| 83 | + ARCHITECTURE.md |
| 84 | + ROADMAP.md |
| 85 | + COLLABORATION.md |
| 86 | + DIFFERENTIATION.md |
| 87 | + RESEARCH_QUEUE.md Index of all research reports |
| 88 | + research/ 01-09: Claude Design teardown, sandbox, PPTX, pi-ai, onboarding UX, … |
| 89 | +examples/ Reproductions of the eight Claude Design demos |
| 90 | +.github/ |
| 91 | + workflows/ CI / Release / CodeQL / Scorecard / Codex bot / Dep review |
| 92 | + prompts/ Bot prompts (PR review, issue auto-response) |
| 93 | +``` |
| 94 | + |
| 95 | +Detailed package boundaries: [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md). |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +## 5. Current state — what is on `main` |
| 100 | + |
| 101 | +✅ Merged: |
| 102 | +- **#1 Onboarding wizard** (3 steps: Welcome / Paste-with-auto-detect / Choose Model) + `safeStorage` keychain + IPC + zod-validated payload |
| 103 | +- **#4 First demo wiring** (system prompt extracted to `packages/templates/src/system/`, real HTML exporter, PreviewToolbar, exporter IPC, `dialog.showSaveDialog`) |
| 104 | +- **#5 Marketing website** (VitePress + Tailwind v4 + en/zh + llms.txt + GitHub Pages deploy workflow) |
| 105 | +- **UIUX iteration v1** (4 commits: Wordmark component, EmptyMark SVG, full token scale — text/leading/tracking/space/motion + warm shadows + global focus-visible) |
| 106 | +- **Preload path fix** (electron-vite outputs `.mjs`, main process now loads it correctly) |
| 107 | + |
| 108 | +🔧 PRs open with conflicts (need manual resolution before merge): |
| 109 | +- **#2 i18n** — adds `packages/i18n`, refactors `BUILTIN_DEMOS` to per-locale, locale IPC. Conflicts with onboarding and first-demo on `App.tsx`, `store.ts`, `main/index.ts`, `preload/index.ts` |
| 110 | +- **#3 preview-ux** — Settings overlay (4 tabs), command palette (Cmd+K), Toast, Sidebar/PreviewPane/TopBar extraction, theme toggle. Conflicts on `App.tsx`, `store.ts` |
| 111 | +- **#6 reliability** — error boundaries, AbortController cancellation, retry with exponential backoff + 429 handling, iframe error reporting + overlay defense. Conflicts on `App.tsx`, `store.ts`, `core/index.ts`, `providers/index.ts` |
| 112 | +- **#7 exporters** — real PDF (puppeteer-core + system Chrome), real PPTX (pptxgenjs + CJK fix), real ZIP (zip-lib). Stacked on #4. Conflicts on `package.json`, `PreviewToolbar.tsx` |
| 113 | + |
| 114 | +🤖 Background agents — none currently running. |
| 115 | + |
| 116 | +--- |
| 117 | + |
| 118 | +## 6. The pilot demo — what works today |
| 119 | + |
| 120 | +Set up: |
| 121 | +```bash |
| 122 | +git clone git@github.com:OpenCoworkAI/open-codesign.git |
| 123 | +cd open-codesign |
| 124 | +pnpm install |
| 125 | +pnpm --filter @open-codesign/desktop dev |
| 126 | +``` |
| 127 | + |
| 128 | +Walk-through: |
| 129 | +1. App launches, shows the **Welcome** step of the onboarding wizard |
| 130 | +2. Click **Use my API key**, paste a real key (`sk-ant-…` for Anthropic, `sk-…` for OpenAI, `sk-or-…` for OpenRouter) |
| 131 | +3. The provider is auto-detected, the key is validated against `/v1/models`, the OS keychain stores the encrypted blob |
| 132 | +4. Step 3 picks default models (primary + fast) |
| 133 | +5. The chat shell appears with four starter chips |
| 134 | +6. Click any starter → press **Send** → the model streams an HTML artifact → it renders in the right pane |
| 135 | +7. Click **Export ▾ → HTML** → save anywhere → opens in browser |
| 136 | +8. **PDF / PPTX / ZIP** show as "Coming in Phase 2" until #7 lands |
| 137 | + |
| 138 | +Dev shortcut: `VITE_OPEN_CODESIGN_DEV_KEY=sk-ant-… pnpm dev` to skip onboarding and go straight to the chat. |
| 139 | + |
| 140 | +--- |
| 141 | + |
| 142 | +## 7. How to add a feature (the workflow) |
| 143 | + |
| 144 | +For a non-trivial change, follow [`docs/COLLABORATION.md`](./docs/COLLABORATION.md). Short version: |
| 145 | + |
| 146 | +1. **Open an Issue or Discussion first** if it isn't obvious. |
| 147 | +2. **Research first**: if the answer isn't already in `docs/research/`, write a short report and add a row to `RESEARCH_QUEUE.md`. |
| 148 | +3. **Plan**: for > 5 tool calls or > 3 files, drop a plan in `.claude/workspace/<slug>/task_plan.md`. |
| 149 | +4. **Worktree**: `git worktree add -b wt/<slug> .claude/worktrees/<slug> main` (gitignored). |
| 150 | +5. **Tier 1 only** — ship the simplest version that works (PRINCIPLES §5). |
| 151 | +6. **Run** `pnpm install && pnpm -r typecheck && pnpm lint && pnpm -r test` before pushing. |
| 152 | +7. **PR with the standard template**, signed (`git commit -s`). |
| 153 | +8. **Squash merge** to main after CI green and one human review. |
| 154 | +9. **Clean up** the worktree and delete the branch. |
| 155 | + |
| 156 | +Currently we are pre-alpha and solo, so we **squash-merge directly without external review** as soon as CI is green. Once we have outside contributors we restore the review gate. |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +## 8. CI / GitHub setup |
| 161 | + |
| 162 | +- **CI** (`.github/workflows/ci.yml`): matrix Mac / Win / Linux. Runs lint, typecheck, test. DCO check separately. |
| 163 | +- **Release** (`.github/workflows/release.yml`): only opens Changesets Version PRs. No publish or signing yet (that needs notarization certs). |
| 164 | +- **CodeQL / Scorecard / Dependency Review**: gated on `repo.visibility == 'public'`. Skipped while private. |
| 165 | +- **Codex bot PR review** + **issue auto-response**: gated on `vars.CODEX_BOT_ENABLED == 'true'`. To enable, set the var and add `OPENAI_API_KEY` + `OPENAI_BASE_URL` secrets. |
| 166 | +- **Renovate**: weekly grouped non-major updates; pi-ai pinned via group rule; **Electron 41.x explicitly excluded**. |
| 167 | +- **GitHub topics**: 20 set, including `ai-design`, `claude-design`, `byok`, `local-first`, `multi-model`, … |
| 168 | + |
| 169 | +--- |
| 170 | + |
| 171 | +## 9. Known gotchas (read before debugging) |
| 172 | + |
| 173 | +- **Preload path**: electron-vite outputs `out/preload/index.mjs`, NOT `.js`. The main process loads `index.mjs` and Electron 33+ supports it natively. (Fixed in `49985a9` follow-up.) |
| 174 | +- **pi-ai is single-maintainer** (`badlogic/pi-mono`, ~36k stars but bus-factor 1). Pin the version, never amend their library, wrap missing capabilities in `packages/providers`. |
| 175 | +- **Electron 41.x has a cross-origin isolation regression**. Renovate excludes it; do not bypass. |
| 176 | +- **`useLiteralKeys` Biome rule is OFF** — it conflicts with TS `noPropertyAccessFromIndexSignature` (we use bracket notation for env / config / record access). |
| 177 | +- **Tailwind v4 arbitrary length values**: use `text-[length:var(--text-xl)]`, not `text-[var(--text-xl)]` — the latter is treated as ambiguous and silently ignored. |
| 178 | +- **Squash-merge can leave conflict markers** if a rebase is partially done before the merge. Always grep for `<<<<<<<` after a merge to be safe. |
| 179 | +- **The `.gitignore` itself was once in conflict** (`.gitignore.add` artifact). If you see it, just `git checkout --ours .gitignore && rm -f .gitignore.add`. |
| 180 | + |
| 181 | +--- |
| 182 | + |
| 183 | +## 10. Open research items / things we deliberately don't know yet |
| 184 | + |
| 185 | +- **No exported HTML sample from Claude Design has been obtained.** Until we have one, the artifact schema in `packages/shared` is tentative. PRs that lock new persisted shapes are blocked. |
| 186 | +- **Bundle-size CI gate is documented but not yet wired** (no `size-limit` step in `ci.yml`). |
| 187 | +- **Mac notarization + Windows Authenticode** certs are not provisioned. Release workflow does not sign. |
| 188 | +- **Discord, ProductHunt hunter, public launch sequence** — all deferred until v0.1 ship readiness. |
| 189 | + |
| 190 | +--- |
| 191 | + |
| 192 | +## 11. Top backlog (post current PRs) |
| 193 | + |
| 194 | +Ordered by `(impact × ease)` per [`docs/research/09-polish-parity-backlog.md`](./docs/research/09-polish-parity-backlog.md): |
| 195 | + |
| 196 | +1. Resolve the four open PR conflicts (#2 i18n, #3 preview-ux, #6 reliability, #7 exporters) |
| 197 | +2. UIUX iteration v2 — chat history list, generation-in-progress states, settings drawer (push 7.5/10 → 9/10) |
| 198 | +3. Streaming generation in `core` (Tier 2 — currently blocking) |
| 199 | +4. Inline comment loop (`wt/inline-comment` per parity backlog) |
| 200 | +5. AI-generated custom sliders (`wt/sliders`) |
| 201 | +6. Three-column model A/B race (`wt/ab-race`) — highest viral potential |
| 202 | +7. CLI mode (`wt/cli`) |
| 203 | +8. Web capture + URL Style Steal (`wt/web-capture`) |
| 204 | +9. Codebase → Design System extraction (`wt/codebase-ds`) |
| 205 | +10. Mac notarization + Homebrew Cask (`wt/release-eng`) |
| 206 | + |
| 207 | +--- |
| 208 | + |
| 209 | +## 12. Where to look for what |
| 210 | + |
| 211 | +| If you want to … | Read | |
| 212 | +|---|---| |
| 213 | +| Understand WHY of any decision | `docs/research/NN-<topic>.md` | |
| 214 | +| See locked product decisions | `docs/VISION.md` | |
| 215 | +| See what NOT to do (CI-enforced) | `docs/PRINCIPLES.md` | |
| 216 | +| See package boundaries | `docs/ARCHITECTURE.md` | |
| 217 | +| See open-source conventions | `docs/COLLABORATION.md`, `CONTRIBUTING.md` | |
| 218 | +| Ship a new feature workflow | `docs/COLLABORATION.md` | |
| 219 | +| Ship a UI change | start at `packages/ui/src/tokens.css`, then `apps/desktop/src/renderer/src/` | |
| 220 | +| Add a model provider | `packages/providers/src/` (validate.ts shows the pattern) | |
| 221 | +| Add a built-in demo | `packages/templates/src/index.ts` | |
| 222 | +| Tune the system prompt | `packages/templates/src/system/design-generator.md` | |
| 223 | + |
| 224 | +--- |
| 225 | + |
| 226 | +## 13. Contact |
| 227 | + |
| 228 | +This is currently a 1-person project (hqhq1025) about to onboard a second contributor. Any of these channels work: |
| 229 | + |
| 230 | +- GitHub Issue (bugs / scoped requests) |
| 231 | +- GitHub Discussion (architecture / open-ended) |
| 232 | +- PR comment (per-line code conversation) |
| 233 | +- (Discord invite — TBD) |
| 234 | + |
| 235 | +When in doubt, open an Issue and link the relevant section of this document. |
0 commit comments