openpencil/README.ko.md
Kayshen Xu 90bbcb16fd
V0.4.0 (#44)
* perf(canvas): bitmap cache during zoom/pan, fix save for large files

- Add canvas-zoom-cache: captures pixel snapshot on first viewport change,
  draws cached bitmap with transform delta (~0.1ms vs ~15ms per frame).
  Refreshes snapshot every 200ms during continuous interaction.
- Integrate zoom cache into wheel zoom and space+drag panning.
- Set renderOnAddRemove: false on Fabric canvas to avoid per-object renders.
- Remove depth/size LOD from viewport culling (zoom cache handles perf).
- Rewrite syncCanvasPositionsToStore: single tree walk + single store set
  instead of per-object updateNode (was O(n²) with 200+ history pushes).
- Unify save/save-as: .op files save in-place, non-.op triggers save-as.
- Add Electron filePath storage for reliable native IPC saves.
- Add error handling with fallback for all save paths.

* feat(canvas): integrate CanvasKit for enhanced rendering and layout

- Added support for CanvasKit WASM to improve rendering performance and capabilities.
- Introduced a new SkiaCanvas component for rendering using CanvasKit.
- Implemented spatial indexing with RBush for efficient hit testing in the Skia engine.
- Enhanced text measurement and layout handling using Canvas 2D for accurate word wrapping.
- Updated layout engine to accommodate badge and overlay nodes without affecting layout flow.
- Bumped version from 0.3.3 to 0.3.4 to reflect these significant changes.

* fix(electron): add graceful-fs to devDependencies for Node.js v25 compat (#38)

* feat(figma): enhance instance override handling and derived data processing

- Added support for symbol tree context in instance conversion.
- Improved the application of instance overrides by filtering derived data to exclude nested instances.
- Implemented a two-strategy approach for resolving overrides and derived data, accommodating both direct index mapping and expanded DFS for nested instances.
- Updated FigmaSymbolOverride interface to extend FigmaNodeChange, enhancing the handling of overridable node properties.

* refactor(canvas): remove loading state and enhance error handling in SkiaCanvas

- Eliminated the loading state management from SkiaCanvas, simplifying the component.
- Updated error handling to directly display error messages without loading indicators.
- Adjusted the EditorLayout to directly render SkiaCanvas without suspense, improving performance.
- Introduced drag-and-drop file handling in the canvas store for better user experience.
- Enhanced Figma import dialog to auto-process pending files from drag-and-drop.

* fix(ai): improve error messages for API authentication and connection issues

- Updated error hints in chat.ts to provide clearer instructions for API authentication, including running "claude login" or setting the ANTHROPIC_API_KEY in settings.json.
- Enhanced friendly error messages in connect-agent.ts to guide users on authentication steps when encountering connection errors.
- Refactored resolve-claude-agent-env.ts to improve environment variable normalization, allowing for better handling of ANTHROPIC_CUSTOM_HEADERS and ensuring proper serialization of object values.

* refactor(env): streamline environment variable reading and enhance settings handling

- Renamed and refactored the function for reading Claude settings to improve clarity and maintainability.
- Introduced a new function to read settings from both `settings.json` and `settings.local.json`, ensuring local settings take precedence.
- Updated test setup to use the system's temporary directory for security tests, enhancing compatibility across environments.

* feat(ai): add fallback models for third-party API proxies in connect-agent

- Introduced FALLBACK_CLAUDE_MODELS to provide default model options when supportedModels() fails, enhancing connectivity with third-party API proxies.
- Updated error handling in connectClaudeCode to return fallback models on specific connection errors, ensuring users can still connect and select a model.

* chore: bump version from 0.3.4 to 0.4.0 in package.json

* feat(ai): enhance prompt handling for basic-tier models

- Introduced logic to inline system prompts into user messages for basic-tier models (e.g., MiniMax, GLM) to ensure proper instruction visibility.
- Updated design modification and orchestrator functions to accommodate this change, improving interaction with third-party routers.
- Added a utility function to strip non-standard XML-like tags from AI responses, enhancing JSON extraction reliability.

* fix(server): add ESM-compatible __dirname polyfill (#42)

- Add fileURLToPath/dirname polyfill to mcp-install.ts
- Add fileURLToPath/dirname polyfill to mcp-server-manager.ts

Fixes browser version crash with "__dirname is not defined"
Fixes MCP over HTTP transport failure since v3.3

Closes #37

* fix(server): make MCP HTTP server survive parent process lifecycle (#43)

## Problem
The MCP HTTP server process died when:
1. User closed the Settings/Agent dialog in the UI
2. User interacted with the editor canvas
3. Nitro server hot-reloaded or restarted
4. Electron app sent SIGTERM to Nitro on window close

This made the MCP server unusable for HTTP transport, requiring users
to keep the settings dialog open constantly.

## Root Cause Analysis
The MCP server was spawned as a regular child process without detached
mode. This created several fatal dependencies:

1. **Signal propagation**: Lines 29-34 registered handlers for SIGINT,
   SIGTERM, SIGHUP that killed the MCP process when the parent received
   these signals (e.g., Electron closing Nitro)

2. **Parent-child lifecycle binding**: Without detached mode, the child
   process is tied to the parent's event loop. Any parent instability
   (hot reload, dialog closure causing microtasks, etc.) could affect
   the child

3. **In-memory process tracking**: The mcpProcess variable was stored
   in module memory, so Nitro restarts/hot-reloads would lose track of
   the running server

## Solution
1. **Detached spawn mode**: Use `detached: true` + `unref()` to make
   the MCP process completely independent of the parent

2. **PID file persistence**: Track the process via files in /tmp
   instead of in-memory variables, surviving parent restarts

3. **Remove signal handlers**: Delete the SIGINT/SIGTERM/SIGHUP
   handlers that were killing the MCP process

4. **Cross-platform kill**: Use process.kill() instead of execSync
   with taskkill for safer process termination

## Testing
### Test Case 1: Settings Dialog Close
- Open OpenPencil → Settings → Start MCP HTTP Server
- Close settings dialog
- Reopen settings → MCP server still running 

### Test Case 2: Editor Interaction
- Start MCP HTTP Server
- Draw on canvas, create shapes, use all tools
- Check MCP server status → Still running 

### Test Case 3: Browser Version
- Run `npx vite --port 3000`
- Start MCP from browser UI
- Close tab, reopen → Server still running 

### Test Case 4: Electron App
- Start MCP from installed app
- Close app window
- Reopen app → Server still running (tracked via PID file) 

### Test Case 5: Stop/Restart Cycle
- Start → Stop → Start again
- Works correctly 

## Files Changed
- server/utils/mcp-server-manager.ts - Complete rewrite with detached mode
- server/api/ai/mcp-install.ts - Add ESM __dirname polyfill

Fixes #37

Co-authored-by: Kayshen Xu <kayshen.xu@gmail.com>

* fix(canvas): respect node-level theme overrides during variable resolution (#41)

Previously, resolveNodeForCanvas was called with a single activeTheme
for all nodes, ignoring any per-node theme property. This meant nodes
with theme: {"Mode": "Light"} would still render using Dark mode colors.

This fix merges each node's theme property with the default activeTheme,
allowing individual nodes to override theme axes for proper themed
variable resolution.

Fixes design documents where some panels need different theme variants
than the default (e.g., Light mode components in a Dark mode document).

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kayshen Xu <kayshen.xu@gmail.com>

* feat(ai): enhance text processing by stripping tool call blocks

- Added a new function to strip fake tool call blocks emitted by basic-tier models, ensuring cleaner JSON extraction.
- Updated the existing text processing flow to incorporate this new function, improving the handling of non-standard model artifacts.
- Modified orchestrator prompts to disallow function calls and tool call syntax in JSON outputs, enhancing response consistency.

* fix(server): resolve merge conflict and clean up ESM __dirname polyfill

- Removed merge conflict markers from mcp-install.ts and mcp-server-manager.ts.
- Ensured consistent implementation of ESM-compatible __dirname polyfill across both files.

* feat(ai): add node availability check and HTTP fallback for MCP server installation

- Implemented a function to check for the availability of Node.js on the system, enhancing compatibility for environments without Node.js.
- Added a fallback mechanism to install the MCP server using an HTTP URL when Node.js is not found, ensuring functionality remains intact.
- Updated the installation response to include a flag indicating if the HTTP fallback was used, allowing the UI to reflect the server status accurately.
- Enhanced the agent settings dialog to synchronize the MCP server status when the HTTP server is auto-started.

* refactor(canvas): replace Fabric.js with CanvasKit/Skia for enhanced rendering performance

- Removed Fabric.js dependencies and related code, transitioning to CanvasKit/Skia as the primary canvas engine.
- Updated documentation and README files to reflect the new canvas technology.
- Adjusted data flow and component interactions to accommodate the new rendering engine.
- Ensured backward compatibility by retaining legacy Fabric.js files for specific utilities until full removal is feasible.

* refactor(canvas): update layout engine and remove Fabric.js dependencies

- Enhanced the canvas layout engine by integrating Skia and CanvasKit, replacing Fabric.js references.
- Improved type safety by refining type assertions and imports across various components.
- Added a new function to retrieve canvas dimensions, defaulting to 800x600 if no engine is mounted.
- Removed obsolete rendering logic related to Fabric.js, streamlining the layout indicator functionality.
- Updated multiple components to utilize the new canvas size retrieval method, ensuring consistent behavior across the application.

* fix(figma): resolve multiple .fig import rendering issues

- Fix layout properties in preserve mode: only apply auto-layout (gap,
  padding, justify, align) for frames with stackMode, use absolute
  positioning for non-auto-layout frames
- Reverse children order for auto-layout frames in preserve mode to
  match Figma's layout flow order (tree builder sorts descending for
  z-stacking but layout needs ascending)
- Fix instance inlining: always inline symbol content when instance has
  no local children, regardless of override/derived data presence
- Fix derived data mapping: use direct GUID matching (Strategy 0) when
  derived guidPath GUIDs are actual symbol node GUIDs, preventing the
  off-by-one size/transform misassignment from index-based mapping
- Add styleIdForFill/styleIdForStrokeFill resolution: resolve fill style
  references to inline paints before tree building, fixing missing fills
  on 448+ nodes including active menu items and styled elements
- Fix collectImageBlobs to detect JPEG/GIF/WebP in addition to PNG
- Fix instance override application: apply overrides even when derived
  data is absent

* fix(figma): skip opacity=0 nodes during import to fix breadcrumb visibility

Nodes with opacity <= 0 are now skipped in convertChildren, along with
all their descendants.  This fixes the breadcrumb "Page / Page / Page"
text showing through despite the parent items having opacity=0, since
the Skia renderer does not propagate parent opacity to child nodes.

* fix(figma): resolve styleIdForFill in instance override entries

Style references (styleIdForFill, styleIdForStrokeFill) inside
symbolOverrides were not being resolved to inline paints.  This caused
text nodes in overridden instances (e.g. "All Products" card on blue
background) to retain the symbol's default colors instead of the
instance-specific white fills.

The resolveStyleReferences pre-processing step now iterates into each
node's symbolData.symbolOverrides array and resolves style references
there as well.

* fix(figma): apply icon colors and fix arc rendering in .fig import

- Fix donut chart missing segment: swap start/end angles when
  endingAngle < startingAngle instead of adding 2π, producing correct
  clockwise arc equivalents for counter-clockwise Figma arcs

- Fix icon stroke thickness: scale strokeWeight proportionally in
  scaleTreeChildren, applyInstanceOverrides derived sizing, and
  convertVector for Lucide icons rendered smaller than 24×24

- Fix nested instance color overrides: build nestedOverrideMap from
  multi-guid override paths (e.g. instanceGuid/childGuid) and inject
  child-scoped overrides into nested INSTANCE symbolOverrides, enabling
  Dashboard Summary Card icons to receive white/blue stroke colors

- Fix override-only instances: when derivedSymbolData is empty but
  symbolOverrides exist (e.g. sidebar icon instances with stroke color
  overrides but no size changes), fall through to direct GUID matching
  so stroke paints are correctly applied

- Include strokePaints in hasVisualOverrides check so instances with
  stroke-only overrides are properly inlined with their symbol children

* feat(canvas): add vector text rendering with bundled fonts for Figma import

Replace bitmap text fallback with CanvasKit Paragraph API for true vector
text rendering. Bundle 11 popular font families locally via @fontsource
packages to ensure reliable rendering in regions where Google Fonts CDN
is unavailable. Key changes:

- SkiaFontManager: local-first font loading with Google Fonts fallback
- Paragraph API rendering with caching, styled segments, and alignment
- Fixed-width text tolerance to prevent unwanted line wrapping from font
  metric differences between Figma and CanvasKit
- Auto-width text manual alignment offset (center/right) to avoid
  infinite layout width issues
- Figma text mapper: support RAW lineHeight units
- Figma import dialog: pre-load fonts after conversion

* fix(canvas): align text centering with CanvasKit and improve font fallback

- Replace Fabric.js FONT_SIZE_MULT (1.13) with actual paragraph height
  (fontSize * lineHeight) for cross-axis text centering, fixing icon
  vertical misalignment in horizontal layouts
- Remove Fabric-specific optical correction (getTextOpticalCenterYOffset)
  since CanvasKit halfLeading handles this correctly
- Add font fallback chain with separate Inter Ext family for latin-ext
  glyph coverage (₦ U+20A6 etc.)
- Cache failed font loads to prevent repeated fetch attempts per frame
- Skip Google Fonts requests for known system/proprietary fonts
  (PingFang SC, Microsoft YaHei, D-DIN-PRO, etc.)

* fix(figma): recursive nested instance expansion and CJK font support

- Fix 3 bugs in applyInstanceOverrides() that broke deeply nested Figma
  component instances (6+ levels): propagate multi-guid derivedSymbolData
  to nested instances, resolve virtual GUIDs via pkToNodeGuid map, and
  build nestedDerivedMap alongside nestedOverrideMap for recursive expansion
- Bundle Noto Sans SC (chinese-simplified + latin subsets, 400/700 weights)
  for offline CJK vector text rendering without Google Fonts dependency
- Add Noto Sans SC to font fallback chain for CJK glyph coverage
- Add China CDN mirror (fonts.font.im) as fallback when Google Fonts is
  inaccessible, with 4s timeout on primary CDN
- Increase .fig file size limits to 150MB compressed / 300MB decompressed

* fix(canvas): enhance CJK font support and pre-load Noto Sans SC

- Update SkiaEngine to pre-load Noto Sans SC alongside Inter for improved CJK glyph coverage in the font fallback chain, preventing rendering issues with system fonts.
- Modify FigmaImportDialog to ensure Noto Sans SC is included when primary fonts are system fonts, ensuring proper rendering of CJK text.

* refactor(figma): optimize instance override handling with full DFS strategy

- Replace hybrid skip-INSTANCE and expanded DFS with a unified full DFS approach for handling all node types, including INSTANCE nodes.
- Update the mapping logic to ensure correct localID assignments and improve the handling of overflow entries during instance expansion.
- Enhance the overall structure and readability of the applyInstanceOverrides function by consolidating the traversal methods.

* refactor(figma): improve layout mapping and instance override logic

- Enhance the mapFigmaLayout function to conditionally set gap based on stackSpacing and justifyContent, ensuring compatibility with Figma's layout behavior.
- Simplify the applyInstanceOverrides function by removing redundant logic and focusing on a unified full DFS approach for node mapping, improving clarity and performance.
- Ensure derivedSymbolData is correctly replaced with nested data from outer instances, preventing incorrect merging of entries.

* refactor(figma): enhance instance override logic with root-inclusive DFS

- Introduce a root-inclusive depth-first search (DFS) to accurately detect and skip overrides targeting the symbol root during instance processing.
- Update the applyInstanceOverrides function to improve clarity and performance by refining the handling of derived data and overrides.
- Ensure that overrides targeting the root are excluded from child nodes, preventing incorrect application of overrides in nested instances.

---------

Co-authored-by: Fini <fini.yang@gmail.com>
Co-authored-by: Related8919 <191752213+Related8919@users.noreply.github.com>
Co-authored-by: Hrijul Dey <44521405+hr1juldey@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2026-03-15 10:01:35 +08:00

12 KiB

OpenPencil

OpenPencil

세계 최초의 오픈소스 AI 네이티브 벡터 디자인 툴.
동시 에이전트 팀 • 디자인-애즈-코드 • 내장 MCP 서버 • 멀티 모델 인텔리전스

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

Stars License CI Discord


OpenPencil — click to watch demo

이미지를 클릭하여 데모 영상 보기


OpenPencil을 선택하는 이유

🎨 프롬프트 → 캔버스

자연어로 어떤 UI든 설명하세요. 무한 캔버스 위에 스트리밍 애니메이션과 함께 실시간으로 나타납니다. 요소를 선택하고 대화하여 기존 디자인을 수정할 수 있습니다.

🤖 동시 에이전트 팀

오케스트레이터가 복잡한 페이지를 공간적 서브태스크로 분해합니다. 여러 AI 에이전트가 히어로, 기능 소개, 푸터 등 각기 다른 섹션을 동시에 작업하며 모두 병렬로 스트리밍됩니다.

🧠 멀티 모델 인텔리전스

각 모델의 역량에 자동 적응합니다. Claude는 사고 모드가 포함된 전체 프롬프트를 받고, GPT-4o/Gemini는 사고 모드를 비활성화하며, 소형 모델(MiniMax, Qwen, Llama)은 안정적인 출력을 위해 단순화된 프롬프트를 받습니다.

🔌 MCP 서버

Claude Code, Codex, Gemini, OpenCode, Kiro 또는 Copilot CLI에 원클릭 설치. 터미널에서 디자인하세요 — MCP 호환 에이전트를 통해 .op 파일을 읽고, 생성하고, 편집할 수 있습니다.

📦 디자인-애즈-코드

.op 파일은 JSON입니다 — 사람이 읽을 수 있고, Git 친화적이며, diff가 가능합니다. 디자인 변수는 CSS 커스텀 프로퍼티를 생성합니다. React + Tailwind 또는 HTML + CSS로 코드 내보내기가 가능합니다.

🖥️ 어디서든 실행

웹 앱 + Electron을 통한 macOS, Windows, Linux 네이티브 데스크톱. GitHub Releases에서 자동 업데이트. .op 파일 연결 — 더블 클릭으로 열기.

빠른 시작

# 의존성 설치
bun install

# http://localhost:3000 에서 개발 서버 시작
bun --bun run dev

또는 데스크톱 앱으로 실행:

bun run electron:dev

필수 조건: Bun >= 1.0 및 Node.js >= 18

AI 네이티브 디자인

프롬프트에서 UI로

  • 텍스트-투-디자인 — 페이지를 설명하면 스트리밍 애니메이션으로 실시간으로 캔버스에 생성
  • 오케스트레이터 — 복잡한 페이지를 공간적 서브태스크로 분해하여 병렬 생성 지원
  • 디자인 수정 — 요소를 선택하고 자연어로 변경 내용을 설명
  • 비전 입력 — 스크린샷이나 목업을 참조로 첨부하여 디자인

멀티 에이전트 지원

에이전트 설정 방법
Claude Code 설정 불필요 — 로컬 OAuth로 Claude Agent SDK 사용
Codex CLI 에이전트 설정에서 연결 (Cmd+,)
OpenCode 에이전트 설정에서 연결 (Cmd+,)
GitHub Copilot copilot login 후 에이전트 설정에서 연결 (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_skeletondesign_contentdesign_refine으로 더 높은 충실도의 멀티 섹션 디자인
  • 세그먼트 프롬프트 검색 — 필요한 디자인 지식만 로드 (스키마, 레이아웃, 역할, 아이콘, 계획 등)
  • 멀티 페이지 지원 — MCP 도구를 통해 페이지 생성, 이름 변경, 순서 변경, 복제

코드 생성

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

기능

캔버스 & 드로잉

  • 팬, 줌, 스마트 정렬 가이드, 스냅 지원의 무한 캔버스
  • 사각형, 타원, 직선, 다각형, 펜(베지어), Frame, 텍스트
  • 불리언 연산 — 합치기, 빼기, 교차 (컨텍스트 도구 모음)
  • 아이콘 피커(Iconify)와 이미지 가져오기(PNG/JPEG/SVG/WebP/GIF)
  • 오토 레이아웃 — 수직/수평 방향, 갭·패딩·justify·align 지원
  • 탭 내비게이션이 있는 멀티 페이지 문서

디자인 시스템

  • 디자인 변수 — 컬러·숫자·문자열 토큰, $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 친화적

프로젝트 구조

src/
  canvas/          CanvasKit/Skia 엔진 — 드로잉, 동기화, 레이아웃, 가이드, 펜 툴
  components/      React UI — 에디터, 패널, 공유 다이얼로그, 아이콘
  services/ai/     AI 채팅, 오케스트레이터, 디자인 생성, 스트리밍
  services/figma/  Figma .fig 바이너리 가져오기 파이프라인
  services/codegen React+Tailwind 및 HTML+CSS 코드 생성기
  stores/          Zustand — 캔버스, 문서, 페이지, 히스토리, AI, 설정
  variables/       디자인 토큰 해석 및 참조 관리
  mcp/             외부 CLI 통합용 MCP 서버 툴
  uikit/           재사용 가능한 컴포넌트 킷 시스템
server/
  api/ai/          Nitro API — 스트리밍 채팅, 생성, 유효성 검사
  utils/           Claude CLI, OpenCode, Codex, Copilot 클라이언트 래퍼
electron/
  main.ts          윈도우, Nitro 포크, 네이티브 메뉴, 자동 업데이터
  preload.ts       IPC 브리지

키보드 단축키

동작 동작
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 electron:dev       # Electron 개발 모드
bun run electron:build     # Electron 패키징

기여하기

기여를 환영합니다! 아키텍처 세부 정보와 코드 스타일은 CLAUDE.md를 참고하세요.

  1. 포크 후 클론
  2. 브랜치 생성: git checkout -b feat/my-feature
  3. 검사 실행: npx tsc --noEmit && bun --bun run test
  4. Conventional Commits 형식으로 커밋: feat(canvas): add rotation snapping
  5. main 브랜치에 PR 생성

로드맵

  • CSS 동기화가 있는 디자인 변수 & 토큰
  • 컴포넌트 시스템(인스턴스 & 오버라이드)
  • 오케스트레이터를 통한 AI 디자인 생성
  • 계층적 디자인 워크플로가 포함된 MCP 서버 통합
  • 멀티 페이지 지원
  • Figma .fig 가져오기
  • 불리언 연산(결합, 빼기, 교차)
  • 멀티 모델 역량 프로파일
  • 공동 편집
  • 플러그인 시스템

기여자

Contributors

커뮤니티

Discord Discord에 참여하기 — 질문하기, 디자인 공유, 기능 제안.

Star History

Star History Chart

라이선스

MIT — Copyright (c) 2026 ZSeven-W