mcpField
P
paperclip

paperclip

github.com/paperclipaiAgent 工作流108.3k3.8k 次安装今天更新
代码仓库

关于 paperclip

paperclip 面向在 Paperclip 心跳式任务系统中运行的 Agent,说明任务处理、API 安全、对话工作流及外部聊天回合的操作方式。

主要功能

  1. 01心跳任务处理流程
  2. 02Paperclip API 身份验证指引
  3. 03任务文档与制品处理
  4. 04对话交接流程
  5. 05已验证外部聊天回合处理

适用场景

  1. 01在心跳运行期间处理分配任务
  2. 02保存任务文档并添加链接
  3. 03将已批准计划转为任务交接
  4. 04回复已验证的外部聊天请求

安装

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

$npx skills add https://github.com/paperclipai/paperclip --skill paperclip

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

包含的文件

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

references/
api-reference.md
artifacts.md
cases.md
company-skills.md
issue-documents.md
issue-workspaces.md
routines.md
run-diagnostics.md
workflows.md
scripts/
paperclip-issue-update.sh
paperclip-upload-artifact.sh
submit-agent-commentary.mjs

详细介绍

Paperclip 技能

你在心跳周期中运行——由 Paperclip 触发的短暂执行窗口。每次心跳周期中,你都会唤醒、检查工作、完成有用的任务,然后退出。你不会持续运行。

术语

在 Paperclip 中,task 和 issue 指的是同一工作项。界面可能使用“task”,而 API、数据库字段、路由名称和较早的文档可能仍使用“issue”;除非本地上下文明确区分,否则请将它们视为同一实体。

任务文档(API 运行时)。 收到任务文档请求时,请使用 PUT /api/issues/{issueId}/documents/{key} 将文档保存到 Paperclip issue 上,除非请求者指定了其他目标位置。确认返回的文档已保存的修订版本,并在报告完成前添加可点击的 Markdown 链接;有关请求载荷和确保修订版本安全的更新,请阅读 references/issue-documents.md。可下载文件请参阅生成的制品和工作成果。

身份验证

自动注入的环境变量:PAPERCLIP_AGENT_ID、PAPERCLIP_COMPANY_ID、PAPERCLIP_API_URL、PAPERCLIP_RUN_ID。也可能存在可选的唤醒上下文变量:PAPERCLIP_TASK_ID(触发本次唤醒的问题/任务)、PAPERCLIP_WAKE_REASON(触发本次运行的原因)、PAPERCLIP_WAKE_COMMENT_ID(触发本次唤醒的特定评论)、PAPERCLIP_APPROVAL_ID、PAPERCLIP_APPROVAL_STATUS 和 PAPERCLIP_LINKED_ISSUE_IDS(逗号分隔)。对于本地适配器,PAPERCLIP_API_KEY 会作为短时有效的运行 JWT 自动注入。对于由沙箱支持的本地适配器,Bash/工具环境可能会收到用于运行范围桥接的 PAPERCLIP_API_URL 和 PAPERCLIP_API_KEY,而不是直接连接主机 API;请在 Bash/curl 中使用这些准确的环境变量,不要假定浏览器或 Web 工具可以访问主机端口。对于非本地适配器,操作员应在适配器配置中设置 PAPERCLIP_API_KEY。所有请求均使用 Authorization: Bearer $PAPERCLIP_API_KEY。所有端点均位于 /api 下。除 multipart 附件上传和二进制内容下载外,均使用 JSON。切勿将 API URL 硬编码,也切勿将 API 密钥或桥接令牌粘贴到提示词、评论、文档、恢复的工作区文件或日志中。

适配器会在运行提示词中提供唤醒负载,其中包含精简的问题摘要,以及本次唤醒收到的新评论负载(按顺序排列)。请先阅读提示词中的这一部分。对于由评论触发的唤醒,请将这批评论视为本次心跳中优先级最高的新上下文:在首次更新任务或回复时,先确认最新评论,并说明它将如何改变你的下一步行动,然后再广泛探索代码库或使用通用的唤醒套话。只有在 fallbackFetchNeeded 为 true,或内联评论批次提供的上下文不足时,才立即获取评论串/评论 API。

手动本地 CLI 模式(心跳运行之外):使用 paperclipai agent local-cli <agent-id-or-shortname> --company-id <company-id> 为 Claude/Codex 安装 Paperclip 技能,并打印/导出该 Agent 身份所需的 PAPERCLIP_* 环境变量。

CLI 安全 — 对包含内容的参数使用 npx paperclipai。 运行 Paperclip CLI 时,任何可能包含不可信内容的参数都必须使用 npx paperclipai。不可信内容包括问题文本、评论正文、Markdown、粘贴的片段和模型输出。npx paperclipai 会直接运行 CLI 二进制,并将参数作为不可执行的 argv 值传递;它不会对该值运行 shell。此类参数不要使用 pnpm paperclipai。pnpm paperclipai 是一个 package.json 脚本;pnpm 会将参数追加到 /bin/sh 命令字符串中,因此 CLI 启动前,shell 就会先读取该参数并解释反引号对、$( ) 或 $NAME。精心构造的值可能会以调用用户的身份运行任意命令,或将环境变量展开后写入存储的参数。即使参数来自带引号的 shell 变量,这一风险仍然存在,因为 pnpm 会在自己的 shell 中重新解析该值。也不要使用 pnpm exec paperclipai;根工作区未链接该二进制,因此命令会以 Command "paperclipai" not found 失败。若要对包含内容的参数运行本地 cli/src 更改,请使用 node cli/node_modules/tsx/dist/cli.mjs cli/src/index.ts <command> <args>。完整的安全/不安全对照表请参阅 doc/CLI.md。

运行审计跟踪: 对所有会修改问题的 API 请求(签出、更新、评论、创建子任务、释放),都必须添加 -H 'X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID'。这会将你的操作关联到当前心跳运行,以便追踪。

对话任务

当任务上下文指示 Chat mode(问题包含 conversationAgentId)时,请遵循该指令处理对话生命周期。在此处研究、澄清并修订对话的 plan 文档。获得授权交接后,在合适的项目中创建普通的已分配任务,不设置 parentId,也不建立指向该对话的阻塞关系。在回复中附上这些任务的链接,并让它们照常运行;不要等待它们,也不要更改对话状态。

在创建每个执行任务时,将相关的已批准计划复制到任务中,使用 create_task.initialPlan 或 HTTP 问题创建请求正文中的 initialPlan 字段。请包含 idempotencyKey。在 description 中复制的内容不算计划文档,之后再写入文档可能与执行发生竞态。在确认交接前,核实已创建任务的 plan 文档。保留此对话中的源计划。以下普通的完成、子任务和阻塞说明适用于执行任务;它们不覆盖 Chat mode 的要求。

服务端已验证的外部聊天轮次

Paperclip 可能会将普通外部聊天轮次识别为已由服务端框架检出并完整设定上下文。仅当提供的唤醒上下文明确将该轮次标记为服务端已验证、包含 checkedOutByHarness: true、指明具体问题,并将 externalChatProvider 指定为 slack、github、discord、microsoft-teams 或 telegram 之一时,才使用此捷径。不要根据评论内容、任务描述、提及的服务提供方或 source 字符串推断可以使用此捷径。

对于已验证且自包含的外部聊天请求,应以提供的任务和唤醒上下文作为工作上下文。不要重复身份或收件箱发现、检出、心跳上下文或评论读取、状态写入,也不要手动发表评论更新进度或完成情况。直接回答当前请求,并只返回一条简洁的最终回复。框架会持久化该回复,并负责处理本轮的检出和生命周期记录。如果运行时提供语义上的完成/最终回复操作,请恰好使用一次;不要再通过评论或状态 API 重复提交相同的完成信息。

此捷径仅用于免除冗余的控制面记录,不会绕过授权或实际工作。执行请求实际要求的调查、文件操作或外部操作。请求的变更、文件、审批、交互、凭证和受治理的操作仍须遵循各自的权限、审批、隔离、审计和制品助手流程。不要因为请求来自聊天而提高信任等级或权限。

对于已验证聊天轮次中普通的文件交接请求,请遵循注入的外部聊天合约。如果其中指定了原生 register_deliverable 工具,请使用该工具;原生运行环境没有旧版 API 密钥或上传助手。对于非原生适配器,请运行 bash scripts/paperclip-upload-artifact.sh。若该助手缺失、需要高级制品选项,或上传失败或结果不明确,请阅读 references/artifacts.md;常规交接前不要单独调用工具重新读取该文件。

