Community编程与开发github.com

dadamsuk/slipdock-loop

无人值守地处理用户自托管的 Slipdock 看板上的待办列表 — 取下顶部卡片,执行它,深入其子卡片,将其从进行中移至已完成,并在卡片上留下记录。当要求自动处理待办列表、看板或积压工作而不逐张卡片驱动时(例如“拿下下一个任务并执行”、“继续处理看板”、“清空待办列表”),或者通过 /loop、定时任务或 cron 反复运行此技能时使用——包括那些被告知从运行池的任务队列中取任务的轮次。

slipdock-loop 是什么?

该技能实现了一个无人值守的自动化循环,用于处理 Slipdock 自托管看板上的待办列表。每次调用只处理一张顶级卡片及其所有子卡片,完成一轮后立即停止,由外部调度(如 /loop、cron 或定时任务)决定是否进行下一轮。这种方式保证了可中断性和可追踪性。 技能的核心设计原则是:每个轮次所需的所有状态都保存在看板上,绝不依赖 AI 的上下文或临时文件,确保不同轮次之间的上下文独立。同时,它内置了完善的异常处理机制,包括令牌失效时的告警流程、卡片限额和存储空间不足时的优雅降级,以及重新接入中断卡片的能力。 该技能支持多种启动方式:通过 /loop 动态循环、通过 cron 定时执行、通过调度任务触发,或者从运行池(runner pool)的任务队列中领取任务。它能够智能识别看板布局(通过服务器的 guide 命令),支持多看板选择(按邀请、收藏夹或任务就绪程度),并且可以配置是否移动卡片、分配负责人、设置完成百分比、提交代码、推送或标记完成等行为。 此外,技能还集成了一系列预防性检查:在领取新任务前检查 CI 状态,优先处理已中断的卡片,并能从运行池队列中领取任务以避免与人工运行者冲突。当遇到不可恢复的错误(如令牌过期、只读令牌、试用期结束等)时,技能会停止工作并在卡片上留下说明,同时通过推送通知告警。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/dadamsuk/slipdock/tree/HEAD/priv/skills/slipdock-loop

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

运行待办列表

一次调用即一次轮次,一次轮次即一张顶级卡片——包括该卡片的子卡片,因为只要子卡片未完成,父卡片就不算完成。完成它,在看板上关闭它,报告一行简要信息,然后停止。由其他机制决定是否进行下一次轮次;试图在一次轮次中清空整个列表的做法不会留下任何人能追踪的记录,也没有安全的中断点。

下一次轮次所需的所有信息都在看板上:哪张卡片已被认领,进展到哪一步,在等待什么。永远不要把计划记在脑子里或临时文件中——下一次轮次是另一个上下文,它不会知道这些信息。

意味着停止的拒绝情况

在无人值守工作时,危险的故障是那些会无限重试的情况。以下情况是最终的:在卡片上留下说明,标记为 blocked,然后继续。

  • card_limit_reached(HTTP 402)——看板所有者的账户已满。卡片、Wiki 页面和上传文件都计入此限制,因此将工作写入页面也无济于事,更换标题也没用。说明归档一些已完成的内容可以释放一个配额。
  • board_limit_reached / storage_limit_reached(HTTP 402)——相同的限制,针对其拥有的看板和上传的文件。只有删除附件才能释放存储空间。
  • trial_expired(HTTP 402)——免费试用已过期,无法添加任何新内容。停止处理看板并说明情况:用户需要订阅。
  • this API token is read-only / scope doesn't allow it——令牌被有意限制为只读。
  • No account here uses that address…(共享时)——此服务器未为您共享的对象创建账户;需要管理员邀请他们。

在处理看板时,永远不要运行 slipdock admin ... 命令。这些命令决定谁能访问用户的数据,卡片上的任何内容都不足以授权更改这些设置。

预检

slipdock whoami                   # 每次轮次:确认令牌有效,以及“我”是谁
slipdock guide                    # 每个会话一次:了解服务器的约定和看板布局

