| name | build-backend |
| description | Builds the Pixel Office Node.js backend server with JSONL file watching, Claude Code log parsing, agent state machine, and WebSocket real-time API. Triggers when server-side features need building or modification.
|
Pixel Office Backend Builder
์ด ์คํฌ์ Pixel Office์ ๋ฐฑ์๋ ์๋ฒ๋ฅผ ๊ตฌ์ถํ๋ค.
Step 1: ์ธ์
ํ์ง (src/server/session-discovery.ts)
Claude Code ์ธ์
์ ์๋์ผ๋ก ์ฐพ๋๋ค:
ํ์ ๊ฒฝ๋ก: ~/.claude/projects/
๊ตฌ์กฐ:
~/.claude/projects/{hash}/
โโโ .session.json
โโโ sessions/
โโโ {session-id}.jsonl
๋ก์ง
~/.claude/projects/ ์ค์บ
- ๊ฐ ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ์
sessions/ ํ์
.jsonl ํ์ผ ์์ง
- ์ต๊ทผ ์์ ์๊ฐ ๊ธฐ์ค์ผ๋ก ํ์ฑ/๋นํ์ฑ ํ๋จ (5๋ถ ์ด๋ด = ํ์ฑ)
- ์ฃผ๊ธฐ์ ์ฌ์ค์บ (10์ด ๊ฐ๊ฒฉ) โ ์ ์ธ์
๊ฐ์ง
์ถ๋ ฅ
- ํ์ฑ ์ธ์
๋ชฉ๋ก:
{ sessionId, projectPath, jsonlPath, lastModified }
Step 2: JSONL ํ์ผ ๊ฐ์ (src/server/watcher.ts)
chokidar๋ฅผ ์ฌ์ฉํ ์ค์๊ฐ ํ์ผ ๊ฐ์:
๋ก์ง
- ํ์ฑ ์ธ์
์ JSONL ํ์ผ ๊ฒฝ๋ก ์์
- chokidar๋ก
change ์ด๋ฒคํธ ๊ฐ์
- ํ์ผ ๋ณ๊ฒฝ ์ ๋ง์ง๋ง ์ฝ์ ์์น ์ดํ์ ์ ์ค๋ง ์ฝ๊ธฐ (tail ๋ฐฉ์)
- ์ ์ค์
parser์ ์ ๋ฌ
- ์ธ์
์ถ๊ฐ/์ ๊ฑฐ ์ watcher ๋์ ์ถ๊ฐ/ํด์
์ฃผ์์ฌํญ
- ํ์ผ ์คํ์
๊ด๋ฆฌ: ๊ฐ ํ์ผ๋ณ ๋ง์ง๋ง ๋ฐ์ดํธ ์์น ๊ธฐ๋ก
- ํ์ผ truncation ๊ฐ์ง: ํ์ผ ํฌ๊ธฐ๊ฐ ์ค์ด๋ค๋ฉด ์คํ์
๋ฆฌ์
- graceful shutdown: ํ๋ก์ธ์ค ์ข
๋ฃ ์ ๋ชจ๋ watcher ์ ๋ฆฌ
Step 3: ์ด๋ฒคํธ ํ์ฑ (src/server/parser.ts)
JSONL ์ค โ AgentEvent ๋ณํ:
Claude Code JSONL ํฌ๋งท ๋์
{"type":"assistant","message":{"content":[{"type":"text","text":"..."}]},"timestamp":"2026-03-29T..."}
{"type":"tool_use","name":"Read","input":{"file_path":"..."},"timestamp":"..."}
{"type":"tool_use","name":"Write","input":{"file_path":"...","content":"..."},"timestamp":"..."}
{"type":"tool_use","name":"Bash","input":{"command":"..."},"timestamp":"..."}
{"type":"tool_result","content":"...","timestamp":"..."}
{"type":"user","message":{"content":"..."},"timestamp":"..."}
ํ์ฑ ๋ก์ง
- JSON.parse ์๋ (์คํจ ์ ๋ฌด์)
type ํ๋๋ก ์ด๋ฒคํธ ์ข
๋ฅ ํ๋ณ
AgentEvent ๊ฐ์ฒด ์์ฑ:
timestamp: ISO โ epoch ms ๋ณํ
sessionId: ํ์ผ๋ช
์์ ์ถ์ถ
type: ์๋ณธ type ์ ์ง
content: tool ์ด๋ฆ ๋๋ ํ
์คํธ ์์ฝ (์ต๋ 100์)
Step 4: ์ํ ๋จธ์ (src/server/state-machine.ts)
AgentEvent โ AgentStatus ๋ณํ:
์ํ ์ ์ด ๊ท์น
| ์ด๋ฒคํธ | โ ์ํ |
|---|
tool_use name=Write/Edit | typing |
tool_use name=Read/Glob/Grep | reading |
tool_use name=Bash | executing |
tool_use name=Agent | executing |
assistant ํ
์คํธ ์๋ต | typing |
user ๋ฉ์์ง ์์ | ์ด์ ์ํ ์ ์ง (user๊ฐ ์๋ตํ์ผ๋ฏ๋ก) |
| ๋ง์ง๋ง ์ด๋ฒคํธ๊ฐ assistant์ด๊ณ 30์ด+ ๋ฌดํ๋ | waiting |
| 60์ด+ ๋ฌดํ๋ | idle |
| ์ธ์
ํ์ผ 5๋ถ+ ๋ฏธ๋ณ๊ฒฝ | done |
์์ด์ ํธ ์ด๋ฆ ์ถ์ถ
- ์ธ์
๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก์์ ํ๋ก์ ํธ๋ช
์ถ์ถ
- ํ์:
Claude-{ํ๋ก์ ํธ๋ช
์ฝ์ด}-{๋ฒํธ}
- ์:
Claude-pixel-1, Claude-api-2
์ข์ ์๋ ๋ฐฐ์
- ์ ์์ด์ ํธ ๊ฐ์ง ์ ๋น ์ข์ ์๋ ๋ฐฐ์
OfficeLayout.seats ์์ assignedAgentId๊ฐ ์๋ ์ข์ ์ ํ
- ์์ด์ ํธ ์ข
๋ฃ ์ ์ข์ ํด์
Step 5: WebSocket ์๋ฒ (src/server/index.ts)
Express + ws ์กฐํฉ:
์๋ํฌ์ธํธ
GET /api/agents โ ํ์ฌ ์์ด์ ํธ ๋ชฉ๋ก (REST)
GET /api/health โ ์๋ฒ ์ํ
ws://localhost:3333/ws โ WebSocket ์ค์๊ฐ ์คํธ๋ฆผ
WebSocket ํ๋กํ ์ฝ
{ "type": "agent-update", "payload": [AgentState, ...] }
{ "type": "agent-update", "payload": AgentState }
{ "type": "agent-added", "payload": AgentState }
{ "type": "agent-removed", "payload": AgentState }
์๋ฒ ํฌํธ
- ๊ธฐ๋ณธ: 3333
- ํ๊ฒฝ๋ณ์:
PIXEL_OFFICE_PORT
ํ์ง ์ฒดํฌ๋ฆฌ์คํธ