6.2 KiB
6.2 KiB
Claude Code 工作状态监控
状态:方案设计中 | 2026-06-05
需求
在 u-desktop 中即时反馈当前 Claude Code 工作状态(多项目、多会话并行),基于会话指令解析出任务便于跟踪。
两个入口:
- 桌面 Overlay 卡片 — 状态概览 + 会话名 + busy/idle
- 托盘看板窗口 — 完整详情 + 任务列表 + 团队信息 + 进度(置顶 + 可调大小)
数据源
| 源文件 | 内容 | 路径 |
|---|---|---|
| sessions/*.json | 活跃进程:PID、sessionId、cwd、status、name | ~/.claude/sessions/ |
| history.jsonl | 用户输入历史:sessionId + display | ~/.claude/history.jsonl |
| tasks//*.json | 任务列表:subject、status、依赖 | ~/.claude/tasks/ |
| teams//config.json | 团队:成员、模型、工作目录 | ~/.claude/teams/ |
数据关联
sessions/*.json → 活跃会话列表
├─ cwd → 项目名(extractProjectName)
├─ name → 会话名(自动生成的任务摘要,优先展示)
└─ sessionId → 关联 history/tasks
history.jsonl → 尾读 64KB(覆盖 ~3 天)
└─ sessionId → lastPrompt(每个会话最后一条指令)
tasks/<sid>/ → 临时文件,完成即清除
└─ N.json → subject + status + 依赖关系
字段实测(2026-06-05)
PID 20804 → name: "knowledge-card-markdown-rendering" status: busy 项目: u-desktop
PID 22244 → name: "claude-code-status-monitor" status: busy 项目: u-desktop
PID 30064 → name: "add-audio-viz-modes" status: idle 项目: u-desktop
PID 7516 → name: "" status: idle 项目: u-desk
name字段是 Claude Code 自动生成的会话名,比 lastPrompt 更结构化status在 busy 时 updatedAt 实时刷新(~15s),idle 时长时间不更新- history.jsonl 64KB 覆盖 352 行 / 4828 分钟 / 28 个会话,lastPrompt 命中率 4/4
技术方案
采集策略
定时轮询 5 秒(非文件监视)。
理由:
- sessions/ 通常 1-5 个文件 × 300B,全读 <1ms
- history.jsonl 尾读 64KB <1ms
- 与现有 weatherLoop/knowledgeLoop 模式一致
- ReadDirectoryChangesW 在此场景无优势
数据结构
type ClaudeSession struct {
PID int `json:"pid"`
SessionID string `json:"sessionId"`
Project string `json:"project"` // cwd → 项目名
CWD string `json:"cwd"`
Status string `json:"status"` // idle | busy
Name string `json:"name"` // 会话名(任务摘要)
LastPrompt string `json:"lastPrompt"` // 最后用户指令
StartedAt int64 `json:"startedAt"`
UpdatedAt int64 `json:"updatedAt"`
Version string `json:"version"`
Duration string `json:"duration"` // 运行时长
}
type ClaudeTask struct {
ID string `json:"id"`
Subject string `json:"subject"`
Status string `json:"status"` // pending | in_progress | completed
}
type ClaudeStatusData struct {
Sessions []ClaudeSession `json:"sessions"`
TotalActive int `json:"totalActive"`
TotalBusy int `json:"totalBusy"`
UpdatedAt int64 `json:"updatedAt"`
}
关键修正(来自研判)
- isProcessAlive(pid) — 用 OpenProcess 验证进程存活,过滤幽灵会话
- history 尾读跳过首行 — Seek 后首行必然被截断,跳过避免 JSON 解析失败
- 缓存 lastPrompts — 按 PID 集合变化决定是否重新读 history,避免重复解析
推送到前端
复用现有 evalJS() + window.updateClaudeStatusFromGo() 模式。
看板窗口通过 WebView2.Dispatch() 独立推送。
卡片设计
┌─────────────────────────────────────┐
│ Claude Code ●2 忙碌 / 4 活跃 │
│ ─────────────────────────────────── │
│ ● u-desktop knowledge-card... │
│ 最后: 知识卡片刷新按钮修复 │
│ ○ u-desktop add-audio-viz-modes │
│ ○ u-desk ~ │
└─────────────────────────────────────┘
- 优先展示
name(会话名),补充lastPrompt - busy = 绿色脉冲,idle = 灰色
- 最多 5 个会话,超出折叠
看板窗口
- 托盘菜单"Claude 看板"入口
- 独立 WebView2,纯 HTML embed(不走 Vite 构建)
- 深色主题匹配 overlay 风格
- 置顶:
wsExTopmost(0x00000008) 切换 - 可调大小:保留
wsSizebox - 会话详情卡片 + 任务列表 + 团队信息
文件清单
| 文件 | 操作 | 说明 |
|---|---|---|
claude_status.go |
新建 | 监控引擎:轮询采集、数据结构、推送 |
claude_board.go |
新建 | 看板窗口:WebView2 + 置顶 + 可调大小 |
web/claude-board.html |
新建 | 看板页面(纯 HTML embed) |
ClaudeStatusCard.vue |
新建 | Overlay 卡片组件 |
config.go |
修改 | +HideClaudeStatus |
win32.go |
修改 | +wsExTopmost + procOpenProcess + procCloseHandle |
systray.go |
修改 | +看板菜单 + 启动 loop |
wallpaper.go |
修改 | +cardVisibility + reloadAllCards |
settings.go |
修改 | +toggle + refreshVisibleCards |
types.ts |
修改 | +ClaudeStatusData 类型 |
useOverlayState.ts |
修改 | +claudeStatus 状态 |
bridge.ts |
修改 | +updateClaudeStatusFromGo |
SingleLayout.vue |
修改 | +ClaudeStatusCard |
MultiLayout.vue |
修改 | +ClaudeStatusCard + grid area |
ToggleSection.vue |
修改 | +Claude 状态 toggle |
研判结论
| 维度 | 评估 |
|---|---|
| 数据可靠性 | 中→高(加进程存活校验后)。sessions 是第一方数据源,字段稳定 |
| 性能影响 | 极低。每轮 <5ms / 65KB I/O。0.1% CPU |
| 对工具负担 | 零。纯只读、共享读、不锁文件、不连 socket |
| 价值 | 高。多会话并行监控的刚需,无其他工具提供 |
| 成本 | 低。~450 行代码。运行开销可忽略 |
| 性价比 | 极高 |