mcpField
L
loop-it

loop-it

github.com/smallnestAgent 工作流296379 次安装6 周前更新
代码仓库

关于 loop-it

loop-it 是一个自动处理 GitHub 开放 issue 的技能,适合希望按依赖顺序实现、审查并交付任务的开发流程。它逐项运行实现、/review-it 和 /ship-it,并将进度写入检查点文件以便中断后恢复。

主要功能

  1. 01获取开放 issue 并解析依赖
  2. 02按依赖顺序逐项处理
  3. 03内联实现并运行测试与 lint
  4. 04调用 /review-it 和 /ship-it
  5. 05检查点记录与中断恢复

适用场景

  1. 01按依赖关系批量处理 GitHub issue
  2. 02中断后从状态文件恢复任务
  3. 03在审查和交付步骤间跟踪 issue 进度

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/smallnest/goal-workflow --skill loop-it

安装后在 Claude Code 中输入/loop-it确认已加载。

详细介绍

loop-it — 带检查点恢复的自动化 Issue 实现循环

Fetch all open GitHub issues, resolve dependency order, implement each through the full pipeline (内联实现 → /review-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、/ship-it 仍是真实 skill,经 Skill 工具调用。loop-it 循环中不调用 /note-it。


Overview

前置检查 → 读取状态文件 → Fetch Issues → 构建依赖图 → 拓扑排序
                                                              |
    ┌───────────────────────────────────────────────────────────┘
    |
    v
┌──────────────── 单 Issue 循环 ────────────────┐
|                                               |
|  从检查点恢复?—— 跳过已完成/失败的             |
|                                               |
|  分支准备 (checkout main, pull, create branch) |
|        |                                      |
|  Skip/Blocked? ── 是 → 标记 skipped/blocked, 写检查点 |
|        |                                      |
|        否                                      |
|        |                                      |
|  内联实现 → 出错?→ 分类 → 恢复 → 重试        |
|        |              |                       |
|        |           失败 → 检查点, 下一个         |
|        |                                      |
|  /review-it → 有问题?→ 修复 → 重跑 review     |
|        |                                      |
|  /ship-it → 出错?→ 分类 → 恢复                |
|        |                                      |
|  分支清理 (checkout main, pull, delete branch) |
|        |                                      |
|  检查点 (标记 shipped)                         |
|        |                                      |
└────────┴──────────────────────────────────────┘
         |
         v
    全部完成 → 最终 Summary

前置检查

开始循环前,按顺序验证所有前提条件。任何检查失败则停止并打印错误。

Check 1: gh CLI 认证
gh auth status

失败 → 打印 ❌ gh CLI 未认证。运行: gh auth login,退出。

Check 2: Git 仓库
git rev-parse --is-inside-work-tree

失败 → 打印 ❌ 不在 git 仓库中,退出。

Check 3: Git 工作树清洁度
git status --porcelain

有输出(dirty)→ 打印 ⚠️ 工作树有未提交的更改,提供选项:

  • A. git stash 暂存后继续
  • B. 中止,让用户自行处理
  • C. 强制继续(不推荐)

默认 B。

Check 4: 在默认分支上
git branch --show-current

不在 main/master → 打印 ⚠️ 当前在 {branch} 分支,提供选项:

  • A. git checkout main && git pull 切换
  • B. 继续在当前分支
Check 5: 远程可达
git ls-remote --heads origin

失败 → 打印 ❌ 无法访问远程仓库。检查网络和权限,退出。

Check 6: 状态文件存在?
cat .loop-state.json

存在 → 打印进度摘要,提供选项:

  • A. 从检查点恢复
  • B. 从头开始(删除状态文件)
  • C. 中止

状态文件

位置

.loop-state.json,放在 repo 根目录。必须添加到 .gitignore。如果文件被 git 跟踪,打印警告并建议用户添加到 .gitignore。

格式
{
  "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:

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
  1. For each failed issue: ask user — retry or skip?
  2. For in_progress issues: check if branch exists, changes exist → decide resume from current state or restart
  3. Skip all shipped/skipped issues
  4. 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:

# 确认在 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. 跳过或实现

阅读 issue 标题和正文。判断是否需要通过代码实现:

如果 issue 属于以下情况,则跳过:

  • 问题/讨论/澄清
  • 仅涉及文档(拼写错误、措辞)
  • 已经实现(检查代码库)
  • 与其他 issue 重复
  • 明确标记为 wontfix、question、discussion 或 invalid
  • 不可执行(没有明确的验收条件,且无法推断)

如果 issue 存在尚未解决的依赖,则跳过(阻塞):

  • 检查第 1 步中的依赖关系图
  • 如果任何依赖 issue 尚未 shipped(仍为 pending、failed、blocked,或不在状态文件中)→ 作为阻塞项跳过
  • 依赖 issue 本身可能已失败或被跳过——无论哪种情况,此 issue 都无法安全推进

跳过时:

⏭️  Skipping Issue #{number}: {title}
   Reason: {why}

阻塞时:

🔒 Blocking Issue #{number}: {title}
   Reason: dependency #{dep_number} not shipped ({status})

更新状态:pending → skipped 或 pending → blocked,写入检查点,运行 3g 分支清理,继续处理下一个 issue。

3c. 实现(内联自主实现)

更新状态:pending → in_progress,phase: "implement",写入检查点。

由 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 而中止——实现就是你自己内联完成的工作。

成功时:

✅ Issue #{number} implementation complete

写入检查点,设置 phase: "implement_done"。

失败时——对错误分类(参见错误分类与恢复),应用恢复策略,最多重试。若用尽所有重试次数:

⚠️  Issue #{number} failed: {error_class} after {N} attempts
   Manual intervention required.

更新状态:in_progress → failed,写入检查点,运行 3g 分支清理,继续处理下一个 issue。

3d. 使用 /review-it 审查

写入检查点,设置 phase: "review"。

/review-it

如果审查发现可处理的问题:

🔍 Review found N issue(s) for #{number}. Fixing...

修复每一项已接受的发现,重新运行 /review-it。重复此过程,直到审查通过或达到最多 2 轮审查。

如果审查通过:

✅ Review clean for Issue #{number}

写入检查点,设置 phase: "review_done"。

3e. 使用 /ship-it 发布
/ship-it

此操作会提交、推送、创建 PR、合并并关闭 issue。

成功时:

🚀 Issue #{number} shipped successfully!

失败时——对错误分类(参见错误分类与恢复),应用恢复策略。若无法解决:

⚠️  Issue #{number} ship failed: {error}. Manual merge required.

更新状态:in_progress → failed,设置 phase: "ship",写入检查点,运行 3g 分支清理,继续处理下一个 issue。

3f. 检查点

成功发布后,更新状态:in_progress → shipped,设置 completed_at,写入检查点。

打印进度(参见进度可观测性)。

3g. 分支清理

每个 issue 处理完成后(已发布、已跳过或失败):

# 切回 main
git checkout main
git pull

# 删除本地功能分支(仅当 shipped 时)
git branch -d feat/issue-{N}-{short-desc}

对于失败的 issue:不要删除分支。保留分支以供调查。

下一个 Issue

按拓扑顺序返回第 3 步处理下一个 issue。

处理完所有 issue 后,打印最终摘要:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 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_failurelint 错误、格式问题自动修复 (lint --fix),重新运行2
merge_conflictCONFLICT 标记rebase origin/main,解决冲突,push2
ci_failuregh pr checks 失败读取 CI 日志,本地修复,push2
auth_failure403、401、认证错误停止,告知用户重新认证0
rate_limitrate limit、secondary abuse等待 60s,重试3
issue_unclearissue 无验收条件且无法推断需求跳过,标记 failed0
network_errortimeout、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
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

日志规则

每个关键步骤都必须打印一行带有表情符号前缀的日志:

表情符号含义
📋获取 / 列出
🔄正在处理 issue
⏭️跳过
🔒受阻(未提供依赖项)
✅成功
❌失败
🔍审查
🚀发布
⚠️警告 / 重试
📊进度 / 摘要

安全防护措施

  • 绝不强制推送到 main/master — 始终使用功能分支
  • 绝不跳过审查 — 在 /ship-it 之前始终运行 /review-it
  • 每种错误类别的最大重试次数 — 参见错误分类与恢复表,不要无限重试
  • 最多 2 轮审查 — 不要过度打磨
  • CI 失败时暂停 — 记录日志并继续,不要自动绕过分支保护
  • 保留 issue 标签 — 仅关闭已实际发布的 issue
  • 绝不自动删除失败的分支 — 保留以供调查
  • 每次状态转换都创建检查点 — 每次状态变更都写入检查点,不仅仅是在发布时
  • 状态文件完整性 — 文件损坏时警告用户,绝不自动覆盖
  • 将状态文件加入 .gitignore — 提醒用户添加 .loop-state.json
  • 严格按顺序处理 — 一次只处理一个 issue(实现会修改工作树,不能并行)
  • 跳过受依赖阻塞的 issue — 依赖的 issue 尚未发布时,将其标记为 blocked
  • 由 Agent 内联完成实现 — 本环境没有可调用的 goal 命令 / skill;「实现 issue」必须由 Agent 自行读取 issue、编写代码并运行测试。遇到 goal is a UI command, not a skill 时不要中止,直接内联实现

边缘情况

情况处理方式
没有未关闭的 issue打印 "nothing to do" 并退出
所有 issue 都是问题全部跳过,并报告摘要
gh 未通过身份验证打印错误,建议运行 gh auth login,然后退出
Issue 没有正文仅根据标题决定跳过还是实现
Issue 引用了 PRD/SPEC读取被引用的 PRD/SPEC 作为上下文,由 Agent 内联实现
多个 issue 相互依赖进行拓扑排序;先处理依赖已发布的 issue
开始前 Git 仓库处于脏状态前置检查 Check 3:暂存 / 中止 / 强制处理
状态文件损坏(无效 JSON)警告用户,并提供从头开始或中止的选项。绝不自动覆盖
状态文件来自其他仓库检测 repo 字段不匹配,发出警告,并提供从头开始的选项
上次运行留下状态为 in_progress 的 issue检查分支是否存在、是否有变更 → 恢复或重新开始
用户在循环中止状态文件已包含最新检查点,下次运行时可恢复
循环期间创建了新 issue不重新获取。完成当前批次后运行新的 /loop-it
循环依赖打印警告,并按编号顺序打破循环
.loop-state.json 已被 Git 跟踪警告用户将其添加到 .gitignore,然后继续
误以为需要外部 goal 命令本环境没有此命令;「实现 issue」由 Agent 内联完成(读取 issue → 编写代码 → 测试),不要中止循环

与其他技能的关系

/loop-it
  ├── 内联实现   ← implement each issue(agent 自主读 issue、写代码、测试;非外部命令)
  ├── /review-it  ← review code before shipping(skill)
  └── /ship-it    ← commit, PR, merge, close(skill)

属于 goal-workflow 流水线的一部分:

/prd → /prd-to-spec → /to-issues → /loop-it (→ 内联实现 → /review-it → /ship-it)×N

评论

支持 Markdown