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

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 (330) 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.3.json +9 -0
  209. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  210. package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
  211. package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
  212. package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
  213. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  214. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  215. package/dist/templates/claude/agents/trellis-check.md +13 -7
  216. package/dist/templates/claude/agents/trellis-implement.md +8 -7
  217. package/dist/templates/claude/settings.json +4 -4
  218. package/dist/templates/codebuddy/agents/trellis-check.md +13 -7
  219. package/dist/templates/codebuddy/agents/trellis-implement.md +8 -7
  220. package/dist/templates/codebuddy/settings.json +4 -4
  221. package/dist/templates/codex/agents/trellis-check.toml +4 -4
  222. package/dist/templates/codex/agents/trellis-implement.toml +4 -4
  223. package/dist/templates/codex/config.toml +5 -3
  224. package/dist/templates/codex/hooks/session-start.py +205 -119
  225. package/dist/templates/codex/hooks.json +2 -2
  226. package/dist/templates/codex/skills/before-dev/SKILL.md +12 -6
  227. package/dist/templates/codex/skills/brainstorm/SKILL.md +69 -457
  228. package/dist/templates/codex/skills/check/SKILL.md +86 -18
  229. package/dist/templates/codex/skills/start/SKILL.md +33 -323
  230. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +7 -4
  231. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
  232. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +3 -2
  233. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +5 -5
  234. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
  235. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +35 -6
  236. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +5 -4
  237. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/SKILL.md +41 -0
  238. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/mcp-setup.md +90 -0
  239. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/repository-analysis.md +59 -0
  240. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-task-planning.md +61 -0
  241. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-writing.md +70 -0
  242. package/dist/templates/common/commands/continue.md +6 -5
  243. package/dist/templates/common/commands/start.md +9 -6
  244. package/dist/templates/common/skills/before-dev.md +12 -6
  245. package/dist/templates/common/skills/brainstorm.md +68 -504
  246. package/dist/templates/common/skills/check.md +7 -1
  247. package/dist/templates/copilot/hooks/session-start.py +219 -101
  248. package/dist/templates/copilot/hooks.json +2 -2
  249. package/dist/templates/copilot/prompts/before-dev.prompt.md +12 -6
  250. package/dist/templates/copilot/prompts/brainstorm.prompt.md +69 -457
  251. package/dist/templates/copilot/prompts/check.prompt.md +86 -18
  252. package/dist/templates/copilot/prompts/parallel.prompt.md +16 -8
  253. package/dist/templates/copilot/prompts/start.prompt.md +33 -367
  254. package/dist/templates/cursor/agents/trellis-check.md +13 -7
  255. package/dist/templates/cursor/agents/trellis-implement.md +8 -7
  256. package/dist/templates/cursor/hooks.json +1 -7
  257. package/dist/templates/droid/droids/trellis-check.md +13 -7
  258. package/dist/templates/droid/droids/trellis-implement.md +8 -7
  259. package/dist/templates/droid/settings.json +4 -4
  260. package/dist/templates/gemini/agents/trellis-check.md +11 -5
  261. package/dist/templates/gemini/agents/trellis-implement.md +7 -6
  262. package/dist/templates/gemini/settings.json +2 -2
  263. package/dist/templates/kiro/agents/trellis-check.json +1 -1
  264. package/dist/templates/kiro/agents/trellis-implement.json +1 -1
  265. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +127 -9
  266. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +171 -6
  267. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +333 -43
  268. package/dist/templates/markdown/spec/guides/index.md.txt +18 -0
  269. package/dist/templates/opencode/agents/trellis-check.md +13 -7
  270. package/dist/templates/opencode/agents/trellis-implement.md +9 -8
  271. package/dist/templates/opencode/lib/session-utils.js +212 -123
  272. package/dist/templates/opencode/lib/trellis-context.js +73 -11
  273. package/dist/templates/opencode/plugins/inject-subagent-context.js +131 -29
  274. package/dist/templates/opencode/plugins/inject-workflow-state.js +9 -5
  275. package/dist/templates/opencode/plugins/session-start.js +9 -1
  276. package/dist/templates/pi/agents/trellis-check.md +5 -4
  277. package/dist/templates/pi/agents/trellis-implement.md +5 -4
  278. package/dist/templates/pi/extensions/trellis/index.ts.txt +1357 -754
  279. package/dist/templates/qoder/agents/trellis-check.md +11 -5
  280. package/dist/templates/qoder/agents/trellis-implement.md +7 -6
  281. package/dist/templates/qoder/settings.json +4 -4
  282. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  283. package/dist/templates/shared-hooks/index.js +0 -1
  284. package/dist/templates/shared-hooks/index.js.map +1 -1
  285. package/dist/templates/shared-hooks/inject-subagent-context.py +36 -14
  286. package/dist/templates/shared-hooks/inject-workflow-state.py +40 -42
  287. package/dist/templates/shared-hooks/session-start.py +222 -171
  288. package/dist/templates/trellis/config.yaml +38 -0
  289. package/dist/templates/trellis/index.d.ts +1 -0
  290. package/dist/templates/trellis/index.d.ts.map +1 -1
  291. package/dist/templates/trellis/index.js +2 -0
  292. package/dist/templates/trellis/index.js.map +1 -1
  293. package/dist/templates/trellis/scripts/add_session.py +50 -24
  294. package/dist/templates/trellis/scripts/common/config.py +57 -1
  295. package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
  296. package/dist/templates/trellis/scripts/common/session_context.py +384 -137
  297. package/dist/templates/trellis/scripts/common/task_context.py +3 -3
  298. package/dist/templates/trellis/scripts/common/task_store.py +161 -15
  299. package/dist/templates/trellis/scripts/common/workflow_phase.py +7 -10
  300. package/dist/templates/trellis/scripts/task.py +3 -3
  301. package/dist/templates/trellis/workflow.md +119 -98
  302. package/dist/utils/cwd-guard.d.ts +38 -0
  303. package/dist/utils/cwd-guard.d.ts.map +1 -0
  304. package/dist/utils/cwd-guard.js +62 -0
  305. package/dist/utils/cwd-guard.js.map +1 -0
  306. package/dist/utils/file-writer.d.ts +13 -0
  307. package/dist/utils/file-writer.d.ts.map +1 -1
  308. package/dist/utils/file-writer.js +59 -1
  309. package/dist/utils/file-writer.js.map +1 -1
  310. package/dist/utils/manifest-prune.d.ts +61 -0
  311. package/dist/utils/manifest-prune.d.ts.map +1 -0
  312. package/dist/utils/manifest-prune.js +136 -0
  313. package/dist/utils/manifest-prune.js.map +1 -0
  314. package/dist/utils/task-json.d.ts +9 -42
  315. package/dist/utils/task-json.d.ts.map +1 -1
  316. package/dist/utils/task-json.js +8 -45
  317. package/dist/utils/task-json.js.map +1 -1
  318. package/dist/utils/template-hash.d.ts +32 -6
  319. package/dist/utils/template-hash.d.ts.map +1 -1
  320. package/dist/utils/template-hash.js +53 -31
  321. package/dist/utils/template-hash.js.map +1 -1
  322. package/dist/utils/uninstall-scrubbers.d.ts +1 -0
  323. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  324. package/dist/utils/uninstall-scrubbers.js +21 -0
  325. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  326. package/dist/utils/workflow-resolver.d.ts +86 -0
  327. package/dist/utils/workflow-resolver.d.ts.map +1 -0
  328. package/dist/utils/workflow-resolver.js +265 -0
  329. package/dist/utils/workflow-resolver.js.map +1 -0
  330. package/package.json +9 -8
