name: skill-status-sync description: 原子性地更新TODO.md和state.json中的任务状态。仅限独立使用。 allowed-tools: Bash, Edit, Read
状态同步技能(直接执行)
直接执行技能,用于原子性地在TODO.md和state.json之间同步状态。此技能内联执行而不产生子代理,避免内存问题。
上下文参考
参考(不要预先加载):
- 路径:
.claude/context/core/patterns/jq-escaping-workarounds.md- jq转义模式(问题 #1132)
仅限独立使用
重要:此技能仅限独立使用。
工作流程技能(skill-researcher、skill-planner、skill-implementer等)现在在其内部处理自己的预检/后检状态更新。这消除了Claude可能在技能调用之间暂停的多技能停止边界问题。
使用此技能用于:
- 手动任务状态修正
- 需要更新任务状态的独立脚本
- 当工作流程技能失败时的恢复操作
- 在隔离环境中测试状态更新行为
不要在工作流程命令中使用此技能(/research、/plan、/implement、/revise)——这些命令现在调用单个技能,该技能处理自己的状态更新。
触发条件
此技能在以下情况激活:
- 需要手动状态修正时
- 需要在正常工作流程之外链接工件时
- 需要在TODO.md和state.json之间进行状态同步恢复时
API操作
此技能暴露三个主要操作:
| 操作 | 目的 | 何时使用 |
|---|---|---|
preflight_update |
设置进行中状态 | GATE IN检查点 |
postflight_update |
设置最终状态 + 链接工件 | GATE OUT检查点 |
artifact_link |
添加单个工件链接(幂等) | 工件创建后 |
执行
1. 输入验证
根据操作类型验证必需输入:
对于preflight_update:
task_number- 必须提供并存在于state.json中target_status- 必须是进行中变体(researching、planning、implementing)session_id- 必须提供用于可追溯性
对于postflight_update:
task_number- 必须提供并存在target_status- 必须是最终变体(researched、planned、implemented、partial)artifacts- 要链接的{path, type}数组session_id- 必须提供
对于artifact_link:
task_number- 必须提供并存在artifact_path- 工件的相对路径artifact_type- 其中之一:research、plan、summary
2. 直接执行操作
路由到适当操作并使用Bash(jq)和Edit工具执行。
操作:preflight_update
目的:在GATE IN检查点设置进行中状态
执行:
- 验证任务存在:
task_data=$(jq -r --arg num "{task_number}" \
'.active_projects[] | select(.project_number == ($num | tonumber))' \
specs/state.json)
if [ -z "$task_data" ]; then
echo "错误:任务{task_number}未找到"
exit 1
fi
- 更新state.json:
jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg status "{target_status}" \
'(.active_projects[] | select(.project_number == {task_number})) |= . + {
status: $status,
last_updated: $ts
}' specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json
- 更新TODO.md状态标记:
- 查找任务条目:
grep -n "^### {task_number}\." specs/TODO.md - 使用Edit工具将
[OLD_STATUS]更改为[NEW_STATUS]
- 查找任务条目:
状态映射:
| state.json | TODO.md |
|---|---|
| not_started | [NOT STARTED] |
| researching | [RESEARCHING] |
| planning | [PLANNING] |
| implementing | [IMPLEMENTING] |
返回:JSON对象,状态为“synced”以及先前/新状态字段。
操作:postflight_update
目的:在GATE OUT检查点设置最终状态并链接工件
执行:
- 更新state.json状态和时间戳:
jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg status "{target_status}" \
'(.active_projects[] | select(.project_number == {task_number})) |= . + {
status: $status,
last_updated: $ts
}' specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json
- 将工件添加到state.json(对于每个工件):
重要:使用两步jq模式以避免问题 #1132 转义错误。参见jq-escaping-workarounds.md。
# 步骤1:更新时间戳
jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'(.active_projects[] | select(.project_number == {task_number})) |= . + {
last_updated: $ts
}' specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json
# 步骤2:添加工件(追加到数组)
jq --arg path "{artifact_path}" \
--arg type "{artifact_type}" \
'(.active_projects[] | select(.project_number == {task_number})).artifacts += [{"path": $path, "type": $type}]' \
specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json
-
更新TODO.md状态标记:
- 使用Edit更改状态:
[RESEARCHING]->[RESEARCHED]
- 使用Edit更改状态:
-
在TODO.md中链接工件:
- 在适当位置添加research/plan/summary链接
状态映射:
| state.json | TODO.md |
|---|---|
| researched | [RESEARCHED] |
| planned | [PLANNED] |
| implemented | [IMPLEMENTED] |
| partial | [PARTIAL] |
返回:JSON对象,包含target_status和artifacts_linked字段。
操作:artifact_link
目的:添加单个工件链接(幂等)
执行:
- 幂等性检查:
if grep -A 30 "^### {task_number}\." specs/TODO.md | grep -q "{artifact_path}"; then
echo "链接已存在"
# 返回“skipped”状态
fi
- 添加到state.json工件数组:
重要:使用两步jq模式以避免问题 #1132 转义错误。参见jq-escaping-workarounds.md。
# 步骤1:更新时间戳
jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
'(.active_projects[] | select(.project_number == {task_number})) |= . + {
last_updated: $ts
}' specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json
# 步骤2:添加工件(追加到数组)
jq --arg path "{artifact_path}" \
--arg type "{artifact_type}" \
'(.active_projects[] | select(.project_number == {task_number})).artifacts += [{"path": $path, "type": $type}]' \
specs/state.json > /tmp/state.json && mv /tmp/state.json specs/state.json
- 使用Edit工具在TODO.md中添加链接:
| 类型 | TODO.md中的格式 |
|---|---|
| research | - **Research**: [research-{NNN}.md]({path}) |
| plan | - **Plan**: [implementation-{NNN}.md]({path}) |
| summary | - **Summary**: [implementation-summary-{DATE}.md]({path}) |
插入顺序:
- research:在Language行后
- plan:在Research行后(如果没有Research,则在Language后)
- summary:在Plan行后
返回:JSON对象,状态为“linked”或“skipped”。
返回格式
preflight_update返回:
{
"status": "synced",
"summary": "更新任务#{N}到[{STATUS}]",
"previous_status": "not_started",
"new_status": "researching"
}
postflight_update返回:
{
"status": "{target_status}",
"summary": "更新任务#{N}到[{STATUS}],包含{M}个工件",
"artifacts_linked": ["path1", "path2"],
"previous_status": "researching",
"new_status": "researched"
}
artifact_link返回:
{
"status": "linked|skipped",
"summary": "将工件链接到任务#{N}" | "链接已存在",
"artifact_path": "path/to/artifact.md",
"artifact_type": "research"
}
错误处理
任务未找到
返回失败状态,建议验证任务编号。
无效状态转换
返回失败状态,包含当前状态和允许的转换。
文件写入失败
返回失败状态,建议检查权限。
jq解析失败
如果jq命令因INVALID_CHARACTER或语法错误失败(问题 #1132):
- 记录到errors.json,包含session_id和原始命令
- 使用
jq-escaping-workarounds.md中的两步模式重试 - 如果重试成功,记录恢复操作
集成说明
对于工作流程命令:不要直接使用此技能。工作流程技能现在在其内部处理自己的状态更新。
对于手动操作:使用此技能进行独立状态修正:
### 手动状态修正
调用skill-status-sync,参数:
- operation: preflight_update或postflight_update
- task_number: {N}
- target_status: {valid_status}
- session_id: manual_correction
- artifacts: [{path, type}, ...](仅postflight需要)
此技能确保:
- 跨两个文件的原子更新
- 一致的jq/Edit模式
- 适当的错误处理
- 直接执行,无子代理开销