@pennixrv/trellis 0.6.17

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 (831) hide show
  1. package/LICENSE +235 -0
  2. package/README.md +168 -0
  3. package/bin/trellis.js +3 -0
  4. package/dist/cli/index.d.ts +3 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +299 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/commands/ablate.d.ts +14 -0
  9. package/dist/commands/ablate.d.ts.map +1 -0
  10. package/dist/commands/ablate.js +307 -0
  11. package/dist/commands/ablate.js.map +1 -0
  12. package/dist/commands/channel/adapters/claude.d.ts +53 -0
  13. package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
  14. package/dist/commands/channel/adapters/claude.js +225 -0
  15. package/dist/commands/channel/adapters/claude.js.map +1 -0
  16. package/dist/commands/channel/adapters/codex.d.ts +93 -0
  17. package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
  18. package/dist/commands/channel/adapters/codex.js +573 -0
  19. package/dist/commands/channel/adapters/codex.js.map +1 -0
  20. package/dist/commands/channel/adapters/index.d.ts +94 -0
  21. package/dist/commands/channel/adapters/index.d.ts.map +1 -0
  22. package/dist/commands/channel/adapters/index.js +116 -0
  23. package/dist/commands/channel/adapters/index.js.map +1 -0
  24. package/dist/commands/channel/adapters/types.d.ts +33 -0
  25. package/dist/commands/channel/adapters/types.d.ts.map +1 -0
  26. package/dist/commands/channel/adapters/types.js +2 -0
  27. package/dist/commands/channel/adapters/types.js.map +1 -0
  28. package/dist/commands/channel/agent-loader.d.ts +32 -0
  29. package/dist/commands/channel/agent-loader.d.ts.map +1 -0
  30. package/dist/commands/channel/agent-loader.js +158 -0
  31. package/dist/commands/channel/agent-loader.js.map +1 -0
  32. package/dist/commands/channel/context-loader.d.ts +26 -0
  33. package/dist/commands/channel/context-loader.d.ts.map +1 -0
  34. package/dist/commands/channel/context-loader.js +311 -0
  35. package/dist/commands/channel/context-loader.js.map +1 -0
  36. package/dist/commands/channel/context-trust.d.ts +31 -0
  37. package/dist/commands/channel/context-trust.d.ts.map +1 -0
  38. package/dist/commands/channel/context-trust.js +139 -0
  39. package/dist/commands/channel/context-trust.js.map +1 -0
  40. package/dist/commands/channel/context.d.ts +16 -0
  41. package/dist/commands/channel/context.d.ts.map +1 -0
  42. package/dist/commands/channel/context.js +83 -0
  43. package/dist/commands/channel/context.js.map +1 -0
  44. package/dist/commands/channel/create.d.ts +27 -0
  45. package/dist/commands/channel/create.d.ts.map +1 -0
  46. package/dist/commands/channel/create.js +39 -0
  47. package/dist/commands/channel/create.js.map +1 -0
  48. package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
  49. package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
  50. package/dist/commands/channel/dev-parse-trace.js +70 -0
  51. package/dist/commands/channel/dev-parse-trace.js.map +1 -0
  52. package/dist/commands/channel/guard.d.ts +150 -0
  53. package/dist/commands/channel/guard.d.ts.map +1 -0
  54. package/dist/commands/channel/guard.js +479 -0
  55. package/dist/commands/channel/guard.js.map +1 -0
  56. package/dist/commands/channel/index.d.ts +3 -0
  57. package/dist/commands/channel/index.d.ts.map +1 -0
  58. package/dist/commands/channel/index.js +535 -0
  59. package/dist/commands/channel/index.js.map +1 -0
  60. package/dist/commands/channel/interrupt.d.ts +10 -0
  61. package/dist/commands/channel/interrupt.d.ts.map +1 -0
  62. package/dist/commands/channel/interrupt.js +22 -0
  63. package/dist/commands/channel/interrupt.js.map +1 -0
  64. package/dist/commands/channel/kill.d.ts +7 -0
  65. package/dist/commands/channel/kill.d.ts.map +1 -0
  66. package/dist/commands/channel/kill.js +130 -0
  67. package/dist/commands/channel/kill.js.map +1 -0
  68. package/dist/commands/channel/list.d.ts +17 -0
  69. package/dist/commands/channel/list.d.ts.map +1 -0
  70. package/dist/commands/channel/list.js +233 -0
  71. package/dist/commands/channel/list.js.map +1 -0
  72. package/dist/commands/channel/messages.d.ts +15 -0
  73. package/dist/commands/channel/messages.d.ts.map +1 -0
  74. package/dist/commands/channel/messages.js +245 -0
  75. package/dist/commands/channel/messages.js.map +1 -0
  76. package/dist/commands/channel/rm.d.ts +27 -0
  77. package/dist/commands/channel/rm.d.ts.map +1 -0
  78. package/dist/commands/channel/rm.js +216 -0
  79. package/dist/commands/channel/rm.js.map +1 -0
  80. package/dist/commands/channel/run.d.ts +30 -0
  81. package/dist/commands/channel/run.d.ts.map +1 -0
  82. package/dist/commands/channel/run.js +134 -0
  83. package/dist/commands/channel/run.js.map +1 -0
  84. package/dist/commands/channel/send.d.ts +11 -0
  85. package/dist/commands/channel/send.d.ts.map +1 -0
  86. package/dist/commands/channel/send.js +24 -0
  87. package/dist/commands/channel/send.js.map +1 -0
  88. package/dist/commands/channel/spawn.d.ts +43 -0
  89. package/dist/commands/channel/spawn.d.ts.map +1 -0
  90. package/dist/commands/channel/spawn.js +247 -0
  91. package/dist/commands/channel/spawn.js.map +1 -0
  92. package/dist/commands/channel/store/events.d.ts +22 -0
  93. package/dist/commands/channel/store/events.d.ts.map +1 -0
  94. package/dist/commands/channel/store/events.js +43 -0
  95. package/dist/commands/channel/store/events.js.map +1 -0
  96. package/dist/commands/channel/store/filter.d.ts +3 -0
  97. package/dist/commands/channel/store/filter.d.ts.map +1 -0
  98. package/dist/commands/channel/store/filter.js +2 -0
  99. package/dist/commands/channel/store/filter.js.map +1 -0
  100. package/dist/commands/channel/store/lock.d.ts +23 -0
  101. package/dist/commands/channel/store/lock.d.ts.map +1 -0
  102. package/dist/commands/channel/store/lock.js +99 -0
  103. package/dist/commands/channel/store/lock.js.map +1 -0
  104. package/dist/commands/channel/store/paths.d.ts +77 -0
  105. package/dist/commands/channel/store/paths.d.ts.map +1 -0
  106. package/dist/commands/channel/store/paths.js +272 -0
  107. package/dist/commands/channel/store/paths.js.map +1 -0
  108. package/dist/commands/channel/store/schema.d.ts +27 -0
  109. package/dist/commands/channel/store/schema.d.ts.map +1 -0
  110. package/dist/commands/channel/store/schema.js +34 -0
  111. package/dist/commands/channel/store/schema.js.map +1 -0
  112. package/dist/commands/channel/store/thread-state.d.ts +5 -0
  113. package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
  114. package/dist/commands/channel/store/thread-state.js +16 -0
  115. package/dist/commands/channel/store/thread-state.js.map +1 -0
  116. package/dist/commands/channel/store/watch.d.ts +19 -0
  117. package/dist/commands/channel/store/watch.d.ts.map +1 -0
  118. package/dist/commands/channel/store/watch.js +153 -0
  119. package/dist/commands/channel/store/watch.js.map +1 -0
  120. package/dist/commands/channel/supervisor/idle.d.ts +45 -0
  121. package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
  122. package/dist/commands/channel/supervisor/idle.js +70 -0
  123. package/dist/commands/channel/supervisor/idle.js.map +1 -0
  124. package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
  125. package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
  126. package/dist/commands/channel/supervisor/inbox.js +160 -0
  127. package/dist/commands/channel/supervisor/inbox.js.map +1 -0
  128. package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
  129. package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
  130. package/dist/commands/channel/supervisor/shutdown.js +146 -0
  131. package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
  132. package/dist/commands/channel/supervisor/stdout.d.ts +71 -0
  133. package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
  134. package/dist/commands/channel/supervisor/stdout.js +229 -0
  135. package/dist/commands/channel/supervisor/stdout.js.map +1 -0
  136. package/dist/commands/channel/supervisor/turns.d.ts +31 -0
  137. package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
  138. package/dist/commands/channel/supervisor/turns.js +45 -0
  139. package/dist/commands/channel/supervisor/turns.js.map +1 -0
  140. package/dist/commands/channel/supervisor/warning.d.ts +48 -0
  141. package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
  142. package/dist/commands/channel/supervisor/warning.js +77 -0
  143. package/dist/commands/channel/supervisor/warning.js.map +1 -0
  144. package/dist/commands/channel/supervisor.d.ts +91 -0
  145. package/dist/commands/channel/supervisor.d.ts.map +1 -0
  146. package/dist/commands/channel/supervisor.js +463 -0
  147. package/dist/commands/channel/supervisor.js.map +1 -0
  148. package/dist/commands/channel/text-body.d.ts +13 -0
  149. package/dist/commands/channel/text-body.d.ts.map +1 -0
  150. package/dist/commands/channel/text-body.js +47 -0
  151. package/dist/commands/channel/text-body.js.map +1 -0
  152. package/dist/commands/channel/threads.d.ts +39 -0
  153. package/dist/commands/channel/threads.d.ts.map +1 -0
  154. package/dist/commands/channel/threads.js +106 -0
  155. package/dist/commands/channel/threads.js.map +1 -0
  156. package/dist/commands/channel/title.d.ts +12 -0
  157. package/dist/commands/channel/title.d.ts.map +1 -0
  158. package/dist/commands/channel/title.js +24 -0
  159. package/dist/commands/channel/title.js.map +1 -0
  160. package/dist/commands/channel/wait.d.ts +17 -0
  161. package/dist/commands/channel/wait.d.ts.map +1 -0
  162. package/dist/commands/channel/wait.js +81 -0
  163. package/dist/commands/channel/wait.js.map +1 -0
  164. package/dist/commands/init.d.ts +71 -0
  165. package/dist/commands/init.d.ts.map +1 -0
  166. package/dist/commands/init.js +1603 -0
  167. package/dist/commands/init.js.map +1 -0
  168. package/dist/commands/mem.d.ts +30 -0
  169. package/dist/commands/mem.d.ts.map +1 -0
  170. package/dist/commands/mem.js +423 -0
  171. package/dist/commands/mem.js.map +1 -0
  172. package/dist/commands/uninstall.d.ts +36 -0
  173. package/dist/commands/uninstall.d.ts.map +1 -0
  174. package/dist/commands/uninstall.js +205 -0
  175. package/dist/commands/uninstall.js.map +1 -0
  176. package/dist/commands/update.d.ts +104 -0
  177. package/dist/commands/update.d.ts.map +1 -0
  178. package/dist/commands/update.js +2163 -0
  179. package/dist/commands/update.js.map +1 -0
  180. package/dist/commands/upgrade.d.ts +28 -0
  181. package/dist/commands/upgrade.d.ts.map +1 -0
  182. package/dist/commands/upgrade.js +84 -0
  183. package/dist/commands/upgrade.js.map +1 -0
  184. package/dist/commands/workflow.d.ts +35 -0
  185. package/dist/commands/workflow.d.ts.map +1 -0
  186. package/dist/commands/workflow.js +232 -0
  187. package/dist/commands/workflow.js.map +1 -0
  188. package/dist/configurators/antigravity.d.ts +7 -0
  189. package/dist/configurators/antigravity.d.ts.map +1 -0
  190. package/dist/configurators/antigravity.js +11 -0
  191. package/dist/configurators/antigravity.js.map +1 -0
  192. package/dist/configurators/claude.d.ts +23 -0
  193. package/dist/configurators/claude.d.ts.map +1 -0
  194. package/dist/configurators/claude.js +123 -0
  195. package/dist/configurators/claude.js.map +1 -0
  196. package/dist/configurators/codebuddy.d.ts +10 -0
  197. package/dist/configurators/codebuddy.d.ts.map +1 -0
  198. package/dist/configurators/codebuddy.js +24 -0
  199. package/dist/configurators/codebuddy.js.map +1 -0
  200. package/dist/configurators/codex.d.ts +57 -0
  201. package/dist/configurators/codex.d.ts.map +1 -0
  202. package/dist/configurators/codex.js +170 -0
  203. package/dist/configurators/codex.js.map +1 -0
  204. package/dist/configurators/copilot.d.ts +14 -0
  205. package/dist/configurators/copilot.d.ts.map +1 -0
  206. package/dist/configurators/copilot.js +46 -0
  207. package/dist/configurators/copilot.js.map +1 -0
  208. package/dist/configurators/cursor.d.ts +10 -0
  209. package/dist/configurators/cursor.d.ts.map +1 -0
  210. package/dist/configurators/cursor.js +23 -0
  211. package/dist/configurators/cursor.js.map +1 -0
  212. package/dist/configurators/devin.d.ts +8 -0
  213. package/dist/configurators/devin.d.ts.map +1 -0
  214. package/dist/configurators/devin.js +12 -0
  215. package/dist/configurators/devin.js.map +1 -0
  216. package/dist/configurators/droid.d.ts +10 -0
  217. package/dist/configurators/droid.d.ts.map +1 -0
  218. package/dist/configurators/droid.js +24 -0
  219. package/dist/configurators/droid.js.map +1 -0
  220. package/dist/configurators/dsh.d.ts +29 -0
  221. package/dist/configurators/dsh.d.ts.map +1 -0
  222. package/dist/configurators/dsh.js +64 -0
  223. package/dist/configurators/dsh.js.map +1 -0
  224. package/dist/configurators/gemini.d.ts +18 -0
  225. package/dist/configurators/gemini.d.ts.map +1 -0
  226. package/dist/configurators/gemini.js +39 -0
  227. package/dist/configurators/gemini.js.map +1 -0
  228. package/dist/configurators/grok.d.ts +17 -0
  229. package/dist/configurators/grok.d.ts.map +1 -0
  230. package/dist/configurators/grok.js +38 -0
  231. package/dist/configurators/grok.js.map +1 -0
  232. package/dist/configurators/index.d.ts +68 -0
  233. package/dist/configurators/index.d.ts.map +1 -0
  234. package/dist/configurators/index.js +191 -0
  235. package/dist/configurators/index.js.map +1 -0
  236. package/dist/configurators/kilo.d.ts +7 -0
  237. package/dist/configurators/kilo.d.ts.map +1 -0
  238. package/dist/configurators/kilo.js +11 -0
  239. package/dist/configurators/kilo.js.map +1 -0
  240. package/dist/configurators/kimi.d.ts +26 -0
  241. package/dist/configurators/kimi.d.ts.map +1 -0
  242. package/dist/configurators/kimi.js +74 -0
  243. package/dist/configurators/kimi.js.map +1 -0
  244. package/dist/configurators/kiro.d.ts +11 -0
  245. package/dist/configurators/kiro.d.ts.map +1 -0
  246. package/dist/configurators/kiro.js +30 -0
  247. package/dist/configurators/kiro.js.map +1 -0
  248. package/dist/configurators/omp.d.ts +6 -0
  249. package/dist/configurators/omp.d.ts.map +1 -0
  250. package/dist/configurators/omp.js +28 -0
  251. package/dist/configurators/omp.js.map +1 -0
  252. package/dist/configurators/opencode.d.ts +5 -0
  253. package/dist/configurators/opencode.d.ts.map +1 -0
  254. package/dist/configurators/opencode.js +80 -0
  255. package/dist/configurators/opencode.js.map +1 -0
  256. package/dist/configurators/pi.d.ts +5 -0
  257. package/dist/configurators/pi.d.ts.map +1 -0
  258. package/dist/configurators/pi.js +39 -0
  259. package/dist/configurators/pi.js.map +1 -0
  260. package/dist/configurators/qoder.d.ts +12 -0
  261. package/dist/configurators/qoder.d.ts.map +1 -0
  262. package/dist/configurators/qoder.js +30 -0
  263. package/dist/configurators/qoder.js.map +1 -0
  264. package/dist/configurators/reasonix.d.ts +17 -0
  265. package/dist/configurators/reasonix.d.ts.map +1 -0
  266. package/dist/configurators/reasonix.js +37 -0
  267. package/dist/configurators/reasonix.js.map +1 -0
  268. package/dist/configurators/shared.d.ts +187 -0
  269. package/dist/configurators/shared.d.ts.map +1 -0
  270. package/dist/configurators/shared.js +589 -0
  271. package/dist/configurators/shared.js.map +1 -0
  272. package/dist/configurators/snow.d.ts +25 -0
  273. package/dist/configurators/snow.d.ts.map +1 -0
  274. package/dist/configurators/snow.js +69 -0
  275. package/dist/configurators/snow.js.map +1 -0
  276. package/dist/configurators/trae.d.ts +16 -0
  277. package/dist/configurators/trae.d.ts.map +1 -0
  278. package/dist/configurators/trae.js +34 -0
  279. package/dist/configurators/trae.js.map +1 -0
  280. package/dist/configurators/workflow.d.ts +51 -0
  281. package/dist/configurators/workflow.d.ts.map +1 -0
  282. package/dist/configurators/workflow.js +210 -0
  283. package/dist/configurators/workflow.js.map +1 -0
  284. package/dist/configurators/zcode.d.ts +25 -0
  285. package/dist/configurators/zcode.d.ts.map +1 -0
  286. package/dist/configurators/zcode.js +67 -0
  287. package/dist/configurators/zcode.js.map +1 -0
  288. package/dist/constants/paths.d.ts +74 -0
  289. package/dist/constants/paths.d.ts.map +1 -0
  290. package/dist/constants/paths.js +83 -0
  291. package/dist/constants/paths.js.map +1 -0
  292. package/dist/constants/version.d.ts +9 -0
  293. package/dist/constants/version.d.ts.map +1 -0
  294. package/dist/constants/version.js +15 -0
  295. package/dist/constants/version.js.map +1 -0
  296. package/dist/index.d.ts +9 -0
  297. package/dist/index.d.ts.map +1 -0
  298. package/dist/index.js +9 -0
  299. package/dist/index.js.map +1 -0
  300. package/dist/migrations/index.d.ts +62 -0
  301. package/dist/migrations/index.d.ts.map +1 -0
  302. package/dist/migrations/index.js +187 -0
  303. package/dist/migrations/index.js.map +1 -0
  304. package/dist/migrations/manifests/0.1.9.json +30 -0
  305. package/dist/migrations/manifests/0.2.0.json +49 -0
  306. package/dist/migrations/manifests/0.2.12.json +9 -0
  307. package/dist/migrations/manifests/0.2.13.json +9 -0
  308. package/dist/migrations/manifests/0.2.14.json +175 -0
  309. package/dist/migrations/manifests/0.2.15.json +33 -0
  310. package/dist/migrations/manifests/0.3.0-beta.0.json +297 -0
  311. package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
  312. package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
  313. package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
  314. package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
  315. package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
  316. package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
  317. package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
  318. package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
  319. package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
  320. package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
  321. package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
  322. package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
  323. package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
  324. package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
  325. package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
  326. package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
  327. package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
  328. package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
  329. package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
  330. package/dist/migrations/manifests/0.3.0-rc.3.json +9 -0
  331. package/dist/migrations/manifests/0.3.0-rc.4.json +9 -0
  332. package/dist/migrations/manifests/0.3.0-rc.5.json +9 -0
  333. package/dist/migrations/manifests/0.3.0-rc.6.json +9 -0
  334. package/dist/migrations/manifests/0.3.0.json +11 -0
  335. package/dist/migrations/manifests/0.3.1.json +9 -0
  336. package/dist/migrations/manifests/0.3.10.json +9 -0
  337. package/dist/migrations/manifests/0.3.2.json +9 -0
  338. package/dist/migrations/manifests/0.3.3.json +9 -0
  339. package/dist/migrations/manifests/0.3.4.json +21 -0
  340. package/dist/migrations/manifests/0.3.5.json +9 -0
  341. package/dist/migrations/manifests/0.3.6.json +9 -0
  342. package/dist/migrations/manifests/0.3.7.json +9 -0
  343. package/dist/migrations/manifests/0.3.8.json +9 -0
  344. package/dist/migrations/manifests/0.3.9.json +9 -0
  345. package/dist/migrations/manifests/0.4.0-beta.1.json +228 -0
  346. package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
  347. package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
  348. package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
  349. package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
  350. package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
  351. package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
  352. package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
  353. package/dist/migrations/manifests/0.4.0-beta.8.json +34 -0
  354. package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
  355. package/dist/migrations/manifests/0.4.0-rc.0.json +9 -0
  356. package/dist/migrations/manifests/0.4.0-rc.1.json +9 -0
  357. package/dist/migrations/manifests/0.4.0.json +9 -0
  358. package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
  359. package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
  360. package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
  361. package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
  362. package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
  363. package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
  364. package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
  365. package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
  366. package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
  367. package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
  368. package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
  369. package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
  370. package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
  371. package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
  372. package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
  373. package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
  374. package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
  375. package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
  376. package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
  377. package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
  378. package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
  379. package/dist/migrations/manifests/0.5.0-rc.1.json +9 -0
  380. package/dist/migrations/manifests/0.5.0-rc.2.json +9 -0
  381. package/dist/migrations/manifests/0.5.0-rc.3.json +9 -0
  382. package/dist/migrations/manifests/0.5.0-rc.4.json +9 -0
  383. package/dist/migrations/manifests/0.5.0-rc.5.json +9 -0
  384. package/dist/migrations/manifests/0.5.0-rc.6.json +9 -0
  385. package/dist/migrations/manifests/0.5.0-rc.7.json +9 -0
  386. package/dist/migrations/manifests/0.5.0.json +9 -0
  387. package/dist/migrations/manifests/0.5.1.json +9 -0
  388. package/dist/migrations/manifests/0.5.10.json +9 -0
  389. package/dist/migrations/manifests/0.5.11.json +16 -0
  390. package/dist/migrations/manifests/0.5.12.json +9 -0
  391. package/dist/migrations/manifests/0.5.13.json +9 -0
  392. package/dist/migrations/manifests/0.5.14.json +9 -0
  393. package/dist/migrations/manifests/0.5.15.json +9 -0
  394. package/dist/migrations/manifests/0.5.16.json +9 -0
  395. package/dist/migrations/manifests/0.5.17.json +9 -0
  396. package/dist/migrations/manifests/0.5.18.json +9 -0
  397. package/dist/migrations/manifests/0.5.19.json +9 -0
  398. package/dist/migrations/manifests/0.5.2.json +9 -0
  399. package/dist/migrations/manifests/0.5.3.json +9 -0
  400. package/dist/migrations/manifests/0.5.4.json +9 -0
  401. package/dist/migrations/manifests/0.5.5.json +9 -0
  402. package/dist/migrations/manifests/0.5.6.json +9 -0
  403. package/dist/migrations/manifests/0.5.7.json +16 -0
  404. package/dist/migrations/manifests/0.5.8.json +9 -0
  405. package/dist/migrations/manifests/0.5.9.json +9 -0
  406. package/dist/migrations/manifests/0.6.0-beta.0.json +16 -0
  407. package/dist/migrations/manifests/0.6.0-beta.1.json +9 -0
  408. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  409. package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
  410. package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
  411. package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
  412. package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
  413. package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
  414. package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
  415. package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
  416. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  417. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  418. package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
  419. package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
  420. package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
  421. package/dist/migrations/manifests/0.6.0-beta.22.json +9 -0
  422. package/dist/migrations/manifests/0.6.0-beta.23.json +88 -0
  423. package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
  424. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  425. package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
  426. package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
  427. package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
  428. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  429. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  430. package/dist/migrations/manifests/0.6.0-rc.0.json +9 -0
  431. package/dist/migrations/manifests/0.6.0.json +1 -0
  432. package/dist/migrations/manifests/0.6.1.json +9 -0
  433. package/dist/migrations/manifests/0.6.10.json +9 -0
  434. package/dist/migrations/manifests/0.6.11.json +9 -0
  435. package/dist/migrations/manifests/0.6.12.json +9 -0
  436. package/dist/migrations/manifests/0.6.13.json +9 -0
  437. package/dist/migrations/manifests/0.6.14.json +9 -0
  438. package/dist/migrations/manifests/0.6.15.json +9 -0
  439. package/dist/migrations/manifests/0.6.16.json +9 -0
  440. package/dist/migrations/manifests/0.6.17.json +9 -0
  441. package/dist/migrations/manifests/0.6.2.json +9 -0
  442. package/dist/migrations/manifests/0.6.3.json +24 -0
  443. package/dist/migrations/manifests/0.6.4.json +9 -0
  444. package/dist/migrations/manifests/0.6.5.json +9 -0
  445. package/dist/migrations/manifests/0.6.6.json +17 -0
  446. package/dist/migrations/manifests/0.6.7.json +9 -0
  447. package/dist/migrations/manifests/0.6.8.json +17 -0
  448. package/dist/migrations/manifests/0.6.9.json +9 -0
  449. package/dist/migrations/manifests/0.7.0-beta.0.json +9 -0
  450. package/dist/migrations/manifests/0.7.0-beta.1.json +9 -0
  451. package/dist/migrations/manifests/0.7.0-beta.2.json +9 -0
  452. package/dist/migrations/manifests/0.7.0-beta.3.json +9 -0
  453. package/dist/templates/claude/agents/trellis-check.md +115 -0
  454. package/dist/templates/claude/agents/trellis-implement.md +110 -0
  455. package/dist/templates/claude/agents/trellis-research.md +137 -0
  456. package/dist/templates/claude/hooks/statusline.py +332 -0
  457. package/dist/templates/claude/index.d.ts +31 -0
  458. package/dist/templates/claude/index.d.ts.map +1 -0
  459. package/dist/templates/claude/index.js +57 -0
  460. package/dist/templates/claude/index.js.map +1 -0
  461. package/dist/templates/claude/settings.json +73 -0
  462. package/dist/templates/codebuddy/agents/trellis-check.md +115 -0
  463. package/dist/templates/codebuddy/agents/trellis-implement.md +110 -0
  464. package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
  465. package/dist/templates/codebuddy/index.d.ts +15 -0
  466. package/dist/templates/codebuddy/index.d.ts.map +1 -0
  467. package/dist/templates/codebuddy/index.js +15 -0
  468. package/dist/templates/codebuddy/index.js.map +1 -0
  469. package/dist/templates/codebuddy/settings.json +69 -0
  470. package/dist/templates/codex/agents/trellis-check.toml +56 -0
  471. package/dist/templates/codex/agents/trellis-implement.toml +37 -0
  472. package/dist/templates/codex/agents/trellis-research.toml +78 -0
  473. package/dist/templates/codex/config.toml +39 -0
  474. package/dist/templates/codex/hooks/session-start.py +552 -0
  475. package/dist/templates/codex/hooks.json +27 -0
  476. package/dist/templates/codex/index.d.ts +35 -0
  477. package/dist/templates/codex/index.d.ts.map +1 -0
  478. package/dist/templates/codex/index.js +67 -0
  479. package/dist/templates/codex/index.js.map +1 -0
  480. package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +67 -0
  481. package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +480 -0
  482. package/dist/templates/common/bundled-skills/trellis-channel/references/forum.md +233 -0
  483. package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +226 -0
  484. package/dist/templates/common/bundled-skills/trellis-channel/references/workers.md +276 -0
  485. package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +128 -0
  486. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +85 -0
  487. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
  488. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +56 -0
  489. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +84 -0
  490. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
  491. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +123 -0
  492. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
  493. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
  494. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +65 -0
  495. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
  496. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +159 -0
  497. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
  498. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
  499. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-channel.md +69 -0
  500. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
  501. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
  502. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +130 -0
  503. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
  504. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
  505. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +83 -0
  506. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +72 -0
  507. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
  508. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +112 -0
  509. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +86 -0
  510. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +81 -0
  511. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +65 -0
  512. package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +93 -0
  513. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/SKILL.md +41 -0
  514. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +90 -0
  515. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/repository-analysis.md +59 -0
  516. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +61 -0
  517. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-writing.md +70 -0
  518. package/dist/templates/common/commands/continue.md +56 -0
  519. package/dist/templates/common/commands/finish-work.md +66 -0
  520. package/dist/templates/common/commands/start.md +59 -0
  521. package/dist/templates/common/index.d.ts +48 -0
  522. package/dist/templates/common/index.d.ts.map +1 -0
  523. package/dist/templates/common/index.js +104 -0
  524. package/dist/templates/common/index.js.map +1 -0
  525. package/dist/templates/common/skills/before-dev.md +46 -0
  526. package/dist/templates/common/skills/brainstorm.md +195 -0
  527. package/dist/templates/common/skills/break-loop.md +184 -0
  528. package/dist/templates/common/skills/check.md +106 -0
  529. package/dist/templates/common/skills/update-spec.md +351 -0
  530. package/dist/templates/copilot/copilot-instructions.md +11 -0
  531. package/dist/templates/copilot/hooks/session-start.py +548 -0
  532. package/dist/templates/copilot/hooks.json +19 -0
  533. package/dist/templates/copilot/index.d.ts +28 -0
  534. package/dist/templates/copilot/index.d.ts.map +1 -0
  535. package/dist/templates/copilot/index.js +61 -0
  536. package/dist/templates/copilot/index.js.map +1 -0
  537. package/dist/templates/copilot/prompts/before-dev.prompt.md +39 -0
  538. package/dist/templates/copilot/prompts/brainstorm.prompt.md +156 -0
  539. package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
  540. package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +170 -0
  541. package/dist/templates/copilot/prompts/check.prompt.md +110 -0
  542. package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
  543. package/dist/templates/copilot/prompts/finish-work.prompt.md +99 -0
  544. package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
  545. package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
  546. package/dist/templates/copilot/prompts/parallel.prompt.md +204 -0
  547. package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
  548. package/dist/templates/copilot/prompts/start.prompt.md +63 -0
  549. package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
  550. package/dist/templates/cursor/agents/trellis-check.md +114 -0
  551. package/dist/templates/cursor/agents/trellis-implement.md +109 -0
  552. package/dist/templates/cursor/agents/trellis-research.md +136 -0
  553. package/dist/templates/cursor/hooks.json +24 -0
  554. package/dist/templates/cursor/index.d.ts +13 -0
  555. package/dist/templates/cursor/index.d.ts.map +1 -0
  556. package/dist/templates/cursor/index.js +13 -0
  557. package/dist/templates/cursor/index.js.map +1 -0
  558. package/dist/templates/droid/droids/trellis-check.md +107 -0
  559. package/dist/templates/droid/droids/trellis-implement.md +102 -0
  560. package/dist/templates/droid/droids/trellis-research.md +137 -0
  561. package/dist/templates/droid/index.d.ts +15 -0
  562. package/dist/templates/droid/index.d.ts.map +1 -0
  563. package/dist/templates/droid/index.js +15 -0
  564. package/dist/templates/droid/index.js.map +1 -0
  565. package/dist/templates/droid/settings.json +69 -0
  566. package/dist/templates/dsh/DSH.md +56 -0
  567. package/dist/templates/dsh/index.d.ts +21 -0
  568. package/dist/templates/dsh/index.d.ts.map +1 -0
  569. package/dist/templates/dsh/index.js +25 -0
  570. package/dist/templates/dsh/index.js.map +1 -0
  571. package/dist/templates/extract.d.ts +40 -0
  572. package/dist/templates/extract.d.ts.map +1 -0
  573. package/dist/templates/extract.js +106 -0
  574. package/dist/templates/extract.js.map +1 -0
  575. package/dist/templates/gemini/agents/trellis-check.md +107 -0
  576. package/dist/templates/gemini/agents/trellis-implement.md +102 -0
  577. package/dist/templates/gemini/agents/trellis-research.md +136 -0
  578. package/dist/templates/gemini/index.d.ts +13 -0
  579. package/dist/templates/gemini/index.d.ts.map +1 -0
  580. package/dist/templates/gemini/index.js +13 -0
  581. package/dist/templates/gemini/index.js.map +1 -0
  582. package/dist/templates/gemini/settings.json +40 -0
  583. package/dist/templates/grok/agents/trellis-check.md +105 -0
  584. package/dist/templates/grok/agents/trellis-implement.md +116 -0
  585. package/dist/templates/grok/agents/trellis-research.md +146 -0
  586. package/dist/templates/grok/index.d.ts +16 -0
  587. package/dist/templates/grok/index.d.ts.map +1 -0
  588. package/dist/templates/grok/index.js +19 -0
  589. package/dist/templates/grok/index.js.map +1 -0
  590. package/dist/templates/kimi/agents/trellis-check.md +103 -0
  591. package/dist/templates/kimi/agents/trellis-implement.md +115 -0
  592. package/dist/templates/kimi/agents/trellis-research.md +144 -0
  593. package/dist/templates/kimi/index.d.ts +20 -0
  594. package/dist/templates/kimi/index.d.ts.map +1 -0
  595. package/dist/templates/kimi/index.js +23 -0
  596. package/dist/templates/kimi/index.js.map +1 -0
  597. package/dist/templates/kiro/agents/trellis-check.json +26 -0
  598. package/dist/templates/kiro/agents/trellis-implement.json +26 -0
  599. package/dist/templates/kiro/agents/trellis-research.json +30 -0
  600. package/dist/templates/kiro/agents/trellis.json +34 -0
  601. package/dist/templates/kiro/hooks/trellis-workflow-state.kiro.hook +14 -0
  602. package/dist/templates/kiro/index.d.ts +32 -0
  603. package/dist/templates/kiro/index.d.ts.map +1 -0
  604. package/dist/templates/kiro/index.js +28 -0
  605. package/dist/templates/kiro/index.js.map +1 -0
  606. package/dist/templates/markdown/agents.md +21 -0
  607. package/dist/templates/markdown/gitignore.txt +15 -0
  608. package/dist/templates/markdown/index.d.ts +27 -0
  609. package/dist/templates/markdown/index.d.ts.map +1 -0
  610. package/dist/templates/markdown/index.js +52 -0
  611. package/dist/templates/markdown/index.js.map +1 -0
  612. package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
  613. package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
  614. package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
  615. package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
  616. package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
  617. package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
  618. package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
  619. package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
  620. package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
  621. package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
  622. package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
  623. package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
  624. package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
  625. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +223 -0
  626. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +327 -0
  627. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +633 -0
  628. package/dist/templates/markdown/spec/guides/index.md.txt +97 -0
  629. package/dist/templates/markdown/workspace-index.md +125 -0
  630. package/dist/templates/markdown/worktree.yaml.txt +58 -0
  631. package/dist/templates/omp/agents/trellis-check.md +41 -0
  632. package/dist/templates/omp/agents/trellis-implement.md +45 -0
  633. package/dist/templates/omp/agents/trellis-research.md +30 -0
  634. package/dist/templates/omp/extensions/trellis/index.ts.txt +1105 -0
  635. package/dist/templates/omp/index.d.ts +4 -0
  636. package/dist/templates/omp/index.d.ts.map +1 -0
  637. package/dist/templates/omp/index.js +9 -0
  638. package/dist/templates/omp/index.js.map +1 -0
  639. package/dist/templates/opencode/agents/trellis-check.md +122 -0
  640. package/dist/templates/opencode/agents/trellis-implement.md +118 -0
  641. package/dist/templates/opencode/agents/trellis-research.md +145 -0
  642. package/dist/templates/opencode/lib/context-visibility.js +148 -0
  643. package/dist/templates/opencode/lib/session-utils.js +527 -0
  644. package/dist/templates/opencode/lib/trellis-context.js +627 -0
  645. package/dist/templates/opencode/package.json +5 -0
  646. package/dist/templates/opencode/plugins/inject-subagent-context.js +569 -0
  647. package/dist/templates/opencode/plugins/inject-workflow-state.js +240 -0
  648. package/dist/templates/opencode/plugins/session-start.js +65 -0
  649. package/dist/templates/pi/agents/trellis-check.md +37 -0
  650. package/dist/templates/pi/agents/trellis-implement.md +42 -0
  651. package/dist/templates/pi/agents/trellis-research.md +25 -0
  652. package/dist/templates/pi/extensions/trellis/index.ts.txt +2027 -0
  653. package/dist/templates/pi/index.d.ts +5 -0
  654. package/dist/templates/pi/index.d.ts.map +1 -0
  655. package/dist/templates/pi/index.js +12 -0
  656. package/dist/templates/pi/index.js.map +1 -0
  657. package/dist/templates/pi/settings.json +9 -0
  658. package/dist/templates/qoder/agents/trellis-check.md +108 -0
  659. package/dist/templates/qoder/agents/trellis-implement.md +103 -0
  660. package/dist/templates/qoder/agents/trellis-research.md +137 -0
  661. package/dist/templates/qoder/index.d.ts +15 -0
  662. package/dist/templates/qoder/index.d.ts.map +1 -0
  663. package/dist/templates/qoder/index.js +15 -0
  664. package/dist/templates/qoder/index.js.map +1 -0
  665. package/dist/templates/qoder/settings.json +59 -0
  666. package/dist/templates/reasonix/agents/trellis-check.md +36 -0
  667. package/dist/templates/reasonix/agents/trellis-implement.md +41 -0
  668. package/dist/templates/reasonix/index.d.ts +13 -0
  669. package/dist/templates/reasonix/index.d.ts.map +1 -0
  670. package/dist/templates/reasonix/index.js +16 -0
  671. package/dist/templates/reasonix/index.js.map +1 -0
  672. package/dist/templates/shared-hooks/index.d.ts +77 -0
  673. package/dist/templates/shared-hooks/index.d.ts.map +1 -0
  674. package/dist/templates/shared-hooks/index.js +140 -0
  675. package/dist/templates/shared-hooks/index.js.map +1 -0
  676. package/dist/templates/shared-hooks/inject-shell-session-context.py +292 -0
  677. package/dist/templates/shared-hooks/inject-subagent-context.py +1212 -0
  678. package/dist/templates/shared-hooks/inject-workflow-state.py +488 -0
  679. package/dist/templates/shared-hooks/session-start.py +949 -0
  680. package/dist/templates/snow/SNOW.md +86 -0
  681. package/dist/templates/snow/agents/trellis-check.md +135 -0
  682. package/dist/templates/snow/agents/trellis-implement.md +153 -0
  683. package/dist/templates/snow/agents/trellis-research.md +114 -0
  684. package/dist/templates/snow/hooks/beforeSubAgentStart.json +15 -0
  685. package/dist/templates/snow/hooks/onSessionStart.json +15 -0
  686. package/dist/templates/snow/hooks/onUserMessage.json +15 -0
  687. package/dist/templates/snow/hooks/write-trellis-context.py +644 -0
  688. package/dist/templates/snow/index.d.ts +26 -0
  689. package/dist/templates/snow/index.d.ts.map +1 -0
  690. package/dist/templates/snow/index.js +36 -0
  691. package/dist/templates/snow/index.js.map +1 -0
  692. package/dist/templates/template-utils.d.ts +26 -0
  693. package/dist/templates/template-utils.d.ts.map +1 -0
  694. package/dist/templates/template-utils.js +64 -0
  695. package/dist/templates/template-utils.js.map +1 -0
  696. package/dist/templates/trae/agents/trellis-check.md +108 -0
  697. package/dist/templates/trae/agents/trellis-implement.md +103 -0
  698. package/dist/templates/trae/agents/trellis-research.md +137 -0
  699. package/dist/templates/trae/hooks.json +39 -0
  700. package/dist/templates/trae/index.d.ts +15 -0
  701. package/dist/templates/trae/index.d.ts.map +1 -0
  702. package/dist/templates/trae/index.js +15 -0
  703. package/dist/templates/trae/index.js.map +1 -0
  704. package/dist/templates/trellis/agents/check.md +70 -0
  705. package/dist/templates/trellis/agents/implement.md +71 -0
  706. package/dist/templates/trellis/config.yaml +158 -0
  707. package/dist/templates/trellis/gitattributes.txt +9 -0
  708. package/dist/templates/trellis/gitignore.txt +32 -0
  709. package/dist/templates/trellis/index.d.ts +67 -0
  710. package/dist/templates/trellis/index.d.ts.map +1 -0
  711. package/dist/templates/trellis/index.js +121 -0
  712. package/dist/templates/trellis/index.js.map +1 -0
  713. package/dist/templates/trellis/scripts/__init__.py +5 -0
  714. package/dist/templates/trellis/scripts/add_session.py +1545 -0
  715. package/dist/templates/trellis/scripts/common/__init__.py +94 -0
  716. package/dist/templates/trellis/scripts/common/active_task.py +857 -0
  717. package/dist/templates/trellis/scripts/common/cli_adapter.py +950 -0
  718. package/dist/templates/trellis/scripts/common/config.py +482 -0
  719. package/dist/templates/trellis/scripts/common/developer.py +192 -0
  720. package/dist/templates/trellis/scripts/common/git.py +203 -0
  721. package/dist/templates/trellis/scripts/common/git_context.py +106 -0
  722. package/dist/templates/trellis/scripts/common/io.py +160 -0
  723. package/dist/templates/trellis/scripts/common/log.py +45 -0
  724. package/dist/templates/trellis/scripts/common/packages_context.py +238 -0
  725. package/dist/templates/trellis/scripts/common/paths.py +543 -0
  726. package/dist/templates/trellis/scripts/common/safe_commit.py +322 -0
  727. package/dist/templates/trellis/scripts/common/session_context.py +892 -0
  728. package/dist/templates/trellis/scripts/common/task_context.py +470 -0
  729. package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
  730. package/dist/templates/trellis/scripts/common/task_store.py +1874 -0
  731. package/dist/templates/trellis/scripts/common/task_utils.py +498 -0
  732. package/dist/templates/trellis/scripts/common/tasks.py +122 -0
  733. package/dist/templates/trellis/scripts/common/trellis_config.py +239 -0
  734. package/dist/templates/trellis/scripts/common/types.py +110 -0
  735. package/dist/templates/trellis/scripts/common/workflow_phase.py +242 -0
  736. package/dist/templates/trellis/scripts/get_context.py +16 -0
  737. package/dist/templates/trellis/scripts/get_developer.py +26 -0
  738. package/dist/templates/trellis/scripts/hooks/linear_sync.py +243 -0
  739. package/dist/templates/trellis/scripts/init_developer.py +51 -0
  740. package/dist/templates/trellis/scripts/task.py +801 -0
  741. package/dist/templates/trellis/tasks/.gitkeep +0 -0
  742. package/dist/templates/trellis/workflow.md +721 -0
  743. package/dist/templates/zcode/agents/trellis-check.md +109 -0
  744. package/dist/templates/zcode/agents/trellis-implement.md +111 -0
  745. package/dist/templates/zcode/agents/trellis-research.md +133 -0
  746. package/dist/templates/zcode/config.json +52 -0
  747. package/dist/templates/zcode/index.d.ts +25 -0
  748. package/dist/templates/zcode/index.d.ts.map +1 -0
  749. package/dist/templates/zcode/index.js +29 -0
  750. package/dist/templates/zcode/index.js.map +1 -0
  751. package/dist/types/ai-tools.d.ts +105 -0
  752. package/dist/types/ai-tools.d.ts.map +1 -0
  753. package/dist/types/ai-tools.js +502 -0
  754. package/dist/types/ai-tools.js.map +1 -0
  755. package/dist/types/migration.d.ts +125 -0
  756. package/dist/types/migration.d.ts.map +1 -0
  757. package/dist/types/migration.js +8 -0
  758. package/dist/types/migration.js.map +1 -0
  759. package/dist/utils/ablation-store.d.ts +123 -0
  760. package/dist/utils/ablation-store.d.ts.map +1 -0
  761. package/dist/utils/ablation-store.js +749 -0
  762. package/dist/utils/ablation-store.js.map +1 -0
  763. package/dist/utils/agent-refs.d.ts +31 -0
  764. package/dist/utils/agent-refs.d.ts.map +1 -0
  765. package/dist/utils/agent-refs.js +63 -0
  766. package/dist/utils/agent-refs.js.map +1 -0
  767. package/dist/utils/atomic-write.d.ts +12 -0
  768. package/dist/utils/atomic-write.d.ts.map +1 -0
  769. package/dist/utils/atomic-write.js +30 -0
  770. package/dist/utils/atomic-write.js.map +1 -0
  771. package/dist/utils/compare-versions.d.ts +12 -0
  772. package/dist/utils/compare-versions.d.ts.map +1 -0
  773. package/dist/utils/compare-versions.js +86 -0
  774. package/dist/utils/compare-versions.js.map +1 -0
  775. package/dist/utils/cwd-guard.d.ts +38 -0
  776. package/dist/utils/cwd-guard.d.ts.map +1 -0
  777. package/dist/utils/cwd-guard.js +62 -0
  778. package/dist/utils/cwd-guard.js.map +1 -0
  779. package/dist/utils/file-writer.d.ts +36 -0
  780. package/dist/utils/file-writer.d.ts.map +1 -0
  781. package/dist/utils/file-writer.js +204 -0
  782. package/dist/utils/file-writer.js.map +1 -0
  783. package/dist/utils/managed-paths.d.ts +5 -0
  784. package/dist/utils/managed-paths.d.ts.map +1 -0
  785. package/dist/utils/managed-paths.js +51 -0
  786. package/dist/utils/managed-paths.js.map +1 -0
  787. package/dist/utils/managed-removal.d.ts +74 -0
  788. package/dist/utils/managed-removal.d.ts.map +1 -0
  789. package/dist/utils/managed-removal.js +270 -0
  790. package/dist/utils/managed-removal.js.map +1 -0
  791. package/dist/utils/manifest-prune.d.ts +61 -0
  792. package/dist/utils/manifest-prune.d.ts.map +1 -0
  793. package/dist/utils/manifest-prune.js +135 -0
  794. package/dist/utils/manifest-prune.js.map +1 -0
  795. package/dist/utils/posix.d.ts +13 -0
  796. package/dist/utils/posix.d.ts.map +1 -0
  797. package/dist/utils/posix.js +15 -0
  798. package/dist/utils/posix.js.map +1 -0
  799. package/dist/utils/project-detector.d.ts +46 -0
  800. package/dist/utils/project-detector.d.ts.map +1 -0
  801. package/dist/utils/project-detector.js +666 -0
  802. package/dist/utils/project-detector.js.map +1 -0
  803. package/dist/utils/proxy.d.ts +25 -0
  804. package/dist/utils/proxy.d.ts.map +1 -0
  805. package/dist/utils/proxy.js +60 -0
  806. package/dist/utils/proxy.js.map +1 -0
  807. package/dist/utils/registry-config.d.ts +7 -0
  808. package/dist/utils/registry-config.d.ts.map +1 -0
  809. package/dist/utils/registry-config.js +172 -0
  810. package/dist/utils/registry-config.js.map +1 -0
  811. package/dist/utils/task-json.d.ts +13 -0
  812. package/dist/utils/task-json.d.ts.map +1 -0
  813. package/dist/utils/task-json.js +12 -0
  814. package/dist/utils/task-json.js.map +1 -0
  815. package/dist/utils/template-fetcher.d.ts +161 -0
  816. package/dist/utils/template-fetcher.d.ts.map +1 -0
  817. package/dist/utils/template-fetcher.js +994 -0
  818. package/dist/utils/template-fetcher.js.map +1 -0
  819. package/dist/utils/template-hash.d.ts +127 -0
  820. package/dist/utils/template-hash.d.ts.map +1 -0
  821. package/dist/utils/template-hash.js +335 -0
  822. package/dist/utils/template-hash.js.map +1 -0
  823. package/dist/utils/uninstall-scrubbers.d.ts +66 -0
  824. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
  825. package/dist/utils/uninstall-scrubbers.js +417 -0
  826. package/dist/utils/uninstall-scrubbers.js.map +1 -0
  827. package/dist/utils/workflow-resolver.d.ts +86 -0
  828. package/dist/utils/workflow-resolver.d.ts.map +1 -0
  829. package/dist/utils/workflow-resolver.js +265 -0
  830. package/dist/utils/workflow-resolver.js.map +1 -0
  831. package/package.json +89 -0
