@mindfoldhq/trellis 0.6.0-beta.2 → 0.6.0-beta.21

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 (331) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.d.ts +1 -1
  3. package/dist/cli/index.d.ts.map +1 -1
  4. package/dist/cli/index.js +58 -2
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/commands/channel/adapters/claude.d.ts +29 -0
  7. package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
  8. package/dist/commands/channel/adapters/claude.js +203 -0
  9. package/dist/commands/channel/adapters/claude.js.map +1 -0
  10. package/dist/commands/channel/adapters/codex.d.ts +85 -0
  11. package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
  12. package/dist/commands/channel/adapters/codex.js +505 -0
  13. package/dist/commands/channel/adapters/codex.js.map +1 -0
  14. package/dist/commands/channel/adapters/index.d.ts +84 -0
  15. package/dist/commands/channel/adapters/index.d.ts.map +1 -0
  16. package/dist/commands/channel/adapters/index.js +115 -0
  17. package/dist/commands/channel/adapters/index.js.map +1 -0
  18. package/dist/commands/channel/adapters/types.d.ts +33 -0
  19. package/dist/commands/channel/adapters/types.d.ts.map +1 -0
  20. package/dist/commands/channel/adapters/types.js +2 -0
  21. package/dist/commands/channel/adapters/types.js.map +1 -0
  22. package/dist/commands/channel/agent-loader.d.ts +32 -0
  23. package/dist/commands/channel/agent-loader.d.ts.map +1 -0
  24. package/dist/commands/channel/agent-loader.js +154 -0
  25. package/dist/commands/channel/agent-loader.js.map +1 -0
  26. package/dist/commands/channel/context-loader.d.ts +26 -0
  27. package/dist/commands/channel/context-loader.d.ts.map +1 -0
  28. package/dist/commands/channel/context-loader.js +290 -0
  29. package/dist/commands/channel/context-loader.js.map +1 -0
  30. package/dist/commands/channel/context.d.ts +16 -0
  31. package/dist/commands/channel/context.d.ts.map +1 -0
  32. package/dist/commands/channel/context.js +83 -0
  33. package/dist/commands/channel/context.js.map +1 -0
  34. package/dist/commands/channel/create.d.ts +27 -0
  35. package/dist/commands/channel/create.d.ts.map +1 -0
  36. package/dist/commands/channel/create.js +39 -0
  37. package/dist/commands/channel/create.js.map +1 -0
  38. package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
  39. package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
  40. package/dist/commands/channel/dev-parse-trace.js +70 -0
  41. package/dist/commands/channel/dev-parse-trace.js.map +1 -0
  42. package/dist/commands/channel/guard.d.ts +150 -0
  43. package/dist/commands/channel/guard.d.ts.map +1 -0
  44. package/dist/commands/channel/guard.js +474 -0
  45. package/dist/commands/channel/guard.js.map +1 -0
  46. package/dist/commands/channel/index.d.ts +3 -0
  47. package/dist/commands/channel/index.d.ts.map +1 -0
  48. package/dist/commands/channel/index.js +531 -0
  49. package/dist/commands/channel/index.js.map +1 -0
  50. package/dist/commands/channel/interrupt.d.ts +10 -0
  51. package/dist/commands/channel/interrupt.d.ts.map +1 -0
  52. package/dist/commands/channel/interrupt.js +22 -0
  53. package/dist/commands/channel/interrupt.js.map +1 -0
  54. package/dist/commands/channel/kill.d.ts +7 -0
  55. package/dist/commands/channel/kill.d.ts.map +1 -0
  56. package/dist/commands/channel/kill.js +121 -0
  57. package/dist/commands/channel/kill.js.map +1 -0
  58. package/dist/commands/channel/list.d.ts +17 -0
  59. package/dist/commands/channel/list.d.ts.map +1 -0
  60. package/dist/commands/channel/list.js +233 -0
  61. package/dist/commands/channel/list.js.map +1 -0
  62. package/dist/commands/channel/messages.d.ts +15 -0
  63. package/dist/commands/channel/messages.d.ts.map +1 -0
  64. package/dist/commands/channel/messages.js +245 -0
  65. package/dist/commands/channel/messages.js.map +1 -0
  66. package/dist/commands/channel/rm.d.ts +27 -0
  67. package/dist/commands/channel/rm.d.ts.map +1 -0
  68. package/dist/commands/channel/rm.js +216 -0
  69. package/dist/commands/channel/rm.js.map +1 -0
  70. package/dist/commands/channel/run.d.ts +30 -0
  71. package/dist/commands/channel/run.d.ts.map +1 -0
  72. package/dist/commands/channel/run.js +130 -0
  73. package/dist/commands/channel/run.js.map +1 -0
  74. package/dist/commands/channel/send.d.ts +11 -0
  75. package/dist/commands/channel/send.d.ts.map +1 -0
  76. package/dist/commands/channel/send.js +24 -0
  77. package/dist/commands/channel/send.js.map +1 -0
  78. package/dist/commands/channel/spawn.d.ts +40 -0
  79. package/dist/commands/channel/spawn.d.ts.map +1 -0
  80. package/dist/commands/channel/spawn.js +244 -0
  81. package/dist/commands/channel/spawn.js.map +1 -0
  82. package/dist/commands/channel/store/events.d.ts +39 -0
  83. package/dist/commands/channel/store/events.d.ts.map +1 -0
  84. package/dist/commands/channel/store/events.js +87 -0
  85. package/dist/commands/channel/store/events.js.map +1 -0
  86. package/dist/commands/channel/store/filter.d.ts +3 -0
  87. package/dist/commands/channel/store/filter.d.ts.map +1 -0
  88. package/dist/commands/channel/store/filter.js +2 -0
  89. package/dist/commands/channel/store/filter.js.map +1 -0
  90. package/dist/commands/channel/store/lock.d.ts +23 -0
  91. package/dist/commands/channel/store/lock.d.ts.map +1 -0
  92. package/dist/commands/channel/store/lock.js +99 -0
  93. package/dist/commands/channel/store/lock.js.map +1 -0
  94. package/dist/commands/channel/store/paths.d.ts +63 -0
  95. package/dist/commands/channel/store/paths.d.ts.map +1 -0
  96. package/dist/commands/channel/store/paths.js +246 -0
  97. package/dist/commands/channel/store/paths.js.map +1 -0
  98. package/dist/commands/channel/store/schema.d.ts +27 -0
  99. package/dist/commands/channel/store/schema.d.ts.map +1 -0
  100. package/dist/commands/channel/store/schema.js +34 -0
  101. package/dist/commands/channel/store/schema.js.map +1 -0
  102. package/dist/commands/channel/store/thread-state.d.ts +5 -0
  103. package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
  104. package/dist/commands/channel/store/thread-state.js +16 -0
  105. package/dist/commands/channel/store/thread-state.js.map +1 -0
  106. package/dist/commands/channel/store/watch.d.ts +19 -0
  107. package/dist/commands/channel/store/watch.d.ts.map +1 -0
  108. package/dist/commands/channel/store/watch.js +146 -0
  109. package/dist/commands/channel/store/watch.js.map +1 -0
  110. package/dist/commands/channel/supervisor/idle.d.ts +46 -0
  111. package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
  112. package/dist/commands/channel/supervisor/idle.js +72 -0
  113. package/dist/commands/channel/supervisor/idle.js.map +1 -0
  114. package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
  115. package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
  116. package/dist/commands/channel/supervisor/inbox.js +160 -0
  117. package/dist/commands/channel/supervisor/inbox.js.map +1 -0
  118. package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
  119. package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
  120. package/dist/commands/channel/supervisor/shutdown.js +146 -0
  121. package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
  122. package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
  123. package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
  124. package/dist/commands/channel/supervisor/stdout.js +121 -0
  125. package/dist/commands/channel/supervisor/stdout.js.map +1 -0
  126. package/dist/commands/channel/supervisor/turns.d.ts +31 -0
  127. package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
  128. package/dist/commands/channel/supervisor/turns.js +45 -0
  129. package/dist/commands/channel/supervisor/turns.js.map +1 -0
  130. package/dist/commands/channel/supervisor/warning.d.ts +48 -0
  131. package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
  132. package/dist/commands/channel/supervisor/warning.js +77 -0
  133. package/dist/commands/channel/supervisor/warning.js.map +1 -0
  134. package/dist/commands/channel/supervisor.d.ts +59 -0
  135. package/dist/commands/channel/supervisor.d.ts.map +1 -0
  136. package/dist/commands/channel/supervisor.js +344 -0
  137. package/dist/commands/channel/supervisor.js.map +1 -0
  138. package/dist/commands/channel/text-body.d.ts +13 -0
  139. package/dist/commands/channel/text-body.d.ts.map +1 -0
  140. package/dist/commands/channel/text-body.js +47 -0
  141. package/dist/commands/channel/text-body.js.map +1 -0
  142. package/dist/commands/channel/threads.d.ts +39 -0
  143. package/dist/commands/channel/threads.d.ts.map +1 -0
  144. package/dist/commands/channel/threads.js +106 -0
  145. package/dist/commands/channel/threads.js.map +1 -0
  146. package/dist/commands/channel/title.d.ts +12 -0
  147. package/dist/commands/channel/title.d.ts.map +1 -0
  148. package/dist/commands/channel/title.js +24 -0
  149. package/dist/commands/channel/title.js.map +1 -0
  150. package/dist/commands/channel/wait.d.ts +17 -0
  151. package/dist/commands/channel/wait.d.ts.map +1 -0
  152. package/dist/commands/channel/wait.js +75 -0
  153. package/dist/commands/channel/wait.js.map +1 -0
  154. package/dist/commands/init.d.ts +2 -0
  155. package/dist/commands/init.d.ts.map +1 -1
  156. package/dist/commands/init.js +97 -42
  157. package/dist/commands/init.js.map +1 -1
  158. package/dist/commands/mem.d.ts +13 -117
  159. package/dist/commands/mem.d.ts.map +1 -1
  160. package/dist/commands/mem.js +168 -1074
  161. package/dist/commands/mem.js.map +1 -1
  162. package/dist/commands/uninstall.d.ts.map +1 -1
  163. package/dist/commands/uninstall.js +28 -2
  164. package/dist/commands/uninstall.js.map +1 -1
  165. package/dist/commands/update.d.ts.map +1 -1
  166. package/dist/commands/update.js +31 -111
  167. package/dist/commands/update.js.map +1 -1
  168. package/dist/commands/upgrade.d.ts +28 -0
  169. package/dist/commands/upgrade.d.ts.map +1 -0
  170. package/dist/commands/upgrade.js +84 -0
  171. package/dist/commands/upgrade.js.map +1 -0
  172. package/dist/commands/workflow.d.ts +35 -0
  173. package/dist/commands/workflow.d.ts.map +1 -0
  174. package/dist/commands/workflow.js +219 -0
  175. package/dist/commands/workflow.js.map +1 -0
  176. package/dist/configurators/claude.d.ts.map +1 -1
  177. package/dist/configurators/claude.js +1 -0
  178. package/dist/configurators/claude.js.map +1 -1
  179. package/dist/configurators/codex.d.ts.map +1 -1
  180. package/dist/configurators/codex.js +5 -3
  181. package/dist/configurators/codex.js.map +1 -1
  182. package/dist/configurators/shared.js +4 -4
  183. package/dist/configurators/shared.js.map +1 -1
  184. package/dist/configurators/workflow.d.ts +8 -0
  185. package/dist/configurators/workflow.d.ts.map +1 -1
  186. package/dist/configurators/workflow.js +3 -2
  187. package/dist/configurators/workflow.js.map +1 -1
  188. package/dist/migrations/manifests/0.5.10.json +9 -0
  189. package/dist/migrations/manifests/0.5.11.json +16 -0
  190. package/dist/migrations/manifests/0.5.12.json +9 -0
  191. package/dist/migrations/manifests/0.5.13.json +9 -0
  192. package/dist/migrations/manifests/0.5.14.json +9 -0
  193. package/dist/migrations/manifests/0.5.15.json +9 -0
  194. package/dist/migrations/manifests/0.5.16.json +9 -0
  195. package/dist/migrations/manifests/0.5.17.json +9 -0
  196. package/dist/migrations/manifests/0.5.18.json +9 -0
  197. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  198. package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
  199. package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
  200. package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
  201. package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
  202. package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
  203. package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
  204. package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
  205. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  206. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  207. package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
  208. package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
  209. package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
  210. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  211. package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
  212. package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
  213. package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
  214. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  215. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  216. package/dist/templates/claude/agents/trellis-check.md +13 -7
  217. package/dist/templates/claude/agents/trellis-implement.md +8 -7
  218. package/dist/templates/claude/settings.json +4 -4
  219. package/dist/templates/codebuddy/agents/trellis-check.md +13 -7
  220. package/dist/templates/codebuddy/agents/trellis-implement.md +8 -7
  221. package/dist/templates/codebuddy/settings.json +4 -4
  222. package/dist/templates/codex/agents/trellis-check.toml +4 -4
  223. package/dist/templates/codex/agents/trellis-implement.toml +4 -4
  224. package/dist/templates/codex/config.toml +9 -16
  225. package/dist/templates/codex/hooks/session-start.py +205 -119
  226. package/dist/templates/codex/hooks.json +2 -2
  227. package/dist/templates/codex/skills/before-dev/SKILL.md +12 -6
  228. package/dist/templates/codex/skills/brainstorm/SKILL.md +69 -457
  229. package/dist/templates/codex/skills/check/SKILL.md +86 -18
  230. package/dist/templates/codex/skills/start/SKILL.md +33 -323
  231. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +7 -4
  232. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
  233. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +3 -2
  234. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +5 -5
  235. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
  236. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +35 -6
  237. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +5 -4
  238. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/SKILL.md +41 -0
  239. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/mcp-setup.md +90 -0
  240. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/repository-analysis.md +59 -0
  241. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-task-planning.md +61 -0
  242. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-writing.md +70 -0
  243. package/dist/templates/common/commands/continue.md +6 -5
  244. package/dist/templates/common/commands/start.md +9 -6
  245. package/dist/templates/common/skills/before-dev.md +12 -6
  246. package/dist/templates/common/skills/brainstorm.md +68 -504
  247. package/dist/templates/common/skills/check.md +7 -1
  248. package/dist/templates/copilot/hooks/session-start.py +219 -101
  249. package/dist/templates/copilot/hooks.json +2 -2
  250. package/dist/templates/copilot/prompts/before-dev.prompt.md +12 -6
  251. package/dist/templates/copilot/prompts/brainstorm.prompt.md +69 -457
  252. package/dist/templates/copilot/prompts/check.prompt.md +86 -18
  253. package/dist/templates/copilot/prompts/parallel.prompt.md +16 -8
  254. package/dist/templates/copilot/prompts/start.prompt.md +33 -367
  255. package/dist/templates/cursor/agents/trellis-check.md +13 -7
  256. package/dist/templates/cursor/agents/trellis-implement.md +8 -7
  257. package/dist/templates/cursor/hooks.json +1 -7
  258. package/dist/templates/droid/droids/trellis-check.md +13 -7
  259. package/dist/templates/droid/droids/trellis-implement.md +8 -7
  260. package/dist/templates/droid/settings.json +4 -4
  261. package/dist/templates/gemini/agents/trellis-check.md +11 -5
  262. package/dist/templates/gemini/agents/trellis-implement.md +7 -6
  263. package/dist/templates/gemini/settings.json +2 -2
  264. package/dist/templates/kiro/agents/trellis-check.json +1 -1
  265. package/dist/templates/kiro/agents/trellis-implement.json +1 -1
  266. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +127 -9
  267. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +171 -6
  268. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +333 -43
  269. package/dist/templates/markdown/spec/guides/index.md.txt +18 -0
  270. package/dist/templates/opencode/agents/trellis-check.md +13 -7
  271. package/dist/templates/opencode/agents/trellis-implement.md +9 -8
  272. package/dist/templates/opencode/lib/session-utils.js +212 -123
  273. package/dist/templates/opencode/lib/trellis-context.js +73 -11
  274. package/dist/templates/opencode/plugins/inject-subagent-context.js +131 -29
  275. package/dist/templates/opencode/plugins/inject-workflow-state.js +9 -5
  276. package/dist/templates/opencode/plugins/session-start.js +9 -1
  277. package/dist/templates/pi/agents/trellis-check.md +5 -4
  278. package/dist/templates/pi/agents/trellis-implement.md +5 -4
  279. package/dist/templates/pi/extensions/trellis/index.ts.txt +1357 -754
  280. package/dist/templates/qoder/agents/trellis-check.md +11 -5
  281. package/dist/templates/qoder/agents/trellis-implement.md +7 -6
  282. package/dist/templates/qoder/settings.json +4 -4
  283. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  284. package/dist/templates/shared-hooks/index.js +0 -1
  285. package/dist/templates/shared-hooks/index.js.map +1 -1
  286. package/dist/templates/shared-hooks/inject-subagent-context.py +36 -14
  287. package/dist/templates/shared-hooks/inject-workflow-state.py +40 -42
  288. package/dist/templates/shared-hooks/session-start.py +222 -171
  289. package/dist/templates/trellis/config.yaml +38 -0
  290. package/dist/templates/trellis/index.d.ts +1 -0
  291. package/dist/templates/trellis/index.d.ts.map +1 -1
  292. package/dist/templates/trellis/index.js +2 -0
  293. package/dist/templates/trellis/index.js.map +1 -1
  294. package/dist/templates/trellis/scripts/add_session.py +50 -24
  295. package/dist/templates/trellis/scripts/common/config.py +57 -1
  296. package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
  297. package/dist/templates/trellis/scripts/common/session_context.py +384 -137
  298. package/dist/templates/trellis/scripts/common/task_context.py +3 -3
  299. package/dist/templates/trellis/scripts/common/task_store.py +161 -15
  300. package/dist/templates/trellis/scripts/common/workflow_phase.py +7 -10
  301. package/dist/templates/trellis/scripts/task.py +3 -3
  302. package/dist/templates/trellis/workflow.md +119 -98
  303. package/dist/utils/cwd-guard.d.ts +38 -0
  304. package/dist/utils/cwd-guard.d.ts.map +1 -0
  305. package/dist/utils/cwd-guard.js +62 -0
  306. package/dist/utils/cwd-guard.js.map +1 -0
  307. package/dist/utils/file-writer.d.ts +13 -0
  308. package/dist/utils/file-writer.d.ts.map +1 -1
  309. package/dist/utils/file-writer.js +59 -1
  310. package/dist/utils/file-writer.js.map +1 -1
  311. package/dist/utils/manifest-prune.d.ts +61 -0
  312. package/dist/utils/manifest-prune.d.ts.map +1 -0
  313. package/dist/utils/manifest-prune.js +136 -0
  314. package/dist/utils/manifest-prune.js.map +1 -0
  315. package/dist/utils/task-json.d.ts +9 -42
  316. package/dist/utils/task-json.d.ts.map +1 -1
  317. package/dist/utils/task-json.js +8 -45
  318. package/dist/utils/task-json.js.map +1 -1
  319. package/dist/utils/template-hash.d.ts +32 -6
  320. package/dist/utils/template-hash.d.ts.map +1 -1
  321. package/dist/utils/template-hash.js +53 -31
  322. package/dist/utils/template-hash.js.map +1 -1
  323. package/dist/utils/uninstall-scrubbers.d.ts +1 -0
  324. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  325. package/dist/utils/uninstall-scrubbers.js +21 -0
  326. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  327. package/dist/utils/workflow-resolver.d.ts +86 -0
  328. package/dist/utils/workflow-resolver.d.ts.map +1 -0
  329. package/dist/utils/workflow-resolver.js +265 -0
  330. package/dist/utils/workflow-resolver.js.map +1 -0
  331. package/package.json +9 -8
