canvas/에 저장된다. (저장소: zhongerxin/cowart · 언어 JavaScript 96% · 패키지 cowart-canvas v0.1.2 · 프론트 React 19 + tldraw 5.1.1 + Vite 7 · 다리 직접 짠 MCP 서버(JSON-RPC/stdio) · 호스트 OpenAI Codex CLI · 제작 ZHONG XIN)한 문장으로 이 프로젝트가 뭘 하는지부터.
cowart = "Codex에게 그림을 시킬 때 쓰는 공용 화이트보드." 보통 AI에게 이미지를 만들라고 하면 채팅창에서 글로만 주고받는다 — 어디에 놓을지, 크기를 맞출지, 만든 그림의 "이 부분만" 고치라고 콕 집기가 어렵다. cowart는 그 대화를 공간(무한 캔버스) 위로 옮긴다. 캔버스에 빈 AI 이미지 액자를 두고 "여기 채워줘" 하면 Codex가 액자 비율에 맞춰 그림을 그려 넣고, 그림에 화살표로 주석을 달아 캡처해 주면 원본은 그대로 둔 채 옆에 수정본을 새로 만든다.
실력 좋은 디자이너(Codex)와 일할 때, 매번 말로만 "더 밝게, 왼쪽으로" 설명하면 답답하다. 가장 빠른 건 화이트보드 앞에 같이 서서 손가락으로 가리키는 것이다.
cowart는 그 화이트보드를 내 컴퓨터에 깔아 준다. 내가 빈 액자를 그려 "여기 이런 그림"이라 하면 디자이너가 그 칸에 맞춰 그려 넣고, 내가 결과물 위에 빨간 화살표로 "이 부분 고쳐"라고 적어 사진을 건네면 원본·메모는 그대로 둔 채 옆에 새 수정본을 붙여 준다. 보드(캔버스 데이터)는 내 프로젝트 서랍(canvas/)에 보관된다.
frame 도형, meta.cowartAiImageHolder=true 표시). "여기에 이런 그림을 채워라"라고 크기·위치·비율을 미리 정해 두는 슬롯이다. 액자를 선택하고 생성을 시키면 그 칸에 딱 맞는 그림이 들어간다. 액자가 없어도 생성은 되지만(현재 페이지 빈 곳에 배치), 액자가 있으면 "어디에 얼마만 한 그림"을 그림처럼 지정할 수 있어 편하다.정리하면 cowart의 핵심 약속은 셋이다. ① AI 이미지 작업을 채팅이 아니라 캔버스(공간) 위에서 — 위치·크기·비교를 눈으로 다룬다. ② 주석 → 수정본 루프 — 결과에 화살표로 메모하면 그대로 반영한 새 그림을 옆에 만든다(원본 보존). ③ 데이터는 내 프로젝트 폴더에 로컬 저장 — 플러그인 저장소가 아니라 canvas/에, 페이지·에셋 단위 JSON으로.
"AI 이미지 생성"을 채팅에서 캔버스로 옮긴 타이밍 + Codex 플러그인 생태계 초기 선점.
cowart는 TrendShift에서 #AI image generation 토픽으로 단숨에 1위권에 올랐다. 별(235개)·커밋(17개) 규모는 아직 작지만, 트렌딩 모멘텀이 큰 이유는 "지금 가장 뜨거운 두 흐름 — AI 이미지 생성과 코딩 에이전트 플러그인 — 의 교차점"에 정확히 서 있기 때문이다. 다섯 가지로 본다.
채팅으로 이미지를 만들면 위치·크기 개념이 없고, 만든 그림의 특정 부분만 고치기가 어렵다. cowart는 무한 캔버스 위에 그림을 놓아, "이 액자에", "원본 오른쪽에", "이 화살표가 가리키는 곳을" 같은 공간적 지시를 자연스럽게 만든다. 생성 → 비교 → 수정의 반복이 눈앞에서 흐른다.
Codex의 플러그인 체계(.codex-plugin/plugin.json + 스킬 + MCP)는 아직 초기다. cowart는 그 위에 GUI(브라우저 캔버스)를 결합한 드문 예 — "에이전트가 터미널을 넘어 시각 도구를 갖는" 패턴을 작은 코드로 보여 준다. 후발 플러그인 제작자에게 참고 견본이 된다.
무한 캔버스·도형 모델·실행취소·직렬화 같은 어려운 것을 직접 짜지 않고 성숙한 tldraw를 쓴다. cowart가 더한 자기 가치는 "AI 이미지 액자 + 주석 도구 + 로컬 저장 + 에이전트 연동" 네 가지뿐 — 작지만 정확한 레버리지다.
캔버스 데이터를 클라우드가 아니라 내 프로젝트의 canvas/에 페이지·에셋 단위 JSON으로 둔다. 그래서 git에 함께 커밋하거나, 프로젝트와 같이 옮기거나, 통째로 백업하기 쉽다. "내 작업은 내 폴더에"라는 프라이버시·이식성 이점.
브라우저(그리기) · 로컬 API 서버(저장) · MCP 서버(에이전트 다리)를 깔끔히 나누고, 셋을 파일 + HTTP + SSE로 잇는다. 덕분에 브라우저와 에이전트가 직접 얽히지 않아 코드가 단순하다. "에이전트와 GUI를 어떻게 잇나"의 작고 읽기 좋은 답안이다.
| 방식 | AI 이미지를 다루는 법 | cowart와의 차이 |
|---|---|---|
| 채팅형 이미지 생성 | 글로 요청, 결과도 채팅에 | 위치·크기·부분 수정이 약함. cowart는 캔버스 위 공간 지시로 해결. |
| tldraw/엑스칼리드로 단독 | 그리기만, AI 없음 | 생성·수정이 없음. cowart는 AI 액자·주석 수정을 얹음. |
| 피그마/클라우드 AI | 브라우저+클라우드 | 데이터가 외부로. cowart는 로컬·프로젝트 폴더 저장. |
| cowart | Codex 안의 로컬 캔버스로 생성·주석수정 | tldraw + AI 액자 + 주석 루프 + 로컬 저장 + 에이전트 연동. |
1천여 줄 남짓의 핵심 코드(App.jsx·vite.config.js·server.mjs)로 무한 캔버스·로컬 API·SSE 동기화·직접 짠 MCP를 모두 보여 준다. tldraw·Vite·MCP·Codex 플러그인을 한 레포에서 동시에 배우기 좋은 교본.
cowart는 독립 앱이 아니라 Codex 플러그인이라, Codex(와 그 이미지 생성 능력)가 없으면 반쪽이다. 이미지 생성 자체는 cowart가 하지 않고 Codex의 imagegen 스킬·이미지 모델에 의존한다. 아직 v0.1대 초기(별 235·커밋 17)라 구조가 바뀔 수 있고, 저장소에 LICENSE 파일이 없어 재사용·배포 조건이 불분명하다. 스킬 일부 문구가 중국어(批注·替换)·OpenAI Codex 내부 도구 가정에 묶여 있어, 다른 호스트로 그대로 옮기긴 어렵다.
package.json · vite.config.js · mcp/server.mjs · src/ 를 실제로 뜯어 확인한 구성.
cowart는 거의 전부 JavaScript(ESM)로 짜였고, 역할별로 ⓐ 브라우저 캔버스, ⓑ 로컬 API 서버, ⓒ MCP 다리, ⓓ Codex 스킬·플러그인, ⓔ 저장(파일시스템)으로 나뉜다. 외부 추론 서버·DB가 전혀 없는 "로컬 파일 + 작은 HTTP" 설계가 특징이다.
| 구성요소 | 무엇 | 역할 |
|---|---|---|
| tldraw ^5.1.1 | 무한 캔버스 라이브러리 | 도형·줌·실행취소·스냅샷의 엔진. cowart UI의 90%가 여기 위에 얹힘. |
| react ^19 / react-dom ^19 | UI 프레임워크 | tldraw를 감싸 캔버스를 렌더링(src/App.jsx·main.jsx). |
| @tiptap/pm 3.27.0 | ProseMirror 묶음 | 주석 화살표의 라벨 글자 편집(리치 텍스트 선택·수정)에 사용. |
| fractional-indexing ^3.2.0 | 분수 인덱스 | 도형 쌓임 순서(z-order)를 generateKeyBetween으로 안전하게 매김. |
| 구성요소 | 무엇 | 역할 |
|---|---|---|
| vite ^7 + @vitejs/plugin-react | 빌드 도구 겸 dev 서버 | React를 번들링하고 127.0.0.1:43217에 캔버스를 띄움. |
| canvasStoragePlugin (자작) | 커스텀 Vite 미들웨어 | 이 레포의 숨은 심장. dev 서버에 /api/* HTTP API와 SSE·정적 에셋 제공을 붙여 "앱 서버"로 만든다. |
| node:http / node:fs | Node 표준 모듈 | 요청 본문 읽기·원자적 파일 쓰기·스트림 전송 등 저수준 처리(외부 의존 없음). |
| 구성요소 | 무엇 | 역할 |
|---|---|---|
| mcp/server.mjs (자작) | 직접 짠 MCP 서버 | SDK 없이 JSON-RPC 2.0을 stdio로 직접 구현. 도구 2개 제공. |
| get_cowart_selection | 읽기 도구 | canvas/cowart-selection.json에서 "지금 무엇이 선택됐나"를 읽음. |
| insert_cowart_image | 쓰기 도구 | 로컬 비트맵을 페이지 에셋 폴더에 복사하고 tldraw 도형으로 삽입, 캔버스 API로 저장. |
플러그인 매니페스트 .codex-plugin/plugin.json이 스킬 3개(cowart-open-canvas·cowart-image-gen·cowart-image-edit)와 MCP 서버(.mcp.json)를 Codex에 등록한다. 각 스킬은 SKILL.md(에이전트가 따를 절차)와 agents/openai.yaml(표시 이름·기본 프롬프트)로 구성된다. 저장은 전적으로 파일시스템 — 프로젝트의 canvas/pages/<페이지id>/cowart-canvas.json(스냅샷) + assets/(이미지) + cowart-selection.json·cowart-view-state.json. 데이터베이스가 없다. 모든 상태가 사람이 열어 볼 수 있는 JSON·이미지 파일이라, git에 함께 담기 좋다.
전체 그림을 한 장으로 본 뒤, "액자에 그림이 채워지기까지"를 끝까지 따라간다.
cowart의 핵심 통찰은 "브라우저(그리기)와 에이전트(Codex)는 직접 대화하지 않는다"는 것이다. 둘 사이에 로컬 HTTP 서버 + 공유 파일이라는 "만남의 광장"을 두고, 거기서만 만난다. 브라우저는 선택·화면 상태를 파일/HTTP로 흘려보내고, 에이전트(MCP)는 그 파일·API를 통해 캔버스를 읽고 바꾼다. 바뀌면 SSE로 브라우저에 "다시 읽어!"라고 알린다. 부품 이름보다 이 광장 구조를 먼저 보자.
initialize → tools/list → tools/call 순서로 악수하고 도구를 호출한다./api/canvas-events로 SSE 채널을 열어, 캔버스가 저장될 때마다 "canvas-changed" 이벤트를 쏜다 → 브라우저가 받아 자동으로 최신본을 다시 읽는다. 이 모든 API·SSE는 Vite 미들웨어 플러그인(configureServer)으로 dev 서버에 직접 붙였다 — 별도 백엔드 서버가 없다.사용자가 액자를 선택하고 "여기 그려 줘"라고 했을 때, 막 뒤에서 벌어지는 일을 순서대로 풀면:
// 사전: ./scripts/start-canvas.sh 로 캔버스(127.0.0.1:43217)가 떠 있음
1. 선택 기록 브라우저: 액자(frame) 선택 → 250ms마다 PUT /api/selection
→ canvas/cowart-selection.json 에 "지금 이 액자가 선택됨" 저장
2. 사용자 요청 Codex 에게 "선택한 액자에 그림 생성" → cowart-image-gen 스킬 발동
3. 선택 읽기 스킬: get_cowart_selection (MCP) 또는 curl /api/selection
→ 선택이 'AI 이미지 액자'인지 확인, 액자의 props.w / props.h 파악
4. 이미지 생성 Codex 내장 imagegen 스킬로 액자 비율에 맞는 비트맵 생성(텍스트 포함 가능)
5. 삽입 insert_cowart_image (MCP): 비트맵을 페이지 assets/ 로 복사 →
tldraw asset+shape 레코드 생성 → PUT /api/canvas 로 저장
6. 저장+알림 Vite 서버: per-page JSON 으로 저장 → SSE canvas-changed 브로드캐스트
7. 자동 반영 브라우저: SSE 수신 → /api/canvas 재요청 → 액자 안에 그림 등장
핵심 관례 둘. 첫째, 선택은 "지금 화면"이 아니라 "파일"에서 읽는다 — 브라우저가 selection을 끊임없이 파일에 적어 두기 때문에, MCP는 캔버스에 직접 묻지 않고 cowart-selection.json만 본다(그래서 캔버스가 떠 있어야 정확하다). 둘째, 삽입할 때 tldraw 레코드를 손으로 쓰지 말고 insert_cowart_image를 쓰라고 스킬이 못 박는다 — 분수 인덱스·자산 경로·겹침 회피 같은 까다로운 일을 도구가 대신 처리한다.
cowart의 시그니처 기능이다. 캔버스의 标注 도구(커스텀 화살표)로 그림 위에 빨간 화살표 + 라벨("여기 더 밝게")을 단다. 그 부분을 캡처해 Codex에 첨부하면 cowart-image-edit 스킬이 작동한다.
1. 주석 달기 캔버스에서 标注 화살표로 "이 부분 고쳐" 표시(원본 위에)
2. 캡처 전달 그 영역 스크린샷을 Codex 에 첨부 (= 한 그림에 대한 '수정 지시서')
3. 의도 해석 스킬: 스크린샷의 화살표·라벨만 읽어 수정 요구 추출
(캔버스 전체를 뒤지지 않음 — 스크린샷이 유일한 근거)
4. 수정본 생성 화살표·라벨·선택표시를 모두 지운 '깨끗한 새 그림' 생성(원본 구도 유지)
5. 옆에 배치 insert_cowart_image(placement:"right", matchAnchor:true)
→ 원본 오른쪽에 같은 크기로 삽입. 원본·주석은 건드리지 않음
설계 의도가 또렷하다. 원본·주석은 절대 지우거나 옮기지 않는다 — 주석은 "수정 지시서"라 증거로 남기고, 결과는 옆에 나란히 둬서 전/후 비교가 쉽게 한다. 여러 장을 주면 각 스크린샷을 독립된 지시서로 처리한다.
MCP 서버는 "현재 선택"을 캔버스에 묻는 게 아니라 cowart-selection.json 파일에서 읽고, 이미지를 삽입할 때도 실행 중인 Vite 서버의 /api/canvas에 HTTP로 저장한다. 그래서 먼저 start-canvas.sh로 캔버스를 띄워야 선택 기록·저장·자동 반영이 모두 작동한다. 캔버스를 안 띄우면 "선택이 비어 있음"으로 보이거나 저장이 실패한다. 또 포트가 다르면(43217이 점유돼 Vite가 43218로 뜨면) cowartUrl로 실제 주소를 넘겨야 한다.
복잡성은 세 파일에 모여 있다 — App.jsx(1025줄) · vite.config.js(627줄) · mcp/server.mjs(651줄).
전체 레포는 작지만 역할이 명확하게 갈린다. 브라우저(src/) · 로컬 서버(vite.config.js) · 에이전트 다리(mcp/) · 플러그인 정의(.codex-plugin/·.mcp.json·skills/) · 실행 스크립트(scripts/)로 묶어 보면 길이 또렷하다.
| 위치 | 한 줄 역할 |
|---|---|
| src/App.jsx | 브라우저의 모든 것. tldraw 마운트, 커스텀 도구(AI 액자·标注 화살표), 선택·화면·캔버스 3중 동기화, SSE 수신. |
| vite.config.js | 로컬 앱 서버. configureServer로 /api/canvas|selection|view-state·SSE·정적 에셋을 dev 서버에 부착. per-page 저장·에셋 지역화. |
| mcp/server.mjs | 에이전트 다리. JSON-RPC/stdio MCP 서버. 선택 읽기·이미지 삽입 도구, 라이브러리 없는 이미지 치수 파서, 겹침 회피 배치. |
| .codex-plugin/plugin.json | Codex에 스킬·MCP·UI 메타(이름·로고·brandColor #25BFEF·기본 프롬프트)를 등록. |
| skills/*/SKILL.md | 에이전트가 따를 자연어 절차서(열기/생성/주석수정). 도구를 언제 어떻게 부를지 규정. |
| scripts/*.sh | 의존성 자동 설치 후 캔버스/ MCP 서버를 띄우는 진입 스크립트. |
| canvas/ (런타임 생성) | 레포엔 없음. 캔버스를 쓰면 사용자 프로젝트 폴더에 생기는 데이터 저장소. |
이 레포 하나로 "tldraw + Vite 미들웨어 + 직접 짠 MCP + 에이전트 연동"을 한 번에 본다.
cowart는 코드가 작은데도 요즘 핵심 주제를 여럿 압축해 담았다. 기술별로 무엇을 건질지 짚는다.
vite.config.js의 canvasStoragePlugin은 configureServer(server) 훅에서 server.middlewares.use(...)로 HTTP API·SSE·정적 파일 서빙을 직접 단다. "프론트 빌드 도구"인 Vite를 작은 백엔드로 쓰는 실전 패턴을 통째로 볼 수 있다.
실습: /api/canvas GET/PUT 핸들러를 읽고, 새 읽기 전용 엔드포인트(예: /api/pages 목록)를 하나 추가해 보기.
mcp/server.mjs는 공식 SDK 없이 readline으로 줄 단위 JSON을 받아 initialize·tools/list·tools/call을 처리한다. MCP가 실제로 어떤 메시지를 주고받는지 추상화 없이 바닥부터 배우는 최고의 교재.
실습: handleRequest 분기를 따라가며, 도구를 하나 더 등록(toolDefinitions + handleToolCall)해 보기.
StateNode를 상속한 标注 화살표 도구, FrameToolbarItem 재구성으로 만든 AI 액자 도구, store.listen으로 변경 감지, migrateSnapshot·mergeRemoteChanges로 원격 스냅샷을 충돌 없이 병합하는 부분이 모두 들어 있다. tldraw를 "쓰는" 수준을 넘어 "확장하는" 법을 본다.
실습: CowartAnnotationTool(StateNode)의 상태 전이를 읽고, 화살표 기본색·굽힘(bend)을 바꿔 보기.
브라우저와 MCP가 직접 안 엮이고 공유 파일(selection) + HTTP API + SSE로만 만나는 디커플링이 핵심 교훈이다. "AI 에이전트가 사람의 GUI와 같은 상태를 보게" 만드는 작고 견고한 패턴을 익힌다.
실습: 브라우저가 selection을 250ms마다 쓰는 루프(syncSelectionState)와 MCP가 그 파일을 읽는 부분(readSelectionState)을 짝지어 읽기.
getImageDimensions는 외부 이미지 라이브러리 없이 파일 앞부분 바이트를 직접 읽어 가로·세로를 구한다(PNG 시그니처, JPEG SOF 마커, WebP VP8X). 파일 포맷의 헤더 구조를 코드로 배우는 알찬 예제다.
실습: PNG 분기(readUInt32BE(16/20))를 따라가며 왜 그 오프셋인지 PNG 스펙과 대조해 보기.
writeJsonAtomic(임시파일→rename)으로 저장 중 깨짐을 막고, isSafeChildPath로 ../ 경로 탈출을 차단하며, fractional-indexing으로 도형 순서를 다시 번호 매기지 않고 끼워 넣는다. 실무 파일 처리의 정석들을 짧게 모아 본다.
실습: saveCanvasSnapshot이 페이지별로 쪼개 저장하고 localizePageAssets로 data URL을 파일화하는 흐름 추적.
GPU 불필요. "Node + 브라우저 + Codex(이미지 생성 가능)"면 충분하다.
cowart 자체는 추론을 하지 않는 로컬 캔버스 + 중계 서버라 고사양이 필요 없다. 이미지 생성은 cowart가 아니라 Codex의 이미지 모델이 담당한다. 실질 요건은 Node 런타임, 브라우저, 그리고 cowart를 플러그인으로 호스팅할 Codex다.
| 항목 | 요구사항 |
|---|---|
| Node.js | Node 18+ 권장(코드가 내장 fetch·structuredClone·ESM 사용). tldraw 5/Vite 7 빌드 환경. |
| 패키지 설치 | npm install(tldraw·react 19·vite 7·@tiptap/pm·fractional-indexing). start-*.sh가 자동 실행. |
| 호스트 | OpenAI Codex CLI — 스킬·MCP·플러그인을 로드하는 주체. cowart는 단독 실행보다 Codex 플러그인으로 동작. |
| 브라우저 | 캔버스 표시용. Codex 인앱 브라우저 권장(스킬이 그 흐름을 안내). |
| 이미지 생성 | Codex의 imagegen 스킬/이미지 모델. cowart는 생성 결과를 캔버스에 배치만 한다. |
| 포트 | 로컬 기본 43217(COWART_PORT로 변경). 점유 시 Vite가 다음 포트로 — 그땐 cowartUrl 전달. |
| 저장 위치 | 사용자 프로젝트 폴더의 canvas/(COWART_PROJECT_DIR/COWART_CANVAS_DIR로 조정). |
| GPU | 불필요(생성은 외부 모델, cowart는 캔버스·파일·HTTP만 다룸). |
가장 빠른 시작은 레포 루트에서 ./scripts/start-canvas.sh /path/to/내-프로젝트를 실행해 http://127.0.0.1:43217을 여는 것이다. Codex로 쓸 땐 README의 설치 안내대로 플러그인을 ~/plugins/cowart에 클론하고 personal 마켓플레이스에 등록한 뒤 codex plugin add cowart@personal로 붙인다.
"캔버스 띄우기"는 10분, "MCP 손으로 호출·도구 추가"는 한나절. 난이도 순으로.
레포를 클론해 npm install 후 ./scripts/start-canvas.sh ~/test-proj로 캔버스를 연다. 도형 몇 개를 그린 뒤 ~/test-proj/canvas/pages/<page-id>/cowart-canvas.json을 열어 tldraw 스냅샷이 어떻게 생겼는지 본다.
캔버스가 떠 있는 상태에서 curl -s http://127.0.0.1:43217/api/canvas와 /api/selection을 호출해 응답 JSON을 살핀다. 캔버스에서 도형을 선택했다 풀었다 하며 selection 응답이 바뀌는 걸 관찰한다.
터미널에서 node mcp/server.mjs를 띄우고, 표준입력에 initialize → tools/list JSON-RPC 메시지를 한 줄씩 붙여넣어 응답을 본다. 도구 2개의 inputSchema와 annotations(readOnlyHint 등)를 읽는다.
캔버스를 띄운 뒤 insert_cowart_image를 dryRun:true로 호출해, 실제 파일을 안 건드리고 배치 좌표만 계산하게 한다. choosePlacement가 앵커 오른쪽에 두되 겹치면 어떻게 비켜 가는지(rectsOverlap) 추적한다.
둘 중 하나를 고른다. (A) server.mjs에 읽기 전용 MCP 도구(예: list_cowart_pages)를 추가한다. (B) App.jsx의 StateNode 패턴을 따라 새 캔버스 도구(예: "측정 자")를 만든다. 빌드 후 동작을 확인한다.
같은 캔버스 URL을 탭 두 개로 연다. 한쪽에서 도형을 옮기면 다른 쪽이 자동 갱신되는지 본다. broadcastCanvasChanged→/api/canvas-events→브라우저 EventSource 수신→loadRemoteCanvasSnapshot의 경로를, 로컬 미저장 변경이 있을 때의 preserveLocalChanges 분기까지 따라간다.
cowart를 100% 소화하기 위한 6주 코스(주당 5~7시간 가정).
| 주차 | 주제 | 학습 자료 / 할 일 |
|---|---|---|
| 1주차 | tldraw 기초 | 무한 캔버스·도형 모델·스냅샷 개념. tldraw 공식 문서 + cowart 캔버스 띄워 보기. 실습 1·2. |
| 2주차 | Vite 플러그인 · 미들웨어 | configureServer로 dev 서버에 API를 붙이는 법. vite.config.js 정독. |
| 3주차 | MCP 프로토콜 | JSON-RPC/stdio, initialize/tools/* 흐름. server.mjs 한 줄씩 + 손으로 호출. 실습 3. |
| 4주차 | Codex 플러그인 시스템 | plugin.json·.mcp.json·skills/*/SKILL.md 구조. 스킬이 도구를 부르는 규칙 이해. |
| 5주차 | SSE · 동기화 · 동시성 | SSE 개념, store.listen·디바운스 저장·mergeRemoteChanges·preserveLocalChanges. 실습 6. |
| 6주차 | 도구/스킬 확장 | 새 MCP 도구 또는 tldraw 커스텀 도구 추가(실습 4·5). 이미지 치수 파서·배치 알고리즘 분석. |
이 문서와 레포에 등장한 용어를 한자리에.
| 용어 | 의미 |
|---|---|
| cowart | Codex 안에서 여는 tldraw 무한 캔버스 플러그인. AI 이미지 생성·주석 수정·로컬 저장이 핵심. |
| Codex | OpenAI의 코딩 에이전트. cowart의 호스트 — 스킬·MCP·플러그인으로 확장된다. |
| tldraw | 오픈소스 무한 캔버스(화이트보드) 라이브러리. cowart의 그리기 엔진. |
| 무한 캔버스 | 경계 없이 펼쳐지고 줌·이동이 자유로운 작업면. |
| MCP | Model Context Protocol. AI가 외부 도구를 쓰는 표준 규약("AI용 USB 포트"). |
| JSON-RPC / stdio | 줄 단위 JSON으로 요청/응답하는 규격 / 표준 입출력 통로. cowart MCP가 이 위에서 동작. |
| SSE | Server-Sent Events. 서버→브라우저 단방향 실시간 알림. 캔버스 자동 갱신에 사용. |
| Vite 미들웨어 플러그인 | configureServer로 dev 서버에 HTTP API·SSE를 붙인 자작 플러그인(canvasStoragePlugin). |
| AI image holder | 캔버스에 두는 빈 액자(frame, meta.cowartAiImageHolder). 생성 그림의 크기·위치 슬롯. |
| 标注 (주석) | cowart 커스텀 화살표 도구. 그림 위에 "여기 고쳐"를 표시 — 수정 지시서가 된다. |
| per-page 스냅샷 | 캔버스를 페이지 단위 JSON으로 쪼개 저장(pages/<id>/cowart-canvas.json). |
| 에셋 지역화(localize) | data URL/외부 이미지 → 페이지 assets/ 파일 + /page-assets/… URL로 변환. |
| selection / view state | 현재 선택·카메라 상태를 파일(JSON)로 기록한 것. 브라우저가 쓰고 MCP/복원이 읽음. |
| fractional-indexing | 도형 쌓임 순서를 분수 키로 매겨, 재번호 없이 사이에 끼워 넣는 기법. |
| StateNode | tldraw에서 커스텀 도구(예: 标注)를 만드는 상태기계 베이스 클래스. |
| structuredClone / 원자적 쓰기 | 객체 깊은 복사 / 임시파일→rename으로 저장 중 깨짐 방지. |
| insert_cowart_image | 비트맵을 페이지 에셋에 복사하고 tldraw 도형으로 삽입·저장하는 MCP 쓰기 도구. |
| get_cowart_selection | 선택 상태 파일을 읽어 "무엇이 선택됐나"를 반환하는 MCP 읽기 도구. |
원문·문서·관련 기술 더 파기.
configureServer 미들웨어)