mcpField
F
fast-ship

fast-ship

github.com/gitbobobo生産性063 回インストール1 日前に更新
リポジトリ

fast-ship について

fast-shipは、Fast Ship APIでプロジェクトのIssueを検索・管理するエージェントスキルです。ワークフロー状態や協業情報、プルリクエストの関連付けを扱い、APIキーはスクリプト経由で読み込み、権限と書き込み検証の要件も示します。

主な機能

  1. 01Issueの検索と作成
  2. 02ワークフロー状態の更新
  3. 03協業の合意事項と要約の記録
  4. 04プルリクエストの関連付けと同期
  5. 05スクリーンショット注釈と切り抜き画像の取得
  6. 06キー管理スクリプトによるAPIリクエスト

活用シーン

  1. 01プロジェクトのIssueを絞り込んで処理
  2. 02決定事項や完了要約の記録
  3. 03実装プルリクエストの関連付けと状態更新
  4. 04スクリーンショット注釈によるUIレビュー

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/fast-shipを入力して読み込まれたか確認します。

同梱ファイルreferences/api.mdscripts/fast-ship-api.mjs

詳細

プロジェクトの README より

Fast Ship API

想做什么实际调用
在 issue 上留言/发评论/写完成总结PUT /api/issues/:iid/collab/summary(API Key 发评论必 40301)
标记完成PUT /api/issues/:iid/internal-meta 置 workflow_status=done(不是 state)
关闭 issue不可——仅 JWT,API Key 传 state 必 40301
开始做了PUT /api/issues/:iid/internal-meta 置 in_progress
记录共识/决策PUT /api/issues/:iid/collab/consensus
按 INT-xxx 找 issueGET /api/projects/:pid/issues?q=INT-56 换 UUID(路径参数只认 UUID)
查 Fast Ship 自身日志GET /api/self-logs(列表)、/aggregate、/trace(request_id 或 run_id 二选一);与项目日志 /projects/:id/logs 无关;fsr_ 令牌 40301
把 PR 挂到 issuePOST /api/issues/:iid/pull-requests,body {"url":"<PR链接>"}
刷新 PR 状态POST /api/issues/:iid/pull-requests/sync(合并后调,逐行失败看 failures[])
摘掉某个 PRDELETE /api/issues/:iid/pull-requests/:lid(:lid 是关联行 id,即 api.md 里的 {id})

调用任何写接口前先读 references/api.md 对应小节,不要凭记忆构造请求体。

Fast Ship 附加块(提示词尾部的引用块)

Fast Ship「启动线程」生成的提示词 = 用户模板正文 + 结尾的 > 引用块。看到引用块里带 项目ID / 问题ID,就按这两个 ID 用技能查询并处理该问题,不需要再追问是哪条 issue:

> 以下信息由 Fast Ship 附加。请使用 fast-ship 技能查询并处理该问题。
> 若当前环境未安装 fast-ship 技能,先征得用户同意,再执行:
> `npx skills add https://github.com/gitbobobo/fast_ship --skill fast-ship`
> 项目ID:<project_id>
> 问题ID:<issue_id>
> 推荐理由:<reason>   ← 可能出现

当前环境未安装本技能时,先征得用户同意,再执行 npx skills add https://github.com/gitbobobo/fast_ship --skill fast-ship。

T3 绑定(Agent 辅助配置)

Fast Ship 项目与 T3 项目是显式绑定,Agent 可辅助完成「发现 → 比对 → 绑定」:

  1. GET /api/environments/t3-projects:列出各环境及其 T3 项目(含 workspace_root)。
  2. 用自身仓库路径比对各项目的 workspace_root,确定自己对应哪个 T3 项目。
  3. PUT /api/projects/{id}/t3-bindings/{environmentId},body {"t3_project_id":"..."} 完成绑定;解绑用 DELETE 同路径。

