@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
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getLogger
4
+ } from "./chunk-FTYWGQFM.js";
5
+
6
+ // src/lib/providers/bitbucket/BitBucketApiClient.ts
7
+ import https from "https";
8
+ var BitBucketApiClient = class {
9
+ constructor(config) {
10
+ this.baseUrl = "https://api.bitbucket.org/2.0";
11
+ const credentials = Buffer.from(`${config.username}:${config.apiToken}`).toString("base64");
12
+ this.authHeader = `Basic ${credentials}`;
13
+ this.workspace = config.workspace;
14
+ this.repoSlug = config.repoSlug;
15
+ }
16
+ /**
17
+ * Make an HTTP request to BitBucket API
18
+ */
19
+ async request(method, endpoint, body) {
20
+ const url = endpoint.startsWith("http://") || endpoint.startsWith("https://") ? new URL(endpoint) : new URL(`${this.baseUrl}${endpoint}`);
21
+ if ((endpoint.startsWith("http://") || endpoint.startsWith("https://")) && url.hostname !== "api.bitbucket.org") {
22
+ throw new Error(`Refusing to send authenticated request to unexpected host: ${url.hostname} (expected api.bitbucket.org)`);
23
+ }
24
+ getLogger().debug(`BitBucket API ${method} request`, { url: url.toString() });
25
+ return new Promise((resolve, reject) => {
26
+ const options = {
27
+ hostname: url.hostname,
28
+ port: url.port || 443,
29
+ path: url.pathname + url.search,
30
+ method,
31
+ headers: {
32
+ "Authorization": this.authHeader,
33
+ "Accept": "application/json",
34
+ "Content-Type": "application/json"
35
+ }
36
+ };
37
+ const req = https.request(options, (res) => {
38
+ let data = "";
39
+ res.on("data", (chunk) => {
40
+ data += chunk;
41
+ });
42
+ res.on("end", () => {
43
+ if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
44
+ reject(new Error(`BitBucket API error (${res.statusCode}): ${data}`));
45
+ return;
46
+ }
47
+ if (res.statusCode === 204 || !data) {
48
+ resolve({});
49
+ return;
50
+ }
51
+ try {
52
+ resolve(JSON.parse(data));
53
+ } catch (error) {
54
+ reject(new Error(`Failed to parse BitBucket API response: ${error}`));
55
+ }
56
+ });
57
+ });
58
+ req.on("error", (error) => {
59
+ reject(new Error(`BitBucket API request failed: ${error.message}`));
60
+ });
61
+ if (body) {
62
+ req.write(JSON.stringify(body));
63
+ }
64
+ req.end();
65
+ });
66
+ }
67
+ /**
68
+ * Make a GET request to BitBucket API
69
+ */
70
+ async get(endpoint) {
71
+ return this.request("GET", endpoint);
72
+ }
73
+ /**
74
+ * Make a POST request to BitBucket API
75
+ */
76
+ async post(endpoint, body) {
77
+ return this.request("POST", endpoint, body);
78
+ }
79
+ /**
80
+ * Make a PUT request to BitBucket API
81
+ */
82
+ async put(endpoint, body) {
83
+ return this.request("PUT", endpoint, body);
84
+ }
85
+ /**
86
+ * Get repository information
87
+ */
88
+ async getRepository(workspace, repoSlug) {
89
+ return this.get(`/repositories/${workspace}/${repoSlug}`);
90
+ }
91
+ /**
92
+ * Get a pull request by ID
93
+ */
94
+ async getPullRequest(workspace, repoSlug, prId) {
95
+ return this.get(
96
+ `/repositories/${workspace}/${repoSlug}/pullrequests/${prId}`
97
+ );
98
+ }
99
+ /**
100
+ * List open pull requests for a branch
101
+ *
102
+ * Note: BitBucket uses BBQL (BitBucket Query Language) for filtering.
103
+ * The q parameter must use the format: q=source.branch.name="branch-name"
104
+ * When using BBQL, we include state filter in the query to ensure it's applied.
105
+ * See: https://developer.atlassian.com/cloud/bitbucket/rest/intro/#filtering
106
+ */
107
+ async listPullRequests(workspace, repoSlug, sourceBranch) {
108
+ let endpoint = `/repositories/${workspace}/${repoSlug}/pullrequests`;
109
+ if (sourceBranch) {
110
+ const safeBranch = sourceBranch.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
111
+ const query = `state="OPEN" AND source.branch.name="${safeBranch}"`;
112
+ endpoint += `?q=${encodeURIComponent(query)}`;
113
+ } else {
114
+ endpoint += `?state=OPEN`;
115
+ }
116
+ const response = await this.get(endpoint);
117
+ return response.values;
118
+ }
119
+ /**
120
+ * Create a pull request
121
+ */
122
+ async createPullRequest(workspace, repoSlug, title, description, sourceBranch, destinationBranch, reviewerAccountIds) {
123
+ const payload = {
124
+ title,
125
+ description,
126
+ source: {
127
+ branch: {
128
+ name: sourceBranch
129
+ }
130
+ },
131
+ destination: {
132
+ branch: {
133
+ name: destinationBranch
134
+ }
135
+ }
136
+ };
137
+ if (reviewerAccountIds && reviewerAccountIds.length > 0) {
138
+ payload.reviewers = reviewerAccountIds.map((id) => ({ account_id: id }));
139
+ }
140
+ return this.post(
141
+ `/repositories/${workspace}/${repoSlug}/pullrequests`,
142
+ payload
143
+ );
144
+ }
145
+ /**
146
+ * Add a comment to a pull request
147
+ */
148
+ async addPRComment(workspace, repoSlug, prId, content) {
149
+ return this.post(
150
+ `/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`,
151
+ {
152
+ content: {
153
+ raw: content
154
+ }
155
+ }
156
+ );
157
+ }
158
+ /**
159
+ * Update an existing comment on a pull request
160
+ */
161
+ async updatePRComment(workspace, repoSlug, prId, commentId, content) {
162
+ return this.put(
163
+ `/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments/${commentId}`,
164
+ {
165
+ content: {
166
+ raw: content
167
+ }
168
+ }
169
+ );
170
+ }
171
+ /**
172
+ * List all comments on a pull request with pagination
173
+ */
174
+ async listPRComments(workspace, repoSlug, prId) {
175
+ const MAX_PAGES = 50;
176
+ const allComments = [];
177
+ let nextUrl = `/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`;
178
+ let pageCount = 0;
179
+ while (nextUrl) {
180
+ pageCount++;
181
+ if (pageCount > MAX_PAGES) {
182
+ console.error(`BitBucket listPRComments: exceeded maximum pagination limit of ${MAX_PAGES} pages, returning ${allComments.length} comments collected so far`);
183
+ break;
184
+ }
185
+ const response = await this.get(nextUrl);
186
+ allComments.push(...response.values);
187
+ nextUrl = response.next ?? null;
188
+ }
189
+ getLogger().debug(`Fetched ${allComments.length} PR comments from BitBucket`);
190
+ return allComments;
191
+ }
192
+ /**
193
+ * Add an inline comment to a specific file and line in a pull request
194
+ */
195
+ async addInlinePRComment(workspace, repoSlug, prId, content, filePath, line) {
196
+ return this.post(
197
+ `/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`,
198
+ {
199
+ content: {
200
+ raw: content
201
+ },
202
+ inline: {
203
+ to: line,
204
+ path: filePath
205
+ }
206
+ }
207
+ );
208
+ }
209
+ /**
210
+ * Find workspace members by usernames
211
+ * Returns a map of username -> account_id for resolved users
212
+ * Handles pagination to fetch all workspace members
213
+ */
214
+ async findUsersByUsername(workspace, usernames) {
215
+ const result = /* @__PURE__ */ new Map();
216
+ const allMembers = await this.getAllWorkspaceMembers(workspace);
217
+ getLogger().debug(`Resolving ${usernames.length} usernames against ${allMembers.length} workspace members`);
218
+ for (const username of usernames) {
219
+ const usernameLower = username.toLowerCase();
220
+ const member = allMembers.find(
221
+ (m) => {
222
+ var _a;
223
+ return ((_a = m.user.nickname) == null ? void 0 : _a.toLowerCase()) === usernameLower || m.user.display_name.toLowerCase() === usernameLower;
224
+ }
225
+ );
226
+ if (member) {
227
+ result.set(username, member.user.account_id);
228
+ getLogger().debug(`Resolved reviewer ${username} to account ID ${member.user.account_id}`);
229
+ } else {
230
+ getLogger().warn(`Could not resolve reviewer ${username} to a BitBucket account ID`);
231
+ }
232
+ }
233
+ return result;
234
+ }
235
+ /**
236
+ * Fetch all workspace members with pagination
237
+ */
238
+ async getAllWorkspaceMembers(workspace) {
239
+ const allMembers = [];
240
+ let nextUrl = `/workspaces/${workspace}/members`;
241
+ while (nextUrl) {
242
+ const response = await this.get(nextUrl);
243
+ allMembers.push(...response.values);
244
+ nextUrl = response.next ?? null;
245
+ }
246
+ getLogger().debug(`Fetched ${allMembers.length} workspace members from BitBucket`);
247
+ return allMembers;
248
+ }
249
+ /**
250
+ * Get the currently authenticated user
251
+ */
252
+ async getCurrentUser() {
253
+ return this.get("/user");
254
+ }
255
+ /**
256
+ * Test connection to BitBucket API
257
+ */
258
+ async testConnection() {
259
+ try {
260
+ await this.getCurrentUser();
261
+ return true;
262
+ } catch (error) {
263
+ getLogger().error("BitBucket connection test failed", { error });
264
+ return false;
265
+ }
266
+ }
267
+ /**
268
+ * Get configured workspace
269
+ */
270
+ getWorkspace() {
271
+ return this.workspace;
272
+ }
273
+ /**
274
+ * Get configured repository slug
275
+ */
276
+ getRepoSlug() {
277
+ return this.repoSlug;
278
+ }
279
+ };
280
+
281
+ export {
282
+ BitBucketApiClient
283
+ };
284
+ //# sourceMappingURL=chunk-P5MXXHXQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/providers/bitbucket/BitBucketApiClient.ts"],"sourcesContent":["// BitBucketApiClient - REST API wrapper for BitBucket operations\n// Handles authentication and common API request patterns\n\nimport https from 'node:https'\nimport { getLogger } from '../../../utils/logger-context.js'\n\n/**\n * BitBucket API configuration\n */\nexport interface BitBucketConfig {\n\tusername: string\n\tapiToken: string // API token from BitBucket settings\n\tworkspace?: string // Optional, can be auto-detected from git remote\n\trepoSlug?: string // Optional, can be auto-detected from git remote\n}\n\n/**\n * BitBucket pull request response from API\n */\nexport interface BitBucketPullRequest {\n\tid: number\n\ttitle: string\n\tdescription: string\n\tstate: 'OPEN' | 'MERGED' | 'DECLINED' | 'SUPERSEDED'\n\tauthor: {\n\t\tdisplay_name: string\n\t\tuuid: string\n\t}\n\tsource: {\n\t\tbranch: {\n\t\t\tname: string\n\t\t}\n\t}\n\tdestination: {\n\t\tbranch: {\n\t\t\tname: string\n\t\t}\n\t}\n\tcreated_on: string\n\tupdated_on: string\n\tlinks: {\n\t\thtml: {\n\t\t\thref: string\n\t\t}\n\t}\n\t[key: string]: unknown\n}\n\n/**\n * BitBucket workspace member response from API\n * Used for resolving usernames to account IDs\n */\nexport interface BitBucketWorkspaceMember {\n\tuser: {\n\t\taccount_id: string\n\t\tdisplay_name: string\n\t\tuuid: string\n\t\tnickname?: string\n\t}\n}\n\n/**\n * BitBucket repository response from API\n */\nexport interface BitBucketRepository {\n\tslug: string\n\tname: string\n\tfull_name: string\n\tworkspace: {\n\t\tslug: string\n\t}\n\tlinks: {\n\t\thtml: {\n\t\t\thref: string\n\t\t}\n\t}\n\t[key: string]: unknown\n}\n\ninterface BitBucketWorkspaceMembersResponse { values: BitBucketWorkspaceMember[]; next?: string }\n\n/**\n * BitBucket current user response from /user endpoint\n */\nexport interface BitBucketCurrentUser {\n\taccount_id: string\n\tdisplay_name: string\n\tnickname?: string\n}\n\n/**\n * BitBucket PR comment response from API\n */\nexport interface BitBucketComment {\n\tid: number\n\tcontent: { raw: string }\n\tinline?: { from: number | null; to: number | null; path: string }\n\tlinks: { html: { href: string } }\n\tuser?: { display_name: string; uuid: string }\n\tcreated_on?: string\n\tupdated_on?: string\n}\n\n/**\n * BitBucketApiClient provides low-level REST API access to BitBucket\n * \n * Authentication: Basic Auth with username and API token\n * API Reference: https://developer.atlassian.com/cloud/bitbucket/rest/intro/\n * \n * Note: As of September 9, 2025, BitBucket app passwords can no longer be created.\n * Use API tokens with scopes instead. All existing app passwords will be disabled on June 9, 2026.\n */\nexport class BitBucketApiClient {\n\tprivate readonly baseUrl = 'https://api.bitbucket.org/2.0'\n\tprivate readonly authHeader: string\n\tprivate readonly workspace: string | undefined\n\tprivate readonly repoSlug: string | undefined\n\n\tconstructor(config: BitBucketConfig) {\n\t\t// Create Basic Auth header with API token\n\t\tconst credentials = Buffer.from(`${config.username}:${config.apiToken}`).toString('base64')\n\t\tthis.authHeader = `Basic ${credentials}`\n\t\t\n\t\tthis.workspace = config.workspace\n\t\tthis.repoSlug = config.repoSlug\n\t}\n\n\t/**\n\t * Make an HTTP request to BitBucket API\n\t */\n\tprivate async request<T>(\n\t\tmethod: 'GET' | 'POST' | 'PUT',\n\t\tendpoint: string,\n\t\tbody?: unknown\n\t): Promise<T> {\n\t\t// If endpoint is already a full URL, use it directly; otherwise prepend baseUrl\n\t\tconst url = endpoint.startsWith('http://') || endpoint.startsWith('https://')\n\t\t\t? new URL(endpoint)\n\t\t\t: new URL(`${this.baseUrl}${endpoint}`)\n\n\t\t// Validate hostname for full URLs to prevent sending auth credentials to unexpected hosts\n\t\tif ((endpoint.startsWith('http://') || endpoint.startsWith('https://')) && url.hostname !== 'api.bitbucket.org') {\n\t\t\tthrow new Error(`Refusing to send authenticated request to unexpected host: ${url.hostname} (expected api.bitbucket.org)`)\n\t\t}\n\t\tgetLogger().debug(`BitBucket API ${method} request`, { url: url.toString() })\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst options: https.RequestOptions = {\n\t\t\t\thostname: url.hostname,\n\t\t\t\tport: url.port || 443,\n\t\t\t\tpath: url.pathname + url.search,\n\t\t\t\tmethod,\n\t\t\t\theaders: {\n\t\t\t\t\t'Authorization': this.authHeader,\n\t\t\t\t\t'Accept': 'application/json',\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t}\n\n\t\t\tconst req = https.request(options, (res) => {\n\t\t\t\tlet data = ''\n\n\t\t\t\tres.on('data', (chunk) => {\n\t\t\t\t\tdata += chunk\n\t\t\t\t})\n\n\t\t\t\tres.on('end', () => {\n\t\t\t\t\tif (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {\n\t\t\t\t\t\treject(new Error(`BitBucket API error (${res.statusCode}): ${data}`))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\t// Handle empty response\n\t\t\t\t\tif (res.statusCode === 204 || !data) {\n\t\t\t\t\t\tresolve({} as T)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresolve(JSON.parse(data) as T)\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treject(new Error(`Failed to parse BitBucket API response: ${error}`))\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\n\t\t\treq.on('error', (error) => {\n\t\t\t\treject(new Error(`BitBucket API request failed: ${error.message}`))\n\t\t\t})\n\n\t\t\tif (body) {\n\t\t\t\treq.write(JSON.stringify(body))\n\t\t\t}\n\n\t\t\treq.end()\n\t\t})\n\t}\n\n\t/**\n\t * Make a GET request to BitBucket API\n\t */\n\tprivate async get<T>(endpoint: string): Promise<T> {\n\t\treturn this.request<T>('GET', endpoint)\n\t}\n\n\t/**\n\t * Make a POST request to BitBucket API\n\t */\n\tprivate async post<T>(endpoint: string, body: unknown): Promise<T> {\n\t\treturn this.request<T>('POST', endpoint, body)\n\t}\n\n\t/**\n\t * Make a PUT request to BitBucket API\n\t */\n\tprivate async put<T>(endpoint: string, body: unknown): Promise<T> {\n\t\treturn this.request<T>('PUT', endpoint, body)\n\t}\n\n\t/**\n\t * Get repository information\n\t */\n\tasync getRepository(workspace: string, repoSlug: string): Promise<BitBucketRepository> {\n\t\treturn this.get<BitBucketRepository>(`/repositories/${workspace}/${repoSlug}`)\n\t}\n\n\t/**\n\t * Get a pull request by ID\n\t */\n\tasync getPullRequest(\n\t\tworkspace: string,\n\t\trepoSlug: string,\n\t\tprId: number\n\t): Promise<BitBucketPullRequest> {\n\t\treturn this.get<BitBucketPullRequest>(\n\t\t\t`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}`\n\t\t)\n\t}\n\n\t/**\n\t * List open pull requests for a branch\n\t *\n\t * Note: BitBucket uses BBQL (BitBucket Query Language) for filtering.\n\t * The q parameter must use the format: q=source.branch.name=\"branch-name\"\n\t * When using BBQL, we include state filter in the query to ensure it's applied.\n\t * See: https://developer.atlassian.com/cloud/bitbucket/rest/intro/#filtering\n\t */\n\tasync listPullRequests(\n\t\tworkspace: string,\n\t\trepoSlug: string,\n\t\tsourceBranch?: string\n\t): Promise<BitBucketPullRequest[]> {\n\t\tlet endpoint = `/repositories/${workspace}/${repoSlug}/pullrequests`\n\n\t\tif (sourceBranch) {\n\t\t\t// Use BBQL query syntax for filtering by source branch AND state\n\t\t\t// Include state=\"OPEN\" in the query to exclude DECLINED/MERGED/SUPERSEDED PRs\n\t\t\tconst safeBranch = sourceBranch.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')\n\t\t\tconst query = `state=\"OPEN\" AND source.branch.name=\"${safeBranch}\"`\n\t\t\tendpoint += `?q=${encodeURIComponent(query)}`\n\t\t} else {\n\t\t\t// No branch filter, just filter by state\n\t\t\tendpoint += `?state=OPEN`\n\t\t}\n\n\t\tconst response = await this.get<{ values: BitBucketPullRequest[] }>(endpoint)\n\t\treturn response.values\n\t}\n\n\t/**\n\t * Create a pull request\n\t */\n\tasync createPullRequest(\n\t\tworkspace: string,\n\t\trepoSlug: string,\n\t\ttitle: string,\n\t\tdescription: string,\n\t\tsourceBranch: string,\n\t\tdestinationBranch: string,\n\t\treviewerAccountIds?: string[]\n\t): Promise<BitBucketPullRequest> {\n\t\tconst payload: Record<string, unknown> = {\n\t\t\ttitle,\n\t\t\tdescription,\n\t\t\tsource: {\n\t\t\t\tbranch: {\n\t\t\t\t\tname: sourceBranch,\n\t\t\t\t},\n\t\t\t},\n\t\t\tdestination: {\n\t\t\t\tbranch: {\n\t\t\t\t\tname: destinationBranch,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\t// Add reviewers if provided\n\t\tif (reviewerAccountIds && reviewerAccountIds.length > 0) {\n\t\t\tpayload.reviewers = reviewerAccountIds.map(id => ({ account_id: id }))\n\t\t}\n\n\t\treturn this.post<BitBucketPullRequest>(\n\t\t\t`/repositories/${workspace}/${repoSlug}/pullrequests`,\n\t\t\tpayload\n\t\t)\n\t}\n\n\t/**\n\t * Add a comment to a pull request\n\t */\n\tasync addPRComment(\n\t\tworkspace: string,\n\t\trepoSlug: string,\n\t\tprId: number,\n\t\tcontent: string\n\t): Promise<BitBucketComment> {\n\t\treturn this.post<BitBucketComment>(\n\t\t\t`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`,\n\t\t\t{\n\t\t\t\tcontent: {\n\t\t\t\t\traw: content,\n\t\t\t\t},\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Update an existing comment on a pull request\n\t */\n\tasync updatePRComment(\n\t\tworkspace: string,\n\t\trepoSlug: string,\n\t\tprId: number,\n\t\tcommentId: number,\n\t\tcontent: string\n\t): Promise<BitBucketComment> {\n\t\treturn this.put<BitBucketComment>(\n\t\t\t`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments/${commentId}`,\n\t\t\t{\n\t\t\t\tcontent: {\n\t\t\t\t\traw: content,\n\t\t\t\t},\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * List all comments on a pull request with pagination\n\t */\n\tasync listPRComments(\n\t\tworkspace: string,\n\t\trepoSlug: string,\n\t\tprId: number\n\t): Promise<BitBucketComment[]> {\n\t\tconst MAX_PAGES = 50\n\t\tconst allComments: BitBucketComment[] = []\n\t\tlet nextUrl: string | null = `/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`\n\t\tlet pageCount = 0\n\n\t\twhile (nextUrl) {\n\t\t\tpageCount++\n\t\t\tif (pageCount > MAX_PAGES) {\n\t\t\t\tconsole.error(`BitBucket listPRComments: exceeded maximum pagination limit of ${MAX_PAGES} pages, returning ${allComments.length} comments collected so far`)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tconst response: { values: BitBucketComment[]; next?: string } =\n\t\t\t\tawait this.get(nextUrl)\n\n\t\t\tallComments.push(...response.values)\n\n\t\t\t// BitBucket pagination uses 'next' field with full URL\n\t\t\tnextUrl = response.next ?? null\n\t\t}\n\n\t\tgetLogger().debug(`Fetched ${allComments.length} PR comments from BitBucket`)\n\t\treturn allComments\n\t}\n\n\t/**\n\t * Add an inline comment to a specific file and line in a pull request\n\t */\n\tasync addInlinePRComment(\n\t\tworkspace: string,\n\t\trepoSlug: string,\n\t\tprId: number,\n\t\tcontent: string,\n\t\tfilePath: string,\n\t\tline: number\n\t): Promise<BitBucketComment> {\n\t\treturn this.post<BitBucketComment>(\n\t\t\t`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`,\n\t\t\t{\n\t\t\t\tcontent: {\n\t\t\t\t\traw: content,\n\t\t\t\t},\n\t\t\t\tinline: {\n\t\t\t\t\tto: line,\n\t\t\t\t\tpath: filePath,\n\t\t\t\t},\n\t\t\t}\n\t\t)\n\t}\n\n\t/**\n\t * Find workspace members by usernames\n\t * Returns a map of username -> account_id for resolved users\n\t * Handles pagination to fetch all workspace members\n\t */\n\tasync findUsersByUsername(\n\t\tworkspace: string,\n\t\tusernames: string[]\n\t): Promise<Map<string, string>> {\n\t\tconst result = new Map<string, string>()\n\n\t\t// Fetch all workspace members with pagination\n\t\tconst allMembers = await this.getAllWorkspaceMembers(workspace)\n\n\t\tgetLogger().debug(`Resolving ${usernames.length} usernames against ${allMembers.length} workspace members`)\n\n\t\t// Match usernames against fetched members\n\t\tfor (const username of usernames) {\n\t\t\tconst usernameLower = username.toLowerCase()\n\t\t\tconst member = allMembers.find(m =>\n\t\t\t\tm.user.nickname?.toLowerCase() === usernameLower ||\n\t\t\t\tm.user.display_name.toLowerCase() === usernameLower\n\t\t\t)\n\n\t\t\tif (member) {\n\t\t\t\tresult.set(username, member.user.account_id)\n\t\t\t\tgetLogger().debug(`Resolved reviewer ${username} to account ID ${member.user.account_id}`)\n\t\t\t} else {\n\t\t\t\tgetLogger().warn(`Could not resolve reviewer ${username} to a BitBucket account ID`)\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/**\n\t * Fetch all workspace members with pagination\n\t */\n\tprivate async getAllWorkspaceMembers(workspace: string): Promise<BitBucketWorkspaceMember[]> {\n\t\tconst allMembers: BitBucketWorkspaceMember[] = []\n\t\tlet nextUrl: string | null = `/workspaces/${workspace}/members`\n\n\t\twhile (nextUrl) {\n\t\t\tconst response: BitBucketWorkspaceMembersResponse =\n\t\t\t\tawait this.get(nextUrl)\n\n\t\t\tallMembers.push(...response.values)\n\n\t\t\t// BitBucket pagination uses 'next' field with full URL\n\t\t\t// Use it directly since request() now handles full URLs\n\t\t\tnextUrl = response.next ?? null\n\t\t}\n\n\t\tgetLogger().debug(`Fetched ${allMembers.length} workspace members from BitBucket`)\n\t\treturn allMembers\n\t}\n\n\t/**\n\t * Get the currently authenticated user\n\t */\n\tasync getCurrentUser(): Promise<BitBucketCurrentUser> {\n\t\treturn this.get<BitBucketCurrentUser>('/user')\n\t}\n\n\t/**\n\t * Test connection to BitBucket API\n\t */\n\tasync testConnection(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.getCurrentUser()\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tgetLogger().error('BitBucket connection test failed', { error })\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Get configured workspace\n\t */\n\tgetWorkspace(): string | undefined {\n\t\treturn this.workspace\n\t}\n\n\t/**\n\t * Get configured repository slug\n\t */\n\tgetRepoSlug(): string | undefined {\n\t\treturn this.repoSlug\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  generateIssueManagementMcpConfig
4
- } from "./chunk-5UFGO4ZT.js";
4
+ } from "./chunk-CQHHEW2M.js";
5
5
  import {
6
6
  openBrowser
7
- } from "./chunk-YETJNRQM.js";
7
+ } from "./chunk-WEBMMJKL.js";
8
8
  import {
9
9
  waitForKeypress
10
- } from "./chunk-CV47VCMQ.js";
10
+ } from "./chunk-NPVA65KS.js";
11
11
  import {
12
12
  launchClaude
13
- } from "./chunk-Y3RX7LZT.js";
13
+ } from "./chunk-DDHWZNGL.js";
14
14
  import {
15
15
  getLogger
16
- } from "./chunk-ZAXRQLK3.js";
16
+ } from "./chunk-FTYWGQFM.js";
17
17
 