@@ -1,17 +1,46 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  """
4
- Copilot Session Start Hook - Emit Trellis session-start diagnostics.
5
-
6
- GitHub Copilot's documented SessionStart behavior ignores hook output, so this
7
- script must not be treated as proof that model-visible context was injected.
8
- The JSON shape is kept for parity with other Trellis hooks and future host
9
- support, but current Copilot users should rely on UserPromptSubmit breadcrumbs
10
- and hook logs instead.
4
+ Copilot Session Start Hook - Emit Trellis session-start context.
5
+
6
+ Microsoft VS Code Agent hooks are in preview and have been documented since
7
+ VS Code 1.110 (February 2026). The official documentation
8
+ (https://code.visualstudio.com/docs/copilot/customization/hooks) defines
9
+ `SessionStart.hookSpecificOutput.additionalContext` as the field used to inject
10
+ additional context into the agent's conversation.
11
+
12
+ This script emits the spec-compliant SessionStart payload. Whether Copilot
13
+ actually consumes `additionalContext` depends on the user's installed VS Code
14
+ and Copilot versions, which is outside Trellis's control. UserPromptSubmit
15
+ breadcrumbs remain available as a per-turn complement.
11
16
  """
12
17
 
13
18
  from __future__ import annotations
14
19
 
20
+ import sys
21
+
22
+ # Force UTF-8 on stdin/stdout/stderr on Windows. Default codepage there is
23
+ # cp936 / cp1252 / etc. — non-ASCII content (Chinese task names, prd snippets)
24
+ # both in stdin (hook payload from host CLI) and stdout (our emitted blocks)
25
+ # raises UnicodeDecodeError / UnicodeEncodeError. Equivalent to `python -X utf8`
26
+ # but applied per-stream so we don't depend on host CLI's command wiring.
27
+ if sys.platform.startswith("win"):
28
+ import io as _io
29
+ for _stream_name in ("stdin", "stdout", "stderr"):
30
+ _stream = getattr(sys, _stream_name, None)
31
+ if _stream is None:
32
+ continue
33
+ if hasattr(_stream, "reconfigure"):
34
+ try:
35
+ _stream.reconfigure(encoding="utf-8", errors="replace") # type: ignore[union-attr]
36
+ except Exception:
37
+ pass
38
+ elif hasattr(_stream, "detach"):
39
+ try:
40
+ setattr(sys, _stream_name, _io.TextIOWrapper(_stream.detach(), encoding="utf-8", errors="replace"))
41
+ except Exception:
42
+ pass
43
+
15
44
  import json
