Install
$ agentstack add skill-yike-gunshi-forge-skills-forge-bugfix ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ● Dynamic code execution Used
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
> 文档落地路径:遵循 forge-doc-policy 规范。完整白名单 + frontmatter schema 见 > ~/claudecode_workspace/工具/forge-cookbook/skills/forge-doc-policy/doc-paths.md。
/forge-bugfix:一次一 bug + Bug 修复验收报告
设计哲学
短会话、单 bug 隔离、结构化证据、可追溯、可丢弃。
核心机制:
- Bug 修复验收报告:每个 bug 从登记/领取开始就创建
docs/bugfix/reviews/BF-XX.md - 发现时:记录来源、现象、初始截图/日志、关联 Feature Spec
- 修复时:记录 worktree、TDD 红绿证据、根因、commit、涉及文件
- QA 时:forge-qa 回填前后端地址、环境身份校验、逐步截图、深度断言
- 人工验收时:用户只看"人工验收指南"和同一组验收地址,填最终结论
- 两种验收节奏:
- 单 bug 模式:QA 全过后立即进入 P6.5,等用户验收该 bug
- QA 自动闭环 / 批量模式:单 bug QA 通过后标记
qa-pass-pending-final-review,最后由批次汇总统一交给用户验收 - 新发现必须分流(禁止顺手修):
- 原 bug 未 Pass 前:只记录为“待确认新发现”,不进入当前修复
- 原 bug 已 Pass 后:先明确告知用户“本次 bug 修复已完成”,再询问是否写入文档
- 用户确认后,独立 bug →
docs/bugfix/backlog.md的待修区,分配 BF-XX 编号 - 用户确认后,新需求 →
docs/bugfix/backlog.md的新需求区,建议 /forge-prd 立项 - 用户确认后,模糊反馈 →
docs/bugfix/backlog.md的待澄清区 - 同根(并入当前修复)→ AI 必须举证(同文件/同函数/同数据流的具体证据),举证不通过默认独立 bug
- Pass 边界接力:
- 只要原 bug 已 Pass,不论新问题来自用户验收、QA 发现,还是 AI 在修复中发现的衍生问题,都不得继续修
- AI 必须先说清楚:原 bug 已收敛、证据是什么、当前修复到此关闭
- 再问用户:是否把新问题更新到
docs/bugfix/backlog.md/ 报告中 - 用户确认后,AI 完成 P7.5 分流,并给一段简短接力 prompt,让用户开另一个会话继续
- 下一个 bug 默认建议新会话或 /clear、/compact:
- 上下文干净 + 边界清晰 + 避免长会话的 scope 蔓延
- 除非用户明确要共因地一起修
> 演进历史和设计决策背景见 forge-cookbook/docs/forge-bugfix-changelog.md。
铁律
- 不做根因分析,就不写修复代码。 直觉再强也要先验证。
- 每次只修 1 bug,或 1-2 个经 P4.5 确认共因的 bug。其余进
docs/bugfix/backlog.md。 - 每个 bug 独立 worktree + 独立 TDD + 独立 commit + 独立 QA 回归。批量只做编排,不合并工程单元。
- 修完不自动合并,必须等用户填完单 bug 或批次最终验收结论。
- 没有 Bug 修复验收报告不算完。每个 BF 编号必须有
docs/bugfix/reviews/BF-XX.md,经 forge-qa 和用户/批次两层验收后才进 P7。 - 新发现的 bug / 新需求 / 模糊反馈 → 原 bug Pass 后询问是否写入
docs/bugfix/backlog.md,绝不在当前修复内夹带。 - 同根判定必须举证。AI 声称"这条新发现是当前 bug 同根"时,必须列出具体证据(同文件、同函数、同数据流),证据不足默认为独立 bug。
- 并行协调必须登记(v6.0)。P2 确认范围 + P3 创建 worktree 之后,必须在项目根
.forge/active.md追加一行会话登记;P2 推荐前必须读.forge/active.md做功能域判重;P7 合并前必须跑git merge --no-commit --no-ff预演。清理 active 的责任在 forge-fupan 或 /forge-status,不在 forge-bugfix 自己。 - 自动闭环有上限。同一 bug 连续回修失败 3 次,或遇到需求/设计/环境身份不确定,必须标记
blocked-human并让用户判断,禁止无限循环。
流程总览
═══════════ 会话级(每会话一次,多次修复复用)═══════════
P0 环境探测(前置脚本,自动执行)
P1 问题理解 + 强制读 PRD/ENGINEERING/Bugfix 历史/Memory
═══════════ 每次修复(一次一 bug,可循环)═══════════
P2 范围推荐
├─ AI 从 docs/bugfix/backlog.md 捞候选 + 列出本会话新报告的 bug
├─ AI 接收 forge-qa 发现的结构化 bug(若来自 QA 自动闭环)
├─ 推荐"本次修 X"(1 个 / 或 1-2 共因),其余 → backlog
└─ 用户确认范围
P2.5 创建/更新 Bug 修复验收报告 docs/bugfix/reviews/BF-XX.md
├─ 写入来源、现象、初始证据、Feature Spec 场景、功能域、当前状态
└─ 同步 backlog.md 的报告链接
P3 创建 worktree(端口预检)+ 复现
P4 根因追踪 + 假设验证 + 5 Whys + 修复方案确认
P5 worktree 内独立 TDD 驱动修复 + 原子提交
P5.3 ⭐ 更新 Bug 修复验收报告为待 QA 状态
├─ 写入 TDD 红绿证据、根因、修复摘要、commit、涉及文件
└─ 写入人工验收指南草案,QA 区域留给 forge-qa
P6 ⭐ 调用 forge-qa 自动验收
├─ forge-qa 针对每个验证项跑自动化测试
├─ 强校验 Frontend/Backend 地址、PID、cwd、commit 一致性
├─ 把每个前端交互关键步骤截图嵌入报告
├─ QA 全过 → 单 bug 模式进 P6.5;批量模式标记 qa-pass-pending-final-review
└─ QA 有挂 → 有界回 P5;达到上限或有疑问则 blocked-human
P6.5 ⭐ 用户人工验收 / 批次最终验收
├─ AI 输出"请人工验收 @ docs/bugfix/reviews/BF-XX.md"
├─ 用户打开文档填"你的验收"列 + 最终结论(Pass / Fail / Pass + 新发现)
└─ 用户说"验收了" → AI 读报告 → 判定
P7 ⭐ 按最终结论分流
├─ Pass → worktree 合并决策(合并 / 暂存 / 推迟)
├─ Fail → 回 P5(只修原 bug,不接新问题)
└─ Pass + 新发现 → 先完成当前修复的合并/暂存决策 → 进 P7.4
P7.4 ⭐ Pass 边界确认 + 文档更新询问
├─ 告知用户:本次 bug 已完成,当前修复到此关闭
├─ 列出新问题来源:用户反馈 / QA 发现 / AI 发现的衍生问题
├─ 询问是否写入 docs/bugfix/backlog.md / 报告索引
├─ 用户确认 → 进 P7.5 分流,并输出简短接力 prompt
└─ 用户不确认 → 不写 backlog,不继续修新问题,结束本次 bugfix
P7.5 ⭐ 新发现分流到 backlog
├─ 逐条分析,AI 做分类判断(同根 / 独立 bug / 新需求 / 模糊反馈)
├─ 同根(声称时必须举证)→ 新 bug 建议在新会话修
├─ 独立 bug → backlog.md 的 🐛 待修区,分配 BF-XX
├─ 新需求 → backlog.md 的 💡 新需求区,建议 /forge-prd 立项
└─ 模糊反馈 → backlog.md 的 🌀 待澄清区
P8 沉淀:归档 backlog 对应条目 + bugfix 文档补记
═══════════ 出口 ═══════════
- 用户想继续修下一个 bug → 默认建议新会话或 /clear、/compact
(除非明确共因才本会话继续,由用户主动选择)
- 全部完成 → 建议 /forge-review、/forge-ship 或 /forge-fupan
红线:
- 写任何修复代码前必须完成 P2-P4(含范围确认和 5 Whys 根因确认)
- 每个 BF 编号必须先有 Bug 修复验收报告(P2.5),修复后必须更新报告(P5.3)才能进入 QA
- 报告没有用户最终结论或批次最终结论前,不进 P7——即使 QA 全过
- 同根判定声称必须举证,证据不足默认独立 bug → 原 bug Pass 后问用户是否写入 backlog,再走新会话
P0 环境探测(会话级·前置脚本,自动执行)
# === 基础信息 ===
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
echo "分支: $_BRANCH"
echo "根目录: $_ROOT"
echo "---"
# === Git 状态 ===
echo "=== Git 状态 ==="
git status --porcelain 2>/dev/null | head -20
echo "=== 最近 10 条提交 ==="
git log --oneline -10 2>/dev/null
echo "---"
# === 现有 worktree 清单 ===
echo "=== 现有 worktree ==="
git worktree list 2>/dev/null
echo "---"
# === 复现引擎 1: gstack/browse → $BROWSE ===
BROWSE=""
for p in "$_ROOT/.Codex/skills/gstack/browse/dist/browse" \
"$HOME/.Codex/skills/gstack/browse/dist/browse" \
"$_ROOT/.Codex/skills/browse/dist/browse" \
"$HOME/.Codex/skills/browse/dist/browse"; do
[ -x "$p" ] && BROWSE="$p" && break
done
[ -n "$BROWSE" ] && echo "BROWSE=$BROWSE" || echo "BROWSE=(不可用)"
# === 复现引擎 2: Playwright → $PW_AVAILABLE ===
PW_AVAILABLE="false"
if command -v npx &>/dev/null && npx playwright --version &>/dev/null 2>&1; then
PW_AVAILABLE="true"
elif python3 -c "from playwright.sync_api import sync_playwright" 2>/dev/null; then
PW_AVAILABLE="true"
fi
echo "PW_AVAILABLE=$PW_AVAILABLE"
# === 框架 / 测试框架 / Dev Server 状态 ===
# ... 框架探测 / 测试框架探测 ...
# === 统一 dev server 入口 → $APP_URL ===
APP_URL=""
DEV_STATUS=""
if [ -f "$_ROOT/package.json" ] && (cd "$_ROOT" && npm run 2>/dev/null | grep -q "dev:status"); then
DEV_STATUS="$(cd "$_ROOT" && npm run dev:status 2>/dev/null || true)"
echo "$DEV_STATUS"
APP_URL="$(printf "%s\n" "$DEV_STATUS" | awk '/Frontend:/{print $2; exit}')"
elif [ -x "$_ROOT/scripts/dev-stack.sh" ]; then
DEV_STATUS="$(cd "$_ROOT" && bash scripts/dev-stack.sh status 2>/dev/null || true)"
echo "$DEV_STATUS"
APP_URL="$(printf "%s\n" "$DEV_STATUS" | awk '/Frontend:/{print $2; exit}')"
else
# 兼容旧项目:只读探测,不把探测结果当作 worktree 启动许可
for port in 3456 3000 4000 5173 8080 8000; do
if lsof -i :"$port" -sTCP:LISTEN &>/dev/null 2>&1; then
APP_URL="http://localhost:$port"
_PID=$(lsof -ti :"$port" -sTCP:LISTEN 2>/dev/null | head -1)
_CWD=$(lsof -p "$_PID" 2>/dev/null | awk '$4=="cwd"{print $9}')
echo "APP_URL=$APP_URL (PID=$_PID cwd=$_CWD)"
break
fi
done
fi
[ -z "$APP_URL" ] && echo "APP_URL=(未检测到运行中的应用)"
# === 项目文档清单 ===
DOC_PRD=""; DOC_ENG=""; DOC_QA=""; DOC_BACKLOG=""; DOC_BUGFIX=""; DOC_REVIEWS=""
for p in "$_ROOT/docs/PRD.md" "$_ROOT/PRD.md"; do [ -f "$p" ] && DOC_PRD="$p" && echo "PRD: $p" && break; done
for p in "$_ROOT/docs/ENGINEERING.md" "$_ROOT/ENGINEERING.md"; do [ -f "$p" ] && DOC_ENG="$p" && echo "ENGINEERING: $p" && break; done
for p in "$_ROOT/docs/QA.md" "$_ROOT/QA.md"; do [ -f "$p" ] && DOC_QA="$p" && echo "QA: $p" && break; done
# backlog(bug 任务池,单一入口)
for p in "$_ROOT/docs/bugfix/backlog.md" "$_ROOT/backlog.md"; do
[ -f "$p" ] && DOC_BACKLOG="$p" && echo "BACKLOG: $p" && break
done
if [ -z "$DOC_BACKLOG" ]; then
DOC_BACKLOG="$_ROOT/docs/bugfix/backlog.md"
echo "BACKLOG(首次使用,将从模板初始化): $DOC_BACKLOG"
fi
# reviews 目录(每个 bug 一个 Bug 修复验收报告)
DOC_REVIEWS="$_ROOT/docs/bugfix/reviews"
mkdir -p "$DOC_REVIEWS" 2>/dev/null
echo "REVIEWS 目录: $DOC_REVIEWS"
[ -d "$_ROOT/docs/bugfix" ] && DOC_BUGFIX="$_ROOT/docs/bugfix" && echo "BUGFIX 历史: $DOC_BUGFIX"
# === 报告目录 ===
REPORT_DIR="$_ROOT/.gstack/bugfix-reports"
mkdir -p "$REPORT_DIR/screenshots" 2>/dev/null
echo "报告目录: $REPORT_DIR"
# === 并行会话环境(v6.0 新增)===
# active.md: 跨 worktree 的心跳文件,项目根 .forge/active.md
mkdir -p "$_ROOT/.forge" 2>/dev/null
ACTIVE="$_ROOT/.forge/active.md"
if [ ! -f "$ACTIVE" ]; then
# 首次使用,从模板初始化(模板路径按 skill 安装位置回退)
for tpl in "$HOME/.claude/skills/forge-bugfix/templates/active.md" \
"$HOME/.claude/skills/forge/skills/forge-bugfix/templates/active.md"; do
[ -f "$tpl" ] && cp "$tpl" "$ACTIVE" && echo "✅ 初始化 .forge/active.md(请编辑功能域声明区)" && break
done
fi
echo "ACTIVE=$ACTIVE"
# 当前 Claude Code session id(通过 PID 回溯 ~/.claude/sessions/.json)
SID_SCRIPT=""
for s in "$HOME/.claude/skills/forge-bugfix/scripts/get-session-id.sh" \
"$HOME/.claude/skills/forge/skills/forge-bugfix/scripts/get-session-id.sh"; do
[ -x "$s" ] || [ -f "$s" ] && SID_SCRIPT="$s" && break
done
CURRENT_SID=""
if [ -n "$SID_SCRIPT" ]; then
CURRENT_SID=$(bash "$SID_SCRIPT" 2>/dev/null || echo "")
fi
[ -n "$CURRENT_SID" ] && echo "SESSION_ID=$CURRENT_SID" || echo "SESSION_ID=(无法自动获取,后续 P3 会提示)"
# 扫一眼 active.md 里"进行中会话"节,报告当前有哪些并行会话
if [ -f "$ACTIVE" ]; then
echo "--- 当前并行会话 ---"
awk '/^## 进行中会话/{flag=1;next} /^## /{flag=0} flag && /^- /{print}' "$ACTIVE" | grep -v ' ⚡ **会话级声明**:本步只在会话首次进入时执行一次。同一会话做多次修复时,P1 不重读,直接复用上下文。
### 1.1 解析用户输入
用户报告 bug 的方式:
- 直接描述现象 / 粘贴错误 / 提供截图 / 引用已有 Bug ID
### 1.2 强制读取项目文档
**不读 PRD 不知道"正确",不读 ENGINEERING.md 不理解数据流,不读 bugfix 历史会重复排查。**
| 文档 | 必须/按需 | 读什么 |
|------|-----------|--------|
| PRD (`$DOC_PRD`) | **必须** | 功能预期行为、验收标准 |
| ENGINEERING.md (`$DOC_ENG`) | **必须** | 架构、数据流、模块边界 |
| Bugfix 历史 (`$DOC_BUGFIX`) | **必须** | 已修 bug 的根因 — 防重复排查 |
| **Backlog (`$DOC_BACKLOG`)** | **必须** | 任务池 — 了解已登记待修 bug / 新需求 / 待澄清反馈 |
| **已归档已处理区** | **必须** | 历史修复回溯 — 以后遇到类似问题时搜这里 |
| QA.md (`$DOC_QA`) | 按需 | 已知问题列表 |
| Memory(MEMORY.md) | **必须** | feedback 类条目 — 历史踩坑 |
| `git log --since="3 days" -- affected-files` | 按需 | 最近变更(回归 Bug 必看)|
#### Bugfix 历史检索
```bash
if [ -n "$DOC_BUGFIX" ]; then
ls -t "$DOC_BUGFIX"/*.md 2>/dev/null | head -5
grep -rl "" "$DOC_BUGFIX" 2>/dev/null
fi
匹配到历史记录 → AskUserQuestion:"这个问题与 BF-XXXX-N 类似,上次根因是 XXX,沿用还是重新排查?"
1.3 检查工作区状态
git status --porcelain
主仓库有未提交变更 → AskUserQuestion:
- A) 先提交 — commit 后再开始(推荐)
- B) 先暂存 — stash,修复完 pop
- C) 直接开始 — worktree 隔离,不影响主仓库
1.4 信息不足时
通过 AskUserQuestion 一次问一个:什么操作触发?预期行为?实际行为?一直存在还是最近出现?
P2 范围推荐(多来源捞候选 + 写入 backlog.md)
> 🎯 核心:不做"全量分诊排序后逐个修",而是"AI 推荐单次修复范围,其余进 backlog.md"。 > v6.0 新增:P2 必须做功能域判重(读 .forge/active.md),决定同域合并到已有会话 vs 异域鼓励新窗口并行。 > v7.0 新增:forge-qa 发现的问题也是正式入口。QA 自动闭环可以批量登记 bug,但修复执行仍然一次一个 bug。
2.0 并行状态读取 + 功能域准备(v6.0 新增)
硬性步骤。在 2.1 捞候选之前,AI 必须:
- 读
.forge/active.md
- 解析"功能域声明"区 → 得到本项目的合法功能域标签清单
$DOMAINS - 解析"进行中会话"节 → 得到所有占用中的域集合
$BUSY_DOMAINS(多域条目视为同时占用多个) - 如果
.forge/active.md不存在,AI 提示用户"首次使用并行化,需要你在 .forge/active.md 里声明功能域标签(示例已给出)",并暂停等用户确认后再继续
- 给每条候选 bug 打功能域标签
- 标签必须从
$DOMAINS选取,不得自创 - 重构型 bug 允许多域(逗号分隔),任一域与
$BUSY_DOMAINS有交集即判冲突 - 无法判定时向用户确认,不猜测
- 对照判定
- bug.功能域 ∩
$BUSY_DOMAINS≠ 空 → 标记"⚠️ 域冲突:域 X 当前由 session Y 占用" - bug.功能域 ∩
$BUSY_DOMAINS= 空 → 标记"✅ 可并行"
2.1 AI 捞候选
候选来源有三个:
- 用户本会话报告的 bug(直接描述)
- forge-qa 发现的结构化 bug(来自功能开发后的 QA 自动闭环或完整 QA 报告)
$DOC_BACKLOG的 🐛 待修区(跨会话登记的)
forge-qa 传入的问题必须包含:标题、严重度、关联 Feature Spec 场景、复现步骤、截图/日志证据、Frontend/Backend 地址、环境身份摘要、是否属于本轮功能范围。缺字段则先补齐报告,不直接修。
AI 合并三个来源,推荐本次修哪个/哪些:
推荐规则:
- 默认推荐 1 个 bug
- 当且仅当 AI 判断 2 个 bug 共享同一根因时,可推荐 1-2 个(必须举证)
- 共因判断标准:
✓ 修同一组文件
✓ 改同一个函数/数据结构
✓ 同一个上游依赖(如同一个 API 端点失效)
- 不共因的"看起来类似" → 拆开走多次修复(单独会话)
- 从 backlog 捞候选时,优先级 P0 > P1 > P2,相同优先级按登记时间
2.2 AskUserQuestion 确认
🎯 本次修复范围推荐
本会话新报告:N 个问题
Backlog 待修区:M 个条目(P0: X 个 / P1: Y 个 / P2: Z 个)
当前并行会话:K 个(域 asr / 域 player ... 被占用)
我推荐本次修:
✅ 本次:[Bug A](BF-0419-2)
来源:本会话新报告 / 或 backlog 登记于 2026-04-17
功能域:asr
并行判定:✅ 可并行(域 asr 当前无活跃会话)
或:⚠️ 域冲突(域 asr 已被 session abc-123 占用——建议你切去那个窗口加入而非新开)
理由:阻塞核心流程且独立可定位(或:Bug A + Bug C 共因 = XX.tsx 的 source 字段处理)
📋 推迟到 backlog(下次修复或下次会话再说):
- Bug B: [症状] → 写入 backlog.md 🐛 待修区(P1,域 auth)
- Bug D: [症状] → 写入 backlog.md 🐛 待修区(P2,域 player)
- 新需求 N1: [描述] → 写入 backlog.md 💡 新需求区(建议 /forge-prd)
我会把推迟的写入 `$DOC_BACKLOG`,把本次修复的在 P3 登记到 `.forge/active.md`。
A) 同意推荐 — 进入 P3 创建 worktree 并登记 active
B) 调整范围 — 改修 [其他 bug]
C) 我想多修一些 — 违反单次修复原则,请说明理由
D) 域冲突,我切到已有会话 — 本次终止,去 session abc-123 的窗口继续
2.3 写入 backlog.md
用户确认后,把推迟的条目追加到 $DOC_BACKLOG 的对应区:
🐛 待修区(独立 bug):追加一行到表格:
| BF-0419-3 | [症状一句话] | 会话 2026-04-19 用户报告 | [相关文件/模块] | auth | P1 | pending | — | docs/bugfix/reviews/BF-0419-3.md |
💡 新需求区:追加一行到表格:
| N-0419-1 | [新需求一句话] | 会话 2026-04-19 用户报告 | 2026-04-19 | 待立项 |
🌀 待澄清区:追加一行到列表:
- [2026-04-19] [模糊反馈原话],未复现 / 待澄清
如果 $DOC_BACKLOG 不存在,AI 从模板 skills/forge-bugfix/templates/backlog.md 初始化。
2.4 Bug 编号
确认范围时为本次修复分配编号:BF-{MMDD}-{N}(N = 当日已用编号 +1)。
- 编号用于:worktree 命名、commit message、Bug 修复验收报告文件名
- 从 backlog 捞的条目,沿用其原编号,不重新分配
2.5 创建 / 更新 Bug 修复验收报告(硬性)
确认本次修复范围后,AI 必须确保 $REVIEW_DOC="$DOC_REVIEWS/${BUG_ID}.md" 存在:
REVIEW_DOC="$DOC_REVIEWS/${BUG_ID}.md"
if [ ! -f "$REVIEW_DOC" ]; then
cp "$HOME/.claude/skills/forge-bugfix/templates/review-checklist.md" "$REVIEW_DOC"
fi
然后写入报告的前置事实:
| 区域 | 填什么 | |---|---| | 当前状态 | pending 或 in-progress | | 问题发现记录 | 来源、原始描述、关联 Feature Spec、初始影响范围 | | 初始证据 | 用户截图、QA 截图、console/network 摘要、日志路径 | | 复现记录 | 当前复现结论和待执行步骤 | | 验收入口 | 如已知 Frontend/Backend 地址,先写入;最终以 P6 forge-qa 强校验结果为准 |
同时把 $DOC_BACKLOG 中该 bug 的“报告”列指向 docs/bugfix/reviews/${BUG_ID}.md。
禁止等到修完代码才创建报告。报告是单个 bug 的过程案卷,不是最后的附录。
P3 创建 worktree + 复现
3.1 创建 worktree
# Bug 编号已在 P2.4 确定,例如 BF-0418-9
BUG_ID="BF-0418-9"
WT_NAME="bf-${BUG_ID#BF-}" # → bf-0418-9
WT_PATH="$_ROOT/.worktrees/$WT_NAME"
WT_BRANCH="bugfix/$WT_NAME"
git worktree add "$WT_PATH" -b "$WT_BRANCH"
echo "✅ worktree 创建: $WT_PATH (分支: $WT_BRANCH)"
3.1.5 登记 .forge/active.md(v6.0 硬性步骤)
worktree 创建成功之后立即登记,不得拖到修复结束再补。
# 字段:session id / worktree 相对路径 / 任务 id / 功能域
DOMAIN=""
REL_WT="${WT_PATH#$_ROOT/}" # 存相对路径,便于跨机器
LINE="- session: $CURRENT_SID / worktree: $REL_WT / 任务: $BUG_ID / 域: $DOMAIN"
# 追加到 active.md 的"进行中会话"节末尾(用 awk 精确插入在 "---" 之前)
python3 -c "
import pathlib,re
p=pathlib.Path('$ACTIVE')
txt=p.read_text()
# 找到'## 进行中会话'节,在它后面的(暂无进行中会话)或第一个 --- 之前插入
pat=re.compile(r'(## 进行中会话\n[\s\S]*?)(\n---)', re.M)
line='''$LINE'''
def repl(m):
body=m.group(1)
# 去掉占位行
body=re.sub(r'\n(暂无进行中会话)', '', body)
if not body.endswith('\n'):
body+='\n'
return body + line + '\n' + m.group(2)
p.write_text(pat.sub(repl, txt, count=1))
"
echo "✅ 已登记到 .forge/active.md: session=$CURRENT_SID 域=$DOMAIN"
硬性要求:
$CURRENT_SID为空时 AI 必须停下问用户,不得用 "unknown" 或占位符登记- 登记失败(awk 未匹配等)必须向用户报错,不得静默跳过
- backlog.md 中对应 bug 的状态同时改
in-progress,"领取会话"字段填 session id 前 12 位即可
3.2 ⚠️ worktree Dev Server 契约
强制步骤。历史踩坑:worktree 内启动的服务和主仓库抢同一端口,curl/前端打到旧代码上,调试 30+ 分钟。
如果本 bug 只需读代码和单元测试即可复现,可以不启动应用;一旦需要浏览器、curl、截图或端到端复现,就必须走项目统一 dev server 入口。
cd "$WT_PATH"
if [ -f package.json ] && npm run 2>/dev/null | grep -q "dev:status"; then
npm run dev:status || true
npm run dev
npm run dev:status | tee /tmp/forge-dev-status.txt
APP_URL=$(awk '/Frontend:/{print $2; exit}' /tmp/forge-dev-status.txt)
elif [ -x scripts/dev-stack.sh ]; then
bash scripts/dev-stack.sh status || true
bash scripts/dev-stack.sh start
bash scripts/dev-stack.sh status | tee /tmp/forge-dev-status.txt
APP_URL=$(awk '/Frontend:/{print $2; exit}' /tmp/forge-dev-status.txt)
else
echo "未发现统一 dev server 入口;必须显式选择非默认端口,并记录 PID/cwd/URL"
echo "旧项目兜底探测:"
for port in 3456 3000 4000 5173 8080 8000; do
PID=$(lsof -ti :"$port" -sTCP:LISTEN 2>/dev/null | head -1)
if [ -n "$PID" ]; then
CWD=$(lsof -p "$PID" 2>/dev/null | awk '$4=="cwd"{print $9}')
echo "端口 $port: PID=$PID cwd=$CWD"
fi
done
fi
硬性要求:
- 有
npm run dev:status或scripts/dev-stack.sh时,不得裸跑uvicorn/vite/next dev。 APP_URL必须从状态输出读取,传给复现、截图和 forge-qa;不得凭常见端口猜。- 状态输出必须显示监听进程 cwd 属于当前 worktree;不一致就先
npm run dev:stop/bash scripts/dev-stack.sh stop后重启。 - 旧项目没有统一入口时,AI 必须把端口、PID、cwd、URL 写进报告,且不得占用主分支固定端口。
3.3 切换到 worktree 工作
cd "$WT_PATH"
# 后续所有操作(复现、修改、com
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [yike-gunshi](https://github.com/yike-gunshi)
- **Source:** [yike-gunshi/forge-skills](https://github.com/yike-gunshi/forge-skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.