feat(docs): update CLAUDE.md and README.md for new features and improvements
- Expand the Fabric.js integration section in CLAUDE.md to include new files and functionalities. - Highlight new features such as double-click frame entry, advanced drag-and-drop capabilities, and per-layer export options in README.md. - Add context optimization and multi-provider support for AI in README.md. - Update the project structure descriptions for clarity and completeness.
This commit is contained in:
parent
586978c450
commit
ca1e215572
43
CLAUDE.md
43
CLAUDE.md
|
|
@ -68,8 +68,9 @@ PenDocument (source of truth)
|
|||
|
||||
### Key Modules
|
||||
|
||||
- **`src/canvas/`** — Fabric.js integration (16 files):
|
||||
- **`src/canvas/`** — Fabric.js integration (25 files):
|
||||
- `fabric-canvas.tsx` — Canvas component initialization
|
||||
- `use-fabric-canvas.ts` — Canvas initialization hook
|
||||
- `canvas-object-factory.ts` — Creates Fabric objects from PenNodes (rect, ellipse, line, polygon, path, text, image, frame, group)
|
||||
- `canvas-object-sync.ts` — Syncs individual object properties between Fabric and store
|
||||
- `canvas-sync-lock.ts` — Prevents circular sync loops
|
||||
|
|
@ -79,12 +80,20 @@ PenDocument (source of truth)
|
|||
- `use-canvas-sync.ts` — Bidirectional PenDocument ↔ Fabric.js sync, node flattening with parent offsets, variable resolution via `resolveNodeForCanvas()`
|
||||
- `use-canvas-viewport.ts` — Wheel zoom, space+drag panning, tool cursor switching, selection toggling per tool
|
||||
- `use-canvas-selection.ts` — Selection sync between Fabric objects and canvas-store
|
||||
- `use-canvas-hover.ts` — Hover state management for objects
|
||||
- `use-canvas-guides.ts` — Smart alignment guides with snapping
|
||||
- `guide-utils.ts` — Guide calculation and rendering
|
||||
- `pen-tool.ts` — Bezier pen tool: anchor points, control handles, path closure, preview rendering
|
||||
- `parent-child-transform.ts` — Propagates parent transforms (move/scale/rotate) to children proportionally
|
||||
- `use-dimension-label.ts` — Shows size/position labels during object manipulation
|
||||
- `use-frame-labels.ts` — Renders frame names and boundaries on canvas
|
||||
- `use-entered-frame-overlay.ts` — Visual overlay when entering a frame for editing
|
||||
- `use-layout-indicator.ts` — Layout indicator rendering during drag operations
|
||||
- `insertion-indicator.ts` — Insertion point indicator for layout drop targets
|
||||
- `drag-into-layout.ts` — Drag-and-drop into auto-layout frames with insertion detection
|
||||
- `drag-reparent.ts` — Reparenting nodes during drag operations
|
||||
- `layout-reorder.ts` — Reorder children within layout frames during drag
|
||||
- `selection-context.ts` — Selection context management for multi-select operations
|
||||
- **`src/variables/`** — Design variables system (2 files):
|
||||
- `resolve-variables.ts` — Core resolution utilities: `resolveVariableRef`, `resolveNodeForCanvas`, `getDefaultTheme`, `isVariableRef`; resolves `$variable` references to concrete values for canvas rendering with circular reference guards
|
||||
- `replace-refs.ts` — `replaceVariableRefsInTree`: recursively walk node tree to replace/resolve `$refs` when renaming or deleting variables (covers opacity, gap, padding, fills, strokes, effects, text)
|
||||
|
|
@ -94,14 +103,16 @@ PenDocument (source of truth)
|
|||
- `history-store.ts` — Undo/redo (max 300 states), batch mode for grouped operations
|
||||
- `ai-store.ts` — Chat messages, streaming state, generated code, model selection
|
||||
- `agent-settings-store.ts` — AI provider config (Anthropic/OpenAI), MCP CLI integrations, localStorage persistence
|
||||
- **`src/types/`** — Type system:
|
||||
- **`src/types/`** — Type system (7 files):
|
||||
- `pen.ts` — PenDocument/PenNode (frame, group, rectangle, ellipse, line, polygon, path, text, image, ref), ContainerProps; `PenDocument.variables` and `PenDocument.themes`
|
||||
- `canvas.ts` — ToolType (select, frame, rectangle, ellipse, line, polygon, path, text, hand), ViewportState, SelectionState
|
||||
- `styles.ts` — PenFill (solid, linear_gradient, radial_gradient), PenStroke, PenEffect (shadow, blur)
|
||||
- `canvas.ts` — ToolType (select, frame, rectangle, ellipse, line, polygon, path, text, hand), ViewportState, SelectionState, CanvasInteraction
|
||||
- `styles.ts` — PenFill (solid, linear_gradient, radial_gradient), PenStroke, PenEffect (shadow, blur), BlendMode, StyledTextSegment
|
||||
- `variables.ts` — `VariableDefinition` (type + value), `ThemedValue` (value per theme), `VariableValue`
|
||||
- `agent-settings.ts` — AI provider config types
|
||||
- `agent-settings.ts` — AI provider config types (`AIProviderType`, `AIProviderConfig`, `MCPCliIntegration`, `GroupedModel`)
|
||||
- `electron.d.ts` — Electron IPC bridge types (file dialogs, save operations)
|
||||
- `opencode-sdk.d.ts` — Type declarations for @opencode-ai/sdk
|
||||
- **`src/components/editor/`** — Editor UI (6 files): editor-layout, toolbar (with variables panel toggle), tool-button, shape-tool-dropdown (rectangle/ellipse/line/path + icon picker + image import), top-bar, status-bar
|
||||
- **`src/components/panels/`** — Panels (17 files):
|
||||
- **`src/components/panels/`** — Panels (18 files):
|
||||
- `layer-panel.tsx` / `layer-item.tsx` / `layer-context-menu.tsx` — Tree view with drag-and-drop reordering and drop-into-children (above/below/inside), visibility/lock toggles, context menu, rename
|
||||
- `property-panel.tsx` — Unified property panel
|
||||
- `fill-section.tsx` — Solid + gradient fill, variable picker integration for color binding
|
||||
|
|
@ -110,6 +121,7 @@ PenDocument (source of truth)
|
|||
- `size-section.tsx` — Position, size, rotation
|
||||
- `text-section.tsx` — Font, size, weight, spacing, alignment
|
||||
- `effects-section.tsx` — Shadow and blur
|
||||
- `export-section.tsx` — Per-layer export to PNG/SVG with scale options (1x/2x/3x)
|
||||
- `layout-section.tsx` — Auto-layout (none/vertical/horizontal), gap, padding, justify, align; variable picker for gap/padding binding
|
||||
- `appearance-section.tsx` — Opacity, visibility, lock, flip; variable picker for opacity binding
|
||||
- `ai-chat-panel.tsx` / `chat-message.tsx` — AI chat with markdown, design block collapse, apply design
|
||||
|
|
@ -117,14 +129,25 @@ PenDocument (source of truth)
|
|||
- `variables-panel.tsx` — Design variables management: theme axes as tabs, variant columns, resizable floating panel, add/rename/delete themes and variants
|
||||
- `variable-row.tsx` — Individual variable row: type icon, editable name, per-theme-variant value cells (color picker, number input, text input), context menu
|
||||
- **`src/components/shared/`** — Reusable UI (9 files): ColorPicker, NumberInput, DropdownSelect, SectionHeader, ExportDialog, SaveDialog, AgentSettingsDialog, IconPickerDialog, VariablePicker
|
||||
- **`src/components/icons/`** — Provider logos: ClaudeLogo, OpenAILogo
|
||||
- **`src/components/icons/`** — Provider logos: ClaudeLogo, OpenAILogo, OpenCodeLogo
|
||||
- **`src/components/ui/`** — shadcn/ui primitives: Button, Select, Separator, Slider, Switch, Toggle, Tooltip
|
||||
- **`src/services/ai/`** — AI chat service, design prompts, design-to-node generation, AI types
|
||||
- **`src/services/ai/`** — AI services (8 files):
|
||||
- `ai-service.ts` — Main AI chat API wrapper, model negotiation, provider selection
|
||||
- `ai-prompts.ts` — System prompts for design generation, context building
|
||||
- `ai-types.ts` — `ChatMessage`, `AIDesignRequest`, streaming response types
|
||||
- `design-generator.ts` — Converts AI JSONL to PenNodes, applies variables, animation coordination
|
||||
- `design-animation.ts` — Fade-in animation coordination for generated design nodes
|
||||
- `orchestrator.ts` — Parallel design generation: decomposes requests into spatial sub-tasks, JSONL streaming, fallback to single-call
|
||||
- `orchestrator-prompts.ts` — Ultra-lightweight orchestrator prompt for spatial decomposition
|
||||
- `context-optimizer.ts` — Chat history trimming, sliding window to prevent unbounded context growth
|
||||
- **`src/services/codegen/`** — React+Tailwind and HTML+CSS code generators (output `var(--name)` for `$variable` refs), CSS variables generator
|
||||
- **`src/hooks/`** — `use-keyboard-shortcuts` (global keyboard event handling: tools, clipboard, undo/redo, save, select all, delete, arrow nudge, z-order)
|
||||
- **`src/lib/`** — Utility functions (`utils.ts` with `cn()` for class merging)
|
||||
- **`src/utils/`** — File operations (save/open .pen), export (PNG/SVG), node clone, pen file normalization (format fixes only, preserves `$variable` refs), SVG parser (import SVG to editable PenNodes), syntax highlight
|
||||
- **`server/api/ai/`** — Nitro server API: `chat.ts` (streaming SSE with thinking state), `generate.ts` (non-streaming generation), `connect-agent.ts` (Claude Code/Codex CLI connection), `models.ts` (model definitions). Supports Anthropic API key or Claude Agent SDK (local OAuth) as dual providers
|
||||
- **`server/api/ai/`** — Nitro server API: `chat.ts` (streaming SSE with thinking state), `generate.ts` (non-streaming generation), `connect-agent.ts` (Claude Code/Codex CLI/OpenCode connection), `models.ts` (model definitions). Supports Anthropic API key or Claude Agent SDK (local OAuth) as dual providers
|
||||
- **`server/utils/`** — Server utilities:
|
||||
- `resolve-claude-cli.ts` — Resolves standalone `claude` binary path (handles Nitro bundling issues with SDK's `import.meta.url`)
|
||||
- `opencode-client.ts` — Shared OpenCode client manager, reuses server on port 4096 with random port fallback
|
||||
|
||||
### Fabric.js v7 Gotchas
|
||||
|
||||
|
|
@ -160,7 +183,7 @@ Tailwind CSS v4 imported via `src/styles.css`. UI primitives from shadcn/ui (`sr
|
|||
|
||||
### Electron Desktop App
|
||||
|
||||
- **`electron/main.ts`** — Main process: window creation, Nitro server fork, IPC for native file dialogs, macOS traffic-light padding
|
||||
- **`electron/main.ts`** — Main process: window creation, Nitro server fork, IPC for native file dialogs, macOS traffic-light padding (auto-hidden in fullscreen)
|
||||
- **`electron/preload.ts`** — Context bridge for renderer ↔ main IPC
|
||||
- **`electron-builder.yml`** — Packaging config: macOS (dmg/zip), Windows (nsis/portable), Linux (AppImage/deb)
|
||||
- **`scripts/electron-dev.ts`** — Dev workflow: starts Vite → waits for port 3000 → compiles electron/ with esbuild → launches Electron
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -12,6 +12,8 @@ Available as a **web app** and **desktop app** (macOS / Windows / Linux via Elec
|
|||
- Smart alignment guides with edge, center, and distance snapping
|
||||
- Dimension labels during object manipulation
|
||||
- Frame labels and boundary visualization
|
||||
- Double-click to enter frames with visual overlay
|
||||
- Advanced drag-and-drop: drag into auto-layout frames with insertion indicators, reparenting, reorder within layout
|
||||
|
||||
### Drawing Tools
|
||||
|
||||
|
|
@ -32,6 +34,7 @@ Available as a **web app** and **desktop app** (macOS / Windows / Linux via Elec
|
|||
- Effects: shadow and blur
|
||||
- Auto-layout: direction, gap, padding, justify-content, align-items
|
||||
- Variable binding: bind any property to a design variable via variable picker
|
||||
- Per-layer export: export individual layers to PNG/SVG with scale options (1x/2x/3x)
|
||||
|
||||
### Design Variables & Tokens
|
||||
|
||||
|
|
@ -85,10 +88,12 @@ Available as a **web app** and **desktop app** (macOS / Windows / Linux via Elec
|
|||
|
||||
- Built-in AI chat panel (Cmd+J)
|
||||
- AI-powered design generation from text prompts
|
||||
- Orchestrator-based parallel design generation: decomposes requests into spatial sub-tasks for faster output
|
||||
- Design block preview with "Apply Design" action
|
||||
- Streaming responses with thinking state
|
||||
- Streaming responses with thinking state and JSONL real-time canvas insertion
|
||||
- Context optimizer: sliding window history trimming to prevent unbounded context growth
|
||||
- Dual provider: Anthropic API or local Claude Code (OAuth)
|
||||
- Multi-provider settings: Claude Code, Codex CLI
|
||||
- Multi-provider settings: Claude Code, Codex CLI, OpenCode
|
||||
|
||||
### Editor UI
|
||||
|
||||
|
|
@ -135,7 +140,7 @@ Available as a **web app** and **desktop app** (macOS / Windows / Linux via Elec
|
|||
- **Icons:** [Lucide React](https://lucide.dev/)
|
||||
- **Server:** [Nitro](https://nitro.build/) (API routes)
|
||||
- **Desktop:** [Electron](https://www.electronjs.org/) 35 + [electron-builder](https://www.electron.build/)
|
||||
- **AI:** [Anthropic SDK](https://docs.anthropic.com/) + [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk)
|
||||
- **AI:** [Anthropic SDK](https://docs.anthropic.com/) + [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk) + [OpenCode SDK](https://github.com/opencode-ai/sdk)
|
||||
- **Runtime:** [Bun](https://bun.sh/)
|
||||
- **Build:** [Vite](https://vite.dev/) 7
|
||||
- **CI/CD:** GitHub Actions
|
||||
|
|
@ -163,10 +168,11 @@ bun run electron:build
|
|||
|
||||
### AI Configuration
|
||||
|
||||
The AI assistant works in two modes:
|
||||
The AI assistant works in multiple modes:
|
||||
|
||||
- **Anthropic API**: Set `ANTHROPIC_API_KEY` in `.env`
|
||||
- **Local Claude Code**: No config needed — uses Claude Agent SDK with OAuth login as fallback
|
||||
- **OpenCode**: Connect via OpenCode SDK for additional model support
|
||||
|
||||
## Scripts
|
||||
|
||||
|
|
@ -211,28 +217,29 @@ git push origin v0.1.0
|
|||
|
||||
```text
|
||||
src/
|
||||
canvas/ # Fabric.js canvas engine
|
||||
variables/ # Design variables/tokens system
|
||||
canvas/ # Fabric.js canvas engine (25 files: sync, events, guides, drag-drop, pen tool, etc.)
|
||||
variables/ # Design variables/tokens system (resolve, replace refs)
|
||||
components/
|
||||
editor/ # Editor layout, toolbar, tool buttons, status bar
|
||||
panels/ # Layer panel, property panel, AI chat, code panel, variables panel
|
||||
editor/ # Editor layout, toolbar, tool buttons, top bar, status bar
|
||||
panels/ # Layer panel, property panel, AI chat, code panel, variables panel, export section
|
||||
shared/ # ColorPicker, NumberInput, VariablePicker, ExportDialog, etc.
|
||||
icons/ # Provider logos (Claude, OpenAI)
|
||||
icons/ # Provider logos (Claude, OpenAI, OpenCode)
|
||||
ui/ # shadcn/ui primitives (Button, Select, Slider, Switch, etc.)
|
||||
hooks/ # Keyboard shortcuts
|
||||
lib/ # Utility functions (cn class merging)
|
||||
services/
|
||||
ai/ # AI chat service, prompts, design generation
|
||||
ai/ # AI chat, orchestrator, context optimizer, design generation, prompts
|
||||
codegen/ # React+Tailwind, HTML+CSS, and CSS variables generators
|
||||
stores/ # Zustand stores (canvas, document, history, AI, agent-settings)
|
||||
types/ # PenDocument/PenNode types, style types, variables, agent settings
|
||||
types/ # PenDocument/PenNode types, style types, variables, agent settings, Electron IPC
|
||||
utils/ # File operations, export, node clone, SVG parser, syntax highlight
|
||||
routes/ # TanStack Router pages (/, /editor)
|
||||
electron/
|
||||
main.ts # Electron main process (window, Nitro server, IPC)
|
||||
main.ts # Electron main process (window, Nitro server, IPC, fullscreen handling)
|
||||
preload.ts # Context bridge for renderer ↔ main IPC
|
||||
server/
|
||||
api/ai/ # Nitro API: streaming chat, generation, agent connection, models
|
||||
utils/ # Server utilities: Claude CLI resolver, OpenCode client manager
|
||||
.github/
|
||||
workflows/
|
||||
ci.yml # CI: type check, test, web build
|
||||
|
|
|
|||
|
|
@ -155,12 +155,27 @@ function createWindow(): void {
|
|||
if (!mainWindow) return
|
||||
if (process.platform === 'darwin') {
|
||||
await mainWindow.webContents.insertCSS(
|
||||
'.electron-traffic-light-pad { margin-left: 74px; }',
|
||||
'.electron-traffic-light-pad { margin-left: 74px; }' +
|
||||
'.electron-fullscreen .electron-traffic-light-pad { margin-left: 0; }',
|
||||
)
|
||||
}
|
||||
mainWindow.show()
|
||||
})
|
||||
|
||||
// Toggle fullscreen class to remove traffic-light padding in fullscreen
|
||||
if (process.platform === 'darwin') {
|
||||
mainWindow.on('enter-full-screen', () => {
|
||||
mainWindow?.webContents.executeJavaScript(
|
||||
'document.body.classList.add("electron-fullscreen")',
|
||||
)
|
||||
})
|
||||
mainWindow.on('leave-full-screen', () => {
|
||||
mainWindow?.webContents.executeJavaScript(
|
||||
'document.body.classList.remove("electron-fullscreen")',
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
mainWindow.loadURL(url)
|
||||
|
||||
if (isDev) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
"dev": "bun --bun vite dev --port 3000",
|
||||
"build": "bun --bun vite build",
|
||||
"preview": "bun --bun vite preview",
|
||||
"test": "bun --bun vitest run",
|
||||
"test": "bun --bun vitest run --passWithNoTests",
|
||||
"electron:dev": "bun run scripts/electron-dev.ts",
|
||||
"electron:compile": "esbuild electron/main.ts electron/preload.ts --bundle --platform=node --target=node20 --outdir=electron-dist --external:electron --format=cjs --out-extension:.js=.cjs --sourcemap",
|
||||
"electron:build": "BUILD_TARGET=electron bun --bun run build && bun run electron:compile && npx electron-builder --config electron-builder.yml"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import { nitro } from 'nitro/vite'
|
|||
const isElectronBuild = process.env.BUILD_TARGET === 'electron'
|
||||
|
||||
const config = defineConfig({
|
||||
test: {
|
||||
teardownTimeout: 1000,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
|
|
|
|||
Loading…
Reference in a new issue