@ibotor/smart-trellis 0.5.19

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 (520) hide show
  1. package/LICENSE +235 -0
  2. package/README.md +263 -0
  3. package/bin/smart-trellis.js +3 -0
  4. package/bin/trellis.js +3 -0
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/index.d.ts.map +1 -0
  7. package/dist/cli/index.js +132 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/cli/smart.d.ts +2 -0
  10. package/dist/cli/smart.d.ts.map +1 -0
  11. package/dist/cli/smart.js +41 -0
  12. package/dist/cli/smart.js.map +1 -0
  13. package/dist/commands/init.d.ts +56 -0
  14. package/dist/commands/init.d.ts.map +1 -0
  15. package/dist/commands/init.js +1466 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/smart-init.d.ts +22 -0
  18. package/dist/commands/smart-init.d.ts.map +1 -0
  19. package/dist/commands/smart-init.js +122 -0
  20. package/dist/commands/smart-init.js.map +1 -0
  21. package/dist/commands/uninstall.d.ts +27 -0
  22. package/dist/commands/uninstall.d.ts.map +1 -0
  23. package/dist/commands/uninstall.js +339 -0
  24. package/dist/commands/uninstall.js.map +1 -0
  25. package/dist/commands/update.d.ts +72 -0
  26. package/dist/commands/update.d.ts.map +1 -0
  27. package/dist/commands/update.js +1926 -0
  28. package/dist/commands/update.js.map +1 -0
  29. package/dist/configurators/antigravity.d.ts +7 -0
  30. package/dist/configurators/antigravity.d.ts.map +1 -0
  31. package/dist/configurators/antigravity.js +19 -0
  32. package/dist/configurators/antigravity.js.map +1 -0
  33. package/dist/configurators/claude.d.ts +9 -0
  34. package/dist/configurators/claude.d.ts.map +1 -0
  35. package/dist/configurators/claude.js +72 -0
  36. package/dist/configurators/claude.js.map +1 -0
  37. package/dist/configurators/codebuddy.d.ts +10 -0
  38. package/dist/configurators/codebuddy.d.ts.map +1 -0
  39. package/dist/configurators/codebuddy.js +30 -0
  40. package/dist/configurators/codebuddy.js.map +1 -0
  41. package/dist/configurators/codex.d.ts +8 -0
  42. package/dist/configurators/codex.d.ts.map +1 -0
  43. package/dist/configurators/codex.js +85 -0
  44. package/dist/configurators/codex.js.map +1 -0
  45. package/dist/configurators/copilot.d.ts +10 -0
  46. package/dist/configurators/copilot.d.ts.map +1 -0
  47. package/dist/configurators/copilot.js +51 -0
  48. package/dist/configurators/copilot.js.map +1 -0
  49. package/dist/configurators/cursor.d.ts +10 -0
  50. package/dist/configurators/cursor.d.ts.map +1 -0
  51. package/dist/configurators/cursor.js +29 -0
  52. package/dist/configurators/cursor.js.map +1 -0
  53. package/dist/configurators/droid.d.ts +10 -0
  54. package/dist/configurators/droid.d.ts.map +1 -0
  55. package/dist/configurators/droid.js +30 -0
  56. package/dist/configurators/droid.js.map +1 -0
  57. package/dist/configurators/gemini.d.ts +16 -0
  58. package/dist/configurators/gemini.d.ts.map +1 -0
  59. package/dist/configurators/gemini.js +38 -0
  60. package/dist/configurators/gemini.js.map +1 -0
  61. package/dist/configurators/index.d.ts +65 -0
  62. package/dist/configurators/index.d.ts.map +1 -0
  63. package/dist/configurators/index.js +367 -0
  64. package/dist/configurators/index.js.map +1 -0
  65. package/dist/configurators/kilo.d.ts +7 -0
  66. package/dist/configurators/kilo.d.ts.map +1 -0
  67. package/dist/configurators/kilo.js +19 -0
  68. package/dist/configurators/kilo.js.map +1 -0
  69. package/dist/configurators/kiro.d.ts +8 -0
  70. package/dist/configurators/kiro.d.ts.map +1 -0
  71. package/dist/configurators/kiro.js +24 -0
  72. package/dist/configurators/kiro.js.map +1 -0
  73. package/dist/configurators/opencode.d.ts +14 -0
  74. package/dist/configurators/opencode.d.ts.map +1 -0
  75. package/dist/configurators/opencode.js +96 -0
  76. package/dist/configurators/opencode.js.map +1 -0
  77. package/dist/configurators/pi.d.ts +3 -0
  78. package/dist/configurators/pi.d.ts.map +1 -0
  79. package/dist/configurators/pi.js +45 -0
  80. package/dist/configurators/pi.js.map +1 -0
  81. package/dist/configurators/qoder.d.ts +11 -0
  82. package/dist/configurators/qoder.d.ts.map +1 -0
  83. package/dist/configurators/qoder.js +31 -0
  84. package/dist/configurators/qoder.js.map +1 -0
  85. package/dist/configurators/shared.d.ts +178 -0
  86. package/dist/configurators/shared.d.ts.map +1 -0
  87. package/dist/configurators/shared.js +538 -0
  88. package/dist/configurators/shared.js.map +1 -0
  89. package/dist/configurators/windsurf.d.ts +7 -0
  90. package/dist/configurators/windsurf.d.ts.map +1 -0
  91. package/dist/configurators/windsurf.js +19 -0
  92. package/dist/configurators/windsurf.js.map +1 -0
  93. package/dist/configurators/workflow.d.ts +29 -0
  94. package/dist/configurators/workflow.d.ts.map +1 -0
  95. package/dist/configurators/workflow.js +163 -0
  96. package/dist/configurators/workflow.js.map +1 -0
  97. package/dist/constants/paths.d.ts +70 -0
  98. package/dist/constants/paths.d.ts.map +1 -0
  99. package/dist/constants/paths.js +79 -0
  100. package/dist/constants/paths.js.map +1 -0
  101. package/dist/constants/version.d.ts +9 -0
  102. package/dist/constants/version.d.ts.map +1 -0
  103. package/dist/constants/version.js +15 -0
  104. package/dist/constants/version.js.map +1 -0
  105. package/dist/index.d.ts +10 -0
  106. package/dist/index.d.ts.map +1 -0
  107. package/dist/index.js +10 -0
  108. package/dist/index.js.map +1 -0
  109. package/dist/migrations/index.d.ts +62 -0
  110. package/dist/migrations/index.d.ts.map +1 -0
  111. package/dist/migrations/index.js +187 -0
  112. package/dist/migrations/index.js.map +1 -0
  113. package/dist/migrations/manifests/0.1.9.json +30 -0
  114. package/dist/migrations/manifests/0.2.0.json +49 -0
  115. package/dist/migrations/manifests/0.2.12.json +9 -0
  116. package/dist/migrations/manifests/0.2.13.json +9 -0
  117. package/dist/migrations/manifests/0.2.14.json +175 -0
  118. package/dist/migrations/manifests/0.2.15.json +33 -0
  119. package/dist/migrations/manifests/0.3.0-beta.0.json +297 -0
  120. package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
  121. package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
  122. package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
  123. package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
  124. package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
  125. package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
  126. package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
  127. package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
  128. package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
  129. package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
  130. package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
  131. package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
  132. package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
  133. package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
  134. package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
  135. package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
  136. package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
  137. package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
  138. package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
  139. package/dist/migrations/manifests/0.3.0-rc.3.json +9 -0
  140. package/dist/migrations/manifests/0.3.0-rc.4.json +9 -0
  141. package/dist/migrations/manifests/0.3.0-rc.5.json +9 -0
  142. package/dist/migrations/manifests/0.3.0-rc.6.json +9 -0
  143. package/dist/migrations/manifests/0.3.0.json +11 -0
  144. package/dist/migrations/manifests/0.3.1.json +9 -0
  145. package/dist/migrations/manifests/0.3.10.json +9 -0
  146. package/dist/migrations/manifests/0.3.2.json +9 -0
  147. package/dist/migrations/manifests/0.3.3.json +9 -0
  148. package/dist/migrations/manifests/0.3.4.json +21 -0
  149. package/dist/migrations/manifests/0.3.5.json +9 -0
  150. package/dist/migrations/manifests/0.3.6.json +9 -0
  151. package/dist/migrations/manifests/0.3.7.json +9 -0
  152. package/dist/migrations/manifests/0.3.8.json +9 -0
  153. package/dist/migrations/manifests/0.3.9.json +9 -0
  154. package/dist/migrations/manifests/0.4.0-beta.1.json +228 -0
  155. package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
  156. package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
  157. package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
  158. package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
  159. package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
  160. package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
  161. package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
  162. package/dist/migrations/manifests/0.4.0-beta.8.json +34 -0
  163. package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
  164. package/dist/migrations/manifests/0.4.0-rc.0.json +9 -0
  165. package/dist/migrations/manifests/0.4.0-rc.1.json +9 -0
  166. package/dist/migrations/manifests/0.4.0.json +9 -0
  167. package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
  168. package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
  169. package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
  170. package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
  171. package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
  172. package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
  173. package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
  174. package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
  175. package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
  176. package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
  177. package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
  178. package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
  179. package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
  180. package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
  181. package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
  182. package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
  183. package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
  184. package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
  185. package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
  186. package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
  187. package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
  188. package/dist/migrations/manifests/0.5.0-rc.1.json +9 -0
  189. package/dist/migrations/manifests/0.5.0-rc.2.json +9 -0
  190. package/dist/migrations/manifests/0.5.0-rc.3.json +9 -0
  191. package/dist/migrations/manifests/0.5.0-rc.4.json +9 -0
  192. package/dist/migrations/manifests/0.5.0-rc.5.json +9 -0
  193. package/dist/migrations/manifests/0.5.0-rc.6.json +9 -0
  194. package/dist/migrations/manifests/0.5.0-rc.7.json +9 -0
  195. package/dist/migrations/manifests/0.5.0.json +9 -0
  196. package/dist/migrations/manifests/0.5.1.json +9 -0
  197. package/dist/migrations/manifests/0.5.10.json +9 -0
  198. package/dist/migrations/manifests/0.5.11.json +16 -0
  199. package/dist/migrations/manifests/0.5.12.json +9 -0
  200. package/dist/migrations/manifests/0.5.13.json +9 -0
  201. package/dist/migrations/manifests/0.5.14.json +9 -0
  202. package/dist/migrations/manifests/0.5.15.json +9 -0
  203. package/dist/migrations/manifests/0.5.16.json +9 -0
  204. package/dist/migrations/manifests/0.5.17.json +9 -0
  205. package/dist/migrations/manifests/0.5.18.json +9 -0
  206. package/dist/migrations/manifests/0.5.19.json +9 -0
  207. package/dist/migrations/manifests/0.5.2.json +9 -0
  208. package/dist/migrations/manifests/0.5.3.json +9 -0
  209. package/dist/migrations/manifests/0.5.4.json +9 -0
  210. package/dist/migrations/manifests/0.5.5.json +9 -0
  211. package/dist/migrations/manifests/0.5.6.json +9 -0
  212. package/dist/migrations/manifests/0.5.7.json +16 -0
  213. package/dist/migrations/manifests/0.5.8.json +9 -0
  214. package/dist/migrations/manifests/0.5.9.json +9 -0
  215. package/dist/migrations/manifests/0.6.0-beta.0.json +16 -0
  216. package/dist/migrations/manifests/0.6.0-beta.1.json +9 -0
  217. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  218. package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
  219. package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
  220. package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
  221. package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
  222. package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
  223. package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
  224. package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
  225. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  226. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  227. package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
  228. package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
  229. package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
  230. package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
  231. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  232. package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
  233. package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
  234. package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
  235. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  236. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  237. package/dist/templates/claude/agents/trellis-check.md +109 -0
  238. package/dist/templates/claude/agents/trellis-implement.md +109 -0
  239. package/dist/templates/claude/agents/trellis-research.md +137 -0
  240. package/dist/templates/claude/index.d.ts +22 -0
  241. package/dist/templates/claude/index.d.ts.map +1 -0
  242. package/dist/templates/claude/index.js +46 -0
  243. package/dist/templates/claude/index.js.map +1 -0
  244. package/dist/templates/claude/settings.json +73 -0
  245. package/dist/templates/codebuddy/agents/trellis-check.md +109 -0
  246. package/dist/templates/codebuddy/agents/trellis-implement.md +109 -0
  247. package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
  248. package/dist/templates/codebuddy/index.d.ts +15 -0
  249. package/dist/templates/codebuddy/index.d.ts.map +1 -0
  250. package/dist/templates/codebuddy/index.js +15 -0
  251. package/dist/templates/codebuddy/index.js.map +1 -0
  252. package/dist/templates/codebuddy/settings.json +59 -0
  253. package/dist/templates/codex/agents/trellis-check.toml +84 -0
  254. package/dist/templates/codex/agents/trellis-implement.toml +65 -0
  255. package/dist/templates/codex/agents/trellis-research.toml +73 -0
  256. package/dist/templates/codex/config.toml +28 -0
  257. package/dist/templates/codex/hooks/session-start.py +481 -0
  258. package/dist/templates/codex/hooks.json +15 -0
  259. package/dist/templates/codex/index.d.ts +39 -0
  260. package/dist/templates/codex/index.d.ts.map +1 -0
  261. package/dist/templates/codex/index.js +85 -0
  262. package/dist/templates/codex/index.js.map +1 -0
  263. package/dist/templates/codex/skills/before-dev/SKILL.md +34 -0
  264. package/dist/templates/codex/skills/brainstorm/SKILL.md +500 -0
  265. package/dist/templates/codex/skills/break-loop/SKILL.md +130 -0
  266. package/dist/templates/codex/skills/check/SKILL.md +30 -0
  267. package/dist/templates/codex/skills/check-cross-layer/SKILL.md +158 -0
  268. package/dist/templates/codex/skills/create-command/SKILL.md +101 -0
  269. package/dist/templates/codex/skills/finish-work/SKILL.md +90 -0
  270. package/dist/templates/codex/skills/improve-ut/SKILL.md +69 -0
  271. package/dist/templates/codex/skills/integrate-skill/SKILL.md +221 -0
  272. package/dist/templates/codex/skills/onboard/SKILL.md +363 -0
  273. package/dist/templates/codex/skills/record-session/SKILL.md +67 -0
  274. package/dist/templates/codex/skills/start/SKILL.md +354 -0
  275. package/dist/templates/codex/skills/update-spec/SKILL.md +335 -0
  276. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
  277. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
  278. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
  279. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +81 -0
  280. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
  281. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
  282. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
  283. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
  284. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +64 -0
  285. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
  286. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
  287. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
  288. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
  289. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
  290. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +101 -0
  291. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
  292. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
  293. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +79 -0
  294. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
  295. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
  296. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
  297. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
  298. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/SKILL.md +41 -0
  299. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/mcp-setup.md +90 -0
  300. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/repository-analysis.md +59 -0
  301. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-task-planning.md +61 -0
  302. package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-writing.md +70 -0
  303. package/dist/templates/common/commands/continue.md +55 -0
  304. package/dist/templates/common/commands/finish-work.md +66 -0
  305. package/dist/templates/common/commands/start.md +58 -0
  306. package/dist/templates/common/index.d.ts +48 -0
  307. package/dist/templates/common/index.d.ts.map +1 -0
  308. package/dist/templates/common/index.js +104 -0
  309. package/dist/templates/common/index.js.map +1 -0
  310. package/dist/templates/common/skills/before-dev.md +29 -0
  311. package/dist/templates/common/skills/brainstorm.md +543 -0
  312. package/dist/templates/common/skills/break-loop.md +125 -0
  313. package/dist/templates/common/skills/check.md +87 -0
  314. package/dist/templates/common/skills/update-spec.md +351 -0
  315. package/dist/templates/copilot/hooks/session-start.py +454 -0
  316. package/dist/templates/copilot/hooks.json +19 -0
  317. package/dist/templates/copilot/index.d.ts +23 -0
  318. package/dist/templates/copilot/index.d.ts.map +1 -0
  319. package/dist/templates/copilot/index.js +54 -0
  320. package/dist/templates/copilot/index.js.map +1 -0
  321. package/dist/templates/copilot/prompts/before-dev.prompt.md +33 -0
  322. package/dist/templates/copilot/prompts/brainstorm.prompt.md +499 -0
  323. package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
  324. package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +157 -0
  325. package/dist/templates/copilot/prompts/check.prompt.md +29 -0
  326. package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
  327. package/dist/templates/copilot/prompts/finish-work.prompt.md +99 -0
  328. package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
  329. package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
  330. package/dist/templates/copilot/prompts/parallel.prompt.md +196 -0
  331. package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
  332. package/dist/templates/copilot/prompts/start.prompt.md +397 -0
  333. package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
  334. package/dist/templates/cursor/agents/trellis-check.md +108 -0
  335. package/dist/templates/cursor/agents/trellis-implement.md +108 -0
  336. package/dist/templates/cursor/agents/trellis-research.md +136 -0
  337. package/dist/templates/cursor/hooks.json +24 -0
  338. package/dist/templates/cursor/index.d.ts +13 -0
  339. package/dist/templates/cursor/index.d.ts.map +1 -0
  340. package/dist/templates/cursor/index.js +13 -0
  341. package/dist/templates/cursor/index.js.map +1 -0
  342. package/dist/templates/droid/droids/trellis-check.md +101 -0
  343. package/dist/templates/droid/droids/trellis-implement.md +101 -0
  344. package/dist/templates/droid/droids/trellis-research.md +137 -0
  345. package/dist/templates/droid/index.d.ts +15 -0
  346. package/dist/templates/droid/index.d.ts.map +1 -0
  347. package/dist/templates/droid/index.js +15 -0
  348. package/dist/templates/droid/index.js.map +1 -0
  349. package/dist/templates/droid/settings.json +59 -0
  350. package/dist/templates/extract.d.ts +40 -0
  351. package/dist/templates/extract.d.ts.map +1 -0
  352. package/dist/templates/extract.js +106 -0
  353. package/dist/templates/extract.js.map +1 -0
  354. package/dist/templates/gemini/agents/trellis-check.md +101 -0
  355. package/dist/templates/gemini/agents/trellis-implement.md +101 -0
  356. package/dist/templates/gemini/agents/trellis-research.md +136 -0
  357. package/dist/templates/gemini/index.d.ts +13 -0
  358. package/dist/templates/gemini/index.d.ts.map +1 -0
  359. package/dist/templates/gemini/index.js +13 -0
  360. package/dist/templates/gemini/index.js.map +1 -0
  361. package/dist/templates/gemini/settings.json +28 -0
  362. package/dist/templates/kiro/agents/trellis-check.json +26 -0
  363. package/dist/templates/kiro/agents/trellis-implement.json +26 -0
  364. package/dist/templates/kiro/agents/trellis-research.json +30 -0
  365. package/dist/templates/kiro/index.d.ts +18 -0
  366. package/dist/templates/kiro/index.d.ts.map +1 -0
  367. package/dist/templates/kiro/index.js +18 -0
  368. package/dist/templates/kiro/index.js.map +1 -0
  369. package/dist/templates/markdown/agents.md +21 -0
  370. package/dist/templates/markdown/gitignore.txt +15 -0
  371. package/dist/templates/markdown/index.d.ts +27 -0
  372. package/dist/templates/markdown/index.d.ts.map +1 -0
  373. package/dist/templates/markdown/index.js +52 -0
  374. package/dist/templates/markdown/index.js.map +1 -0
  375. package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
  376. package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
  377. package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
  378. package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
  379. package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
  380. package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
  381. package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
  382. package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
  383. package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
  384. package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
  385. package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
  386. package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
  387. package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
  388. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +105 -0
  389. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +162 -0
  390. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +595 -0
  391. package/dist/templates/markdown/spec/guides/index.md.txt +79 -0
  392. package/dist/templates/markdown/workspace-index.md +125 -0
  393. package/dist/templates/markdown/worktree.yaml.txt +58 -0
  394. package/dist/templates/opencode/agents/trellis-check.md +116 -0
  395. package/dist/templates/opencode/agents/trellis-implement.md +117 -0
  396. package/dist/templates/opencode/agents/trellis-research.md +145 -0
  397. package/dist/templates/opencode/lib/session-utils.js +432 -0
  398. package/dist/templates/opencode/lib/trellis-context.js +381 -0
  399. package/dist/templates/opencode/package.json +5 -0
  400. package/dist/templates/opencode/plugins/inject-subagent-context.js +497 -0
  401. package/dist/templates/opencode/plugins/inject-workflow-state.js +162 -0
  402. package/dist/templates/opencode/plugins/session-start.js +101 -0
  403. package/dist/templates/pi/agents/trellis-check.md +36 -0
  404. package/dist/templates/pi/agents/trellis-implement.md +41 -0
  405. package/dist/templates/pi/agents/trellis-research.md +25 -0
  406. package/dist/templates/pi/extensions/trellis/index.ts.txt +1172 -0
  407. package/dist/templates/pi/index.d.ts +5 -0
  408. package/dist/templates/pi/index.d.ts.map +1 -0
  409. package/dist/templates/pi/index.js +12 -0
  410. package/dist/templates/pi/index.js.map +1 -0
  411. package/dist/templates/pi/settings.json +21 -0
  412. package/dist/templates/qoder/agents/trellis-check.md +102 -0
  413. package/dist/templates/qoder/agents/trellis-implement.md +102 -0
  414. package/dist/templates/qoder/agents/trellis-research.md +137 -0
  415. package/dist/templates/qoder/index.d.ts +15 -0
  416. package/dist/templates/qoder/index.d.ts.map +1 -0
  417. package/dist/templates/qoder/index.js +15 -0
  418. package/dist/templates/qoder/index.js.map +1 -0
  419. package/dist/templates/qoder/settings.json +47 -0
  420. package/dist/templates/shared-hooks/index.d.ts +50 -0
  421. package/dist/templates/shared-hooks/index.d.ts.map +1 -0
  422. package/dist/templates/shared-hooks/index.js +88 -0
  423. package/dist/templates/shared-hooks/index.js.map +1 -0
  424. package/dist/templates/shared-hooks/inject-shell-session-context.py +183 -0
  425. package/dist/templates/shared-hooks/inject-subagent-context.py +749 -0
  426. package/dist/templates/shared-hooks/inject-workflow-state.py +387 -0
  427. package/dist/templates/shared-hooks/session-start.py +797 -0
  428. package/dist/templates/template-utils.d.ts +26 -0
  429. package/dist/templates/template-utils.d.ts.map +1 -0
  430. package/dist/templates/template-utils.js +60 -0
  431. package/dist/templates/template-utils.js.map +1 -0
  432. package/dist/templates/trellis/config.yaml +90 -0
  433. package/dist/templates/trellis/gitignore.txt +32 -0
  434. package/dist/templates/trellis/index.d.ts +52 -0
  435. package/dist/templates/trellis/index.d.ts.map +1 -0
  436. package/dist/templates/trellis/index.js +97 -0
  437. package/dist/templates/trellis/index.js.map +1 -0
  438. package/dist/templates/trellis/scripts/__init__.py +5 -0
  439. package/dist/templates/trellis/scripts/add_session.py +547 -0
  440. package/dist/templates/trellis/scripts/common/__init__.py +92 -0
  441. package/dist/templates/trellis/scripts/common/active_task.py +626 -0
  442. package/dist/templates/trellis/scripts/common/cli_adapter.py +811 -0
  443. package/dist/templates/trellis/scripts/common/config.py +445 -0
  444. package/dist/templates/trellis/scripts/common/developer.py +190 -0
  445. package/dist/templates/trellis/scripts/common/git.py +31 -0
  446. package/dist/templates/trellis/scripts/common/git_context.py +106 -0
  447. package/dist/templates/trellis/scripts/common/io.py +37 -0
  448. package/dist/templates/trellis/scripts/common/log.py +45 -0
  449. package/dist/templates/trellis/scripts/common/packages_context.py +238 -0
  450. package/dist/templates/trellis/scripts/common/paths.py +447 -0
  451. package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
  452. package/dist/templates/trellis/scripts/common/session_context.py +821 -0
  453. package/dist/templates/trellis/scripts/common/task_context.py +223 -0
  454. package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
  455. package/dist/templates/trellis/scripts/common/task_store.py +697 -0
  456. package/dist/templates/trellis/scripts/common/task_utils.py +274 -0
  457. package/dist/templates/trellis/scripts/common/tasks.py +112 -0
  458. package/dist/templates/trellis/scripts/common/trellis_config.py +131 -0
  459. package/dist/templates/trellis/scripts/common/types.py +110 -0
  460. package/dist/templates/trellis/scripts/common/workflow_phase.py +215 -0
  461. package/dist/templates/trellis/scripts/get_context.py +16 -0
  462. package/dist/templates/trellis/scripts/get_developer.py +26 -0
  463. package/dist/templates/trellis/scripts/hooks/linear_sync.py +243 -0
  464. package/dist/templates/trellis/scripts/init_developer.py +51 -0
  465. package/dist/templates/trellis/scripts/task.py +500 -0
  466. package/dist/templates/trellis/tasks/.gitkeep +0 -0
  467. package/dist/templates/trellis/workflow.md +690 -0
  468. package/dist/types/ai-tools.d.ts +95 -0
  469. package/dist/types/ai-tools.d.ts.map +1 -0
  470. package/dist/types/ai-tools.js +280 -0
  471. package/dist/types/ai-tools.js.map +1 -0
  472. package/dist/types/migration.d.ts +125 -0
  473. package/dist/types/migration.d.ts.map +1 -0
  474. package/dist/types/migration.js +8 -0
  475. package/dist/types/migration.js.map +1 -0
  476. package/dist/utils/compare-versions.d.ts +12 -0
  477. package/dist/utils/compare-versions.d.ts.map +1 -0
  478. package/dist/utils/compare-versions.js +86 -0
  479. package/dist/utils/compare-versions.js.map +1 -0
  480. package/dist/utils/cwd-guard.d.ts +38 -0
  481. package/dist/utils/cwd-guard.d.ts.map +1 -0
  482. package/dist/utils/cwd-guard.js +62 -0
  483. package/dist/utils/cwd-guard.js.map +1 -0
  484. package/dist/utils/file-writer.d.ts +36 -0
  485. package/dist/utils/file-writer.d.ts.map +1 -0
  486. package/dist/utils/file-writer.js +203 -0
  487. package/dist/utils/file-writer.js.map +1 -0
  488. package/dist/utils/manifest-prune.d.ts +61 -0
  489. package/dist/utils/manifest-prune.d.ts.map +1 -0
  490. package/dist/utils/manifest-prune.js +136 -0
  491. package/dist/utils/manifest-prune.js.map +1 -0
  492. package/dist/utils/posix.d.ts +13 -0
  493. package/dist/utils/posix.d.ts.map +1 -0
  494. package/dist/utils/posix.js +15 -0
  495. package/dist/utils/posix.js.map +1 -0
  496. package/dist/utils/project-detector.d.ts +46 -0
  497. package/dist/utils/project-detector.d.ts.map +1 -0
  498. package/dist/utils/project-detector.js +666 -0
  499. package/dist/utils/project-detector.js.map +1 -0
  500. package/dist/utils/proxy.d.ts +25 -0
  501. package/dist/utils/proxy.d.ts.map +1 -0
  502. package/dist/utils/proxy.js +60 -0
  503. package/dist/utils/proxy.js.map +1 -0
  504. package/dist/utils/task-json.d.ts +46 -0
  505. package/dist/utils/task-json.d.ts.map +1 -0
  506. package/dist/utils/task-json.js +49 -0
  507. package/dist/utils/task-json.js.map +1 -0
  508. package/dist/utils/template-fetcher.d.ts +150 -0
  509. package/dist/utils/template-fetcher.d.ts.map +1 -0
  510. package/dist/utils/template-fetcher.js +907 -0
  511. package/dist/utils/template-fetcher.js.map +1 -0
  512. package/dist/utils/template-hash.d.ts +123 -0
  513. package/dist/utils/template-hash.d.ts.map +1 -0
  514. package/dist/utils/template-hash.js +334 -0
  515. package/dist/utils/template-hash.js.map +1 -0
  516. package/dist/utils/uninstall-scrubbers.d.ts +66 -0
  517. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
  518. package/dist/utils/uninstall-scrubbers.js +342 -0
  519. package/dist/utils/uninstall-scrubbers.js.map +1 -0
  520. package/package.json +89 -0