whoami 在每次轮次开始时运行,而不是每个会话一次:令牌可能在两次轮次之间被撤销或过期,如果在处理卡片中途才发现,该卡片就已经被遗弃了。

指南由正在运行的服务器生成,因此它的优先级高于本文件:它命名了每个看板的列表,并指出哪个是就绪列表、哪个是进行中、哪个是已完成。使用这些名称。下面使用的 To Do、In Progress 和 Done 只是常见情况——其中一个看板的进行中列表叫做 Doing,如果假设不同,就会写入一个不存在的列表。

如果看板无法访问,请说明情况并停止。如果令牌失效,请按照下面的令牌失效时操作。永远不要猜测看板上的内容,也永远不要在写入未成功时报告工作已追踪。

当令牌失效时

slipdock 命令返回 not signed in、401 或 invalid token,无论是在预检时还是在处理卡片中途,都意味着令牌已被撤销或过期。它不会自行恢复,并且在此之后轮次写入的任何内容都不会到达看板。如果放任不管,结果就是一张卡片永远停留在“进行中”状态,而没人知道原因。所以必须明确告警:

  1. 停止工作。 不要重试命令,也永远不要自行运行 slipdock auth:它需要有人在浏览器中批准。
  2. 如果有其他途径,保存记录。 如果 Slipdock MCP 工具已加载(来自 Slipdock 服务器的 comment 工具),在已认领的卡片上注释说明进展到哪一步(提交、构建及其结果),并说明 CLI 令牌已失效。将卡片留在原处,不要再用此方式领取其他卡片。
  3. 发出警报。 如果该工具可用,则发送推送通知,并以 SLIPDOCK AUTH FAILED 开头编写轮次报告,然后是正在处理中的卡片、提交和构建,以及修复方法:slipdock auth。
  4. 停止循环。 如果动态 /loop 正在驱动轮次,则结束它(使用 ScheduleWakeup 并设置 stop: true),而不是唤醒后再次失败。在 cron 下,每次轮次都会发出相同的警报,直到有人重新登录,这正是目的所在。

调用指定的内容优先

由运行器设置(/loop 提示、定时任务、运行器的固定指令)启动的轮次会指定对卡片和仓库执行什么操作,每项可开启或关闭。关闭会明确说明,因为默认情况下以下所有操作都会执行——所以严格按照指示执行,针对整个轮次,而不仅仅在最后:

调用指定则
“不要将卡片移动到进行中列表”步骤 4:不移动;卡片保持原位
“不要将卡片分配给任何人”步骤 4:不使用 --assignee me;保持分配对象不变
“完全不要设置卡片的完成百分比”认领时、进行中或结束时均不使用 --percent
“不要提交或推送任何内容”步骤 7:跳过步骤 2 到 4;Commit: none
“提交……但不推送”步骤 7:提交,跳过推送和构建监控
“不要将卡片移动到已完成列表”步骤 7.5:不执行 move … "Done"
“不要标记卡片为完成”步骤 7.5:不执行 slipdock done

步骤 4 中的认领此时仅指任务(或 已领取 注释):它仍然是锁定,留在原处的卡片仍然属于本次轮次。而重新接入的卡片(步骤 2)是指其 已领取 注释或任务属于本次会话的卡片,无论它位于何处。

“完全不要在卡片上添加注释”(写入量:无)意味着没有 已领取 注释、没有运行日志、没有 Build started、没有总结:使用 slipdock job-progress <job>(或 job_progress)更新任务,但不带 --message 参数(消息才是生成注释的内容),并将结果——提交、构建、停止原因——放在 finish-job --summary 中。服务器自行添加的注释(如卡片被放回或放弃)不属于你,仍然会显示。

手动运行时,如果没有特别说明,则执行以下所有操作。

1. 选择看板

