ワンクリックで
openspec-workflow-execute
在 worktree 隔离环境执行 OpenSpec change 的实施计划。基于 Prometheus 生成的 .sisyphus/plans/ 执行,执行后回写 tasks.md 以同步 openspec CLI 状态。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
在 worktree 隔离环境执行 OpenSpec change 的实施计划。基于 Prometheus 生成的 .sisyphus/plans/ 执行,执行后回写 tasks.md 以同步 openspec CLI 状态。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
交互式工作流向导——检查环境、追踪进度、引导用户完成 openspec-workflow 全流程(propose→plan→execute→status/archive)。基于 Markdown 状态文件跨 session 恢复。
发现所有已创建但未建立 branch/worktree 的 OpenSpec change,用户选择后创建 worktree 并生成 Prometheus 实施计划。
分析项目文档与代码的差距,生成 propose 建议列表,用户选择后调用 openspec-propose 创建 artifacts。可多次调用生成多个 propose。
使用 OpenSpec 工作流状态管理工具,检查 worktree 与 change 状态,检测同步问题并修复,支持 merge → archive → cleanup 完整归档流程
CppHDL component lifecycle: ch_device vs ch_module patterns. Use when writing tests, creating Components, or instantiating modules. Covers ch_device (standalone) vs ch_module (hierarchical), correct usage in tests vs Component::describe(), and troubleshooting SIGSEGV from missing parent context.
| 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"} |
在 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 instructions apply --json(tasks.md) | .sisyphus/plans/<name>.md(Prometheus 分解) |
| 执行环境 | 当前目录 | worktree 隔离(.zcf/<name>-wt/) |
| 进度反馈 | 无自动回写 | 每个 Work Unit 完成后 sed 更新 tasks.md |
此技能始终在 git worktree 隔离环境中执行。
所有代码修改和构建都在独立的 .zcf/<name>-wt/ 目录中进行。
# 检测当前 git 上下文
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "unknown")
# 列出所有 worktree 以确定关系
WORKTREE_LIST=$(git worktree list)
# 判断是否在 worktree 内
if echo "$CURRENT_BRANCH" | grep -q '^openspec/'; then
CHANGE_NAME=$(echo "$CURRENT_BRANCH" | sed 's/^openspec\///')
WORKTREE_PATH=$(pwd)
HAS_WORKTREE=true
# 验证当前目录确实是对应的 worktree 目录
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
# ============================================================
# P0 修复:不在 worktree 内时,提供自动引导而非直接退出
# ============================================================
echo "⚠️ 当前不在 worktree 内"
echo ""
# 检查是否有已创建的 worktree
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
# 有 worktree 存在,显示选择菜单
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
# 解析选择 - 动态处理多个 worktree
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 时无冲突
echo "✅ 在 worktree 中: $(pwd)"
echo " Branch: $(git branch --show-current)"
echo " Change: $CHANGE_NAME"
# 检查 build 目录,不存在则创建(首次构建)
if [ ! -d "build" ]; then
echo "⏳ 首次构建(ccache 冷缓存)..."
# ccache 通过 CCACHE_DIR/CCACHE_PREFIX 等环境变量全局配置
# 此处不设 -DCMAKE_CXX_COMPILER_LAUNCHER=ccache,避免与 CMakeLists.txt 预设冲突
cmake -B build
fi
cmake --build build -j$(nproc) 2>&1 | tail -5
# ccache 如果已安装会自动生效(通过 CMake 预设或环境变量)
# 冷构建约 30s,后续增量 <5s
PLAN_FILE=".sisyphus/plans/$CHANGE_NAME.md"
test -f "$PLAN_FILE" || { echo "❌ 计划文件不存在"; exit 1; }
解析计划中的 Work Units:
# 对可并行执行的 Work Units,同时委托多个子代理
for each parallel_group in plan.parallel_groups:
# 同组内 Work Units 无依赖关系
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()
# 执行串行依赖链中的下一个 Work Unit
对存在依赖的 Work Units,按序执行:
for each work_unit in plan.serial_chain:
委托 single deep 代理 → 验证 → 更新 tasks.md
执行完成后,输出清晰的后续操作指引:
# 获取最终进度
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 "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# ============================================================
# P0 FIX: 执行完毕后自动检查是否还有其他 worktree 需要处理
# ============================================================
# 使用 awk 检查分支名(第二列)而非路径,避免路径含 openspec/ 的误匹配
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 完成后必须通过:
1. LSP diagnostics:所有修改文件无 error
2. 编译:cmake --build build -j$(nproc) 成功(0 error, 0 warning)
3. 测试:ctest --output-on-failure 相关测试通过
任何验证失败 → 修复当前 Work Unit → 再继续下一个。
执行完成后必须同步 tasks.md 以通知 openspec CLI:
# 方法 A:已知任务描述,精确匹配(推荐)
# 使用 awk 的 index() 进行字面量匹配(不是 gsub 的正则匹配),
# 避免 TASK_DESC 中的正则元字符(如 [ ] . *)导致静默失败
TASK_DESC="实现UART寄存器配置"
# 使用 index() 精确查找,只在匹配时替换
# index() 返回子串位置(1-based),0 表示不匹配
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
# 方法 B:批量标记所有未完成任务(仅当全部完成时使用)
TMPFILE=$(mktemp /tmp/tasks_XXXXXX.md)
awk '{gsub(/- \[ \] /,"- [x] ")}1' \
openspec/changes/<name>/tasks.md > "$TMPFILE" && \
mv "$TMPFILE" openspec/changes/<name>/tasks.md
# 注意:
# - index() 进行字面量匹配,不会将 TASK_DESC 中的 [ ] . * 等解释为正则
# - 方法 A 使用 exit code 验证替换是否实际发生(方法 B 是全量替换无需验证)
# - mktemp 避免并发场景文件冲突
| 问题 | 检测 | 处理 |
|---|---|---|
| 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}' 动态获取 |