16
45
  import os
17
46
  import re
@@ -199,12 +228,19 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
199
228
  def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
200
229
  active = _resolve_active_task(trellis_dir, hook_input)
201
230
  if not active.task_path:
202
- return f"Status: NO ACTIVE TASK\nSource: {active.source}\nNext: Describe what you want to work on"
231
+ return (
232
+ "Status: NO ACTIVE TASK\n"
233
+ "Next: Classify the current turn and ask for task-creation consent "
234
+ "before creating any Trellis task."
235
+ )
203
236
 
204
237
  task_ref = active.task_path
205
238
  task_dir = _resolve_task_dir(trellis_dir, task_ref)
206
239
  if active.stale or not task_dir.is_dir():
207
- return f"Status: STALE POINTER\nTask: {task_ref}\nSource: {active.source}\nNext: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
240
+ return (
241
+ f"Status: STALE POINTER\nTask: {task_ref}\n"
242
+ "Next: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
243
+ )
208
244
 
209
245
  task_json_path = task_dir / "task.json"
210
246
  task_data: dict = {}
@@ -218,36 +254,170 @@ def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
218
254
  task_status = task_data.get("status", "unknown")
219
255
 
220
256
  if task_status == "completed":
221
- return f"Status: COMPLETED\nTask: {task_title}\nSource: {active.source}\nNext: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` or start a new task"
222
-
223
- has_context = False
224
- for jsonl_name in ("implement.jsonl", "check.jsonl", "spec.jsonl"):
225
- jsonl_path = task_dir / jsonl_name
226
- if jsonl_path.is_file() and _has_curated_jsonl_entry(jsonl_path):
227
- has_context = True
228
- break
257
+ return (
258
+ f"Status: COMPLETED\nTask: {task_title}\n"
259
+ f"Next: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` "
260
+ "or start a new task."
261
+ )
229
262
 
230
263
  has_prd = (task_dir / "prd.md").is_file()
264
+ has_design = (task_dir / "design.md").is_file()
265
+ has_implement = (task_dir / "implement.md").is_file()
266
+ present = [
267
+ name
268
+ for name in ("prd.md", "design.md", "implement.md", "implement.jsonl", "check.jsonl")
269
+ if (task_dir / name).is_file()
270
+ ]
271
+ present_line = ", ".join(present) if present else "none"
231
272
 
232
273
  if not has_prd:
233
- return f"Status: NOT READY\nTask: {task_title}\nSource: {active.source}\nMissing: prd.md not created\nNext: Write PRD (see workflow.md Phase 1.1) then curate implement.jsonl per Phase 1.3"
274
+ return (
275
+ f"Status: PLANNING\nTask: {task_title}\nPresent: {present_line}\n"
276
+ "Next: Load trellis-brainstorm and write prd.md. Stay in planning."
277
+ )
234
278
 
