@mindfoldhq/trellis 0.5.0-beta.9 → 0.5.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/README.md +60 -95
  2. package/dist/cli/index.js +7 -0
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/init.d.ts +3 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +117 -117
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.d.ts.map +1 -1
  9. package/dist/commands/update.js +289 -33
  10. package/dist/commands/update.js.map +1 -1
  11. package/dist/configurators/antigravity.d.ts.map +1 -1
  12. package/dist/configurators/antigravity.js +2 -8
  13. package/dist/configurators/antigravity.js.map +1 -1
  14. package/dist/configurators/claude.d.ts.map +1 -1
  15. package/dist/configurators/claude.js +4 -10
  16. package/dist/configurators/claude.js.map +1 -1
  17. package/dist/configurators/codebuddy.d.ts.map +1 -1
  18. package/dist/configurators/codebuddy.js +3 -3
  19. package/dist/configurators/codebuddy.js.map +1 -1
  20. package/dist/configurators/codex.d.ts.map +1 -1
  21. package/dist/configurators/codex.js +5 -13
  22. package/dist/configurators/codex.js.map +1 -1
  23. package/dist/configurators/copilot.d.ts.map +1 -1
  24. package/dist/configurators/copilot.js +5 -19
  25. package/dist/configurators/copilot.js.map +1 -1
  26. package/dist/configurators/cursor.d.ts.map +1 -1
  27. package/dist/configurators/cursor.js +3 -3
  28. package/dist/configurators/cursor.js.map +1 -1
  29. package/dist/configurators/droid.d.ts.map +1 -1
  30. package/dist/configurators/droid.js +3 -3
  31. package/dist/configurators/droid.js.map +1 -1
  32. package/dist/configurators/gemini.d.ts.map +1 -1
  33. package/dist/configurators/gemini.js +3 -5
  34. package/dist/configurators/gemini.js.map +1 -1
  35. package/dist/configurators/index.d.ts.map +1 -1
  36. package/dist/configurators/index.js +37 -49
  37. package/dist/configurators/index.js.map +1 -1
  38. package/dist/configurators/kilo.d.ts.map +1 -1
  39. package/dist/configurators/kilo.js +2 -8
  40. package/dist/configurators/kilo.js.map +1 -1
  41. package/dist/configurators/kiro.d.ts.map +1 -1
  42. package/dist/configurators/kiro.js +3 -3
  43. package/dist/configurators/kiro.js.map +1 -1
  44. package/dist/configurators/opencode.d.ts.map +1 -1
  45. package/dist/configurators/opencode.js +7 -4
  46. package/dist/configurators/opencode.js.map +1 -1
  47. package/dist/configurators/pi.d.ts +3 -0
  48. package/dist/configurators/pi.d.ts.map +1 -0
  49. package/dist/configurators/pi.js +44 -0
  50. package/dist/configurators/pi.js.map +1 -0
  51. package/dist/configurators/qoder.d.ts.map +1 -1
  52. package/dist/configurators/qoder.js +3 -5
  53. package/dist/configurators/qoder.js.map +1 -1
  54. package/dist/configurators/shared.d.ts +28 -6
  55. package/dist/configurators/shared.d.ts.map +1 -1
  56. package/dist/configurators/shared.js +47 -15
  57. package/dist/configurators/shared.js.map +1 -1
  58. package/dist/configurators/windsurf.d.ts.map +1 -1
  59. package/dist/configurators/windsurf.js +2 -8
  60. package/dist/configurators/windsurf.js.map +1 -1
  61. package/dist/constants/paths.d.ts +2 -0
  62. package/dist/constants/paths.d.ts.map +1 -1
  63. package/dist/constants/paths.js +2 -0
  64. package/dist/constants/paths.js.map +1 -1
  65. package/dist/migrations/manifests/0.5.0-beta.0.json +2 -0
  66. package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
  67. package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
  68. package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
  69. package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
  70. package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
  71. package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
  72. package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
  73. package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
  74. package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
  75. package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
  76. package/dist/migrations/manifests/0.5.0-beta.5.json +2 -0
  77. package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
  78. package/dist/templates/claude/agents/trellis-research.md +1 -1
  79. package/dist/templates/claude/settings.json +0 -4
  80. package/dist/templates/codebuddy/agents/trellis-research.md +1 -1
  81. package/dist/templates/codex/agents/trellis-research.toml +3 -2
  82. package/dist/templates/codex/hooks/session-start.py +126 -26
  83. package/dist/templates/codex/skills/finish-work/SKILL.md +41 -109
  84. package/dist/templates/codex/skills/start/SKILL.md +12 -9
  85. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
  86. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
  87. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
  88. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +81 -0
  89. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
  90. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
  91. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
  92. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
  93. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +64 -0
  94. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
  95. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
  96. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
  97. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
  98. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
  99. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +101 -0
  100. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
  101. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
  102. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +79 -0
  103. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
  104. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
  105. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
  106. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
  107. package/dist/templates/common/commands/continue.md +9 -5
  108. package/dist/templates/common/commands/finish-work.md +34 -10
  109. package/dist/templates/common/index.d.ts +22 -2
  110. package/dist/templates/common/index.d.ts.map +1 -1
  111. package/dist/templates/common/index.js +53 -4
  112. package/dist/templates/common/index.js.map +1 -1
  113. package/dist/templates/common/skills/brainstorm.md +3 -0
  114. package/dist/templates/copilot/hooks/session-start.py +127 -30
  115. package/dist/templates/copilot/prompts/finish-work.prompt.md +44 -112
  116. package/dist/templates/copilot/prompts/start.prompt.md +12 -9
  117. package/dist/templates/cursor/agents/trellis-check.md +1 -1
  118. package/dist/templates/cursor/agents/trellis-implement.md +1 -1
  119. package/dist/templates/cursor/agents/trellis-research.md +2 -2
  120. package/dist/templates/cursor/hooks.json +7 -1
  121. package/dist/templates/droid/droids/trellis-research.md +1 -1
  122. package/dist/templates/extract.d.ts +6 -0
  123. package/dist/templates/extract.d.ts.map +1 -1
  124. package/dist/templates/extract.js +14 -0
  125. package/dist/templates/extract.js.map +1 -1
  126. package/dist/templates/gemini/agents/trellis-research.md +1 -1
  127. package/dist/templates/kiro/agents/trellis-research.json +1 -1
  128. package/dist/templates/markdown/agents.md +19 -12
  129. package/dist/templates/markdown/gitignore.txt +3 -0
  130. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +24 -0
  131. package/dist/templates/opencode/agents/trellis-check.md +1 -1
  132. package/dist/templates/opencode/agents/trellis-implement.md +7 -4
  133. package/dist/templates/opencode/agents/trellis-research.md +2 -2
  134. package/dist/templates/opencode/lib/trellis-context.js +100 -13
  135. package/dist/templates/opencode/plugins/inject-subagent-context.js +70 -5
  136. package/dist/templates/opencode/plugins/inject-workflow-state.js +38 -58
  137. package/dist/templates/opencode/plugins/session-start.js +76 -31
  138. package/dist/templates/pi/agents/trellis-check.md +28 -0
  139. package/dist/templates/pi/agents/trellis-implement.md +33 -0
  140. package/dist/templates/pi/agents/trellis-research.md +25 -0
  141. package/dist/templates/pi/extensions/trellis/index.ts.txt +997 -0
  142. package/dist/templates/pi/index.d.ts +5 -0
  143. package/dist/templates/pi/index.d.ts.map +1 -0
  144. package/dist/templates/pi/index.js +12 -0
  145. package/dist/templates/pi/index.js.map +1 -0
  146. package/dist/templates/pi/settings.json +12 -0
  147. package/dist/templates/qoder/agents/trellis-research.md +1 -1
  148. package/dist/templates/shared-hooks/index.d.ts +31 -0
  149. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  150. package/dist/templates/shared-hooks/index.js +59 -0
  151. package/dist/templates/shared-hooks/index.js.map +1 -1
  152. package/dist/templates/shared-hooks/inject-shell-session-context.py +180 -0
  153. package/dist/templates/shared-hooks/inject-subagent-context.py +156 -27
  154. package/dist/templates/shared-hooks/inject-workflow-state.py +85 -105
  155. package/dist/templates/shared-hooks/session-start.py +222 -36
  156. package/dist/templates/trellis/gitignore.txt +3 -0
  157. package/dist/templates/trellis/index.d.ts +1 -0
  158. package/dist/templates/trellis/index.d.ts.map +1 -1
  159. package/dist/templates/trellis/index.js +2 -0
  160. package/dist/templates/trellis/index.js.map +1 -1
  161. package/dist/templates/trellis/scripts/common/__init__.py +8 -0
  162. package/dist/templates/trellis/scripts/common/active_task.py +593 -0
  163. package/dist/templates/trellis/scripts/common/cli_adapter.py +72 -14
  164. package/dist/templates/trellis/scripts/common/paths.py +61 -58
  165. package/dist/templates/trellis/scripts/common/session_context.py +12 -0
  166. package/dist/templates/trellis/scripts/common/task_context.py +27 -194
  167. package/dist/templates/trellis/scripts/common/task_store.py +102 -26
  168. package/dist/templates/trellis/scripts/common/tasks.py +4 -1
  169. package/dist/templates/trellis/scripts/common/workflow_phase.py +15 -3
  170. package/dist/templates/trellis/scripts/task.py +99 -34
  171. package/dist/templates/trellis/workflow.md +332 -69
  172. package/dist/types/ai-tools.d.ts +12 -3
  173. package/dist/types/ai-tools.d.ts.map +1 -1
  174. package/dist/types/ai-tools.js +29 -0
  175. package/dist/types/ai-tools.js.map +1 -1
  176. package/dist/utils/file-writer.d.ts.map +1 -1
  177. package/dist/utils/file-writer.js +7 -2
  178. package/dist/utils/file-writer.js.map +1 -1
  179. package/dist/utils/posix.d.ts +13 -0
  180. package/dist/utils/posix.d.ts.map +1 -0
  181. package/dist/utils/posix.js +15 -0
  182. package/dist/utils/posix.js.map +1 -0
  183. package/dist/utils/template-fetcher.d.ts +22 -6
  184. package/dist/utils/template-fetcher.d.ts.map +1 -1
  185. package/dist/utils/template-fetcher.js +405 -27
  186. package/dist/utils/template-fetcher.js.map +1 -1
  187. package/dist/utils/template-hash.d.ts +22 -3
  188. package/dist/utils/template-hash.d.ts.map +1 -1
  189. package/dist/utils/template-hash.js +99 -19
  190. package/dist/utils/template-hash.js.map +1 -1
  191. package/package.json +7 -7
  192. package/dist/templates/shared-hooks/statusline.py +0 -218
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.0-beta.17",
3
+ "description": "Beta.17 installs trellis-meta as a bundled built-in skill, hardens Pi subagent launch/configuration, removes promotional init completion output, and improves subagent context wiring. No migration actions are required.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Enhancements:**\n- feat(cli): Install `trellis-meta` as a bundled multi-file built-in skill under every platform skill root. The shared template pipeline now supports `packages/cli/src/templates/common/bundled-skills/<skill>/` through `getBundledSkillTemplates()`, `resolveBundledSkills()`, `collectSkillTemplates()`, and `writeSkills()`.\n- feat(pi): Harden the Trellis Pi `subagent` launcher. The generated extension resolves `@mariozechner/pi-coding-agent/dist/cli.js` when possible, runs child Pi with `--mode text -p --no-session`, sends delegated prompts through stdin, bounds stdout/stderr buffers, forwards `TRELLIS_CONTEXT_ID`, and wires `AbortSignal` cancellation.\n- feat(pi): Add Pi subagent model/thinking configuration. `.pi/agents/*.md` frontmatter may provide `model`, `thinking`, and `fallbackModels`, while the `subagent` tool accepts per-call `model` and `thinking` overrides and maps them to `--model <model[:thinking]>` or `--thinking <level>`.\n- docs(workflow): Clarify that `task.py create --slug <auto>` receives a slug without a date prefix because the script adds the `MM-DD-` directory prefix automatically.\n\n**Behavior Changes:**\n- chore(init): Remove promotional completion output from `trellis init`; completion output now stays focused on generated files and next actions.\n\n**Bug Fixes:**\n- fix(trellis): Improve subagent context wiring across local platform files. Cursor native custom-agent payloads are parsed from `Task`/`Subagent` tool input, workflow-state breadcrumbs require exact `trellis-implement` / `trellis-check` / `trellis-research` agent names, and Claude/Cursor/Codex hook paths preserve session identity for later shell or subagent context loading.",
7
+ "migrations": [],
8
+ "notes": "Run `trellis update` to receive the bundled `trellis-meta` skill, Pi subagent launcher/config updates, init output cleanup, and subagent context wiring fixes. No `--migrate` flag is required."
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.0-beta.18",
3
+ "description": "Beta.18 redesigns the Phase 3 workflow: Phase 3.4 adds an AI-driven batched commit step, and `/trellis:finish-work` becomes a 4-step survey + archive + journal flow that refuses to run on a dirty working tree. Also fixes parent-task progress regression on child archive, hash-tracks AGENTS.md during update, and supports OpenCode PowerShell context injection on Windows. No migration actions are required.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Enhancements:**\n- feat(workflow): Add `Phase 3.4 Commit changes` to `workflow.md`. The AI inspects `git status --porcelain`, learns commit-message style from `git log --oneline -5`, classifies dirty files into AI-edited-this-session vs unrecognized groups, drafts a batched commit plan, and commits per batch only after one-shot user confirmation. Rejecting the plan exits to manual mode without a flag. Wrap-up reminder renumbers from 3.4 to 3.5. The `[workflow-state:completed]` breadcrumb (and the four hook fallbacks in `inject-workflow-state.py`/`.js`) now direct users at `/trellis:finish-work` instead of the legacy `task.py finish` + `task.py archive` sequence.\n- feat(skills): Rewrite `/trellis:finish-work` as a 4-step survey + archive + journal flow. Step 1 runs `get_context.py --mode record` to print active tasks, git status, and recent commits — when other completed-but-unarchived tasks surface, the AI prompts once for one-shot batch cleanup. Step 2 runs `git status --porcelain` (excluding `.trellis/workspace/` and `.trellis/tasks/`) and bails out if anything else is dirty. Step 3 archives the active task plus any cleanup tasks the user confirmed in Step 1. Step 4 records the session journal using hashes from Step 1's recent-commits output. Code commits belong in Phase 3.4, not here. The common skill template uses `{{CMD_REF:finish-work}}` so `cmdRefPrefix` resolves correctly per platform (`/trellis:` for Claude/OpenCode, `$` for Codex, `/trellis-` for Cursor).\n\n**Bug Fixes:**\n- fix(scripts): Stop pruning archived children from a parent task's `children` list. `cmd_archive` previously removed the child name on archive, which made `children_progress` shrink both numerator and denominator (e.g. `[1/6 done]` → `[0/5 done]`, hiding completed work). The list now stays intact; `children_progress` treats children missing from active statuses as completed (cmd_archive sets `status=completed` before moving the dir).\n- fix(update): Hash-track `AGENTS.md` during `trellis update`. Pre-0.5.0-beta.18 projects wrote `AGENTS.md` without recording its template hash, which would surface as a false \"modified by you\" conflict on update. The new `<!-- TRELLIS:START -->` / `<!-- TRELLIS:END -->` managed-block replacement plus a legacy pristine-hash allowlist (`LEGACY_UNTRACKED_AGENTS_MD_BLOCK_HASHES`) lets old untouched projects update cleanly while still preserving any user customizations outside the block.\n- fix(opencode): Support PowerShell context injection in OpenCode on Windows. `inject-subagent-context.js` now emits `$env:TRELLIS_CONTEXT_ID = '...'; ` instead of the POSIX `export` form when the host platform is `win32`, and the explicit-assignment dedup detector matches both POSIX and PowerShell forms.\n\n**Internal:**\n- test: Add `test/setup.ts` registered via `setupFiles` in `vitest.config.ts`. It deletes `process.env.TRELLIS_CONTEXT_ID` and `process.env.OPENCODE_RUN_ID` at vitest process start so the OpenCode resolver tests no longer pick up a Claude/OpenCode host-session env that would hijack the platform-input-derived contextKey.\n- docs(spec): Document the parent-child `children` list invariant in `script-conventions.md` and the host-shell env-leak isolation pattern in `unit-test/conventions.md`.",
7
+ "migrations": [],
8
+ "notes": "Run `trellis update` to receive the Phase 3.4 commit step, the rewritten `/trellis:finish-work` skill, the parent-child progress fix, AGENTS.md hash tracking, and OpenCode PowerShell support. No `--migrate` flag is required."
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.0-beta.19",
3
+ "description": "Beta.19 hot-fixes a regression introduced in beta.18: when an AGENTS.md exists without `<!-- TRELLIS:START -->` / `<!-- TRELLIS:END -->` markers (pre-beta.18 projects, or hand-authored files), `trellis update` was clobbering the user's content with the bare Trellis template. The managed block now appends to the existing file instead of overwriting it. No migration actions are required.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Bug Fixes:**\n- fix(update): Preserve user content in `AGENTS.md` when the file has no `<!-- TRELLIS:START -->` / `<!-- TRELLIS:END -->` markers. Beta.18's managed-block replacement returned the bare template as a fallback when no markers were found, which silently replaced the user's hand-written `AGENTS.md` content during `trellis update`. The fallback now appends the canonical managed block to the existing content instead, so user-authored sections are preserved verbatim. Existing tests cover the legacy-pristine and modified-managed-block cases; the new `#4d preserves user AGENTS.md without TRELLIS markers by appending the managed block` case covers the hand-authored-without-markers path.",
7
+ "migrations": [],
8
+ "notes": "Run `trellis update` to receive the AGENTS.md preservation fix. No `--migrate` flag is required. If beta.18 already overwrote your `AGENTS.md`, restore the file from git history and re-run `trellis update` on beta.19 to merge in the managed block while keeping your content."
9
+ }
@@ -4,6 +4,8 @@
4
4
  "breaking": true,
