mcpField
S
ship

ship

github.com/gharib89开发045 次安装今天更新
代码仓库

关于 ship

面向编码 Agent 的通用交付技能,通过仓库专属 ship profile 提供项目细节。流程涵盖工作项处理、实施、评审、CI 和合并关卡,并支持有人参与与无人值守模式。

主要功能

  1. 01分阶段交付流程
  2. 02工作项认领与跟踪
  3. 03实施与验证关卡
  4. 04PR 评审和 CI 处理
  5. 05有人参与与无人值守模式

适用场景

  1. 01将跟踪中的问题从选取推进至合并
  2. 02以无人值守模式运行交付流程
  3. 03在合并关卡重新处理 Pull Request

安装

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

$npx skills add https://github.com/gharib89/skills --skill ship

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CHANGELOG.md
retired-terms.md
reference/
context-discipline.md
evidence-lines.md
implement.md
isolate.md
mechanics.md
merge-gate.md
phase-steps.md
pr-body.md
review-loop.md
rework.md
small-lane.md
unattended.md
verify.md
scripts/
_lib.sh
base-fresh.sh
ci-wait.sh
cleanup.sh
comment-issue.sh
comment-pr.sh
dropped-lines.sh
file-issue.sh
scripts/host/
ado.sh
github.sh
scripts/host/ado.d/
prs.sh
threads-and-lists.sh
scripts/host/github.d/
issues.sh
prs.sh
runs-and-reviews.sh

详细介绍

原文在翻译后有更新,译文可能不是最新。

ship

此技能是通用的:它只知道如何交付,不了解仓库的任何信息;所有仓库信息都来自交付配置文件 docs/agents/ship.md。.claude/skills/ship 中的副本是派生副本,在其源仓库 Gharib89/skills 中修改,并通过仓库 CLAUDE.md 中 ### Ship 段落所载的命令刷新。

版本。 加载时,运行环境会剥除此文件的 frontmatter,因此请在运行开始时读取一次版本,使用 sed -n 's/^ version: //p' <base directory>/SKILL.md,然后在运行标题、第一条回复的第一行,以及合并摘要中再次打印 ship <version>,这样每个 PR 都会记录由哪个 ship 产出。

参数和标志

$ARGUMENTS:

  • <issue>:问题编号(Azure DevOps 工作项 ID);单独使用 prepare 时不需要。未提供且没有标志时:询问要处理哪个问题。
  • 用自由文本代替数字:文本本身即为任务规格。不获取问题、不认领、不添加 Closes 或反映,也不添加点名这些内容的 Done when: 子句;对 preflight、isolate、open-pr、merge 和 cleanup,问题参数为 none。
  • --unattended:无人值守运行,详见 reference/unattended.md。没有人在场:遇到阻塞时停止并交还,而不是提问;沙箱克隆即为隔离环境;合并关卡会将摘要作为 PR 评论发布并返回。若没有 <issue>,则先运行无人值守流程:prepare、PR 上限检查、选择。
  • --inline [--review]:内联流程;在 prepare 之前,先阅读 small-lane.md 了解规则。

不带 --unattended 时,运行处于有人值守状态:任何需要人工操作的情况都会停止并提问,等待期间认领仍然有效。每次运行都要在 run-file init 之前执行准备,但无问题流程中的内层运行除外:prepare(该流程中使用 --unattended)。在云沙箱(CLAUDE_CODE_REMOTE=true)中,或使用该标志时,运行 tooling --install,然后运行配置文件的 ## Cloud lane Bootstrap:;其他情况下不执行任何操作。若某个步骤失败,则停止运行,不进行认领,并附上该步骤的末尾输出:tooling 对应 host-unreachable,bootstrap 对应 bootstrap-failed。

组合使用,不要内联重写

在相应阶段通过 Skill 工具加载 tdd(阶段 2)、writing-for-agents(阶段 4,面向 Agent 的文档)、code-review(阶段 4),以及 find-docs(涉及任何 API 声明时,包括配置文件的 Pinned: 库:implement.md),从各技能本身获取其逻辑,并明确告知任何带有无人值守模式的组合技能,本次运行是无人值守的,因为它们无法通过其他方式得知。第 6 阶段的 Change outline 请阅读 show-me;pr-body.md 说明了原因。

流程

按顺序执行各阶段,让主线程专注于编排和决策。首先,阅读 reference/context-discipline.md:了解委派规则,以及避免长时间运行导致上下文窗口膨胀的手段。然后执行本次运行必须首先执行的操作:在 prepare 之后、阶段 0 之前,运行 run-file init <issue|slug> --from-profile,初始化用于保存十项检查清单的 Run 文件。以下每个阶段都要通过 run-file next、open、close 或 skip 更新状态;只有满足其 Done when: 条件后才能关闭,不能提前关闭。

每个阶段都运行其指定的机制,而不是重新推导该机制封装的内容。所有主机写入操作和所有门控读取操作都必须通过机制执行:任何未由机制执行的操作都属于 Ship 缺陷,必须列入合并摘要的 Ship defects: 行,绝不能手动调用;merge-gate.md 说明了草稿应放置的位置。reference/mechanics.md 完整说明了该规则、允许的信息性读取、各阶段运行的机制及其共同约定,包括 --help。 0 · 隔离。 reference/isolate.md 说明了预检会验证和拒绝什么、会加载哪个配置文件及其原因,以及为何要按这种方式创建工作树。运行 preflight <issue>(无人值守运行时加上 --unattended):每条 reasons 都对应下方停止表中的一行。然后运行 read-issue <issue>,这是第 1 阶段的输入;据此推导分支 <type>(feat、fix、docs 等)和 <slug>。接着运行 isolate <issue> <type> <slug>,并使用配置文件中的 Carry: 文件;无人值守时则运行 isolate ... --in-place。所有编辑、提交和 PR 都要在 isolate 打印出的路径下进行,并且边做边提交,因为 PR 需要真实提交。## Worktree 下的 Bootstrap: 在此处运行一次,即隔离完成后。 完成条件:preflight 返回 ok: true,isolate 打印出路径,并且任何 ## Worktree 下的 Bootstrap: 均已成功运行。

1 · 理解。 如果 read-issue 的结果过于含糊,无法据此制定计划:停止为 ambiguous,不领取任务。否则,先领取,再开展任何工作:运行 manage-issue <issue> take,领取状态保持到合并;之后的停止情况遵循停止表。然后搜索问题引用的每个锚点;如果代码树与其中一项矛盾,就通过 update-issue-body 改写该项(implement.md)。如果某项验收标准需要由任何机制都无法执行的宿主操作,则保持原文不变:无人值守时,它是合并摘要中要列出的未满足验收标准;有人值守时,先按两种情况下都适用的 implement.md 询问。之后才能将成功标准写入 Run 文件,作为后续阶段可检查的验收标准;后续具有权威性的评论优先于正文(规范优先级)。 完成条件:claim: taken,已搜索锚点,Run 文件中已记录验收标准。

2 · 实现。 reference/implement.md 说明了各类别、TDD 覆盖规则、外部声明探查、判断与执行的区分,以及相邻发现的处置方式。将工作归类为 docs / code / infra;说明类别、由此决定的跳过路径、三个通道键是否成立,以及 ## Verification 中适用的验证项(其中的 Applies when: 行属于需要在此处判断的说明文字)。根据配置文件的 Subject constraints:,使用 run-file grade <patch|minor|breaking> 记录公共接口变更的版本等级:open-pr 和 update-pr-title 会拒绝等级低于该变更的标题类型。然后按类别先写测试,再实现;无论类别如何,Tripwires: 和 In-PR requirement: 都必须随本次变更一起落地。 从首次编辑起就维护偏差日志:每当实际情况迫使你偏离问题、简述或计划时,采取保守方案,记录偏离内容及原因,然后继续;这些内容会原样写入合并摘要。如果差异超出单个 PR 的范围,或修复需要进行问题范围之外的重新设计,则以 needs-split 停止,并提出拆分方案。 **完成条件:**适用的测试均通过(按类别先失败后通过);Tripwires: 和 In-PR requirement: 均已落地;已记录 Grade:;小型通道的差异统计已记录且未超上限;到目前为止的每项偏离和相邻发现均已记录在 Run 文件中,并注明处置方式。