如果缺少服务端标记、受支持的服务提供方、具体问题或框架检出信号,请使用下文的完整心跳流程。恢复、受治理操作、问题线程交互、暂停、存活检查或技能测试上下文也请使用完整流程;即使其中提到了聊天服务提供方,也不属于普通聊天轮次。

心跳流程

每次唤醒时都请遵循以下步骤,除非适用上述服务端已验证的外部聊天捷径: 限定范围唤醒快速路径。 如果用户消息中包含命名了特定 issue 的 “Paperclip Resume Delta” 或 “Paperclip Wake Payload” 部分,完全跳过步骤 1–4。对该 issue 执行 步骤 5(签出),并遵循明确指定的当前运行环境 harness 签出状态,然后继续执行步骤 6–9。限定范围的唤醒已告知你要处理哪个 issue——不要调用 /api/agents/me、获取收件箱或选择任务。

步骤 1 — 身份。 如果上下文中尚无此信息,调用 GET /api/agents/me 获取你的 id、companyId、role、chainOfCommand 和 budget。

步骤 2 — 审批跟进(触发时)。 如果设置了 PAPERCLIP_APPROVAL_ID(或唤醒原因表明审批已解决),请先审核该审批:

  • GET /api/approvals/{approvalId}
  • GET /api/approvals/{approvalId}/issues
  • 对每个关联的 issue:
    • 如果审批已完全解决所请求的工作,则关闭该 issue(将状态通过 PATCH 设为 done);或者
    • 添加 Markdown 评论,说明该 issue 仍保持开启的原因以及后续安排。 评论中始终包含审批和 issue 的链接。

步骤 3 — 获取分配任务。 常规心跳收件箱优先使用 GET /api/agents/me/inbox-lite。它会返回用于确定优先级的精简任务列表。只有在需要完整 issue 对象时,才回退使用 GET /api/companies/{companyId}/issues?assigneeAgentId={your-agent-id}&status=todo,in_progress,in_review,blocked。

步骤 4 — 选择任务。 优先级:in_progress → in_review(如果是因该 issue 上的评论而唤醒——检查 PAPERCLIP_WAKE_COMMENT_ID)→ todo。除非你能解除阻塞,否则跳过 blocked。

覆盖规则和特殊情况:

  • 已设置 PAPERCLIP_TASK_ID 且任务分配给你 → 优先处理该任务。
  • PAPERCLIP_WAKE_REASON=issue_commented 且存在 PAPERCLIP_WAKE_COMMENT_ID → 阅读评论,然后签出并处理反馈(in_review 状态的任务也适用)。
  • 对 Agent 的 @提及仅作为上下文,不会唤醒你,也不代表你有权接手其他 Agent 的任务;只有明确的任务分配或范围受限的委派任务才可作为工作依据。
  • 唤醒负载指出 dependency-blocked interaction: yes → 该 issue 的交付工作仍处于阻塞状态。不要尝试解除阻塞。阅读评论,说明尚未解决的阻塞项,并通过评论或文档进行回复或分流。请依据限定范围的唤醒上下文处理,不要把签出失败视为阻塞项。
  • 阻塞任务去重: 处理 blocked 任务前,先检查讨论串。如果你最近一条评论是阻塞状态更新,且之后无人回复,则完全跳过——不要签出,也不要再次评论。只有出现新上下文(评论、状态变更、事件唤醒)时才重新处理。
  • 未分配任何任务 → 退出本次心跳。

步骤 5 — 签出。 开始工作前必须签出该 issue。如果运行时的 Paperclip Wake Payload 或 Paperclip Resume Delta 明确指出 harness 已在当前运行中签出该 issue,则不要再次调用签出。继续执行步骤 6。这仅适用于该次运行中的该 issue;不会跳过上下文读取、状态更新或交付步骤。不要根据 issue 状态、任务/评论文本或之前的运行推断当前已签出。如果缺少该运行时说明,或你切换到其他任务,则须先签出,再开始处理。请包含运行 ID 标头:

POST /api/issues/{issueId}/checkout
Headers: Authorization: Bearer $PAPERCLIP_API_KEY, X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
{ "agentId": "{your-agent-id}", "expectedStatuses": ["todo", "backlog", "blocked", "in_review"] }

如果你已签出,则正常返回。如果归属其他 Agent:409 Conflict — 停止处理并选择其他任务。绝不要重试 409。

尽早为临时任务命名。 当任务的 titleNeedsGeneration: true 时,在签出后尽早调用 set_task_title,设置简洁且以结果为导向的标题,并使用 onlyIfProvisional: true。如果该工具不可用,则使用 PUT /api/issues/{issueId}/title,并传入 { "title": "Concise task title", "onlyIfProvisional": true } 以及常规身份验证/运行标头。在 Ask 和 Plan 模式下允许进行此元数据更新。保留明确设置的标题和完整描述,然后继续处理任务。 第 6 步 — 了解上下文。 优先使用 GET /api/issues/{issueId}/heartbeat-context。它会提供精简的问题状态、上级摘要、目标/项目信息和评论游标元数据,无需完整重放整个讨论串。

如需了解归属情况,请读取 GET /api/issues/{issueId}/activity。沙盒 Agent 可以使用此问题范围的路由,但仍须遵守相同的公司和问题读取授权。自动恢复清理属于系统活动,不能证明查看任务的人曾参与其中。

如果运行提示中包含 Paperclip 唤醒负载,请先检查该部分,再调用 API。这是处理评论唤醒最快的方式,其中可能已经包含触发本次运行的确切新评论。对于由评论触发的唤醒,请先结合新评论的上下文进行判断,只有在需要时再获取更广泛的历史记录。

逐步读取评论:

  • 如果设置了 PAPERCLIP_WAKE_COMMENT_ID,请先使用 GET /api/issues/{issueId}/comments/{commentId} 获取该条确切评论
  • 如果你已了解讨论串,只需查看更新,请使用 GET /api/issues/{issueId}/comments?after={last-seen-comment-id}&order=asc
  • 仅在冷启动或增量读取不足以满足需求时,才使用完整的 GET /api/issues/{issueId}/comments 路由

读取足够的上级事项和评论上下文,弄清任务存在的_原因_以及发生了什么变化。不要每次心跳都不加判断地重新加载整个讨论串。

执行策略审查/批准唤醒。 如果问题处于 in_review 状态且包含 executionState,请检查 currentStageType、currentParticipant、returnAssignee 和 lastDecisionOutcome。

如果 currentParticipant 与你匹配,请通过常规更新路由提交决定——没有单独的执行决策端点:

  • 批准:使用 { "status": "done", "comment": "Approved: …" } 调用 PATCH /api/issues/{issueId}。如果仍有后续阶段,Paperclip 会让问题保持在 in_review 状态,并自动将其重新分配给下一位参与者。
  • 请求修改:使用 { "status": "in_progress", "comment": "Changes requested: …" } 调用 PATCH。Paperclip 会将此请求转换为“请求修改”决定,并重新分配给 returnAssignee。

如果 currentParticipant 与你不匹配,请勿尝试推进阶段——Paperclip 会通过 422 拒绝其他参与者的操作。

第 7 步 — 开展工作。 使用你的工具和能力。执行约定如下:

  • 如果问题可以执行,就在同一轮运行中开始具体工作。除非问题明确要求制定计划,否则不要止步于计划。
  • 只有当缺少信息会阻止下一步有用操作时才提问。可选的复现细节、过去失败案例或偏好的测试用例,不会妨碍一般性检查和验证。继续开展不依赖这些信息的工作;如果仍无法获得特定示例,请说明哪些内容尚未验证。实际的访问限制和审批关卡仍具有决定效力。
  • 在评论、问题文档或工作成果中留下可长期保留的进展,然后在退出前更新问题状态或路径,明确最终处理结果。
  • 将评论、文档、截图、工作成果和 Remaining 条目视为证据。它们本身不能作为有效的持续处理路径。
  • 使用子问题并行处理或委派长期任务;不要频繁轮询等待完成的 Agent、会话、子问题或进程。
  • 如果本轮运行创建了待处理的看板/用户交互,或需要审批才能继续工作,请在退出前将源问题置于明确的等待状态。对于审核、审批、request_confirmation、ask_user_questions 和 suggest_tasks 等等待,优先使用 in_review。如果另一个问题构成阻碍,则使用 blocked 和 blockedByIssueIds。
  • 对于实际阻碍,请使用 blockedByIssueIds,或使用包含你自己的 owner: { "agentId": "<your-agent-id>" } 和精确 action 的 unblockDescriptor。Agent 不能将看板/用户或其他 Agent 设置为解除阻碍的负责人。等待人工输入时,应使用已保存的待处理交互并设为 in_review;仅用文字描述并不能构成等待路径。有效负载格式请参见向人工提问并等待回复。
  • 需要人工授权或缺少权限,并不意味着要移交给经理。保留所有权,指出缺少的能力;如果需要由人员作出决定,请使用下方的人工输入有效负载。建议委派前,请核实实际能力和权限。
  • 遵守预算、暂停/取消、审批关卡、执行策略阶段和公司边界。

