@mindfoldhq/trellis 0.6.0-beta.9 → 0.6.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 (328) hide show
  1. package/README.md +49 -49
  2. package/dist/cli/index.d.ts.map +1 -1
  3. package/dist/cli/index.js +36 -0
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/commands/channel/adapters/claude.d.ts +29 -0
  6. package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
  7. package/dist/commands/channel/adapters/claude.js +203 -0
  8. package/dist/commands/channel/adapters/claude.js.map +1 -0
  9. package/dist/commands/channel/adapters/codex.d.ts +85 -0
  10. package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
  11. package/dist/commands/channel/adapters/codex.js +505 -0
  12. package/dist/commands/channel/adapters/codex.js.map +1 -0
  13. package/dist/commands/channel/adapters/index.d.ts +84 -0
  14. package/dist/commands/channel/adapters/index.d.ts.map +1 -0
  15. package/dist/commands/channel/adapters/index.js +115 -0
  16. package/dist/commands/channel/adapters/index.js.map +1 -0
  17. package/dist/commands/channel/adapters/types.d.ts +33 -0
  18. package/dist/commands/channel/adapters/types.d.ts.map +1 -0
  19. package/dist/commands/channel/adapters/types.js +2 -0
  20. package/dist/commands/channel/adapters/types.js.map +1 -0
  21. package/dist/commands/channel/agent-loader.d.ts +32 -0
  22. package/dist/commands/channel/agent-loader.d.ts.map +1 -0
  23. package/dist/commands/channel/agent-loader.js +154 -0
  24. package/dist/commands/channel/agent-loader.js.map +1 -0
  25. package/dist/commands/channel/context-loader.d.ts +26 -0
  26. package/dist/commands/channel/context-loader.d.ts.map +1 -0
  27. package/dist/commands/channel/context-loader.js +290 -0
  28. package/dist/commands/channel/context-loader.js.map +1 -0
  29. package/dist/commands/channel/context.d.ts +16 -0
  30. package/dist/commands/channel/context.d.ts.map +1 -0
  31. package/dist/commands/channel/context.js +83 -0
  32. package/dist/commands/channel/context.js.map +1 -0
  33. package/dist/commands/channel/create.d.ts +27 -0
  34. package/dist/commands/channel/create.d.ts.map +1 -0
  35. package/dist/commands/channel/create.js +39 -0
  36. package/dist/commands/channel/create.js.map +1 -0
  37. package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
  38. package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
  39. package/dist/commands/channel/dev-parse-trace.js +70 -0
  40. package/dist/commands/channel/dev-parse-trace.js.map +1 -0
  41. package/dist/commands/channel/guard.d.ts +150 -0
  42. package/dist/commands/channel/guard.d.ts.map +1 -0
  43. package/dist/commands/channel/guard.js +474 -0
  44. package/dist/commands/channel/guard.js.map +1 -0
  45. package/dist/commands/channel/index.d.ts +3 -0
  46. package/dist/commands/channel/index.d.ts.map +1 -0
  47. package/dist/commands/channel/index.js +531 -0
  48. package/dist/commands/channel/index.js.map +1 -0
  49. package/dist/commands/channel/interrupt.d.ts +10 -0
  50. package/dist/commands/channel/interrupt.d.ts.map +1 -0
  51. package/dist/commands/channel/interrupt.js +22 -0
  52. package/dist/commands/channel/interrupt.js.map +1 -0
  53. package/dist/commands/channel/kill.d.ts +7 -0
  54. package/dist/commands/channel/kill.d.ts.map +1 -0
  55. package/dist/commands/channel/kill.js +121 -0
  56. package/dist/commands/channel/kill.js.map +1 -0
  57. package/dist/commands/channel/list.d.ts +17 -0
  58. package/dist/commands/channel/list.d.ts.map +1 -0
  59. package/dist/commands/channel/list.js +233 -0
  60. package/dist/commands/channel/list.js.map +1 -0
  61. package/dist/commands/channel/messages.d.ts +15 -0
  62. package/dist/commands/channel/messages.d.ts.map +1 -0
  63. package/dist/commands/channel/messages.js +245 -0
  64. package/dist/commands/channel/messages.js.map +1 -0
  65. package/dist/commands/channel/rm.d.ts +27 -0
  66. package/dist/commands/channel/rm.d.ts.map +1 -0
  67. package/dist/commands/channel/rm.js +216 -0
  68. package/dist/commands/channel/rm.js.map +1 -0
  69. package/dist/commands/channel/run.d.ts +30 -0
  70. package/dist/commands/channel/run.d.ts.map +1 -0
  71. package/dist/commands/channel/run.js +130 -0
  72. package/dist/commands/channel/run.js.map +1 -0
  73. package/dist/commands/channel/send.d.ts +11 -0
  74. package/dist/commands/channel/send.d.ts.map +1 -0
  75. package/dist/commands/channel/send.js +24 -0
  76. package/dist/commands/channel/send.js.map +1 -0
  77. package/dist/commands/channel/spawn.d.ts +40 -0
  78. package/dist/commands/channel/spawn.d.ts.map +1 -0
  79. package/dist/commands/channel/spawn.js +244 -0
  80. package/dist/commands/channel/spawn.js.map +1 -0
  81. package/dist/commands/channel/store/events.d.ts +39 -0
  82. package/dist/commands/channel/store/events.d.ts.map +1 -0
  83. package/dist/commands/channel/store/events.js +87 -0
  84. package/dist/commands/channel/store/events.js.map +1 -0
  85. package/dist/commands/channel/store/filter.d.ts +3 -0
  86. package/dist/commands/channel/store/filter.d.ts.map +1 -0
  87. package/dist/commands/channel/store/filter.js +2 -0
  88. package/dist/commands/channel/store/filter.js.map +1 -0
  89. package/dist/commands/channel/store/lock.d.ts +23 -0
  90. package/dist/commands/channel/store/lock.d.ts.map +1 -0
  91. package/dist/commands/channel/store/lock.js +99 -0
  92. package/dist/commands/channel/store/lock.js.map +1 -0
  93. package/dist/commands/channel/store/paths.d.ts +63 -0
  94. package/dist/commands/channel/store/paths.d.ts.map +1 -0
  95. package/dist/commands/channel/store/paths.js +246 -0
  96. package/dist/commands/channel/store/paths.js.map +1 -0
  97. package/dist/commands/channel/store/schema.d.ts +27 -0
  98. package/dist/commands/channel/store/schema.d.ts.map +1 -0
  99. package/dist/commands/channel/store/schema.js +34 -0
  100. package/dist/commands/channel/store/schema.js.map +1 -0
  101. package/dist/commands/channel/store/thread-state.d.ts +5 -0
  102. package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
  103. package/dist/commands/channel/store/thread-state.js +16 -0
  104. package/dist/commands/channel/store/thread-state.js.map +1 -0
  105. package/dist/commands/channel/store/watch.d.ts +19 -0
  106. package/dist/commands/channel/store/watch.d.ts.map +1 -0
  107. package/dist/commands/channel/store/watch.js +146 -0
  108. package/dist/commands/channel/store/watch.js.map +1 -0
  109. package/dist/commands/channel/supervisor/idle.d.ts +46 -0
  110. package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
  111. package/dist/commands/channel/supervisor/idle.js +72 -0
  112. package/dist/commands/channel/supervisor/idle.js.map +1 -0
  113. package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
  114. package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
  115. package/dist/commands/channel/supervisor/inbox.js +160 -0
  116. package/dist/commands/channel/supervisor/inbox.js.map +1 -0
  117. package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
  118. package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
  119. package/dist/commands/channel/supervisor/shutdown.js +146 -0
  120. package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
  121. package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
  122. package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
  123. package/dist/commands/channel/supervisor/stdout.js +121 -0
  124. package/dist/commands/channel/supervisor/stdout.js.map +1 -0
  125. package/dist/commands/channel/supervisor/turns.d.ts +31 -0
  126. package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
  127. package/dist/commands/channel/supervisor/turns.js +45 -0
  128. package/dist/commands/channel/supervisor/turns.js.map +1 -0
  129. package/dist/commands/channel/supervisor/warning.d.ts +48 -0
  130. package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
  131. package/dist/commands/channel/supervisor/warning.js +77 -0
  132. package/dist/commands/channel/supervisor/warning.js.map +1 -0
  133. package/dist/commands/channel/supervisor.d.ts +59 -0
  134. package/dist/commands/channel/supervisor.d.ts.map +1 -0
  135. package/dist/commands/channel/supervisor.js +344 -0
  136. package/dist/commands/channel/supervisor.js.map +1 -0
  137. package/dist/commands/channel/text-body.d.ts +13 -0
  138. package/dist/commands/channel/text-body.d.ts.map +1 -0
  139. package/dist/commands/channel/text-body.js +47 -0
  140. package/dist/commands/channel/text-body.js.map +1 -0
  141. package/dist/commands/channel/threads.d.ts +39 -0
  142. package/dist/commands/channel/threads.d.ts.map +1 -0
  143. package/dist/commands/channel/threads.js +106 -0
  144. package/dist/commands/channel/threads.js.map +1 -0
  145. package/dist/commands/channel/title.d.ts +12 -0
  146. package/dist/commands/channel/title.d.ts.map +1 -0
  147. package/dist/commands/channel/title.js +24 -0
  148. package/dist/commands/channel/title.js.map +1 -0
  149. package/dist/commands/channel/wait.d.ts +17 -0
  150. package/dist/commands/channel/wait.d.ts.map +1 -0
  151. package/dist/commands/channel/wait.js +75 -0
  152. package/dist/commands/channel/wait.js.map +1 -0
  153. package/dist/commands/init.d.ts +3 -0
  154. package/dist/commands/init.d.ts.map +1 -1
  155. package/dist/commands/init.js +162 -43
  156. package/dist/commands/init.js.map +1 -1
  157. package/dist/commands/mem.d.ts +13 -217
  158. package/dist/commands/mem.d.ts.map +1 -1
  159. package/dist/commands/mem.js +142 -1587
  160. package/dist/commands/mem.js.map +1 -1
  161. package/dist/commands/uninstall.d.ts.map +1 -1
  162. package/dist/commands/uninstall.js +28 -2
  163. package/dist/commands/uninstall.js.map +1 -1
  164. package/dist/commands/update.d.ts.map +1 -1
  165. package/dist/commands/update.js +102 -5
  166. package/dist/commands/update.js.map +1 -1
  167. package/dist/commands/workflow.d.ts +35 -0
  168. package/dist/commands/workflow.d.ts.map +1 -0
  169. package/dist/commands/workflow.js +232 -0
  170. package/dist/commands/workflow.js.map +1 -0
  171. package/dist/configurators/claude.d.ts.map +1 -1
  172. package/dist/configurators/claude.js +1 -0
  173. package/dist/configurators/claude.js.map +1 -1
  174. package/dist/configurators/index.d.ts.map +1 -1
  175. package/dist/configurators/index.js +5 -0
  176. package/dist/configurators/index.js.map +1 -1
  177. package/dist/configurators/reasonix.d.ts +23 -0
  178. package/dist/configurators/reasonix.d.ts.map +1 -0
  179. package/dist/configurators/reasonix.js +60 -0
  180. package/dist/configurators/reasonix.js.map +1 -0
  181. package/dist/configurators/shared.d.ts.map +1 -1
  182. package/dist/configurators/shared.js +8 -0
  183. package/dist/configurators/shared.js.map +1 -1
  184. package/dist/configurators/workflow.d.ts +8 -0
  185. package/dist/configurators/workflow.d.ts.map +1 -1
  186. package/dist/configurators/workflow.js +14 -3
  187. package/dist/configurators/workflow.js.map +1 -1
  188. package/dist/constants/paths.d.ts +4 -0
  189. package/dist/constants/paths.d.ts.map +1 -1
  190. package/dist/constants/paths.js +4 -0
  191. package/dist/constants/paths.js.map +1 -1
  192. package/dist/migrations/manifests/0.5.14.json +9 -0
  193. package/dist/migrations/manifests/0.5.15.json +9 -0
  194. package/dist/migrations/manifests/0.5.16.json +9 -0
  195. package/dist/migrations/manifests/0.5.17.json +9 -0
  196. package/dist/migrations/manifests/0.5.18.json +9 -0
  197. package/dist/migrations/manifests/0.5.19.json +9 -0
  198. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  199. package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
  200. package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
  201. package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
  202. package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
  203. package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
  204. package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
  205. package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
  206. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  207. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  208. package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
  209. package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
  210. package/dist/migrations/manifests/0.6.0-beta.22.json +9 -0
  211. package/dist/migrations/manifests/0.6.0-beta.23.json +88 -0
  212. package/dist/migrations/manifests/0.6.0-rc.0.json +9 -0
  213. package/dist/migrations/manifests/0.6.0.json +1 -0
  214. package/dist/templates/claude/agents/trellis-check.md +12 -6
  215. package/dist/templates/claude/agents/trellis-implement.md +1 -1
  216. package/dist/templates/claude/agents/trellis-research.md +1 -1
  217. package/dist/templates/codebuddy/agents/trellis-check.md +12 -6
  218. package/dist/templates/codebuddy/agents/trellis-implement.md +1 -1
  219. package/dist/templates/codebuddy/agents/trellis-research.md +1 -1
  220. package/dist/templates/codex/agents/trellis-check.toml +0 -25
  221. package/dist/templates/codex/agents/trellis-implement.toml +0 -25
  222. package/dist/templates/codex/config.toml +9 -16
  223. package/dist/templates/codex/hooks/session-start.py +22 -0
  224. package/dist/templates/codex/hooks.json +1 -1
  225. package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +67 -0
  226. package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +480 -0
  227. package/dist/templates/common/bundled-skills/trellis-channel/references/forum.md +233 -0
  228. package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +226 -0
  229. package/dist/templates/common/bundled-skills/trellis-channel/references/workers.md +276 -0
  230. package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +128 -0
  231. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +46 -34
  232. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +47 -3
  233. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +146 -0
  234. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-channel.md +69 -0
  235. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +27 -0
  236. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +11 -1
  237. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +81 -0
  238. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +66 -0
  239. package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +93 -0
  240. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/SKILL.md +41 -0
  241. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +90 -0
  242. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/repository-analysis.md +59 -0
  243. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +61 -0
  244. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-writing.md +70 -0
  245. package/dist/templates/copilot/hooks/session-start.py +24 -0
  246. package/dist/templates/cursor/agents/trellis-check.md +12 -6
  247. package/dist/templates/cursor/agents/trellis-implement.md +1 -1
  248. package/dist/templates/cursor/agents/trellis-research.md +1 -1
  249. package/dist/templates/cursor/hooks.json +0 -6
  250. package/dist/templates/droid/droids/trellis-check.md +12 -6
  251. package/dist/templates/droid/droids/trellis-implement.md +1 -1
  252. package/dist/templates/droid/droids/trellis-research.md +1 -1
  253. package/dist/templates/gemini/agents/trellis-check.md +11 -5
  254. package/dist/templates/kiro/agents/trellis-check.json +1 -1
  255. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +127 -9
  256. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +130 -0
  257. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +38 -0
  258. package/dist/templates/markdown/spec/guides/index.md.txt +18 -0
  259. package/dist/templates/opencode/agents/trellis-check.md +11 -5
  260. package/dist/templates/pi/agents/trellis-check.md +5 -4
  261. package/dist/templates/pi/agents/trellis-implement.md +5 -4
  262. package/dist/templates/pi/extensions/trellis/index.ts.txt +1339 -913
  263. package/dist/templates/pi/settings.json +0 -9
  264. package/dist/templates/qoder/agents/trellis-check.md +12 -6
  265. package/dist/templates/qoder/agents/trellis-implement.md +1 -1
  266. package/dist/templates/qoder/agents/trellis-research.md +1 -1
  267. package/dist/templates/reasonix/agents/trellis-check.md +36 -0
  268. package/dist/templates/reasonix/agents/trellis-implement.md +41 -0
  269. package/dist/templates/reasonix/index.d.ts +13 -0
  270. package/dist/templates/reasonix/index.d.ts.map +1 -0
  271. package/dist/templates/reasonix/index.js +16 -0
  272. package/dist/templates/reasonix/index.js.map +1 -0
  273. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  274. package/dist/templates/shared-hooks/index.js +0 -1
  275. package/dist/templates/shared-hooks/index.js.map +1 -1
  276. package/dist/templates/shared-hooks/inject-workflow-state.py +22 -0
  277. package/dist/templates/shared-hooks/session-start.py +25 -8
  278. package/dist/templates/trellis/agents/check.md +70 -0
  279. package/dist/templates/trellis/agents/implement.md +71 -0
  280. package/dist/templates/trellis/config.yaml +20 -0
  281. package/dist/templates/trellis/index.d.ts +13 -0
  282. package/dist/templates/trellis/index.d.ts.map +1 -1
  283. package/dist/templates/trellis/index.js +22 -0
  284. package/dist/templates/trellis/index.js.map +1 -1
  285. package/dist/templates/trellis/scripts/common/safe_commit.py +49 -19
  286. package/dist/templates/trellis/scripts/common/task_store.py +94 -16
  287. package/dist/templates/trellis/workflow.md +21 -0
  288. package/dist/types/ai-tools.d.ts +4 -4
  289. package/dist/types/ai-tools.d.ts.map +1 -1
  290. package/dist/types/ai-tools.js +16 -0
  291. package/dist/types/ai-tools.js.map +1 -1
  292. package/dist/utils/agent-refs.d.ts +31 -0
  293. package/dist/utils/agent-refs.d.ts.map +1 -0
  294. package/dist/utils/agent-refs.js +63 -0
  295. package/dist/utils/agent-refs.js.map +1 -0
  296. package/dist/utils/cwd-guard.d.ts +38 -0
  297. package/dist/utils/cwd-guard.d.ts.map +1 -0
  298. package/dist/utils/cwd-guard.js +62 -0
  299. package/dist/utils/cwd-guard.js.map +1 -0
  300. package/dist/utils/file-writer.d.ts +13 -0
  301. package/dist/utils/file-writer.d.ts.map +1 -1
  302. package/dist/utils/file-writer.js +59 -1
  303. package/dist/utils/file-writer.js.map +1 -1
  304. package/dist/utils/manifest-prune.d.ts +61 -0
  305. package/dist/utils/manifest-prune.d.ts.map +1 -0
  306. package/dist/utils/manifest-prune.js +136 -0
  307. package/dist/utils/manifest-prune.js.map +1 -0
  308. package/dist/utils/registry-config.d.ts +7 -0
  309. package/dist/utils/registry-config.d.ts.map +1 -0
  310. package/dist/utils/registry-config.js +171 -0
  311. package/dist/utils/registry-config.js.map +1 -0
  312. package/dist/utils/task-json.d.ts +9 -42
  313. package/dist/utils/task-json.d.ts.map +1 -1
  314. package/dist/utils/task-json.js +8 -45
  315. package/dist/utils/task-json.js.map +1 -1
  316. package/dist/utils/template-fetcher.d.ts +11 -0
  317. package/dist/utils/template-fetcher.d.ts.map +1 -1
  318. package/dist/utils/template-fetcher.js +51 -2
  319. package/dist/utils/template-fetcher.js.map +1 -1
  320. package/dist/utils/template-hash.d.ts +32 -6
  321. package/dist/utils/template-hash.d.ts.map +1 -1
  322. package/dist/utils/template-hash.js +53 -31
  323. package/dist/utils/template-hash.js.map +1 -1
  324. package/dist/utils/workflow-resolver.d.ts +86 -0
  325. package/dist/utils/workflow-resolver.d.ts.map +1 -0
  326. package/dist/utils/workflow-resolver.js +265 -0
  327. package/dist/utils/workflow-resolver.js.map +1 -0
  328. package/package.json +9 -8
