状态同步技能Skill skill-status-sync

该技能用于原子性地同步TODO.md和state.json文件中的任务状态,仅限独立使用,避免多技能调用问题。支持preflight_update、postflight_update和artifact_link操作,适用于手动状态修正、独立脚本执行和恢复操作。关键词:任务状态同步、原子更新、Bash脚本、DevOps工具、项目管理自动化。

DevOps 0 次安装 0 次浏览 更新于 3/22/2026

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检查点设置进行中状态

执行

  1. 验证任务存在
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
  1. 更新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
  1. 更新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检查点设置最终状态并链接工件

执行

  1. 更新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
  1. 将工件添加到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
  1. 更新TODO.md状态标记

    • 使用Edit更改状态:[RESEARCHING] -> [RESEARCHED]
  2. 在TODO.md中链接工件

    • 在适当位置添加research/plan/summary链接

状态映射

state.json TODO.md
researched [RESEARCHED]
planned [PLANNED]
implemented [IMPLEMENTED]
partial [PARTIAL]

返回:JSON对象,包含target_status和artifacts_linked字段。


操作:artifact_link

目的:添加单个工件链接(幂等)

执行

  1. 幂等性检查
if grep -A 30 "^### {task_number}\." specs/TODO.md | grep -q "{artifact_path}"; then
  echo "链接已存在"
  # 返回“skipped”状态
fi
  1. 添加到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
  1. 使用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):

  1. 记录到errors.json,包含session_id和原始命令
  2. 使用jq-escaping-workarounds.md中的两步模式重试
  3. 如果重试成功,记录恢复操作

集成说明

对于工作流程命令:不要直接使用此技能。工作流程技能现在在其内部处理自己的状态更新。

对于手动操作:使用此技能进行独立状态修正:

### 手动状态修正
调用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模式
  • 适当的错误处理
  • 直接执行,无子代理开销