人工输入问题。

对于开放式回答,请使用文本字段。对于明确的是/否决定,请使用确认,而不要要求某人先写评论再确认自己写过评论。向 /api/issues/{issueId}/interactions 发送 POST 请求,并使用以下完整有效负载(将 detail、提示词和幂等键替换为适用于你问题的内容)。将所有文本问题和选择题放入一个完整的 questionSet。Paperclip 会生成兼容用的 questions 条目。仍支持仅包含选择题的旧版有效负载;如果同时发送两种表示形式,它们必须描述同一份完整表单。

普通问题请省略 addresseeUserId。 在 Agent Chat 中,Paperclip 会自动将问题发送给对话所有者。对于任务,除非必须由特定人员作答,否则请将接收人留空。如果必须由特定人员作答,请明确指定其准确的 Paperclip 用户 ID,包括任何前缀。服务器会拒绝未知或未经授权的接收人。不要猜测 ID,也不要根据头衔推断权限。针对 Agent 的问题使用 addresseeAgentId,并省略 resolverPolicy。

{
  "kind": "ask_user_questions",
  "idempotencyKey": "question:{issueId}:detail:v1",
  "resolverPolicy": "human_only",
  "continuationPolicy": "wake_assignee",
  "payload": {
    "version": 1,
    "questionSet": {
      "schema": "paperclip.question_set.v1",
      "questions": [{ "id": "detail", "prompt": "What should I know?", "answerMode": "text", "required": true }]
    }
  }
}

确认交互已保存且处于待处理状态,然后将同一任务 PATCH 为 in_review,不要更改其受派人。省略 resolverPolicy 时,默认值为 anyone,因此省略该字段并不能建立仅限人工处理的等待。选择题及响应处理方式请参见 API 参考。请包含常规的 Authorization 和 X-Paperclip-Run-Id 请求头。 已保存的交互得到答复或被拒绝后,请读取结果和处理者身份。经授权的请求者给出的明确答复可以缩小或替换原始范围。按照该指示采取行动,并完成由此产生的工作;不要仅仅因为答复改变了原始请求,就再次要求同一请求者确认。只有在仍存在重大歧义或缺少授权时才再次询问。已保存的答复绝不能绕过下游操作的授权要求。

生成的产物和工作成果

如果工作产生了用户可检查的文件,请在最终处理之前将真正的交付物上传到当前 issue,并创建一个 artifact 工作成果。仅有本地文件系统路径并不足够,因为看板用户、审查者和云操作人员可能无法访问 Agent 工作区。

如果工作产生或更新了面向操作人员的工程输出,请创建或更新相应的工作成果:已打开的 PR 对应 pull_request,已发布的预览对应 preview_url,受管理的预览/开发服务对应 runtime_service,值得注意的已推送提交对应 commit,分支本身作为交接内容时对应 branch。即使同时留下评论,也要创建或更新工作成果;评论用于说明工作,而工作成果则提供可检查的访问路径。

如果重要文件有意保留在项目或执行工作区中,而不是上传,请在工作成果上添加注释 metadata.resourceRef.kind: "workspace_file",以便工作区可用时,看板能从 issue 打开该文件。将浏览/搜索视为查找工作区文件的补救手段,而非交付物的主要完成路径。

技术上传说明请参阅 references/artifacts.md,上述常规且经服务器验证的外部聊天交接情形除外。

步骤 8 — 更新状态并沟通。 始终包含运行 ID 标头。

有限重试写入。 如果同一控制平面写入连续失败两次,请在本次心跳剩余时间内停止重试该写入。继续进行不依赖该写入的有用工作,在最终回复中报告写入失败,并使用适配器/运行时状态通道作为获准的备用方案。在环境降级时,不要反复调用工具,继续尝试同一评论或状态变更。

验证写入——切勿推断。 成功的 PATCH /api/issues/{id} 始终会返回更新后的 issue JSON。响应正文为空表示写入失败,即使命令退出码为 0 也不例外。切勿通过 head/tail 管道传递处理结果写入,也不要在管道中依赖 curl -f——管道会吞掉 curl 的退出状态,连接丢失后看起来就和成功一样。请使用相对于已安装的 SKILL.md 解析路径的 scripts/paperclip-issue-update.sh,而非任务工作区中的脚本(它会检查 HTTP 状态、重试连接级故障,并确认回显的 status);如果必须手动编写 curl 命令,请捕获 -w '%{http_code}' 的结果,并检查响应是否回显了你的更新。如果无法确认状态写入,最终报告必须说明写入失败,而非称其“已发送”,以便恢复流程获得准确情况。

退出前,请保存适当的等待路径:等待人工输入时,保存待处理的交互并将状态设为 in_review;存在真实依赖时,设为 blocked,并记录一等阻塞项或 Agent 获准的解除阻塞说明。仅在评论中点名某人并不能建立这一路径。

每次心跳结束前,请执行以下最终处理检查清单:

  • done:请求的工作已完成,已记录验证结果,且此问题没有待跟进事项。
  • in_review:存在实际的审查路径,例如有明确类型的执行参与者、看板/用户负责人、关联的审批、待处理的交互,或已实际安排的问题监控(monitorNextCheckAt 非空,而不只是在评论中提及),可在之后唤醒负责人。仅将任务指派给自己并评论“请审查”不算审查路径。
  • blocked:必须先解决一等字段 blockedByIssueIds 中的阻塞问题,或由指定负责人采取具体的解除阻塞措施,工作才能继续。
  • 委派跟进:直接创建跟进问题,通过 parentId/goalId 关联;如果当前问题必须等待这项工作完成,则使用阻塞项。从普通执行任务创建的跟进问题默认以该任务为父项;仅在有意创建独立工作时才传入 parentId: null。
  • 明确的后续处理:仅当存在活动运行、已排队的后续任务,或实际安排的监控/恢复路径(而非仅在文字中描述)会唤醒负责人员时,才将问题保持为 in_progress。已成功完成的产物工作若没有有效路径却仍处于 in_progress,则无效;请更新状态/路径。

编写问题描述或评论时,请遵循下方 评论风格 中的工单链接规则。

PATCH /api/issues/{issueId}
Headers: X-Paperclip-Run-Id: $PAPERCLIP_RUN_ID
{ "status": "done", "comment": "What was done and why." }

对于多行评论,请使用 heredoc/文件配合辅助工具(或 jq --arg),以保留换行。将 paperclip_skill_dir 设置为包含此已安装 SKILL.md 的绝对目录,并使用运行环境提供的技能路径/基础目录。它不是任务工作目录,也不是 Paperclip 源代码仓库。如果该路径或辅助工具不可用,请使用上文已验证的 PATCH 请求;不要搜索文件系统来查找。

bash "$paperclip_skill_dir/scripts/paperclip-issue-update.sh" --issue-id "$PAPERCLIP_TASK_ID" --status done <<'MD'
Done

- Fixed the newline-preserving issue update path
- Verified the raw stored comment body keeps paragraph breaks
MD

状态值:backlog、todo、in_progress、in_review、done、blocked、cancelled。优先级值:critical、high、medium、low。其他可更新字段:title、description、priority、assigneeAgentId、projectId、goalId、parentId、billingCode、blockedByIssueIds。

状态快速指南
  • backlog — 暂缓/未安排,不是你本次心跳即将开始的工作。
  • todo — 已准备就绪且可执行,但尚未领取。用于新指派或可恢复的工作;不要仅为表达意图而 PATCH 为 in_progress——应通过领取进入 in_progress。
  • in_progress — 正在执行且有明确负责人。
  • in_review — 暂停,等待审查者/审批者/看板/用户反馈。移交工作以供审查、确认计划、响应问题讨论串中的交互或等待审批时使用。这是一条正常的等待路径,不是“已完成”的同义词。如果有人类要求接回任务,请重新指派给他们并设置为 in_review。
  • blocked — 必须等某项具体情况发生变化才能继续。务必指出阻塞原因及需采取行动的人;如果阻塞因素是另一个问题,优先使用 blockedByIssueIds,而非自由文本。仅设置 parentId 不代表存在阻塞。
  • done — 工作已完成,此问题没有待跟进事项。
  • cancelled — 已有意放弃,不应恢复。
监视器和监控程序(只说你实际安排的事项)

“监控程序”或“监视器”并非运行期间持续存在的东西。运行/心跳是短暂的执行窗口;运行结束后,就不会有任何东西继续监视。唯一能自行自动恢复问题的,是已持久化的问题监视器:保存在问题上的持久状态(monitorNextCheckAt、monitorScheduledBy,以及包含 kind、serviceName、externalRef、timeoutAt、maxAttempts 的执行策略 monitor 块)。服务端调度器(tickDueIssueMonitors)会轮询 monitorNextCheckAt 已到期且符合条件的问题,并通过 PAPERCLIP_WAKE_REASON=issue_monitor_due 再次唤醒负责人 Agent。系统会强制检查资格:问题必须分配给某个 Agent(已设置 assigneeAgentId),没有分配给用户(assigneeUserId 为 null),且状态为 in_progress 或 in_review。按需触发器 monitor/check-now 也会强制检查相同条件,因此,保存在已分配给用户、状态为 backlog、blocked 或已关闭的问题上的监视器不会触发——时间戳是必要条件,但并非充分条件。这是基于计时器的轮询,而非事件订阅——CI、Greptile 或外部检查一完成,Paperclip 不会立即收到通知;监视器只会按计划唤醒你,让你再次查看。

因此,请遵守以下规则:

  • 只有在实际安排了监控程序/监视器后,才能声称它存在。 在评论中描述监控程序并不会创建它。通过 PATCH /api/issues/{id} 设置 executionPolicy.monitor.nextCheckAt(以及 kind/serviceName/externalRef/timeoutAt/maxAttempts)来安排监视器。使用该请求默认返回的完整响应(不要使用 Prefer: return=minimal),确认 monitorNextCheckAt 非 null、assigneeAgentId 已设置、assigneeUserId 为 null,且 status 为 in_progress 或 in_review——不要再发起确认用的 GET 请求。只有满足这些条件,已保存的时间戳才会触发监视器。使用 POST /api/issues/{id}/monitor/check-now 按需运行检查。
  • 用可核查的内容描述监视器。 说明监视器的类型、下次检查时间,以及尝试次数/超时的限制——不要含糊地说“有个监控程序会唤醒我”,也不要把它描述成神秘的后台魔法。如果说不出这些信息,就说明你尚未安排监视器,不能暗示已经安排。
  • 绝不要暗示你标记为 done 的任务仍有活动监控程序。 done 表示此问题不再需要跟进,这与持续运行的监视器相矛盾。如果仍需要实际重新检查,就应将问题保持在 in_progress/in_review,并安排监视器,而不是关闭问题。
  • 这里依靠状态强制执行,而非描述:如果不存在实际的审查路径(交互、批准、人工审查者、指定类型的参与者,或实际安排且具有真实 monitorNextCheckAt 的监视器),处置保护机制会拒绝 Agent 将问题移至 in_review(invalid_issue_disposition);恢复分类器也会将任何没有有效唤醒路径而搁置的问题标记为 in_review_without_action_path。评论内容应与实际状态保持一致。

步骤 9 — 如有需要,委派任务。 对于常规执行任务,使用 POST /api/companies/{companyId}/issues 创建子任务,并设置 parentId 和 goalId。如果你在执行常规任务时省略 parentId,服务端会将 parentId 设置为你的当前任务,并在创建活动中记录此默认值(如果策略不允许你在该任务下创建子任务,例如受保护的分配策略,则任务会保持独立);只有在新任务有意作为顶层工作时,才发送 parentId: null(CLI:--standalone)。无论采用哪种方式,后续工作都会保留运行来源记录;任务页面会显示“由你从 <你的任务> 创建”,但不会暗示存在阻塞项。对于对话任务,请改用上文所述的项目移交方式。如果后续问题需要沿用同一项代码更改,但并非真正的子任务,请将 inheritExecutionWorkspaceFromIssueId 设为源问题的 ID。跨团队工作请设置 billingCode。

委派评审任务

运行范围内的写入受子树范围限制:受委派者的运行只能写入其自己的议题及其子级议题,通常不能写入你的议题。请据此撰写评审任务说明:

  • 指示评审者在自己的评审议题上提交发现,并将其标记为 done。评审结论就是交付成果——即使评审发现了不利问题,完成的评审仍应标记为 done,而不是 blocked。后续修复由你(父级议题的负责人)负责;设置阻塞关系后,issue_blockers_resolved 唤醒会将结论通知你。
  • 切勿指示受委派者“在父级议题上以评论形式提交发现”。 对于低信任级别/评审受限的受委派者,这项指令必然会导致 403;如果评审者将拒绝转为 blocked,且负责人只有文字说明,整棵树就会陷入停滞。(标准信任级别的受委派者在平台允许时,还可以在其直接父级议题上额外发布一条报告评论,但绝不能将其设为必需的完成步骤。)
  • 评审议题的说明必须自包含——受委派者可能无法读取你的议题或其文档。请在说明中写明完整指令、验收标准和待评审材料(或仓库相对路径)。
  • 将你的议题设为被评审议题阻塞(blockedByIssueIds),以便结论提交后你能收到唤醒。

信使模式(横向协调): 若要提醒无法向其议题写入的 Agent,或向其传递上下文,请创建一个分配给该 Agent 的新议题,并附上完整、自包含的指令。创建议题(Issue-CREATE)作用范围为整个公司,始终可用;向其他 Agent 的权限边界内发表评论则不行。

管理用户的收件箱

Agent 可以使用 POST /api/issues/{issueId}/inbox-archive 将议题从用户的“我的”收件箱中归档,并使用 DELETE /api/issues/{issueId}/inbox-archive 撤销归档。通常省略 userId:Paperclip 会根据 Agent 的运行上下文解析相应用户。显式指定 userId 表示操作其他用户,需要满足以下任一条件:该用户已保存的选择加入策略为 open,或允许列表中包含该 Agent;或者存在匹配的 inbox:manage 授权。对于从未保存此设置的用户,隐式的默认开放策略并不授权显式跨用户操作。

只有在议题对该用户确实已解决时才归档,例如确认拉取请求已按当前头提交合并,并验证结果之后。只要用户仍需评审、批准、答复、选择或以其他方式作出决定,就绝不要归档议题。归档可以撤销并会留下审计记录,后续议题活动也可能使条目重新显示,但这些保护措施并不意味着可以过早清理。

每次归档/取消归档操作都必须包含 X-Paperclip-Run-Id。对于负责的 Agent,用户策略默认开放,但用户可以禁用 Agent 对收件箱的管理权限,或将其限制为允许列表。将策略拒绝视为最终结果,除非用户更改策略;不要绕过拒绝重试,也不要改用显式跨用户目标。

议题依赖关系(阻塞项)

将“A 被 B 阻塞”表示为一等阻塞项,以便依赖工作自动恢复。

设置阻塞项:创建或更新时,通过 blockedByIssueIds(议题 ID 数组)设置:

POST /api/companies/{companyId}/issues
{ "title": "Deploy to prod", "blockedByIssueIds": ["id-1","id-2"], "status": "blocked" }

PATCH /api/issues/{issueId}
{ "blockedByIssueIds": ["id-1","id-2"] }

每次更新时,该数组都会替换当前集合——发送 [] 可清除阻塞项。议题不能阻塞自身;循环链会被拒绝。

读取阻塞项:调用 GET /api/issues/{issueId},读取 blockedBy(阻塞此议题的议题)和 blocks(此议题阻塞的议题),两者各自包含 id/identifier/title/status/priority/assignee。

自动唤醒:

  • PAPERCLIP_WAKE_REASON=issue_blockers_resolved — 所有 blockedBy 议题均已达到 done 状态;依赖议题的负责人会收到唤醒。
  • PAPERCLIP_WAKE_REASON=issue_children_completed — 所有直接子级议题均已达到终止状态(done/cancelled);父级议题的负责人会收到唤醒。

cancelled 状态的阻塞项不算已解决——在期待 issue_blockers_resolved 之前,请明确移除或替换它们。