@@ -0,0 +1,497 @@
1
+ /* global process */
2
+ /**
3
+ * Trellis Context Injection Plugin
4
+ *
5
+ * Injects context when Task tool is called with supported subagent types.
6
+ * Uses OpenCode's tool.execute.before hook.
7
+ */
8
+
9
+ import { existsSync, readdirSync } from "fs"
10
+ import { join } from "path"
11
+ import { TrellisContext, debugLog } from "../lib/trellis-context.js"
12
+
13
+ // Supported subagent types
14
+ const AGENTS_ALL = ["implement", "check", "research"]
15
+ const AGENTS_REQUIRE_TASK = ["implement", "check"]
16
+
17
+ // Match `Active task: <path>` on the first non-empty line of the dispatch
18
+ // prompt. Mirrors the contract in workflow.md's [workflow-state:in_progress]
19
+ // breadcrumb so multi-window users can disambiguate which task is targeted.
20
+ const ACTIVE_TASK_HINT_RE = /^\s*Active task:\s*(\S+)\s*$/m
21
+
22
+ function extractActiveTaskHint(prompt) {
23
+ if (typeof prompt !== "string" || !prompt) return null
24
+ const match = prompt.match(ACTIVE_TASK_HINT_RE)
25
+ return match ? match[1].trim() : null
26
+ }
27
+
28
+ /**
29
+ * Get context for implement agent. `taskDir` may be relative
30
+ * (`.trellis/tasks/foo`) or absolute; both are resolved via
31
+ * `ctx.resolveTaskDir`.
32
+ */
33
+ function getImplementContext(ctx, taskDir) {
34
+ const parts = []
35
+ const taskDirFull = ctx.resolveTaskDir(taskDir)
36
+ if (!taskDirFull) return ""
37
+
38
+ const jsonlPath = join(taskDirFull, "implement.jsonl")
39
+ const entries = ctx.readJsonlWithFiles(jsonlPath)
40
+ if (entries.length > 0) {
41
+ parts.push(ctx.buildContextFromEntries(entries))
42
+ }
43
+
44
+ const prd = ctx.readFile(join(taskDirFull, "prd.md"))
45
+ if (prd) {
46
+ parts.push(`=== ${taskDir}/prd.md (Requirements) ===\n${prd}`)
47
+ }
48
+
49
+ const info = ctx.readFile(join(taskDirFull, "info.md"))
50
+ if (info) {
51
+ parts.push(`=== ${taskDir}/info.md (Technical Design) ===\n${info}`)
52
+ }
53
+
54
+ return parts.join("\n\n")
55
+ }
56
+
57
+ /**
58
+ * Get context for check agent. `taskDir` may be relative or absolute.
59
+ */
60
+ function getCheckContext(ctx, taskDir) {
61
+ const parts = []
62
+ const taskDirFull = ctx.resolveTaskDir(taskDir)
63
+ if (!taskDirFull) return ""
64
+
65
+ const jsonlPath = join(taskDirFull, "check.jsonl")
66
+ const entries = ctx.readJsonlWithFiles(jsonlPath)
67
+ if (entries.length > 0) {
68
+ parts.push(ctx.buildContextFromEntries(entries))
69
+ }
70
+
71
+ const prd = ctx.readFile(join(taskDirFull, "prd.md"))
72
+ if (prd) {
73
+ parts.push(`=== ${taskDir}/prd.md (Requirements) ===\n${prd}`)
74
+ }
75
+
76
+ return parts.join("\n\n")
77
+ }
78
+
79
+ /**
80
+ * Get context for finish phase (final check before PR)
81
+ */
82
+ function getFinishContext(ctx, taskDir) {
83
+ // Finish reuses check context (same JSONL source)
84
+ return getCheckContext(ctx, taskDir)
85
+ }
86
+
87
+
88
+ /**
89
+ * Get context for research agent
90
+ */
91
+ function getResearchContext(ctx) {
92
+ const parts = []
93
+
94
+ // Dynamic project structure (scan actual spec directory)
95
+ const specPath = ".trellis/spec"
96
+ const specFull = join(ctx.directory, specPath)
97
+
98
+ const structureLines = [`## Project Spec Directory Structure\n\n\`\`\`\n${specPath}/`]
99
+ if (existsSync(specFull)) {
100
+ try {
101
+ const entries = readdirSync(specFull, { withFileTypes: true })
102
+ .filter(d => d.isDirectory() && !d.name.startsWith("."))
103
+ .sort((a, b) => a.name.localeCompare(b.name))
104
+
105
+ for (const entry of entries) {
106
+ const entryPath = join(specFull, entry.name)
107
+ if (existsSync(join(entryPath, "index.md"))) {
108
+ structureLines.push(`├── ${entry.name}/`)
109
+ } else {
110
+ try {
111
+ const nested = readdirSync(entryPath, { withFileTypes: true })
112
+ .filter(d => d.isDirectory() && existsSync(join(entryPath, d.name, "index.md")))
113
+ .sort((a, b) => a.name.localeCompare(b.name))
114
+ if (nested.length > 0) {
115
+ structureLines.push(`├── ${entry.name}/`)
116
+ for (const n of nested) {
117
+ structureLines.push(`│ ├── ${n.name}/`)
118
+ }
119
+ }
120
+ } catch {
121
+ // Ignore nested read errors
122
+ }
123
+ }
124
+ }
125
+ } catch {
126
+ // Ignore read errors
127
+ }
128
+ }
129
+ structureLines.push("```")
130
+
131
+ parts.push(structureLines.join("\n") + `
132
+
133
+ ## Search Tips
134
+
135
+ - Spec files: \`.trellis/spec/**/*.md\`
136
+ - Known issues: \`.trellis/big-question/\`
137
+ - Code search: Use Glob and Grep tools
138
+ - Tech solutions: Use mcp__exa__web_search_exa or mcp__exa__get_code_context_exa`)
139
+
140
+ return parts.join("\n\n")
141
+ }
142
+
143
+ /**
144
+ * Build enhanced prompt with context
145
+ */
146
+ function buildPrompt(agentType, originalPrompt, context, isFinish = false) {
147
+ const templates = {
148
+ implement: `<!-- trellis-hook-injected -->
149
+ # Implement Agent Task
150
+
151
+ You are the Implement Agent in the Multi-Agent Pipeline.
152
+
153
+ ## Your Context
154
+
155
+ ${context}
156
+
157
+ ---
158
+
159
+ ## Your Task
160
+
161
+ ${originalPrompt}
162
+
163
+ ---
164
+
165
+ ## Workflow
166
+
167
+ 1. **Understand specs** - All dev specs are injected above
168
+ 2. **Understand requirements** - Read requirements and technical design
169
+ 3. **Implement feature** - Follow specs and design
170
+ 4. **Self-check** - Ensure code quality
171
+
172
+ ## Important Constraints
173
+
174
+ - Do NOT execute git commit
175
+ - Follow all dev specs injected above
176
+ - Report list of modified/created files when done`,
177
+
178
+ check: isFinish ? `<!-- trellis-hook-injected -->
179
+ # Finish Agent Task
180
+
181
+ You are performing the final check before creating a PR.
182
+
183
+ ## Your Context
184
+
185
+ ${context}
186
+
187
+ ---
188
+
189
+ ## Your Task
190
+
191
+ ${originalPrompt}
192
+
193
+ ---
194
+
195
+ ## Workflow
196
+
197
+ 1. **Review changes** - Run \`git diff --name-only\` to see all changed files
198
+ 2. **Verify requirements** - Check each requirement in prd.md is implemented
199
+ 3. **Spec sync** - Analyze whether changes introduce new patterns, contracts, or conventions
200
+ - If new pattern/convention found: read target spec file → update it → update index.md if needed
201
+ - If infra/cross-layer change: follow the 7-section mandatory template from update-spec.md
202
+ - If pure code fix with no new patterns: skip this step
203
+ 4. **Run final checks** - Execute lint and typecheck
204
+ 5. **Confirm ready** - Ensure code is ready for PR
205
+
206
+ ## Important Constraints
207
+
208
+ - You MAY update spec files when gaps are detected (use update-spec.md as guide)
209
+ - MUST read the target spec file BEFORE editing (avoid duplicating existing content)
210
+ - Do NOT update specs for trivial changes (typos, formatting, obvious fixes)
211
+ - If critical CODE issues found, report them clearly (fix specs, not code)
212
+ - Verify all acceptance criteria in prd.md are met` :
213
+ `<!-- trellis-hook-injected -->
214
+ # Check Agent Task
215
+
216
+ You are the Check Agent in the Multi-Agent Pipeline.
217
+
218
+ ## Your Context
219
+
220
+ ${context}
221
+
222
+ ---
223
+
224
+ ## Your Task
225
+
226
+ ${originalPrompt}
227
+
228
+ ---
229
+
230
+ ## Workflow
231
+
232
+ 1. **Get changes** - Run \`git diff --name-only\` and \`git diff\`
233
+ 2. **Check against specs** - Check item by item
234
+ 3. **Self-fix** - Fix issues directly, don't just report
235
+ 4. **Run verification** - Run lint and typecheck
236
+
237
+ ## Important Constraints
238
+
239
+ - Fix issues yourself, don't just report
240
+ - Must execute complete checklist`,
241
+
242
+ research: `<!-- trellis-hook-injected -->
243
+ # Research Agent Task
244
+
245
+ You are the Research Agent in the Multi-Agent Pipeline.
246
+
247
+ ## Core Principle
248
+
249
+ **You do one thing: find and explain information.**
250
+
251
+ ## Project Info
252
+
253
+ ${context}
254
+
255
+ ---
256
+
257
+ ## Your Task
258
+
259
+ ${originalPrompt}
260
+
261
+ ---
262
+
263
+ ## Workflow
264
+
265
+ 1. **Understand query** - Determine search type and scope
266
+ 2. **Plan search** - List search steps
267
+ 3. **Execute search** - Run multiple searches in parallel
268
+ 4. **Organize results** - Output structured report
269
+
270
+ ## Strict Boundaries
271
+
272
+ **Only allowed**: Describe what exists, where it is, how it works
273
+
274
+ **Forbidden**: Suggest improvements, criticize implementation, modify files`
275
+ }
276
+
277
+ return templates[agentType] || originalPrompt
278
+ }
279
+
280
+ function shellQuote(value) {
281
+ return `'${String(value).replace(/'/g, "'\\''")}'`
282
+ }
283
+
284
+ function powershellQuote(value) {
285
+ return `'${String(value).replace(/'/g, "''")}'`
286
+ }
287
+
288
+ function envValue(env, key) {
289
+ const value = env?.[key]
290
+ return typeof value === "string" && value.trim() ? value.trim() : null
291
+ }
292
+
293
+ function shellBasename(value) {
294
+ return value.replace(/\\/g, "/").split("/").pop()?.toLowerCase() || ""
295
+ }
296
+
297
+ function isWindowsPosixShell(env = process.env) {
298
+ if (envValue(env, "MSYSTEM")) return true
299
+ if (envValue(env, "MINGW_PREFIX")) return true
300
+ if (envValue(env, "OPENCODE_GIT_BASH_PATH")) return true
301
+
302
+ const ostype = envValue(env, "OSTYPE")?.toLowerCase() || ""
303
+ if (/(msys|mingw|cygwin)/.test(ostype)) return true
304
+
305
+ const shell = shellBasename(envValue(env, "SHELL") || "")
306
+ return /^(bash|sh|zsh)(\.exe)?$/.test(shell)
307
+ }
308
+
309
+ function buildTrellisContextPrefix(contextKey, hostPlatform = process.platform, env = process.env) {
310
+ if (hostPlatform === "win32" && !isWindowsPosixShell(env)) {
311
+ return `$env:TRELLIS_CONTEXT_ID = ${powershellQuote(contextKey)}; `
312
+ }
313
+
314
+ return `export TRELLIS_CONTEXT_ID=${shellQuote(contextKey)}; `
315
+ }
316
+
317
+ function getBashCommandKey(args) {
318
+ if (!args || typeof args !== "object") return null
319
+ if (typeof args.command === "string") return "command"
320
+ if (typeof args.cmd === "string") return "cmd"
321
+ return null
322
+ }
323
+
324
+ function commandStartsWithTrellisContext(command) {
325
+ const firstCommand = command.trimStart().split(/[;&|]/, 1)[0].trimStart()
326
+ return (
327
+ /^TRELLIS_CONTEXT_ID\s*=/.test(firstCommand) ||
328
+ /^export\s+TRELLIS_CONTEXT_ID\s*=/.test(firstCommand) ||
329
+ /^env\s+(?:(?:-\S+|[A-Za-z_][A-Za-z0-9_]*=\S*)\s+)*TRELLIS_CONTEXT_ID\s*=/.test(firstCommand) ||
330
+ /^\$env:TRELLIS_CONTEXT_ID\s*=/i.test(firstCommand)
331
+ )
332
+ }
333
+
334
+ /**
335
+ * OpenCode TUI may not expose OPENCODE_RUN_ID to Bash. The plugin hook still
336
+ * receives session identity, so inject it into Bash commands before execution.
337
+ */
338
+ function injectTrellisContextIntoBash(ctx, input, output, hostPlatform, env) {
339
+ const args = output?.args
340
+ const commandKey = getBashCommandKey(args)
341
+ if (!commandKey) return false
342
+
343
+ const command = args[commandKey]
344
+ if (!command.trim()) return false
345
+ if (commandStartsWithTrellisContext(command)) return false
346
+
347
+ const contextKey = ctx.getContextKey(input)
348
+ if (!contextKey) return false
349
+
350
+ args[commandKey] = `${buildTrellisContextPrefix(contextKey, hostPlatform, env)}${command}`
351
+ return true
352
+ }
353
+
354
+ // OpenCode plugin factory: `export default async (input) => hooks`.
355
+ // OpenCode 1.2.x iterates every module export and invokes it as a function
356
+ // (packages/opencode/src/plugin/index.ts — `for ([_, fn] of Object.entries(mod)) await fn(input)`);
357
+ // the previous `{ id, server }` object shape failed with
358
+ // `TypeError: fn is not a function` in 1.2.x.
359
+ export default async ({ directory, platform: hostPlatform = process.platform, env = process.env }) => {
360
+ const ctx = new TrellisContext(directory)
361
+ debugLog("inject", "Plugin loaded, directory:", directory)
362
+
363
+ return {
364
+ "tool.execute.before": async (input, output) => {
365
+ try {
366
+ if (process.env.TRELLIS_HOOKS === "0" || process.env.TRELLIS_DISABLE_HOOKS === "1") {
367
+ return
368
+ }
369
+ debugLog("inject", "tool.execute.before called, tool:", input?.tool)
370
+
371
+ const toolName = input?.tool?.toLowerCase()
372
+ if (toolName === "bash") {
373
+ if (injectTrellisContextIntoBash(ctx, input, output, hostPlatform, env)) {
374
+ debugLog("inject", "Injected TRELLIS_CONTEXT_ID into Bash command")
375
+ }
376
+ return
377
+ }
378
+
379
+ if (toolName !== "task") {
380
+ return
381
+ }
382
+
383
+ const args = output?.args
384
+ if (!args) return
385
+
386
+ const rawSubagentType = args.subagent_type
387
+ // Strip "trellis-" prefix added by v0.5.0-beta.5 agent rename migration
388
+ const subagentType = (rawSubagentType || "").replace(/^trellis-/, "")
389
+ const originalPrompt = args.prompt || ""
390
+
391
+ debugLog("inject", "Task tool called, subagent_type:", rawSubagentType)
392
+
393
+ if (!AGENTS_ALL.includes(subagentType)) {
394
+ debugLog("inject", "Skipping - unsupported subagent_type")
395
+ return
396
+ }
397
+
398
+ // Resolve active task in this priority order (only later steps
399
+ // run when earlier ones miss):
400
+ // 1. Exact session runtime context lookup for input.sessionID
401
+ // 2. `Active task: <path>` hint in the dispatch prompt
402
+ // (explicit per-dispatch override — beats single-session
403
+ // inference so multi-window users can disambiguate)
404
+ // 3. Single-session fallback — only when exactly 1 session
405
+ // runtime file exists locally
406
+ let taskDir = null
407
+ let taskSource = null
408
+
409
+ const contextKey = ctx.getContextKey(input)
410
+ if (contextKey) {
411
+ const context = ctx.readContext(contextKey)
412
+ const exactRef = ctx.normalizeTaskRef(context?.current_task || "")
413
+ if (exactRef) {
414
+ taskDir = exactRef
415
+ taskSource = `session:${contextKey}`
416
+ }
417
+ }
418
+
419
+ if (!taskDir) {
420
+ const hintRef = extractActiveTaskHint(originalPrompt)
421
+ if (hintRef) {
422
+ const hintNormalized = ctx.normalizeTaskRef(hintRef)
423
+ if (hintNormalized) {
424
+ const hintDir = ctx.resolveTaskDir(hintNormalized)
425
+ if (hintDir && existsSync(hintDir)) {
426
+ taskDir = hintNormalized
427
+ taskSource = "prompt-hint"
428
+ debugLog("inject", "Resolved task from Active task: hint:", hintNormalized)
429
+ }
430
+ }
431
+ }
432
+ }
433
+
434
+ if (!taskDir) {
435
+ const fallback = ctx._resolveSingleSessionFallback()
436
+ if (fallback?.taskPath) {
437
+ const fallbackDir = ctx.resolveTaskDir(fallback.taskPath)
438
+ if (fallbackDir && existsSync(fallbackDir)) {
439
+ taskDir = fallback.taskPath
440
+ taskSource = fallback.source
441
+ debugLog("inject", "Resolved task via single-session fallback:", taskDir, "source:", taskSource)
442
+ }
443
+ }
444
+ }
445
+
446
+ // Agents requiring task directory
447
+ if (AGENTS_REQUIRE_TASK.includes(subagentType)) {
448
+ // subagentType is already stripped of "trellis-" prefix above
449
+ if (!taskDir) {
450
+ debugLog("inject", "Skipping - no current task")
451
+ return
452
+ }
453
+ const taskDirFull = ctx.resolveTaskDir(taskDir)
454
+ if (!taskDirFull || !existsSync(taskDirFull)) {
455
+ debugLog("inject", "Skipping - task directory not found")
456
+ return
457
+ }
458
+ }
459
+
460
+ // Check for [finish] marker
461
+ const isFinish = originalPrompt.toLowerCase().includes("[finish]")
462
+
463
+ // Get context based on agent type
464
+ let context = ""
465
+ switch (subagentType) {
466
+ case "implement":
467
+ context = getImplementContext(ctx, taskDir)
468
+ break
469
+ case "check":
470
+ context = isFinish
471
+ ? getFinishContext(ctx, taskDir)
472
+ : getCheckContext(ctx, taskDir)
473
+ break
474
+ case "research":
475
+ context = getResearchContext(ctx, taskDir)
476
+ break
477
+ }
478
+
479
+ if (!context) {
480
+ debugLog("inject", "No context to inject")
481
+ return
482
+ }
483
+
484
+ const newPrompt = buildPrompt(subagentType, originalPrompt, context, isFinish)
485
+
486
+ // Mutate args in-place — whole-object replacement does NOT work for the task tool
487
+ // because the runtime holds a local reference to the same args object.
488
+ args.prompt = newPrompt
489
+
490
+ debugLog("inject", "Injected context for", subagentType, "prompt length:", newPrompt.length)
491
+
492
+ } catch (error) {
493
+ debugLog("inject", "Error in tool.execute.before:", error.message, error.stack)
494
+ }
495
+ }
496
+ }
497
+ }
@@ -0,0 +1,162 @@
1
+ /* global process */
2
+ /**
3
+ * Trellis Workflow State Injection Plugin
4
+ *
5
+ * Per-turn UserPromptSubmit equivalent for OpenCode.
6
+ *
7
+ * On every chat.message, if a Trellis task is active, inject a short
8
+ * <workflow-state> breadcrumb reminding the main AI what task is
9
+ * active and its expected flow. Breadcrumb text is pulled exclusively
10
+ * from the project's workflow.md [workflow-state:STATUS] tag blocks —
11
+ * workflow.md is the single source of truth. There are no fallback
12
+ * tables in this plugin: when workflow.md is missing or a tag is
13
+ * absent, the breadcrumb degrades to a generic
14
+ * "Refer to workflow.md for current step." line so users see (and fix)
15
+ * the broken state instead of the plugin silently masking it.
16
+ *
17
+ * Unlike session-start, this plugin does NOT dedupe — the breadcrumb
18
+ * should surface on every turn so long conversations don't drift.
19
+ *
20
+ * Silently skips when:
21
+ * - No .trellis/ directory
22
+ * - No active task in the session runtime context
23
+ * - task.json malformed or missing status
24
+ */
25
+
26
+ import { existsSync, readFileSync } from "fs"
27
+ import { join } from "path"
28
+ import { TrellisContext, debugLog, isTrellisSubagent } from "../lib/trellis-context.js"
29
+
30
+ // Supports STATUS values with letters, digits, underscores, hyphens
31
+ // (so "in-review" / "blocked-by-team" work alongside "in_progress").
32
+ const TAG_RE = /\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n([\s\S]*?)\n\s*\[\/workflow-state:\1\]/g
33
+
34
+ /**
35
+ * Parse workflow.md for [workflow-state:STATUS] blocks.
36
+ *
37
+ * Returns {status: body}. workflow.md is the single source of truth —
38
+ * there are no fallback tables here. Missing tags (or a missing /
39
+ * unreadable workflow.md) fall back to a generic line in
40
+ * buildBreadcrumb so users see the broken state and fix workflow.md
41
+ * rather than the plugin silently masking it.
42
+ */
43
+ function loadBreadcrumbs(directory) {
44
+ const workflowPath = join(directory, ".trellis", "workflow.md")
45
+ if (!existsSync(workflowPath)) return {}
46
+ let content
47
+ try {
48
+ content = readFileSync(workflowPath, "utf-8")
49
+ } catch {
50
+ return {}
51
+ }
52
+ const result = {}
53
+ for (const match of content.matchAll(TAG_RE)) {
54
+ const status = match[1]
55
+ const body = match[2].trim()
56
+ if (body) result[status] = body
57
+ }
58
+ return result
59
+ }
60
+
61
+ /**
62
+ * Get (taskId, status) from active task, or null if no active task.
63
+ */
64
+ function getActiveTask(ctx, platformInput = null) {
65
+ const active = ctx.getActiveTask(platformInput)
66
+ const taskRef = active.taskPath
67
+ if (!taskRef) return null
68
+ const taskDir = ctx.resolveTaskDir(taskRef)
69
+ if (active.stale || !taskDir || !existsSync(taskDir)) {
70
+ return { id: taskRef.split("/").pop(), status: "stale", source: active.source }
71
+ }
72
+ const taskJsonPath = join(taskDir, "task.json")
73
+ if (!existsSync(taskJsonPath)) return null
74
+ try {
75
+ const data = JSON.parse(readFileSync(taskJsonPath, "utf-8"))
76
+ const status = typeof data.status === "string" ? data.status : ""
77
+ if (!status) return null
78
+ const id = data.id || taskRef.split("/").pop()
79
+ return { id, status, source: active.source }
80
+ } catch {
81
+ return null
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Build the <workflow-state>...</workflow-state> block.
87
+ * - Known status (tag present in workflow.md) → detailed body
88
+ * - Unknown status (no tag, or workflow.md missing) → generic
89
+ * "Refer to workflow.md for current step." line
90
+ * - no_task pseudo-status (id === null) → header omits task info
91
+ */
92
+ function buildBreadcrumb(id, status, templates, source = null) {
93
+ let body = templates[status]
94
+ if (body === undefined) {
95
+ body = "Refer to workflow.md for current step."
96
+ }
97
+ let header = id === null ? `Status: ${status}` : `Task: ${id} (${status})`
98
+ if (source) {
99
+ header = `${header}\nSource: ${source}`
100
+ }
101
+ return `<workflow-state>\n${header}\n${body}\n</workflow-state>`
102
+ }
103
+
104
+ // OpenCode 1.2.x expects plugins to be factory functions (see inject-subagent-context.js comment).
105
+ export default async ({ directory }) => {
106
+ const ctx = new TrellisContext(directory)
107
+ debugLog("workflow-state", "Plugin loaded, directory:", directory)
108
+
109
+ return {
110
+ // chat.message fires on every user message. Inject breadcrumb in-place
111
+ // so it persists in conversation history.
112
+ "chat.message": async (input, output) => {
113
+ try {
114
+ // Skip Trellis sub-agent turns — the per-turn breadcrumb is for the
115
+ // main session only; sub-agent context comes from the parent's
116
+ // tool.execute.before injection.
117
+ if (isTrellisSubagent(input)) {
118
+ debugLog("workflow-state", "Skipping trellis subagent turn:", input?.agent)
119
+ return
120
+ }
121
+ if (process.env.TRELLIS_HOOKS === "0" || process.env.TRELLIS_DISABLE_HOOKS === "1") {
122
+ return
123
+ }
124
+ if (process.env.OPENCODE_NON_INTERACTIVE === "1") {
125
+ return
126
+ }
127
+ if (!ctx.isTrellisProject()) {
128
+ return
129
+ }
130
+ const templates = loadBreadcrumbs(directory)
131
+ const task = getActiveTask(ctx, input)
132
+ const breadcrumb = task
133
+ ? buildBreadcrumb(task.id, task.status, templates, task.source)
134
+ : buildBreadcrumb(null, "no_task", templates)
135
+
136
+ const parts = output?.parts || []
137
+ const textPartIndex = parts.findIndex(
138
+ p => p.type === "text" && p.text !== undefined,
139
+ )
140
+ if (textPartIndex !== -1) {
141
+ const originalText = parts[textPartIndex].text || ""
142
+ parts[textPartIndex].text = `${breadcrumb}\n\n${originalText}`
143
+ } else {
144
+ parts.unshift({ type: "text", text: breadcrumb })
145
+ }
146
+ debugLog(
147
+ "workflow-state",
148
+ "Injected breadcrumb for task",
149
+ task ? task.id : "none",
150
+ "status",
151
+ task ? task.status : "no_task",
152
+ )
153
+ } catch (error) {
154
+ debugLog(
155
+ "workflow-state",
156
+ "Error in chat.message:",
157
+ error instanceof Error ? error.message : String(error),
158
+ )
159
+ }
160
+ },
161
+ }
162
+ }