@@ -58,6 +58,29 @@ grep -r "keyword" .
58
58
 
59
59
  **Good**: Single source of truth, import everywhere
60
60
 
61
+ ### Pattern 4: Repeated Payload Field Extraction
62
+
63
+ **Bad**: Multiple consumers cast the same JSON/event fields locally:
64
+
65
+ ```typescript
66
+ const description = (ev as { description?: string }).description;
67
+ const context = (ev as { context?: ContextEntry[] }).context;
68
+ ```
69
+
70
+ This is duplicated contract logic even when the code is only two lines. Each
71
+ consumer now has its own definition of what a valid payload means.
72
+
73
+ **Good**: Put the decoder, type guard, or projection next to the data owner:
74
+
75
+ ```typescript
76
+ if (isThreadEvent(ev)) {
77
+ renderThreadEvent(ev);
78
+ }
79
+ ```
80
+
81
+ **Rule**: If the same untyped payload field is read in 2+ places, create a
82
+ shared type guard / normalizer / projection before adding a third reader.
83
+
61
84
  ---
62
85
 
63
86
  ## When to Abstract
@@ -82,6 +105,74 @@ When you've made similar changes to multiple files:
82
105
  2. **Search**: Run grep to find any missed
83
106
  3. **Consider**: Should this be abstracted?