235
- if not has_context:
236
- return f"Status: NOT READY\nTask: {task_title}\nSource: {active.source}\nMissing: implement.jsonl / check.jsonl missing or empty\nNext: Curate entries per workflow.md Phase 1.3 (spec + research files only), then `task.py start`"
279
+ if task_status == "planning":
280
+ if has_design and has_implement:
281
+ next_action = "Review planning artifacts with the user before `task.py start`."
282
+ else:
283
+ next_action = (
284
+ "Lightweight task can ask for start review with PRD-only; "
285
+ "complex task must add design.md and implement.md before `task.py start`."
286
+ )
287
+ return (
288
+ f"Status: PLANNING\nTask: {task_title}\nPresent: {present_line}\n"
289
+ f"Next: {next_action}"
290
+ )
237
291
 
238
292
  return (
239
- f"Status: READY\nTask: {task_title}\n"
240
- f"Source: {active.source}\n"
241
- "Next required action: dispatch `trellis-implement` per Phase 2.1. "
242
- "For agent-capable platforms, the default is to NOT edit code in the main session. "
243
- "After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
244
- "User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
245
- "main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
246
- "\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
247
- "Per-turn only; do NOT invent an override the user did not say."
293
+ f"Status: {task_status.upper()}\nTask: {task_title}\nPresent: {present_line}\n"
294
+ "Next: Follow the matching per-turn workflow-state. Context order is jsonl entries, "
295
+ "prd.md, design.md if present, implement.md if present."
248
296
  )
249
297
 
250
298
 