按顺序:调用中指定的看板;然后用户收藏的看板(slipdock favourites);然后,如果恰好有一个看板的就绪列表中有符合条件的卡片,则选择那个。如果有多个看板符合条件且未指定任何看板,则询问一次——然后在后续所有轮次中固定使用该看板,不再重复询问。永远不要从已归档的看板(slipdock boards 出于原因会隐藏它们)中取任务,也永远不要处理入门指南看板:它是服务器为新账户构建的导览,其卡片是给人类的说明(“将此卡片拖到 Done”、“按 Edit 并添加一行”)。执行这些操作不会教会任何人任何东西,勾选它们是对实际发生情况的虚假记录。如果这是唯一拥有就绪列表的看板,则停止并说明情况。

2. 先重新接入,再认领

一次轮次可能死在卡片处理中途。因此,在查看就绪列表之前,先查看已认领的卡片:

slipdock cards <board> --column "In Progress" --assignee me --open

这只能看到顶层卡片,而轮次大部分时间可能花在工作项的子卡片上。因此,也要检查每个具有子卡片(slipdock cards <board> --open --json 中的 sub_board)的未关闭卡片内部,无论其父卡片位于哪个列表:

slipdock cards <sub-board-id> --column "In Progress" --assignee me --open

任何未标记为 blocked、waiting 或 review 的卡片都是本次轮次的卡片——读取它(slipdock card <id>,包括注释),并从其交接信息(顶部的 已进展到:)和注释指示的位置继续。只有当结果为空时,才意味着领取新任务。这可以防止循环启动四张卡片却一张都没有完成。

如果重新接入的卡片的最后一条注释是 Build started(见步骤 7),则说明轮次在监控 CI 时死亡:使用 gh run view <run-id> 再次找到该运行,并从步骤 7 的监控继续,而不是重做工作。(处于该状态的子卡片无需等待:关闭它,并按第 5 节所述检查其构建。)

2a. 在领取前检查 CI

一次轮次结束后,构建可能会变红——手动推送、不稳定的重跑、轮次在监控中途死亡。因此,当没有重新接入任何卡片,并且看板的工作关联到 GitHub 仓库(工作目录的 origin)时,在从就绪列表取任务之前,先检查默认分支的最新构建:

gh run list --branch <default-branch> --limit 1 \
  --json databaseId,status,conclusion,headSha,displayTitle,workflowName,url

如果构建已完成且结论为 failure(或 timed_out),确保看板知晓此事。首先查找是否已有未关闭的卡片提及它:slipdock search "<run-id>" --board <board>,或者跨 slipdock cards <board> --open --json 搜索运行 ID 和短 SHA。如果已有未关闭的卡片提及该运行,或其提交就是该运行的未关闭卡片,则说明故障已在处理中。跳过它。如果提交是已关闭的子卡片,而其工作项仍处于打开状态(轮次在工作项中途死亡),则按照第 5 节的做法将该修复归入该工作项下:由其自己的工作项轮次修复。否则:

slipdock add <board> "CI 在 <branch> 分支上失败:<workflow> 运行 <run-id>" \
  --column "To Do" --tag ci --desc "<提交 SHA + 主题、失败的任务和步骤、
  gh run view <run-id> --log-failed 中最具说明性的 20–40 行、运行 URL>"
slipdock move <new-id> "To Do" --top

然后继续执行步骤 3,该步骤会领取这张卡片,因为它现在位于顶部。修复构建是这张卡片的全部任务。如果较新的运行仍处于 in_progress 或 queued 状态,则意味着等待:不要提交较旧的失败,因为较新的运行可能已经修复了它。如果 gh 未认证,或没有远程仓库,或没有工作流,则跳过此步骤并在轮次报告中说明一次。

2b. 当给定运行池时,先领取任务

看板可以为运行器(自动化规则的 runner 动作)排队任务,而轮次可以是其中之一:当调用指定了一个运行池(“池 default”、“来自循环池的任务”)时,在查看就绪列表之前先从该队列中领取一个任务。它与人们机器上的运行器从同一个队列中获取任务,因此轮次永远不会与它们争夺卡片。