84
107
 
108
+ ### Reducers Should Use Exhaustive Structure
109
+
110
+ When state is derived from action-like values (`action`, `kind`, `status`,
111
+ `phase`), prefer a reducer with one `switch` over scattered `if/else` updates.
112
+
113
+ ```typescript
114
+ // BAD - action-specific state transitions are hard to audit
115
+ if (action === "opened") { ... }
116
+ else if (action === "comment") { ... }
117
+ else if (action === "status") { ... }
118
+
119
+ // GOOD - one reducer owns the transition table
120
+ switch (event.action) {
121
+ case "opened":
122
+ ...
123
+ return;
124
+ case "comment":
125
+ ...
126
+ return;
127
+ }
128
+ ```
129
+
130
+ This matters when the event log is the source of truth. A reducer is the
131
+ documented replay model; display code and commands should not duplicate pieces
132
+ of that replay model.
133
+
134
+ ---
135
+
136
+ ## Checklist Before Commit
137
+
138
+ - [ ] Searched for existing similar code
139
+ - [ ] No copy-pasted logic that should be shared
140
+ - [ ] No repeated untyped payload field extraction outside a shared decoder
141
+ - [ ] Constants defined in one place
142
+ - [ ] Similar patterns follow same structure
143
+ - [ ] Reducer/action transitions live in one reducer or command dispatcher
144
+
145
+ ---
146
+
147
+ ## Gotcha: Python if/elif/else Exhaustive Check
148
+
149
+ **Problem**: Python's if/elif/else chains have no compile-time exhaustive check. When you add a new value to a `Literal` type (e.g., `Platform`), existing if/elif/else chains silently fall through to `else` with wrong defaults.
150
+
151
+ **Symptom**: New platform works partially — some methods return Claude defaults instead of platform-specific values. No error is raised.
152
+
153
+ **Example** (`cli_adapter.py`):
154
+ ```python
155
+ # BAD: "gemini" falls through to else, returns "claude"
156
+ @property
157
+ def cli_name(self) -> str:
158
+ if self.platform == "opencode":
159
+ return "opencode"
160
+ else:
161
+ return "claude" # gemini silently gets "claude"!
162
+
163
+ # GOOD: explicit branch for every platform
164
+ @property
165
+ def cli_name(self) -> str:
166
+ if self.platform == "opencode":
167
+ return "opencode"
168
+ elif self.platform == "gemini":
169
+ return "gemini"
170
+ else:
171
+ return "claude"
172
+ ```
173
+
174
+ **Prevention**: When adding a new value to a Python `Literal` type, search for ALL if/elif/else chains that switch on that type and add explicit branches. Don't rely on `else` being correct for new values.
175
+
85
176
  ---
