Files
2026-08-14 23:41:57 +08:00

563 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: loop-it
description: "Automated issue loop with checkpoint/resume: fetch open GitHub issues → dependency-aware topological sort → implement each issue end-to-end → review with /review-it → document with /note-it → ship with /ship-it → repeat. Persists state to .loop-state.json for crash recovery. Triggers on: loop-it, loop issues, auto implement, 批量实现, 循环实现, 实现所有issue, 恢复循环, resume loop."
user-invocable: true
allowed-tools:
- Bash(gh:*)
- Bash(git:*)
- Bash(cat:*)
---
# loop-it — 带检查点恢复的自动化 Issue 实现循环
Fetch all open GitHub issues, resolve dependency order, implement each through the full pipeline (内联实现 → `/review-it``/note-it``/ship-it`), persist progress to state file, and resume from checkpoint on crash.
> **⚠️ 关键前提:实现步骤由 agent 内联自主完成,不依赖任何外部 `/goal` 命令。**
> 本环境中不存在可调用的 `goal` 命令或 skill。因此「实现 issue」这一步**必须由 agent 内联完成**:直接读取该 issue 的标题与正文(含其引用的 PRD/SPEC 与验收条件),自主完成"理解需求 → 写/改代码 → 跑测试与 lint → 满足全部验收条件"的闭环,持续工作直到该 issue 的验收条件全部满足且测试/构建通过。**不要**尝试用 Skill 工具调用 `goal`(会报 `goal is a UI command, not a skill`),也**不要**因为找不到 `/goal` 而中止循环。`/review-it`、`/note-it`、`/ship-it` 仍是真实 skill,经 Skill 工具调用。
---
## Overview
```
前置检查 → 读取状态文件 → Fetch Issues → 构建依赖图 → 拓扑排序
|
┌───────────────────────────────────────────────────────────┘
|
v
┌──────────────── 单 Issue 循环 ────────────────┐
| |
| 从检查点恢复?—— 跳过已完成/失败的 |
| |
| 分支准备 (checkout main, pull, create branch) |
| | |
| Skip/Blocked? ── 是 → 标记 skipped/blocked, 写检查点 |
| | |
| 否 |
| | |
| 内联实现 → 出错?→ 分类 → 恢复 → 重试 |
| | | |
| | 失败 → 检查点, 下一个 |
| | |
| /review-it → 有问题?→ 修复 → 重跑 review |
| | |
| /note-it (捕获实现笔记, best-effort) |
| | |
| /ship-it → 出错?→ 分类 → 恢复 |
| | |
| 分支清理 (checkout main, pull, delete branch) |
| | |
| 检查点 (标记 shipped) |
| | |
└────────┴──────────────────────────────────────┘
|
v
全部完成 → 最终 Summary
```
---
## 前置检查
开始循环前,按顺序验证所有前提条件。任何检查失败则停止并打印错误。
### Check 1: gh CLI 认证
```bash
gh auth status
```
失败 → 打印 `❌ gh CLI 未认证。运行: gh auth login`,退出。
### Check 2: Git 仓库
```bash
git rev-parse --is-inside-work-tree
```
失败 → 打印 `❌ 不在 git 仓库中`,退出。
### Check 3: Git 工作树清洁度
```bash
git status --porcelain
```
有输出(dirty)→ 打印 `⚠️ 工作树有未提交的更改`,提供选项:
- A. `git stash` 暂存后继续
- B. 中止,让用户自行处理
- C. 强制继续(不推荐)
默认 B。
### Check 4: 在默认分支上
```bash
git branch --show-current
```
不在 main/master → 打印 `⚠️ 当前在 {branch} 分支`,提供选项:
- A. `git checkout main && git pull` 切换
- B. 继续在当前分支
### Check 5: 远程可达
```bash
git ls-remote --heads origin
```
失败 → 打印 `❌ 无法访问远程仓库。检查网络和权限`,退出。
### Check 6: 状态文件存在?
```bash
cat .loop-state.json
```
存在 → 打印进度摘要,提供选项:
- A. 从检查点恢复
- B. 从头开始(删除状态文件)
- C. 中止
---
## 状态文件
### 位置
`.loop-state.json`,放在 repo 根目录。**必须添加到 `.gitignore`**。如果文件被 git 跟踪,打印警告并建议用户添加到 `.gitignore`
### 格式
```json
{
"version": 1,
"started_at": "2025-06-09T10:00:00Z",
"updated_at": "2025-06-09T10:30:00Z",
"repo": "owner/repo-name",
"total_issues": 8,
"issues": {
"3": {
"status": "shipped",
"branch": "feat/issue-3-add-priority",
"started_at": "2025-06-09T10:00:00Z",
"completed_at": "2025-06-09T10:15:00Z",
"attempts": 1
},
"4": {
"status": "failed",
"phase": "goal",
"error_class": "build_failure",
"branch": "feat/issue-4-filter-tasks",
"started_at": "2025-06-09T10:15:00Z",
"updated_at": "2025-06-09T10:30:00Z",
"attempts": 3,
"last_error": "test TestFilterPriority failed: expected 3, got 0"
},
"7": {
"status": "pending"
}
}
}
```
### 状态值
`pending` | `in_progress` | `skipped` | `shipped` | `failed` | `blocked`
### 写入规则
- 每次状态转换后立即写入(`pending``in_progress``in_progress``shipped`/`failed`/`skipped` 等)
- 写入使用 `cat > .loop-state.json << 'LOOPSTATE'\n{json}\nLOOPSTATE`
- 如果状态文件已存在但内容损坏(非法 JSON),打印警告,提供从头开始或中止的选项。**绝不自动覆盖损坏文件**
- 循环完成后保留状态文件(作为记录),用户可手动删除
---
## Step 1: Fetch Issues & Build Dependency Graph
Fetch all open issues:
```bash
gh issue list --state open --json number,title,labels,body --limit 100
```
### Parse Dependencies
Read each issue body, look for patterns:
- `Dependencies: #3, #5` or `Depends on: #3`
- `depends on #3` or `requires #3` (in body text)
Build a dependency graph. Sort using topological order:
1. Issues with no dependencies first (sorted by number ascending)
2. Issues whose dependencies are all shipped/closed next
3. Blocked issues (depend on other open issues) last
4. Circular dependencies → print warning `⚠️ 循环依赖检测到: #A ↔ #B,按编号顺序处理`break cycle by number order
If no dependency patterns found in any issue body, fall back to number-ascending sort.
Print ordered list:
```
📋 Found N open issues (topological sort):
#1: Add priority field (无依赖)
#3: Display indicator (依赖 #1)
#5: Add selector (依赖 #1)
#7: Filter view (依赖 #1, #3)
```
If no open issues → print `✅ No open issues found. Nothing to do.` and exit.
---
## Step 2: Resume or Initialize
### If `.loop-state.json` exists (from 前置检查 Check 6)
1. Read the file
2. Print progress summary:
```
📊 从检查点恢复 (上次更新: {updated_at})
✅ Shipped: #1, #3
⏭️ Skipped: #2 (question)
❌ Failed: #4 (build_failure — 3 attempts)
📋 Remaining: #5, #7
```
3. For each `failed` issue: ask user — retry or skip?
4. For `in_progress` issues: check if branch exists, changes exist → decide resume from current state or restart
5. Skip all `shipped`/`skipped` issues
6. Continue from first pending/retryable issue
### If no state file
1. Initialize new state file with all fetched issues as `pending`
2. Start from first issue in topological order
---
## Step 3: Process Single Issue
For each issue, print a banner:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔄 Processing Issue #{number}: {title}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
### 3a. Branch Prep
Prepare a clean git environment for this issue:
```bash
# 确认在 main 上
git checkout main
git pull
# 创建功能分支
git checkout -b feat/issue-{N}-{short-desc}
```
Branch naming: `feat/issue-N-short-desc` or `fix/issue-N-short-desc`(与 /ship-it 保持一致)
### 3b. Skip or Implement
Read the issue title and body. Decide if it needs code implementation:
**Skip if the issue is:**
- A question / discussion / clarification
- Documentation-only (typos, wording)
- Already implemented (check codebase)
- A duplicate of another issue
- Clearly labeled `wontfix`, `question`, `discussion`, or `invalid`
- Not actionable (no clear acceptance criteria and cannot infer any)
**Skip (blocked) if the issue has unresolved dependencies:**
- Check the dependency graph from Step 1
- If any dependency issue is not `shipped` (still `pending`, `failed`, `blocked`, or not in state file) → skip as blocked
- The dependency issue itself may have failed or been skipped — in either case, this issue cannot proceed safely
When skipping:
```
⏭️ Skipping Issue #{number}: {title}
Reason: {why}
```
When blocked:
```
🔒 Blocking Issue #{number}: {title}
Reason: dependency #{dep_number} not shipped ({status})
```
Update state: `pending``skipped` or `pending``blocked`, write checkpoint, run **3h Branch Cleanup**, proceed to next issue.
### 3c. Implement (内联自主实现)
Update state: `pending``in_progress`, `phase: "implement"`, write checkpoint.
**由 agent 内联完成实现**(本环境无 `goal` 命令/skill 可调用,必须自己干):
1. 读取该 issue 的标题与正文,提取需求与全部验收条件(Acceptance Criteria);若正文引用了 PRD/SPEC 文件(如 `tasks/prd-*.md`),一并读取作为上下文
2. 阅读相关现有代码,遵循项目既有风格、命名与依赖约定
3. 实现/修改代码以满足全部验收条件
4. 跑项目的构建、测试与 lint(如 `go build ./...``go vet ./...``go test ./...`
5. 持续工作直到该 issue 的验收条件**全部满足**且测试/构建/lint 通过
> 不要尝试用 Skill 工具调用 `goal`(会报 `goal is a UI command, not a skill`),也不要因找不到 `/goal` 而中止——实现就是你自己内联完成的工作。
**On success:**
```
✅ Issue #{number} implementation complete
```
Write checkpoint with `phase: "implement_done"`.
**On failure** — classify error (see 错误分类与恢复), apply recovery strategy, retry up to max attempts. If all retries exhausted:
```
⚠️ Issue #{number} failed: {error_class} after {N} attempts
Manual intervention required.
```
Update state: `in_progress``failed`, write checkpoint, run **3h Branch Cleanup**, proceed to next issue.
### 3d. Review with /review-it
Write checkpoint with `phase: "review"`.
```
/review-it
```
**If review finds actionable issues:**
```
🔍 Review found N issue(s) for #{number}. Fixing...
```
Fix each accepted finding, re-run `/review-it`. Repeat until clean or max 2 review rounds.
**If review is clean:**
```
✅ Review clean for Issue #{number}
```
Write checkpoint with `phase: "review_done"`.
### 3e. Document with /note-it
After review, before ship — capture implementation notes:
```
/note-it
```
This creates `docs/issue#XXXX.html` with design decisions, deviations, tradeoffs, and open questions.
**On success:**
```
📝 Issue #{number} notes captured
```
**On failure** (can't determine issue number, etc.) — print warning but **do not block shipping**:
```
⚠️ /note-it failed for Issue #{number}: {reason}. Continuing to ship.
```
Write checkpoint with `phase: "note_done"`.
### 3f. Ship with /ship-it
```
/ship-it
```
This commits, pushes, creates PR, merges, and closes the issue.
**On success:**
```
🚀 Issue #{number} shipped successfully!
```
**On failure** — classify error (see 错误分类与恢复), apply recovery. If unresolvable:
```
⚠️ Issue #{number} ship failed: {error}. Manual merge required.
```
Update state: `in_progress``failed`, `phase: "ship"`, write checkpoint, run **3h Branch Cleanup**, proceed to next issue.
### 3g. Checkpoint
After successful ship, update state: `in_progress``shipped`, set `completed_at`, write checkpoint.
Print progress (see 进度可观测性).
### 3h. Branch Cleanup
After each issue (shipped, skipped, or failed):
```bash
# 切回 main
git checkout main
git pull
# 删除本地功能分支(仅当 shipped 时)
git branch -d feat/issue-{N}-{short-desc}
```
**For failed issues**: do NOT delete the branch. Keep it for investigation.
### Next Issue
Return to Step 3 for the next issue in topological order.
When all issues processed, print final summary:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Loop Complete — Summary
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Shipped: N issues (#1, #3, ...)
⏭️ Skipped: N issues (#2 — reason, #5 — reason, ...)
🔒 Blocked: N issues (#7 — depends on #4, ...)
❌ Failed: N issues (#4 — error, ...)
📋 Total: N issues
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
---
## 错误分类与恢复
当错误发生时,先分类,再按策略恢复。
| 错误类别 | 检测信号 | 恢复策略 | 最大重试 |
|----------|---------|---------|---------|
| build_failure | 编译错误、undefined、类型错误 | 读错误,修代码,重新构建 | 3 |
| test_failure | 断言失败、test failed | 读测试输出,修实现,重跑测试 | 3 |
| lint_failure | lint 错误、格式问题 | 自动修复 (lint --fix),重跑 | 2 |
| merge_conflict | CONFLICT 标记 | rebase origin/main,解决冲突,push | 2 |
| ci_failure | gh pr checks 失败 | 读 CI 日志,本地修复,push | 2 |
| auth_failure | 403、401、认证错误 | 停止,告知用户重新认证 | 0 |
| rate_limit | rate limit、secondary abuse | 等待 60s,重试 | 3 |
| issue_unclear | issue 无验收条件且无法推断需求 | 跳过,标记 failed | 0 |
| network_error | timeout、connection refused | 等待 30s,重试 | 3 |
| unknown | 其他情况 | 记录完整错误,跳过 | 0 |
**恢复协议:**
1. 匹配错误类别
2. 匹配成功 → 应用恢复策略,重试最多 N 次
3. 重试全部失败 → 标记 `failed`,写检查点,继续下一个 issue
4. 无法匹配 → 标记 `failed`error_class: `unknown`),继续
5. **绝不无限重试。绝不未经确认 force-push。**
---
## 进度可观测性
每完成一个 issue 后,打印结构化进度:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 Progress: 3/8 issues (37%)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Shipped: #1, #3
⏭️ Skipped: #2 (question), #6 (duplicate)
🔒 Blocked: #7 (depends on #4 — failed)
❌ Failed: #4 (build_failure — 3 attempts)
📋 Remaining: #5, #8
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
---
## Logging Rules
Every key step MUST print a log line with emoji prefix:
| Emoji | Meaning |
|-------|---------|
| 📋 | Fetch / list |
| 🔄 | Processing issue |
| ⏭️ | Skip |
| 🔒 | Blocked (dependency not shipped) |
| ✅ | Success |
| ❌ | Failure |
| 🔍 | Review |
| 📝 | Notes (/note-it) |
| 🚀 | Ship |
| ⚠️ | Warning / retry |
| 📊 | Progress / summary |
---
## Safety Guards
- **Never force-push to main/master** — always use feature branches
- **Never skip review** — always run `/review-it` before `/ship-it`
- **Never skip notes** — always run `/note-it` before `/ship-it`best-effort,不阻塞)
- **Max retries per error class** — 参见错误分类与恢复表,不无限重试
- **Max 2 review rounds** — don't over-polish
- **Pause on CI failure** — log and continue, don't auto-override branch protection
- **Preserve issue labels** — only close issues that were actually shipped
- **Never auto-delete failed branches** — 保留供调查
- **Checkpoint at every transition** — 每次状态变更写检查点,不仅仅在 ship 时
- **State file integrity** — 损坏时警告用户,绝不自动覆盖
- **State file in .gitignore** — 提醒用户添加 `.loop-state.json`
- **Strictly sequential** — 一次只处理一个 issue(实现会修改工作树,不能并行)
- **Skip dependency-blocked issues** — 依赖的 issue 未 shipped 时标记 `blocked`
- **实现由 agent 内联完成** — 本环境无 `goal` 命令/skill 可调用;「实现 issue」必须由 agent 自己读 issue、写代码、跑测试完成。报 `goal is a UI command, not a skill` 时不要中止,直接内联实现
---
## Edge Cases
| Scenario | Handling |
|----------|----------|
| No open issues | Print "nothing to do" and exit |
| All issues are questions | Skip all, report summary |
| `gh` not authenticated | Print error, suggest `gh auth login`, exit |
| Issue has no body | Use title only to decide skip/implement |
| Issue references PRD/SPEC | 读取被引用的 PRD/SPEC 作为上下文,agent 内联实现 |
| Multiple issues depend on each other | Topological sort; dependencies already shipped first |
| Git repo is dirty before starting | 前置检查 Check 3: stash/abort/force |
| State file corrupted (invalid JSON) | 警告用户,提供从头开始或中止选项。绝不自动覆盖 |
| State file from different repo | 检测 repo 字段不匹配,警告,提供从头开始选项 |
| Issue `in_progress` from previous run | 检查分支是否存在、是否有变更 → 恢复或重新开始 |
| User aborts mid-loop | 状态文件已包含最新检查点,下次运行可恢复 |
| New issues created during loop | 不重新获取。完成当前批次后运行新 `/loop-it` |
| Circular dependencies | 打印警告,按编号顺序打破循环 |
| `/note-it` can't find issue number | 打印警告,跳过 /note-it,继续 /ship-it |
| `.loop-state.json` is git-tracked | 警告用户添加到 .gitignore,继续 |
| 误以为需要外部 `goal` 命令 | 本环境无此命令;「实现 issue」由 agent 内联完成(读 issue → 写代码 → 测试),不要中止循环 |
---
## Relationship to Other Skills
```
/loop-it
├── 内联实现 ← implement each issueagent 自主读 issue、写代码、测试;非外部命令)
├── /review-it ← review code before shippingskill
├── /note-it ← capture implementation notes (best-effort)skill
└── /ship-it ← commit, PR, merge, closeskill
```
Part of the goal-workflow pipeline:
```
/prd → /prd-to-spec → /to-issues → /loop-it (→ 内联实现 → /review-it → /note-it → /ship-it)×N
```