取消技能 是做什么的?
智能取消,检测并取消激活的OMC模式。
取消技能是完成并退出任何OMC模式的标准方式。
当停止钩子检测到工作完成时,它会指示LLM调用此技能以进行正确的状态清理。如果取消失败或被中断,请使用--force标志重试,或等待2小时的陈旧超时作为最后手段。
功能
自动检测哪个模式激活并取消它:
- Autopilot:停止工作流,保留进度以供恢复
- Ralph:停止持久化循环
- Legacy Ultrawork状态:仅清理已升级安装的残存;不是激活的工作流
- UltraQA(已退役):没有实时工作流剩余;清除过时的pre-5.0.0
ultraqa-state.json(如果存在) - Ultragoal:清除会话作用域的ultragoal运行时守卫(
.omc/state/.../ultragoal-state.json),以便PreToolUse/goal执行和Stop强化释放。持久化的.omc/ultragoal/计划/账本工件会被保留。 - Swarm:停止协调的代理集群,释放已认领的任务
- Ultrapilot:停止并行的自动导航工作进程
- Pipeline:停止顺序的代理管道
- Team:通过激活的团队/对话界面请求所有队友关闭,等待响应/超时,清除OMC团队状态,清除关联的ralph(如果存在)。Claude Code 2.1.178+没有TeamDelete。
- Team+Ralph(链接):先取消团队(优雅关闭),然后清除ralph状态。取消已经链接的ralph也会先取消团队。
用法
/oh-my-claudecode:cancel
或者说:"cancelomc", "stopomc"
关键:推迟工具处理
状态管理工具(state_clear、state_read、state_write、state_list_active、state_get_status)可能被Claude Code注册为推迟工具。在调用任何状态工具之前,您必须先通过ToolSearch加载所有这些工具:
ToolSearch(query="select:mcp__plugin_oh-my-claudecode_t__state_clear,mcp__plugin_oh-my-claudecode_t__state_read,mcp__plugin_oh-my-claudecode_t__state_write,mcp__plugin_oh-my-claudecode_t__state_list_active,mcp__plugin_oh-my-claudecode_t__state_get_status")
如果state_clear不可用或失败,请使用此bash回退作为从停止钩子循环中的紧急逃逸。这不是取消流程的完整替代——它仅移除状态文件以解锁会话。链接的激活模式(例如,autopilot→ralph)必须通过为每个模式运行一次回退来分别清除。
将MODE替换为特定模式(例如ralplan、ralph、ultrawork、ultragoal)。
警告: 不要将此回退用于autopilot或omc-teams。Autopilot需要state_write(active=false)来保留恢复数据。omc-teams需要tmux会话清理,仅通过文件删除无法完成。
# 回退:当state_clear MCP工具不可用时直接删除文件
SESSION_ID="${CLAUDE_SESSION_ID:-${CLAUDECODE_SESSION_ID:-}}"
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || { d="$PWD"; while [ "$d" != "/" ] && [ ! -d "$d/.omc" ]; do d="$(dirname "$d")"; done; echo "$d"; })"
# 跨平台SHA-256(macOS:shasum,Linux:sha256sum)
sha256portable() { printf '%s' "$1" | (sha256sum 2>/dev/null || shasum -a 256) | cut -c1-16; }
# 解析状态目录(支持OMC_STATE_DIR集中存储)
if [ -n "${OMC_STATE_DIR:-}" ]; then
# 来自worktree-paths.ts的getProjectIdentifier()镜像
SOURCE="$(git remote get-url origin 2>/dev/null || echo "$REPO_ROOT")"
HASH="$(sha256portable "$SOURCE")"
DIR_NAME="$(basename "$REPO_ROOT" | sed 's/[^a-zA-Z0-9_-]/_/g')"
OMC_STATE="$OMC_STATE_DIR/${DIR_NAME}-${HASH}/state"
[ ! -d "$OMC_STATE" ] && { echo "ERROR: State dir not found at $OMC_STATE" >&2; exit 1; }
elif [ "$REPO_ROOT" != "/" ] && [ -d "$REPO_ROOT/.omc" ]; then
OMC_STATE="$REPO_ROOT/.omc/state"
else
echo "ERROR: Could not locate .omc state directory" >&2
exit 1
fi
MODE="ralplan" # <-- 替换为目标模式
# 清除特定模式的会话作用域状态
if [ -n "$SESSION_ID" ] && [ -d "$OMC_STATE/sessions/$SESSION_ID" ]; then
rm -f "$OMC_STATE/sessions/$SESSION_ID/${MODE}-state.json"
rm -f "$OMC_STATE/sessions/$SESSION_ID/${MODE}-stop-breaker.json"
rm -f "$OMC_STATE/sessions/$SESSION_ID/skill-active-state.json"
# 写入取消信号,以便停止钩子检测到取消正在进行
NOW_ISO="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
EXPIRES_ISO="$(date -u -d "+30 seconds" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || python3 - <<'PY'\nfrom datetime import datetime, timedelta, timezone\nprint((datetime.now(timezone.utc) + timedelta(seconds=30)).strftime('%Y-%m-%dT%H:%M:%SZ'))\nPY
)"
printf '{"active":true,"requested_at":"%s","expires_at":"%s","mode":"%s","source":"bash_fallback"}' \
"$NOW_ISO" "$EXPIRES_ISO" "$MODE" > "$OMC_STATE/sessions/$SESSION_ID/cancel-signal-state.json"
fi
# 仅在无会话ID时清除旧状态(避免清除其他会话的状态)
if [ -z "$SESSION_ID" ]; then
rm -f "$OMC_STATE/${MODE}-state.json"
fi
自动检测
/oh-my-claudecode:cancel遵循会话感知的状态契约:
- 默认情况下,该命令通过
state_list_active和state_get_status检查当前会话,遍历.omc/state/sessions/{sessionId}/…以发现哪个模式激活。 - 当提供了会话ID或已知道时,该会话作用域路径是权威的。如果会话ID缺失或为空,
.omc/state/*.json中的遗留文件仅作为兼容性回退使用。 - Swarm是一个共享的SQLite/标记模式(
.omc/state/swarm.db/.omc/state/swarm-active.marker),不在会话作用域内。 - 默认清理流程会调用
state_clear并传入会话ID,以仅删除匹配的会话文件;模式保持绑定到其原始会话。
激活模式仍然按依赖顺序取消:
- Autopilot(包括链接的ralph和退役状态清理)
- Ralph
- 旧版Ultrawork/UltraQA状态清理
- Ultragoal(独立运行时守卫——
state_clear(mode="ultragoal");保留持久化的.omc/ultragoal/工件) - Swarm(独立)
- Ultrapilot(独立)
- Pipeline(独立)
- Team(Claude Code原生)
- OMC Teams(tmux CLI工作进程)
- Plan Consensus(独立)
- Self-Improve(独立——清除状态,清理孤儿工作树,保留
iteration_state供恢复使用,在解析后的<self-improve-root>/state/agent-settings.json中设置状态:"user_stopped";新运行使用.omc/self-improve/topics/<topic-slug>/,保留扁平的.omc/self-improve/仅用于旧版单轨恢复)
强制清除所有
使用--force或--all当您需要擦除所有会话和遗留工件时,例如完全重置工作区。
/oh-my-claudecode:cancel --force
/oh-my-claudecode:cancel --all
底层步骤:
state_list_active枚举.omc/state/sessions/{sessionId}/…以查找所有已知会话。state_clear为每个会话运行一次以删除该会话的文件。- 不带
session_id的全局state_clear移除.omc/state/*.json、.omc/state/swarm*.db和兼容性工件下的遗留文件(参见列表)。 - Team工件(
~/.claude/teams/*/、~/.claude/tasks/*/、.omc/state/team-state.json)在遗留回退中尽力清除。- 原生团队的取消不影响omc-teams状态,反之亦然。
每个state_clear命令都遵循session_id参数,因此即使在强制模式下,也会先使用会话感知路径,然后再删除遗留文件。
遗留兼容性列表(仅在--force/--all下移除):
.omc/state/autopilot-state.json.omc/state/ralph-state.json.omc/state/ralph-plan-state.json.omc/state/ralph-verification.json.omc/state/ultrawork-state.json.omc/state/ultraqa-state.json.omc/state/swarm.db.omc/state/swarm.db-wal.omc/state/swarm.db-shm.omc/state/swarm-active.marker.omc/state/swarm-tasks.db.omc/state/ultrapilot-state.json.omc/state/ultrapilot-ownership.json.omc/state/pipeline-state.json.omc/state/omc-teams-state.json.omc/state/plan-consensus.json.omc/state/ralplan-state.json.omc/state/boulder.json.omc/state/hud-state.json.omc/state/subagent-tracking.json.omc/state/subagent-tracker.lock.omc/state/rate-limit-daemon.pid.omc/state/rate-limit-daemon.log.omc/state/checkpoints/(目录).omc/state/sessions/(清除会话后空目录清理)
实现步骤
当您调用此技能时:
1. 解析参数
# 检查 --force 或 --all 标志
FORCE_MODE=false
if [[ "$*" == *"--force"* ]] || [[ "$*" == *"--all"* ]]; then
FORCE_MODE=true
fi
2. 检测激活模式
该技能现在依赖于会话感知的状态契约,而不是硬编码的文件路径:
- 调用
state_list_active枚举.omc/state/sessions/{sessionId}/…并发现所有激活的会话。 - 对于每个会话ID,调用
state_get_status以了解哪个激活模式在运行以及是否存在依赖模式;将任何Ultrawork记录仅视为退役清理输入。 - 如果向
/oh-my-claudecode:cancel提供了session_id,则完全跳过遗留回退,仅在该会话路径内操作;否则,仅当状态工具报告没有激活会话时,才查询.omc/state/*.json中的遗留文件。Swarm仍然是一个在会话作用域之外的共享SQLite/标记模式。 - 本文档中的任何取消逻辑都反映了通过状态工具发现的依赖顺序(autopilot → ralph → …)。
3A. 强制模式(如果使用了--force或--all)
使用强制模式通过state_clear清除所有会话和遗留工件。当状态工具报告没有激活会话时,直接文件删除保留用于遗留清理。
3B. 智能取消(默认)
如果团队激活(Claude Code隐式团队)
团队通过OMC团队状态检测,而不是移除的Claude Code ~/.claude/teams配置目录:
# 检查激活的OMC团队状态
state_read(mode="team")
两遍取消协议:
第1遍:优雅关闭
对于激活的OMC团队状态:
1. 从OMC状态/交接/任务簿中读取team_name和工作标签
2. 对于每个激活的队友:
a. 通过激活的对话/团队消息界面询问或通知指定名字的队友
b. 等待最多15秒的shutdown_response
c. 如果响应:标记成员为已确认
d. 如果超时:标记成员为无响应,继续下一个
3. 记录:“优雅通过:X/Y成员已响应”
第2遍:协调
在优雅通过之后:
1. 等待额外5秒,给可能仍在处理的无响应的队友
2. 在取消报告中记录任何剩余的无响应的队友
3. 不要调用TeamDelete;Claude Code 2.1.178+移除了每个团队的原生清理
OMC状态清理:
1. 清除团队状态:state_clear(mode="team")
2. 检查链接的ralph:state_read(mode="ralph") — 如果linked_team为true:
a. 清除ralph状态:state_clear(mode="ralph")
3. 仅对遗留的`omc team` / `/omc-teams`工作进程运行OMC tmux/CLI孤儿扫描(见下文)
4. 发出结构化的取消报告
孤儿检测(清理后):
对于遗留的OMC tmux/CLI工作进程运行,验证没有工作进程残留:
node "${CLAUDE_PLUGIN_ROOT}/scripts/cleanup-orphans.mjs" --team-name "{team_name}"
孤儿扫描程序:
- 检查
ps aux(Unix)或tasklist(Windows)中带有匹配清理团队名称的--team-name的OMC工作进程 - 发送SIGTERM,等待5秒,如果仍存活则发送SIGKILL
- 以JSON格式报告清理结果
使用--dry-run检查而不终止。该扫描程序可以安全地多次运行。
结构化的取消报告:
团队"{team_name}"已取消:
- 通知成员数:N
- 收到的响应数:M
- 无响应数:K(如果存在请列出名称)
- OMC状态已清除:是/否
- 需要手动清理:是/否
路径:OMC团队状态 / tmux工作进程(如果存在)
**实现注意事项:**取消技能由LLM执行,而不是作为bash脚本。当您检测到激活的团队时:
- 读取
state_read(mode="team")以找到激活的OMC团队 - 从状态、交接或任务簿中识别激活的指定名字的队友
- 对于每个队友,通过激活的对话/团队消息界面询问或通知指定名字的队友
- 短暂等待关闭响应(每个成员超时15秒)
- 在协调等待后记录无响应的队友
- 清除团队状态:
state_clear(mode="team", session_id) - 向用户报告结构化摘要
如果Autopilot激活
Autopilot处理其自己的主优先清理:指定名称的工作流额外仅移除其会话拥有的嵌套ralplan强制状态,然后再处理链接的ralph和退役的ultraqa清理。
- 通过
state_read(mode="autopilot", session_id)读取autopilot状态,以捕获确切的当前运行,包括存在的workflowRunId。 - 使用窄变异
state_write(mode="autopilot", session_id, active=false, state={workflowRunId: "<exact run id>"})暂停该确切运行。不要重播或复制状态回读。在带有flock的Linux上,工具在其变异锁下重新验证保持的运行和工作流完整性,然后仅将active更改为false;它保留工作流、管道跟踪和任务标识。target_state_sha256仅当它是当前序列化状态的精确SHA-256时才能包含。- 如果此写入失败,立即停止。不要清除嵌套的ralplan、链接状态、取消信号或运行时工件。
- 对于指定名称的工作流,仅清除由相同
session_id拥有的ralplan状态;永远不要清除另一个会话的独立ralplan状态。记录失败但保持暂停的主状态可恢复。 - 仅在主暂停提交后,通过`state_read(mode="ra…
(已截断)