@pennixrv/trellis 0.7.0-beta.8 → 0.7.1

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 (484) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.d.ts.map +1 -1
  3. package/dist/cli/index.js +14 -26
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/commands/ablate.js +1 -1
  6. package/dist/commands/ablate.js.map +1 -1
  7. package/dist/commands/init.d.ts.map +1 -1
  8. package/dist/commands/init.js +30 -56
  9. package/dist/commands/init.js.map +1 -1
  10. package/dist/commands/task-progress.d.ts +2 -0
  11. package/dist/commands/task-progress.d.ts.map +1 -1
  12. package/dist/commands/task-progress.js +37 -30
  13. package/dist/commands/task-progress.js.map +1 -1
  14. package/dist/commands/{channel → teamwork}/adapters/claude.d.ts +3 -3
  15. package/dist/commands/teamwork/adapters/claude.d.ts.map +1 -0
  16. package/dist/commands/{channel → teamwork}/adapters/claude.js +3 -3
  17. package/dist/commands/teamwork/adapters/claude.js.map +1 -0
  18. package/dist/commands/{channel → teamwork}/adapters/codex.d.ts +1 -15
  19. package/dist/commands/teamwork/adapters/codex.d.ts.map +1 -0
  20. package/dist/commands/{channel → teamwork}/adapters/codex.js +5 -42
  21. package/dist/commands/teamwork/adapters/codex.js.map +1 -0
  22. package/dist/commands/{channel → teamwork}/adapters/index.d.ts +6 -6
  23. package/dist/commands/teamwork/adapters/index.d.ts.map +1 -0
  24. package/dist/commands/{channel → teamwork}/adapters/index.js +16 -52
  25. package/dist/commands/teamwork/adapters/index.js.map +1 -0
  26. package/dist/commands/{channel → teamwork}/adapters/types.d.ts +2 -2
  27. package/dist/commands/teamwork/adapters/types.d.ts.map +1 -0
  28. package/dist/commands/teamwork/adapters/types.js.map +1 -0
  29. package/dist/commands/{channel → teamwork}/agent-loader.d.ts +2 -4
  30. package/dist/commands/teamwork/agent-loader.d.ts.map +1 -0
  31. package/dist/commands/{channel → teamwork}/agent-loader.js +4 -35
  32. package/dist/commands/teamwork/agent-loader.js.map +1 -0
  33. package/dist/commands/teamwork/artifact.d.ts +177 -0
  34. package/dist/commands/teamwork/artifact.d.ts.map +1 -0
  35. package/dist/commands/teamwork/artifact.js +908 -0
  36. package/dist/commands/teamwork/artifact.js.map +1 -0
  37. package/dist/commands/{channel → teamwork}/context-loader.d.ts +1 -1
  38. package/dist/commands/teamwork/context-loader.d.ts.map +1 -0
  39. package/dist/commands/{channel → teamwork}/context-loader.js +12 -12
  40. package/dist/commands/teamwork/context-loader.js.map +1 -0
  41. package/dist/commands/{channel → teamwork}/context-trust.d.ts +6 -6
  42. package/dist/commands/teamwork/context-trust.d.ts.map +1 -0
  43. package/dist/commands/{channel → teamwork}/context-trust.js +16 -16
  44. package/dist/commands/teamwork/context-trust.js.map +1 -0
  45. package/dist/commands/teamwork/context.d.ts +16 -0
  46. package/dist/commands/teamwork/context.d.ts.map +1 -0
  47. package/dist/commands/{channel → teamwork}/context.js +17 -17
  48. package/dist/commands/teamwork/context.js.map +1 -0
  49. package/dist/commands/teamwork/coordinator.d.ts +89 -0
  50. package/dist/commands/teamwork/coordinator.d.ts.map +1 -0
  51. package/dist/commands/teamwork/coordinator.js +1198 -0
  52. package/dist/commands/teamwork/coordinator.js.map +1 -0
  53. package/dist/commands/teamwork/create.d.ts +23 -0
  54. package/dist/commands/teamwork/create.d.ts.map +1 -0
  55. package/dist/commands/teamwork/create.js +39 -0
  56. package/dist/commands/teamwork/create.js.map +1 -0
  57. package/dist/commands/{channel → teamwork}/dev-parse-trace.d.ts +1 -1
  58. package/dist/commands/teamwork/dev-parse-trace.d.ts.map +1 -0
  59. package/dist/commands/{channel → teamwork}/dev-parse-trace.js +1 -1
  60. package/dist/commands/teamwork/dev-parse-trace.js.map +1 -0
  61. package/dist/commands/{channel → teamwork}/guard.d.ts +27 -46
  62. package/dist/commands/teamwork/guard.d.ts.map +1 -0
  63. package/dist/commands/{channel → teamwork}/guard.js +54 -156
  64. package/dist/commands/teamwork/guard.js.map +1 -0
  65. package/dist/commands/teamwork/index.d.ts +3 -0
  66. package/dist/commands/teamwork/index.d.ts.map +1 -0
  67. package/dist/commands/{channel → teamwork}/index.js +135 -165
  68. package/dist/commands/teamwork/index.js.map +1 -0
  69. package/dist/commands/{channel → teamwork}/interrupt.d.ts +1 -1
  70. package/dist/commands/teamwork/interrupt.d.ts.map +1 -0
  71. package/dist/commands/teamwork/interrupt.js +22 -0
  72. package/dist/commands/teamwork/interrupt.js.map +1 -0
  73. package/dist/commands/teamwork/kill.d.ts +7 -0
  74. package/dist/commands/teamwork/kill.d.ts.map +1 -0
  75. package/dist/commands/{channel → teamwork}/kill.js +21 -21
  76. package/dist/commands/teamwork/kill.js.map +1 -0
  77. package/dist/commands/teamwork/list.d.ts +17 -0
  78. package/dist/commands/teamwork/list.d.ts.map +1 -0
  79. package/dist/commands/{channel → teamwork}/list.js +18 -27
  80. package/dist/commands/teamwork/list.js.map +1 -0
  81. package/dist/commands/{channel → teamwork}/messages.d.ts +1 -1
  82. package/dist/commands/teamwork/messages.d.ts.map +1 -0
  83. package/dist/commands/{channel → teamwork}/messages.js +18 -18
  84. package/dist/commands/teamwork/messages.js.map +1 -0
  85. package/dist/commands/teamwork/profiles.d.ts +25 -0
  86. package/dist/commands/teamwork/profiles.d.ts.map +1 -0
  87. package/dist/commands/teamwork/profiles.js +125 -0
  88. package/dist/commands/teamwork/profiles.js.map +1 -0
  89. package/dist/commands/teamwork/rm.d.ts +27 -0
  90. package/dist/commands/teamwork/rm.d.ts.map +1 -0
  91. package/dist/commands/{channel → teamwork}/rm.js +21 -22
  92. package/dist/commands/teamwork/rm.js.map +1 -0
  93. package/dist/commands/teamwork/run.d.ts +29 -0
  94. package/dist/commands/{channel → teamwork}/run.d.ts.map +1 -1
  95. package/dist/commands/teamwork/run.js +129 -0
  96. package/dist/commands/teamwork/run.js.map +1 -0
  97. package/dist/commands/{channel → teamwork}/send.d.ts +1 -1
  98. package/dist/commands/teamwork/send.d.ts.map +1 -0
  99. package/dist/commands/{channel → teamwork}/send.js +7 -7
  100. package/dist/commands/teamwork/send.js.map +1 -0
  101. package/dist/commands/{channel → teamwork}/spawn.d.ts +8 -12
  102. package/dist/commands/teamwork/spawn.d.ts.map +1 -0
  103. package/dist/commands/{channel → teamwork}/spawn.js +51 -112
  104. package/dist/commands/teamwork/spawn.js.map +1 -0
  105. package/dist/commands/teamwork/store/events.d.ts +22 -0
  106. package/dist/commands/teamwork/store/events.d.ts.map +1 -0
  107. package/dist/commands/{channel → teamwork}/store/events.js +8 -8
  108. package/dist/commands/teamwork/store/events.js.map +1 -0
  109. package/dist/commands/teamwork/store/filter.d.ts +3 -0
  110. package/dist/commands/teamwork/store/filter.d.ts.map +1 -0
  111. package/dist/commands/teamwork/store/filter.js +2 -0
  112. package/dist/commands/teamwork/store/filter.js.map +1 -0
  113. package/dist/commands/{channel → teamwork}/store/lock.d.ts +1 -1
  114. package/dist/commands/teamwork/store/lock.d.ts.map +1 -0
  115. package/dist/commands/{channel → teamwork}/store/lock.js +2 -2
  116. package/dist/commands/teamwork/store/lock.js.map +1 -0
  117. package/dist/commands/{channel → teamwork}/store/paths.d.ts +18 -32
  118. package/dist/commands/teamwork/store/paths.d.ts.map +1 -0
  119. package/dist/commands/{channel → teamwork}/store/paths.js +42 -109
  120. package/dist/commands/teamwork/store/paths.js.map +1 -0
  121. package/dist/commands/teamwork/store/schema.d.ts +18 -0
  122. package/dist/commands/teamwork/store/schema.d.ts.map +1 -0
  123. package/dist/commands/teamwork/store/schema.js +23 -0
  124. package/dist/commands/teamwork/store/schema.js.map +1 -0
  125. package/dist/commands/{channel → teamwork}/store/thread-state.d.ts +3 -3
  126. package/dist/commands/teamwork/store/thread-state.d.ts.map +1 -0
  127. package/dist/commands/{channel → teamwork}/store/thread-state.js +1 -1
  128. package/dist/commands/teamwork/store/thread-state.js.map +1 -0
  129. package/dist/commands/teamwork/store/watch.d.ts +19 -0
  130. package/dist/commands/teamwork/store/watch.d.ts.map +1 -0
  131. package/dist/commands/{channel → teamwork}/store/watch.js +8 -8
  132. package/dist/commands/teamwork/store/watch.js.map +1 -0
  133. package/dist/commands/teamwork/supervisor/idle.d.ts.map +1 -0
  134. package/dist/commands/teamwork/supervisor/idle.js.map +1 -0
  135. package/dist/commands/{channel → teamwork}/supervisor/inbox.d.ts +2 -2
  136. package/dist/commands/teamwork/supervisor/inbox.d.ts.map +1 -0
  137. package/dist/commands/{channel → teamwork}/supervisor/inbox.js +14 -14
  138. package/dist/commands/teamwork/supervisor/inbox.js.map +1 -0
  139. package/dist/commands/{channel → teamwork}/supervisor/shutdown.d.ts +3 -6
  140. package/dist/commands/teamwork/supervisor/shutdown.d.ts.map +1 -0
  141. package/dist/commands/{channel → teamwork}/supervisor/shutdown.js +7 -17
  142. package/dist/commands/teamwork/supervisor/shutdown.js.map +1 -0
  143. package/dist/commands/{channel → teamwork}/supervisor/stdout.d.ts +3 -5
  144. package/dist/commands/teamwork/supervisor/stdout.d.ts.map +1 -0
  145. package/dist/commands/{channel → teamwork}/supervisor/stdout.js +12 -23
  146. package/dist/commands/teamwork/supervisor/stdout.js.map +1 -0
  147. package/dist/commands/teamwork/supervisor/turns.d.ts.map +1 -0
  148. package/dist/commands/teamwork/supervisor/turns.js.map +1 -0
  149. package/dist/commands/{channel → teamwork}/supervisor/warning.d.ts +5 -5
  150. package/dist/commands/teamwork/supervisor/warning.d.ts.map +1 -0
  151. package/dist/commands/{channel → teamwork}/supervisor/warning.js +6 -6
  152. package/dist/commands/teamwork/supervisor/warning.js.map +1 -0
  153. package/dist/commands/{channel → teamwork}/supervisor.d.ts +21 -21
  154. package/dist/commands/teamwork/supervisor.d.ts.map +1 -0
  155. package/dist/commands/{channel → teamwork}/supervisor.js +53 -63
  156. package/dist/commands/teamwork/supervisor.js.map +1 -0
  157. package/dist/commands/teamwork/teammate-adapters.d.ts +31 -0
  158. package/dist/commands/teamwork/teammate-adapters.d.ts.map +1 -0
  159. package/dist/commands/teamwork/teammate-adapters.js +96 -0
  160. package/dist/commands/teamwork/teammate-adapters.js.map +1 -0
  161. package/dist/commands/teamwork/teammate-config.d.ts +19 -0
  162. package/dist/commands/teamwork/teammate-config.d.ts.map +1 -0
  163. package/dist/commands/teamwork/teammate-config.js +97 -0
  164. package/dist/commands/teamwork/teammate-config.js.map +1 -0
  165. package/dist/commands/teamwork/teammate-launch.d.ts +58 -0
  166. package/dist/commands/teamwork/teammate-launch.d.ts.map +1 -0
  167. package/dist/commands/teamwork/teammate-launch.js +125 -0
  168. package/dist/commands/teamwork/teammate-launch.js.map +1 -0
  169. package/dist/commands/teamwork/text-body.d.ts +13 -0
  170. package/dist/commands/teamwork/text-body.d.ts.map +1 -0
  171. package/dist/commands/{channel → teamwork}/text-body.js +3 -3
  172. package/dist/commands/teamwork/text-body.js.map +1 -0
  173. package/dist/commands/teamwork/threads.d.ts +35 -0
  174. package/dist/commands/teamwork/threads.d.ts.map +1 -0
  175. package/dist/commands/{channel → teamwork}/threads.js +19 -19
  176. package/dist/commands/teamwork/threads.js.map +1 -0
  177. package/dist/commands/teamwork/title.d.ts +12 -0
  178. package/dist/commands/teamwork/title.d.ts.map +1 -0
  179. package/dist/commands/teamwork/title.js +24 -0
  180. package/dist/commands/teamwork/title.js.map +1 -0
  181. package/dist/commands/{channel → teamwork}/wait.d.ts +1 -5
  182. package/dist/commands/teamwork/wait.d.ts.map +1 -0
  183. package/dist/commands/{channel → teamwork}/wait.js +8 -21
  184. package/dist/commands/teamwork/wait.js.map +1 -0
  185. package/dist/commands/update.d.ts.map +1 -1
  186. package/dist/commands/update.js +48 -89
  187. package/dist/commands/update.js.map +1 -1
  188. package/dist/commands/workflow.d.ts +1 -1
  189. package/dist/commands/workflow.d.ts.map +1 -1
  190. package/dist/commands/workflow.js +9 -10
  191. package/dist/commands/workflow.js.map +1 -1
  192. package/dist/configurators/claude.d.ts +0 -17
  193. package/dist/configurators/claude.d.ts.map +1 -1
  194. package/dist/configurators/claude.js +2 -61
  195. package/dist/configurators/claude.js.map +1 -1
  196. package/dist/configurators/shared.d.ts.map +1 -1
  197. package/dist/configurators/shared.js +2 -2
  198. package/dist/configurators/shared.js.map +1 -1
  199. package/dist/configurators/snow.js +1 -1
  200. package/dist/configurators/snow.js.map +1 -1
  201. package/dist/configurators/workflow.d.ts +1 -1
  202. package/dist/configurators/workflow.js +5 -5
  203. package/dist/configurators/workflow.js.map +1 -1
  204. package/dist/constants/paths.d.ts +1 -1
  205. package/dist/constants/paths.d.ts.map +1 -1
  206. package/dist/constants/paths.js +1 -1
  207. package/dist/constants/paths.js.map +1 -1
  208. package/dist/migrations/manifests/0.7.0-beta.10.json +9 -0
  209. package/dist/migrations/manifests/0.7.0-beta.11.json +9 -0
  210. package/dist/migrations/manifests/0.7.0-beta.12.json +9 -0
  211. package/dist/migrations/manifests/0.7.0-beta.13.json +9 -0
  212. package/dist/migrations/manifests/0.7.0-beta.14.json +9 -0
  213. package/dist/migrations/manifests/0.7.0-beta.15.json +9 -0
  214. package/dist/migrations/manifests/0.7.0-beta.16.json +9 -0
  215. package/dist/migrations/manifests/0.7.0-beta.17.json +9 -0
  216. package/dist/migrations/manifests/0.7.0-beta.18.json +9 -0
  217. package/dist/migrations/manifests/0.7.0-beta.19.json +9 -0
  218. package/dist/migrations/manifests/0.7.0-beta.20.json +9 -0
  219. package/dist/migrations/manifests/0.7.0-beta.21.json +17 -0
  220. package/dist/migrations/manifests/0.7.0-beta.22.json +9 -0
  221. package/dist/migrations/manifests/0.7.0-beta.23.json +9 -0
  222. package/dist/migrations/manifests/0.7.0-beta.24.json +9 -0
  223. package/dist/migrations/manifests/0.7.0-beta.25.json +9 -0
  224. package/dist/migrations/manifests/0.7.0-beta.26.json +9 -0
  225. package/dist/migrations/manifests/0.7.0-beta.27.json +9 -0
  226. package/dist/migrations/manifests/0.7.0-beta.28.json +9 -0
  227. package/dist/migrations/manifests/0.7.0-beta.29.json +9 -0
  228. package/dist/migrations/manifests/0.7.0-beta.30.json +9 -0
  229. package/dist/migrations/manifests/0.7.0-beta.31.json +9 -0
  230. package/dist/migrations/manifests/0.7.0-beta.32.json +9 -0
  231. package/dist/migrations/manifests/0.7.0-beta.33.json +9 -0
  232. package/dist/migrations/manifests/0.7.0-beta.34.json +9 -0
  233. package/dist/migrations/manifests/0.7.0-beta.35.json +9 -0
  234. package/dist/migrations/manifests/0.7.0-beta.36.json +9 -0
  235. package/dist/migrations/manifests/0.7.0-beta.37.json +9 -0
  236. package/dist/migrations/manifests/0.7.0-beta.38.json +9 -0
  237. package/dist/migrations/manifests/0.7.0-beta.39.json +9 -0
  238. package/dist/migrations/manifests/0.7.0-beta.40.json +9 -0
  239. package/dist/migrations/manifests/0.7.0-beta.41.json +9 -0
  240. package/dist/migrations/manifests/0.7.0-beta.42.json +9 -0
  241. package/dist/migrations/manifests/0.7.0-beta.43.json +9 -0
  242. package/dist/migrations/manifests/0.7.0-beta.44.json +9 -0
  243. package/dist/migrations/manifests/0.7.0-beta.45.json +9 -0
  244. package/dist/migrations/manifests/0.7.0-beta.46.json +9 -0
  245. package/dist/migrations/manifests/0.7.0-beta.47.json +9 -0
  246. package/dist/migrations/manifests/0.7.0-beta.48.json +9 -0
  247. package/dist/migrations/manifests/0.7.0-beta.49.json +13 -0
  248. package/dist/migrations/manifests/0.7.0-beta.50.json +12 -0
  249. package/dist/migrations/manifests/0.7.0-beta.51.json +9 -0
  250. package/dist/migrations/manifests/0.7.0-beta.52.json +9 -0
  251. package/dist/migrations/manifests/0.7.0-beta.53.json +27 -0
  252. package/dist/migrations/manifests/0.7.0-beta.54.json +8 -0
  253. package/dist/migrations/manifests/0.7.0-beta.9.json +9 -0
  254. package/dist/migrations/manifests/0.7.1.json +9 -0
  255. package/dist/templates/claude/hooks/statusline.py +0 -7
  256. package/dist/templates/codex/hooks/session-start.py +31 -38
  257. package/dist/templates/common/bundled-skills/trellis-decision-space-construction-and-merging/SKILL.md +10 -0
  258. package/dist/templates/common/bundled-skills/trellis-decision-space-construction-and-merging/workflow.md +40 -0
  259. package/dist/templates/common/bundled-skills/trellis-delivery-review-and-closeout/SKILL.md +10 -0
  260. package/dist/templates/common/bundled-skills/trellis-delivery-review-and-closeout/workflow.md +55 -0
  261. package/dist/templates/common/bundled-skills/trellis-goal-exploration-and-requirements/SKILL.md +10 -0
  262. package/dist/templates/common/bundled-skills/trellis-goal-exploration-and-requirements/workflow.md +33 -0
  263. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +25 -25
  264. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +1 -1
  265. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +13 -19
  266. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
  267. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +27 -75
  268. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +17 -56
  269. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +1 -1
  270. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +14 -11
  271. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +0 -33
  272. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-teamwork.md +32 -0
  273. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
  274. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +25 -111
  275. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +19 -60
  276. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +1 -1
  277. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +1 -1
  278. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +1 -1
  279. package/dist/templates/common/bundled-skills/trellis-solution-design-and-convergence/SKILL.md +10 -0
  280. package/dist/templates/common/bundled-skills/trellis-solution-design-and-convergence/workflow.md +36 -0
  281. package/dist/templates/common/bundled-skills/trellis-task-implementation/SKILL.md +10 -0
  282. package/dist/templates/common/bundled-skills/trellis-task-implementation/workflow.md +29 -0
  283. package/dist/templates/common/bundled-skills/trellis-teamwork/SKILL.md +73 -0
  284. package/dist/templates/common/bundled-skills/trellis-teamwork/references/coordination-modes.md +29 -0
  285. package/dist/templates/common/bundled-skills/trellis-teamwork/references/teammate-configuration-matrix.md +31 -0
  286. package/dist/templates/common/bundled-skills/trellis-teamwork/references/teammate-processes.md +37 -0
  287. package/dist/templates/common/bundled-skills/trellis-teamwork/references/teamwork-plan-construction.md +78 -0
  288. package/dist/templates/common/commands/continue.md +9 -49
  289. package/dist/templates/common/commands/finish-work.md +10 -58
  290. package/dist/templates/common/commands/start.md +19 -49
  291. package/dist/templates/common/skills/brainstorm.md +11 -191
  292. package/dist/templates/copilot/hooks/session-start.py +30 -26
  293. package/dist/templates/copilot/prompts/brainstorm.prompt.md +7 -150
  294. package/dist/templates/copilot/prompts/finish-work.prompt.md +11 -88
  295. package/dist/templates/copilot/prompts/record-session.prompt.md +4 -12
  296. package/dist/templates/copilot/prompts/start.prompt.md +12 -10
  297. package/dist/templates/dsh/DSH.md +2 -2
  298. package/dist/templates/kiro/agents/trellis.json +2 -2
  299. package/dist/templates/markdown/agents.md +14 -3
  300. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +9 -8
  301. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +1 -1
  302. package/dist/templates/markdown/workspace-index.md +0 -1
  303. package/dist/templates/omp/extensions/trellis/index.ts.txt +28 -17
  304. package/dist/templates/opencode/lib/session-utils.js +20 -25
  305. package/dist/templates/opencode/lib/trellis-context.js +4 -76
  306. package/dist/templates/opencode/plugins/inject-subagent-context.js +5 -4
  307. package/dist/templates/opencode/plugins/inject-workflow-state.js +14 -17
  308. package/dist/templates/shared-hooks/inject-shell-session-context.py +3 -3
  309. package/dist/templates/shared-hooks/inject-subagent-context.py +445 -67
  310. package/dist/templates/shared-hooks/inject-workflow-state.py +44 -36
  311. package/dist/templates/shared-hooks/session-start.py +21 -33
  312. package/dist/templates/trellis/agents/delegated-worktree-primary-agent.md +18 -0
  313. package/dist/templates/trellis/agents/teammate-profiles.json +8 -0
  314. package/dist/templates/trellis/agents/teammate.md +63 -0
  315. package/dist/templates/trellis/config.yaml +29 -38
  316. package/dist/templates/trellis/gitignore.txt +1 -0
  317. package/dist/templates/trellis/index.d.ts +8 -12
  318. package/dist/templates/trellis/index.d.ts.map +1 -1
  319. package/dist/templates/trellis/index.js +14 -25
  320. package/dist/templates/trellis/index.js.map +1 -1
  321. package/dist/templates/trellis/scripts/add_session.py +1 -1
  322. package/dist/templates/trellis/scripts/common/__init__.py +0 -1
  323. package/dist/templates/trellis/scripts/common/active_task.py +136 -100
  324. package/dist/templates/trellis/scripts/common/config.py +7 -9
  325. package/dist/templates/trellis/scripts/common/git_context.py +1 -1
  326. package/dist/templates/trellis/scripts/common/io.py +19 -0
  327. package/dist/templates/trellis/scripts/common/paths.py +0 -1
  328. package/dist/templates/trellis/scripts/common/safe_commit.py +11 -90
  329. package/dist/templates/trellis/scripts/common/session_context.py +1 -8
  330. package/dist/templates/trellis/scripts/common/spec_match.py +1 -1
  331. package/dist/templates/trellis/scripts/common/task_context.py +152 -59
  332. package/dist/templates/trellis/scripts/common/task_continuity.py +563 -0
  333. package/dist/templates/trellis/scripts/common/task_store.py +70 -548
  334. package/dist/templates/trellis/scripts/common/task_utils.py +4 -98
  335. package/dist/templates/trellis/scripts/common/task_workflow.py +1096 -0
  336. package/dist/templates/trellis/scripts/common/tasks.py +5 -8
  337. package/dist/templates/trellis/scripts/common/workflow_phase.py +8 -7
  338. package/dist/templates/trellis/scripts/hooks/linear_sync.py +3 -3
  339. package/dist/templates/trellis/scripts/task.py +114 -377
  340. package/dist/templates/trellis/workflow.md +111 -699
  341. package/dist/utils/agent-refs.d.ts +5 -5
  342. package/dist/utils/agent-refs.js +6 -6
  343. package/dist/utils/file-writer.d.ts +3 -2
  344. package/dist/utils/file-writer.d.ts.map +1 -1
  345. package/dist/utils/file-writer.js +3 -2
  346. package/dist/utils/file-writer.js.map +1 -1
  347. package/dist/utils/managed-paths.d.ts +0 -7
  348. package/dist/utils/managed-paths.d.ts.map +1 -1
  349. package/dist/utils/managed-paths.js +0 -40
  350. package/dist/utils/managed-paths.js.map +1 -1
  351. package/dist/utils/manifest-prune.d.ts.map +1 -1
  352. package/dist/utils/manifest-prune.js +2 -11
  353. package/dist/utils/manifest-prune.js.map +1 -1
  354. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  355. package/dist/utils/uninstall-scrubbers.js +3 -3
  356. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  357. package/dist/utils/workflow-resolver.d.ts +10 -16
  358. package/dist/utils/workflow-resolver.d.ts.map +1 -1
  359. package/dist/utils/workflow-resolver.js +25 -36
  360. package/dist/utils/workflow-resolver.js.map +1 -1
  361. package/package.json +2 -2
  362. package/dist/commands/channel/adapters/claude.d.ts.map +0 -1
  363. package/dist/commands/channel/adapters/claude.js.map +0 -1
  364. package/dist/commands/channel/adapters/codex.d.ts.map +0 -1
  365. package/dist/commands/channel/adapters/codex.js.map +0 -1
  366. package/dist/commands/channel/adapters/index.d.ts.map +0 -1
  367. package/dist/commands/channel/adapters/index.js.map +0 -1
  368. package/dist/commands/channel/adapters/types.d.ts.map +0 -1
  369. package/dist/commands/channel/adapters/types.js.map +0 -1
  370. package/dist/commands/channel/agent-loader.d.ts.map +0 -1
  371. package/dist/commands/channel/agent-loader.js.map +0 -1
  372. package/dist/commands/channel/context-loader.d.ts.map +0 -1
  373. package/dist/commands/channel/context-loader.js.map +0 -1
  374. package/dist/commands/channel/context-trust.d.ts.map +0 -1
  375. package/dist/commands/channel/context-trust.js.map +0 -1
  376. package/dist/commands/channel/context.d.ts +0 -16
  377. package/dist/commands/channel/context.d.ts.map +0 -1
  378. package/dist/commands/channel/context.js.map +0 -1
  379. package/dist/commands/channel/create.d.ts +0 -29
  380. package/dist/commands/channel/create.d.ts.map +0 -1
  381. package/dist/commands/channel/create.js +0 -47
  382. package/dist/commands/channel/create.js.map +0 -1
  383. package/dist/commands/channel/dev-parse-trace.d.ts.map +0 -1
  384. package/dist/commands/channel/dev-parse-trace.js.map +0 -1
  385. package/dist/commands/channel/guard.d.ts.map +0 -1
  386. package/dist/commands/channel/guard.js.map +0 -1
  387. package/dist/commands/channel/index.d.ts +0 -3
  388. package/dist/commands/channel/index.d.ts.map +0 -1
  389. package/dist/commands/channel/index.js.map +0 -1
  390. package/dist/commands/channel/interrupt.d.ts.map +0 -1
  391. package/dist/commands/channel/interrupt.js +0 -22
  392. package/dist/commands/channel/interrupt.js.map +0 -1
  393. package/dist/commands/channel/kill.d.ts +0 -7
  394. package/dist/commands/channel/kill.d.ts.map +0 -1
  395. package/dist/commands/channel/kill.js.map +0 -1
  396. package/dist/commands/channel/list.d.ts +0 -18
  397. package/dist/commands/channel/list.d.ts.map +0 -1
  398. package/dist/commands/channel/list.js.map +0 -1
  399. package/dist/commands/channel/messages.d.ts.map +0 -1
  400. package/dist/commands/channel/messages.js.map +0 -1
  401. package/dist/commands/channel/rm.d.ts +0 -27
  402. package/dist/commands/channel/rm.d.ts.map +0 -1
  403. package/dist/commands/channel/rm.js.map +0 -1
  404. package/dist/commands/channel/run.d.ts +0 -32
  405. package/dist/commands/channel/run.js +0 -141
  406. package/dist/commands/channel/run.js.map +0 -1
  407. package/dist/commands/channel/send.d.ts.map +0 -1
  408. package/dist/commands/channel/send.js.map +0 -1
  409. package/dist/commands/channel/spawn.d.ts.map +0 -1
  410. package/dist/commands/channel/spawn.js.map +0 -1
  411. package/dist/commands/channel/store/events.d.ts +0 -22
  412. package/dist/commands/channel/store/events.d.ts.map +0 -1
  413. package/dist/commands/channel/store/events.js.map +0 -1
  414. package/dist/commands/channel/store/filter.d.ts +0 -3
  415. package/dist/commands/channel/store/filter.d.ts.map +0 -1
  416. package/dist/commands/channel/store/filter.js +0 -2
  417. package/dist/commands/channel/store/filter.js.map +0 -1
  418. package/dist/commands/channel/store/lock.d.ts.map +0 -1
  419. package/dist/commands/channel/store/lock.js.map +0 -1
  420. package/dist/commands/channel/store/paths.d.ts.map +0 -1
  421. package/dist/commands/channel/store/paths.js.map +0 -1
  422. package/dist/commands/channel/store/schema.d.ts +0 -27
  423. package/dist/commands/channel/store/schema.d.ts.map +0 -1
  424. package/dist/commands/channel/store/schema.js +0 -34
  425. package/dist/commands/channel/store/schema.js.map +0 -1
  426. package/dist/commands/channel/store/thread-state.d.ts.map +0 -1
  427. package/dist/commands/channel/store/thread-state.js.map +0 -1
  428. package/dist/commands/channel/store/watch.d.ts +0 -19
  429. package/dist/commands/channel/store/watch.d.ts.map +0 -1
  430. package/dist/commands/channel/store/watch.js.map +0 -1
  431. package/dist/commands/channel/supervisor/idle.d.ts.map +0 -1
  432. package/dist/commands/channel/supervisor/idle.js.map +0 -1
  433. package/dist/commands/channel/supervisor/inbox.d.ts.map +0 -1
  434. package/dist/commands/channel/supervisor/inbox.js.map +0 -1
  435. package/dist/commands/channel/supervisor/shutdown.d.ts.map +0 -1
  436. package/dist/commands/channel/supervisor/shutdown.js.map +0 -1
  437. package/dist/commands/channel/supervisor/stdout.d.ts.map +0 -1
  438. package/dist/commands/channel/supervisor/stdout.js.map +0 -1
  439. package/dist/commands/channel/supervisor/turns.d.ts.map +0 -1
  440. package/dist/commands/channel/supervisor/turns.js.map +0 -1
  441. package/dist/commands/channel/supervisor/warning.d.ts.map +0 -1
  442. package/dist/commands/channel/supervisor/warning.js.map +0 -1
  443. package/dist/commands/channel/supervisor.d.ts.map +0 -1
  444. package/dist/commands/channel/supervisor.js.map +0 -1
  445. package/dist/commands/channel/text-body.d.ts +0 -13
  446. package/dist/commands/channel/text-body.d.ts.map +0 -1
  447. package/dist/commands/channel/text-body.js.map +0 -1
  448. package/dist/commands/channel/threads.d.ts +0 -39
  449. package/dist/commands/channel/threads.d.ts.map +0 -1
  450. package/dist/commands/channel/threads.js.map +0 -1
  451. package/dist/commands/channel/title.d.ts +0 -12
  452. package/dist/commands/channel/title.d.ts.map +0 -1
  453. package/dist/commands/channel/title.js +0 -24
  454. package/dist/commands/channel/title.js.map +0 -1
  455. package/dist/commands/channel/wait.d.ts.map +0 -1
  456. package/dist/commands/channel/wait.js.map +0 -1
  457. package/dist/commands/channel/workers.d.ts +0 -9
  458. package/dist/commands/channel/workers.d.ts.map +0 -1
  459. package/dist/commands/channel/workers.js +0 -31
  460. package/dist/commands/channel/workers.js.map +0 -1
  461. package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +0 -69
  462. package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +0 -549
  463. package/dist/templates/common/bundled-skills/trellis-channel/references/forum.md +0 -233
  464. package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +0 -237
  465. package/dist/templates/common/bundled-skills/trellis-channel/references/subnode-work.md +0 -193
  466. package/dist/templates/common/bundled-skills/trellis-channel/references/workers.md +0 -295
  467. package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +0 -131
  468. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-channel.md +0 -70
  469. package/dist/templates/common/bundled-skills/trellis-research-record/SKILL.md +0 -14
  470. package/dist/templates/copilot/prompts/parallel.prompt.md +0 -204
  471. package/dist/templates/trellis/agents/check.md +0 -70
  472. package/dist/templates/trellis/agents/implement.md +0 -71
  473. package/dist/templates/trellis/agents/subnode.env +0 -4
  474. package/dist/templates/trellis/agents/subnode.md +0 -69
  475. package/dist/templates/trellis/scripts/common/context_projection.py +0 -508
  476. package/dist/templates/trellis/scripts/common/continuation_record.py +0 -450
  477. package/dist/templates/trellis/scripts/common/ownership_record.py +0 -439
  478. package/dist/templates/trellis/scripts/subnode_artifact.py +0 -597
  479. package/dist/templates/trellis/scripts/workspace_note.py +0 -126
  480. /package/dist/commands/{channel → teamwork}/adapters/types.js +0 -0
  481. /package/dist/commands/{channel → teamwork}/supervisor/idle.d.ts +0 -0
  482. /package/dist/commands/{channel → teamwork}/supervisor/idle.js +0 -0
  483. /package/dist/commands/{channel → teamwork}/supervisor/turns.d.ts +0 -0
  484. /package/dist/commands/{channel → teamwork}/supervisor/turns.js +0 -0
