openpencil/README.id.md
Kayshen Xu 8472d4ac04 V0.5.0 (#67)
* 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>
2026-03-22 09:44:04 +08:00

14 KiB

OpenPencil

OpenPencil

Alat desain vektor open-source berbasis AI pertama di dunia.
Tim Agen Konkuren • Design-as-Code • Server MCP Bawaan • Kecerdasan Multi-model

English · 简体中文 · 繁體中文 · 日本語 · 한국어 · Français · Español · Deutsch · Português · Русский · हिन्दी · Türkçe · ไทย · Tiếng Việt · Bahasa Indonesia

Stars License CI Discord


OpenPencil — klik untuk menonton demo

Klik gambar untuk menonton video demo


Mengapa OpenPencil

🎨 Prompt → Kanvas

Deskripsikan UI apa pun dalam bahasa alami. Saksikan hasilnya muncul di kanvas tak terbatas secara real-time dengan animasi streaming. Modifikasi desain yang ada dengan memilih elemen dan berdialog.

🤖 Tim Agen Konkuren

Orkestrator menguraikan halaman kompleks menjadi sub-tugas spasial. Beberapa agen AI bekerja pada bagian yang berbeda secara bersamaan — hero, fitur, footer — semuanya streaming secara paralel.

🧠 Kecerdasan Multi-Model

Secara otomatis menyesuaikan dengan kemampuan setiap model. Claude mendapat prompt lengkap dengan thinking; GPT-4o/Gemini menonaktifkan thinking; model yang lebih kecil (MiniMax, Qwen, Llama) mendapat prompt yang disederhanakan untuk keluaran yang andal.

🔌 Server MCP

Instal satu klik ke Claude Code, Codex, Gemini, OpenCode, Kiro, atau Copilot CLI. Desain dari terminal Anda — baca, buat, dan modifikasi file .op melalui agen yang kompatibel dengan MCP.

📦 Design-as-Code

File .op adalah JSON — mudah dibaca manusia, ramah Git, mudah dibandingkan. Variabel desain menghasilkan CSS custom properties. Ekspor kode ke React + Tailwind atau HTML + CSS.

🖥️ Berjalan di Mana Saja

Aplikasi web + desktop native di macOS, Windows, dan Linux melalui Electron. Pembaruan otomatis dari GitHub Releases. Asosiasi file .op — klik dua kali untuk membuka.

Mulai Cepat

# Instal dependensi
bun install

# Jalankan server pengembangan di http://localhost:3000
bun --bun run dev

Atau jalankan sebagai aplikasi desktop:

bun run electron:dev

Prasyarat: Bun >= 1.0 dan Node.js >= 18

Docker

Tersedia beberapa varian image — pilih yang sesuai kebutuhan Anda:

Image Ukuran Termasuk
openpencil:latest ~226 MB Hanya aplikasi 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 Semua alat CLI

Jalankan (hanya web):

docker run -d -p 3000:3000 ghcr.io/zseven-w/openpencil:latest

Jalankan dengan AI CLI (misal Claude Code):

Chat AI bergantung pada login OAuth Claude CLI. Gunakan volume Docker untuk menyimpan sesi login:

# Langkah 1 — Login (satu kali)
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

# Langkah 2 — Mulai
docker run -d -p 3000:3000 \
  -v openpencil-claude-auth:/root/.claude \
  ghcr.io/zseven-w/openpencil-claude:latest

Build secara lokal:

# Dasar (hanya web)
docker build --target base -t openpencil .

# Dengan CLI tertentu
docker build --target with-claude -t openpencil-claude .

# Lengkap (semua CLI)
docker build --target full -t openpencil-full .

Desain Berbasis AI

Dari Prompt ke UI

  • Teks ke desain — deskripsikan halaman, dan hasilkan di kanvas secara real-time dengan animasi streaming
  • Orkestrator — menguraikan halaman kompleks menjadi sub-tugas spasial untuk pembuatan secara paralel
  • Modifikasi desain — pilih elemen, lalu deskripsikan perubahan dalam bahasa alami
  • Masukan visual — lampirkan tangkapan layar atau mockup sebagai referensi desain

Dukungan Multi-Agen

Agen Pengaturan
Claude Code Tanpa konfigurasi — menggunakan Claude Agent SDK dengan OAuth lokal
Codex CLI Hubungkan di Pengaturan Agen (Cmd+,)
OpenCode Hubungkan di Pengaturan Agen (Cmd+,)
GitHub Copilot copilot login lalu hubungkan di Pengaturan Agen (Cmd+,)
Gemini CLI Hubungkan di Pengaturan Agen (Cmd+,)

Profil Kemampuan Model — secara otomatis menyesuaikan prompt, mode thinking, dan timeout per tingkatan model. Model tingkat penuh (Claude) mendapat prompt lengkap; tingkat standar (GPT-4o, Gemini, DeepSeek) menonaktifkan thinking; tingkat dasar (MiniMax, Qwen, Llama, Mistral) mendapat prompt JSON bertingkat yang disederhanakan untuk keandalan maksimum.

Server MCP

  • Server MCP bawaan — instal satu klik ke Claude Code / Codex / Gemini / OpenCode / Kiro / Copilot CLI
  • Deteksi otomatis Node.js — jika tidak terinstal, otomatis beralih ke transport HTTP dan memulai server MCP HTTP
  • Otomasi desain dari terminal: baca, buat, dan modifikasi file .op melalui agen yang kompatibel dengan MCP
  • Alur kerja desain berlapisdesign_skeletondesign_contentdesign_refine untuk desain multi-bagian dengan fidelitas lebih tinggi
  • Pengambilan prompt tersegmentasi — muat hanya pengetahuan desain yang Anda butuhkan (schema, layout, roles, icons, planning, dll.)
  • Dukungan multi-halaman — buat, ganti nama, urutkan ulang, dan duplikasi halaman melalui alat MCP

Pembuatan Kode

  • React + Tailwind CSS, HTML + CSS, CSS Variables
  • Vue, Svelte, Flutter, SwiftUI, Jetpack Compose, React Native

Fitur

Kanvas & Menggambar

  • Kanvas tak terbatas dengan pan, zoom, panduan perataan cerdas, dan snapping
  • Persegi panjang, Elips, Garis, Poligon, Pen (Bezier), Frame, Teks
  • Operasi Boolean — gabungan, kurangi, irisan dengan toolbar kontekstual
  • Pemilih ikon (Iconify) dan impor gambar (PNG/JPEG/SVG/WebP/GIF)
  • Auto-layout — vertikal/horizontal dengan gap, padding, justify, align
  • Dokumen multi-halaman dengan navigasi tab

Sistem Desain

  • Variabel desain — token warna, angka, string dengan referensi $variable
  • Dukungan multi-tema — beberapa sumbu, masing-masing dengan varian (Terang/Gelap, Ringkas/Nyaman)
  • Sistem komponen — komponen yang dapat digunakan ulang dengan instans dan penggantian
  • Sinkronisasi CSS — properti kustom yang dibuat otomatis, var(--name) dalam keluaran kode

Impor Figma

  • Impor file .fig dengan tata letak, fill, stroke, efek, teks, gambar, dan vektor tetap terjaga

Aplikasi Desktop

  • macOS, Windows, dan Linux native melalui Electron
  • Asosiasi file .op — klik dua kali untuk membuka, kunci instans tunggal
  • Pembaruan otomatis dari GitHub Releases
  • Menu aplikasi native dan dialog file

Tumpukan Teknologi

Frontend React 19 · TanStack Start · Tailwind CSS v4 · shadcn/ui
Kanvas CanvasKit/Skia (WASM, akselerasi GPU)
State Zustand v5
Server Nitro
Desktop Electron 35
AI Anthropic SDK · Claude Agent SDK · OpenCode SDK · Copilot SDK
Runtime Bun · Vite 7
Format file .op — berbasis JSON, mudah dibaca manusia, ramah Git

Struktur Proyek

openpencil/
├── apps/
│   ├── web/                 Aplikasi web TanStack Start
│   │   ├── src/
│   │   │   ├── canvas/      Mesin CanvasKit/Skia — menggambar, sinkronisasi, tata letak
│   │   │   ├── components/  UI React — editor, panel, dialog bersama, ikon
│   │   │   ├── services/ai/ Chat AI, orkestrator, pembuatan desain, streaming
│   │   │   ├── stores/      Zustand — kanvas, dokumen, halaman, riwayat, AI
│   │   │   ├── mcp/         Alat server MCP untuk integrasi CLI eksternal
│   │   │   ├── hooks/       Pintasan keyboard, seret file, tempel Figma
│   │   │   └── uikit/       Sistem kit komponen yang dapat digunakan ulang
│   │   └── server/
│   │       ├── api/ai/      Nitro API — chat streaming, pembuatan, validasi
│   │       └── utils/       Pembungkus Claude CLI, OpenCode, Codex, Copilot
│   └── desktop/             Aplikasi desktop Electron
│       ├── main.ts          Jendela, fork Nitro, menu native, pembaruan otomatis
│       ├── ipc-handlers.ts  Dialog file native, sinkronisasi tema, preferensi IPC
│       └── preload.ts       Jembatan IPC
├── packages/
│   ├── pen-types/           Definisi tipe untuk model PenDocument
│   ├── pen-core/            Operasi pohon dokumen, mesin tata letak, variabel
│   ├── pen-codegen/         Generator kode (React, HTML, Vue, Flutter, ...)
│   ├── pen-figma/           Parser dan konverter file Figma .fig
│   ├── pen-renderer/        Renderer CanvasKit/Skia mandiri
│   └── pen-sdk/             SDK payung (re-ekspor semua paket)
└── .githooks/               Pre-commit sinkronisasi versi dari nama branch

Pintasan Keyboard

Tombol Aksi Tombol Aksi
V Pilih Cmd+S Simpan
R Persegi panjang Cmd+Z Batalkan
O Elips Cmd+Shift+Z Ulangi
L Garis Cmd+C/X/V/D Salin/Potong/Tempel/Duplikat
T Teks Cmd+G Grup
F Frame Cmd+Shift+G Pisahkan grup
P Alat pen Cmd+Shift+E Ekspor
H Hand (pan) Cmd+Shift+C Panel kode
Del Hapus Cmd+Shift+V Panel variabel
[ / ] Ubah urutan Cmd+J Chat AI
Panah Geser 1px Cmd+, Pengaturan agen
Cmd+Alt+U Union Boolean Cmd+Alt+S Subtract Boolean
Cmd+Alt+I Intersect Boolean

Skrip

bun --bun run dev          # Server pengembangan (port 3000)
bun --bun run build        # Build produksi
bun --bun run test         # Jalankan pengujian (Vitest)
npx tsc --noEmit           # Pemeriksaan tipe
bun run bump <version>     # Sinkronisasi versi di semua package.json
bun run electron:dev       # Pengembangan Electron
bun run electron:build     # Paket Electron

Berkontribusi

Kontribusi sangat disambut! Lihat CLAUDE.md untuk detail arsitektur dan gaya kode.

  1. Fork dan clone
  2. Atur sinkronisasi versi: git config core.hooksPath .githooks
  3. Buat cabang: git checkout -b feat/my-feature
  4. Jalankan pemeriksaan: npx tsc --noEmit && bun --bun run test
  5. Commit dengan Conventional Commits: feat(canvas): add rotation snapping
  6. Buka PR ke main

Peta Jalan

  • Variabel & token desain dengan sinkronisasi CSS
  • Sistem komponen (instans & penggantian)
  • Pembuatan desain AI dengan orkestrator
  • Integrasi server MCP dengan alur kerja desain berlapis
  • Dukungan multi-halaman
  • Impor Figma .fig
  • Operasi boolean (gabung, kurangi, potong)
  • Profil kemampuan multi-model
  • Restrukturisasi monorepo dengan paket yang dapat digunakan ulang
  • Pengeditan kolaboratif
  • Sistem plugin

Kontributor

Contributors

Komunitas

Discord Bergabung dengan Discord kami — Ajukan pertanyaan, bagikan desain, sarankan fitur.

Star History

Star History Chart

Lisensi

MIT — Copyright (c) 2026 ZSeven-W