@blulotus/trellis 0.7.0 → 0.7.2

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 (343) hide show
  1. package/README.md +2 -2
  2. package/dist/cli/index.js +2 -29
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/init.d.ts +0 -22
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +5 -12
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/mem.d.ts +2 -2
  9. package/dist/commands/mem.d.ts.map +1 -1
  10. package/dist/commands/mem.js +7 -40
  11. package/dist/commands/mem.js.map +1 -1
  12. package/dist/commands/uninstall.d.ts +1 -1
  13. package/dist/commands/uninstall.d.ts.map +1 -1
  14. package/dist/commands/uninstall.js +4 -34
  15. package/dist/commands/uninstall.js.map +1 -1
  16. package/dist/commands/update.d.ts.map +1 -1
  17. package/dist/commands/update.js +2 -28
  18. package/dist/commands/update.js.map +1 -1
  19. package/dist/configurators/index.d.ts.map +1 -1
  20. package/dist/configurators/index.js +7 -73
  21. package/dist/configurators/index.js.map +1 -1
  22. package/dist/configurators/shared.d.ts +18 -70
  23. package/dist/configurators/shared.d.ts.map +1 -1
  24. package/dist/configurators/shared.js +20 -299
  25. package/dist/configurators/shared.js.map +1 -1
  26. package/dist/configurators/workflow.d.ts +0 -14
  27. package/dist/configurators/workflow.d.ts.map +1 -1
  28. package/dist/configurators/workflow.js +1 -37
  29. package/dist/configurators/workflow.js.map +1 -1
  30. package/dist/migrations/manifests/0.1.9.json +0 -12
  31. package/dist/migrations/manifests/0.2.14.json +0 -84
  32. package/dist/migrations/manifests/0.3.0-beta.0.json +0 -87
  33. package/dist/migrations/manifests/0.3.4.json +1 -13
  34. package/dist/migrations/manifests/0.4.0-beta.1.json +24 -176
  35. package/dist/migrations/manifests/0.5.0-beta.0.json +67 -1203
  36. package/dist/migrations/manifests/0.5.0-beta.15.json +0 -96
  37. package/dist/migrations/manifests/0.5.0-beta.5.json +0 -168
  38. package/dist/migrations/manifests/0.5.0-beta.9.json +0 -20
  39. package/dist/migrations/manifests/0.6.0-beta.23.json +0 -66
  40. package/dist/migrations/manifests/0.6.3.json +1 -16
  41. package/dist/migrations/manifests/0.6.6.json +1 -9
  42. package/dist/migrations/manifests/0.7.0.json +9 -0
  43. package/dist/migrations/manifests/0.7.1.json +9 -0
  44. package/dist/migrations/manifests/0.7.2.json +9 -0
  45. package/dist/migrations/manifests/0.8.0.json +9 -0
  46. package/dist/templates/codex/hooks/session-start.py +37 -13
  47. package/dist/templates/codex/hooks.json +5 -0
  48. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +5 -5
  49. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +0 -10
  50. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +1 -1
  51. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +1 -13
  52. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +2 -2
  53. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +9 -28
  54. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +5 -5
  55. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +1 -1
  56. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +1 -17
  57. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +4 -12
  58. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +6 -6
  59. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +5 -75
  60. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +0 -16
  61. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +1 -1
  62. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +2 -3
  63. package/dist/templates/common/commands/continue.md +24 -4
  64. package/dist/templates/common/commands/finish-work.md +19 -9
  65. package/dist/templates/common/commands/start.md +38 -29
  66. package/dist/templates/extract.d.ts +0 -10
  67. package/dist/templates/extract.d.ts.map +1 -1
  68. package/dist/templates/extract.js +0 -24
  69. package/dist/templates/extract.js.map +1 -1
  70. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +7 -9
  71. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +4 -8
  72. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +5 -5
  73. package/dist/templates/shared-hooks/index.d.ts +11 -43
  74. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  75. package/dist/templates/shared-hooks/index.js +9 -86
  76. package/dist/templates/shared-hooks/index.js.map +1 -1
  77. package/dist/templates/shared-hooks/inject-spec-context.py +1 -1
  78. package/dist/templates/shared-hooks/inject-subagent-context.py +23 -85
  79. package/dist/templates/shared-hooks/inject-workflow-state.py +56 -86
  80. package/dist/templates/shared-hooks/session-start.py +76 -98
  81. package/dist/templates/trellis/config.yaml +8 -8
  82. package/dist/templates/trellis/index.d.ts +1 -4
  83. package/dist/templates/trellis/index.d.ts.map +1 -1
  84. package/dist/templates/trellis/index.js +1 -5
  85. package/dist/templates/trellis/index.js.map +1 -1
  86. package/dist/templates/trellis/scripts/add_session.py +12 -11
  87. package/dist/templates/trellis/scripts/common/__init__.py +2 -0
  88. package/dist/templates/trellis/scripts/common/active_task.py +80 -152
  89. package/dist/templates/trellis/scripts/common/config.py +7 -7
  90. package/dist/templates/trellis/scripts/common/git_context.py +1 -1
  91. package/dist/templates/trellis/scripts/common/session_context.py +2 -2
  92. package/dist/templates/trellis/scripts/common/spec_inject.py +2 -2
  93. package/dist/templates/trellis/scripts/common/task_store.py +8 -28
  94. package/dist/templates/trellis/scripts/common/workflow_phase.py +4 -8
  95. package/dist/templates/trellis/scripts/get_context.py +2 -2
  96. package/dist/templates/trellis/scripts/init_developer.py +1 -1
  97. package/dist/templates/trellis/scripts/task.py +90 -57
  98. package/dist/templates/trellis/workflow.md +44 -66
  99. package/dist/types/ai-tools.d.ts +10 -10
  100. package/dist/types/ai-tools.d.ts.map +1 -1
  101. package/dist/types/ai-tools.js +3 -434
  102. package/dist/types/ai-tools.js.map +1 -1
  103. package/dist/utils/uninstall-scrubbers.d.ts +3 -18
  104. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  105. package/dist/utils/uninstall-scrubbers.js +24 -154
  106. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  107. package/package.json +2 -2
  108. package/dist/configurators/antigravity.d.ts +0 -7
  109. package/dist/configurators/antigravity.d.ts.map +0 -1
  110. package/dist/configurators/antigravity.js +0 -11
  111. package/dist/configurators/antigravity.js.map +0 -1
  112. package/dist/configurators/codebuddy.d.ts +0 -10
  113. package/dist/configurators/codebuddy.d.ts.map +0 -1
  114. package/dist/configurators/codebuddy.js +0 -24
  115. package/dist/configurators/codebuddy.js.map +0 -1
  116. package/dist/configurators/copilot.d.ts +0 -14
  117. package/dist/configurators/copilot.d.ts.map +0 -1
  118. package/dist/configurators/copilot.js +0 -46
  119. package/dist/configurators/copilot.js.map +0 -1
  120. package/dist/configurators/cursor.d.ts +0 -10
  121. package/dist/configurators/cursor.d.ts.map +0 -1
  122. package/dist/configurators/cursor.js +0 -23
  123. package/dist/configurators/cursor.js.map +0 -1
  124. package/dist/configurators/devin.d.ts +0 -8
  125. package/dist/configurators/devin.d.ts.map +0 -1
  126. package/dist/configurators/devin.js +0 -12
  127. package/dist/configurators/devin.js.map +0 -1
  128. package/dist/configurators/droid.d.ts +0 -10
  129. package/dist/configurators/droid.d.ts.map +0 -1
  130. package/dist/configurators/droid.js +0 -24
  131. package/dist/configurators/droid.js.map +0 -1
  132. package/dist/configurators/dsh.d.ts +0 -26
  133. package/dist/configurators/dsh.d.ts.map +0 -1
  134. package/dist/configurators/dsh.js +0 -76
  135. package/dist/configurators/dsh.js.map +0 -1
  136. package/dist/configurators/gemini.d.ts +0 -18
  137. package/dist/configurators/gemini.d.ts.map +0 -1
  138. package/dist/configurators/gemini.js +0 -39
  139. package/dist/configurators/gemini.js.map +0 -1
  140. package/dist/configurators/grok.d.ts +0 -17
  141. package/dist/configurators/grok.d.ts.map +0 -1
  142. package/dist/configurators/grok.js +0 -38
  143. package/dist/configurators/grok.js.map +0 -1
  144. package/dist/configurators/kilo.d.ts +0 -7
  145. package/dist/configurators/kilo.d.ts.map +0 -1
  146. package/dist/configurators/kilo.js +0 -11
  147. package/dist/configurators/kilo.js.map +0 -1
  148. package/dist/configurators/kimi.d.ts +0 -26
  149. package/dist/configurators/kimi.d.ts.map +0 -1
  150. package/dist/configurators/kimi.js +0 -74
  151. package/dist/configurators/kimi.js.map +0 -1
  152. package/dist/configurators/kiro.d.ts +0 -11
  153. package/dist/configurators/kiro.d.ts.map +0 -1
  154. package/dist/configurators/kiro.js +0 -30
  155. package/dist/configurators/kiro.js.map +0 -1
  156. package/dist/configurators/omp.d.ts +0 -6
  157. package/dist/configurators/omp.d.ts.map +0 -1
  158. package/dist/configurators/omp.js +0 -28
  159. package/dist/configurators/omp.js.map +0 -1
  160. package/dist/configurators/opencode.d.ts +0 -5
  161. package/dist/configurators/opencode.d.ts.map +0 -1
  162. package/dist/configurators/opencode.js +0 -84
  163. package/dist/configurators/opencode.js.map +0 -1
  164. package/dist/configurators/pi.d.ts +0 -5
  165. package/dist/configurators/pi.d.ts.map +0 -1
  166. package/dist/configurators/pi.js +0 -39
  167. package/dist/configurators/pi.js.map +0 -1
  168. package/dist/configurators/qoder.d.ts +0 -12
  169. package/dist/configurators/qoder.d.ts.map +0 -1
  170. package/dist/configurators/qoder.js +0 -30
  171. package/dist/configurators/qoder.js.map +0 -1
  172. package/dist/configurators/reasonix.d.ts +0 -17
  173. package/dist/configurators/reasonix.d.ts.map +0 -1
  174. package/dist/configurators/reasonix.js +0 -37
  175. package/dist/configurators/reasonix.js.map +0 -1
  176. package/dist/configurators/snow.d.ts +0 -25
  177. package/dist/configurators/snow.d.ts.map +0 -1
  178. package/dist/configurators/snow.js +0 -69
  179. package/dist/configurators/snow.js.map +0 -1
  180. package/dist/configurators/trae.d.ts +0 -16
  181. package/dist/configurators/trae.d.ts.map +0 -1
  182. package/dist/configurators/trae.js +0 -34
  183. package/dist/configurators/trae.js.map +0 -1
  184. package/dist/configurators/zcode.d.ts +0 -23
  185. package/dist/configurators/zcode.d.ts.map +0 -1
  186. package/dist/configurators/zcode.js +0 -63
  187. package/dist/configurators/zcode.js.map +0 -1
  188. package/dist/templates/codebuddy/agents/trellis-check.md +0 -115
  189. package/dist/templates/codebuddy/agents/trellis-implement.md +0 -115
  190. package/dist/templates/codebuddy/agents/trellis-research.md +0 -137
  191. package/dist/templates/codebuddy/index.d.ts +0 -15
  192. package/dist/templates/codebuddy/index.d.ts.map +0 -1
  193. package/dist/templates/codebuddy/index.js +0 -15
  194. package/dist/templates/codebuddy/index.js.map +0 -1
  195. package/dist/templates/codebuddy/settings.json +0 -69
  196. package/dist/templates/copilot/copilot-instructions.md +0 -11
  197. package/dist/templates/copilot/hooks/session-start.py +0 -564
  198. package/dist/templates/copilot/hooks.json +0 -19
  199. package/dist/templates/copilot/index.d.ts +0 -28
  200. package/dist/templates/copilot/index.d.ts.map +0 -1
  201. package/dist/templates/copilot/index.js +0 -61
  202. package/dist/templates/copilot/index.js.map +0 -1
  203. package/dist/templates/copilot/prompts/before-dev.prompt.md +0 -39
  204. package/dist/templates/copilot/prompts/brainstorm.prompt.md +0 -173
  205. package/dist/templates/copilot/prompts/break-loop.prompt.md +0 -129
  206. package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +0 -170
  207. package/dist/templates/copilot/prompts/check.prompt.md +0 -110
  208. package/dist/templates/copilot/prompts/create-command.prompt.md +0 -116
  209. package/dist/templates/copilot/prompts/finish-work.prompt.md +0 -99
  210. package/dist/templates/copilot/prompts/integrate-skill.prompt.md +0 -223
  211. package/dist/templates/copilot/prompts/onboard.prompt.md +0 -362
  212. package/dist/templates/copilot/prompts/parallel.prompt.md +0 -204
  213. package/dist/templates/copilot/prompts/record-session.prompt.md +0 -66
  214. package/dist/templates/copilot/prompts/start.prompt.md +0 -63
  215. package/dist/templates/copilot/prompts/update-spec.prompt.md +0 -358
  216. package/dist/templates/cursor/agents/trellis-check.md +0 -114
  217. package/dist/templates/cursor/agents/trellis-implement.md +0 -114
  218. package/dist/templates/cursor/agents/trellis-research.md +0 -136
  219. package/dist/templates/cursor/hooks.json +0 -24
  220. package/dist/templates/cursor/index.d.ts +0 -13
  221. package/dist/templates/cursor/index.d.ts.map +0 -1
  222. package/dist/templates/cursor/index.js +0 -13
  223. package/dist/templates/cursor/index.js.map +0 -1
  224. package/dist/templates/droid/droids/trellis-check.md +0 -107
  225. package/dist/templates/droid/droids/trellis-implement.md +0 -107
  226. package/dist/templates/droid/droids/trellis-research.md +0 -137
  227. package/dist/templates/droid/index.d.ts +0 -15
  228. package/dist/templates/droid/index.d.ts.map +0 -1
  229. package/dist/templates/droid/index.js +0 -15
  230. package/dist/templates/droid/index.js.map +0 -1
  231. package/dist/templates/droid/settings.json +0 -69
  232. package/dist/templates/dsh/DSH.md +0 -80
  233. package/dist/templates/dsh/agents/trellis-check.md +0 -99
  234. package/dist/templates/dsh/agents/trellis-implement.md +0 -106
  235. package/dist/templates/dsh/agents/trellis-research.md +0 -134
  236. package/dist/templates/dsh/index.d.ts +0 -22
  237. package/dist/templates/dsh/index.d.ts.map +0 -1
  238. package/dist/templates/dsh/index.js +0 -27
  239. package/dist/templates/dsh/index.js.map +0 -1
  240. package/dist/templates/gemini/agents/trellis-check.md +0 -107
  241. package/dist/templates/gemini/agents/trellis-implement.md +0 -107
  242. package/dist/templates/gemini/agents/trellis-research.md +0 -136
  243. package/dist/templates/gemini/index.d.ts +0 -13
  244. package/dist/templates/gemini/index.d.ts.map +0 -1
  245. package/dist/templates/gemini/index.js +0 -13
  246. package/dist/templates/gemini/index.js.map +0 -1
  247. package/dist/templates/gemini/settings.json +0 -40
  248. package/dist/templates/grok/agents/trellis-check.md +0 -106
  249. package/dist/templates/grok/agents/trellis-implement.md +0 -121
  250. package/dist/templates/grok/agents/trellis-research.md +0 -146
  251. package/dist/templates/grok/index.d.ts +0 -16
  252. package/dist/templates/grok/index.d.ts.map +0 -1
  253. package/dist/templates/grok/index.js +0 -19
  254. package/dist/templates/grok/index.js.map +0 -1
  255. package/dist/templates/kimi/agents/trellis-check.md +0 -104
  256. package/dist/templates/kimi/agents/trellis-implement.md +0 -120
  257. package/dist/templates/kimi/agents/trellis-research.md +0 -144
  258. package/dist/templates/kimi/index.d.ts +0 -20
  259. package/dist/templates/kimi/index.d.ts.map +0 -1
  260. package/dist/templates/kimi/index.js +0 -23
  261. package/dist/templates/kimi/index.js.map +0 -1
  262. package/dist/templates/kiro/agents/trellis-check.json +0 -26
  263. package/dist/templates/kiro/agents/trellis-implement.json +0 -26
  264. package/dist/templates/kiro/agents/trellis-research.json +0 -30
  265. package/dist/templates/kiro/agents/trellis.json +0 -34
  266. package/dist/templates/kiro/hooks/trellis-workflow-state.kiro.hook +0 -14
  267. package/dist/templates/kiro/index.d.ts +0 -32
  268. package/dist/templates/kiro/index.d.ts.map +0 -1
  269. package/dist/templates/kiro/index.js +0 -28
  270. package/dist/templates/kiro/index.js.map +0 -1
  271. package/dist/templates/omp/agents/trellis-check.md +0 -41
  272. package/dist/templates/omp/agents/trellis-implement.md +0 -55
  273. package/dist/templates/omp/agents/trellis-research.md +0 -30
  274. package/dist/templates/omp/extensions/trellis/index.ts.txt +0 -592
  275. package/dist/templates/omp/index.d.ts +0 -4
  276. package/dist/templates/omp/index.d.ts.map +0 -1
  277. package/dist/templates/omp/index.js +0 -9
  278. package/dist/templates/omp/index.js.map +0 -1
  279. package/dist/templates/opencode/agents/trellis-check.md +0 -122
  280. package/dist/templates/opencode/agents/trellis-implement.md +0 -123
  281. package/dist/templates/opencode/agents/trellis-research.md +0 -145
  282. package/dist/templates/opencode/lib/context-visibility.js +0 -86
  283. package/dist/templates/opencode/lib/session-utils.js +0 -526
  284. package/dist/templates/opencode/lib/trellis-context.js +0 -627
  285. package/dist/templates/opencode/package.json +0 -5
  286. package/dist/templates/opencode/plugins/inject-spec-context.js +0 -121
  287. package/dist/templates/opencode/plugins/inject-subagent-context.js +0 -569
  288. package/dist/templates/opencode/plugins/inject-workflow-state.js +0 -340
  289. package/dist/templates/opencode/plugins/session-start.js +0 -74
  290. package/dist/templates/pi/agents/trellis-check.md +0 -37
  291. package/dist/templates/pi/agents/trellis-implement.md +0 -52
  292. package/dist/templates/pi/agents/trellis-research.md +0 -25
  293. package/dist/templates/pi/extensions/trellis/index.ts.txt +0 -2033
  294. package/dist/templates/pi/index.d.ts +0 -5
  295. package/dist/templates/pi/index.d.ts.map +0 -1
  296. package/dist/templates/pi/index.js +0 -12
  297. package/dist/templates/pi/index.js.map +0 -1
  298. package/dist/templates/pi/settings.json +0 -9
  299. package/dist/templates/qoder/agents/trellis-check.md +0 -108
  300. package/dist/templates/qoder/agents/trellis-implement.md +0 -108
  301. package/dist/templates/qoder/agents/trellis-research.md +0 -137
  302. package/dist/templates/qoder/index.d.ts +0 -15
  303. package/dist/templates/qoder/index.d.ts.map +0 -1
  304. package/dist/templates/qoder/index.js +0 -15
  305. package/dist/templates/qoder/index.js.map +0 -1
  306. package/dist/templates/qoder/settings.json +0 -59
  307. package/dist/templates/reasonix/agents/trellis-check.md +0 -36
  308. package/dist/templates/reasonix/agents/trellis-implement.md +0 -51
  309. package/dist/templates/reasonix/index.d.ts +0 -13
  310. package/dist/templates/reasonix/index.d.ts.map +0 -1
  311. package/dist/templates/reasonix/index.js +0 -16
  312. package/dist/templates/reasonix/index.js.map +0 -1
  313. package/dist/templates/shared-hooks/inject-shell-session-context.py +0 -292
  314. package/dist/templates/snow/SNOW.md +0 -86
  315. package/dist/templates/snow/agents/trellis-check.md +0 -136
  316. package/dist/templates/snow/agents/trellis-implement.md +0 -158
  317. package/dist/templates/snow/agents/trellis-research.md +0 -114
  318. package/dist/templates/snow/hooks/beforeSubAgentStart.json +0 -15
  319. package/dist/templates/snow/hooks/onSessionStart.json +0 -15
  320. package/dist/templates/snow/hooks/onUserMessage.json +0 -15
  321. package/dist/templates/snow/hooks/write-trellis-context.py +0 -644
  322. package/dist/templates/snow/index.d.ts +0 -26
  323. package/dist/templates/snow/index.d.ts.map +0 -1
  324. package/dist/templates/snow/index.js +0 -36
  325. package/dist/templates/snow/index.js.map +0 -1
  326. package/dist/templates/trae/agents/trellis-check.md +0 -108
  327. package/dist/templates/trae/agents/trellis-implement.md +0 -108
  328. package/dist/templates/trae/agents/trellis-research.md +0 -137
  329. package/dist/templates/trae/hooks.json +0 -39
  330. package/dist/templates/trae/index.d.ts +0 -15
  331. package/dist/templates/trae/index.d.ts.map +0 -1
  332. package/dist/templates/trae/index.js +0 -15
  333. package/dist/templates/trae/index.js.map +0 -1
  334. package/dist/templates/trellis/gitattributes.txt +0 -9
  335. package/dist/templates/trellis/scripts/common/cli_adapter.py +0 -982
  336. package/dist/templates/zcode/agents/trellis-check.md +0 -110
  337. package/dist/templates/zcode/agents/trellis-implement.md +0 -116
  338. package/dist/templates/zcode/agents/trellis-research.md +0 -133
  339. package/dist/templates/zcode/config.json +0 -52
  340. package/dist/templates/zcode/index.d.ts +0 -25
  341. package/dist/templates/zcode/index.d.ts.map +0 -1
  342. package/dist/templates/zcode/index.js +0 -29
  343. package/dist/templates/zcode/index.js.map +0 -1