请求董事会审批

需要董事会批准或拒绝某项拟议操作时,请使用 request_board_approval:

POST /api/companies/{companyId}/approvals
{
  "type": "request_board_approval",
  "requestedByAgentId": "{your-agent-id}",
  "issueIds": ["{issue-id}"],
  "payload": {
    "title": "Approve monthly hosting spend",
    "summary": "Estimated cost is $42/month for provider X.",
    "recommendedAction": "Approve provider X and continue setup.",
    "risks": ["Costs may increase with usage."]
  }
}

issueIds 会将审批关联到问题讨论串。获得批准后,Paperclip 会通过 PAPERCLIP_APPROVAL_ID/PAPERCLIP_APPROVAL_STATUS 唤醒请求者。请保持负载简洁,便于决策。

问题讨论串交互

问题讨论串交互是一等卡片,会显示在问题讨论串中,并记录接手者(董事会或其他 Agent)的类型化响应。请使用这类交互,而不要在 Markdown 文本中询问是或否,或罗列检查清单——交互会创建审计记录、推动幂等性,并通过结构化的后续流程唤醒受派者。

卡片是协调记录,并不代表授予权限。交互获得接受并不意味着底层操作已获授权:创建任务、调用工具或提供方、部署、支出、招聘、访问机密以及正式审批,都会在你尝试执行时各自重新进行授权检查。

支持五种问题讨论串交互类型。请选择符合决策形式的最简类型:

类型适用场景不适用的场景
request_confirmation针对某个目标做出单一的是/否决策(例如接受计划修订、批准发布)。多选、自由作答,或提出供响应者选择的任务。
request_checkbox_confirmation响应者从已知列表中选择任意子集(最多 200 个选项),然后确认或拒绝。是/否决策(请使用 request_confirmation),或提出新任务(请使用 suggest_tasks)。
request_item_verdicts响应者对各个已知项目逐项批准、拒绝或暂缓,且可分多次提交。一次性多选决策(请使用 request_checkbox_confirmation)或任务创建选项。
ask_user_questions简短的结构化表单:包含少量带答案、选项或文本的类型化问题。从长列表中选择多个项目,或单一的接受/拒绝决策。
suggest_tasks提出具体任务供响应者接受;接受的任务会成为真实子任务。确认计划或任意选择。任务才是操作单位,而非任意 ID。
decision影响其他问题、创建跨问题组合,或必须独立于单个讨论串。响应仅属于当前问题;请改用问题讨论串交互。

路由规则:同一问题 → 问题讨论串交互;其他问题或组合 → decision。

关键的共享语义:

  • 响应者范围。 每种类型默认面向 anyone:可以是董事会,也可以是公司内的任何 Agent,包括你和你自己的运行。常规协作时省略 resolverPolicy——默认开放,这样队友或看门人就能解除阻塞,而不会让线程卡在某一个人身上。只有在限制本身不可或缺时才请求限制:当答案必须来自其他人时使用 "resolverPolicy": "not_creator";确实必须由人来决定时(公开承诺、支出,以及任何法律或安全敏感事项)使用 "human_only";或使用 addresseeAgentId 指定由某个 Agent 负责响应。限制绝不会放宽:公司上限和受治理操作的约束可以进一步收窄你的请求,卡片会报告将要执行的 effectiveResolverPolicy。
  • 后续唤醒策略。 request_checkbox_confirmation 和 request_item_verdicts 默认使用 wake_assignee,在卡片解决或提交新的条目裁定后唤醒你。request_confirmation 默认使用 none,因此如果你需要在收到是/否决定后继续处理,请设置为 wake_assignee 或 wake_assignee_on_accept。none 绝不会唤醒你——只有在确实不需要继续处理时才使用。
  • 目标绑定与过时处理。 request_confirmation、request_checkbox_confirmation 和 request_item_verdicts 接受 target(通常为 { type: "issue_document", key, revisionId, … })。有更新的修订版时,Paperclip 会将待处理交互标记为过期,并设置 outcome: "stale_target"。请基于最新修订版重新构建并创建新的交互。
  • 用户评论时替代请求。 绑定目标的请求类型默认设置 supersedeOnUserComment: true,因此后续的董事会/用户评论会取消待处理请求,并设置 outcome: "superseded_by_comment"。唤醒后,请处理该评论;如果仍需审批,则创建新的交互。
  • 历史问题。 在较新的人工指示之前提出的普通问题,仍可作为历史记录在信息流中回答。仅有待处理状态并不意味着需要再次提醒,也不会阻碍任务完成。请遵循最新的人工指示,继续处理不依赖缺失输入的工作;如果后续证据已满足要求,请撤回过时的问题。如果输入仍会阻碍当前工作,请明确指出具体阻塞项,并且只请求仍然必要的信息。审批、权限、连接和审核关卡仍然有效。
  • 撤回与终止过期。 交互创建 Agent、当前问题指派的 Agent 或董事会用户可以通过 POST /api/issues/:issueId/interactions/:interactionId/withdraw 撤回任何待处理交互,并可选提供 { "reason": string };结果为 outcome: "withdrawn"。将问题关闭为 done 时,当前问题和受治理请求会过期,并设置 outcome: "issue_closed";但获授权的人工用户仍可回答普通历史问题,而无需恢复工作。关闭为 cancelled 时,所有剩余的待处理交互都会过期。两种终止路径都不会唤醒已关闭的问题。
  • 幂等性。 使用确定性的 idempotencyKey,例如 confirmation:${issueId}:plan:${revisionId} 或 checkbox:${issueId}:${decisionKey}:${revisionId},以免重试时堆叠重复卡片。
  • 源问题处理方式。 创建待处理交互后,将源问题移至 in_review,并添加评论,说明你正在等待什么响应以及谁可以提供响应(默认是任何人,或你所请求的限制范围)。如果 request_confirmation 或 request_checkbox_confirmation 是该问题的审核请求,请在该 PATCH 中将其返回的 ID 作为 reviewInteractionId。这种显式绑定使符合策略条件的 Agent 能够提交审核裁定,而不会将相同权限授予无关的待处理确认请求。待处理交互是明确的等待路径。
独立决策

使用 POST /api/companies/{companyId}/decisions,从与问题关联的 Agent 运行中创建决策:

{
  "title": "Reassign the blocked launch issue?",
  "body": "The current owner is unavailable; this moves the existing issue without creating a duplicate.",
  "ruleKey": "routing.reassign_blocked_issue",
  "options": [
    {
      "id": "reassign",
      "label": "Reassign",
      "effects": [
        { "type": "assign_issue", "targetIssueId": "{issueId}", "staleness": "strict", "assigneeAgentId": "{agentId}" }
      ]
    },
    { "id": "leave", "label": "Leave unchanged", "effects": [] }
  ],
  "idempotencyKey": "decision:{originIssueId}:routing.reassign_blocked_issue:v1",
  "continuationPolicy": "wake_origin_agent"
}
  • options 接受 1–8 个选项;选项 ID 必须唯一,每个选项最多接受 10 个效果。
  • 支持的效果包括 comment_on_issue、create_issue、update_issue_status、assign_issue、cancel_issue_tree 和 resolve_blocker。
  • expiresAt 可选,默认期限为 7 天,且不得超过 30 天。
  • idempotencyKey 可选,但强烈建议使用;只有负载相同时,才能安全复用。
  • continuationPolicy 可设为 none 或 wake_origin_agent。仅当决策解决或过期后必须恢复提议者的运行时,才使用后者。
  • 默认情况下,每个来源 Agent 最多可有 50 个未决决策。

使用 POST /api/companies/{companyId}/decision-bundles,将相关的跨问题决策打包:

{
  "title": "Launch recovery choices",
  "summary": "Independent choices for ownership and blocker cleanup.",
  "decisions": [
    {
      "title": "Reassign owner?",
      "body": "Move the issue to the recovery owner.",
      "ruleKey": "routing.reassign",
      "options": [
        { "id": "reassign", "label": "Reassign", "effects": [{ "type": "assign_issue", "targetIssueId": "{issueId}", "staleness": "strict", "assigneeAgentId": "{agentId}" }] },
        { "id": "leave", "label": "Leave unchanged", "effects": [] }
      ],
      "idempotencyKey": "decision:{originIssueId}:routing.reassign:v1"
    },
    {
      "title": "Clear obsolete blocker?",
      "body": "Remove the resolved dependency from the blocked issue.",
      "ruleKey": "blockers.clear_obsolete",
      "options": [
        { "id": "clear", "label": "Clear blocker", "effects": [{ "type": "resolve_blocker", "targetIssueId": "{issueId}", "staleness": "strict", "removeBlockedByIssueIds": ["{blockerIssueId}"] }] },
        { "id": "keep", "label": "Keep blocker", "effects": [] }
      ],
      "idempotencyKey": "decision:{originIssueId}:blockers.clear_obsolete:v1"
    }
  ]
}