@@ -0,0 +1,1212 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Multi-Platform Sub-Agent Context Injection Hook
5
+
6
+ Injects task-specific context when sub-agents (implement, check, research) are spawned.
7
+
8
+ Core Design Philosophy:
9
+ - Hook is responsible for injecting all context, subagent works autonomously with complete info
10
+ - Each agent has a dedicated jsonl file defining its context
11
+ - No resume needed, no segmentation, behavior controlled by code not prompt
12
+
13
+ Trigger: PreToolUse (before Task tool call)
14
+
15
+ Context Source: Trellis active task resolver points to task directory
16
+ - implement.jsonl - Implement agent dedicated context
17
+ - check.jsonl - Check agent dedicated context
18
+ - prd.md - Requirements document
19
+ - design.md - Technical design for complex tasks
20
+ - implement.md - Execution plan for complex tasks
21
+ - codex-review-output.txt - Code Review results
22
+ """
23
+ from __future__ import annotations
24
+
25
+ # IMPORTANT: Suppress all warnings FIRST
26
+ import warnings
27
+ warnings.filterwarnings("ignore")
28
+
29
+ import json
30
+ import os
31
+ import sys
32
+ from pathlib import Path
33
+ from typing import Any
34
+
35
+ # Hook hosts send UTF-8 JSON regardless of the process locale.
36
+ _stdin_reconfigure = getattr(sys.stdin, "reconfigure", None)
37
+ if callable(_stdin_reconfigure):
38
+ try:
39
+ _stdin_reconfigure(encoding="utf-8", errors="replace")
40
+ except (OSError, ValueError):
41
+ pass
42
+
43
+ # IMPORTANT: Force stdout to use UTF-8 on Windows
44
+ # This fixes UnicodeEncodeError when outputting non-ASCII characters
45
+ if sys.platform.startswith("win"):
46
+ import io as _io
47
+ if hasattr(sys.stdout, "reconfigure"):
48
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace") # type: ignore[union-attr]
49
+ elif hasattr(sys.stdout, "detach"):
50
+ sys.stdout = _io.TextIOWrapper(sys.stdout.detach(), encoding="utf-8", errors="replace") # type: ignore[union-attr]
51
+
52
+
53
+ # =============================================================================
54
+ # Path Constants (change here to rename directories)
55
+ # =============================================================================
56
+
57
+ DIR_WORKFLOW = ".trellis"
58
+ DIR_SPEC = "spec"
59
+ FILE_TASK_JSON = "task.json"
60
+
61
+ # =============================================================================
62
+ # Subagent Constants (change here to rename subagent types)
63
+ # =============================================================================
64
+
65
+ AGENT_IMPLEMENT = "trellis-implement"
66
+ AGENT_CHECK = "trellis-check"
67
+ AGENT_RESEARCH = "trellis-research"
68
+
69
+ # Agents that require a task directory
70
+ AGENTS_REQUIRE_TASK = (AGENT_IMPLEMENT, AGENT_CHECK)
71
+ # All supported agents
72
+ AGENTS_ALL = (AGENT_IMPLEMENT, AGENT_CHECK, AGENT_RESEARCH)
73
+
74
+
75
+ def find_repo_root(start_path: str) -> str | None:
76
+ """
77
+ Find git repo root from start_path upwards
78
+
79
+ Returns:
80
+ Repo root path, or None if not found
81
+ """
82
+ current = Path(start_path).resolve()
83
+ while current != current.parent:
84
+ if (current / ".git").exists():
85
+ return str(current)
86
+ current = current.parent
87
+ return None
88
+
89
+
90
+ def _detect_platform(input_data: dict) -> str | None:
91
+ if _hook_event_name(input_data) == "SubagentStart":
92
+ return "codex"
93
+ if isinstance(input_data.get("cursor_version"), str):
94
+ return "cursor"
95
+ # CLAUDE_PROJECT_DIR is a compatibility alias that several hosts set
96
+ # alongside their own variable — CodeBuddy, ZCode and Trae all do. It must
97
+ # therefore be checked LAST, or every one of them is detected as claude and
98
+ # the context key becomes `claude_<their-session-id>`. That key does not
99
+ # match the session file `task.py start` wrote under the host's real name,
100
+ # so the sub-agent starts with no task context while the pointer exists on
101
+ # disk. Same fix as inject-workflow-state.py and session-start.py; this
102
+ # third copy was missed when those two were corrected.
103
+ env_map = {
104
+ "ZCODE_PROJECT_DIR": "zcode",
105
+ "CURSOR_PROJECT_DIR": "cursor",
106
+ "CODEBUDDY_PROJECT_DIR": "codebuddy",
107
+ "FACTORY_PROJECT_DIR": "droid",
108
+ "GEMINI_PROJECT_DIR": "gemini",
109
+ "QODER_PROJECT_DIR": "qoder",
110
+ "KIRO_PROJECT_DIR": "kiro",
111
+ "COPILOT_PROJECT_DIR": "copilot",
112
+ "TRAE_PROJECT_DIR": "trae",
113
+ # Last: the shared alias, only meaningful once no vendor key matched.
114
+ "CLAUDE_PROJECT_DIR": "claude",
115
+ }
116
+ for env_name, platform in env_map.items():
117
+ if os.environ.get(env_name):
118
+ return platform
119
+ script_parts = set(Path(sys.argv[0]).parts)
120
+ if ".claude" in script_parts:
121
+ return "claude"
122
+ if ".cursor" in script_parts:
123
+ return "cursor"
124
+ if ".gemini" in script_parts:
125
+ return "gemini"
126
+ if ".qoder" in script_parts:
127
+ return "qoder"
128
+ if ".codebuddy" in script_parts:
129
+ return "codebuddy"
130
+ if ".factory" in script_parts:
131
+ return "droid"
132
+ if ".kiro" in script_parts:
133
+ return "kiro"
134
+ if ".zcode" in script_parts:
135
+ return "zcode"
136
+ return None
137
+
138
+
139
+ def get_current_task(
140
+ repo_root: str,
141
+ input_data: dict,
142
+ *,
143
+ platform: str | None = None,
144
+ allow_single_session_fallback: bool = True,
145
+ allow_environment_context: bool = True,
146
+ require_existing: bool = False,
147
+ ) -> str | None:
148
+ """Resolve current task directory through the unified active task resolver."""
149
+ scripts_dir = Path(repo_root) / DIR_WORKFLOW / "scripts"
150
+ if str(scripts_dir) not in sys.path:
151
+ sys.path.insert(0, str(scripts_dir))
152
+ try:
153
+ from common.active_task import resolve_active_task # type: ignore[import-not-found]
154
+ except Exception:
155
+ return None
156
+
157
+ active = resolve_active_task(
158
+ Path(repo_root),
159
+ input_data,
160
+ platform=platform or _detect_platform(input_data),
161
+ allow_single_session_fallback=allow_single_session_fallback,
162
+ allow_environment_context=allow_environment_context,
163
+ )
164
+ if require_existing and active.stale:
165
+ return None
166
+ return active.task_path
167
+
168
+
169
+ # =============================================================================
170
+ # Context Injection Limits (issue #441)
171
+ #
172
+ # Notice text and behavior mirrored byte-for-byte in the Pi TS extension
173
+ # (templates/pi/extensions/trellis/index.ts.txt). Changing wording here
174
+ # requires changing it there too.
175
+ # =============================================================================
176
+
177
+ DEFAULT_MAX_FILE_BYTES = 32768
178
+ DEFAULT_MAX_ARTIFACT_BYTES = 65536
179
+ DEFAULT_MAX_TOTAL_BYTES = 131072
180
+
181
+ DEFAULT_LIMITS: dict[str, int] = {
182
+ "max_file_bytes": DEFAULT_MAX_FILE_BYTES,
183
+ "max_artifact_bytes": DEFAULT_MAX_ARTIFACT_BYTES,
184
+ "max_total_bytes": DEFAULT_MAX_TOTAL_BYTES,
185
+ }
186
+
187
+
188
+ def _get_limits(repo_root: str) -> dict[str, int]:
189
+ """Load context-injection byte limits from config.yaml, with safe fallback."""
190
+ scripts_dir = Path(repo_root) / DIR_WORKFLOW / "scripts"
191
+ if str(scripts_dir) not in sys.path:
192
+ sys.path.insert(0, str(scripts_dir))
193
+ try:
194
+ from common.config import get_context_injection_limits # type: ignore[import-not-found]
195
+
196
+ return get_context_injection_limits(Path(repo_root))
197
+ except Exception:
198
+ return dict(DEFAULT_LIMITS)
199
+
200
+
201
+ def truncate_utf8(data: bytes, cap: int) -> bytes:
202
+ """Truncate ``data`` to at most ``cap`` bytes without splitting a UTF-8
203
+ multi-byte sequence.
204
+
205
+ ``cap <= 0`` means "no limit" — returns ``data`` unchanged.
206
+ """
207
+ if cap <= 0 or len(data) <= cap:
208
+ return data
209
+
210
+ truncated = data[:cap]
211
+ i = len(truncated)
212
+ # Back off over continuation bytes (10xxxxxx) to find the lead byte.
213
+ while i > 0 and (truncated[i - 1] & 0xC0) == 0x80:
214
+ i -= 1
215
+ if i == 0:
216
+ return b""
217
+
218
+ lead = truncated[i - 1]
219
+ if lead & 0x80:
220
+ if (lead & 0xE0) == 0xC0:
221
+ seq_len = 2
222
+ elif (lead & 0xF0) == 0xE0:
223
+ seq_len = 3
224
+ elif (lead & 0xF8) == 0xF0:
225
+ seq_len = 4
226
+ else:
227
+ seq_len = 1
228
+ # Drop the lead byte too if its full sequence didn't fit.
229
+ if (i - 1) + seq_len > len(truncated):
230
+ i -= 1
231
+
232
+ return truncated[:i]
233
+
234
+
235
+ class _Budget:
236
+ """Tracks the running total of bytes emitted into the sub-agent context."""
237
+
238
+ def __init__(self, max_total_bytes: int) -> None:
239
+ self.max_total_bytes = max_total_bytes
240
+ self.used = 0
241
+
242
+ def has_room(self, size: int) -> bool:
243
+ if self.max_total_bytes <= 0:
244
+ return True
245
+ return self.used + size <= self.max_total_bytes
246
+
247
+ def add(self, size: int) -> None:
248
+ self.used += size
249
+
250
+
251
+ def _real_path_contained(base_real: str, target_real: str) -> bool:
252
+ """Whether an already-realpath'd target sits under an already-realpath'd base.
253
+
254
+ ValueError on Windows when the two sit on different drives; that is
255
+ outside the base by definition, so it fails closed.
256
+ """
257
+ try:
258
+ return os.path.commonpath([base_real, target_real]) == base_real
259
+ except ValueError:
260
+ return False
261
+
262
+
263
+ def _read_file_bytes(base_path: str, file_path: str) -> bytes | None:
264
+ """Read raw file bytes, return None if file doesn't exist."""
265
+ full_path = os.path.join(base_path, file_path)
266
+ try:
267
+ root_real = os.path.realpath(base_path)
268
+ # `.trellis` may itself be a symlink into a store outside the repo
269
+ # (#567); its real location is a second legitimate containment base.
270
+ workflow_real = os.path.realpath(os.path.join(base_path, ".trellis"))
271
+ full_real = os.path.realpath(full_path)
272
+ if not _real_path_contained(root_real, full_real) and not (
273
+ _real_path_contained(workflow_real, full_real)
274
+ ):
275
+ return None
276
+ except OSError:
277
+ return None
278
+ if os.path.exists(full_path) and os.path.isfile(full_path):
279
+ try:
280
+ with open(full_path, "rb") as f:
281
+ return f.read()
282
+ except Exception:
283
+ return None
284
+ return None
285
+
286
+
287
+ def _truncate_notice(path: str, cap: int) -> str:
288
+ return f"\n[Trellis: truncated at {cap} bytes — read {path} for the full content]"
289
+
290
+
291
+ def _is_binary_content(data: bytes) -> bool:
292
+ """Return True when raw bytes should not be decoded into model context."""
293
+ if b"\x00" in data:
294
+ return True
295
+ try:
296
+ data.decode("utf-8", errors="strict")
297
+ except UnicodeDecodeError:
298
+ return True
299
+ return False
300
+
301
+
302
+ def _binary_notice(path: str, size: int, reason: str) -> str:
303
+ return (
304
+ f"[Trellis: not inlined (binary file) — "
305
+ f"{path} ({size} bytes): {reason}]"
306
+ )
307
+
308
+
309
+ def _index_notice(path: str, size: int, reason: str) -> str:
310
+ return (
311
+ f"[Trellis: not inlined (total context limit reached) — "
312
+ f"{path} ({size} bytes): {reason}]"
313
+ )
314
+
315
+
316
+ def _budgeted_block(
317
+ budget: _Budget,
318
+ header: str,
319
+ plain_path: str,
320
+ content: str,
321
+ reason: str,
322
+ size_for_index: int,
323
+ ) -> str:
324
+ """Return an inlined ``=== header ===`` block, or degrade to an index
325
+ notice once the total context budget is exhausted."""
326
+ block = f"=== {header} ===\n{content}"
327
+ block_bytes = len(block.encode("utf-8"))
328
+ if not budget.has_room(block_bytes):
329
+ notice = _index_notice(plain_path, size_for_index, reason)
330
+ budget.add(len(notice.encode("utf-8")))
331
+ return notice
332
+ budget.add(block_bytes)
333
+ return block
334
+
335
+
336
+ def _materialize_file(
337
+ base_path: str,
338
+ file_path: str,
339
+ reason: str,
340
+ limits: dict[str, int],
341
+ budget: _Budget,
342
+ ) -> str | None:
343
+ """Read a JSONL-referenced file, apply the per-file cap, then budget it."""
344
+ data = _read_file_bytes(base_path, file_path)
345
+ if data is None:
346
+ return None
347
+
348
+ size = len(data)
349
+ if _is_binary_content(data):
350
+ notice = _binary_notice(file_path, size, reason)
351
+ budget.add(len(notice.encode("utf-8")))
352
+ return notice
353
+
354
+ cap = limits["max_file_bytes"]
355
+ truncated_bytes = truncate_utf8(data, cap)
356
+ content = truncated_bytes.decode("utf-8", errors="replace")
357
+ if len(truncated_bytes) < size:
358
+ content += _truncate_notice(file_path, cap)
359
+
360
+ return _budgeted_block(budget, file_path, file_path, content, reason, size)
361
+
362
+
363
+ def _materialize_directory(
364
+ base_path: str,
365
+ dir_path: str,
366
+ reason: str,
367
+ limits: dict[str, int],
368
+ budget: _Budget,
369
+ max_files: int = 20,
370
+ ) -> list[str]:
371
+ """Read all .md files in a directory, applying the same per-file and
372
+ total caps as a single-file JSONL entry."""
373
+ full_path = os.path.join(base_path, dir_path)
374
+ if not os.path.exists(full_path) or not os.path.isdir(full_path):
375
+ return []
376
+
377
+ blocks: list[str] = []
378
+ try:
379
+ md_files = sorted(
380
+ f
381
+ for f in os.listdir(full_path)
382
+ if f.endswith(".md") and os.path.isfile(os.path.join(full_path, f))
383
+ )
384
+ for filename in md_files[:max_files]:
385
+ relative_path = os.path.join(dir_path, filename)
386
+ block = _materialize_file(base_path, relative_path, reason, limits, budget)
387
+ if block:
388
+ blocks.append(block)
389
+ except Exception:
390
+ pass
391
+
392
+ return blocks
393
+
394
+
395
+ def read_jsonl_entries(base_path: str, jsonl_path: str) -> list[dict]:
396
+ """
397
+ Parse all file/directory entries referenced in a jsonl context file.
398
+
399
+ Schema:
400
+ {"file": "path/to/file.md", "reason": "..."}
401
+ {"file": "path/to/dir/", "type": "directory", "reason": "..."}
402
+ {"_example": "..."} # legacy placeholder — skipped (no `file` field)
403
+
404
+ Rows without a ``file`` field (e.g. the placeholder line older Trellis
405
+ versions wrote at ``task.py create`` time) are skipped silently. If the
406
+ resulting entry list is empty, a stderr warning is emitted so the operator
407
+ can debug missing context.
408
+
409
+ Returns:
410
+ [{"file": path, "type": "file" | "directory", "reason": reason}, ...]
411
+ """
412
+ full_path = os.path.join(base_path, jsonl_path)
413
+ if not os.path.exists(full_path):
414
+ print(
415
+ f"[inject-subagent-context] WARN: {jsonl_path} not found — "
416
+ f"sub-agent will receive only task artifacts",
417
+ file=sys.stderr,
418
+ )
419
+ return []
420
+
421
+ entries: list[dict] = []
422
+ saw_real_entry = False
423
+ try:
424
+ with open(full_path, "r", encoding="utf-8") as f:
425
+ for line in f:
426
+ line = line.strip()
427
+ if not line:
428
+ continue
429
+ try:
430
+ item = json.loads(line)
431
+ file_path = item.get("file") or item.get("path")
432
+
433
+ if not file_path:
434
+ # Seed / comment row — skip silently
435
+ continue
436
+
437
+ saw_real_entry = True
438
+ entries.append(
439
+ {
440
+ "file": file_path,
441
+ "type": item.get("type", "file"),
442
+ "reason": item.get("reason") or "-",
443
+ }
444
+ )
445
+ except json.JSONDecodeError:
446
+ continue
447
+ except Exception:
448
+ pass
449
+
450
+ if not saw_real_entry:
451
+ print(
452
+ f"[inject-subagent-context] WARN: {jsonl_path} has no curated "
453
+ f"entries (only seed / empty) — sub-agent will receive only "
454
+ f"task artifacts. See workflow.md planning artifact guidance.",
455
+ file=sys.stderr,
456
+ )
457
+
458
+ return entries
459
+
460
+
461
+ def _materialize_jsonl_entries(
462
+ base_path: str, jsonl_path: str, limits: dict[str, int], budget: _Budget
463
+ ) -> list[str]:
464
+ """Materialize every entry in a jsonl context file into context blocks,
465
+ applying per-file and total budget caps."""
466
+ blocks: list[str] = []
467
+ for entry in read_jsonl_entries(base_path, jsonl_path):
468
+ if entry["type"] == "directory":
469
+ blocks.extend(
470
+ _materialize_directory(
471
+ base_path, entry["file"], entry["reason"], limits, budget
472
+ )
473
+ )
474
+ else:
475
+ block = _materialize_file(
476
+ base_path, entry["file"], entry["reason"], limits, budget
477
+ )
478
+ if block:
479
+ blocks.append(block)
480
+ return blocks
481
+
482
+
483
+ def get_agent_context(
484
+ repo_root: str,
485
+ task_dir: str,
486
+ agent_type: str,
487
+ limits: dict[str, int],
488
+ budget: _Budget,
489
+ ) -> str:
490
+ """
491
+ Get context from {agent_type}.jsonl for the specified agent.
492
+ Only reads implement.jsonl or check.jsonl (the two JSONL files the task system creates).
493
+ """
494
+ agent_jsonl = f"{task_dir}/{agent_type}.jsonl"
495
+ blocks = _materialize_jsonl_entries(repo_root, agent_jsonl, limits, budget)
496
+ if not blocks:
497
+ # Zero curated context reaches the model silently otherwise — the
498
+ # stderr WARN above never enters any session (#573). Put the fact in
499
+ # the prompt itself so the sub-agent compensates instead of assuming
500
+ # the spec context was complete.
501
+ return (
502
+ f"[Trellis] {agent_jsonl} has no curated entries, so no spec/research "
503
+ "context was injected. Before working, read the guidelines relevant "
504
+ "to the code you will touch under .trellis/spec/, and treat the task "
505
+ "artifacts below as the only prepared context."
506
+ )
507
+ return "\n\n".join(blocks)
508
+
509
+
510
+ def _materialize_artifact(
511
+ base_path: str,
512
+ file_path: str,
513
+ header_label: str,
514
+ reason: str,
515
+ limits: dict[str, int],
516
+ budget: _Budget,
517
+ ) -> str | None:
518
+ """Read a task artifact (prd/design/implement.md), apply the per-artifact
519
+ cap, then budget it."""
520
+ data = _read_file_bytes(base_path, file_path)
521
+ if data is None:
522
+ return None
523
+
524
+ size = len(data)
525
+ cap = limits["max_artifact_bytes"]
526
+ truncated_bytes = truncate_utf8(data, cap)
527
+ content = truncated_bytes.decode("utf-8", errors="replace")
528
+ if len(truncated_bytes) < size:
529
+ content += _truncate_notice(file_path, cap)
530
+
531
+ return _budgeted_block(budget, header_label, file_path, content, reason, size)
532
+
533
+
534
+ def get_implement_context(repo_root: str, task_dir: str) -> str:
535
+ """
536
+ Complete context for Implement Agent
537
+
538
+ Read order:
539
+ 1. All files in implement.jsonl (spec/research manifests)
540
+ 2. prd.md (requirements)
541
+ 3. design.md if present (technical design)
542
+ 4. implement.md if present (execution plan)
543
+ """
544
+ limits = _get_limits(repo_root)
545
+ budget = _Budget(limits["max_total_bytes"])
546
+ context_parts = []
547
+
548
+ # 1. Read implement.jsonl
549
+ base_context = get_agent_context(repo_root, task_dir, "implement", limits, budget)
550
+ if base_context:
551
+ context_parts.append(base_context)
552
+
553
+ # 2. Requirements document
554
+ prd_block = _materialize_artifact(
555
+ repo_root,
556
+ f"{task_dir}/prd.md",
557
+ f"{task_dir}/prd.md (Requirements)",
558
+ "Requirements document",
559
+ limits,
560
+ budget,
561
+ )
562
+ if prd_block:
563
+ context_parts.append(prd_block)
564
+
565
+ # 3. Technical design for complex tasks
566
+ design_block = _materialize_artifact(
567
+ repo_root,
568
+ f"{task_dir}/design.md",
569
+ f"{task_dir}/design.md (Technical Design)",
570
+ "Technical design document",
571
+ limits,
572
+ budget,
573
+ )
574
+ if design_block:
575
+ context_parts.append(design_block)
576
+
577
+ # 4. Execution plan for complex tasks
578
+ implement_plan_block = _materialize_artifact(
579
+ repo_root,
580
+ f"{task_dir}/implement.md",
581
+ f"{task_dir}/implement.md (Execution Plan)",
582
+ "Execution plan document",
583
+ limits,
584
+ budget,
585
+ )
586
+ if implement_plan_block:
587
+ context_parts.append(implement_plan_block)
588
+
589
+ return "\n\n".join(context_parts)
590
+
591
+
592
+ def get_check_context(repo_root: str, task_dir: str) -> str:
593
+ """
594
+ Context for Check Agent: check.jsonl + task artifacts.
595
+ """
596
+ limits = _get_limits(repo_root)
597
+ budget = _Budget(limits["max_total_bytes"])
598
+ context_parts = []
599
+
600
+ base_context = get_agent_context(repo_root, task_dir, "check", limits, budget)
601
+ if base_context:
602
+ context_parts.append(base_context)
603
+
604
+ prd_block = _materialize_artifact(
605
+ repo_root,
606
+ f"{task_dir}/prd.md",
607
+ f"{task_dir}/prd.md (Requirements)",
608
+ "Requirements document",
609
+ limits,
610
+ budget,
611
+ )
612
+ if prd_block:
613
+ context_parts.append(prd_block)
614
+
615
+ design_block = _materialize_artifact(
616
+ repo_root,
617
+ f"{task_dir}/design.md",
618
+ f"{task_dir}/design.md (Technical Design)",
619
+ "Technical design document",
620
+ limits,
621
+ budget,
622
+ )
623
+ if design_block:
624
+ context_parts.append(design_block)
625
+
626
+ implement_plan_block = _materialize_artifact(
627
+ repo_root,
628
+ f"{task_dir}/implement.md",
629
+ f"{task_dir}/implement.md (Execution Plan)",
630
+ "Execution plan document",
631
+ limits,
632
+ budget,
633
+ )
634
+ if implement_plan_block:
635
+ context_parts.append(implement_plan_block)
636
+
637
+ return "\n\n".join(context_parts)
638
+
639
+
640
+ def get_finish_context(repo_root: str, task_dir: str) -> str:
641
+ """
642
+ Context for Finish phase: reuses check.jsonl + prd.md
643
+ (Finish is a final check, same context source.)
644
+ """
645
+ return get_check_context(repo_root, task_dir)
646
+
647
+
648
+
649
+ def build_implement_prompt(original_prompt: str, context: str) -> str:
650
+ """Build complete prompt for Implement"""
651
+ return f"""<!-- trellis-hook-injected -->
652
+ # Implement Agent Task
653
+
654
+ You are the Implement Agent in the Multi-Agent Pipeline.
655
+
656
+ ## Your Context
657
+
658
+ All the information you need has been prepared for you:
659
+
660
+ {context}
661
+
662
+ ---
663
+
664
+ ## Your Task
665
+
666
+ {original_prompt}
667
+
668
+ ---
669
+
670
+ ## Workflow
671
+
672
+ 1. **Understand specs** - All dev specs are injected above, understand them
673
+ 2. **Understand task artifacts** - Read requirements, technical design if present, and execution plan if present
674
+ 3. **Implement feature** - Implement following specs and task artifacts
675
+ 4. **Self-check** - Ensure code quality against check specs
676
+
677
+ ## Important Constraints
678
+
679
+ - Do NOT execute git commit, only code modifications
680
+ - Follow all dev specs injected above
681
+ - Report list of modified/created files when done"""
682
+
683
+
684
+ def build_check_prompt(original_prompt: str, context: str) -> str:
685
+ """Build complete prompt for Check"""
686
+ return f"""<!-- trellis-hook-injected -->
687
+ # Check Agent Task
688
+
689
+ You are the Check Agent in the Multi-Agent Pipeline (code and cross-layer checker).
690
+
691
+ ## Your Context
692
+
693
+ All check specs and dev specs you need:
694
+
695
+ {context}
696
+
697
+ ---
698
+
699
+ ## Your Task
700
+
701
+ {original_prompt}
702
+
703
+ ---
704
+
705
+ ## Workflow
706
+
707
+ 1. **Get changes** - Run `git diff --name-only` and `git diff` to get code changes
708
+ 2. **Check against specs** - Check item by item against specs above
709
+ 3. **Self-fix** - Fix issues directly, don't just report
710
+ 4. **Run verification** - Run project's lint and typecheck commands
711
+
712
+ ## Important Constraints
713
+
714
+ - Fix issues yourself, don't just report
715
+ - Must execute complete checklist in check specs
716
+ - Pay special attention to impact radius analysis (L1-L5)"""
717
+
718
+
719
+ def build_finish_prompt(original_prompt: str, context: str) -> str:
720
+ """Build complete prompt for Finish (final check before PR)"""
721
+ return f"""<!-- trellis-hook-injected -->
722
+ # Finish Agent Task
723
+
724
+ You are performing the final check before creating a PR.
725
+
726
+ ## Your Context
727
+
728
+ Finish checklist and requirements:
729
+
730
+ {context}
731
+
732
+ ---
733
+
734
+ ## Your Task
735
+
736
+ {original_prompt}
737
+
738
+ ---
739
+
740
+ ## Workflow
741
+
742
+ 1. **Review changes** - Run `git diff --name-only` to see all changed files
743
+ 2. **Verify task artifacts** - Check requirements in prd.md and, when present, design.md / implement.md
744
+ 3. **Spec sync** - Analyze whether changes introduce new patterns, contracts, or conventions
745
+ - If new pattern/convention found: read target spec file → update it → update index.md if needed
746
+ - If infra/cross-layer change: follow the 7-section mandatory template from update-spec.md
747
+ - If pure code fix with no new patterns: skip this step
748
+ 4. **Run final checks** - Execute lint and typecheck
749
+ 5. **Confirm ready** - Ensure code is ready for PR
750
+
751
+ ## Important Constraints
752
+
753
+ - You MAY update spec files when gaps are detected (use update-spec.md as guide)
754
+ - MUST read the target spec file BEFORE editing (avoid duplicating existing content)
755
+ - Do NOT update specs for trivial changes (typos, formatting, obvious fixes)
756
+ - If critical CODE issues found, report them clearly (fix specs, not code)
757
+ - Verify all acceptance criteria in prd.md are met
758
+ - Verify design.md and implement.md constraints when those files are present"""
759
+
760
+
761
+
762
+ def get_research_context(repo_root: str, task_dir: str | None) -> str:
763
+ """
764
+ Context for Research Agent — project structure overview for spec directories.
765
+
766
+ `task_dir` kept for signature parity with get_implement_context / get_check_context
767
+ so the dispatcher can call them uniformly.
768
+ """
769
+ _ = task_dir
770
+ context_parts = []
771
+
772
+ # 1. Project structure overview (dynamically discover spec directories)
773
+ spec_path = f"{DIR_WORKFLOW}/{DIR_SPEC}"
774
+ spec_root = Path(repo_root) / DIR_WORKFLOW / DIR_SPEC
775
+
776
+ # Build spec tree dynamically
777
+ tree_lines = [f"{spec_path}/"]
778
+ if spec_root.is_dir():
779
+ pkg_dirs = sorted(d for d in spec_root.iterdir() if d.is_dir())
780
+ for i, pkg_dir in enumerate(pkg_dirs):
781
+ is_last = i == len(pkg_dirs) - 1
782
+ prefix = "└── " if is_last else "├── "
783
+ layers = sorted(d.name for d in pkg_dir.iterdir() if d.is_dir())
784
+ layer_info = f" ({', '.join(layers)})" if layers else ""
785
+ tree_lines.append(f"{prefix}{pkg_dir.name}/{layer_info}")
786
+
787
+ spec_tree = "\n".join(tree_lines)
788
+
789
+ project_structure = f"""## Project Spec Directory Structure
790
+
791
+ ```
792
+ {spec_tree}
793
+ ```
794
+
795
+ To get structured package info, run: `python3 ./{DIR_WORKFLOW}/scripts/get_context.py --mode packages`
796
+
797
+ ## Search Tips
798
+
799
+ - Spec files: `{spec_path}/**/*.md`
800
+ - Code search: Use Glob and Grep tools
801
+ - Tech solutions: Use mcp__exa__web_search_exa or mcp__exa__get_code_context_exa"""
802
+
803
+ context_parts.append(project_structure)
804
+
805
+ return "\n\n".join(context_parts)
806
+
807
+
808
+ def build_research_prompt(original_prompt: str, context: str) -> str:
809
+ """Build complete prompt for Research"""
810
+ return f"""# Research Agent Task
811
+
812
+ You are the Research Agent in the Multi-Agent Pipeline (search researcher).
813
+
814
+ ## Core Principle
815
+
816
+ **You do one thing: find and explain information.**
817
+
818
+ You are a documenter, not a reviewer.
819
+
820
+ ## Project Info
821
+
822
+ {context}
823
+
824
+ ---
825
+
826
+ ## Your Task
827
+
828
+ {original_prompt}
829
+
830
+ ---
831
+
832
+ ## Workflow
833
+
834
+ 1. **Understand query** - Determine search type (internal/external) and scope
835
+ 2. **Plan search** - List search steps for complex queries
836
+ 3. **Execute search** - Execute multiple independent searches in parallel
837
+ 4. **Organize results** - Output structured report
838
+
839
+ ## Search Tools
840
+
841
+ | Tool | Purpose |
842
+ |------|---------|
843
+ | Glob | Search by filename pattern |
844
+ | Grep | Search by content |
845
+ | Read | Read file content |
846
+ | mcp__exa__web_search_exa | External web search |
847
+ | mcp__exa__get_code_context_exa | External code/doc search |
848
+
849
+ ## Strict Boundaries
850
+
851
+ **Only allowed**: Describe what exists, where it is, how it works
852
+
853
+ **Forbidden** (unless explicitly asked):
854
+ - Suggest improvements
855
+ - Criticize implementation
856
+ - Recommend refactoring
857
+ - Modify any files
858
+
859
+ ## Report Format
860
+
861
+ Provide structured search results including:
862
+ - List of files found (with paths)
863
+ - Code pattern analysis (if applicable)
864
+ - Related spec documents
865
+ - External references (if any)"""
866
+
867
+
868
+ def _string_value(value: Any) -> str:
869
+ if isinstance(value, str):
870
+ stripped = value.strip()
871
+ return stripped
872
+ return ""
873
+
874
+
875
+ def _hook_event_name(input_data: dict) -> str:
876
+ """Return a hook event name from the documented snake/camel-case fields."""
877
+ return _string_value(
878
+ input_data.get("hook_event_name") or input_data.get("hookEventName")
879
+ )
880
+
881
+
882
+ def _codex_subagent_type(input_data: dict) -> str:
883
+ """Return a Trellis Codex agent type only for a native start event."""
884
+ if _hook_event_name(input_data) != "SubagentStart":
885
+ return ""
886
+ agent_type = _string_value(
887
+ input_data.get("agent_type") or input_data.get("agentType")
888
+ )
889
+ return agent_type if agent_type in AGENTS_ALL else ""
890
+
891
+
892
+ def build_codex_subagent_context(
893
+ subagent_type: str,
894
+ task_dir: str,
895
+ context: str,
896
+ ) -> str:
897
+ """Build developer context for a native, already-dispatched Codex role."""
898
+ role = subagent_type.removeprefix("trellis-")
899
+ return f"""<!-- trellis-hook-injected -->
900
+ # Trellis Native {role.title()} Subagent
901
+
902
+ You are the dispatched `{subagent_type}` role for this task. Perform that role
903
+ directly; do not follow main-session dispatch or wait instructions, and do not
904
+ spawn another Trellis subagent.
905
+
906
+ Active task: {task_dir}
907
+
908
+ ## Curated Context
909
+
910
+ {context}"""
911
+
912
+
913
+ def _handle_codex_subagent_start(input_data: dict) -> None:
914
+ """Emit Codex developer context for a recognised native Trellis subagent.
915
+
916
+ The event supplies the parent session id. Disabling the generic
917
+ single-session fallback is essential here: native starts must never borrow
918
+ a task from another Codex window when that parent id is absent or stale.
919
+ """
920
+ subagent_type = _codex_subagent_type(input_data)
921
+ parent_session_id = _string_value(input_data.get("session_id"))
922
+ if not subagent_type or not parent_session_id:
923
+ return
924
+
925
+ # Payload cwd first, then our own — some hosts (CodeBuddy IDE 4.10.4)
926
+ # report "/" for every hook event. See inject-workflow-state.py.
927
+ repo_root = None
928
+ for candidate in (_string_value(input_data.get("cwd")), os.getcwd()):
929
+ if not candidate:
930
+ continue
931
+ repo_root = find_repo_root(candidate)
932
+ if repo_root:
933
+ break
934
+ if not repo_root:
935
+ return
936
+
937
+ task_dir = get_current_task(
938
+ repo_root,
939
+ {"session_id": parent_session_id},
940
+ platform="codex",
941
+ allow_single_session_fallback=False,
942
+ allow_environment_context=False,
943
+ require_existing=True,
944
+ )
945
+ if not task_dir:
946
+ return
947
+
948
+ if subagent_type in AGENTS_REQUIRE_TASK:
949
+ task_dir_full = Path(repo_root) / task_dir
950
+ if not task_dir_full.is_dir():
951
+ return
952
+
953
+ if subagent_type == AGENT_IMPLEMENT:
954
+ context = get_implement_context(repo_root, task_dir)
955
+ elif subagent_type == AGENT_CHECK:
956
+ context = get_check_context(repo_root, task_dir)
957
+ else:
958
+ context = get_research_context(repo_root, task_dir)
959
+
960
+ if not context:
961
+ return
962
+
963
+ output = {
964
+ "hookSpecificOutput": {
965
+ "hookEventName": "SubagentStart",
966
+ "additionalContext": build_codex_subagent_context(
967
+ subagent_type, task_dir, context
968
+ ),
969
+ }
970
+ }
971
+ print(json.dumps(output, ensure_ascii=False))
972
+
973
+
974
+ def _extract_subagent_name(value: Any) -> str:
975
+ """Extract a sub-agent name from common platform encodings.
976
+
977
+ Cursor's native Task args encode custom sub-agents as a protobuf oneof,
978
+ which can appear in hook JSON as either ``{"custom": {"name": "..."}}``
979
+ or ``{"type": {"case": "custom", "value": {"name": "..."}}}``.
980
+ """
981
+ direct = _string_value(value)
982
+ if direct:
983
+ return direct
984
+
985
+ if not isinstance(value, dict):
986
+ return ""
987
+
988
+ for key in ("name", "subagent_type_name", "subagentTypeName"):
989
+ direct = _string_value(value.get(key))
990
+ if direct:
991
+ return direct
992
+
993
+ custom = value.get("custom")
994
+ if isinstance(custom, dict):
995
+ custom_name = _string_value(custom.get("name"))
996
+ if custom_name:
997
+ return custom_name
998
+
999
+ oneof = value.get("type")
1000
+ if isinstance(oneof, dict):
1001
+ case_name = _string_value(oneof.get("case"))
1002
+ if case_name == "custom":
1003
+ nested_value = oneof.get("value")
1004
+ if isinstance(nested_value, dict):
1005
+ custom_name = _string_value(nested_value.get("name"))
1006
+ if custom_name:
1007
+ return custom_name
1008
+ if case_name:
1009
+ return case_name
1010
+
1011
+ case_name = _string_value(value.get("case"))
1012
+ if case_name == "custom":
1013
+ nested_value = value.get("value")
1014
+ if isinstance(nested_value, dict):
1015
+ custom_name = _string_value(nested_value.get("name"))
1016
+ if custom_name:
1017
+ return custom_name
1018
+ if case_name:
1019
+ return case_name
1020
+
1021
+ for agent_name in AGENTS_ALL:
1022
+ if agent_name in value:
1023
+ return agent_name
1024
+
1025
+ return ""
1026
+
1027
+
1028
+ def _extract_subagent_type(tool_input: dict) -> str:
1029
+ for key in (
1030
+ "subagent_type",
1031
+ "subagentType",
1032
+ "subagent_type_name",
1033
+ "subagentTypeName",
1034
+ "subagent_name",
1035
+ "subagentName",
1036
+ "agent_type",
1037
+ "agentType",
1038
+ "name",
1039
+ ):
1040
+ agent_name = _extract_subagent_name(tool_input.get(key))
1041
+ if agent_name:
1042
+ return agent_name
1043
+ return ""
1044
+
1045
+
1046
+ def _parse_hook_input(input_data: dict) -> tuple[str, str, dict]:
1047
+ """Parse hook input across different platform formats.
1048
+
1049
+ Returns (subagent_type, original_prompt, tool_input).
1050
+ Handles:
1051
+ - Claude Code / Qoder / Droid: tool_name=Task|Agent, tool_input.subagent_type
1052
+ - CodeBuddy: tool_name=task (IDE) or Task (CLI), tool_input.subagent_name
1053
+ - Cursor: tool_name=Task|Subagent, tool_input.subagent_type
1054
+ - Copilot CLI: toolName=task (camelCase key, lowercase value)
1055
+ - ZCode: toolName=Agent, toolInput/tool_input.subagent_type
1056
+ - Gemini CLI: tool_name IS the agent name (BeforeTool matcher already filtered)
1057
+ - Kiro: agentSpawn hook, agent_name field at top level
1058
+ """
1059
+ tool_input = input_data.get("tool_input", {})
1060
+ if not isinstance(tool_input, dict):
1061
+ tool_input = input_data.get("toolInput", {})
1062
+ if not isinstance(tool_input, dict):
1063
+ tool_input = {}
1064
+
1065
+ # Standard format: Task/Agent tool with subagent_type
1066
+ tool_name = input_data.get("tool_name", "") or input_data.get("toolName", "")
1067
+ if tool_name.lower() in ("task", "agent", "subagent"):
1068
+ return (
1069
+ _extract_subagent_type(tool_input),
1070
+ tool_input.get("prompt", ""),
1071
+ tool_input,
1072
+ )
1073
+
1074
+ # Kiro: agentSpawn hook passes agent_name at top level
1075
+ agent_name = input_data.get("agent_name", "")
1076
+ if agent_name:
1077
+ return agent_name, tool_input.get("prompt", input_data.get("prompt", "")), tool_input
1078
+
1079
+ # Gemini CLI: BeforeTool where tool_name IS the agent name
1080
+ # (matcher already ensured it's one of our agents)
1081
+ if tool_name in AGENTS_ALL:
1082
+ return tool_name, tool_input.get("prompt", ""), tool_input
1083
+
1084
+ # Copilot CLI: toolName field (camelCase), value might be the agent name
1085
+ tool_name_camel = input_data.get("toolName", "")
1086
+ if tool_name_camel in AGENTS_ALL:
1087
+ return tool_name_camel, input_data.get("toolArgs", ""), tool_input
1088
+
1089
+ return "", "", tool_input
1090
+
1091
+
1092
+ def main():
1093
+ if os.environ.get("TRELLIS_HOOKS") == "0" or os.environ.get("TRELLIS_DISABLE_HOOKS") == "1":
1094
+ sys.exit(0)
1095
+
1096
+ try:
1097
+ input_data = json.load(sys.stdin)
1098
+ except json.JSONDecodeError:
1099
+ sys.exit(0)
1100
+ if not isinstance(input_data, dict):
1101
+ sys.exit(0)
1102
+
1103
+ if _hook_event_name(input_data) == "SubagentStart":
1104
+ try:
1105
+ _handle_codex_subagent_start(input_data)
1106
+ except Exception:
1107
+ # A native context hook must never prevent Codex from spawning the
1108
+ # requested child when its runtime state is unavailable or stale.
1109
+ pass
1110
+ sys.exit(0)
1111
+
1112
+ subagent_type, original_prompt, tool_input = _parse_hook_input(input_data)
1113
+ cwd = input_data.get("cwd", os.getcwd())
1114
+
1115
+ # Only handle subagent types we care about
1116
+ if subagent_type not in AGENTS_ALL:
1117
+ sys.exit(0)
1118
+
1119
+ # Find repo root
1120
+ repo_root = find_repo_root(cwd)
1121
+ if not repo_root:
1122
+ sys.exit(0)
1123
+
1124
+ # Get current task directory (research doesn't require it)
1125
+ task_dir = get_current_task(repo_root, input_data)
1126
+
1127
+ # implement/check need task directory
1128
+ if subagent_type in AGENTS_REQUIRE_TASK:
1129
+ if not task_dir:
1130
+ sys.exit(0)
1131
+ # Contain the pointer before reading anything through it. `task.py` now
1132
+ # refuses to store a ref that leaves the repo, but a session file
1133
+ # written before that fix can still hold one, and `trellis update`
1134
+ # does not rewrite session files — so a poisoned pointer outlives the
1135
+ # upgrade that closed the writer. This is the last hop before the
1136
+ # task's prd.md/design.md reach the model prompt, so it checks again.
1137
+ try:
1138
+ root_real = os.path.realpath(repo_root)
1139
+ # `.trellis` may itself be a symlink into a store outside the
1140
+ # repo (#567); its real location is a second legitimate base.
1141
+ workflow_real = os.path.realpath(os.path.join(repo_root, ".trellis"))
1142
+ task_dir_full = os.path.realpath(os.path.join(repo_root, task_dir))
1143
+ if not _real_path_contained(root_real, task_dir_full) and not (
1144
+ _real_path_contained(workflow_real, task_dir_full)
1145
+ ):
1146
+ sys.exit(0)
1147
+ except OSError:
1148
+ sys.exit(0)
1149
+ if not os.path.exists(task_dir_full):
1150
+ sys.exit(0)
1151
+
1152
+ # Check for [finish] marker in prompt (check agent with finish context)
1153
+ is_finish_phase = "[finish]" in original_prompt.lower()
1154
+
1155
+ # Get context and build prompt based on subagent type
1156
+ if subagent_type == AGENT_IMPLEMENT:
1157
+ assert task_dir is not None # validated above
1158
+ context = get_implement_context(repo_root, task_dir)
1159
+ new_prompt = build_implement_prompt(original_prompt, context)
1160
+ elif subagent_type == AGENT_CHECK:
1161
+ assert task_dir is not None # validated above
1162
+ if is_finish_phase:
1163
+ # Finish phase: use finish context (lighter, focused on final verification)
1164
+ context = get_finish_context(repo_root, task_dir)
1165
+ new_prompt = build_finish_prompt(original_prompt, context)
1166
+ else:
1167
+ # Regular check phase: use check context (full specs for self-fix loop)
1168
+ context = get_check_context(repo_root, task_dir)
1169
+ new_prompt = build_check_prompt(original_prompt, context)
1170
+ elif subagent_type == AGENT_RESEARCH:
1171
+ # Research can work without task directory
1172
+ context = get_research_context(repo_root, task_dir)
1173
+ new_prompt = build_research_prompt(original_prompt, context)
1174
+ else:
1175
+ sys.exit(0)
1176
+
1177
+ if not context:
1178
+ sys.exit(0)
1179
+
1180
+ # Return updated input. Most platforms ignore unrecognized fields, so we
1181
+ # include multiple formats. ZCode is stricter; live probing confirmed the
1182
+ # nested Claude-compatible shape below reaches the sub-agent prompt.
1183
+ updated = {**tool_input, "prompt": new_prompt}
1184
+ if _detect_platform(input_data) == "zcode":
1185
+ output = {
1186
+ "hookSpecificOutput": {
1187
+ "hookEventName": "PreToolUse",
1188
+ "permissionDecision": "allow",
1189
+ "updatedInput": updated,
1190
+ }
1191
+ }
1192
+ else:
1193
+ output = {
1194
+ # Claude Code / Qoder / CodeBuddy / Droid format
1195
+ "hookSpecificOutput": {
1196
+ "hookEventName": "PreToolUse",
1197
+ "permissionDecision": "allow",
1198
+ "updatedInput": updated,
1199
+ },
1200
+ # Cursor format
1201
+ "permission": "allow",
1202
+ "updated_input": updated,
1203
+ # Gemini format
1204
+ "updatedInput": updated,
1205
+ }
1206
+
1207
+ print(json.dumps(output, ensure_ascii=False))
1208
+ sys.exit(0)
1209
+
1210
+
1211
+ if __name__ == "__main__":
1212
+ main()