Skip to content

Latest commit

Β 

History

History
230 lines (180 loc) Β· 13.8 KB

File metadata and controls

230 lines (180 loc) Β· 13.8 KB

Quickstart

English Β· Deutsch Β· ζ—₯本θͺž

Run the full product locally.

Environment requirements

  • Node.js: ~24 (Node 24.x). The repo enforces this through package.json#engines.
  • pnpm: 10.33.x. The repo pins pnpm@10.33.2 through packageManager; use Corepack so the pinned version is selected automatically.
  • OS: macOS, Linux, and WSL2 are the primary paths. Windows native should work for most flows, but WSL2 is the safer baseline.
  • Optional local agent CLI: Claude Code, Codex, Devin for Terminal, Gemini CLI, OpenCode, Cursor Agent, Qwen, GitHub Copilot CLI, etc. If none are installed, use the BYOK API mode from Settings.

nvm / fnm are optional convenience tools, not required project setup. If you use one, install/select Node 24 before running pnpm:

# nvm
nvm install 24
nvm use 24

# fnm
fnm install 24
fnm use 24

Then enable Corepack and let the repo select pnpm:

corepack enable
corepack pnpm --version   # should print 10.33.2

One-shot (dev mode)

corepack enable
pnpm install
pnpm tools-dev run web # starts daemon + web in the foreground
# open the web URL printed by tools-dev

For the desktop shell and all managed sidecars in the background:

pnpm tools-dev # starts daemon + web + desktop in the background

On first load, the app detects your installed code-agent CLI (Claude Code / Codex / Devin for Terminal / Gemini / OpenCode / Cursor Agent / Qwen), 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.

The Design system dropdown ships with 129 design systems β€” 2 hand-authored starters (Neutral Modern, Warm Editorial), 70 bundled product systems, and 57 design skills sourced from awesome-design-skills. Pick one to skin every prototype in that brand's aesthetic.