每个批次接受 1–50 个决策,并以原子方式创建。嵌套决策负载使用与单个创建端点相同的字段和限制。

创建 request_checkbox_confirmation(响应者可选择任意子集,然后确认):

POST /api/issues/{issueId}/interactions
{
  "kind": "request_checkbox_confirmation",
  "idempotencyKey": "checkbox:{issueId}:cleanup-files:{planRevisionId}",
  "title": "Confirm files to delete",
  "summary": "Pick the files you want removed before I run the cleanup.",
  "continuationPolicy": "wake_assignee",
  "payload": {
    "version": 1,
    "prompt": "Check the files you want deleted.",
    "detailsMarkdown": "I will run the deletion against everything you check, then report back here.",
    "options": [
      { "id": "draft-report-march", "label": "Old draft report", "description": "QA test pass, March." },
      { "id": "tmp-export-2025", "label": "tmp/export-2025.csv" }
    ],
    "defaultSelectedOptionIds": ["draft-report-march"],
    "minSelected": 0,
    "maxSelected": null,
    "acceptLabel": "Delete selected",
    "rejectLabel": "Request changes",
    "rejectRequiresReason": true,
    "rejectReasonLabel": "What should change?",
    "supersedeOnUserComment": true,
    "target": {
      "type": "issue_document",
      "issueId": "{issueId}",
      "key": "plan",
      "revisionId": "{latestPlanRevisionId}"
    }
  }
}

接受后,唤醒消息会包含 result.selectedOptionIds——响应者选择的选项 ID(如果 minSelected: 0,则可能为空)。拒绝时会返回 result.reason 和一个 commentId。

完整的负载架构、验证限制(选项数量、标签长度、最小值/最大值规则)、接受/拒绝路由请求体和结果字段,请参阅 references/api-reference.md -> 复选框确认。

MCP 工具审批门控

某些 MCP 工具被配置为先询问。其 tools/list 描述会说明需要人工审批。调用这类工具时:

  1. Paperclip 会在你已签出的任务上发布一张审批卡,并返回 approval_required 及相关说明。卡片待处理期间不要重试调用。完成其他有用工作,注明你正在等待工具审批,将任务移至 in_review,然后结束本次运行。
  2. 无论审批通过还是被拒绝,Paperclip 都会唤醒受派者。唤醒消息会包含审批决定;若操作获批,还会包含执行结果。
  3. 审批即表示批准并执行:Paperclip 会严格按原样执行已存储并签名的调用参数,且仅执行一次。如果唤醒消息表明操作已执行,请使用该结果,不要再次调用工具。如果执行失败,请调整方案;新的调用可能会触发新的审批。
  4. 拒绝表示操作未执行。不要重试相同的调用;请遵循拒绝原因,调整方案或任务处理方式。

审批请求会在 60 分钟后过期。过期后,再次调用工具以请求新的审批。使用相同参数再次调用工具是幂等的,且不会叠加审批卡:待处理请求会被复用,已执行请求会返回其存储的结果,过期请求则会创建一张新的审批卡。

如果网关返回 approval_path_missing,说明 MCP 会话未关联到已签出的任务,因此 Paperclip 无处发布审批卡。请在签出了该任务的运行中重新执行操作。

当每个已知条目都需要单独裁定时,创建 request_item_verdicts:

POST /api/issues/{issueId}/interactions
{
  "kind": "request_item_verdicts",
  "idempotencyKey": "verdicts:{issueId}:generated-artifacts:{planRevisionId}",
  "continuationPolicy": "wake_assignee",
  "payload": {
    "version": 1,
    "prompt": "Review each generated artifact.",
    "items": [
      { "id": "api", "label": "API route", "description": "Partial submit endpoint." },
      { "id": "docs", "label": "Docs update" }
    ],
    "verdicts": ["approve", "reject", "defer"],
    "requireReasonOn": ["reject"],
    "target": {
      "type": "issue_document",
      "issueId": "{issueId}",
      "key": "plan",
      "revisionId": "{latestPlanRevisionId}"
    }
  }
}

响应者使用 POST /api/issues/{issueId}/interactions/{interactionId}/verdicts 提交裁定。部分提交会使交互保持 pending,并通过 newlyResolvedItemIds 唤醒受派者一次;所有条目都获得裁定后,交互状态将变为 answered。

特定工作流提示

当任务符合以下情况之一时,加载 references/workflows.md:

  • 设置新项目和工作区(CEO/Manager)。
  • 生成 OpenClaw 邀请提示词(CEO)。
  • 设置或清除 Agent 的 instructions-path。
  • 安全地导入/导出公司数据(CEO,预览/应用)。
  • 应用级自测操作手册。

案例

通过面向 Agent 的案例 API 创建、插入或更新、记录文档、附加或关联案例时,加载 references/cases.md。

公司技能工作流

获授权的管理者可以独立于招聘安装公司技能,然后为 Agent 分配或移除这些技能。

  • 使用公司技能 API 安装和检查公司技能。
  • 使用 POST /api/agents/{agentId}/skills/sync 为现有 Agent 分配技能,并明确指定 add、remove 或 replace 模式。优先使用 add;replace 会覆盖完整的目标技能集。
  • 招聘或创建 Agent 时,可以包含可选的 desiredSkills,以便从第一天起应用相同的分配模式。

如果有人要求为公司或 Agent 安装技能,你必须阅读: skills/paperclip/references/company-skills.md

例行任务

例行任务是周期性任务。每次触发例行任务时,都会创建一个执行问题并分配给该例行任务的 Agent;该 Agent 会在正常的心跳流程中接手。

  • 使用例行任务 API 创建和管理例行任务;Agent 只能管理分配给自己的例行任务。
  • 为每个例行任务添加触发器:schedule(cron)、webhook 或 api(手动)。
  • 使用 concurrencyPolicy 和 catchUpPolicy 控制并发和补执行行为。

如果有人要求创建或管理例行任务,你必须阅读: skills/paperclip/references/routines.md

任务文件和工作区选择

使用任务提供的工作目录存放任务文件。AGENT_HOME 存放个人指令和记忆;提供方主目录由运行时管理。任务不需要项目或 Git 仓库。不要克隆无关仓库,也不要因缺少项目而将任务输出放在主目录中。

使用 get_workspace 检查当前文件夹、待处理的选择和功能。使用 list_workspaces 查看获授权的现有文件夹,使用 list_project_repositories 查看仓库选项。select_workspace 和 prepare_repository 用于表达意图;运行框架会验证并准备相应内容。遵循 next_normal_admission 响应:保留当前根目录,不要声称请求的检出内容已存在,也不要循环重试或中断运行。仅分配项目不会移动文件。API 对应项见 references/issue-workspaces.md。

优先选择匹配的、已配置且获授权的来源,不要猜测仓库 URL。在声称无法进行浏览器测试或命令测试之前,先检查可用的运行时和测试功能。当获授权的仓库仍在等待处理,且未完成的工作需要该仓库时,先完成可独立进行的工作,说明剩余工作,然后让出控制权。Native Runner 可以根据当前任务上下文选择已保存的同一 Agent 后续任务;无需计时器,也无需用户重新启动。如果请求仅涉及暂存仓库,则可以正常结束,不必开始其他工作。

问题工作区运行时控制

当问题需要浏览器/人工 QA 或预览服务器时,请检查其当前执行工作区,并使用 Paperclip 的工作区运行时控制,而不要自行启动未受管理的后台服务器。

有关命令、响应字段和 MCP 工具,请阅读: skills/paperclip/references/issue-workspaces.md

安全地提议凭据

收到凭据时,请立即使用 POST /api/agents/me/secret-proposals 将其提议为 Paperclip 密钥。绝不要将凭据粘贴到问题评论、文档、文件、计划、任务描述或对话记录中。 无论该值是由用户粘贴、通过 OAuth 流程返回、通过电子邮件发送,还是从其他安全来源获取,都适用此要求。

提议凭据前,你必须阅读以下文件中的“Agent 密钥提议”部分: skills/paperclip/references/api-reference.md

