* 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>
14 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 호환 에이전트를 통해 |
📦 디자인-애즈-코드
|
🖥️ 어디서든 실행웹 앱 + Electron을 통한 macOS, Windows, Linux 네이티브 데스크톱. GitHub Releases에서 자동 업데이트. |
빠른 시작
# 의존성 설치
bun install
# http://localhost:3000 에서 개발 서버 시작
bun --bun run dev
또는 데스크톱 앱으로 실행:
bun run electron:dev
Docker
여러 이미지 변형을 사용할 수 있습니다 — 필요에 맞는 것을 선택하세요:
| 이미지 | 크기 | 포함 내용 |
|---|---|---|
openpencil:latest |
~226 MB | 웹 앱만 |
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 도구 |
실행 (웹만):
docker run -d -p 3000:3000 ghcr.io/zseven-w/openpencil:latest
AI CLI와 함께 실행 (예: Claude Code):
AI 채팅은 Claude CLI OAuth 로그인에 의존합니다. Docker 볼륨을 사용하여 로그인 세션을 유지하세요:
# 1단계 — 로그인 (최초 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
로컬 빌드:
# 기본 (웹만)
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 | 설정 불필요 — 로컬 OAuth로 Claude Agent SDK 사용 |
| Codex CLI | 에이전트 설정에서 연결 (Cmd+,) |
| OpenCode | 에이전트 설정에서 연결 (Cmd+,) |
| GitHub Copilot | copilot login 후 에이전트 설정에서 연결 (Cmd+,) |
| Gemini CLI | 에이전트 설정에서 연결 (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
기능
캔버스 & 드로잉
- 팬, 줌, 스마트 정렬 가이드, 스냅 지원의 무한 캔버스
- Rectangle, Ellipse, Line, Polygon, Pen(Bezier), Frame, Text
- 불리언 연산 — 합치기, 빼기, 교차 (컨텍스트 툴바)
- 아이콘 피커(Iconify)와 이미지 가져오기(PNG/JPEG/SVG/WebP/GIF)
- 오토 레이아웃 — 수직/수평 방향, gap, padding, justify, align 지원
- 탭 내비게이션이 있는 멀티 페이지 문서
디자인 시스템
- 디자인 변수 — 컬러, 숫자, 문자열 토큰,
$variable참조 지원 - 멀티 테마 지원 — 여러 테마 축, 각 축에 변형(Light/Dark, Compact/Comfortable)
- 컴포넌트 시스템 — 인스턴스와 오버라이드를 가진 재사용 가능한 컴포넌트
- 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 웹 앱
│ │ ├── 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 (모든 패키지 재export)
└── .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를 참고하세요.
- 포크 후 클론
- 버전 동기화 설정:
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가져오기 - 불리언 연산 (합치기, 빼기, 교차)
- 멀티 모델 역량 프로파일
- 재사용 가능한 패키지를 포함한 모노레포 구조 변경
- 공동 편집
- 플러그인 시스템
기여자
커뮤니티
Star History
라이선스
MIT — Copyright (c) 2026 ZSeven-W