@mindfoldhq/trellis 0.4.0 → 0.5.0-beta.10

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 (427) hide show
  1. package/dist/cli/index.js +0 -1
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/commands/init.d.ts +10 -1
  4. package/dist/commands/init.d.ts.map +1 -1
  5. package/dist/commands/init.js +382 -120
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/commands/update.d.ts +5 -0
  8. package/dist/commands/update.d.ts.map +1 -1
  9. package/dist/commands/update.js +178 -61
  10. package/dist/commands/update.js.map +1 -1
  11. package/dist/configurators/antigravity.d.ts +3 -4
  12. package/dist/configurators/antigravity.d.ts.map +1 -1
  13. package/dist/configurators/antigravity.js +17 -10
  14. package/dist/configurators/antigravity.js.map +1 -1
  15. package/dist/configurators/claude.d.ts +5 -28
  16. package/dist/configurators/claude.d.ts.map +1 -1
  17. package/dist/configurators/claude.js +30 -51
  18. package/dist/configurators/claude.js.map +1 -1
  19. package/dist/configurators/codebuddy.d.ts +6 -7
  20. package/dist/configurators/codebuddy.d.ts.map +1 -1
  21. package/dist/configurators/codebuddy.js +23 -51
  22. package/dist/configurators/codebuddy.js.map +1 -1
  23. package/dist/configurators/codex.d.ts +3 -6
  24. package/dist/configurators/codex.d.ts.map +1 -1
  25. package/dist/configurators/codex.js +29 -12
  26. package/dist/configurators/codex.js.map +1 -1
  27. package/dist/configurators/copilot.d.ts +6 -5
  28. package/dist/configurators/copilot.d.ts.map +1 -1
  29. package/dist/configurators/copilot.js +42 -13
  30. package/dist/configurators/copilot.js.map +1 -1
  31. package/dist/configurators/cursor.d.ts +6 -1
  32. package/dist/configurators/cursor.d.ts.map +1 -1
  33. package/dist/configurators/cursor.js +22 -45
  34. package/dist/configurators/cursor.js.map +1 -1
  35. package/dist/configurators/droid.d.ts +6 -1
  36. package/dist/configurators/droid.d.ts.map +1 -1
  37. package/dist/configurators/droid.js +23 -41
  38. package/dist/configurators/droid.js.map +1 -1
  39. package/dist/configurators/gemini.d.ts +8 -4
  40. package/dist/configurators/gemini.d.ts.map +1 -1
  41. package/dist/configurators/gemini.js +28 -47
  42. package/dist/configurators/gemini.js.map +1 -1
  43. package/dist/configurators/index.d.ts +1 -1
  44. package/dist/configurators/index.d.ts.map +1 -1
  45. package/dist/configurators/index.js +146 -100
  46. package/dist/configurators/index.js.map +1 -1
  47. package/dist/configurators/kilo.d.ts +3 -4
  48. package/dist/configurators/kilo.d.ts.map +1 -1
  49. package/dist/configurators/kilo.js +19 -46
  50. package/dist/configurators/kilo.js.map +1 -1
  51. package/dist/configurators/kiro.d.ts +4 -4
  52. package/dist/configurators/kiro.d.ts.map +1 -1
  53. package/dist/configurators/kiro.js +18 -14
  54. package/dist/configurators/kiro.js.map +1 -1
  55. package/dist/configurators/opencode.d.ts +7 -25
  56. package/dist/configurators/opencode.d.ts.map +1 -1
  57. package/dist/configurators/opencode.js +57 -56
  58. package/dist/configurators/opencode.js.map +1 -1
  59. package/dist/configurators/qoder.d.ts +6 -3
  60. package/dist/configurators/qoder.d.ts.map +1 -1
  61. package/dist/configurators/qoder.js +27 -46
  62. package/dist/configurators/qoder.js.map +1 -1
  63. package/dist/configurators/shared.d.ts +68 -3
  64. package/dist/configurators/shared.d.ts.map +1 -1
  65. package/dist/configurators/shared.js +274 -3
  66. package/dist/configurators/shared.js.map +1 -1
  67. package/dist/configurators/windsurf.d.ts +3 -4
  68. package/dist/configurators/windsurf.d.ts.map +1 -1
  69. package/dist/configurators/windsurf.js +17 -10
  70. package/dist/configurators/windsurf.js.map +1 -1
  71. package/dist/configurators/workflow.d.ts +0 -3
  72. package/dist/configurators/workflow.d.ts.map +1 -1
  73. package/dist/configurators/workflow.js +1 -7
  74. package/dist/configurators/workflow.js.map +1 -1
  75. package/dist/migrations/manifests/0.4.0.json +1 -1
  76. package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
  77. package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
  78. package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
  79. package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
  80. package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
  81. package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
  82. package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
  83. package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
  84. package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
  85. package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
  86. package/dist/templates/claude/agents/{check.md → trellis-check.md} +3 -31
  87. package/dist/templates/claude/agents/{implement.md → trellis-implement.md} +1 -2
  88. package/dist/templates/claude/agents/trellis-research.md +137 -0
  89. package/dist/templates/claude/index.d.ts +5 -37
  90. package/dist/templates/claude/index.d.ts.map +1 -1
  91. package/dist/templates/claude/index.js +3 -42
  92. package/dist/templates/claude/index.js.map +1 -1
  93. package/dist/templates/claude/settings.json +6 -4
  94. package/dist/templates/{iflow/agents/check.md → codebuddy/agents/trellis-check.md} +3 -31
  95. package/dist/templates/{iflow/agents/implement.md → codebuddy/agents/trellis-implement.md} +1 -2
  96. package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
  97. package/dist/templates/codebuddy/index.d.ts +6 -16
  98. package/dist/templates/codebuddy/index.d.ts.map +1 -1
  99. package/dist/templates/codebuddy/index.js +6 -36
  100. package/dist/templates/codebuddy/index.js.map +1 -1
  101. package/dist/templates/codebuddy/settings.json +59 -0
  102. package/dist/templates/codex/agents/trellis-check.toml +38 -0
  103. package/dist/templates/codex/agents/{implement.toml → trellis-implement.toml} +1 -1
  104. package/dist/templates/codex/agents/trellis-research.toml +60 -0
  105. package/dist/templates/codex/config.toml +10 -0
  106. package/dist/templates/codex/hooks/session-start.py +65 -29
  107. package/dist/templates/codex/hooks.json +11 -0
  108. package/dist/templates/codex/index.d.ts +0 -1
  109. package/dist/templates/codex/index.d.ts.map +1 -1
  110. package/dist/templates/codex/index.js +1 -8
  111. package/dist/templates/codex/index.js.map +1 -1
  112. package/dist/templates/codex/skills/start/SKILL.md +1 -1
  113. package/dist/templates/common/commands/continue.md +51 -0
  114. package/dist/templates/common/commands/finish-work.md +32 -0
  115. package/dist/templates/common/commands/start.md +56 -0
  116. package/dist/templates/common/index.d.ts +28 -0
  117. package/dist/templates/common/index.d.ts.map +1 -0
  118. package/dist/templates/common/index.js +55 -0
  119. package/dist/templates/common/index.js.map +1 -0
  120. package/dist/templates/{droid/commands/trellis → common/skills}/brainstorm.md +51 -12
  121. package/dist/templates/{iflow/commands/trellis → common/skills}/break-loop.md +4 -4
  122. package/dist/templates/common/skills/check.md +87 -0
  123. package/dist/templates/{codebuddy/commands/trellis → common/skills}/update-spec.md +18 -21
  124. package/dist/templates/copilot/hooks/session-start.py +65 -29
  125. package/dist/templates/copilot/hooks.json +8 -0
  126. package/dist/templates/copilot/prompts/start.prompt.md +13 -16
  127. package/dist/templates/cursor/agents/trellis-check.md +94 -0
  128. package/dist/templates/cursor/agents/trellis-implement.md +94 -0
  129. package/dist/templates/cursor/agents/trellis-research.md +137 -0
  130. package/dist/templates/cursor/hooks.json +24 -0
  131. package/dist/templates/cursor/index.d.ts +6 -17
  132. package/dist/templates/cursor/index.d.ts.map +1 -1
  133. package/dist/templates/cursor/index.js +6 -37
  134. package/dist/templates/cursor/index.js.map +1 -1
  135. package/dist/templates/droid/droids/trellis-check.md +94 -0
  136. package/dist/templates/droid/droids/trellis-implement.md +94 -0
  137. package/dist/templates/droid/droids/trellis-research.md +137 -0
  138. package/dist/templates/droid/index.d.ts +7 -19
  139. package/dist/templates/droid/index.d.ts.map +1 -1
  140. package/dist/templates/droid/index.js +7 -39
  141. package/dist/templates/droid/index.js.map +1 -1
  142. package/dist/templates/droid/settings.json +59 -0
  143. package/dist/templates/extract.d.ts +7 -193
  144. package/dist/templates/extract.d.ts.map +1 -1
  145. package/dist/templates/extract.js +7 -310
  146. package/dist/templates/extract.js.map +1 -1
  147. package/dist/templates/gemini/agents/trellis-check.md +94 -0
  148. package/dist/templates/gemini/agents/trellis-implement.md +94 -0
  149. package/dist/templates/gemini/agents/trellis-research.md +137 -0
  150. package/dist/templates/gemini/index.d.ts +6 -14
  151. package/dist/templates/gemini/index.d.ts.map +1 -1
  152. package/dist/templates/gemini/index.js +6 -37
  153. package/dist/templates/gemini/index.js.map +1 -1
  154. package/dist/templates/gemini/settings.json +28 -0
  155. package/dist/templates/kiro/agents/trellis-check.json +13 -0
  156. package/dist/templates/kiro/agents/trellis-implement.json +13 -0
  157. package/dist/templates/kiro/agents/trellis-research.json +21 -0
  158. package/dist/templates/kiro/index.d.ts +11 -11
  159. package/dist/templates/kiro/index.d.ts.map +1 -1
  160. package/dist/templates/kiro/index.js +11 -33
  161. package/dist/templates/kiro/index.js.map +1 -1
  162. package/dist/templates/opencode/agents/{check.md → trellis-check.md} +3 -30
  163. package/dist/templates/opencode/agents/{implement.md → trellis-implement.md} +1 -1
  164. package/dist/templates/opencode/agents/{research.md → trellis-research.md} +1 -2
  165. package/dist/templates/opencode/plugins/inject-subagent-context.js +18 -190
  166. package/dist/templates/opencode/plugins/inject-workflow-state.js +172 -0
  167. package/dist/templates/opencode/plugins/session-start.js +76 -39
  168. package/dist/templates/qoder/agents/trellis-check.md +94 -0
  169. package/dist/templates/qoder/agents/trellis-implement.md +94 -0
  170. package/dist/templates/qoder/agents/trellis-research.md +137 -0
  171. package/dist/templates/qoder/index.d.ts +7 -10
  172. package/dist/templates/qoder/index.d.ts.map +1 -1
  173. package/dist/templates/qoder/index.js +7 -32
  174. package/dist/templates/qoder/index.js.map +1 -1
  175. package/dist/templates/qoder/settings.json +47 -0
  176. package/dist/templates/shared-hooks/index.d.ts +19 -0
  177. package/dist/templates/shared-hooks/index.d.ts.map +1 -0
  178. package/dist/templates/shared-hooks/index.js +30 -0
  179. package/dist/templates/shared-hooks/index.js.map +1 -0
  180. package/dist/templates/{iflow/hooks → shared-hooks}/inject-subagent-context.py +77 -266
  181. package/dist/templates/shared-hooks/inject-workflow-state.py +244 -0
  182. package/dist/templates/{claude/hooks → shared-hooks}/session-start.py +172 -55
  183. package/dist/templates/template-utils.d.ts +26 -0
  184. package/dist/templates/template-utils.d.ts.map +1 -0
  185. package/dist/templates/template-utils.js +60 -0
  186. package/dist/templates/template-utils.js.map +1 -0
  187. package/dist/templates/trellis/config.yaml +6 -0
  188. package/dist/templates/trellis/index.d.ts +1 -15
  189. package/dist/templates/trellis/index.d.ts.map +1 -1
  190. package/dist/templates/trellis/index.js +2 -29
  191. package/dist/templates/trellis/index.js.map +1 -1
  192. package/dist/templates/trellis/scripts/common/cli_adapter.py +31 -8
  193. package/dist/templates/trellis/scripts/common/config.py +126 -1
  194. package/dist/templates/trellis/scripts/common/git_context.py +25 -2
  195. package/dist/templates/trellis/scripts/common/task_context.py +23 -28
  196. package/dist/templates/trellis/scripts/common/task_store.py +0 -12
  197. package/dist/templates/trellis/scripts/common/types.py +0 -2
  198. package/dist/templates/trellis/scripts/common/workflow_phase.py +176 -0
  199. package/dist/templates/trellis/scripts/task.py +13 -35
  200. package/dist/templates/trellis/workflow.md +283 -298
  201. package/dist/types/ai-tools.d.ts +30 -3
  202. package/dist/types/ai-tools.d.ts.map +1 -1
  203. package/dist/types/ai-tools.js +119 -15
  204. package/dist/types/ai-tools.js.map +1 -1
  205. package/dist/types/migration.d.ts +8 -1
  206. package/dist/types/migration.d.ts.map +1 -1
  207. package/dist/utils/project-detector.d.ts +2 -0
  208. package/dist/utils/project-detector.d.ts.map +1 -1
  209. package/dist/utils/project-detector.js +120 -11
  210. package/dist/utils/project-detector.js.map +1 -1
  211. package/dist/utils/task-json.d.ts +46 -0
  212. package/dist/utils/task-json.d.ts.map +1 -0
  213. package/dist/utils/task-json.js +49 -0
  214. package/dist/utils/task-json.js.map +1 -0
  215. package/package.json +3 -2
  216. package/dist/configurators/iflow.d.ts +0 -33
  217. package/dist/configurators/iflow.d.ts.map +0 -1
  218. package/dist/configurators/iflow.js +0 -99
  219. package/dist/configurators/iflow.js.map +0 -1
  220. package/dist/templates/antigravity/index.d.ts +0 -12
  221. package/dist/templates/antigravity/index.d.ts.map +0 -1
  222. package/dist/templates/antigravity/index.js +0 -29
  223. package/dist/templates/antigravity/index.js.map +0 -1
  224. package/dist/templates/claude/agents/debug.md +0 -106
  225. package/dist/templates/claude/agents/dispatch.md +0 -213
  226. package/dist/templates/claude/agents/plan.md +0 -396
  227. package/dist/templates/claude/agents/research.md +0 -120
  228. package/dist/templates/claude/commands/trellis/brainstorm.md +0 -487
  229. package/dist/templates/claude/commands/trellis/break-loop.md +0 -125
  230. package/dist/templates/claude/commands/trellis/check-cross-layer.md +0 -153
  231. package/dist/templates/claude/commands/trellis/check.md +0 -25
  232. package/dist/templates/claude/commands/trellis/create-command.md +0 -154
  233. package/dist/templates/claude/commands/trellis/finish-work.md +0 -153
  234. package/dist/templates/claude/commands/trellis/integrate-skill.md +0 -219
  235. package/dist/templates/claude/commands/trellis/onboard.md +0 -358
  236. package/dist/templates/claude/commands/trellis/parallel.md +0 -192
  237. package/dist/templates/claude/commands/trellis/record-session.md +0 -62
  238. package/dist/templates/claude/commands/trellis/start.md +0 -393
  239. package/dist/templates/claude/commands/trellis/update-spec.md +0 -354
  240. package/dist/templates/claude/hooks/inject-subagent-context.py +0 -803
  241. package/dist/templates/claude/hooks/ralph-loop.py +0 -396
  242. package/dist/templates/codebuddy/commands/trellis/before-dev.md +0 -29
  243. package/dist/templates/codebuddy/commands/trellis/brainstorm.md +0 -487
  244. package/dist/templates/codebuddy/commands/trellis/break-loop.md +0 -107
  245. package/dist/templates/codebuddy/commands/trellis/check-cross-layer.md +0 -153
  246. package/dist/templates/codebuddy/commands/trellis/check.md +0 -25
  247. package/dist/templates/codebuddy/commands/trellis/create-command.md +0 -154
  248. package/dist/templates/codebuddy/commands/trellis/finish-work.md +0 -143
  249. package/dist/templates/codebuddy/commands/trellis/integrate-skill.md +0 -219
  250. package/dist/templates/codebuddy/commands/trellis/onboard.md +0 -358
  251. package/dist/templates/codebuddy/commands/trellis/record-session.md +0 -61
  252. package/dist/templates/codebuddy/commands/trellis/start.md +0 -373
  253. package/dist/templates/codex/agents/check.toml +0 -23
  254. package/dist/templates/codex/agents/research.toml +0 -26
  255. package/dist/templates/codex/codex-skills/parallel/SKILL.md +0 -194
  256. package/dist/templates/cursor/commands/trellis-before-dev.md +0 -29
  257. package/dist/templates/cursor/commands/trellis-brainstorm.md +0 -487
  258. package/dist/templates/cursor/commands/trellis-break-loop.md +0 -107
  259. package/dist/templates/cursor/commands/trellis-check-cross-layer.md +0 -153
  260. package/dist/templates/cursor/commands/trellis-check.md +0 -25
  261. package/dist/templates/cursor/commands/trellis-create-command.md +0 -154
  262. package/dist/templates/cursor/commands/trellis-finish-work.md +0 -143
  263. package/dist/templates/cursor/commands/trellis-integrate-skill.md +0 -219
  264. package/dist/templates/cursor/commands/trellis-onboard.md +0 -358
  265. package/dist/templates/cursor/commands/trellis-record-session.md +0 -62
  266. package/dist/templates/cursor/commands/trellis-start.md +0 -373
  267. package/dist/templates/cursor/commands/trellis-update-spec.md +0 -354
  268. package/dist/templates/droid/commands/trellis/before-dev.md +0 -33
  269. package/dist/templates/droid/commands/trellis/break-loop.md +0 -111
  270. package/dist/templates/droid/commands/trellis/check-cross-layer.md +0 -157
  271. package/dist/templates/droid/commands/trellis/check.md +0 -29
  272. package/dist/templates/droid/commands/trellis/create-command.md +0 -158
  273. package/dist/templates/droid/commands/trellis/finish-work.md +0 -147
  274. package/dist/templates/droid/commands/trellis/integrate-skill.md +0 -223
  275. package/dist/templates/droid/commands/trellis/onboard.md +0 -362
  276. package/dist/templates/droid/commands/trellis/record-session.md +0 -66
  277. package/dist/templates/droid/commands/trellis/start.md +0 -377
  278. package/dist/templates/droid/commands/trellis/update-spec.md +0 -358
  279. package/dist/templates/gemini/commands/trellis/before-dev.toml +0 -33
  280. package/dist/templates/gemini/commands/trellis/brainstorm.toml +0 -435
  281. package/dist/templates/gemini/commands/trellis/break-loop.toml +0 -129
  282. package/dist/templates/gemini/commands/trellis/check-cross-layer.toml +0 -147
  283. package/dist/templates/gemini/commands/trellis/check.toml +0 -29
  284. package/dist/templates/gemini/commands/trellis/create-command.toml +0 -119
  285. package/dist/templates/gemini/commands/trellis/finish-work.toml +0 -133
  286. package/dist/templates/gemini/commands/trellis/integrate-skill.toml +0 -104
  287. package/dist/templates/gemini/commands/trellis/onboard.toml +0 -111
  288. package/dist/templates/gemini/commands/trellis/record-session.toml +0 -66
  289. package/dist/templates/gemini/commands/trellis/start.toml +0 -354
  290. package/dist/templates/gemini/commands/trellis/update-spec.toml +0 -132
  291. package/dist/templates/iflow/agents/debug.md +0 -106
  292. package/dist/templates/iflow/agents/dispatch.md +0 -213
  293. package/dist/templates/iflow/agents/plan.md +0 -396
  294. package/dist/templates/iflow/agents/research.md +0 -120
  295. package/dist/templates/iflow/commands/trellis/before-dev.md +0 -29
  296. package/dist/templates/iflow/commands/trellis/brainstorm.md +0 -487
  297. package/dist/templates/iflow/commands/trellis/check-cross-layer.md +0 -153
  298. package/dist/templates/iflow/commands/trellis/check.md +0 -25
  299. package/dist/templates/iflow/commands/trellis/create-command.md +0 -152
  300. package/dist/templates/iflow/commands/trellis/finish-work.md +0 -153
  301. package/dist/templates/iflow/commands/trellis/integrate-skill.md +0 -219
  302. package/dist/templates/iflow/commands/trellis/onboard.md +0 -358
  303. package/dist/templates/iflow/commands/trellis/parallel.md +0 -192
  304. package/dist/templates/iflow/commands/trellis/record-session.md +0 -62
  305. package/dist/templates/iflow/commands/trellis/start.md +0 -393
  306. package/dist/templates/iflow/commands/trellis/update-spec.md +0 -354
  307. package/dist/templates/iflow/hooks/ralph-loop.py +0 -395
  308. package/dist/templates/iflow/hooks/session-start.py +0 -403
  309. package/dist/templates/iflow/index.d.ts +0 -54
  310. package/dist/templates/iflow/index.d.ts.map +0 -1
  311. package/dist/templates/iflow/index.js +0 -85
  312. package/dist/templates/iflow/index.js.map +0 -1
  313. package/dist/templates/iflow/settings.json +0 -60
  314. package/dist/templates/kilo/index.d.ts +0 -16
  315. package/dist/templates/kilo/index.d.ts.map +0 -1
  316. package/dist/templates/kilo/index.js +0 -39
  317. package/dist/templates/kilo/index.js.map +0 -1
  318. package/dist/templates/kilo/workflows/before-dev.md +0 -29
  319. package/dist/templates/kilo/workflows/brainstorm.md +0 -487
  320. package/dist/templates/kilo/workflows/break-loop.md +0 -125
  321. package/dist/templates/kilo/workflows/check-cross-layer.md +0 -153
  322. package/dist/templates/kilo/workflows/check.md +0 -25
  323. package/dist/templates/kilo/workflows/create-command.md +0 -152
  324. package/dist/templates/kilo/workflows/finish-work.md +0 -129
  325. package/dist/templates/kilo/workflows/integrate-skill.md +0 -219
  326. package/dist/templates/kilo/workflows/onboard.md +0 -358
  327. package/dist/templates/kilo/workflows/parallel.md +0 -193
  328. package/dist/templates/kilo/workflows/record-session.md +0 -62
  329. package/dist/templates/kilo/workflows/start.md +0 -387
  330. package/dist/templates/kilo/workflows/update-spec.md +0 -285
  331. package/dist/templates/kiro/skills/before-dev/SKILL.md +0 -34
  332. package/dist/templates/kiro/skills/brainstorm/SKILL.md +0 -492
  333. package/dist/templates/kiro/skills/break-loop/SKILL.md +0 -130
  334. package/dist/templates/kiro/skills/check/SKILL.md +0 -30
  335. package/dist/templates/kiro/skills/check-cross-layer/SKILL.md +0 -158
  336. package/dist/templates/kiro/skills/create-command/SKILL.md +0 -101
  337. package/dist/templates/kiro/skills/finish-work/SKILL.md +0 -148
  338. package/dist/templates/kiro/skills/integrate-skill/SKILL.md +0 -221
  339. package/dist/templates/kiro/skills/onboard/SKILL.md +0 -363
  340. package/dist/templates/kiro/skills/record-session/SKILL.md +0 -67
  341. package/dist/templates/kiro/skills/start/SKILL.md +0 -351
  342. package/dist/templates/kiro/skills/update-spec/SKILL.md +0 -335
  343. package/dist/templates/markdown/spec/backend/directory-structure.md +0 -292
  344. package/dist/templates/markdown/spec/backend/index.md +0 -40
  345. package/dist/templates/markdown/spec/backend/script-conventions.md +0 -742
  346. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md +0 -118
  347. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md +0 -394
  348. package/dist/templates/opencode/agents/debug.md +0 -129
  349. package/dist/templates/opencode/agents/dispatch.md +0 -223
  350. package/dist/templates/opencode/agents/trellis-plan.md +0 -427
  351. package/dist/templates/opencode/commands/trellis/before-dev.md +0 -29
  352. package/dist/templates/opencode/commands/trellis/brainstorm.md +0 -487
  353. package/dist/templates/opencode/commands/trellis/break-loop.md +0 -125
  354. package/dist/templates/opencode/commands/trellis/check-cross-layer.md +0 -153
  355. package/dist/templates/opencode/commands/trellis/check.md +0 -25
  356. package/dist/templates/opencode/commands/trellis/create-command.md +0 -154
  357. package/dist/templates/opencode/commands/trellis/finish-work.md +0 -144
  358. package/dist/templates/opencode/commands/trellis/integrate-skill.md +0 -219
  359. package/dist/templates/opencode/commands/trellis/migrate-specs.md +0 -0
  360. package/dist/templates/opencode/commands/trellis/onboard.md +0 -358
  361. package/dist/templates/opencode/commands/trellis/parallel.md +0 -193
  362. package/dist/templates/opencode/commands/trellis/record-session.md +0 -62
  363. package/dist/templates/opencode/commands/trellis/start.md +0 -351
  364. package/dist/templates/opencode/commands/trellis/update-spec.md +0 -354
  365. package/dist/templates/qoder/skills/before-dev/SKILL.md +0 -34
  366. package/dist/templates/qoder/skills/brainstorm/SKILL.md +0 -492
  367. package/dist/templates/qoder/skills/break-loop/SKILL.md +0 -130
  368. package/dist/templates/qoder/skills/check/SKILL.md +0 -30
  369. package/dist/templates/qoder/skills/check-cross-layer/SKILL.md +0 -158
  370. package/dist/templates/qoder/skills/create-command/SKILL.md +0 -101
  371. package/dist/templates/qoder/skills/finish-work/SKILL.md +0 -134
  372. package/dist/templates/qoder/skills/integrate-skill/SKILL.md +0 -221
  373. package/dist/templates/qoder/skills/onboard/SKILL.md +0 -363
  374. package/dist/templates/qoder/skills/record-session/SKILL.md +0 -67
  375. package/dist/templates/qoder/skills/start/SKILL.md +0 -388
  376. package/dist/templates/qoder/skills/update-spec/SKILL.md +0 -290
  377. package/dist/templates/trellis/scripts/common/phase.py +0 -254
  378. package/dist/templates/trellis/scripts/common/registry.py +0 -335
  379. package/dist/templates/trellis/scripts/common/worktree.py +0 -305
  380. package/dist/templates/trellis/scripts/create_bootstrap.py +0 -298
  381. package/dist/templates/trellis/scripts/multi_agent/__init__.py +0 -5
  382. package/dist/templates/trellis/scripts/multi_agent/_bootstrap.py +0 -17
  383. package/dist/templates/trellis/scripts/multi_agent/cleanup.py +0 -398
  384. package/dist/templates/trellis/scripts/multi_agent/create_pr.py +0 -620
  385. package/dist/templates/trellis/scripts/multi_agent/plan.py +0 -213
  386. package/dist/templates/trellis/scripts/multi_agent/start.py +0 -539
  387. package/dist/templates/trellis/scripts/multi_agent/status.py +0 -76
  388. package/dist/templates/trellis/scripts/multi_agent/status_display.py +0 -542
  389. package/dist/templates/trellis/scripts/multi_agent/status_monitor.py +0 -225
  390. package/dist/templates/trellis/scripts-shell-archive/add-session.sh +0 -384
  391. package/dist/templates/trellis/scripts-shell-archive/common/developer.sh +0 -129
  392. package/dist/templates/trellis/scripts-shell-archive/common/git-context.sh +0 -263
  393. package/dist/templates/trellis/scripts-shell-archive/common/paths.sh +0 -208
  394. package/dist/templates/trellis/scripts-shell-archive/common/phase.sh +0 -150
  395. package/dist/templates/trellis/scripts-shell-archive/common/registry.sh +0 -247
  396. package/dist/templates/trellis/scripts-shell-archive/common/task-queue.sh +0 -142
  397. package/dist/templates/trellis/scripts-shell-archive/common/task-utils.sh +0 -151
  398. package/dist/templates/trellis/scripts-shell-archive/common/worktree.sh +0 -128
  399. package/dist/templates/trellis/scripts-shell-archive/create-bootstrap.sh +0 -299
  400. package/dist/templates/trellis/scripts-shell-archive/get-context.sh +0 -7
  401. package/dist/templates/trellis/scripts-shell-archive/get-developer.sh +0 -15
  402. package/dist/templates/trellis/scripts-shell-archive/init-developer.sh +0 -34
  403. package/dist/templates/trellis/scripts-shell-archive/multi-agent/cleanup.sh +0 -396
  404. package/dist/templates/trellis/scripts-shell-archive/multi-agent/create-pr.sh +0 -241
  405. package/dist/templates/trellis/scripts-shell-archive/multi-agent/plan.sh +0 -207
  406. package/dist/templates/trellis/scripts-shell-archive/multi-agent/start.sh +0 -317
  407. package/dist/templates/trellis/scripts-shell-archive/multi-agent/status.sh +0 -828
  408. package/dist/templates/trellis/scripts-shell-archive/task.sh +0 -1204
  409. package/dist/templates/trellis/worktree.yaml +0 -47
  410. package/dist/templates/windsurf/index.d.ts +0 -21
  411. package/dist/templates/windsurf/index.d.ts.map +0 -1
  412. package/dist/templates/windsurf/index.js +0 -44
  413. package/dist/templates/windsurf/index.js.map +0 -1
  414. package/dist/templates/windsurf/workflows/trellis-before-dev.md +0 -31
  415. package/dist/templates/windsurf/workflows/trellis-brainstorm.md +0 -491
  416. package/dist/templates/windsurf/workflows/trellis-break-loop.md +0 -111
  417. package/dist/templates/windsurf/workflows/trellis-check-cross-layer.md +0 -157
  418. package/dist/templates/windsurf/workflows/trellis-check.md +0 -27
  419. package/dist/templates/windsurf/workflows/trellis-create-command.md +0 -154
  420. package/dist/templates/windsurf/workflows/trellis-finish-work.md +0 -147
  421. package/dist/templates/windsurf/workflows/trellis-integrate-skill.md +0 -220
  422. package/dist/templates/windsurf/workflows/trellis-onboard.md +0 -362
  423. package/dist/templates/windsurf/workflows/trellis-record-session.md +0 -66
  424. package/dist/templates/windsurf/workflows/trellis-start.md +0 -373
  425. package/dist/templates/windsurf/workflows/trellis-update-spec.md +0 -358
  426. /package/dist/templates/{claude/commands/trellis → common/skills}/before-dev.md +0 -0
  427. /package/dist/templates/{claude/hooks → shared-hooks}/statusline.py +0 -0
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env python3
2
+ """Trellis UserPromptSubmit hook: inject per-turn workflow breadcrumb.
3
+
4
+ Runs on every user prompt. Reads the active task (.trellis/.current-task)
5
+ and emits a short <workflow-state> block reminding the main AI what task
6
+ is active and its expected flow. Breadcrumb text is pulled from
7
+ workflow.md [workflow-state:STATUS] tag blocks (single source of truth
8
+ for users who fork the Trellis workflow), with hardcoded fallbacks so
9
+ the hook never breaks when workflow.md is missing or malformed.
10
+
11
+ Shared across all hook-capable platforms (Claude, Cursor, Codex, Qoder,
12
+ CodeBuddy, Droid, Gemini, Copilot). Kiro is not wired (no per-turn
13
+ hook entry point). Written to each platform's hooks directory via
14
+ writeSharedHooks() at init time.
15
+
16
+ Silent exit 0 cases (no output):
17
+ - No .trellis/ directory found (not a Trellis project)
18
+ - No .current-task file, or it's empty
19
+ - task.json malformed or missing status
20
+
21
+ Unknown status (no tag + no hardcoded fallback) emits a generic
22
+ breadcrumb rather than silent-exiting, so custom statuses surface in
23
+ the UI instead of appearing as "randomly broken".
24
+ """
25
+ from __future__ import annotations
26
+
27
+ import json
28
+ import os
29
+ import re
30
+ import sys
31
+ from pathlib import Path
32
+ from typing import Optional, Tuple
33
+
34
+
35
+ # ---------------------------------------------------------------------------
36
+ # CWD-robust Trellis root discovery (fixes hook-path-robustness for this hook)
37
+ # ---------------------------------------------------------------------------
38
+
39
+ def find_trellis_root(start: Path) -> Optional[Path]:
40
+ """Walk up from start to find directory containing .trellis/.
41
+
42
+ Handles CWD drift: subdirectory launches, monorepo packages, etc.
43
+ Returns None if no .trellis/ found (silent no-op).
44
+ """
45
+ cur = start.resolve()
46
+ while cur != cur.parent:
47
+ if (cur / ".trellis").is_dir():
48
+ return cur
49
+ cur = cur.parent
50
+ return None
51
+
52
+
53
+ # ---------------------------------------------------------------------------
54
+ # Active task discovery
55
+ # ---------------------------------------------------------------------------
56
+
57
+ def _normalize_task_ref(task_ref: str) -> str:
58
+ """Normalize .current-task path ref.
59
+
60
+ Accepts:
61
+ - Absolute paths (left as-is)
62
+ - Windows-style backslashes (converted to forward slash)
63
+ - Legacy relative refs like "tasks/foo" (prefixed with .trellis/)
64
+ """
65
+ normalized = task_ref.strip()
66
+ if not normalized:
67
+ return ""
68
+ path_obj = Path(normalized)
69
+ if path_obj.is_absolute():
70
+ return str(path_obj)
71
+ normalized = normalized.replace("\\", "/")
72
+ while normalized.startswith("./"):
73
+ normalized = normalized[2:]
74
+ if normalized.startswith("tasks/"):
75
+ normalized = f".trellis/{normalized}"
76
+ return normalized
77
+
78
+
79
+ def get_active_task(root: Path) -> Optional[Tuple[str, str]]:
80
+ """Return (task_id, status) from the current active task, else None.
81
+
82
+ Reads .trellis/.current-task (a path relative to root, e.g.
83
+ ".trellis/tasks/04-17-foo") then that task's task.json.
84
+ Normalizes backslashes so Windows paths work on Unix and vice versa.
85
+ """
86
+ ref_file = root / ".trellis" / ".current-task"
87
+ if not ref_file.is_file():
88
+ return None
89
+ try:
90
+ raw = ref_file.read_text(encoding="utf-8").strip()
91
+ except OSError:
92
+ return None
93
+ task_ref = _normalize_task_ref(raw)
94
+ if not task_ref:
95
+ return None
96
+
97
+ path_obj = Path(task_ref)
98
+ task_dir = path_obj if path_obj.is_absolute() else root / path_obj
99
+ task_json = task_dir / "task.json"
100
+ if not task_json.is_file():
101
+ return None
102
+ try:
103
+ data = json.loads(task_json.read_text(encoding="utf-8"))
104
+ except (json.JSONDecodeError, OSError):
105
+ return None
106
+
107
+ task_id = data.get("id") or task_dir.name
108
+ status = data.get("status", "")
109
+ if not isinstance(status, str) or not status:
110
+ return None
111
+ return task_id, status
112
+
113
+
114
+ # ---------------------------------------------------------------------------
115
+ # Breadcrumb loading: parse workflow.md, fall back to hardcoded defaults
116
+ # ---------------------------------------------------------------------------
117
+
118
+ # Supports STATUS values with letters, digits, underscores, hyphens
119
+ # (so "in-review" / "blocked-by-team" work alongside "in_progress").
120
+ _TAG_RE = re.compile(
121
+ r"\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n(.*?)\n\s*\[/workflow-state:\1\]",
122
+ re.DOTALL,
123
+ )
124
+
125
+ # Hardcoded defaults for built-in Trellis statuses. Used when workflow.md is
126
+ # missing, malformed, or lacks the tag for this status.
127
+ #
128
+ # `no_task` is a pseudo-status emitted when .current-task is missing — it keeps
129
+ # the Next-Action reminder flowing per-turn even without an active task.
130
+ _FALLBACK_BREADCRUMBS = {
131
+ "no_task": (
132
+ "No active task.\n"
133
+ "Trigger words in the user message that REQUIRE creating a task "
134
+ "(non-negotiable, do NOT self-exempt): 重构 / 抽成 / 独立 / 分发 / "
135
+ "拆出来 / 搞一个 / 做成 / 接入 / 集成 / refactor / rewrite / extract / "
136
+ "productize / publish / build X / design Y.\n"
137
+ "Task is NOT required ONLY if ALL three hold: (a) zero file writes "
138
+ "this turn, (b) answer fits in one reply with no multi-round plan, "
139
+ "(c) no research beyond reading 1-2 repo files.\n"
140
+ "When in doubt: create task. Over-tasking is cheap; under-tasking "
141
+ "leaks plans and research into main context.\n"
142
+ "Flow: load `trellis-brainstorm` skill → it creates the task via "
143
+ "`python3 ./.trellis/scripts/task.py create` and drives requirements Q&A. "
144
+ "For research-heavy work (tool comparison, docs, cross-platform survey), "
145
+ "spawn `trellis-research` sub-agents via Task tool — NEVER do 3+ inline "
146
+ "WebFetch/WebSearch/`gh api` calls in the main conversation."
147
+ ),
148
+ "planning": (
149
+ "Complete prd.md via trellis-brainstorm skill; then run task.py start.\n"
150
+ "Research belongs in `{task_dir}/research/*.md`, written by "
151
+ "`trellis-research` sub-agents. Do NOT inline WebFetch/WebSearch in "
152
+ "main session — PRD only links to research files."
153
+ ),
154
+ "in_progress": (
155
+ "Flow: trellis-implement → trellis-check → trellis-update-spec → finish\n"
156
+ "Check conversation history + git status to determine current step; "
157
+ "do NOT skip trellis-check."
158
+ ),
159
+ "completed": (
160
+ "User commits changes; then run task.py archive."
161
+ ),
162
+ }
163
+
164
+
165
+ def load_breadcrumbs(root: Path) -> dict[str, str]:
166
+ """Parse workflow.md for [workflow-state:STATUS] blocks.
167
+
168
+ Returns {status: body_text}. Missing tags fall back to hardcoded
169
+ defaults so the hook always has something to say for built-in
170
+ statuses. Custom statuses without tags fall to generic breadcrumb
171
+ downstream (see build_breadcrumb).
172
+ """
173
+ result = dict(_FALLBACK_BREADCRUMBS)
174
+
175
+ workflow = root / ".trellis" / "workflow.md"
176
+ if not workflow.is_file():
177
+ return result
178
+ try:
179
+ content = workflow.read_text(encoding="utf-8")
180
+ except OSError:
181
+ return result
182
+
183
+ for match in _TAG_RE.finditer(content):
184
+ status = match.group(1)
185
+ body = match.group(2).strip()
186
+ if body:
187
+ result[status] = body
188
+ return result
189
+
190
+
191
+ def build_breadcrumb(
192
+ task_id: Optional[str], status: str, templates: dict[str, str]
193
+ ) -> str:
194
+ """Build the <workflow-state>...</workflow-state> block.
195
+
196
+ - Known status (in templates or fallback) → detailed template body
197
+ - Unknown status (no tag + no fallback) → generic "refer to workflow.md"
198
+ - `no_task` pseudo-status (task_id is None) → header omits task info
199
+ """
200
+ body = templates.get(status)
201
+ if body is None:
202
+ body = "Refer to workflow.md for current step."
203
+ header = f"Status: {status}" if task_id is None else f"Task: {task_id} ({status})"
204
+ return f"<workflow-state>\n{header}\n{body}\n</workflow-state>"
205
+
206
+
207
+ # ---------------------------------------------------------------------------
208
+ # Entry
209
+ # ---------------------------------------------------------------------------
210
+
211
+ def main() -> int:
212
+ try:
213
+ data = json.load(sys.stdin)
214
+ except (json.JSONDecodeError, ValueError):
215
+ data = {}
216
+
217
+ cwd_str = data.get("cwd") or os.getcwd()
218
+ cwd = Path(cwd_str)
219
+
220
+ root = find_trellis_root(cwd)
221
+ if root is None:
222
+ return 0 # not a Trellis project
223
+
224
+ templates = load_breadcrumbs(root)
225
+ task = get_active_task(root)
226
+ if task is None:
227
+ # No active task — still emit a breadcrumb nudging AI toward
228
+ # trellis-brainstorm + task.py create when user describes real work.
229
+ breadcrumb = build_breadcrumb(None, "no_task", templates)
230
+ else:
231
+ breadcrumb = build_breadcrumb(*task, templates=templates)
232
+
233
+ output = {
234
+ "hookSpecificOutput": {
235
+ "hookEventName": "UserPromptSubmit",
236
+ "additionalContext": breadcrumb,
237
+ }
238
+ }
239
+ print(json.dumps(output))
240
+ return 0
241
+
242
+
243
+ if __name__ == "__main__":
244
+ sys.exit(main())
@@ -25,11 +25,20 @@ if sys.platform == "win32":
25
25
  sys.stdout = _io.TextIOWrapper(sys.stdout.detach(), encoding="utf-8", errors="replace") # type: ignore[union-attr]
