@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,215 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Workflow Phase Extraction.
5
+
6
+ Extracts step-level content from .trellis/workflow.md and optionally filters
7
+ platform-specific blocks.
8
+
9
+ Platform marker syntax in workflow.md:
10
+
11
+ [Claude Code, Cursor, ...]
12
+ agent-capable content
13
+ [/Claude Code, Cursor, ...]
14
+
15
+ Provides:
16
+ get_phase_index - Extract the Phase Index section (no --step)
17
+ get_step - Extract a single step (#### X.X) section
18
+ filter_platform - Strip platform blocks that don't include the given name
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import re
24
+
25
+ from .paths import DIR_WORKFLOW, get_repo_root
26
+
27
+
28
+ def _workflow_md_path():
29
+ return get_repo_root() / DIR_WORKFLOW / "workflow.md"
30
+
31
+ # Match a line that *is* a platform marker: "[A, B, C]" or "[/A, B, C]"
32
+ _MARKER_RE = re.compile(r"^\[(/?)([A-Za-z][^\[\]]*)\]\s*$")
33
+
34
+ # Step heading: "#### 1.0 Title" or "#### 1.0 ..."
35
+ _STEP_HEADING_RE = re.compile(r"^####\s+(\d+\.\d+)\b.*$")
36
+
37
+ # Phase Index starts here; Phase 1/2/3 step bodies follow; ends at Breadcrumbs.
38
+ _PHASE_INDEX_HEADING = "## Phase Index"
39
+
40
+
41
+ def _read_workflow() -> str:
42
+ path = _workflow_md_path()
43
+ if not path.exists():
44
+ raise FileNotFoundError(f"workflow.md not found: {path}")
45
+ return path.read_text(encoding="utf-8")
46
+
47
+
48
+ def _parse_marker(line: str) -> tuple[bool, list[str]] | None:
49
+ """Parse a platform marker line.
50
+
51
+ Returns:
52
+ (is_closing, [platform_names]) if line is a marker, else None.
53
+ """
54
+ m = _MARKER_RE.match(line)
55
+ if not m:
56
+ return None
57
+ is_closing = m.group(1) == "/"
58
+ names = [p.strip() for p in m.group(2).split(",") if p.strip()]
59
+ return is_closing, names
60
+
61
+
62
+ def get_phase_index() -> str:
63
+ """Return Phase Index + Phase 1/2/3 step bodies from workflow.md.
64
+
65
+ Matches what the SessionStart hook injects into the `<workflow>` block:
66
+ starts at `## Phase Index`, continues through `## Phase 1: Plan`,
67
+ `## Phase 2: Execute`, `## Phase 3: Finish`, stops at
68
+ `## Customizing Trellis (for forks)` (the docs-for-forks footer).
69
+ `[workflow-state:STATUS]` tag blocks (now embedded in Phase Index since
70
+ v0.5.0-rc.0) are consumed by the UserPromptSubmit hook so they're
71
+ stripped from this output.
72
+ """
73
+ text = _read_workflow()
74
+ lines = text.splitlines()
75
+
76
+ start: int | None = None
77
+ end: int | None = None
78
+ for i, line in enumerate(lines):
79
+ stripped = line.strip()
80
+ if start is None and stripped == _PHASE_INDEX_HEADING:
81
+ start = i
82
+ continue
83
+ if start is not None and stripped == "## Customizing Trellis (for forks)":
84
+ end = i
85
+ break
86
+
87
+ if start is None:
88
+ return ""
89
+ if end is None:
90
+ end = len(lines)
91
+
92
+ section = "\n".join(lines[start:end]).rstrip()
93
+ # Strip [workflow-state:STATUS]...[/workflow-state:STATUS] blocks since
94
+ # they're injected separately by inject-workflow-state.py per-turn.
95
+ import re as _re
96
+ tag_re = _re.compile(
97
+ r"\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n.*?\n\s*\[/workflow-state:\1\]\n?",
98
+ _re.DOTALL,
99
+ )
100
+ return tag_re.sub("", section).rstrip() + "\n"
101
+
102
+
103
+ def get_step(step_id: str) -> str:
104
+ """Return the `#### X.X` section matching step_id (header + body).
105
+
106
+ Body ends at the next `####` or `---` or `##` heading (whichever comes first).
107
+ """
108
+ text = _read_workflow()
109
+ lines = text.splitlines()
110
+
111
+ start: int | None = None
112
+ for i, line in enumerate(lines):
113
+ m = _STEP_HEADING_RE.match(line)
114
+ if m and m.group(1) == step_id:
115
+ start = i
116
+ break
117
+ if start is None:
118
+ return ""
119
+
120
+ end: int = len(lines)
121
+ for j in range(start + 1, len(lines)):
122
+ line = lines[j]
123
+ if line.startswith("#### "):
124
+ end = j
125
+ break
126
+ if line.startswith("## "):
127
+ end = j
128
+ break
129
+ # Horizontal rule at column 0
130
+ if line.strip() == "---":
131
+ end = j
132
+ break
133
+
134
+ return "\n".join(lines[start:end]).rstrip() + "\n"
135
+
136
+
137
+ def _platform_matches(platform: str, block_names: list[str]) -> bool:
138
+ """Case-insensitive fuzzy match: accept 'cursor', 'Cursor', 'claude-code', 'Claude Code'."""
139
+ needle = platform.lower().replace("-", "").replace("_", "").replace(" ", "")
140
+ for name in block_names:
141
+ hay = name.lower().replace("-", "").replace("_", "").replace(" ", "")
142
+ if needle == hay:
143
+ return True
144
+ return False
145
+
146
+
147
+ def resolve_effective_platform(platform: str, config: dict) -> str:
148
+ """Map ``codex`` to a dispatch-mode-namespaced virtual platform name.
149
+
150
+ When ``--platform codex`` is passed, return ``"codex-inline"`` (default)
151
+ or ``"codex-sub-agent"`` based on ``.trellis/config.yaml`` ``codex.dispatch_mode``.
152
+ ``filter_platform`` then surfaces blocks whose marker lists include the
153
+ namespaced name (e.g. ``[codex-sub-agent, ...]`` or ``[codex-inline, Kilo,
154
+ Antigravity, Windsurf]``).
155
+
156
+ Default is ``inline`` because Codex sub-agents run with ``fork_turns="none"``
157
+ isolation and can't inherit the parent session's task context — inline
158
+ keeps the main agent in charge so context isn't lost. Invalid / missing
159
+ values also fall back to inline.
160
+
161
+ Other platforms are returned unchanged.
162
+ """
163
+ if platform == "codex":
164
+ mode = "inline"
165
+ codex_cfg = config.get("codex") if isinstance(config, dict) else None
166
+ if isinstance(codex_cfg, dict):
167
+ cfg_mode = codex_cfg.get("dispatch_mode")
168
+ if cfg_mode in ("inline", "sub-agent"):
169
+ mode = cfg_mode
170
+ return f"codex-{mode}"
171
+ return platform
172
+
173
+
174
+ def filter_platform(content: str, platform: str) -> str:
175
+ """Keep lines outside any `[...]` block + lines inside blocks that include platform.
176
+
177
+ Marker lines themselves are dropped from the output.
178
+ """
179
+ lines = content.splitlines()
180
+ out: list[str] = []
181
+
182
+ in_block = False
183
+ keep_block = False
184
+
185
+ for line in lines:
186
+ marker = _parse_marker(line)
187
+ if marker is not None:
188
+ is_closing, names = marker
189
+ if not is_closing:
190
+ in_block = True
191
+ keep_block = _platform_matches(platform, names)
192
+ else:
193
+ in_block = False
194
+ keep_block = False
195
+ continue # drop the marker line itself
196
+
197
+ if in_block:
198
+ if keep_block:
199
+ out.append(line)
200
+ continue
201
+ out.append(line)
202
+
203
+ # Collapse runs of 3+ blank lines that may arise from dropped markers
204
+ collapsed: list[str] = []
205
+ blank_run = 0
206
+ for line in out:
207
+ if line.strip() == "":
208
+ blank_run += 1
209
+ if blank_run <= 2:
210
+ collapsed.append(line)
211
+ else:
212
+ blank_run = 0
213
+ collapsed.append(line)
214
+
215
+ return "\n".join(collapsed).rstrip() + "\n"
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Get Session Context for AI Agent.
4
+
5
+ Usage:
6
+ python3 get_context.py Output context in text format
7
+ python3 get_context.py --json Output context in JSON format
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from common.git_context import main
13
+
14
+
15
+ if __name__ == "__main__":
16
+ main()
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Get current developer name.
4
+
5
+ This is a wrapper that uses common/paths.py
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import sys
11
+
12
+ from common.paths import get_developer
13
+
14
+
15
+ def main() -> None:
16
+ """CLI entry point."""
17
+ developer = get_developer()
18
+ if developer:
19
+ print(developer)
20
+ else:
21
+ print("Developer not initialized", file=sys.stderr)
22
+ sys.exit(1)
23
+
24
+
25
+ if __name__ == "__main__":
26
+ main()
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env python3
2
+ """Linear sync hook for Trellis task lifecycle.
3
+
4
+ Syncs task events to Linear via the `linearis` CLI.
5
+
6
+ Usage (called automatically by task.py hooks):
7
+ python3 .trellis/scripts/hooks/linear_sync.py create
8
+ python3 .trellis/scripts/hooks/linear_sync.py start
9
+ python3 .trellis/scripts/hooks/linear_sync.py archive
10
+
11
+ Manual usage:
12
+ TASK_JSON_PATH=.trellis/tasks/<name>/task.json python3 .trellis/scripts/hooks/linear_sync.py sync
13
+
14
+ Environment:
15
+ TASK_JSON_PATH - Absolute path to task.json (set by task.py)
16
+
17
+ Configuration:
18
+ .trellis/hooks.local.json - Local config (gitignored), example:
19
+ {
20
+ "linear": {
21
+ "team": "TEAM_KEY",
22
+ "project": "Project Name",
23
+ "assignees": {
24
+ "dev-name": "linear-user-id"
25
+ }
26
+ }
27
+ }
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import json
33
+ import os
34
+ import subprocess
35
+ import sys
36
+ from pathlib import Path
37
+
38
+ # ─── Configuration ────────────────────────────────────────────────────────────
39
+
40
+ # Trellis priority → Linear priority (1=Urgent, 2=High, 3=Medium, 4=Low)
41
+ PRIORITY_MAP = {"P0": 1, "P1": 2, "P2": 3, "P3": 4}
42
+
43
+ # Linear status names (must match your team's workflow)
44
+ STATUS_IN_PROGRESS = "In Progress"
45
+ STATUS_DONE = "Done"
46
+
47
+
48
+ def _load_config() -> dict:
49
+ """Load local hook config from .trellis/hooks.local.json."""
50
+ task_json_path = os.environ.get("TASK_JSON_PATH", "")
51
+ if task_json_path:
52
+ # Walk up from task.json to find .trellis/
53
+ trellis_dir = Path(task_json_path).parent.parent.parent
54
+ else:
55
+ trellis_dir = Path(".trellis")
56
+
57
+ config_path = trellis_dir / "hooks.local.json"
58
+ try:
59
+ with open(config_path, encoding="utf-8") as f:
60
+ return json.load(f)
61
+ except (OSError, json.JSONDecodeError):
62
+ return {}
63
+
64
+
65
+ CONFIG = _load_config()
66
+ LINEAR_CFG = CONFIG.get("linear", {})
67
+
68
+ TEAM = LINEAR_CFG.get("team", "")
69
+ PROJECT = LINEAR_CFG.get("project", "")
70
+ ASSIGNEE_MAP = LINEAR_CFG.get("assignees", {})
71
+
72
+ # ─── Helpers ──────────────────────────────────────────────────────────────────
73
+
74
+
75
+ def _read_task() -> tuple[dict, str]:
76
+ path = os.environ.get("TASK_JSON_PATH", "")
77
+ if not path:
78
+ print("TASK_JSON_PATH not set", file=sys.stderr)
79
+ sys.exit(1)
80
+ with open(path, encoding="utf-8") as f:
81
+ return json.load(f), path
82
+
83
+
84
+ def _write_task(data: dict, path: str) -> None:
85
+ with open(path, "w", encoding="utf-8") as f:
86
+ json.dump(data, f, indent=2, ensure_ascii=False)
87
+ f.write("\n")
88
+
89
+
90
+ def _linearis(*args: str) -> dict | None:
91
+ result = subprocess.run(
92
+ ["linearis", *args],
93
+ capture_output=True,
94
+ text=True,
95
+ encoding="utf-8",
96
+ errors="replace",
97
+ )
98
+ if result.returncode != 0:
99
+ print(f"linearis error: {result.stderr.strip()}", file=sys.stderr)
100
+ sys.exit(1)
101
+ stdout = result.stdout.strip()
102
+ if stdout:
103
+ return json.loads(stdout)
104
+ return None
105
+
106
+
107
+ def _get_linear_issue(task: dict) -> str | None:
108
+ meta = task.get("meta")
109
+ if isinstance(meta, dict):
110
+ return meta.get("linear_issue")
111
+ return None
112
+
113
+
114
+ # ─── Actions ──────────────────────────────────────────────────────────────────
115
+
116
+
117
+ def cmd_create() -> None:
118
+ if not TEAM:
119
+ print("No linear.team configured in hooks.local.json", file=sys.stderr)
120
+ sys.exit(1)
121
+
122
+ task, path = _read_task()
123
+
124
+ # Skip if already linked
125
+ if _get_linear_issue(task):
126
+ print(f"Already linked: {_get_linear_issue(task)}")
127
+ return
128
+
129
+ title = task.get("title") or task.get("name") or "Untitled"
130
+ args = ["issues", "create", title, "--team", TEAM]
131
+
132
+ # Map priority
133
+ priority = PRIORITY_MAP.get(task.get("priority", ""), 0)
134
+ if priority:
135
+ args.extend(["-p", str(priority)])
136
+
137
+ # Set project
138
+ if PROJECT:
139
+ args.extend(["--project", PROJECT])
140
+
141
+ # Assign to Linear user
142
+ assignee = task.get("assignee", "")
143
+ linear_user_id = ASSIGNEE_MAP.get(assignee)
144
+ if linear_user_id:
145
+ args.extend(["--assignee", linear_user_id])
146
+
147
+ # Link to parent's Linear issue if available
148
+ parent_issue = _resolve_parent_linear_issue(task)
149
+ if parent_issue:
150
+ args.extend(["--parent-ticket", parent_issue])
151
+
152
+ result = _linearis(*args)
153
+ if result and "identifier" in result:
154
+ if not isinstance(task.get("meta"), dict):
155
+ task["meta"] = {}
156
+ task["meta"]["linear_issue"] = result["identifier"]
157
+ _write_task(task, path)
158
+ print(f"Created Linear issue: {result['identifier']}")
159
+
160
+
161
+ def cmd_start() -> None:
162
+ task, _ = _read_task()
163
+ issue = _get_linear_issue(task)
164
+ if not issue:
165
+ return
166
+ _linearis("issues", "update", issue, "-s", STATUS_IN_PROGRESS)
167
+ print(f"Updated {issue} -> {STATUS_IN_PROGRESS}")
168
+ cmd_sync()
169
+
170
+
171
+ def cmd_archive() -> None:
172
+ task, _ = _read_task()
173
+ issue = _get_linear_issue(task)
174
+ if not issue:
175
+ return
176
+ _linearis("issues", "update", issue, "-s", STATUS_DONE)
177
+ print(f"Updated {issue} -> {STATUS_DONE}")
178
+
179
+
180
+ def cmd_sync() -> None:
181
+ """Sync prd.md content to Linear issue description."""
182
+ task, _ = _read_task()
183
+ issue = _get_linear_issue(task)
184
+ if not issue:
185
+ print("No linear_issue in meta, run create first", file=sys.stderr)
186
+ sys.exit(1)
187
+
188
+ # Find prd.md next to task.json
189
+ task_json_path = os.environ.get("TASK_JSON_PATH", "")
190
+ prd_path = Path(task_json_path).parent / "prd.md"
191
+ if not prd_path.is_file():
192
+ print(f"No prd.md found at {prd_path}", file=sys.stderr)
193
+ sys.exit(1)
194
+
195
+ description = prd_path.read_text(encoding="utf-8").strip()
196
+ _linearis("issues", "update", issue, "-d", description)
197
+ print(f"Synced prd.md to {issue} description")
198
+
199
+
200
+ # ─── Parent Issue Resolution ─────────────────────────────────────────────────
201
+
202
+
203
+ def _resolve_parent_linear_issue(task: dict) -> str | None:
204
+ """Find parent task's Linear issue identifier."""
205
+ parent_name = task.get("parent")
206
+ if not parent_name:
207
+ return None
208
+
209
+ task_json_path = os.environ.get("TASK_JSON_PATH", "")
210
+ if not task_json_path:
211
+ return None
212
+
213
+ current_task_dir = Path(task_json_path).parent
214
+ tasks_dir = current_task_dir.parent
215
+ parent_json = tasks_dir / parent_name / "task.json"
216
+
217
+ if parent_json.exists():
218
+ try:
219
+ with open(parent_json, encoding="utf-8") as f:
220
+ parent_task = json.load(f)
221
+ return _get_linear_issue(parent_task)
222
+ except (json.JSONDecodeError, OSError):
223
+ pass
224
+ return None
225
+
226
+
227
+ # ─── Main ─────────────────────────────────────────────────────────────────────
228
+
229
+ if __name__ == "__main__":
230
+ action = sys.argv[1] if len(sys.argv) > 1 else ""
231
+ actions = {
232
+ "create": cmd_create,
233
+ "start": cmd_start,
234
+ "archive": cmd_archive,
235
+ "sync": cmd_sync,
236
+ }
237
+ fn = actions.get(action)
238
+ if fn:
239
+ fn()
240
+ else:
241
+ print(f"Unknown action: {action}", file=sys.stderr)
242
+ print(f"Valid actions: {', '.join(actions)}", file=sys.stderr)
243
+ sys.exit(1)
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Initialize developer for workflow.
4
+
5
+ Usage:
6
+ python3 init_developer.py <developer-name>
7
+
8
+ This creates:
9
+ - .trellis/.developer file with developer info
10
+ - .trellis/workspace/<name>/ directory structure
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import sys
16
+
17
+ from common.paths import (
18
+ DIR_WORKFLOW,
19
+ FILE_DEVELOPER,
20
+ get_developer,
21
+ )
22
+ from common.developer import init_developer
23
+
24
+
25
+ def main() -> None:
26
+ """CLI entry point."""
27
+ if len(sys.argv) < 2:
28
+ print(f"Usage: {sys.argv[0]} <developer-name>")
29
+ print()
30
+ print("Example:")
31
+ print(f" {sys.argv[0]} john")
32
+ sys.exit(1)
33
+
34
+ name = sys.argv[1]
35
+
36
+ # Check if already initialized
37
+ existing = get_developer()
38
+ if existing:
39
+ print(f"Developer already initialized: {existing}")
40
+ print()
41
+ print(f"To reinitialize, remove {DIR_WORKFLOW}/{FILE_DEVELOPER} first")
42
+ sys.exit(0)
43
+
44
+ if init_developer(name):
45
+ sys.exit(0)
46
+ else:
47
+ sys.exit(1)
48
+
49
+
50
+ if __name__ == "__main__":
51
+ main()