@iloom/cli 0.11.1 → 0.13.0-beta.0
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.
- package/LICENSE +1 -1
- package/README.md +170 -15
- package/dist/BitBucketApiClient-J2ZSCS5N.js +10 -0
- package/dist/BitBucketVCSProvider-5X64IXXW.js +12 -0
- package/dist/{BranchNamingService-XBCO747L.js → BranchNamingService-MEK2WZUD.js} +4 -4
- package/dist/ClaudeContextManager-RRGREEZQ.js +14 -0
- package/dist/ClaudeService-LEPW6QAC.js +13 -0
- package/dist/GitHubService-UTAYZXL3.js +12 -0
- package/dist/IssueTrackerFactory-KE2BDCLC.js +15 -0
- package/dist/{LoomLauncher-5AZU2F5I.js → LoomLauncher-GKQMR5E6.js} +10 -10
- package/dist/MetadataManager-V4LSJ2PB.js +10 -0
- package/dist/ProjectCapabilityDetector-I4J66WKF.js +11 -0
- package/dist/{PromptTemplateManager-T5VTLJP3.js → PromptTemplateManager-I75WKXM4.js} +3 -3
- package/dist/README.md +170 -15
- package/dist/{SettingsManager-WQ5NSGAH.js → SettingsManager-KQU7OX7G.js} +15 -5
- package/dist/SettingsMigrationManager-ZPARZ5KH.js +10 -0
- package/dist/agents/iloom-code-reviewer.md +2 -1
- package/dist/agents/iloom-framework-detector.md +0 -1
- package/dist/agents/iloom-issue-analyze-and-plan.md +4 -1
- package/dist/agents/iloom-issue-analyzer.md +4 -1
- package/dist/agents/iloom-issue-complexity-evaluator.md +4 -1
- package/dist/agents/iloom-issue-enhancer.md +4 -1
- package/dist/agents/iloom-issue-implementer.md +5 -2
- package/dist/agents/iloom-issue-planner.md +4 -1
- package/dist/agents/iloom-wave-verifier.md +186 -0
- package/dist/browser-VZY7F2DF.js +10 -0
- package/dist/build-V3KADFMO.js +27 -0
- package/dist/{chunk-XXFSOVL3.js → chunk-3XEXT35Z.js} +4 -4
- package/dist/{chunk-YRCEOQPX.js → chunk-4JZEQBWV.js} +4 -3
- package/dist/chunk-4JZEQBWV.js.map +1 -0
- package/dist/{chunk-LE2NOUTN.js → chunk-4VQXMEEP.js} +3 -3
- package/dist/{chunk-G2MNSPA4.js → chunk-772N5WCA.js} +2 -2
- package/dist/{chunk-WG4MLJ6J.js → chunk-7RCUWU3I.js} +2 -2
- package/dist/chunk-7RCUWU3I.js.map +1 -0
- package/dist/{chunk-NOMQ5RFG.js → chunk-7UBEHQTP.js} +2 -2
- package/dist/{chunk-7NFCGKZT.js → chunk-AQUSMNBF.js} +3 -3
- package/dist/{chunk-IDCE26KD.js → chunk-AUYSAMXV.js} +3 -3
- package/dist/chunk-AYLC633W.js +406 -0
- package/dist/chunk-AYLC633W.js.map +1 -0
- package/dist/{chunk-QVAA5KHK.js → chunk-BZ7KTXPB.js} +16 -8
- package/dist/chunk-BZ7KTXPB.js.map +1 -0
- package/dist/{chunk-K7R5QY6C.js → chunk-CE676WCN.js} +2 -2
- package/dist/{chunk-5UFGO4ZT.js → chunk-CQHHEW2M.js} +6 -3
- package/dist/chunk-CQHHEW2M.js.map +1 -0
- package/dist/{chunk-LHDD4JHC.js → chunk-D4Q7T5KD.js} +4 -4
- package/dist/{chunk-RBYTXYGD.js → chunk-D75KSI3V.js} +2 -2
- package/dist/{chunk-Y3RX7LZT.js → chunk-DDHWZNGL.js} +18 -12
- package/dist/chunk-DDHWZNGL.js.map +1 -0
- package/dist/{chunk-5LTID2AF.js → chunk-DMSL5BAP.js} +35 -6
- package/dist/{chunk-5LTID2AF.js.map → chunk-DMSL5BAP.js.map} +1 -1
- package/dist/{chunk-SQYHPBFP.js → chunk-EGNUOALL.js} +2 -2
- package/dist/{chunk-ZAXRQLK3.js → chunk-FTYWGQFM.js} +2 -2
- package/dist/{chunk-5PNZBH6V.js → chunk-H3T3EPF3.js} +2 -2
- package/dist/{chunk-VNYWBHKR.js → chunk-JD3K2344.js} +3 -3
- package/dist/{chunk-6YVJVUR4.js → chunk-JDN4SPV3.js} +3 -3
- package/dist/{chunk-NCPZYQ4B.js → chunk-K3QGG4O2.js} +2 -2
- package/dist/{chunk-ABVMUNCD.js → chunk-KQSV7FOG.js} +64 -10
- package/dist/chunk-KQSV7FOG.js.map +1 -0
- package/dist/{chunk-NH3QZYE5.js → chunk-KV4NU3RP.js} +2 -2
- package/dist/{chunk-NDSGJZI2.js → chunk-LOAYWTJJ.js} +2 -2
- package/dist/{chunk-GMDSYLI6.js → chunk-MY2Q3FJ3.js} +2 -2
- package/dist/{chunk-CV47VCMQ.js → chunk-NPVA65KS.js} +2 -2
- package/dist/{chunk-RMLADZRY.js → chunk-NTDY5AMO.js} +5 -5
- package/dist/{chunk-UHIBKD73.js → chunk-NUUFP53X.js} +13 -32
- package/dist/{chunk-UHIBKD73.js.map → chunk-NUUFP53X.js.map} +1 -1
- package/dist/{chunk-7OCGBJLR.js → chunk-OIVFHJOA.js} +2 -2
- package/dist/chunk-P5MXXHXQ.js +284 -0
- package/dist/chunk-P5MXXHXQ.js.map +1 -0
- package/dist/{chunk-TEJAGQX2.js → chunk-PD75ZCFT.js} +35 -35
- package/dist/chunk-PD75ZCFT.js.map +1 -0
- package/dist/{chunk-NN5RYWXA.js → chunk-PH65MFQM.js} +6 -6
- package/dist/{chunk-LL6TOX3G.js → chunk-Q7VXHJP6.js} +10 -10
- package/dist/chunk-Q7VXHJP6.js.map +1 -0
- package/dist/chunk-QC65IOV3.js +304 -0
- package/dist/chunk-QC65IOV3.js.map +1 -0
- package/dist/{chunk-V4STTBQD.js → chunk-QED2WB2D.js} +9 -9
- package/dist/{chunk-3RXYOBME.js → chunk-QNPJXO53.js} +5 -5
- package/dist/{chunk-3RXYOBME.js.map → chunk-QNPJXO53.js.map} +1 -1
- package/dist/chunk-QQULYI2S.js +696 -0
- package/dist/chunk-QQULYI2S.js.map +1 -0
- package/dist/{chunk-QNHZM5ZV.js → chunk-QXGM32TO.js} +3 -3
- package/dist/{chunk-TZNNJLGT.js → chunk-RFCAPHL5.js} +6 -6
- package/dist/{chunk-7FIXNAUO.js → chunk-SA446KA2.js} +66 -43
- package/dist/chunk-SA446KA2.js.map +1 -0
- package/dist/{chunk-UDCI3QTS.js → chunk-SN4S5CWL.js} +2 -2
- package/dist/{chunk-VUUN3KE4.js → chunk-TAEVA4QR.js} +8 -8
- package/dist/chunk-TAEVA4QR.js.map +1 -0
- package/dist/{chunk-IR74O2F6.js → chunk-TN2D2RX7.js} +253 -174
- package/dist/chunk-TN2D2RX7.js.map +1 -0
- package/dist/{chunk-3GTUXW26.js → chunk-VIQOQ463.js} +19 -3
- package/dist/chunk-VIQOQ463.js.map +1 -0
- package/dist/{chunk-H2SSF24U.js → chunk-VRPPI6GU.js} +17 -6
- package/dist/{chunk-H2SSF24U.js.map → chunk-VRPPI6GU.js.map} +1 -1
- package/dist/{chunk-XFQGI2E3.js → chunk-VVQQIG64.js} +58 -53
- package/dist/chunk-VVQQIG64.js.map +1 -0
- package/dist/{chunk-YETJNRQM.js → chunk-WEBMMJKL.js} +2 -1
- package/dist/{chunk-ET6A2JR4.js → chunk-WGUGB54H.js} +120 -18
- package/dist/chunk-WGUGB54H.js.map +1 -0
- package/dist/{chunk-QR4FU53I.js → chunk-X5DRLONY.js} +22 -12
- package/dist/chunk-X5DRLONY.js.map +1 -0
- package/dist/{chunk-KQFIGI37.js → chunk-XCP2WDYA.js} +7 -7
- package/dist/{chunk-VMZG66UV.js → chunk-YUOVWWJX.js} +312 -7
- package/dist/chunk-YUOVWWJX.js.map +1 -0
- package/dist/{chunk-HLDY5S4C.js → chunk-ZUIFO7B4.js} +3 -3
- package/dist/{claude-ONQTDWV3.js → claude-ACL7G4CF.js} +4 -4
- package/dist/{cleanup-YOM6PQCN.js → cleanup-RJKLI47I.js} +40 -37
- package/dist/cleanup-RJKLI47I.js.map +1 -0
- package/dist/cli.js +322 -169
- package/dist/cli.js.map +1 -1
- package/dist/{color-VQD52LOI.js → color-AC6F2QE7.js} +3 -3
- package/dist/{commit-DC2Q5CDY.js → commit-SUHRUMDE.js} +15 -15
- package/dist/{compile-4NCQECKE.js → compile-2MD346PO.js} +11 -11
- package/dist/{contribute-M5UWXCAV.js → contribute-P4BMRY7C.js} +11 -11
- package/dist/{contribute-M5UWXCAV.js.map → contribute-P4BMRY7C.js.map} +1 -1
- package/dist/{mcp/darwin-3JFFE3W2.js → darwin-5K3I4FTH.js} +2 -2
- package/dist/database-helpers-PRDFNDRO.js +11 -0
- package/dist/{dev-server-CYRP6M73.js → dev-server-ZNTLWOL5.js} +35 -21
- package/dist/dev-server-ZNTLWOL5.js.map +1 -0
- package/dist/{feedback-BMAZGKRW.js → feedback-Q6WG2WX4.js} +17 -17
- package/dist/{git-BXUD6CL5.js → git-TX2IEMB3.js} +6 -6
- package/dist/ignite-P644W2PK.js +35 -0
- package/dist/index.d.ts +236 -18
- package/dist/index.js +180 -63
- package/dist/index.js.map +1 -1
- package/dist/{init-CI43GJHV.js → init-5HFY7JG6.js} +18 -18
- package/dist/{install-deps-SRTM5U7D.js → install-deps-J4ALTM27.js} +11 -11
- package/dist/{installation-detector-HF6QN7KP.js → installation-detector-PYAZ2O6U.js} +3 -3
- package/dist/{issues-DMRQJH7E.js → issues-LZMIF22U.js} +69 -56
- package/dist/issues-LZMIF22U.js.map +1 -0
- package/dist/lint-XIXKU22H.js +27 -0
- package/dist/{linux-RYLOP2LY.js → linux-WUGRYCJY.js} +2 -2
- package/dist/mcp/{chunk-PIIRD4LO.js → chunk-4HZMW2V3.js} +1 -1
- package/dist/mcp/{chunk-PIIRD4LO.js.map → chunk-4HZMW2V3.js.map} +1 -1
- package/dist/{darwin-5BHWRJ7D.js → mcp/darwin-U25WIGH6.js} +2 -2
- package/dist/mcp/issue-management-server.js +908 -20
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/mcp/{linux-JBVS4R3A.js → linux-5BXVBGSY.js} +2 -2
- package/dist/mcp/recap-server.js +24 -22
- package/dist/mcp/recap-server.js.map +1 -1
- package/dist/mcp/{tmux-RYBLEHUZ.js → tmux-CU26ZTNM.js} +2 -2
- package/dist/mcp/{wsl-4QZIQLLE.js → wsl-KI25UDOF.js} +2 -2
- package/dist/{open-2Y7GSUTJ.js → open-KUO35JIJ.js} +36 -21
- package/dist/open-KUO35JIJ.js.map +1 -0
- package/dist/{plan-SWFPLNJE.js → plan-7CF56OIR.js} +47 -43
- package/dist/{plan-SWFPLNJE.js.map → plan-7CF56OIR.js.map} +1 -1
- package/dist/{projects-IUSUXD5D.js → projects-L5AHUBGA.js} +6 -6
- package/dist/{prompt-7LZB4PAT.js → prompt-FUU5NMJQ.js} +3 -3
- package/dist/prompt-FUU5NMJQ.js.map +1 -0
- package/dist/prompts/init-prompt.txt +184 -23
- package/dist/prompts/issue-prompt.txt +94 -158
- package/dist/prompts/plan-prompt.txt +55 -0
- package/dist/prompts/regular-prompt.txt +1 -1
- package/dist/prompts/swarm-orchestrator-prompt.txt +78 -21
- package/dist/{rebase-S6OHAOOF.js → rebase-MAMWPA2L.js} +12 -12
- package/dist/{recap-GGVCG5VH.js → recap-IDBO3KM5.js} +9 -9
- package/dist/{remote-MZTFHHTU.js → remote-RO4LZKT2.js} +3 -3
- package/dist/remote-RO4LZKT2.js.map +1 -0
- package/dist/{run-ST3FR75O.js → run-RGZHCQ6M.js} +36 -21
- package/dist/run-RGZHCQ6M.js.map +1 -0
- package/dist/schema/settings.schema.json +171 -11
- package/dist/{shell-W4SBQPTE.js → shell-7ADCDFIV.js} +8 -8
- package/dist/{summary-P2JCIIJO.js → summary-7J2HORFD.js} +21 -19
- package/dist/summary-7J2HORFD.js.map +1 -0
- package/dist/test-SRB7EWU6.js +27 -0
- package/dist/{test-git-2KFFAQ6B.js → test-git-G7ATVIXG.js} +6 -6
- package/dist/{test-jira-FKDKG6CD.js → test-jira-Q2HPA522.js} +8 -8
- package/dist/{test-prefix-GP2DAX37.js → test-prefix-JMDGXR5A.js} +6 -6
- package/dist/{test-tabs-YDWMWTVA.js → test-tabs-NGPTFD5T.js} +2 -2
- package/dist/{test-webserver-QI3QQFZ3.js → test-webserver-GZFVXBGD.js} +8 -8
- package/dist/{tmux-7ZTA3BDI.js → tmux-6LRFH3DM.js} +2 -2
- package/dist/{update-XLW7R7FL.js → update-AD3GE5C4.js} +4 -4
- package/dist/{update-notifier-EYLAXZAA.js → update-notifier-VYDTDMSJ.js} +3 -3
- package/dist/update-notifier-VYDTDMSJ.js.map +1 -0
- package/dist/{vscode-TOGE5N67.js → vscode-3I7ISHUU.js} +12 -12
- package/dist/{vscode-announcement-NIX7O2MG.js → vscode-announcement-AL3EHORH.js} +3 -3
- package/dist/{wsl-Y4GUTOQ7.js → wsl-4VMVT2PO.js} +2 -2
- package/package.json +1 -1
- package/dist/ClaudeContextManager-SXDCWDJA.js +0 -14
- package/dist/ClaudeService-6E6MCGJE.js +0 -13
- package/dist/GitHubService-2R5GQG4K.js +0 -12
- package/dist/IssueTrackerFactory-XN6MQ4UN.js +0 -14
- package/dist/MetadataManager-CMQQTFLQ.js +0 -10
- package/dist/ProjectCapabilityDetector-IC6NAFGY.js +0 -11
- package/dist/SettingsMigrationManager-S6J7OHUH.js +0 -10
- package/dist/build-OLS6J5KZ.js +0 -27
- package/dist/chunk-3GTUXW26.js.map +0 -1
- package/dist/chunk-5UFGO4ZT.js.map +0 -1
- package/dist/chunk-7FIXNAUO.js.map +0 -1
- package/dist/chunk-ABVMUNCD.js.map +0 -1
- package/dist/chunk-ET6A2JR4.js.map +0 -1
- package/dist/chunk-IR74O2F6.js.map +0 -1
- package/dist/chunk-LL6TOX3G.js.map +0 -1
- package/dist/chunk-QR4FU53I.js.map +0 -1
- package/dist/chunk-QVAA5KHK.js.map +0 -1
- package/dist/chunk-RVI6C2H5.js +0 -220
- package/dist/chunk-RVI6C2H5.js.map +0 -1
- package/dist/chunk-TEJAGQX2.js.map +0 -1
- package/dist/chunk-VMZG66UV.js.map +0 -1
- package/dist/chunk-VUUN3KE4.js.map +0 -1
- package/dist/chunk-WG4MLJ6J.js.map +0 -1
- package/dist/chunk-XFQGI2E3.js.map +0 -1
- package/dist/chunk-Y3RX7LZT.js.map +0 -1
- package/dist/chunk-YRCEOQPX.js.map +0 -1
- package/dist/cleanup-YOM6PQCN.js.map +0 -1
- package/dist/dev-server-CYRP6M73.js.map +0 -1
- package/dist/ignite-IO4LXVXJ.js +0 -35
- package/dist/issues-DMRQJH7E.js.map +0 -1
- package/dist/lint-BSWRMGPZ.js +0 -27
- package/dist/neon-helpers-HWIYRKOW.js +0 -11
- package/dist/open-2Y7GSUTJ.js.map +0 -1
- package/dist/run-ST3FR75O.js.map +0 -1
- package/dist/summary-P2JCIIJO.js.map +0 -1
- package/dist/test-6JH4FE2X.js +0 -27
- /package/dist/{BranchNamingService-XBCO747L.js.map → BitBucketApiClient-J2ZSCS5N.js.map} +0 -0
- /package/dist/{ClaudeContextManager-SXDCWDJA.js.map → BitBucketVCSProvider-5X64IXXW.js.map} +0 -0
- /package/dist/{ClaudeService-6E6MCGJE.js.map → BranchNamingService-MEK2WZUD.js.map} +0 -0
- /package/dist/{GitHubService-2R5GQG4K.js.map → ClaudeContextManager-RRGREEZQ.js.map} +0 -0
- /package/dist/{IssueTrackerFactory-XN6MQ4UN.js.map → ClaudeService-LEPW6QAC.js.map} +0 -0
- /package/dist/{MetadataManager-CMQQTFLQ.js.map → GitHubService-UTAYZXL3.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-IC6NAFGY.js.map → IssueTrackerFactory-KE2BDCLC.js.map} +0 -0
- /package/dist/{LoomLauncher-5AZU2F5I.js.map → LoomLauncher-GKQMR5E6.js.map} +0 -0
- /package/dist/{PromptTemplateManager-T5VTLJP3.js.map → MetadataManager-V4LSJ2PB.js.map} +0 -0
- /package/dist/{SettingsManager-WQ5NSGAH.js.map → ProjectCapabilityDetector-I4J66WKF.js.map} +0 -0
- /package/dist/{SettingsMigrationManager-S6J7OHUH.js.map → PromptTemplateManager-I75WKXM4.js.map} +0 -0
- /package/dist/{claude-ONQTDWV3.js.map → SettingsManager-KQU7OX7G.js.map} +0 -0
- /package/dist/{color-VQD52LOI.js.map → SettingsMigrationManager-ZPARZ5KH.js.map} +0 -0
- /package/dist/{darwin-5BHWRJ7D.js.map → browser-VZY7F2DF.js.map} +0 -0
- /package/dist/{build-OLS6J5KZ.js.map → build-V3KADFMO.js.map} +0 -0
- /package/dist/{chunk-XXFSOVL3.js.map → chunk-3XEXT35Z.js.map} +0 -0
- /package/dist/{chunk-LE2NOUTN.js.map → chunk-4VQXMEEP.js.map} +0 -0
- /package/dist/{chunk-G2MNSPA4.js.map → chunk-772N5WCA.js.map} +0 -0
- /package/dist/{chunk-NOMQ5RFG.js.map → chunk-7UBEHQTP.js.map} +0 -0
- /package/dist/{chunk-7NFCGKZT.js.map → chunk-AQUSMNBF.js.map} +0 -0
- /package/dist/{chunk-IDCE26KD.js.map → chunk-AUYSAMXV.js.map} +0 -0
- /package/dist/{chunk-K7R5QY6C.js.map → chunk-CE676WCN.js.map} +0 -0
- /package/dist/{chunk-LHDD4JHC.js.map → chunk-D4Q7T5KD.js.map} +0 -0
- /package/dist/{chunk-RBYTXYGD.js.map → chunk-D75KSI3V.js.map} +0 -0
- /package/dist/{chunk-SQYHPBFP.js.map → chunk-EGNUOALL.js.map} +0 -0
- /package/dist/{chunk-ZAXRQLK3.js.map → chunk-FTYWGQFM.js.map} +0 -0
- /package/dist/{chunk-5PNZBH6V.js.map → chunk-H3T3EPF3.js.map} +0 -0
- /package/dist/{chunk-VNYWBHKR.js.map → chunk-JD3K2344.js.map} +0 -0
- /package/dist/{chunk-6YVJVUR4.js.map → chunk-JDN4SPV3.js.map} +0 -0
- /package/dist/{chunk-NCPZYQ4B.js.map → chunk-K3QGG4O2.js.map} +0 -0
- /package/dist/{chunk-NH3QZYE5.js.map → chunk-KV4NU3RP.js.map} +0 -0
- /package/dist/{chunk-NDSGJZI2.js.map → chunk-LOAYWTJJ.js.map} +0 -0
- /package/dist/{chunk-GMDSYLI6.js.map → chunk-MY2Q3FJ3.js.map} +0 -0
- /package/dist/{chunk-CV47VCMQ.js.map → chunk-NPVA65KS.js.map} +0 -0
- /package/dist/{chunk-RMLADZRY.js.map → chunk-NTDY5AMO.js.map} +0 -0
- /package/dist/{chunk-7OCGBJLR.js.map → chunk-OIVFHJOA.js.map} +0 -0
- /package/dist/{chunk-NN5RYWXA.js.map → chunk-PH65MFQM.js.map} +0 -0
- /package/dist/{chunk-V4STTBQD.js.map → chunk-QED2WB2D.js.map} +0 -0
- /package/dist/{chunk-QNHZM5ZV.js.map → chunk-QXGM32TO.js.map} +0 -0
- /package/dist/{chunk-TZNNJLGT.js.map → chunk-RFCAPHL5.js.map} +0 -0
- /package/dist/{chunk-UDCI3QTS.js.map → chunk-SN4S5CWL.js.map} +0 -0
- /package/dist/{chunk-YETJNRQM.js.map → chunk-WEBMMJKL.js.map} +0 -0
- /package/dist/{chunk-KQFIGI37.js.map → chunk-XCP2WDYA.js.map} +0 -0
- /package/dist/{chunk-HLDY5S4C.js.map → chunk-ZUIFO7B4.js.map} +0 -0
- /package/dist/{git-BXUD6CL5.js.map → claude-ACL7G4CF.js.map} +0 -0
- /package/dist/{ignite-IO4LXVXJ.js.map → color-AC6F2QE7.js.map} +0 -0
- /package/dist/{commit-DC2Q5CDY.js.map → commit-SUHRUMDE.js.map} +0 -0
- /package/dist/{compile-4NCQECKE.js.map → compile-2MD346PO.js.map} +0 -0
- /package/dist/{installation-detector-HF6QN7KP.js.map → darwin-5K3I4FTH.js.map} +0 -0
- /package/dist/{mcp/darwin-3JFFE3W2.js.map → database-helpers-PRDFNDRO.js.map} +0 -0
- /package/dist/{feedback-BMAZGKRW.js.map → feedback-Q6WG2WX4.js.map} +0 -0
- /package/dist/{neon-helpers-HWIYRKOW.js.map → git-TX2IEMB3.js.map} +0 -0
- /package/dist/{prompt-7LZB4PAT.js.map → ignite-P644W2PK.js.map} +0 -0
- /package/dist/{init-CI43GJHV.js.map → init-5HFY7JG6.js.map} +0 -0
- /package/dist/{install-deps-SRTM5U7D.js.map → install-deps-J4ALTM27.js.map} +0 -0
- /package/dist/{remote-MZTFHHTU.js.map → installation-detector-PYAZ2O6U.js.map} +0 -0
- /package/dist/{lint-BSWRMGPZ.js.map → lint-XIXKU22H.js.map} +0 -0
- /package/dist/{linux-RYLOP2LY.js.map → linux-WUGRYCJY.js.map} +0 -0
- /package/dist/{update-notifier-EYLAXZAA.js.map → mcp/darwin-U25WIGH6.js.map} +0 -0
- /package/dist/mcp/{linux-JBVS4R3A.js.map → linux-5BXVBGSY.js.map} +0 -0
- /package/dist/mcp/{tmux-RYBLEHUZ.js.map → tmux-CU26ZTNM.js.map} +0 -0
- /package/dist/mcp/{wsl-4QZIQLLE.js.map → wsl-KI25UDOF.js.map} +0 -0
- /package/dist/{projects-IUSUXD5D.js.map → projects-L5AHUBGA.js.map} +0 -0
- /package/dist/{rebase-S6OHAOOF.js.map → rebase-MAMWPA2L.js.map} +0 -0
- /package/dist/{recap-GGVCG5VH.js.map → recap-IDBO3KM5.js.map} +0 -0
- /package/dist/{shell-W4SBQPTE.js.map → shell-7ADCDFIV.js.map} +0 -0
- /package/dist/{test-6JH4FE2X.js.map → test-SRB7EWU6.js.map} +0 -0
- /package/dist/{test-git-2KFFAQ6B.js.map → test-git-G7ATVIXG.js.map} +0 -0
- /package/dist/{test-jira-FKDKG6CD.js.map → test-jira-Q2HPA522.js.map} +0 -0
- /package/dist/{test-prefix-GP2DAX37.js.map → test-prefix-JMDGXR5A.js.map} +0 -0
- /package/dist/{test-tabs-YDWMWTVA.js.map → test-tabs-NGPTFD5T.js.map} +0 -0
- /package/dist/{test-webserver-QI3QQFZ3.js.map → test-webserver-GZFVXBGD.js.map} +0 -0
- /package/dist/{tmux-7ZTA3BDI.js.map → tmux-6LRFH3DM.js.map} +0 -0
- /package/dist/{update-XLW7R7FL.js.map → update-AD3GE5C4.js.map} +0 -0
- /package/dist/{vscode-TOGE5N67.js.map → vscode-3I7ISHUU.js.map} +0 -0
- /package/dist/{vscode-announcement-NIX7O2MG.js.map → vscode-announcement-AL3EHORH.js.map} +0 -0
- /package/dist/{wsl-Y4GUTOQ7.js.map → wsl-4VMVT2PO.js.map} +0 -0
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
import {
|
|
3
3
|
detectPackageManager,
|
|
4
4
|
runScript
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VIQOQ463.js";
|
|
6
6
|
import {
|
|
7
7
|
ProjectCapabilityDetector
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-772N5WCA.js";
|
|
9
9
|
import {
|
|
10
10
|
getPackageConfig,
|
|
11
11
|
hasScript
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-K3QGG4O2.js";
|
|
13
13
|
import {
|
|
14
14
|
detectClaudeCli,
|
|
15
15
|
launchClaude
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-DDHWZNGL.js";
|
|
17
17
|
import {
|
|
18
18
|
GitCommandError,
|
|
19
19
|
executeGitCommand,
|
|
@@ -21,16 +21,16 @@ import {
|
|
|
21
21
|
findMainWorktreePathWithSettings,
|
|
22
22
|
findWorktreeForBranch,
|
|
23
23
|
getMergeTargetBranch
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-QNPJXO53.js";
|
|
25
25
|
import {
|
|
26
26
|
SettingsManager
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-WGUGB54H.js";
|
|
28
28
|
import {
|
|
29
29
|
MetadataManager
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-4JZEQBWV.js";
|
|
31
31
|
import {
|
|
32
32
|
getLogger
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-FTYWGQFM.js";
|
|
34
34
|
|
|
35
35
|
// src/lib/MergeManager.ts
|
|
36
36
|
var MergeManager = class {
|
|
@@ -67,7 +67,7 @@ var MergeManager = class {
|
|
|
67
67
|
const isChildLoom = !!(metadata == null ? void 0 : metadata.parentLoom);
|
|
68
68
|
const settings = await this.settingsManager.loadSettings(worktreePath);
|
|
69
69
|
const mergeBehaviorMode = ((_a = settings.mergeBehavior) == null ? void 0 : _a.mode) ?? "local";
|
|
70
|
-
const isPRMode = mergeBehaviorMode === "
|
|
70
|
+
const isPRMode = mergeBehaviorMode === "pr" || mergeBehaviorMode === "draft-pr";
|
|
71
71
|
const useRemote = isPRMode && !isChildLoom;
|
|
72
72
|
let targetBranch;
|
|
73
73
|
if (useRemote) {
|
|
@@ -539,4 +539,4 @@ export {
|
|
|
539
539
|
MergeManager,
|
|
540
540
|
BuildRunner
|
|
541
541
|
};
|
|
542
|
-
//# sourceMappingURL=chunk-
|
|
542
|
+
//# sourceMappingURL=chunk-Q7VXHJP6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/MergeManager.ts","../src/lib/BuildRunner.ts"],"sourcesContent":["import { executeGitCommand, fetchOrigin, findMainWorktreePathWithSettings, findWorktreeForBranch, getMergeTargetBranch, GitCommandError } from '../utils/git.js'\nimport { getLogger } from '../utils/logger-context.js'\nimport { detectClaudeCli, launchClaude } from '../utils/claude.js'\nimport { SettingsManager } from './SettingsManager.js'\nimport { MetadataManager } from './MetadataManager.js'\nimport type { MergeOptions, RebaseOutcome } from '../types/index.js'\n\n/**\n * MergeManager handles Git rebase and fast-forward merge operations\n * Implements fail-fast behavior for conflicts (Phase 1 - no Claude assistance)\n *\n * Ports bash/merge-and-clean.sh lines 781-1090\n */\nexport class MergeManager {\n\tprivate settingsManager: SettingsManager\n\tprivate metadataManager: MetadataManager\n\n\tconstructor(settingsManager?: SettingsManager, metadataManager?: MetadataManager) {\n\t\tthis.settingsManager = settingsManager ?? new SettingsManager()\n\t\tthis.metadataManager = metadataManager ?? new MetadataManager()\n\t}\n\n\t/**\n\t * Get the merge target branch for a loom\n\t * Priority: parent loom metadata > configured main branch > 'main'\n\t * @param worktreePath - Optional path to load settings/metadata from (defaults to process.cwd())\n\t * @private\n\t */\n\tprivate async getMainBranch(worktreePath?: string): Promise<string> {\n\t\t// Delegate to shared utility function\n\t\treturn getMergeTargetBranch(worktreePath ?? process.cwd(), {\n\t\t\tsettingsManager: this.settingsManager,\n\t\t\tmetadataManager: this.metadataManager,\n\t\t})\n\t}\n\n\t/**\n\t * Rebase current branch on main with fail-fast on conflicts\n\t * Ports bash/merge-and-clean.sh lines 781-913\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @param options - Merge options (dryRun, force)\n\t * @throws Error if main branch doesn't exist, uncommitted changes exist, or conflicts occur\n\t */\n\tasync rebaseOnMain(worktreePath: string, options: MergeOptions = {}): Promise<RebaseOutcome> {\n\t\tconst { dryRun = false, force = false, jsonStream = false } = options\n\n\t\t// Pre-check: abort any in-progress rebase before starting a new one\n\t\tawait this.abortInProgressRebase(worktreePath)\n\n\t\tconst mainBranch = await this.getMainBranch(worktreePath)\n\n\t\t// Determine whether to use remote (origin/) or local branch reference\n\t\t// - Child looms: always use local parent branch (parent may not be pushed)\n\t\t// - PR modes (pr, draft-pr) for non-child: fetch and use origin/{branch}\n\t\t// - Local mode: use local branch (no fetch)\n\t\tconst metadata = await this.metadataManager.readMetadata(worktreePath)\n\t\tconst isChildLoom = !!metadata?.parentLoom\n\t\tconst settings = await this.settingsManager.loadSettings(worktreePath)\n\t\tconst mergeBehaviorMode = settings.mergeBehavior?.mode ?? 'local'\n\t\tconst isPRMode = mergeBehaviorMode === 'pr' || mergeBehaviorMode === 'draft-pr'\n\t\tconst useRemote = isPRMode && !isChildLoom\n\n\t\tlet targetBranch: string\n\t\tif (useRemote) {\n\t\t\t// PR modes (non-child): fetch and use origin/{branch}\n\t\t\tgetLogger().info('Fetching from origin...')\n\t\t\tawait fetchOrigin(worktreePath)\n\t\t\ttargetBranch = `origin/${mainBranch}`\n\t\t} else {\n\t\t\t// Local mode or child loom: use local branch\n\t\t\tgetLogger().info(`Using local branch ${mainBranch} for rebase...`)\n\t\t\ttargetBranch = mainBranch\n\t\t}\n\n\t\tgetLogger().info(`Starting rebase on ${targetBranch}...`)\n\n\t\t// Step 1: Check if branch exists (remote ref for origin/, local ref otherwise)\n\t\tconst refPath = useRemote ? `refs/remotes/${targetBranch}` : `refs/heads/${targetBranch}`\n\t\ttry {\n\t\t\tawait executeGitCommand(['show-ref', '--verify', '--quiet', refPath], {\n\t\t\t\tcwd: worktreePath,\n\t\t\t})\n\t\t} catch {\n\t\t\tif (useRemote) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Remote branch \"${targetBranch}\" does not exist. Cannot rebase.\\n` +\n\t\t\t\t\t\t`Ensure the repository has a \"${mainBranch}\" branch on origin.`\n\t\t\t\t)\n\t\t\t} else {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Local branch \"${targetBranch}\" does not exist. Cannot rebase.\\n` +\n\t\t\t\t\t\t`Ensure the branch exists locally.`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Step 2: Check for uncommitted changes and create WIP commit if needed\n\t\tconst statusOutput = await executeGitCommand(['status', '--porcelain'], {\n\t\t\tcwd: worktreePath,\n\t\t})\n\n\t\tlet wipCommitHash: string | null = null\n\t\tif (statusOutput.trim()) {\n\t\t\tgetLogger().info('Uncommitted changes detected, creating temporary WIP commit...')\n\t\t\twipCommitHash = await this.createWipCommit(worktreePath)\n\t\t\tgetLogger().debug(`Created WIP commit: ${wipCommitHash}`)\n\t\t}\n\n\t\t// Step 3: Check if rebase is needed by comparing merge-base with target HEAD\n\t\tconst mergeBase = await executeGitCommand(['merge-base', targetBranch, 'HEAD'], {\n\t\t\tcwd: worktreePath,\n\t\t})\n\n\t\tconst targetHead = await executeGitCommand(['rev-parse', targetBranch], {\n\t\t\tcwd: worktreePath,\n\t\t})\n\n\t\tconst mergeBaseTrimmed = mergeBase.trim()\n\t\tconst targetHeadTrimmed = targetHead.trim()\n\n\t\t// If merge-base matches target HEAD, branch is already up to date\n\t\tif (mergeBaseTrimmed === targetHeadTrimmed) {\n\t\t\tgetLogger().success(`Branch is already up to date with ${targetBranch}. No rebase needed.`)\n\t\t\t// Restore WIP commit if created (soft reset to remove temporary commit)\n\t\t\tif (wipCommitHash) {\n\t\t\t\tawait this.restoreWipCommit(worktreePath, wipCommitHash)\n\t\t\t}\n\t\t\treturn { conflictsDetected: false, claudeLaunched: false, conflictsResolved: false }\n\t\t}\n\n\t\t// Step 4: Show commits to be rebased (for informational purposes)\n\t\tconst commitsOutput = await executeGitCommand(['log', '--oneline', `${targetBranch}..HEAD`], {\n\t\t\tcwd: worktreePath,\n\t\t})\n\n\t\tconst commits = commitsOutput.trim()\n\t\tconst commitLines = commits ? commits.split('\\n') : []\n\n\t\tif (commits) {\n\t\t\t// Show commits that will be rebased\n\t\t\tgetLogger().info(`Found ${commitLines.length} commit(s) to rebase:`)\n\t\t\tcommitLines.forEach((commit) => getLogger().info(` ${commit}`))\n\t\t} else {\n\t\t\t// Target has moved forward but branch has no new commits\n\t\t\tgetLogger().info(`${targetBranch} has moved forward. Rebasing to update branch...`)\n\t\t}\n\n\t\t// Step 5: User confirmation (unless force mode or dry-run)\n\t\tif (!force && !dryRun) {\n\t\t\t// TODO: Implement interactive prompt for confirmation\n\t\t\t// For now, proceeding automatically (use --force to skip this message)\n\t\t\tgetLogger().info('Proceeding with rebase... (use --force to skip confirmations)')\n\t\t}\n\n\t\t// Step 6: Execute rebase (unless dry-run)\n\t\tif (dryRun) {\n\t\t\tgetLogger().info(`[DRY RUN] Would execute: git rebase ${targetBranch}`)\n\t\t\tif (commitLines.length > 0) {\n\t\t\t\tgetLogger().info(`[DRY RUN] This would rebase ${commitLines.length} commit(s)`)\n\t\t\t}\n\t\t\treturn { conflictsDetected: false, claudeLaunched: false, conflictsResolved: false }\n\t\t}\n\n\t\t// Execute rebase\n\t\t// Use -c core.hooksPath=/dev/null to disable hooks during rebase\n\t\t// This prevents pre-commit hooks from running when commits are re-applied\n\t\ttry {\n\t\t\tawait executeGitCommand(['-c', 'core.hooksPath=/dev/null', 'rebase', targetBranch], { cwd: worktreePath })\n\t\t\tgetLogger().success('Rebase completed successfully!')\n\n\t\t\t// Restore WIP commit if created\n\t\t\tif (wipCommitHash) {\n\t\t\t\tawait this.restoreWipCommit(worktreePath, wipCommitHash)\n\t\t\t}\n\t\t\treturn { conflictsDetected: false, claudeLaunched: false, conflictsResolved: false }\n\t\t} catch (error) {\n\t\t\t// Detect conflicts\n\t\t\tconst conflictedFiles = await this.detectConflictedFiles(worktreePath)\n\n\t\t\tif (conflictedFiles.length > 0) {\n\t\t\t\t// Try Claude-assisted resolution first\n\t\t\t\tgetLogger().info('Merge conflicts detected, attempting Claude-assisted resolution...')\n\n\t\t\t\tconst resolved = await this.attemptClaudeConflictResolution(\n\t\t\t\t\tworktreePath,\n\t\t\t\t\tconflictedFiles,\n\t\t\t\t\t{ jsonStream }\n\t\t\t\t)\n\n\t\t\t\tif (resolved) {\n\t\t\t\t\tgetLogger().success('Conflicts resolved with Claude assistance, rebase completed')\n\n\t\t\t\t\t// Restore WIP commit if created\n\t\t\t\t\tif (wipCommitHash) {\n\t\t\t\t\t\tawait this.restoreWipCommit(worktreePath, wipCommitHash)\n\t\t\t\t\t}\n\t\t\t\t\treturn { conflictsDetected: true, claudeLaunched: true, conflictsResolved: true }\n\t\t\t\t}\n\n\t\t\t\t// Claude couldn't resolve or not available - fail fast\n\t\t\t\tconst conflictError = this.formatConflictError(conflictedFiles)\n\t\t\t\tthrow new Error(conflictError)\n\t\t\t}\n\n\t\t\t// If not a conflict, re-throw the original error\n\t\t\tthrow new Error(\n\t\t\t\t`Rebase failed: ${error instanceof Error ? error.message : String(error)}\\n` +\n\t\t\t\t\t'Run: git status for more details\\n' +\n\t\t\t\t\t'Or: git rebase --abort to cancel the rebase'\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Validate that fast-forward merge is possible\n\t * Ports bash/merge-and-clean.sh lines 957-968\n\t *\n\t * @param branchName - Name of the branch to merge\n\t * @param mainWorktreePath - Path where main branch is checked out\n\t * @throws Error if fast-forward is not possible\n\t */\n\tasync validateFastForwardPossible(mainBranch: string, branchName: string, mainWorktreePath: string): Promise<void> {\n\n\t\t// Step 1: Get merge-base between main and branch\n\t\tconst mergeBase = await executeGitCommand(['merge-base', mainBranch, branchName], {\n\t\t\tcwd: mainWorktreePath,\n\t\t})\n\n\t\t// Step 2: Get current HEAD of main\n\t\tconst mainHead = await executeGitCommand(['rev-parse', mainBranch], {\n\t\t\tcwd: mainWorktreePath,\n\t\t})\n\n\t\t// Step 3: Compare - they must match for fast-forward\n\t\tconst mergeBaseTrimmed = mergeBase.trim()\n\t\tconst mainHeadTrimmed = mainHead.trim()\n\n\t\tif (mergeBaseTrimmed !== mainHeadTrimmed) {\n\t\t\tthrow new Error(\n\t\t\t\t'Cannot perform fast-forward merge.\\n' +\n\t\t\t\t\t`The ${mainBranch} branch has moved forward since this branch was created.\\n` +\n\t\t\t\t\t`Merge base: ${mergeBaseTrimmed}\\n` +\n\t\t\t\t\t`Main HEAD: ${mainHeadTrimmed}\\n\\n` +\n\t\t\t\t\t'To fix this:\\n' +\n\t\t\t\t\t` 1. Rebase the branch on ${mainBranch}: git rebase ${mainBranch}\\n` +\n\t\t\t\t\t` 2. Or use: il finish to automatically rebase and merge\\n`\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Perform fast-forward only merge\n\t * Ports bash/merge-and-clean.sh lines 938-994\n\t *\n\t * @param branchName - Name of the branch to merge\n\t * @param worktreePath - Path to the worktree\n\t * @param options - Merge options (dryRun, force)\n\t * @throws Error if checkout, validation, or merge fails\n\t */\n\tasync performFastForwardMerge(\n\t\tbranchName: string,\n\t\tworktreePath: string,\n\t\toptions: MergeOptions = {}\n\t): Promise<void> {\n\t\tconst { dryRun = false, force = false } = options\n\n\t\tgetLogger().info('Starting fast-forward merge...')\n\n\t\t// Step 1: Get the merge target branch FIRST\n\t\t// For child looms, this will be the parent branch from metadata\n\t\t// For regular looms, this falls back to settings.mainBranch or 'main'\n\t\tconst mainBranch = await this.getMainBranch(worktreePath)\n\n\t\t// Step 2: Find where the merge target branch is checked out\n\t\t// CRITICAL: We must find the worktree for the MERGE TARGET, not settings.mainBranch\n\t\t// This fixes the child loom bug where we'd find the 'main' worktree instead of the parent branch worktree\n\t\tlet mainWorktreePath: string\n\t\tif (options.repoRoot) {\n\t\t\tmainWorktreePath = options.repoRoot\n\t\t} else {\n\t\t\ttry {\n\t\t\t\t// First try to find worktree with the exact merge target branch checked out\n\t\t\t\tmainWorktreePath = await findWorktreeForBranch(mainBranch, worktreePath)\n\t\t\t} catch {\n\t\t\t\t// Fallback: if no worktree has the branch checked out, use settings-based lookup\n\t\t\t\t// This handles edge cases like bare repos or detached HEAD states\n\t\t\t\tgetLogger().debug(`No worktree found for branch '${mainBranch}', falling back to settings-based lookup`)\n\t\t\t\tmainWorktreePath = await findMainWorktreePathWithSettings(worktreePath, this.settingsManager)\n\t\t\t}\n\t\t}\n\n\t\t// Step 3: No need to checkout - the merge target branch is already checked out in mainWorktreePath\n\t\tgetLogger().debug(`Using ${mainBranch} branch location: ${mainWorktreePath}`)\n\n\t\t// Step 4: Verify we're on the correct branch\n\t\tconst currentBranch = await executeGitCommand(['branch', '--show-current'], {\n\t\t\tcwd: mainWorktreePath,\n\t\t})\n\n\t\tif (currentBranch.trim() !== mainBranch) {\n\t\t\tthrow new Error(\n\t\t\t\t`Expected ${mainBranch} branch but found: ${currentBranch.trim()}\\n` +\n\t\t\t\t\t`At location: ${mainWorktreePath}\\n` +\n\t\t\t\t\t'This indicates the main worktree detection failed.'\n\t\t\t)\n\t\t}\n\n\t\t// Step 5: Validate fast-forward is possible\n\t\tawait this.validateFastForwardPossible(mainBranch, branchName, mainWorktreePath)\n\n\t\t// Step 6: Show commits to be merged\n\t\tconst commitsOutput = await executeGitCommand(['log', '--oneline', `${mainBranch}..${branchName}`], {\n\t\t\tcwd: mainWorktreePath,\n\t\t})\n\n\t\tconst commits = commitsOutput.trim()\n\n\t\t// If no commits, branch has no changes ahead of main\n\t\tif (!commits) {\n\t\t\tgetLogger().success(`Branch has no commits ahead of ${mainBranch}. No merge needed.`)\n\t\t\treturn\n\t\t}\n\n\t\t// Show commits that will be merged\n\t\tconst commitLines = commits.split('\\n')\n\t\tgetLogger().info(`Found ${commitLines.length} commit(s) to merge:`)\n\t\tcommitLines.forEach((commit) => getLogger().info(` ${commit}`))\n\n\t\t// Step 7: User confirmation (unless force mode or dry-run)\n\t\tif (!force && !dryRun) {\n\t\t\t// TODO: Implement interactive prompt for confirmation\n\t\t\t// For now, proceeding automatically (use --force to skip this message)\n\t\t\tgetLogger().info('Proceeding with fast-forward merge... (use --force to skip confirmations)')\n\t\t}\n\n\t\t// Step 8: Execute merge (unless dry-run)\n\t\tif (dryRun) {\n\t\t\tgetLogger().info(`[DRY RUN] Would execute: git merge --ff-only ${branchName}`)\n\t\t\tgetLogger().info(`[DRY RUN] This would merge ${commitLines.length} commit(s)`)\n\t\t\treturn\n\t\t}\n\n\t\t// Execute fast-forward merge\n\t\ttry {\n\t\t\tgetLogger().debug(`Executing fast-forward merge of ${branchName} into ${mainBranch} using cwd: ${mainWorktreePath}...`)\n\t\t\tawait executeGitCommand(['merge', '--ff-only', branchName], { cwd: mainWorktreePath })\n\t\t\tgetLogger().success(`Fast-forward merge completed! Merged ${commitLines.length} commit(s).`)\n\t\t} catch (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Fast-forward merge failed: ${error instanceof Error ? error.message : String(error)}\\n\\n` +\n\t\t\t\t\t'To recover:\\n' +\n\t\t\t\t\t' 1. Check merge status: git status\\n' +\n\t\t\t\t\t' 2. Abort merge if needed: git merge --abort\\n' +\n\t\t\t\t\t' 3. Verify branch is rebased: git rebase main\\n' +\n\t\t\t\t\t' 4. Try merge again: il finish'\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Helper: Detect conflicted files after failed rebase\n\t * @private\n\t */\n\tprivate async detectConflictedFiles(worktreePath: string): Promise<string[]> {\n\t\ttry {\n\t\t\tconst output = await executeGitCommand(['diff', '--name-only', '--diff-filter=U'], {\n\t\t\t\tcwd: worktreePath,\n\t\t\t})\n\n\t\t\treturn output\n\t\t\t\t.trim()\n\t\t\t\t.split('\\n')\n\t\t\t\t.filter((file) => file.length > 0)\n\t\t} catch {\n\t\t\t// If command fails, return empty array (might not be a conflict)\n\t\t\treturn []\n\t\t}\n\t}\n\n\t/**\n\t * Create a temporary WIP commit to preserve uncommitted changes during rebase\n\t * Stages all changes (tracked, untracked) using git add -A\n\t * Uses --no-verify to skip pre-commit hooks since this is a temporary internal commit\n\t * @param worktreePath - Path to the worktree\n\t * @returns The commit hash of the WIP commit\n\t * @private\n\t */\n\tprivate async createWipCommit(worktreePath: string): Promise<string> {\n\t\t// Stage all changes including untracked files\n\t\tawait executeGitCommand(['add', '-A'], { cwd: worktreePath })\n\n\t\t// Create WIP commit with distinctive message\n\t\t// Use --no-verify to skip pre-commit hooks - this is a temporary internal commit\n\t\tawait executeGitCommand(['commit', '--no-verify', '-m', 'WIP: Auto-stash for rebase'], { cwd: worktreePath })\n\n\t\t// Get and return the commit hash\n\t\tconst hash = await executeGitCommand(['rev-parse', 'HEAD'], { cwd: worktreePath })\n\t\treturn hash.trim()\n\t}\n\n\t/**\n\t * Restore uncommitted changes from WIP commit via soft reset\n\t * Logs warning but does not fail if soft reset fails (changes are safe in commit history)\n\t * @param worktreePath - Path to the worktree\n\t * @param wipCommitHash - Original WIP commit hash for verification logging\n\t * @private\n\t */\n\tprivate async restoreWipCommit(worktreePath: string, wipCommitHash: string): Promise<void> {\n\t\tgetLogger().info('Restoring uncommitted changes from WIP commit...')\n\n\t\ttry {\n\t\t\t// Soft reset to parent - changes become staged\n\t\t\tawait executeGitCommand(['reset', '--soft', 'HEAD~1'], { cwd: worktreePath })\n\n\t\t\t// Unstage files to restore to original working directory state\n\t\t\tawait executeGitCommand(['reset', 'HEAD'], { cwd: worktreePath })\n\n\t\t\tgetLogger().success('Restored uncommitted changes from WIP commit')\n\t\t} catch (error) {\n\t\t\t// Log warning but consider rebase successful - work is not lost\n\t\t\tgetLogger().warn(\n\t\t\t\t`Failed to restore WIP commit (${wipCommitHash}). ` +\n\t\t\t\t\t`Your changes are safe in the commit history. ` +\n\t\t\t\t\t`Manual recovery: git reset --soft HEAD~1`,\n\t\t\t\t{ error: error instanceof Error ? error.message : String(error) }\n\t\t\t)\n\t\t}\n\t}\n\n\t/**\n\t * Helper: Format conflict error message with manual resolution steps\n\t * @private\n\t */\n\tprivate formatConflictError(conflictedFiles: string[]): string {\n\t\tconst fileList = conflictedFiles.map((file) => ` • ${file}`).join('\\n')\n\n\t\treturn (\n\t\t\t'Rebase failed - merge conflicts detected in:\\n' +\n\t\t\tfileList +\n\t\t\t'\\n\\n' +\n\t\t\t'To resolve manually:\\n' +\n\t\t\t' 1. Fix conflicts in the files above\\n' +\n\t\t\t' 2. Stage resolved files: git add <files>\\n' +\n\t\t\t' 3. Continue rebase: git rebase --continue\\n' +\n\t\t\t' 4. Or abort rebase: git rebase --abort\\n' +\n\t\t\t' 5. Then re-run: il finish <issue-number>'\n\t\t)\n\t}\n\n\t/**\n\t * Attempt to resolve conflicts using Claude\n\t * Ports bash/merge-and-clean.sh lines 839-894\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @param conflictedFiles - List of files with conflicts\n\t * @returns true if conflicts resolved, false otherwise\n\t * @private\n\t */\n\tprivate async attemptClaudeConflictResolution(\n\t\tworktreePath: string,\n\t\tconflictedFiles: string[],\n\t\toptions: { jsonStream?: boolean } = {}\n\t): Promise<boolean> {\n\t\t// Check if Claude CLI is available\n\t\tconst isClaudeAvailable = await detectClaudeCli()\n\t\tif (!isClaudeAvailable) {\n\t\t\tgetLogger().debug('Claude CLI not available, skipping conflict resolution')\n\t\t\treturn false\n\t\t}\n\n\t\tgetLogger().info(`Launching Claude to resolve conflicts in ${conflictedFiles.length} file(s)...`)\n\n\t\t// Hard-coded prompt matching bash script line 844\n\t\t// No templates, no complexity - just the essential instruction\n\t\tconst systemPrompt =\n\t\t\t`Please help resolve the git rebase conflicts in this repository. ` +\n\t\t\t`Analyze the conflicted files, understand the changes from both branches, ` +\n\t\t\t`fix the conflicts, then run 'git add .' to stage the resolved files, ` +\n\t\t\t`and finally run 'git rebase --continue' to continue the rebase process. ` +\n\t\t\t`Once the issue is resolved, tell the user they can use /exit to continue with the process.`\n\n\t\tconst prompt =\n\t\t\t`Help me with this rebase please.`\n\n\t\t// Git commands to auto-approve during rebase conflict resolution\n\t\t// These are the essential commands Claude needs to analyze and resolve conflicts\n\t\t// Note: git reset and git checkout are intentionally excluded as they can be destructive\n\t\tconst rebaseAllowedTools = [\n\t\t\t'Bash(git status:*)',\n\t\t\t'Bash(git diff:*)',\n\t\t\t'Bash(git log:*)',\n\t\t\t'Bash(git add:*)',\n\t\t\t'Bash(git rebase:*)',\n\t\t\t'Bash(GIT_EDITOR=true git rebase:*)',\n\t\t]\n\n\t\ttry {\n\t\t\t// Launch Claude interactively in current terminal\n\t\t\t// User will interact directly with Claude to resolve conflicts\n\t\t\t// When jsonStream is true, run headless with stdout passthrough for JSONL streaming\n\t\t\tawait launchClaude(prompt, {\n\t\t\t\tappendSystemPrompt: systemPrompt,\n\t\t\t\taddDir: worktreePath,\n\t\t\t\theadless: options.jsonStream ? true : false,\n\t\t\t\t...(options.jsonStream && {\n\t\t\t\t\tpermissionMode: 'bypassPermissions' as const,\n\t\t\t\t\tpassthroughStdout: true,\n\t\t\t\t}),\n\t\t\t\tallowedTools: rebaseAllowedTools,\n\t\t\t\tnoSessionPersistence: true, // Utility operation - no session persistence needed\n\t\t\t})\n\n\t\t\t// After Claude interaction completes, check if conflicts resolved\n\t\t\tconst remainingConflicts = await this.detectConflictedFiles(worktreePath)\n\n\t\t\tif (remainingConflicts.length > 0) {\n\t\t\t\tgetLogger().warn(\n\t\t\t\t\t`Conflicts still exist in ${remainingConflicts.length} file(s) after Claude assistance`\n\t\t\t\t)\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// Check if rebase completed or still in progress\n\t\t\tconst rebaseInProgress = await this.isRebaseInProgress(worktreePath)\n\n\t\t\tif (rebaseInProgress) {\n\t\t\t\tgetLogger().warn('Rebase still in progress after Claude assistance')\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tgetLogger().warn('Claude conflict resolution failed', {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t})\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Check if a git rebase is currently in progress\n\t * Checks for .git/rebase-merge or .git/rebase-apply directories\n\t * Ports bash script logic from lines 853-856\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @returns true if rebase in progress, false otherwise\n\t * @private\n\t */\n\tprivate async isRebaseInProgress(worktreePath: string): Promise<boolean> {\n\t\tconst fs = await import('node:fs/promises')\n\t\tconst path = await import('node:path')\n\n\t\t// In git worktrees, .git is a file pointing to the actual git dir.\n\t\t// Use git rev-parse to resolve the real git directory.\n\t\tconst gitDir = (await executeGitCommand(\n\t\t\t['rev-parse', '--absolute-git-dir'],\n\t\t\t{ cwd: worktreePath }\n\t\t)).trim()\n\n\t\tconst rebaseMergePath = path.join(gitDir, 'rebase-merge')\n\t\tconst rebaseApplyPath = path.join(gitDir, 'rebase-apply')\n\n\t\t// Check for rebase-merge directory\n\t\ttry {\n\t\t\tawait fs.access(rebaseMergePath)\n\t\t\treturn true\n\t\t} catch {\n\t\t\t// Directory doesn't exist, continue checking\n\t\t}\n\n\t\t// Check for rebase-apply directory\n\t\ttry {\n\t\t\tawait fs.access(rebaseApplyPath)\n\t\t\treturn true\n\t\t} catch {\n\t\t\t// Directory doesn't exist\n\t\t}\n\n\t\treturn false\n\t}\n\n\t/**\n\t * Abort an in-progress rebase if one is detected\n\t * This handles cases where a previous rebase was interrupted (e.g., terminal closed,\n\t * Claude session ended, user manually stopped) and the worktree is left in a dirty state.\n\t * Since we're about to start a new rebase, the stale rebase state is irrelevant and safe to abort.\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @private\n\t */\n\tprivate async abortInProgressRebase(worktreePath: string): Promise<void> {\n\t\tconst rebaseInProgress = await this.isRebaseInProgress(worktreePath)\n\n\t\tif (!rebaseInProgress) {\n\t\t\treturn\n\t\t}\n\n\t\tgetLogger().warn('A rebase is already in progress. Aborting the stale rebase before proceeding...')\n\n\t\ttry {\n\t\t\tawait executeGitCommand(['rebase', '--abort'], { cwd: worktreePath })\n\t\t\tgetLogger().info('Stale rebase aborted successfully.')\n\t\t} catch (error) {\n\t\t\t// Handle race condition: rebase may have been resolved between check and abort\n\t\t\tconst errorMsg = error instanceof Error ? error.message : String(error)\n\t\t\tif (errorMsg.includes('No rebase in progress')) {\n\t\t\t\tgetLogger().info('Rebase was already resolved by another process.')\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (error instanceof GitCommandError) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to abort in-progress rebase: ${error.message}\\n` +\n\t\t\t\t\t\t'Manual recovery: run \"git rebase --abort\" in the worktree directory.'\n\t\t\t\t)\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n}\n","import { getLogger } from '../utils/logger-context.js'\nimport { detectPackageManager, runScript } from '../utils/package-manager.js'\nimport { getPackageConfig, hasScript } from '../utils/package-json.js'\nimport { ProjectCapabilityDetector } from './ProjectCapabilityDetector.js'\n\nexport interface BuildOptions {\n\tdryRun?: boolean\n}\n\nexport interface BuildResult {\n\tsuccess: boolean\n\tskipped: boolean\n\treason?: string\n\tduration: number\n}\n\n/**\n * BuildRunner handles post-merge build verification for CLI projects\n * Only runs build when project has CLI capabilities (bin field in package.json)\n */\nexport class BuildRunner {\n\tprivate capabilityDetector: ProjectCapabilityDetector\n\n\tconstructor(capabilityDetector?: ProjectCapabilityDetector) {\n\t\tthis.capabilityDetector = capabilityDetector ?? new ProjectCapabilityDetector()\n\t}\n\n\t/**\n\t * Run build verification in the specified directory\n\t * @param buildPath - Path where build should run (typically main worktree path)\n\t * @param options - Build options\n\t */\n\tasync runBuild(buildPath: string, options: BuildOptions = {}): Promise<BuildResult> {\n\t\tconst startTime = Date.now()\n\n\t\ttry {\n\t\t\t// Step 1: Check if build script exists (checks .iloom/package.iloom.json first, then package.json)\n\t\t\tconst pkgJson = await getPackageConfig(buildPath)\n\t\t\tconst hasBuildScript = hasScript(pkgJson, 'build')\n\n\t\t\tif (!hasBuildScript) {\n\t\t\tgetLogger().debug('Skipping build - no build script found')\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tskipped: true,\n\t\t\t\t\treason: 'No build script found in package configuration',\n\t\t\t\t\tduration: Date.now() - startTime,\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Handle missing package.json - skip build for non-Node.js projects without package.iloom.json\n\t\t\tif (error instanceof Error && error.message.includes('package.json not found')) {\n\t\t\tgetLogger().debug('Skipping build - no package configuration found')\n\t\t\t\treturn {\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tskipped: true,\n\t\t\t\t\treason: 'No package configuration found in project',\n\t\t\t\t\tduration: Date.now() - startTime,\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Re-throw other errors\n\t\t\tthrow error\n\t\t}\n\n\t\t// Step 2: Check if project has CLI capability (bin field)\n\t\tconst capabilities = await this.capabilityDetector.detectCapabilities(buildPath)\n\t\tconst isCLIProject = capabilities.capabilities.includes('cli')\n\n\t\tif (!isCLIProject) {\n\t\tgetLogger().debug('Skipping build - not a CLI project (no bin field)')\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tskipped: true,\n\t\t\t\treason: 'Project is not a CLI project (no bin field in package.json)',\n\t\t\t\tduration: Date.now() - startTime,\n\t\t\t}\n\t\t}\n\n\t\t// Step 3: Detect package manager\n\t\tconst packageManager = await detectPackageManager(buildPath)\n\n\t\t// Step 4: Handle dry-run mode\n\t\tif (options.dryRun) {\n\t\t\tconst command =\n\t\t\t\tpackageManager === 'npm' ? 'npm run build' : `${packageManager} build`\n\t\tgetLogger().info(`[DRY RUN] Would run: ${command}`)\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tskipped: false,\n\t\t\t\tduration: Date.now() - startTime,\n\t\t\t}\n\t\t}\n\n\t\t// Step 5: Execute build\n\tgetLogger().info('Running build...')\n\n\t\ttry {\n\t\t\tawait runScript('build', buildPath, [], { quiet: true })\n\t\tgetLogger().success('Build completed successfully')\n\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tskipped: false,\n\t\t\t\tduration: Date.now() - startTime,\n\t\t\t}\n\t\t} catch {\n\t\t\t// Step 6: Throw detailed error on failure\n\t\t\tconst runCommand =\n\t\t\t\tpackageManager === 'npm' ? 'npm run build' : `${packageManager} build`\n\n\t\t\tthrow new Error(\n\t\t\t\t`Error: Build failed.\\n` +\n\t\t\t\t\t`Fix build errors before proceeding.\\n\\n` +\n\t\t\t\t\t`Run '${runCommand}' to see detailed errors.`\n\t\t\t)\n\t\t}\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/providers/bitbucket/BitBucketVCSProvider.ts"],"sourcesContent":["// BitBucketVCSProvider - Implements VersionControlProvider for BitBucket\n// Provides PR/VCS operations via BitBucket REST API\n\nimport type { VersionControlProvider, ExistingPR, PRCreationResult, ReviewComment } from '../../VersionControlProvider.js'\nimport type { PullRequest } from '../../../types/index.js'\nimport { BitBucketApiClient, type BitBucketConfig, type BitBucketPullRequest } from './BitBucketApiClient.js'\nimport type { IloomSettings } from '../../SettingsManager.js'\nimport { getLogger } from '../../../utils/logger-context.js'\nimport { parseGitRemotes } from '../../../utils/remote.js'\n\n/**\n * BitBucket-specific configuration\n * Extends BitBucketConfig with username, appPassword, workspace, and repoSlug\n */\nexport interface BitBucketVCSConfig extends BitBucketConfig {\n\treviewers?: string[] // Usernames of reviewers to add to PRs\n}\n\n/**\n * BitBucketVCSProvider implements VersionControlProvider for BitBucket\n * \n * Key differences from GitHub:\n * - Uses workspace/repository slug instead of owner/repo\n * - PR states are different (OPEN, MERGED, DECLINED, SUPERSEDED)\n * - No native draft PR support\n */\nexport class BitBucketVCSProvider implements VersionControlProvider {\n\treadonly providerName = 'bitbucket'\n\treadonly supportsForks = true\n\treadonly supportsDraftPRs = false // BitBucket doesn't have draft PRs\n\n\tprivate readonly client: BitBucketApiClient\n\tprivate readonly reviewerUsernames?: string[]\n\n\t/**\n\t * Create a BitBucketVCSProvider from IloomSettings\n\t * Extracts and validates BitBucket config from settings\n\t */\n\tstatic fromSettings(settings: IloomSettings): BitBucketVCSProvider {\n\t\tconst bbSettings = settings.versionControl?.bitbucket\n\n\t\tif (!bbSettings?.username) {\n\t\t\tthrow new Error('BitBucket username is required. Configure versionControl.bitbucket.username in .iloom/settings.json')\n\t\t}\n\t\tif (!bbSettings?.apiToken) {\n\t\t\tthrow new Error('BitBucket API token is required. Configure versionControl.bitbucket.apiToken in .iloom/settings.local.json')\n\t\t}\n\n\t\tconst config: BitBucketVCSConfig = {\n\t\t\tusername: bbSettings.username,\n\t\t\tapiToken: bbSettings.apiToken,\n\t\t}\n\n\t\tif (bbSettings.workspace) {\n\t\t\tconfig.workspace = bbSettings.workspace\n\t\t}\n\t\tif (bbSettings.repoSlug) {\n\t\t\tconfig.repoSlug = bbSettings.repoSlug\n\t\t}\n\t\tif (bbSettings.reviewers) {\n\t\t\tconfig.reviewers = bbSettings.reviewers\n\t\t}\n\n\t\treturn new BitBucketVCSProvider(config)\n\t}\n\n\tconstructor(config: BitBucketVCSConfig) {\n\t\tthis.client = new BitBucketApiClient(config)\n\t\tif (config.reviewers) {\n\t\t\tthis.reviewerUsernames = config.reviewers\n\t\t}\n\t}\n\n\t/**\n\t * Check if a PR already exists for the given branch\n\t */\n\tasync checkForExistingPR(branchName: string, cwd?: string): Promise<ExistingPR | null> {\n\t\ttry {\n\t\t\t// Get workspace and repo slug from config or detect from git remote\n\t\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\t\tconst prs = await this.client.listPullRequests(workspace, repoSlug, branchName)\n\t\t\t\n\t\t\tif (prs.length > 0 && prs[0]) {\n\t\t\t\tconst pr = prs[0]\n\t\t\t\treturn {\n\t\t\t\t\tnumber: pr.id,\n\t\t\t\t\turl: pr.links.html.href,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) {\n\t\t\t\tconst statusMatch = error.message.match(/BitBucket API error \\((\\d+)\\)/)\n\t\t\t\tif (statusMatch?.[1]) {\n\t\t\t\t\tconst statusCode = parseInt(statusMatch[1], 10)\n\t\t\t\t\tif (statusCode === 401 || statusCode === 403) {\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tgetLogger().debug('Error checking for existing PR', { error })\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Create a pull request\n\t */\n\tasync createPR(\n\t\tbranchName: string,\n\t\ttitle: string,\n\t\tbody: string,\n\t\tbaseBranch: string,\n\t\tcwd?: string\n\t): Promise<PRCreationResult> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\t// Log the target repository so users can verify it's correct\n\t\tgetLogger().info(`Creating BitBucket PR in ${workspace}/${repoSlug}`)\n\t\tgetLogger().debug('PR details', { branchName, title, baseBranch })\n\n\t\t// Resolve reviewer usernames to account IDs if configured\n\t\tlet reviewerIds: string[] | undefined\n\t\tif (this.reviewerUsernames && this.reviewerUsernames.length > 0) {\n\t\t\treviewerIds = await this.resolveReviewerUsernames(workspace, this.reviewerUsernames)\n\n\t\t\t// Filter out the current user from reviewers (BitBucket doesn't allow PR author as reviewer)\n\t\t\tif (reviewerIds.length > 0) {\n\t\t\t\tconst currentUser = await this.client.getCurrentUser()\n\t\t\t\tconst originalCount = reviewerIds.length\n\t\t\t\treviewerIds = reviewerIds.filter(id => id !== currentUser.account_id)\n\n\t\t\t\tif (reviewerIds.length < originalCount) {\n\t\t\t\t\tgetLogger().debug(\n\t\t\t\t\t\t`Removed current user (${currentUser.display_name}) from reviewers list - PR author cannot be a reviewer`\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst pr = await this.client.createPullRequest(\n\t\t\tworkspace,\n\t\t\trepoSlug,\n\t\t\ttitle,\n\t\t\tbody,\n\t\t\tbranchName,\n\t\t\tbaseBranch,\n\t\t\treviewerIds\n\t\t)\n\n\t\t// Validate the response structure\n\t\tif (!pr?.id || !pr?.links?.html?.href) {\n\t\t\tgetLogger().error('Invalid BitBucket API response', { pr })\n\t\t\tthrow new Error(\n\t\t\t\t`BitBucket API returned invalid PR response. ` +\n\t\t\t\t`Expected PR with id and links.html.href, got: ${JSON.stringify(pr)}`\n\t\t\t)\n\t\t}\n\n\t\tgetLogger().info(`BitBucket PR #${pr.id} created successfully`)\n\t\treturn { url: pr.links.html.href, number: pr.id, wasExisting: false }\n\t}\n\n\t/**\n\t * Fetch PR details\n\t */\n\tasync fetchPR(prNumber: number, cwd?: string): Promise<PullRequest> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\tconst bbPR = await this.client.getPullRequest(workspace, repoSlug, prNumber)\n\t\treturn this.mapBitBucketPRToPullRequest(bbPR)\n\t}\n\n\t/**\n\t * Get PR URL\n\t */\n\tasync getPRUrl(prNumber: number, cwd?: string): Promise<string> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\tconst bbPR = await this.client.getPullRequest(workspace, repoSlug, prNumber)\n\t\treturn bbPR.links.html.href\n\t}\n\n\t/**\n\t * Create a comment on a PR\n\t */\n\tasync createPRComment(prNumber: number, body: string, cwd?: string): Promise<{ id: string; url: string }> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\tgetLogger().debug('Creating BitBucket PR comment', { workspace, repoSlug, prNumber })\n\n\t\tconst comment = await this.client.addPRComment(workspace, repoSlug, prNumber, body)\n\t\treturn { id: String(comment.id), url: comment.links.html.href }\n\t}\n\n\t/**\n\t * Update an existing comment on a PR\n\t */\n\tasync updatePRComment(prNumber: number, commentId: string, body: string, cwd?: string): Promise<{ id: string; url: string }> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\tgetLogger().debug('Updating BitBucket PR comment', { workspace, repoSlug, prNumber, commentId })\n\n\t\tconst numericCommentId = parseInt(commentId, 10)\n\t\tif (isNaN(numericCommentId)) {\n\t\t\tthrow new Error(`Invalid comment ID \"${commentId}\": expected a numeric value`)\n\t\t}\n\n\t\tconst comment = await this.client.updatePRComment(workspace, repoSlug, prNumber, numericCommentId, body)\n\t\treturn { id: String(comment.id), url: comment.links.html.href }\n\t}\n\n\t/**\n\t * Get inline review comments on a PR\n\t * Fetches all comments and filters for those with inline metadata\n\t */\n\tasync getReviewComments(prNumber: number, cwd?: string): Promise<ReviewComment[]> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\tgetLogger().debug('Fetching BitBucket PR review comments', { workspace, repoSlug, prNumber })\n\n\t\tconst allComments = await this.client.listPRComments(workspace, repoSlug, prNumber)\n\n\t\t// Filter for inline comments only (those with inline metadata) and map to ReviewComment\n\t\tconst inlineComments: ReviewComment[] = []\n\t\tfor (const c of allComments) {\n\t\t\tif (c.inline == null) continue\n\t\t\tinlineComments.push({\n\t\t\t\tid: String(c.id),\n\t\t\t\tbody: c.content.raw,\n\t\t\t\tpath: c.inline.path,\n\t\t\t\tline: c.inline.to ?? c.inline.from ?? null,\n\t\t\t\tside: null, // BitBucket doesn't have a \"side\" concept like GitHub\n\t\t\t\tauthor: c.user\n\t\t\t\t\t? { id: c.user.uuid, displayName: c.user.display_name }\n\t\t\t\t\t: null,\n\t\t\t\tcreatedAt: c.created_on ?? '',\n\t\t\t\tupdatedAt: c.updated_on ?? null,\n\t\t\t\tinReplyToId: null, // BitBucket uses nested comments, not reply chains\n\t\t\t})\n\t\t}\n\t\treturn inlineComments\n\t}\n\n\t/**\n\t * Create an inline review comment on a specific file and line in a PR\n\t */\n\tasync createReviewComment(prNumber: number, path: string, line: number, body: string, cwd?: string): Promise<{ id: string; url: string }> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\n\t\tgetLogger().debug('Creating BitBucket inline PR comment', { workspace, repoSlug, prNumber, path, line })\n\n\t\tconst comment = await this.client.addInlinePRComment(workspace, repoSlug, prNumber, body, path, line)\n\t\treturn { id: String(comment.id), url: comment.links.html.href }\n\t}\n\n\t/**\n\t * List open pull requests for the repository\n\t * Uses getWorkspaceAndRepo for auto-detection from git remotes\n\t */\n\tasync listPullRequests(cwd?: string): Promise<BitBucketPullRequest[]> {\n\t\tconst { workspace, repoSlug } = await this.getWorkspaceAndRepo(cwd)\n\t\treturn this.client.listPullRequests(workspace, repoSlug)\n\t}\n\n\t/**\n\t * Detect repository from git remote\n\t */\n\tasync detectRepository(cwd?: string): Promise<{ owner: string; repo: string } | null> {\n\t\ttry {\n\t\t\tconst remotes = await parseGitRemotes(cwd)\n\t\t\t\n\t\t\t// Look for bitbucket.org remote\n\t\t\tconst bbRemote = remotes.find(r => \n\t\t\t\tr.url.includes('bitbucket.org')\n\t\t\t)\n\n\t\t\tif (!bbRemote) {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\t// BitBucket URLs: https://bitbucket.org/workspace/repo.git\n\t\t\t// or git@bitbucket.org:workspace/repo.git\n\t\t\treturn {\n\t\t\t\towner: bbRemote.owner, // workspace\n\t\t\t\trepo: bbRemote.repo,\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tgetLogger().error('Failed to detect BitBucket repository', { error })\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Get target remote for PR operations\n\t */\n\tasync getTargetRemote(_cwd?: string): Promise<string> {\n\t\t// For BitBucket, we typically use 'origin'\n\t\t// Fork workflows are less common in BitBucket\n\t\treturn 'origin'\n\t}\n\n\t/**\n\t * Get workspace and repository slug from config or git remote\n\t */\n\tprivate async getWorkspaceAndRepo(cwd?: string): Promise<{ workspace: string; repoSlug: string }> {\n\t\tlet workspace = this.client.getWorkspace()\n\t\tlet repoSlug = this.client.getRepoSlug()\n\n\t\t// If not configured, try to detect from git remote\n\t\tif (!workspace || !repoSlug) {\n\t\t\tconst detected = await this.detectRepository(cwd)\n\t\t\tif (!detected) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t'Could not determine BitBucket workspace/repository. ' +\n\t\t\t\t\t'Either configure them in settings or ensure git remote points to bitbucket.org'\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tworkspace = workspace ?? detected.owner\n\t\t\trepoSlug = repoSlug ?? detected.repo\n\t\t}\n\n\t\treturn { workspace, repoSlug }\n\t}\n\n\t/**\n\t * Resolve reviewer usernames to BitBucket account IDs\n\t * Warns for any usernames that cannot be resolved but continues with partial list\n\t */\n\tprivate async resolveReviewerUsernames(workspace: string, usernames: string[]): Promise<string[]> {\n\t\tgetLogger().debug(`Resolving ${usernames.length} reviewer username(s) to BitBucket account IDs`)\n\n\t\tconst usernameToAccountId = await this.client.findUsersByUsername(workspace, usernames)\n\n\t\tconst resolvedIds: string[] = []\n\t\tconst unresolvedUsernames: string[] = []\n\n\t\tfor (const username of usernames) {\n\t\t\tconst accountId = usernameToAccountId.get(username)\n\t\t\tif (accountId) {\n\t\t\t\tresolvedIds.push(accountId)\n\t\t\t} else {\n\t\t\t\tunresolvedUsernames.push(username)\n\t\t\t}\n\t\t}\n\n\t\tif (unresolvedUsernames.length > 0) {\n\t\t\tgetLogger().warn(\n\t\t\t\t`Could not resolve ${unresolvedUsernames.length} reviewer username(s) to BitBucket account IDs: ${unresolvedUsernames.join(', ')}. ` +\n\t\t\t\t`These reviewers will not be added to the PR.`\n\t\t\t)\n\t\t}\n\n\t\tif (resolvedIds.length > 0) {\n\t\t\tgetLogger().info(`Resolved ${resolvedIds.length} reviewer(s) for PR`)\n\t\t}\n\n\t\treturn resolvedIds\n\t}\n\n\t/**\n\t * Map BitBucket PR to generic PullRequest type\n\t */\n\tprivate mapBitBucketPRToPullRequest(bbPR: BitBucketPullRequest): PullRequest {\n\t\t// Map BitBucket states to generic states\n\t\tlet state: 'open' | 'closed' | 'merged'\n\t\tif (bbPR.state === 'OPEN') {\n\t\t\tstate = 'open'\n\t\t} else if (bbPR.state === 'MERGED') {\n\t\t\tstate = 'merged'\n\t\t} else {\n\t\t\tstate = 'closed' // DECLINED or SUPERSEDED\n\t\t}\n\n\t\treturn {\n\t\t\tnumber: bbPR.id,\n\t\t\ttitle: bbPR.title,\n\t\t\tbody: bbPR.description,\n\t\t\tstate,\n\t\t\tbranch: bbPR.source.branch.name,\n\t\t\tbaseBranch: bbPR.destination.branch.name,\n\t\t\turl: bbPR.links.html.href,\n\t\t\tisDraft: false, // BitBucket doesn't have draft PRs\n\t\t}\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
IdentifierParser
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SN4S5CWL.js";
|
|
5
5
|
import {
|
|
6
6
|
runScript
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
getPackageScripts
|
|
10
|
-
} from "./chunk-NCPZYQ4B.js";
|
|
7
|
+
} from "./chunk-VIQOQ463.js";
|
|
11
8
|
import {
|
|
12
9
|
GitWorktreeManager
|
|
13
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4VQXMEEP.js";
|
|
11
|
+
import {
|
|
12
|
+
getPackageScripts
|
|
13
|
+
} from "./chunk-K3QGG4O2.js";
|
|
14
14
|
import {
|
|
15
15
|
extractIssueNumber
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-QNPJXO53.js";
|
|
17
17
|
import {
|
|
18
18
|
logger
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-VRPPI6GU.js";
|
|
20
20
|
|
|
21
21
|
// src/commands/script-command-base.ts
|
|
22
22
|
import path from "path";
|
|
@@ -156,4 +156,4 @@ var ScriptCommandBase = class {
|
|
|
156
156
|
export {
|
|
157
157
|
ScriptCommandBase
|
|
158
158
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-QED2WB2D.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SettingsManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WGUGB54H.js";
|
|
5
5
|
import {
|
|
6
6
|
MetadataManager
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-4JZEQBWV.js";
|
|
8
8
|
import {
|
|
9
9
|
logger
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-VRPPI6GU.js";
|
|
11
11
|
|
|
12
12
|
// src/utils/git.ts
|
|
13
13
|
import path from "path";
|
|
@@ -375,7 +375,7 @@ async function getDefaultBranch(path2 = process.cwd()) {
|
|
|
375
375
|
}
|
|
376
376
|
async function findAllBranchesForIssue(issueNumber, path2 = process.cwd(), settingsManager) {
|
|
377
377
|
if (!settingsManager) {
|
|
378
|
-
const { SettingsManager: SM } = await import("./SettingsManager-
|
|
378
|
+
const { SettingsManager: SM } = await import("./SettingsManager-KQU7OX7G.js");
|
|
379
379
|
settingsManager = new SM();
|
|
380
380
|
}
|
|
381
381
|
const protectedBranches = await settingsManager.getProtectedBranches(path2);
|
|
@@ -738,4 +738,4 @@ export {
|
|
|
738
738
|
removePlaceholderCommitFromHead,
|
|
739
739
|
removePlaceholderCommitFromHistory
|
|
740
740
|
};
|
|
741
|
-
//# sourceMappingURL=chunk-
|
|
741
|
+
//# sourceMappingURL=chunk-QNPJXO53.js.map
|