@@ -1,508 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Shared materialization for Python sub-agent context.
3
-
4
- The shared Python Hook renders this projection for implement/check agents and
5
- ``task.py validate`` reads the same result before a task starts. A notice is
6
- still useful in a live prompt, but it is never a complete projection.
7
- """
8
-
9
- from __future__ import annotations
10
-
11
- import json
12
- import os
13
- from dataclasses import dataclass, field
14
- from pathlib import Path
15
-
16
- from .paths import DIR_ARCHIVE, DIR_TASKS, DIR_WORKFLOW
17
-
18
-
19
- DIRECTORY_MAX_FILES = 20
20
-
21
-
22
- @dataclass(frozen=True)
23
- class ContextEntry:
24
- """A normalised JSONL entry consumed by the Python Hook."""
25
-
26
- path: str
27
- entry_type: str
28
- reason: str
29
- line: int
30
-
31
-
32
- @dataclass(frozen=True)
33
- class ManifestProblem:
34
- """A malformed manifest row that the CLI must reject."""
35
-
36
- line: int
37
- message: str
38
-
39
-
40
- @dataclass(frozen=True)
41
- class ProjectionIssue:
42
- """Why one declared source was not represented as complete body text."""
43
-
44
- role: str
45
- category: str
46
- path: str
47
- reason: str
48
- line: int | None = None
49
-
50
-
51
- @dataclass
52
- class ContextProjection:
53
- """The Hook text and the facts the validator must fail closed on."""
54
-
55
- role: str
56
- text: str
57
- entries: list[ContextEntry] = field(default_factory=list)
58
- manifest_problems: list[ManifestProblem] = field(default_factory=list)
59
- issues: list[ProjectionIssue] = field(default_factory=list)
60
- manifest_exists: bool = False
61
-
62
-
63
- class _Budget:
64
- def __init__(self, max_total_bytes: int) -> None:
65
- self.max_total_bytes = max_total_bytes
66
- self.used = 0
67
-
68
- def has_room(self, size: int) -> bool:
69
- return self.max_total_bytes <= 0 or self.used + size <= self.max_total_bytes
70
-
71
- def add(self, size: int) -> None:
72
- self.used += size
73
-
74
-
75
- def truncate_utf8(data: bytes, cap: int) -> bytes:
76
- """Truncate at a valid UTF-8 boundary; zero means unlimited."""
77
- if cap <= 0 or len(data) <= cap:
78
- return data
79
-
80
- truncated = data[:cap]
81
- index = len(truncated)
82
- while index > 0 and (truncated[index - 1] & 0xC0) == 0x80:
83
- index -= 1
84
- if index == 0:
85
- return b""
86
-
87
- lead = truncated[index - 1]
88
- if lead & 0x80:
89
- if (lead & 0xE0) == 0xC0:
90
- sequence_length = 2
91
- elif (lead & 0xF0) == 0xE0:
92
- sequence_length = 3
93
- elif (lead & 0xF8) == 0xF0:
94
- sequence_length = 4
95
- else:
96
- sequence_length = 1
97
- if (index - 1) + sequence_length > len(truncated):
98
- return truncated[: index - 1]
99
- return truncated
100
-
101
-
102
- def is_binary_content(data: bytes) -> bool:
103
- if b"\x00" in data:
104
- return True
105
- try:
106
- data.decode("utf-8", errors="strict")
107
- except UnicodeDecodeError:
108
- return True
109
- return False
110
-
111
-
112
- def parse_context_manifest(jsonl_file: Path) -> tuple[list[ContextEntry], list[ManifestProblem], bool]:
113
- """Parse the JSONL schema shared by the Hook and validation command."""
114
- if not jsonl_file.is_file():
115
- return [], [], False
116
- try:
117
- lines = jsonl_file.read_text(encoding="utf-8").splitlines()
118
- except (OSError, UnicodeDecodeError):
119
- return [], [ManifestProblem(0, "Manifest is unreadable or is not valid UTF-8")], True
120
-
121
- entries: list[ContextEntry] = []
122
- problems: list[ManifestProblem] = []
123
- for line_number, line in enumerate(lines, start=1):
124
- if not line.strip():
125
- continue
126
- try:
127
- data = json.loads(line)
128
- except json.JSONDecodeError:
129
- problems.append(ManifestProblem(line_number, "Invalid JSON"))
130
- continue
131
- if not isinstance(data, dict):
132
- problems.append(ManifestProblem(line_number, "Expected a JSON object"))
133
- continue
134
- if "_example" in data:
135
- problems.append(
136
- ManifestProblem(
137
- line_number,
138
- "Placeholder `_example` row left by an older task.py create — delete this line, or replace it with "
139
- '{"file": "<path>", "reason": "<why>"}',
140
- )
141
- )
142
- continue
143
-
144
- file_value = data.get("file")
145
- path_value = data.get("path")
146
- if file_value not in (None, "") and not isinstance(file_value, str):
147
- problems.append(
148
- ManifestProblem(line_number, "`file` or legacy `path` must be a string path")
149
- )
150
- continue
151
- if path_value not in (None, "") and not isinstance(path_value, str):
152
- problems.append(
153
- ManifestProblem(line_number, "`file` or legacy `path` must be a string path")
154
- )
155
- continue
156
- value = file_value or path_value
157
- if not value:
158
- continue
159
- if not isinstance(value, str):
160
- problems.append(ManifestProblem(line_number, "`file` or legacy `path` must be a string path"))
161
- continue
162
-
163
- entry_type = data.get("type", "file")
164
- reason = data.get("reason") or "-"
165
- entries.append(
166
- ContextEntry(
167
- path=value,
168
- entry_type=entry_type if isinstance(entry_type, str) else "file",
169
- reason=reason if isinstance(reason, str) else str(reason),
170
- line=line_number,
171
- )
172
- )
173
- return entries, problems, True
174
-
175
-
176
- def _real_path_contained(base_real: str, target_real: str) -> bool:
177
- try:
178
- return os.path.commonpath([base_real, target_real]) == base_real
179
- except ValueError:
180
- return False
181
-
182
-
183
- def _is_allowed_path(repo_root: Path, candidate: Path) -> bool:
184
- try:
185
- root_real = os.path.realpath(repo_root)
186
- workflow_real = os.path.realpath(repo_root / DIR_WORKFLOW)
187
- candidate_real = os.path.realpath(candidate)
188
- except OSError:
189
- return False
190
- return _real_path_contained(root_real, candidate_real) or _real_path_contained(
191
- workflow_real, candidate_real
192
- )
193
-
194
-
195
- def resolve_context_entry_path(file_path: str, repo_root: Path, task_dir: Path | None) -> Path | None:
196
- """Resolve an entry and preserve archived task self-reference semantics."""
197
- repo_path = repo_root / file_path
198
- if task_dir is None:
199
- return repo_path
200
-
201
- try:
202
- task_parts = task_dir.resolve().relative_to(repo_root.resolve()).parts
203
- except ValueError:
204
- return repo_path
205
-
206
- archive_prefix = (DIR_WORKFLOW, DIR_TASKS, DIR_ARCHIVE)
207
- if len(task_parts) != 5 or task_parts[:3] != archive_prefix:
208
- return repo_path
209
-
210
- year_month = task_parts[3]
211
- if (
212
- len(year_month) != 7
213
- or year_month[4] != "-"
214
- or not year_month[:4].isdigit()
215
- or not year_month[5:].isdigit()
216
- ):
217
- return repo_path
218
-
219
- historical_root = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_dir.name}"
220
- posix_path = file_path.replace("\\", "/")
221
- if posix_path == historical_root:
222
- relative_parts: tuple[str, ...] = ()
223
- elif posix_path.startswith(f"{historical_root}/"):
224
- relative_path = posix_path[len(historical_root) + 1 :].rstrip("/")
225
- relative_parts = tuple(relative_path.split("/")) if relative_path else ()
226
- if any(part in ("", ".", "..") for part in relative_parts):
227
- return None
228
- else:
229
- return repo_path
230
-
231
- try:
232
- archive_root = task_dir.resolve()
233
- resolved_path = task_dir.joinpath(*relative_parts).resolve()
234
- resolved_path.relative_to(archive_root)
235
- except (OSError, RuntimeError, ValueError):
236
- return None
237
- return resolved_path
238
-
239
-
240
- def _display_task_path(repo_root: Path, task_dir: Path, file_name: str) -> str:
241
- try:
242
- return (task_dir.relative_to(repo_root) / file_name).as_posix()
243
- except ValueError:
244
- return f"{task_dir.as_posix().rstrip('/')}/{file_name}"
245
-
246
-
247
- def _truncate_notice(path: str, cap: int) -> str:
248
- return f"\n[Trellis: truncated at {cap} bytes — read {path} for the full content]"
249
-
250
-
251
- def _binary_notice(path: str, size: int, reason: str) -> str:
252
- return f"[Trellis: not inlined (binary file) — {path} ({size} bytes): {reason}]"
253
-
254
-
255
- def _index_notice(path: str, size: int, reason: str) -> str:
256
- return f"[Trellis: not inlined (total context limit reached) — {path} ({size} bytes): {reason}]"
257
-
258
-
259
- def _append_block(
260
- projection: ContextProjection,
261
- budget: _Budget,
262
- *,
263
- header: str,
264
- path: str,
265
- content: str,
266
- size: int,
267
- reason: str,
268
- category: str,
269
- line: int | None,
270
- ) -> str:
271
- block = f"=== {header} ===\n{content}"
272
- block_bytes = len(block.encode("utf-8"))
273
- if budget.has_room(block_bytes):
274
- budget.add(block_bytes)
275
- return block
276
-
277
- notice = _index_notice(path, size, reason)
278
- budget.add(len(notice.encode("utf-8")))
279
- limit = budget.max_total_bytes
280
- projection.issues.append(
281
- ProjectionIssue(
282
- role=projection.role,
283
- category="total",
284
- path=path,
285
- reason=f"exceeds context_injection.max_total_bytes ({limit}); injection uses an index notice",
286
- line=line,
287
- )
288
- )
289
- return notice
290
-
291
-
292
- def _new_projection(role: str, entries: list[ContextEntry], problems: list[ManifestProblem], manifest_exists: bool) -> ContextProjection:
293
- projection = ContextProjection(
294
- role=role,
295
- text="",
296
- entries=entries,
297
- manifest_problems=problems,
298
- manifest_exists=manifest_exists,
299
- )
300
- return projection
301
-
302
-
303
- def _read_material(
304
- repo_root: Path, target: Path | None, category: str, path: str, projection: ContextProjection, line: int | None
305
- ) -> bytes | None:
306
- if target is None:
307
- projection.issues.append(
308
- ProjectionIssue(projection.role, category, path, "path cannot be resolved safely", line)
309
- )
310
- return None
311
- if not _is_allowed_path(repo_root, target):
312
- projection.issues.append(
313
- ProjectionIssue(projection.role, category, path, "path escapes the allowed project roots", line)
314
- )
315
- return None
316
- try:
317
- if not target.is_file():
318
- raise OSError
319
- return target.read_bytes()
320
- except OSError:
321
- projection.issues.append(
322
- ProjectionIssue(projection.role, category, path, "file is missing or unreadable", line)
323
- )
324
- return None
325
-
326
-
327
- def _materialize_file(
328
- repo_root: Path,
329
- target: Path | None,
330
- path: str,
331
- reason: str,
332
- limits: dict[str, int],
333
- budget: _Budget,
334
- projection: ContextProjection,
335
- *,
336
- category: str,
337
- line: int | None,
338
- header: str | None = None,
339
- cap_key: str = "max_file_bytes",
340
- ) -> str | None:
341
- data = _read_material(repo_root, target, category, path, projection, line)
342
- if data is None:
343
- return None
344
-
345
- size = len(data)
346
- if is_binary_content(data):
347
- notice = _binary_notice(path, size, reason)
348
- budget.add(len(notice.encode("utf-8")))
349
- projection.issues.append(
350
- ProjectionIssue(projection.role, category, path, "binary content is not inlined", line)
351
- )
352
- return notice
353
-
354
- cap = limits[cap_key]
355
- materialized = truncate_utf8(data, cap)
356
- content = materialized.decode("utf-8")
357
- if len(materialized) < size:
358
- content += _truncate_notice(path, cap)
359
- projection.issues.append(
360
- ProjectionIssue(
361
- projection.role,
362
- category,
363
- path,
364
- f"exceeds context_injection.{cap_key} ({cap}); injection truncates it",
365
- line,
366
- )
367
- )
368
- return _append_block(
369
- projection,
370
- budget,
371
- header=header or path,
372
- path=path,
373
- content=content,
374
- size=size,
375
- reason=reason,
376
- category=category,
377
- line=line,
378
- )
379
-
380
-
381
- def _materialize_directory(
382
- repo_root: Path,
383
- entry: ContextEntry,
384
- task_dir: Path,
385
- limits: dict[str, int],
386
- budget: _Budget,
387
- projection: ContextProjection,
388
- ) -> list[str]:
389
- target = resolve_context_entry_path(entry.path, repo_root, task_dir)
390
- if target is None or not _is_allowed_path(repo_root, target) or not target.is_dir():
391
- reason = "directory is missing, unreadable, or escapes the allowed project roots"
392
- projection.issues.append(
393
- ProjectionIssue(projection.role, "directory", entry.path, reason, entry.line)
394
- )
395
- return []
396
- try:
397
- files = sorted(
398
- child for child in target.iterdir() if child.suffix == ".md" and child.is_file()
399
- )
400
- except OSError:
401
- projection.issues.append(
402
- ProjectionIssue(projection.role, "directory", entry.path, "directory is unreadable", entry.line)
403
- )
404
- return []
405
-
406
- if not files:
407
- projection.issues.append(
408
- ProjectionIssue(
409
- projection.role, "directory", entry.path, "directory has no direct Markdown files to inject", entry.line
410
- )
411
- )
412
- return []
413
- if len(files) > DIRECTORY_MAX_FILES:
414
- projection.issues.append(
415
- ProjectionIssue(
416
- projection.role,
417
- "directory",
418
- entry.path,
419
- f"directory contains {len(files)} Markdown files; injection selects only the first {DIRECTORY_MAX_FILES}",
420
- entry.line,
421
- )
422
- )
423
-
424
- blocks: list[str] = []
425
- for child in files[:DIRECTORY_MAX_FILES]:
426
- display = f"{entry.path.rstrip('/')}/{child.name}"
427
- block = _materialize_file(
428
- repo_root,
429
- child,
430
- display,
431
- entry.reason,
432
- limits,
433
- budget,
434
- projection,
435
- category="file",
436
- line=entry.line,
437
- )
438
- if block:
439
- blocks.append(block)
440
- return blocks
441
-
442
-
443
- def project_agent_context(
444
- repo_root: Path, task_dir: Path, agent_type: str, limits: dict[str, int]
445
- ) -> ContextProjection:
446
- """Render the exact Python Hook context and record every loss of body text."""
447
- jsonl_name = f"{agent_type}.jsonl"
448
- entries, manifest_problems, manifest_exists = parse_context_manifest(task_dir / jsonl_name)
449
- projection = _new_projection(agent_type, entries, manifest_problems, manifest_exists)
450
- budget = _Budget(limits["max_total_bytes"])
451
- blocks: list[str] = []
452
-
453
- for entry in entries:
454
- if entry.entry_type == "directory":
455
- blocks.extend(_materialize_directory(repo_root, entry, task_dir, limits, budget, projection))
456
- continue
457
- target = resolve_context_entry_path(entry.path, repo_root, task_dir)
458
- block = _materialize_file(
459
- repo_root,
460
- target,
461
- entry.path,
462
- entry.reason,
463
- limits,
464
- budget,
465
- projection,
466
- category="file",
467
- line=entry.line,
468
- )
469
- if block:
470
- blocks.append(block)
471
-
472
- if blocks:
473
- context_parts = ["\n\n".join(blocks)]
474
- else:
475
- context_parts = [
476
- f"[Trellis] {_display_task_path(repo_root, task_dir, jsonl_name)} has no curated entries, so no spec/research "
477
- "context was injected. Before working, read the guidelines relevant to the code you will touch under "
478
- ".trellis/spec/, and treat the task artifacts below as the only prepared context."
479
- ]
480
-
481
- artifact_specs = (
482
- ("prd.md", "Requirements", "Requirements document"),
483
- ("design.md", "Technical Design", "Technical design document"),
484
- ("implement.md", "Execution Plan", "Execution plan document"),
485
- )
486
- for file_name, label, reason in artifact_specs:
487
- target = task_dir / file_name
488
- if not target.exists():
489
- continue
490
- display = _display_task_path(repo_root, task_dir, file_name)
491
- block = _materialize_file(
492
- repo_root,
493
- target,
494
- display,
495
- reason,
496
- limits,
497
- budget,
498
- projection,
499
- category="artifact",
500
- line=None,
501
- header=f"{display} ({label})",
502
- cap_key="max_artifact_bytes",
503
- )
504
- if block:
505
- context_parts.append(block)
506
-
507
- projection.text = "\n\n".join(context_parts)
508
- return projection