86
177
 
87
178
  ## Gotcha: Asymmetric Mechanisms Producing Same Output
@@ -90,16 +181,43 @@ When you've made similar changes to multiple files:
90
181
 
91
182
  **Symptom**: Init works perfectly, but update creates files at wrong paths or misses files entirely.
92
183
 
93
- **Prevention checklist**:
94
- - [ ] When migrating directory structures, search for ALL code paths that reference the old structure
95
- - [ ] If one path is auto-derived (glob/copy) and another is manually listed, the manual one needs updating
96
- - [ ] Add a regression test that compares outputs from both mechanisms
184
+ **Prevention**:
185
+ - **Best**: Eliminate the asymmetry have the manual path call the automatic one (e.g., `collectTemplateFiles()` calls `getAllScripts()` instead of maintaining its own list)
186
+ - **If asymmetry is unavoidable**: Add a regression test that compares outputs from both mechanisms
187
+ - When migrating directory structures, search for ALL code paths that reference the old structure
188
+
189
+ **Real example**: `trellis update` had a manual `files.set()` list for 11 scripts that `getAllScripts()` already tracked. Fix: replaced the manual list with a `for..of getAllScripts()` loop. See `update.ts` refactor in v0.4.0-beta.3.
97
190
 
98
191
  ---
99
192
 
