用途
external-repo-intake 用于处理把外部 GitHub 仓库内容首次引入本 marketplace 的工作流。当用户提出「import」「pull」「vendor」「cherry-pick」或「borrow from」某个尚未登记在 upstream-sync 技能 sync 表中的外部仓库时,应在改动任何本地文件之前先走此流程,它覆盖的是首次引入;对已登记仓库的重新同步由 upstream-sync 技能负责。
引入模式为 vendoring:把上游内容一次性或可追踪地复制进「中性内核」,保留归属并适配本地约定。它不创建 fork 或 submodule。运行时依赖保持为显式的 plugin.toml 声明:对另一个本地插件的运行时引用需要在 [dependencies].required 中声明该插件;禁止本地可选依赖,也禁止为缺失的必需插件提供通用回退。
本地源码位于 plugins/<name>/ 下,包括 plugin.toml、roles/、带 TOML sidecar 的 workflows/、skills/、contracts/ 和 policies/。host 绑定位于 adapters/。exports/ 下的原生包副本与根目录 catalog 为生成产物。
子模式
- Full vendoring:上游是一个完整可替换单元(例如单个 SKILL.md、一小组 references)且本地无等价物。示例:kotlin-development。
- Cherry-pick vendoring:上游文件很多但只有一部分有价值,或上游命令与现有命名空间冲突。示例:wshobson/agents(导入 3 个 codebase-cleanup 命令,为避重叠跳过 2 个 agent;该 vendor 后来在 marketplace 19.0.0 中退役)。
- Hybrid merge:上游覆盖范围与本地文件重叠时,把上游内容作为带分隔的章节追加,而不是创建重复文件。示例:wshobson/agents 的 e2e-testing-patterns references/details.md 内联保留在本地 SKILL.md 章节中(该 vendor 后来在 marketplace 18.0.0 中交还上游)。
- Inspiration only:只采用模式或工作流思路,从零自写内容,不复制上游文本。示例:来自 gsd-build/get-shit-done 的 codebase-xray。
组合使用是正常的。
四项决策维度
在写任何文件之前,应从任务授权与既有决策中解决以下维度;仅在仍有实质选择未决时通过 host 的提问机制询问,不要为新 owner 重复请求同一批准。
- Selection:整仓库还是 cherry-pick?上游庞大、存在冲突或带有未使用基础设施时选 cherry-pick。
- Merge:独立新文件还是合并进现有本地文件?存在重叠时合并;孤立主题用独立文件。
- Sync strategy:一次性快照还是持续同步?上游变化慢或不希望有变动噪声时用快照;上游活跃维护且与方向一致时用持续同步。
- Tracking:登记进 upstream-synced 表还是保持未追踪?仅当选择「持续同步」才登记;快照也可为便于重新导入而登记。
许可证合规门槛
抓取前阻断,先读取上游 LICENSE 文件,四种预期结果:
- MIT / BSD / ISC / Apache-2.0:继续;在每个派生文件中保留归属头部。
- MPL-2.0:仅文档内容可继续;导入源代码前需向用户提示。
- GPL-2.0 / GPL-3.0 / AGPL:STOP。显式询问用户;本 marketplace 为 MIT,不兼容许可证必须成为有意识的决定。
- 无许可证 / 专有:STOP,不要导入。
对 Apache-2.0 需专门检查上游是否有 NOTICE 文件;若有,需将其内容与派生文件一并保留。
每个派生文件(新文件或合并章节)的归属头部格式:
<!--
Portions of this file are derived from <owner>/<repo>
(https://github.com/<owner>/<repo>), <SPDX-license> License.
Snapshot YYYY-MM-DD.
-->
抓取与检查(只读)
使用 gh api repos/<owner>/<repo>/contents/<path> 配合 --jq '.content' | base64 -d。把所有内容保存到 .upstream-scratch/<repo>/(从提交中排除)。在写本地文件之前先读完每个抓取的文件。提出合并计划前先统计并评估体量。
适配本地约定
保存任何派生文件前,扫描并改写:
- 破折号插入语构造("X — Y — Z" / "X -- Y -- Z" / "X - Y - Z" 包裹子句):改为句子、括号或冒号。绝不用一种破折号形式替换另一种。
- Emoji:若目标插件现有文件没有 emoji,则移除。
- 上游特有的交叉引用:把 reference/foo.md 风格链接改写为指向本地目标路径(目标未导入则移除)。改写 {{template_vars}} 及仅上游命令的引用。
- 命名空间前缀:把上游 <their-plugin>:X 技能引用改写为本地等价的 <our-plugin>:X,若无对应 vendor 则删除。
- 团队相关导入中的 host 工具原语:用中性 Markdown 与 workflow sidecar 表达隔离调度、文件归属、交付状态、屏障与报告归属。host adapter 提供其原生机制。不要在内核中把上游 Claude 工具名替换为另一个原生工具名;运行 host-vocabulary linter。
接线到现有 roles 与 workflows
导入无人读取的内容是浪费。保存派生文件后:
- 运行时引用与 helper 放在 skills/<skill>/ 下,并在该技能的 SKILL.md 中以一行主题描述建立索引。内核根目录的 references、scripts 与 MCP 目录不随发布。
- 更新会查阅该材料的 roles 或 workflows。自有插件路径使用 ${CLAUDE_PLUGIN_ROOT}/skills/<skill>/... 或 skill 相对路径 references/...。跨插件消费方加载 owner 的具名技能,并声明其必需依赖;绝不通过路径伸手进另一个插件的文件。当被加载的方法需要时,在 workflow 的 phases 或 dispatch 表中声明 role 绑定。
- 避免预加载纪律:消费方必须按需读取 references,而非全部预先加载。在接线文本中说明这一点。
追踪与重新同步
若子模式为「持续同步」(或「快照但值得追踪以便重新导入」),在 .agents/skills/upstream-sync/SKILL.md 的 sync 表中追加一行,包含:
- 插件(及子技能,如适用)加非 MIT 来源的许可证标签
- 上游仓库及具体子路径
- 全部派生本地文件清单与任何合并章节
然后在该技能「How to sync a plugin」代码块中追加匹配的 gh api 抓取循环。即使对快照也要这样做;它让未来的重新导入成为一条命令而非考古。
若子模式为「inspiration only」,不要添加 sync 表行。在受影响的文件中添加内联说明,描述采用了什么、来自何处,但不加 sync 条目。
绝不为 AGENTS.md 中「Deliberately not vendored」下列出的任何内容添加 sync 表行。这些区域是刻意交还其上游的。
版本升级与提交
- 在每个改动的内核的 plugins/<name>/plugin.toml 中升级版本。
- 升级 .claude-plugin/marketplace.json 中的 metadata.version(新上游首次引入用 minor,既有引入的后续改造用 patch)。catalog 条目保持生成。
- 内核变化时用 python scripts/daodan_build.py 重建每个 host,并用 python scripts/sync_plugin_docs.py 重新生成组件/依赖参考。当仓库 workflow 技能的权威副本变化时,用 python scripts/sync_codex_instructions.py 重新生成其原生 Codex 适配。
- 单次提交,把导入的内核文件、本地编辑、SKILL.md 接线、sync 表更新、版本升级以及所有重新生成的 exports/catalogs、文档参考与指令副本放在一起。
- 提交信息:Cherry-pick / Vendor / Import <subject> from <owner>/<repo> (v<new>),附一段简短描述块,列出新文件、合并章节、许可证与归属日期。
推送前验证
- 对派生文件 grep,检查残留的仅上游引用、过时工具名或破折号插入语构造。
- 发布前运行 python scripts/daodan_build.py --check、python scripts/sync_plugin_docs.py --check、python scripts/sync_codex_instructions.py --check,以及仓库要求的依赖、bundled-path、registration、fact-anchor、host-vocabulary 与测试门禁。
- git status 显示 .upstream-scratch/ 中无内容被暂存。
- git diff --stat 检查改动范围。
适用场景
适用于需要把外部 GitHub 仓库内容首次引入本 marketplace 的场景,包括复制完整单元、挑选部分文件、与本地文件合并,或仅借鉴思路。不适用于已登记仓库的重新同步(由 upstream-sync 负责)。
限制
- 许可证不兼容(GPL/AGPL)或无许可证/专有的时候必须停止,需用户显式决定。
- 禁止本地可选依赖与缺失必需插件的通用回退。
- 内核中不得把上游 host 工具名替换为另一个原生工具名。
- 不得为「Deliberately not vendored」区域添加 sync 表行。