mcpField
F
fast-ship

fast-ship

github.com/gitboboboProductivity063 installsUpdated 1d ago
Repository

About fast-ship

fast-ship is an agent skill for querying and managing project issues through the Fast Ship API, including workflow status, collaboration details, and pull request links. It uses a script to read the API key and documents endpoint permissions and write verification requirements.

Key features

  1. 01Query and create issues
  2. 02Update workflow status
  3. 03Record collaboration consensus and summaries
  4. 04Link and sync pull requests
  5. 05Read screenshot annotations and crops
  6. 06Send API requests with a key-handling script

Use cases

  1. 01Filter and work on project issues
  2. 02Record decisions or completion summaries
  3. 03Link implementation pull requests and refresh their status
  4. 04Review interface feedback through screenshot annotations

Install

Copy the command and run it in a terminal.

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

After installing, type/fast-shipin Claude Code to confirm it loaded.

Bundled filesreferences/api.mdscripts/fast-ship-api.mjs

Details

From the project 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。

Comments

Markdown supported