pstack 架构拆解
H09 / 十层 · 地基

它不跨 runtime。
它绑死一个宿主

上游 50 个技能的正文里,找不到 Codex、Claude Code、Gemini、OpenCode 任何一个词。 方言只有一种:Cursor。作者 Lauren Tan 在 README 里写得很直白—— "these are the same skills i use everyday to ship high quality code at Cursor", 她还写着 "this turns cursor into a real engineering team"。 这不是妥协出来的移植品,是照着 Cursor 的接口长出来的。

图 9-1七个硬编码点

"硬编码"在这里的意思是:把这几个接口换掉,正文就得改写。左边是文件里原样出现的名字,右边是它在 Cursor 里对应什么。

在 pstack 正文里出现的次数(全库 grep 实测,含 skills/ 与 agents/) 绑定点 原文里的样子 Cursor 的对应物 命中 1 · 派子代理 Task tool · subagent_type · generalPurpose Cursor 的 Task 工具 9 / 16 / 11 2 · 子代理参数 run_in_background · environment: "cloud" · cloud_base_branch 云端 agent,本地要显式改 local 3 / 2 / 1 3 · 配置注入 ~/.cursor/rules · pstack-models.mdc · alwaysApply Cursor 的 rules 目录 + .mdc 格式 8 / 12 / 2 4 · 安装与发现 /add-plugin · ~/.cursor/plugins/ 插件市场 slash 命令 2 / 3 5 · 磁盘状态仓 ~/.cursor/projects/ · agent-transcripts/ Cursor 的 project store(H10) 8 / 12 6 · 抢宿主的名字 babysit · create-skill 内置技能同名,必须点名绕开 43 / 19 7 · 提问与 forge AskQuestion · gh pr · origin pr Cursor 的选项工具;Origin 是内部 forge CLI 6 / 18 / 26 值得注意的两点 ① origin pr 出现 26 次,比 gh pr 的 18 次还多。原文写死:"GitHub CLI (gh) is the default. If command -v origin succeeds and Origin can resolve the repository, use origin pr ..."——把内部 forge 当一等公民写进了公开插件。 ② 第 6 项不是技术依赖,是命名空间冲突。宿主自带同名技能(babysit、create-skill)时,pstack 只能在正文里显式声明覆盖或路由,没有别的机制可用。
图 9-1 · "命中"= 该字符串在整个 pstack/ 目录里的出现次数(grep -ro 实测,提交 e43c7ee)。一行里有多个数时,按中间列从左到右同序对应,例如第 1 行 = Task tool 9 次、subagent_type 16 次、generalPurpose 11 次。

图 9-2插件清单只认两个目录

这是"绑宿主"最硬的一条证据——.cursor-plugin/plugin.json 只声明 skills 和 agents,其余目录 Cursor 看不见。

pstack/ · 161 个文件 · 128 个 .md(80%) 被 manifest 注册 skills/50 个目录 → "skills": "./skills/" agents/2 份 → "agents": "./agents/" agents/poteto-agent.md frontmatter 带 is_background: true 描述里写:"Substituting generalPurpose skips that read and drifts." 没被注册,靠人读 docs/guide/10 章 + README + images automations/benny/3 个技能 docs/guide 是写给人的教程 01-setup → 10-recipes-and-pitfalls 含 mermaid 流程图和 jpg 插图 benny 是另一套 issue-triage 自动化 要单独按 FOR_AGENTS.md 装 真正的代码在哪 skills/poteto-mode/scripts/(含配置 20 个) bootstrap.ts · check-plan.mjs · worktree-audit.sh orch/ → orch.ts + store.ts + orch.test.ts watch-pr/ → 10 个 .ts(cli/github/policy/render/types) skills/show-me-your-work/scripts/log.sh 全库只有 1 个 package.json(跑在 bun 上) 14 个 .ts 里 5 个是测试:orch/cli/github/policy.test + fakes.test-helper 另有 types.compile.ts 专门做编译期断言 读法:161 个文件里 128 份 .md、7 张图,非文档只有 26 个。所以这一层"绑宿主"绑的主要不是依赖,而是正文里那些接口名。 对比端口版:michael-denyer/pstack-claude 用仓库名自称"Claude Code, Codex, Pi, OpenCode, Gemini, and Prime Agent versions"——跨 runtime 是那个移植项目的目标,不是上游的。
图 9-2 · 文件普查取自 find pstack -type f(提交 e43c7ee)。agents/ 里两份:poteto-agent.md 与 comment-sicko.md。

9-3深绑换来的是什么

收益
判据可以写到极细
因为确定宿主,reflect 才敢写"Readonly strips MCPs"这一句因果;arena 才敢写"如果 Task 工具拒绝这个 slug,就去读它的报错文本挑替代"。抽象层拿不到这么具体的信息。
收益
状态可以放在宿主里
H10 的决策链和 transcript 直接读 ~/.cursor/projects/<slug>/。跨 runtime 的话,这个路径必须变成参数。
代价
换宿主 = 换项目
上游不给你迁移路径。想在自己的 runtime 上用,只能像端口版那样逐文件改写方言——那是一份新作品,不是配置。
端口版改了什么:它新增了 references/codex-tools.md 与 references/pi-tools.md 两张星型映射表 (Task → spawn_agent、wait → wait_agent、AskUserQuestion → 纯文本提问), 在两处开头插一句 "On Codex, read the platform mapping before following this skill.", 并把 .mdc 换成按 runtime 各存一份的 pstack-models.md。 它还顺手扩了规模:73 个技能目录、23 条原则、163 行根文件(上游 50 / 24 / 147),并多出一节 Platform Adaptation。
本层的检验问题:为什么不做一层工具名抽象? 因为上游从来没把跨 runtime 当需求。README 的口号是 "fork it. improve it. make it yours."—— 它邀请的是你改它,不是你带着它跑。这一判断让 H07/H08/H10 能写得非常具体,代价是这一层。 下一层 H10 是它唯一真的写了代码、并且真的写了测试的地方。
上一站← H08 模型配置