299
+ def _run_git(repo_root: Path, args: list[str]) -> str:
300
+ try:
301
+ result = subprocess.run(
302
+ ["git", *args],
303
+ capture_output=True,
304
+ text=True,
305
+ encoding="utf-8",
306
+ errors="replace",
307
+ timeout=3,
308
+ cwd=str(repo_root),
309
+ )
310
+ except (subprocess.TimeoutExpired, FileNotFoundError, PermissionError):
311
+ return ""
312
+ if result.returncode != 0:
313
+ return ""
314
+ return result.stdout.strip()
315
+
316
+
317
+ def _format_git_state(repo_root: Path) -> str:
318
+ branch = _run_git(repo_root, ["branch", "--show-current"]) or "(detached)"
319
+ dirty_lines = [
320
+ line for line in _run_git(repo_root, ["status", "--porcelain"]).splitlines()
321
+ if line.strip()
322
+ ]
323
+ dirty_text = "clean" if not dirty_lines else f"dirty {len(dirty_lines)} paths"
324
+ return f"Git: branch {branch}; {dirty_text}."
325
+
326
+
327
+ def _repo_relative(repo_root: Path, path: Path) -> str:
328
+ try:
329
+ return path.relative_to(repo_root).as_posix()
330
+ except ValueError:
331
+ return str(path)
332
+
333
+
334
+ def _collect_spec_index_paths(trellis_dir: Path) -> list[str]:
335
+ paths: list[str] = []
336
+ guides_index = trellis_dir / "spec" / "guides" / "index.md"
337
+ if guides_index.is_file():
338
+ paths.append(".trellis/spec/guides/index.md")
339
+
340
+ spec_dir = trellis_dir / "spec"
341
+ if not spec_dir.is_dir():
342
+ return paths
343
+
344
+ for sub in sorted(spec_dir.iterdir()):
345
+ if not sub.is_dir() or sub.name.startswith(".") or sub.name == "guides":
346
+ continue
347
+ index_file = sub / "index.md"
348
+ if index_file.is_file():
349
+ paths.append(f".trellis/spec/{sub.name}/index.md")
350
+ continue
351
+ for nested in sorted(sub.iterdir()):
352
+ if not nested.is_dir():
353
+ continue
354
+ nested_index = nested / "index.md"
355
+ if nested_index.is_file():
356
+ paths.append(f".trellis/spec/{sub.name}/{nested.name}/index.md")
357
+
358
+ return paths
359
+
360
+
361
+ def _build_compact_current_state(
362
+ trellis_dir: Path,
363
+ hook_input: dict,
364
+ spec_index_paths: list[str],
365
+ ) -> str:
366
+ repo_root = trellis_dir.parent
367
+ lines: list[str] = []
368
+
369
+ try:
370
+ from common.paths import get_active_journal_file, get_developer, get_tasks_dir, count_lines # type: ignore[import-not-found]
371
+ from common.tasks import iter_active_tasks # type: ignore[import-not-found]
372
+ except Exception:
373
+ get_active_journal_file = None # type: ignore[assignment]
374
+ get_developer = None # type: ignore[assignment]
375
+ get_tasks_dir = None # type: ignore[assignment]
376
+ count_lines = None # type: ignore[assignment]
377
+ iter_active_tasks = None # type: ignore[assignment]
378
+
379
+ developer = get_developer(repo_root) if get_developer else None
380
+ lines.append(f"Developer: {developer or '(not initialized)'}")
381
+ lines.append(_format_git_state(repo_root))
382
+
383
+ active = _resolve_active_task(trellis_dir, hook_input)
384
+ if active.task_path:
385
+ task_dir = _resolve_task_dir(trellis_dir, active.task_path)
386
+ status = "unknown"
387
+ task_json = task_dir / "task.json"
388
+ if task_json.is_file():
389
+ try:
390
+ data = json.loads(task_json.read_text(encoding="utf-8"))
391
+ if isinstance(data, dict):
392
+ status = str(data.get("status") or "unknown")
393
+ except (json.JSONDecodeError, OSError):
394
+ pass
395
+ lines.append(f"Current task: {_repo_relative(repo_root, task_dir)}; status={status}.")
396
+ else:
397
+ lines.append("Current task: none.")
398
+
399
+ if get_tasks_dir and iter_active_tasks:
400
+ try:
401
+ task_count = sum(1 for _ in iter_active_tasks(get_tasks_dir(repo_root)))
402
+ lines.append(
403
+ f"Active tasks: {task_count} total. Use `python3 ./.trellis/scripts/task.py list --mine` only if needed."
404
+ )
405
+ except Exception:
406
+ pass
407
+
408
+ if get_active_journal_file and count_lines:
409
+ journal = get_active_journal_file(repo_root)
410
+ if journal:
411
+ lines.append(
412
+ f"Journal: {_repo_relative(repo_root, journal)}, {count_lines(journal)} / 2000 lines."
413
+ )
414
+
415
+ if spec_index_paths:
416
+ lines.append(f"Spec indexes: {len(spec_index_paths)} available.")
417
+
418
+ return "\n".join(lines)
419
+
420
+
251
421
  def _extract_range(content: str, start_header: str, end_header: str) -> str:
252
422
  """Extract lines starting at `## start_header` up to (but excluding) `## end_header`."""
253
423
  lines = content.splitlines()
