port-github-app-to-origin

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Port a GitHub App to an Origin App

将 GitHub App 移植到 Origin App

Run this inside the app's codebase. The output is a porting brief for the team plus a Feedback for Cursor section they can send as is (
references/brief.md
). This skill plans. It does not write or change code unless the user asks for that after reading the brief. Follow the
origin-api
skill for the docs and the rules to check first. Two more rules:
  1. Find it in the code, do not ask. Read what the app uses out of its source. Anything you cannot find becomes a question for the team.
  2. Feedback describes use cases, not the team's code. The team's parts of the brief may cite
    file:line
    . Feedback for Cursor says only what the app needs to do and what Origin lacks for it, in Origin terms, with no file paths, module names, framework details, or repository names.
在 App 的代码库中运行本 skill。输出内容包括供团队使用的移植简报,以及一份他们可以直接原样发送的“Cursor 反馈”章节(
references/brief.md
)。本 skill 仅用于规划。除非用户在阅读简报后提出要求,否则不会编写或修改代码。请先遵循
origin-api
skill 查阅文档并执行检查规则。另有两条规则:
  1. 在代码中查找,不要询问。 从源代码中读取 App 使用的功能。任何无法找到的内容都应转化为向团队提出的问题。
  2. 反馈描述使用场景,而不是团队的代码。 简报中面向团队的部分可以引用
    file:line
    。“Cursor 反馈”只应使用 Origin 术语说明 App 需要执行什么操作,以及 Origin 缺少哪些能力;不得包含文件路径、模块名称、框架细节或仓库名称。

What to find

需要查找的内容

Record
file:line
for each item, and note what you looked for but did not find.
  • Declared permissions and events, from a manifest or infrastructure code if one is checked in. Otherwise derive them from the calls.
  • Every webhook event the app handles, and every payload field each handler reads, including fields it only logs.
  • Every REST and GraphQL call, with the parameters and filters the code passes, the response fields it reads, whether it runs on every webhook or in a loop, and how it paginates.
  • Authentication: the JWT algorithm, how the app learns the installation ID after install, how it handles token expiry, any user sign-in and what it is for, and whether the app clones or pushes git.
  • The webhook receiver: how it verifies signatures, whether it has the raw body when it verifies, and how it deduplicates deliveries.
  • Calls a framework or library makes for the app. Probot's receiver, token cache, and config loader; Octokit
    App
    's installation and repository listing; app-auth libraries. Read the dependency's docs and list these calls marked "from
    <dependency>
    ".
对于每一项,记录
file:line
,并注明查找过但未找到的内容。
  • 已声明的 permissions 和 events:如果代码库中已提交 manifest 或基础设施代码,则从中获取;否则根据调用推导。
  • App 处理的每个 webhook event,以及每个 handler 读取的每个 payload 字段,包括仅用于记录的字段。
  • 每个 REST 和 GraphQL 调用,包括代码传入的 parameters 和 filters、读取的 response 字段、调用是在每个 webhook 上执行还是在 loop 中执行,以及采用何种分页方式。
  • Authentication:JWT algorithm、App 在安装后如何获知 installation ID、如何处理 token 过期、是否存在 user sign-in 及其用途,以及 App 是否会 clone 或 push git。
  • Webhook receiver:如何验证 signatures、验证时是否拥有 raw body,以及如何对 deliveries 去重。
  • Framework 或 library 代表 App 发出的调用,例如 Probot 的 receiver、token cache 和 config loader,以及 Octokit
    App
    的 installation 和 repository listing,还包括 app-auth libraries。阅读相关 dependency 的文档,并将这些调用标记为“from
    <dependency>
    ”。

How to map

映射方式

A brief needs the whole spec, but
openapi.yaml
and
llms-full.txt
are each several hundred kilobytes, too large to read into context whole. Save them locally if you can, in a temporary location outside the app's repository so nothing in the working tree is overwritten or left behind, then search them and read only the matching part:
  • x-origin-scopes:
    in
    openapi.yaml
    marks every operation with its scopes; the
    operationId
    sits a line above.
  • x-origin-webhook-events:
    in
    openapi.yaml
    marks every webhook payload schema with the event slugs that deliver it.
  • ### <Endpoint name>
    and
    ### <Payload type>
    headings in
    llms-full.txt
    start the section that spells out that endpoint's or payload's fields as dotted paths; read from the heading to the next
    ###
    .