5
5
  "recommendMigrate": true,
6
6
  "changelog": "**Breaking Changes:**\n- rename(agents): `implement` / `check` / `research` sub-agents are now `trellis-implement` / `trellis-check` / `trellis-research` across all 10 platforms (claude, cursor, opencode, codex, kiro, gemini, qoder, codebuddy, copilot, droid). Generic names were colliding with user-defined agents and being matched by the main agent's description heuristics on some platforms. Prefixing with `trellis-` makes them unambiguously Trellis sub-agents. `workflow.md`, copilot start prompt, `shared-hooks/inject-subagent-context.py`, and configurator detection all updated to use the new names.\n\n**Bug Fixes:**\n- fix(agents): drop `model: opus` from all 18 markdown agent frontmatters + the example `Task()` calls in `copilot/prompts/start.prompt.md`. On Claude Code this merely hardcoded Opus for all sub-agent runs (ignoring user preference); on Cursor it actively mapped to Claude Opus billing at ~5x Sonnet cost and surprised users; on Gemini/Droid/Codebuddy/Qoder `opus` isn't even a valid model identifier. Agents now inherit whatever model the user configured for their platform.",
7
+ "migrationGuide": "## Sub-Agent Rename: `implement` / `check` / `research` → `trellis-*`\n\nbeta.5 renames the three core sub-agents to add a `trellis-` prefix across all 10 agent-capable platforms (Claude, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid). The generic names (`implement`, `check`, `research`) were colliding with user-defined agents in some setups.\n\n### What changes\n\n| Old name | New name |\n|---|---|\n| `implement` | `trellis-implement` |\n| `check` | `trellis-check` |\n| `research` | `trellis-research` |\n\nPaths per platform:\n\n- **Claude / OpenCode / Cursor / etc.**: `.<platform>/agents/implement.md` → `.<platform>/agents/trellis-implement.md`\n- **Codex**: `.codex/agents/implement.toml` → `.codex/agents/trellis-implement.toml`\n- **Kiro**: `.kiro/agents/implement.json` → `.kiro/agents/trellis-implement.json`\n\n### Side-effect: removed `model: opus` from agent templates\n\nAgent YAML frontmatter no longer hardcodes a model. Falls back to whatever the platform default is. If you pinned opus explicitly for a reason (budget, performance), re-add `model: opus` to your local agent files after migrate.\n\n### How to upgrade\n\n```bash\ntrellis update --migrate\n```\n\n30 rename entries run. Unmodified agent files are renamed silently; customized ones (e.g. you tweaked the agent prompt) land on the standard `Modified by you` confirm prompt — pressing Enter (backup-rename) is safe.\n\n### What to check after migrate\n\n1. **Any code that spawns agents by name** — shell scripts, CI jobs, or other automation calling `Task(subagent_type=\"implement\")` must update to `Task(subagent_type=\"trellis-implement\")`.\n2. **Aliases / hot keys** — if you had a keyboard shortcut or prompt alias that referenced `implement` / `check` / `research`, update it.\n3. **Model pin** — if you customized `model: opus` in agent frontmatter, re-add it. Trellis no longer pins a model by default.",
8
+ "aiInstructions": "When helping a user migrate to 0.5.0-beta.5:\n\n1. **Grep for bare agent names in user code**: look for `Task(subagent_type=\"implement\"|\"check\"|\"research\")` in any .md / .ts / .py / shell files. Rename each to the `trellis-` prefixed version.\n\n2. **Check agent customizations**: diff the user's `.<platform>/agents/{implement,check,research}.*` against the new `trellis-*` templates. If they had custom content, help merge it into the new file.\n\n3. **Model pinning**: if their agent frontmatter had `model: opus` and they still want it pinned, re-add it after migrate. beta.5 removes the default pin in favor of platform-default.\n\n4. **Run migrate**: `trellis update --migrate`. Hash-verified renames — pristine files renamed silently, customized files land on the confirm prompt (Enter = backup-rename is safe).\n\n5. **Verify clean second run**: after migrate, running `trellis update` again should report \"Already up to date!\". Any diff indicates a rename that didn't complete (user chose skip on a modified file).",
7
9
  "migrations": [
8
10
  {
9
11
  "type": "rename",
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.0-rc.0",
3
+ "description": "First 0.5.0 release candidate. Stabilizes the beta.19 line with non-interactive init recovery fixes, workflow breadcrumbs that read from workflow.md, automatic updates for [workflow-state:*] blocks, and refreshed trellis-meta references. rc.0 adds no new migration actions; projects upgrading from 0.4.x still inherit the 0.5 migration chain from beta.0.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Enhancements:**\n- feat(workflow-state): Per-turn workflow breadcrumbs now read from `.trellis/workflow.md` `[workflow-state:STATUS]` blocks. Python and OpenCode JS fallback dictionaries were removed so workflow forks have one file to edit. The planning breadcrumb now calls out Phase 1.3 `implement.jsonl` / `check.jsonl` curation, and the in-progress breadcrumb includes Phase 3.4 commit before `/trellis:finish-work`.\n- feat(update): `trellis update` now refreshes `.trellis/workflow.md` breadcrumb blocks per status: replace existing `[workflow-state:*]` bodies from the CLI template, append missing blocks, preserve content outside the blocks, and warn when customized prompt text inside the blocks is replaced.\n- feat(task): `task.py create` best-effort sets the session active-task pointer, making the planning breadcrumb reachable immediately after task creation. `trellis continue` routes by `task.json.status` and required artifacts instead of PRD existence alone.\n- docs(meta): Refresh bundled `trellis-meta` references to explain how workflow-state reads `workflow.md`.\n\n**Bug Fixes:**\n- fix(init): `trellis init --yes` is fully non-interactive. `--yes` now maps conflicts to skip mode, and `writeFile()` falls back to skip in non-TTY `ask` mode to avoid prompts or `ERR_USE_AFTER_CLOSE` in scripted runs.\n- fix(init): Recover aborted first init runs where `.trellis/` exists but `tasks/` is empty. The second `trellis init -u <name> --codex --yes` now creates `00-bootstrap-guidelines` instead of mis-routing to joiner onboarding.\n\n**Testing:**\n- test(init): Add integration coverage for empty-`tasks/` recovery with and without `--force`, plus non-TTY file-writer conflict behavior.\n- test(workflow-state): Add regression coverage for workflow.md tag parsing, fallback removal, Phase 1.3 / Phase 3.4 breadcrumb invariants, session-start tag stripping, and workflow.md breadcrumb block updates.",
7
+ "migrations": [],
8
+ "notes": "RC install: `npm install -g @mindfoldhq/trellis@rc`. Projects already on 0.5 beta can run `trellis update`. Projects upgrading from 0.4.x should run `trellis update --migrate` because the 0.5 migration chain begins at 0.5.0-beta.0. rc.0 itself adds no new migration entries."
9
+ }
@@ -29,7 +29,7 @@ Conversations get compacted; files don't. Every research output MUST end up as a
29
29
 
30
30
  ### Step 1: Resolve Current Task
31
31
 
32
- Read `.trellis/.current-task` → task directory (e.g. `.trellis/tasks/04-17-foo/`). If empty or missing, ask the user where to write output; do NOT guess.
32
+ Run `python3 ./.trellis/scripts/task.py current --source` → active task path. If no active task is set, ask the user where to write output; do NOT guess.
33
33
 
34
34
  Ensure `{TASK_DIR}/research/` exists:
35
35
 
@@ -2,10 +2,6 @@
2
2
  "env": {
3
3
  "CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": "1"
4
4
  },
5
- "statusLine": {
6
- "type": "command",
7
- "command": "{{PYTHON_CMD}} .claude/hooks/statusline.py"
8
- },
9
5
  "hooks": {
10
6
  "SessionStart": [
11
7
  {
@@ -29,7 +29,7 @@ Conversations get compacted; files don't. Every research output MUST end up as a
29
29
 
30
30
  ### Step 1: Resolve Current Task
31
31
 
32
- Read `.trellis/.current-task` → task directory (e.g. `.trellis/tasks/04-17-foo/`). If empty or missing, ask the user where to write output; do NOT guess.
32
+ Run `python3 ./.trellis/scripts/task.py current --source` → active task path. If no active task is set, ask the user where to write output; do NOT guess.
33
33
 
34
34
  Ensure `{TASK_DIR}/research/` exists:
35
35
 
@@ -13,8 +13,9 @@ through the chat reply is a failure.
13
13
 
14
14
  ## Workflow
15
15
 
16
- 1. Read `.trellis/.current-task` to get the task directory. If empty,
17
- ask the user where to write output; do not guess.
16
+ 1. Run `python3 ./.trellis/scripts/task.py current --source` to get the
17
+ active task path and source. If no active task is set, ask the user
18
+ where to write output; do not guess.
18
19
  2. Run `mkdir -p <TASK_DIR>/research` to ensure the directory exists.
19
20
  3. Read `.trellis/workflow.md`, relevant `.trellis/spec/` files, and
20
21
  target code before forming an opinion.
@@ -11,6 +11,7 @@ from __future__ import annotations
11
11
 
12
12
  import json
13
13
  import os
14
+ import re
14
15
  import subprocess
15
16
  import sys
16
17
  import warnings
@@ -19,11 +20,54 @@ from pathlib import Path
19
20
 
20
21
  warnings.filterwarnings("ignore")
21
22
 
23
+ FIRST_REPLY_NOTICE = """<first-reply-notice>
24
+ On the first visible assistant reply in this session, begin with exactly one short Chinese sentence:
25
+ Trellis SessionStart 已注入:workflow、当前任务状态、开发者身份、git 状态、active tasks、spec 索引已加载。
26
+ Then continue directly with the user's request. This notice is one-shot: do not repeat it after the first assistant reply in the same session.
27
+ </first-reply-notice>"""
28
+
22
29
 
23
30
  def should_skip_injection() -> bool:
24
31
  return os.environ.get("CODEX_NON_INTERACTIVE") == "1"
25
32
 
26
33
 
34
+ def configure_project_encoding(project_dir: Path) -> None:
35
+ """Reuse Trellis' shared Windows stdio encoding helper before JSON output."""
36
+ scripts_dir = project_dir / ".trellis" / "scripts"
37
+ if str(scripts_dir) not in sys.path:
38
+ sys.path.insert(0, str(scripts_dir))
39
+
40
+ try:
41
+ from common import configure_encoding # type: ignore[import-not-found]
42
+
43
+ configure_encoding()
44
+ except Exception:
45
+ pass
46
+
47
+
48
+ def _has_curated_jsonl_entry(jsonl_path: Path) -> bool:
49
+ """Return True iff jsonl has at least one row with a ``file`` field.
50
+
51
+ A freshly seeded jsonl only contains a ``{"_example": ...}`` row (no
52
+ ``file`` key) — that is NOT "ready". Readiness requires at least one
53
+ curated entry. Matches the contract used by ``inject-subagent-context.py``.
54
+ """
55
+ try:
56
+ for line in jsonl_path.read_text(encoding="utf-8").splitlines():
57
+ line = line.strip()
58
+ if not line:
59
+ continue
60
+ try:
61
+ row = json.loads(line)
62
+ except json.JSONDecodeError:
63
+ continue
64
+ if isinstance(row, dict) and row.get("file"):
65
+ return True
66
+ except (OSError, UnicodeDecodeError):
67
+ return False
68
+ return False
69
+
70
+
27
71
  def read_file(path: Path, fallback: str = "") -> str:
28
72
  try:
29
73
  return path.read_text(encoding="utf-8")
@@ -31,10 +75,32 @@ def read_file(path: Path, fallback: str = "") -> str:
31
75
  return fallback
32
76
 
33
77
 
34
- def run_script(script_path: Path) -> str:
78
+ def _resolve_context_key(project_dir: Path, hook_input: dict) -> str | None:
79
+ scripts_dir = project_dir / ".trellis" / "scripts"
80
+ if str(scripts_dir) not in sys.path:
81
+ sys.path.insert(0, str(scripts_dir))
82
+ try:
83
+ from common.active_task import resolve_context_key # type: ignore[import-not-found]
84
+ except Exception:
85
+ return None
86
+ return resolve_context_key(hook_input, platform="codex")
87
+
88
+
89
+ def _resolve_active_task(trellis_dir: Path, hook_input: dict):
90
+ scripts_dir = trellis_dir / "scripts"
91
+ if str(scripts_dir) not in sys.path:
92
+ sys.path.insert(0, str(scripts_dir))
93
+ from common.active_task import resolve_active_task # type: ignore[import-not-found]
94
+
95
+ return resolve_active_task(trellis_dir.parent, hook_input, platform="codex")
96
+
97
+
98
+ def run_script(script_path: Path, context_key: str | None = None) -> str:
35
99
  try:
36
100
  env = os.environ.copy()
37
101
  env["PYTHONIOENCODING"] = "utf-8"
102
+ if context_key:
103
+ env["TRELLIS_CONTEXT_ID"] = context_key
38
104
  cmd = [sys.executable, "-W", "ignore", str(script_path)]
39
105
  result = subprocess.run(
40
106
  cmd,
@@ -80,18 +146,15 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
80
146
  return trellis_dir / "tasks" / path_obj
81
147
 
82
148
 
83
- def _get_task_status(trellis_dir: Path) -> str:
84
- current_task_file = trellis_dir / ".current-task"
85
- if not current_task_file.is_file():
86
- return "Status: NO ACTIVE TASK\nNext: Describe what you want to work on"
87
-
88
- task_ref = _normalize_task_ref(current_task_file.read_text(encoding="utf-8").strip())
89
- if not task_ref:
90
- return "Status: NO ACTIVE TASK\nNext: Describe what you want to work on"
149
+ def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
150
+ active = _resolve_active_task(trellis_dir, hook_input)
151
+ if not active.task_path:
152
+ return f"Status: NO ACTIVE TASK\nSource: {active.source}\nNext: Describe what you want to work on"
91
153
 
154
+ task_ref = active.task_path
92
155
  task_dir = _resolve_task_dir(trellis_dir, task_ref)
93
- if not task_dir.is_dir():
94
- return f"Status: STALE POINTER\nTask: {task_ref}\nNext: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
156
+ if active.stale or not task_dir.is_dir():
157
+ return f"Status: STALE POINTER\nTask: {task_ref}\nSource: {active.source}\nNext: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
95
158
 
96
159
  task_json_path = task_dir / "task.json"
97
160
  task_data: dict = {}
@@ -105,24 +168,34 @@ def _get_task_status(trellis_dir: Path) -> str:
105
168
  task_status = task_data.get("status", "unknown")
106
169
 
107
170
  if task_status == "completed":
108
- return f"Status: COMPLETED\nTask: {task_title}\nNext: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` or start a new task"
171
+ return f"Status: COMPLETED\nTask: {task_title}\nSource: {active.source}\nNext: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` or start a new task"
109
172
 
110
173
  has_context = False
111
174
  for jsonl_name in ("implement.jsonl", "check.jsonl", "spec.jsonl"):
112
175
  jsonl_path = task_dir / jsonl_name
113
- if jsonl_path.is_file() and jsonl_path.stat().st_size > 0:
176
+ if jsonl_path.is_file() and _has_curated_jsonl_entry(jsonl_path):
114
177
  has_context = True
115
178
  break
116
179
 
117
180
  has_prd = (task_dir / "prd.md").is_file()
118
181
 
119
182
  if not has_prd:
120
- return f"Status: NOT READY\nTask: {task_title}\nMissing: prd.md not created\nNext: Write PRD, then research init-context start"
183
+ return f"Status: NOT READY\nTask: {task_title}\nSource: {active.source}\nMissing: prd.md not created\nNext: Write PRD (see workflow.md Phase 1.1) then curate implement.jsonl per Phase 1.3"
121
184
 
122
185
  if not has_context:
123
- return f"Status: NOT READY\nTask: {task_title}\nMissing: Context not configured (no jsonl files)\nNext: Complete Phase 2 (research init-context start) before implementing"
124
-
125
- return f"Status: READY\nTask: {task_title}\nNext: Continue with implement or check"
186
+ return f"Status: NOT READY\nTask: {task_title}\nSource: {active.source}\nMissing: implement.jsonl / check.jsonl missing or empty\nNext: Curate entries per workflow.md Phase 1.3 (spec + research files only), then `task.py start`"
187
+
188
+ return (
189
+ f"Status: READY\nTask: {task_title}\n"
190
+ f"Source: {active.source}\n"
191
+ "Next required action: dispatch `trellis-implement` per Phase 2.1. "
192
+ "For agent-capable platforms, the default is to NOT edit code in the main session. "
193
+ "After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
194
+ "User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
195
+ "main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
196
+ "\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
197
+ "Per-turn only; do NOT invent an override the user did not say."
198
+ )
126
199
 
127
200
 
128
201
  def _extract_range(content: str, start_header: str, end_header: str) -> str:
@@ -145,8 +218,24 @@ def _extract_range(content: str, start_header: str, end_header: str) -> str:
145
218
  return "\n".join(lines[start:end]).rstrip()
146
219
 
147
220
 
221
+ _BREADCRUMB_TAG_RE = re.compile(
222
+ r"\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n.*?\n\s*\[/workflow-state:\1\]",
223
+ re.DOTALL,
224
+ )
225
+
226
+
227
+ def _strip_breadcrumb_tag_blocks(content: str) -> str:
228
+ return _BREADCRUMB_TAG_RE.sub("", content)
229
+
230
+
148
231
  def _build_workflow_toc(workflow_path: Path) -> str:
149
- """Inject workflow guide: TOC + Phase Index + Phase 1/2/3 step details."""
232
+ """Inject workflow guide: TOC + Phase Index + Phase 1/2/3 step details.
233
+
234
+ Since v0.5.0-rc.0 the [workflow-state:STATUS] breadcrumb tag blocks
235
+ live inside ## Phase Index. They're consumed by inject-workflow-state.py
236
+ on each UserPromptSubmit, so strip them from the session-start payload
237
+ to avoid duplicating context.
238
+ """
150
239
  content = read_file(workflow_path)
151
240
  if not content:
152
241
  return "No workflow.md found"
@@ -162,9 +251,9 @@ def _build_workflow_toc(workflow_path: Path) -> str:
162
251
  out_lines.append(line)
163
252
  out_lines += ["", "---", ""]
164
253
 
165
- phases = _extract_range(content, "Phase Index", "Workflow State Breadcrumbs")
254
+ phases = _extract_range(content, "Phase Index", "Customizing Trellis (for forks)")
166
255
  if phases:
167
- out_lines.append(phases)
256
+ out_lines.append(_strip_breadcrumb_tag_blocks(phases).rstrip())
168
257
 
169
258
  return "\n".join(out_lines).rstrip()
170
259
 
@@ -176,11 +265,17 @@ def main() -> None:
176
265
  # Read hook input from stdin
177
266
  try:
178
267
  hook_input = json.loads(sys.stdin.read())
268
+ if not isinstance(hook_input, dict):
269
+ hook_input = {}
179
270
  project_dir = Path(hook_input.get("cwd", ".")).resolve()
180
271
  except (json.JSONDecodeError, KeyError):
272
+ hook_input = {}
181
273
  project_dir = Path(".").resolve()
182
274
 
275
+ configure_project_encoding(project_dir)
276
+
183
277
  trellis_dir = project_dir / ".trellis"
278
+ context_key = _resolve_context_key(project_dir, hook_input)
184
279
 
185
280
  output = StringIO()
186
281
 
@@ -190,10 +285,12 @@ Read and follow all instructions below carefully.
190
285
  </session-context>
191
286
 
192
287
  """)
288
+ output.write(FIRST_REPLY_NOTICE)
289
+ output.write("\n\n")
193
290
 
194
291
  output.write("<current-state>\n")
195
292
  context_script = trellis_dir / "scripts" / "get_context.py"
196
- output.write(run_script(context_script))
293
+ output.write(run_script(context_script, context_key))
197
294
  output.write("\n</current-state>\n\n")
198
295
 
199
296
  output.write("<workflow>\n")
@@ -208,8 +305,11 @@ Read and follow all instructions below carefully.
208
305
  "- If you're spawning an implement/check sub-agent, context is injected "
209
306
  "automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
210
307
  "need to read these indexes yourself.\n"
211
- "- If you're editing code directly in the main session, Read the relevant "
212
- "index(es) on-demand and follow their Pre-Dev Checklist.\n\n"
308
+ "- For agent-capable platforms, the default is to dispatch "
309
+ "`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
310
+ "the sub-agents) rather than editing code in the main session. "
311
+ "Honor a per-turn user override only if the user's current message "
312
+ "explicitly opts out (see <task-status> below for override phrases).\n\n"
213
313
  )
214
314
 
215
315
  # guides/ inlined (cross-package thinking, broadly useful)
@@ -253,13 +353,13 @@ Read and follow all instructions below carefully.
253
353
  )
254
354
  output.write("</guidelines>\n\n")
255
355
 
256
- task_status = _get_task_status(trellis_dir)
356
+ task_status = _get_task_status(trellis_dir, hook_input)
257
357
  output.write(f"<task-status>\n{task_status}\n</task-status>\n\n")
258
358
 
259
359
  output.write("""<ready>
260
360
  Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
261
- Wait for the user's first message, then handle it following the workflow guide.
262
- If there is an active task, ask whether to continue it.
361
+ When the user sends the first message, follow <task-status> and the workflow guide.
362
+ If a task is READY, execute its Next required action without asking whether to continue.
263
363
  </ready>""")
264
364
 
265
365
  context = output.getvalue()
@@ -1,148 +1,80 @@
1
1
  ---
2
2
  name: finish-work
3
- description: "Pre-commit quality checklist covering lint, typecheck, tests, code-spec sync, API changes, database migrations, cross-layer verification, and manual testing. Blocks commit if infra or cross-layer specs lack executable depth. Use when code is written and tested but not yet committed, before submitting changes, or as a final review before git commit."
3
+ description: "Wrap up an active Trellis task: archive it (and any other completed-but-unarchived tasks the user wants to clean up) and record a session journal. Refuses to run if the working tree has uncommitted code changes (those belong in workflow Phase 3.4 first). Use when the user asks to finish / wrap up / call it a day, or invokes $finish-work."
4
4
  ---
5
5
 
6
- # Finish Work - Pre-Commit Checklist
6
+ # Finish Work
7
7
 
8
- Before submitting or committing, use this checklist to ensure work completeness.
8
+ Wrap up the current session: archive the active task (and any other completed-but-unarchived tasks the user wants to clean up) and record the session journal. Code commits are NOT done here — those happen in workflow Phase 3.4 before you invoke this skill.
9
9
 
10
- **Timing**: After code is written and tested, before commit
11
-
12
- ---
13
-
14
- ## Checklist
15
-
16
- ### 1. Code Quality
10
+ ## Step 1: Survey current state
17
11
 
18
12
  ```bash
19
- # Must pass
20
- pnpm lint
21
- pnpm type-check
22
- pnpm test
13
+ python3 ./.trellis/scripts/get_context.py --mode record
23
14
  ```
24
15
 
25
- - [ ] `pnpm lint` passes with 0 errors?
26
- - [ ] `pnpm type-check` passes with no type errors?
27
- - [ ] Tests pass?
28
- - [ ] No `console.log` statements (use logger)?
29
- - [ ] No non-null assertions (the `x!` operator)?
30
- - [ ] No `any` types?
31
-
32
- ### 2. Code-Spec Sync
33
-
34
- **Code-Spec Docs**:
35
- - [ ] Does `.trellis/spec/backend/` need updates?
36
- - New patterns, new modules, new conventions
37
- - [ ] Does `.trellis/spec/frontend/` need updates?
38
- - New components, new hooks, new patterns
39
- - [ ] Does `.trellis/spec/guides/` need updates?
40
- - New cross-layer flows, lessons from bugs
41
-
42
- **Key Question**:
43
- > "If I fixed a bug or discovered something non-obvious, should I document it so future me (or others) won't hit the same issue?"
16
+ This prints:
44
17
 
45
- If YES -> Update the relevant code-spec doc.
18
+ - **My active tasks** — review whether any besides the current one are actually done (code merged, AC met) and should be archived this round.
19
+ - **Git status** — quick visual on what's dirty.
20
+ - **Recent commits** — you'll need their hashes in Step 4 for `--commit`.
46
21
 
47
- ### 2.5. Code-Spec Hard Block (Infra/Cross-Layer)
22
+ If `--mode record` surfaces other completed tasks not tied to the current session, surface them to the user with a one-shot confirmation: "These N tasks look done — archive them too in this round? [y/N]". Default is no; the current active task is always archived in Step 3 regardless.
48
23
 
49
- If this change touches infra or cross-layer contracts, this is a blocking checklist:
24
+ ## Step 2: Sanity check working tree must be clean
50
25
 
51
- - [ ] Spec content is executable (real signatures/contracts), not principle-only text
52
- - [ ] Includes file path + command/API name + payload field names
53
- - [ ] Includes validation and error matrix
54
- - [ ] Includes Good/Base/Bad cases
55
- - [ ] Includes required tests and assertion points
26
+ Run:
56
27
 
57
- **Block Rule**:
58
- If infra/cross-layer changed but the related spec is still abstract, do NOT finish. Run `$update-spec` manually first.
59
-
60
- ### 3. API Changes
61
-
62
- If you modified API endpoints:
63
-
64
- - [ ] Input schema updated?
65
- - [ ] Output schema updated?
66
- - [ ] API documentation updated?
67
- - [ ] Client code updated to match?
68
-
69
- ### 4. Database Changes
28
+ ```bash
29
+ git status --porcelain
30
+ ```
70
31
 
71
- If you modified database schema:
32
+ Filter out paths under `.trellis/workspace/` and `.trellis/tasks/` — those are managed by `add_session.py` and `task.py archive` auto-commits and will appear dirty as part of this skill's own work.
72
33
 
73
- - [ ] Migration file created?
74
- - [ ] Schema file updated?
75
- - [ ] Related queries updated?
76
- - [ ] Seed data updated (if applicable)?
34
+ If anything else is dirty (any path outside those two prefixes), **stop and bail out** with:
77
35
 
78
- ### 5. Cross-Layer Verification
36
+ > "Working tree has uncommitted code changes. Return to workflow Phase 3.4 to commit them before running `$finish-work`."
79
37
 
80
- If the change spans multiple layers:
38
+ Do NOT run `git commit` here. Do NOT prompt the user to commit. The user goes back to Phase 3.4 and the AI drives the batched commit there.
81
39
 
82
- - [ ] Data flows correctly through all layers?
83
- - [ ] Error handling works at each boundary?
84
- - [ ] Types are consistent across layers?
85
- - [ ] Loading states handled?
40
+ ## Step 3: Archive task(s)
86
41
 
87
- ### 6. Manual Testing
42
+ ```bash
43
+ python3 ./.trellis/scripts/task.py archive <task-name>
44
+ ```
88
45
 
89
- - [ ] Feature works in browser/app?
90
- - [ ] Edge cases tested?
91
- - [ ] Error states tested?
92
- - [ ] Works after page refresh?
46
+ At minimum: the current active task (if any). Plus any extra tasks the user confirmed in Step 1. Each archive produces a `chore(task): archive ...` commit via the script's auto-commit.
93
47
 
94
- ---
48
+ If there is no active task and the user did not confirm any cleanup archives, skip this step.
95
49
 
96
- ## Quick Check Flow
50
+ ## Step 4: Record session journal
97
51
 
98
52
  ```bash
99
- # 1. Code checks
100
- pnpm lint && pnpm type-check
101
-
102
- # 2. View changes
103
- git status
104
- git diff --name-only
105
-
106
- # 3. Based on changed files, check relevant items above
53
+ python3 ./.trellis/scripts/add_session.py \
54
+ --title "Session Title" \
55
+ --commit "hash1,hash2" \
56
+ --summary "Brief summary"
107
57
  ```
108
58
 
109
- ---
110
-
111
- ## Common Oversights
59
+ Use the work-commit hashes produced in Phase 3.4 (visible in Step 1's `Recent commits` list, or via `git log --oneline`) for `--commit`. Do not include the archive commit hashes from Step 3. This produces a `chore: record journal` commit.
112
60
 
113
- | Oversight | Consequence | Check |
114
- |-----------|-------------|-------|
115
- | Code-spec docs not updated | Others don't know the change | Check .trellis/spec/ |
116
- | Spec text is abstract only | Easy regressions in infra/cross-layer changes | Require signature/contract/matrix/cases/tests |
117
- | Migration not created | Schema out of sync | Check db/migrations/ |
118
- | Types not synced | Runtime errors | Check shared types |
119
- | Tests not updated | False confidence | Run full test suite |
120
- | Console.log left in | Noisy production logs | Search for console.log |
61
+ Final git log order: `<work commits from 3.4>` → `chore(task): archive ...` (one or more) → `chore: record journal`.
121
62
 
122
63
  ---
123
64
 
124
- ## Relationship to Other Commands
65
+ ## Relationship to Other Skills
125
66
 
126
67
  ```
127
68
  Development Flow:
128
- Write code -> Test -> $finish-work -> git commit -> $record-session
129
- | |
130
- Ensure completeness Record progress
131
-
69
+ Phase 3.4 (workflow.md) -> AI drafts batched commits -> user confirms -> git commit
70
+ |
71
+ v
72
+ $finish-work
73
+ (survey + archive + journal)
74
+
132
75
  Debug Flow:
133
76
  Hit bug -> Fix -> $break-loop -> Knowledge capture
134
- |
135
- Deep analysis
136
77
  ```
137
78
 
138
- - `$finish-work` - Check work completeness (this skill)
139
- - `$record-session` - Record session and commits
140
- - `$break-loop` - Deep analysis after debugging
141
-
142
- ---
143
-
144
- ## Core Principle
145
-
146
- > **Delivery includes not just code, but also documentation, verification, and knowledge capture.**
147
-
148
- Complete work = Code + Docs + Tests + Verification
79
+ - `$finish-work` this skill, survey + archive + record session
80
+ - `$break-loop` deep analysis after debugging
@@ -244,17 +244,21 @@ Use this output format:
244
244
 
245
245
  **Step 6: Configure Context** `[AI]`
246
246
 
247
- Initialize default context:
247
+ `implement.jsonl` and `check.jsonl` were seeded on `task.py create` with a single self-describing `_example` line. Curate real entries now (see workflow.md Phase 1.3 for the full rule):
248
+
249
+ - Put **spec files** (`.trellis/spec/<package>/<layer>/*.md`) and **research files** (`{TASK_DIR}/research/*.md`) only.
250
+ - Do NOT put code files (`src/**`, `packages/**`) — those are read during implementation, not pre-registered here.
251
+ - Split: `implement.jsonl` = specs the implement sub-agent needs; `check.jsonl` = specs the check sub-agent needs.
252
+
253
+ Discover available specs:
248
254
 
249
255
  ```bash
250
- python3 ./.trellis/scripts/task.py init-context "$TASK_DIR" <type>
251
- # type: backend | frontend | fullstack
256
+ python3 ./.trellis/scripts/get_context.py --mode packages
252
257
  ```
253
258
 
254
- Add specs found in your research pass:
259
+ Append entries (either edit the jsonl file directly, or):
255
260
 
256
261
  ```bash
257
- # For each relevant spec and code pattern:
258
262
  python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" implement "<path>" "<reason>"
259
263
  python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reason>"
260
264
  ```
@@ -265,7 +269,7 @@ python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reas
265
269
  python3 ./.trellis/scripts/task.py start "$TASK_DIR"
266
270
  ```
267
271
 
268
- This sets `.current-task` so hooks can inject context.
272
+ This sets the active task through Trellis' session resolver so hooks can inject context for this AI session. If the command fails because no session identity is available, rerun it from an IDE/session that exposes session identity or set `TRELLIS_CONTEXT_ID`.
269
273
 
270
274
  ---
271
275
 
@@ -325,9 +329,8 @@ If yes, resume from the appropriate step (usually Step 7 or 8).
325
329
  | Script | Purpose |
326
330
  |--------|---------|
327
331
  | `python3 ./.trellis/scripts/get_context.py` | Get session context |
328
- | `python3 ./.trellis/scripts/task.py create` | Create task directory |
329
- | `python3 ./.trellis/scripts/task.py init-context` | Initialize jsonl files |
330
- | `python3 ./.trellis/scripts/task.py add-context` | Add spec to jsonl |
332
+ | `python3 ./.trellis/scripts/task.py create` | Create task directory (seeds jsonl on sub-agent platforms) |
333
+ | `python3 ./.trellis/scripts/task.py add-context` | Append spec/research entry to jsonl |
331
334
  | `python3 ./.trellis/scripts/task.py start` | Set current task |
332
335
  | `python3 ./.trellis/scripts/task.py finish` | Clear current task |
333
336
  | `python3 ./.trellis/scripts/task.py archive` | Archive completed task |