3 · 验证。 reference/verify.md 说明了结果用语、Without it: 的处置方式,以及 unexercised 的含义。针对你改动的内容,在问题所报告的环境中运行每项适用验证的 Run: 行:在其他环境中通过不代表问题已修复。运行时间较长的验证交给 verify 临时目录中的低成本层级子 Agent。docs 类和小型通道跳过此阶段。 完成条件:run-file close 3 已为每项验证填写 --result;每项适用验证的结果均为 pass、deferred-to-ci 或 unexercised;任何其他结果均已记录,随后按其指定的停止方式处理。或者,run-file skip 3 已记录跳过原因。 4 · 同步文档,然后自我审查。 先处理文档,这样审查时会将文档编辑视为差异的一部分。仅当公开接口或可观察行为发生变化时才触发文档同步:使配置文件中的 Targets: 保持一致,并将编辑纳入本次更改,或纳入跟踪问题的起草章节。内部重构、恢复文档所述行为的 Bug 修复、仅涉及测试或工具的更改,以及注释更改,都跳过此步骤,并在合并门禁处用一行说明。writing-for-agents 流程有自己的触发条件,即使跳过文档同步也会触发:只要差异涉及配置文件 Agent-facing: 行中列出的目标,就必须在判断层级、writing 临时目录中,对差异中所有面向 Agent 的文件执行该流程。人类可读的文案则走机械检查流程。文档同步的编辑提交后,加载 code-review,然后在同一轮中调度该流程及其两个维度,并结束本阶段;每项都要注明其 Report 文件。小型流程:先调度两个维度,再内联运行该流程。

自我审查,所有流程都必须执行:针对自 origin/HEAD 以来的差异调用 code-review;其 Standards 维度读取配置文件中的 ## Coding standards 路径,其 Spec 维度读取问题说明;每个维度的提示词都要包含各自的临时目录(standards、spec),并说明 Local 门禁将在本次运行的后续阶段执行,因此该维度读取门禁的 JSON,绝不自行运行 check.sh full 或测试套件。必须等到所有 Report 文件都到齐才能进行分诊;如果在停止规则规定的两次修复并重试后仍未收到某个文件,应标记为 red-after-retry: <axis>,绝不可凭记忆写出处置结果。按照 implement.md 中的约束和深度检查,在判断层级对每条发现进行自动分诊,每条发现各写一项处置结果。run-file close 4 会拒绝关闭,除非 Run 文件中已包含该节检查要求的证据行:Reverted-fix:、Dropped:、Near-miss: 和 Probe:,以及 run-file prove 和 run-file probe 生成的 red 行和 Probe: 行。 **完成条件:**每个已触发的报告都有对应的 Report 文件存于磁盘上,且其路径已写入 Run 文件;每条发现都有处置结果;close 4 已接收证据行;文档同步已完成,或已用一行说明跳过原因。

5 · 本地门禁。 *前置条件:*所有适用的验证项状态均为 pass、deferred-to-ci 或 unexercised,或者类别为 docs,并且第 4 阶段的每条发现都有处置结果;否则返回前一阶段。先运行 base-fresh:CI 会测试合并引用,因此即便分支早于某次合并,仍可能通过,但工作树中所有“是否存在?”的判断都是在合并前做出的;若落后:遵循其建议、重新运行,然后继续。确认每个 Carry: 文件仍与主检出中的副本一致;若不一致,则视为 carried file modified,因为 ship 绝不会编辑未跟踪的密钥。然后从工作树中内联运行配置文件 Location: 指定的门禁,并对其 JSON 运行 run-file gate record(小型流程:small-lane.md)。每种流程中的 JSON 都包含 verdict(pass|fail|unavailable)、每项门禁的状态(pass|fail|deferred-to-ci|unavailable),以及 gates.secrets;若输出无法解析或缺少 secrets 键,则视为 unavailable。 fail:进入修复循环。deferred-to-ci:继续,并在合并摘要中列出每项延后到 CI 的门禁。unavailable:停止,标记为 local gate unavailable,不创建 PR。 完成条件:base-fresh 返回 fresh: true,Carry: 文件均一致,且记录的 verdict 为 verdict: pass 并包含 gates.secrets。 6 · 开启 PR。reference/pr-body.md 说明正文包含哪些内容,以及正文的编写与回读方式。使用 open-pr <issue> --title --body-file,且必须非草稿(草稿可能不会触发审核者)。标题:根据问题派生的 Conventional Commit 主题,遵守 Subject constraints:;它会成为发布工具读取的 squash 主题,之后若发现标题有误,则使用 update-pr-title 修正。每次写入未关闭 PR 的标题或正文后,都要执行 read-pr <pr>,并检查其中的 ## 标题是否与正文应包含的标题一致。然后执行 reflect <issue> <pr>。 完成条件:read-pr 显示一个未关闭、非草稿的 PR,且包含正文应有的标题;reflect 已发布。