100
- ## Checklist Before Commit
193
+ ## Template File Registration (Trellis-specific)
101
194
 
102
- - [ ] Searched for existing similar code
103
- - [ ] No copy-pasted logic that should be shared
104
- - [ ] Constants defined in one place
105
- - [ ] Similar patterns follow same structure
195
+ When adding new files to `src/templates/trellis/scripts/`:
196
+
197
+ **Single registration point**: `src/templates/trellis/index.ts`
198
+
199
+ 1. Add `export const xxxScript = readTemplate("scripts/path/file.py");`
200
+ 2. Add to `getAllScripts()` Map
201
+
202
+ That's it. `commands/update.ts` uses `getAllScripts()` directly — no manual sync needed.
203
+
204
+ **Why this matters**: Without registration in `getAllScripts()`, `trellis update` won't sync the file to user projects. Bug fixes and features won't propagate.
205
+
206
+ **History**: Before v0.4.0-beta.3, `update.ts` had its own hand-maintained file list that frequently fell out of sync with `getAllScripts()`. This caused 11 Python files to be silently skipped during `trellis update`. The fix was to eliminate the duplicate list and use `getAllScripts()` as the single source of truth.
207
+
208
+ ### Quick Checklist for New Scripts
209
+
210
+ ```bash
211
+ # After adding a new .py file, verify it's in getAllScripts():
212
+ grep -l "newFileName" src/templates/trellis/index.ts # Should match
213
+ ```
214
+
215
+ ### Template Sync Convention
216
+
217
+ `.trellis/scripts/` (dogfooded) and `packages/cli/src/templates/trellis/scripts/` (template) must stay identical. After editing `.trellis/scripts/`, always sync:
218
+
219
+ ```bash
220
+ rsync -av --delete --exclude='__pycache__' .trellis/scripts/ packages/cli/src/templates/trellis/scripts/
221
+ ```
222
+
223
+ **Gotcha**: Running rsync with wrong source/destination paths can create nested garbage directories (e.g., `.trellis/scripts/packages/cli/...`). Always double-check paths before running.
@@ -71,6 +71,35 @@ For each boundary:
71
71
 
72
72
  **Good**: Each layer only knows its neighbors
73
73
 