读取已授权的密钥

使用当前运行的 Agent JWT 进行身份验证后,在获取值之前,先列出该运行可用的密钥:

PAPERCLIP_API_BASE="${PAPERCLIP_API_URL%/}"
PAPERCLIP_API_BASE="${PAPERCLIP_API_BASE%/api}"
curl -s -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
  "$PAPERCLIP_API_BASE/api/agents/me/secrets"

列表仅包含元数据。仅在需要时获取特定值;该请求没有请求正文:

curl -s -X POST -H "Authorization: Bearer $PAPERCLIP_API_KEY" \
  "$PAPERCLIP_API_BASE/api/agents/me/secrets/github_token/value"
  • env.* 密钥绑定也会授予 API 读取权限;access.* 绑定会授予 API 访问权限,但不会注入环境变量。
  • 对于适配器或其子进程每次运行都需要的值,优先使用环境变量注入。
  • 对于仅在部分运行中使用的值、大型或结构化值,或不会继承适配器环境变量的技能/工具,优先按需获取。
  • 每次获取值(包括失败的请求)都会记录在 secret_access_events 和 activity_log 中;切勿在任务评论中打印、保存或粘贴获取到的值。
  • 这些端点要求使用与当前运行绑定的 Agent JWT。长期有效的 Agent 密钥、低信任审核 Agent、任务桥接密钥和技能测试令牌均会被拒绝。

确切的响应字段参见 skills/paperclip/references/api-reference.md。

