--- name: Agent Team pane 未关闭修复 description: tmux agent pane 收到关闭要求后未被关闭的根因分析和修复方案 type: feedback originSessionId: 786eafcb-68a7-48e9-838a-174584e5d9e8 --- # Agent Team tmux Pane 未关闭 — 根因分析与修复 ## 问题现象 Agent Team 的 teammate(如 arch-writer-3)收到 `shutdown_request` 后,其 tmux pane 未被关闭,成为孤立 pane。 ## 根因分析(3 个) ### 根因 1: 快照文件被覆盖(最关键) `agent-pane-track.sh` 的 `PreToolUse` 分支每次都会覆盖快照文件。当多个 Agent 同时 spawn 时: ``` Pre(Agent-A) → 写快照 S1 (3 panes) Pre(Agent-B) → 覆盖为 S2 (3 panes,但时间点不同) Post(Agent-A) → 用 S2 比较 → 可能遗漏 Agent-A 创建的 pane ``` **修复**: 仅在快照文件不存在时才创建(`if [ ! -f "${SNAPSHOT_FILE}" ]`),防止后续 Agent 调用覆盖初始快照。同时快照文件名加入 `team_name` 确保同一 team 共享。 ### 根因 2: 清理终止策略不够强 Claude Code 是交互式 Node.js 进程,单次 Ctrl+C 触发确认提示而非退出: - `sleep 1` 太短(Claude 需要更长时间处理中断) - `exit` + Enter 在 Claude 仍在运行时被 Claude 拦截 - `kill-pane` 有条件检查,可能跳过 **修复**: 双次 Ctrl+C → 等 3 秒 → exit → 无条件 kill-pane → 验证关闭 → 失败重试。 ### 根因 3: 无持久化日志 hook 脚本只写 stderr,Claude Code 不持久化 stderr。出问题后无任何痕迹可查。 **修复**: 添加 `.claude/team-panes.log` 持久化日志,记录每次追踪和清理操作。 ## Why: 为什么这些根因会导致问题 Agent Team 通常同时 spawn 多个 teammate(parallel Agent 调用),这触发了快照覆盖的竞态条件。被遗漏的 pane 不会被记录到 `team-panes.json`,因此 `TeamDelete` 清理时根本不知道这些 pane 的存在。 ## How to apply: 后续开发注意事项 1. **tmux hook 脚本必须考虑并发**: 多个 Agent 可能同时触发 hook,共享资源(文件、状态)需要原子操作 2. **kill-pane 应作为最终手段无条件执行**: 不要假设 graceful shutdown 一定成功 3. **持久化日志是必须的**: hook 的 stderr 不会持久化,必须写日志文件 4. **排查孤立 pane 时检查 `team-panes.log`**: 路径 `.claude/team-panes.log` ## 关键文件 | 文件 | 说明 | |------|------| | `.claude/hooks/agent-pane-track.sh` | pane 追踪 hook(已修复快照覆盖) | | `.claude/hooks/team-pane-cleanup.sh` | pane 清理 hook(已增强终止策略) | | `.claude/team-panes.json` | 运行时状态文件 | | `.claude/team-panes.log` | 持久化日志(新增) |