摘要: 參考 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>
78 lines
1.6 KiB
TypeScript
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;
|
|
}
|