@@ -275,32 +445,25 @@ _BREADCRUMB_TAG_RE = re.compile(
275
445
 
276
446
 
277
447
  def _strip_breadcrumb_tag_blocks(content: str) -> str:
278
- return _BREADCRUMB_TAG_RE.sub("", content)
448
+ stripped = _BREADCRUMB_TAG_RE.sub("", content)
449
+ stripped = re.sub(r"<!--.*?-->", "", stripped, flags=re.DOTALL)
450
+ stripped = re.sub(r"^\[(?!/?workflow-state:)/?[^\]\n]+\]\s*\n?", "", stripped, flags=re.MULTILINE)
451
+ return re.sub(r"\n{3,}", "\n\n", stripped).strip()
279
452
 
280
453
 
281
454
  def _build_workflow_toc(workflow_path: Path) -> str:
282
- """Inject workflow guide: TOC + Phase Index + Phase 1/2/3 step details.
283
-
284
- Since v0.5.0-rc.0 the [workflow-state:STATUS] breadcrumb tag blocks
285
- live inside ## Phase Index. They're consumed by inject-workflow-state.py
286
- on each UserPromptSubmit, so strip them from the session-start payload.
287
- """
455
+ """Inject only the compact Phase Index summary for SessionStart."""
288
456
  content = read_file(workflow_path)
289
457
  if not content:
290
458
  return "No workflow.md found"
291
459
 
292
460
  out_lines = [
293
- "# Development Workflow Section Index",
294
- "Full guide: .trellis/workflow.md (read on demand)",
461
+ "# Development Workflow - Session Summary",
462
+ "Full guide: .trellis/workflow.md. Step detail: `python3 ./.trellis/scripts/get_context.py --mode phase --step <X.Y>`.",
295
463
  "",
296
- "## Table of Contents",
297
464
  ]
298
- for line in content.splitlines():
299
- if line.startswith("## "):
300
- out_lines.append(line)
301
- out_lines += ["", "---", ""]
302
465
 
303
- phases = _extract_range(content, "Phase Index", "Customizing Trellis (for forks)")
466
+ phases = _extract_range(content, "Phase Index", "Phase 1: Plan")
304
467
  if phases:
305
468
  out_lines.append(_strip_breadcrumb_tag_blocks(phases).rstrip())
306
469
 
@@ -324,73 +487,34 @@ def main() -> None:
324
487
  configure_project_encoding(project_dir)
325
488
 
326
489
  trellis_dir = project_dir / ".trellis"
327
- context_key = _resolve_context_key(project_dir, hook_input)
490
+ spec_index_paths = _collect_spec_index_paths(trellis_dir)
328
491
 
329
492
  output = StringIO()
330
493
 
331
494
  output.write("""<session-context>
332
- You are starting a new session in a Trellis-managed project.
333
- Read and follow all instructions below carefully.
495
+ Trellis compact SessionStart context. Use it to orient the session; load details on demand.
334
496
  </session-context>
335
497
 
336
498
  """)
337
499
 
338
500
  output.write("<current-state>\n")
339
- context_script = trellis_dir / "scripts" / "get_context.py"
340
- output.write(run_script(context_script, context_key))
501
+ output.write(_build_compact_current_state(trellis_dir, hook_input, spec_index_paths))
341
502
  output.write("\n</current-state>\n\n")
342
503
 
343
- output.write("<workflow>\n")
504
+ output.write("<trellis-workflow>\n")
344
505
  output.write(_build_workflow_toc(trellis_dir / "workflow.md"))
345
- output.write("\n</workflow>\n\n")
506
+ output.write("\n</trellis-workflow>\n\n")
346
507
 
347
508
  output.write("<guidelines>\n")
348
509
  output.write(
349
- "Project spec indexes are listed by path below. Each index contains a "
350
- "**Pre-Development Checklist** listing the specific guideline files to "
351
- "read before coding.\n\n"
352
- "- If you're spawning an implement/check sub-agent, context is injected "
353
- "automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
354
- "need to read these indexes yourself.\n"
355
- "- For agent-capable platforms, the default is to dispatch "
356
- "`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
357
- "the sub-agents) rather than editing code in the main session. "
358
- "Honor a per-turn user override only if the user's current message "
359
- "explicitly opts out (see <task-status> below for override phrases).\n\n"
510
+ "Task context order for implementation/check: jsonl entries -> `prd.md` -> "
511
+ "`design.md if present` -> `implement.md if present`. Missing optional artifacts "
512
+ "are skipped for lightweight tasks.\n\n"
360
513
  )
361
514
 
362
- # guides/ inlined (cross-package thinking, broadly useful)
363
- guides_index = trellis_dir / "spec" / "guides" / "index.md"
364
- if guides_index.is_file():
365
- output.write("## guides (inlined — cross-package thinking guides)\n")
366
- output.write(read_file(guides_index))
367
- output.write("\n\n")
368
-
369
- # Other indexes — paths only
370
- paths: list[str] = []
371
- spec_dir = trellis_dir / "spec"
372
- if spec_dir.is_dir():
373
- for sub in sorted(spec_dir.iterdir()):
374
- if not sub.is_dir() or sub.name.startswith("."):
375
- continue
376
- if sub.name == "guides":
377
- continue
378
- index_file = sub / "index.md"
379
- if index_file.is_file():
380
- paths.append(f".trellis/spec/{sub.name}/index.md")
381
- else:
382
- for nested in sorted(sub.iterdir()):
383
- if not nested.is_dir():
384
- continue
385
- nested_index = nested / "index.md"
386
- if nested_index.is_file():
387
- paths.append(
388
- f".trellis/spec/{sub.name}/{nested.name}/index.md"
389
- )
390
-
391
- if paths:
392
- output.write("## Available spec indexes (read on demand)\n")
393
- for p in paths:
515
+ if spec_index_paths:
516
+ output.write("## Available indexes (read on demand)\n")
517
+ for p in spec_index_paths:
394
518
  output.write(f"- {p}\n")
395
519
  output.write("\n")
396
520
 
@@ -404,18 +528,12 @@ Read and follow all instructions below carefully.
404
528
  output.write(f"<task-status>\n{task_status}\n</task-status>\n\n")
405
529
 
406
530
  output.write("""<ready>
407
- Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
408
- When the user sends the first message, follow <task-status> and the workflow guide.
409
- If a task is READY, execute its Next required action without asking whether to continue.
531
+ Context loaded. Follow <task-status>. Load workflow/spec/task details only when needed.
410
532
  </ready>""")
411
533
 
412
534
  context = output.getvalue()
413
535
  result = {
414
536
  "suppressOutput": True,
415
- "systemMessage": (
416
- f"Trellis SessionStart diagnostics emitted ({len(context)} chars); "
417
- "Copilot currently ignores sessionStart hook output."
418
- ),
419
537
  "hookSpecificOutput": {
420
538
  "hookEventName": "SessionStart",
421
539
  "additionalContext": context,
@@ -4,7 +4,7 @@
4
4
  {
5
5
  "type": "command",
6
6
  "command": "{{PYTHON_CMD}} .github/copilot/hooks/session-start.py",
7
- "timeout": 10
7
+ "timeout": 30
8
8
  }
9
9
  ],
10
10
  "userPromptSubmitted": [
@@ -12,7 +12,7 @@
12
12
  "type": "command",
13
13
  "bash": "{{PYTHON_CMD}} .github/copilot/hooks/inject-workflow-state.py",
14
14
  "powershell": "{{PYTHON_CMD}} .github/copilot/hooks/inject-workflow-state.py",
15
- "timeoutSec": 5
15
+ "timeoutSec": 15
16
16
  }
17
17
  ]
18
18
  }
