Files
claude-office/src/lib/types.ts
T
JianMiauandClaude Fable 5 f935a2ef2d 建立 Claude Office 虛擬辦公室(模擬 + 實況雙模式)
摘要:
參考 WW-AI-Lab/openclaw-office(MIT)的 office-2d 邏輯,重新實作 Claude 風格的
multi-agent 虛擬辦公室:四分區平面圖、走廊尋路、chibi 小人、狀態表情氣泡、
subagent 熱桌、會議聚集,以及可視化真實 Claude Code 活動的實況模式。

根本原因:
需要一個能一眼看出各專案 Claude Code 工作狀態(是否派發任務、調用工具、
派生 subagent)的監控介面,現有工具沒有對應的視覺化。

影響:
新專案,不影響既有系統。實況模式的監看伺服器僅綁 localhost:5179,
會讀取本機 ~/.claude/projects/ 的 session transcripts。

修法:
- Vite 6 + React 19 + Zustand,SVG 平面圖 + CSS 動畫,實測 60fps
- src/sim/director.ts:劇本模擬引擎(FSM + 會議排程)
- server/watch.mjs:零依賴 Node watcher,tail JSONL 轉譯為 SSE 事件
- src/gateway/live.ts:事件對映 store action,支援模式即時切換

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 12:31:18 +08:00

78 lines
1.6 KiB
TypeScript

export type AgentStatus =
| "idle"
| "thinking"
| "tool_calling"
| "speaking"
| "spawning"
| "error"
| "offline";
export type AgentZone = "desk" | "meeting" | "hotDesk" | "lounge" | "corridor";
export type AgentRole = "lead" | "agent" | "subagent";
export interface Point {
x: number;
y: number;
}
export interface MovementState {
path: Point[];
/** total walk duration in seconds */
duration: number;
/** elapsed seconds */
elapsed: number;
toZone: AgentZone;
/** status to apply when the walk finishes */
arriveStatus?: AgentStatus;
/** remove the agent from the office when the walk finishes */
despawnOnArrive?: boolean;
}
export interface ToolCall {
name: string;
startedAt: number;
}
export interface VisualAgent {
id: string;
name: string;
role: AgentRole;
/** model tag shown in the detail panel, e.g. "fable-5" */
model: string;
status: AgentStatus;
position: Point;
zone: AgentZone;
/** permanently assigned seat (desk / hot-desk slot centre) */
homePosition: Point;
homeZone: AgentZone;
homeSlot: number;
currentTool: ToolCall | null;
speech: string | null;
movement: MovementState | null;
parentId: string | null;
childIds: string[];
toolCallCount: number;
toolHistory: string[];
spawnedAt: number;
}
export interface CollaborationLink {
sourceId: string;
targetId: string;
strength: number;
kind: "spawn" | "meeting";
}
export interface Meeting {
id: string;
agentIds: string[];
center: Point;
}
export interface OfficeEvent {
at: number;
text: string;
icon: string;
}