Adds the campaign stale-path banner (839f474a..d2d8104c), documents op-util, the shared host-logic module tables, the three input-ladder spines, the i18n panel-shard key workflow, block_on_anywhere, and the typed-error recipe; deletes claims the reorg made false (old file splits, 113-tool count, shell-core paths, five-file property panel). Every path named was existence-checked against the tree.
77 lines
5.3 KiB
Markdown
77 lines
5.3 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
> **The TypeScript OpenPencil has been retired.** `apps/web`, `apps/desktop`, `apps/cli`, and the `pen-*` packages (pen-types/core/engine/renderer/figma/mcp/ai-skills/sdk/react/acp) are gone. The product is now implemented in **Rust** (`crates/`) with a thin **wasm-backed web SDK** (`packages/op-web-sdk*`). Historical `// ported from pen-*` comments in the Rust sources name the retired TS as their origin — that code no longer exists in-tree; consult git history (last TS tag `v0.7.5`) if you need it.
|
|
|
|
Detailed module docs load automatically in subdirectories:
|
|
|
|
- **`crates/CLAUDE.md`** — Rust shell: crate layout, editor core, widgets, hosts (native/web/desktop), MCP, AI, orchestrator, codegen. **The canonical architecture doc.**
|
|
- **`packages/CLAUDE.md`** — Remaining packages (op-web-sdk web viewer SDK family).
|
|
|
|
## Commands
|
|
|
|
Tooling is **Cargo** (Rust — the product). The root has **no `package.json`**; the JS/**Bun** tooling for the web SDK lives under `packages/` — run SDK/JS scripts from there.
|
|
|
|
- **Web dev server (Rust):** `bash scripts/start-web-rust.sh`
|
|
- **Build (Rust):** `cargo build --workspace --release`
|
|
- **Run all tests (Rust):** `cargo test --workspace`; single crate: `cargo test -p <crate>`
|
|
- **Type check:** `cargo check --workspace`; wasm: `cargo check --target wasm32-unknown-unknown -p op-host-web --no-default-features --features web`
|
|
- **Lint / format (Rust):** `cargo clippy --workspace --all-targets -- -D warnings` / `cargo fmt --all`
|
|
- **Lint / format (remaining TS SDK):** from `packages/`: `bun run lint` (oxlint) / `bun run format` (oxfmt)
|
|
- **Desktop app:** `cargo build -p op-host-desktop` → binary `openpencil-desktop` (live MCP on `127.0.0.1:<port>/mcp`)
|
|
- **CLI:** `cargo build -p op-cli` → binary `op`
|
|
- **MCP server:** built into the desktop/web host (`--mcp <path>`); crate `op-mcp`
|
|
- **Iconify catalog (Rust assets):** from `packages/`: `bun run generate-iconify-catalog`
|
|
- **Sync all managed versions:** `scripts/sync-version.sh` reads the canonical version from root `Cargo.toml`; verify without writing via `tools/check-version-sync.sh`
|
|
|
|
## Architecture
|
|
|
|
OpenPencil is an open-source, AI-native vector design tool (Design-as-Code). The editor — canvas engine, chrome, stores, MCP, AI — is Rust, built on the vendored **jian** skia/widget/render/event toolkit (`vendor/jian`) and **casement** winit fork (`vendor/casement`). See **`crates/CLAUDE.md`** for the authoritative crate map; the essentials:
|
|
|
|
```text
|
|
crates/
|
|
├── op-editor-core/ Canonical `.op` (PenDocument) editor state + EditorCommand + design-variable resolution
|
|
├── op-editor-ui/ Platform-free widgets + RenderBackend facade (wasm32-clean)
|
|
├── op-editor-host-core/ Transport-free host state machines shared by all hosts
|
|
├── op-host-native/ Native host lib (winit + skia-safe GL) — desktop + mobile
|
|
├── op-host-web/ Browser bundle: wasm32 cdylib, CanvasKit renderer
|
|
├── op-host-desktop/ Desktop binary `openpencil-desktop`; also the `--serve-web` daemon
|
|
├── op-host-services/ Headless serve-web / MCP daemon lib (shared by desktop + web-server)
|
|
├── op-host-web-server/ Thin GL-free web-server binary
|
|
├── op-cli/ `op` command-line tool
|
|
├── op-util/ Dependency-free leaf: hex-colour parsing + JSON / XML escaping
|
|
└── op-mcp / op-ai / op-ai-skills / op-codegen / op-orchestrator / op-figma /
|
|
op-git / op-opmerge / op-pen-loader / op-design-lint / op-i18n / op-html /
|
|
op-auth-bridge / op-smoke / …
|
|
|
|
packages/
|
|
├── op-web-sdk/ Read-only `.op` web viewer SDK (wraps the op-host-web wasm bundle)
|
|
├── op-web-sdk-react/ React 19 adapter for op-web-sdk
|
|
└── op-web-sdk-vue/ Vue 3 adapter for op-web-sdk
|
|
```
|
|
|
|
Data flow, canvas engine, Document/EditorCommand model, MCP layered-design workflow, design variables, and the run/debug recipe are all documented in **`crates/CLAUDE.md`**.
|
|
|
|
## Code Style
|
|
|
|
- Single files must not exceed **800 lines** — split into smaller modules when they grow beyond this. The workspace currently has **zero violations**; the convention is a spine (public surface + `mod` declarations) plus sibling files, with re-exports keeping import paths stable.
|
|
- One component/widget per file, single responsibility.
|
|
- `.rs` filenames use snake_case; `.ts`/`.tsx` (SDK) use kebab-case.
|
|
- Source comments (`.rs`/`.ts`/`.toml`) in **English** (spec/plan markdown + test CJK fixtures may keep Chinese).
|
|
- Rust widgets paint against jian's `Painter`; `draw_text` is **baseline-relative** (label components center via `centered_text_baseline_y`, not `(h-fs)/2`).
|
|
|
|
## Git Commit Convention
|
|
|
|
Use [Conventional Commits](https://www.conventionalcommits.org/): `<type>(<scope>): <subject>`
|
|
|
|
**Types:** `feat`, `fix`, `refactor`, `perf`, `style`, `docs`, `test`, `chore`
|
|
|
|
**Scopes:** `editor`, `canvas`, `panels`, `history`, `ai`, `codegen`, `store`, `types`, `variables`, `figma`, `mcp`, `desktop`, `web`, `renderer`, `sdk`, `cli`, `agent`, `i18n`
|
|
|
|
**Rules:** Subject in English, lowercase start, no period, imperative mood. Body optional; explain **why** not what. One commit per change.
|
|
|
|
## License
|
|
|
|
MIT License. See [LICENSE](./LICENSE) for details.
|