7 · 审核者。reference/review-loop.md 说明每种触发条件对应的轮次、作为预算的上限、如何读取一轮审核、退出语句和回退方案。尽力而为:每轮针对 ## Reviewers 下的每位审核者,先按其 Trigger: 启动,等待一个 poll-pr --brief 时段,分类处理所有新内容,集中推送修复,然后使用 reply-thread 回复每个讨论串,接着执行该区块的 Resolve:;Cap: 限定轮数,只有文档变更的纯修复差异则结束审核。每轮修复通过其针对性测试节点和仓库的编辑检查级别来证明,即其测试框架在每次编辑后对所改文件运行的检查(check.sh edit <file>...);没有测试框架、因而没有编辑检查级别的仓库,则用本地门禁证明。否则,不会在每轮重新运行本地门禁:最终提交的门禁检查,是在 gate read 显示 current: false 时重新运行合并门禁,且绝不能在 code-review 尚未结束时运行(阶段 5)。对于 Fallback-for: 为 None. 的每位审核者,先处理该审核者,再处理回退审核者;当主要审核者退出状态为 not reviewed 时,分别触发每个回退方案(inline lane 除外)。每位审核者的审核均受上限约束,必须留下审核结果或以 not landed 停止。退出状态:reviewed、not reviewed: <reason> 或 not invoked: <primary> reviewed;not reviewed 时,只要 CI 为绿色,就继续执行合并门禁,并在该处报告。退出时,使用 update-pr-body --section --body-file 写入各轮新增的章节、未达标的 Change outline,最后写入 Review;检查标题是否符合 Grade:,然后执行阶段 6 的回读;达到上限、纯文档变更和未落地的轮次所需的本地审核,按 review-loop.md 中的说明处理。 **完成条件:**每位审核者都有一个退出状态词;poll-pr 返回的每个讨论串都已回复,并按 Resolve: 要求解决;每轮新增的章节都已重写;标题符合 Grade:;达到上限、纯文档变更或未落地的轮次所需的任何本地审核都已处理;close 7 收录了每位审核者的 Round: 和 Stop: 语句;read-pr 显示每位审核者各有一行 ## Review。

**8 · CI。**CI 在 PR 开启时启动,并与阶段 7 并行;ci-wait <pr> 会按照配置文件的 Legs: 等待。ci-wait 和 poll-pr 会等待预期的提交版本(mechanics.md)。遇到 conflict 时,标准错误输出会包含恢复方法。只有在 No-checks legal: 明确允许的情况下,no-checks 才可接受。验证项的 Also proven by CI: 行中列出的红色检查项,表示该验证失败:返回阶段 2。审核者退出后若检查项变红:修复、推送,并在 CI 变绿后继续。遵守 Push policy::推送会消耗 CI 时间和审核额度,因此仅在工作树发生变化时推送。 完成条件:ci-wait 返回 green;每个 missing_legs 条目都被 No-checks legal: 允许,或者 no-checks 在允许时使用。 9 · 合并门禁。 reference/merge-gate.md 规定摘要的格式、merge 的作用、两种拒绝情况以及跟踪器草稿。按该文件撰写摘要。有人值守时:遵循其中的 Merge: 分支,默认等待明确的“merge”指令;或者在 Merge: on-clean-gate 时,或运行处于 inline lane 且 run-file gate clean 返回 clean: true 时进行合并;未满足的条件需要人工明确豁免。获得任一授权后,运行 merge <pr> <issue|none> [--worktree <path>],按跟踪器草稿执行 update-issue-body,处理每份 Ship 缺陷草稿(只有在对方明确要求时才提交),运行 run-file close 9,然后最后运行 cleanup <issue|none>,因为它会删除 Run 文件;如果退出码非零,或 merge 或 cleanup 的 JSON 中出现 false,则重新运行负责该步骤的机制;若没有任何机制可重做某一步,则将其作为 Ship 缺陷写入摘要。无人值守时:通过最终 head 的门禁后,再运行 comment-pr <pr> --body-file 并附上摘要,然后运行 run-file close 9。任一流程结束后即返回。 完成条件: 有人值守时,merge 和每个 update-issue-body 的退出码均为 0 且没有 false;每份 Ship 缺陷草稿均已提交、已用候选方案作答,并包含其 command 或已被拒绝;随后 close 9,再运行 cleanup <issue|none>,其退出码为 0 且没有 false。无人值守时,comment-pr 已发布。

停止条件

合并门禁会像第 9 阶段所述那样停止;无人值守通道则会发布结果并返回。 以下停止条件表具有权威性。 其他所有事项,例如分诊自己的发现、修复、重新运行,都由你自主处理。以下两条护栏适用于此流程:

  • 红灯问题要修复或报告。 合并门禁前的任何失败,最多可进行两次修复并重试;第二次后仍为红灯时,记为 red-after-retry: <what>;如果失败信息表明方法有误,则应更早停止。无论哪种情况,都要停止并报告,附上具体证据;如果能轻松找到经过验证可行的替代方案,也一并提供,让报告能迅速得到确认。
  • 每个停止条件都有名称,必须原样报告,并按下方要求处理认领。
