@blulotus/trellis 0.7.0

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 (821) hide show
  1. package/LICENSE +235 -0
  2. package/README.md +149 -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 +276 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/commands/channel/adapters/claude.d.ts +29 -0
  9. package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
  10. package/dist/commands/channel/adapters/claude.js +203 -0
  11. package/dist/commands/channel/adapters/claude.js.map +1 -0
  12. package/dist/commands/channel/adapters/codex.d.ts +93 -0
  13. package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
  14. package/dist/commands/channel/adapters/codex.js +573 -0
  15. package/dist/commands/channel/adapters/codex.js.map +1 -0
  16. package/dist/commands/channel/adapters/index.d.ts +86 -0
  17. package/dist/commands/channel/adapters/index.d.ts.map +1 -0
  18. package/dist/commands/channel/adapters/index.js +115 -0
  19. package/dist/commands/channel/adapters/index.js.map +1 -0
  20. package/dist/commands/channel/adapters/types.d.ts +33 -0
  21. package/dist/commands/channel/adapters/types.d.ts.map +1 -0
  22. package/dist/commands/channel/adapters/types.js +2 -0
  23. package/dist/commands/channel/adapters/types.js.map +1 -0
  24. package/dist/commands/channel/agent-loader.d.ts +32 -0
  25. package/dist/commands/channel/agent-loader.d.ts.map +1 -0
  26. package/dist/commands/channel/agent-loader.js +158 -0
  27. package/dist/commands/channel/agent-loader.js.map +1 -0
  28. package/dist/commands/channel/context-loader.d.ts +26 -0
  29. package/dist/commands/channel/context-loader.d.ts.map +1 -0
  30. package/dist/commands/channel/context-loader.js +311 -0
  31. package/dist/commands/channel/context-loader.js.map +1 -0
  32. package/dist/commands/channel/context-trust.d.ts +31 -0
  33. package/dist/commands/channel/context-trust.d.ts.map +1 -0
  34. package/dist/commands/channel/context-trust.js +139 -0
  35. package/dist/commands/channel/context-trust.js.map +1 -0
  36. package/dist/commands/channel/context.d.ts +16 -0
  37. package/dist/commands/channel/context.d.ts.map +1 -0
  38. package/dist/commands/channel/context.js +83 -0
  39. package/dist/commands/channel/context.js.map +1 -0
  40. package/dist/commands/channel/create.d.ts +27 -0
  41. package/dist/commands/channel/create.d.ts.map +1 -0
  42. package/dist/commands/channel/create.js +39 -0
  43. package/dist/commands/channel/create.js.map +1 -0
  44. package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
  45. package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
  46. package/dist/commands/channel/dev-parse-trace.js +70 -0
  47. package/dist/commands/channel/dev-parse-trace.js.map +1 -0
  48. package/dist/commands/channel/guard.d.ts +150 -0
  49. package/dist/commands/channel/guard.d.ts.map +1 -0
  50. package/dist/commands/channel/guard.js +479 -0
  51. package/dist/commands/channel/guard.js.map +1 -0
  52. package/dist/commands/channel/index.d.ts +3 -0
  53. package/dist/commands/channel/index.d.ts.map +1 -0
  54. package/dist/commands/channel/index.js +535 -0
  55. package/dist/commands/channel/index.js.map +1 -0
  56. package/dist/commands/channel/interrupt.d.ts +10 -0
  57. package/dist/commands/channel/interrupt.d.ts.map +1 -0
  58. package/dist/commands/channel/interrupt.js +22 -0
  59. package/dist/commands/channel/interrupt.js.map +1 -0
  60. package/dist/commands/channel/kill.d.ts +7 -0
  61. package/dist/commands/channel/kill.d.ts.map +1 -0
  62. package/dist/commands/channel/kill.js +121 -0
  63. package/dist/commands/channel/kill.js.map +1 -0
  64. package/dist/commands/channel/list.d.ts +17 -0
  65. package/dist/commands/channel/list.d.ts.map +1 -0
  66. package/dist/commands/channel/list.js +233 -0
  67. package/dist/commands/channel/list.js.map +1 -0
  68. package/dist/commands/channel/messages.d.ts +15 -0
  69. package/dist/commands/channel/messages.d.ts.map +1 -0
  70. package/dist/commands/channel/messages.js +245 -0
  71. package/dist/commands/channel/messages.js.map +1 -0
  72. package/dist/commands/channel/rm.d.ts +27 -0
  73. package/dist/commands/channel/rm.d.ts.map +1 -0
  74. package/dist/commands/channel/rm.js +216 -0
  75. package/dist/commands/channel/rm.js.map +1 -0
  76. package/dist/commands/channel/run.d.ts +30 -0
  77. package/dist/commands/channel/run.d.ts.map +1 -0
  78. package/dist/commands/channel/run.js +130 -0
  79. package/dist/commands/channel/run.js.map +1 -0
  80. package/dist/commands/channel/send.d.ts +11 -0
  81. package/dist/commands/channel/send.d.ts.map +1 -0
  82. package/dist/commands/channel/send.js +24 -0
  83. package/dist/commands/channel/send.js.map +1 -0
  84. package/dist/commands/channel/spawn.d.ts +43 -0
  85. package/dist/commands/channel/spawn.d.ts.map +1 -0
  86. package/dist/commands/channel/spawn.js +247 -0
  87. package/dist/commands/channel/spawn.js.map +1 -0
  88. package/dist/commands/channel/store/events.d.ts +39 -0
  89. package/dist/commands/channel/store/events.d.ts.map +1 -0
  90. package/dist/commands/channel/store/events.js +87 -0
  91. package/dist/commands/channel/store/events.js.map +1 -0
  92. package/dist/commands/channel/store/filter.d.ts +3 -0
  93. package/dist/commands/channel/store/filter.d.ts.map +1 -0
  94. package/dist/commands/channel/store/filter.js +2 -0
  95. package/dist/commands/channel/store/filter.js.map +1 -0
  96. package/dist/commands/channel/store/lock.d.ts +23 -0
  97. package/dist/commands/channel/store/lock.d.ts.map +1 -0
  98. package/dist/commands/channel/store/lock.js +99 -0
  99. package/dist/commands/channel/store/lock.js.map +1 -0
  100. package/dist/commands/channel/store/paths.d.ts +77 -0
  101. package/dist/commands/channel/store/paths.d.ts.map +1 -0
  102. package/dist/commands/channel/store/paths.js +272 -0
  103. package/dist/commands/channel/store/paths.js.map +1 -0
  104. package/dist/commands/channel/store/schema.d.ts +27 -0
  105. package/dist/commands/channel/store/schema.d.ts.map +1 -0
  106. package/dist/commands/channel/store/schema.js +34 -0
  107. package/dist/commands/channel/store/schema.js.map +1 -0
  108. package/dist/commands/channel/store/thread-state.d.ts +5 -0
  109. package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
  110. package/dist/commands/channel/store/thread-state.js +16 -0
  111. package/dist/commands/channel/store/thread-state.js.map +1 -0
  112. package/dist/commands/channel/store/watch.d.ts +19 -0
  113. package/dist/commands/channel/store/watch.d.ts.map +1 -0
  114. package/dist/commands/channel/store/watch.js +146 -0
  115. package/dist/commands/channel/store/watch.js.map +1 -0
  116. package/dist/commands/channel/supervisor/idle.d.ts +45 -0
  117. package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
  118. package/dist/commands/channel/supervisor/idle.js +70 -0
  119. package/dist/commands/channel/supervisor/idle.js.map +1 -0
  120. package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
  121. package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
  122. package/dist/commands/channel/supervisor/inbox.js +160 -0
  123. package/dist/commands/channel/supervisor/inbox.js.map +1 -0
  124. package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
  125. package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
  126. package/dist/commands/channel/supervisor/shutdown.js +146 -0
  127. package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
  128. package/dist/commands/channel/supervisor/stdout.d.ts +53 -0
  129. package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
  130. package/dist/commands/channel/supervisor/stdout.js +168 -0
  131. package/dist/commands/channel/supervisor/stdout.js.map +1 -0
  132. package/dist/commands/channel/supervisor/turns.d.ts +31 -0
  133. package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
  134. package/dist/commands/channel/supervisor/turns.js +45 -0
  135. package/dist/commands/channel/supervisor/turns.js.map +1 -0
  136. package/dist/commands/channel/supervisor/warning.d.ts +48 -0
  137. package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
  138. package/dist/commands/channel/supervisor/warning.js +77 -0
  139. package/dist/commands/channel/supervisor/warning.js.map +1 -0
  140. package/dist/commands/channel/supervisor.d.ts +75 -0
  141. package/dist/commands/channel/supervisor.d.ts.map +1 -0
  142. package/dist/commands/channel/supervisor.js +397 -0
  143. package/dist/commands/channel/supervisor.js.map +1 -0
  144. package/dist/commands/channel/text-body.d.ts +13 -0
  145. package/dist/commands/channel/text-body.d.ts.map +1 -0
  146. package/dist/commands/channel/text-body.js +47 -0
  147. package/dist/commands/channel/text-body.js.map +1 -0
  148. package/dist/commands/channel/threads.d.ts +39 -0
  149. package/dist/commands/channel/threads.d.ts.map +1 -0
  150. package/dist/commands/channel/threads.js +106 -0
  151. package/dist/commands/channel/threads.js.map +1 -0
  152. package/dist/commands/channel/title.d.ts +12 -0
  153. package/dist/commands/channel/title.d.ts.map +1 -0
  154. package/dist/commands/channel/title.js +24 -0
  155. package/dist/commands/channel/title.js.map +1 -0
  156. package/dist/commands/channel/wait.d.ts +17 -0
  157. package/dist/commands/channel/wait.d.ts.map +1 -0
  158. package/dist/commands/channel/wait.js +75 -0
  159. package/dist/commands/channel/wait.js.map +1 -0
  160. package/dist/commands/init.d.ts +71 -0
  161. package/dist/commands/init.d.ts.map +1 -0
  162. package/dist/commands/init.js +1603 -0
  163. package/dist/commands/init.js.map +1 -0
  164. package/dist/commands/mem.d.ts +30 -0
  165. package/dist/commands/mem.d.ts.map +1 -0
  166. package/dist/commands/mem.js +447 -0
  167. package/dist/commands/mem.js.map +1 -0
  168. package/dist/commands/uninstall.d.ts +36 -0
  169. package/dist/commands/uninstall.d.ts.map +1 -0
  170. package/dist/commands/uninstall.js +410 -0
  171. package/dist/commands/uninstall.js.map +1 -0
  172. package/dist/commands/update.d.ts +111 -0
  173. package/dist/commands/update.d.ts.map +1 -0
  174. package/dist/commands/update.js +2152 -0
  175. package/dist/commands/update.js.map +1 -0
  176. package/dist/commands/upgrade.d.ts +28 -0
  177. package/dist/commands/upgrade.d.ts.map +1 -0
  178. package/dist/commands/upgrade.js +84 -0
  179. package/dist/commands/upgrade.js.map +1 -0
  180. package/dist/commands/workflow.d.ts +52 -0
  181. package/dist/commands/workflow.d.ts.map +1 -0
  182. package/dist/commands/workflow.js +454 -0
  183. package/dist/commands/workflow.js.map +1 -0
  184. package/dist/configurators/antigravity.d.ts +7 -0
  185. package/dist/configurators/antigravity.d.ts.map +1 -0
  186. package/dist/configurators/antigravity.js +11 -0
  187. package/dist/configurators/antigravity.js.map +1 -0
  188. package/dist/configurators/claude.d.ts +23 -0
  189. package/dist/configurators/claude.d.ts.map +1 -0
  190. package/dist/configurators/claude.js +123 -0
  191. package/dist/configurators/claude.js.map +1 -0
  192. package/dist/configurators/codebuddy.d.ts +10 -0
  193. package/dist/configurators/codebuddy.d.ts.map +1 -0
  194. package/dist/configurators/codebuddy.js +24 -0
  195. package/dist/configurators/codebuddy.js.map +1 -0
  196. package/dist/configurators/codex.d.ts +57 -0
  197. package/dist/configurators/codex.d.ts.map +1 -0
  198. package/dist/configurators/codex.js +170 -0
  199. package/dist/configurators/codex.js.map +1 -0
  200. package/dist/configurators/copilot.d.ts +14 -0
  201. package/dist/configurators/copilot.d.ts.map +1 -0
  202. package/dist/configurators/copilot.js +46 -0
  203. package/dist/configurators/copilot.js.map +1 -0
  204. package/dist/configurators/cursor.d.ts +10 -0
  205. package/dist/configurators/cursor.d.ts.map +1 -0
  206. package/dist/configurators/cursor.js +23 -0
  207. package/dist/configurators/cursor.js.map +1 -0
  208. package/dist/configurators/devin.d.ts +8 -0
  209. package/dist/configurators/devin.d.ts.map +1 -0
  210. package/dist/configurators/devin.js +12 -0
  211. package/dist/configurators/devin.js.map +1 -0
  212. package/dist/configurators/droid.d.ts +10 -0
  213. package/dist/configurators/droid.d.ts.map +1 -0
  214. package/dist/configurators/droid.js +24 -0
  215. package/dist/configurators/droid.js.map +1 -0
  216. package/dist/configurators/dsh.d.ts +26 -0
  217. package/dist/configurators/dsh.d.ts.map +1 -0
  218. package/dist/configurators/dsh.js +76 -0
  219. package/dist/configurators/dsh.js.map +1 -0
  220. package/dist/configurators/gemini.d.ts +18 -0
  221. package/dist/configurators/gemini.d.ts.map +1 -0
  222. package/dist/configurators/gemini.js +39 -0
  223. package/dist/configurators/gemini.js.map +1 -0
  224. package/dist/configurators/grok.d.ts +17 -0
  225. package/dist/configurators/grok.d.ts.map +1 -0
  226. package/dist/configurators/grok.js +38 -0
  227. package/dist/configurators/grok.js.map +1 -0
  228. package/dist/configurators/index.d.ts +68 -0
  229. package/dist/configurators/index.d.ts.map +1 -0
  230. package/dist/configurators/index.js +191 -0
  231. package/dist/configurators/index.js.map +1 -0
  232. package/dist/configurators/kilo.d.ts +7 -0
  233. package/dist/configurators/kilo.d.ts.map +1 -0
  234. package/dist/configurators/kilo.js +11 -0
  235. package/dist/configurators/kilo.js.map +1 -0
  236. package/dist/configurators/kimi.d.ts +26 -0
  237. package/dist/configurators/kimi.d.ts.map +1 -0
  238. package/dist/configurators/kimi.js +74 -0
  239. package/dist/configurators/kimi.js.map +1 -0
  240. package/dist/configurators/kiro.d.ts +11 -0
  241. package/dist/configurators/kiro.d.ts.map +1 -0
  242. package/dist/configurators/kiro.js +30 -0
  243. package/dist/configurators/kiro.js.map +1 -0
  244. package/dist/configurators/omp.d.ts +6 -0
  245. package/dist/configurators/omp.d.ts.map +1 -0
  246. package/dist/configurators/omp.js +28 -0
  247. package/dist/configurators/omp.js.map +1 -0
  248. package/dist/configurators/opencode.d.ts +5 -0
  249. package/dist/configurators/opencode.d.ts.map +1 -0
  250. package/dist/configurators/opencode.js +84 -0
  251. package/dist/configurators/opencode.js.map +1 -0
  252. package/dist/configurators/pi.d.ts +5 -0
  253. package/dist/configurators/pi.d.ts.map +1 -0
  254. package/dist/configurators/pi.js +39 -0
  255. package/dist/configurators/pi.js.map +1 -0
  256. package/dist/configurators/qoder.d.ts +12 -0
  257. package/dist/configurators/qoder.d.ts.map +1 -0
  258. package/dist/configurators/qoder.js +30 -0
  259. package/dist/configurators/qoder.js.map +1 -0
  260. package/dist/configurators/reasonix.d.ts +17 -0
  261. package/dist/configurators/reasonix.d.ts.map +1 -0
  262. package/dist/configurators/reasonix.js +37 -0
  263. package/dist/configurators/reasonix.js.map +1 -0
  264. package/dist/configurators/shared.d.ts +187 -0
  265. package/dist/configurators/shared.d.ts.map +1 -0
  266. package/dist/configurators/shared.js +590 -0
  267. package/dist/configurators/shared.js.map +1 -0
  268. package/dist/configurators/snow.d.ts +25 -0
  269. package/dist/configurators/snow.d.ts.map +1 -0
  270. package/dist/configurators/snow.js +69 -0
  271. package/dist/configurators/snow.js.map +1 -0
  272. package/dist/configurators/trae.d.ts +16 -0
  273. package/dist/configurators/trae.d.ts.map +1 -0
  274. package/dist/configurators/trae.js +34 -0
  275. package/dist/configurators/trae.js.map +1 -0
  276. package/dist/configurators/workflow.d.ts +51 -0
  277. package/dist/configurators/workflow.d.ts.map +1 -0
  278. package/dist/configurators/workflow.js +210 -0
  279. package/dist/configurators/workflow.js.map +1 -0
  280. package/dist/configurators/zcode.d.ts +23 -0
  281. package/dist/configurators/zcode.d.ts.map +1 -0
  282. package/dist/configurators/zcode.js +63 -0
  283. package/dist/configurators/zcode.js.map +1 -0
  284. package/dist/constants/paths.d.ts +74 -0
  285. package/dist/constants/paths.d.ts.map +1 -0
  286. package/dist/constants/paths.js +83 -0
  287. package/dist/constants/paths.js.map +1 -0
  288. package/dist/constants/version.d.ts +9 -0
  289. package/dist/constants/version.d.ts.map +1 -0
  290. package/dist/constants/version.js +15 -0
  291. package/dist/constants/version.js.map +1 -0
  292. package/dist/index.d.ts +9 -0
  293. package/dist/index.d.ts.map +1 -0
  294. package/dist/index.js +9 -0
  295. package/dist/index.js.map +1 -0
  296. package/dist/migrations/index.d.ts +62 -0
  297. package/dist/migrations/index.d.ts.map +1 -0
  298. package/dist/migrations/index.js +187 -0
  299. package/dist/migrations/index.js.map +1 -0
  300. package/dist/migrations/manifests/0.1.9.json +30 -0
  301. package/dist/migrations/manifests/0.2.0.json +49 -0
  302. package/dist/migrations/manifests/0.2.12.json +9 -0
  303. package/dist/migrations/manifests/0.2.13.json +9 -0
  304. package/dist/migrations/manifests/0.2.14.json +175 -0
  305. package/dist/migrations/manifests/0.2.15.json +33 -0
  306. package/dist/migrations/manifests/0.3.0-beta.0.json +297 -0
  307. package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
  308. package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
  309. package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
  310. package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
  311. package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
  312. package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
  313. package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
  314. package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
  315. package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
  316. package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
  317. package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
  318. package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
  319. package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
  320. package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
  321. package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
  322. package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
  323. package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
  324. package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
  325. package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
  326. package/dist/migrations/manifests/0.3.0-rc.3.json +9 -0
  327. package/dist/migrations/manifests/0.3.0-rc.4.json +9 -0
  328. package/dist/migrations/manifests/0.3.0-rc.5.json +9 -0
  329. package/dist/migrations/manifests/0.3.0-rc.6.json +9 -0
  330. package/dist/migrations/manifests/0.3.0.json +11 -0
  331. package/dist/migrations/manifests/0.3.1.json +9 -0
  332. package/dist/migrations/manifests/0.3.10.json +9 -0
  333. package/dist/migrations/manifests/0.3.2.json +9 -0
  334. package/dist/migrations/manifests/0.3.3.json +9 -0
  335. package/dist/migrations/manifests/0.3.4.json +21 -0
  336. package/dist/migrations/manifests/0.3.5.json +9 -0
  337. package/dist/migrations/manifests/0.3.6.json +9 -0
  338. package/dist/migrations/manifests/0.3.7.json +9 -0
  339. package/dist/migrations/manifests/0.3.8.json +9 -0
  340. package/dist/migrations/manifests/0.3.9.json +9 -0
  341. package/dist/migrations/manifests/0.4.0-beta.1.json +228 -0
  342. package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
  343. package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
  344. package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
  345. package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
  346. package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
  347. package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
  348. package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
  349. package/dist/migrations/manifests/0.4.0-beta.8.json +34 -0
  350. package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
  351. package/dist/migrations/manifests/0.4.0-rc.0.json +9 -0
  352. package/dist/migrations/manifests/0.4.0-rc.1.json +9 -0
  353. package/dist/migrations/manifests/0.4.0.json +9 -0
  354. package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
  355. package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
  356. package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
  357. package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
  358. package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
  359. package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
  360. package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
  361. package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
  362. package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
  363. package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
  364. package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
  365. package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
  366. package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
  367. package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
  368. package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
  369. package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
  370. package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
  371. package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
  372. package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
  373. package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
  374. package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
  375. package/dist/migrations/manifests/0.5.0-rc.1.json +9 -0
  376. package/dist/migrations/manifests/0.5.0-rc.2.json +9 -0
  377. package/dist/migrations/manifests/0.5.0-rc.3.json +9 -0
  378. package/dist/migrations/manifests/0.5.0-rc.4.json +9 -0
  379. package/dist/migrations/manifests/0.5.0-rc.5.json +9 -0
  380. package/dist/migrations/manifests/0.5.0-rc.6.json +9 -0
  381. package/dist/migrations/manifests/0.5.0-rc.7.json +9 -0
  382. package/dist/migrations/manifests/0.5.0.json +9 -0
  383. package/dist/migrations/manifests/0.5.1.json +9 -0
  384. package/dist/migrations/manifests/0.5.10.json +9 -0
  385. package/dist/migrations/manifests/0.5.11.json +16 -0
  386. package/dist/migrations/manifests/0.5.12.json +9 -0
  387. package/dist/migrations/manifests/0.5.13.json +9 -0
  388. package/dist/migrations/manifests/0.5.14.json +9 -0
  389. package/dist/migrations/manifests/0.5.15.json +9 -0
  390. package/dist/migrations/manifests/0.5.16.json +9 -0
  391. package/dist/migrations/manifests/0.5.17.json +9 -0
  392. package/dist/migrations/manifests/0.5.18.json +9 -0
  393. package/dist/migrations/manifests/0.5.19.json +9 -0
  394. package/dist/migrations/manifests/0.5.2.json +9 -0
  395. package/dist/migrations/manifests/0.5.3.json +9 -0
  396. package/dist/migrations/manifests/0.5.4.json +9 -0
  397. package/dist/migrations/manifests/0.5.5.json +9 -0
  398. package/dist/migrations/manifests/0.5.6.json +9 -0
  399. package/dist/migrations/manifests/0.5.7.json +16 -0
  400. package/dist/migrations/manifests/0.5.8.json +9 -0
  401. package/dist/migrations/manifests/0.5.9.json +9 -0
  402. package/dist/migrations/manifests/0.6.0-beta.0.json +16 -0
  403. package/dist/migrations/manifests/0.6.0-beta.1.json +9 -0
  404. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  405. package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
  406. package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
  407. package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
  408. package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
  409. package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
  410. package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
  411. package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
  412. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  413. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  414. package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
  415. package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
  416. package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
  417. package/dist/migrations/manifests/0.6.0-beta.22.json +9 -0
  418. package/dist/migrations/manifests/0.6.0-beta.23.json +88 -0
  419. package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
  420. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  421. package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
  422. package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
  423. package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
  424. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  425. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  426. package/dist/migrations/manifests/0.6.0-rc.0.json +9 -0
  427. package/dist/migrations/manifests/0.6.0.json +1 -0
  428. package/dist/migrations/manifests/0.6.1.json +9 -0
  429. package/dist/migrations/manifests/0.6.10.json +9 -0
  430. package/dist/migrations/manifests/0.6.11.json +9 -0
  431. package/dist/migrations/manifests/0.6.12.json +9 -0
  432. package/dist/migrations/manifests/0.6.13.json +9 -0
  433. package/dist/migrations/manifests/0.6.14.json +9 -0
  434. package/dist/migrations/manifests/0.6.2.json +9 -0
  435. package/dist/migrations/manifests/0.6.3.json +24 -0
  436. package/dist/migrations/manifests/0.6.4.json +9 -0
  437. package/dist/migrations/manifests/0.6.5.json +9 -0
  438. package/dist/migrations/manifests/0.6.6.json +17 -0
  439. package/dist/migrations/manifests/0.6.7.json +9 -0
  440. package/dist/migrations/manifests/0.6.8.json +17 -0
  441. package/dist/migrations/manifests/0.6.9.json +9 -0
  442. package/dist/migrations/manifests/0.7.0-beta.0.json +9 -0
  443. package/dist/migrations/manifests/0.7.0-beta.1.json +9 -0
  444. package/dist/migrations/manifests/0.7.0-beta.2.json +9 -0
  445. package/dist/migrations/manifests/0.7.0-beta.3.json +9 -0
  446. package/dist/templates/claude/agents/trellis-check.md +115 -0
  447. package/dist/templates/claude/agents/trellis-implement.md +115 -0
  448. package/dist/templates/claude/agents/trellis-research.md +137 -0
  449. package/dist/templates/claude/hooks/statusline.py +332 -0
  450. package/dist/templates/claude/index.d.ts +31 -0
  451. package/dist/templates/claude/index.d.ts.map +1 -0
  452. package/dist/templates/claude/index.js +57 -0
  453. package/dist/templates/claude/index.js.map +1 -0
  454. package/dist/templates/claude/settings.json +95 -0
  455. package/dist/templates/codebuddy/agents/trellis-check.md +115 -0
  456. package/dist/templates/codebuddy/agents/trellis-implement.md +115 -0
  457. package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
  458. package/dist/templates/codebuddy/index.d.ts +15 -0
  459. package/dist/templates/codebuddy/index.d.ts.map +1 -0
  460. package/dist/templates/codebuddy/index.js +15 -0
  461. package/dist/templates/codebuddy/index.js.map +1 -0
  462. package/dist/templates/codebuddy/settings.json +69 -0
  463. package/dist/templates/codex/agents/trellis-check.toml +56 -0
  464. package/dist/templates/codex/agents/trellis-implement.toml +37 -0
  465. package/dist/templates/codex/agents/trellis-research.toml +78 -0
  466. package/dist/templates/codex/config.toml +39 -0
  467. package/dist/templates/codex/hooks/session-start.py +568 -0
  468. package/dist/templates/codex/hooks.json +52 -0
  469. package/dist/templates/codex/index.d.ts +35 -0
  470. package/dist/templates/codex/index.d.ts.map +1 -0
  471. package/dist/templates/codex/index.js +67 -0
  472. package/dist/templates/codex/index.js.map +1 -0
  473. package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +67 -0
  474. package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +480 -0
  475. package/dist/templates/common/bundled-skills/trellis-channel/references/forum.md +233 -0
  476. package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +226 -0
  477. package/dist/templates/common/bundled-skills/trellis-channel/references/workers.md +276 -0
  478. package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +128 -0
  479. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +85 -0
  480. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
  481. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +56 -0
  482. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +84 -0
  483. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
  484. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +123 -0
  485. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
  486. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
  487. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +65 -0
  488. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
  489. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +159 -0
  490. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
  491. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
  492. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-channel.md +69 -0
  493. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
  494. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
  495. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +130 -0
  496. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
  497. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
  498. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +84 -0
  499. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +73 -0
  500. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
  501. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +113 -0
  502. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +87 -0
  503. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +81 -0
  504. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +65 -0
  505. package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +93 -0
  506. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/SKILL.md +41 -0
  507. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +90 -0
  508. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/repository-analysis.md +59 -0
  509. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +61 -0
  510. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-writing.md +70 -0
  511. package/dist/templates/common/commands/continue.md +56 -0
  512. package/dist/templates/common/commands/finish-work.md +66 -0
  513. package/dist/templates/common/commands/start.md +59 -0
  514. package/dist/templates/common/index.d.ts +48 -0
  515. package/dist/templates/common/index.d.ts.map +1 -0
  516. package/dist/templates/common/index.js +104 -0
  517. package/dist/templates/common/index.js.map +1 -0
  518. package/dist/templates/common/skills/before-dev.md +46 -0
  519. package/dist/templates/common/skills/brainstorm.md +212 -0
  520. package/dist/templates/common/skills/break-loop.md +184 -0
  521. package/dist/templates/common/skills/check.md +106 -0
  522. package/dist/templates/common/skills/tdd.md +142 -0
  523. package/dist/templates/common/skills/update-spec.md +351 -0
  524. package/dist/templates/copilot/copilot-instructions.md +11 -0
  525. package/dist/templates/copilot/hooks/session-start.py +564 -0
  526. package/dist/templates/copilot/hooks.json +19 -0
  527. package/dist/templates/copilot/index.d.ts +28 -0
  528. package/dist/templates/copilot/index.d.ts.map +1 -0
  529. package/dist/templates/copilot/index.js +61 -0
  530. package/dist/templates/copilot/index.js.map +1 -0
  531. package/dist/templates/copilot/prompts/before-dev.prompt.md +39 -0
  532. package/dist/templates/copilot/prompts/brainstorm.prompt.md +173 -0
  533. package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
  534. package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +170 -0
  535. package/dist/templates/copilot/prompts/check.prompt.md +110 -0
  536. package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
  537. package/dist/templates/copilot/prompts/finish-work.prompt.md +99 -0
  538. package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
  539. package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
  540. package/dist/templates/copilot/prompts/parallel.prompt.md +204 -0
  541. package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
  542. package/dist/templates/copilot/prompts/start.prompt.md +63 -0
  543. package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
  544. package/dist/templates/cursor/agents/trellis-check.md +114 -0
  545. package/dist/templates/cursor/agents/trellis-implement.md +114 -0
  546. package/dist/templates/cursor/agents/trellis-research.md +136 -0
  547. package/dist/templates/cursor/hooks.json +24 -0
  548. package/dist/templates/cursor/index.d.ts +13 -0
  549. package/dist/templates/cursor/index.d.ts.map +1 -0
  550. package/dist/templates/cursor/index.js +13 -0
  551. package/dist/templates/cursor/index.js.map +1 -0
  552. package/dist/templates/droid/droids/trellis-check.md +107 -0
  553. package/dist/templates/droid/droids/trellis-implement.md +107 -0
  554. package/dist/templates/droid/droids/trellis-research.md +137 -0
  555. package/dist/templates/droid/index.d.ts +15 -0
  556. package/dist/templates/droid/index.d.ts.map +1 -0
  557. package/dist/templates/droid/index.js +15 -0
  558. package/dist/templates/droid/index.js.map +1 -0
  559. package/dist/templates/droid/settings.json +69 -0
  560. package/dist/templates/dsh/DSH.md +80 -0
  561. package/dist/templates/dsh/agents/trellis-check.md +99 -0
  562. package/dist/templates/dsh/agents/trellis-implement.md +106 -0
  563. package/dist/templates/dsh/agents/trellis-research.md +134 -0
  564. package/dist/templates/dsh/index.d.ts +22 -0
  565. package/dist/templates/dsh/index.d.ts.map +1 -0
  566. package/dist/templates/dsh/index.js +27 -0
  567. package/dist/templates/dsh/index.js.map +1 -0
  568. package/dist/templates/extract.d.ts +40 -0
  569. package/dist/templates/extract.d.ts.map +1 -0
  570. package/dist/templates/extract.js +106 -0
  571. package/dist/templates/extract.js.map +1 -0
  572. package/dist/templates/gemini/agents/trellis-check.md +107 -0
  573. package/dist/templates/gemini/agents/trellis-implement.md +107 -0
  574. package/dist/templates/gemini/agents/trellis-research.md +136 -0
  575. package/dist/templates/gemini/index.d.ts +13 -0
  576. package/dist/templates/gemini/index.d.ts.map +1 -0
  577. package/dist/templates/gemini/index.js +13 -0
  578. package/dist/templates/gemini/index.js.map +1 -0
  579. package/dist/templates/gemini/settings.json +40 -0
  580. package/dist/templates/grok/agents/trellis-check.md +106 -0
  581. package/dist/templates/grok/agents/trellis-implement.md +121 -0
  582. package/dist/templates/grok/agents/trellis-research.md +146 -0
  583. package/dist/templates/grok/index.d.ts +16 -0
  584. package/dist/templates/grok/index.d.ts.map +1 -0
  585. package/dist/templates/grok/index.js +19 -0
  586. package/dist/templates/grok/index.js.map +1 -0
  587. package/dist/templates/kimi/agents/trellis-check.md +104 -0
  588. package/dist/templates/kimi/agents/trellis-implement.md +120 -0
  589. package/dist/templates/kimi/agents/trellis-research.md +144 -0
  590. package/dist/templates/kimi/index.d.ts +20 -0
  591. package/dist/templates/kimi/index.d.ts.map +1 -0
  592. package/dist/templates/kimi/index.js +23 -0
  593. package/dist/templates/kimi/index.js.map +1 -0
  594. package/dist/templates/kiro/agents/trellis-check.json +26 -0
  595. package/dist/templates/kiro/agents/trellis-implement.json +26 -0
  596. package/dist/templates/kiro/agents/trellis-research.json +30 -0
  597. package/dist/templates/kiro/agents/trellis.json +34 -0
  598. package/dist/templates/kiro/hooks/trellis-workflow-state.kiro.hook +14 -0
  599. package/dist/templates/kiro/index.d.ts +32 -0
  600. package/dist/templates/kiro/index.d.ts.map +1 -0
  601. package/dist/templates/kiro/index.js +28 -0
  602. package/dist/templates/kiro/index.js.map +1 -0
  603. package/dist/templates/markdown/agents.md +21 -0
  604. package/dist/templates/markdown/gitignore.txt +15 -0
  605. package/dist/templates/markdown/index.d.ts +27 -0
  606. package/dist/templates/markdown/index.d.ts.map +1 -0
  607. package/dist/templates/markdown/index.js +52 -0
  608. package/dist/templates/markdown/index.js.map +1 -0
  609. package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
  610. package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
  611. package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
  612. package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
  613. package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
  614. package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
  615. package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
  616. package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
  617. package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
  618. package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
  619. package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
  620. package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
  621. package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
  622. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +223 -0
  623. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +327 -0
  624. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +633 -0
  625. package/dist/templates/markdown/spec/guides/index.md.txt +97 -0
  626. package/dist/templates/markdown/workspace-index.md +125 -0
  627. package/dist/templates/markdown/worktree.yaml.txt +58 -0
  628. package/dist/templates/omp/agents/trellis-check.md +41 -0
  629. package/dist/templates/omp/agents/trellis-implement.md +55 -0
  630. package/dist/templates/omp/agents/trellis-research.md +30 -0
  631. package/dist/templates/omp/extensions/trellis/index.ts.txt +592 -0
  632. package/dist/templates/omp/index.d.ts +4 -0
  633. package/dist/templates/omp/index.d.ts.map +1 -0
  634. package/dist/templates/omp/index.js +9 -0
  635. package/dist/templates/omp/index.js.map +1 -0
  636. package/dist/templates/opencode/agents/trellis-check.md +122 -0
  637. package/dist/templates/opencode/agents/trellis-implement.md +123 -0
  638. package/dist/templates/opencode/agents/trellis-research.md +145 -0
  639. package/dist/templates/opencode/lib/context-visibility.js +86 -0
  640. package/dist/templates/opencode/lib/session-utils.js +526 -0
  641. package/dist/templates/opencode/lib/trellis-context.js +627 -0
  642. package/dist/templates/opencode/package.json +5 -0
  643. package/dist/templates/opencode/plugins/inject-spec-context.js +121 -0
  644. package/dist/templates/opencode/plugins/inject-subagent-context.js +569 -0
  645. package/dist/templates/opencode/plugins/inject-workflow-state.js +340 -0
  646. package/dist/templates/opencode/plugins/session-start.js +74 -0
  647. package/dist/templates/pi/agents/trellis-check.md +37 -0
  648. package/dist/templates/pi/agents/trellis-implement.md +52 -0
  649. package/dist/templates/pi/agents/trellis-research.md +25 -0
  650. package/dist/templates/pi/extensions/trellis/index.ts.txt +2033 -0
  651. package/dist/templates/pi/index.d.ts +5 -0
  652. package/dist/templates/pi/index.d.ts.map +1 -0
  653. package/dist/templates/pi/index.js +12 -0
  654. package/dist/templates/pi/index.js.map +1 -0
  655. package/dist/templates/pi/settings.json +9 -0
  656. package/dist/templates/qoder/agents/trellis-check.md +108 -0
  657. package/dist/templates/qoder/agents/trellis-implement.md +108 -0
  658. package/dist/templates/qoder/agents/trellis-research.md +137 -0
  659. package/dist/templates/qoder/index.d.ts +15 -0
  660. package/dist/templates/qoder/index.d.ts.map +1 -0
  661. package/dist/templates/qoder/index.js +15 -0
  662. package/dist/templates/qoder/index.js.map +1 -0
  663. package/dist/templates/qoder/settings.json +59 -0
  664. package/dist/templates/reasonix/agents/trellis-check.md +36 -0
  665. package/dist/templates/reasonix/agents/trellis-implement.md +51 -0
  666. package/dist/templates/reasonix/index.d.ts +13 -0
  667. package/dist/templates/reasonix/index.d.ts.map +1 -0
  668. package/dist/templates/reasonix/index.js +16 -0
  669. package/dist/templates/reasonix/index.js.map +1 -0
  670. package/dist/templates/shared-hooks/index.d.ts +83 -0
  671. package/dist/templates/shared-hooks/index.d.ts.map +1 -0
  672. package/dist/templates/shared-hooks/index.js +152 -0
  673. package/dist/templates/shared-hooks/index.js.map +1 -0
  674. package/dist/templates/shared-hooks/inject-shell-session-context.py +292 -0
  675. package/dist/templates/shared-hooks/inject-spec-context.py +844 -0
  676. package/dist/templates/shared-hooks/inject-subagent-context.py +1175 -0
  677. package/dist/templates/shared-hooks/inject-workflow-state.py +501 -0
  678. package/dist/templates/shared-hooks/session-start.py +969 -0
  679. package/dist/templates/snow/SNOW.md +86 -0
  680. package/dist/templates/snow/agents/trellis-check.md +136 -0
  681. package/dist/templates/snow/agents/trellis-implement.md +158 -0
  682. package/dist/templates/snow/agents/trellis-research.md +114 -0
  683. package/dist/templates/snow/hooks/beforeSubAgentStart.json +15 -0
  684. package/dist/templates/snow/hooks/onSessionStart.json +15 -0
  685. package/dist/templates/snow/hooks/onUserMessage.json +15 -0
  686. package/dist/templates/snow/hooks/write-trellis-context.py +644 -0
  687. package/dist/templates/snow/index.d.ts +26 -0
  688. package/dist/templates/snow/index.d.ts.map +1 -0
  689. package/dist/templates/snow/index.js +36 -0
  690. package/dist/templates/snow/index.js.map +1 -0
  691. package/dist/templates/template-utils.d.ts +26 -0
  692. package/dist/templates/template-utils.d.ts.map +1 -0
  693. package/dist/templates/template-utils.js +64 -0
  694. package/dist/templates/template-utils.js.map +1 -0
  695. package/dist/templates/trae/agents/trellis-check.md +108 -0
  696. package/dist/templates/trae/agents/trellis-implement.md +108 -0
  697. package/dist/templates/trae/agents/trellis-research.md +137 -0
  698. package/dist/templates/trae/hooks.json +39 -0
  699. package/dist/templates/trae/index.d.ts +15 -0
  700. package/dist/templates/trae/index.d.ts.map +1 -0
  701. package/dist/templates/trae/index.js +15 -0
  702. package/dist/templates/trae/index.js.map +1 -0
  703. package/dist/templates/trellis/agents/check.md +70 -0
  704. package/dist/templates/trellis/agents/implement.md +81 -0
  705. package/dist/templates/trellis/config.yaml +205 -0
  706. package/dist/templates/trellis/gitattributes.txt +9 -0
  707. package/dist/templates/trellis/gitignore.txt +32 -0
  708. package/dist/templates/trellis/index.d.ts +70 -0
  709. package/dist/templates/trellis/index.d.ts.map +1 -0
  710. package/dist/templates/trellis/index.js +127 -0
  711. package/dist/templates/trellis/index.js.map +1 -0
  712. package/dist/templates/trellis/scripts/__init__.py +5 -0
  713. package/dist/templates/trellis/scripts/add_session.py +681 -0
  714. package/dist/templates/trellis/scripts/common/__init__.py +92 -0
  715. package/dist/templates/trellis/scripts/common/active_task.py +787 -0
  716. package/dist/templates/trellis/scripts/common/cli_adapter.py +982 -0
  717. package/dist/templates/trellis/scripts/common/config.py +587 -0
  718. package/dist/templates/trellis/scripts/common/developer.py +190 -0
  719. package/dist/templates/trellis/scripts/common/git.py +74 -0
  720. package/dist/templates/trellis/scripts/common/git_context.py +138 -0
  721. package/dist/templates/trellis/scripts/common/io.py +61 -0
  722. package/dist/templates/trellis/scripts/common/log.py +45 -0
  723. package/dist/templates/trellis/scripts/common/packages_context.py +238 -0
  724. package/dist/templates/trellis/scripts/common/paths.py +508 -0
  725. package/dist/templates/trellis/scripts/common/safe_commit.py +315 -0
  726. package/dist/templates/trellis/scripts/common/session_context.py +892 -0
  727. package/dist/templates/trellis/scripts/common/spec_inject.py +439 -0
  728. package/dist/templates/trellis/scripts/common/spec_match.py +395 -0
  729. package/dist/templates/trellis/scripts/common/task_context.py +372 -0
  730. package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
  731. package/dist/templates/trellis/scripts/common/task_store.py +1016 -0
  732. package/dist/templates/trellis/scripts/common/task_utils.py +309 -0
  733. package/dist/templates/trellis/scripts/common/tasks.py +112 -0
  734. package/dist/templates/trellis/scripts/common/trellis_config.py +132 -0
  735. package/dist/templates/trellis/scripts/common/types.py +110 -0
  736. package/dist/templates/trellis/scripts/common/workflow_phase.py +243 -0
  737. package/dist/templates/trellis/scripts/common/workflow_selection.py +177 -0
  738. package/dist/templates/trellis/scripts/get_context.py +16 -0
  739. package/dist/templates/trellis/scripts/get_developer.py +26 -0
  740. package/dist/templates/trellis/scripts/hooks/linear_sync.py +243 -0
  741. package/dist/templates/trellis/scripts/init_developer.py +51 -0
  742. package/dist/templates/trellis/scripts/task.py +694 -0
  743. package/dist/templates/trellis/tasks/.gitkeep +0 -0
  744. package/dist/templates/trellis/workflow.md +777 -0
  745. package/dist/templates/zcode/agents/trellis-check.md +110 -0
  746. package/dist/templates/zcode/agents/trellis-implement.md +116 -0
  747. package/dist/templates/zcode/agents/trellis-research.md +133 -0
  748. package/dist/templates/zcode/config.json +52 -0
  749. package/dist/templates/zcode/index.d.ts +25 -0
  750. package/dist/templates/zcode/index.d.ts.map +1 -0
  751. package/dist/templates/zcode/index.js +29 -0
  752. package/dist/templates/zcode/index.js.map +1 -0
  753. package/dist/types/ai-tools.d.ts +95 -0
  754. package/dist/types/ai-tools.d.ts.map +1 -0
  755. package/dist/types/ai-tools.js +509 -0
  756. package/dist/types/ai-tools.js.map +1 -0
  757. package/dist/types/migration.d.ts +125 -0
  758. package/dist/types/migration.d.ts.map +1 -0
  759. package/dist/types/migration.js +8 -0
  760. package/dist/types/migration.js.map +1 -0
  761. package/dist/utils/agent-refs.d.ts +31 -0
  762. package/dist/utils/agent-refs.d.ts.map +1 -0
  763. package/dist/utils/agent-refs.js +63 -0
  764. package/dist/utils/agent-refs.js.map +1 -0
  765. package/dist/utils/atomic-write.d.ts +12 -0
  766. package/dist/utils/atomic-write.d.ts.map +1 -0
  767. package/dist/utils/atomic-write.js +30 -0
  768. package/dist/utils/atomic-write.js.map +1 -0
  769. package/dist/utils/compare-versions.d.ts +12 -0
  770. package/dist/utils/compare-versions.d.ts.map +1 -0
  771. package/dist/utils/compare-versions.js +86 -0
  772. package/dist/utils/compare-versions.js.map +1 -0
  773. package/dist/utils/cwd-guard.d.ts +38 -0
  774. package/dist/utils/cwd-guard.d.ts.map +1 -0
  775. package/dist/utils/cwd-guard.js +62 -0
  776. package/dist/utils/cwd-guard.js.map +1 -0
  777. package/dist/utils/file-writer.d.ts +36 -0
  778. package/dist/utils/file-writer.d.ts.map +1 -0
  779. package/dist/utils/file-writer.js +204 -0
  780. package/dist/utils/file-writer.js.map +1 -0
  781. package/dist/utils/manifest-prune.d.ts +61 -0
  782. package/dist/utils/manifest-prune.d.ts.map +1 -0
  783. package/dist/utils/manifest-prune.js +136 -0
  784. package/dist/utils/manifest-prune.js.map +1 -0
  785. package/dist/utils/posix.d.ts +13 -0
  786. package/dist/utils/posix.d.ts.map +1 -0
  787. package/dist/utils/posix.js +15 -0
  788. package/dist/utils/posix.js.map +1 -0
  789. package/dist/utils/project-detector.d.ts +46 -0
  790. package/dist/utils/project-detector.d.ts.map +1 -0
  791. package/dist/utils/project-detector.js +666 -0
  792. package/dist/utils/project-detector.js.map +1 -0
  793. package/dist/utils/proxy.d.ts +25 -0
  794. package/dist/utils/proxy.d.ts.map +1 -0
  795. package/dist/utils/proxy.js +60 -0
  796. package/dist/utils/proxy.js.map +1 -0
  797. package/dist/utils/registry-config.d.ts +7 -0
  798. package/dist/utils/registry-config.d.ts.map +1 -0
  799. package/dist/utils/registry-config.js +172 -0
  800. package/dist/utils/registry-config.js.map +1 -0
  801. package/dist/utils/task-json.d.ts +13 -0
  802. package/dist/utils/task-json.d.ts.map +1 -0
  803. package/dist/utils/task-json.js +12 -0
  804. package/dist/utils/task-json.js.map +1 -0
  805. package/dist/utils/template-fetcher.d.ts +161 -0
  806. package/dist/utils/template-fetcher.d.ts.map +1 -0
  807. package/dist/utils/template-fetcher.js +994 -0
  808. package/dist/utils/template-fetcher.js.map +1 -0
  809. package/dist/utils/template-hash.d.ts +123 -0
  810. package/dist/utils/template-hash.d.ts.map +1 -0
  811. package/dist/utils/template-hash.js +335 -0
  812. package/dist/utils/template-hash.js.map +1 -0
  813. package/dist/utils/uninstall-scrubbers.d.ts +67 -0
  814. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
  815. package/dist/utils/uninstall-scrubbers.js +361 -0
  816. package/dist/utils/uninstall-scrubbers.js.map +1 -0
  817. package/dist/utils/workflow-resolver.d.ts +86 -0
  818. package/dist/utils/workflow-resolver.d.ts.map +1 -0
  819. package/dist/utils/workflow-resolver.js +265 -0
  820. package/dist/utils/workflow-resolver.js.map +1 -0
  821. package/package.json +89 -0
