* docs: add image search & generation design spec and implementation plan - Spec: dual-source image search (Openverse + Wikimedia), multi-provider image generation - Plan: 16 tasks covering types, server endpoints, settings UI, property panel, auto-search pipeline, MCP integration * feat(types): add image service types and imagePrompt to ImageNode * feat(server): add image service API key validation endpoint Adds POST /api/ai/image-service-test that validates credentials for openverse (client_credentials), openai/custom (Bearer + /v1/models), gemini (API key + v1beta/models), and replicate (Bearer + /v1/models). * feat(server): add multi-provider image generation endpoint * feat(server): add dual-source image search endpoint (Openverse + Wikimedia) POST /api/ai/image-search searches freely-licensed images via Openverse with automatic fallback to Wikimedia Commons on 429 rate-limit responses. Supports optional OAuth credentials for authenticated Openverse requests. * feat(store): add imageSearchStatuses to canvas store for runtime status tracking * feat(store): add image generation config and Openverse OAuth to agent settings * feat(editor): add Images tab to agent settings dialog Adds Popover primitive, ImagesPage component with Image Search (Openverse OAuth, test) and Image Generation (provider select, API key, model, base URL) sections, and wires them into the settings dialog sidebar. * feat(panels): add image search popover with Openverse/Wikimedia results grid * feat(panels): add image generate popover with multi-provider support * feat(panels): add Search and Generate buttons to image property section * feat(ai): update prompts to use imagePrompt instead of src for image nodes * feat(ai): add auto-search pipeline with Openverse/Wikimedia fallback * feat(ai): trigger auto image search after design generation completes * feat(mcp): implement G() operation for image search in batch design DSL Adds the G(parent, mode, prompt) operation to batch_design DSL that creates an image node and optionally fetches a real image URL via the image-search API when mode is "search". Converts executeLine to async to support the network call. * feat(mcp): auto-fill images after design refinement in layered pipeline * feat(ai): split imageSearchQuery and imagePrompt for search vs generation - ImageNode now has both imageSearchQuery (short keywords for search) and imagePrompt (long description for AI image generation) - AI prompts instruct LLM to generate both fields - Search pipeline and popovers use imageSearchQuery - Generate popover uses imagePrompt - Server-side simplifySearchQuery kept as fallback for manual input * fix(ai): hook auto image search into orchestrator completion path The primary generation path uses executeOrchestration -> insertStreamingNode, not applyNodesToCanvas/animateNodesToCanvas. Added scanAndFillImages call to orchestrator.ts after all sub-agents complete. Added debug logging. Removed plan/spec docs from git. * style(editor): remove provider names from image search ready status * fix(panels): clean up image gen error display and settings UI - Parse API error response to show concise message instead of raw JSON - Limit error text to 2 lines with line-clamp - Fix image gen test button sending wrong service name - Inline Image Search ready indicator with section header - Remove debug logging from image search pipeline * style(panels): allow up to 4 lines for image gen error message * fix: avoid 1-frame delay when resizing canvas (#60) rAF callbacks run before ResizeObserver in the same frame. Scheduling render in ResizeObserver via rAF defers it to the next frame. Invoke render() synchronously to leverage ResizeObserver's pre-paint timing and ensure immediate visual update. * feat(electron): implement desktop application structure and auto-updater - Introduced a new Electron desktop application with a structured directory for apps and packages. - Added auto-updater functionality to manage application updates seamlessly. - Created a comprehensive menu system for the desktop app. - Implemented logging capabilities for better debugging and error tracking. - Configured build settings for various platforms (macOS, Windows, Linux) using electron-builder. - Established TypeScript configurations for both the desktop and web applications. - Integrated Vite for the web application with support for React and Tailwind CSS. - Added icons and assets for the desktop application. * chore: update package versions to 0.5.0 across all package.json files and add pre-commit hook for version synchronization - Bumped version to 0.5.0 in package.json files for the main project, desktop app, web app, and all packages. - Introduced a pre-commit hook to automatically sync version numbers from branch names to all package.json files. * chore: update package versions to 0.5.0 and refactor Skia components - Bumped version to 0.5.0 in bun.lock and all relevant package.json files. - Refactored Skia components to utilize shared functionality from @zseven-w/pen-renderer, including image loading, hit testing, and path utilities. - Removed redundant code and improved modularity by re-exporting necessary functions and classes from the renderer package. * fix(panels): handle string fill values in icon nodes (#61) AI-generated icon/path nodes may have fill stored as a raw string instead of a PenFill[] array, causing "Cannot use 'in' operator" crash when selecting the node in the property panel. * chore: update documentation and project structure for monorepo organization - Added a new version bump command to synchronize all package.json files. - Updated the project structure to reflect a monorepo setup with organized workspaces for apps and packages. - Enhanced README files in multiple languages to include the new structure and commands. - Adjusted image paths in documentation to point to the correct locations for the desktop application. * feat(ai): incremental image search and improved image generation prompts - Refactor image search from batch post-generation to incremental queue: enqueueImageForSearch() triggers as each image node is inserted during streaming, so images appear progressively instead of all at once after generation completes. scanAndFillImages() remains as a final sweep. - Update imagePrompt guidance to avoid "transparent background" and similar phrases that many models cannot reliably produce. - Pass node width/height from image panel to generation endpoint for aspect-ratio-aware output (Gemini aspect ratio mapping, OpenAI size selection, Replicate dimensions). * feat(ai): multi-profile image generation config and cleaner error messages - Support multiple image generation profiles with active selection; first configured profile becomes default. Old single-config migrated automatically on hydrate. - Fix Gemini aspect ratio: move to generationConfig.imageConfig per API spec. - Extract clean error messages from provider JSON responses (Gemini error.message, OpenAI error.message, Replicate detail) instead of returning raw JSON text. - Remove destructive client-side regex that mangled error display. * feat(design-md): integrate design system panel and functionality - Added a new DesignMdPanel component for managing design system specifications. - Implemented functionality to toggle the design system panel in the editor layout and toolbar. - Introduced new commands for importing, exporting, and auto-generating design.md content. - Updated AI chat handlers to utilize design.md data for enhanced design generation. - Enhanced localization support for design system features across multiple languages. * perf(canvas): skip draw calls for nodes outside the viewport (#64) Add viewport culling in render() to avoid issuing CanvasKit draw calls for off-screen nodes. A 64px screen-space buffer is kept around the viewport edges so nearby nodes are pre-rendered, preventing pop-in during fast panning. * feat(utils): enhance Windows process spawning for CLI scripts - Updated the buildSpawnClaudeCodeProcess function to handle .cmd and .ps1 scripts appropriately. - Implemented PowerShell invocation for .ps1 files and ensured safe defaults for .cmd and .exe files. - Improved handling of command execution to avoid limitations of cmd.exe. * feat(ai): add support for Gemini CLI integration - Extended the AI provider options to include 'gemini' across various components and APIs. - Implemented functions for generating, validating, and connecting to the Gemini CLI. - Added Gemini-specific error handling and model fetching logic. - Updated UI components to display Gemini as a selectable provider with appropriate icons and labels. - Enhanced localization support for Gemini-related features in multiple languages. * feat(editor): warn before closing with unsaved changes Intercept window/tab close when isDirty is true: - Electron: native dialog with Save / Don't Save / Cancel - Web: beforeunload handler + confirm on New/Open actions - i18n: close-confirm strings for all 15 locales * feat(ipc): extract IPC handlers to a dedicated module - Moved IPC dialog handling and updater functions from main.ts to ipc-handlers.ts for better organization and maintainability. - Implemented file open/save dialogs, theme setting, and preferences management through IPC. - Enhanced updater functionality with state management and auto-update settings. - Improved code structure by separating concerns, making it easier to manage IPC-related logic. * feat(docs): update CLAUDE documentation and add new files for desktop and web apps - Enhanced CLAUDE.md with detailed module documentation references for `packages/` and `apps/`. - Updated `pen-core` description to include clone utilities in `pen-core`. - Added new documentation files for the desktop and web applications, outlining their structure, components, and functionalities. - Included IPC handler details in the desktop app documentation for better clarity on file dialogs and theme synchronization. * feat(docker): add Gemini CLI support and update documentation - Introduced a new Docker build stage for the Gemini CLI, allowing users to install and run it. - Updated the Dockerfile to include the installation of the Gemini CLI alongside existing CLI tools. - Enhanced README files in multiple languages to document the new `openpencil-gemini` image variant. - Added Gemini CLI connection instructions to the main README for better user guidance. * feat(docs): add Gemini CLI connection instructions to multiple language READMEs - Updated README files in German, Spanish, French, Hindi, Indonesian, Japanese, Korean, Portuguese, Russian, Thai, Turkish, Vietnamese, and both Traditional and Simplified Chinese to include connection instructions for the Gemini CLI. - Enhanced documentation to improve user guidance for connecting the Gemini CLI in agent settings. * perf(renderer): replace count-based text cache limits with memory-based eviction (#66) previous limits (PARA_CACHE_MAX=200, TEXT_CACHE_MAX=300) were too small for scenes with many nodes, causing constant cache churn and paragraph rebuilds every frame, which dropped FPS significantly during canvas pan. - switch to byte-budget limits (64 MB paragraphs, 256 MB bitmaps) - bitmap size measured exactly as cw*ch*4; paragraph WASM heap estimated as content.length*64+4096 - eviction uses Map insertion order (FIFO) instead of a separate string[] array, replacing O(n) array.shift() with O(1) Map.entries().next() - evict before insert so the budget check includes the incoming entry --------- Co-authored-by: Fini <fini.yang@gmail.com> Co-authored-by: leinaldo <60176594+leinaldo@users.noreply.github.com>
13 KiB
OpenPencil
全球首個開源 AI 原生向量設計工具。
並行智能體團隊 • 設計即程式碼 • 內建 MCP 伺服器 • 多模型智慧
English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Français · Español · Deutsch · Português · Русский · हिन्दी · Türkçe · ไทย · Tiếng Việt · Bahasa Indonesia
點擊圖片觀看示範影片
為什麼選擇 OpenPencil
🎨 提示詞 → 畫布用自然語言描述任何 UI。即時以串流動畫在無限畫布上生成。選取元素並透過對話修改現有設計。 |
🤖 並行智能體團隊編排器將複雜頁面分解為空間子任務。多個 AI 智能體同時處理不同區塊 — 主視覺、功能區塊、頁尾 — 全部並行串流生成。 |
🧠 多模型智慧自動適配每個模型的能力。Claude 獲得完整提示詞與思考模式;GPT-4o/Gemini 停用思考模式;較小模型(MiniMax、Qwen、Llama)獲得精簡提示詞,確保輸出可靠。 |
🔌 MCP 伺服器一鍵安裝至 Claude Code、Codex、Gemini、OpenCode、Kiro 或 Copilot CLI。從終端機進行設計 — 透過任意 MCP 相容的智能體讀取、建立和修改 |
📦 設計即程式碼
|
🖥️ 隨處執行Web 應用程式 + 透過 Electron 在 macOS、Windows 和 Linux 上原生執行。從 GitHub Releases 自動更新。 |
快速開始
# 安裝相依套件
bun install
# 在 http://localhost:3000 啟動開發伺服器
bun --bun run dev
或以桌面應用程式形式執行:
bun run electron:dev
Docker
提供多種映像檔變體 — 選擇適合您需求的版本:
| 映像檔 | 大小 | 包含 |
|---|---|---|
openpencil:latest |
~226 MB | 僅 Web 應用程式 |
openpencil-claude:latest |
— | + Claude Code CLI |
openpencil-codex:latest |
— | + Codex CLI |
openpencil-opencode:latest |
— | + OpenCode CLI |
openpencil-copilot:latest |
— | + GitHub Copilot CLI |
openpencil-gemini:latest |
— | + Gemini CLI |
openpencil-full:latest |
~1 GB | 所有 CLI 工具 |
執行(僅 Web):
docker run -d -p 3000:3000 ghcr.io/zseven-w/openpencil:latest
搭配 AI CLI 執行(例如 Claude Code):
AI 聊天功能依賴 Claude CLI OAuth 登入。使用 Docker volume 來保留登入狀態:
# 步驟 1 — 登入(僅需一次)
docker volume create openpencil-claude-auth
docker run -it --rm \
-v openpencil-claude-auth:/root/.claude \
ghcr.io/zseven-w/openpencil-claude:latest claude login
# 步驟 2 — 啟動
docker run -d -p 3000:3000 \
-v openpencil-claude-auth:/root/.claude \
ghcr.io/zseven-w/openpencil-claude:latest
本地建置:
# 基礎(僅 Web)
docker build --target base -t openpencil .
# 搭配特定 CLI
docker build --target with-claude -t openpencil-claude .
# 完整版(所有 CLI)
docker build --target full -t openpencil-full .
AI 原生設計
提示詞生成 UI
- 文字轉設計 — 描述一個頁面,即時以串流動畫在畫布上生成
- 編排器 — 將複雜頁面分解為空間子任務,支援並行生成
- 設計修改 — 選取元素後,以自然語言描述變更
- 視覺輸入 — 附加截圖或線框圖作為參考進行設計
多智能體支援
| 智能體 | 設定方式 |
|---|---|
| Claude Code | 無需設定 — 使用 Claude Agent SDK 本地 OAuth |
| Codex CLI | 在 Agent 設定中連接(Cmd+,) |
| OpenCode | 在 Agent 設定中連接(Cmd+,) |
| GitHub Copilot | 執行 copilot login 後在 Agent 設定中連接(Cmd+,) |
| Gemini CLI | 在 Agent 設定中連接(Cmd+,) |
模型能力設定檔 — 自動依據模型層級調整提示詞、思考模式和逾時設定。完整層級模型(Claude)獲得完整提示詞;標準層級(GPT-4o、Gemini、DeepSeek)停用思考模式;基礎層級(MiniMax、Qwen、Llama、Mistral)獲得精簡巢狀 JSON 提示詞,確保最大可靠性。
MCP 伺服器
- 內建 MCP 伺服器 — 一鍵安裝至 Claude Code / Codex / Gemini / OpenCode / Kiro / Copilot CLI
- 自動偵測 Node.js — 若未安裝則自動回退到 HTTP 傳輸模式並啟動 MCP HTTP 伺服器
- 從終端機進行設計自動化:透過任意 MCP 相容的智能體讀取、建立和修改
.op檔案 - 分層設計工作流 —
design_skeleton→design_content→design_refine,適用於高保真多區塊設計 - 分段提示詞擷取 — 僅載入所需的設計知識(schema、layout、roles、icons、planning 等)
- 多頁面支援 — 透過 MCP 工具建立、重新命名、重新排序和複製頁面
程式碼生成
- React + Tailwind CSS、HTML + CSS、CSS Variables
- Vue、Svelte、Flutter、SwiftUI、Jetpack Compose、React Native
功能特色
畫布與繪圖
- 無限畫布,支援平移、縮放、智慧對齊參考線和吸附
- 矩形、橢圓、直線、多邊形、鋼筆(貝茲曲線)、Frame、文字
- 布林運算 — 聯合、減去、交集,搭配上下文工具列
- 圖示選擇器(Iconify)和圖片匯入(PNG/JPEG/SVG/WebP/GIF)
- 自動版面配置 — 垂直/水平方向,支援間距、內邊距、主軸對齊、交叉軸對齊
- 多頁面文件,支援分頁導覽
設計系統
- 設計變數 — 顏色、數字、字串令牌,支援
$variable參照 - 多主題支援 — 多個主題軸,每個軸有多個變體(亮色/暗色、緊湊/舒適)
- 元件系統 — 可重複使用元件,支援實體和覆寫
- CSS 同步 — 自動生成自訂屬性,程式碼輸出中使用
var(--name)
Figma 匯入
- 匯入
.fig檔案,保留版面配置、填色、筆觸、效果、文字、圖片和向量圖形
桌面應用程式
- 透過 Electron 支援原生 macOS、Windows 和 Linux
.op檔案關聯 — 雙擊即可開啟,支援單一實體鎖定- 從 GitHub Releases 自動更新
- 原生應用程式選單和檔案對話框
技術堆疊
| 前端 | React 19 · TanStack Start · Tailwind CSS v4 · shadcn/ui |
| 畫布 | CanvasKit/Skia(WASM、GPU 加速) |
| 狀態管理 | Zustand v5 |
| 伺服器 | Nitro |
| 桌面端 | Electron 35 |
| AI | Anthropic SDK · Claude Agent SDK · OpenCode SDK · Copilot SDK |
| 執行環境 | Bun · Vite 7 |
| 檔案格式 | .op — 基於 JSON,人類可讀,對 Git 友好 |
專案結構
openpencil/
├── apps/
│ ├── web/ TanStack Start Web 應用程式
│ │ ├── src/
│ │ │ ├── canvas/ CanvasKit/Skia 引擎 — 繪圖、同步、版面配置
│ │ │ ├── components/ React UI — 編輯器、面板、共用對話框、圖示
│ │ │ ├── services/ai/ AI 聊天、編排器、設計生成、串流處理
│ │ │ ├── stores/ Zustand — 畫布、文件、頁面、歷程、AI
│ │ │ ├── mcp/ 供外部 CLI 整合使用的 MCP 伺服器工具
│ │ │ ├── hooks/ 鍵盤快捷鍵、檔案拖放、Figma 貼上
│ │ │ └── uikit/ 可重複使用元件套件系統
│ │ └── server/
│ │ ├── api/ai/ Nitro API — 串流聊天、生成、驗證
│ │ └── utils/ Claude CLI、OpenCode、Codex、Copilot 客戶端封裝
│ └── desktop/ Electron 桌面應用程式
│ ├── main.ts 視窗、Nitro 子處理序、原生選單、自動更新
│ ├── ipc-handlers.ts 原生檔案對話框、主題同步、偏好設定 IPC
│ └── preload.ts IPC 橋接
├── packages/
│ ├── pen-types/ PenDocument 模型型別定義
│ ├── pen-core/ 文件樹操作、版面配置引擎、變數
│ ├── pen-codegen/ 程式碼生成器(React、HTML、Vue、Flutter...)
│ ├── pen-figma/ Figma .fig 檔案解析器與轉換器
│ ├── pen-renderer/ 獨立 CanvasKit/Skia 渲染器
│ └── pen-sdk/ 整合 SDK(重新匯出所有套件)
└── .githooks/ Pre-commit 版本號同步(從分支名稱)
鍵盤快捷鍵
| 按鍵 | 操作 | 按鍵 | 操作 | |
|---|---|---|---|---|
V |
選取 | Cmd+S |
儲存 | |
R |
矩形 | Cmd+Z |
復原 | |
O |
橢圓 | Cmd+Shift+Z |
重做 | |
L |
直線 | Cmd+C/X/V/D |
複製/剪下/貼上/重複 | |
T |
文字 | Cmd+G |
群組 | |
F |
Frame | Cmd+Shift+G |
解散群組 | |
P |
鋼筆工具 | Cmd+Shift+E |
匯出 | |
H |
手形(平移) | Cmd+Shift+C |
程式碼面板 | |
Del |
刪除 | Cmd+Shift+V |
變數面板 | |
[ / ] |
調整圖層順序 | Cmd+J |
AI 聊天 | |
| 方向鍵 | 微移 1px | Cmd+, |
智能體設定 | |
Cmd+Alt+U |
布林聯合 | Cmd+Alt+S |
布林減去 | |
Cmd+Alt+I |
布林交集 |
指令碼命令
bun --bun run dev # 開發伺服器(連接埠 3000)
bun --bun run build # 正式版建置
bun --bun run test # 執行測試(Vitest)
npx tsc --noEmit # 型別檢查
bun run bump <version> # 在所有 package.json 間同步版本號
bun run electron:dev # Electron 開發模式
bun run electron:build # Electron 封裝
參與貢獻
歡迎貢獻!請查閱 CLAUDE.md 了解架構細節和程式碼風格。
- Fork 並複製存放庫
- 設定版本同步:
git config core.hooksPath .githooks - 建立分支:
git checkout -b feat/my-feature - 執行檢查:
npx tsc --noEmit && bun --bun run test - 使用 Conventional Commits 提交:
feat(canvas): add rotation snapping - 向
main分支發起 PR
路線圖
- 設計變數與令牌,支援 CSS 同步
- 元件系統(實體與覆寫)
- 帶編排器的 AI 設計生成
- MCP 伺服器整合,支援分層設計工作流
- 多頁面支援
- Figma
.fig匯入 - 布林運算(聯集、減去、交集)
- 多模型能力設定檔
- Monorepo 重構,支援可重複使用套件
- 協同編輯
- 外掛程式系統
貢獻者
社群
Star History
授權條款
MIT — Copyright (c) 2026 ZSeven-W