@baoanaz/cviauto 0.6.5

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 (740) hide show
  1. package/LICENSE +235 -0
  2. package/README.md +46 -0
  3. package/bin/trellis.js +3 -0
  4. package/dist/cli/index.d.ts +3 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +209 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/commands/channel/adapters/claude.d.ts +29 -0
  9. package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
  10. package/dist/commands/channel/adapters/claude.js +203 -0
  11. package/dist/commands/channel/adapters/claude.js.map +1 -0
  12. package/dist/commands/channel/adapters/codex.d.ts +85 -0
  13. package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
  14. package/dist/commands/channel/adapters/codex.js +505 -0
  15. package/dist/commands/channel/adapters/codex.js.map +1 -0
  16. package/dist/commands/channel/adapters/index.d.ts +84 -0
  17. package/dist/commands/channel/adapters/index.d.ts.map +1 -0
  18. package/dist/commands/channel/adapters/index.js +115 -0
  19. package/dist/commands/channel/adapters/index.js.map +1 -0
  20. package/dist/commands/channel/adapters/types.d.ts +33 -0
  21. package/dist/commands/channel/adapters/types.d.ts.map +1 -0
  22. package/dist/commands/channel/adapters/types.js +2 -0
  23. package/dist/commands/channel/adapters/types.js.map +1 -0
  24. package/dist/commands/channel/agent-loader.d.ts +32 -0
  25. package/dist/commands/channel/agent-loader.d.ts.map +1 -0
  26. package/dist/commands/channel/agent-loader.js +154 -0
  27. package/dist/commands/channel/agent-loader.js.map +1 -0
  28. package/dist/commands/channel/context-loader.d.ts +26 -0
  29. package/dist/commands/channel/context-loader.d.ts.map +1 -0
  30. package/dist/commands/channel/context-loader.js +290 -0
  31. package/dist/commands/channel/context-loader.js.map +1 -0
  32. package/dist/commands/channel/context.d.ts +16 -0
  33. package/dist/commands/channel/context.d.ts.map +1 -0
  34. package/dist/commands/channel/context.js +83 -0
  35. package/dist/commands/channel/context.js.map +1 -0
  36. package/dist/commands/channel/create.d.ts +27 -0
  37. package/dist/commands/channel/create.d.ts.map +1 -0
  38. package/dist/commands/channel/create.js +39 -0
  39. package/dist/commands/channel/create.js.map +1 -0
  40. package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
  41. package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
  42. package/dist/commands/channel/dev-parse-trace.js +70 -0
  43. package/dist/commands/channel/dev-parse-trace.js.map +1 -0
  44. package/dist/commands/channel/guard.d.ts +150 -0
  45. package/dist/commands/channel/guard.d.ts.map +1 -0
  46. package/dist/commands/channel/guard.js +474 -0
  47. package/dist/commands/channel/guard.js.map +1 -0
  48. package/dist/commands/channel/index.d.ts +3 -0
  49. package/dist/commands/channel/index.d.ts.map +1 -0
  50. package/dist/commands/channel/index.js +531 -0
  51. package/dist/commands/channel/index.js.map +1 -0
  52. package/dist/commands/channel/interrupt.d.ts +10 -0
  53. package/dist/commands/channel/interrupt.d.ts.map +1 -0
  54. package/dist/commands/channel/interrupt.js +22 -0
  55. package/dist/commands/channel/interrupt.js.map +1 -0
  56. package/dist/commands/channel/kill.d.ts +7 -0
  57. package/dist/commands/channel/kill.d.ts.map +1 -0
  58. package/dist/commands/channel/kill.js +121 -0
  59. package/dist/commands/channel/kill.js.map +1 -0
  60. package/dist/commands/channel/list.d.ts +17 -0
  61. package/dist/commands/channel/list.d.ts.map +1 -0
  62. package/dist/commands/channel/list.js +233 -0
  63. package/dist/commands/channel/list.js.map +1 -0
  64. package/dist/commands/channel/messages.d.ts +15 -0
  65. package/dist/commands/channel/messages.d.ts.map +1 -0
  66. package/dist/commands/channel/messages.js +245 -0
  67. package/dist/commands/channel/messages.js.map +1 -0
  68. package/dist/commands/channel/rm.d.ts +27 -0
  69. package/dist/commands/channel/rm.d.ts.map +1 -0
  70. package/dist/commands/channel/rm.js +216 -0
  71. package/dist/commands/channel/rm.js.map +1 -0
  72. package/dist/commands/channel/run.d.ts +30 -0
  73. package/dist/commands/channel/run.d.ts.map +1 -0
  74. package/dist/commands/channel/run.js +130 -0
  75. package/dist/commands/channel/run.js.map +1 -0
  76. package/dist/commands/channel/send.d.ts +11 -0
  77. package/dist/commands/channel/send.d.ts.map +1 -0
  78. package/dist/commands/channel/send.js +24 -0
  79. package/dist/commands/channel/send.js.map +1 -0
  80. package/dist/commands/channel/spawn.d.ts +40 -0
  81. package/dist/commands/channel/spawn.d.ts.map +1 -0
  82. package/dist/commands/channel/spawn.js +244 -0
  83. package/dist/commands/channel/spawn.js.map +1 -0
  84. package/dist/commands/channel/store/events.d.ts +39 -0
  85. package/dist/commands/channel/store/events.d.ts.map +1 -0
  86. package/dist/commands/channel/store/events.js +87 -0
  87. package/dist/commands/channel/store/events.js.map +1 -0
  88. package/dist/commands/channel/store/filter.d.ts +3 -0
  89. package/dist/commands/channel/store/filter.d.ts.map +1 -0
  90. package/dist/commands/channel/store/filter.js +2 -0
  91. package/dist/commands/channel/store/filter.js.map +1 -0
  92. package/dist/commands/channel/store/lock.d.ts +23 -0
  93. package/dist/commands/channel/store/lock.d.ts.map +1 -0
  94. package/dist/commands/channel/store/lock.js +99 -0
  95. package/dist/commands/channel/store/lock.js.map +1 -0
  96. package/dist/commands/channel/store/paths.d.ts +63 -0
  97. package/dist/commands/channel/store/paths.d.ts.map +1 -0
  98. package/dist/commands/channel/store/paths.js +246 -0
  99. package/dist/commands/channel/store/paths.js.map +1 -0
  100. package/dist/commands/channel/store/schema.d.ts +27 -0
  101. package/dist/commands/channel/store/schema.d.ts.map +1 -0
  102. package/dist/commands/channel/store/schema.js +34 -0
  103. package/dist/commands/channel/store/schema.js.map +1 -0
  104. package/dist/commands/channel/store/thread-state.d.ts +5 -0
  105. package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
  106. package/dist/commands/channel/store/thread-state.js +16 -0
  107. package/dist/commands/channel/store/thread-state.js.map +1 -0
  108. package/dist/commands/channel/store/watch.d.ts +19 -0
  109. package/dist/commands/channel/store/watch.d.ts.map +1 -0
  110. package/dist/commands/channel/store/watch.js +146 -0
  111. package/dist/commands/channel/store/watch.js.map +1 -0
  112. package/dist/commands/channel/supervisor/idle.d.ts +46 -0
  113. package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
  114. package/dist/commands/channel/supervisor/idle.js +72 -0
  115. package/dist/commands/channel/supervisor/idle.js.map +1 -0
  116. package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
  117. package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
  118. package/dist/commands/channel/supervisor/inbox.js +160 -0
  119. package/dist/commands/channel/supervisor/inbox.js.map +1 -0
  120. package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
  121. package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
  122. package/dist/commands/channel/supervisor/shutdown.js +146 -0
  123. package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
  124. package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
  125. package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
  126. package/dist/commands/channel/supervisor/stdout.js +121 -0
  127. package/dist/commands/channel/supervisor/stdout.js.map +1 -0
  128. package/dist/commands/channel/supervisor/turns.d.ts +31 -0
  129. package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
  130. package/dist/commands/channel/supervisor/turns.js +45 -0
  131. package/dist/commands/channel/supervisor/turns.js.map +1 -0
  132. package/dist/commands/channel/supervisor/warning.d.ts +48 -0
  133. package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
  134. package/dist/commands/channel/supervisor/warning.js +77 -0
  135. package/dist/commands/channel/supervisor/warning.js.map +1 -0
  136. package/dist/commands/channel/supervisor.d.ts +59 -0
  137. package/dist/commands/channel/supervisor.d.ts.map +1 -0
  138. package/dist/commands/channel/supervisor.js +376 -0
  139. package/dist/commands/channel/supervisor.js.map +1 -0
  140. package/dist/commands/channel/text-body.d.ts +13 -0
  141. package/dist/commands/channel/text-body.d.ts.map +1 -0
  142. package/dist/commands/channel/text-body.js +47 -0
  143. package/dist/commands/channel/text-body.js.map +1 -0
  144. package/dist/commands/channel/threads.d.ts +39 -0
  145. package/dist/commands/channel/threads.d.ts.map +1 -0
  146. package/dist/commands/channel/threads.js +106 -0
  147. package/dist/commands/channel/threads.js.map +1 -0
  148. package/dist/commands/channel/title.d.ts +12 -0
  149. package/dist/commands/channel/title.d.ts.map +1 -0
  150. package/dist/commands/channel/title.js +24 -0
  151. package/dist/commands/channel/title.js.map +1 -0
  152. package/dist/commands/channel/wait.d.ts +17 -0
  153. package/dist/commands/channel/wait.d.ts.map +1 -0
  154. package/dist/commands/channel/wait.js +75 -0
  155. package/dist/commands/channel/wait.js.map +1 -0
  156. package/dist/commands/init.d.ts +66 -0
  157. package/dist/commands/init.d.ts.map +1 -0
  158. package/dist/commands/init.js +1704 -0
  159. package/dist/commands/init.js.map +1 -0
  160. package/dist/commands/mem.d.ts +30 -0
  161. package/dist/commands/mem.d.ts.map +1 -0
  162. package/dist/commands/mem.js +424 -0
  163. package/dist/commands/mem.js.map +1 -0
  164. package/dist/commands/uninstall.d.ts +27 -0
  165. package/dist/commands/uninstall.d.ts.map +1 -0
  166. package/dist/commands/uninstall.js +340 -0
  167. package/dist/commands/uninstall.js.map +1 -0
  168. package/dist/commands/update.d.ts +72 -0
  169. package/dist/commands/update.d.ts.map +1 -0
  170. package/dist/commands/update.js +2023 -0
  171. package/dist/commands/update.js.map +1 -0
  172. package/dist/commands/upgrade.d.ts +28 -0
  173. package/dist/commands/upgrade.d.ts.map +1 -0
  174. package/dist/commands/upgrade.js +88 -0
  175. package/dist/commands/upgrade.js.map +1 -0
  176. package/dist/commands/workflow.d.ts +35 -0
  177. package/dist/commands/workflow.d.ts.map +1 -0
  178. package/dist/commands/workflow.js +232 -0
  179. package/dist/commands/workflow.js.map +1 -0
  180. package/dist/configurators/antigravity.d.ts +7 -0
  181. package/dist/configurators/antigravity.d.ts.map +1 -0
  182. package/dist/configurators/antigravity.js +19 -0
  183. package/dist/configurators/antigravity.js.map +1 -0
  184. package/dist/configurators/claude.d.ts +12 -0
  185. package/dist/configurators/claude.d.ts.map +1 -0
  186. package/dist/configurators/claude.js +107 -0
  187. package/dist/configurators/claude.js.map +1 -0
  188. package/dist/configurators/codebuddy.d.ts +10 -0
  189. package/dist/configurators/codebuddy.d.ts.map +1 -0
  190. package/dist/configurators/codebuddy.js +30 -0
  191. package/dist/configurators/codebuddy.js.map +1 -0
  192. package/dist/configurators/codex.d.ts +8 -0
  193. package/dist/configurators/codex.d.ts.map +1 -0
  194. package/dist/configurators/codex.js +73 -0
  195. package/dist/configurators/codex.js.map +1 -0
  196. package/dist/configurators/copilot.d.ts +10 -0
  197. package/dist/configurators/copilot.d.ts.map +1 -0
  198. package/dist/configurators/copilot.js +51 -0
  199. package/dist/configurators/copilot.js.map +1 -0
  200. package/dist/configurators/cursor.d.ts +10 -0
  201. package/dist/configurators/cursor.d.ts.map +1 -0
  202. package/dist/configurators/cursor.js +29 -0
  203. package/dist/configurators/cursor.js.map +1 -0
  204. package/dist/configurators/devin.d.ts +7 -0
  205. package/dist/configurators/devin.d.ts.map +1 -0
  206. package/dist/configurators/devin.js +19 -0
  207. package/dist/configurators/devin.js.map +1 -0
  208. package/dist/configurators/droid.d.ts +10 -0
  209. package/dist/configurators/droid.d.ts.map +1 -0
  210. package/dist/configurators/droid.js +30 -0
  211. package/dist/configurators/droid.js.map +1 -0
  212. package/dist/configurators/gemini.d.ts +16 -0
  213. package/dist/configurators/gemini.d.ts.map +1 -0
  214. package/dist/configurators/gemini.js +38 -0
  215. package/dist/configurators/gemini.js.map +1 -0
  216. package/dist/configurators/index.d.ts +86 -0
  217. package/dist/configurators/index.d.ts.map +1 -0
  218. package/dist/configurators/index.js +430 -0
  219. package/dist/configurators/index.js.map +1 -0
  220. package/dist/configurators/kilo.d.ts +7 -0
  221. package/dist/configurators/kilo.d.ts.map +1 -0
  222. package/dist/configurators/kilo.js +19 -0
  223. package/dist/configurators/kilo.js.map +1 -0
  224. package/dist/configurators/kiro.d.ts +10 -0
  225. package/dist/configurators/kiro.d.ts.map +1 -0
  226. package/dist/configurators/kiro.js +33 -0
  227. package/dist/configurators/kiro.js.map +1 -0
  228. package/dist/configurators/opencode.d.ts +14 -0
  229. package/dist/configurators/opencode.d.ts.map +1 -0
  230. package/dist/configurators/opencode.js +102 -0
  231. package/dist/configurators/opencode.js.map +1 -0
  232. package/dist/configurators/pi.d.ts +3 -0
  233. package/dist/configurators/pi.d.ts.map +1 -0
  234. package/dist/configurators/pi.js +55 -0
  235. package/dist/configurators/pi.js.map +1 -0
  236. package/dist/configurators/qoder.d.ts +11 -0
  237. package/dist/configurators/qoder.d.ts.map +1 -0
  238. package/dist/configurators/qoder.js +31 -0
  239. package/dist/configurators/qoder.js.map +1 -0
  240. package/dist/configurators/reasonix.d.ts +23 -0
  241. package/dist/configurators/reasonix.d.ts.map +1 -0
  242. package/dist/configurators/reasonix.js +60 -0
  243. package/dist/configurators/reasonix.js.map +1 -0
  244. package/dist/configurators/shared.d.ts +172 -0
  245. package/dist/configurators/shared.d.ts.map +1 -0
  246. package/dist/configurators/shared.js +530 -0
  247. package/dist/configurators/shared.js.map +1 -0
  248. package/dist/configurators/trae.d.ts +17 -0
  249. package/dist/configurators/trae.d.ts.map +1 -0
  250. package/dist/configurators/trae.js +42 -0
  251. package/dist/configurators/trae.js.map +1 -0
  252. package/dist/configurators/workflow.d.ts +37 -0
  253. package/dist/configurators/workflow.d.ts.map +1 -0
  254. package/dist/configurators/workflow.js +177 -0
  255. package/dist/configurators/workflow.js.map +1 -0
  256. package/dist/configurators/zcode.d.ts +19 -0
  257. package/dist/configurators/zcode.d.ts.map +1 -0
  258. package/dist/configurators/zcode.js +54 -0
  259. package/dist/configurators/zcode.js.map +1 -0
  260. package/dist/constants/paths.d.ts +74 -0
  261. package/dist/constants/paths.d.ts.map +1 -0
  262. package/dist/constants/paths.js +83 -0
  263. package/dist/constants/paths.js.map +1 -0
  264. package/dist/constants/version.d.ts +9 -0
  265. package/dist/constants/version.d.ts.map +1 -0
  266. package/dist/constants/version.js +15 -0
  267. package/dist/constants/version.js.map +1 -0
  268. package/dist/index.d.ts +9 -0
  269. package/dist/index.d.ts.map +1 -0
  270. package/dist/index.js +9 -0
  271. package/dist/index.js.map +1 -0
  272. package/dist/migrations/index.d.ts +62 -0
  273. package/dist/migrations/index.d.ts.map +1 -0
  274. package/dist/migrations/index.js +187 -0
  275. package/dist/migrations/index.js.map +1 -0
  276. package/dist/migrations/manifests/0.1.9.json +30 -0
  277. package/dist/migrations/manifests/0.2.0.json +49 -0
  278. package/dist/migrations/manifests/0.2.12.json +9 -0
  279. package/dist/migrations/manifests/0.2.13.json +9 -0
  280. package/dist/migrations/manifests/0.2.14.json +175 -0
  281. package/dist/migrations/manifests/0.2.15.json +33 -0
  282. package/dist/migrations/manifests/0.3.0-beta.0.json +297 -0
  283. package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
  284. package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
  285. package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
  286. package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
  287. package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
  288. package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
  289. package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
  290. package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
  291. package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
  292. package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
  293. package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
  294. package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
  295. package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
  296. package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
  297. package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
  298. package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
  299. package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
  300. package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
  301. package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
  302. package/dist/migrations/manifests/0.3.0-rc.3.json +9 -0
  303. package/dist/migrations/manifests/0.3.0-rc.4.json +9 -0
  304. package/dist/migrations/manifests/0.3.0-rc.5.json +9 -0
  305. package/dist/migrations/manifests/0.3.0-rc.6.json +9 -0
  306. package/dist/migrations/manifests/0.3.0.json +11 -0
  307. package/dist/migrations/manifests/0.3.1.json +9 -0
  308. package/dist/migrations/manifests/0.3.10.json +9 -0
  309. package/dist/migrations/manifests/0.3.2.json +9 -0
  310. package/dist/migrations/manifests/0.3.3.json +9 -0
  311. package/dist/migrations/manifests/0.3.4.json +21 -0
  312. package/dist/migrations/manifests/0.3.5.json +9 -0
  313. package/dist/migrations/manifests/0.3.6.json +9 -0
  314. package/dist/migrations/manifests/0.3.7.json +9 -0
  315. package/dist/migrations/manifests/0.3.8.json +9 -0
  316. package/dist/migrations/manifests/0.3.9.json +9 -0
  317. package/dist/migrations/manifests/0.4.0-beta.1.json +300 -0
  318. package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
  319. package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
  320. package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
  321. package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
  322. package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
  323. package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
  324. package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
  325. package/dist/migrations/manifests/0.4.0-beta.8.json +42 -0
  326. package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
  327. package/dist/migrations/manifests/0.4.0-rc.0.json +9 -0
  328. package/dist/migrations/manifests/0.4.0-rc.1.json +9 -0
  329. package/dist/migrations/manifests/0.4.0.json +9 -0
  330. package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
  331. package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
  332. package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
  333. package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
  334. package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
  335. package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
  336. package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
  337. package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
  338. package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
  339. package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
  340. package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
  341. package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
  342. package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
  343. package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
  344. package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
  345. package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
  346. package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
  347. package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
  348. package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
  349. package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
  350. package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
  351. package/dist/migrations/manifests/0.5.0-rc.1.json +9 -0
  352. package/dist/migrations/manifests/0.5.0-rc.2.json +9 -0
  353. package/dist/migrations/manifests/0.5.0-rc.3.json +9 -0
  354. package/dist/migrations/manifests/0.5.0-rc.4.json +9 -0
  355. package/dist/migrations/manifests/0.5.0-rc.5.json +9 -0
  356. package/dist/migrations/manifests/0.5.0-rc.6.json +9 -0
  357. package/dist/migrations/manifests/0.5.0-rc.7.json +9 -0
  358. package/dist/migrations/manifests/0.5.0.json +9 -0
  359. package/dist/migrations/manifests/0.5.1.json +9 -0
  360. package/dist/migrations/manifests/0.5.10.json +9 -0
  361. package/dist/migrations/manifests/0.5.11.json +16 -0
  362. package/dist/migrations/manifests/0.5.12.json +9 -0
  363. package/dist/migrations/manifests/0.5.13.json +9 -0
  364. package/dist/migrations/manifests/0.5.14.json +9 -0
  365. package/dist/migrations/manifests/0.5.15.json +9 -0
  366. package/dist/migrations/manifests/0.5.16.json +9 -0
  367. package/dist/migrations/manifests/0.5.17.json +9 -0
  368. package/dist/migrations/manifests/0.5.18.json +9 -0
  369. package/dist/migrations/manifests/0.5.19.json +9 -0
  370. package/dist/migrations/manifests/0.5.2.json +9 -0
  371. package/dist/migrations/manifests/0.5.3.json +9 -0
  372. package/dist/migrations/manifests/0.5.4.json +9 -0
  373. package/dist/migrations/manifests/0.5.5.json +9 -0
  374. package/dist/migrations/manifests/0.5.6.json +9 -0
  375. package/dist/migrations/manifests/0.5.7.json +16 -0
  376. package/dist/migrations/manifests/0.5.8.json +9 -0
  377. package/dist/migrations/manifests/0.5.9.json +9 -0
  378. package/dist/migrations/manifests/0.6.0-beta.0.json +16 -0
  379. package/dist/migrations/manifests/0.6.0-beta.1.json +9 -0
  380. package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
  381. package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
  382. package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
  383. package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
  384. package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
  385. package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
  386. package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
  387. package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
  388. package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
  389. package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
  390. package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
  391. package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
  392. package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
  393. package/dist/migrations/manifests/0.6.0-beta.22.json +9 -0
  394. package/dist/migrations/manifests/0.6.0-beta.23.json +88 -0
  395. package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
  396. package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
  397. package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
  398. package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
  399. package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
  400. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  401. package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
  402. package/dist/migrations/manifests/0.6.0-rc.0.json +9 -0
  403. package/dist/migrations/manifests/0.6.0.json +9 -0
  404. package/dist/migrations/manifests/0.6.1.json +9 -0
  405. package/dist/migrations/manifests/0.6.2.json +9 -0
  406. package/dist/migrations/manifests/0.6.3.json +24 -0
  407. package/dist/migrations/manifests/0.6.4.json +9 -0
  408. package/dist/migrations/manifests/0.6.5.json +9 -0
  409. package/dist/templates/claude/agents/trellis-check.md +115 -0
  410. package/dist/templates/claude/agents/trellis-implement.md +110 -0
  411. package/dist/templates/claude/agents/trellis-research.md +137 -0
  412. package/dist/templates/claude/hooks/statusline.py +324 -0
  413. package/dist/templates/claude/index.d.ts +31 -0
  414. package/dist/templates/claude/index.d.ts.map +1 -0
  415. package/dist/templates/claude/index.js +58 -0
  416. package/dist/templates/claude/index.js.map +1 -0
  417. package/dist/templates/claude/settings.json +73 -0
  418. package/dist/templates/codebuddy/agents/trellis-check.md +115 -0
  419. package/dist/templates/codebuddy/agents/trellis-implement.md +110 -0
  420. package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
  421. package/dist/templates/codebuddy/index.d.ts +15 -0
  422. package/dist/templates/codebuddy/index.d.ts.map +1 -0
  423. package/dist/templates/codebuddy/index.js +15 -0
  424. package/dist/templates/codebuddy/index.js.map +1 -0
  425. package/dist/templates/codebuddy/settings.json +59 -0
  426. package/dist/templates/codex/agents/trellis-check.toml +59 -0
  427. package/dist/templates/codex/agents/trellis-implement.toml +40 -0
  428. package/dist/templates/codex/agents/trellis-research.toml +73 -0
  429. package/dist/templates/codex/config.toml +28 -0
  430. package/dist/templates/codex/hooks/session-start.py +545 -0
  431. package/dist/templates/codex/hooks.json +15 -0
  432. package/dist/templates/codex/index.d.ts +39 -0
  433. package/dist/templates/codex/index.d.ts.map +1 -0
  434. package/dist/templates/codex/index.js +86 -0
  435. package/dist/templates/codex/index.js.map +1 -0
  436. package/dist/templates/codex/skills/before-dev/SKILL.md +40 -0
  437. package/dist/templates/codex/skills/brainstorm/SKILL.md +130 -0
  438. package/dist/templates/codex/skills/break-loop/SKILL.md +130 -0
  439. package/dist/templates/codex/skills/check/SKILL.md +98 -0
  440. package/dist/templates/codex/skills/check-cross-layer/SKILL.md +158 -0
  441. package/dist/templates/codex/skills/create-command/SKILL.md +101 -0
  442. package/dist/templates/codex/skills/finish-work/SKILL.md +98 -0
  443. package/dist/templates/codex/skills/improve-ut/SKILL.md +69 -0
  444. package/dist/templates/codex/skills/integrate-skill/SKILL.md +221 -0
  445. package/dist/templates/codex/skills/onboard/SKILL.md +363 -0
  446. package/dist/templates/codex/skills/record-session/SKILL.md +67 -0
  447. package/dist/templates/codex/skills/start/SKILL.md +64 -0
  448. package/dist/templates/codex/skills/update-spec/SKILL.md +335 -0
  449. package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +67 -0
  450. package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +480 -0
  451. package/dist/templates/common/bundled-skills/trellis-channel/references/forum.md +233 -0
  452. package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +226 -0
  453. package/dist/templates/common/bundled-skills/trellis-channel/references/workers.md +276 -0
  454. package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +128 -0
  455. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +85 -0
  456. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
  457. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +56 -0
  458. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +84 -0
  459. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
  460. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +123 -0
  461. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
  462. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
  463. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +66 -0
  464. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
  465. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +146 -0
  466. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
  467. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
  468. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-channel.md +69 -0
  469. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
  470. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
  471. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +130 -0
  472. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
  473. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
  474. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +82 -0
  475. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +72 -0
  476. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
  477. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +88 -0
  478. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +85 -0
  479. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +81 -0
  480. package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +65 -0
  481. package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +93 -0
  482. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/SKILL.md +41 -0
  483. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +90 -0
  484. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/repository-analysis.md +59 -0
  485. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +61 -0
  486. package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-writing.md +70 -0
  487. package/dist/templates/common/commands/continue.md +57 -0
  488. package/dist/templates/common/commands/finish-work.md +74 -0
  489. package/dist/templates/common/commands/start.md +59 -0
  490. package/dist/templates/common/index.d.ts +48 -0
  491. package/dist/templates/common/index.d.ts.map +1 -0
  492. package/dist/templates/common/index.js +104 -0
  493. package/dist/templates/common/index.js.map +1 -0
  494. package/dist/templates/common/skills/before-dev.md +35 -0
  495. package/dist/templates/common/skills/brainstorm.md +168 -0
  496. package/dist/templates/common/skills/break-loop.md +184 -0
  497. package/dist/templates/common/skills/check.md +93 -0
  498. package/dist/templates/common/skills/update-spec.md +351 -0
  499. package/dist/templates/copilot/hooks/session-start.py +547 -0
  500. package/dist/templates/copilot/hooks.json +19 -0
  501. package/dist/templates/copilot/index.d.ts +23 -0
  502. package/dist/templates/copilot/index.d.ts.map +1 -0
  503. package/dist/templates/copilot/index.js +54 -0
  504. package/dist/templates/copilot/index.js.map +1 -0
  505. package/dist/templates/copilot/prompts/before-dev.prompt.md +39 -0
  506. package/dist/templates/copilot/prompts/brainstorm.prompt.md +129 -0
  507. package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
  508. package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +157 -0
  509. package/dist/templates/copilot/prompts/check.prompt.md +97 -0
  510. package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
  511. package/dist/templates/copilot/prompts/finish-work.prompt.md +107 -0
  512. package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
  513. package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
  514. package/dist/templates/copilot/prompts/parallel.prompt.md +204 -0
  515. package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
  516. package/dist/templates/copilot/prompts/start.prompt.md +63 -0
  517. package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
  518. package/dist/templates/cursor/agents/trellis-check.md +114 -0
  519. package/dist/templates/cursor/agents/trellis-implement.md +109 -0
  520. package/dist/templates/cursor/agents/trellis-research.md +136 -0
  521. package/dist/templates/cursor/hooks.json +24 -0
  522. package/dist/templates/cursor/index.d.ts +13 -0
  523. package/dist/templates/cursor/index.d.ts.map +1 -0
  524. package/dist/templates/cursor/index.js +13 -0
  525. package/dist/templates/cursor/index.js.map +1 -0
  526. package/dist/templates/droid/droids/trellis-check.md +107 -0
  527. package/dist/templates/droid/droids/trellis-implement.md +102 -0
  528. package/dist/templates/droid/droids/trellis-research.md +137 -0
  529. package/dist/templates/droid/index.d.ts +15 -0
  530. package/dist/templates/droid/index.d.ts.map +1 -0
  531. package/dist/templates/droid/index.js +15 -0
  532. package/dist/templates/droid/index.js.map +1 -0
  533. package/dist/templates/droid/settings.json +59 -0
  534. package/dist/templates/extract.d.ts +40 -0
  535. package/dist/templates/extract.d.ts.map +1 -0
  536. package/dist/templates/extract.js +106 -0
  537. package/dist/templates/extract.js.map +1 -0
  538. package/dist/templates/gemini/agents/trellis-check.md +107 -0
  539. package/dist/templates/gemini/agents/trellis-implement.md +102 -0
  540. package/dist/templates/gemini/agents/trellis-research.md +136 -0
  541. package/dist/templates/gemini/index.d.ts +13 -0
  542. package/dist/templates/gemini/index.d.ts.map +1 -0
  543. package/dist/templates/gemini/index.js +13 -0
  544. package/dist/templates/gemini/index.js.map +1 -0
  545. package/dist/templates/gemini/settings.json +28 -0
  546. package/dist/templates/kiro/agents/trellis-check.json +14 -0
  547. package/dist/templates/kiro/agents/trellis-implement.json +14 -0
  548. package/dist/templates/kiro/agents/trellis-research.json +22 -0
  549. package/dist/templates/kiro/agents/trellis.json +20 -0
  550. package/dist/templates/kiro/hooks/cviauto-workflow-state.kiro.hook +14 -0
  551. package/dist/templates/kiro/index.d.ts +32 -0
  552. package/dist/templates/kiro/index.d.ts.map +1 -0
  553. package/dist/templates/kiro/index.js +28 -0
  554. package/dist/templates/kiro/index.js.map +1 -0
  555. package/dist/templates/markdown/agents.md +21 -0
  556. package/dist/templates/markdown/gitignore.txt +15 -0
  557. package/dist/templates/markdown/index.d.ts +27 -0
  558. package/dist/templates/markdown/index.d.ts.map +1 -0
  559. package/dist/templates/markdown/index.js +52 -0
  560. package/dist/templates/markdown/index.js.map +1 -0
  561. package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
  562. package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
  563. package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
  564. package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
  565. package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
  566. package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
  567. package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
  568. package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
  569. package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
  570. package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
  571. package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
  572. package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
  573. package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
  574. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +223 -0
  575. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +327 -0
  576. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +633 -0
  577. package/dist/templates/markdown/spec/guides/index.md.txt +97 -0
  578. package/dist/templates/markdown/workspace-index.md +125 -0
  579. package/dist/templates/markdown/worktree.yaml.txt +58 -0
  580. package/dist/templates/opencode/agents/trellis-check.md +122 -0
  581. package/dist/templates/opencode/agents/trellis-implement.md +118 -0
  582. package/dist/templates/opencode/agents/trellis-research.md +145 -0
  583. package/dist/templates/opencode/lib/cviauto-context.js +418 -0
  584. package/dist/templates/opencode/lib/session-utils.js +609 -0
  585. package/dist/templates/opencode/package.json +5 -0
  586. package/dist/templates/opencode/plugins/inject-subagent-context.js +570 -0
  587. package/dist/templates/opencode/plugins/inject-workflow-state.js +175 -0
  588. package/dist/templates/opencode/plugins/session-start.js +140 -0
  589. package/dist/templates/pi/agents/trellis-check.md +37 -0
  590. package/dist/templates/pi/agents/trellis-implement.md +42 -0
  591. package/dist/templates/pi/agents/trellis-research.md +25 -0
  592. package/dist/templates/pi/extensions/trellis/index.ts.txt +1680 -0
  593. package/dist/templates/pi/index.d.ts +5 -0
  594. package/dist/templates/pi/index.d.ts.map +1 -0
  595. package/dist/templates/pi/index.js +12 -0
  596. package/dist/templates/pi/index.js.map +1 -0
  597. package/dist/templates/pi/settings.json +6 -0
  598. package/dist/templates/qoder/agents/trellis-check.md +108 -0
  599. package/dist/templates/qoder/agents/trellis-implement.md +103 -0
  600. package/dist/templates/qoder/agents/trellis-research.md +137 -0
  601. package/dist/templates/qoder/index.d.ts +15 -0
  602. package/dist/templates/qoder/index.d.ts.map +1 -0
  603. package/dist/templates/qoder/index.js +15 -0
  604. package/dist/templates/qoder/index.js.map +1 -0
  605. package/dist/templates/qoder/settings.json +47 -0
  606. package/dist/templates/reasonix/agents/trellis-check.md +36 -0
  607. package/dist/templates/reasonix/agents/trellis-implement.md +41 -0
  608. package/dist/templates/reasonix/index.d.ts +13 -0
  609. package/dist/templates/reasonix/index.d.ts.map +1 -0
  610. package/dist/templates/reasonix/index.js +16 -0
  611. package/dist/templates/reasonix/index.js.map +1 -0
  612. package/dist/templates/shared-hooks/index.d.ts +58 -0
  613. package/dist/templates/shared-hooks/index.d.ts.map +1 -0
  614. package/dist/templates/shared-hooks/index.js +101 -0
  615. package/dist/templates/shared-hooks/index.js.map +1 -0
  616. package/dist/templates/shared-hooks/inject-shell-session-context.py +183 -0
  617. package/dist/templates/shared-hooks/inject-subagent-context.py +786 -0
  618. package/dist/templates/shared-hooks/inject-workflow-state.py +408 -0
  619. package/dist/templates/shared-hooks/session-start.py +844 -0
  620. package/dist/templates/template-utils.d.ts +28 -0
  621. package/dist/templates/template-utils.d.ts.map +1 -0
  622. package/dist/templates/template-utils.js +95 -0
  623. package/dist/templates/template-utils.js.map +1 -0
  624. package/dist/templates/trae/agents/trellis-check.md +108 -0
  625. package/dist/templates/trae/agents/trellis-implement.md +103 -0
  626. package/dist/templates/trae/agents/trellis-research.md +137 -0
  627. package/dist/templates/trae/hooks.json +27 -0
  628. package/dist/templates/trae/index.d.ts +15 -0
  629. package/dist/templates/trae/index.d.ts.map +1 -0
  630. package/dist/templates/trae/index.js +15 -0
  631. package/dist/templates/trae/index.js.map +1 -0
  632. package/dist/templates/trellis/agents/check.md +70 -0
  633. package/dist/templates/trellis/agents/implement.md +71 -0
  634. package/dist/templates/trellis/config.yaml +110 -0
  635. package/dist/templates/trellis/gitignore.txt +40 -0
  636. package/dist/templates/trellis/index.d.ts +65 -0
  637. package/dist/templates/trellis/index.d.ts.map +1 -0
  638. package/dist/templates/trellis/index.js +119 -0
  639. package/dist/templates/trellis/index.js.map +1 -0
  640. package/dist/templates/trellis/scripts/__init__.py +5 -0
  641. package/dist/templates/trellis/scripts/add_session.py +567 -0
  642. package/dist/templates/trellis/scripts/common/__init__.py +92 -0
  643. package/dist/templates/trellis/scripts/common/active_task.py +628 -0
  644. package/dist/templates/trellis/scripts/common/cli_adapter.py +851 -0
  645. package/dist/templates/trellis/scripts/common/config.py +444 -0
  646. package/dist/templates/trellis/scripts/common/cviauto_config.py +131 -0
  647. package/dist/templates/trellis/scripts/common/developer.py +190 -0
  648. package/dist/templates/trellis/scripts/common/git.py +31 -0
  649. package/dist/templates/trellis/scripts/common/git_context.py +106 -0
  650. package/dist/templates/trellis/scripts/common/io.py +37 -0
  651. package/dist/templates/trellis/scripts/common/log.py +45 -0
  652. package/dist/templates/trellis/scripts/common/packages_context.py +238 -0
  653. package/dist/templates/trellis/scripts/common/paths.py +447 -0
  654. package/dist/templates/trellis/scripts/common/safe_commit.py +315 -0
  655. package/dist/templates/trellis/scripts/common/session_context.py +821 -0
  656. package/dist/templates/trellis/scripts/common/task_context.py +223 -0
  657. package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
  658. package/dist/templates/trellis/scripts/common/task_store.py +747 -0
  659. package/dist/templates/trellis/scripts/common/task_utils.py +274 -0
  660. package/dist/templates/trellis/scripts/common/tasks.py +112 -0
  661. package/dist/templates/trellis/scripts/common/types.py +110 -0
  662. package/dist/templates/trellis/scripts/common/workflow_phase.py +212 -0
  663. package/dist/templates/trellis/scripts/get_context.py +16 -0
  664. package/dist/templates/trellis/scripts/get_developer.py +26 -0
  665. package/dist/templates/trellis/scripts/hooks/linear_sync.py +243 -0
  666. package/dist/templates/trellis/scripts/init_developer.py +51 -0
  667. package/dist/templates/trellis/scripts/task.py +500 -0
  668. package/dist/templates/trellis/tasks/.gitkeep +0 -0
  669. package/dist/templates/trellis/workflow.md +697 -0
  670. package/dist/templates/zcode/agents/trellis-check.md +102 -0
  671. package/dist/templates/zcode/agents/trellis-implement.md +102 -0
  672. package/dist/templates/zcode/index.d.ts +15 -0
  673. package/dist/templates/zcode/index.d.ts.map +1 -0
  674. package/dist/templates/zcode/index.js +18 -0
  675. package/dist/templates/zcode/index.js.map +1 -0
  676. package/dist/types/ai-tools.d.ts +95 -0
  677. package/dist/types/ai-tools.d.ts.map +1 -0
  678. package/dist/types/ai-tools.js +330 -0
  679. package/dist/types/ai-tools.js.map +1 -0
  680. package/dist/types/migration.d.ts +125 -0
  681. package/dist/types/migration.d.ts.map +1 -0
  682. package/dist/types/migration.js +8 -0
  683. package/dist/types/migration.js.map +1 -0
  684. package/dist/utils/agent-refs.d.ts +31 -0
  685. package/dist/utils/agent-refs.d.ts.map +1 -0
  686. package/dist/utils/agent-refs.js +63 -0
  687. package/dist/utils/agent-refs.js.map +1 -0
  688. package/dist/utils/compare-versions.d.ts +12 -0
  689. package/dist/utils/compare-versions.d.ts.map +1 -0
  690. package/dist/utils/compare-versions.js +86 -0
  691. package/dist/utils/compare-versions.js.map +1 -0
  692. package/dist/utils/cwd-guard.d.ts +38 -0
  693. package/dist/utils/cwd-guard.d.ts.map +1 -0
  694. package/dist/utils/cwd-guard.js +62 -0
  695. package/dist/utils/cwd-guard.js.map +1 -0
  696. package/dist/utils/file-writer.d.ts +36 -0
  697. package/dist/utils/file-writer.d.ts.map +1 -0
  698. package/dist/utils/file-writer.js +203 -0
  699. package/dist/utils/file-writer.js.map +1 -0
  700. package/dist/utils/manifest-prune.d.ts +61 -0
  701. package/dist/utils/manifest-prune.d.ts.map +1 -0
  702. package/dist/utils/manifest-prune.js +137 -0
  703. package/dist/utils/manifest-prune.js.map +1 -0
  704. package/dist/utils/posix.d.ts +13 -0
  705. package/dist/utils/posix.d.ts.map +1 -0
  706. package/dist/utils/posix.js +15 -0
  707. package/dist/utils/posix.js.map +1 -0
  708. package/dist/utils/project-detector.d.ts +46 -0
  709. package/dist/utils/project-detector.d.ts.map +1 -0
  710. package/dist/utils/project-detector.js +666 -0
  711. package/dist/utils/project-detector.js.map +1 -0
  712. package/dist/utils/proxy.d.ts +25 -0
  713. package/dist/utils/proxy.d.ts.map +1 -0
  714. package/dist/utils/proxy.js +60 -0
  715. package/dist/utils/proxy.js.map +1 -0
  716. package/dist/utils/registry-config.d.ts +7 -0
  717. package/dist/utils/registry-config.d.ts.map +1 -0
  718. package/dist/utils/registry-config.js +171 -0
  719. package/dist/utils/registry-config.js.map +1 -0
  720. package/dist/utils/task-json.d.ts +13 -0
  721. package/dist/utils/task-json.d.ts.map +1 -0
  722. package/dist/utils/task-json.js +12 -0
  723. package/dist/utils/task-json.js.map +1 -0
  724. package/dist/utils/template-fetcher.d.ts +161 -0
  725. package/dist/utils/template-fetcher.d.ts.map +1 -0
  726. package/dist/utils/template-fetcher.js +956 -0
  727. package/dist/utils/template-fetcher.js.map +1 -0
  728. package/dist/utils/template-hash.d.ts +123 -0
  729. package/dist/utils/template-hash.d.ts.map +1 -0
  730. package/dist/utils/template-hash.js +334 -0
  731. package/dist/utils/template-hash.js.map +1 -0
  732. package/dist/utils/uninstall-scrubbers.d.ts +64 -0
  733. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
  734. package/dist/utils/uninstall-scrubbers.js +367 -0
  735. package/dist/utils/uninstall-scrubbers.js.map +1 -0
  736. package/dist/utils/workflow-resolver.d.ts +86 -0
  737. package/dist/utils/workflow-resolver.d.ts.map +1 -0
  738. package/dist/utils/workflow-resolver.js +265 -0
  739. package/dist/utils/workflow-resolver.js.map +1 -0
  740. package/package.json +89 -0