这四个接口是对 API Key 开放的 T3 只读面(不含凭证、不含线程内容);线程相关端点仍仅 JWT。字段细节见 references/api.md。

上表的 :pid 在 api.md 里是 {id},:iid 是 {iid};:lid 是 PR 关联行 id(api.md 里 pull-requests 路径下的 {id})。

认证配置

Fast Ship 使用 API Key 进行程序化认证。Key 格式为 fsk_ 开头的随机字符串。

请求方式(硬性规则)
  • 禁止把 API Key 读出来写进命令、参数、环境变量赋值或任何输出——curl -H "Authorization: Bearer fsk_..." 这类写法会把 Key 留在会话记录和进程列表里。
  • 所有请求一律走技能自带脚本。脚本自行读取 config 并附加认证头,Key 不出现在命令行:
node <技能目录>/scripts/fast-ship-api.mjs <METHOD> <path> [body.json] [--verify [读回路径]]
  • 需要请求体时,把 JSON 写成 UTF-8 文件,以 body.json 位置参数传入。
  • --verify [读回路径]:写请求成功(2xx)后再发一次 GET,输出 { "response": …, "verify": … },用于写后读回校验。缺省对同一路径 GET;没有对应 GET 路由的写端点(如 internal-meta、recommendation、collab 的 PUT;批量 PUT /api/issues/internal-meta 的缺省读回会命中 GET /issues/:iid 而 404)必须显式给出读回路径(如对 Issue 本身 GET /api/issues/:iid)。对 DELETE,读回 404 视为确认删除。
  • 脚本不可用时的兜底:把 Authorization: Bearer <api_key> 整行写入临时头文件,用 curl -H @<header文件> 引用,用完立即删除该文件。
首次使用(配置持久化)

如果 ~/.config/fast-ship/config.yaml 不存在,必须向用户询问以下信息:

  1. Base URL:Fast Ship 服务地址,例如 http://localhost:8080 或 https://fast-ship.example.com
  2. API Key:从 Fast Ship Web 界面「设置 → API Key」创建的密钥(fsk_ 开头)

然后将配置写入文件:

# ~/.config/fast-ship/config.yaml
base_url: "https://fast-ship.example.com"
api_key: "fsk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

注意:~/.config 目录在 macOS/Linux 上通常已存在;如果不存在,请先创建目录。

后续使用

脚本会自行读取 ~/.config/fast-ship/config.yaml 中的 base_url 和 api_key,不再询问用户。Agent 不要把 Key 读出来写进命令或输出。

请求头

脚本自动为所有请求携带以下请求头(无需手工添加):

Authorization: Bearer <api_key>
Content-Type: application/json; charset=utf-8

核心工作流

未说明来源时创建 source: "internal"。只有用户明确要求同步 GitHub 时才用 source: "github"。API Key 只能建 internal。

字段一律见 references/api.md,这里只留端点。

  1. GET /api/projects,确定 project_id。
  2. 打标前先 GET /api/projects/{id}/issues/repo-labels。项目没配 GitHub 仓库或标签为空时,改 GET /api/projects/{id}/issues/filter-options。
  3. POST /api/projects/{id}/issues 创建。后续路径只用响应里的 id(UUID)。给用户的页面是 {base_url}/projects/{project_id}/issues/{id}。
  4. 要打标就 PUT /api/issues/{iid},标签名必须已经存在。不要靠创建请求里的 workflow_status 推进进度。
  5. 推进用 PUT /api/issues/{iid}/internal-meta,值为 todo、in_progress 或 done。
  6. 查一条用 GET /api/issues/{iid}。列表用 GET /api/projects/{id}/issues。

截图标注(AI 评审闭环)