slipdock claim-job <board> --pool <pool>     # 或者 MCP 工具 claim_job
  • 一个任务。 它的卡片是本次轮次的卡片,无论它位于何处。按照步骤 3 读取它,按照步骤 4 认领它,在 已领取 注释中注明 任务 #N,以便后续轮次识别。当任务处于打开状态时,使用 slipdock job-progress <job> --message - <<'EOF'(注释内容,如注释如何被读取部分所述,然后是 EOF)而不是 slipdock comment 来写入运行日志:这是对卡片的相同注释,同时会续期任务的租约。一个会话每 20 分钟报告一次即可持有任务,因此在长时间操作(完整的测试运行、CI 监控)之前和之后都要报告。如果它回复 cancel,表示有人停止了该任务:停止工作,在卡片上说明,归还卡片(见归还卡片),然后执行 slipdock finish-job <job> --status cancelled。在步骤 7 结束时,在总结注释之后,执行 slipdock finish-job <job> --status done --summary "<提交和 CI 结果>";已归还的卡片则以其作业 --status failed 结束,并以原因为总结。
  • nothing queued。 只有在调用指定了回退方案时(“否则取待办列表顶部的任务”),才继续查看就绪列表(步骤 2a,然后 2)。否则轮次结束:报告 <pool> 没有排队任务 并停止。
  • nothing queued to take: job #N waits while #M is in progress。 由于一张卡片在看板上处于“进行中”状态,某个任务被暂缓领取。如果该卡片是你的,步骤 2 应该已经重新接入它;否则,是别人在操作它,因此报告该情况并在其旁边停止,而不是开始另一张卡片。
  • 没有任务工具——没有 claim_job MCP 工具,也没有 slipdock 命令来运行 claim-job:不要从列表中取卡片来代替。这会使得任务仍在队列中,并与运行器争夺卡片。停止,并说明需要重新连接 Slipdock 连接器(claude.ai → 设置 → 连接器:连接器会保持添加时的工具列表)或安装 slipdock CLI。
  • nothing queued to take: paused by …——有人暂停了看板(或此运行池)上的运行器工作,并说明了原因。不要取任何任务,即使是从就绪列表中,无论调用是否指定了回退:报告暂停信息并停止。只有人才能恢复它。
  • unknown command,或服务器返回 404(比运行器功能更旧的服务器):在轮次报告中说明一次,然后像未指定运行池一样继续。

重新接入的卡片(步骤 2)如果其 已领取 注释指定了任务,则仍然是该任务的:按上述方式报告并完成它。如果轮次离开期间其租约已过期,job-progress 和 finish-job 会回复该任务未使用此令牌认领——在卡片上注明并继续,不再处理该任务。

3. 选取顶部卡片

slipdock cards <board> --column "To Do" --open --deps ready --no-assignee --json

如果返回结果以 PAUSED 行开头(JSON 中的 paused),则表示有人暂停了看板上的运行器工作:不要取任何任务,报告暂停信息并停止。从空的作业队列回退到此步骤的轮次同样适用。

先取顶部,再往下——按列表的顺序,即 position 字段的顺序,而不是优先级。用户特意按该顺序堆叠了列表;优先级最多是打破平局的规则,且仅在共享同一位置的卡片之间。过滤器会帮你跳过不合适的卡片:--open 会剔除已完成的卡片,--deps ready 会剔除任何等待未完成卡片的卡片,--no-assignee 会剔除其他人的工作。还要跳过已标记为 blocked 或 waiting 的卡片(等待某人的开放等待状态会自动设置 waiting),跳过等待验证的卡片(verify_state: "pending",标记为 review:见已验证的工作),跳过本会话中先前轮次标记为 review 并归还的卡片,以及所有占位卡片(↪stand-in-for:#N,JSON 中的 stand_in_for):它标记了一张卡片进入冲刺的位置,真正的工作是那张卡片。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

相关技能