@iloom/cli 0.11.1 → 0.12.1

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 (289) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +153 -13
  3. package/dist/BitBucketApiClient-J2ZSCS5N.js +10 -0
  4. package/dist/BitBucketVCSProvider-5X64IXXW.js +12 -0
  5. package/dist/{BranchNamingService-XBCO747L.js → BranchNamingService-MEK2WZUD.js} +4 -4
  6. package/dist/ClaudeContextManager-IENAE2CP.js +14 -0
  7. package/dist/ClaudeService-YIJCZUUB.js +13 -0
  8. package/dist/GitHubService-UTAYZXL3.js +12 -0
  9. package/dist/IssueTrackerFactory-2OI7YIN6.js +15 -0
  10. package/dist/{LoomLauncher-5AZU2F5I.js → LoomLauncher-3TSFW7QP.js} +10 -10
  11. package/dist/MetadataManager-V4LSJ2PB.js +10 -0
  12. package/dist/ProjectCapabilityDetector-I4J66WKF.js +11 -0
  13. package/dist/{PromptTemplateManager-T5VTLJP3.js → PromptTemplateManager-I75WKXM4.js} +3 -3
  14. package/dist/README.md +153 -13
  15. package/dist/{SettingsManager-WQ5NSGAH.js → SettingsManager-BMQCAXPP.js} +13 -5
  16. package/dist/SettingsMigrationManager-ZPARZ5KH.js +10 -0
  17. package/dist/agents/iloom-code-reviewer.md +2 -1
  18. package/dist/agents/iloom-framework-detector.md +0 -1
  19. package/dist/agents/iloom-issue-analyze-and-plan.md +4 -1
  20. package/dist/agents/iloom-issue-analyzer.md +4 -1
  21. package/dist/agents/iloom-issue-complexity-evaluator.md +4 -1
  22. package/dist/agents/iloom-issue-enhancer.md +4 -1
  23. package/dist/agents/iloom-issue-implementer.md +5 -2
  24. package/dist/agents/iloom-issue-planner.md +4 -1
  25. package/dist/agents/iloom-wave-verifier.md +186 -0
  26. package/dist/browser-VZY7F2DF.js +10 -0
  27. package/dist/build-DMWSIME6.js +27 -0
  28. package/dist/{chunk-UHIBKD73.js → chunk-35CBWAJL.js} +13 -32
  29. package/dist/{chunk-UHIBKD73.js.map → chunk-35CBWAJL.js.map} +1 -1
  30. package/dist/{chunk-YRCEOQPX.js → chunk-4JZEQBWV.js} +4 -3
  31. package/dist/chunk-4JZEQBWV.js.map +1 -0
  32. package/dist/{chunk-ET6A2JR4.js → chunk-653XBU3L.js} +111 -18
  33. package/dist/chunk-653XBU3L.js.map +1 -0
  34. package/dist/{chunk-G2MNSPA4.js → chunk-772N5WCA.js} +2 -2
  35. package/dist/{chunk-WG4MLJ6J.js → chunk-7RCUWU3I.js} +2 -2
  36. package/dist/chunk-7RCUWU3I.js.map +1 -0
  37. package/dist/{chunk-NOMQ5RFG.js → chunk-7UBEHQTP.js} +2 -2
  38. package/dist/{chunk-7NFCGKZT.js → chunk-AQUSMNBF.js} +3 -3
  39. package/dist/{chunk-IDCE26KD.js → chunk-AUYSAMXV.js} +3 -3
  40. package/dist/chunk-AYLC633W.js +406 -0
  41. package/dist/chunk-AYLC633W.js.map +1 -0
  42. package/dist/{chunk-HLDY5S4C.js → chunk-BFF27W3S.js} +3 -3
  43. package/dist/{chunk-QVAA5KHK.js → chunk-BZ7KTXPB.js} +16 -8
  44. package/dist/chunk-BZ7KTXPB.js.map +1 -0
  45. package/dist/{chunk-K7R5QY6C.js → chunk-CE676WCN.js} +2 -2
  46. package/dist/{chunk-5UFGO4ZT.js → chunk-CQHHEW2M.js} +6 -3
  47. package/dist/chunk-CQHHEW2M.js.map +1 -0
  48. package/dist/{chunk-LHDD4JHC.js → chunk-D4Q7T5KD.js} +4 -4
  49. package/dist/{chunk-RBYTXYGD.js → chunk-D75KSI3V.js} +2 -2
  50. package/dist/{chunk-Y3RX7LZT.js → chunk-DDHWZNGL.js} +18 -12
  51. package/dist/chunk-DDHWZNGL.js.map +1 -0
  52. package/dist/{chunk-5LTID2AF.js → chunk-DMSL5BAP.js} +35 -6
  53. package/dist/{chunk-5LTID2AF.js.map → chunk-DMSL5BAP.js.map} +1 -1
  54. package/dist/{chunk-TEJAGQX2.js → chunk-DY6MUWQW.js} +36 -36
  55. package/dist/chunk-DY6MUWQW.js.map +1 -0
  56. package/dist/{chunk-SQYHPBFP.js → chunk-EGNUOALL.js} +2 -2
  57. package/dist/{chunk-LL6TOX3G.js → chunk-EQIII6GI.js} +10 -10
  58. package/dist/chunk-EQIII6GI.js.map +1 -0
  59. package/dist/{chunk-ZAXRQLK3.js → chunk-FTYWGQFM.js} +2 -2
  60. package/dist/{chunk-LE2NOUTN.js → chunk-FV4KXBGO.js} +3 -3
  61. package/dist/{chunk-XFQGI2E3.js → chunk-GWJWECZB.js} +51 -45
  62. package/dist/chunk-GWJWECZB.js.map +1 -0
  63. package/dist/{chunk-QNHZM5ZV.js → chunk-HIGWKLQR.js} +3 -3
  64. package/dist/{chunk-VMZG66UV.js → chunk-HKEXRZMU.js} +3 -3
  65. package/dist/{chunk-V4STTBQD.js → chunk-IHSA7VGI.js} +9 -9
  66. package/dist/{chunk-NCPZYQ4B.js → chunk-K3QGG4O2.js} +2 -2
  67. package/dist/{chunk-QR4FU53I.js → chunk-KCZSUJUR.js} +22 -12
  68. package/dist/chunk-KCZSUJUR.js.map +1 -0
  69. package/dist/{chunk-NH3QZYE5.js → chunk-KV4NU3RP.js} +2 -2
  70. package/dist/{chunk-NDSGJZI2.js → chunk-LOAYWTJJ.js} +2 -2
  71. package/dist/{chunk-ABVMUNCD.js → chunk-M3FBM4T3.js} +64 -10
  72. package/dist/chunk-M3FBM4T3.js.map +1 -0
  73. package/dist/{chunk-GMDSYLI6.js → chunk-MY2Q3FJ3.js} +2 -2
  74. package/dist/{chunk-CV47VCMQ.js → chunk-NPVA65KS.js} +2 -2
  75. package/dist/{chunk-7OCGBJLR.js → chunk-OIVFHJOA.js} +2 -2
  76. package/dist/{chunk-7FIXNAUO.js → chunk-OKB2NEDQ.js} +66 -43
  77. package/dist/chunk-OKB2NEDQ.js.map +1 -0
  78. package/dist/{chunk-3RXYOBME.js → chunk-OPQC4OWM.js} +5 -5
  79. package/dist/{chunk-3RXYOBME.js.map → chunk-OPQC4OWM.js.map} +1 -1
  80. package/dist/chunk-P5MXXHXQ.js +284 -0
  81. package/dist/chunk-P5MXXHXQ.js.map +1 -0
  82. package/dist/{chunk-NN5RYWXA.js → chunk-PH65MFQM.js} +6 -6
  83. package/dist/{chunk-TZNNJLGT.js → chunk-PMB6TYV4.js} +6 -6
  84. package/dist/chunk-QC65IOV3.js +304 -0
  85. package/dist/chunk-QC65IOV3.js.map +1 -0
  86. package/dist/{chunk-6YVJVUR4.js → chunk-QF2DROQR.js} +3 -3
  87. package/dist/{chunk-XXFSOVL3.js → chunk-QFDM23CO.js} +4 -4
  88. package/dist/{chunk-RMLADZRY.js → chunk-R7DGN73N.js} +5 -5
  89. package/dist/{chunk-IR74O2F6.js → chunk-UVXB6O24.js} +245 -187
  90. package/dist/chunk-UVXB6O24.js.map +1 -0
  91. package/dist/{chunk-5PNZBH6V.js → chunk-V5IYLWRA.js} +2 -2
  92. package/dist/{chunk-KQFIGI37.js → chunk-VA6CWUAE.js} +7 -7
  93. package/dist/{chunk-3GTUXW26.js → chunk-VIQOQ463.js} +19 -3
  94. package/dist/chunk-VIQOQ463.js.map +1 -0
  95. package/dist/{chunk-H2SSF24U.js → chunk-VRPPI6GU.js} +17 -6
  96. package/dist/{chunk-H2SSF24U.js.map → chunk-VRPPI6GU.js.map} +1 -1
  97. package/dist/{chunk-YETJNRQM.js → chunk-WEBMMJKL.js} +2 -1
  98. package/dist/{chunk-VUUN3KE4.js → chunk-XVCGPTEQ.js} +8 -8
  99. package/dist/chunk-XVCGPTEQ.js.map +1 -0
  100. package/dist/{chunk-VNYWBHKR.js → chunk-Y2MVSEJK.js} +33 -3
  101. package/dist/chunk-Y2MVSEJK.js.map +1 -0
  102. package/dist/chunk-YWNF5755.js +696 -0
  103. package/dist/chunk-YWNF5755.js.map +1 -0
  104. package/dist/{chunk-UDCI3QTS.js → chunk-ZM2AYHMO.js} +2 -2
  105. package/dist/{claude-ONQTDWV3.js → claude-ACL7G4CF.js} +4 -4
  106. package/dist/{cleanup-YOM6PQCN.js → cleanup-RLBLNQZN.js} +37 -34
  107. package/dist/{cleanup-YOM6PQCN.js.map → cleanup-RLBLNQZN.js.map} +1 -1
  108. package/dist/cli.js +290 -141
  109. package/dist/cli.js.map +1 -1
  110. package/dist/{color-VQD52LOI.js → color-AC6F2QE7.js} +3 -3
  111. package/dist/{commit-DC2Q5CDY.js → commit-RILBXFWO.js} +15 -15
  112. package/dist/{compile-4NCQECKE.js → compile-QEL5724K.js} +11 -11
  113. package/dist/{contribute-M5UWXCAV.js → contribute-EHWLYOMZ.js} +11 -11
  114. package/dist/{contribute-M5UWXCAV.js.map → contribute-EHWLYOMZ.js.map} +1 -1
  115. package/dist/{mcp/darwin-3JFFE3W2.js → darwin-5K3I4FTH.js} +2 -2
  116. package/dist/{dev-server-CYRP6M73.js → dev-server-2WSWZXJG.js} +35 -21
  117. package/dist/dev-server-2WSWZXJG.js.map +1 -0
  118. package/dist/{feedback-BMAZGKRW.js → feedback-RFWGB4I5.js} +17 -17
  119. package/dist/{git-BXUD6CL5.js → git-I3PO6FY7.js} +6 -6
  120. package/dist/ignite-X2NNTNUN.js +35 -0
  121. package/dist/index.d.ts +200 -16
  122. package/dist/index.js +164 -55
  123. package/dist/index.js.map +1 -1
  124. package/dist/{init-CI43GJHV.js → init-LWU2M53W.js} +18 -18
  125. package/dist/{install-deps-SRTM5U7D.js → install-deps-HXP2TM7G.js} +11 -11
  126. package/dist/{installation-detector-HF6QN7KP.js → installation-detector-PYAZ2O6U.js} +3 -3
  127. package/dist/{issues-DMRQJH7E.js → issues-SUFQJY6O.js} +69 -56
  128. package/dist/issues-SUFQJY6O.js.map +1 -0
  129. package/dist/lint-FDZC77GL.js +27 -0
  130. package/dist/{linux-RYLOP2LY.js → linux-WUGRYCJY.js} +2 -2
  131. package/dist/mcp/{chunk-PIIRD4LO.js → chunk-4HZMW2V3.js} +1 -1
  132. package/dist/mcp/{chunk-PIIRD4LO.js.map → chunk-4HZMW2V3.js.map} +1 -1
  133. package/dist/{darwin-5BHWRJ7D.js → mcp/darwin-U25WIGH6.js} +2 -2
  134. package/dist/mcp/issue-management-server.js +900 -20
  135. package/dist/mcp/issue-management-server.js.map +1 -1
  136. package/dist/mcp/{linux-JBVS4R3A.js → linux-5BXVBGSY.js} +2 -2
  137. package/dist/mcp/recap-server.js +24 -22
  138. package/dist/mcp/recap-server.js.map +1 -1
  139. package/dist/mcp/{tmux-RYBLEHUZ.js → tmux-CU26ZTNM.js} +2 -2
  140. package/dist/mcp/{wsl-4QZIQLLE.js → wsl-KI25UDOF.js} +2 -2
  141. package/dist/neon-helpers-LCZAN4U4.js +11 -0
  142. package/dist/{open-2Y7GSUTJ.js → open-US4XACLW.js} +36 -21
  143. package/dist/open-US4XACLW.js.map +1 -0
  144. package/dist/{plan-SWFPLNJE.js → plan-5S6355GF.js} +68 -75
  145. package/dist/plan-5S6355GF.js.map +1 -0
  146. package/dist/{projects-IUSUXD5D.js → projects-L5AHUBGA.js} +6 -6
  147. package/dist/{prompt-7LZB4PAT.js → prompt-FUU5NMJQ.js} +3 -3
  148. package/dist/prompt-FUU5NMJQ.js.map +1 -0
  149. package/dist/prompts/init-prompt.txt +160 -23
  150. package/dist/prompts/issue-prompt.txt +93 -157
  151. package/dist/prompts/plan-prompt.txt +86 -6
  152. package/dist/prompts/swarm-orchestrator-prompt.txt +78 -21
  153. package/dist/{rebase-S6OHAOOF.js → rebase-JA3RW2XO.js} +12 -12
  154. package/dist/{recap-GGVCG5VH.js → recap-5TO42HN2.js} +9 -9
  155. package/dist/{remote-MZTFHHTU.js → remote-RO4LZKT2.js} +3 -3
  156. package/dist/remote-RO4LZKT2.js.map +1 -0
  157. package/dist/{run-ST3FR75O.js → run-KKCRBRLW.js} +36 -21
  158. package/dist/run-KKCRBRLW.js.map +1 -0
  159. package/dist/schema/settings.schema.json +147 -11
  160. package/dist/{shell-W4SBQPTE.js → shell-GAB2FCXH.js} +8 -8
  161. package/dist/{summary-P2JCIIJO.js → summary-P7QE3TNW.js} +21 -19
  162. package/dist/summary-P7QE3TNW.js.map +1 -0
  163. package/dist/test-6LFB5WOO.js +27 -0
  164. package/dist/{test-git-2KFFAQ6B.js → test-git-PYJOYSED.js} +6 -6
  165. package/dist/{test-jira-FKDKG6CD.js → test-jira-SM7IU5HW.js} +8 -8
  166. package/dist/{test-prefix-GP2DAX37.js → test-prefix-HIRZBXTM.js} +6 -6
  167. package/dist/{test-tabs-YDWMWTVA.js → test-tabs-NGPTFD5T.js} +2 -2
  168. package/dist/{test-webserver-QI3QQFZ3.js → test-webserver-43PVP2JL.js} +8 -8
  169. package/dist/{tmux-7ZTA3BDI.js → tmux-6LRFH3DM.js} +2 -2
  170. package/dist/{update-XLW7R7FL.js → update-AD3GE5C4.js} +4 -4
  171. package/dist/{update-notifier-EYLAXZAA.js → update-notifier-VYDTDMSJ.js} +3 -3
  172. package/dist/update-notifier-VYDTDMSJ.js.map +1 -0
  173. package/dist/{vscode-TOGE5N67.js → vscode-HXIXRZ3A.js} +12 -12
  174. package/dist/{vscode-announcement-NIX7O2MG.js → vscode-announcement-AL3EHORH.js} +3 -3
  175. package/dist/{wsl-Y4GUTOQ7.js → wsl-4VMVT2PO.js} +2 -2
  176. package/package.json +1 -1
  177. package/dist/ClaudeContextManager-SXDCWDJA.js +0 -14
  178. package/dist/ClaudeService-6E6MCGJE.js +0 -13
  179. package/dist/GitHubService-2R5GQG4K.js +0 -12
  180. package/dist/IssueTrackerFactory-XN6MQ4UN.js +0 -14
  181. package/dist/MetadataManager-CMQQTFLQ.js +0 -10
  182. package/dist/ProjectCapabilityDetector-IC6NAFGY.js +0 -11
  183. package/dist/SettingsMigrationManager-S6J7OHUH.js +0 -10
  184. package/dist/build-OLS6J5KZ.js +0 -27
  185. package/dist/chunk-3GTUXW26.js.map +0 -1
  186. package/dist/chunk-5UFGO4ZT.js.map +0 -1
  187. package/dist/chunk-7FIXNAUO.js.map +0 -1
  188. package/dist/chunk-ABVMUNCD.js.map +0 -1
  189. package/dist/chunk-ET6A2JR4.js.map +0 -1
  190. package/dist/chunk-IR74O2F6.js.map +0 -1
  191. package/dist/chunk-LL6TOX3G.js.map +0 -1
  192. package/dist/chunk-QR4FU53I.js.map +0 -1
  193. package/dist/chunk-QVAA5KHK.js.map +0 -1
  194. package/dist/chunk-RVI6C2H5.js +0 -220
  195. package/dist/chunk-RVI6C2H5.js.map +0 -1
  196. package/dist/chunk-TEJAGQX2.js.map +0 -1
  197. package/dist/chunk-VNYWBHKR.js.map +0 -1
  198. package/dist/chunk-VUUN3KE4.js.map +0 -1
  199. package/dist/chunk-WG4MLJ6J.js.map +0 -1
  200. package/dist/chunk-XFQGI2E3.js.map +0 -1
  201. package/dist/chunk-Y3RX7LZT.js.map +0 -1
  202. package/dist/chunk-YRCEOQPX.js.map +0 -1
  203. package/dist/dev-server-CYRP6M73.js.map +0 -1
  204. package/dist/ignite-IO4LXVXJ.js +0 -35
  205. package/dist/issues-DMRQJH7E.js.map +0 -1
  206. package/dist/lint-BSWRMGPZ.js +0 -27
  207. package/dist/neon-helpers-HWIYRKOW.js +0 -11
  208. package/dist/open-2Y7GSUTJ.js.map +0 -1
  209. package/dist/plan-SWFPLNJE.js.map +0 -1
  210. package/dist/run-ST3FR75O.js.map +0 -1
  211. package/dist/summary-P2JCIIJO.js.map +0 -1
  212. package/dist/test-6JH4FE2X.js +0 -27
  213. /package/dist/{BranchNamingService-XBCO747L.js.map → BitBucketApiClient-J2ZSCS5N.js.map} +0 -0
  214. /package/dist/{ClaudeContextManager-SXDCWDJA.js.map → BitBucketVCSProvider-5X64IXXW.js.map} +0 -0
  215. /package/dist/{ClaudeService-6E6MCGJE.js.map → BranchNamingService-MEK2WZUD.js.map} +0 -0
  216. /package/dist/{GitHubService-2R5GQG4K.js.map → ClaudeContextManager-IENAE2CP.js.map} +0 -0
  217. /package/dist/{IssueTrackerFactory-XN6MQ4UN.js.map → ClaudeService-YIJCZUUB.js.map} +0 -0
  218. /package/dist/{MetadataManager-CMQQTFLQ.js.map → GitHubService-UTAYZXL3.js.map} +0 -0
  219. /package/dist/{ProjectCapabilityDetector-IC6NAFGY.js.map → IssueTrackerFactory-2OI7YIN6.js.map} +0 -0
  220. /package/dist/{LoomLauncher-5AZU2F5I.js.map → LoomLauncher-3TSFW7QP.js.map} +0 -0
  221. /package/dist/{PromptTemplateManager-T5VTLJP3.js.map → MetadataManager-V4LSJ2PB.js.map} +0 -0
  222. /package/dist/{SettingsManager-WQ5NSGAH.js.map → ProjectCapabilityDetector-I4J66WKF.js.map} +0 -0
  223. /package/dist/{SettingsMigrationManager-S6J7OHUH.js.map → PromptTemplateManager-I75WKXM4.js.map} +0 -0
  224. /package/dist/{claude-ONQTDWV3.js.map → SettingsManager-BMQCAXPP.js.map} +0 -0
  225. /package/dist/{color-VQD52LOI.js.map → SettingsMigrationManager-ZPARZ5KH.js.map} +0 -0
  226. /package/dist/{darwin-5BHWRJ7D.js.map → browser-VZY7F2DF.js.map} +0 -0
  227. /package/dist/{build-OLS6J5KZ.js.map → build-DMWSIME6.js.map} +0 -0
  228. /package/dist/{chunk-G2MNSPA4.js.map → chunk-772N5WCA.js.map} +0 -0
  229. /package/dist/{chunk-NOMQ5RFG.js.map → chunk-7UBEHQTP.js.map} +0 -0
  230. /package/dist/{chunk-7NFCGKZT.js.map → chunk-AQUSMNBF.js.map} +0 -0
  231. /package/dist/{chunk-IDCE26KD.js.map → chunk-AUYSAMXV.js.map} +0 -0
  232. /package/dist/{chunk-HLDY5S4C.js.map → chunk-BFF27W3S.js.map} +0 -0
  233. /package/dist/{chunk-K7R5QY6C.js.map → chunk-CE676WCN.js.map} +0 -0
  234. /package/dist/{chunk-LHDD4JHC.js.map → chunk-D4Q7T5KD.js.map} +0 -0
  235. /package/dist/{chunk-RBYTXYGD.js.map → chunk-D75KSI3V.js.map} +0 -0
  236. /package/dist/{chunk-SQYHPBFP.js.map → chunk-EGNUOALL.js.map} +0 -0
  237. /package/dist/{chunk-ZAXRQLK3.js.map → chunk-FTYWGQFM.js.map} +0 -0
  238. /package/dist/{chunk-LE2NOUTN.js.map → chunk-FV4KXBGO.js.map} +0 -0
  239. /package/dist/{chunk-QNHZM5ZV.js.map → chunk-HIGWKLQR.js.map} +0 -0
  240. /package/dist/{chunk-VMZG66UV.js.map → chunk-HKEXRZMU.js.map} +0 -0
  241. /package/dist/{chunk-V4STTBQD.js.map → chunk-IHSA7VGI.js.map} +0 -0
  242. /package/dist/{chunk-NCPZYQ4B.js.map → chunk-K3QGG4O2.js.map} +0 -0
  243. /package/dist/{chunk-NH3QZYE5.js.map → chunk-KV4NU3RP.js.map} +0 -0
  244. /package/dist/{chunk-NDSGJZI2.js.map → chunk-LOAYWTJJ.js.map} +0 -0
  245. /package/dist/{chunk-GMDSYLI6.js.map → chunk-MY2Q3FJ3.js.map} +0 -0
  246. /package/dist/{chunk-CV47VCMQ.js.map → chunk-NPVA65KS.js.map} +0 -0
  247. /package/dist/{chunk-7OCGBJLR.js.map → chunk-OIVFHJOA.js.map} +0 -0
  248. /package/dist/{chunk-NN5RYWXA.js.map → chunk-PH65MFQM.js.map} +0 -0
  249. /package/dist/{chunk-TZNNJLGT.js.map → chunk-PMB6TYV4.js.map} +0 -0
  250. /package/dist/{chunk-6YVJVUR4.js.map → chunk-QF2DROQR.js.map} +0 -0
  251. /package/dist/{chunk-XXFSOVL3.js.map → chunk-QFDM23CO.js.map} +0 -0
  252. /package/dist/{chunk-RMLADZRY.js.map → chunk-R7DGN73N.js.map} +0 -0
  253. /package/dist/{chunk-5PNZBH6V.js.map → chunk-V5IYLWRA.js.map} +0 -0
  254. /package/dist/{chunk-KQFIGI37.js.map → chunk-VA6CWUAE.js.map} +0 -0
  255. /package/dist/{chunk-YETJNRQM.js.map → chunk-WEBMMJKL.js.map} +0 -0
  256. /package/dist/{chunk-UDCI3QTS.js.map → chunk-ZM2AYHMO.js.map} +0 -0
  257. /package/dist/{git-BXUD6CL5.js.map → claude-ACL7G4CF.js.map} +0 -0
  258. /package/dist/{ignite-IO4LXVXJ.js.map → color-AC6F2QE7.js.map} +0 -0
  259. /package/dist/{commit-DC2Q5CDY.js.map → commit-RILBXFWO.js.map} +0 -0
  260. /package/dist/{compile-4NCQECKE.js.map → compile-QEL5724K.js.map} +0 -0
  261. /package/dist/{installation-detector-HF6QN7KP.js.map → darwin-5K3I4FTH.js.map} +0 -0
  262. /package/dist/{feedback-BMAZGKRW.js.map → feedback-RFWGB4I5.js.map} +0 -0
  263. /package/dist/{mcp/darwin-3JFFE3W2.js.map → git-I3PO6FY7.js.map} +0 -0
  264. /package/dist/{neon-helpers-HWIYRKOW.js.map → ignite-X2NNTNUN.js.map} +0 -0
  265. /package/dist/{init-CI43GJHV.js.map → init-LWU2M53W.js.map} +0 -0
  266. /package/dist/{install-deps-SRTM5U7D.js.map → install-deps-HXP2TM7G.js.map} +0 -0
  267. /package/dist/{prompt-7LZB4PAT.js.map → installation-detector-PYAZ2O6U.js.map} +0 -0
  268. /package/dist/{lint-BSWRMGPZ.js.map → lint-FDZC77GL.js.map} +0 -0
  269. /package/dist/{linux-RYLOP2LY.js.map → linux-WUGRYCJY.js.map} +0 -0
  270. /package/dist/{remote-MZTFHHTU.js.map → mcp/darwin-U25WIGH6.js.map} +0 -0
  271. /package/dist/mcp/{linux-JBVS4R3A.js.map → linux-5BXVBGSY.js.map} +0 -0
  272. /package/dist/mcp/{tmux-RYBLEHUZ.js.map → tmux-CU26ZTNM.js.map} +0 -0
  273. /package/dist/mcp/{wsl-4QZIQLLE.js.map → wsl-KI25UDOF.js.map} +0 -0
  274. /package/dist/{update-notifier-EYLAXZAA.js.map → neon-helpers-LCZAN4U4.js.map} +0 -0
  275. /package/dist/{projects-IUSUXD5D.js.map → projects-L5AHUBGA.js.map} +0 -0
  276. /package/dist/{rebase-S6OHAOOF.js.map → rebase-JA3RW2XO.js.map} +0 -0
  277. /package/dist/{recap-GGVCG5VH.js.map → recap-5TO42HN2.js.map} +0 -0
  278. /package/dist/{shell-W4SBQPTE.js.map → shell-GAB2FCXH.js.map} +0 -0
  279. /package/dist/{test-6JH4FE2X.js.map → test-6LFB5WOO.js.map} +0 -0
  280. /package/dist/{test-git-2KFFAQ6B.js.map → test-git-PYJOYSED.js.map} +0 -0
  281. /package/dist/{test-jira-FKDKG6CD.js.map → test-jira-SM7IU5HW.js.map} +0 -0
  282. /package/dist/{test-prefix-GP2DAX37.js.map → test-prefix-HIRZBXTM.js.map} +0 -0
  283. /package/dist/{test-tabs-YDWMWTVA.js.map → test-tabs-NGPTFD5T.js.map} +0 -0
  284. /package/dist/{test-webserver-QI3QQFZ3.js.map → test-webserver-43PVP2JL.js.map} +0 -0
  285. /package/dist/{tmux-7ZTA3BDI.js.map → tmux-6LRFH3DM.js.map} +0 -0
  286. /package/dist/{update-XLW7R7FL.js.map → update-AD3GE5C4.js.map} +0 -0
  287. /package/dist/{vscode-TOGE5N67.js.map → vscode-HXIXRZ3A.js.map} +0 -0
  288. /package/dist/{vscode-announcement-NIX7O2MG.js.map → vscode-announcement-AL3EHORH.js.map} +0 -0
  289. /package/dist/{wsl-Y4GUTOQ7.js.map → wsl-4VMVT2PO.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  logger
4
- } from "./chunk-H2SSF24U.js";
4
+ } from "./chunk-VRPPI6GU.js";
5
5
 