截图页画布上的矩形框选标注挂在具体截图上,供人/AI 交换评审意见。API Key 可读全部标注、拉裁剪图、标为已解决;不能创建/删除标注或批量处理(40301),改文字/关联 Issue/重开也要 JWT。

  • 列表:GET /api/projects/{id}/screenshot-annotations → {items:[...]},query 可按 status(open/resolved)、outdated(true/false)、issue_id、screen_id、platform/locale/theme(逗号多值,__none__ = 未标注桶)过滤。
  • Issue 维度:GET /api/issues/{iid} 的 screenshot_annotations[] 内嵌关联到该 Issue 的标注(无则缺省)。
  • 每条标注带:image_url(所在截图原图)、crop_url(框选区域裁剪图,PNG,四周带外边距)、比例坐标 x/y/width/height(0~1)、像素坐标 pixel_rect(尺寸未知时为 null)、screen_key/screen_title/screen_platform/screen_locale/screen_theme、outdated(截图被覆盖更新后待确认)、status。
  • crop_url/image_url 是 <img> 直链路径:脚本调用带 Authorization 头即可,Web 端 <img> 才需要 ?token=<jwt>。
  • 标已解决:PUT /api/screenshot-annotations/{aid},body 整包只传 {"status":"resolved"}——带其他字段或 open 会被 40301。
  • 原图超过解码像素上限(约 64MP)时 crop 返回 40004(尺寸超出可处理范围),此时用 image_url 拉原图自行缩放。

AI 评审闭环(字段细节见 api.md screenshots 章):

  1. GET /api/issues/{iid} 读 screenshot_annotations,或按维度过滤 + status=open 拉项目标注。
  2. 按 crop_url 拉裁剪图,看用户框选了哪块区域、写了什么意见。
  3. 修改 UI 后,POST /api/projects/{id}/screenshots 以同一 screen_key + 同一组 platform/locale/theme 上传新截图(同变体即覆盖更新,文件与宽高/上传时间被替换;该截图上全部 open 标注置 outdated=true,等待人工「确认保留」或你确认修完后置 resolved)。
  4. 逐条 PUT {"status":"resolved"} 标已解决(JWT 批量场景可用 POST /api/projects/{id}/screenshot-annotations/batch,API Key 无此能力)。

删 Issue 只清空标注的 issue_id(标注保留);删截图会级联删标注。界面随版本增删时,用 DELETE /api/screenshot-screens/{sid} 清理过时截图(JWT / API Key 均可)。

Issue 关联 PR

一个 Issue 可挂多个 PR(跨仓库也可以)。时机:建完 PR 立刻 attach,让 Issue 页能看到实现进度;PR 合并后调一次 sync 刷新状态。

  • attach:body 只传 {"url":"https://github.com/<owner>/<repo>/pull/<n>"},支持 /files、query 等后缀。服务端自行去 GitHub 拉标题/状态/作者,拉取失败不落记录(502)。重复 attach 幂等,不产生第二行。attach 必须读回确认:加 --verify /api/issues/{iid} 或紧接一次 GET,确认 pull_requests[] 里出现该 PR 才算挂上——502/超时会留下「以为挂上了、实际没落记录」的窟窿,只看退出码不够。
  • 读:详情 GET /api/issues/:iid 的 pull_requests[] 是全量列表;列表项带 pull_request_summary {total, open, merged}(closed = total - open - merged)。
  • sync:返回 {items, failures},每条 PR 是独立失败域——某条拉不到(404/限流)只进 failures[],其余照常刷新;failures[].id 是关联行 id。
  • detach:DELETE /api/issues/:iid/pull-requests/:lid;不存在的关联返回 40412(非幂等,重复调用会报错)。
  • PR 状态与 workflow_status 无耦合:PR 全合并不等于需求完成,internal-meta 仍要自己推。
  • link_origin=manual 的关联永不被 GitHub 同步投影的清理逻辑误删。

语义陷阱与权限分工

multipart

这些端点是 curl -F file=@路径,不是 JSON。Issue 图片的响应里有 markdown,把这段贴进正文才算挂上附件。

  • POST /api/auth/avatar
  • POST /api/projects/{id}/issues/assets(草稿,仅 JWT)
  • POST /api/issues/{iid}/assets
  • POST /api/versions/{vid}/artifacts(可选表单字段 platform)