@@ -0,0 +1,1704 @@
1
+ import { execSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import readline from "node:readline";
5
+ import chalk from "chalk";
6
+ import figlet from "figlet";
7
+ import inquirer from "inquirer";
8
+ import { createWorkflowStructure } from "../configurators/workflow.js";
9
+ import { getPublicInitToolChoices, resolveCliFlag, configurePlatform, getConfiguredPlatforms, getPlatformsWithPythonHooks, } from "../configurators/index.js";
10
+ import { getPythonCommandForPlatform, setResolvedPythonCommand, } from "../configurators/shared.js";
11
+ import { AI_TOOLS } from "../types/ai-tools.js";
12
+ import { DIR_NAMES, FILE_NAMES, PATHS } from "../constants/paths.js";
13
+ import { VERSION } from "../constants/version.js";
14
+ import { agentsMdContent } from "../templates/markdown/index.js";
15
+ import { setWriteMode, startRecordingWrites, stopRecordingWrites, writeFile, } from "../utils/file-writer.js";
16
+ import { emptyTaskJson } from "../utils/task-json.js";
17
+ import { detectProjectType, detectMonorepo, sanitizePkgName, } from "../utils/project-detector.js";
18
+ import { initializeHashes, removeHash } from "../utils/template-hash.js";
19
+ import { NATIVE_WORKFLOW_ID, resolveWorkflowTemplate, } from "../utils/workflow-resolver.js";
20
+ import { isCwdHomedir, homedirGuardMessage, homedirBypassEnabled, } from "../utils/cwd-guard.js";
21
+ import { writeSpecRegistryConfig, } from "../utils/registry-config.js";
22
+ import { fetchTemplateIndex, probeRegistryIndex, downloadTemplateById, downloadRegistryDirect, parseRegistrySource, TIMEOUTS, TEMPLATE_INDEX_URL, } from "../utils/template-fetcher.js";
23
+ import { setupProxy, maskProxyUrl } from "../utils/proxy.js";
24
+ import { toPosix } from "../utils/posix.js";
25
+ import { updateHashes } from "../utils/template-hash.js";
26
+ const MIN_PYTHON_MAJOR = 3;
27
+ const MIN_PYTHON_MINOR = 9;
28
+ const PYTHON_VERSION_RE = /Python (\d+)\.(\d+)/;
29
+ const CVIAUTO_DEFAULT_SPEC_REGISTRY = "gh:baoanaz/cviauto-default-specs/marketplace";
30
+ const CVIAUTO_DEFAULT_SPEC_TEMPLATE = "Cviauto-spec";
31
+ function collectSpecPaths(cwd) {
32
+ const specRoot = path.join(cwd, PATHS.SPEC);
33
+ const paths = new Set();
34
+ if (!fs.existsSync(specRoot))
35
+ return paths;
36
+ const walk = (dir) => {
37
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
38
+ const fullPath = path.join(dir, entry.name);
39
+ if (entry.isDirectory()) {
40
+ walk(fullPath);
41
+ }
42
+ else if (entry.isFile()) {
43
+ paths.add(toPosix(path.relative(cwd, fullPath)));
44
+ }
45
+ }
46
+ };
47
+ walk(specRoot);
48
+ return paths;
49
+ }
50
+ export function isSupportedPythonVersion(versionOutput) {
51
+ const match = versionOutput.match(PYTHON_VERSION_RE);
52
+ if (!match)
53
+ return false;
54
+ const major = Number(match[1]);
55
+ const minor = Number(match[2]);
56
+ return (major > MIN_PYTHON_MAJOR ||
57
+ (major === MIN_PYTHON_MAJOR && minor >= MIN_PYTHON_MINOR));
58
+ }
59
+ function detectPythonVersion(command) {
60
+ try {
61
+ return execSync(`${command} --version`, {
62
+ encoding: "utf-8",
63
+ stdio: "pipe",
64
+ }).trim();
65
+ }
66
+ catch (err) {
67
+ const code = err?.code;
68
+ if (code === "EPERM" || code === "EACCES") {
69
+ return "sandbox-restricted";
70
+ }
71
+ return null;
72
+ }
73
+ }
74
+ export function requireSupportedPython(command) {
75
+ // Final escape hatch — set when the user knows python3 is on PATH but
76
+ // the probe keeps failing for environment-specific reasons.
77
+ if (process.env.TRELLIS_SKIP_PYTHON_CHECK === "1") {
78
+ return `version check skipped (TRELLIS_SKIP_PYTHON_CHECK=1)`;
79
+ }
80
+ const versionOutput = detectPythonVersion(command);
81
+ if (versionOutput === "sandbox-restricted") {
82
+ console.warn(chalk.yellow(`⚠ Python version check skipped — sandboxed environment blocked ` +
83
+ `child_process spawn (EPERM/EACCES). Assuming "${command}" is on ` +
84
+ `PATH. If init fails later, re-run on the host or set ` +
85
+ `TRELLIS_SKIP_PYTHON_CHECK=1.`));
86
+ return `version unknown (sandbox-restricted)`;
87
+ }
88
+ if (!versionOutput) {
89
+ throw new Error(`Python command "${command}" not found. Cviauto init requires Python ≥ 3.9.`);
90
+ }
91
+ if (!isSupportedPythonVersion(versionOutput)) {
92
+ throw new Error(`${versionOutput} detected via "${command}", but Cviauto init requires Python ≥ 3.9.`);
93
+ }
94
+ return versionOutput;
95
+ }
96
+ /**
97
+ * Candidate Python command list per platform.
98
+ *
99
+ * Windows: `python` is the usual python.org installer choice, but Microsoft
100
+ * Store ships `python3`, and the `py` launcher is `py -3`. We try all three
101
+ * before giving up — fixes #236 where users with only `python3` (not
102
+ * `python`) had `cviauto init` fail outright.
103
+ *
104
+ * Non-Windows: `python3` is canonical; `python` is a fallback for systems
105
+ * where Python 3 is the only Python and is named `python` (some Arch
106
+ * configs, conda envs).
107
+ */
108
+ const PYTHON_CANDIDATES = {
109
+ win32: ["python", "python3", "py -3"],
110
+ other: ["python3", "python"],
111
+ };
112
+ /**
113
+ * Detect a working Python ≥ 3.9 command on the host platform.
114
+ *
115
+ * Honors `TRELLIS_PYTHON_CMD` (explicit override, no probe) and
116
+ * `TRELLIS_SKIP_PYTHON_CHECK=1` (skip probe, trust platform default).
117
+ *
118
+ * Otherwise tries each candidate in `PYTHON_CANDIDATES` in order and returns
119
+ * the first whose `--version` matches `Python ≥ 3.9`. Caches the result via
120
+ * `setResolvedPythonCommand` so all downstream template / configurator
121
+ * writes pick up the resolved value.
122
+ *
123
+ * Throws a helpful, Windows-aware error if no candidate works.
124
+ */
125
+ export function resolveSupportedPython() {
126
+ // Explicit override — user knows their environment.
127
+ const override = process.env.TRELLIS_PYTHON_CMD?.trim();
128
+ if (override) {
129
+ setResolvedPythonCommand(override);
130
+ return { command: override, version: "set via TRELLIS_PYTHON_CMD" };
131
+ }
132
+ // Skip probe entirely.
133
+ if (process.env.TRELLIS_SKIP_PYTHON_CHECK === "1") {
134
+ const fallback = getPythonCommandForPlatform();
135
+ setResolvedPythonCommand(fallback);
136
+ return {
137
+ command: fallback,
138
+ version: "version check skipped (TRELLIS_SKIP_PYTHON_CHECK=1)",
139
+ };
140
+ }
141
+ const candidates = process.platform === "win32"
142
+ ? PYTHON_CANDIDATES.win32
143
+ : PYTHON_CANDIDATES.other;
144
+ const probeFailures = [];
145
+ for (const candidate of candidates) {
146
+ const probe = detectPythonVersion(candidate);
147
+ if (probe === "sandbox-restricted") {
148
+ console.warn(chalk.yellow(`⚠ Python version check skipped — sandboxed environment blocked ` +
149
+ `child_process spawn (EPERM/EACCES). Assuming "${candidate}" is ` +
150
+ `on PATH. If init fails later, re-run on the host or set ` +
151
+ `TRELLIS_SKIP_PYTHON_CHECK=1.`));
152
+ setResolvedPythonCommand(candidate);
153
+ return {
154
+ command: candidate,
155
+ version: "version unknown (sandbox-restricted)",
156
+ };
157
+ }
158
+ if (!probe) {
159
+ probeFailures.push(`${candidate}: not found`);
160
+ continue;
161
+ }
162
+ if (!isSupportedPythonVersion(probe)) {
163
+ probeFailures.push(`${candidate}: ${probe} (< 3.9)`);
164
+ continue;
165
+ }
166
+ setResolvedPythonCommand(candidate);
167
+ return { command: candidate, version: probe };
168
+ }
169
+ const isWindows = process.platform === "win32";
170
+ const installHint = isWindows
171
+ ? `Install Python ≥ 3.9 from https://www.python.org/downloads/windows/ — make sure ` +
172
+ `"Add Python to PATH" is checked in the installer. Or, if Python is ` +
173
+ `installed under a different name, set TRELLIS_PYTHON_CMD=<your-cmd> ` +
174
+ `before re-running init (e.g. \`set TRELLIS_PYTHON_CMD=py -3\`).`
175
+ : `Install Python ≥ 3.9 from https://www.python.org/downloads/ or via your ` +
176
+ `package manager. Or set TRELLIS_PYTHON_CMD=<your-cmd> before re-running.`;
177
+ throw new Error(`No supported Python command found. Tried: ${candidates.join(", ")}.\n` +
178
+ `Probe results:\n ${probeFailures.join("\n ")}\n\n` +
179
+ `Cviauto init requires Python ≥ 3.9. ${installHint}\n` +
180
+ `Last-resort escape hatch: set TRELLIS_SKIP_PYTHON_CHECK=1 to skip the probe entirely.`);
181
+ }
182
+ function getOsDisplayName(platform = process.platform) {
183
+ switch (platform) {
184
+ case "win32":
185
+ return "Windows";
186
+ case "darwin":
187
+ return "macOS";
188
+ case "linux":
189
+ return "Linux";
190
+ default:
191
+ return platform;
192
+ }
193
+ }
194
+ function logPythonAdaptationNotice(command) {
195
+ const osName = getOsDisplayName();
196
+ console.log(chalk.blue(`📌 ${osName} detected: Cviauto rendered Python commands as "${command}" in generated hooks, settings, and help text`));
197
+ }
198
+ // =============================================================================
199
+ // Bootstrap Task Creation
200
+ // =============================================================================
201
+ const BOOTSTRAP_TASK_NAME = "00-bootstrap-guidelines";
202
+ /**
203
+ * Slugify a developer name for safe use in task directory names.
204
+ *
205
+ * Unlike `sanitizePkgName` (which only strips npm @scope/ prefixes), this
206
+ * handles arbitrary developer input: spaces, Unicode letters, punctuation,
207
+ * path separators. Returns "user" fallback when input slugifies to empty.
208
+ *
209
+ * Exported for unit testing; not part of the public API.
210
+ */
211
+ export function slugifyDeveloperName(name) {
212
+ const slug = name
213
+ .toLowerCase()
214
+ .normalize("NFKD")
215
+ .replace(/[^\p{Letter}\p{Number}]+/gu, "-")
216
+ .replace(/^-+|-+$/g, "");
217
+ return slug || "user";
218
+ }
219
+ /**
220
+ * Write a task skeleton (task.json + prd.md).
221
+ *
222
+ * Idempotent: if the task dir already exists, returns true without touching
223
+ * anything. Shared by both creator bootstrap and joiner onboarding flows.
224
+ */
225
+ function writeTaskSkeleton(cwd, taskName, taskJson, prdContent) {
226
+ const taskDir = path.join(cwd, PATHS.TASKS, taskName);
227
+ if (fs.existsSync(taskDir))
228
+ return true; // idempotent
229
+ try {
230
+ fs.mkdirSync(taskDir, { recursive: true });
231
+ fs.writeFileSync(path.join(taskDir, FILE_NAMES.TASK_JSON), JSON.stringify(taskJson, null, 2), "utf-8");
232
+ fs.writeFileSync(path.join(taskDir, FILE_NAMES.PRD), prdContent, "utf-8");
233
+ return true;
234
+ }
235
+ catch {
236
+ return false;
237
+ }
238
+ }
239
+ /**
240
+ * Compute the bootstrap checklist items (previously stored as structured
241
+ * `subtasks: [{name, status}]` in task.json). Per task 04-21-task-schema-unify
242
+ * (D1), these live as markdown `- [ ]` items in prd.md instead, so task.json
243
+ * stays canonical with `subtasks: string[]` (child task dir names, same as
244
+ * task_store.py).
245
+ */
246
+ function getBootstrapChecklistItems(projectType, packages, useCviautoSpec = false) {
247
+ if (useCviautoSpec) {
248
+ return [
249
+ "Review Cviauto common specs",
250
+ "Fill team-specific TODOs in common specs",
251
+ "Add feature-specific specs under features/ when needed",
252
+ "Remove or update the example feature spec when real feature specs exist",
253
+ ];
254
+ }
255
+ if (packages && packages.length > 0) {
256
+ const items = packages.map((pkg) => `Fill guidelines for ${pkg.name}`);
257
+ items.push("Add code examples");
258
+ return items;
259
+ }
260
+ if (projectType === "frontend") {
261
+ return ["Fill frontend guidelines", "Add code examples"];
262
+ }
263
+ if (projectType === "backend") {
264
+ return ["Fill backend guidelines", "Add code examples"];
265
+ }
266
+ return [
267
+ "Fill backend guidelines",
268
+ "Fill frontend guidelines",
269
+ "Add code examples",
270
+ ];
271
+ }
272
+ function getBootstrapRelatedFiles(projectType, packages, useCviautoSpec = false) {
273
+ if (useCviautoSpec) {
274
+ return [
275
+ ".cviauto/spec/index.md",
276
+ ".cviauto/spec/common/",
277
+ ".cviauto/spec/features/",
278
+ ];
279
+ }
280
+ if (packages && packages.length > 0) {
281
+ return packages.map((pkg) => `.cviauto/spec/${sanitizePkgName(pkg.name)}/`);
282
+ }
283
+ if (projectType === "frontend") {
284
+ return [".cviauto/spec/frontend/"];
285
+ }
286
+ if (projectType === "backend") {
287
+ return [".cviauto/spec/backend/"];
288
+ }
289
+ return [".cviauto/spec/backend/", ".cviauto/spec/frontend/"];
290
+ }
291
+ function getBootstrapPrdContent(projectType, pythonCmd, packages, useCviautoSpec = false) {
292
+ const checklistItems = getBootstrapChecklistItems(projectType, packages, useCviautoSpec);
293
+ const checklistMarkdown = checklistItems
294
+ .map((item) => `- [ ] ${item}`)
295
+ .join("\n");
296
+ if (useCviautoSpec) {
297
+ return `# Bootstrap Task: Fill Cviauto Project Specs
298
+
299
+ **You (the AI) are running this task. The developer does not read this file by default.**
300
+
301
+ The developer just ran \`cviauto init -u <name> ...\` on this project for the
302
+ first time. Cviauto installed the Cviauto default spec registry into
303
+ \`.cviauto/spec/\`, then created this bootstrap task under \`.cviauto/tasks/\`.
304
+
305
+ **Your job**: help the team turn the installed Cviauto spec scaffold into
306
+ project-accurate rules. The default files are intentionally conservative:
307
+ they define where rules belong and contain TODO sections for the owning team
308
+ to fill with real repository paths, protocol definitions, commands, and
309
+ validation steps.
310
+
311
+ Do not invent project facts. Ask for missing details or inspect the repository.
312
+
313
+ ---
314
+
315
+ ## Status
316
+
317
+ ${checklistMarkdown}
318
+
319
+ ---
320
+
321
+ ## Installed spec structure
322
+
323
+ | Path | Purpose |
324
+ |------|---------|
325
+ | \`.cviauto/spec/index.md\` | Top-level discovery map for all Cviauto specs |
326
+ | \`.cviauto/spec/common/index.md\` | Discovery map for Cviauto-wide rules |
327
+ | \`.cviauto/spec/common/cviauto-jira-bug-workflow.md\` | Jira bug and defect workflow |
328
+ | \`.cviauto/spec/common/cviauto-ivi-mcu-protocol.md\` | IVI-to-MCU protocol and state rules |
329
+ | \`.cviauto/spec/common/cviauto-multi-repo-layout.md\` | Multi-repo ownership, generated files, and build boundaries |
330
+ | \`.cviauto/spec/common/cviauto-commit.md\` | Commit planning and review handoff rules |
331
+ | \`.cviauto/spec/features/index.md\` | Discovery map for team-owned feature specs |
332
+ | \`.cviauto/spec/features/cviauto-example.md\` | Example shape for future feature specs |
333
+
334
+ ---
335
+
336
+ ## How to work through this bootstrap task
337
+
338
+ 1. Read \`.cviauto/spec/index.md\`, \`.cviauto/spec/common/index.md\`, and
339
+ \`.cviauto/spec/features/index.md\`.
340
+ 2. Inspect existing project docs such as \`CLAUDE.md\`, \`AGENTS.md\`,
341
+ \`CONTRIBUTING.md\`, README files, build scripts, protocol definitions,
342
+ and test docs.
343
+ 3. Fill only confirmed team rules into \`.cviauto/spec/common/*.md\`.
344
+ 4. If the team owns a concrete feature such as reverse camera or ECALL, add a
345
+ new file under \`.cviauto/spec/features/\` using a \`cviauto-*.md\` name.
346
+ 5. Keep every \`index.md\` short: one row per spec file with the reason to load it.
347
+ 6. Keep private Jira cases, customer data, secrets, internal URLs, raw logs,
348
+ and personal machine paths out of specs.
349
+
350
+ Feature-specific specs belong in \`.cviauto/spec/features/\`; do not add a
351
+ feature's product PRD to \`common/\`.
352
+
353
+ ---
354
+
355
+ ## Runtime reminder
356
+
357
+ Cviauto uses \`.cviauto/spec/\` as the source of project-specific guidance.
358
+ Brainstorm/research phases discover candidate spec files from \`index.md\`
359
+ files, then write the relevant files into task JSONL manifests. Implement and
360
+ check agents load the files listed in those manifests before coding or review.
361
+
362
+ ---
363
+
364
+ ## Completion
365
+
366
+ When the team confirms the common TODOs are filled with real project evidence
367
+ and any initial feature specs are in place, guide them to run:
368
+
369
+ \`\`\`bash
370
+ ${pythonCmd} ./.cviauto/scripts/task.py finish
371
+ ${pythonCmd} ./.cviauto/scripts/task.py archive 00-bootstrap-guidelines --no-commit
372
+ \`\`\`
373
+
374
+ ---
375
+
376
+ ## Suggested opening line
377
+
378
+ "Cviauto has installed the Cviauto default spec scaffold. I can help fill the
379
+ TODOs with this project's real repository paths, protocol files, build commands,
380
+ and feature-specific rules. Which team/repository should we document first?"
381
+ `;
382
+ }
383
+ const header = `# Bootstrap Task: Fill Project Development Guidelines
384
+
385
+ **You (the AI) are running this task. The developer does not read this file.**
386
+
387
+ The developer just ran \`cviauto init\` on this project for the first time.
388
+ \`.cviauto/\` now exists with empty spec scaffolding, and this bootstrap task
389
+ exists under \`.cviauto/tasks/\`. When they want to work on it, they should start
390
+ this task from a session that provides Cviauto session identity.
391
+
392
+ **Your job**: help them populate \`.cviauto/spec/\` with the team's real
393
+ coding conventions. Every future AI session — this project's
394
+ \`cviauto-implement\` and \`cviauto-check\` sub-agents — auto-loads spec files
395
+ listed in per-task jsonl manifests. Empty spec = sub-agents write generic
396
+ code. Real spec = sub-agents match the team's actual patterns.
397
+
398
+ Don't dump instructions. Open with a short greeting, figure out if the repo
399
+ has any existing convention docs (CLAUDE.md, AGENTS.md, etc.), and drive
400
+ the rest conversationally.
401
+
402
+ ---
403
+
404
+ ## Status (update the checkboxes as you complete each item)
405
+
406
+ ${checklistMarkdown}
407
+
408
+ ---
409
+
410
+ ## Spec files to populate
411
+ `;
412
+ const backendSection = `
413
+
414
+ ### Backend guidelines
415
+
416
+ | File | What to document |
417
+ |------|------------------|
418
+ | \`.cviauto/spec/backend/directory-structure.md\` | Where different file types go (routes, services, utils) |
419
+ | \`.cviauto/spec/backend/database-guidelines.md\` | ORM, migrations, query patterns, naming conventions |
420
+ | \`.cviauto/spec/backend/error-handling.md\` | How errors are caught, logged, and returned |
421
+ | \`.cviauto/spec/backend/logging-guidelines.md\` | Log levels, format, what to log |
422
+ | \`.cviauto/spec/backend/quality-guidelines.md\` | Code review standards, testing requirements |
423
+ `;
424
+ const frontendSection = `
425
+
426
+ ### Frontend guidelines
427
+
428
+ | File | What to document |
429
+ |------|------------------|
430
+ | \`.cviauto/spec/frontend/directory-structure.md\` | Component/page/hook organization |
431
+ | \`.cviauto/spec/frontend/component-guidelines.md\` | Component patterns, props conventions |
432
+ | \`.cviauto/spec/frontend/hook-guidelines.md\` | Custom hook naming, patterns |
433
+ | \`.cviauto/spec/frontend/state-management.md\` | State library, patterns, what goes where |
434
+ | \`.cviauto/spec/frontend/type-safety.md\` | TypeScript conventions, type organization |
435
+ | \`.cviauto/spec/frontend/quality-guidelines.md\` | Linting, testing, accessibility |
436
+ `;
437
+ const footer = `
438
+
439
+ ### Thinking guides (already populated)
440
+
441
+ \`.cviauto/spec/guides/\` contains general thinking guides pre-filled with
442
+ best practices. Customize only if something clearly doesn't fit this project.
443
+
444
+ ---
445
+
446
+ ## How to fill the spec
447
+
448
+ ### Step 1: Import from existing convention files first (preferred)
449
+
450
+ Search the repo for existing convention docs. If any exist, read them and
451
+ extract the relevant rules into the matching \`.cviauto/spec/\` files —
452
+ usually much faster than documenting from scratch.
453
+
454
+ | File / Directory | Tool |
455
+ |------|------|
456
+ | \`CLAUDE.md\` / \`CLAUDE.local.md\` | Claude Code |
457
+ | \`AGENTS.md\` | Codex / Claude Code / agent-compatible tools |
458
+ | \`.codex/AGENTS.md\` | Codex project notes |
459
+ | \`CONVENTIONS.md\` | General project conventions |
460
+ | \`CONTRIBUTING.md\` | General project conventions |
461
+ | \`.editorconfig\` | Editor formatting rules |
462
+
463
+ ### Step 2: Analyze the codebase for anything not covered by existing docs
464
+
465
+ Scan real code to discover patterns. Before writing each spec file:
466
+ - Find 2-3 real examples of each pattern in the codebase.
467
+ - Reference real file paths (not hypothetical ones).
468
+ - Document anti-patterns the team clearly avoids.
469
+
470
+ ### Step 3: Document reality, not ideals
471
+
472
+ **Critical**: write what the code *actually does*, not what it should do.
473
+ Sub-agents match the spec, so aspirational patterns that don't exist in the
474
+ codebase will cause sub-agents to write code that looks out of place.
475
+
476
+ If the team has known tech debt, document the current state — improvement
477
+ is a separate conversation, not a bootstrap concern.
478
+
479
+ ---
480
+
481
+ ## Quick explainer of the runtime (share when they ask "why do we need spec at all")
482
+
483
+ - Every AI coding task spawns two sub-agents: \`cviauto-implement\` (writes
484
+ code) and \`cviauto-check\` (verifies quality).
485
+ - Each task has \`implement.jsonl\` / \`check.jsonl\` manifests listing which
486
+ spec files to load.
487
+ - The platform hook auto-injects those spec files + the task's \`prd.md\`
488
+ into every sub-agent prompt, so the sub-agent codes/reviews per team
489
+ conventions without anyone pasting them manually.
490
+ - Source of truth: \`.cviauto/spec/\`. That's why filling it well now pays
491
+ off forever.
492
+
493
+ ---
494
+
495
+ ## Completion
496
+
497
+ When the developer confirms the checklist items above are done with real
498
+ examples (not placeholders), guide them to run:
499
+
500
+ \`\`\`bash
501
+ ${pythonCmd} ./.cviauto/scripts/task.py finish
502
+ ${pythonCmd} ./.cviauto/scripts/task.py archive 00-bootstrap-guidelines --no-commit
503
+ \`\`\`
504
+
505
+ After archive, every new developer who joins this project will get a
506
+ \`00-join-<slug>\` onboarding task instead of this bootstrap task.
507
+
508
+ ---
509
+
510
+ ## Suggested opening line
511
+
512
+ "Welcome to Cviauto! Your init just set me up to help you fill the project
513
+ spec — a one-time setup so every future AI session follows the team's
514
+ conventions instead of writing generic code. Before we start, do you have
515
+ any existing convention docs (CLAUDE.md, AGENTS.md, CONTRIBUTING.md,
516
+ etc.) I can pull from, or should I scan the codebase from scratch?"
517
+ `;
518
+ let content = header;
519
+ if (packages && packages.length > 0) {
520
+ // Monorepo: generate per-package sections
521
+ for (const pkg of packages) {
522
+ const pkgType = pkg.type === "unknown" ? "fullstack" : pkg.type;
523
+ const specName = sanitizePkgName(pkg.name);
524
+ content += `\n### Package: ${pkg.name} (\`spec/${specName}/\`)\n`;
525
+ if (pkgType !== "frontend") {
526
+ content += `\n- Backend guidelines: \`.cviauto/spec/${specName}/backend/\`\n`;
527
+ }
528
+ if (pkgType !== "backend") {
529
+ content += `\n- Frontend guidelines: \`.cviauto/spec/${specName}/frontend/\`\n`;
530
+ }
531
+ }
532
+ }
533
+ else if (projectType === "frontend") {
534
+ content += frontendSection;
535
+ }
536
+ else if (projectType === "backend") {
537
+ content += backendSection;
538
+ }
539
+ else {
540
+ // fullstack
541
+ content += backendSection;
542
+ content += frontendSection;
543
+ }
544
+ content += footer;
545
+ return content;
546
+ }
547
+ function getBootstrapTaskJson(developer, projectType, packages, useCviautoSpec = false) {
548
+ const today = new Date().toISOString().split("T")[0];
549
+ const relatedFiles = getBootstrapRelatedFiles(projectType, packages, useCviautoSpec);
550
+ // Canonical 24-field shape via emptyTaskJson factory.
551
+ // Checklist items (previously stored as structured `subtasks`) are now
552
+ // rendered as `- [ ]` items in prd.md; task.json.subtasks is always
553
+ // string[] (child task dir names) per the canonical schema.
554
+ return emptyTaskJson({
555
+ id: BOOTSTRAP_TASK_NAME,
556
+ name: BOOTSTRAP_TASK_NAME,
557
+ title: useCviautoSpec ? "Bootstrap Cviauto Specs" : "Bootstrap Guidelines",
558
+ description: useCviautoSpec
559
+ ? "Fill in Cviauto project specs for AI agents"
560
+ : "Fill in project development guidelines for AI agents",
561
+ status: "in_progress",
562
+ dev_type: "docs",
563
+ priority: "P1",
564
+ creator: developer,
565
+ assignee: developer,
566
+ createdAt: today,
567
+ relatedFiles,
568
+ notes: useCviautoSpec
569
+ ? "First-time setup task created by cviauto init (Cviauto default specs)"
570
+ : `First-time setup task created by cviauto init (${projectType} project)`,
571
+ });
572
+ }
573
+ /**
574
+ * Create bootstrap task for first-time setup
575
+ */
576
+ function createBootstrapTask(cwd, developer, pythonCmd, projectType, packages, useCviautoSpec = false) {
577
+ const taskJson = getBootstrapTaskJson(developer, projectType, packages, useCviautoSpec);
578
+ const prdContent = getBootstrapPrdContent(projectType, pythonCmd, packages, useCviautoSpec);
579
+ return writeTaskSkeleton(cwd, BOOTSTRAP_TASK_NAME, taskJson, prdContent);
580
+ }
581
+ // =============================================================================
582
+ // Joiner Onboarding Task Creation
583
+ // =============================================================================
584
+ /**
585
+ * task.json factory for joiner onboarding. Mirrors the bootstrap factory but
586
+ * uses dev_type "docs", higher priority "P1", and the developer-specific task
587
+ * name (so multiple joiners in the same checkout don't collide).
588
+ */
589
+ function getJoinerTaskJson(developer, taskName) {
590
+ const today = new Date().toISOString().split("T")[0];
591
+ return emptyTaskJson({
592
+ id: taskName,
593
+ name: taskName,
594
+ title: `Joining: Onboard to this Cviauto project (${developer})`,
595
+ description: "Onboard a new developer to an existing Cviauto project: learn the workflow, conventions, and find assigned work",
596
+ status: "in_progress",
597
+ dev_type: "docs",
598
+ priority: "P1",
599
+ creator: developer,
600
+ assignee: developer,
601
+ createdAt: today,
602
+ notes: "Generated by cviauto init for a new developer joining an existing Cviauto project",
603
+ });
604
+ }
605
+ /**
606
+ * PRD content for joiner onboarding. Kept concise (~80 lines) — deeper
607
+ * guidance lives in skills and docs.
608
+ */
609
+ function getJoinerPrdContent(developer, pythonCmd) {
610
+ const slug = slugifyDeveloperName(developer);
611
+ return `# Joiner Onboarding Task
612
+
613
+ **You (the AI) are running this task. The developer does not read this file.**
614
+
615
+ \`${developer}\` just ran \`cviauto init\` on a fresh clone, saw "Developer
616
+ initialized", and will now start asking you questions in chat. This joiner task
617
+ exists under \`.cviauto/tasks/\`; when they want to work on it, they should
618
+ start it from a session that provides Cviauto session identity.
619
+
620
+ Your job is to orient them to Cviauto. Don't dump all of this at them — open
621
+ with a short greeting, ask where they want to start, and fill in the rest as
622
+ they engage.
623
+
624
+ ---
625
+
626
+ ## Topics to cover (adapt order to their questions)
627
+
628
+ ### 1. What Cviauto is + the workflow
629
+
630
+ Cviauto is a workflow layer over Claude Code / Codex / OpenCode that keeps AI
631
+ agents consistent with project-specific conventions instead of writing generic
632
+ code every session.
633
+
634
+ - **Three phases**: Plan (brainstorm → \`prd.md\`) → Execute (code + check) →
635
+ Finish (capture + wrap). Full reference: \`.cviauto/workflow.md\`.
636
+ - **Task lifecycle**: planning → in_progress → done → archive, under
637
+ \`.cviauto/tasks/\`.
638
+ - **Core slash commands**:
639
+ - \`/cviauto:continue\` — resume the current session's active task
640
+ - \`/cviauto:finish-work\` — wrap up a finished task
641
+ - \`/cviauto:start\` — session boot from scratch (not needed here; the
642
+ SessionStart hook does its job automatically)
643
+
644
+ ### 2. Runtime mechanics (explain when they ask "how does it know what to do")
645
+
646
+ - **SessionStart hook** runs \`get_context.py\` and injects identity, git
647
+ status, session active task, active tasks, and workflow phase into the AI
648
+ conversation at every session start.
649
+ - **\`<workflow-state>\` tag** is auto-injected with every user message,
650
+ carrying the current task + phase hint.
651
+ - **\`/cviauto:continue\`** loads the Phase Index, reads \`prd.md\` + recent
652
+ activity, and routes to the right skill (\`cviauto-brainstorm\` for planning,
653
+ \`cviauto-implement\` for coding, \`cviauto-check\` for verification).
654
+ - **\`cviauto-implement\` sub-agent** is spawned when code needs to be written.
655
+ The platform hook reads \`{TASK_DIR}/implement.jsonl\` and auto-injects those
656
+ spec files + \`prd.md\` into the sub-agent's prompt so it codes per project
657
+ conventions.
658
+ - **\`cviauto-check\` sub-agent** follows the same pattern with \`check.jsonl\`
659
+ — reviews changes against specs, auto-fixes issues, runs lint/typecheck.
660
+
661
+ File layout (mention when they ask "where does what live"):
662
+ - \`.cviauto/.runtime/sessions/<session>.json\` — session active-task state, gitignored
663
+ - \`.cviauto/tasks/<task>/{implement,check}.jsonl\` — per-task context manifests
664
+ - \`.cviauto/spec/\` — project-wide conventions (source of truth)
665
+ - \`.cviauto/workspace/${developer}/journal-*.md\` — their session log,
666
+ rotated at ~2000 lines
667
+
668
+ ### 3. This project's actual conventions
669
+
670
+ - Summarize \`.cviauto/spec/\` for them — what coding conventions this
671
+ specific team enforces.
672
+ - Point at the last 5 entries in \`.cviauto/tasks/archive/\` as a rhythm
673
+ example of how people actually work here. **If archive is empty** (the
674
+ project just started), skip this — don't invent examples.
675
+ - Not your job in this onboarding to teach them the business code itself —
676
+ the README and their teammates handle that.
677
+
678
+ ### 4. Their assigned work
679
+
680
+ - Check if \`.cviauto/workspace/${developer}/\` already exists — if yes, it's
681
+ their journal from another machine and worth mentioning.
682
+ - Run \`${pythonCmd} ./.cviauto/scripts/task.py list --assignee ${developer}\` to
683
+ show tasks assigned to them. (Quote the name if it contains spaces.)
684
+ - Remind them that the "My Tasks" section appears in the SessionStart context
685
+ on every new session.
686
+
687
+ ---
688
+
689
+ ## Optional: walk through a small task end-to-end
690
+
691
+ If they want to practice before touching real work, offer to pick a tiny
692
+ P3 task or a typo fix and run the full cycle together: \`/cviauto:continue\`
693
+ → you implement via sub-agents → \`/cviauto:finish-work\`.
694
+
695
+ ---
696
+
697
+ ## Completion
698
+
699
+ When they feel oriented (or after you've covered the four topics with
700
+ reasonable back-and-forth), guide them to run:
701
+
702
+ \`\`\`bash
703
+ ${pythonCmd} ./.cviauto/scripts/task.py finish
704
+ ${pythonCmd} ./.cviauto/scripts/task.py archive 00-join-${slug} --no-commit
705
+ \`\`\`
706
+
707
+ ---
708
+
709
+ ## Suggested opening line
710
+
711
+ "Welcome! Your \`cviauto init\` set me up to onboard you to this project. I
712
+ can walk you through the workflow, show you the runtime mechanics under the
713
+ hood, summarize the team's spec, or jump to what you're already curious about
714
+ — which would you prefer?"
715
+ `;
716
+ }
717
+ /**
718
+ * Create joiner onboarding task for a new developer on an existing Cviauto
719
+ * project. Task name is slugified to be filesystem-safe for arbitrary
720
+ * developer names (spaces, Unicode, punctuation).
721
+ */
722
+ function createJoinerOnboardingTask(cwd, developer, pythonCmd) {
723
+ const slug = slugifyDeveloperName(developer);
724
+ const taskName = `00-join-${slug}`;
725
+ const taskJson = getJoinerTaskJson(developer, taskName);
726
+ const prdContent = getJoinerPrdContent(developer, pythonCmd);
727
+ return writeTaskSkeleton(cwd, taskName, taskJson, prdContent);
728
+ }
729
+ /**
730
+ * Handle re-init when .cviauto/ already exists.
731
+ * Returns true if handled (caller should return), false if user chose full re-init.
732
+ */
733
+ async function handleReinit(cwd, options, developerName, pythonCmd) {
734
+ const TOOLS = getPublicInitToolChoices();
735
+ const configuredPlatforms = getConfiguredPlatforms(cwd);
736
+ const publicToolsById = new Map(TOOLS.map((tool) => [tool.platformId, tool]));
737
+ const configuredNames = [...configuredPlatforms]
738
+ .map((id) => publicToolsById.get(id)?.name)
739
+ .filter((name) => Boolean(name))
740
+ .join(", ") || "none";
741
+ // Determine explicit platform flags
742
+ const explicitTools = TOOLS.filter((t) => options[t.key]).map((t) => t.key);
743
+ let doAddPlatforms = explicitTools.length > 0;
744
+ let doAddDeveloper = !!options.user;
745
+ let platformsToAdd = explicitTools;
746
+ // No explicit flags → show menu
747
+ if (!doAddPlatforms && !doAddDeveloper) {
748
+ if (options.yes) {
749
+ console.log(chalk.gray(`Already initialized with: ${configuredNames}`));
750
+ console.log(chalk.gray("Use platform flags (e.g., --codex) or -u <name> to add platforms/developer."));
751
+ return true;
752
+ }
753
+ console.log(chalk.gray(`\n Already initialized with: ${configuredNames}\n`));
754
+ const { action } = await inquirer.prompt([
755
+ {
756
+ type: "list",
757
+ name: "action",
758
+ message: "Cviauto is already initialized. What would you like to do?",
759
+ choices: [
760
+ { name: "Add AI platform(s)", value: "add-platform" },
761
+ {
762
+ name: "Set up developer identity on this device",
763
+ value: "add-developer",
764
+ },
765
+ { name: "Full re-initialize", value: "full" },
766
+ ],
767
+ },
768
+ ]);
769
+ if (action === "full") {
770
+ return false; // Fall through to full init
771
+ }
772
+ if (action === "add-platform")
773
+ doAddPlatforms = true;
774
+ if (action === "add-developer")
775
+ doAddDeveloper = true;
776
+ }
777
+ // --- Add platforms ---
778
+ if (doAddPlatforms) {
779
+ if (platformsToAdd.length === 0) {
780
+ // Interactive: show only unconfigured platforms
781
+ const unconfigured = TOOLS.filter((t) => {
782
+ const pid = resolveCliFlag(t.key);
783
+ return pid && !configuredPlatforms.has(pid);
784
+ });
785
+ if (unconfigured.length === 0) {
786
+ console.log(chalk.green("✓ All available platforms are already configured."));
787
+ }
788
+ else {
789
+ const answers = await inquirer.prompt([
790
+ {
791
+ type: "checkbox",
792
+ name: "tools",
793
+ message: "Select platforms to add:",
794
+ choices: unconfigured.map((t) => ({
795
+ name: t.name,
796
+ value: t.key,
797
+ })),
798
+ },
799
+ ]);
800
+ platformsToAdd = answers.tools;
801
+ }
802
+ }
803
+ const reinitWritten = startRecordingWrites(cwd);
804
+ try {
805
+ for (const tool of platformsToAdd) {
806
+ const platformId = resolveCliFlag(tool);
807
+ if (platformId) {
808
+ if (configuredPlatforms.has(platformId)) {
809
+ console.log(chalk.gray(` ○ ${AI_TOOLS[platformId].name} already configured, skipping`));
810
+ }
811
+ else {
812
+ console.log(chalk.blue(`📝 Configuring ${AI_TOOLS[platformId].name}...`));
813
+ await configurePlatform(platformId, cwd, {
814
+ withStatusline: options.withStatusline,
815
+ });
816
+ if (platformId === "claude-code" && options.withStatusline) {
817
+ console.log(chalk.gray(" ↳ Cviauto statusLine installed (--with-statusline)"));
818
+ }
819
+ }
820
+ }
821
+ }
822
+ }
823
+ finally {
824
+ stopRecordingWrites();
825
+ }
826
+ // Update template hashes. Merge mode: preserve previously-tracked
827
+ // platforms' hashes, layer in the newly-added platform's writes.
828
+ const hashedCount = initializeHashes(cwd, {
829
+ trackedPaths: reinitWritten,
830
+ merge: true,
831
+ });
832
+ if (hashedCount > 0) {
833
+ console.log(chalk.gray(`📋 Tracking ${hashedCount} template files for updates`));
834
+ }
835
+ }
836
+ // --- Add developer ---
837
+ if (doAddDeveloper) {
838
+ let devName = developerName;
839
+ if (!options.user && !options.yes) {
840
+ devName = await promptDeveloperName(devName);
841
+ }
842
+ if (!devName) {
843
+ throw new Error("Developer name is required");
844
+ }
845
+ console.log(chalk.blue("👤 Developer:"), chalk.gray(devName));
846
+ // Capture pre-init state: if .developer did not exist before we ran
847
+ // init_developer.py, this checkout had no identity → treat as a new
848
+ // joiner onboarding onto an existing Cviauto project.
849
+ const hadDeveloperFileBefore = fs.existsSync(path.join(cwd, DIR_NAMES.WORKFLOW, FILE_NAMES.DEVELOPER));
850
+ try {
851
+ const scriptPath = path.join(cwd, PATHS.SCRIPTS, "init_developer.py");
852
+ execSync(`${pythonCmd} "${scriptPath}" "${devName}"`, {
853
+ cwd,
854
+ stdio: "pipe",
855
+ });
856
+ console.log(chalk.green(`✓ Developer "${devName}" initialized`));
857
+ }
858
+ catch {
859
+ console.log(chalk.yellow("⚠ Could not initialize developer. Run manually:"));
860
+ console.log(chalk.gray(` ${pythonCmd} .cviauto/scripts/init_developer.py ${devName}`));
861
+ }
862
+ // Create joiner onboarding task for fresh checkouts (no prior .developer).
863
+ // Runs outside the init_developer try/catch so failures surface as warnings.
864
+ if (!hadDeveloperFileBefore) {
865
+ try {
866
+ if (!createJoinerOnboardingTask(cwd, devName, pythonCmd)) {
867
+ console.warn(chalk.yellow("⚠ Failed to create joiner onboarding task"));
868
+ }
869
+ }
870
+ catch (err) {
871
+ console.warn(chalk.yellow(`⚠ Joiner onboarding setup failed: ${err instanceof Error ? err.message : String(err)}`));
872
+ }
873
+ }
874
+ }
875
+ return true;
876
+ }
877
+ const _cliFlagCheck = true;
878
+ /**
879
+ * Write monorepo package configuration to config.yaml (non-destructive patch).
880
+ * Appends packages: and default_package: without disturbing existing config.
881
+ */
882
+ function writeMonorepoConfig(cwd, packages) {
883
+ const configPath = path.join(cwd, DIR_NAMES.WORKFLOW, "config.yaml");
884
+ let content = "";
885
+ try {
886
+ content = fs.readFileSync(configPath, "utf-8");
887
+ }
888
+ catch {
889
+ // Config not created yet; will be created by createWorkflowStructure
890
+ return;
891
+ }
892
+ // Don't overwrite if packages: already exists (re-init case)
893
+ if (/^packages\s*:/m.test(content)) {
894
+ return;
895
+ }
896
+ const lines = ["\n# Auto-detected monorepo packages", "packages:"];
897
+ for (const pkg of packages) {
898
+ lines.push(` ${sanitizePkgName(pkg.name)}:`);
899
+ lines.push(` path: ${pkg.path}`);
900
+ if (pkg.isSubmodule) {
901
+ lines.push(" type: submodule");
902
+ }
903
+ else if (pkg.isGitRepo) {
904
+ lines.push(" git: true");
905
+ }
906
+ }
907
+ // Use first non-submodule package as default, fallback to first package
908
+ const defaultPkg = packages.find((p) => !p.isSubmodule)?.name ?? packages[0]?.name;
909
+ if (defaultPkg) {
910
+ lines.push(`default_package: ${defaultPkg}`);
911
+ }
912
+ fs.writeFileSync(configPath, content.trimEnd() + "\n" + lines.join("\n") + "\n", "utf-8");
913
+ }
914
+ function detectDeveloperNameFromGit(cwd) {
915
+ if (!fs.existsSync(path.join(cwd, ".git")))
916
+ return undefined;
917
+ try {
918
+ const name = execSync("git config user.name", {
919
+ cwd,
920
+ encoding: "utf-8",
921
+ }).trim();
922
+ return name || undefined;
923
+ }
924
+ catch {
925
+ return undefined;
926
+ }
927
+ }
928
+ async function promptDeveloperName(defaultName) {
929
+ console.log(chalk.gray("\nCviauto supports team collaboration - each developer has their own\n" +
930
+ `workspace directory (${PATHS.WORKSPACE}/{name}/) to track AI sessions.\n` +
931
+ "Tip: Usually this is your git username (git config user.name).\n"));
932
+ const answer = await inquirer.prompt([
933
+ {
934
+ type: "input",
935
+ name: "developerName",
936
+ message: "Developer name:",
937
+ default: defaultName,
938
+ filter: (value) => value.trim(),
939
+ validate: (value) => value.trim().length > 0 ? true : "Name is required",
940
+ },
941
+ ]);
942
+ const promptedName = answer.developerName?.trim();
943
+ const fallbackName = defaultName?.trim();
944
+ const resolved = promptedName && promptedName.length > 0
945
+ ? promptedName
946
+ : (fallbackName ?? "");
947
+ if (!resolved) {
948
+ throw new Error("Developer name is required");
949
+ }
950
+ return resolved;
951
+ }
952
+ export async function init(options) {
953
+ // Refuse to run in $HOME — running here would scoop platform runtime data
954
+ // (Claude/Codex/OpenCode session histories etc.) into the cviauto hash
955
+ // manifest, and a subsequent `cviauto uninstall` would wipe it.
956
+ if (isCwdHomedir() && !homedirBypassEnabled()) {
957
+ console.error(chalk.red(homedirGuardMessage("init")));
958
+ process.exit(1);
959
+ }
960
+ const cwd = process.cwd();
961
+ const isFirstInit = !fs.existsSync(path.join(cwd, DIR_NAMES.WORKFLOW));
962
+ // Captured here (before createWorkflowStructure + init_developer run) so
963
+ // the three-branch dispatch at the bottom can tell "fresh clone joiner"
964
+ // (.cviauto/ exists, .developer missing) apart from "creator first init".
965
+ const hadDeveloperFileAtStart = fs.existsSync(path.join(cwd, DIR_NAMES.WORKFLOW, FILE_NAMES.DEVELOPER));
966
+ // Generate ASCII art banner dynamically using FIGlet "Rebel" font
967
+ const banner = figlet.textSync("Cviauto", { font: "Rebel" });
968
+ console.log(chalk.cyan(`\n${banner.trimEnd()}`));
969
+ console.log(chalk.gray("\n Cviauto AI workflow toolkit for Claude Code, Codex, and OpenCode\n"));
970
+ // Set up proxy before any network calls
971
+ const proxyUrl = setupProxy();
972
+ if (proxyUrl) {
973
+ console.log(chalk.gray(` Using proxy: ${maskProxyUrl(proxyUrl)}\n`));
974
+ }
975
+ // Set write mode based on options
976
+ let writeMode = "ask";
977
+ if (options.force) {
978
+ writeMode = "force";
979
+ console.log(chalk.gray("Mode: Force overwrite existing files\n"));
980
+ }
981
+ else if (options.skipExisting) {
982
+ writeMode = "skip";
983
+ console.log(chalk.gray("Mode: Skip existing files\n"));
984
+ }
985
+ else if (options.yes) {
986
+ // -y implies non-interactive: never prompt on conflicts. Default to skip
987
+ // (preserve user files) — explicit --force is required to overwrite.
988
+ writeMode = "skip";
989
+ console.log(chalk.gray("Mode: Non-interactive (skip existing files)\n"));
990
+ }
991
+ setWriteMode(writeMode);
992
+ const optionDeveloperName = options.user?.trim();
993
+ const developerDefault = optionDeveloperName && optionDeveloperName.length > 0
994
+ ? optionDeveloperName
995
+ : detectDeveloperNameFromGit(cwd);
996
+ let developerName = developerDefault;
997
+ const { command: pythonCmd } = resolveSupportedPython();
998
+ // ==========================================================================
999
+ // Re-init fast path: skip full flow when .cviauto/ already exists
1000
+ // ==========================================================================
1001
+ // Aborted-init recovery (issue #204): if .cviauto/ exists but tasks/ is
1002
+ // empty, the previous init never reached bootstrap creation. Fall through
1003
+ // to the full flow so the main-dispatch tasksEmpty fallback fires —
1004
+ // handleReinit's joiner branch would otherwise mis-route the recovery.
1005
+ const tasksDirEarly = path.join(cwd, PATHS.TASKS);
1006
+ const tasksEmptyEarly = !fs.existsSync(tasksDirEarly) || fs.readdirSync(tasksDirEarly).length === 0;
1007
+ const hasTemplateRequest = !!options.template || !!options.registry;
1008
+ if (!isFirstInit &&
1009
+ !options.force &&
1010
+ !options.skipExisting &&
1011
+ !tasksEmptyEarly &&
1012
+ !hasTemplateRequest) {
1013
+ const reinitDone = await handleReinit(cwd, options, developerName, pythonCmd);
1014
+ if (reinitDone)
1015
+ return;
1016
+ // reinitDone === false means user chose "full re-initialize" → fall through
1017
+ }
1018
+ if (!options.user && !options.yes) {
1019
+ developerName = await promptDeveloperName(developerDefault);
1020
+ }
1021
+ if (developerName) {
1022
+ console.log(chalk.blue("👤 Developer:"), chalk.gray(developerName));
1023
+ }
1024
+ // Detect project type (silent - no output)
1025
+ const detectedType = detectProjectType(cwd);
1026
+ // Parse custom registry source early (needed by both monorepo + single-repo flows).
1027
+ // Cviauto fork default: when the user does not explicitly choose a registry
1028
+ // or marketplace template, install the team default spec marketplace entry.
1029
+ let registry;
1030
+ let registrySourceForConfig;
1031
+ const useCviautoDefaultSpecRegistry = !options.registry && !options.template;
1032
+ const registrySource = options.registry ??
1033
+ (useCviautoDefaultSpecRegistry ? CVIAUTO_DEFAULT_SPEC_REGISTRY : undefined);
1034
+ if (registrySource) {
1035
+ try {
1036
+ registry = parseRegistrySource(registrySource);
1037
+ registrySourceForConfig = registrySource;
1038
+ }
1039
+ catch (error) {
1040
+ console.log(chalk.red(error instanceof Error ? error.message : "Invalid registry source"));
1041
+ return;
1042
+ }
1043
+ }
1044
+ // Determine template strategy from flags (needed before monorepo template downloads)
1045
+ let templateStrategy = "skip";
1046
+ if (options.overwrite) {
1047
+ templateStrategy = "overwrite";
1048
+ }
1049
+ else if (options.append) {
1050
+ templateStrategy = "append";
1051
+ }
1052
+ // ==========================================================================
1053
+ // Monorepo Detection
1054
+ // ==========================================================================
1055
+ let monorepoPackages;
1056
+ let remoteSpecPackages;
1057
+ if (options.monorepo !== false) {
1058
+ // options.monorepo: true = --monorepo, false = --no-monorepo, undefined = auto
1059
+ const detected = detectMonorepo(cwd);
1060
+ if (options.monorepo === true && !detected) {
1061
+ console.log(chalk.red("Error: --monorepo specified but no multi-package layout detected."));
1062
+ console.log("");
1063
+ console.log(chalk.gray("Checked:"));
1064
+ console.log(chalk.gray(" ✗ pnpm-workspace.yaml"));
1065
+ console.log(chalk.gray(" ✗ package.json workspaces"));
1066
+ console.log(chalk.gray(" ✗ Cargo.toml [workspace]"));
1067
+ console.log(chalk.gray(" ✗ go.work"));
1068
+ console.log(chalk.gray(" ✗ pyproject.toml [tool.uv.workspace]"));
1069
+ console.log(chalk.gray(" ✗ .gitmodules"));
1070
+ console.log(chalk.gray(" ✗ sibling .git directories (need ≥ 2)"));
1071
+ console.log("");
1072
+ console.log("To configure manually, add to .cviauto/config.yaml:");
1073
+ console.log("");
1074
+ console.log(chalk.cyan(" packages:"));
1075
+ console.log(chalk.cyan(" frontend:"));
1076
+ console.log(chalk.cyan(" path: ./frontend"));
1077
+ console.log(chalk.cyan(" git: true # if it has its own .git"));
1078
+ console.log(chalk.cyan(" backend:"));
1079
+ console.log(chalk.cyan(" path: ./backend"));
1080
+ console.log(chalk.cyan(" git: true"));
1081
+ return;
1082
+ }
1083
+ if (detected && detected.length > 0) {
1084
+ let enableMonorepo = false;
1085
+ if (options.monorepo === true || options.yes) {
1086
+ enableMonorepo = true;
1087
+ }
1088
+ else {
1089
+ // Show detected packages and ask
1090
+ console.log(chalk.blue("\n🔍 Detected monorepo packages:"));
1091
+ for (const pkg of detected) {
1092
+ const tag = pkg.isSubmodule
1093
+ ? chalk.gray(" (submodule)")
1094
+ : pkg.isGitRepo
1095
+ ? chalk.gray(" (git repo)")
1096
+ : "";
1097
+ console.log(chalk.gray(` - ${pkg.name}`) +
1098
+ chalk.gray(` (${pkg.path})`) +
1099
+ chalk.gray(` [${pkg.type}]`) +
1100
+ tag);
1101
+ }
1102
+ console.log("");
1103
+ const { useMonorepo } = await inquirer.prompt([
1104
+ {
1105
+ type: "confirm",
1106
+ name: "useMonorepo",
1107
+ message: "Enable monorepo mode?",
1108
+ default: true,
1109
+ },
1110
+ ]);
1111
+ enableMonorepo = useMonorepo;
1112
+ }
1113
+ if (enableMonorepo) {
1114
+ monorepoPackages = detected;
1115
+ remoteSpecPackages = new Set();
1116
+ // Per-package template selection (unless -y mode: all use blank spec)
1117
+ if (!options.yes && !options.template) {
1118
+ for (const pkg of detected) {
1119
+ const { specSource } = await inquirer.prompt([
1120
+ {
1121
+ type: "list",
1122
+ name: "specSource",
1123
+ message: `Spec source for ${pkg.name} (${pkg.path}):`,
1124
+ choices: [
1125
+ { name: "From scratch (Cviauto default)", value: "blank" },
1126
+ { name: "Download remote template", value: "remote" },
1127
+ ],
1128
+ default: "blank",
1129
+ },
1130
+ ]);
1131
+ if (specSource === "remote") {
1132
+ // Use existing template download flow, targeting spec/<name>/
1133
+ const destDir = path.join(cwd, PATHS.SPEC, sanitizePkgName(pkg.name));
1134
+ console.log(chalk.blue(`📦 Select template for ${pkg.name}...`));
1135
+ // Fetch templates if not already done
1136
+ const templates = await fetchTemplateIndex();
1137
+ const specTemplates = templates
1138
+ .filter((t) => t.type === "spec")
1139
+ .map((t) => ({
1140
+ name: `${t.id} (${t.name})`,
1141
+ value: t.id,
1142
+ }));
1143
+ if (specTemplates.length > 0) {
1144
+ const { templateId } = await inquirer.prompt([
1145
+ {
1146
+ type: "list",
1147
+ name: "templateId",
1148
+ message: `Select template for ${pkg.name}:`,
1149
+ choices: specTemplates,
1150
+ },
1151
+ ]);
1152
+ const result = await downloadTemplateById(cwd, templateId, templateStrategy, templates.find((t) => t.id === templateId), undefined, destDir);
1153
+ if (result.success) {
1154
+ console.log(chalk.green(` ${result.message}`));
1155
+ remoteSpecPackages.add(sanitizePkgName(pkg.name));
1156
+ }
1157
+ else {
1158
+ console.log(chalk.yellow(` ${result.message}`));
1159
+ console.log(chalk.gray(" Falling back to blank spec..."));
1160
+ }
1161
+ }
1162
+ else {
1163
+ console.log(chalk.gray(" No templates available. Using blank spec."));
1164
+ }
1165
+ }
1166
+ }
1167
+ }
1168
+ else if (options.template) {
1169
+ // --template as default for all packages
1170
+ for (const pkg of detected) {
1171
+ const destDir = path.join(cwd, PATHS.SPEC, sanitizePkgName(pkg.name));
1172
+ const result = await downloadTemplateById(cwd, options.template, templateStrategy, undefined, registry, destDir);
1173
+ if (result.success && !result.skipped) {
1174
+ remoteSpecPackages.add(sanitizePkgName(pkg.name));
1175
+ }
1176
+ }
1177
+ }
1178
+ }
1179
+ }
1180
+ }
1181
+ // Tool definitions derived from platform registry
1182
+ const TOOLS = getPublicInitToolChoices();
1183
+ // Build tools from explicit flags
1184
+ const explicitTools = TOOLS.filter((t) => options[t.key]).map((t) => t.key);
1185
+ let tools;
1186
+ if (explicitTools.length > 0) {
1187
+ // Explicit flags take precedence (works with or without -y)
1188
+ tools = explicitTools;
1189
+ }
1190
+ else if (options.yes) {
1191
+ // No explicit tools + -y: use the registry defaults.
1192
+ tools = TOOLS.filter((t) => t.defaultChecked).map((t) => t.key);
1193
+ }
1194
+ else {
1195
+ // Interactive mode
1196
+ const answers = await inquirer.prompt([
1197
+ {
1198
+ type: "checkbox",
1199
+ name: "tools",
1200
+ message: "Select AI tools to configure:",
1201
+ choices: TOOLS.map((t) => ({
1202
+ name: t.name,
1203
+ value: t.key,
1204
+ checked: t.defaultChecked,
1205
+ })),
1206
+ },
1207
+ ]);
1208
+ tools = answers.tools;
1209
+ }
1210
+ // Treat unknown project type as fullstack
1211
+ const projectType = detectedType === "unknown" ? "fullstack" : detectedType;
1212
+ if (tools.length === 0) {
1213
+ console.log(chalk.yellow("No tools selected. At least one tool is required."));
1214
+ return;
1215
+ }
1216
+ // ==========================================================================
1217
+ // Template Selection (single-repo only; monorepo handles templates above)
1218
+ // ==========================================================================
1219
+ let selectedTemplate = useCviautoDefaultSpecRegistry
1220
+ ? CVIAUTO_DEFAULT_SPEC_TEMPLATE
1221
+ : null;
1222
+ // Pre-fetched templates list (used to pass selected SpecTemplate to downloadTemplateById)
1223
+ let fetchedTemplates = [];
1224
+ let registryBackend;
1225
+ // Determine the index URL based on registry
1226
+ const indexUrl = registry
1227
+ ? `${registry.rawBaseUrl}/index.json`
1228
+ : TEMPLATE_INDEX_URL;
1229
+ if (monorepoPackages) {
1230
+ // Monorepo: template selection already handled above
1231
+ }
1232
+ else if (options.template) {
1233
+ // Template specified via --template flag
1234
+ selectedTemplate = options.template;
1235
+ if (registry) {
1236
+ const probeResult = await probeRegistryIndex(indexUrl, registry);
1237
+ registryBackend = probeResult.backend;
1238
+ if (probeResult.error) {
1239
+ console.log(chalk.red(`Error: ${probeResult.error.message}`));
1240
+ return;
1241
+ }
1242
+ if (probeResult.isNotFound) {
1243
+ console.log(chalk.red("Error: Registry has no index.json. Remove --template to use direct download mode."));
1244
+ return;
1245
+ }
1246
+ fetchedTemplates = probeResult.templates;
1247
+ }
1248
+ }
1249
+ else if (!options.yes) {
1250
+ // Interactive mode: show template selection
1251
+ const timeoutSec = TIMEOUTS.INDEX_FETCH_MS / 1000;
1252
+ const sourceLabel = registry ? registry.gigetSource : TEMPLATE_INDEX_URL;
1253
+ console.log(chalk.gray(` Fetching available templates from ${sourceLabel}`));
1254
+ let elapsed = 0;
1255
+ const ticker = setInterval(() => {
1256
+ elapsed++;
1257
+ process.stdout.write(`\r${chalk.gray(` Loading... ${elapsed}s/${timeoutSec}s`)}`);
1258
+ }, 1000);
1259
+ process.stdout.write(chalk.gray(` Loading... 0s/${timeoutSec}s`));
1260
+ let templates;
1261
+ let registryProbeNotFound = false;
1262
+ let registryProbeError;
1263
+ if (registry) {
1264
+ const probeResult = await probeRegistryIndex(indexUrl, registry);
1265
+ templates = probeResult.templates;
1266
+ registryProbeNotFound = probeResult.isNotFound;
1267
+ registryProbeError = probeResult.error;
1268
+ registryBackend = probeResult.backend;
1269
+ }
1270
+ else {
1271
+ templates = await fetchTemplateIndex(indexUrl);
1272
+ }
1273
+ clearInterval(ticker);
1274
+ // Clear the loading line
1275
+ process.stdout.write("\r\x1b[2K");
1276
+ fetchedTemplates = templates;
1277
+ if (templates.length === 0 && registry && registryProbeNotFound) {
1278
+ // Custom registry: confirmed no index.json — will try direct download later
1279
+ console.log(chalk.gray(" No index.json found at registry. Will download as direct spec template."));
1280
+ }
1281
+ else if (templates.length === 0 && registry) {
1282
+ // Custom registry: transient error (not a 404) — abort, don't misclassify
1283
+ console.log(chalk.red(` ${registryProbeError?.message ?? "Could not reach registry. Check your connection and try again."}`));
1284
+ return;
1285
+ }
1286
+ else if (templates.length === 0) {
1287
+ console.log(chalk.gray(" Could not fetch templates (offline or server unavailable)."));
1288
+ console.log(chalk.gray(" Using blank templates.\n"));
1289
+ }
1290
+ if (templates.length > 0) {
1291
+ // Build template choices
1292
+ const specTemplates = templates
1293
+ .filter((t) => t.type === "spec")
1294
+ .map((t) => ({
1295
+ name: `${t.id} (${t.name})`,
1296
+ value: t.id,
1297
+ }));
1298
+ const templateChoices = registry
1299
+ ? specTemplates
1300
+ : [
1301
+ {
1302
+ name: "from scratch (default)",
1303
+ value: "blank",
1304
+ },
1305
+ ...specTemplates,
1306
+ {
1307
+ name: "custom (enter a registry source)",
1308
+ value: "__custom__",
1309
+ },
1310
+ ];
1311
+ // Loop to allow returning from custom source input back to the picker
1312
+ let templatePicked = false;
1313
+ while (templateChoices.length > 0 && !templatePicked) {
1314
+ const templateAnswer = await inquirer.prompt([
1315
+ {
1316
+ type: "list",
1317
+ name: "template",
1318
+ message: "Select a spec template:",
1319
+ choices: templateChoices,
1320
+ default: registry ? undefined : "blank",
1321
+ },
1322
+ ]);
1323
+ if (templateAnswer.template === "__custom__") {
1324
+ // Prompt for custom registry source (empty → back to picker)
1325
+ const customSource = await askInput("Enter registry source (e.g., gh:myorg/myrepo/specs), or press Enter to go back: ");
1326
+ if (!customSource) {
1327
+ continue; // Back to picker
1328
+ }
1329
+ try {
1330
+ registry = parseRegistrySource(customSource);
1331
+ registrySourceForConfig = customSource;
1332
+ fetchedTemplates = []; // Reset so direct-download guard works correctly
1333
+ // Probe index.json to detect marketplace vs direct download
1334
+ const customIndexUrl = `${registry.rawBaseUrl}/index.json`;
1335
+ console.log(chalk.gray(` Checking for templates at ${registry.gigetSource}...`));
1336
+ const customProbe = await probeRegistryIndex(customIndexUrl, registry);
1337
+ const customTemplates = customProbe.templates;
1338
+ registryBackend = customProbe.backend;
1339
+ if (customTemplates.length > 0) {
1340
+ // Marketplace mode: show picker with custom templates
1341
+ fetchedTemplates = customTemplates;
1342
+ const customChoices = customTemplates
1343
+ .filter((t) => t.type === "spec")
1344
+ .map((t) => ({
1345
+ name: `${t.id} (${t.name})`,
1346
+ value: t.id,
1347
+ }));
1348
+ if (customChoices.length > 0) {
1349
+ const customAnswer = await inquirer.prompt([
1350
+ {
1351
+ type: "list",
1352
+ name: "template",
1353
+ message: "Select a spec template:",
1354
+ choices: customChoices,
1355
+ },
1356
+ ]);
1357
+ selectedTemplate = customAnswer.template;
1358
+ // Check if spec directory already exists and ask what to do
1359
+ const specDir = path.join(cwd, PATHS.SPEC);
1360
+ if (fs.existsSync(specDir) &&
1361
+ !options.overwrite &&
1362
+ !options.append) {
1363
+ const actionAnswer = await inquirer.prompt([
1364
+ {
1365
+ type: "list",
1366
+ name: "action",
1367
+ message: `Directory ${PATHS.SPEC} already exists. What do you want to do?`,
1368
+ choices: [
1369
+ { name: "Skip (keep existing)", value: "skip" },
1370
+ {
1371
+ name: "Overwrite (replace all)",
1372
+ value: "overwrite",
1373
+ },
1374
+ {
1375
+ name: "Append (add missing files only)",
1376
+ value: "append",
1377
+ },
1378
+ ],
1379
+ default: "skip",
1380
+ },
1381
+ ]);
1382
+ templateStrategy = actionAnswer.action;
1383
+ }
1384
+ }
1385
+ templatePicked = true;
1386
+ }
1387
+ else if (customProbe.isNotFound) {
1388
+ // No index.json → direct download mode
1389
+ templatePicked = true;
1390
+ }
1391
+ else {
1392
+ // Transient error (not 404) — loop back, don't misclassify
1393
+ console.log(chalk.yellow(` ${customProbe.error?.message ?? "Could not reach registry. Try again or enter a different source."}`));
1394
+ registry = undefined; // Reset so we don't fall through to direct download
1395
+ registrySourceForConfig = undefined;
1396
+ }
1397
+ }
1398
+ catch (error) {
1399
+ console.log(chalk.red(error instanceof Error
1400
+ ? error.message
1401
+ : "Invalid registry source"));
1402
+ // Loop back to picker
1403
+ }
1404
+ }
1405
+ else {
1406
+ templatePicked = true;
1407
+ if (templateAnswer.template !== "blank") {
1408
+ selectedTemplate = templateAnswer.template;
1409
+ // Check if spec directory already exists and ask what to do
1410
+ const specDir = path.join(cwd, PATHS.SPEC);
1411
+ if (fs.existsSync(specDir) &&
1412
+ !options.overwrite &&
1413
+ !options.append) {
1414
+ const actionAnswer = await inquirer.prompt([
1415
+ {
1416
+ type: "list",
1417
+ name: "action",
1418
+ message: `Directory ${PATHS.SPEC} already exists. What do you want to do?`,
1419
+ choices: [
1420
+ { name: "Skip (keep existing)", value: "skip" },
1421
+ { name: "Overwrite (replace all)", value: "overwrite" },
1422
+ {
1423
+ name: "Append (add missing files only)",
1424
+ value: "append",
1425
+ },
1426
+ ],
1427
+ default: "skip",
1428
+ },
1429
+ ]);
1430
+ templateStrategy = actionAnswer.action;
1431
+ }
1432
+ }
1433
+ }
1434
+ }
1435
+ }
1436
+ }
1437
+ // -y mode with --registry (no --template): probe index.json to detect mode
1438
+ // Skip when monorepo mode already handled templates above
1439
+ if (options.yes && registry && !selectedTemplate && !monorepoPackages) {
1440
+ const probeResult = await probeRegistryIndex(`${registry.rawBaseUrl}/index.json`, registry);
1441
+ registryBackend = probeResult.backend;
1442
+ if (probeResult.templates.length > 0) {
1443
+ // Marketplace mode requires interactive selection — can't auto-select
1444
+ console.log(chalk.red("Error: Registry is a marketplace with multiple templates. " +
1445
+ "Use --template <id> to specify which one, or remove -y for interactive selection."));
1446
+ return;
1447
+ }
1448
+ if (!probeResult.isNotFound) {
1449
+ // Transient error (not 404) — abort, don't misclassify as direct-download
1450
+ console.log(chalk.red(`Error: ${probeResult.error?.message ?? "Could not reach registry. Check your connection and try again."}`));
1451
+ return;
1452
+ }
1453
+ // isNotFound=true → no index.json, proceed with direct download (fetchedTemplates stays empty)
1454
+ }
1455
+ // ==========================================================================
1456
+ // Download Remote Template (if selected or direct registry download)
1457
+ // ==========================================================================
1458
+ let useRemoteTemplate = false;
1459
+ let registrySpecConfigToPersist = null;
1460
+ if (selectedTemplate) {
1461
+ // Marketplace mode: download specific template by ID
1462
+ console.log(chalk.blue(`📦 Downloading template "${selectedTemplate}"...`));
1463
+ console.log(chalk.gray(" This may take a moment on slow connections."));
1464
+ // Find pre-fetched SpecTemplate to avoid double-fetch
1465
+ const prefetched = fetchedTemplates.find((t) => t.id === selectedTemplate);
1466
+ const result = await downloadTemplateById(cwd, selectedTemplate, templateStrategy, prefetched, registry, undefined, registryBackend);
1467
+ if (result.success) {
1468
+ useRemoteTemplate = true;
1469
+ if (result.skipped) {
1470
+ console.log(chalk.gray(` ${result.message}`));
1471
+ }
1472
+ else {
1473
+ console.log(chalk.green(` ${result.message}`));
1474
+ if (registry) {
1475
+ registrySpecConfigToPersist = {
1476
+ source: registrySourceForConfig ?? registry.gigetSource,
1477
+ template: selectedTemplate,
1478
+ };
1479
+ }
1480
+ }
1481
+ }
1482
+ else {
1483
+ if (useCviautoDefaultSpecRegistry) {
1484
+ console.log(chalk.red(`Error: Could not install Cviauto default specs from ${CVIAUTO_DEFAULT_SPEC_REGISTRY}.`));
1485
+ console.log(chalk.red(` ${result.message}`));
1486
+ return;
1487
+ }
1488
+ console.log(chalk.yellow(` ${result.message}`));
1489
+ console.log(chalk.gray(" Falling back to blank templates..."));
1490
+ const retryCmd = registry
1491
+ ? `cviauto init --registry ${registry.gigetSource} --template ${selectedTemplate}`
1492
+ : `cviauto init --template ${selectedTemplate}`;
1493
+ console.log(chalk.gray(` You can retry later: ${retryCmd}`));
1494
+ }
1495
+ }
1496
+ else if (registry && fetchedTemplates.length === 0) {
1497
+ // Direct download mode: registry has no index.json, download directory directly
1498
+ console.log(chalk.blue(`📦 Downloading spec from ${registry.gigetSource}...`));
1499
+ console.log(chalk.gray(" This may take a moment on slow connections."));
1500
+ // Ask about existing spec dir in interactive mode
1501
+ if (!options.yes && !options.overwrite && !options.append) {
1502
+ const specDir = path.join(cwd, PATHS.SPEC);
1503
+ if (fs.existsSync(specDir)) {
1504
+ const actionAnswer = await inquirer.prompt([
1505
+ {
1506
+ type: "list",
1507
+ name: "action",
1508
+ message: `Directory ${PATHS.SPEC} already exists. What do you want to do?`,
1509
+ choices: [
1510
+ { name: "Skip (keep existing)", value: "skip" },
1511
+ { name: "Overwrite (replace all)", value: "overwrite" },
1512
+ { name: "Append (add missing files only)", value: "append" },
1513
+ ],
1514
+ default: "skip",
1515
+ },
1516
+ ]);
1517
+ templateStrategy = actionAnswer.action;
1518
+ }
1519
+ }
1520
+ const result = await downloadRegistryDirect(cwd, registry, templateStrategy, undefined, registryBackend);
1521
+ if (result.success) {
1522
+ useRemoteTemplate = true;
1523
+ if (result.skipped) {
1524
+ console.log(chalk.gray(` ${result.message}`));
1525
+ }
1526
+ else {
1527
+ console.log(chalk.green(` ${result.message}`));
1528
+ registrySpecConfigToPersist = {
1529
+ source: registrySourceForConfig ?? registry.gigetSource,
1530
+ };
1531
+ }
1532
+ }
1533
+ else {
1534
+ if (useCviautoDefaultSpecRegistry) {
1535
+ console.log(chalk.red(`Error: Could not install Cviauto default specs from ${CVIAUTO_DEFAULT_SPEC_REGISTRY}.`));
1536
+ console.log(chalk.red(` ${result.message}`));
1537
+ return;
1538
+ }
1539
+ console.log(chalk.yellow(` ${result.message}`));
1540
+ console.log(chalk.gray(" Falling back to blank templates..."));
1541
+ console.log(chalk.gray(` You can retry later: cviauto init --registry ${registry.gigetSource}`));
1542
+ }
1543
+ }
1544
+ // ==========================================================================
1545
+ // Resolve workflow template (default: native bundled)
1546
+ // ==========================================================================
1547
+ const workflowIdInput = options.workflow?.trim();
1548
+ const workflowId = workflowIdInput && workflowIdInput.length > 0
1549
+ ? workflowIdInput
1550
+ : NATIVE_WORKFLOW_ID;
1551
+ let workflowMdOverride;
1552
+ if (workflowId !== NATIVE_WORKFLOW_ID || options.workflowSource) {
1553
+ const resolved = await resolveWorkflowTemplate(workflowId, {
1554
+ source: options.workflowSource,
1555
+ });
1556
+ if (resolved.id !== NATIVE_WORKFLOW_ID) {
1557
+ workflowMdOverride = resolved.content;
1558
+ console.log(chalk.blue(`🧭 Using workflow template: ${chalk.cyan(resolved.id)}`));
1559
+ }
1560
+ }
1561
+ // ==========================================================================
1562
+ // Create Workflow Structure
1563
+ // ==========================================================================
1564
+ // Record every successful write from here through createRootFiles. The
1565
+ // captured set is the source of truth for `.template-hashes.json`'s
1566
+ // platform/root entries — replacing the previous "walk every managed dir"
1567
+ // approach that swept user-owned runtime files into the manifest
1568
+ // (.codex/sessions/, .claude/projects/, pre-existing AGENTS.md).
1569
+ const writtenPaths = startRecordingWrites(cwd);
1570
+ try {
1571
+ // Create workflow structure with project type
1572
+ console.log(chalk.blue("📁 Creating workflow structure..."));
1573
+ await createWorkflowStructure(cwd, {
1574
+ projectType,
1575
+ skipSpecTemplates: useRemoteTemplate,
1576
+ packages: monorepoPackages,
1577
+ remoteSpecPackages,
1578
+ workflowMdOverride,
1579
+ });
1580
+ // Write monorepo packages to config.yaml (non-destructive patch)
1581
+ if (monorepoPackages) {
1582
+ writeMonorepoConfig(cwd, monorepoPackages);
1583
+ console.log(chalk.blue("📦 Monorepo packages written to config.yaml"));
1584
+ }
1585
+ // Write version file for update tracking
1586
+ const versionPath = path.join(cwd, DIR_NAMES.WORKFLOW, ".version");
1587
+ fs.writeFileSync(versionPath, VERSION);
1588
+ // Configure selected tools by copying entire directories (dogfooding)
1589
+ for (const tool of tools) {
1590
+ const platformId = resolveCliFlag(tool);
1591
+ if (platformId) {
1592
+ console.log(chalk.blue(`📝 Configuring ${AI_TOOLS[platformId].name}...`));
1593
+ await configurePlatform(platformId, cwd, {
1594
+ withStatusline: options.withStatusline,
1595
+ });
1596
+ if (platformId === "claude-code" && options.withStatusline) {
1597
+ console.log(chalk.gray(" ↳ Cviauto statusLine installed (--with-statusline)"));
1598
+ }
1599
+ }
1600
+ }
1601
+ const pythonPlatforms = getPlatformsWithPythonHooks();
1602
+ const hasSelectedPythonPlatform = pythonPlatforms.some((id) => tools.includes(AI_TOOLS[id].cliFlag));
1603
+ if (hasSelectedPythonPlatform) {
1604
+ logPythonAdaptationNotice(pythonCmd);
1605
+ }
1606
+ // Create root files (skip if exists)
1607
+ await createRootFiles(cwd);
1608
+ }
1609
+ finally {
1610
+ stopRecordingWrites();
1611
+ }
1612
+ if (registrySpecConfigToPersist) {
1613
+ writeSpecRegistryConfig(cwd, registrySpecConfigToPersist);
1614
+ }
1615
+ // Initialize template hashes for modification tracking
1616
+ const hashedCount = initializeHashes(cwd, { trackedPaths: writtenPaths });
1617
+ if (useRemoteTemplate) {
1618
+ const specFilesToHash = new Map();
1619
+ for (const relativePath of collectSpecPaths(cwd)) {
1620
+ const content = fs.readFileSync(path.join(cwd, relativePath), "utf-8");
1621
+ specFilesToHash.set(relativePath, content);
1622
+ }
1623
+ if (specFilesToHash.size > 0) {
1624
+ updateHashes(cwd, specFilesToHash);
1625
+ }
1626
+ }
1627
+ if (hashedCount > 0) {
1628
+ console.log(chalk.gray(`📋 Tracking ${hashedCount} template files for updates`));
1629
+ }
1630
+ // Non-native workflow is user-managed local content. Drop the
1631
+ // `.cviauto/workflow.md` hash entry so `cviauto update` classifies it as
1632
+ // modified and does not silently restore native bytes. See design.md
1633
+ // "Durable-state contract".
1634
+ if (workflowMdOverride !== undefined && workflowId !== NATIVE_WORKFLOW_ID) {
1635
+ removeHash(cwd, PATHS.WORKFLOW_GUIDE_FILE);
1636
+ }
1637
+ // Initialize developer identity (silent - no output)
1638
+ if (developerName) {
1639
+ try {
1640
+ const scriptPath = path.join(cwd, PATHS.SCRIPTS, "init_developer.py");
1641
+ execSync(`${pythonCmd} "${scriptPath}" "${developerName}"`, {
1642
+ cwd,
1643
+ stdio: "pipe", // Silent
1644
+ });
1645
+ }
1646
+ catch {
1647
+ // Silent failure - user can run init_developer.py manually
1648
+ }
1649
+ // Three-branch dispatch using flags captured at init() start (before
1650
+ // createWorkflowStructure/init_developer ran, so they reflect the disk
1651
+ // state of the user's checkout, not the state this init just produced):
1652
+ // isFirstInit=true → creator bootstrap (new project)
1653
+ // isFirstInit=false + no .developer file → joiner onboarding (fresh clone)
1654
+ // isFirstInit=false + .developer exists → same-dev re-init, no task
1655
+ //
1656
+ // Tasks-empty fallback (issue #204): if .cviauto/ exists but tasks dir is
1657
+ // empty, the previous init aborted before creating the bootstrap task. Run
1658
+ // bootstrap creation regardless of isFirstInit. writeTaskSkeleton is
1659
+ // idempotent so repeated triggers are safe.
1660
+ //
1661
+ // Runs OUTSIDE the init_developer try/catch (which uses stdio: "pipe")
1662
+ // so joiner failures surface as warnings instead of being silently
1663
+ // swallowed.
1664
+ const tasksDir = path.join(cwd, PATHS.TASKS);
1665
+ const tasksEmpty = !fs.existsSync(tasksDir) || fs.readdirSync(tasksDir).length === 0;
1666
+ if (isFirstInit || tasksEmpty) {
1667
+ createBootstrapTask(cwd, developerName, pythonCmd, projectType, useCviautoDefaultSpecRegistry ? undefined : monorepoPackages, useCviautoDefaultSpecRegistry);
1668
+ }
1669
+ else if (!hadDeveloperFileAtStart) {
1670
+ try {
1671
+ if (!createJoinerOnboardingTask(cwd, developerName, pythonCmd)) {
1672
+ console.warn(chalk.yellow("⚠ Failed to create joiner onboarding task"));
1673
+ }
1674
+ }
1675
+ catch (err) {
1676
+ console.warn(chalk.yellow(`⚠ Joiner onboarding setup failed: ${err instanceof Error ? err.message : String(err)}`));
1677
+ }
1678
+ }
1679
+ }
1680
+ }
1681
+ /**
1682
+ * Simple readline-based input (no flickering like inquirer)
1683
+ */
1684
+ function askInput(prompt) {
1685
+ const rl = readline.createInterface({
1686
+ input: process.stdin,
1687
+ output: process.stdout,
1688
+ });
1689
+ return new Promise((resolve) => {
1690
+ rl.question(prompt, (answer) => {
1691
+ rl.close();
1692
+ resolve(answer.trim());
1693
+ });
1694
+ });
1695
+ }
1696
+ async function createRootFiles(cwd) {
1697
+ const agentsPath = path.join(cwd, FILE_NAMES.AGENTS);
1698
+ // Write AGENTS.md from template
1699
+ const agentsWritten = await writeFile(agentsPath, agentsMdContent);
1700
+ if (agentsWritten) {
1701
+ console.log(chalk.blue("📄 Created AGENTS.md"));
1702
+ }
1703
+ }
1704
+ //# sourceMappingURL=init.js.map