26
26
 
27
27
 
28
+
28
29
  def should_skip_injection() -> bool:
29
- return (
30
- os.environ.get("CLAUDE_NON_INTERACTIVE") == "1"
31
- or os.environ.get("OPENCODE_NON_INTERACTIVE") == "1"
32
- )
30
+ """Check if any platform's non-interactive flag is set."""
31
+ non_interactive_vars = [
32
+ "CLAUDE_NON_INTERACTIVE",
33
+ "QODER_NON_INTERACTIVE",
34
+ "CODEBUDDY_NON_INTERACTIVE",
35
+ "FACTORY_NON_INTERACTIVE",
36
+ "CURSOR_NON_INTERACTIVE",
37
+ "GEMINI_NON_INTERACTIVE",
38
+ "KIRO_NON_INTERACTIVE",
39
+ "COPILOT_NON_INTERACTIVE",
40
+ ]
41
+ return any(os.environ.get(var) == "1" for var in non_interactive_vars)
33
42
 
34
43
 
35
44
  def read_file(path: Path, fallback: str = "") -> str:
@@ -95,19 +104,37 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
95
104
 
96
105
 
97
106
  def _get_task_status(trellis_dir: Path) -> str:
98
- """Check current task status and return structured status string."""
107
+ """Check current task status and return structured status string with explicit next action.
108
+
109
+ Returns a block with three fields:
110
+ - Status: current state
111
+ - Task: task identifier (when applicable)
112
+ - Next-Action: explicit skill/command/tool call the AI should invoke
113
+ """
99
114
  current_task_file = trellis_dir / ".current-task"
100
- if not current_task_file.is_file():
101
- return "Status: NO ACTIVE TASK\nNext: Describe what you want to work on"
115
+
116
+ # Case 1: No active task waiting for user to describe intent
117
+ if not current_task_file.is_file() or not current_task_file.read_text(encoding="utf-8").strip():
118
+ return (
119
+ "Status: NO ACTIVE TASK\n"
120
+ "Next-Action: After the user describes their intent, load skill `trellis-brainstorm` "
121
+ "to clarify requirements and create a task via `python3 ./.trellis/scripts/task.py create`.\n"
122
+ "Research reminder: for research-heavy tasks (comparing tools, reading external docs, "
123
+ "cross-platform surveys), spawn `trellis-research` sub-agents via the Task tool — "
124
+ "they persist findings to `{TASK_DIR}/research/*.md` and keep main context clean. "
125
+ "Do NOT do 10+ inline WebFetch/WebSearch in the main conversation."
126
+ )
102
127
 
103
128
  task_ref = _normalize_task_ref(current_task_file.read_text(encoding="utf-8").strip())
104
- if not task_ref:
105
- return "Status: NO ACTIVE TASK\nNext: Describe what you want to work on"
106
129
 
107
- # Resolve task directory
130
+ # Case 2: Stale pointer — task dir was deleted
108
131
  task_dir = _resolve_task_dir(trellis_dir, task_ref)
109
132
  if not task_dir.is_dir():
110
- return f"Status: STALE POINTER\nTask: {task_ref}\nNext: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
133
+ return (
134
+ f"Status: STALE POINTER\nTask: {task_ref}\n"
135
+ f"Next-Action: Run `python3 ./.trellis/scripts/task.py finish` to clear the stale pointer, "
136
+ "then ask the user what to work on next."
137
+ )
111
138
 
112
139
  # Read task.json
113
140
  task_json_path = task_dir / "task.json"
@@ -121,26 +148,37 @@ def _get_task_status(trellis_dir: Path) -> str:
121
148
  task_title = task_data.get("title", task_ref)
122
149
  task_status = task_data.get("status", "unknown")
123
150
 
151
+ # Case 3: Task completed — time to archive
124
152
  if task_status == "completed":
125
- return f"Status: COMPLETED\nTask: {task_title}\nNext: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` or start a new task"
126
-
127
- # Check if context is configured (jsonl files exist and non-empty)
128
- has_context = False
129
- for jsonl_name in ("implement.jsonl", "check.jsonl", "spec.jsonl"):
130
- jsonl_path = task_dir / jsonl_name
131
- if jsonl_path.is_file() and jsonl_path.stat().st_size > 0:
132
- has_context = True
133
- break
153
+ return (
154
+ f"Status: COMPLETED\nTask: {task_title}\n"
155
+ f"Next-Action: Load skill `trellis-update-spec` to capture learnings, "
156
+ f"then archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}`."
157
+ )
134
158
 
135
159
  has_prd = (task_dir / "prd.md").is_file()
136
160
 
161
+ # Case 4: No PRD — still in Plan phase
137
162
  if not has_prd:
138
- return f"Status: NOT READY\nTask: {task_title}\nMissing: prd.md not created\nNext: Write PRD, then research → init-context → start"
139
-
140
- if not has_context:
141
- 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"
163
+ return (
164
+ f"Status: PLANNING\nTask: {task_title}\n"
165
+ "Next-Action: Load skill `trellis-brainstorm` to clarify requirements with the user "
166
+ "and produce prd.md in the task directory.\n"
167
+ "Research reminder: when the task needs external research (tool comparison, docs, "
168
+ "conventions survey), spawn `trellis-research` sub-agents — don't WebFetch/WebSearch "
169
+ "inline in the main session. Findings go to `{task_dir}/research/*.md`; PRD only links to them."
170
+ )
142
171
 
143
- return f"Status: READY\nTask: {task_title}\nNext: Continue with implement or check"
172
+ # Case 5: PRD ready enter Execute phase
173
+ return (
174
+ f"Status: READY\nTask: {task_title}\n"
175
+ "Next-Action: Load skill `trellis-before-dev` to read relevant specs, "
176
+ "then spawn `trellis-implement` sub-agent via the Task tool. "
177
+ "After implementation, spawn `trellis-check` sub-agent for quality verification.\n"
178
+ "Sub-agent roster: `trellis-implement` (writes code), `trellis-check` (verifies + self-fixes), "
179
+ "`trellis-research` (persists findings to `research/*.md` — use when you'd otherwise do "
180
+ "multiple WebFetch/WebSearch inline)."
181
+ )
144
182
 
145
183
 
146
184
  def _load_trellis_config(trellis_dir: Path) -> tuple:
@@ -288,37 +326,97 @@ def _resolve_spec_scope(
288
326
  return None # Unknown scope type: full scan
289
327
 
290
328
 
291
- def _build_workflow_toc(workflow_path: Path) -> str:
292
- """Build a compact section index for workflow.md (lazy-load the full file on demand).
329
+ def _extract_range(content: str, start_header: str, end_header: str) -> str:
330
+ """Extract lines starting at `## start_header` up to (but excluding) `## end_header`.
293
331
 
294
- Replaces full-file injection to keep additionalContext payload small.
295
- The full file is accessible via: Read tool on .trellis/workflow.md
332
+ Both parameters are full header lines WITHOUT the `## ` prefix (e.g. "Phase Index").
333
+ Returns empty string if start header is not found.
334
+ End header missing → extracts to end of file.
335
+ """
336
+ lines = content.splitlines()
337
+ start: int | None = None
338
+ end: int = len(lines)
339
+ start_match = f"## {start_header}"
340
+ end_match = f"## {end_header}"
341
+ for i, line in enumerate(lines):
342
+ stripped = line.strip()
343
+ if start is None and stripped == start_match:
344
+ start = i
345
+ continue
346
+ if start is not None and stripped == end_match:
347
+ end = i
348
+ break
349
+ if start is None:
350
+ return ""
351
+ return "\n".join(lines[start:end]).rstrip()
352
+
353
+
354
+ def _build_workflow_overview(workflow_path: Path) -> str:
355
+ """Inject the workflow guide for the session.
356
+
357
+ Contents:
358
+ 1. Section index (all `## ` headings — navigation)
359
+ 2. Phase Index section (rules, skill routing table, anti-rationalization table)
360
+ 3. Phase 1/2/3 step-level details (the actual how-to for each step)
361
+
362
+ The meta sections (Core Principles / Trellis System / Workflow State
363
+ Breadcrumbs) are NOT injected — Core Principles is short prose the AI can
364
+ Read on demand; Trellis System lists reference commands duplicated in
365
+ step bodies; Breadcrumbs are consumed by the UserPromptSubmit hook.
366
+
367
+ Total budget: Phase Index ~2 KB + Phase 1/2/3 ~7 KB = ~9 KB.
296
368
  """
297
369
  content = read_file(workflow_path)
298
370
  if not content:
299
371
  return "No workflow.md found"
300
372
 
301
- toc_lines = [
373
+ out_lines = [
302
374
  "# Development Workflow — Section Index",
303
375
  "Full guide: .trellis/workflow.md (read on demand)",
304
376
  "",
377
+ "## Table of Contents",
305
378
  ]
306
379
  for line in content.splitlines():
307
380
  if line.startswith("## "):
308
- toc_lines.append(line)
381
+ out_lines.append(line)
382
+ out_lines += ["", "---", ""]
383
+
384
+ # Extract Phase Index through the end of Phase 3 (before Breadcrumbs).
385
+ # Since sections appear in order Phase Index → Phase 1 → Phase 2 → Phase 3
386
+ # → Workflow State Breadcrumbs, a single range grab captures all four.
387
+ phases = _extract_range(
388
+ content, "Phase Index", "Workflow State Breadcrumbs"
389
+ )
390
+ if phases:
391
+ out_lines.append(phases)
309
392
 
310
- toc_lines += [
311
- "",
312
- "To read a section: use the Read tool on .trellis/workflow.md",
313
- ]
314
- return "\n".join(toc_lines)
393
+ return "\n".join(out_lines).rstrip()
315
394
 
316
395
 
317
396
  def main():
318
397
  if should_skip_injection():
319
398
  sys.exit(0)
320
399
 
321
- project_dir = Path(os.environ.get("CLAUDE_PROJECT_DIR", ".")).resolve()
400
+ # Try platform-specific env vars, fallback to cwd
401
+ project_dir_env_vars = [
402
+ "CLAUDE_PROJECT_DIR",
403
+ "QODER_PROJECT_DIR",
404
+ "CODEBUDDY_PROJECT_DIR",
405
+ "FACTORY_PROJECT_DIR",
406
+ "CURSOR_PROJECT_DIR",
407
+ "GEMINI_PROJECT_DIR",
408
+ "KIRO_PROJECT_DIR",
409
+ "COPILOT_PROJECT_DIR",
410
+ ]
411
+ project_dir = None
412
+ for var in project_dir_env_vars:
413
+ val = os.environ.get(var)
414
+ if val:
415
+ project_dir = Path(val).resolve()
416
+ break
417
+ if project_dir is None:
418
+ project_dir = Path(".").resolve()
419
+
322
420
  trellis_dir = project_dir / ".trellis"
323
421
 
324
422
  # Load config for scope filtering and legacy detection
@@ -345,34 +443,43 @@ Read and follow all instructions below carefully.
345
443
  output.write("\n</current-state>\n\n")
346
444
 
347
445
  output.write("<workflow>\n")
348
- output.write(_build_workflow_toc(trellis_dir / "workflow.md"))
446
+ output.write(_build_workflow_overview(trellis_dir / "workflow.md"))
349
447
  output.write("\n</workflow>\n\n")
350
448
 
351
449
  output.write("<guidelines>\n")
352
- output.write("**Note**: The guidelines below are index files — they list available guideline documents and their locations.\n")
353
- output.write("During actual development, you MUST read the specific guideline files listed in each index's Pre-Development Checklist.\n\n")
450
+ output.write(
451
+ "Project spec indexes are listed by path below. Each index contains a "
452
+ "**Pre-Development Checklist** listing the specific guideline files to "
453
+ "read before coding.\n\n"
454
+ "- If you're spawning an implement/check sub-agent, context is injected "
455
+ "automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
456
+ "need to read these indexes yourself.\n"
457
+ "- If you're editing code directly in the main session, Read the relevant "
458
+ "index(es) on-demand and follow their Pre-Dev Checklist.\n\n"
459
+ )
460
+
461
+ # guides/ is cross-package thinking — always include inline (small, broadly useful)
462
+ guides_index = trellis_dir / "spec" / "guides" / "index.md"
463
+ if guides_index.is_file():
464
+ output.write("## guides (inlined — cross-package thinking guides)\n")
465
+ output.write(read_file(guides_index))
466
+ output.write("\n\n")
354
467
 
468
+ # Other spec indexes — paths only (main agent reads on demand;
469
+ # sub-agents get their specific specs via jsonl injection)
470
+ paths: list[str] = []
355
471
  spec_dir = trellis_dir / "spec"
356
472
  if spec_dir.is_dir():
357
473
  for sub in sorted(spec_dir.iterdir()):
358
474
  if not sub.is_dir() or sub.name.startswith("."):
359
475
  continue
360
-
361
- # Always include guides/ regardless of scope
362
476
  if sub.name == "guides":
363
- index_file = sub / "index.md"
364
- if index_file.is_file():
365
- output.write(f"## {sub.name}\n")
366
- output.write(read_file(index_file))
367
- output.write("\n\n")
368
- continue
477
+ continue # already inlined above
369
478
 
370
479
  index_file = sub / "index.md"
371
480
  if index_file.is_file():
372
481
  # Flat spec dir (single-repo layer like spec/backend/)
373
- output.write(f"## {sub.name}\n")
374
- output.write(read_file(index_file))
375
- output.write("\n\n")
482
+ paths.append(f".trellis/spec/{sub.name}/index.md")
376
483
  else:
377
484
  # Nested package dirs (monorepo: spec/<pkg>/<layer>/index.md)
378
485
  # Apply scope filter
@@ -383,10 +490,20 @@ Read and follow all instructions below carefully.
383
490
  continue
384
491
  nested_index = nested / "index.md"
385
492
  if nested_index.is_file():
386
- output.write(f"## {sub.name}/{nested.name}\n")
387
- output.write(read_file(nested_index))
388
- output.write("\n\n")
389
-
493
+ paths.append(
494
+ f".trellis/spec/{sub.name}/{nested.name}/index.md"
495
+ )
496
+
497
+ if paths:
498
+ output.write("## Available spec indexes (read on demand)\n")
499
+ for p in paths:
500
+ output.write(f"- {p}\n")
501
+ output.write("\n")
502
+
503
+ output.write(
504
+ "Discover more via: "
505
+ "`python3 ./.trellis/scripts/get_context.py --mode packages`\n"
506
+ )
390
507
  output.write("</guidelines>\n\n")
391
508
 
392
509
  # Check task status and inject structured tag
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Shared utilities for platform template modules.
3
+ * Eliminates boilerplate across qoder/, codebuddy/, droid/, cursor/, gemini/, kiro/ index.ts files.
4
+ */
5
+ export interface AgentTemplate {
6
+ name: string;
7
+ content: string;
8
+ }
9
+ export interface HookTemplate {
10
+ targetPath: string;
11
+ content: string;
12
+ }
13
+ export interface TemplateReader {
14
+ readTemplate: (relativePath: string) => string;
15
+ listFiles: (dir: string) => string[];
16
+ listMdAgents: (dir?: string) => AgentTemplate[];
17
+ listJsonAgents: (dir?: string) => AgentTemplate[];
18
+ getSettings: (filename?: string) => HookTemplate;
19
+ getConfig: (filename: string) => string;
20
+ }
21
+ /**
22
+ * Create a template reader bound to the caller's directory.
23
+ * Usage: `const { readTemplate, listMdAgents, getSettings } = createTemplateReader(import.meta.url);`
24
+ */
25
+ export declare function createTemplateReader(importMetaUrl: string): TemplateReader;
26
+ //# sourceMappingURL=template-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-utils.d.ts","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACrC,YAAY,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAClD,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;IACjD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,CAqD1E"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Shared utilities for platform template modules.
3
+ * Eliminates boilerplate across qoder/, codebuddy/, droid/, cursor/, gemini/, kiro/ index.ts files.
4
+ */
5
+ import { readdirSync, readFileSync } from "node:fs";
6
+ import { dirname, join } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ /**
9
+ * Create a template reader bound to the caller's directory.
10
+ * Usage: `const { readTemplate, listMdAgents, getSettings } = createTemplateReader(import.meta.url);`
11
+ */
12
+ export function createTemplateReader(importMetaUrl) {
13
+ const __dirname = dirname(fileURLToPath(importMetaUrl));
14
+ function readTemplate(relativePath) {
15
+ return readFileSync(join(__dirname, relativePath), "utf-8");
16
+ }
17
+ function listFiles(dir) {
18
+ try {
19
+ return readdirSync(join(__dirname, dir)).sort();
20
+ }
21
+ catch {
22
+ return [];
23
+ }
24
+ }
25
+ /** Read all .md agent files from a subdirectory */
26
+ function listMdAgents(dir = "agents") {
27
+ return listFiles(dir)
28
+ .filter((f) => f.endsWith(".md"))
29
+ .map((f) => ({
30
+ name: f.replace(".md", ""),
31
+ content: readTemplate(`${dir}/${f}`),
32
+ }));
33
+ }
34
+ /** Read all .json agent files from a subdirectory (Kiro) */
35
+ function listJsonAgents(dir = "agents") {
36
+ return listFiles(dir)
37
+ .filter((f) => f.endsWith(".json"))
38
+ .map((f) => ({
39
+ name: f.replace(".json", ""),
40
+ content: readTemplate(`${dir}/${f}`),
41
+ }));
42
+ }
43
+ /** Read settings.json and return as HookTemplate */
44
+ function getSettings(filename = "settings.json") {
45
+ return { targetPath: filename, content: readTemplate(filename) };
46
+ }
47
+ /** Read a config file and return raw string */
48
+ function getConfig(filename) {
49
+ return readTemplate(filename);
50
+ }
51
+ return {
52
+ readTemplate,
53
+ listFiles,
54
+ listMdAgents,
55
+ listJsonAgents,
56
+ getSettings,
57
+ getConfig,
58
+ };
59
+ }
60
+ //# sourceMappingURL=template-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-utils.js","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAqBzC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;IAExD,SAAS,YAAY,CAAC,YAAoB;QACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,SAAS,SAAS,CAAC,GAAW;QAC5B,IAAI,CAAC;YACH,OAAO,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,SAAS,YAAY,CAAC,GAAG,GAAG,QAAQ;QAClC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,4DAA4D;IAC5D,SAAS,cAAc,CAAC,GAAG,GAAG,QAAQ;QACpC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,oDAAoD;IACpD,SAAS,WAAW,CAAC,QAAQ,GAAG,eAAe;QAC7C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnE,CAAC;IAED,+CAA+C;IAC/C,SAAS,SAAS,CAAC,QAAgB;QACjC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,cAAc;QACd,WAAW;QACX,SAAS;KACV,CAAC;AACJ,CAAC"}
@@ -48,6 +48,12 @@ max_journal_lines: 2000
48
48
  # docs:
49
49
  # path: docs-site
50
50
  # type: submodule
51
+ # # For polyrepo / meta-repo layouts (independent .git in each subdir),
52
+ # # mark the package with `git: true`. The runtime treats it as an
53
+ # # independent repository for things like git-context display.
54
+ # webapp:
55
+ # path: ./webapp
56
+ # git: true
51
57
 
52
58
  # Default package used when --package is not specified.
53
59
  # default_package: frontend