| name | openspec-workflow-execute |
| description | 在 worktree 隔离环境执行 OpenSpec change 的实施计划。基于 Prometheus 生成的 .sisyphus/plans/ 执行,执行后回写 tasks.md 以同步 openspec CLI 状态。 |
| license | MIT |
| compatibility | Requires openspec CLI and git worktree. |
| metadata | {"author":"sisyphus","version":"2.4","generatedBy":"1.3.1"} |
OpenSpec 工作流 — Execute
在 git worktree 隔离环境中执行 OpenSpec change 的实施计划。
工作流位置
worktree (openspec/<name>): 本技能在此执行
│
├── 读取 .sisyphus/plans/<name>.md(Prometheus 详细计划)
├── 循环执行每个 Work Unit
│ ├── 委托 deep/unspecified-high 代理实现
│ ├── cmake --build + ctest 验证
│ └── sed 更新 tasks.md([x])通知 openspec CLI
├── 全部完成 → 提示运行 status
└──
与 openspec-apply-change 的关系
本技能是 openspec-apply-change 的扩展版本。区别:
| 维度 | openspec-apply-change | 本技能 |
|---|
| 任务来源 | openspec instructions apply --json(tasks.md) | .sisyphus/plans/<name>.md(Prometheus 分解) |
| 执行环境 | 当前目录 | worktree 隔离(.zcf/<name>-wt/) |
| 进度反馈 | 无自动回写 | 每个 Work Unit 完成后 sed 更新 tasks.md |
输入
- change name(可选,从 git branch 自动推断)
工作模式
此技能始终在 git worktree 隔离环境中执行。
所有代码修改和构建都在独立的 .zcf/<name>-wt/ 目录中进行。
模式自动识别
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "unknown")
WORKTREE_LIST=$(git worktree list)
if echo "$CURRENT_BRANCH" | grep -q '^openspec/'; then
CHANGE_NAME=$(echo "$CURRENT_BRANCH" | sed 's/^openspec\///')
WORKTREE_PATH=$(pwd)
HAS_WORKTREE=true
MAIN_WT_PATH=$(echo "$WORKTREE_LIST" | grep "openspec/$CHANGE_NAME" | awk '{print $1}')
if [ "$MAIN_WT_PATH" != "$(pwd)" ]; then
echo "⚠️ 分支名与 worktree 路径不匹配"
echo " branch: openspec/$CHANGE_NAME"
echo " worktree from list: $MAIN_WT_PATH"
echo " current dir: $(pwd)"
fi
else
echo "⚠️ 当前不在 worktree 内"
echo ""
WT_INFO=$(git worktree list | grep "openspec/" | awk '{print $1, $3}')
if [ -z "$WT_INFO" ]; then
echo "❌ 无已创建的 worktree"
echo ""
echo "请先执行 plan 技能创建 worktree:"
echo " skill_use(\"openspec-workflow-plan <change-name>\")"
echo ""
echo "可用 change 列表:"
ls -d openspec/changes/*/ 2>/dev/null | grep -v archive/ | while read dir; do
name=$(basename "$dir")
echo " - $name"
done
exit 1
fi
echo "📋 发现 $(echo "$WT_INFO" | wc -l) 个已创建的 worktree:"
echo ""
WORKTREE_COUNT=0
while read -r wt_path wt_branch; do
WORKTREE_COUNT=$((WORKTREE_COUNT + 1))
name=$(echo "$wt_branch" | sed 's|^openspec/||')
plan_file="$wt_path/.sisyphus/plans/$name.md"
if [ -f "$plan_file" ]; then
status="✅ 有计划文件"
else
status="⏳ 无计划文件"
fi
echo " $WORKTREE_COUNT. $name"
echo " 路径: $wt_path"
echo " 分支: $wt_branch"
echo " 状态: $status"
echo ""
done <<< "$WT_INFO"
echo "请选择要进入的 worktree(输入编号),或按 Ctrl+C 取消:"
read -p "编号: " choice
selected_line=$(echo "$WT_INFO" | sed -n "${choice}p")
if [ -z "$selected_line" ]; then
echo "❌ 无效选择,请输入 1 到 $WORKTREE_COUNT 之间的编号"
exit 1
fi
target_path=$(echo "$selected_line" | awk '{print $1}')
target_branch=$(echo "$selected_line" | awk '{print $2}')
echo ""
echo "正在切换到 worktree:$target_path"
cd "$target_path"
CHANGE_NAME=$(echo "$target_branch" | sed 's|^openspec/||')
echo "✅ 已切换到: $(pwd)"
echo " Branch: $(git branch --show-current)"
echo " Change: $CHANGE_NAME"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "💡 提示:下次可直接使用以下命令进入此 worktree"
echo " cd $target_path"
echo " skill_use(\"openspec-workflow-execute\")"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
fi
为什么必须在 worktree 内执行?
- 避免对 main 分支的直接修改
- 独立构建目录(
.zcf/<name>-wt/build/)互不干扰
- 支持并行执行多个 change(每个 worktree 独立)
- 隔离 git 操作,merge 时无冲突
执行步骤
Step 1:确认在 worktree 内
echo "✅ 在 worktree 中: $(pwd)"
echo " Branch: $(git branch --show-current)"
echo " Change: $CHANGE_NAME"
Step 2:验证 worktree 构建环境
if [ ! -d "build" ]; then
echo "⏳ 首次构建(ccache 冷缓存)..."
cmake -B build
fi
cmake --build build -j$(nproc) 2>&1 | tail -5
Step 3:读取 Prometheus 计划
PLAN_FILE=".sisyphus/plans/$CHANGE_NAME.md"
test -f "$PLAN_FILE" || { echo "❌ 计划文件不存在"; exit 1; }
解析计划中的 Work Units:
- 标记依赖关系
- 识别可并行执行的独立单元
- 识别串行依赖链
Step 4:并行执行
for each parallel_group in plan.parallel_groups:
for each work_unit in parallel_group:
task(
category="deep",
load_skills=[],
run_in_background=true,
prompt="
WORKTREE: .zcf/<CHANGE_NAME>-wt(在此目录下工作)
目标:实现 Work Unit: <description>
参考计划文件:.sisyphus/plans/<CHANGE_NAME>.md
完成后:
1. 使用 awk 更新 openspec/changes/<CHANGE_NAME>/tasks.md 标记 [x]
2. cmake --build .zcf/<CHANGE_NAME>-wt/build -j$(nproc) 验证
"
)
wait_for_all()
Step 5:串行依赖链执行
对存在依赖的 Work Units,按序执行:
for each work_unit in plan.serial_chain:
委托 single deep 代理 → 验证 → 更新 tasks.md
Step 6:全部完成后输出报告
Step 7:输出明确的下一步操作指引
执行完成后,输出清晰的后续操作指引:
COMPLETE=$(grep -c '^- \[x\]' "openspec/changes/$CHANGE_NAME/tasks.md")
TOTAL=$(grep -c '^- \[' "openspec/changes/$CHANGE_NAME/tasks.md")
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ 执行完成"
echo ""
echo "Change: $CHANGE_NAME"
echo "当前进度:$COMPLETE/$TOTAL"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📋 下一步操作:"
echo ""
echo "1. 在主 session 查看最新进度:"
echo " skill_use(\"openspec-workflow-guide\")"
echo " → 进入 Execute 监控模式"
echo ""
echo "2. 直接归档(如果已完成所有任务):"
echo " cd /workspace/project/CppHDL"
echo " skill_use(\"openspec-workflow-status $CHANGE_NAME --archive\")"
echo ""
echo "3. 继续处理其他 worktree:"
echo " skill_use(\"openspec-workflow-plan\")"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
OTHER_WTS=$(git worktree list | awk '$2 ~ /^openspec\// && $2 != "openspec/'"$CHANGE_NAME"'" {print $1}' | wc -l)
if [ "$OTHER_WTS" -gt 0 ]; then
echo ""
echo "📋 发现其他 $OTHER_WTS 个 worktree:"
git worktree list | awk '$2 ~ /^openspec\// && $2 != "openspec/'"$CHANGE_NAME"'" {print $1, $2}' | while read path branch; do
name=$(echo "$branch" | sed 's|openspec/||')
echo " - $name → $path"
done
echo ""
echo "请选择:"
echo "1. 切换到另一个 worktree 继续执行"
echo "2. 返回主 session(skill_use(\"openspec-workflow-guide\"))"
echo "i. 其他输入"
fi
注意:此输出在每个独立的 execute session 结束时显示,引导用户回到 guide 或继续其他操作。
Work Unit 验证标准
每个 Work Unit 完成后必须通过:
1. LSP diagnostics:所有修改文件无 error
2. 编译:cmake --build build -j$(nproc) 成功(0 error, 0 warning)
3. 测试:ctest --output-on-failure 相关测试通过
任何验证失败 → 修复当前 Work Unit → 再继续下一个。
tasks.md 回写规范
执行完成后必须同步 tasks.md 以通知 openspec CLI:
TASK_DESC="实现UART寄存器配置"
TMPFILE=$(mktemp /tmp/tasks_XXXXXX.md)
awk -v desc="- [ ] $TASK_DESC" -v repl="- [x] $TASK_DESC" '
index($0, desc) { sub(desc, repl); changed=1 }
{ print }
END { exit (changed ? 0 : 1) }
' "openspec/changes/<name>/tasks.md" > "$TMPFILE"
if [ $? -eq 0 ]; then
mv "$TMPFILE" "openspec/changes/<name>/tasks.md"
echo "✅ tasks.md 已更新"
else
echo "⚠️ 未找到匹配的任务描述: $TASK_DESC"
rm -f "$TMPFILE"
fi
TMPFILE=$(mktemp /tmp/tasks_XXXXXX.md)
awk '{gsub(/- \[ \] /,"- [x] ")}1' \
openspec/changes/<name>/tasks.md > "$TMPFILE" && \
mv "$TMPFILE" openspec/changes/<name>/tasks.md
常见问题处理
| 问题 | 检测 | 处理 |
|---|
| plan 文件不存在 | test -f .sisyphus/plans/<name>.md | 提示先执行 plan skill |
| change 不存在 | openspec status 失败 | 提示先 propose |
| worktree 不存在 | test -d .zcf/<name>-wt | 提示先执行 plan skill(含 worktree 创建) |
| 构建失败 | cmake --build 非零退出 | 分析错误,修复后重试当前 Work Unit |
| worktree 路径查找 | test -d .zcf/<name>-wt 不可靠 | 用 git worktree list | awk '$2=="openspec/<name>" {print $1}' 动态获取 |