@@ -24,6 +24,7 @@ from pathlib import Path
24
24
 
25
25
  from .config import (
26
26
  get_packages,
27
+ get_session_auto_commit,
27
28
  is_monorepo,
28
29
  resolve_package,
29
30
  validate_package,
@@ -41,6 +42,11 @@ from .paths import (
41
42
  get_repo_root,
42
43
  get_tasks_dir,
43
44
  )
45
+ from .safe_commit import (
46
+ print_gitignore_warning,
47
+ safe_archive_paths_to_add,
48
+ safe_git_add,
49
+ )
44
50
  from .task_utils import (
45
51
  archive_task_complete,
46
52
  find_task_by_name,
@@ -77,6 +83,30 @@ def ensure_tasks_dir(repo_root: Path) -> Path:
77
83
  return tasks_dir
78
84
 
79
85
 
86
+ def _find_archived_task_by_dir_name(tasks_dir: Path, dir_name: str) -> Path | None:
87
+ """Find an archived task directory with the exact active-task dir name."""
88
+ archive_dir = tasks_dir / DIR_ARCHIVE
89
+ if not archive_dir.is_dir():
90
+ return None
91
+
92
+ for month_dir in sorted(archive_dir.iterdir()):
93
+ if not month_dir.is_dir():
94
+ continue
95
+ candidate = month_dir / dir_name
96
+ if candidate.is_dir():
97
+ return candidate
98
+
99
+ return None
100
+
101
+
102
+ def _repo_relative_path(path: Path, repo_root: Path) -> str:
103
+ """Format a path relative to the repo root when possible."""
104
+ try:
105
+ return path.relative_to(repo_root).as_posix()
106
+ except ValueError:
107
+ return str(path)
108
+
109
+
80
110
  # =============================================================================
81
111
  # Sub-agent platform detection + JSONL seeding
82
112
  # =============================================================================
@@ -132,6 +162,32 @@ def _write_seed_jsonl(path: Path) -> None:
132
162
  path.write_text(json.dumps(seed, ensure_ascii=False) + "\n", encoding="utf-8")
133
163
 
134
164
 
165
+ def _default_prd_content(title: str, description: str | None = None) -> str:
166
+ """Return the default PRD skeleton created with every task."""
167
+ goal = (description or "").strip() or "TBD."
168
+ heading = title.strip() or "Untitled task"
169
+ return f"""# {heading}
170
+
171
+ ## Goal
172
+
173
+ {goal}
174
+
175
+ ## Requirements
176
+
177
+ - TBD
178
+
179
+ ## Acceptance Criteria
180
+
181
+ - [ ] TBD
182
+
183
+ ## Notes
184
+
185
+ - Keep `prd.md` focused on requirements, constraints, and acceptance criteria.
186
+ - Lightweight tasks can remain PRD-only.
187
+ - For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`.
188
+ """
189
+
190
+
135
191
  # =============================================================================
136
192
  # Command: create
137
193
  # =============================================================================
@@ -187,6 +243,13 @@ def cmd_create(args: argparse.Namespace) -> int:
187
243
  task_dir = tasks_dir / dir_name
188
244
  task_json_path = task_dir / FILE_TASK_JSON
189
245
 
246
+ archived_task_dir = _find_archived_task_by_dir_name(tasks_dir, dir_name)
247
+ if archived_task_dir:
248
+ print(colored(f"Error: Task already archived: {dir_name}", Colors.RED), file=sys.stderr)
249
+ print(f"Archived at: {_repo_relative_path(archived_task_dir, repo_root)}", file=sys.stderr)
250
+ print("Use a new slug if you intend to create a new task.", file=sys.stderr)
251
+ return 1
252
+
190
253
  if task_dir.exists():
191
254
  print(colored(f"Warning: Task directory already exists: {dir_name}", Colors.YELLOW), file=sys.stderr)
192
255
  else:
@@ -227,8 +290,15 @@ def cmd_create(args: argparse.Namespace) -> int:
227
290
 
228
291
  write_json(task_json_path, task_data)
229
292
 
293
+ prd_path = task_dir / "prd.md"
294
+ if not prd_path.exists():
295
+ prd_path.write_text(
296
+ _default_prd_content(args.title, args.description),
297
+ encoding="utf-8",
298
+ )
299
+
230
300
  # Seed implement.jsonl / check.jsonl for sub-agent-capable platforms.
231
- # Agent curates real entries in Phase 1.3 (see .trellis/workflow.md).
301
+ # Agent curates real entries during planning when the task needs them.
232
302
  # Agent-less platforms (Kilo / Antigravity / Windsurf) skip this — they
233
303
  # load specs via the trellis-before-dev skill instead of JSONL.
234
304
  seeded_jsonl = False
@@ -280,16 +350,15 @@ def cmd_create(args: argparse.Namespace) -> int:
280
350
  print(colored(f"Created task: {dir_name}", Colors.GREEN), file=sys.stderr)
281
351
  print("", file=sys.stderr)
282
352
  print(colored("Next steps:", Colors.BLUE), file=sys.stderr)
283
- print(" 1. Create prd.md with requirements", file=sys.stderr)
353
+ print(" - Fill prd.md with requirements and acceptance criteria", file=sys.stderr)
354
+ print(" - Lightweight task: PRD-only is valid", file=sys.stderr)
355
+ print(" - Complex task: add design.md and implement.md before task.py start", file=sys.stderr)
284
356
  if seeded_jsonl:
285
357
  print(
286
- " 2. Curate implement.jsonl / check.jsonl (spec + research files only "
287
- "see .trellis/workflow.md Phase 1.3)",
358
+ " - Curate implement.jsonl / check.jsonl as spec/research manifests when sub-agents need context",
288
359
  file=sys.stderr,
289
360
  )
290
- print(" 3. Run: python3 task.py start <dir>", file=sys.stderr)
291
- else:
292
- print(" 2. Run: python3 task.py start <dir>", file=sys.stderr)
361
+ print(" - Use /trellis:continue or phase context to decide the next step", file=sys.stderr)
293
362
  print("", file=sys.stderr)
294
363
 
295
364
  # Output relative path for script chaining
@@ -331,6 +400,9 @@ def cmd_archive(args: argparse.Namespace) -> int:
331
400
 
332
401
  # Update status before archiving
333
402
  today = datetime.now().strftime("%Y-%m-%d")
403
+ # Names of child task dirs whose task.json gets modified below; passed
404
+ # into safe_archive_paths_to_add so they're staged in this commit.
405
+ modified_children: list[str] = []
334
406
  if task_json_path.is_file():
335
407
  data = read_json(task_json_path)
336
408
  if data:
@@ -355,6 +427,7 @@ def cmd_archive(args: argparse.Namespace) -> int:
355
427
  if child_data:
356
428
  child_data["parent"] = None
357
429
  write_json(child_json, child_data)
430
+ modified_children.append(child_dir_path.name)
358
431
 
359
432
  # Clear any session that still points at this task before the path moves.
360
433
  from .active_task import clear_task_from_sessions
@@ -369,7 +442,16 @@ def cmd_archive(args: argparse.Namespace) -> int:
369
442
 
370
443
  # Auto-commit unless --no-commit
371
444
  if not getattr(args, "no_commit", False):
372
- _auto_commit_archive(dir_name, repo_root)
445
+ if not _auto_commit_archive(dir_name, repo_root, modified_children):
446
+ print(
447
+ colored(
448
+ "Archive moved on disk, but git auto-commit did not complete. "
449
+ "Resolve `git status` before continuing.",
450
+ Colors.RED,
451
+ ),
452
+ file=sys.stderr,
453
+ )
454
+ return 1
373
455
 
374
456
  # Return the archive path
375
457
  print(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{year_month}/{dir_name}")
@@ -382,25 +464,89 @@ def cmd_archive(args: argparse.Namespace) -> int:
382
464
  return 1
383
465
 
384
466
 
385
- def _auto_commit_archive(task_name: str, repo_root: Path) -> None:
386
- """Stage .trellis/tasks/ changes and commit after archive."""
387
- tasks_rel = f"{DIR_WORKFLOW}/{DIR_TASKS}"
388
- run_git(["add", "-A", tasks_rel], cwd=repo_root)
467
+ def _auto_commit_archive(
468
+ task_name: str,
469
+ repo_root: Path,
470
+ modified_children: list[str] | None = None,
471
+ ) -> bool:
472
+ """Stage Trellis-owned task paths and commit after archive.
473
+
474
+ Scoped narrowly to the archived task's source + destination paths
475
+ plus any child task dirs whose ``task.json`` was edited (parent →
476
+ children relationship update). Dirty changes in OTHER active task
477
+ dirs are NOT bundled into the archive commit.
478
+
479
+ If ``.gitignore`` blocks the paths, we warn + skip — we do NOT
480
+ retry with ``git add -f``. The warning explicitly forbids
481
+ ``git add -f .trellis/`` (which would fan out to caches/backups)
482
+ and points users at ``session_auto_commit: false``.
483
+
484
+ Honors ``session_auto_commit`` in ``.trellis/config.yaml``: when
485
+ set to ``false``, this function returns immediately without
486
+ touching git (the archive directory move on disk is unaffected).
487
+ """
488
+ if not get_session_auto_commit(repo_root):
489
+ print(
490
+ "[OK] session_auto_commit: false — skipping git stage/commit.",
491
+ file=sys.stderr,
492
+ )
493
+ return True
494
+
495
+ source_rel = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}"
496
+ rc, tracked_out, _ = run_git(
497
+ ["ls-files", "--", source_rel],
498
+ cwd=repo_root,
499
+ )
500
+ source_was_tracked = rc == 0 and bool(tracked_out.strip())
501
+
502
+ paths = safe_archive_paths_to_add(
503
+ repo_root, task_name=task_name, modified_children=modified_children
504
+ )
505
+ if not paths:
506
+ print("[OK] No task changes to commit.", file=sys.stderr)
507
+ return True
508
+
509
+ success, _, err = safe_git_add(paths, repo_root)
510
+ if not success:
511
+ if err and "ignored by" in err.lower():
512
+ print_gitignore_warning(paths)
513
+ else:
514
+ print(
515
+ f"[WARN] git add failed: {err.strip() if err else 'unknown error'}",
516
+ file=sys.stderr,
517
+ )
518
+ return not source_was_tracked
519
+
520
+ # Belt-and-suspenders for the phantom-delete bug: `safe_git_add` uses
521
+ # `git add` (no -A) which only stages additions/modifications. The
522
+ # source task directory was moved away by `shutil.move`, so its files
523
+ # need an explicit `git rm --cached` to stage the deletions in this
524
+ # same commit — otherwise they sit as uncommitted "phantom deletes"
525
+ # against HEAD until something later picks them up.
526
+ #
527
+ # `--ignore-unmatch` makes this a no-op when the task was never tracked
528
+ # (e.g. archiving a task that lived only in working tree).
529
+ run_git(
530
+ ["rm", "-r", "--cached", "--ignore-unmatch", "--", source_rel],
531
+ cwd=repo_root,
532
+ )
389
533
 
390
- # Check if there are staged changes
391
534
  rc, _, _ = run_git(
392
- ["diff", "--cached", "--quiet", "--", tasks_rel], cwd=repo_root
535
+ ["diff", "--cached", "--quiet", "--", *paths, source_rel],
536
+ cwd=repo_root,
393
537
  )
394
538
  if rc == 0:
395
539
  print("[OK] No task changes to commit.", file=sys.stderr)
396
- return
540
+ return True
397
541
 
398
542
  commit_msg = f"chore(task): archive {task_name}"
399
543
  rc, _, err = run_git(["commit", "-m", commit_msg], cwd=repo_root)
400
544
  if rc == 0:
401
545
  print(f"[OK] Auto-committed: {commit_msg}", file=sys.stderr)
546
+ return True
402
547
  else:
403
548
  print(f"[WARN] Auto-commit failed: {err.strip()}", file=sys.stderr)
549
+ return not source_was_tracked
404
550
 
405
551
 
406
552
  # =============================================================================
@@ -60,15 +60,12 @@ def _parse_marker(line: str) -> tuple[bool, list[str]] | None:
60
60
 
61
61
 
62
62
  def get_phase_index() -> str:
63
- """Return Phase Index + Phase 1/2/3 step bodies from workflow.md.
64
-
65
- Matches what the SessionStart hook injects into the `<workflow>` block:
66
- starts at `## Phase Index`, continues through `## Phase 1: Plan`,
67
- `## Phase 2: Execute`, `## Phase 3: Finish`, stops at
68
- `## Customizing Trellis (for forks)` (the docs-for-forks footer).
69
- `[workflow-state:STATUS]` tag blocks (now embedded in Phase Index since
70
- v0.5.0-rc.0) are consumed by the UserPromptSubmit hook so they're
71
- stripped from this output.
63
+ """Return the compact Phase Index summary from workflow.md.
64
+
65
+ SessionStart and no-step phase context use this small summary as their
66
+ orientation payload. Detailed Phase 1/2/3 instructions are loaded with
67
+ ``get_step`` on demand. ``[workflow-state:STATUS]`` tag blocks are
68
+ consumed by the per-turn hook, so they're stripped from this output.
72
69
  """
73
70
  text = _read_workflow()
74
71
  lines = text.splitlines()
@@ -80,7 +77,7 @@ def get_phase_index() -> str:
80
77
  if start is None and stripped == _PHASE_INDEX_HEADING:
81
78
  start = i
82
79
  continue
83
- if start is not None and stripped == "## Customizing Trellis (for forks)":
80
+ if start is not None and stripped == "## Phase 1: Plan":
84
81
  end = i
85
82
  break
86
83
 
@@ -369,12 +369,12 @@ def main() -> int:
369
369
  file=sys.stderr,
370
370
  )
371
371
  print(
372
- "sub-agent-capable platforms and curated by the AI during Phase 1.3.",
372
+ "sub-agent-capable platforms and curated by the AI during planning when needed.",
373
373
  file=sys.stderr,
374
374
  )
375
- print("See .trellis/workflow.md Phase 1.3 or run:", file=sys.stderr)
375
+ print("See .trellis/workflow.md planning artifact guidance or run:", file=sys.stderr)
376
376
  print(
377
- " python3 ./.trellis/scripts/get_context.py --mode phase --step 1.3",
377
+ " python3 ./.trellis/scripts/get_context.py --mode phase --step 1",
378
378
  file=sys.stderr,
379
379
  )
380
380
  print(