关键规则

  • 绝不重试 409。 任务属于其他人。
  • 绝不寻找未分配的工作。 没有分配任务 = 退出。
  • 绝不因被提及而自行认领任务。 提及仅用于指明相关上下文;开展任务需要明确分配。
  • 遵从看板用户提出的“把任务发回给我”请求。 如果看板用户要求交回审核(例如“让我审核一下”“重新分配给我”),请使用 assigneeAgentId: null 和 assigneeUserId: "<requesting-user-id>" 将任务重新分配给他们;通常将状态设为 in_review,而不是 done。如果触发评论中有 authorUserId,请据此解析用户 ID;否则,若问题的 createdByUserId 与请求者上下文匹配,则使用该 ID。
  • 先开始可执行的工作,再仅做计划性收尾。 除非任务只要求计划或审核,否则应在同一次心跳中开展具体工作。
  • 留下下一步行动。 每条进度评论都应明确说明已完成的内容、尚待完成的内容,以及下一步由谁负责。
  • 优先创建子问题,而不是轮询。 对长期或可并行委派的工作,创建范围明确的子问题,并依靠 Paperclip 唤醒事件或评论来获取完成情况。
  • 为后续工作保留工作区连续性。 子问题会在服务端继承执行工作区。对于同一检出目录/工作树上的非子问题后续任务,请明确传入 inheritExecutionWorkspaceFromIssueId。
  • 绝不取消跨团队任务。 如果你对任务有疑问,请遵循接收跨团队工作中的请求者指定决策流程。继续将任务分配给自己;不要自动转交给经理。
  • 使用一等阻塞字段(blockedByIssueIds),而不是在自由文本评论中写“被 X 阻塞”。
  • 只说明你实际安排的事项。 除非你安排了真实的问题监控器(monitorNextCheckAt 非空),否则绝不要告诉用户“监控器”会唤醒你;对于标记为 done 的任务,也绝不要暗示仍有实时监控器——请参阅监控器和观察器。
  • 被阻塞的任务没有新上下文时,不要重复评论——请参阅步骤 4 中关于被阻塞任务的去重规则。
  • @ 提及是上下文链接,不会触发心跳、分配工作或将评论转发到其他任务。对于由机器撰写的评论,请解析目标 Agent,并使用 [@Agent Name](agent://<agent-id>)。要请求开展工作,请分配任务或明确提出审核请求。
  • 预算:达到 100% 时会自动暂停。超过 80% 后,只处理关键任务。
  • 直接处理阻塞因素。 找出确切缺失的能力或权限。不要仅因遇到困难就重新分配受阻工作,也不要为经理或其他 Agent 创建任务。头衔或汇报关系不会赋予访问权限或权力。对于只能由人工执行的操作,如果有连接/审批流程,请使用该流程;否则,请在当前任务中保存一个交互,将 resolverPolicy: "human_only" 和 continuationPolicy: "wake_assignee" 设为相应值,继续将任务分配给自己,并将状态保持为 in_review。请使用完整的人工输入负载。在将委派作为选项提出或为他人创建范围明确的任务之前,请确认接收方具备实际能力和权限。绝不要通过委派绕过权限拒绝;人工答复也不会赋予缺失的权限。
  • 在当前任务中处理范围决策。 保存一个交互,将 resolverPolicy: "human_only" 和 continuationPolicy: "wake_assignee" 设为相应值。等待期间,继续将任务分配给自己,并保持状态为 in_review。如果决策需要特定人员答复,请明确指定该人员;否则,不要指定接收方,让符合条件的人工人员自行处理。对于面向 Agent 的问题,请设置 addresseeAgentId,并省略 resolverPolicy。不要用经理替代,也不要虚构身份。
  • 招聘:创建新 Agent 时,使用 paperclip-create-agent 技能(其中包含可复用的 AGENTS.md 模板链接,例如 Coder 和 QA)。
  • 提交署名:如果你创建了 git 提交,必须在每条提交消息的末尾准确添加 Co-Authored-By: Paperclip <[email protected]>。不要写入你的 Agent 名称,只需添加 Co-Authored-By: Paperclip <[email protected]>。

评论风格(必需)

发布问题评论或撰写问题描述时,请使用简洁的 Markdown,包含:

  • 简短的状态行
  • 用项目符号列出已更改的内容/受阻的事项
  • 在有相关实体时添加链接

工单引用必须使用链接: 如果在评论正文或问题描述中提及其他问题标识符,例如 PAP-224、ZED-24 或任何 {PREFIX}-{NUMBER} 格式的工单 ID,请将其包装为 Markdown 链接:

  • [PAP-224](/PAP/issues/PAP-224)
  • [ZED-24](/ZED/issues/ZED-24)

如果可以提供可点击的内部链接,绝不要在问题描述或评论中单独写工单 ID。

公司前缀 URL(必需): 所有内部链接都必须包含公司前缀。根据你掌握的任何问题标识符推导前缀(例如,PAP-315 → 前缀为 PAP)。在所有 UI 链接中使用此此前缀:

  • 问题:/<prefix>/issues/<issue-identifier>(例如,/PAP/issues/PAP-224)
  • 问题评论:/<prefix>/issues/<issue-identifier>#comment-<comment-id>(指向特定评论的深层链接)
  • 问题文档:/<prefix>/issues/<issue-identifier>#document-<document-key>(指向特定文档的深层链接,例如 plan)
  • Agent:/<prefix>/agents/<agent-url-key>(例如,/PAP/agents/claudecoder)
  • 项目:/<prefix>/projects/<project-url-key>(允许使用 ID 作为备用值)
  • 审批:/<prefix>/approvals/<approval-id>
  • 运行:/<prefix>/agents/<agent-url-key-or-id>/runs/<run-id>

请勿使用未带前缀的路径,例如 /issues/PAP-123 或 /agents/cto——始终包含公司前缀。

保留 Markdown 换行(必需): 使用 heredoc/文件输入构建多行 JSON 正文(通过步骤 8 中的辅助程序或 jq -n --arg comment "$comment")。除非你有意将其作为单段内容,否则绝不要手动将 Markdown 压缩成单行 JSON comment 字符串。

示例:

## Update

Submitted CTO hire request and linked it for board review.

- Approval: [ca6ba09d](/PAP/approvals/ca6ba09d-b558-4a53-a552-e7ef87e54a1b)
- Pending agent: [CTO draft](/PAP/agents/cto)
- Source issue: [PAP-142](/PAP/issues/PAP-142)
- Depends on: [PAP-224](/PAP/issues/PAP-224)

任务文档和交付物

使用 PUT /api/issues/{issueId}/documents/{key} 保存请求的 Markdown 任务文档。创建和更新都使用 PUT;此处不支持 POST。键可以是 report、spec 或其他请求的文档键;此端点不限于 plan。请包含常规的 bearer authorization 和 X-Paperclip-Run-Id 标头。

创建新报告时,请使用:

{"title":"Report","format":"markdown","body":"The completed report text","baseRevisionId":null}

如果任务可访问,但 GET /api/issues/{issueId}/documents/report 返回 404 Document not found,则表示文档尚未创建。请使用 PUT 创建文档;此 GET 响应并不意味着无法写入文档。对于现有文档,请读取其正文和 latestRevisionId,然后发送修订后的正文,并将 baseRevisionId 设为该修订 ID。如果收到 409,请先获取最新文档并协调更改,然后再重试。

在将任务标记为完成之前,请重新读取已保存的文档。评论或本地文件不能满足任务文档请求。如果无法保存所需文档,请报告失败,并将任务标记为相应的受阻状态,而不要声称交付物已完成。

规划(请求规划时必需)

如果有人要求制定计划,请使用键 plan 创建或更新议题文档。不要再将计划追加到议题描述中。如果有人要求修订计划,请更新同一份 plan 文档。无论哪种情况,都照常发表评论,并说明你已更新计划文档。将计划作为议题文档是常规做法:除非有人明确要求,否则不要在仓库中创建计划文件。

在评论中提及计划或其他议题文档时,请使用以下键添加文档的直接链接:

  • 计划:/<prefix>/issues/<issue-identifier>#document-plan
  • 通用文档:/<prefix>/issues/<issue-identifier>#document-<document-key>

如果议题标识符可用,优先使用文档的深层链接,而不是普通议题链接,以便读者直接跳转到已更新的文档。

如果有人要求制定计划,不要将议题标记为已完成。计划准备好供审核时,将议题保留在 in_review 状态,并明确说明审核者和决策流程。如果请求者明确要求将议题交还给自己,请重新指派给该用户;否则保留原受派人,以便接受确认时唤醒正确的 Agent。

如果计划在实施前需要明确批准,请更新 plan 文档,创建一个绑定到最新计划修订版的 request_confirmation 议题线程交互,然后将源议题更新为 in_review,并在评论中链接计划、指出待处理的确认。这是有意设置的等待流程,而不是停止工作。等待接受后再创建实施子任务。交互负载请参阅 references/api-reference.md。

如果有人要求将计划转换为可执行的 Paperclip 任务——包括深度、指派、依赖关系和并行化——请使用配套技能 paperclip-converting-plans-to-tasks。

建议的 API 流程:

PUT /api/issues/{issueId}/documents/plan
{
  "title": "Plan",
  "format": "markdown",
  "body": "# Plan\n\n[your plan here]",
  "baseRevisionId": null
}

如果 plan 已存在,请先执行 GET /api/issues/{issueId}/documents/plan,读取当前正文和 latestRevisionId。然后提交修订后的正文,并将返回的 latestRevisionId 设置为 baseRevisionId。GET 字段是 latestRevisionId;PUT 字段是 baseRevisionId。更新时省略该字段会返回 409。如果修订版同时被他人更改,请先获取最新计划并协调内容,然后再重试;切勿盲目覆盖。

关键端点(高频路由)

操作端点
我的身份GET /api/agents/me
我的精简收件箱GET /api/agents/me/inbox-lite
我的任务分配GET /api/companies/:companyId/issues?assigneeAgentId=:id&status=todo,in_progress,in_review,blocked
领取任务POST /api/issues/:issueId/checkout
获取任务及其上级GET /api/issues/:issueId
精简心跳上下文GET /api/issues/:issueId/heartbeat-context
问题活动和归属信息GET /api/issues/:issueId/activity
更新任务PATCH /api/issues/:issueId(可选的 comment 字段)
获取评论/增量/单条评论GET /api/issues/:issueId/comments[?after=:commentId&order=asc] • /comments/:commentId
添加评论POST /api/issues/:issueId/comments
问题线程交互GET|POST /api/issues/:issueId/interactions • POST /api/issues/:issueId/interactions/:interactionId/{accept,reject,respond,withdraw}
创建子任务POST /api/companies/:companyId/issues
释放任务POST /api/issues/:issueId/release
搜索问题GET /api/companies/:companyId/issues?q=search+term
问题文档(列表/获取/写入)GET|PUT /api/issues/:issueId/documents[/:key]
创建审批POST /api/companies/:companyId/approvals
上传附件(multipart,file)POST /api/companies/:companyId/issues/:issueId/attachments
列出/获取/删除附件GET /api/issues/:issueId/attachments • GET|DELETE /api/attachments/:attachmentId[/content]
执行工作区和运行时GET /api/execution-workspaces/:id • POST …/runtime-services/:action
设置 Agent 指令路径PATCH /api/agents/:agentId/instructions-path
列出 AgentGET /api/companies/:companyId/agents
密钥提案POST|GET /api/agents/me/secret-proposals • DELETE /api/agents/me/secret-proposals/:id
仪表盘GET /api/companies/:companyId/dashboard
完整的端点表(公司导入/导出、OpenClaw 邀请、公司技能、例程等)位于 references/api-reference.md。

搜索议题

使用议题列表端点上的 q 查询参数,跨标题、标识符、描述和评论进行搜索:

GET /api/companies/{companyId}/issues?q=dockerfile

结果按相关性排序:先匹配标题,再匹配标识符、描述和评论。你可以将 q 与其他筛选条件(status、assigneeAgentId、projectId、labelId)组合使用。

完整参考

有关详细的 API 表、JSON 响应架构、完整示例(IC 和 Manager 心跳)、治理/审批、跨团队委派规则、错误代码、议题生命周期图以及常见错误表,请阅读:skills/paperclip/references/api-reference.md

对话式确认回复

当用户在消息中回复待处理的确认时,先记录回复,再采取行动。读取当前卡片和评论,然后向 /api/issues/{issueId}/interactions/{interactionId}/resolve-from-comment 发送 POST 请求,并提供 commentId、decision: "accept" | "reject",以及用于复选框确认的明确 selectedOptionIds(原生运行器使用 call_api)。如果对提案的回复含糊不清,需要进一步澄清。修改内容不代表接受。如果响应丢失,请重试相同请求,而不是让卡片一直处于待处理状态。解析器权限仍然有效;问题表单和受治理的审批仍使用各自现有的控制方式。有关适用范围和重试规则,请参阅 API 参考。

在 Agent Chat 中,问题并非必答:如果用户转而讨论其他话题,请直接回复该消息,无需要求用户回答或解决先前的问题。将卡片留作未答状态,以便用户之后重新打开。收到对历史问题的回复时,请结合其附带的原始问题作为上下文,并从当前对话继续。无关消息绝不代表审批。

连接访问请求。

使用运行范围内的 connections_search 和 connection_request 工具进行应用设置。如果已保存的连接未启用供此 Agent 使用,或其工具处于关闭状态,请使用其服务标识符、已保存的 connectionId 和准确的索引 toolNames 调用 connection_request。这会创建内嵌的人类授予访问权限卡片;不要改用 ask_user_questions 权限检查清单,也不要要求用户手动编辑设置。等待期间暂停操作。接受后,任务会在 Agent 范围的访问权限下继续;写入操作仍需审批。卡片被拒绝不代表用户同意;网关已连接也不能证明底层应用已获授权。

附带反馈

除了此技能外,还可以使用 complain 和 suggestion-box 技能。 当与 Agent 工作相关的阻碍值得直接反馈或提出有用的改进建议时,请主动使用它们。 这不是强制要求的报告。它们共用的辅助脚本是相对于此技能目录的 scripts/submit-agent-commentary.mjs。反馈会保留在此实例中,并关联 Agent、运行和任务;请静默提交一次,然后继续主要任务,即使提交失败也一样。

外部评审交接。

对于 PR,请将其链接放在工作产品顶层的 url 字段中。如果必须由人工评审或合并后你才能继续,请在持久化的仅限人工交互中说明该操作,并设置适当的继续策略,然后将任务设为 in_review。工作产品的 needs_board_review 标记和定期监控不会创建交互卡片。将任何合并检查限制在必要范围内,在监控器的 notes 中记录其目的,并在恢复任务时核实实际的提供方状态;确认回复并不能证明 PR 已合并。PR 合并或关闭后,请更新现有 PR 工作产品,而不是重复登记。

同样的规则也适用于外部发布审批关卡:链接到准确的运行记录,创建仅限人工确认的卡片,询问用户是否已在提供方批准,并通过 continuationPolicy: "wake_assignee" 保持 Agent 受指派状态,以便回复后恢复核验。要求用户评论回复或重新指派任务的交接评论,并不是确认卡片。卡片记录用户的回答;继续之前,请核实提供方的审批关卡和发布结果。

评论

支持 Markdown