EcoPaste 项目中 Trellis 平台文件体系解析:共享运行时与 AI 工具适配层的工作原理
EcoPaste 项目中 Trellis 平台文件体系解析:共享运行时与 AI 工具适配层的工作原理
导读
Trellis 将同一套本地运行架构接入不同的 AI 工具(Claude Code、Codex、Cursor、OpenCode、Gemini CLI 等),其核心思路是把"共享运行时"(.trellis/)与"平台适配文件"(各工具目录)严格分层。本文以当前仓库(EcoPaste)中实际生成的 Trellis 文件为例,系统讲解如何区分共享文件与平台文件、五类平台文件的职责划分、三种平台集成模式(Hook 驱动 / Agent Prelude 拉取 / 主会话工作流)以及本地定制时应遵循的检查顺序,帮助你在多 AI 工具共存的仓库中精准定位"该改哪个文件"。
一、先分清两类文件:共享文件 vs 平台文件
Trellis 把同一套本地架构连接到不同的 AI 工具。.trellis/ 目录存放共享运行时;平台目录存放适配文件,定义每个 AI 工具如何进入 Trellis。
当本地 AI 修改 Trellis 时,应首先区分两类文件:
- 共享文件:
.trellis/workflow.md、.trellis/tasks/、.trellis/spec/、.trellis/scripts/。 - 平台文件:
.claude/、.codex/、.cursor/、.opencode/、.kiro/、.gemini/、.qoder/、.codebuddy/、.github/、.factory/、.pi/、.trae/、.kilocode/、.agent/、.devin/、.reasonix/、.zcode/等类似目录。
在 EcoPaste 仓库根目录中可以看到这两类文件真实共存:既有 .trellis 共享运行时,也同时生成了 .claude/、.codex/、.cursor/、.opencode/、.github/、.kiro/、.gemini/ 等多个平台目录——这正是 Trellis 在同一仓库内为不同 AI 工具生成入口的直接证据。
关键原则:平台文件不存储业务状态。它们的作用是让对应的 AI 工具能够读取 Trellis 状态、调用 Trellis 脚本、加载 Trellis 的 skills / agents / hooks。
二、平台文件五大分类
| 分类 | 常见路径 | 用途 |
|---|---|---|
| settings/config | .claude/settings.json、.codex/hooks.json、.qoder/settings.json、.trae/hooks.json |
注册 hooks、插件、扩展或平台行为 |
| hooks/plugins/extensions | .claude/hooks/、.opencode/plugins/、.pi/extensions/ |
在会话开始、用户输入、Agent 启动、shell 执行等事件处注入上下文 |
| agents | .claude/agents/、.codex/agents/、.kiro/agents/ |
定义 trellis-research、trellis-implement、trellis-check |
| skills | .claude/skills/、.agents/skills/、.qoder/skills/ |
能力描述,可自动触发或按需读取 |
| commands/prompts/workflows | .cursor/commands/、.github/prompts/、.devin/workflows/ |
由用户显式调用的入口点 |
在 EcoPaste 仓库中,五类文件均有落地实例:
- settings/config:.claude/settings.json 注册了
SessionStart、UserPromptSubmit、PreToolUse三类事件 hook;.codex/hooks.json 与 .codex/config.toml 对应 Codex 平台;.cursor/hooks.json 对应 Cursor。 - hooks/plugins/extensions:.claude/hooks/ 下存放
session-start.py、inject-subagent-context.py、inject-workflow-state.py;.cursor/hooks/ 额外包含inject-shell-session-context.py;而 OpenCode 平台则使用 .opencode/plugins/ 下的 JavaScript 插件(session-start.js、inject-workflow-state.js、inject-subagent-context.js),体现了"同一功能、不同平台、不同实现语言"的适配思路。 - agents:
.claude/agents/、.cursor/agents/下各有trellis-research.md、trellis-implement.md、trellis-check.md;而 .codex/agents/ 下的同名文件则是.toml格式——同一职责边界,按各平台约定改变文件格式。 - skills:.claude/skills/ 与 .cursor/skills/ 均生成了
trellis-meta、trellis-channel、trellis-spec-bootstrap等能力描述目录,每个 skill 以SKILL.md作为入口。 - commands:.claude/commands/trellis/ 下有
continue.md、finish-work.md等用户显式调用入口;OpenCode 侧对应 .opencode/commands/trellis/ 的start.md、continue.md、finish-work.md。
三、三种平台集成模式
1. Hook / Extension 驱动
这类平台可以在特定事件上触发脚本或插件,主动把 Trellis 上下文注入 AI。常见能力包括:
- session-start 时注入
.trellis/概览; - 每一轮用户输入时给出 workflow 状态提示;
- 子 Agent 启动时注入 PRD / spec / research;
- shell 命令继承会话身份。
以 EcoPaste 的 .claude/settings.json 为例,hook 注册清晰可见:
{
"hooks": {
"SessionStart": [
{ "hooks": [{ "command": "python3 .claude/hooks/session-start.py", "timeout": 30 }], "matcher": "startup" },
{ "hooks": [{ "command": "python3 .claude/hooks/session-start.py", "timeout": 30 }], "matcher": "clear" },
{ "hooks": [{ "command": "python3 .claude/hooks/session-start.py", "timeout": 30 }], "matcher": "compact" }
],
"UserPromptSubmit": [
{ "hooks": [{ "command": "python3 .claude/hooks/inject-workflow-state.py", "timeout": 15 }] }
],
"PreToolUse": [
{ "hooks": [{ "command": "python3 .claude/hooks/inject-subagent-context.py", "timeout": 30 }], "matcher": "Task" },
{ "hooks": [{ "command": "python3 .claude/hooks/inject-subagent-context.py", "timeout": 30 }], "matcher": "Agent" }
]
}
}
从中可以推断出三类事件的触发时机:会话新建/清除/压缩时注入会话概览;每次用户提交 prompt 时解析 workflow 状态;Task 或 Agent 工具调用前注入子 Agent 上下文。
OpenCode 平台则走插件路线,.opencode/plugins/session-start.js 通过 chat.message 钩子在用户发送第一条消息时构建并持久化会话上下文(buildSessionContext),并借助 hasPersistedInjectedContext / markContextInjected 避免重复注入——这是"插件驱动注入"的典型实现。
要改变"AI 何时知道什么",应首先检查 hooks / plugins / extensions 与 settings。
2. Agent Prelude / Pull-Based(Agent 拉取)
有些平台无法可靠地让 hook 改写子 Agent 的 prompt,因此改为在 Agent 文件本身中指示:启动后读取活动任务、PRD 与 JSONL 上下文。
在 EcoPaste 的 .opencode/agents/trellis-research.md 中可以看到这种 pull 模式:Agent 启动后第一步执行 python3 ./.trellis/scripts/task.py current --source 解析当前活动任务路径,并要求把所有研究成果持久化到 {TASK_DIR}/research/<topic>.md,同时以 frontmatter 声明 mode: subagent 与权限边界。
要改变子 Agent 如何加载上下文,直接检查 Agent 文件本身。
3. 主会话工作流(Main-Session Workflow)
有些平台不具备 Trellis 子 Agent 或 hook 能力,只能依靠 workflows / skills / commands 引导主会话 AI 读取文件、运行脚本、推进任务。EcoPaste 仓库的共享运行时中,.trellis/workflow.md 即承担这一"主会话指南"角色:它从核心原则(先规划后编码、规范注入而非记忆、增量开发、任务收尾沉淀知识)到 Spec 系统、Task 系统逐步展开,并通过 python3 ./.trellis/scripts/get_context.py --mode packages 之类命令让主会话 AI 获取项目上下文。
要改变此类平台的行为,检查平台 workflows / skills / commands 与 .trellis/workflow.md。
四、本地定制时的修改顺序
当用户要求为某个平台定制行为时,AI 应按以下顺序检查文件:
- 读取
.trellis/workflow.md,确认共享流程; - 读取目标平台的 settings/config,确认注册了哪些 hooks / agents / skills / commands;
- 读取目标平台的 agents / skills / commands / hooks;
- 修改最贴近用户需求的本地文件;
- 若改动影响共享流程,同步
.trellis/workflow.md或.trellis/spec/。
两个必须避免的极端:只改平台文件却忘记共享 workflow;或只改 .trellis/workflow.md,却忘记平台的入口点可能仍描述旧内容。
结合仓库的实操示例
假设你在 EcoPaste 仓库中需要调整"research 子 Agent 的输出格式":
- 先读 .trellis/workflow.md 确认共享流程中 research 阶段的职责划分;
- 再读对应平台的注册文件(Claude 看
.claude/settings.json,Codex 看 .codex/hooks.json,OpenCode 看 .opencode/package.json 中的插件声明); - 找到对应 Agent 文件:Claude/Cursor 为
.claude/agents/trellis-research.md/.cursor/agents/trellis-research.md,Codex 为.codex/agents/trellis-research.toml,OpenCode 为 .opencode/agents/trellis-research.md; - 修改该 Agent 文件(例如收紧 research 的写边界:只允许写入
research/); - 若该改动需要所有平台同步生效,逐一检查其他平台目录中的等价文件,避免出现"某平台 Agent 仍按旧规则运行"。
从源码结构看,EcoPaste 的 .claude/、.codex/、.cursor/、.opencode/ 四个平台都生成了同名的三个子 Agent(research / implement / check),因此"多平台语义同步"在这类仓库中是需要实际执行的动作,而非抽象原则。
五、平台文件定制的四条底线
结合当前仓库中真实文件可以总结出以下定制准则:
- 职责单一:research、implement、check 三者职责边界保持一致,不在一个 Agent 中混搭(对照 .opencode/agents/trellis-research.md 与同目录下另外两个文件即可看出边界划分);
- 明确读取顺序:Agent 应知道从活动任务开始,先读 JSONL / spec 上下文,再读
prd.md,若存在再读design.md、implement.md; - 明确写边界:research 通常只写
research/,implement 可改代码,check 可修复问题; - 多平台语义同步:若用户同时配置了 Claude、Codex 和 Cursor,需要判断某一平台 Agent 的改动是否也应同步到其他平台。
关于文件是否存在的前提
本仓库实际生成哪些平台目录,取决于初始化时执行了哪些 trellis init --<platform> 命令。EcoPaste 当前同时存在 .claude/、.codex/、.cursor/、.opencode/ 等多个目录,说明初始化覆盖了多个平台;而配置文件(如 .trellis/config.yaml)则注释说明"所有值都有合理默认值,只覆盖你需要的项"——这同样适用于平台文件:只修改与用户需求相关的文件,保持其余内容为生成默认值。
六、故障排查:当"AI 没有读取 Trellis 状态"时
当用户反馈"AI 没有读取 Trellis 状态"时,按照以下路径排查:
- 检查平台 settings 是否注册了对应 hook;
- 检查 hook 文件是否存在;
- 手动运行 hook 依赖的命令(如
python3 ./.trellis/scripts/get_context.py或python3 ./.trellis/scripts/task.py current --source,这两个脚本均真实存在于 .trellis/scripts/); - 检查
.trellis/.runtime/sessions/中是否存在活动任务状态; - 检查平台 shell 是否传递了会话身份。
这套排查顺序在 EcoPaste 仓库中可直接验证:.claude/、.cursor/ 各平台目录下 hook 脚本与 settings 注册一一对应,.trellis/scripts/task.py 等脚本由共享运行时统一提供,任何一层断裂都会导致上下文注入失败。
总结
Trellis 的"共享运行时 + 平台适配层"设计让同一套 .trellis/ 状态可以被任意数量的 AI 工具消费。正确理解共享文件与平台文件的边界、五类平台文件的职责、三种集成模式(Hook 驱动、Agent 拉取、主会话工作流)以及本地修改顺序,是安全定制任何多 AI 工具仓库的前提。EcoPaste 仓库本身就是一份"多平台并存"的活样本:同一个 trellis-research 职责,在 Claude/Cursor 中是 .md、在 Codex 中是 .toml、在 OpenCode 中配合 JS 插件,而所有平台的上下文源头都指向同一个 .trellis/ 共享运行时。