@@ -0,0 +1,787 @@
1
+ #!/usr/bin/env python3
2
+ """Session-scoped active task resolution.
3
+
4
+ The user-facing concept is a single "active task". Trellis stores that pointer
5
+ per AI session/window under `.trellis/.runtime/sessions/`; without a stable
6
+ session key there is no active task.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import hashlib
12
+ import json
13
+ import os
14
+ import re
15
+ import sys
16
+ import time
17
+ from dataclasses import dataclass
18
+ from datetime import datetime, timezone
19
+ from pathlib import Path
20
+ from typing import Any
21
+
22
+ DIR_WORKFLOW = ".trellis"
23
+ DIR_TASKS = "tasks"
24
+ DIR_RUNTIME = ".runtime"
25
+ DIR_SESSIONS = "sessions"
26
+ DIR_SHELL_TICKETS = "shell-tickets"
27
+ # Pre-0.6.13 name, when the bridge was Cursor-only. Still read so a session that
28
+ # was mid-command across an upgrade does not silently degrade; never written.
29
+ # Tickets are 30-second ephemera, so the old directory ages out by itself —
30
+ # there is nothing to migrate, only a glob on a directory that is normally
31
+ # absent. The alternative (ignore it) would land its one lost command on the
32
+ # platform that works today.
33
+ DIR_LEGACY_CURSOR_SHELL_TICKETS = "cursor-shell"
34
+ SHELL_TICKET_TTL_SECONDS = 30
35
+ TASK_SESSION_COMMANDS = {"start", "current", "finish"}
36
+
37
+ _SESSION_KEYS = ("session_id", "sessionId", "sessionID")
38
+ _CONVERSATION_KEYS = ("conversation_id", "conversationId", "conversationID")
39
+ _TRANSCRIPT_KEYS = ("transcript_path", "transcriptPath", "transcript")
40
+ _NESTED_KEYS = ("input", "properties", "event", "hook_input", "hookInput")
41
+ _KNOWN_PLATFORMS = {
42
+ "claude",
43
+ "codex",
44
+ "cursor",
45
+ "opencode",
46
+ "gemini",
47
+ "droid",
48
+ "qoder",
49
+ "codebuddy",
50
+ "kiro",
51
+ "copilot",
52
+ "pi",
53
+ "trae",
54
+ "grok",
55
+ "kimi",
56
+ "zcode",
57
+ "snow",
58
+ "dsh",
59
+ }
60
+
61
+ # Every name below records how it was checked. Do NOT add a name by analogy
62
+ # with a neighbour: a 2026-08-05 audit of the then-current 21 platforms found
63
+ # 12 declared names had never existed anywhere — they were pattern-guessed from
64
+ # `<PLATFORM>_SESSION_ID` shape no vendor agreed to, and the uniformity was the
65
+ # only "evidence" behind them. A platform with no verified name belongs in no
66
+ # table; it resolves through TRELLIS_CONTEXT_ID or its hook/plugin bridge.
67
+ _ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
68
+ # REAL (reported 2026-08-13 against DSH 0.1.0-rc.6 by @SajoLuo, from a live
69
+ # run: DSH exports DSH_SESSION_ID plus DSH_SHELL=1 into its managed shell).
70
+ # MUST STAY FIRST. A DSH session can inherit an outer host's identity — a
71
+ # DSH launched from Codex still carries CODEX_THREAD_ID — and the untargeted
72
+ # lookup below walks this table in order, so any earlier entry would claim
73
+ # the session and write a foreign `codex_<thread>` pointer for DSH work.
74
+ # DSH_SESSION_ID is the only name here no other vendor sets, so first place
75
+ # is safe: it cannot mis-claim a non-DSH session.
76
+ ("dsh", ("DSH_SESSION_ID",)),
77
+ # REAL, undocumented (verified 2026-08-05 in a live Claude Code 2.1.221 bash
78
+ # child; absent from code.claude.com/docs/en/env-vars). CLAUDE_SESSION_ID
79
+ # was removed here — verified absent from that same live environment.
80
+ ("claude", ("CLAUDE_CODE_SESSION_ID",)),
81
+ # REAL, undocumented (verified 2026-08-05: injected by codex-cli 0.146.0
82
+ # into shell children, absent from the parent env; openai/codex#19937).
83
+ # CODEX_SESSION_ID was removed — absent from a live `codex exec` env.
84
+ ("codex", ("CODEX_THREAD_ID",)),
85
+ # REAL but HOOK-SCOPE ONLY (verified 2026-08-05): set by Gemini's
86
+ # hookRunner.ts. Its shell tool builds the child env in
87
+ # shellExecutionService.ts and adds only GEMINI_CLI/TERM/PAGER/GIT_PAGER, so
88
+ # this never reaches a bash child — it resolves only inside a hook process.
89
+ ("gemini", ("GEMINI_SESSION_ID",)),
90
+ # REAL but HOOK-SCOPE ONLY (verified 2026-08-05): docs.qoder.com/zh/
91
+ # extensions/hooks documents it as injected during hook execution by the
92
+ # Qoder *IDE plugin*. Absent from the Qoder CLI hook docs and from Lingma.
93
+ ("qoder", ("QODER_SESSION_ID",)),
94
+ # UNVERIFIED (2026-08-05): absent from kiro.dev/docs/hooks/, but Dynatrace
95
+ # dtctl, oh-my-agent and gastown all key agent detection on it and one notes
96
+ # it is "set in both interactive and --no-interactive". Kept because that is
97
+ # absence of evidence, not evidence of absence. To settle: run
98
+ # `env | grep KIRO` from a Kiro shell-tool call on a machine with Kiro.
99
+ ("kiro", ("KIRO_SESSION_ID",)),
100
+ # UNVERIFIED (2026-08-05): absent from docs.github.com/en/copilot/reference/
101
+ # hooks-reference and from the CLI programmatic reference. To settle: run
102
+ # `copilot help environment` (the authoritative list per those docs) — not
103
+ # runnable here, the CLI is not installed and copilot-cli ships no source.
104
+ ("copilot", ("COPILOT_SESSION_ID", "COPILOT_SESSIONID")),
105
+ # REASONED, UNVERIFIED (2026-08-05): ZCode is closed-source and not
106
+ # installable here. It mirrors Claude's naming elsewhere (CLAUDE_PLUGIN_ROOT
107
+ # / CLAUDE_PLUGIN_DATA compat aliases are in its docs), and the previously
108
+ # declared CLAUDE_SESSION_ID does not exist on Claude Code either — so the
109
+ # name ZCode would actually reuse is CLAUDE_CODE_SESSION_ID. Try that first,
110
+ # keep the historical name as a fallback: if neither exists nothing changes.
111
+ # Platform-scoped lookup (_iter_env_keys filters by platform name), so the
112
+ # entry only fires once the resolver detected "zcode" — no collision with
113
+ # the claude entry above.
114
+ ("zcode", ("CLAUDE_CODE_SESSION_ID", "CLAUDE_SESSION_ID")),
115
+ # REAL by vendor design (verified 2026-08-05): Snow's sessionIdentityEnv.ts
116
+ # exports SNOW_SESSION_ID into hook/terminal/sub-agent children and names
117
+ # Trellis in its source header. TRELLIS_CONTEXT_ID stays the preferred
118
+ # override — Snow sets that too.
119
+ ("snow", ("SNOW_SESSION_ID",)),
120
+ )
121
+ _ENV_CONVERSATION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
122
+ # REAL in cursor-agent (CLI), undocumented (verified 2026-08-05: the value
123
+ # matches ~/.cursor/chats/<ws>/<id>). The Cursor *IDE* is unverified — a
124
+ # 2026-05 forum request for it drew no staff reply. The invented
125
+ # CURSOR_SESSION_ID was removed from the session table: empty in a live
126
+ # cursor-agent shell. Cursor's other path is the shell ticket below
127
+ # (_lookup_shell_ticket_context_key), which is not Cursor-specific.
128
+ ("cursor", ("CURSOR_CONVERSATION_ID", "CURSOR_CONVERSATIONID")),
129
+ )
130
+ _ENV_TRANSCRIPT_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
131
+ # REAL but HOOK-SCOPE ONLY (verified 2026-08-05): documented for Cursor hook
132
+ # scripts; empty in the agent's own shell env.
133
+ ("cursor", ("CURSOR_TRANSCRIPT_PATH",)),
134
+ # UNVERIFIED — never researched. The 2026-08-05 audit covered the session
135
+ # table only, so do not infer these are real *or* fake from that work
136
+ # (CLAUDE_/CODEX_TRANSCRIPT_PATH were removed because those two *were*
137
+ # checked: absent from docs and from live envs). To settle each: run
138
+ # `env | grep _TRANSCRIPT_PATH` inside a hook and inside a shell-tool call.
139
+ ("gemini", ("GEMINI_TRANSCRIPT_PATH",)),
140
+ ("droid", ("FACTORY_TRANSCRIPT_PATH", "DROID_TRANSCRIPT_PATH")),
141
+ ("qoder", ("QODER_TRANSCRIPT_PATH",)),
142
+ ("codebuddy", ("CODEBUDDY_TRANSCRIPT_PATH",)),
143
+ )
144
+ _ENV_PLATFORM_ALIASES = {
145
+ "claude-code": "claude",
146
+ "factory": "droid",
147
+ "factory-ai": "droid",
148
+ "github-copilot": "copilot",
149
+ }
150
+ # ZCode intentionally reuses Claude's session env var name. Hooks know the host
151
+ # is ZCode, while later shell commands see only the shared env name and resolve
152
+ # it through the claude entry. Canonicalize both paths to one runtime filename.
153
+ _CONTEXT_KEY_PLATFORM_ALIASES = {
154
+ "zcode": "claude",
155
+ # Factory Droid's config directory is `.factory/`, so a hook that names its
156
+ # platform after the directory it was installed in reports "factory". Its
157
+ # sibling hooks report "droid". One runtime filename either way.
158
+ "factory": "droid",
159
+ }
160
+
161
+
162
+ @dataclass(frozen=True)
163
+ class ActiveTask:
164
+ """Resolved active task state."""
165
+
166
+ task_path: str | None
167
+ source_type: str
168
+ context_key: str | None = None
169
+ stale: bool = False
170
+
171
+ @property
172
+ def source(self) -> str:
173
+ """Human-readable source label."""
174
+ if self.source_type == "session" and self.context_key:
175
+ return f"session:{self.context_key}"
176
+ if self.source_type == "session-fallback" and self.context_key:
177
+ return f"session-fallback:{self.context_key}"
178
+ return self.source_type
179
+
180
+
181
+ def normalize_task_ref(task_ref: str) -> str:
182
+ """Normalize a task ref for stable storage and comparison."""
183
+ normalized = task_ref.strip()
184
+ if not normalized:
185
+ return ""
186
+
187
+ path_obj = Path(normalized)
188
+ if path_obj.is_absolute():
189
+ return str(path_obj)
190
+
191
+ normalized = normalized.replace("\\", "/")
192
+ while normalized.startswith("./"):
193
+ normalized = normalized[2:]
194
+
195
+ if normalized.startswith(f"{DIR_TASKS}/"):
196
+ return f"{DIR_WORKFLOW}/{normalized}"
197
+
198
+ return normalized
199
+
200
+
201
+ def resolve_task_ref(task_ref: str, repo_root: Path) -> Path | None:
202
+ """Resolve a task ref to an absolute task directory inside the repo.
203
+
204
+ Mirrors `paths.resolve_task_ref` (same containment check). Duplicated
205
+ rather than imported because this module is loaded standalone — hooks add
206
+ it to `sys.path` directly — so it stays zero-relative-import on purpose.
207
+ """
208
+ normalized = normalize_task_ref(task_ref)
209
+ if not normalized:
210
+ return None
211
+
212
+ path_obj = Path(normalized)
213
+ if path_obj.is_absolute():
214
+ candidate = path_obj
215
+ elif normalized.startswith(f"{DIR_WORKFLOW}/"):
216
+ candidate = repo_root / path_obj
217
+ else:
218
+ candidate = repo_root / DIR_WORKFLOW / DIR_TASKS / path_obj
219
+
220
+ # Both sides are resolved because repo_root itself may sit behind a
221
+ # symlink (/tmp on macOS does), and resolve() is what collapses `..`
222
+ # instead of leaving it for a lexical relative_to() to wave through.
223
+ try:
224
+ resolved = candidate.resolve()
225
+ root = repo_root.resolve()
226
+ except OSError:
227
+ return None
228
+
229
+ try:
230
+ resolved.relative_to(root)
231
+ except ValueError:
232
+ return None
233
+
234
+ return resolved
235
+
236
+
237
+ def _runtime_sessions_dir(repo_root: Path) -> Path:
238
+ return repo_root / DIR_WORKFLOW / DIR_RUNTIME / DIR_SESSIONS
239
+
240
+
241
+ def _sanitize_key(raw: str) -> str:
242
+ safe = re.sub(r"[^A-Za-z0-9._-]+", "_", raw.strip())
243
+ safe = safe.strip("._-")
244
+ return safe[:160] if safe else ""
245
+
246
+
247
+ def _hash_value(raw: str) -> str:
248
+ return hashlib.sha256(raw.encode("utf-8")).hexdigest()[:24]
249
+
250
+
251
+ def _as_dict(value: Any) -> dict[str, Any] | None:
252
+ return value if isinstance(value, dict) else None
253
+
254
+
255
+ def _string_value(value: Any) -> str | None:
256
+ if isinstance(value, str):
257
+ stripped = value.strip()
258
+ return stripped or None
259
+ return None
260
+
261
+
262
+ def _lookup_string(data: dict[str, Any], keys: tuple[str, ...]) -> str | None:
263
+ for key in keys:
264
+ value = _string_value(data.get(key))
265
+ if value:
266
+ return value
267
+
268
+ for nested_key in _NESTED_KEYS:
269
+ nested = _as_dict(data.get(nested_key))
270
+ if not nested:
271
+ continue
272
+ value = _lookup_string(nested, keys)
273
+ if value:
274
+ return value
275
+
276
+ return None
277
+
278
+
279
+ def _detect_platform(platform_input: dict[str, Any] | None, platform: str | None) -> str:
280
+ if platform:
281
+ return _sanitize_key(platform) or "session"
282
+ if platform_input:
283
+ for key in ("_trellis_platform", "trellis_platform", "platform", "source"):
284
+ value = _string_value(platform_input.get(key))
285
+ if value:
286
+ return _sanitize_key(value) or "session"
287
+ if _string_value(platform_input.get("cursor_version")):
288
+ return "cursor"
289
+ return "session"
290
+
291
+
292
+ def _context_key(platform_name: str, kind: str, value: str) -> str:
293
+ platform_name = _CONTEXT_KEY_PLATFORM_ALIASES.get(platform_name, platform_name)
294
+ if kind == "transcript":
295
+ return f"{platform_name}_transcript_{_hash_value(value)}"
296
+ safe_value = _sanitize_key(value)
297
+ if safe_value:
298
+ return f"{platform_name}_{safe_value}"
299
+ return f"{platform_name}_{_hash_value(value)}"
300
+
301
+
302
+ def _iter_env_keys(
303
+ env_keys: tuple[tuple[str, tuple[str, ...]], ...],
304
+ platform_name: str | None,
305
+ ) -> tuple[tuple[str, tuple[str, ...]], ...]:
306
+ """Narrow an env-key table to one platform, or return all of it.
307
+
308
+ A platform with no entry yields an empty tuple, and the caller's `for` loop
309
+ simply does not run. That is the normal case, not an error: platforms with
310
+ no verified env var name are deliberately absent from these tables.
311
+ """
312
+ if not platform_name:
313
+ return env_keys
314
+ matched = tuple((name, keys) for name, keys in env_keys if name == platform_name)
315
+ return matched
316
+
317
+
318
+ def _env_platform_name(platform_name: str | None) -> str | None:
319
+ if not platform_name or platform_name == "session":
320
+ return None
321
+ return _ENV_PLATFORM_ALIASES.get(platform_name, platform_name)
322
+
323
+
324
+ def _lookup_env_context_key(platform_name: str | None) -> str | None:
325
+ """Resolve a context key from platform-provided environment variables.
326
+
327
+ Hooks pass `TRELLIS_CONTEXT_ID` to subprocesses they launch, but an AI-run
328
+ shell command can only see session identity if the host platform exports it
329
+ in the command environment. These names are best-effort adapters; if none
330
+ are present, there is no session-scoped active task.
331
+ """
332
+ env_platform_name = _env_platform_name(platform_name)
333
+
334
+ for name, keys in _iter_env_keys(_ENV_SESSION_KEYS, env_platform_name):
335
+ for key in keys:
336
+ value = _string_value(os.environ.get(key))
337
+ if value:
338
+ return _context_key(name, "session", value)
339
+
340
+ for name, keys in _iter_env_keys(_ENV_CONVERSATION_KEYS, env_platform_name):
341
+ for key in keys:
342
+ value = _string_value(os.environ.get(key))
343
+ if value:
344
+ return _context_key(name, "conversation", value)
345
+
346
+ for name, keys in _iter_env_keys(_ENV_TRANSCRIPT_KEYS, env_platform_name):
347
+ for key in keys:
348
+ value = _string_value(os.environ.get(key))
349
+ if value:
350
+ return _context_key(name, "transcript", value)
351
+
352
+ return None
353
+
354
+
355
+ def _find_repo_root_from_cwd() -> Path | None:
356
+ current = Path.cwd().resolve()
357
+ while True:
358
+ if (current / DIR_WORKFLOW).is_dir():
359
+ return current
360
+ if current == current.parent:
361
+ return None
362
+ current = current.parent
363
+
364
+
365
+ def _shell_ticket_dirs(repo_root: Path) -> tuple[Path, ...]:
366
+ runtime_dir = repo_root / DIR_WORKFLOW / DIR_RUNTIME
367
+ return (
368
+ runtime_dir / DIR_SHELL_TICKETS,
369
+ runtime_dir / DIR_LEGACY_CURSOR_SHELL_TICKETS,
370
+ )
371
+
372
+
373
+ def _remove_file(path: Path) -> bool:
374
+ try:
375
+ path.unlink()
376
+ return True
377
+ except OSError:
378
+ return False
379
+
380
+
381
+ def _task_refs_match(left: str | None, right: str | None, repo_root: Path) -> bool:
382
+ if not left or not right:
383
+ return False
384
+ left_path = resolve_task_ref(left, repo_root)
385
+ right_path = resolve_task_ref(right, repo_root)
386
+ if left_path is not None and right_path is not None:
387
+ return left_path == right_path
388
+ return normalize_task_ref(left) == normalize_task_ref(right)
389
+
390
+
391
+ def _pending_ticket_matches_args(ticket: dict[str, Any], repo_root: Path) -> bool:
392
+ if Path(sys.argv[0]).name != "task.py":
393
+ return False
394
+ args = tuple(sys.argv[1:])
395
+ if not args:
396
+ return False
397
+
398
+ command_name = args[0]
399
+ if command_name not in TASK_SESSION_COMMANDS:
400
+ return False
401
+
402
+ subcommands = ticket.get("subcommands")
403
+ if not isinstance(subcommands, list):
404
+ return False
405
+
406
+ for subcommand in subcommands:
407
+ if not isinstance(subcommand, dict):
408
+ continue
409
+ if _string_value(subcommand.get("name")) != command_name:
410
+ continue
411
+ if command_name != "start":
412
+ return True
413
+ task_ref = args[1] if len(args) > 1 else None
414
+ if _task_refs_match(_string_value(subcommand.get("task_ref")), task_ref, repo_root):
415
+ return True
416
+
417
+ return False
418
+
419
+
420
+ def _ticket_is_fresh(ticket: dict[str, Any], ticket_path: Path, now: float) -> bool:
421
+ expires_at = ticket.get("expires_at_epoch")
422
+ if isinstance(expires_at, (int, float)) and expires_at < now:
423
+ _remove_file(ticket_path)
424
+ return False
425
+
426
+ created_at = ticket.get("created_at_epoch")
427
+ if isinstance(created_at, (int, float)):
428
+ if now - created_at <= SHELL_TICKET_TTL_SECONDS:
429
+ return True
430
+ _remove_file(ticket_path)
431
+ return False
432
+ return True
433
+
434
+
435
+ def _ticket_cwd_matches_repo(ticket: dict[str, Any], repo_root: Path) -> bool:
436
+ cwd = _string_value(ticket.get("cwd"))
437
+ if not cwd:
438
+ return True
439
+ try:
440
+ Path(cwd).resolve().relative_to(repo_root)
441
+ except ValueError:
442
+ return False
443
+ return True
444
+
445
+
446
+ def _matching_ticket_context_key(
447
+ ticket_path: Path,
448
+ repo_root: Path,
449
+ now: float,
450
+ ) -> str | None:
451
+ """Accept a ticket on its merits, never on which platform wrote it.
452
+
453
+ The `platform` field a ticket carries is debugging metadata; gating on it
454
+ was what kept this bridge invisible to every platform but Cursor.
455
+ """
456
+ ticket = _read_json(ticket_path)
457
+ if ticket is None:
458
+ return None
459
+ if not _ticket_is_fresh(ticket, ticket_path, now):
460
+ return None
461
+ if not _ticket_cwd_matches_repo(ticket, repo_root):
462
+ return None
463
+ if not _pending_ticket_matches_args(ticket, repo_root):
464
+ return None
465
+ return _string_value(ticket.get("context_key"))
466
+
467
+
468
+ def _lookup_shell_ticket_context_key() -> str | None:
469
+ """Resolve session identity from a short-lived shell ticket.
470
+
471
+ No researched platform exports its session id into a shell child, but every
472
+ hook-capable one hands that id to a hook. So the hook that runs just before
473
+ a shell command writes a ticket, and this reads it back. A ticket counts
474
+ only when it is fresh, was written for this repo, and matches the `task.py`
475
+ subcommand now running — and only when exactly one fresh context key
476
+ matches. Two concurrent windows therefore both degrade rather than one
477
+ inheriting the other's pointer.
478
+ """
479
+ repo_root = _find_repo_root_from_cwd()
480
+ if repo_root is None:
481
+ return None
482
+
483
+ now = time.time()
484
+ candidates: set[str] = set()
485
+ for ticket_dir in _shell_ticket_dirs(repo_root):
486
+ if not ticket_dir.is_dir():
487
+ continue
488
+ for ticket_path in ticket_dir.glob("*.json"):
489
+ context_key = _matching_ticket_context_key(ticket_path, repo_root, now)
490
+ if context_key:
491
+ candidates.add(context_key)
492
+
493
+ if len(candidates) == 1:
494
+ return next(iter(candidates))
495
+ return None
496
+
497
+
498
+ def resolve_context_key(
499
+ platform_input: dict[str, Any] | None = None,
500
+ platform: str | None = None,
501
+ *,
502
+ allow_environment_context: bool = True,
503
+ ) -> str | None:
504
+ """Resolve a stable session/window context key, if one is available.
505
+
506
+ `TRELLIS_CONTEXT_ID` is an explicit context-key override used by CLI
507
+ scripts and subprocesses. It does not store the task itself.
508
+ """
509
+ if allow_environment_context:
510
+ # The optional dsh-trellis plugin contributes this managed DSH_* value
511
+ # per shell execution from the current DSH session header. DSH scrubs
512
+ # ambient DSH_* values before rebuilding that namespace, so this value
513
+ # cannot be inherited from an outer Claude/Codex Trellis session. It
514
+ # must outrank the generic override below, which ordinary child
515
+ # processes inherit indiscriminately.
516
+ dsh_override = _string_value(os.environ.get("DSH_TRELLIS_CONTEXT_ID"))
517
+ if dsh_override:
518
+ return _sanitize_key(dsh_override) or _hash_value(dsh_override)
519
+
520
+ # A real DSH managed shell rebuilds the complete DSH_* namespace: the
521
+ # paired sentinel and session id cannot be inherited from an outer
522
+ # Trellis host. Prefer that canonical env-table identity over
523
+ # a generic override that ordinary process inheritance may carry in.
524
+ if (
525
+ _string_value(os.environ.get("DSH_SHELL")) == "1"
526
+ and _string_value(os.environ.get("DSH_SESSION_ID"))
527
+ ):
528
+ dsh_context_key = _lookup_env_context_key("dsh")
529
+ if dsh_context_key:
530
+ return dsh_context_key
531
+
532
+ override = _string_value(os.environ.get("TRELLIS_CONTEXT_ID"))
533
+ if override:
534
+ return _sanitize_key(override) or _hash_value(override)
535
+
536
+ data = _as_dict(platform_input)
537
+ platform_name = _detect_platform(data, platform) if data or platform else None
538
+
539
+ if data:
540
+ session_id = _lookup_string(data, _SESSION_KEYS)
541
+ if session_id:
542
+ return _context_key(platform_name or "session", "session", session_id)
543
+
544
+ conversation_id = _lookup_string(data, _CONVERSATION_KEYS)
545
+ if conversation_id:
546
+ return _context_key(platform_name or "session", "conversation", conversation_id)
547
+
548
+ transcript_path = _lookup_string(data, _TRANSCRIPT_KEYS)
549
+ if transcript_path:
550
+ return _context_key(platform_name or "session", "transcript", transcript_path)
551
+
552
+ if allow_environment_context:
553
+ env_context_key = _lookup_env_context_key(platform_name)
554
+ if env_context_key:
555
+ return env_context_key
556
+
557
+ # Last in the chain on purpose: a platform that genuinely exports identity
558
+ # into the shell outranks a ticket, and no platform name gates the lookup.
559
+ if allow_environment_context:
560
+ return _lookup_shell_ticket_context_key()
561
+ return None
562
+
563
+
564
+ def _read_json(path: Path) -> dict[str, Any] | None:
565
+ try:
566
+ data = json.loads(path.read_text(encoding="utf-8"))
567
+ except (FileNotFoundError, json.JSONDecodeError, OSError):
568
+ return None
569
+ return data if isinstance(data, dict) else None
570
+
571
+
572
+ def _write_json(path: Path, data: dict[str, Any]) -> bool:
573
+ try:
574
+ path.parent.mkdir(parents=True, exist_ok=True)
575
+ path.write_text(
576
+ json.dumps(data, indent=2, ensure_ascii=False) + "\n",
577
+ encoding="utf-8",
578
+ )
579
+ return True
580
+ except OSError:
581
+ return False
582
+
583
+
584
+ def _canonical_task_ref(task_path: str, repo_root: Path) -> str | None:
585
+ normalized = normalize_task_ref(task_path)
586
+ if not normalized:
587
+ return None
588
+ full_path = resolve_task_ref(normalized, repo_root)
589
+ if full_path is None or not full_path.is_dir():
590
+ return None
591
+ try:
592
+ return full_path.relative_to(repo_root.resolve()).as_posix()
593
+ except ValueError:
594
+ # resolve_task_ref already refused everything outside the repo, so this
595
+ # is unreachable. Refuse rather than fall back to an absolute path —
596
+ # that fallback is how an out-of-repo ref used to reach the session
597
+ # pointer and get replayed on every later turn.
598
+ return None
599
+
600
+
601
+ def _active_from_ref(
602
+ task_ref: str | None,
603
+ repo_root: Path,
604
+ source_type: str,
605
+ context_key: str | None = None,
606
+ ) -> ActiveTask | None:
607
+ if not task_ref:
608
+ return None
609
+ resolved = resolve_task_ref(task_ref, repo_root)
610
+ stale = resolved is None or not resolved.is_dir()
611
+ return ActiveTask(task_ref, source_type, context_key, stale)
612
+
613
+
614
+ def _context_path(repo_root: Path, context_key: str) -> Path:
615
+ return _runtime_sessions_dir(repo_root) / f"{context_key}.json"
616
+
617
+
618
+ def resolve_active_task(
619
+ repo_root: Path,
620
+ platform_input: dict[str, Any] | None = None,
621
+ platform: str | None = None,
622
+ *,
623
+ allow_single_session_fallback: bool = True,
624
+ allow_environment_context: bool = True,
625
+ ) -> ActiveTask:
626
+ """Resolve the active task from session runtime state only.
627
+
628
+ A stale session task is returned as stale. Missing context identity or a
629
+ missing/empty session context falls back to single-session inference: if
630
+ exactly one session file exists in the runtime, return its task with
631
+ source_type="session-fallback" — covers pull-based platform sub-agents
632
+ (copilot, gemini, qoder) that don't inherit the parent's session id. ≥2
633
+ files or 0 files yield ActiveTask(None) — refuses to guess across windows.
634
+ """
635
+ context_key = resolve_context_key(
636
+ platform_input,
637
+ platform,
638
+ allow_environment_context=allow_environment_context,
639
+ )
640
+ if context_key:
641
+ context = _read_json(_context_path(repo_root, context_key)) or {}
642
+ task_ref = _string_value(context.get("current_task"))
643
+ active = _active_from_ref(task_ref, repo_root, "session", context_key)
644
+ if active:
645
+ return active
646
+
647
+ if allow_single_session_fallback:
648
+ fallback = _resolve_single_session_fallback(repo_root)
649
+ if fallback is not None:
650
+ return fallback
651
+
652
+ return ActiveTask(None, "none", context_key)
653
+
654
+
655
+ def _resolve_single_session_fallback(repo_root: Path) -> ActiveTask | None:
656
+ """Return the task pointed at by the sole session file, if exactly one exists.
657
+
658
+ Used when context-key resolution fails (typical for class-2 platform
659
+ sub-agents). Returns None if 0 or ≥2 session files are present — refuses
660
+ to pick across windows so 04-21's multi-session isolation contract holds.
661
+ """
662
+ sessions_dir = _runtime_sessions_dir(repo_root)
663
+ if not sessions_dir.is_dir():
664
+ return None
665
+
666
+ session_files = sorted(sessions_dir.glob("*.json"))
667
+ if len(session_files) != 1:
668
+ return None
669
+
670
+ session_file = session_files[0]
671
+ context = _read_json(session_file) or {}
672
+ task_ref = _string_value(context.get("current_task"))
673
+ if not task_ref:
674
+ return None
675
+
676
+ fallback_key = session_file.stem
677
+ return _active_from_ref(task_ref, repo_root, "session-fallback", fallback_key)
678
+
679
+
680
+ def _utc_now() -> str:
681
+ return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z")
682
+
683
+
684
+ def _context_metadata(
685
+ platform_input: dict[str, Any] | None,
686
+ platform: str | None,
687
+ context_key: str | None = None,
688
+ ) -> dict[str, Any]:
689
+ data = _as_dict(platform_input) or {}
690
+ platform_name = _detect_platform(data, platform)
691
+ if platform_name == "session" and context_key:
692
+ prefix = context_key.split("_", 1)[0]
693
+ if prefix in _KNOWN_PLATFORMS:
694
+ platform_name = prefix
695
+ metadata: dict[str, Any] = {
696
+ "platform": platform_name,
697
+ "last_seen_at": _utc_now(),
698
+ }
699
+ for key in (*_SESSION_KEYS, *_CONVERSATION_KEYS, *_TRANSCRIPT_KEYS):
700
+ value = _lookup_string(data, (key,))
701
+ if value:
702
+ metadata[key] = value
703
+ return metadata
704
+
705
+
706
+ def set_active_task(
707
+ task_path: str,
708
+ repo_root: Path,
709
+ platform_input: dict[str, Any] | None = None,
710
+ platform: str | None = None,
711
+ ) -> ActiveTask | None:
712
+ """Set the active task in session scope.
713
+
714
+ Returns None when no context key is available; callers should surface a
715
+ user-facing error that explains how to provide session identity.
716
+ """
717
+ canonical = _canonical_task_ref(task_path, repo_root)
718
+ if canonical is None:
719
+ return None
720
+
721
+ context_key = resolve_context_key(platform_input, platform)
722
+ if not context_key:
723
+ return None
724
+
725
+ context_path = _context_path(repo_root, context_key)
726
+ context = _read_json(context_path) or {}
727
+ context.update(_context_metadata(platform_input, platform, context_key))
728
+ context["current_task"] = canonical
729
+ context.setdefault("current_run", None)
730
+ if not _write_json(context_path, context):
731
+ return None
732
+ return ActiveTask(canonical, "session", context_key)
733
+
734
+
735
+ def clear_active_task(
736
+ repo_root: Path,
737
+ platform_input: dict[str, Any] | None = None,
738
+ platform: str | None = None,
739
+ ) -> ActiveTask:
740
+ """Clear the active task by deleting its resolved session context file."""
741
+ context_key = resolve_context_key(platform_input, platform)
742
+ if not context_key:
743
+ return ActiveTask(None, "none")
744
+
745
+ previous = resolve_active_task(repo_root, platform_input, platform)
746
+ if not previous.task_path or not previous.context_key:
747
+ return previous
748
+
749
+ context_path = _context_path(repo_root, previous.context_key)
750
+ if context_path.is_file():
751
+ _remove_file(context_path)
752
+ return previous
753
+
754
+
755
+ def clear_task_from_sessions(task_path: str, repo_root: Path) -> int:
756
+ """Delete all session runtime files that point at a task."""
757
+ target = _canonical_task_ref(task_path, repo_root) or normalize_task_ref(task_path)
758
+ if not target:
759
+ return 0
760
+
761
+ cleared = 0
762
+ sessions_dir = _runtime_sessions_dir(repo_root)
763
+ if not sessions_dir.is_dir():
764
+ return cleared
765
+
766
+ for session_path in sessions_dir.glob("*.json"):
767
+ context = _read_json(session_path) or {}
768
+ current = _string_value(context.get("current_task"))
769
+ if not current:
770
+ continue
771
+ current_ref = _canonical_task_ref(current, repo_root) or normalize_task_ref(current)
772
+ if current_ref != target:
773
+ continue
774
+ if session_path.is_file() and _remove_file(session_path):
775
+ cleared += 1
776
+
777
+ return cleared
778
+
779
+
780
+ def get_current_task_source(
781
+ repo_root: Path,
782
+ platform_input: dict[str, Any] | None = None,
783
+ platform: str | None = None,
784
+ ) -> tuple[str, str | None, str | None]:
785
+ """Return (`source_type`, `context_key`, `task_path`) for compatibility."""
786
+ active = resolve_active_task(repo_root, platform_input, platform)
787
+ return active.source_type, active.context_key, active.task_path