74
+ ### Mistake 4: Every Consumer Parses The Same Payload
75
+
76
+ **Bad**: A command reads JSONL events and casts fields inline:
77
+
78
+ ```typescript
79
+ const thread = (ev as { thread?: string }).thread;
80
+ const labels = (ev as { labels?: string[] }).labels;
81
+ ```
82
+
83
+ This looks local, but it means every consumer owns a private version of the
84
+ event contract. The next field change will update one command and miss another.
85
+
86
+ **Good**: Decode once at the event boundary, then export typed projections:
87
+
88
+ ```typescript
89
+ if (!isThreadEvent(ev)) return false;
90
+ return ev.thread === filter.thread;
91
+ ```
92
+
93
+ **Rule**: For append-only logs, JSON streams, RPC payloads, or config files,
94
+ create one owner for:
95
+
96
+ - event / payload type definitions
97
+ - type guards and normalization from `unknown`
98
+ - metadata projections used by UI commands
99
+ - reducers that replay state from the source of truth
100
+
101
+ Rendering code may format fields, but it must not redefine the payload contract.
102
+
74
103
  ---
75
104
 
76
105
  ## Checklist for Cross-Layer Features
@@ -87,6 +116,10 @@ After implementation:
87
116
  - [ ] Tested with edge cases (null, empty, invalid)
88
117
  - [ ] Verified error handling at each boundary
89
118
  - [ ] Checked data survives round-trip
119
+ - [ ] Checked that consumers import shared decoders / projections instead of
120
+ casting payload fields locally
121
+ - [ ] Checked that derived state points back to the source event identifier
122
+ (`seq`, `id`, `version`) instead of inventing a second cursor
90
123
 
91
124
  ---
92
125
 