@@ -6,28 +6,34 @@ Read the relevant development guidelines before starting your task.
6
6
 
7
7
  Execute these steps:
8
8
 
9
- 1. **Discover packages and their spec layers**:
9
+ 1. **Read current task artifacts**:
10
+ - `prd.md` for requirements and acceptance criteria
11
+ - `design.md` if present for technical design
12
+ - `implement.md` if present for execution order and validation plan
13
+
14
+ 2. **Discover packages and their spec layers**:
10
15
  ```bash
11
16
  python3 ./.trellis/scripts/get_context.py --mode packages
12
17
  ```
13
18
 
14
- 2. **Identify which specs apply** to your task based on:
19
+ 3. **Identify which specs apply** to your task based on:
15
20
  - Which package you're modifying (e.g., `cli/`, `docs-site/`)
16
21
  - What type of work (backend, frontend, unit-test, docs, etc.)
22
+ - Any spec/research paths referenced by the task artifacts
17
23
 
18
- 3. **Read the spec index** for each relevant module:
24
+ 4. **Read the spec index** for each relevant module:
19
25
  ```bash
20
26
  cat .trellis/spec/<package>/<layer>/index.md
21
27
  ```
22
28
  Follow the **"Pre-Development Checklist"** section in the index.
23
29
 
24
- 4. **Read the specific guideline files** listed in the Pre-Development Checklist that are relevant to your task. The index is NOT the goal �?it points you to the actual guideline files (e.g., `error-handling.md`, `conventions.md`, `mock-strategies.md`). Read those files to understand the coding standards and patterns.
30
+ 5. **Read the specific guideline files** listed in the Pre-Development Checklist that are relevant to your task. The index is NOT the goal it points you to the actual guideline files (e.g., `error-handling.md`, `conventions.md`, `mock-strategies.md`). Read those files to understand the coding standards and patterns.
25
31
 
26
- 5. **Always read shared guides**:
32
+ 6. **Always read shared guides**:
27
33
  ```bash
28
34
  cat .trellis/spec/guides/index.md
29
35
  ```
30
36
 
31
- 6. Understand the coding standards and patterns you need to follow, then proceed with your development plan.
37
+ 7. Understand the coding standards and patterns you need to follow, then proceed with your development plan.
32
38
 
33
39
  This step is **mandatory** before writing any code.