停止条件原因认领处理
配置缺失或无效,主机无法访问profile missing、profile invalid: <detail>、host-unreachable不认领
composes 所需的某项 skill 未按指定版本安装,或其版本指定格式错误skill missing: <skill>; run <install line>、skill off pin: <skill> at <ref>, pinned <sha>; run <install line>、skills lock unreadable: skills-lock.json; repair it, then re-run preflight、composes pin invalid: <entry>; want <form>不认领
预检无法执行closed、is a pull request、already claimed、existing PR、existing branch、worktree exists、not triaged: run /triage first、ready-for-human: attended only不认领
问题描述过于含糊,无法制定计划ambiguous不认领
变更超出一个 PR 的范围,或需要重新设计问题中未列明的内容needs-split有人值守:询问;无人值守:交还
调查发现问题定义有误mis-specified有人值守:询问;无人值守:交还
缺少验证所需的前置条件hand-off(有人值守时等待,认领保持不变)/blocked-verification有人值守:保持认领;无人值守:交还
本地门禁结果为 unavailablelocal gate unavailable: <gates>有人值守:询问;无人值守:交还
随附文件已更改carried file modified: <file>有人值守:询问;无人值守:交还
重试后仍为红灯red-after-retry: <what>有人值守:询问;无人值守:交还
合并前,分支落后于其基准分支stale-base: behind <n> on <base>有人值守:等待你合并基准分支;无人值守:交还
PR 在合并门禁处已关闭pr-closed: <state>有人值守:询问;无人值守:交还
--inline 与 --unattended 或自由文本同时使用inline refused不认领
prepare 未通过 Cloud 通道的 Bootstrap:bootstrap-failed不认领
未关闭的 PR 数量达到或超过配置文件中的 PR cap:pr-queue-full不认领
没有问题符合筛选条件nothing-ready不认领
主机的阻塞项查询存在但执行失败blockers-unavailable不认领
已到达合并门禁无:表示本次运行成功保持认领,直到合并

交还操作为 manage-issue <issue> handback "<reason>":取消指派、移除 ready-for-agent、添加 ready-for-human,并评论说明原因;如果该命令以 1 退出,其输出会说明认领最终处于何种状态。有人值守的运行中,应停止并询问;只有在人类要求停止时,才交还给人工队列:绝不能交给 Agent 队列,否则会无限循环。

各通道

除非变更已证明是小型,否则每次运行都按完整通道处理:你必须在阶段 2 断言以下三个条件均成立,并宣布类别。无法确定时,就不算小型。

  1. 不改变公共接口。 公共接口指配置文件中的 ## Public surface;Default. 表示导出或发布的 API、CLI 标志和退出代码、配置架构、文件格式及文档说明的行为。
  2. 无需真实环境即可证明。 单元测试或回归测试能够充分证明这一点,或者类别为 docs 且没有可测试的行为;无论哪种情况,配置文件中的 ## Verification 均不适用。
  3. 范围受限。 不引入新依赖,配置文件中的 Tripwires: 均未触发,并且变更差异在 small-lane.md 规定的大小上限内。

允许改变行为:修复缺陷就是一种行为变更。涉及防护条件、允许列表或拒绝规则的变更属于完整通道,--review 下的内联变更除外。对于小型或内联变更,请先阅读 reference/small-lane.md。

模型层级

为每个子代理选择模型时,必须依据 context-discipline.md 中唯一的层级表,并为每个子代理标注其模型和临时目录;两者都不会继承。

工作准则

这些准则适用于每次运行在任何仓库中所做的每项编辑,无论个人的 ~/.claude/CLAUDE.md、~/.claude/rules/ 或个人技能中有何规定:

  • 用最简单的形式解决问题。 不要为只使用一次的代码添加臆测的功能、可配置性或抽象;如果变更差异可以缩小到三分之一,就重写。
  • 精准修改。 只修改问题所需的内容,每一处变更都必须对应问题或已记录的偏离,并遵循现有风格,不动相邻代码、注释和格式。
  • 修复根因,而非症状。 不要打临时补丁、吞掉错误,也不要用 TODO 代替修复;如果真正的修复超出范围,请说明并登记后续事项。
  • 注释说明原因。 为公共 API 以及不明显的约束、不变量和变通方案添加说明;不要为内部实现写叙述性注释。
  • PR 正文始终简洁,并说明原因。 说明改了什么以及为什么改;读者可以通过差异了解如何实现。合并摘要除外:请完整撰写。

评论

支持 Markdown