@@ -187,6 +220,74 @@ When a CLI auto-detects a mode by probing a remote resource (e.g., checking if `
187
220
 
188
221
  ---
189
222
 
223
+ ## Cross-Platform Template Consistency
224
+
225
+ In Trellis, command templates (e.g., `record-session.md`) exist in **multiple platforms** with identical or near-identical content. This is a cross-layer boundary.
226
+
227
+ ### Checklist: After Modifying Any Command Template
228
+
229
+ - [ ] Find all platforms with the same command: `find src/templates/*/commands/trellis/ -name "<command>.*"`
230
+ - [ ] Update all platform copies (Markdown `.md` and TOML `.toml`)
231
+ - [ ] For Gemini TOML: adapt line continuations (`\\` vs `\`) and triple-quoted strings
232
+ - [ ] Run `/trellis:check-cross-layer` to verify nothing was missed
233
+
234
+ **Real-world example**: Updated `record-session.md` in Claude to use `--mode record`, but forgot iFlow, Kilo, OpenCode, and Gemini — caught by cross-layer check.
235
+
236
+ ---
237
+
238
+ ## Generated Runtime Template Upgrade Consistency
239
+
240
+ Some generated files are both documentation and runtime input. In Trellis,
241
+ `.trellis/workflow.md` is parsed by `get_context.py`, `workflow_phase.py`,
242
+ SessionStart filters, and per-turn hooks. Template changes must be validated
243
+ against both fresh init and upgrade paths.
244
+
245
+ ### Checklist: After Modifying A Runtime-Parsed Template
246
+
247
+ - [ ] Identify every runtime parser that reads the template, not just the file
248
+ writer that installs it
249
+ - [ ] Check whether relevant syntax lives outside obvious managed regions
250
+ such as tag blocks
251
+ - [ ] Verify fresh `init` output and a versioned `update` scenario that writes
252
+ the older `.trellis/.version`
253
+ - [ ] Add an upgrade regression using an older pristine template fixture, then
254
+ assert the installed file reaches the current packaged shape
255
+ - [ ] Update the backend spec that owns the runtime contract
256
+
257
+ **Real-world example**: Codex inline mode changed workflow platform markers from
258
+ `[Codex]` / `[Kilo, Antigravity, Windsurf]` to `[codex-sub-agent]` /
259
+ `[codex-inline, Kilo, Antigravity, Windsurf]`. Fresh init was correct, but
260
+ `trellis update` only merged `[workflow-state:*]` blocks and preserved stale
261
+ markers outside those blocks. Result: upgraded projects got new hook scripts
262
+ but old workflow routing, so `get_context.py --mode phase --platform codex`
263
+ could return empty Phase 2.1 detail.
264
+
265
+ ---
266
+
267
+ ## Mode-Detection Probe Checklist
268
+
269
+ When a CLI auto-detects a mode by probing a remote resource (e.g., checking if `index.json` exists to decide marketplace vs direct download):
270
+
271
+ ### Before implementing:
272
+ - [ ] Probe runs in **ALL** code paths that use the result (interactive, `-y`, `--flag` combos)
273
+ - [ ] 404 vs transient error are distinguished — don't treat both as "not found"
274
+ - [ ] Transient errors **abort or retry**, never silently switch modes
275
+ - [ ] Shared state (caches, prefetched data) is **reset** when context changes (e.g., user switches source)
276
+ - [ ] **Shortcut paths** (e.g., `--template` skipping picker) must have the same error-handling quality as the probed path — check that downstream functions don't call catch-all wrappers
277
+
278
+ ### After implementing:
279
+ - [ ] Trace every path from probe result to the mode-decision branch — no fallthrough
280
+ - [ ] External format contracts (giget URI, raw URLs) are tested or at least documented as comments
281
+ - [ ] Metadata reads consume a complete response or use a streaming parser — never parse a fixed-size prefix as full JSON
282
+ - [ ] When reconstructing a composite identifier from parsed parts, verify **all** fields are included and in the **correct position** (e.g., `provider:repo/path#ref` not `provider:repo#ref/path`)
283
+ - [ ] Verify that **action functions** called after a shortcut don't internally use the old catch-all fetch — they must use the probe-quality variant when error distinction matters
284
+
285
+ **Real-world example**: Custom registry flow had 8 bugs across 3 review rounds: (1) probe only ran in interactive mode, (2) transient errors fell through to wrong mode, (3) giget URI had `#ref` in wrong position, (4) prefetched templates leaked across source switches, (5) `--template` shortcut bypassed probe but `downloadTemplateById` internally used catch-all `fetchTemplateIndex`, turning timeouts into "Template not found".
286
+
287
+ **Real-world example**: Agent-session update hints fetched npm `latest` metadata with `response.read(4096)` and then parsed it as complete JSON. The `@mindfoldhq/trellis` package metadata exceeded 4 KB, so the JSON was truncated, parse failed silently, and the first session injection showed no update hint. Fix: read the complete response before parsing, and add a regression where `version` is followed by an 8 KB metadata tail.
288
+
289
+ ---
290
+
190
291
  ## When to Create Flow Documentation
191
292
 
192
293
  Create detailed flow docs when:
@@ -195,3 +296,32 @@ Create detailed flow docs when:
195
296
  - Multiple teams are involved
196
297
  - Data format is complex
197
298
  - Feature has caused bugs before
299
+
300
+ ---
301
+
302
+ ## Event Log / Projection Boundary
303
+
304
+ Append-only logs are cross-layer contracts. A single event travels through:
305
+
306
+ ```
307
+ CLI input → event writer → events.jsonl → reader → filter → reducer → display
308
+ ```
309
+
310
+ ### Checklist: After Adding A New Event Kind Or Field
311
+
312
+ - [ ] Add the event kind to the central event taxonomy
313
+ - [ ] Add a typed event variant or type guard at the event layer
314
+ - [ ] Add normalization helpers for array/object fields that come from
315
+ user input or JSON
316
+ - [ ] Keep `seq` / `id` assignment in the event writer only
317
+ - [ ] Make filters and reducers consume the typed event guard, not local casts
318
+ - [ ] Make display code consume reducer output or typed events, not raw JSON
319
+ - [ ] Add at least one regression that proves history replay and live filtering
320
+ use the same filter model
321
+
322
+ **Real-world example**: Thread channels added `kind: "thread"`, `description`,
323
+ `context`, labels, and `lastSeq`. The first implementation replayed thread
324
+ state correctly, but several commands still re-parsed event payload fields with
325
+ local casts. The fix was to make the core event layer own `ThreadChannelEvent`
326
+ and `isThreadEvent`, make `reduceChannelMetadata` the only channel metadata
327
+ projection, and make `reduceThreads` the only thread replay reducer.
@@ -593,3 +593,41 @@ const { getMigrationsForVersion } = require('./dist/migrations/index.js');
593
593
  console.log('From 0.2.12:', getMigrationsForVersion('0.2.12', 'CURRENT').length);
594
594
  "
595
595
  ```
596
+
597
+ ## Release Checklist: Bundled Assets
598
+
599
+ When release notes or docs claim an asset is bundled, installed automatically, or
600
+ included with Trellis, verify the whole distribution path:
601
+
602
+ - [ ] Source file exists in the branch being tagged, not only in another branch,
603
+ docs submodule, or marketplace tree.
604
+ - [ ] `pnpm build` copies the asset into `dist/templates/**`.
605
+ - [ ] `npm pack --dry-run --json` includes the expected `dist/**` path.
606
+ - [ ] The built binary installs the asset in a fresh temp repository.
607
+ - [ ] `.trellis/.template-hashes.json` tracks the generated asset path.
608
+ - [ ] `trellis update --dry-run` reports `Already up to date!` in that temp
609
+ repository.
610
+
611
+ **Why this matters**: docs/changelog text can move independently from the code
612
+ branch that owns distributable templates. A feature can be documented as bundled
613
+ while the published npm tarball still lacks the files.
614
+
615
+ ```bash
616
+ pnpm --filter @mindfoldhq/trellis build
617
+
618
+ cd packages/cli
619
+ npm pack --dry-run --json | grep 'dist/templates/common/bundled-skills/<skill>/SKILL.md'
620
+ cd ../..
621
+
622
+ tmpdir=$(mktemp -d /tmp/trellis-built-bin-smoke-XXXXXX)
623
+ printf '{"name":"trellis-smoke","version":"0.0.0"}\n' > "$tmpdir/package.json"
624
+ git -C "$tmpdir" init -q
625
+ (
626
+ cd "$tmpdir"
627
+ node /path/to/Trellis/packages/cli/bin/trellis.js init -u smoke --yes --claude --codex
628
+ test -f .claude/skills/<skill>/SKILL.md
629
+ test -f .agents/skills/<skill>/SKILL.md
630
+ grep -q '<skill>' .trellis/.template-hashes.json
631
+ node /path/to/Trellis/packages/cli/bin/trellis.js update --dry-run
632
+ )
633
+ ```
@@ -34,6 +34,8 @@ These guides help you **ask the right questions before coding**.
34
34
  - [ ] Data format changes between layers
35
35
  - [ ] Multiple consumers need the same data
36
36
  - [ ] You're not sure where to put some logic
37
+ - [ ] You are adding an event kind, JSONL record, RPC payload, or config field
38
+ - [ ] UI / command code starts casting raw payload fields directly
37
39
 
38
40
  → Read [Cross-Layer Thinking Guide](./cross-layer-thinking-guide.md)
39
41
 
@@ -44,9 +46,25 @@ These guides help you **ask the right questions before coding**.
44
46
  - [ ] You're adding a new field to multiple places
45
47
  - [ ] **You're modifying any constant or config**
46
48
  - [ ] **You're creating a new utility/helper function** ← Search first!
49
+ - [ ] Two files read the same untyped payload field with local casts
50
+ - [ ] Multiple branches update the same derived state from `kind` / `action`
47
51
 
48
52
  → Read [Code Reuse Thinking Guide](./code-reuse-thinking-guide.md)
49
53
 
54
+ ### When Verifying AI Cross-Review Results
55
+
56
+ - [ ] Reviewer claims "user input can be malicious" → Check the actual data source (internal manifest? user config? external API?)
57
+ - [ ] Reviewer flags "missing validation" → Is the data from a trusted internal source?
58
+ - [ ] Reviewer says "behavior change" → Read the code comments — is it intentional design?
59
+ - [ ] Reviewer identifies a "bug" in test → Mentally delete the feature being tested — does the test still pass? If yes → tautological test
60
+
61
+ **Common AI reviewer false-positive patterns**:
62
+ 1. **Trust boundary confusion**: Treating internal data (bundled JSON manifests) as untrusted external input
63
+ 2. **Ignoring design comments**: Flagging intentional behavior documented in code comments as bugs
64
+ 3. **Variable misreading**: Not tracing a variable to its actual definition (e.g., Map keyed by path vs name)
65
+
66
+ **Verification rule**: Every CRITICAL/WARNING finding must be verified against the actual code before prioritizing. Budget ~35% false-positive rate for AI reviews.
67
+
50
68
  ---
51
69
 
52
70
  ## Pre-Modification Rule (CRITICAL)
@@ -34,14 +34,18 @@ Look for the `<!-- trellis-hook-injected -->` marker in your input above.
34
34
 
35
35
  Before checking, read:
36
36
  - `.trellis/spec/` - Development guidelines
37
+ - Task `prd.md` - Requirements document
38
+ - Task `design.md` - Technical design (if exists)
39
+ - Task `implement.md` - Execution plan (if exists)
37
40
  - Pre-commit checklist for quality standards
38
41
 
39
42
  ## Core Responsibilities
40
43
 
41
44
  1. **Get code changes** - Use git diff to get uncommitted code
42
- 2. **Check against specs** - Verify code follows guidelines
43
- 3. **Self-fix** - Fix issues yourself, not just report them
44
- 4. **Run verification** - typecheck and lint
45
+ 2. **Review task artifacts** - Check changes against prd.md, design.md if present, and implement.md if present
46
+ 3. **Check against specs** - Verify code follows guidelines
47
+ 4. **Self-fix** - Fix issues yourself, not just report them
48
+ 5. **Run verification** - typecheck and lint
45
49
 
46
50
  ## Important
47
51
 
@@ -60,10 +64,12 @@ git diff --name-only # List changed files
60
64
  git diff # View specific changes
61
65
  ```
62
66
 
63
- ### Step 2: Check Against Specs
67
+ ### Step 2: Check Against Specs and Task Artifacts
64
68
 
65
- Read relevant specs in `.trellis/spec/` to check code:
69
+ Read the task's prd.md, design.md if present, and implement.md if present, then read relevant specs in `.trellis/spec/` to check code:
66
70
 
71
+ - Does it satisfy the task requirements
72
+ - Does it follow the technical design and implementation plan when present
67
73
  - Does it follow directory structure conventions
68
74
  - Does it follow naming conventions
69
75
  - Does it follow code patterns
@@ -19,10 +19,11 @@ You are already the `trellis-check` sub-agent that the main session dispatched.
19
19
  ## Core Responsibilities
20
20
 
21
21
  1. Inspect the current git diff.
22
- 2. Read and follow the spec and research files listed in the task's `check.jsonl`.
23
- 3. Review all changed code against the task PRD and project specs.
24
- 4. Fix issues directly when they are within scope.
25
- 5. Run the relevant lint, typecheck, and focused tests available for the touched code.
22
+ 2. Read `prd.md`, `design.md` if present, and `implement.md` if present.
23
+ 3. Read and follow the spec and research files listed in the task's `check.jsonl`.
24
+ 4. Review all changed code against the task artifacts and project specs.
25
+ 5. Fix issues directly when they are within scope.
26
+ 6. Run the relevant lint, typecheck, and focused tests available for the touched code.
26
27
 
27
28
  ## Review Priorities
28
29
 
@@ -19,10 +19,11 @@ You are already the `trellis-implement` sub-agent that the main session dispatch
19
19
  ## Core Responsibilities
20
20
 
21
21
  1. Understand the active task requirements.
22
- 2. Read and follow the spec and research files listed in the task's `implement.jsonl`.
23
- 3. Implement the requested change using existing project patterns.
24
- 4. Run the relevant lint, typecheck, and focused tests available for the touched code.
25
- 5. Report files changed and verification results.
22
+ 2. Read `prd.md`, `design.md` if present, and `implement.md` if present.
23
+ 3. Read and follow the spec and research files listed in the task's `implement.jsonl`.
24
+ 4. Implement the requested change using existing project patterns.
25
+ 5. Run the relevant lint, typecheck, and focused tests available for the touched code.
26
+ 6. Report files changed and verification results.
26
27
 
27
28
  ## Forbidden Operations
28
29