6
6
  // src/lib/SettingsManager.ts
7
7
  import { readFile } from "fs/promises";
@@ -9,6 +9,11 @@ import path from "path";
9
9
  import os from "os";
10
10
  import { z } from "zod";
11
11
  import deepmerge from "deepmerge";
12
+ var mergeModeValues = ["local", "pr", "draft-pr", "github-pr", "github-draft-pr", "bitbucket-pr"];
13
+ var mergeModeTransform = (val) => {
14
+ const map = { "github-pr": "pr", "github-draft-pr": "draft-pr", "bitbucket-pr": "pr" };
15
+ return map[val] ?? val;
16
+ };
12
17
  var BaseAgentSettingsSchema = z.object({
13
18
  model: z.enum(["sonnet", "opus", "haiku"]).optional().describe("Claude model shorthand: sonnet, opus, or haiku"),
14
19
  swarmModel: z.enum(["sonnet", "opus", "haiku"]).optional().describe("Model to use for this agent in swarm mode. Overrides the base model when running inside swarm workers."),
@@ -20,9 +25,7 @@ var BaseAgentSettingsSchema = z.object({
20
25
  review: z.boolean().optional().describe("Whether artifacts from this agent should be reviewed before posting (defaults to false)"),
21
26
  swarmReview: z.boolean().optional().describe("Whether artifacts from this agent should be reviewed in swarm mode. Defaults to false if not set (review is off in swarm mode for speed and cost unless explicitly enabled).")
22
27
  });
23
- var AgentSettingsSchema = BaseAgentSettingsSchema.extend({
24
- subAgentTimeout: z.number().min(1, "Sub-agent timeout must be at least 1 minute").max(120, "Sub-agent timeout cannot exceed 120 minutes").default(10).describe("Timeout in minutes for sub-agent claude -p invocations in swarm mode. Applies to each phase agent (evaluator, analyzer, planner, implementer) when invoked via the Bash tool. Default: 10 minutes. Only meaningful under the iloom-swarm-worker agent entry.")
25
- });
28
+ var AgentSettingsSchema = BaseAgentSettingsSchema;
26
29
  var SpinAgentSettingsSchema = z.object({
27
30
  model: z.enum(["sonnet", "opus", "haiku"]).default("opus").describe("Claude model shorthand for spin orchestrator"),
28
31
  swarmModel: z.enum(["sonnet", "opus", "haiku"]).optional().describe("Model for the spin orchestrator when running in swarm mode. Overrides spin.model for swarm workflows."),
@@ -31,7 +34,8 @@ var SpinAgentSettingsSchema = z.object({
31
34
  var PlanCommandSettingsSchema = z.object({
32
35
  model: z.enum(["sonnet", "opus", "haiku"]).default("opus").describe("Claude model shorthand for plan command"),
33
36
  planner: z.enum(["claude", "gemini", "codex"]).default("claude").describe("AI provider for creating the plan"),
34
- reviewer: z.enum(["claude", "gemini", "codex", "none"]).default("none").describe("AI provider for reviewing the plan (none to skip review)")
37
+ reviewer: z.enum(["claude", "gemini", "codex", "none"]).default("none").describe("AI provider for reviewing the plan (none to skip review)"),
38
+ waveVerification: z.boolean().default(true).describe("When enabled, the planner generates verification child issues between dependency waves to catch integration issues early.")
35
39
  });
36
40
  var SummarySettingsSchema = z.object({
37
41
  model: z.enum(["sonnet", "opus", "haiku"]).default("sonnet").describe("Claude model shorthand for session summary generation")
@@ -66,7 +70,12 @@ var WorkflowsSettingsSchemaNoDefaults = z.object({
66
70
  }).optional();
67
71
  var CapabilitiesSettingsSchema = z.object({
68
72
  web: z.object({
69
- basePort: z.number().min(1, "Base port must be >= 1").max(65535, "Base port must be <= 65535").optional().describe("Base port for web workspace port calculations (default: 3000)")
73
+ basePort: z.number().min(1, "Base port must be >= 1").max(65535, "Base port must be <= 65535").optional().describe("Base port for web workspace port calculations (default: 3000)"),
74
+ devServer: z.enum(["process", "docker"]).default("process").describe('Dev server mode: "process" runs natively, "docker" runs inside a Docker container with port mapping'),
75
+ dockerFile: z.string().default("./Dockerfile").describe('Path to Dockerfile relative to worktree root (only used when devServer is "docker")'),
76
+ containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
77
+ dockerBuildArgs: z.record(z.string()).optional().describe('Build arguments to pass to docker build (e.g., {"NODE_ENV": "development"})'),
78
+ dockerRunArgs: z.array(z.string()).optional().describe('Additional arguments for docker run (e.g., ["-v", "./src:/app/src"] for volume mounts)')
70
79
  }).optional().describe('Web dev server settings. To declare a project as a web project, add "web" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json.'),
71
80
  database: z.object({
72
81
  databaseUrlEnvVarName: z.string().min(1, "Database URL variable name cannot be empty").regex(/^[A-Z_][A-Z0-9_]*$/, "Must be valid env var name (uppercase, underscores)").optional().default("DATABASE_URL").describe("Name of environment variable for database connection URL")
@@ -74,12 +83,56 @@ var CapabilitiesSettingsSchema = z.object({
74
83
  }).optional();
75
84
  var CapabilitiesSettingsSchemaNoDefaults = z.object({
76
85
  web: z.object({
77
- basePort: z.number().min(1, "Base port must be >= 1").max(65535, "Base port must be <= 65535").optional().describe("Base port for web workspace port calculations (default: 3000)")
86
+ basePort: z.number().min(1, "Base port must be >= 1").max(65535, "Base port must be <= 65535").optional().describe("Base port for web workspace port calculations (default: 3000)"),
87
+ devServer: z.enum(["process", "docker"]).optional().describe('Dev server mode: "process" runs natively, "docker" runs inside a Docker container with port mapping'),
88
+ dockerFile: z.string().optional().describe('Path to Dockerfile relative to worktree root (only used when devServer is "docker")'),
89
+ containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
90
+ dockerBuildArgs: z.record(z.string()).optional().describe('Build arguments to pass to docker build (e.g., {"NODE_ENV": "development"})'),
91
+ dockerRunArgs: z.array(z.string()).optional().describe('Additional arguments for docker run (e.g., ["-v", "./src:/app/src"] for volume mounts)')
78
92
  }).optional().describe('Web dev server settings. To declare a project as a web project, add "web" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json.'),
79
93
  database: z.object({
80
94
  databaseUrlEnvVarName: z.string().min(1, "Database URL variable name cannot be empty").regex(/^[A-Z_][A-Z0-9_]*$/, "Must be valid env var name (uppercase, underscores)").optional().describe("Name of environment variable for database connection URL")
81
95
  }).optional()
82
96
  }).optional();
97
+ var DevServerSettingsSchema = z.object({
98
+ mode: z.enum(["docker"]).default("docker").describe('Dev server mode. Currently only "docker" is supported.'),
99
+ docker: z.object({
100
+ dockerFile: z.string().default("./Dockerfile").refine(
101
+ (val) => {
102
+ if (path.isAbsolute(val)) return false;
103
+ const normalized = path.normalize(val);
104
+ if (normalized.startsWith("..")) return false;
105
+ return true;
106
+ },
107
+ {
108
+ message: 'dockerFile must be a relative path that does not traverse outside the project root (no leading "/" and no "../" escaping)'
109
+ }
110
+ ).describe("Path to Dockerfile relative to worktree root"),
111
+ containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
112
+ buildArgs: z.record(z.string(), z.string()).optional().describe("Build arguments to pass to docker build"),
113
+ runArgs: z.array(z.string()).optional().describe("Additional arguments for docker run")
114
+ }).optional()
115
+ });
116
+ var DevServerSettingsSchemaNoDefaults = z.object({
117
+ mode: z.enum(["docker"]).optional().describe('Dev server mode. Currently only "docker" is supported.'),
118
+ docker: z.object({
119
+ dockerFile: z.string().optional().refine(
120
+ (val) => {
121
+ if (val === void 0) return true;
122
+ if (path.isAbsolute(val)) return false;
123
+ const normalized = path.normalize(val);
124
+ if (normalized.startsWith("..")) return false;
125
+ return true;
126
+ },
127
+ {
128
+ message: 'dockerFile must be a relative path that does not traverse outside the project root (no leading "/" and no "../" escaping)'
129
+ }
130
+ ).describe("Path to Dockerfile relative to worktree root"),
131
+ containerPort: z.number().min(1, "Container port must be >= 1").max(65535, "Container port must be <= 65535").optional().describe("Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)"),
132
+ buildArgs: z.record(z.string(), z.string()).optional().describe("Build arguments to pass to docker build"),
133
+ runArgs: z.array(z.string()).optional().describe("Additional arguments for docker run")
134
+ }).optional()
135
+ });
83
136
  var NeonSettingsSchema = z.object({
84
137
  projectId: z.string().min(1).regex(/^[a-zA-Z0-9-]+$/, "Neon project ID must contain only letters, numbers, and hyphens").describe('Neon project ID found in your project URL (e.g., "fantastic-fox-3566354")'),
85
138
  parentBranch: z.string().min(1).describe("Branch from which new database branches are created")
@@ -131,6 +184,7 @@ var IloomSettingsSchema = z.object({
131
184
  "Session summary generation configuration. Model defaults to sonnet when not configured."
132
185
  ),
133
186
  capabilities: CapabilitiesSettingsSchema.describe("Project capability configurations"),
187
+ devServer: DevServerSettingsSchema.optional().describe("Docker-based dev server configuration"),
134
188
  databaseProviders: DatabaseProvidersSettingsSchema.describe("Database provider configurations"),
135
189
  issueManagement: z.object({
136
190
  // SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts
@@ -155,17 +209,28 @@ var IloomSettingsSchema = z.object({
155
209
  doneStatuses: z.array(z.string()).optional().default(["Done"]).describe('Status names to exclude from issue lists (e.g., ["Done", "Closed", "Verify"])')
156
210
  }).optional()
157
211
  }).optional().describe("Issue management configuration"),
212
+ versionControl: z.object({
213
+ provider: z.enum(["github", "bitbucket"]).optional().default("github").describe("Version control provider (github, bitbucket)"),
214
+ bitbucket: z.object({
215
+ username: z.string().min(1, "BitBucket username cannot be empty").describe("BitBucket username"),
216
+ apiToken: z.string().optional().describe("BitBucket API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://bitbucket.org/account/settings/app-passwords/ (Note: App passwords deprecated Sep 2025, use API tokens)"),
217
+ workspace: z.string().optional().describe("BitBucket workspace (optional, auto-detected from git remote if not provided)"),
218
+ repoSlug: z.string().optional().describe("BitBucket repository slug (optional, auto-detected from git remote if not provided)"),
219
+ reviewers: z.array(z.string().describe("Reviewer username")).optional().describe("List of usernames to add as PR reviewers. Usernames are resolved to Bitbucket account IDs at PR creation time.")
220
+ }).optional()
221
+ }).optional().describe("Version control provider configuration"),
158
222
  mergeBehavior: z.object({
159
223
  // SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts
160
- mode: z.enum(["local", "github-pr", "github-draft-pr"]).default("local"),
224
+ mode: z.enum(mergeModeValues).default("local").transform(mergeModeTransform),
161
225
  remote: z.string().optional(),
162
226
  autoCommitPush: z.boolean().optional().describe(
163
- "Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr."
227
+ "Auto-commit and push after code review in draft PR mode. Defaults to true when mode is draft-pr."
164
228
  ),
229
+ prTitlePrefix: z.boolean().default(false).optional().describe('Prefix PR titles with the issue number (e.g., "QLH-123: Title"). Default: false'),
165
230
  openBrowserOnFinish: z.boolean().default(true).describe(
166
- "Open the PR in the default browser after finishing in github-pr or github-draft-pr mode. Use --no-browser flag to override."
231
+ "Open the PR in the default browser after finishing in pr or draft-pr mode. Use --no-browser flag to override."
167
232
  )
168
- }).optional().describe("Merge behavior configuration: local (merge locally), github-pr (create PR), or github-draft-pr (create draft PR at start, mark ready on finish)"),
233
+ }).optional().describe("Merge behavior configuration: local (merge locally), pr (create PR), or draft-pr (create draft PR at start, mark ready on finish)"),
169
234
  ide: z.object({
170
235
  // SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts
171
236
  type: z.enum(["vscode", "cursor", "webstorm", "sublime", "intellij", "windsurf", "antigravity"]).default("vscode").describe(
@@ -227,12 +292,14 @@ var IloomSettingsSchemaNoDefaults = z.object({
227
292
  plan: z.object({
228
293
  model: z.enum(["sonnet", "opus", "haiku"]).optional(),
229
294
  planner: z.enum(["claude", "gemini", "codex"]).optional(),
230
- reviewer: z.enum(["claude", "gemini", "codex", "none"]).optional()
295
+ reviewer: z.enum(["claude", "gemini", "codex", "none"]).optional(),
296
+ waveVerification: z.boolean().optional()
231
297
  }).optional().describe("Plan command configuration"),
232
298
  summary: z.object({
233
299
  model: z.enum(["sonnet", "opus", "haiku"]).optional()
234
300
  }).optional().describe("Session summary generation configuration"),
235
301
  capabilities: CapabilitiesSettingsSchemaNoDefaults.describe("Project capability configurations"),
302
+ devServer: DevServerSettingsSchemaNoDefaults.optional().describe("Docker-based dev server configuration"),
236
303
  databaseProviders: DatabaseProvidersSettingsSchema.describe("Database provider configurations"),
237
304
  issueManagement: z.object({
238
305
  provider: z.enum(["github", "linear", "jira"]).optional().describe("Issue tracker provider (github, linear, jira)"),
@@ -256,16 +323,27 @@ var IloomSettingsSchemaNoDefaults = z.object({
256
323
  doneStatuses: z.array(z.string()).optional().default(["Done"]).describe('Status names to exclude from issue lists (e.g., ["Done", "Closed", "Verify"])')
257
324
  }).optional()
258
325
  }).optional().describe("Issue management configuration"),
326
+ versionControl: z.object({
327
+ provider: z.enum(["github", "bitbucket"]).optional().describe("Version control provider (github, bitbucket)"),
328
+ bitbucket: z.object({
329
+ username: z.string().min(1, "BitBucket username cannot be empty").describe("BitBucket username"),
330
+ apiToken: z.string().optional().describe("BitBucket API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://bitbucket.org/account/settings/app-passwords/ (Note: App passwords deprecated Sep 2025, use API tokens)"),
331
+ workspace: z.string().optional().describe("BitBucket workspace (optional, auto-detected from git remote if not provided)"),
332
+ repoSlug: z.string().optional().describe("BitBucket repository slug (optional, auto-detected from git remote if not provided)"),
333
+ reviewers: z.array(z.string().describe("Reviewer username")).optional().describe("List of usernames to add as PR reviewers. Usernames are resolved to Bitbucket account IDs at PR creation time.")
334
+ }).optional()
335
+ }).optional().describe("Version control provider configuration"),
259
336
  mergeBehavior: z.object({
260
- mode: z.enum(["local", "github-pr", "github-draft-pr"]).optional(),
337
+ mode: z.enum(mergeModeValues).transform(mergeModeTransform).optional(),
261
338
  remote: z.string().optional(),
262
339
  autoCommitPush: z.boolean().optional().describe(
263
- "Auto-commit and push after code review in draft PR mode. Defaults to true when mode is github-draft-pr."
340
+ "Auto-commit and push after code review in draft PR mode. Defaults to true when mode is draft-pr."
264
341
  ),
342
+ prTitlePrefix: z.boolean().optional(),
265
343
  openBrowserOnFinish: z.boolean().optional().describe(
266
- "Open the PR in the default browser after finishing in github-pr or github-draft-pr mode. Use --no-browser flag to override."
344
+ "Open the PR in the default browser after finishing in pr or draft-pr mode. Use --no-browser flag to override."
267
345
  )
268
- }).optional().describe("Merge behavior configuration: local (merge locally), github-pr (create PR), or github-draft-pr (create draft PR at start, mark ready on finish)"),
346
+ }).optional().describe("Merge behavior configuration: local (merge locally), pr (create PR), or draft-pr (create draft PR at start, mark ready on finish)"),
269
347
  ide: z.object({
270
348
  type: z.enum(["vscode", "cursor", "webstorm", "sublime", "intellij", "windsurf", "antigravity"]).optional().describe(
271
349
  "IDE to launch when starting a loom. Options: vscode (Visual Studio Code), cursor (Cursor AI editor), webstorm (JetBrains WebStorm), sublime (Sublime Text), intellij (JetBrains IntelliJ IDEA), windsurf (Windsurf editor), antigravity (Antigravity IDE)."
@@ -290,7 +368,7 @@ function redactSensitiveFields(obj) {
290
368
  if (obj === null || obj === void 0) return obj;
291
369
  if (typeof obj !== "object") return obj;
292
370
  if (Array.isArray(obj)) return obj.map(redactSensitiveFields);
293
- const sensitiveKeys = ["apitoken", "token", "secret", "password"];
371
+ const sensitiveKeys = ["apitoken", "token", "secret", "password", "credential"];
294
372
  const result = {};
295
373
  for (const [key, value] of Object.entries(obj)) {
296
374
  const lowerKey = key.toLowerCase();
@@ -555,6 +633,17 @@ ${errorMessages.join("\n")}`
555
633
  var _a;
556
634
  return ((_a = settings == null ? void 0 : settings.plan) == null ? void 0 : _a.reviewer) ?? "none";
557
635
  }
636
+ /**
637
+ * Get the plan command waveVerification setting with default applied
638
+ * Default is true (verification tasks are generated)
639
+ *
640
+ * @param settings - Pre-loaded settings object
641
+ * @returns Whether wave verification is enabled
642
+ */
643
+ getPlanWaveVerification(settings) {
644
+ var _a;
645
+ return ((_a = settings == null ? void 0 : settings.plan) == null ? void 0 : _a.waveVerification) !== false;
646
+ }
558
647
  /**
559
648
  * Get the session summary model with default applied
560
649
  * Default is defined in SummarySettingsSchema
@@ -569,6 +658,7 @@ ${errorMessages.join("\n")}`
569
658
  };
570
659
 
571
660
  export {
661
+ mergeModeValues,
572
662
  BaseAgentSettingsSchema,
573
663
  AgentSettingsSchema,
574
664
  SpinAgentSettingsSchema,
@@ -580,10 +670,13 @@ export {
580
670
  WorkflowsSettingsSchemaNoDefaults,
581
671
  CapabilitiesSettingsSchema,
582
672
  CapabilitiesSettingsSchemaNoDefaults,
673
+ DevServerSettingsSchema,
674
+ DevServerSettingsSchemaNoDefaults,
583
675
  NeonSettingsSchema,
584
676
  DatabaseProvidersSettingsSchema,
585
677
  IloomSettingsSchema,
586
678
  IloomSettingsSchemaNoDefaults,
679
+ redactSensitiveFields,
587
680
  SettingsManager
588
681
  };
589
- //# sourceMappingURL=chunk-ET6A2JR4.js.map
682
+ //# sourceMappingURL=chunk-653XBU3L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/SettingsManager.ts"],"sourcesContent":["import { readFile } from 'fs/promises'\nimport path from 'path'\nimport os from 'os'\nimport { z } from 'zod'\nimport deepmerge from 'deepmerge'\nimport { logger } from '../utils/logger.js'\n\n// Merge mode: canonical values + legacy aliases accepted at parse time\nexport const mergeModeValues = ['local', 'pr', 'draft-pr', 'github-pr', 'github-draft-pr', 'bitbucket-pr'] as const\nexport type MergeMode = 'local' | 'pr' | 'draft-pr'\nconst mergeModeTransform = (val: string): MergeMode => {\n\tconst map: Record<string, MergeMode> = { 'github-pr': 'pr', 'github-draft-pr': 'draft-pr', 'bitbucket-pr': 'pr' }\n\treturn (map[val] ?? val) as MergeMode\n}\n\n/**\n * Zod schema for base agent settings (without nested agents)\n */\nexport const BaseAgentSettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.optional()\n\t\t.describe('Claude model shorthand: sonnet, opus, or haiku'),\n\tswarmModel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.optional()\n\t\t.describe('Model to use for this agent in swarm mode. Overrides the base model when running inside swarm workers.'),\n\tenabled: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Whether this agent is enabled. Defaults to true.'),\n\tproviders: z\n\t\t.record(\n\t\t\tz.enum(['claude', 'gemini', 'codex']),\n\t\t\tz.string()\n\t\t)\n\t\t.optional()\n\t\t.describe('Map of review providers to model names. Keys: claude, gemini, codex. Values: model name strings (e.g., \"sonnet\", \"gemini-3-pro-preview\", \"gpt-5.2-codex\")'),\n\treview: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Whether artifacts from this agent should be reviewed before posting (defaults to false)'),\n\tswarmReview: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Whether artifacts from this agent should be reviewed in swarm mode. Defaults to false if not set (review is off in swarm mode for speed and cost unless explicitly enabled).'),\n})\n\n/**\n * Zod schema for agent settings.\n */\nexport const AgentSettingsSchema = BaseAgentSettingsSchema\n\n/**\n * Zod schema for spin agent settings with default model\n * Used for the spin orchestrator configuration\n */\nexport const SpinAgentSettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.default('opus')\n\t\t.describe('Claude model shorthand for spin orchestrator'),\n\tswarmModel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.optional()\n\t\t.describe('Model for the spin orchestrator when running in swarm mode. Overrides spin.model for swarm workflows.'),\n\tpostSwarmReview: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Run a full code review after swarm completion, auto-fixing issues with confidence 80+. Defaults to true.'),\n})\n\n/**\n * Zod schema for plan command settings with default model\n * Used for the plan command configuration\n */\nexport const PlanCommandSettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.default('opus')\n\t\t.describe('Claude model shorthand for plan command'),\n\tplanner: z\n\t\t.enum(['claude', 'gemini', 'codex'])\n\t\t.default('claude')\n\t\t.describe('AI provider for creating the plan'),\n\treviewer: z\n\t\t.enum(['claude', 'gemini', 'codex', 'none'])\n\t\t.default('none')\n\t\t.describe('AI provider for reviewing the plan (none to skip review)'),\n\twaveVerification: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('When enabled, the planner generates verification child issues between dependency waves to catch integration issues early.'),\n})\n\n/**\n * Zod schema for summary settings with default model\n * Used for session summary generation configuration\n */\nexport const SummarySettingsSchema = z.object({\n\tmodel: z\n\t\t.enum(['sonnet', 'opus', 'haiku'])\n\t\t.default('sonnet')\n\t\t.describe('Claude model shorthand for session summary generation'),\n})\n\n/**\n * Zod schema for workflow permission configuration\n */\nexport const WorkflowPermissionSchema = z.object({\n\tpermissionMode: z\n\t\t.enum(['plan', 'acceptEdits', 'bypassPermissions', 'default'])\n\t\t.optional()\n\t\t.describe('Permission mode for Claude CLI in this workflow type'),\n\tnoVerify: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Skip pre-commit hooks (--no-verify) when committing during commit and finish workflows'),\n\tstartIde: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Launch IDE (code) when starting this workflow type'),\n\tstartDevServer: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Launch development server when starting this workflow type'),\n\tstartAiAgent: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Launch Claude Code agent when starting this workflow type'),\n\tstartTerminal: z\n\t\t.boolean()\n\t\t.default(false)\n\t\t.describe('Launch terminal window without dev server when starting this workflow type'),\n\tgenerateSummary: z\n\t\t.boolean()\n\t\t.default(true)\n\t\t.describe('Generate and post Claude session summary when finishing this workflow type'),\n})\n\n/**\n * Non-defaulting variant for pre-merge validation\n * This prevents Zod from polluting partial settings with default values before merge\n */\nexport const WorkflowPermissionSchemaNoDefaults = z.object({\n\tpermissionMode: z\n\t\t.enum(['plan', 'acceptEdits', 'bypassPermissions', 'default'])\n\t\t.optional()\n\t\t.describe('Permission mode for Claude CLI in this workflow type'),\n\tnoVerify: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Skip pre-commit hooks (--no-verify) when committing during commit and finish workflows'),\n\tstartIde: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch IDE (code) when starting this workflow type'),\n\tstartDevServer: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch development server when starting this workflow type'),\n\tstartAiAgent: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch Claude Code agent when starting this workflow type'),\n\tstartTerminal: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Launch terminal window without dev server when starting this workflow type'),\n\tgenerateSummary: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe('Generate and post Claude session summary when finishing this workflow type'),\n})\n\n/**\n * Zod schema for workflows settings\n */\nexport const WorkflowsSettingsSchema = z\n\t.object({\n\t\tissue: WorkflowPermissionSchema.optional(),\n\t\tpr: WorkflowPermissionSchema.optional(),\n\t\tregular: WorkflowPermissionSchema.optional(),\n\t})\n\t.optional()\n\n/**\n * Non-defaulting variant for pre-merge validation\n */\nexport const WorkflowsSettingsSchemaNoDefaults = z\n\t.object({\n\t\tissue: WorkflowPermissionSchemaNoDefaults.optional(),\n\t\tpr: WorkflowPermissionSchemaNoDefaults.optional(),\n\t\tregular: WorkflowPermissionSchemaNoDefaults.optional(),\n\t})\n\t.optional()\n\n/**\n * Zod schema for capabilities settings\n */\nexport const CapabilitiesSettingsSchema = z\n\t.object({\n\t\tweb: z\n\t\t\t.object({\n\t\t\t\tbasePort: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.min(1, 'Base port must be >= 1')\n\t\t\t\t\t.max(65535, 'Base port must be <= 65535')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Base port for web workspace port calculations (default: 3000)'),\n\t\t\t\tdevServer: z\n\t\t\t\t\t.enum(['process', 'docker'])\n\t\t\t\t\t.default('process')\n\t\t\t\t\t.describe('Dev server mode: \"process\" runs natively, \"docker\" runs inside a Docker container with port mapping'),\n\t\t\t\tdockerFile: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.default('./Dockerfile')\n\t\t\t\t\t.describe('Path to Dockerfile relative to worktree root (only used when devServer is \"docker\")'),\n\t\t\t\tcontainerPort: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.min(1, 'Container port must be >= 1')\n\t\t\t\t\t.max(65535, 'Container port must be <= 65535')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)'),\n\t\t\t\tdockerBuildArgs: z\n\t\t\t\t\t.record(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Build arguments to pass to docker build (e.g., {\"NODE_ENV\": \"development\"})'),\n\t\t\t\tdockerRunArgs: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Additional arguments for docker run (e.g., [\"-v\", \"./src:/app/src\"] for volume mounts)'),\n\t\t\t})\n\t\t\t.optional()\n\t\t\t.describe('Web dev server settings. To declare a project as a web project, add \"web\" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json.'),\n\t\tdatabase: z\n\t\t\t.object({\n\t\t\t\tdatabaseUrlEnvVarName: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1, 'Database URL variable name cannot be empty')\n\t\t\t\t\t.regex(/^[A-Z_][A-Z0-9_]*$/, 'Must be valid env var name (uppercase, underscores)')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.default('DATABASE_URL')\n\t\t\t\t\t.describe('Name of environment variable for database connection URL'),\n\t\t\t})\n\t\t\t.optional(),\n\t})\n\t.optional()\n\n/**\n * Non-defaulting variant for pre-merge validation\n */\nexport const CapabilitiesSettingsSchemaNoDefaults = z\n\t.object({\n\t\tweb: z\n\t\t\t.object({\n\t\t\t\tbasePort: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.min(1, 'Base port must be >= 1')\n\t\t\t\t\t.max(65535, 'Base port must be <= 65535')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Base port for web workspace port calculations (default: 3000)'),\n\t\t\t\tdevServer: z\n\t\t\t\t\t.enum(['process', 'docker'])\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Dev server mode: \"process\" runs natively, \"docker\" runs inside a Docker container with port mapping'),\n\t\t\t\tdockerFile: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Path to Dockerfile relative to worktree root (only used when devServer is \"docker\")'),\n\t\t\t\tcontainerPort: z\n\t\t\t\t\t.number()\n\t\t\t\t\t.min(1, 'Container port must be >= 1')\n\t\t\t\t\t.max(65535, 'Container port must be <= 65535')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)'),\n\t\t\t\tdockerBuildArgs: z\n\t\t\t\t\t.record(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Build arguments to pass to docker build (e.g., {\"NODE_ENV\": \"development\"})'),\n\t\t\t\tdockerRunArgs: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Additional arguments for docker run (e.g., [\"-v\", \"./src:/app/src\"] for volume mounts)'),\n\t\t\t})\n\t\t\t.optional()\n\t\t\t.describe('Web dev server settings. To declare a project as a web project, add \"web\" to the capabilities array in .iloom/package.iloom.json or .iloom/package.iloom.local.json.'),\n\t\tdatabase: z\n\t\t\t.object({\n\t\t\t\tdatabaseUrlEnvVarName: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.min(1, 'Database URL variable name cannot be empty')\n\t\t\t\t\t.regex(/^[A-Z_][A-Z0-9_]*$/, 'Must be valid env var name (uppercase, underscores)')\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('Name of environment variable for database connection URL'),\n\t\t\t})\n\t\t\t.optional(),\n\t})\n\t.optional()\n\n/**\n * Zod schema for Docker dev server settings\n */\nexport const DevServerSettingsSchema = z.object({\n\tmode: z\n\t\t.enum(['docker'])\n\t\t.default('docker')\n\t\t.describe('Dev server mode. Currently only \"docker\" is supported.'),\n\tdocker: z\n\t\t.object({\n\t\t\tdockerFile: z\n\t\t\t\t.string()\n\t\t\t\t.default('./Dockerfile')\n\t\t\t\t.refine(\n\t\t\t\t\t(val) => {\n\t\t\t\t\t\t// Must be a relative path (no leading slash)\n\t\t\t\t\t\tif (path.isAbsolute(val)) return false\n\t\t\t\t\t\t// Must not traverse outside the project root\n\t\t\t\t\t\tconst normalized = path.normalize(val)\n\t\t\t\t\t\tif (normalized.startsWith('..')) return false\n\t\t\t\t\t\treturn true\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t'dockerFile must be a relative path that does not traverse outside the project root (no leading \"/\" and no \"../\" escaping)',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\t.describe('Path to Dockerfile relative to worktree root'),\n\t\t\tcontainerPort: z\n\t\t\t\t.number()\n\t\t\t\t.min(1, 'Container port must be >= 1')\n\t\t\t\t.max(65535, 'Container port must be <= 65535')\n\t\t\t\t.optional()\n\t\t\t\t.describe('Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)'),\n\t\t\tbuildArgs: z\n\t\t\t\t.record(z.string(), z.string())\n\t\t\t\t.optional()\n\t\t\t\t.describe('Build arguments to pass to docker build'),\n\t\t\trunArgs: z\n\t\t\t\t.array(z.string())\n\t\t\t\t.optional()\n\t\t\t\t.describe('Additional arguments for docker run'),\n\t\t})\n\t\t.optional(),\n})\n\n/**\n * Non-defaulting variant of DevServerSettingsSchema for pre-merge validation\n * This prevents Zod from polluting partial settings with default values before merge\n */\nexport const DevServerSettingsSchemaNoDefaults = z.object({\n\tmode: z\n\t\t.enum(['docker'])\n\t\t.optional()\n\t\t.describe('Dev server mode. Currently only \"docker\" is supported.'),\n\tdocker: z\n\t\t.object({\n\t\t\tdockerFile: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.refine(\n\t\t\t\t\t(val) => {\n\t\t\t\t\t\tif (val === undefined) return true\n\t\t\t\t\t\tif (path.isAbsolute(val)) return false\n\t\t\t\t\t\tconst normalized = path.normalize(val)\n\t\t\t\t\t\tif (normalized.startsWith('..')) return false\n\t\t\t\t\t\treturn true\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t'dockerFile must be a relative path that does not traverse outside the project root (no leading \"/\" and no \"../\" escaping)',\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\t.describe('Path to Dockerfile relative to worktree root'),\n\t\t\tcontainerPort: z\n\t\t\t\t.number()\n\t\t\t\t.min(1, 'Container port must be >= 1')\n\t\t\t\t.max(65535, 'Container port must be <= 65535')\n\t\t\t\t.optional()\n\t\t\t\t.describe('Port the app runs on inside the Docker container (auto-detected from EXPOSE directive if not set)'),\n\t\t\tbuildArgs: z\n\t\t\t\t.record(z.string(), z.string())\n\t\t\t\t.optional()\n\t\t\t\t.describe('Build arguments to pass to docker build'),\n\t\t\trunArgs: z\n\t\t\t\t.array(z.string())\n\t\t\t\t.optional()\n\t\t\t\t.describe('Additional arguments for docker run'),\n\t\t})\n\t\t.optional(),\n})\n\n/**\n * Zod schema for Neon database provider settings\n */\nexport const NeonSettingsSchema = z.object({\n\tprojectId: z\n\t\t.string()\n\t\t.min(1)\n\t\t.regex(/^[a-zA-Z0-9-]+$/, 'Neon project ID must contain only letters, numbers, and hyphens')\n\t\t.describe('Neon project ID found in your project URL (e.g., \"fantastic-fox-3566354\")'),\n\tparentBranch: z\n\t\t.string()\n\t\t.min(1)\n\t\t.describe('Branch from which new database branches are created'),\n})\n\n/**\n * Zod schema for database provider settings\n */\nexport const DatabaseProvidersSettingsSchema = z\n\t.object({\n\t\tneon: NeonSettingsSchema.optional().describe(\n\t\t\t'Neon database configuration. Requires Neon CLI installed and authenticated for database branching.',\n\t\t),\n\t})\n\t.optional()\n\n/**\n * Zod schema for iloom settings\n */\nexport const IloomSettingsSchema = z.object({\n\tmainBranch: z\n\t\t.string()\n\t\t.min(1, \"Settings 'mainBranch' cannot be empty\")\n\t\t.optional()\n\t\t.describe('Name of the main/primary branch for the repository'),\n\tsourceEnvOnStart: z\n\t\t.boolean()\n\t\t.default(false)\n\t\t.describe(\n\t\t\t'Source all dotenv-flow files (.env, .env.local, .env.development, .env.development.local) when launching terminal processes (Claude, dev server, terminal). ' +\n\t\t\t\t'Files are sourced in precedence order so later files override earlier ones. ' +\n\t\t\t\t'NOTE TO AI AGENTS: Before making changes to settings files, YOU MUST OFFER to check .env file compatibility. ' +\n\t\t\t\t'WARNING: Unquoted values in .env files may break sourcing in bash/zsh shells. ' +\n\t\t\t\t'Before enabling, verify ALL your .env.* files do not contain unquoted special characters ' +\n\t\t\t\t'(e.g., database URLs with ?, &, or other shell metacharacters). ' +\n\t\t\t\t'Shell compatibility issues may cause processes to fail or behave unexpectedly.',\n\t\t),\n\tworktreePrefix: z\n\t\t.string()\n\t\t.optional()\n\t\t.refine(\n\t\t\t(val) => {\n\t\t\t\tif (val === undefined) return true // undefined = use default calculation\n\t\t\t\tif (val === '') return true // empty string = no prefix mode\n\n\t\t\t\t// Allowlist: only alphanumeric, hyphens, underscores, and forward slashes\n\t\t\t\tconst allowedChars = /^[a-zA-Z0-9\\-_/]+$/\n\t\t\t\tif (!allowedChars.test(val)) return false\n\n\t\t\t\t// Reject if only special characters (no alphanumeric content)\n\t\t\t\tif (/^[-_/]+$/.test(val)) return false\n\n\t\t\t\t// Check each segment (split by /) contains at least one alphanumeric character\n\t\t\t\tconst segments = val.split('/')\n\t\t\t\tfor (const segment of segments) {\n\t\t\t\t\tif (segment && /^[-_]+$/.test(segment)) {\n\t\t\t\t\t\t// Segment exists but contains only hyphens/underscores\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true\n\t\t\t},\n\t\t\t{\n\t\t\t\tmessage:\n\t\t\t\t\t\"worktreePrefix contains invalid characters. Only alphanumeric characters, hyphens (-), underscores (_), and forward slashes (/) are allowed. Use forward slashes for nested directories.\",\n\t\t\t},\n\t\t)\n\t\t.describe(\n\t\t\t'Prefix for worktree directories. Empty string disables prefix. Defaults to <repo-name>-looms if not set.',\n\t\t),\n\tprotectedBranches: z\n\t\t.array(z.string().min(1, 'Protected branch name cannot be empty'))\n\t\t.optional()\n\t\t.describe('List of branches that cannot be deleted (defaults to [mainBranch, \"main\", \"master\", \"develop\"])'),\n\tcopyGitIgnoredPatterns: z\n\t\t.array(z.string().min(1, 'Pattern cannot be empty'))\n\t\t.optional()\n\t\t.describe('Glob patterns for gitignored files to copy to looms (e.g., [\"*.db\", \"data/*.sqlite\"]). Great for local dbs and large test data files that are too big to commit to git. Note: .env (dotenv-flow) files, iloom\\'s and claude\\'s local settings are automatically copied and do not need to be specified here.'),\n\tworkflows: WorkflowsSettingsSchema.describe('Per-workflow-type permission configurations'),\n\tagents: z\n\t\t.record(z.string(), AgentSettingsSchema)\n\t\t.optional()\n\t\t.nullable()\n\t\t.describe(\n\t\t\t'Per-agent configuration overrides. Available agents: ' +\n\t\t\t\t'iloom-issue-analyzer (analyzes issues), ' +\n\t\t\t\t'iloom-issue-planner (creates implementation plans), ' +\n\t\t\t\t'iloom-issue-analyze-and-plan (combined analysis and planning), ' +\n\t\t\t\t'iloom-issue-complexity-evaluator (evaluates complexity), ' +\n\t\t\t\t'iloom-issue-enhancer (enhances issue descriptions), ' +\n\t\t\t\t'iloom-issue-implementer (implements code changes), ' +\n\t\t\t\t'iloom-code-reviewer (reviews code changes against requirements), ' +\n\t\t\t\t'iloom-artifact-reviewer (reviews artifacts before posting), ' +\n\t\t\t\t'iloom-swarm-worker (swarm worker agent, dynamically generated). ' +\n\t\t\t\t'Use swarmModel on any agent to override its model in swarm mode.',\n\t\t),\n\tspin: SpinAgentSettingsSchema.optional().describe(\n\t\t'Spin orchestrator configuration. Model defaults to opus when not configured.',\n\t),\n\tplan: PlanCommandSettingsSchema.optional().describe(\n\t\t'Plan command configuration. Model defaults to opus, planner to claude, reviewer to none when not configured.',\n\t),\n\tsummary: SummarySettingsSchema.optional().describe(\n\t\t'Session summary generation configuration. Model defaults to sonnet when not configured.',\n\t),\n\tcapabilities: CapabilitiesSettingsSchema.describe('Project capability configurations'),\n\tdevServer: DevServerSettingsSchema.optional().describe('Docker-based dev server configuration'),\n\tdatabaseProviders: DatabaseProvidersSettingsSchema.describe('Database provider configurations'),\n\tissueManagement: z\n\t\t.object({\n\t\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\t\tprovider: z.enum(['github', 'linear', 'jira']).optional().default('github').describe('Issue tracker provider (github, linear, jira)'),\n\t\t\tgithub: z\n\t\t\t\t.object({\n\t\t\t\t\tremote: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Remote name cannot be empty')\n\t\t\t\t\t\t.describe('Git remote name to use for GitHub operations'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tlinear: z\n\t\t\t\t.object({\n\t\t\t\t\tteamId: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Team ID cannot be empty')\n\t\t\t\t\t\t.describe('Linear team identifier (e.g., \"ENG\", \"PLAT\")'),\n\t\t\t\t\tbranchFormat: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Branch naming template for Linear issues'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Linear API token (lin_api_...). SECURITY: Store in settings.local.json only, never commit to source control.'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tjira: z\n\t\t\t\t.object({\n\t\t\t\t\thost: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Jira host cannot be empty')\n\t\t\t\t\t\t.describe('Jira instance URL (e.g., \"https://yourcompany.atlassian.net\")'),\n\t\t\t\t\tusername: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Jira username/email cannot be empty')\n\t\t\t\t\t\t.describe('Jira username or email address'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Jira API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://id.atlassian.com/manage-profile/security/api-tokens'),\n\t\t\t\t\tprojectKey: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Project key cannot be empty')\n\t\t\t\t\t\t.describe('Jira project key (e.g., \"PROJ\", \"ENG\")'),\n\t\t\t\t\tboardId: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Jira board ID for sprint/workflow operations (optional)'),\n\t\t\t\t\ttransitionMappings: z\n\t\t\t\t\t\t.record(z.string(), z.string())\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Map iloom states to Jira transition names (e.g., {\"In Review\": \"Start Review\"})'),\n\t\t\t\t\tdefaultIssueType: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1)\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.default('Task')\n\t\t\t\t\t\t.describe('Default Jira issue type name for creating issues (e.g., \"Task\", \"Story\", \"Bug\")'),\n\t\t\t\t\tdefaultSubtaskType: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1)\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.default('Subtask')\n\t\t\t\t\t\t.describe('Default Jira issue type name for creating subtasks/child issues (e.g., \"Subtask\", \"Sub-task\")'),\n\t\t\t\t\tdoneStatuses: z\n\t\t\t\t\t\t.array(z.string())\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.default(['Done'])\n\t\t\t\t\t\t.describe('Status names to exclude from issue lists (e.g., [\"Done\", \"Closed\", \"Verify\"])'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Issue management configuration'),\n\tversionControl: z\n\t\t.object({\n\t\t\tprovider: z.enum(['github', 'bitbucket']).optional().default('github').describe('Version control provider (github, bitbucket)'),\n\t\t\tbitbucket: z\n\t\t\t\t.object({\n\t\t\t\t\tusername: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'BitBucket username cannot be empty')\n\t\t\t\t\t\t.describe('BitBucket username'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('BitBucket API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://bitbucket.org/account/settings/app-passwords/ (Note: App passwords deprecated Sep 2025, use API tokens)'),\n\t\t\t\t\tworkspace: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('BitBucket workspace (optional, auto-detected from git remote if not provided)'),\n\t\t\t\t\trepoSlug: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('BitBucket repository slug (optional, auto-detected from git remote if not provided)'),\n\t\t\t\treviewers: z\n\t\t\t\t\t.array(z.string().describe('Reviewer username'))\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('List of usernames to add as PR reviewers. Usernames are resolved to Bitbucket account IDs at PR creation time.'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Version control provider configuration'),\n\tmergeBehavior: z\n\t\t.object({\n\t\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\t\tmode: z.enum(mergeModeValues).default('local').transform(mergeModeTransform),\n\t\t\tremote: z.string().optional(),\n\t\t\tautoCommitPush: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Auto-commit and push after code review in draft PR mode. Defaults to true when mode is draft-pr.'\n\t\t\t\t),\n\t\t\tprTitlePrefix: z.boolean().default(false).optional().describe('Prefix PR titles with the issue number (e.g., \"QLH-123: Title\"). Default: false'),\n\t\t\topenBrowserOnFinish: z\n\t\t\t\t.boolean()\n\t\t\t\t.default(true)\n\t\t\t\t.describe(\n\t\t\t\t\t'Open the PR in the default browser after finishing in pr or draft-pr mode. Use --no-browser flag to override.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Merge behavior configuration: local (merge locally), pr (create PR), or draft-pr (create draft PR at start, mark ready on finish)'),\n\tide: z\n\t\t.object({\n\t\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\t\ttype: z\n\t\t\t\t.enum(['vscode', 'cursor', 'webstorm', 'sublime', 'intellij', 'windsurf', 'antigravity'])\n\t\t\t\t.default('vscode')\n\t\t\t\t.describe(\n\t\t\t\t\t'IDE to launch when starting a loom. Options: vscode (Visual Studio Code), cursor (Cursor AI editor), ' +\n\t\t\t\t\t\t'webstorm (JetBrains WebStorm), sublime (Sublime Text), intellij (JetBrains IntelliJ IDEA), ' +\n\t\t\t\t\t\t'windsurf (Windsurf editor), antigravity (Antigravity IDE).'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe(\n\t\t\t'IDE configuration for workspace launches. Controls which editor opens when you start a loom. ' +\n\t\t\t\t'Supports VSCode, Cursor, WebStorm, Sublime Text, IntelliJ, Windsurf, and Antigravity. ' +\n\t\t\t\t'Note: Color synchronization (title bar colors) only works with VSCode-compatible editors (vscode, cursor, windsurf, antigravity).'\n\t\t),\n\tcolors: z\n\t\t.object({\n\t\t\tterminal: z\n\t\t\t\t.boolean()\n\t\t\t\t.default(true)\n\t\t\t\t.describe('Apply terminal background colors based on branch name (macOS only)'),\n\t\t\tvscode: z\n\t\t\t\t.boolean()\n\t\t\t\t.default(false)\n\t\t\t\t.describe(\n\t\t\t\t\t'Apply VSCode/Cursor title bar colors based on branch name. ' +\n\t\t\t\t\t\t'Note: This modifies .vscode/settings.json which may be in source control. ' +\n\t\t\t\t\t\t'Default is false for safety; enable via init or explicitly if .vscode is gitignored.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Color synchronization settings for workspace identification'),\n\tattribution: z\n\t\t.enum(['off', 'upstreamOnly', 'on'])\n\t\t.default('upstreamOnly')\n\t\t.describe(\n\t\t\t'Controls when iloom attribution appears in session summaries. ' +\n\t\t\t\t'\"off\" - never show attribution. ' +\n\t\t\t\t'\"upstreamOnly\" - only show for contributions to external repositories (e.g., open source). ' +\n\t\t\t\t'\"on\" - always show attribution.'\n\t\t),\n\tgit: z\n\t\t.object({\n\t\t\tcommitTimeout: z\n\t\t\t\t.number()\n\t\t\t\t.min(1000, 'Commit timeout must be at least 1000ms')\n\t\t\t\t.max(600000, 'Commit timeout cannot exceed 600000ms (10 minutes)')\n\t\t\t\t.default(60000)\n\t\t\t\t.describe('Timeout in milliseconds for git commit operations. Increase for long-running pre-commit hooks.'),\n\t\t})\n\t\t.default({ }) // ensures the object always exists and uses default for the inner properties\n\t\t.describe('Git operation settings'),\n})\n\n/**\n * Non-defaulting variant for pre-merge validation\n * This prevents Zod from polluting partial settings with default values before merge\n */\nexport const IloomSettingsSchemaNoDefaults = z.object({\n\tmainBranch: z\n\t\t.string()\n\t\t.min(1, \"Settings 'mainBranch' cannot be empty\")\n\t\t.optional()\n\t\t.describe('Name of the main/primary branch for the repository'),\n\tsourceEnvOnStart: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.describe(\n\t\t\t'Source all dotenv-flow files (.env, .env.local, .env.development, .env.development.local) when launching terminal processes (Claude, dev server, terminal). ' +\n\t\t\t\t'Files are sourced in precedence order so later files override earlier ones. ' +\n\t\t\t\t'NOTE TO AI AGENTS: Before making changes to settings files, YOU MUST OFFER to check .env compatibility. ' +\n\t\t\t\t'WARNING: Unquoted values in .env files may break sourcing in bash/zsh shells. ' +\n\t\t\t\t'Before enabling, verify ALL your .env.* files do not contain unquoted special characters ' +\n\t\t\t\t'(e.g., database URLs with ?, &, or other shell metacharacters). ' +\n\t\t\t\t'Shell compatibility issues may cause processes to fail or behave unexpectedly.',\n\t\t),\n\tworktreePrefix: z\n\t\t.string()\n\t\t.optional()\n\t\t.refine(\n\t\t\t(val) => {\n\t\t\t\tif (val === undefined) return true // undefined = use default calculation\n\t\t\t\tif (val === '') return true // empty string = no prefix mode\n\n\t\t\t\t// Allowlist: only alphanumeric, hyphens, underscores, and forward slashes\n\t\t\t\tconst allowedChars = /^[a-zA-Z0-9\\-_/]+$/\n\t\t\t\tif (!allowedChars.test(val)) return false\n\n\t\t\t\t// Reject if only special characters (no alphanumeric content)\n\t\t\t\tif (/^[-_/]+$/.test(val)) return false\n\n\t\t\t\t// Check each segment (split by /) contains at least one alphanumeric character\n\t\t\t\tconst segments = val.split('/')\n\t\t\t\tfor (const segment of segments) {\n\t\t\t\t\tif (segment && /^[-_]+$/.test(segment)) {\n\t\t\t\t\t\t// Segment exists but contains only hyphens/underscores\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn true\n\t\t\t},\n\t\t\t{\n\t\t\t\tmessage:\n\t\t\t\t\t\"worktreePrefix contains invalid characters. Only alphanumeric characters, hyphens (-), underscores (_), and forward slashes (/) are allowed. Use forward slashes for nested directories.\",\n\t\t\t},\n\t\t)\n\t\t.describe(\n\t\t\t'Prefix for worktree directories. Empty string disables prefix. Defaults to <repo-name>-looms if not set.',\n\t\t),\n\tprotectedBranches: z\n\t\t.array(z.string().min(1, 'Protected branch name cannot be empty'))\n\t\t.optional()\n\t\t.describe('List of branches that cannot be deleted (defaults to [mainBranch, \"main\", \"master\", \"develop\"])'),\n\tcopyGitIgnoredPatterns: z\n\t\t.array(z.string().min(1, 'Pattern cannot be empty'))\n\t\t.optional()\n\t\t.describe('Glob patterns for gitignored files to copy to looms (e.g., [\"*.db\", \"data/*.sqlite\"]). Great for local dbs and large test data files that are too big to commit to git. Note: .env (dotenv-flow) files, iloom\\'s and claude\\'s local settings are automatically copied and do not need to be specified here.'),\n\tworkflows: WorkflowsSettingsSchemaNoDefaults.describe('Per-workflow-type permission configurations'),\n\tagents: z\n\t\t.record(z.string(), AgentSettingsSchema)\n\t\t.optional()\n\t\t.nullable()\n\t\t.describe(\n\t\t\t'Per-agent configuration overrides. Available agents: ' +\n\t\t\t\t'iloom-issue-analyzer (analyzes issues), ' +\n\t\t\t\t'iloom-issue-planner (creates implementation plans), ' +\n\t\t\t\t'iloom-issue-analyze-and-plan (combined analysis and planning), ' +\n\t\t\t\t'iloom-issue-complexity-evaluator (evaluates complexity), ' +\n\t\t\t\t'iloom-issue-enhancer (enhances issue descriptions), ' +\n\t\t\t\t'iloom-issue-implementer (implements code changes), ' +\n\t\t\t\t'iloom-code-reviewer (reviews code changes against requirements), ' +\n\t\t\t\t'iloom-artifact-reviewer (reviews artifacts before posting), ' +\n\t\t\t\t'iloom-swarm-worker (swarm worker agent, dynamically generated). ' +\n\t\t\t\t'Use swarmModel on any agent to override its model in swarm mode.',\n\t\t),\n\tspin: z\n\t\t.object({\n\t\t\tmodel: z.enum(['sonnet', 'opus', 'haiku']).optional(),\n\t\t\tswarmModel: z.enum(['sonnet', 'opus', 'haiku']).optional(),\n\t\t\tpostSwarmReview: z.boolean().optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Spin orchestrator configuration'),\n\tplan: z\n\t\t.object({\n\t\t\tmodel: z.enum(['sonnet', 'opus', 'haiku']).optional(),\n\t\t\tplanner: z.enum(['claude', 'gemini', 'codex']).optional(),\n\t\t\treviewer: z.enum(['claude', 'gemini', 'codex', 'none']).optional(),\n\t\t\twaveVerification: z.boolean().optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Plan command configuration'),\n\tsummary: z\n\t\t.object({\n\t\t\tmodel: z.enum(['sonnet', 'opus', 'haiku']).optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Session summary generation configuration'),\n\tcapabilities: CapabilitiesSettingsSchemaNoDefaults.describe('Project capability configurations'),\n\tdevServer: DevServerSettingsSchemaNoDefaults.optional().describe('Docker-based dev server configuration'),\n\tdatabaseProviders: DatabaseProvidersSettingsSchema.describe('Database provider configurations'),\n\tissueManagement: z\n\t\t.object({\n\t\t\tprovider: z.enum(['github', 'linear', 'jira']).optional().describe('Issue tracker provider (github, linear, jira)'),\n\t\t\tgithub: z\n\t\t\t\t.object({\n\t\t\t\t\tremote: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Remote name cannot be empty')\n\t\t\t\t\t\t.describe('Git remote name to use for GitHub operations'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tlinear: z\n\t\t\t\t.object({\n\t\t\t\t\tteamId: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Team ID cannot be empty')\n\t\t\t\t\t\t.describe('Linear team identifier (e.g., \"ENG\", \"PLAT\")'),\n\t\t\t\t\tbranchFormat: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Branch naming template for Linear issues'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Linear API token (lin_api_...). SECURITY: Store in settings.local.json only, never commit to source control.'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t\tjira: z\n\t\t\t\t.object({\n\t\t\t\t\thost: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Jira host cannot be empty')\n\t\t\t\t\t\t.describe('Jira instance URL (e.g., \"https://yourcompany.atlassian.net\")'),\n\t\t\t\t\tusername: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Jira username/email cannot be empty')\n\t\t\t\t\t\t.describe('Jira username or email address'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Jira API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://id.atlassian.com/manage-profile/security/api-tokens'),\n\t\t\t\t\tprojectKey: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'Project key cannot be empty')\n\t\t\t\t\t\t.describe('Jira project key (e.g., \"PROJ\", \"ENG\")'),\n\t\t\t\t\tboardId: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Jira board ID for sprint/workflow operations (optional)'),\n\t\t\t\t\ttransitionMappings: z\n\t\t\t\t\t\t.record(z.string(), z.string())\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Map iloom states to Jira transition names (e.g., {\"In Review\": \"Start Review\"})'),\n\t\t\t\t\tdefaultIssueType: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1)\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Default Jira issue type name for creating issues (e.g., \"Task\", \"Story\", \"Bug\")'),\n\t\t\t\t\tdefaultSubtaskType: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1)\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('Default Jira issue type name for creating subtasks/child issues (e.g., \"Subtask\", \"Sub-task\")'),\n\t\t\t\t\tdoneStatuses: z\n\t\t\t\t\t\t.array(z.string())\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.default(['Done'])\n\t\t\t\t\t\t.describe('Status names to exclude from issue lists (e.g., [\"Done\", \"Closed\", \"Verify\"])'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Issue management configuration'),\n\tversionControl: z\n\t\t.object({\n\t\t\tprovider: z.enum(['github', 'bitbucket']).optional().describe('Version control provider (github, bitbucket)'),\n\t\t\tbitbucket: z\n\t\t\t\t.object({\n\t\t\t\t\tusername: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.min(1, 'BitBucket username cannot be empty')\n\t\t\t\t\t\t.describe('BitBucket username'),\n\t\t\t\t\tapiToken: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('BitBucket API token. SECURITY: Store in settings.local.json only, never commit to source control. Generate at: https://bitbucket.org/account/settings/app-passwords/ (Note: App passwords deprecated Sep 2025, use API tokens)'),\n\t\t\t\t\tworkspace: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('BitBucket workspace (optional, auto-detected from git remote if not provided)'),\n\t\t\t\t\trepoSlug: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe('BitBucket repository slug (optional, auto-detected from git remote if not provided)'),\n\t\t\t\treviewers: z\n\t\t\t\t\t.array(z.string().describe('Reviewer username'))\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe('List of usernames to add as PR reviewers. Usernames are resolved to Bitbucket account IDs at PR creation time.'),\n\t\t\t\t})\n\t\t\t\t.optional(),\n\t\t})\n\t\t.optional()\n\t\t.describe('Version control provider configuration'),\n\tmergeBehavior: z\n\t\t.object({\n\t\t\tmode: z.enum(mergeModeValues).transform(mergeModeTransform).optional(),\n\t\t\tremote: z.string().optional(),\n\t\t\tautoCommitPush: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Auto-commit and push after code review in draft PR mode. Defaults to true when mode is draft-pr.'\n\t\t\t\t),\n\t\t\tprTitlePrefix: z.boolean().optional(),\n\t\t\topenBrowserOnFinish: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Open the PR in the default browser after finishing in pr or draft-pr mode. Use --no-browser flag to override.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Merge behavior configuration: local (merge locally), pr (create PR), or draft-pr (create draft PR at start, mark ready on finish)'),\n\tide: z\n\t\t.object({\n\t\t\ttype: z\n\t\t\t\t.enum(['vscode', 'cursor', 'webstorm', 'sublime', 'intellij', 'windsurf', 'antigravity'])\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'IDE to launch when starting a loom. Options: vscode (Visual Studio Code), cursor (Cursor AI editor), ' +\n\t\t\t\t\t\t'webstorm (JetBrains WebStorm), sublime (Sublime Text), intellij (JetBrains IntelliJ IDEA), ' +\n\t\t\t\t\t\t'windsurf (Windsurf editor), antigravity (Antigravity IDE).'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe(\n\t\t\t'IDE configuration for workspace launches. Controls which editor opens when you start a loom. ' +\n\t\t\t\t'Supports VSCode, Cursor, WebStorm, Sublime Text, IntelliJ, Windsurf, and Antigravity. ' +\n\t\t\t\t'Note: Color synchronization (title bar colors) only works with VSCode-compatible editors (vscode, cursor, windsurf, antigravity).'\n\t\t),\n\tcolors: z\n\t\t.object({\n\t\t\tterminal: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe('Apply terminal background colors based on branch name (macOS only)'),\n\t\t\tvscode: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t'Apply VSCode/Cursor title bar colors based on branch name. ' +\n\t\t\t\t\t\t'Note: This modifies .vscode/settings.json which may be in source control.'\n\t\t\t\t),\n\t\t})\n\t\t.optional()\n\t\t.describe('Color synchronization settings for workspace identification'),\n\tattribution: z\n\t\t.enum(['off', 'upstreamOnly', 'on'])\n\t\t.optional()\n\t\t.describe(\n\t\t\t'Controls when iloom attribution appears in session summaries. ' +\n\t\t\t\t'\"off\" - never show attribution. ' +\n\t\t\t\t'\"upstreamOnly\" - only show for contributions to external repositories (e.g., open source). ' +\n\t\t\t\t'\"on\" - always show attribution.'\n\t\t),\n\tgit: z\n\t\t.object({\n\t\t\tcommitTimeout: z\n\t\t\t\t.number()\n\t\t\t\t.min(1000, 'Commit timeout must be at least 1000ms')\n\t\t\t\t.max(600000, 'Commit timeout cannot exceed 600000ms (10 minutes)')\n\t\t\t\t.optional()\n\t\t\t\t.describe('Timeout in milliseconds for git commit operations. Increase for long-running pre-commit hooks.'),\n\t\t})\n\t\t.optional()\n\t\t.describe('Git operation settings'),\n})\n\n/**\n * TypeScript type for dev server settings derived from Zod schema\n */\nexport type DevServerSettings = z.infer<typeof DevServerSettingsSchema>\n\n/**\n * TypeScript type for Neon settings derived from Zod schema\n */\nexport type NeonSettings = z.infer<typeof NeonSettingsSchema>\n\n/**\n * TypeScript type for database providers settings derived from Zod schema\n */\nexport type DatabaseProvidersSettings = z.infer<typeof DatabaseProvidersSettingsSchema>\n\n/**\n * TypeScript type for agent settings derived from Zod schema\n */\nexport type AgentSettings = z.infer<typeof AgentSettingsSchema>\n\n/**\n * TypeScript type for spin agent settings derived from Zod schema\n */\nexport type SpinAgentSettings = z.infer<typeof SpinAgentSettingsSchema>\n\n/**\n * TypeScript type for plan command settings derived from Zod schema\n */\nexport type PlanCommandSettings = z.infer<typeof PlanCommandSettingsSchema>\n\n/**\n * TypeScript type for summary settings derived from Zod schema\n */\nexport type SummarySettings = z.infer<typeof SummarySettingsSchema>\n\n/**\n * TypeScript type for workflow permission configuration derived from Zod schema\n */\nexport type WorkflowPermission = z.infer<typeof WorkflowPermissionSchema>\n\n/**\n * TypeScript type for workflows settings derived from Zod schema\n */\nexport type WorkflowsSettings = z.infer<typeof WorkflowsSettingsSchema>\n\n/**\n * TypeScript type for capabilities settings derived from Zod schema\n */\nexport type CapabilitiesSettings = z.infer<typeof CapabilitiesSettingsSchema>\n\n/**\n * TypeScript type for IDE settings derived from Zod schema\n */\nexport type IdeSettings = z.infer<typeof IloomSettingsSchema>['ide']\n\n/**\n * TypeScript type for iloom settings derived from Zod schema\n */\nexport type IloomSettings = z.infer<typeof IloomSettingsSchema>\n\n/**\n * TypeScript input type for iloom settings (before Zod defaults are applied)\n * Used for validation where partial/input objects need to be accepted\n */\nexport type IloomSettingsInput = z.input<typeof IloomSettingsSchema>\n\n/**\n * Recursively redact sensitive fields (tokens, secrets, passwords) from an object.\n * Returns a deep copy with sensitive string values replaced by '[REDACTED]'.\n */\nexport function redactSensitiveFields(obj: unknown): unknown {\n\tif (obj === null || obj === undefined) return obj\n\tif (typeof obj !== 'object') return obj\n\tif (Array.isArray(obj)) return obj.map(redactSensitiveFields)\n\n\tconst sensitiveKeys = ['apitoken', 'token', 'secret', 'password', 'credential']\n\tconst result: Record<string, unknown> = {}\n\tfor (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n\t\tconst lowerKey = key.toLowerCase()\n\t\tif (sensitiveKeys.some(s => lowerKey.includes(s)) && typeof value === 'string') {\n\t\t\tresult[key] = '[REDACTED]'\n\t\t} else if (typeof value === 'object' && value !== null) {\n\t\t\tresult[key] = redactSensitiveFields(value)\n\t\t} else {\n\t\t\tresult[key] = value\n\t\t}\n\t}\n\treturn result\n}\n\n/**\n * Manages project-level settings from .iloom/settings.json\n */\nexport class SettingsManager {\n\t/**\n\t * Load settings from global, project, and local sources with proper precedence\n\t * Merge hierarchy (lowest to highest priority):\n\t * 1. Global settings (~/.config/iloom-ai/settings.json)\n\t * 2. Project settings (<PROJECT_ROOT>/.iloom/settings.json)\n\t * 3. Local settings (<PROJECT_ROOT>/.iloom/settings.local.json)\n\t * 4. CLI overrides (--set flags)\n\t * Returns empty object if all files don't exist (not an error)\n\t */\n\tasync loadSettings(\n\t\tprojectRoot?: string,\n\t\tcliOverrides?: Partial<IloomSettings>,\n\t): Promise<IloomSettings> {\n\t\tconst root = this.getProjectRoot(projectRoot)\n\n\t\t// Load global settings (lowest priority)\n\t\tconst globalSettings = await this.loadGlobalSettingsFile()\n\t\tconst globalSettingsPath = this.getGlobalSettingsPath()\n\t\tlogger.debug(`🌍 Global settings from ${globalSettingsPath}:`, JSON.stringify(redactSensitiveFields(globalSettings), null, 2))\n\n\t\t// Load base settings from settings.json\n\t\tconst baseSettings = await this.loadSettingsFile(root, 'settings.json')\n\t\tconst baseSettingsPath = path.join(root, '.iloom', 'settings.json')\n\t\tlogger.debug(`📄 Base settings from ${baseSettingsPath}:`, JSON.stringify(redactSensitiveFields(baseSettings), null, 2))\n\n\t\t// Load local overrides from settings.local.json\n\t\tconst localSettings = await this.loadSettingsFile(root, 'settings.local.json')\n\t\tconst localSettingsPath = path.join(root, '.iloom', 'settings.local.json')\n\t\tlogger.debug(`📄 Local settings from ${localSettingsPath}:`, JSON.stringify(redactSensitiveFields(localSettings), null, 2))\n\n\t\t// Deep merge with priority: cliOverrides > localSettings > baseSettings > globalSettings\n\t\tlet merged = this.mergeSettings(this.mergeSettings(globalSettings, baseSettings), localSettings)\n\t\tlogger.debug('🔄 After merging global + base + local settings:', JSON.stringify(redactSensitiveFields(merged), null, 2))\n\n\t\tif (cliOverrides && Object.keys(cliOverrides).length > 0) {\n\t\t\tlogger.debug('⚙️ CLI overrides to apply:', JSON.stringify(redactSensitiveFields(cliOverrides), null, 2))\n\t\t\tmerged = this.mergeSettings(merged, cliOverrides)\n\t\t\tlogger.debug('🔄 After applying CLI overrides:', JSON.stringify(redactSensitiveFields(merged), null, 2))\n\t\t}\n\n\t\t// Validate merged result\n\t\ttry {\n\t\t\tconst finalSettings = IloomSettingsSchema.parse(merged)\n\n\t\t\t// Debug: Log final merged configuration\n\t\t\tthis.logFinalConfiguration(finalSettings)\n\n\t\t\treturn finalSettings\n\t\t} catch (error) {\n\t\t\t// Show all Zod validation errors\n\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\tconst errorMsg = this.formatAllZodErrors(error, '<merged settings>')\n\t\t\t\t// Enhance error message if CLI overrides were applied\n\t\t\t\tif (cliOverrides && Object.keys(cliOverrides).length > 0) {\n\t\t\t\t\tthrow new Error(`${errorMsg.message}\\n\\nNote: CLI overrides were applied. Check your --set arguments.`)\n\t\t\t\t}\n\t\t\t\tthrow errorMsg\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Log the final merged configuration for debugging\n\t */\n\tprivate logFinalConfiguration(settings: IloomSettings): void {\n\t\tlogger.debug('📋 Final merged configuration:', JSON.stringify(redactSensitiveFields(settings), null, 2))\n\t}\n\n\t/**\n\t * Load and parse a single settings file\n\t * Returns empty object if file doesn't exist (not an error)\n\t * Uses non-defaulting schema to prevent polluting partial settings with defaults before merge\n\t */\n\tprivate async loadSettingsFile(\n\t\tprojectRoot: string,\n\t\tfilename: string,\n\t): Promise<z.infer<typeof IloomSettingsSchemaNoDefaults>> {\n\t\tconst settingsPath = path.join(projectRoot, '.iloom', filename)\n\n\t\ttry {\n\t\t\tconst content = await readFile(settingsPath, 'utf-8')\n\t\t\tlet parsed: unknown\n\n\t\t\ttry {\n\t\t\t\tparsed = JSON.parse(content)\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to parse settings file at ${settingsPath}: ${error instanceof Error ? error.message : 'Invalid JSON'}`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// Basic type checking - ensure it's an object, but don't validate schema completeness\n\t\t\t// Individual files may be incomplete (e.g., Linear config split between files)\n\t\t\t// Final validation will happen on the merged result in loadSettings()\n\t\t\tif (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Settings validation failed at ${filename}:\\n - root: Expected object, received ${typeof parsed}`\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn parsed as z.infer<typeof IloomSettingsSchemaNoDefaults>\n\t\t} catch (error) {\n\t\t\t// File not found is not an error - return empty settings\n\t\t\tif ((error as { code?: string }).code === 'ENOENT') {\n\t\t\t\tlogger.debug(`No settings file found at ${settingsPath}, using defaults`)\n\t\t\t\treturn {}\n\t\t\t}\n\n\t\t\t// Re-throw parsing errors\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Deep merge two settings objects with priority to override\n\t * Uses deepmerge library with array replacement strategy\n\t */\n\tprivate mergeSettings(\n\t\tbase: Partial<IloomSettings> | z.infer<typeof IloomSettingsSchemaNoDefaults>,\n\t\toverride: Partial<IloomSettings> | z.infer<typeof IloomSettingsSchemaNoDefaults>,\n\t): IloomSettings {\n\t\t// Use deepmerge with array replacement (not concatenation)\n\t\t// Type assertion is safe because the merged result will be validated with IloomSettingsSchema\n\t\t// which applies all the defaults after merging\n\t\treturn deepmerge(base as Record<string, unknown>, override as Record<string, unknown>, {\n\t\t\t// Replace arrays instead of concatenating them\n\t\t\tarrayMerge: (_destinationArray, sourceArray) => sourceArray,\n\t\t}) as IloomSettings\n\t}\n\n\t/**\n\t * Format all Zod validation errors into a single error message\n\t */\n\tprivate formatAllZodErrors(error: z.ZodError, settingsPath: string): Error {\n\t\tconst errorMessages = error.issues.map(issue => {\n\t\t\tconst path = issue.path.length > 0 ? issue.path.join('.') : 'root'\n\t\t\treturn ` - ${path}: ${issue.message}`\n\t\t})\n\n\t\treturn new Error(\n\t\t\t`Settings validation failed at ${settingsPath}:\\n${errorMessages.join('\\n')}`,\n\t\t)\n\t}\n\n\t/**\n\t * Validate settings structure and model names using Zod schema\n\t * This method is kept for testing purposes but uses Zod internally\n\t * @internal - Only used in tests via bracket notation\n\t */\n\t// @ts-expect-error - Used in tests via bracket notation, TypeScript can't detect this usage\n\tprivate validateSettings(settings: IloomSettingsInput): void {\n\t\ttry {\n\t\t\tIloomSettingsSchema.parse(settings)\n\t\t} catch (error) {\n\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\tthrow this.formatAllZodErrors(error, '<validation>')\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Get project root (defaults to process.cwd())\n\t */\n\tprivate getProjectRoot(projectRoot?: string): string {\n\t\treturn projectRoot ?? process.cwd()\n\t}\n\n\t/**\n\t * Get global config directory path (~/.config/iloom-ai)\n\t */\n\tprivate getGlobalConfigDir(): string {\n\t\treturn path.join(os.homedir(), '.config', 'iloom-ai')\n\t}\n\n\t/**\n\t * Get global settings file path (~/.config/iloom-ai/settings.json)\n\t */\n\tprivate getGlobalSettingsPath(): string {\n\t\treturn path.join(this.getGlobalConfigDir(), 'settings.json')\n\t}\n\n\t/**\n\t * Load and parse global settings file\n\t * Returns empty object if file doesn't exist (not an error)\n\t * Warns but returns empty object on validation/parse errors (graceful degradation)\n\t */\n\tprivate async loadGlobalSettingsFile(): Promise<z.infer<typeof IloomSettingsSchemaNoDefaults>> {\n\t\tconst settingsPath = this.getGlobalSettingsPath()\n\n\t\ttry {\n\t\t\tconst content = await readFile(settingsPath, 'utf-8')\n\t\t\tlet parsed: unknown\n\n\t\t\ttry {\n\t\t\t\tparsed = JSON.parse(content)\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Failed to parse global settings file at ${settingsPath}: ${error instanceof Error ? error.message : 'Invalid JSON'}. Ignoring global settings.`,\n\t\t\t\t)\n\t\t\t\treturn {}\n\t\t\t}\n\n\t\t\t// Validate with non-defaulting schema\n\t\t\ttry {\n\t\t\t\tconst validated = IloomSettingsSchemaNoDefaults.strict().parse(parsed)\n\t\t\t\treturn validated\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof z.ZodError) {\n\t\t\t\t\tconst errorMsg = this.formatAllZodErrors(error, 'global settings')\n\t\t\t\t\tlogger.warn(`${errorMsg.message}. Ignoring global settings.`)\n\t\t\t\t} else {\n\t\t\t\t\tlogger.warn(`Validation error in global settings: ${error instanceof Error ? error.message : 'Unknown error'}. Ignoring global settings.`)\n\t\t\t\t}\n\t\t\t\treturn {}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// File not found is not an error - return empty settings\n\t\t\tif ((error as { code?: string }).code === 'ENOENT') {\n\t\t\t\tlogger.debug(`No global settings file found at ${settingsPath}`)\n\t\t\t\treturn {}\n\t\t\t}\n\n\t\t\t// Other file system errors - warn and continue\n\t\t\tlogger.warn(`Error reading global settings file at ${settingsPath}: ${error instanceof Error ? error.message : 'Unknown error'}. Ignoring global settings.`)\n\t\t\treturn {}\n\t\t}\n\t}\n\n\t/**\n\t * Get effective protected branches list with mainBranch always included\n\t *\n\t * This method provides a single source of truth for protected branches logic:\n\t * 1. Use configured protectedBranches if provided\n\t * 2. Otherwise use defaults: [mainBranch, 'main', 'master', 'develop']\n\t * 3. ALWAYS ensure mainBranch is included even if user configured custom list\n\t *\n\t * @param projectRoot - Optional project root directory (defaults to process.cwd())\n\t * @returns Array of protected branch names with mainBranch guaranteed to be included\n\t */\n\tasync getProtectedBranches(projectRoot?: string): Promise<string[]> {\n\t\tconst settings = await this.loadSettings(projectRoot)\n\t\t// SYNC: If this default changes, update displayDefaultsBox() in src/utils/first-run-setup.ts\n\t\tconst mainBranch = settings.mainBranch ?? 'main'\n\n\t\t// Build protected branches list:\n\t\t// 1. Use configured protectedBranches if provided\n\t\t// 2. Otherwise use defaults: [mainBranch, 'main', 'master', 'develop']\n\t\t// 3. ALWAYS ensure mainBranch is included even if user configured custom list\n\t\tlet protectedBranches: string[]\n\t\tif (settings.protectedBranches) {\n\t\t\t// Use configured list but ensure mainBranch is always included\n\t\t\tprotectedBranches = settings.protectedBranches.includes(mainBranch)\n\t\t\t\t? settings.protectedBranches\n\t\t\t\t: [mainBranch, ...settings.protectedBranches]\n\t\t} else {\n\t\t\t// Use defaults with current mainBranch\n\t\t\tprotectedBranches = [mainBranch, 'main', 'master', 'develop']\n\t\t}\n\n\t\treturn protectedBranches\n\t}\n\n\t/**\n\t * Get the spin orchestrator model with default applied\n\t * Default is defined in SpinAgentSettingsSchema\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Model shorthand ('opus', 'sonnet', or 'haiku')\n\t */\n\tgetSpinModel(settings?: IloomSettings, mode?: 'swarm'): 'sonnet' | 'opus' | 'haiku' {\n\t\tif (mode === 'swarm') {\n\t\t\tif (settings?.spin?.swarmModel) {\n\t\t\t\treturn settings.spin.swarmModel\n\t\t\t}\n\t\t\t// Default to opus for swarm orchestrator (\"Balanced\" mode)\n\t\t\treturn 'opus'\n\t\t}\n\t\treturn settings?.spin?.model ?? SpinAgentSettingsSchema.parse({}).model\n\t}\n\n\t/**\n\t * Get the plan command model with default applied\n\t * Default is defined in PlanCommandSettingsSchema\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Model shorthand ('opus', 'sonnet', or 'haiku')\n\t */\n\tgetPlanModel(settings?: IloomSettings): 'sonnet' | 'opus' | 'haiku' {\n\t\treturn settings?.plan?.model ?? PlanCommandSettingsSchema.parse({}).model\n\t}\n\n\t/**\n\t * Get the plan command planner with default applied\n\t * Default is 'claude'\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Planner provider ('claude', 'gemini', or 'codex')\n\t */\n\tgetPlanPlanner(settings?: IloomSettings): 'claude' | 'gemini' | 'codex' {\n\t\treturn settings?.plan?.planner ?? 'claude'\n\t}\n\n\t/**\n\t * Get the plan command reviewer with default applied\n\t * Default is 'none' (no review step)\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Reviewer provider ('claude', 'gemini', 'codex', or 'none')\n\t */\n\tgetPlanReviewer(settings?: IloomSettings): 'claude' | 'gemini' | 'codex' | 'none' {\n\t\treturn settings?.plan?.reviewer ?? 'none'\n\t}\n\n\t/**\n\t * Get the plan command waveVerification setting with default applied\n\t * Default is true (verification tasks are generated)\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Whether wave verification is enabled\n\t */\n\tgetPlanWaveVerification(settings?: IloomSettings): boolean {\n\t\treturn settings?.plan?.waveVerification !== false\n\t}\n\n\t/**\n\t * Get the session summary model with default applied\n\t * Default is defined in SummarySettingsSchema\n\t *\n\t * @param settings - Pre-loaded settings object\n\t * @returns Model shorthand ('opus', 'sonnet', or 'haiku')\n\t */\n\tgetSummaryModel(settings?: IloomSettings): 'sonnet' | 'opus' | 'haiku' {\n\t\treturn settings?.summary?.model ?? SummarySettingsSchema.parse({}).model\n\t}\n}\n"],"mappings":"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","names":["path"]}
@@ -4,7 +4,7 @@ import {
4
4
  getPackageConfig,
5
5
  hasWebDependencies,
6
6
  parseBinField
7
- } from "./chunk-NCPZYQ4B.js";
7
+ } from "./chunk-K3QGG4O2.js";
8
8
 
9
9
  // src/lib/ProjectCapabilityDetector.ts
10
10
  var ProjectCapabilityDetector = class {
@@ -46,4 +46,4 @@ var ProjectCapabilityDetector = class {
46
46
  export {
47
47
  ProjectCapabilityDetector
48
48
  };
49
- //# sourceMappingURL=chunk-G2MNSPA4.js.map
49
+ //# sourceMappingURL=chunk-772N5WCA.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  logger
4
- } from "./chunk-H2SSF24U.js";
4
+ } from "./chunk-VRPPI6GU.js";
5
5
 
6
6
  // src/lib/PromptTemplateManager.ts
7
7
  import { readFile } from "fs/promises";
@@ -133,4 +133,4 @@ export {
133
133
  buildReviewTemplateVariables,
134
134
  PromptTemplateManager
135
135
  };
136
- //# sourceMappingURL=chunk-WG4MLJ6J.js.map
136
+ //# sourceMappingURL=chunk-7RCUWU3I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/PromptTemplateManager.ts"],"sourcesContent":["import { readFile } from 'fs/promises'\nimport { accessSync } from 'fs'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport Handlebars from 'handlebars'\nimport { logger } from '../utils/logger.js'\nimport type { AgentSettings } from './SettingsManager.js'\n\n// Register raw helper to handle content with curly braces (e.g., JSON)\n// Usage: {{{{raw}}}}{{VARIABLE}}{{{{/raw}}}}\n// This outputs the variable content as-is without Handlebars parsing its curly braces\nHandlebars.registerHelper('raw', function (this: unknown, options: Handlebars.HelperOptions) {\n\treturn options.fn(this)\n})\n\nexport interface TemplateVariables {\n\tISSUE_NUMBER?: string | number\n\tPR_NUMBER?: number\n\tISSUE_TITLE?: string\n\tPR_TITLE?: string\n\tWORKSPACE_PATH?: string\n\tPORT?: number\n\tONE_SHOT_MODE?: boolean\n\tINTERACTIVE_MODE?: boolean\n\tSETTINGS_SCHEMA?: string\n\tSETTINGS_GLOBAL_JSON?: string\n\tSETTINGS_JSON?: string\n\tSETTINGS_LOCAL_JSON?: string\n\tSHELL_TYPE?: string\n\tSHELL_CONFIG_PATH?: string\n\tSHELL_CONFIG_CONTENT?: string\n\tREMOTES_INFO?: string\n\tMULTIPLE_REMOTES?: string\n\tSINGLE_REMOTE?: string\n\tSINGLE_REMOTE_NAME?: string\n\tSINGLE_REMOTE_URL?: string\n\tNO_REMOTES?: string\n\tREADME_CONTENT?: string\n\tSETTINGS_SCHEMA_CONTENT?: string\n\tFIRST_TIME_USER?: boolean\n\tVSCODE_SETTINGS_GITIGNORED?: string\n\t// Session summary template variables\n\tSESSION_CONTEXT?: string // Session ID for Claude to reference its conversation\n\tBRANCH_NAME?: string // Branch being finished\n\tLOOM_TYPE?: string // 'issue' or 'pr'\n\tCOMPACT_SUMMARIES?: string // Extracted compact summaries from session transcript\n\tRECAP_DATA?: string // Formatted recap data (goal, complexity, entries, artifacts)\n\t// Draft PR mode variables - mutually exclusive with standard issue mode\n\tDRAFT_PR_NUMBER?: number // PR number for draft PR workflow\n\tDRAFT_PR_URL?: string // Full URL of the draft PR (e.g., https://github.com/owner/repo/pull/123)\n\tDRAFT_PR_MODE?: boolean // True when using draft-pr merge mode\n\tAUTO_COMMIT_PUSH?: boolean // True when auto-commit/push is enabled for draft PR mode\n\tSTANDARD_ISSUE_MODE?: boolean // True when using standard issue commenting (not draft PR)\n\tSTANDARD_BRANCH_MODE?: boolean // True when using standard branch mode (not draft PR)\n\t// Direct prompt mode - agent enhances raw text without issue context or MCP tools\n\tDIRECT_PROMPT_MODE?: boolean\n\t// VS Code environment detection\n\tIS_VSCODE_MODE?: boolean // True when ILOOM_VSCODE=1 environment variable is set\n\t// Multi-language support variables - mutually exclusive\n\tHAS_PACKAGE_JSON?: boolean // True when project has package.json\n\tNO_PACKAGE_JSON?: boolean // True when project does not have package.json (non-Node.js projects)\n\t// Review agent configuration variables (code reviewer)\n\tREVIEW_ENABLED?: boolean // True if review is enabled (defaults to true)\n\tREVIEW_CLAUDE_MODEL?: string // Claude model if configured (defaults to 'sonnet')\n\tREVIEW_GEMINI_MODEL?: string // Gemini model if configured\n\tREVIEW_CODEX_MODEL?: string // Codex model if configured\n\tHAS_REVIEW_CLAUDE?: boolean // True if claude provider configured (defaults to true)\n\tHAS_REVIEW_GEMINI?: boolean // True if gemini provider configured\n\tHAS_REVIEW_CODEX?: boolean // True if codex provider configured\n\t// Artifact reviewer configuration variables\n\tARTIFACT_REVIEW_ENABLED?: boolean // True if artifact review is enabled (defaults to true)\n\tARTIFACT_REVIEW_CLAUDE_MODEL?: string // Claude model if configured (defaults to 'sonnet')\n\tARTIFACT_REVIEW_GEMINI_MODEL?: string // Gemini model if configured\n\tARTIFACT_REVIEW_CODEX_MODEL?: string // Codex model if configured\n\tHAS_ARTIFACT_REVIEW_CLAUDE?: boolean // True if claude provider configured (defaults to true)\n\tHAS_ARTIFACT_REVIEW_GEMINI?: boolean // True if gemini provider configured\n\tHAS_ARTIFACT_REVIEW_CODEX?: boolean // True if codex provider configured\n\t// Per-agent review flags (whether artifacts should be reviewed before posting)\n\tENHANCER_REVIEW_ENABLED?: boolean // True if enhancer artifacts should be reviewed\n\tANALYZER_REVIEW_ENABLED?: boolean // True if analyzer artifacts should be reviewed\n\tPLANNER_REVIEW_ENABLED?: boolean // True if planner artifacts should be reviewed\n\tANALYZE_AND_PLAN_REVIEW_ENABLED?: boolean // True if analyze-and-plan artifacts should be reviewed\n\tIMPLEMENTER_REVIEW_ENABLED?: boolean // True if implementer artifacts should be reviewed\n\tCOMPLEXITY_REVIEW_ENABLED?: boolean // True if complexity evaluator artifacts should be reviewed\n\tCOMPLEXITY_OVERRIDE?: 'trivial' | 'simple' | 'complex' // Complexity override from CLI flag or loom metadata\n\t// Planning mode variables - mutually exclusive\n\tEXISTING_ISSUE_MODE?: boolean // True when decomposing an existing issue (il plan 42)\n\tFRESH_PLANNING_MODE?: boolean // True when starting fresh planning session (il plan \"feature idea\")\n\t// Issue context for decomposition mode\n\tPARENT_ISSUE_NUMBER?: string | undefined // Issue number being decomposed\n\tPARENT_ISSUE_TITLE?: string | undefined // Title of issue being decomposed\n\tPARENT_ISSUE_BODY?: string | undefined // Body of issue being decomposed\n\t// Existing children and dependencies context for decomposition mode\n\tPARENT_ISSUE_CHILDREN?: string | undefined // Formatted list of existing child issues (if any)\n\tPARENT_ISSUE_DEPENDENCIES?: string | undefined // Formatted list of existing dependencies (if any)\n\t// Multi-AI provider support for plan command\n\tPLANNER?: 'claude' | 'gemini' | 'codex'\n\tREVIEWER?: 'claude' | 'gemini' | 'codex' | 'none'\n\tUSE_CLAUDE_PLANNER?: boolean\n\tUSE_GEMINI_PLANNER?: boolean\n\tUSE_CODEX_PLANNER?: boolean\n\tUSE_CLAUDE_REVIEWER?: boolean\n\tUSE_GEMINI_REVIEWER?: boolean\n\tUSE_CODEX_REVIEWER?: boolean\n\tHAS_REVIEWER?: boolean\n\t// Git remote configuration\n\tGIT_REMOTE?: string // Remote name for push (defaults to 'origin')\n\t// Swarm orchestrator variables\n\tEPIC_ISSUE_NUMBER?: string | number\n\tEPIC_WORKTREE_PATH?: string\n\tEPIC_METADATA_PATH?: string // Path to the epic's metadata JSON file\n\tCHILD_ISSUES?: string // JSON stringified array of child issues with worktree paths\n\tDEPENDENCY_MAP?: string // JSON stringified dependency map\n\tSWARM_MODE?: boolean // True when rendering agents in swarm mode\n\tWAVE_VERIFICATION?: boolean // True when wave verification is enabled (planner generates verification child issues)\n\tAUTO_SWARM_MODE?: boolean // True when plan command launched with --auto-swarm flag\n\tNO_CLEANUP?: boolean // True when child loom cleanup should be skipped (e.g., manual cleanup later)\n\tPOST_SWARM_REVIEW?: boolean // True when post-swarm code review is enabled (defaults to true)\n\tISSUE_PREFIX?: string // \"#\" for GitHub, \"\" for Linear/Jira — used in commit message templates\n\tSWARM_TEAM_NAME?: string // Unique team name for swarm orchestrator (project-epic-timestamp)\n}\n\n/**\n * Build review-related template variables from settings.\n * Used by both the ignite command (for prompt templates) and AgentManager (for agent prompts).\n */\nexport function buildReviewTemplateVariables(isSwarmMode: boolean, agents?: Record<string, AgentSettings> | null): Partial<TemplateVariables> {\n\tconst variables: Partial<TemplateVariables> = {}\n\n\t// Code reviewer configuration\n\tconst reviewerSettings = agents?.['iloom-code-reviewer']\n\tconst reviewEnabled = reviewerSettings?.enabled !== false // Default to true\n\tvariables.REVIEW_ENABLED = reviewEnabled\n\n\tif (reviewEnabled) {\n\t\tconst providers = reviewerSettings?.providers ?? {}\n\t\tconst hasAnyProvider = Object.keys(providers).length > 0\n\n\t\tconst claudeModel = providers.claude ?? (hasAnyProvider ? undefined : 'sonnet')\n\t\tif (claudeModel) {\n\t\t\tvariables.REVIEW_CLAUDE_MODEL = claudeModel\n\t\t}\n\t\tif (providers.gemini) {\n\t\t\tvariables.REVIEW_GEMINI_MODEL = providers.gemini\n\t\t}\n\t\tif (providers.codex) {\n\t\t\tvariables.REVIEW_CODEX_MODEL = providers.codex\n\t\t}\n\t\tvariables.HAS_REVIEW_CLAUDE = !!claudeModel\n\t\tvariables.HAS_REVIEW_GEMINI = !!providers.gemini\n\t\tvariables.HAS_REVIEW_CODEX = !!providers.codex\n\t}\n\n\t// Artifact reviewer configuration\n\tconst artifactReviewerSettings = agents?.['iloom-artifact-reviewer']\n\tconst artifactReviewEnabled = artifactReviewerSettings?.enabled !== false // Default to true\n\tvariables.ARTIFACT_REVIEW_ENABLED = artifactReviewEnabled\n\n\tif (artifactReviewEnabled) {\n\t\tconst artifactProviders = artifactReviewerSettings?.providers ?? {}\n\t\tconst hasAnyArtifactProvider = Object.keys(artifactProviders).length > 0\n\n\t\tconst artifactClaudeModel = artifactProviders.claude ?? (hasAnyArtifactProvider ? undefined : 'sonnet')\n\t\tif (artifactClaudeModel) {\n\t\t\tvariables.ARTIFACT_REVIEW_CLAUDE_MODEL = artifactClaudeModel\n\t\t}\n\t\tif (artifactProviders.gemini) {\n\t\t\tvariables.ARTIFACT_REVIEW_GEMINI_MODEL = artifactProviders.gemini\n\t\t}\n\t\tif (artifactProviders.codex) {\n\t\t\tvariables.ARTIFACT_REVIEW_CODEX_MODEL = artifactProviders.codex\n\t\t}\n\t\tvariables.HAS_ARTIFACT_REVIEW_CLAUDE = !!artifactClaudeModel\n\t\tvariables.HAS_ARTIFACT_REVIEW_GEMINI = !!artifactProviders.gemini\n\t\tvariables.HAS_ARTIFACT_REVIEW_CODEX = !!artifactProviders.codex\n\t}\n\n\t// Per-agent review flags (defaults to false for each)\n\t// In swarm mode, swarmReview is used directly (defaults to false if not set)\n\tconst resolveReview = (agent: AgentSettings | undefined): boolean => {\n\t\tif (isSwarmMode) {\n\t\t\treturn agent?.swarmReview === true\n\t\t}\n\t\treturn agent?.review === true\n\t}\n\tvariables.ENHANCER_REVIEW_ENABLED = resolveReview(agents?.['iloom-issue-enhancer'])\n\tvariables.ANALYZER_REVIEW_ENABLED = resolveReview(agents?.['iloom-issue-analyzer'])\n\tvariables.PLANNER_REVIEW_ENABLED = resolveReview(agents?.['iloom-issue-planner'])\n\tvariables.ANALYZE_AND_PLAN_REVIEW_ENABLED = resolveReview(agents?.['iloom-issue-analyze-and-plan'])\n\tvariables.IMPLEMENTER_REVIEW_ENABLED = resolveReview(agents?.['iloom-issue-implementer'])\n\tvariables.COMPLEXITY_REVIEW_ENABLED = resolveReview(agents?.['iloom-issue-complexity-evaluator'])\n\n\treturn variables\n}\n\nexport class PromptTemplateManager {\n\tprivate templateDir: string\n\n\tconstructor(templateDir?: string) {\n\t\tif (templateDir) {\n\t\t\tthis.templateDir = templateDir\n\t\t} else {\n\t\t\t// Find templates relative to the package installation\n\t\t\t// When running from dist/, templates are copied to dist/prompts/\n\t\t\tconst currentFileUrl = import.meta.url\n\t\t\tconst currentFilePath = fileURLToPath(currentFileUrl)\n\t\t\tconst distDir = path.dirname(currentFilePath) // dist directory (may be chunked file location)\n\n\t\t\t// Walk up to find the dist directory (in case of chunked files)\n\t\t\tlet templateDir = path.join(distDir, 'prompts')\n\t\t\tlet currentDir = distDir\n\n\t\t\t// Try to find the prompts directory by walking up\n\t\t\twhile (currentDir !== path.dirname(currentDir)) {\n\t\t\t\tconst candidatePath = path.join(currentDir, 'prompts')\n\t\t\t\ttry {\n\t\t\t\t\t// Check if this directory exists (sync check for constructor)\n\t\t\t\t\taccessSync(candidatePath)\n\t\t\t\t\ttemplateDir = candidatePath\n\t\t\t\t\tbreak\n\t\t\t\t} catch {\n\t\t\t\t\tcurrentDir = path.dirname(currentDir)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.templateDir = templateDir\n\t\t\tlogger.debug('PromptTemplateManager initialized', {\n\t\t\t\tcurrentFilePath,\n\t\t\t\tdistDir,\n\t\t\t\ttemplateDir: this.templateDir\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Load a template file by name\n\t */\n\tasync loadTemplate(templateName: 'issue' | 'pr' | 'regular' | 'init' | 'session-summary' | 'plan' | 'swarm-orchestrator'): Promise<string> {\n\t\tconst templatePath = path.join(this.templateDir, `${templateName}-prompt.txt`)\n\n\t\tlogger.debug('Loading template', {\n\t\t\ttemplateName,\n\t\t\ttemplateDir: this.templateDir,\n\t\t\ttemplatePath\n\t\t})\n\n\t\ttry {\n\t\t\treturn await readFile(templatePath, 'utf-8')\n\t\t} catch (error) {\n\t\t\tlogger.error('Failed to load template', { templateName, templatePath, error })\n\t\t\tthrow new Error(`Template not found: ${templatePath}`)\n\t\t}\n\t}\n\n\t/**\n\t * Substitute variables in a template string using Handlebars\n\t */\n\tsubstituteVariables(template: string, variables: TemplateVariables): string {\n\t\tconst compiled = Handlebars.compile(template, { noEscape: true })\n\t\treturn compiled(variables)\n\t}\n\n\t/**\n\t * Get a fully processed prompt for a workflow type\n\t */\n\tasync getPrompt(\n\t\ttype: 'issue' | 'pr' | 'regular' | 'init' | 'session-summary' | 'plan' | 'swarm-orchestrator',\n\t\tvariables: TemplateVariables\n\t): Promise<string> {\n\t\tconst template = await this.loadTemplate(type)\n\t\treturn this.substituteVariables(template, variables)\n\t}\n}\n"],"mappings":"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","names":["templateDir"]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getLogger
4
- } from "./chunk-ZAXRQLK3.js";
4
+ } from "./chunk-FTYWGQFM.js";
5
5
 
6
6
  // src/utils/claude-trust.ts
7
7
  import lockfile from "proper-lockfile";
@@ -115,4 +115,4 @@ export {
115
115
  preAcceptClaudeTrust,
116
116
  removeClaudeTrust
117
117
  };
118
- //# sourceMappingURL=chunk-NOMQ5RFG.js.map
118
+ //# sourceMappingURL=chunk-7UBEHQTP.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getLogger
4
- } from "./chunk-ZAXRQLK3.js";
4
+ } from "./chunk-FTYWGQFM.js";
5
5
 
6
6
  // src/lib/BranchNamingService.ts
7
7
  var SimpleBranchNameStrategy = class {
@@ -15,7 +15,7 @@ var ClaudeBranchNameStrategy = class {
15
15
  this.claudeModel = claudeModel;
16
16
  }
17
17
  async generate(issueNumber, title) {
18
- const { generateBranchName } = await import("./claude-ONQTDWV3.js");
18
+ const { generateBranchName } = await import("./claude-ACL7G4CF.js");
19
19
  return generateBranchName(title, issueNumber, this.claudeModel);
20
20
  }
21
21
  };
@@ -52,4 +52,4 @@ export {
52
52
  ClaudeBranchNameStrategy,
53
53
  DefaultBranchNamingService
54
54
  };
55
- //# sourceMappingURL=chunk-7NFCGKZT.js.map
55
+ //# sourceMappingURL=chunk-AQUSMNBF.js.map
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  promptConfirmation
4
- } from "./chunk-CV47VCMQ.js";
4
+ } from "./chunk-NPVA65KS.js";
5
5
  import {
6
6
  logger
7
- } from "./chunk-H2SSF24U.js";
7
+ } from "./chunk-VRPPI6GU.js";
8
8
 
9
9
  // src/lib/SettingsMigrationManager.ts
10
10
  import fs from "fs-extra";
@@ -144,4 +144,4 @@ var SettingsMigrationManager = class {
144
144
  export {
145
145
  SettingsMigrationManager
146
146
  };
147
- //# sourceMappingURL=chunk-IDCE26KD.js.map
147
+ //# sourceMappingURL=chunk-AUYSAMXV.js.map