18
18
  // src/lib/IssueEnhancementService.ts
19
19
  var IssueEnhancementService = class {
@@ -243,4 +243,4 @@ IMPORTANT: When you create your analysis comment, tag @${author} in the "Questio
243
243
  export {
244
244
  IssueEnhancementService
245
245
  };
246
- //# sourceMappingURL=chunk-NN5RYWXA.js.map
246
+ //# sourceMappingURL=chunk-PH65MFQM.js.map
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  IssueTrackerFactory
4
- } from "./chunk-UHIBKD73.js";
4
+ } from "./chunk-35CBWAJL.js";
5
5
  import {
6
6
  getLinearIssueDependencies
7
- } from "./chunk-5LTID2AF.js";
7
+ } from "./chunk-DMSL5BAP.js";
8
8
  import {
9
9
  getIssueDependencies
10
- } from "./chunk-NH3QZYE5.js";
10
+ } from "./chunk-KV4NU3RP.js";
11
11
  import {
12
12
  getLogger
13
- } from "./chunk-ZAXRQLK3.js";
13
+ } from "./chunk-FTYWGQFM.js";
14
14
  import {
15
15
  logger
16
- } from "./chunk-H2SSF24U.js";
16
+ } from "./chunk-VRPPI6GU.js";
17
17
 
