关于 goal-supervisor
Goal Supervisor 是一项用于在 Claude 工作进程退出后继续推进长期目标或工作流的技能。它从会话记录或检查点恢复任务,并通过标记文件报告完成、阻塞或重试耗尽。
主要功能
- 01以退避策略重启失败进程
- 02通过会话记录和检查点恢复
- 03标记文件报告完成或阻塞
- 04支持受监督的工作流运行
适用场景
- 01Claude 进程退出后恢复目标任务
- 02在独立会话中运行长期工作流
- 03注销或重启后继续监督目标任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ joelfrancisco/ skills --skill goal-supervisor安装后在 Claude Code 中输入/goal-supervisor确认已加载。
附带文件supervise.sh
详细介绍
Goal Supervisor
当负责协调 /goal 的 claude 进程终止时,其子 Agent 仍然存活,但不再有任何进程驱动循环。不过,状态保存在会话记录中——claude -p --resume <session-id> 会恢复会话并保留完整上下文。此技能会启动 supervise.sh(与此 SKILL.md 位于同一目录中——请据此解析绝对路径),利用一对一监督树实现这一机制:
launchd/systemd/tmux (optional) ← keeps the supervisor alive
└── supervise.sh ← restart policy + backoff + stall detection
└── claude -p /goal ← worker, session pinned via --session-id
└── subagents ← survive on their own; the worker re-adopts state
**恢复方式:**监督器自行选择会话 UUID(uuidgen + --session-id)。如果工作进程终止时尚未创建 .supervisor/DONE,监督器就会通过 claude -p --resume <uuid> 重新启动它,并保留完整上下文。工作进程会收到指示:每完成一步,都要更新 .supervisor/checkpoint.md(简短的 claude-handoff 风格摘要);当会话无法恢复时(记录缺失,或恢复反复快速失败),监督器会丢弃该会话,并启动一个新会话,其提示词会指向该检查点,以便延续进度。
**结果:**每次主动停止时,监督器都会以 0 退出,并留下一个标记文件说明停止原因——.supervisor/DONE(目标已完成)、.supervisor/BLOCKED(需要人工处理;阻塞原因写在 checkpoint.md 中)、.supervisor/GAVE_UP(已达到重启次数上限)。非零退出表示监督器本身崩溃——根监督器正是为此而重新启动它。当存在 BLOCKED 或 GAVE_UP 时,重新启动监督器会立即以 0 退出——解决阻塞问题并删除标记文件(或传入 --fresh)即可重试。
调用方式
优先使用守护进程。 agent-supervisord(本脚本原型所基于的 Rust 守护进程)使用相同的标记文件协议进行监督,但语义严格更优:遇到模型或配额限制时会立即转为 BLOCKED,而不是消耗重启次数(bash 脚本会在限制下反复重试),此外还支持重启类型、分组、邮箱 call/cast 以及自监控。只要守护进程运行,就应通过它启动;否则使用 supervise.sh。
- 结合用户意图,确定无头模式下的权限模式——在
-p模式下不会出现交互式提示,因此若目标未使用--permission-mode acceptEdits(或用户要求时使用bypassPermissions),首次遇到被拒绝的编辑时就会卡住。守护进程按类型设置的默认值为 goal→acceptEdits、workflow→bypassPermissions;可传入--claude-arg参数对进行覆盖。 - 如果
agentctl ping有响应,则添加并启动任务。--workdir必须是该目标自己的目录(.supervisor/位于此处,且不同目标之间不得共用;工作进程仍会沿父级目录查找仓库的 CLAUDE.md):
agentctl add --name goal-<slug> --kind goal \
--target "<abs path>/goals/<slug>/goal.md" \
--workdir "<abs path>/goals/<slug>" \
--claude-arg=--permission-mode --claude-arg=bypassPermissions \
--start
(如果目标是 Workflow 脚本,则使用 --kind workflow。)只有在守护进程未运行时,才在后台、当前会话的进程树之外启动 bash 后备方案:
nohup "<path-to-this-skill>/supervise.sh" "goals/<slug>/goal.md" \
-- --permission-mode acceptEdits >/dev/null 2>&1 &
- 告知用户在哪里查看进度,以及哪些标记文件表示运行结果(两种运行方式下路径相同):
agentctl status goal-<slug>/agentctl logs goal-<slug> -f— 守护进程视图tail -f goals/<slug>/.supervisor/worker.log— claude 输出.supervisor/DONE/BLOCKED/GAVE_UP— 结果标记文件(见上文)- 指引正在运行的任务:
agentctl cast goal-<slug> "<instruction>"(会在任务的下一轮传递;仅限守护进程)
supervise.sh 选项
--max-restarts N/--window S— 重启强度(默认每 3600 秒最多重启 10 次,不计首次启动);超过上限后,监督器会放弃、写入GAVE_UP并发送通知。--stall S— 若 S 秒内会话记录没有活动 → 终止并重启(默认 3600;0 表示禁用)。找不到记录文件时不会触发,因此路径不匹配不会导致正常工作的进程被终止。对于存在长时间静默阶段的目标(大型构建、长时间运行的子 Agent),请调高此值。--fresh— 丢弃先前的会话和结果标记文件并重新开始(保留检查点作为记忆)。
工作流(--kind workflow)
长时间运行的工作流会在承载它们的对话压缩时终止——解决方法是隔离:在专用的受监督会话中运行工作流,让该会话的对话保持精简,这样就不会触发压缩。使用相同的目录树,换一个工作进程:
nohup "<path-to-this-skill>/supervise.sh" "path/to/workflow.js" --kind workflow \
-- --permission-mode bypassPermissions --model sonnet >/dev/null 2>&1 &
- 运行器会话对脚本调用 Workflow 工具,将
runId保存到.supervisor/workflow-run-id,等待完成,然后写入.supervisor/result.md和DONE。 - 会话终止后,恢复的会话会使用该文件中的
resumeFromRunId调用 Workflow:已完成的agent()调用会从日志缓存中重放,只有剩余部分会实时运行。恢复后会继续使用相同的 runId 和日志。 - 日志缓存与会话绑定:如果主管必须丢弃会话(记录无法恢复),工作流就会从头开始。
- **权限:**仅有
acceptEdits不够——在无头会话中执行动态工作流脚本会触发交互式审批,导致运行立即终止。请使用--permission-mode bypassPermissions(已验证),或者配置涵盖 Workflow 工具的权限允许列表,以使用范围更窄的权限。 - 端到端验证通过:在第 3/12 阶段运行期间收到 SIGKILL → 恢复 → 从缓存中恢复 3 个阶段,实时运行 9 个阶段,完整结果已交付。
主管的主管(目录树根节点)
要在注销或重启后继续运行,请在系统 init 下运行 supervise.sh 本身。 由于主动停止会以 0 退出,“仅在失败时重启”在两个平台上都能实现所需行为:崩溃会重启,DONE/BLOCKED/GAVE_UP 则保持停止状态。
**macOS(launchd):**生成 ~/Library/LaunchAgents/com.user.goal-<slug>.plist,将 ProgramArguments 指向 supervise.sh + goal.md,将 WorkingDirectory 设为仓库目录,添加 RunAtLoad 和 KeepAlive: {SuccessfulExit: false},然后使用 launchctl load 加载。
**Linux(systemd 用户单元):**快捷方式是使用临时单元:
systemd-run --user --unit=goal-<slug> \
--property=Restart=on-failure --property=RestartSec=30 \
--working-directory=<repo> \
"<path-to-this-skill>/supervise.sh" "goals/<slug>/goal.md" -- --permission-mode acceptEdits
# follow along: journalctl --user -u goal-<slug> -f
要在注销后继续运行,请启用 linger:loginctl enable-linger $USER。
(持久化方式:在 ~/.config/systemd/user/ 中创建 .service,设置 Restart=on-failure + WorkingDirectory,然后运行 systemctl --user enable --now。)
两个平台上的简单替代方案:tmux new -d -s goal-<slug> '...supervise.sh ...'。