@@ -1,526 +0,0 @@
1
- /* global process */
2
- import { existsSync, readFileSync, readdirSync, statSync } from "fs"
3
- import { join } from "path"
4
- import { execFileSync } from "child_process"
5
- import { platform } from "os"
6
- import { debugLog } from "./trellis-context.js"
7
-
8
- const PYTHON_CMD = platform() === "win32" ? "python" : "python3"
9
-
10
- const FIRST_REPLY_NOTICE = `<first-reply-notice>
11
- On the first visible assistant reply in this session, briefly acknowledge that Trellis SessionStart context loaded.
12
- Choose the acknowledgment language in this order:
13
- 1. Use the language of the user's current request (the user message that triggered this reply).
14
- 2. If that request has no clear natural language, use an explicitly established project communication language.
15
- 3. If neither provides a language, output the language-neutral fallback exactly: \`Trellis SessionStart ✓\`.
16
- Continue directly with the user's request after the acknowledgment.
17
- The acknowledgment must not alter the language used for the remainder of the response.
18
- This notice is one-shot: do not repeat it after the first visible assistant reply in this session.
19
- </first-reply-notice>`
20
-
21
- function hasCuratedJsonlEntry(jsonlPath) {
22
- try {
23
- const content = readFileSync(jsonlPath, "utf-8")
24
- for (const rawLine of content.split(/\r?\n/)) {
25
- const line = rawLine.trim()
26
- if (!line) continue
27
- try {
28
- const row = JSON.parse(line)
29
- if (row && typeof row === "object" && typeof row.file === "string" && row.file) {
30
- return true
31
- }
32
- } catch {
33
- // Ignore malformed line
34
- }
35
- }
36
- } catch {
37
- return false
38
- }
39
- return false
40
- }
41
-
42
- function getTaskStatus(ctx, platformInput = null) {
43
- const active = ctx.getActiveTask(platformInput)
44
- const taskRef = active.taskPath
45
- if (!taskRef) {
46
- return (
47
- "Status: NO ACTIVE TASK\n" +
48
- "Next-Action: Work inline. Do not ask whether to create a Trellis task; " +
49
- "create one only when the user explicitly asks for it."
50
- )
51
- }
52
-
53
- const taskDir = ctx.resolveTaskDir(taskRef)
54
-
55
- if (active.stale || !taskDir || !existsSync(taskDir)) {
56
- return `Status: STALE POINTER\nTask: ${taskRef}\nNext-Action: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish`
57
- }
58
-
59
- let taskData = {}
60
- const taskJsonPath = join(taskDir, "task.json")
61
- if (existsSync(taskJsonPath)) {
62
- try {
63
- taskData = JSON.parse(readFileSync(taskJsonPath, "utf-8"))
64
- } catch {
65
- // Ignore parse errors
66
- }
67
- }
68
-
69
- const taskTitle = taskData.title || taskRef
70
- const taskStatus = taskData.status || "unknown"
71
-
72
- if (taskStatus === "completed") {
73
- return `Status: COMPLETED\nTask: ${taskTitle}\nNext-Action: Run /trellis:finish-work. If the working tree is dirty, return to Phase 3.4 first.`
74
- }
75
-
76
- const hasPrd = existsSync(join(taskDir, "prd.md"))
77
- const hasDesign = existsSync(join(taskDir, "design.md"))
78
- const hasImplementPlan = existsSync(join(taskDir, "implement.md"))
79
- const artifactNames = ["prd.md", "design.md", "implement.md", "implement.jsonl", "check.jsonl"]
80
- const present = artifactNames.filter(name => existsSync(join(taskDir, name)))
81
- if (existsSync(join(taskDir, "research"))) present.push("research/")
82
- const presentLine = present.length > 0 ? present.join(", ") : "(none)"
83
- const implementJsonl = join(taskDir, "implement.jsonl")
84
- const checkJsonl = join(taskDir, "check.jsonl")
85
- const jsonlReady =
86
- (!existsSync(implementJsonl) || hasCuratedJsonlEntry(implementJsonl)) &&
87
- (!existsSync(checkJsonl) || hasCuratedJsonlEntry(checkJsonl))
88
-
89
- if (taskStatus === "planning" && !hasPrd) {
90
- return `Status: PLANNING\nTask: ${taskTitle}\nPresent: ${presentLine}\nNext-Action: Load trellis-brainstorm and write prd.md. Stay in planning.`
91
- }
92
-
93
- if (taskStatus === "planning") {
94
- const missingComplex = []
95
- if (!hasDesign) missingComplex.push("design.md")
96
- if (!hasImplementPlan) missingComplex.push("implement.md")
97
- const nextBits = []
98
- if (missingComplex.length > 0) {
99
- nextBits.push(
100
- `Planning is incomplete: add ${missingComplex.join(", ")} before start`,
101
- )
102
- } else {
103
- nextBits.push("Planning artifacts are present; ask for review before `task.py start`")
104
- }
105
- if (!jsonlReady) {
106
- nextBits.push("curate `implement.jsonl` and `check.jsonl` before sub-agent mode start")
107
- }
108
- return `Status: PLANNING\nTask: ${taskTitle}\nPresent: ${presentLine}\nNext-Action: ${nextBits.join("; ")}. Do not enter implementation until the user confirms start.`
109
- }
110
-
111
- return (
112
- `Status: ${String(taskStatus).toUpperCase()}\nTask: ${taskTitle}\n` +
113
- `Present: ${presentLine}\n` +
114
- "Next-Action: Follow the matching per-turn workflow-state. " +
115
- "Implementation/check context order is jsonl entries -> `prd.md` -> `design.md if present` -> `implement.md if present`."
116
- )
117
- }
118
-
119
- function loadTrellisConfig(directory, contextKey = null) {
120
- const scriptPath = join(directory, ".trellis", "scripts", "get_context.py")
121
- if (!existsSync(scriptPath)) {
122
- return { isMonorepo: false, packages: {}, specScope: null, activeTaskPackage: null, defaultPackage: null }
123
- }
124
- try {
125
- const output = execFileSync(PYTHON_CMD, [scriptPath, "--mode", "packages", "--json"], {
126
- cwd: directory,
127
- timeout: 5000,
128
- encoding: "utf-8",
129
- stdio: ["pipe", "pipe", "pipe"],
130
- env: {
131
- ...process.env,
132
- ...(contextKey ? { TRELLIS_CONTEXT_ID: contextKey } : {}),
133
- },
134
- })
135
- const data = JSON.parse(output)
136
- if (data.mode !== "monorepo") {
137
- return { isMonorepo: false, packages: {}, specScope: null, activeTaskPackage: null, defaultPackage: null }
138
- }
139
- const pkgDict = {}
140
- for (const pkg of (data.packages || [])) {
141
- pkgDict[pkg.name] = pkg
142
- }
143
- return {
144
- isMonorepo: true,
145
- packages: pkgDict,
146
- specScope: data.specScope || null,
147
- activeTaskPackage: data.activeTaskPackage || null,
148
- defaultPackage: data.defaultPackage || null,
149
- }
150
- } catch (e) {
151
- debugLog("session", "loadTrellisConfig error:", e.message)
152
- return { isMonorepo: false, packages: {}, specScope: null, activeTaskPackage: null, defaultPackage: null }
153
- }
154
- }
155
-
156
- function checkLegacySpec(directory, config) {
157
- if (!config.isMonorepo || Object.keys(config.packages).length === 0) {
158
- return null
159
- }
160
-
161
- const specDir = join(directory, ".trellis", "spec")
162
- if (!existsSync(specDir)) return null
163
-
164
- let hasLegacy = false
165
- for (const name of ["backend", "frontend"]) {
166
- if (existsSync(join(specDir, name, "index.md"))) {
167
- hasLegacy = true
168
- break
169
- }
170
- }
171
- if (!hasLegacy) return null
172
-
173
- const pkgNames = Object.keys(config.packages).sort()
174
- const missing = pkgNames.filter(name => !existsSync(join(specDir, name)))
175
-
176
- if (missing.length === 0) return null
177
-
178
- if (missing.length === pkgNames.length) {
179
- return (
180
- `[!] Legacy spec structure detected: found \`spec/backend/\` or \`spec/frontend/\` ` +
181
- `but no package-scoped \`spec/<package>/\` directories.\n` +
182
- `Monorepo packages: ${pkgNames.join(", ")}\n` +
183
- `Please reorganize: \`spec/backend/\` -> \`spec/<package>/backend/\``
184
- )
185
- }
186
- return (
187
- `[!] Partial spec migration detected: packages ${missing.join(", ")} ` +
188
- `still missing \`spec/<pkg>/\` directory.\n` +
189
- `Please complete migration for all packages.`
190
- )
191
- }
192
-
193
- function resolveSpecScope(config) {
194
- if (!config.isMonorepo || Object.keys(config.packages).length === 0) {
195
- return null
196
- }
197
-
198
- const { specScope, activeTaskPackage, defaultPackage, packages } = config
199
- if (specScope == null) return null
200
-
201
- if (specScope === "active_task") {
202
- if (activeTaskPackage && activeTaskPackage in packages) return new Set([activeTaskPackage])
203
- if (defaultPackage && defaultPackage in packages) return new Set([defaultPackage])
204
- return null
205
- }
206
-
207
- if (Array.isArray(specScope)) {
208
- const valid = new Set()
209
- for (const entry of specScope) {
210
- if (entry in packages) {
211
- valid.add(entry)
212
- }
213
- }
214
- if (valid.size > 0) return valid
215
- if (activeTaskPackage && activeTaskPackage in packages) return new Set([activeTaskPackage])
216
- if (defaultPackage && defaultPackage in packages) return new Set([defaultPackage])
217
- return null
218
- }
219
-
220
- return null
221
- }
222
-
223
- function collectSpecIndexPaths(directory, allowedPkgs) {
224
- const specDir = join(directory, ".trellis", "spec")
225
- const paths = []
226
-
227
- const guidesIndex = join(specDir, "guides", "index.md")
228
- if (existsSync(guidesIndex)) {
229
- paths.push(".trellis/spec/guides/index.md")
230
- }
231
-
232
- if (!existsSync(specDir)) return paths
233
-
234
- try {
235
- const subs = readdirSync(specDir).filter(name => {
236
- if (name.startsWith(".") || name === "guides") return false
237
- try {
238
- return statSync(join(specDir, name)).isDirectory()
239
- } catch {
240
- return false
241
- }
242
- }).sort()
243
-
244
- for (const sub of subs) {
245
- const indexFile = join(specDir, sub, "index.md")
246
- if (existsSync(indexFile)) {
247
- paths.push(`.trellis/spec/${sub}/index.md`)
248
- } else {
249
- if (allowedPkgs !== null && !allowedPkgs.has(sub)) continue
250
- try {
251
- const nested = readdirSync(join(specDir, sub)).filter(name => {
252
- try {
253
- return statSync(join(specDir, sub, name)).isDirectory()
254
- } catch {
255
- return false
256
- }
257
- }).sort()
258
- for (const layer of nested) {
259
- const nestedIndex = join(specDir, sub, layer, "index.md")
260
- if (existsSync(nestedIndex)) {
261
- paths.push(`.trellis/spec/${sub}/${layer}/index.md`)
262
- }
263
- }
264
- } catch {
265
- // Ignore directory read errors
266
- }
267
- }
268
- }
269
- } catch {
270
- // Ignore spec directory read errors
271
- }
272
-
273
- return paths
274
- }
275
-
276
- function readDeveloper(directory) {
277
- try {
278
- const content = readFileSync(join(directory, ".trellis", ".developer"), "utf-8")
279
- for (const line of content.split(/\r?\n/)) {
280
- if (line.startsWith("name=")) return line.slice("name=".length).trim()
281
- }
282
- } catch {
283
- // Ignore missing developer file
284
- }
285
- return "(not initialized)"
286
- }
287
-
288
- function runGit(directory, args) {
289
- try {
290
- return execFileSync("git", args, {
291
- cwd: directory,
292
- timeout: 3000,
293
- encoding: "utf-8",
294
- stdio: ["pipe", "pipe", "pipe"],
295
- }).trim()
296
- } catch {
297
- return ""
298
- }
299
- }
300
-
301
- function buildCompactCurrentState(ctx, platformInput, specIndexPaths) {
302
- const directory = ctx.directory
303
- const lines = []
304
- lines.push(`Developer: ${readDeveloper(directory)}`)
305
-
306
- const branch = runGit(directory, ["branch", "--show-current"]) || "(detached)"
307
- const dirtyCount = runGit(directory, ["status", "--porcelain"])
308
- .split(/\r?\n/)
309
- .filter(line => line.trim()).length
310
- lines.push(`Git: branch ${branch}; ${dirtyCount === 0 ? "clean" : `dirty ${dirtyCount} paths`}.`)
311
-
312
- const active = ctx.getActiveTask(platformInput)
313
- if (active.taskPath) {
314
- const taskDir = ctx.resolveTaskDir(active.taskPath)
315
- let status = "unknown"
316
- if (taskDir) {
317
- try {
318
- const data = JSON.parse(readFileSync(join(taskDir, "task.json"), "utf-8"))
319
- status = data.status || "unknown"
320
- } catch {
321
- // Ignore parse errors
322
- }
323
- }
324
- lines.push(`Current task: ${active.taskPath}; status=${status}.`)
325
- } else {
326
- lines.push("Current task: none.")
327
- }
328
-
329
- const tasksDir = join(directory, ".trellis", "tasks")
330
- if (existsSync(tasksDir)) {
331
- try {
332
- const activeTasks = readdirSync(tasksDir, { withFileTypes: true })
333
- .filter(entry => entry.isDirectory() && entry.name !== "archive" && existsSync(join(tasksDir, entry.name, "task.json")))
334
- lines.push(`Active tasks: ${activeTasks.length} total. Use \`python3 ./.trellis/scripts/task.py list --mine\` only if needed.`)
335
- } catch {
336
- // Ignore task list errors
337
- }
338
- }
339
-
340
- const developer = readDeveloper(directory)
341
- const workspaceDir = join(directory, ".trellis", "workspace", developer)
342
- if (developer !== "(not initialized)" && existsSync(workspaceDir)) {
343
- try {
344
- const journals = readdirSync(workspaceDir)
345
- .filter(name => /^journal-\d+\.md$/.test(name))
346
- .sort((a, b) => Number(a.match(/\d+/)?.[0] || 0) - Number(b.match(/\d+/)?.[0] || 0))
347
- const journal = journals[journals.length - 1]
348
- if (journal) {
349
- const journalPath = join(workspaceDir, journal)
350
- const lineCount = readFileSync(journalPath, "utf-8").split(/\r?\n/).length
351
- lines.push(`Journal: .trellis/workspace/${developer}/${journal}, ${lineCount} / 2000 lines.`)
352
- }
353
- } catch {
354
- // Ignore journal errors
355
- }
356
- }
357
-
358
- if (specIndexPaths.length > 0) {
359
- lines.push(`Spec indexes: ${specIndexPaths.length} available.`)
360
- }
361
-
362
- return lines.join("\n")
363
- }
364
-
365
- export function buildSessionContext(ctx, platformInput = null) {
366
- const directory = ctx.directory
367
- const contextKey = typeof ctx.getContextKey === "function"
368
- ? ctx.getContextKey(platformInput)
369
- : null
370
-
371
- const config = loadTrellisConfig(directory, contextKey)
372
- const allowedPkgs = resolveSpecScope(config)
373
- const paths = collectSpecIndexPaths(directory, allowedPkgs)
374
-
375
- const parts = []
376
-
377
- parts.push(`<session-context>
378
- Trellis compact SessionStart context. Use it to orient the session; load details on demand.
379
- </session-context>`)
380
- parts.push(FIRST_REPLY_NOTICE)
381
-
382
- const legacyWarning = checkLegacySpec(directory, config)
383
- if (legacyWarning) {
384
- parts.push(`<migration-warning>\n${legacyWarning}\n</migration-warning>`)
385
- }
386
-
387
- parts.push("<current-state>")
388
- parts.push(buildCompactCurrentState(ctx, platformInput, paths))
389
- parts.push("</current-state>")
390
-
391
- const workflowContent = ctx.readProjectFile(".trellis/workflow.md")
392
- if (workflowContent) {
393
- const allLines = workflowContent.split("\n")
394
- const overviewLines = [
395
- "# Development Workflow - Session Summary",
396
- "Full guide: .trellis/workflow.md. Step detail: `python3 ./.trellis/scripts/get_context.py --mode phase --step <X.Y>`.",
397
- "",
398
- ]
399
-
400
- let rangeStart = -1
401
- let rangeEnd = allLines.length
402
- for (let i = 0; i < allLines.length; i++) {
403
- const stripped = allLines[i].trim()
404
- if (rangeStart === -1 && stripped === "## Phase Index") {
405
- rangeStart = i
406
- } else if (rangeStart !== -1 && stripped === "## Phase 1: Plan") {
407
- rangeEnd = i
408
- break
409
- }
410
- }
411
- if (rangeStart !== -1) {
412
- const strippedStateBlocks = allLines
413
- .slice(rangeStart, rangeEnd)
414
- .join("\n")
415
- .replace(/\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n[\s\S]*?\n\s*\[\/workflow-state:\1\]\n?/g, "")
416
- .replace(/<!--[\s\S]*?-->/g, "")
417
- .replace(/^\[(?!\/?workflow-state:)\/?[^\]\n]+\]\s*\n?/gm, "")
418
- .replace(/\n{3,}/g, "\n\n")
419
- overviewLines.push(strippedStateBlocks.trimEnd())
420
- }
421
-
422
- parts.push("<trellis-workflow>")
423
- parts.push(overviewLines.join("\n").trimEnd())
424
- parts.push("</trellis-workflow>")
425
- }
426
-
427
- parts.push("<guidelines>")
428
- parts.push(
429
- "Task context order for implementation/check: jsonl entries -> `prd.md` -> " +
430
- "`design.md` -> `implement.md`. All three " +
431
- "are required; a missing one means planning is incomplete.\n"
432
- )
433
-
434
- if (paths.length > 0) {
435
- parts.push("## Available indexes (read on demand)")
436
- for (const p of paths) {
437
- parts.push(`- ${p}`)
438
- }
439
- parts.push("")
440
- }
441
-
442
- parts.push(
443
- "Discover more via: " +
444
- "`python3 ./.trellis/scripts/get_context.py --mode packages`"
445
- )
446
- parts.push("</guidelines>")
447
-
448
- const taskStatus = getTaskStatus(ctx, platformInput)
449
- parts.push(`<task-status>\n${taskStatus}\n</task-status>`)
450
-
451
- parts.push(`<ready>
452
- Context loaded. Follow <task-status>. Load workflow/spec/task details only when needed.
453
- </ready>`)
454
-
455
- return parts.join("\n\n")
456
- }
457
-
458
- function getTrellisMetadata(metadata) {
459
- if (!metadata || typeof metadata !== "object") {
460
- return {}
461
- }
462
-
463
- const trellis = metadata.trellis
464
- if (!trellis || typeof trellis !== "object") {
465
- return {}
466
- }
467
-
468
- return trellis
469
- }
470
-
471
- function markPartAsSessionStart(part) {
472
- const metadata = part.metadata && typeof part.metadata === "object"
473
- ? part.metadata
474
- : {}
475
- part.metadata = {
476
- ...metadata,
477
- trellis: {
478
- ...getTrellisMetadata(metadata),
479
- sessionStart: true,
480
- },
481
- }
482
- }
483
-
484
- function hasSessionStartMarker(part) {
485
- if (!part || part.type !== "text" || typeof part.text !== "string") {
486
- return false
487
- }
488
-
489
- return getTrellisMetadata(part.metadata).sessionStart === true
490
- }
491
-
492
- export function hasInjectedTrellisContext(messages) {
493
- if (!Array.isArray(messages)) {
494
- return false
495
- }
496
-
497
- return messages.some(message => {
498
- if (!message?.info || message.info.role !== "user" || !Array.isArray(message.parts)) {
499
- return false
500
- }
501
-
502
- return message.parts.some(hasSessionStartMarker)
503
- })
504
- }
505
-
506
- export async function hasPersistedInjectedContext(client, directory, sessionID) {
507
- try {
508
- const response = await client.session.messages({
509
- path: { id: sessionID },
510
- query: { directory },
511
- throwOnError: true,
512
- })
513
- return hasInjectedTrellisContext(response.data || [])
514
- } catch (error) {
515
- debugLog(
516
- "session",
517
- "Failed to read session history for dedupe:",
518
- error instanceof Error ? error.message : String(error),
519
- )
520
- return false
521
- }
522
- }
523
-
524
- export function markContextInjected(part) {
525
- markPartAsSessionStart(part)
526
- }