For a single question later, start at
llms.txt
and fetch just that section.
  • A matching name is a candidate, not an answer. Read the operation's description, parameters, and response fields against what the code passes and reads. If a parameter or field the code depends on is missing, that is a workaround or a gap, not a match.
  • GitHub's pull request calls that live under
    /issues/{n}/…
    (comments, labels) live under the pull request endpoints on Origin. If the code uses them on real issues, see "Where GitHub features live on Origin" in
    references/brief.md
    .
  • Origin has no GraphQL. Break each query into REST calls and record the fan-out.
  • The scopes to request are the union of
    x-origin-scopes.scopes
    over the operations you named. Do not translate the GitHub manifest.
  • Each GitHub event and action pair maps to at most one slug in "Events". The action is part of the slug. A pair with no slug is not an event on Origin.
  • For each payload field the code reads, record whether it is in the payload, in the delivery envelope around the payload (
    event.type
    carries the action), needs an extra read (say which operation and how many calls per event), can be computed from other fields, or is missing. Payloads are snapshots. A field the REST resource has but the payload lacks needs an extra read.
  • A capability the docs never mention is not available today. Ask the team about it. A behavior the docs neither confirm nor deny gets a question plus a step in the end-to-end test that checks it. Do not assume it works the way it did on GitHub.
简报需要涵盖完整规范,但
openapi.yaml
和
llms-full.txt
各有数百 KB,大到无法一次性完整读入上下文。如果可以,请将它们保存在 App 代码库之外的临时位置,确保不覆盖 working tree 中的任何内容,也不留下多余文件;然后搜索这些文件,只读取匹配的部分:
  • openapi.yaml
    中的
    x-origin-scopes:
    标记每个 operation 及其 scopes;
    operationId
    位于其上方一行。
  • openapi.yaml
    中的
    x-origin-webhook-events:
    标记每个 webhook payload schema 及其用于投递该 payload 的 event slugs。
  • llms-full.txt
    中的
    ### <Endpoint name>
    和
    ### <Payload type>
    标题会开启相应章节,其中以 dotted paths 列出该 endpoint 或 payload 的字段;从标题读取到下一个
    ###
    为止。
对于后续的单个问题,从
llms.txt
开始,只获取对应 section。
  • 名称匹配只表示候选,并不代表最终匹配。对照代码传入和读取的内容,检查 operation 的 description、parameters 和 response fields。如果代码依赖的 parameter 或 field 缺失,则应记录为 workaround 或 gap,而不是匹配项。
  • GitHub 中位于
    /issues/{n}/…
    下的 pull request 调用(comments、labels),在 Origin 上位于 pull request endpoints 下。如果代码将这些调用用于真正的 issues,请参阅
    references/brief.md
    中的“GitHub 功能在 Origin 中的位置”。
  • Origin 没有 GraphQL。将每个 query 拆分为 REST calls,并记录 fan-out。
  • 要申请的 scopes 是你指定的各 operations 的
    x-origin-scopes.scopes
    的并集。不要翻译 GitHub manifest。
  • 每个 GitHub event 和 action 的组合最多映射到“Events”中的一个 slug。action 是 slug 的一部分。没有对应 slug 的组合在 Origin 上不是 event。
  • 对于代码读取的每个 payload 字段,记录它位于 payload 中、位于 payload 周围的 delivery envelope 中(
    event.type
    携带 action)、需要额外读取(说明是哪个 operation,以及每个 event 需要多少次调用)、可由其他字段计算得到,还是缺失。Payloads 是 snapshots。如果 REST resource 拥有某字段而 payload 中没有,则需要额外读取。
  • 文档从未提及的 capability 目前不可用,应向团队询问。对于文档既未确认也未否认的行为,应提出问题,并在 end-to-end test 中添加相应的检查步骤。不要假设它的行为与 GitHub 相同。

Before finishing

完成之前

Every claim about Origin points at something in the saved docs. Every gap has a feedback entry that names its cost. The feedback reveals nothing about the team's internals. The summary names the native-or-mirror question.
关于 Origin 的每项论断都应指向已保存文档中的具体内容。每个 gap 都应有一条反馈条目,并说明其成本。反馈不得泄露团队实现的任何内部信息。Summary 应明确提出“native-or-mirror”问题。