无版本号更新:pstack 支持 Claude Code(PR #637 原文翻译与关键代码解读)
更新于 2026-10-17
2026 年 10 月 17 日,pstack 的一个新 PR 被合并了:
feat(pstack): install pstack in Claude Code from a generated tree(#637)
作者是 poteto,对应的合并 commit 是 182f2ce。
这次是一次没有版本号的更新。 它不是 pstack 这个 Cursor 插件的版本发布,而是专门为了支持 Claude Code 才做的改动,所以插件的版本号没有变,仍然是 0.15.25。版本更新栏目里的其他文章都对应一个新版本号,这一篇是个例外,所以这里不写版本号,改用日期 2026-10-17 和提交 182f2ce 来标记它。
这次更新解决的是一个挺实际的问题:pstack 虽然采用 Skill 格式,但此前主要是为 Cursor 编写的,并不能直接当成一套完整的 Claude Code 插件使用。
PR 的方案也很有意思。它没有去逐个改造原有 Skill,而是写了一套生成脚本,把原本的 Skill 打包成 Claude Code 可以安装的插件,再通过一份适配文档处理两边工具和参数的差异。
下面先看 PR 作者自己怎么说,再看代码。
一、PR 正文翻译
Section titled “一、PR 正文翻译”本节翻译 PR #637 的主要正文,保留原文的 Why、What changed、Scope、Tradeoffs、Blast Radius 和 Verification 结构。路径、命令和技术术语尽量沿用原文,省略页面自动生成的按钮与评审页脚。
1. Why:为什么要做这件事?
Section titled “1. Why:为什么要做这件事?”Claude Code 用户现在可以从这个仓库安装 pstack:
claude plugin install pstack@cursor-plugins下面的验证部分已经实际测试过这条安装路径。
此前,main 分支上的 .claude-plugin/marketplace.json 并没有列出 pstack。
另外,pstack 的 Skill 使用了 Cursor 的工具名、子代理字段以及模型标识,而 Claude Code 对这些东西有不同的命名方式。
这个 PR 做了两件事:
- 为 Claude Code 生成一套独立的 Skill 文件副本。
- 提供一份 adapter(适配文档),负责映射 Cursor 和 Claude Code 之间不同的名称及参数。
对于维护者来说,这也意味着多了一个维护步骤。
以后修改 pstack 的 Skills、Agents、adapter 或 pstack/plugin.json 后,都需要运行:
node scripts/generate-pstack-harness-trees.mjs然后把生成结果一起提交。
2. What changed:具体改了什么?
Section titled “2. What changed:具体改了什么?”首先,新增了生成脚本:
scripts/generate-pstack-harness-trees.mjs
它以 pstack/skills、pstack/agents、pstack/docs/harness/claude-code.md、许可证和插件清单为输入,生成:
harness/pstack/claude-code/
其中有 21 个 Skill 使用了 Cursor 专有名称。生成脚本会在这些 Skill 的标题下面插入一条提示,告诉 Claude Code 在执行 Skill 前先阅读 adapter。
其次,修改了 .claude-plugin/marketplace.json,让其中的 pstack 条目指向生成出来的插件目录。
生成文件会直接提交到仓库,而不是在安装时临时生成。
原因是:Claude Code 安装插件时只会复制插件目录,不会执行构建脚本。
最后,CI 新增了生成结果检查。
执行生成器的 --check 模式时,以下情况会导致检查失败:
- 已提交的生成目录和源文件不同步。
- 生成目录里的相对链接无法正确解析。
- 某个 Cursor 专有名称没有在 adapter 中找到对应规则。
同时,scripts/validate-plugins.mjs 也开始检查 Claude Code marketplace 中的插件条目。
3. Scope:这次改动的边界
Section titled “3. Scope:这次改动的边界”对 Cursor 用户来说,原有的 Skills 和 Agents 没有变化。
作者用 git diff --quiet 验证过,pstack/skills 和 pstack/agents 与原先的 main 分支逐字节一致。
生成目录包含:
- Skills 和 Agents
- Claude Code adapter
- 许可证
- 插件 manifest
但不包含指南文档、README、pstack/assets 和 pstack/automations。
如果某个 Skill 里有指向这些被排除文件的相对链接,生成器会把它改成指向 GitHub main 分支的链接。
本次 PR 不包含 Codex 的适配工作,也不会提升 pstack 的版本号。
4. Tradeoffs:作者做了哪些取舍?
Section titled “4. Tradeoffs:作者做了哪些取舍?”完整复制 Skill,而不是只保存引用。
作者考虑过另一种做法:在生成目录中只放一个很薄的 SKILL.md,让模型真正执行时再去读取原始 Skill。
这种方式可以让首次请求减少大约 480 个 token,但后续每次读取原始文件,又会增加一次调用,带来约 104~186 个 token 的额外开销。
最终选择的是完整复制 Skill。
生成目录放在仓库根目录,而不是 pstack/ 内部。
因为 Cursor 安装插件时会复制整个插件文件夹。
生成的 Claude Code 目录有 138 个文件,大小约 643 KB。如果把它放进 pstack/,Cursor 用户每次安装也会把这些用不到的文件一起复制下来。
指南链接改为 GitHub 地址。
代价是:这些地址指向 main 分支,可能比用户已经安装的插件版本更新,而且读取时需要网络。
例如 poteto-help 在 Claude Code 中读取指南页面时,会使用 WebFetch。在交互会话中,可能需要用户批准权限。
不主动阻止 Codex 使用这套插件。
作者特别解释了一个细节:当 Codex 没有找到 .agents/plugins/marketplace.json 时,可能会回退读取 .claude-plugin/marketplace.json。
因此,Codex 用户也可能通过这个 marketplace 安装到为 Claude Code 生成的 pstack。
但这不意味着本 PR 正式支持 Codex。作者没有增加 Codex 专用文件,也没有改变这种回退行为。
5. Blast Radius:影响范围
Section titled “5. Blast Radius:影响范围”Cursor 原有的 pstack 安装目录从 169 个文件变成了 170 个文件。
新增的那一个文件就是 Claude Code adapter,其余原有内容保持不变。
此前通过这个仓库安装 Claude Code 插件的用户,也不会受到已有 pstack 行为变化的影响,因为此前根本没有官方的 Claude Code pstack 安装入口。
不过,未来维护者需要注意生成目录同步的问题。
作者当时统计,有 47 个尚未合并的 PR 修改了 pstack/skills。这些 PR 如果后续要合入,就必须重新生成 Claude Code 目录,否则 CI 会失败。
6. Verification:作者是怎么验证的?
Section titled “6. Verification:作者是怎么验证的?”作者使用一个全新的 HOME 环境,在 Claude Code 2.1.301 中完成了安装测试。
测试中:
- Claude Code 成功安装了
pstack@cursor-plugins。 - 安装后的内容与生成目录逐文件比较一致。
claude plugin details列出了 54 个 Skills 和 2 个 Agents。- Skill 名称与
pstack/skills中保持一致。
随后,作者实际试运行了 /pstack:setup-pstack 和 /pstack:poteto-help。
测试确认,Claude Code 能从已安装的插件目录中加载 SKILL.md 和 adapter,并在本地没有指南文件时,通过 GitHub 读取需要的页面。
有个细节值得说明:主要验证环境没有 Anthropic API Key,因此模型请求通过本地 LiteLLM 代理转发到了 OpenAI 的 gpt-5.5。插件安装、Skill 加载和文件读取仍然由 Claude Code 执行。
作者也在此前的一个提交版本上使用 Claude Sonnet 5.5 验证过相关文件的读取。
最后,两个检查命令均通过:
node scripts/generate-pstack-harness-trees.mjs --checknode scripts/validate-plugins.mjs作者还验证了一个失败场景:只修改源 Skill、不重新生成副本,--check 就会指出过期文件、提示重新运行生成命令,并返回退出码 1。
以上是 PR 正文的主要内容。
二、合并 commit 的关键 diff 解读
Section titled “二、合并 commit 的关键 diff 解读”现在看真正合并进仓库的代码:
这个 commit 一共涉及 146 个文件,其中 138 个是自动生成的 Claude Code 插件文件。
所以没必要逐个看文件。
真正需要理解的,是下面五处变化。
1. Adapter:把 Cursor 的规则翻译给 Claude Code
Section titled “1. Adapter:把 Cursor 的规则翻译给 Claude Code”文件:
pstack/docs/harness/claude-code.md
这是这次 PR 最核心的文件之一。
它没有把原来的 Skill 改写成 Claude Code 语法,而是提供了一份映射规则,让模型执行 Skill 时自行做适配。
例如工具映射:
| Cursor 中的写法 | Claude Code 中的处理 |
|---|---|
Task |
Agent |
AskQuestion |
AskUserQuestion |
subagent_type: generalPurpose |
subagent_type: "general-purpose" |
poteto-agent |
pstack:poteto-agent |
readonly: true |
使用 Explore,并明确要求不要修改文件 |
environment: "cloud" |
使用 isolation: "worktree" |
run_in_background: true |
省略该字段 |
看起来像是一份名称对照表,但实际处理的不只是改名。
比如 Cursor 的 environment: "cloud" 并不能简单翻译成 Claude Code 的某个同名参数。
adapter 选择使用 Git worktree 隔离来代替。两者并不完全等价,只是在 Claude Code 的能力范围内尽量接近原本的意图。
模型的处理也类似。
例如 Cursor 里可能会写:
model: claude-opus-5-5-xhighadapter 要求在 Claude Code 中把它拆成模型家族和推理档位:
model: opuseffort: xhigh但如果 Skill 指定的是 gpt-* 或 grok-* 这样的非 Claude 模型,就不能原样传给 Claude Code。
adapter 的处理方法是省略 model,使用当前会话模型,并明确告知用户。
这意味着某些依赖不同模型交叉评审的 pstack 工作流,在 Claude Code 里可能会失去原本的模型多样性。
此外,adapter 还特别规定:
如果某个 Cursor 字段没有对应映射,就跳过它并说明原因。不要向工具传入不支持的参数。
这条规则很重要。它承认两边的能力并不完全一致,而不是假装所有操作都能无损转换。
2. 生成器:让一套源 Skill 对应两套安装目录
Section titled “2. 生成器:让一套源 Skill 对应两套安装目录”文件:
scripts/generate-pstack-harness-trees.mjs
这份脚本负责从原始 pstack/ 生成 Claude Code 插件。
整体关系可以理解为:
flowchart TD
A["pstack/skills + agents"] --> C["生成脚本"]
B["Claude Code adapter"] --> C
C --> D["harness/pstack/claude-code/"]
D --> E["Claude Code 安装"]
A --> F["Cursor 原有安装"]
生成器的主要工作有三个。
第一,复制源文件。
把 Skills、Agents、许可证和 manifest 复制到 Claude Code 对应目录。
第二,给需要适配的 Skill 增加一句提示。
例如,原本的 interrogate/SKILL.md 只有:
# Interrogate
Spawn one reviewer per configured model...生成后的版本会变成:
# Interrogate
In Claude Code, read [the Claude Code adapter](../../docs/harness/claude-code.md) once per session before you follow this skill.
Spawn one reviewer per configured model...注意,这里并没有把 interrogate 的整个执行流程改写一遍。
只是增加了一句话:在 Claude Code 中执行此 Skill 前,先阅读 adapter,每个会话读一次即可。
此次有 21 个 Skill 被插入了这样的提示。
第三,修正部分文件链接。
Claude Code 的安装包不包含完整指南目录,所以原来指向 ../../docs/guide/... 的链接不能直接使用。
生成器会将这类链接改成 GitHub 地址,避免安装后引用到不存在的文件。
换句话说,这个脚本不是简单的 cp -r。它在复制过程中,还完成了一部分针对 Claude Code 的打包处理。
3. Marketplace:让 Claude Code 真正找得到 pstack
Section titled “3. Marketplace:让 Claude Code 真正找得到 pstack”文件:
.claude-plugin/marketplace.json
这一处 diff 很短:
{ "name": "pstack", "source": "./harness/pstack/claude-code", "description": "if you want to go fast, go deep first..."}关键不是 name,而是 source。
它指向的是:
./harness/pstack/claude-code而不是:
./pstack这就把两个环境分开了。
Cursor 继续加载原来的 pstack/。
Claude Code 则通过自己的 marketplace 安装生成后的目录。
另外,生成目录中还带有 Claude Code 需要的插件 manifest,例如:
harness/pstack/claude-code/.claude-plugin/plugin.json
这里的版本号仍然是 0.15.25。
也就是说,这次 PR 增加了平台支持,但并没有顺便发布一个新的 pstack 版本。
4. CI:避免改了 Skill 却忘记更新 Claude Code 副本
Section titled “4. CI:避免改了 Skill 却忘记更新 Claude Code 副本”文件:
.github/workflows/validate-plugins.yml
新增的核心检查只有一条:
- name: Check generated pstack harness trees run: node scripts/generate-pstack-harness-trees.mjs --check不过,它解决的是生成副本方案最容易出现的问题。
假设以后有人修改了:
pstack/skills/interrogate/SKILL.md却没有更新:
harness/pstack/claude-code/skills/interrogate/SKILL.md那么两边安装的就不是同一份逻辑。
这条 CI 会重新计算预期生成结果,再与仓库里已提交的内容比较。
如果不一致,检查失败。
同时,PR 还扩展了 CI 的触发路径。修改 pstack/**、harness/**、相关脚本或 marketplace 文件时,都会触发验证。
因此,Claude Code 副本不是靠维护者手动记得同步,而是把同步要求写进了 PR 检查。
这也是整个生成式适配方案能长期维护的关键。
5. 原始 Skills 没有被修改
Section titled “5. 原始 Skills 没有被修改”最后看一处很容易忽略的事情:这个 commit 没有直接修改 pstack/skills 和 pstack/agents 的现有内容。
这其实说明了作者的设计选择。
要兼容 Claude Code,理论上有两条路线。
一种是直接修改源 Skill,让每个 Skill 都知道自己当前运行在 Cursor 还是 Claude Code,并分别处理工具名、参数和路径。
另一种则是保留源 Skill,再通过打包生成和 adapter 来完成适配。
PR #637 选择了第二种。
这样做的优点很明确:Cursor 原有行为不需要跟着变化,Claude Code 的兼容逻辑集中放在 adapter 和生成器里。
但代价也同样明显:以后每次修改源 Skill,都必须维护生成结果;而且有些能力差异无法靠名称映射真正消除。
例如 Cursor 的 Automations、Bugbot、云端 Agents,以及某些模型选择能力,都不能因为加了一份 adapter 就自动变成 Claude Code 的原生能力。
另外,/setup-pstack 原本用于生成 Cursor 的 .mdc 模型规则。Claude Code 不会加载这套文件,所以 adapter 明确要求:在 Claude Code 中遇到该配置流程时说明情况并停止,不要擅自把配置写进 CLAUDE.md。
三、怎么看这次 PR?
Section titled “三、怎么看这次 PR?”读完 PR 和 diff,其实可以把这次更新概括成三件事:
- 让 Claude Code 能安装。 通过 marketplace 条目和生成目录,提供正式的插件安装入口。
- 让 Claude Code 尽可能理解并执行原来的 Skill。 通过 adapter 映射工具、模型、子代理和路径差异。
- 让两套文件保持同步。 通过生成器与 CI 避免后续维护时出现版本分叉。
这次更新并不是重写了一套 Claude Code 版 pstack。
更准确地说,它是保留 Cursor 版本作为源文件,再为 Claude Code 生成一个可安装、带适配规则的副本。
这也解释了为什么一个基于 Skill 格式的项目,仍然需要专门做 Claude Code 支持:文件格式兼容,只是第一步;Skill 里面调用的工具、模型和运行环境,也得能对上。
目前这套方案已经解决了安装和相当一部分执行兼容问题,但还不能理解成两边完全等价。
相关链接
- PR #637:原始讨论与说明
- Commit
182f2ce:完整 diff - pstack 官方支持 Claude Code 了:站长对这次更新的个人解读
- Claude Code / Codex 能用吗:本站此前写的跨宿主说明,哪些是 Cursor 专用的,哪些思路能搬走
- pstack 中文站
