task.py init-context;在 sub-agent 平台上,task.py create 会给 implement.jsonl 和 check.jsonl 各自预写一行自描述的 _example seed,之后由 AI 按 workflow.md Phase 1.3 填入真实的 spec + research 条目。4 个 session-start 实现的 READY gate 现在要求至少一条 curated 条目才算就绪。Skill Routing 表按平台分支。发版脚本新增 manifest 连续性前置检查,堵掉已发版 manifest 被重写或删除的路径。非破坏性,trellis update 对既有任务无感。
功能变动
workflow.md 的 Phase 1.3 由 agent 生成,不再由脚本生成预填充的内容
之前的task.py init-context 会按照 dev_type + package 进行 implement.jsonl / check.jsonl 的预填充,模板路径假设的是 spec/<package>/{backend,frontend}/index.md,但如果按语言分包的 monorepo(如 package = backend + package = frontend)会产出指向不存在的文件,进而会导致 agent 自主填充,多轮 tool call 调用导致模型注意力涣散,遗忘 trellis 工作流。
Seed 行格式(每个 jsonl 一行,没有 file 字段,所有读取端都会跳过):
Skill Routing 表按平台分支
workflow.md 的 Skill Routing 和 DO-NOT-skip 表现在有两种派发方式,分别是有 sub agent 的 IDE/CLI,会调用 trellis-implement 实际 coding;而没有 sub agent 的平台会在主 agent 里加载 trellis-before-dev 自己 coding。
| 有 sub agent 的平台 | 无 sub agent 的平台 |
|---|---|
| Claude / Cursor / OpenCode / Codex / Kiro / Gemini / Qoder / CodeBuddy / Copilot / Droid | Kilo / Antigravity / Windsurf |
按 Phase 2.1 派 trellis-implement sub-agent | 加载 trellis-before-dev skill(主线程流程) |
4 个 session-start 实现的 READY gate 统一
此前所有 4 个 session-start 实现都以”implement.jsonl 文件存在”为”Phase 2 就绪”判据。task.py create seed 完 jsonl 后,面包屑直接跳到 Status: READY,AI 会跳过 Phase 1.3 curate。
现在每个实现扫描 jsonl,要求至少一行带 file 字段。只有 seed 的 jsonl 现在显示为 Status: PLANNING (Phase 1.3),Next-Action 指向 curate 步骤。
| 实现 | 被谁消费 |
|---|---|
shared-hooks/session-start.py | Claude、Cursor、Kiro、CodeBuddy、Droid、Gemini、Qoder |
codex/hooks/session-start.py | Codex |
copilot/hooks/session-start.py | Copilot |
opencode/plugins/session-start.js | OpenCode(JS plugin 运行时) |
Hook + prelude 对只有 seed 的 jsonl 做兼容处理
shared-hooks/inject-subagent-context.py:read_jsonl_entries 静默过滤不带 file 的行(不报错),但在结果为空时打一条 stderr warning。
configurators/shared.ts:buildPullBasedPrelude 告诉 Class-2 sub-agent(Codex / Copilot / Gemini / Qoder)跳过没有 file 的行,并在 jsonl 只有 seed 时退回到读 prd.md + 自己判断 spec。
内部优化
Manifest 连续性前置检查
packages/cli/scripts/check-manifest-continuity.js 查 npm view @mindfoldhq/trellis versions --json 并和本地 src/migrations/manifests/*.json 对比。任何 npm 上存在但本地缺失的版本都会让检查 exit 非零。
背景:trellis update 按 v > installed && v <= current 应用迁移。某版本在 npm 上但本地没对应 manifest,会让从相邻版本升级的用户静默漏掉那批迁移——参见 .trellis/spec/cli/backend/migrations.md 里的 beta.10 事件。
| Release 脚本 | 前置流程 |
|---|---|
release / release:minor / release:major | check-manifest-continuity.js → pnpm test → bump → commit → tag → push |
release:beta / release:rc / release:promote | check-manifest-continuity.js → check-docs-changelog.js → pnpm test → bump → … |
KNOWN_GAPS 冻结。注释注明这个列表不该扩展——出现新 gap 意味着应该修根因,不是加白名单。
紧急绕过:SKIP_MANIFEST_CONTINUITY=1 pnpm release:beta。设置时会打一条醒目的警告横幅。
trellis update 备份阶段的爆栈修复
createFullBackup() 扫 .trellis/ 时会递归进入旧的 .trellis/.backup-* 目录,而旧备份里还套着 .opencode/node_modules(数万个文件)。原来的 collectAllFiles() 用递归 + files.push(...largeArray),文件量一大直接触发 V8 Maximum call stack size exceeded,trellis update 在确认后的备份阶段崩溃。
| 修复点 | 位置 |
|---|---|
collectAllFiles 改成迭代栈遍历,避免递归 + 大数组 spread | packages/cli/src/commands/update.ts:770 |
扫描阶段直接跳过 node_modules、.backup-* 等 exclude 目录(不只是复制阶段跳) | packages/cli/src/commands/update.ts:683 |
BACKUP_EXCLUDE_PATTERNS 匹配前把路径反斜杠统一成正斜杠,和 isManagedPath 的正则化对齐,Windows 上 .claude\worktrees\... 这种也能匹配 | packages/cli/src/commands/update.ts:689 |
collectAllFiles 跳过 symlink / Windows NTFS junction(isSymbolicLink() 对 junction 也返回 true),防止环形路径导致无限扫描 | packages/cli/src/commands/update.ts:787 |
DEBUG=1 / TRELLIS_DEBUG=1 时打完整堆栈,方便定位同类问题 | packages/cli/src/cli/index.ts:130 |
test/commands/update-internals.test.ts 和 test/commands/update.integration.test.ts。
临时绕过(如果还在用已发布的旧 CLI):rm -rf .trellis/.backup-* 删掉旧备份,再跑 trellis update 就不会触发爆栈。
create-manifest.js 守卫:禁止重写已发版 manifest
脚本现在拒绝(重)写 npm 上已存在版本的 manifest,即使传 force: true 也拒绝。交互模式在原有”本地文件已存在”prompt 之前先做 npm 查询检查。
vi.mock("node:child_process") 给 Python 版本探测一个合法返回值
update.integration.test.ts 和 init-joiner.integration.test.ts 原本把 execSync stub 成对所有命令返回空字符串。init() 内部会调 requireSupportedPython() → execSync("python3 --version"),空字符串被判为”Python 未找到”抛异常,任何后续断言都跑不到。
升级
既有项目:implement.jsonl / check.jsonl 继续可用——没有 file 的 seed 行会被所有读取端忽略。如果你早先 init-context 生成的 jsonl 指向 monorepo spec 布局里不存在的路径(典型场景是 package = backend | frontend 项目),按 workflow.md Phase 1.3 重 curate:
PLANNING (Phase 1.3) 翻到 READY。
全新安装: