@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
@@ -1,742 +0,0 @@
1
- # Script Conventions
2
-
3
- > Standards for Python scripts in the `.trellis/scripts/` directory.
4
-
5
- ---
6
-
7
- ## Overview
8
-
9
- All workflow scripts are written in **Python 3.10+** for cross-platform compatibility. Scripts use only the standard library (no external dependencies).
10
-
11
- ---
12
-
13
- ## Directory Structure
14
-
15
- ```
16
- .trellis/scripts/
17
- ├── __init__.py # Package init
18
- ├── common/ # Shared modules
19
- │ ├── __init__.py
20
- │ ├── paths.py # Path constants and functions
21
- │ ├── developer.py # Developer identity management
22
- │ ├── task_queue.py # Task queue CRUD
23
- │ ├── task_utils.py # Task helper functions
24
- │ ├── phase.py # Multi-agent phase tracking
25
- │ ├── registry.py # Agent registry management
26
- │ ├── config.py # Config reader (config.yaml, hooks)
27
- │ ├── worktree.py # Git worktree utilities + YAML parser
28
- │ └── git_context.py # Git/session context
29
- ├── hooks/ # Lifecycle hook scripts (project-specific)
30
- │ └── linear_sync.py # Example: sync tasks to Linear
31
- ├── multi_agent/ # Multi-agent pipeline scripts
32
- │ ├── __init__.py
33
- │ ├── start.py # Start worktree agent
34
- │ ├── status.py # Monitor agent status
35
- │ ├── plan.py # Start plan agent
36
- │ ├── cleanup.py # Cleanup worktree
37
- │ └── create_pr.py # Create PR from task
38
- ├── task.py # Main task management CLI
39
- ├── get_context.py # Session context retrieval
40
- ├── init_developer.py # Developer initialization
41
- ├── get_developer.py # Get current developer
42
- ├── add_session.py # Session recording
43
- └── create_bootstrap.py # Bootstrap task creation
44
- ```
45
-
46
- ---
47
-
48
- ## Script Types
49
-
50
- ### Library Modules (`common/*.py`)
51
-
52
- Shared utilities imported by other scripts. **Never run directly.**
53
-
54
- ```python
55
- # common/paths.py - Example library module
56
-
57
- from __future__ import annotations
58
-
59
- from pathlib import Path
60
-
61
- # Constants
62
- DIR_WORKFLOW = ".trellis"
63
- DIR_SCRIPTS = "scripts"
64
- DIR_TASKS = "tasks"
65
-
66
- def get_repo_root() -> Path | None:
67
- """Find repository root by looking for .trellis directory."""
68
- current = Path.cwd().resolve()
69
- while current != current.parent:
70
- if (current / DIR_WORKFLOW).is_dir():
71
- return current
72
- current = current.parent
73
- return None
74
- ```
75
-
76
- ### Entry Scripts (`*.py`)
77
-
78
- CLI tools that users run directly. Include docstring with usage.
79
-
80
- ```python
81
- #!/usr/bin/env python3
82
- """
83
- Task Management Script.
84
-
85
- Usage:
86
- python3 task.py create "<title>" [--slug <name>]
87
- python3 task.py init-context <dir> <dev_type>
88
- python3 task.py add-context <dir> <file> <reason>
89
- python3 task.py validate <dir>
90
- python3 task.py list-context <dir>
91
- python3 task.py start <dir>
92
- python3 task.py finish
93
- python3 task.py set-branch <dir> <branch>
94
- python3 task.py set-base-branch <dir> <branch>
95
- python3 task.py set-scope <dir> <scope>
96
- python3 task.py create-pr [dir] [--dry-run]
97
- python3 task.py archive <task-name>
98
- python3 task.py list [--mine] [--status <status>]
99
- python3 task.py list-archive [YYYY-MM]
100
- """
101
-
102
- from __future__ import annotations
103
-
104
- import argparse
105
- import sys
106
- from pathlib import Path
107
-
108
- from common.paths import get_repo_root, DIR_WORKFLOW
109
-
110
-
111
- def main() -> int:
112
- """Main entry point."""
113
- parser = argparse.ArgumentParser(description="Task management")
114
- # ... argument setup
115
- args = parser.parse_args()
116
- # ... command dispatch
117
- return 0
118
-
119
-
120
- if __name__ == "__main__":
121
- sys.exit(main())
122
- ```
123
-
124
- ---
125
-
126
- ## Coding Standards
127
-
128
- ### Type Hints
129
-
130
- Use modern type hints (Python 3.10+ syntax):
131
-
132
- ```python
133
- # Good
134
- def get_tasks(status: str | None = None) -> list[dict]:
135
- ...
136
-
137
- def read_json(path: Path) -> dict | None:
138
- ...
139
-
140
- # Bad - old style
141
- from typing import Optional, List, Dict
142
- def get_tasks(status: Optional[str] = None) -> List[Dict]:
143
- ...
144
- ```
145
-
146
- ### Path Handling
147
-
148
- Always use `pathlib.Path`:
149
-
150
- ```python
151
- # Good
152
- from pathlib import Path
153
-
154
- def read_file(path: Path) -> str:
155
- return path.read_text(encoding="utf-8")
156
-
157
- config_path = repo_root / DIR_WORKFLOW / "config.json"
158
-
159
- # Bad - string concatenation
160
- config_path = repo_root + "/" + DIR_WORKFLOW + "/config.json"
161
- ```
162
-
163
- ### JSON Operations
164
-
165
- Use helper functions for consistent error handling:
166
-
167
- ```python
168
- import json
169
- from pathlib import Path
170
-
171
-
172
- def read_json(path: Path) -> dict | None:
173
- """Read JSON file, return None on error."""
174
- try:
175
- return json.loads(path.read_text(encoding="utf-8"))
176
- except (FileNotFoundError, json.JSONDecodeError):
177
- return None
178
-
179
-
180
- def write_json(path: Path, data: dict) -> bool:
181
- """Write JSON file, return success status."""
182
- try:
183
- path.write_text(
184
- json.dumps(data, indent=2, ensure_ascii=False),
185
- encoding="utf-8"
186
- )
187
- return True
188
- except Exception:
189
- return False
190
- ```
191
-
192
- ### Subprocess Execution
193
-
194
- ```python
195
- import subprocess
196
- from pathlib import Path
197
-
198
-
199
- def run_command(
200
- cmd: list[str],
201
- cwd: Path | None = None
202
- ) -> tuple[int, str, str]:
203
- """Run command and return (returncode, stdout, stderr)."""
204
- result = subprocess.run(
205
- cmd,
206
- cwd=cwd,
207
- capture_output=True,
208
- text=True
209
- )
210
- return result.returncode, result.stdout, result.stderr
211
- ```
212
-
213
- ---
214
-
215
- ## Cross-Platform Compatibility
216
-
217
- ### CRITICAL: Windows stdio Encoding (stdout + stdin)
218
-
219
- On Windows, Python's stdout AND stdin default to the system code page (e.g., GBK/CP936 in China, CP1252 in Western locales). This causes:
220
- - `UnicodeEncodeError` when **printing** non-ASCII characters (stdout)
221
- - `UnicodeDecodeError` when **reading piped** UTF-8 content (stdin), e.g. Chinese text via `cat << EOF | python3 script.py`
222
-
223
- **The Problem Chain (stdout)**:
224
-
225
- ```
226
- Windows code page = GBK (936)
227
-
228
- Python stdout defaults to GBK encoding
229
-
230
- Subprocess output contains special chars → replaced with \ufffd (replacement char)
231
-
232
- json.dumps(ensure_ascii=False) → print()
233
-
234
- GBK cannot encode \ufffd → UnicodeEncodeError: 'gbk' codec can't encode character
235
- ```
236
-
237
- **The Problem Chain (stdin)**:
238
-
239
- ```
240
- AI agent pipes UTF-8 content via heredoc: cat << 'EOF' | python3 add_session.py ...
241
-
242
- Python stdin defaults to GBK encoding (PowerShell default code page)
243
-
244
- sys.stdin.read() decodes bytes as GBK, not UTF-8
245
-
246
- Chinese text garbled or UnicodeDecodeError
247
- ```
248
-
249
- **Root Cause**: Even if you set `PYTHONIOENCODING` in subprocess calls, the **parent process's stdio** still uses the system code page.
250
-
251
- ---
252
-
253
- #### GOOD: Centralize encoding fix in `common/__init__.py`
254
-
255
- All stdio encoding is handled in one place. Scripts that `from common import ...` automatically get the fix:
256
-
257
- ```python
258
- # common/__init__.py
259
- import io
260
- import sys
261
-
262
- def _configure_stream(stream):
263
- """Configure a stream for UTF-8 encoding on Windows."""
264
- if hasattr(stream, "reconfigure"):
265
- stream.reconfigure(encoding="utf-8", errors="replace")
266
- return stream
267
- elif hasattr(stream, "detach"):
268
- return io.TextIOWrapper(stream.detach(), encoding="utf-8", errors="replace")
269
- return stream
270
-
271
- if sys.platform == "win32":
272
- sys.stdout = _configure_stream(sys.stdout)
273
- sys.stderr = _configure_stream(sys.stderr)
274
- sys.stdin = _configure_stream(sys.stdin) # Don't forget stdin!
275
- ```
276
-
277
- ---
278
-
279
- #### DON'T: Inline encoding code in individual scripts
280
-
281
- ```python
282
- # BAD - Duplicated in every script, easy to forget stdin
283
- import sys
284
- if sys.platform == "win32":
285
- sys.stdout.reconfigure(encoding="utf-8", errors="replace")
286
- # Forgot stdin! Piped Chinese text will break.
287
- ```
288
-
289
- **Why this is bad**:
290
- 1. **Easy to forget streams**: stdout was fixed but stdin was missed in multiple scripts, causing real user bugs
291
- 2. **Duplicated code**: Same logic copy-pasted across `add_session.py`, `git_context.py`, etc.
292
- 3. **Inconsistent coverage**: Some scripts fix stdout only, others fix stdout+stderr, none fixed stdin
293
-
294
- **Real-world failure**: Users on Windows reported garbled Chinese text when using `cat << EOF | python3 add_session.py`. Root cause: stdin was never reconfigured to UTF-8.
295
-
296
- ---
297
-
298
- #### Summary
299
-
300
- | Method | Works? | Reason |
301
- |--------|--------|--------|
302
- | `common/__init__.py` centralized fix | ✅ Yes | All streams, all scripts, one place |
303
- | `sys.stdout.reconfigure(encoding="utf-8")` | ⚠️ Partial | Only stdout; easy to forget stdin/stderr |
304
- | `io.TextIOWrapper(sys.stdout.buffer, ...)` | ❌ No | Creates wrapper, doesn't fix underlying encoding |
305
- | `PYTHONIOENCODING=utf-8` env var | ⚠️ Partial | Only works if set **before** Python starts |
306
-
307
- ### CRITICAL: Always Use `python3` Explicitly
308
-
309
- Windows does not support shebang (`#!/usr/bin/env python3`). Always document invocation with explicit `python3`:
310
-
311
- ```python
312
- # In docstrings
313
- """
314
- Usage:
315
- python3 task.py create "My Task"
316
- python3 task.py list --mine
317
- """
318
-
319
- # In error messages
320
- print("Usage: python3 task.py <command>")
321
- print("Run: python3 ./.trellis/scripts/init_developer.py <name>")
322
-
323
- # In help text
324
- print("Next steps:")
325
- print(" python3 task.py start <dir>")
326
- ```
327
-
328
- ### Path Separators
329
-
330
- Use `pathlib.Path` - it handles separators automatically:
331
-
332
- ```python
333
- # Good - works on all platforms
334
- path = Path(".trellis") / "scripts" / "task.py"
335
-
336
- # Bad - Unix-only
337
- path = ".trellis/scripts/task.py"
338
- ```
339
-
340
- ---
341
-
342
- ## Task Lifecycle Hooks
343
-
344
- ### Scope / Trigger
345
-
346
- Task lifecycle events (`after_create`, `after_start`, `after_finish`, `after_archive`) execute user-defined shell commands configured in `config.yaml`.
347
-
348
- ### Signatures
349
-
350
- ```python
351
- # config.py — read hook commands from config
352
- def get_hooks(event: str, repo_root: Path | None = None) -> list[str]
353
-
354
- # task.py — execute hooks (never blocks main operation)
355
- def _run_hooks(event: str, task_json_path: Path, repo_root: Path) -> None
356
- ```
357
-
358
- ### Contracts
359
-
360
- **Config format** (`config.yaml`):
361
- ```yaml
362
- hooks:
363
- after_create:
364
- - "python3 .trellis/scripts/hooks/my_hook.py create"
365
- after_start:
366
- - "python3 .trellis/scripts/hooks/my_hook.py start"
367
- after_archive:
368
- - "python3 .trellis/scripts/hooks/my_hook.py archive"
369
- ```
370
-
371
- **Environment variables passed to hooks**:
372
-
373
- | Key | Type | Description |
374
- |-----|------|-------------|
375
- | `TASK_JSON_PATH` | Absolute path string | Path to the task's `task.json` |
376
-
377
- - `cwd` is set to `repo_root`
378
- - Hooks inherit the parent process environment + `TASK_JSON_PATH`
379
-
380
- ### Subprocess Execution
381
-
382
- ```python
383
- import os
384
- import subprocess
385
-
386
- env = {**os.environ, "TASK_JSON_PATH": str(task_json_path)}
387
-
388
- result = subprocess.run(
389
- cmd,
390
- shell=True,
391
- cwd=repo_root,
392
- env=env,
393
- capture_output=True,
394
- text=True,
395
- encoding="utf-8", # REQUIRED: cross-platform
396
- errors="replace", # REQUIRED: cross-platform
397
- )
398
- ```
399
-
400
- ### Validation & Error Matrix
401
-
402
- | Condition | Behavior |
403
- |-----------|----------|
404
- | No `hooks` key in config | No-op (empty list) |
405
- | `hooks` is not a dict | No-op (empty list) |
406
- | Event key missing | No-op (empty list) |
407
- | Hook command exits non-zero | `[WARN]` to stderr, continues to next hook |
408
- | Hook command throws exception | `[WARN]` to stderr, continues to next hook |
409
- | `linearis` not installed | Hook fails with warning, task operation succeeds |
410
-
411
- ### Wrong vs Correct
412
-
413
- #### Wrong — blocking on hook failure
414
- ```python
415
- result = subprocess.run(cmd, shell=True, check=True) # Raises on failure!
416
- ```
417
-
418
- #### Correct — warn and continue
419
- ```python
420
- try:
421
- result = subprocess.run(cmd, shell=True, ...)
422
- if result.returncode != 0:
423
- print(f"[WARN] Hook failed: {cmd}", file=sys.stderr)
424
- except Exception as e:
425
- print(f"[WARN] Hook error: {cmd} — {e}", file=sys.stderr)
426
- ```
427
-
428
- ### Hook Script Pattern
429
-
430
- Hook scripts that need project-specific config (API keys, user IDs) should:
431
- 1. Store config in a **gitignored** local file (e.g., `.trellis/hooks.local.json`)
432
- 2. Read config at startup, fail with clear message if missing
433
- 3. Keep the script itself committable (no hardcoded secrets)
434
-
435
- ```python
436
- # .trellis/scripts/hooks/my_hook.py — committable, no secrets
437
- CONFIG = _load_config() # reads from .trellis/hooks.local.json (gitignored)
438
- TEAM = CONFIG.get("linear", {}).get("team", "")
439
- ```
440
-
441
- ---
442
-
443
- ## Auto-Commit Pattern
444
-
445
- Scripts that modify `.trellis/` tracked files should auto-commit their changes to keep the workspace clean. Use a `--no-commit` flag for opt-out.
446
-
447
- ### Convention: Auto-Commit After Mutation
448
-
449
- ```python
450
- def _auto_commit(scope: str, message: str, repo_root: Path) -> None:
451
- """Stage and commit changes in a specific .trellis/ subdirectory."""
452
- subprocess.run(["git", "add", "-A", scope], cwd=repo_root, capture_output=True)
453
- # Check if there are staged changes
454
- result = subprocess.run(
455
- ["git", "diff", "--cached", "--quiet", "--", scope],
456
- cwd=repo_root,
457
- )
458
- if result.returncode == 0:
459
- print("[OK] No changes to commit.", file=sys.stderr)
460
- return
461
- commit_result = subprocess.run(
462
- ["git", "commit", "-m", message],
463
- cwd=repo_root, capture_output=True, text=True,
464
- )
465
- if commit_result.returncode == 0:
466
- print(f"[OK] Auto-committed: {message}", file=sys.stderr)
467
- else:
468
- print(f"[WARN] Auto-commit failed: {commit_result.stderr.strip()}", file=sys.stderr)
469
- ```
470
-
471
- **Scripts using this pattern**:
472
- - `add_session.py` — commits `.trellis/workspace` + `.trellis/tasks` after recording a session
473
- - `task.py archive` — commits `.trellis/tasks` after archiving a task
474
-
475
- **Always add `--no-commit` flag** for scripts that auto-commit, so users can opt out.
476
-
477
- ---
478
-
479
- ## CLI Mode Extension Pattern
480
-
481
- ### Design Decision: `--mode` for Context-Dependent Output
482
-
483
- When a script needs different output for different use cases, use `--mode` (not separate scripts or additional flags).
484
-
485
- **Example**: `get_context.py` serves two modes:
486
- - `--mode default` — full session context (DEVELOPER, GIT STATUS, RECENT COMMITS, CURRENT TASK, ACTIVE TASKS, MY TASKS, JOURNAL, PATHS)
487
- - `--mode record` — focused output for record-session (MY ACTIVE TASKS first with emphasis, GIT STATUS, RECENT COMMITS, CURRENT TASK)
488
-
489
- ```python
490
- parser.add_argument(
491
- "--mode", "-m",
492
- choices=["default", "record"],
493
- default="default",
494
- help="Output mode: default (full context) or record (for record-session)",
495
- )
496
- ```
497
-
498
- **When to add a new mode** (not a new script):
499
- - Output is a subset/reordering of the same data
500
- - The underlying data sources are shared
501
- - The difference is in presentation, not in data fetching
502
-
503
- ---
504
-
505
- ## Parsing Structured Command Output
506
-
507
- ### CRITICAL: Preserve Semantic Whitespace
508
-
509
- Many CLI tools encode status information in leading/trailing whitespace characters. **Never blindly `.strip()` before parsing.**
510
-
511
- **Example — `git submodule status` output format**:
512
-
513
- ```
514
- abc1234 path/to/submodule (v1.0) ← space prefix = initialized
515
- -def5678 path/to/other (v2.0) ← minus prefix = not initialized
516
- +ghi9012 path/to/modified (v3.0) ← plus prefix = modified (out of sync)
517
- ```
518
-
519
- ```python
520
- # BAD — .strip() removes the leading space that means "initialized"
521
- status_line = status_out.strip()
522
- prefix = status_line[0] # Reads commit hash char, not status prefix!
523
-
524
- # GOOD — parse the raw line, then strip individual fields
525
- raw_line = status_out.rstrip("\n") # Only remove trailing newline
526
- if not raw_line:
527
- continue
528
- prefix = raw_line[0] # ' ', '-', or '+'
529
- rest = raw_line[1:].strip() # Now safe to strip the rest
530
- commit_hash = rest.split()[0]
531
- ```
532
-
533
- **General rule**: When a command's output uses positional formatting (columns, prefixes, fixed-width fields), parse the structure first, then clean up individual values.
534
-
535
- **Other commands with semantic whitespace**:
536
- - `git status --porcelain` — two-char status prefix (`XY`)
537
- - `git diff --name-status` — tab-separated with status prefix
538
- - `docker ps --format` — column-aligned output
539
-
540
- ---
541
-
542
- ## Monorepo Config API (`common/config.py`)
543
-
544
- ### Config Functions
545
-
546
- | Function | Return | Purpose |
547
- |----------|--------|---------|
548
- | `is_monorepo(repo_root)` | `bool` | Whether `packages:` exists in config.yaml |
549
- | `get_packages(repo_root)` | `dict[str, dict] \| None` | All packages from config.yaml (`{name: {path, type?}}`) |
550
- | `get_default_package(repo_root)` | `str \| None` | The `default_package` from config.yaml |
551
- | `get_submodule_packages(repo_root)` | `dict[str, str]` | Packages with `type: submodule` (`{name: path}`) |
552
- | `get_spec_base(package, repo_root)` | `str` | `"spec"` (single-repo) or `"spec/<package>"` (monorepo) |
553
- | `validate_package(package, repo_root)` | `bool` | Whether package exists in config (always `True` for single-repo) |
554
- | `resolve_package(task_pkg, repo_root)` | `str \| None` | Resolve package: task → default → None |
555
- | `get_spec_scope(repo_root)` | `str \| list \| None` | The `session.spec_scope` config value |
556
- | `get_hooks(event, repo_root)` | `list[str]` | Hook commands for lifecycle event |
557
-
558
- ### Config.yaml Schema
559
-
560
- ```yaml
561
- # Auto-detected monorepo packages (written by trellis init)
562
- packages:
563
- cli:
564
- path: packages/cli
565
- docs-site:
566
- path: docs-site
567
- type: submodule # optional, marks git submodule
568
- default_package: cli # first non-submodule package
569
-
570
- # Session behavior
571
- session:
572
- spec_scope: active_task # or ["cli", "docs-site"] or omit for full scan
573
-
574
- # Update behavior
575
- update:
576
- skip:
577
- - .claude/commands/trellis/my-custom.md
578
-
579
- # Lifecycle hooks
580
- hooks:
581
- after_create:
582
- - "python3 .trellis/scripts/hooks/my_hook.py create"
583
- ```
584
-
585
- ### Worktree Submodule Initialization
586
-
587
- When `start.py` creates a worktree for a task, it calls `_init_submodules_for_task()`:
588
-
589
- 1. Read `packages` from config.yaml via `get_packages()`
590
- 2. Resolve target package from task data or `default_package`
591
- 3. Check if the package is a submodule via `get_submodule_packages()`
592
- 4. Run `git submodule status <path>` in the worktree
593
- 5. Parse the status prefix (see "Parsing Structured Command Output" above)
594
- 6. If uninitialized (`-` prefix): run `git submodule update --init <path>`
595
-
596
- ---
597
-
598
- ## Error Handling
599
-
600
- ### Exit Codes
601
-
602
- | Code | Meaning |
603
- |------|---------|
604
- | 0 | Success |
605
- | 1 | General error |
606
- | 2 | Usage error (wrong arguments) |
607
-
608
- ### Error Messages
609
-
610
- Print errors to stderr with context:
611
-
612
- ```python
613
- import sys
614
-
615
- def error(msg: str) -> None:
616
- """Print error message to stderr."""
617
- print(f"Error: {msg}", file=sys.stderr)
618
-
619
- # Usage
620
- if not repo_root:
621
- error("Not in a Trellis project (no .trellis directory found)")
622
- sys.exit(1)
623
- ```
624
-
625
- ---
626
-
627
- ## Argument Parsing
628
-
629
- Use `argparse` for consistent CLI interface:
630
-
631
- ```python
632
- import argparse
633
-
634
-
635
- def main() -> int:
636
- parser = argparse.ArgumentParser(
637
- description="Task management",
638
- formatter_class=argparse.RawDescriptionHelpFormatter,
639
- epilog="""
640
- Examples:
641
- python3 task.py create "Add login" --slug add-login
642
- python3 task.py list --mine --status in_progress
643
- """
644
- )
645
-
646
- subparsers = parser.add_subparsers(dest="command", required=True)
647
-
648
- # create command
649
- create_parser = subparsers.add_parser("create", help="Create new task")
650
- create_parser.add_argument("title", help="Task title")
651
- create_parser.add_argument("--slug", help="URL-friendly name")
652
-
653
- # list command
654
- list_parser = subparsers.add_parser("list", help="List tasks")
655
- list_parser.add_argument("--mine", "-m", action="store_true")
656
- list_parser.add_argument("--status", "-s", choices=["planning", "in_progress", "review", "completed"])
657
-
658
- args = parser.parse_args()
659
-
660
- if args.command == "create":
661
- return cmd_create(args)
662
- elif args.command == "list":
663
- return cmd_list(args)
664
-
665
- return 0
666
- ```
667
-
668
- ---
669
-
670
- ## Import Conventions
671
-
672
- ### Relative Imports Within Package
673
-
674
- ```python
675
- # In task.py (root level)
676
- from common.paths import get_repo_root, DIR_WORKFLOW
677
- from common.developer import get_developer
678
-
679
- # In common/developer.py
680
- from .paths import get_repo_root, DIR_WORKFLOW
681
- ```
682
-
683
- ### Standard Library Imports
684
-
685
- Group and order imports:
686
-
687
- ```python
688
- # 1. Future imports
689
- from __future__ import annotations
690
-
691
- # 2. Standard library
692
- import argparse
693
- import json
694
- import os
695
- import subprocess
696
- import sys
697
- from datetime import datetime
698
- from pathlib import Path
699
-
700
- # 3. Local imports
701
- from common.paths import get_repo_root
702
- from common.developer import get_developer
703
- ```
704
-
705
- ---
706
-
707
- ## DO / DON'T
708
-
709
- ### DO
710
-
711
- - Use `pathlib.Path` for all path operations
712
- - Use type hints (Python 3.10+ syntax)
713
- - Return exit codes from `main()`
714
- - Print errors to stderr
715
- - Always use `python3` in documentation and messages
716
- - Use `encoding="utf-8"` for all file operations
717
-
718
- ### DON'T
719
-
720
- - Don't use string path concatenation
721
- - Don't use `os.path` when `pathlib` works
722
- - Don't rely on shebang for invocation documentation
723
- - Don't use `print()` for errors (use stderr)
724
- - Don't hardcode paths - use constants from `common/paths.py`
725
- - Don't use external dependencies (stdlib only)
726
-
727
- ---
728
-
729
- ## Example: Complete Script
730
-
731
- See `.trellis/scripts/task.py` for a comprehensive example with:
732
- - Multiple subcommands
733
- - Argument parsing
734
- - JSON file operations
735
- - Error handling
736
- - Cross-platform path handling
737
-
738
- ---
739
-
740
- ## Migration Note
741
-
742
- > **Historical Context**: Scripts were migrated from Bash to Python in v0.3.0 for cross-platform compatibility. The old shell scripts are archived in `.trellis/scripts-shell-archive/` (if preserved).