The Skill dropdown groups by mode (Prototype / Deck / Template / Design system) and shows the default skill per mode with a Β· default suffix. Bundled skills:

  • Prototype β€” web-prototype (generic), saas-landing, dashboard, pricing-page, docs-page, blog-post, mobile-app.
  • Deck / PPT β€” simple-deck (single-file horizontal swipe) and magazine-web-ppt (the guizang-ppt bundle from op7418/guizang-ppt-skill β€” default for deck mode, ships its own assets/template + 4 references). Skills with side files get an automatic "Skill root (absolute)" preamble so the agent can resolve assets/template.html and references/*.md against the real on-disk path instead of its CWD.

Pair a skill with a design system and a single prompt produces a layout-appropriate prototype or deck in the chosen visual language.

Other scripts

pnpm tools-dev                 # daemon + web + desktop in the background
pnpm tools-dev start web       # daemon + web in the background
pnpm tools-dev run web         # daemon + web in the foreground (e2e/dev server)
pnpm tools-dev restart         # restart daemon + web + desktop
pnpm tools-dev restart --daemon-port 7457 --web-port 5175
pnpm tools-dev status          # inspect managed runtimes
pnpm tools-dev logs            # show daemon/web/desktop logs
pnpm tools-dev check           # status + recent logs + common diagnostics
pnpm tools-dev stop            # stop managed runtimes
pnpm --filter @open-design/daemon build  # build apps/daemon/dist/cli.js for `od`
pnpm build                     # production build + static export to apps/web/out/
pnpm typecheck                 # workspace typecheck

pnpm tools-dev is the only local lifecycle entry point. Do not use the removed legacy root aliases (pnpm dev, pnpm dev:all, pnpm daemon, pnpm preview, pnpm start).

During local development, tools-dev starts the daemon first, passes its port into apps/web, and apps/web/next.config.ts rewrites /api/*, /artifacts/*, and /frames/* to that daemon port so the App Router app can talk to the sibling Express process without CORS setup.

Media generation / agent dispatcher checks

Image, video, audio, and HyperFrames skills call the local od CLI through environment variables injected by the daemon when it spawns an agent:

  • OD_BIN β€” absolute path to apps/daemon/dist/cli.js.
  • OD_DAEMON_URL β€” the running daemon URL.
  • OD_PROJECT_ID β€” the active project id.
  • OD_PROJECT_DIR β€” the active project's file directory.

If media generation fails with OD_BIN: parameter not set, apps/daemon/dist/cli.js missing, or failed to reach daemon at http://127.0.0.1:0, rebuild the daemon CLI and restart the managed runtime:

pnpm --filter @open-design/daemon build
pnpm tools-dev restart --daemon-port 7457 --web-port 5175
ls -la apps/daemon/dist/cli.js
curl -s http://127.0.0.1:7457/api/health

Then open the project from the Open Design app again instead of resuming an old terminal agent session. A daemon-spawned agent should see values like:

echo "OD_BIN=$OD_BIN"
echo "OD_PROJECT_ID=$OD_PROJECT_ID"
echo "OD_PROJECT_DIR=$OD_PROJECT_DIR"
echo "OD_DAEMON_URL=$OD_DAEMON_URL"
ls -la "$OD_BIN"

OD_DAEMON_URL must be a real daemon port such as http://127.0.0.1:7457, not http://127.0.0.1:0. The :0 value is only an internal "pick a free port" launch hint and should not leak into agent sessions.

For the daemon-only production mode, the daemon serves the static Next.js export itself at http://localhost:7456, so no reverse proxy is involved.

If you place nginx in front of the daemon, keep SSE routes unbuffered and uncompressed. A common failure is the browser console showing net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK) after 80-90 seconds because nginx gzip on buffers chunked SSE responses even when the daemon sends X-Accel-Buffering: no.

location /api/ {
    proxy_pass http://127.0.0.1:7456;

    proxy_buffering off;
    gzip off;

    proxy_read_timeout 86400s;
    proxy_send_timeout 86400s;
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Two execution modes

Mode Picker value How a request flows
Local CLI (default when daemon detects an agent) "Local CLI" Frontend β†’ daemon /api/chat β†’ spawn(<agent>, ...) β†’ stdout β†’ SSE β†’ artifact parser β†’ preview
Anthropic API (fallback / no CLI) "Anthropic API Β· BYOK" Frontend β†’ @anthropic-ai/sdk direct (dangerouslyAllowBrowser) β†’ artifact parser β†’ preview

Both modes feed the same <artifact> parser and the same sandboxed iframe. The only thing that differs is the transport and the system-prompt delivery (local CLIs have no separate system channel, so the composed prompt is folded into the user message).

Prompt composition

For every send, the app builds a system prompt from three layers and sends it to the provider:

BASE_SYSTEM_PROMPT   (output contract: wrap in <artifact>, no code fences)
   + active design system body  (DESIGN.md β€” palette/type/layout)
   + active skill body          (SKILL.md β€” workflow and output rules)

Swap the skill or the design system in the top bar and the next send uses the new stack. Bodies are cached in-memory per session so this is a single daemon fetch per pick.

File map

open-design/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ daemon/                # Node/Express β€” spawns local agents + serves APIs
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ cli.ts             # `od` bin entry
β”‚   β”‚       β”œβ”€β”€ server.ts          # /api/* + static serving
β”‚   β”‚       β”œβ”€β”€ agents.ts          # PATH scanner for claude/codex/devin/gemini/opencode/cursor-agent/qwen/copilot
β”‚   β”‚       β”œβ”€β”€ skills.ts          # SKILL.md loader (frontmatter parser)
β”‚   β”‚       └── design-systems.ts  # DESIGN.md loader
β”‚   β”‚   β”œβ”€β”€ sidecar/           # tools-dev daemon sidecar wrapper
β”‚   β”‚   └── tests/             # daemon package tests
β”‚   β”œβ”€β”€ web/                   # Next.js 16 App Router + React client
β”‚       β”œβ”€β”€ app/               # App Router entrypoints
β”‚       β”œβ”€β”€ src/               # React + TypeScript client/runtime modules
β”‚       β”‚   β”œβ”€β”€ App.tsx        # orchestrates mode / skill / DS pickers + send
β”‚       β”‚   β”œβ”€β”€ providers/     # daemon + BYOK API transports
β”‚       β”‚   β”œβ”€β”€ prompts/       # system, discovery, directions, deck framework
β”‚       β”‚   β”œβ”€β”€ artifacts/     # streaming <artifact> parser + manifests
β”‚       β”‚   β”œβ”€β”€ runtime/       # iframe srcdoc, markdown, export helpers
β”‚       β”‚   └── state/         # localStorage + daemon-backed project state
β”‚       β”œβ”€β”€ sidecar/           # tools-dev web sidecar wrapper
β”‚       └── next.config.ts     # tools-dev rewrites + prod apps/web/out export config
β”‚   └── desktop/               # Electron runtime, launched/inspected by tools-dev
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ contracts/             # shared web/daemon app contracts
β”‚   β”œβ”€β”€ sidecar-proto/         # Open Design sidecar protocol contract
β”‚   β”œβ”€β”€ sidecar/               # generic sidecar runtime primitives
β”‚   └── platform/              # generic process/platform primitives
β”œβ”€β”€ tools/dev/                 # `pnpm tools-dev` lifecycle and inspect CLI
β”œβ”€β”€ e2e/                       # Playwright UI + external integration/Vitest harness
β”œβ”€β”€ skills/                    # SKILL.md β€” drops in from any Claude Code skill repo
β”‚   β”œβ”€β”€ web-prototype/         # generic single-screen prototype (default for prototype mode)
β”‚   β”œβ”€β”€ saas-landing/          # marketing page (hero / features / pricing / CTA)
β”‚   β”œβ”€β”€ dashboard/             # admin / analytics dashboard
β”‚   β”œβ”€β”€ pricing-page/          # standalone pricing + comparison
β”‚   β”œβ”€β”€ docs-page/             # 3-column documentation layout
β”‚   β”œβ”€β”€ blog-post/             # editorial long-form
β”‚   β”œβ”€β”€ mobile-app/            # phone-frame single screen
β”‚   β”œβ”€β”€ simple-deck/           # minimal horizontal-swipe deck
β”‚   └── guizang-ppt/           # magazine-web-ppt β€” bundled deck/PPT default
β”‚       β”œβ”€β”€ SKILL.md
β”‚       β”œβ”€β”€ assets/template.html
β”‚       └── references/{themes,layouts,components,checklist}.md
β”œβ”€β”€ design-systems/            # DESIGN.md β€” 9-section schema (awesome-claude-design)
β”‚   β”œβ”€β”€ default/               # Neutral Modern (starter)
β”‚   β”œβ”€β”€ warm-editorial/        # Warm Editorial (starter)
β”‚   β”œβ”€β”€ README.md              # catalog overview
β”‚   └── …129 systems           # 2 starters Β· 70 product systems Β· 57 design skills
β”œβ”€β”€ scripts/sync-design-systems.ts    # re-import from upstream getdesign tarball
β”œβ”€β”€ docs/                      # product vision + spec
β”œβ”€β”€ .od/                       # runtime data (gitignored, auto-created)
β”‚   β”œβ”€β”€ app.sqlite              #   projects / conversations / messages / tabs
β”‚   β”œβ”€β”€ artifacts/              #   one-off "Save to disk" renders
β”‚   └── projects/<id>/          #   per-project working dir + agent cwd
β”œβ”€β”€ pnpm-workspace.yaml        # apps/* + packages/* + tools/* + e2e
└── package.json               # root quality scripts + `od` bin

Troubleshooting

  • "no agents found on PATH" β€” install one of: claude, codex, devin, gemini, opencode, cursor-agent, qwen, copilot. Or switch to "Anthropic API Β· BYOK" in the top bar and paste a key in Settings.
  • daemon 500 on /api/chat β€” check the daemon terminal for the stderr tail; usually the CLI rejected its args. Different CLIs take different argv shapes; see apps/daemon/src/agents.ts buildArgs if you need to tweak.
  • media generation says OD_BIN is missing or daemon URL is :0 β€” run the media dispatcher checks above. Do not resume the old CLI session; reopen the project from the Open Design app so the daemon can inject fresh OD_* variables.
  • Codex loads too much plugin context β€” start Open Design with OD_CODEX_DISABLE_PLUGINS=1 pnpm tools-dev to make daemon-spawned Codex processes run with --disable plugins.
  • artifact never renders β€” the model produced text without wrapping in <artifact>. Confirm the system prompt is going through (check daemon log) and consider switching to a more capable model or a stricter skill.

Mapping back to the vision

This Quickstart is the runnable seed of the spec in docs/. The spec describes where this grows (see docs/roadmap.md). Highlights:

  • docs/architecture.md describes the shipped stack: Next.js 16 App Router in front, local daemon behind it, and apps/web/next.config.ts rewrites in dev to keep the browser talking to the same /api surface.
  • docs/skills-protocol.md describes the full od: frontmatter (typed inputs, sliders, capability gating). This MVP reads name / description / triggers / od.mode / od.design_system.requires only β€” extend apps/daemon/src/skills.ts to add the rest.
  • docs/agent-adapters.md foresees richer dispatch (capability detection, streaming tool-calls). Our apps/daemon/src/agents.ts is a minimal dispatcher β€” enough to prove the wiring.
  • docs/modes.md lists four modes: prototype / deck / template / design-system. We ship skills for the first two; the picker already filters by mode.