JianMiauandClaude Fable 5 bc78457372 新增 PM2 部署設定與生產用靜態伺服器
摘要:
加入 ecosystem.config.cjs(web + watch 兩個 app)與零依賴靜態伺服器
server/serve.mjs,並將監看伺服器改為僅綁 127.0.0.1。

根本原因:
先前只能用 vite dev server 開發模式跑,沒有常駐部署方式;
且 watch.mjs 預設綁所有介面,transcript 資料有暴露到區網的風險。

影響:
pm2 start ecosystem.config.cjs 即可常駐:
- claude-office-web:5180,綁 0.0.0.0,區網可看(模擬模式)
- claude-office-watch:5179,僅 127.0.0.1,實況模式限本機瀏覽器

修法:
- server/serve.mjs:零依賴靜態服務 dist/,SPA fallback,
  assets 走 immutable 快取
- watch.mjs listen 加上 127.0.0.1
- README 補 PM2 部署章節(含 Windows 開機自啟說明)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 13:53:54 +08:00

✳ Claude Office

Claude 風格的 multi-agent 虛擬辦公室視覺化。參考 WW-AI-Lab/openclaw-office(MIT)的虛擬辦公室邏輯重新實作,改為 Claude Code 的語意與暖色系視覺。

概念

功能

  • 2D 平面圖辦公室 — 一棟建築、十字走廊、四個分區:
    • 主力工位區(main agents 固定座位)
    • Subagent 熱桌區(subagent 臨時工位)
    • 會議區(協作時自動聚集圓桌)
    • 休息區(咖啡機、沙發、✳ Claude Office 接待櫃台)
  • Chibi 小人 — 依 agent id 確定性生成外觀;姿勢(站/坐/走)與動作(打字/說話/搖晃)由狀態驅動
  • 狀態表情氣泡 — 思考雲、工具調用膠囊(轉動齒輪 + 工具名)、對話氣泡、錯誤驚嘆號、生成火花
  • 走廊尋路 — agent 沿走廊的折線路徑行走(進門 → 走廊中心 → 目的地),等速插值 + 走路擺動
  • 協作連線 — 上級 ↔ subagent(陶土色)、會議成員(紫色)的流動虛線
  • 模擬導演 — 內建劇本引擎:進場報到 → 接任務 → 思考 → 調用工具 → 派 subagent → 回報 → 開會 → 倒咖啡,全部自動循環
  • 控制列 — 暫停 / 1×2×4× 倍速 / 明暗主題 / 招募 agent
  • 側邊面板 — 點擊 agent 查看狀態、模型、工具歷史、上下級關係,可手動指派任務;下方為即時事件紀錄

快速開始

npm install
npm run dev        # http://localhost:5173(預設為劇本模擬模式)
npm run typecheck  # tsc --noEmit
npm run build      # 產出 dist/

實況模式(LIVE)— 顯示真實 Claude Code 活動

另開一個終端啟動監看伺服器,然後點頂欄的「▶ 模擬」切換成「● LIVE」:

npm run watch      # http://localhost:5179/events (SSE)

原理:server/watch.mjs(純 Node、零依賴)輪詢 ~/.claude/projects/ 底下的 session transcript(JSONL),只讀取新增的位元組,轉譯成事件推播給前端:

Transcript 內容 辦公室畫面
近 7 天有活動的專案 一位 agent 入座主力工位(最多 6 席,依最近活躍排序)
使用者送出 prompt 思考中(思考雲)
tool_use(Bash / Edit / Read⋯) 工具調用(齒輪膠囊 + 工具名)
assistant 文字回覆 回覆中(對話氣泡,顯示回覆片段)
Agent / Task 工具派發 subagent subagent 走進熱桌區,和上級連線
subagent 的 tool_result 回來 subagent 離場
專案 15 秒沒動靜 待命;5 分鐘沒動靜 → 離線(Zzz)

注意:監看伺服器會讀取本機的 Claude Code 對話記錄(含程式碼與提示詞), 只綁 127.0.0.1、不要對外開放;如需團隊共用請自行加上驗證。

PM2 部署

npm run build                    # 產出 dist/
pm2 start ecosystem.config.cjs   # 啟動 web(5180)+ watch(5179)
pm2 save                         # 記住程序清單
App Port 綁定 說明
claude-office-web 5180 0.0.0.0 server/serve.mjs 靜態服務 dist/(區網手機可看,模擬模式)
claude-office-watch 5179 127.0.0.1 transcript 監看,僅本機(實況模式只在本機瀏覽器可用)

常用指令:pm2 logs claude-office-webpm2 restart claude-office-webpm2 delete claude-office-web claude-office-watch。 更新版本:git pull && npm run build && pm2 restart all(靜態檔重讀即可, 其實只有 server/ 變動才需要 restart)。

Windows 開機自啟:PM2 原生 pm2 startup 不支援 Windows,可另裝 pm2-windows-startup 或用工作排程器執行 pm2 resurrect

架構

src/
├── lib/
│   ├── constants.ts    # 辦公室幾何(分區/走廊/入口)、Claude 配色、狀態色
│   ├── types.ts        # VisualAgent / MovementState / Meeting / Link
│   ├── appearance.ts   # id → 確定性小人外觀(髮型/膚色/衣著)
│   ├── movement.ts     # 走廊尋路 + 折線等距插值
│   ├── positions.ts    # 工位格點、熱桌、會議圓桌座位、休息區錨點
│   └── phrases.ts      # 模擬台詞庫(任務名/完成語/會議語/工具名)
├── store/
│   └── office-store.ts # Zustand:agents/links/meetings/events + 全部動作
├── sim/
│   ├── director.ts     # 每個 agent 的有限狀態機 + 會議排程器
│   └── runtime.ts      # 單一 rAF 迴圈:tick 移動 → director 更新
└── components/
    ├── FloorPlan.tsx   # 建築外殼、地板紋理、隔間牆、家具、圖層合成
    ├── Pawn.tsx        # chibi 小人(SVG 部件 + CSS 動畫)
    ├── AgentAvatar.tsx # 小人 + 表情氣泡 + 名牌 + 點擊選取
    ├── Emotes.tsx      # 六種狀態氣泡
    ├── ConnectionLine.tsx
    ├── furniture.tsx   # 桌椅/圓桌/沙發/咖啡機/盆栽
    ├── HeaderBar.tsx / SidePanel.tsx
    └── ...

接上真實資料

模擬導演(sim/director.ts)只透過 store 的 action 改變世界。要接上真實的 Claude Code / gateway 事件流,把 director 換成事件轉譯器即可:

事件 對應 action
session 建立 spawnAgent + startWalk 進場
assistant 思考 / 串流 setStatus("thinking" / "speaking") + setSpeech
tool_use setStatus("tool_calling") + setTool
Task(subagent)派生 spawnAgent(role: "subagent") + addLink
session 間協作 startMeeting / endMeeting
session 結束 startWalk(entrance, { despawnOnArrive: true })
S
Description
Claude Office
Readme
1.1 MiB
Languages
TypeScript 75.2%
JavaScript 13.8%
CSS 10.4%
HTML 0.6%