字段级权限

spec 的 security 经常同时写 JWT 和 API Key,真正的拒绝在 handler 里。

  • API Key 不能传 state / state_reason,不能 POST /api/issues/{iid}/comments,不能 PUT 或 DELETE /api/issues/{iid}/ship-hook。做了就是 403(40301)。ship_hook 只出现在 Issue 的 GET 和列表里,只读。
  • PUT /api/issues/{iid}/collab/consensus、PUT /api/issues/{iid}/collab/summary、PUT /api/issues/{iid}/recommendation 只接受 API Key。JWT 调用返回 403(40303)。
  • 推荐被用户延后后,PUT recommendation 返回 409(40911)——不要重试再推荐,也不要试图 DELETE(同样 40911)。PUT/DELETE /api/issues/{iid}/recommendation/defer 是延后/恢复,仅 JWT(API Key 40301)。彻底移除延后项只能由 JWT 用户做。
  • POST /api/projects/{id}/logs 只接受 API Key。JWT 调用返回 403(40303)。
自身日志不是项目日志

GET /api/self-logs、/aggregate、/trace 查的是 Fast Ship 服务端自己的 slog(INT-94)。项目运行日志仍走 /api/projects/{id}/logs。fsr_ 令牌查自身日志返回 40301。失败请求用响应头 X-Request-Id 调 /trace?request_id=;审查运行链路用 run_id。

checklist 是整组替换

PUT /api/issues/{iid}/checklist 提交的 items 就是最终清单。没带上的旧条目会被删掉。items=[] 会清空清单。

q 是内存全量过滤

GET /api/projects/{id}/issues 的 q 不是索引查询。它扫全量,匹配标题、正文、作者 login、INT-xxx / GH-xxx。纯数字还会匹配 sequence_number 或 GitHub number。

详情自带 collab

GET /api/issues/{iid} 的 data 里有 collab(consensus 和 summary)。列表项没有。要看协作区,读详情即可,不必再打一次 GET /collab。

批量改工作流

PUT /api/issues/internal-meta 的请求体是 {items:[{issue_id, workflow_status}]},最多 200 条。某一条失败不会让整批变成 4xx,HTTP 仍是 200,看 failures[]。

collab 先读后写

PUT consensus 或 summary 之前先 GET。用户已经清空的块,不要写回去。DELETE 幂等,目标本来就没有也返回 200。

追问还没结束时不要写共识。决策问完、用户确认可以开工之后,再 PUT 已经拍板的内容。用户说别问了直接做,共识留空,不要编「按 Issue 原文实施」。未经许可不要关单,不要提交或推送代码。

完成总结写给普通人看,两段就够:之前怎样,现在怎样。不列文件,不贴 commit SHA,不写测试清单。改动还没落到能感知的结果上,就先别写「现在」。

请求编码

请求体写成 UTF-8 JSON 文件,用脚本的 body.json 传入。不要在 shell 里拼接中文。

Breaking Changes
  • API Key 不可通过 PUT /api/issues/:issue_id 修改 state / state_reason(open/close);Agent 应改用 PUT /api/issues/:issue_id/internal-meta 的 workflow_status 标记完成,open/close 由 JWT 用户在 Web 端操作。
  • API Key 不可发表评论(POST /api/issues/:issue_id/comments)。
  • API Key 不可 PUT/DELETE /api/issues/:issue_id/ship-hook。ship_hook 仅出现在 Issue GET/列表中供只读。发货后关单/留言由 JWT 用户在 Web 配置,发货成功后由服务器执行。
  • 协作区旧端点 POST/PUT/DELETE /collab/notes、/collab/questions 已移除;suggestions、plan、review 与 commit_ids 一并废弃。当前 GET /collab 只返回 consensus 与 summary。

コメント