18
18
  // src/utils/list-children.ts
19
19
  async function fetchChildIssues(parentIssueNumber, issueTracker, repo) {
@@ -204,4 +204,4 @@ export {
204
204
  fetchChildIssueDetails,
205
205
  buildDependencyMap
206
206
  };
207
- //# sourceMappingURL=chunk-TZNNJLGT.js.map
207
+ //# sourceMappingURL=chunk-PMB6TYV4.js.map
@@ -0,0 +1,304 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ BitBucketApiClient
4
+ } from "./chunk-P5MXXHXQ.js";
5
+ import {
6
+ parseGitRemotes
7
+ } from "./chunk-BZ7KTXPB.js";
8
+ import {
9
+ getLogger
10
+ } from "./chunk-FTYWGQFM.js";
11
+
12
+ // src/lib/providers/bitbucket/BitBucketVCSProvider.ts
13
+ var BitBucketVCSProvider = class _BitBucketVCSProvider {
14
+ constructor(config) {
15
+ this.providerName = "bitbucket";
16
+ this.supportsForks = true;
17
+ this.supportsDraftPRs = false;
18
+ this.client = new BitBucketApiClient(config);
19
+ if (config.reviewers) {
20
+ this.reviewerUsernames = config.reviewers;
21
+ }
22
+ }
23
+ /**
24
+ * Create a BitBucketVCSProvider from IloomSettings
25
+ * Extracts and validates BitBucket config from settings
26
+ */
27
+ static fromSettings(settings) {
28
+ var _a;
29
+ const bbSettings = (_a = settings.versionControl) == null ? void 0 : _a.bitbucket;
30
+ if (!(bbSettings == null ? void 0 : bbSettings.username)) {
31
+ throw new Error("BitBucket username is required. Configure versionControl.bitbucket.username in .iloom/settings.json");
32
+ }
33
+ if (!(bbSettings == null ? void 0 : bbSettings.apiToken)) {
34
+ throw new Error("BitBucket API token is required. Configure versionControl.bitbucket.apiToken in .iloom/settings.local.json");
35
+ }
36
+ const config = {
37
+ username: bbSettings.username,
38
+ apiToken: bbSettings.apiToken
39
+ };
40
+ if (bbSettings.workspace) {
41
+ config.workspace = bbSettings.workspace;
42
+ }
43
+ if (bbSettings.repoSlug) {
44
+ config.repoSlug = bbSettings.repoSlug;
45
+ }
46
+ if (bbSettings.reviewers) {
47
+ config.reviewers = bbSettings.reviewers;
48
+ }
49
+ return new _BitBucketVCSProvider(config);
50
+ }
51
+ /**
52
+ * Check if a PR already exists for the given branch
53
+ */
54
+ async checkForExistingPR(branchName, cwd) {
55
+ try {
56
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
57
+ const prs = await this.client.listPullRequests(workspace, repoSlug, branchName);
58
+ if (prs.length > 0 && prs[0]) {
59
+ const pr = prs[0];
60
+ return {
61
+ number: pr.id,
62
+ url: pr.links.html.href
63
+ };
64
+ }
65
+ return null;
66
+ } catch (error) {
67
+ if (error instanceof Error) {
68
+ const statusMatch = error.message.match(/BitBucket API error \((\d+)\)/);
69
+ if (statusMatch == null ? void 0 : statusMatch[1]) {
70
+ const statusCode = parseInt(statusMatch[1], 10);
71
+ if (statusCode === 401 || statusCode === 403) {
72
+ throw error;
73
+ }
74
+ }
75
+ }
76
+ getLogger().debug("Error checking for existing PR", { error });
77
+ return null;
78
+ }
79
+ }
80
+ /**
81
+ * Create a pull request
82
+ */
83
+ async createPR(branchName, title, body, baseBranch, cwd) {
84
+ var _a, _b;
85
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
86
+ getLogger().info(`Creating BitBucket PR in ${workspace}/${repoSlug}`);
87
+ getLogger().debug("PR details", { branchName, title, baseBranch });
88
+ let reviewerIds;
89
+ if (this.reviewerUsernames && this.reviewerUsernames.length > 0) {
90
+ reviewerIds = await this.resolveReviewerUsernames(workspace, this.reviewerUsernames);
91
+ if (reviewerIds.length > 0) {
92
+ const currentUser = await this.client.getCurrentUser();
93
+ const originalCount = reviewerIds.length;
94
+ reviewerIds = reviewerIds.filter((id) => id !== currentUser.account_id);
95
+ if (reviewerIds.length < originalCount) {
96
+ getLogger().debug(
97
+ `Removed current user (${currentUser.display_name}) from reviewers list - PR author cannot be a reviewer`
98
+ );
99
+ }
100
+ }
101
+ }
102
+ const pr = await this.client.createPullRequest(
103
+ workspace,
104
+ repoSlug,
105
+ title,
106
+ body,
107
+ branchName,
108
+ baseBranch,
109
+ reviewerIds
110
+ );
111
+ if (!(pr == null ? void 0 : pr.id) || !((_b = (_a = pr == null ? void 0 : pr.links) == null ? void 0 : _a.html) == null ? void 0 : _b.href)) {
112
+ getLogger().error("Invalid BitBucket API response", { pr });
113
+ throw new Error(
114
+ `BitBucket API returned invalid PR response. Expected PR with id and links.html.href, got: ${JSON.stringify(pr)}`
115
+ );
116
+ }
117
+ getLogger().info(`BitBucket PR #${pr.id} created successfully`);
118
+ return { url: pr.links.html.href, number: pr.id, wasExisting: false };
119
+ }
120
+ /**
121
+ * Fetch PR details
122
+ */
123
+ async fetchPR(prNumber, cwd) {
124
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
125
+ const bbPR = await this.client.getPullRequest(workspace, repoSlug, prNumber);
126
+ return this.mapBitBucketPRToPullRequest(bbPR);
127
+ }
128
+ /**
129
+ * Get PR URL
130
+ */
131
+ async getPRUrl(prNumber, cwd) {
132
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
133
+ const bbPR = await this.client.getPullRequest(workspace, repoSlug, prNumber);
134
+ return bbPR.links.html.href;
135
+ }
136
+ /**
137
+ * Create a comment on a PR
138
+ */
139
+ async createPRComment(prNumber, body, cwd) {
140
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
141
+ getLogger().debug("Creating BitBucket PR comment", { workspace, repoSlug, prNumber });
142
+ const comment = await this.client.addPRComment(workspace, repoSlug, prNumber, body);
143
+ return { id: String(comment.id), url: comment.links.html.href };
144
+ }
145
+ /**
146
+ * Update an existing comment on a PR
147
+ */
148
+ async updatePRComment(prNumber, commentId, body, cwd) {
149
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
150
+ getLogger().debug("Updating BitBucket PR comment", { workspace, repoSlug, prNumber, commentId });
151
+ const numericCommentId = parseInt(commentId, 10);
152
+ if (isNaN(numericCommentId)) {
153
+ throw new Error(`Invalid comment ID "${commentId}": expected a numeric value`);
154
+ }
155
+ const comment = await this.client.updatePRComment(workspace, repoSlug, prNumber, numericCommentId, body);
156
+ return { id: String(comment.id), url: comment.links.html.href };
157
+ }
158
+ /**
159
+ * Get inline review comments on a PR
160
+ * Fetches all comments and filters for those with inline metadata
161
+ */
162
+ async getReviewComments(prNumber, cwd) {
163
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
164
+ getLogger().debug("Fetching BitBucket PR review comments", { workspace, repoSlug, prNumber });
165
+ const allComments = await this.client.listPRComments(workspace, repoSlug, prNumber);
166
+ const inlineComments = [];
167
+ for (const c of allComments) {
168
+ if (c.inline == null) continue;
169
+ inlineComments.push({
170
+ id: String(c.id),
171
+ body: c.content.raw,
172
+ path: c.inline.path,
173
+ line: c.inline.to ?? c.inline.from ?? null,
174
+ side: null,
175
+ // BitBucket doesn't have a "side" concept like GitHub
176
+ author: c.user ? { id: c.user.uuid, displayName: c.user.display_name } : null,
177
+ createdAt: c.created_on ?? "",
178
+ updatedAt: c.updated_on ?? null,
179
+ inReplyToId: null
180
+ // BitBucket uses nested comments, not reply chains
181
+ });
182
+ }
183
+ return inlineComments;
184
+ }
185
+ /**
186
+ * Create an inline review comment on a specific file and line in a PR
187
+ */
188
+ async createReviewComment(prNumber, path, line, body, cwd) {
189
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
190
+ getLogger().debug("Creating BitBucket inline PR comment", { workspace, repoSlug, prNumber, path, line });
191
+ const comment = await this.client.addInlinePRComment(workspace, repoSlug, prNumber, body, path, line);
192
+ return { id: String(comment.id), url: comment.links.html.href };
193
+ }
194
+ /**
195
+ * List open pull requests for the repository
196
+ * Uses getWorkspaceAndRepo for auto-detection from git remotes
197
+ */
198
+ async listPullRequests(cwd) {
199
+ const { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd);
200
+ return this.client.listPullRequests(workspace, repoSlug);
201
+ }
202
+ /**
203
+ * Detect repository from git remote
204
+ */
205
+ async detectRepository(cwd) {
206
+ try {
207
+ const remotes = await parseGitRemotes(cwd);
208
+ const bbRemote = remotes.find(
209
+ (r) => r.url.includes("bitbucket.org")
210
+ );
211
+ if (!bbRemote) {
212
+ return null;
213
+ }
214
+ return {
215
+ owner: bbRemote.owner,
216
+ // workspace
217
+ repo: bbRemote.repo
218
+ };
219
+ } catch (error) {
220
+ getLogger().error("Failed to detect BitBucket repository", { error });
221
+ return null;
222
+ }
223
+ }
224
+ /**
225
+ * Get target remote for PR operations
226
+ */
227
+ async getTargetRemote(_cwd) {
228
+ return "origin";
229
+ }
230
+ /**
231
+ * Get workspace and repository slug from config or git remote
232
+ */
233
+ async getWorkspaceAndRepo(cwd) {
234
+ let workspace = this.client.getWorkspace();
235
+ let repoSlug = this.client.getRepoSlug();
236
+ if (!workspace || !repoSlug) {
237
+ const detected = await this.detectRepository(cwd);
238
+ if (!detected) {
239
+ throw new Error(
240
+ "Could not determine BitBucket workspace/repository. Either configure them in settings or ensure git remote points to bitbucket.org"
241
+ );
242
+ }
243
+ workspace = workspace ?? detected.owner;
244
+ repoSlug = repoSlug ?? detected.repo;
245
+ }
246
+ return { workspace, repoSlug };
247
+ }
248
+ /**
249
+ * Resolve reviewer usernames to BitBucket account IDs
250
+ * Warns for any usernames that cannot be resolved but continues with partial list
251
+ */
252
+ async resolveReviewerUsernames(workspace, usernames) {
253
+ getLogger().debug(`Resolving ${usernames.length} reviewer username(s) to BitBucket account IDs`);
254
+ const usernameToAccountId = await this.client.findUsersByUsername(workspace, usernames);
255
+ const resolvedIds = [];
256
+ const unresolvedUsernames = [];
257
+ for (const username of usernames) {
258
+ const accountId = usernameToAccountId.get(username);
259
+ if (accountId) {
260
+ resolvedIds.push(accountId);
261
+ } else {
262
+ unresolvedUsernames.push(username);
263
+ }
264
+ }
265
+ if (unresolvedUsernames.length > 0) {
266
+ getLogger().warn(
267
+ `Could not resolve ${unresolvedUsernames.length} reviewer username(s) to BitBucket account IDs: ${unresolvedUsernames.join(", ")}. These reviewers will not be added to the PR.`
268
+ );
269
+ }
270
+ if (resolvedIds.length > 0) {
271
+ getLogger().info(`Resolved ${resolvedIds.length} reviewer(s) for PR`);
272
+ }
273
+ return resolvedIds;
274
+ }
275
+ /**
276
+ * Map BitBucket PR to generic PullRequest type
277
+ */
278
+ mapBitBucketPRToPullRequest(bbPR) {
279
+ let state;
280
+ if (bbPR.state === "OPEN") {
281
+ state = "open";
282
+ } else if (bbPR.state === "MERGED") {
283
+ state = "merged";
284
+ } else {
285
+ state = "closed";
286
+ }
287
+ return {
288
+ number: bbPR.id,
289
+ title: bbPR.title,
290
+ body: bbPR.description,
291
+ state,
292
+ branch: bbPR.source.branch.name,
293
+ baseBranch: bbPR.destination.branch.name,
294
+ url: bbPR.links.html.href,
295
+ isDraft: false
296
+ // BitBucket doesn't have draft PRs
297
+ };
298
+ }
299
+ };
300
+
301
+ export {
302
+ BitBucketVCSProvider
303
+ };
304
+ //# sourceMappingURL=chunk-QC65IOV3.js.map