一键导入
specflow-update
更新本機 SpecFlow 安裝到 upstream 最新版。Fetch 最新 .claude/ 與 CLAUDE.md,顯示變更摘要,保留本地自訂後套用。觸發關鍵字:"update", "升級", "更新 specflow"。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
更新本機 SpecFlow 安裝到 upstream 最新版。Fetch 最新 .claude/ 與 CLAUDE.md,顯示變更摘要,保留本地自訂後套用。觸發關鍵字:"update", "升級", "更新 specflow"。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
啟動完整的 specflow 專案流程。使用者只需與 spec agent 對話確認需求和架構,之後 tech-lead → (engineer + qa 並行) → verify → release 全部自動背景執行。觸發關鍵字:"start", "開始", "啟動專案", "新專案"。
啟動實作流程(Lane 制:每個類型同時最多 1 個 agent)。Backend / Frontend / Pipeline 各自 1 個 engineer,加 1 個 QA、1 個 UI Designer,共最多 5 個 background agent。觸發關鍵字:"implement", "實作", "開發"。
從 .specflow/state.json 讀取 SpecFlow 流程進度,重建狀態後繼續執行。在 /clear context 之後、或重開 session 時用來接續工作。觸發關鍵字:"resume", "繼續", "接續"。
啟動 QA 撰寫 Playwright e2e tests。根據 spec .md 中的 acceptance criteria 撰寫 Playwright 測試,與 engineer 同時進行。觸發關鍵字:"qa", "測試", "test", "e2e"。
對當前 sprint 進行三維度驗證:Completeness(完整性)、Correctness(正確性)、Coherence(一致性)。在 QA 通過後、release 前執行。觸發關鍵字:"verify", "驗證", "檢查"。
為已完成的專案新增需求變更(Change Request)。spec-writer 評估影響範圍 → 建立 CR 文件 + 新 Sprint milestone → 走原本的 tech-lead → engineer + qa → verify 流程。觸發關鍵字:"change", "新需求", "需求變更", "CR", "後續功能", "新增功能"。
| name | specflow:update |
| description | 更新本機 SpecFlow 安裝到 upstream 最新版。Fetch 最新 .claude/ 與 CLAUDE.md,顯示變更摘要,保留本地自訂後套用。觸發關鍵字:"update", "升級", "更新 specflow"。 |
| user-invocable | true |
| allowed-tools | Read, Write, Edit, Bash, AskUserQuestion |
把本機的 .claude/、CLAUDE.md、.github/workflows/ 同步到 gpwork4u/specflow main branch 的最新版本。
specs/, dev/, test/, design/ — 你的專案內容.specflow/state.json — 進度狀態(schema 變動時走 migration,不直接覆蓋).claude/agents/*.md 或 CLAUDE.md 做的本地改動 — 會先 diff 給你看,保留或合併由你選LOCAL_VERSION_FILE=".specflow/version"
LOCAL_SHA=""
[ -f "$LOCAL_VERSION_FILE" ] && LOCAL_SHA=$(cat "$LOCAL_VERSION_FILE")
echo "本機版本: ${LOCAL_SHA:-(未記錄,視為首次更新)}"
TMPDIR=$(mktemp -d)
git clone --depth 50 https://github.com/gpwork4u/specflow.git "$TMPDIR/specflow" 2>&1 | tail -3
UPSTREAM_SHA=$(cd "$TMPDIR/specflow" && git rev-parse HEAD)
echo "Upstream 最新: $UPSTREAM_SHA"
if [ "$LOCAL_SHA" = "$UPSTREAM_SHA" ]; then
echo "✅ 已是最新版"
rm -rf "$TMPDIR"
exit 0
fi
if [ -n "$LOCAL_SHA" ]; then
echo ""
echo "📋 自上次更新以來的變更:"
echo ""
( cd "$TMPDIR/specflow" && git log --oneline --no-merges "$LOCAL_SHA..HEAD" 2>/dev/null \
|| git log --oneline --no-merges -20 ) | head -30
echo ""
fi
對照「本機現有檔案」和「upstream 對應檔案」,找出本機改過、且 upstream 也改了的檔案 → 衝突需手動決定。
CONFLICT_FILES=""
LOCAL_ONLY=""
SAFE_UPDATE=""
for f in $(cd "$TMPDIR/specflow" && find .claude CLAUDE.md .github/workflows -type f 2>/dev/null); do
UPSTREAM_FILE="$TMPDIR/specflow/$f"
LOCAL_FILE="$f"
if [ ! -f "$LOCAL_FILE" ]; then
LOCAL_ONLY="$LOCAL_ONLY $f"
continue
fi
if cmp -s "$UPSTREAM_FILE" "$LOCAL_FILE"; then
continue # 完全相同
fi
# 本機與 upstream 都不同 — 檢查是否本機有自訂(用 git log 看本機 commit 是否動過)
LOCAL_MODIFIED=$(git log --oneline -- "$LOCAL_FILE" 2>/dev/null | head -1)
if [ -n "$LOCAL_MODIFIED" ] && [ -n "$LOCAL_SHA" ]; then
# 用 git 判斷:upstream 的 LOCAL_SHA 版本和本機現有檔案是否一致
UPSTREAM_AT_LOCAL_SHA=$(cd "$TMPDIR/specflow" && git show "$LOCAL_SHA:$f" 2>/dev/null || echo "")
LOCAL_CONTENT=$(cat "$LOCAL_FILE")
if [ "$UPSTREAM_AT_LOCAL_SHA" != "$LOCAL_CONTENT" ]; then
CONFLICT_FILES="$CONFLICT_FILES $f"
continue
fi
fi
SAFE_UPDATE="$SAFE_UPDATE $f"
done
echo ""
echo "🔄 可安全更新(本機未改動):$(echo $SAFE_UPDATE | wc -w) 個檔案"
echo "🆕 新增檔案:$(echo $LOCAL_ONLY | wc -w) 個"
echo "⚠️ 衝突(本機有自訂):$(echo $CONFLICT_FILES | wc -w) 個"
[ -n "$CONFLICT_FILES" ] && echo "$CONFLICT_FILES" | tr ' ' '\n' | sed 's/^/ /'
AskUserQuestion({
questions: [{
question: "更新策略?",
header: "Update",
multiSelect: false,
options: [
{ label: "全部覆蓋 (Recommended for clean install)", description: "用 upstream 版本覆蓋所有檔案。本機自訂會丟失。建議先 commit 本機改動。" },
{ label: "只更新無衝突的", description: "安全更新沒有本機自訂的檔案,衝突檔案保留本機版本,跑 update 後手動 merge。" },
{ label: "保留衝突備份再覆蓋", description: "把本機衝突檔複製到 .specflow/backup-{timestamp}/,再用 upstream 版本覆蓋,事後可比對 merge。" },
{ label: "取消", description: "不更新,先去檢查本機改動。" }
]
}]
})
根據選擇執行:
case "$STRATEGY" in
"全部覆蓋")
cp -R "$TMPDIR/specflow/.claude/." .claude/
cp "$TMPDIR/specflow/CLAUDE.md" CLAUDE.md
mkdir -p .github/workflows
cp -R "$TMPDIR/specflow/.github/workflows/." .github/workflows/
;;
"只更新無衝突的")
for f in $SAFE_UPDATE $LOCAL_ONLY; do
mkdir -p "$(dirname "$f")"
cp "$TMPDIR/specflow/$f" "$f"
done
;;
"保留衝突備份再覆蓋")
BACKUP=".specflow/backup-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP"
for f in $CONFLICT_FILES; do
mkdir -p "$BACKUP/$(dirname "$f")"
cp "$f" "$BACKUP/$f"
done
cp -R "$TMPDIR/specflow/.claude/." .claude/
cp "$TMPDIR/specflow/CLAUDE.md" CLAUDE.md
mkdir -p .github/workflows
cp -R "$TMPDIR/specflow/.github/workflows/." .github/workflows/
echo "📦 衝突檔備份在 $BACKUP/"
;;
"取消")
rm -rf "$TMPDIR"
exit 0
;;
esac
state.json 結構如果有新欄位(例如這版加的 lane_closed / sprint_test_outcome),補進舊檔案不覆蓋既有值:
if [ -f .specflow/state.json ]; then
# 確保所有預期欄位存在;缺的補預設值
tmp=$(mktemp)
jq '
. + {
lane_closed: (.lane_closed // {feature: false, design: false, qa: false, bug: false}),
sprint_base_sha: (.sprint_base_sha // null),
sprint_test_outcome: (.sprint_test_outcome // null),
sprint_review_outcome: (.sprint_review_outcome // null)
}
' .specflow/state.json > "$tmp" && mv "$tmp" .specflow/state.json
echo "✅ state.json schema 已對齊"
fi
echo "$UPSTREAM_SHA" > .specflow/version
rm -rf "$TMPDIR"
echo ""
echo "✅ SpecFlow 已更新到 $(echo $UPSTREAM_SHA | cut -c1-7)"
echo ""
echo "建議後續:"
echo " 1. 檢查 .github/workflows/ 是否需要 commit + push"
echo " 2. 如果 init-github.sh 有更新(labels / branch protection)→ 重跑 /specflow:init"
echo " 3. 如果有衝突備份,比對 .specflow/backup-*/ 與當前檔案決定 merge"
echo ""
echo "本機 commit 變更:"
echo " git add .claude/ CLAUDE.md .github/workflows/ .specflow/version"
echo " git commit -m 'chore: update specflow to $(echo $UPSTREAM_SHA | cut -c1-7)'"
specs/, dev/, test/, design/, .specflow/state.json 的業務資料只動 schema 不動 value// fallback 不覆蓋).specflow/version 紀錄當前 SHA,下次 update 才能算 changelogcp -R 是 atomic 不會半套.specflow/backup-*/ 拷回衝突檔