@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/DevServerManager.ts","../src/lib/DockerDevServerStrategy.ts","../src/lib/NativeDevServerStrategy.ts","../src/utils/dev-server.ts"],"sourcesContent":["import path from 'path'\nimport { ProcessManager } from './process/ProcessManager.js'\nimport { DockerManager, type DockerConfig } from './DockerManager.js'\nimport { DockerDevServerStrategy, type DockerConfig as StrategyDockerConfig, type DockerUtils } from './DockerDevServerStrategy.js'\nimport { NativeDevServerStrategy } from './NativeDevServerStrategy.js'\nimport { logger } from '../utils/logger.js'\n\n/**\n * Default startup timeout in milliseconds (180 seconds)\n * Can be overridden via ILOOM_DEV_SERVER_TIMEOUT environment variable\n */\nconst DEFAULT_STARTUP_TIMEOUT = 180000\n\n/**\n * Bridge DockerManager static methods to the DockerUtils interface\n * expected by DockerDevServerStrategy.\n */\nconst dockerUtils: DockerUtils = {\n\tparseDockerfileExpose: (filePath: string) => DockerManager.parseExposeFromDockerfile(filePath),\n\tinspectImagePorts: (imageName: string) => DockerManager.inspectImagePorts(imageName),\n\tbuildContainerName: (id: string | number) => DockerManager.buildContainerName(id),\n\tbuildImageName: (id: string | number) => DockerManager.buildImageName(id),\n\tassertDockerAvailable: () => DockerManager.assertAvailable(),\n}\n\nfunction getStartupTimeout(): number {\n\tconst envTimeout = process.env.ILOOM_DEV_SERVER_TIMEOUT\n\tif (envTimeout) {\n\t\tconst parsed = parseInt(envTimeout, 10)\n\t\tif (!isNaN(parsed) && parsed > 0) {\n\t\t\treturn parsed\n\t\t}\n\t}\n\treturn DEFAULT_STARTUP_TIMEOUT\n}\n\nexport interface DevServerManagerOptions {\n\t/**\n\t * Maximum time to wait for server to start (in milliseconds)\n\t * Default: 180000 (180 seconds)\n\t * Can be overridden via ILOOM_DEV_SERVER_TIMEOUT environment variable\n\t */\n\tstartupTimeout?: number\n\n\t/**\n\t * Interval between port checks (in milliseconds)\n\t * Default: 1000 (1 second)\n\t */\n\tcheckInterval?: number\n}\n\n// Re-export DockerConfig from DockerManager for backward compatibility\nexport type { DockerConfig } from './DockerManager.js'\n\n/**\n * Convert a DockerConfig (from DockerManager) to a StrategyDockerConfig\n * (for DockerDevServerStrategy).\n */\nfunction toStrategyConfig(config: DockerConfig): StrategyDockerConfig {\n\treturn {\n\t\tdockerFile: config.dockerFile,\n\t\tcontainerPort: config.containerPort,\n\t\tbuildArgs: config.dockerBuildArgs,\n\t\trunArgs: config.dockerRunArgs,\n\t\tidentifier: config.identifier,\n\t}\n}\n\n/**\n * DevServerManager handles auto-starting and monitoring dev servers.\n * Used by open/run commands to ensure dev server is running before opening browser.\n *\n * When devServer config is absent OR mode is not 'docker', behavior is identical\n * to the native process-based implementation via NativeDevServerStrategy.\n * When Docker mode is configured, all operations delegate to DockerDevServerStrategy.\n */\nexport class DevServerManager {\n\tprivate readonly processManager: ProcessManager\n\tprivate readonly options: Required<DevServerManagerOptions>\n\tprivate readonly nativeStrategy: NativeDevServerStrategy\n\tprivate runningDockerContainers: Map<number, string> = new Map()\n\n\tconstructor(\n\t\tprocessManager?: ProcessManager,\n\t\toptions: DevServerManagerOptions = {}\n\t) {\n\t\tthis.processManager = processManager ?? new ProcessManager()\n\t\tthis.options = {\n\t\t\tstartupTimeout: options.startupTimeout ?? getStartupTimeout(),\n\t\t\tcheckInterval: options.checkInterval ?? 1000,\n\t\t}\n\t\tthis.nativeStrategy = new NativeDevServerStrategy(\n\t\t\tthis.processManager,\n\t\t\tthis.options.startupTimeout,\n\t\t\tthis.options.checkInterval\n\t\t)\n\t}\n\n\t/**\n\t * Create a DockerDevServerStrategy for the given Docker config.\n\t * The strategy encapsulates all Docker container lifecycle operations.\n\t */\n\tprivate createDockerStrategy(dockerConfig: DockerConfig): DockerDevServerStrategy {\n\t\treturn new DockerDevServerStrategy(toStrategyConfig(dockerConfig), dockerUtils)\n\t}\n\n\t/**\n\t * Ensure dev server is running on the specified port.\n\t * If not running, start it and wait for it to be ready.\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @param port - Port the server should run on\n\t * @param dockerConfig - Optional Docker configuration for container-based server\n\t * @returns true if server is ready, false if startup failed/timed out\n\t */\n\tasync ensureServerRunning(worktreePath: string, port: number, dockerConfig?: DockerConfig): Promise<boolean> {\n\t\tlogger.debug(`Checking if dev server is running on port ${port}...`)\n\n\t\t// Docker mode: check if container is already running\n\t\tif (dockerConfig) {\n\t\t\tconst strategy = this.createDockerStrategy(dockerConfig)\n\t\t\tconst containerName = dockerUtils.buildContainerName(dockerConfig.identifier)\n\t\t\tconst isRunning = await strategy.isContainerRunning(containerName)\n\t\t\tif (isRunning) {\n\t\t\t\tlogger.debug(`Docker container \"${containerName}\" already running on port ${port}`)\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tlogger.info(`Docker dev server not running on port ${port}, starting...`)\n\t\t\ttry {\n\t\t\t\tawait this.startDockerServer(worktreePath, port, dockerConfig, strategy)\n\t\t\t\treturn true\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\n\t\t\t\t\t`Failed to start Docker dev server: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t\t)\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// Native mode: check if a process is listening on the port\n\t\tconst existingProcess = await this.processManager.detectDevServer(port)\n\t\tif (existingProcess) {\n\t\t\tlogger.debug(\n\t\t\t\t`Dev server already running on port ${port} (PID: ${existingProcess.pid})`\n\t\t\t)\n\t\t\treturn true\n\t\t}\n\n\t\t// Not running - start it\n\t\tlogger.info(`Dev server not running on port ${port}, starting...`)\n\n\t\ttry {\n\t\t\tawait this.nativeStrategy.startBackground(worktreePath, port)\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tlogger.error(\n\t\t\t\t`Failed to start dev server: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t)\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Start dev server in Docker container (background) and wait for it to be ready.\n\t * Builds the image, resolves the container port, starts the container detached,\n\t * and polls the host port for readiness.\n\t */\n\tprivate async startDockerServer(\n\t\tworktreePath: string,\n\t\tport: number,\n\t\tdockerConfig: DockerConfig,\n\t\tstrategy: DockerDevServerStrategy\n\t): Promise<void> {\n\t\tconst strategyConfig = toStrategyConfig(dockerConfig)\n\t\tconst imageName = dockerUtils.buildImageName(dockerConfig.identifier)\n\t\tconst dockerfilePath = path.resolve(worktreePath, dockerConfig.dockerFile)\n\n\t\t// Build image\n\t\tawait strategy.buildImage(worktreePath, strategyConfig)\n\n\t\t// Resolve container port (config > image inspect > Dockerfile EXPOSE)\n\t\tconst containerPort = await strategy.resolveContainerPort(\n\t\t\tstrategyConfig,\n\t\t\timageName,\n\t\t\tdockerfilePath\n\t\t)\n\n\t\t// Run container detached\n\t\tconst containerName = await strategy.runContainerDetached(\n\t\t\tworktreePath,\n\t\t\tport,\n\t\t\tcontainerPort,\n\t\t\tstrategyConfig\n\t\t)\n\n\t\t// Track for cleanup\n\t\tthis.runningDockerContainers.set(port, containerName)\n\n\t\t// Wait for server to be ready via TCP probe (Docker proxy listens on host port)\n\t\t// Pass container name for early crash detection\n\t\tlogger.info(`Waiting for Docker dev server to start on port ${port}...`)\n\t\tconst ready = await strategy.waitForReady(\n\t\t\tport,\n\t\t\tthis.options.startupTimeout,\n\t\t\tthis.options.checkInterval,\n\t\t\tcontainerName\n\t\t)\n\n\t\tif (!ready) {\n\t\t\t// Clean up the container if startup failed\n\t\t\tawait strategy.stopContainer(containerName)\n\t\t\tthis.runningDockerContainers.delete(port)\n\t\t\tthrow new Error(\n\t\t\t\t`Docker dev server failed to start within ${this.options.startupTimeout}ms timeout`\n\t\t\t)\n\t\t}\n\n\t\tlogger.success(`Docker dev server started successfully on port ${port}`)\n\t}\n\n\t/**\n\t * Check if a dev server is running on the specified port\n\t *\n\t * @param port - Port to check\n\t * @param dockerConfig - Optional Docker configuration; when provided, checks container status\n\t * @returns true if server is running, false otherwise\n\t */\n\tasync isServerRunning(port: number, dockerConfig?: DockerConfig): Promise<boolean> {\n\t\tif (dockerConfig) {\n\t\t\tconst strategy = this.createDockerStrategy(dockerConfig)\n\t\t\tconst containerName = dockerUtils.buildContainerName(dockerConfig.identifier)\n\t\t\treturn strategy.isContainerRunning(containerName)\n\t\t}\n\t\tconst existingProcess = await this.processManager.detectDevServer(port)\n\t\treturn existingProcess !== null\n\t}\n\n\t/**\n\t * Run dev server in foreground mode (blocking).\n\t * This method blocks until the server is stopped (e.g., via Ctrl+C).\n\t *\n\t * @param worktreePath - Path to the worktree\n\t * @param port - Port the server should run on\n\t * @param redirectToStderr - If true, redirect stdout/stderr to stderr (useful for JSON output)\n\t * @param onProcessStarted - Callback called immediately after process starts with PID\n\t * @returns Process information including PID\n\t */\n\tasync runServerForeground(\n\t\tworktreePath: string,\n\t\tport: number,\n\t\tredirectToStderr = false,\n\t\tonProcessStarted?: (pid?: number) => void,\n\t\tenvOverrides?: Record<string, string>,\n\t\tdockerConfig?: DockerConfig\n\t): Promise<{ pid?: number }> {\n\t\t// Docker mode: build image and run container in foreground\n\t\tif (dockerConfig) {\n\t\t\tlogger.debug(`Starting Docker dev server in foreground on port ${port}`)\n\n\t\t\tconst strategy = this.createDockerStrategy(dockerConfig)\n\t\t\tconst strategyConfig = toStrategyConfig(dockerConfig)\n\t\t\tconst imageName = dockerUtils.buildImageName(dockerConfig.identifier)\n\t\t\tconst containerName = dockerUtils.buildContainerName(dockerConfig.identifier)\n\t\t\tconst dockerfilePath = path.resolve(worktreePath, dockerConfig.dockerFile)\n\n\t\t\t// Build image\n\t\t\tawait strategy.buildImage(worktreePath, strategyConfig)\n\n\t\t\t// Resolve container port\n\t\t\tconst containerPort = await strategy.resolveContainerPort(\n\t\t\t\tstrategyConfig,\n\t\t\t\timageName,\n\t\t\t\tdockerfilePath\n\t\t\t)\n\n\t\t\tif (onProcessStarted) {\n\t\t\t\tonProcessStarted(undefined)\n\t\t\t}\n\n\t\t\t// Track container for cleanup\n\t\t\tthis.runningDockerContainers.set(port, containerName)\n\t\t\ttry {\n\t\t\t\t// Run container in foreground (blocks until stopped)\n\t\t\t\t// DockerDevServerStrategy.runContainerForeground handles signal forwarding internally\n\t\t\t\tawait strategy.runContainerForeground(\n\t\t\t\t\tworktreePath,\n\t\t\t\t\tport,\n\t\t\t\t\tcontainerPort,\n\t\t\t\t\tstrategyConfig,\n\t\t\t\t\t{ redirectToStderr, envOverrides }\n\t\t\t\t)\n\t\t\t} finally {\n\t\t\t\tthis.runningDockerContainers.delete(port)\n\t\t\t}\n\n\t\t\treturn {}\n\t\t}\n\n\t\t// Native mode: delegate to NativeDevServerStrategy\n\t\treturn this.nativeStrategy.startForeground(worktreePath, port, {\n\t\t\tredirectToStderr,\n\t\t\t...(onProcessStarted !== undefined && { onProcessStarted }),\n\t\t\t...(envOverrides !== undefined && { envOverrides }),\n\t\t})\n\t}\n\n\t/**\n\t * Clean up all running server processes and Docker containers.\n\t * This should be called when the manager is being disposed.\n\t */\n\tasync cleanup(): Promise<void> {\n\t\t// Clean up native process-based servers\n\t\tawait this.nativeStrategy.stopAll()\n\n\t\t// Clean up Docker containers using DockerDevServerStrategy\n\t\tfor (const [port, containerName] of this.runningDockerContainers.entries()) {\n\t\t\ttry {\n\t\t\t\tlogger.debug(`Cleaning up Docker container \"${containerName}\" on port ${port}`)\n\t\t\t\t// Create a minimal strategy just for stopContainer\n\t\t\t\tconst strategy = new DockerDevServerStrategy({}, dockerUtils)\n\t\t\t\tawait strategy.stopContainer(containerName)\n\t\t\t} catch (error) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Failed to stop Docker container \"${containerName}\" on port ${port}: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tthis.runningDockerContainers.clear()\n\t}\n}\n","import { execa } from 'execa'\nimport net from 'net'\nimport { logger } from '../utils/logger.js'\nimport { restoreTerminalState } from '../utils/terminal.js'\n\n/**\n * Docker configuration shape consumed by DockerDevServerStrategy.\n * Matches the DevServerSettings['docker'] shape from the settings schema.\n */\nexport interface DockerConfig {\n\t/** Path to Dockerfile (relative to worktree) */\n\tdockerFile?: string | undefined\n\t/** Port inside the container (auto-detected from image inspect or Dockerfile EXPOSE if not set) */\n\tcontainerPort?: number | undefined\n\t/** Build arguments passed as --build-arg to docker build */\n\tbuildArgs?: Record<string, string> | undefined\n\t/** Additional docker run flags */\n\trunArgs?: string[] | undefined\n\t/** Identifier for naming containers/images (issue number, branch name). Falls back to worktreePath if not set. */\n\tidentifier?: string | undefined\n}\n\n/**\n * Options for runContainerForeground.\n */\nexport interface RunForegroundOptions {\n\t/** If true, redirect stdout/stderr to process.stderr */\n\tredirectToStderr?: boolean | undefined\n\t/** Called immediately after the container starts */\n\tonProcessStarted?: ((pid?: number) => void) | undefined\n\t/** Additional environment variables to forward into the container */\n\tenvOverrides?: Record<string, string> | undefined\n}\n\n/**\n * Utility function contracts from the docker-utils sibling issue.\n * Coded against these shapes so this class compiles without waiting for the sibling merge.\n */\ntype ParseDockerfileExposeFn = (path: string) => Promise<number | null>\ntype InspectImagePortsFn = (name: string) => Promise<number | null>\ntype BuildContainerNameFn = (id: string | number) => string\ntype BuildImageNameFn = (id: string | number) => string\ntype AssertDockerAvailableFn = () => Promise<void>\n\n/**\n * Injected docker utility functions.\n * Default implementations are imported from DockerManager for backward compatibility\n * until the dedicated docker-utils module is merged.\n */\nexport interface DockerUtils {\n\tparseDockerfileExpose: ParseDockerfileExposeFn\n\tinspectImagePorts: InspectImagePortsFn\n\tbuildContainerName: BuildContainerNameFn\n\tbuildImageName: BuildImageNameFn\n\tassertDockerAvailable: AssertDockerAvailableFn\n}\n\n/**\n * Attempt a single TCP connection to localhost:port.\n * Resolves true if the connection succeeds, false otherwise.\n */\nfunction tcpProbe(port: number): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = net.createConnection({ port, host: '127.0.0.1' })\n\t\tsocket.once('connect', () => {\n\t\t\tsocket.destroy()\n\t\t\tresolve(true)\n\t\t})\n\t\tsocket.once('error', () => {\n\t\t\tsocket.destroy()\n\t\t\tresolve(false)\n\t\t})\n\t})\n}\n\n/**\n * DockerDevServerStrategy handles the full Docker container lifecycle for a dev server:\n * - Image building\n * - Container running (detached and foreground)\n * - Container stopping\n * - Readiness detection via TCP probe\n * - Port resolution (3-tier: config > image inspect > Dockerfile EXPOSE)\n *\n * This class is the core Docker logic delegated to by DevServerManager.\n * It does NOT modify DevServerManager, ResourceCleanup, or CLI commands.\n */\nexport class DockerDevServerStrategy {\n\tprivate readonly utils: DockerUtils\n\n\tconstructor(_config: DockerConfig, utils: DockerUtils) {\n\t\tthis.utils = utils\n\t}\n\n\t/**\n\t * Resolve the container port using 3-tier fallback:\n\t * 1. config.containerPort (explicit)\n\t * 2. inspectImagePorts(imageName) (from built image)\n\t * 3. parseDockerfileExpose(dockerfilePath) (from Dockerfile)\n\t *\n\t * Throws a clear error if all three return null.\n\t *\n\t * @param config - Docker config (may override the constructor config)\n\t * @param imageName - Name of the built Docker image\n\t * @param dockerfilePath - Absolute path to the Dockerfile\n\t */\n\tasync resolveContainerPort(\n\t\tconfig: DockerConfig,\n\t\timageName: string,\n\t\tdockerfilePath: string\n\t): Promise<number> {\n\t\tif (config.containerPort !== undefined) {\n\t\t\treturn config.containerPort\n\t\t}\n\n\t\tconst inspectedPort = await this.utils.inspectImagePorts(imageName)\n\t\tif (inspectedPort !== null) {\n\t\t\tlogger.debug(`Auto-detected container port ${inspectedPort} from Docker image inspect`)\n\t\t\treturn inspectedPort\n\t\t}\n\n\t\tconst exposedPort = await this.utils.parseDockerfileExpose(dockerfilePath)\n\t\tif (exposedPort !== null) {\n\t\t\tlogger.debug(`Auto-detected container port ${exposedPort} from Dockerfile EXPOSE directive`)\n\t\t\treturn exposedPort\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t'Cannot determine container port. Set `devServer.docker.containerPort` in settings or add an `EXPOSE` directive to your Dockerfile.'\n\t\t)\n\t}\n\n\t/**\n\t * Build a Docker image for the worktree.\n\t * Build context is always the worktree root directory.\n\t *\n\t * @param worktreePath - Absolute path to the worktree (build context)\n\t * @param config - Docker config with Dockerfile path and build args\n\t */\n\tasync buildImage(worktreePath: string, config: DockerConfig): Promise<void> {\n\t\tconst imageName = this.utils.buildImageName(config.identifier ?? worktreePath)\n\t\tconst dockerfilePath = config.dockerFile ?? './Dockerfile'\n\n\t\tconst args = ['build', '-t', imageName, '-f', dockerfilePath]\n\n\t\tif (config.buildArgs) {\n\t\t\tfor (const [key, value] of Object.entries(config.buildArgs)) {\n\t\t\t\targs.push('--build-arg', `${key}=${value}`)\n\t\t\t}\n\t\t}\n\n\t\t// Context is always the worktree root\n\t\targs.push('.')\n\n\t\tlogger.info(`Building Docker image \"${imageName}\" from ${dockerfilePath}...`)\n\n\t\ttry {\n\t\t\tawait execa('docker', args, {\n\t\t\t\tcwd: worktreePath,\n\t\t\t\tstdio: 'inherit',\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error'\n\t\t\tthrow new Error(`Docker build failed for image \"${imageName}\": ${message}`)\n\t\t}\n\n\t\tlogger.success(`Docker image \"${imageName}\" built successfully`)\n\t}\n\n\t/**\n\t * Run a container in detached (background) mode.\n\t * Force-removes any existing container with the same name first.\n\t * Mounts the worktree at /app and adds an anonymous volume for node_modules.\n\t * Forwards PORT and any envOverrides into the container.\n\t *\n\t * @param worktreePath - Absolute path to the worktree (mounted at /app)\n\t * @param hostPort - Port on the host to map\n\t * @param containerPort - Port inside the container\n\t * @param config - Docker config with run args\n\t * @param envOverrides - Additional environment variables to set in the container\n\t * @returns The container name\n\t */\n\tasync runContainerDetached(\n\t\tworktreePath: string,\n\t\thostPort: number,\n\t\tcontainerPort: number,\n\t\tconfig: DockerConfig,\n\t\tenvOverrides?: Record<string, string>\n\t): Promise<string> {\n\t\tconst nameId = config.identifier ?? worktreePath\n\t\tconst imageName = this.utils.buildImageName(nameId)\n\t\tconst containerName = this.utils.buildContainerName(nameId)\n\n\t\t// Force-remove any existing container with same name\n\t\tawait execa('docker', ['rm', '-f', containerName], { reject: false })\n\n\t\tconst args = [\n\t\t\t'run', '-d',\n\t\t\t'--name', containerName,\n\t\t\t'-p', `${hostPort}:${containerPort}`,\n\t\t\t// Mount worktree at /app\n\t\t\t'-v', `${worktreePath}:/app`,\n\t\t\t// Anonymous volume for node_modules to prevent host/container conflicts\n\t\t\t'-v', '/app/node_modules',\n\t\t\t// Forward PORT as the container port so the app listens where Docker expects.\n\t\t\t// The -p mapping handles host-to-container translation.\n\t\t\t'-e', `PORT=${containerPort}`,\n\t\t]\n\n\t\t// Forward additional environment variables\n\t\tif (envOverrides) {\n\t\t\tfor (const [key, value] of Object.entries(envOverrides)) {\n\t\t\t\targs.push('-e', `${key}=${value}`)\n\t\t\t}\n\t\t}\n\n\t\t// Additional run flags from config\n\t\tif (config.runArgs) {\n\t\t\targs.push(...config.runArgs)\n\t\t}\n\n\t\targs.push(imageName)\n\n\t\tlogger.info(`Starting Docker container \"${containerName}\" in background (http://localhost:${hostPort} → container:${containerPort})...`)\n\n\t\ttry {\n\t\t\tawait execa('docker', args)\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : 'Unknown error'\n\t\t\tthrow new Error(`Failed to start Docker container \"${containerName}\": ${message}`)\n\t\t}\n\n\t\tlogger.success(`Docker container \"${containerName}\" started on port ${hostPort}`)\n\t\treturn containerName\n\t}\n\n\t/**\n\t * Run a container in foreground (blocking) mode.\n\t * The container is automatically removed on exit (--rm flag).\n\t * Traps SIGINT and SIGTERM and forwards them to the container via docker stop.\n\t *\n\t * @param worktreePath - Absolute path to the worktree (mounted at /app)\n\t * @param hostPort - Port on the host to map\n\t * @param containerPort - Port inside the container\n\t * @param config - Docker config with run args\n\t * @param opts - Additional options (redirectToStderr, onProcessStarted, envOverrides)\n\t * @returns Object with optional pid (Docker containers don't expose host PID)\n\t */\n\tasync runContainerForeground(\n\t\tworktreePath: string,\n\t\thostPort: number,\n\t\tcontainerPort: number,\n\t\tconfig: DockerConfig,\n\t\topts: RunForegroundOptions = {}\n\t): Promise<{ pid?: number }> {\n\t\tconst nameId = config.identifier ?? worktreePath\n\t\tconst imageName = this.utils.buildImageName(nameId)\n\t\tconst containerName = this.utils.buildContainerName(nameId)\n\t\tconst { redirectToStderr, onProcessStarted, envOverrides } = opts\n\n\t\t// Force-remove any existing container with same name (stale from previous ungraceful exit)\n\t\tawait execa('docker', ['rm', '-f', containerName], { reject: false })\n\n\t\tconst args = [\n\t\t\t'run', '--rm',\n\t\t\t'--name', containerName,\n\t\t\t'-p', `${hostPort}:${containerPort}`,\n\t\t\t// Mount worktree at /app\n\t\t\t'-v', `${worktreePath}:/app`,\n\t\t\t// Anonymous volume for node_modules to prevent host/container conflicts\n\t\t\t'-v', '/app/node_modules',\n\t\t\t// Forward PORT as the container port so the app listens where Docker expects.\n\t\t\t// The -p mapping handles host-to-container translation.\n\t\t\t'-e', `PORT=${containerPort}`,\n\t\t]\n\n\t\t// Forward additional environment variables\n\t\tif (envOverrides) {\n\t\t\tfor (const [key, value] of Object.entries(envOverrides)) {\n\t\t\t\targs.push('-e', `${key}=${value}`)\n\t\t\t}\n\t\t}\n\n\t\t// Additional run flags from config\n\t\tif (config.runArgs) {\n\t\t\targs.push(...config.runArgs)\n\t\t}\n\n\t\targs.push(imageName)\n\n\t\tlogger.info(`Running Docker container \"${containerName}\" in foreground (http://localhost:${hostPort} → container:${containerPort})...`)\n\n\t\tconst stdio = redirectToStderr\n\t\t\t? [process.stdin, process.stderr, process.stderr] as const\n\t\t\t: 'inherit' as const\n\n\t\t// Signal forwarding: trap SIGINT/SIGTERM and forward to container\n\t\tconst forwardSignal = (): void => {\n\t\t\tlogger.debug(`Stopping container \"${containerName}\"`)\n\t\t\tvoid execa('docker', ['stop', containerName], { reject: false })\n\t\t}\n\n\t\tconst onSigint = (): void => forwardSignal()\n\t\tconst onSigterm = (): void => forwardSignal()\n\n\t\tprocess.on('SIGINT', onSigint)\n\t\tprocess.on('SIGTERM', onSigterm)\n\n\t\tif (onProcessStarted) {\n\t\t\tonProcessStarted(undefined)\n\t\t}\n\n\t\ttry {\n\t\t\tawait execa('docker', args, { stdio })\n\t\t} finally {\n\t\t\t// Clean up signal handlers to avoid leaks\n\t\t\tprocess.removeListener('SIGINT', onSigint)\n\t\t\tprocess.removeListener('SIGTERM', onSigterm)\n\t\t\trestoreTerminalState()\n\t\t}\n\n\t\treturn {}\n\t}\n\n\t/**\n\t * Stop and remove a container by name.\n\t * Uses docker rm -f which handles both running and stopped containers atomically.\n\t * Handles already-stopped containers gracefully (no error thrown).\n\t *\n\t * @param containerName - Name of the container to stop and remove\n\t */\n\tasync stopContainer(containerName: string): Promise<void> {\n\t\tlogger.debug(`Stopping and removing container \"${containerName}\"...`)\n\t\tawait execa('docker', ['rm', '-f', containerName], { reject: false })\n\t\tlogger.debug(`Container \"${containerName}\" stopped and removed`)\n\t}\n\n\t/**\n\t * Check if a named container is currently running.\n\t * Uses exact name matching with anchored regex to avoid partial name matches.\n\t *\n\t * @param containerName - Name of the container to check\n\t * @returns true if the container is running, false otherwise\n\t */\n\tasync isContainerRunning(containerName: string): Promise<boolean> {\n\t\ttry {\n\t\t\tconst result = await execa('docker', [\n\t\t\t\t'ps',\n\t\t\t\t'--filter', `name=^${containerName}$`,\n\t\t\t\t'--format', '{{.Names}}',\n\t\t\t], { reject: false })\n\n\t\t\treturn result.exitCode === 0 && result.stdout.trim() === containerName\n\t\t} catch {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Wait for the dev server to be ready by probing the TCP port.\n\t * Uses net.createConnection instead of lsof-based detection since Docker port\n\t * forwarding shows com.docker.backend as the listening process (not the dev server).\n\t * Exits early if the container has stopped (crash detection).\n\t *\n\t * @param port - Host port to probe\n\t * @param timeout - Maximum time to wait in milliseconds\n\t * @param interval - Interval between probes in milliseconds\n\t * @param containerName - Optional container name to monitor for early exit\n\t * @returns true if the port accepts connections within the timeout, false otherwise\n\t */\n\tasync waitForReady(port: number, timeout: number, interval: number, containerName?: string): Promise<boolean> {\n\t\tconst startTime = Date.now()\n\t\tlet attempts = 0\n\n\t\twhile (Date.now() - startTime < timeout) {\n\t\t\tattempts++\n\n\t\t\t// Early exit: if the container has stopped, stop polling\n\t\t\tif (containerName && attempts % 3 === 0) {\n\t\t\t\tconst stillRunning = await this.isContainerRunning(containerName)\n\t\t\t\tif (!stillRunning) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t`Docker container \"${containerName}\" exited before becoming ready (after ${attempts} attempts, ${Date.now() - startTime}ms)`\n\t\t\t\t\t)\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst isReady = await tcpProbe(port)\n\t\t\tif (isReady) {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tawait new Promise<void>((resolve) => globalThis.setTimeout(resolve, interval))\n\t\t}\n\n\t\treturn false\n\t}\n}\n","import { execa, type ExecaChildProcess, type ExecaError } from 'execa'\nimport { setTimeout } from 'timers/promises'\nimport { ProcessManager } from './process/ProcessManager.js'\nimport { buildDevServerCommand } from '../utils/dev-server.js'\nimport { runScript } from '../utils/package-manager.js'\nimport { getPackageScripts } from '../utils/package-json.js'\nimport { logger } from '../utils/logger.js'\nimport { restoreTerminalState } from '../utils/terminal.js'\nimport type { DevServerStrategy, ForegroundOpts } from './DevServerStrategy.js'\n\n/**\n * NativeDevServerStrategy implements DevServerStrategy for process-based dev servers.\n * This is the default mode — the dev server runs directly on the host as a child process.\n */\nexport class NativeDevServerStrategy implements DevServerStrategy {\n\tprivate readonly processManager: ProcessManager\n\tprivate readonly startupTimeout: number\n\tprivate readonly checkInterval: number\n\tprivate runningServers: Map<number, ExecaChildProcess> = new Map()\n\n\tconstructor(\n\t\tprocessManager: ProcessManager,\n\t\tstartupTimeout: number,\n\t\tcheckInterval: number\n\t) {\n\t\tthis.processManager = processManager\n\t\tthis.startupTimeout = startupTimeout\n\t\tthis.checkInterval = checkInterval\n\t}\n\n\tasync isRunning(port: number): Promise<boolean> {\n\t\tconst process = await this.processManager.detectDevServer(port)\n\t\treturn process !== null\n\t}\n\n\tasync startBackground(\n\t\tworktreePath: string,\n\t\tport: number,\n\t\tenvOverrides?: Record<string, string>\n\t): Promise<void> {\n\t\t// Guard: Check if a dev script exists in package.json or package.iloom.json\n\t\tconst scripts = await getPackageScripts(worktreePath)\n\t\tif (!scripts['dev']) {\n\t\t\tlogger.warn('Skipping auto-start: no \"dev\" script found in package.json or package.iloom.json')\n\t\t\treturn\n\t\t}\n\n\t\t// Build dev server command\n\t\tconst devCommand = await buildDevServerCommand(worktreePath)\n\t\tlogger.debug(`Starting dev server with command: ${devCommand}`)\n\n\t\t// Start server in background\n\t\tconst serverProcess = execa('sh', ['-c', devCommand], {\n\t\t\tcwd: worktreePath,\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\t...envOverrides,\n\t\t\t\tPORT: port.toString(),\n\t\t\t},\n\t\t\t// Important: Don't inherit stdio - server runs in background\n\t\t\tstdio: 'ignore',\n\t\t\t// Detach from parent process so it continues running\n\t\t\tdetached: true,\n\t\t})\n\n\t\t// Store reference to prevent cleanup\n\t\tthis.runningServers.set(port, serverProcess)\n\n\t\t// Remove from map when process exits naturally or crashes\n\t\tserverProcess.on('exit', () => {\n\t\t\tthis.runningServers.delete(port)\n\t\t})\n\n\t\t// Unref so parent can exit\n\t\tserverProcess.unref()\n\n\t\t// Wait for server to be ready (pass process ref for early crash detection)\n\t\tlogger.info(`Waiting for dev server to start on port ${port}...`)\n\t\tconst ready = await this.waitForReady(port, serverProcess)\n\n\t\tif (!ready) {\n\t\t\tthrow new Error(\n\t\t\t\t`Dev server failed to start within ${this.startupTimeout}ms timeout`\n\t\t\t)\n\t\t}\n\n\t\tlogger.success(`Dev server started successfully on port ${port}`)\n\t}\n\n\tasync startForeground(\n\t\tworktreePath: string,\n\t\tport: number,\n\t\topts: ForegroundOpts\n\t): Promise<{ pid?: number }> {\n\t\tconst { redirectToStderr = false, onProcessStarted, envOverrides } = opts\n\n\t\tlogger.debug(`Starting dev server in foreground on port ${port}`)\n\n\t\tif (redirectToStderr) {\n\t\t\t// For redirectToStderr, we need direct execa control for custom stdio\n\t\t\tconst devCommand = await buildDevServerCommand(worktreePath)\n\t\t\tlogger.debug(`Starting dev server with command: ${devCommand}`)\n\n\t\t\tconst serverProcess = execa('sh', ['-c', devCommand], {\n\t\t\t\tcwd: worktreePath,\n\t\t\t\tenv: {\n\t\t\t\t\t...process.env,\n\t\t\t\t\t...envOverrides,\n\t\t\t\t\tPORT: port.toString(),\n\t\t\t\t},\n\t\t\t\tstdio: [process.stdin, process.stderr, process.stderr],\n\t\t\t})\n\n\t\t\tconst processInfo: { pid?: number } =\n\t\t\t\tserverProcess.pid !== undefined ? { pid: serverProcess.pid } : {}\n\n\t\t\tif (onProcessStarted) {\n\t\t\t\tonProcessStarted(processInfo.pid)\n\t\t\t}\n\n\t\t\t// Register no-op SIGINT handler to prevent signal-exit from re-raising SIGINT\n\t\t\t// before finally blocks can run, ensuring terminal state is restored on Ctrl+C.\n\t\t\tconst onSigint = (): void => {}\n\t\t\tprocess.on('SIGINT', onSigint)\n\n\t\t\ttry {\n\t\t\t\tawait serverProcess\n\t\t\t} catch (error) {\n\t\t\t\tconst execaError = error as ExecaError\n\t\t\t\t// If killed by SIGINT, the user intentionally cancelled — return silently\n\t\t\t\tif (execaError.signal !== 'SIGINT') {\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tprocess.removeListener('SIGINT', onSigint)\n\t\t\t\trestoreTerminalState()\n\t\t\t}\n\n\t\t\treturn processInfo\n\t\t}\n\n\t\t// Use runScript for standard foreground mode\n\t\treturn await runScript('dev', worktreePath, [], {\n\t\t\tenv: {\n\t\t\t\t...envOverrides,\n\t\t\t\tPORT: port.toString(),\n\t\t\t},\n\t\t\tforeground: true,\n\t\t\t...(onProcessStarted && { onStart: onProcessStarted }),\n\t\t\tnoCi: true, // Dev servers should not have CI=true\n\t\t})\n\t}\n\n\tasync stop(port: number): Promise<boolean> {\n\t\tconst serverProcess = this.runningServers.get(port)\n\t\tif (!serverProcess) {\n\t\t\treturn false\n\t\t}\n\n\t\ttry {\n\t\t\t// Kill the entire process group (negative PID) since the server is\n\t\t\t// spawned with detached:true via `sh -c`. Without this, only the\n\t\t\t// shell process receives the signal and the actual dev server\n\t\t\t// (node/vite/next) remains running as an orphan.\n\t\t\tif (serverProcess.pid) {\n\t\t\t\tprocess.kill(-serverProcess.pid, 'SIGTERM')\n\t\t\t} else {\n\t\t\t\tserverProcess.kill()\n\t\t\t}\n\t\t\tthis.runningServers.delete(port)\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tlogger.warn(\n\t\t\t\t`Failed to kill server process on port ${port}: ${error instanceof Error ? error.message : 'Unknown error'}`\n\t\t\t)\n\t\t\treturn false\n\t\t}\n\t}\n\n\t/**\n\t * Stop all tracked server processes. Called during cleanup.\n\t */\n\tasync stopAll(): Promise<void> {\n\t\tfor (const [port] of this.runningServers.entries()) {\n\t\t\tawait this.stop(port)\n\t\t}\n\t}\n\n\t/**\n\t * Wait for server to be ready by polling the port.\n\t * Exits early if the spawned process has already exited (crash detection).\n\t * Public so DevServerManager can reuse it for Docker mode readiness checks.\n\t *\n\t * @param port - Port to poll\n\t * @param processRef - Optional spawned process to monitor for early exit\n\t */\n\tasync waitForReady(port: number, processRef?: ExecaChildProcess): Promise<boolean> {\n\t\tconst startTime = Date.now()\n\t\tlet attempts = 0\n\n\t\twhile (Date.now() - startTime < this.startupTimeout) {\n\t\t\tattempts++\n\n\t\t\t// Early exit: if the spawned process has already exited, stop polling\n\t\t\t// Check both null and undefined since exitCode is undefined before the process exits\n\t\t\tif (processRef && processRef.exitCode != null) {\n\t\t\t\tlogger.warn(\n\t\t\t\t\t`Dev server process exited with code ${processRef.exitCode} before becoming ready (after ${attempts} attempts, ${Date.now() - startTime}ms)`\n\t\t\t\t)\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tconst processInfo = await this.processManager.detectDevServer(port)\n\n\t\t\tif (processInfo) {\n\t\t\t\tlogger.debug(\n\t\t\t\t\t`Server detected on port ${port} after ${attempts} attempts (${Date.now() - startTime}ms)`\n\t\t\t\t)\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tawait setTimeout(this.checkInterval)\n\t\t}\n\n\t\tlogger.warn(\n\t\t\t`Server did not start on port ${port} after ${this.startupTimeout}ms (${attempts} attempts)`\n\t\t)\n\t\treturn false\n\t}\n}\n","import { detectPackageManager } from './package-manager.js'\nimport { logger } from './logger.js'\nimport type { Capability } from '../types/loom.js'\n\n/**\n * Build dev server command for workspace\n * Detects package manager and constructs appropriate command\n */\nexport async function buildDevServerCommand(\n\tworkspacePath: string\n): Promise<string> {\n\tconst packageManager = await detectPackageManager(workspacePath)\n\n\tlet devCommand: string\n\n\tswitch (packageManager) {\n\t\tcase 'pnpm':\n\t\t\tdevCommand = 'pnpm dev'\n\t\t\tbreak\n\t\tcase 'npm':\n\t\t\tdevCommand = 'npm run dev'\n\t\t\tbreak\n\t\tcase 'yarn':\n\t\t\tdevCommand = 'yarn dev'\n\t\t\tbreak\n\t\tdefault:\n\t\t\t// Fallback to npm (handles bun and other package managers)\n\t\t\tlogger.warn(`Unknown or unsupported package manager: ${packageManager}, defaulting to npm`)\n\t\t\tdevCommand = 'npm run dev'\n\t}\n\n\tlogger.debug(`Dev server command: ${devCommand}`)\n\treturn devCommand\n}\n\n/**\n * Build complete dev server launch command for terminal\n * Includes VSCode launch, echo message (only for web projects), and dev server start\n */\nexport async function getDevServerLaunchCommand(\n\tworkspacePath: string,\n\tport?: number,\n\tcapabilities: Capability[] = []\n): Promise<string> {\n\tconst devCommand = await buildDevServerCommand(workspacePath)\n\n\tconst commands: string[] = []\n\n\t// // Open VSCode\n\t// commands.push('code .')\n\n\t// Echo message (only for web projects)\n\tif (capabilities.includes('web')) {\n\t\tif (port !== undefined) {\n\t\t\tcommands.push(`echo 'Starting dev server on PORT=${port}...'`)\n\t\t} else {\n\t\t\tcommands.push(`echo 'Starting dev server...'`)\n\t\t}\n\t}\n\n\t// Start dev server\n\tcommands.push(devCommand)\n\n\treturn commands.join(' && ')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,OAAO,UAAU;;;ACAjB,SAAS,aAAa;AACtB,OAAO,SAAS;AA4DhB,SAAS,SAAS,MAAgC;AACjD,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC/B,UAAM,SAAS,IAAI,iBAAiB,EAAE,MAAM,MAAM,YAAY,CAAC;AAC/D,WAAO,KAAK,WAAW,MAAM;AAC5B,aAAO,QAAQ;AACf,cAAQ,IAAI;AAAA,IACb,CAAC;AACD,WAAO,KAAK,SAAS,MAAM;AAC1B,aAAO,QAAQ;AACf,cAAQ,KAAK;AAAA,IACd,CAAC;AAAA,EACF,CAAC;AACF;AAaO,IAAM,0BAAN,MAA8B;AAAA,EAGpC,YAAY,SAAuB,OAAoB;AACtD,SAAK,QAAQ;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,qBACL,QACA,WACA,gBACkB;AAClB,QAAI,OAAO,kBAAkB,QAAW;AACvC,aAAO,OAAO;AAAA,IACf;AAEA,UAAM,gBAAgB,MAAM,KAAK,MAAM,kBAAkB,SAAS;AAClE,QAAI,kBAAkB,MAAM;AAC3B,aAAO,MAAM,gCAAgC,aAAa,4BAA4B;AACtF,aAAO;AAAA,IACR;AAEA,UAAM,cAAc,MAAM,KAAK,MAAM,sBAAsB,cAAc;AACzE,QAAI,gBAAgB,MAAM;AACzB,aAAO,MAAM,gCAAgC,WAAW,mCAAmC;AAC3F,aAAO;AAAA,IACR;AAEA,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,WAAW,cAAsB,QAAqC;AAC3E,UAAM,YAAY,KAAK,MAAM,eAAe,OAAO,cAAc,YAAY;AAC7E,UAAM,iBAAiB,OAAO,cAAc;AAE5C,UAAM,OAAO,CAAC,SAAS,MAAM,WAAW,MAAM,cAAc;AAE5D,QAAI,OAAO,WAAW;AACrB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,SAAS,GAAG;AAC5D,aAAK,KAAK,eAAe,GAAG,GAAG,IAAI,KAAK,EAAE;AAAA,MAC3C;AAAA,IACD;AAGA,SAAK,KAAK,GAAG;AAEb,WAAO,KAAK,0BAA0B,SAAS,UAAU,cAAc,KAAK;AAE5E,QAAI;AACH,YAAM,MAAM,UAAU,MAAM;AAAA,QAC3B,KAAK;AAAA,QACL,OAAO;AAAA,MACR,CAAC;AAAA,IACF,SAAS,OAAO;AACf,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,MAAM,kCAAkC,SAAS,MAAM,OAAO,EAAE;AAAA,IAC3E;AAEA,WAAO,QAAQ,iBAAiB,SAAS,sBAAsB;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,qBACL,cACA,UACA,eACA,QACA,cACkB;AAClB,UAAM,SAAS,OAAO,cAAc;AACpC,UAAM,YAAY,KAAK,MAAM,eAAe,MAAM;AAClD,UAAM,gBAAgB,KAAK,MAAM,mBAAmB,MAAM;AAG1D,UAAM,MAAM,UAAU,CAAC,MAAM,MAAM,aAAa,GAAG,EAAE,QAAQ,MAAM,CAAC;AAEpE,UAAM,OAAO;AAAA,MACZ;AAAA,MAAO;AAAA,MACP;AAAA,MAAU;AAAA,MACV;AAAA,MAAM,GAAG,QAAQ,IAAI,aAAa;AAAA;AAAA,MAElC;AAAA,MAAM,GAAG,YAAY;AAAA;AAAA,MAErB;AAAA,MAAM;AAAA;AAAA;AAAA,MAGN;AAAA,MAAM,QAAQ,aAAa;AAAA,IAC5B;AAGA,QAAI,cAAc;AACjB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACxD,aAAK,KAAK,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE;AAAA,MAClC;AAAA,IACD;AAGA,QAAI,OAAO,SAAS;AACnB,WAAK,KAAK,GAAG,OAAO,OAAO;AAAA,IAC5B;AAEA,SAAK,KAAK,SAAS;AAEnB,WAAO,KAAK,8BAA8B,aAAa,qCAAqC,QAAQ,qBAAgB,aAAa,MAAM;AAEvI,QAAI;AACH,YAAM,MAAM,UAAU,IAAI;AAAA,IAC3B,SAAS,OAAO;AACf,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,MAAM,qCAAqC,aAAa,MAAM,OAAO,EAAE;AAAA,IAClF;AAEA,WAAO,QAAQ,qBAAqB,aAAa,qBAAqB,QAAQ,EAAE;AAChF,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,uBACL,cACA,UACA,eACA,QACA,OAA6B,CAAC,GACF;AAC5B,UAAM,SAAS,OAAO,cAAc;AACpC,UAAM,YAAY,KAAK,MAAM,eAAe,MAAM;AAClD,UAAM,gBAAgB,KAAK,MAAM,mBAAmB,MAAM;AAC1D,UAAM,EAAE,kBAAkB,kBAAkB,aAAa,IAAI;AAG7D,UAAM,MAAM,UAAU,CAAC,MAAM,MAAM,aAAa,GAAG,EAAE,QAAQ,MAAM,CAAC;AAEpE,UAAM,OAAO;AAAA,MACZ;AAAA,MAAO;AAAA,MACP;AAAA,MAAU;AAAA,MACV;AAAA,MAAM,GAAG,QAAQ,IAAI,aAAa;AAAA;AAAA,MAElC;AAAA,MAAM,GAAG,YAAY;AAAA;AAAA,MAErB;AAAA,MAAM;AAAA;AAAA;AAAA,MAGN;AAAA,MAAM,QAAQ,aAAa;AAAA,IAC5B;AAGA,QAAI,cAAc;AACjB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACxD,aAAK,KAAK,MAAM,GAAG,GAAG,IAAI,KAAK,EAAE;AAAA,MAClC;AAAA,IACD;AAGA,QAAI,OAAO,SAAS;AACnB,WAAK,KAAK,GAAG,OAAO,OAAO;AAAA,IAC5B;AAEA,SAAK,KAAK,SAAS;AAEnB,WAAO,KAAK,6BAA6B,aAAa,qCAAqC,QAAQ,qBAAgB,aAAa,MAAM;AAEtI,UAAM,QAAQ,mBACX,CAAC,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,MAAM,IAC9C;AAGH,UAAM,gBAAgB,MAAY;AACjC,aAAO,MAAM,uBAAuB,aAAa,GAAG;AACpD,WAAK,MAAM,UAAU,CAAC,QAAQ,aAAa,GAAG,EAAE,QAAQ,MAAM,CAAC;AAAA,IAChE;AAEA,UAAM,WAAW,MAAY,cAAc;AAC3C,UAAM,YAAY,MAAY,cAAc;AAE5C,YAAQ,GAAG,UAAU,QAAQ;AAC7B,YAAQ,GAAG,WAAW,SAAS;AAE/B,QAAI,kBAAkB;AACrB,uBAAiB,MAAS;AAAA,IAC3B;AAEA,QAAI;AACH,YAAM,MAAM,UAAU,MAAM,EAAE,MAAM,CAAC;AAAA,IACtC,UAAE;AAED,cAAQ,eAAe,UAAU,QAAQ;AACzC,cAAQ,eAAe,WAAW,SAAS;AAC3C,2BAAqB;AAAA,IACtB;AAEA,WAAO,CAAC;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cAAc,eAAsC;AACzD,WAAO,MAAM,oCAAoC,aAAa,MAAM;AACpE,UAAM,MAAM,UAAU,CAAC,MAAM,MAAM,aAAa,GAAG,EAAE,QAAQ,MAAM,CAAC;AACpE,WAAO,MAAM,cAAc,aAAa,uBAAuB;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,mBAAmB,eAAyC;AACjE,QAAI;AACH,YAAM,SAAS,MAAM,MAAM,UAAU;AAAA,QACpC;AAAA,QACA;AAAA,QAAY,SAAS,aAAa;AAAA,QAClC;AAAA,QAAY;AAAA,MACb,GAAG,EAAE,QAAQ,MAAM,CAAC;AAEpB,aAAO,OAAO,aAAa,KAAK,OAAO,OAAO,KAAK,MAAM;AAAA,IAC1D,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,aAAa,MAAc,SAAiB,UAAkB,eAA0C;AAC7G,UAAM,YAAY,KAAK,IAAI;AAC3B,QAAI,WAAW;AAEf,WAAO,KAAK,IAAI,IAAI,YAAY,SAAS;AACxC;AAGA,UAAI,iBAAiB,WAAW,MAAM,GAAG;AACxC,cAAM,eAAe,MAAM,KAAK,mBAAmB,aAAa;AAChE,YAAI,CAAC,cAAc;AAClB,iBAAO;AAAA,YACN,qBAAqB,aAAa,yCAAyC,QAAQ,cAAc,KAAK,IAAI,IAAI,SAAS;AAAA,UACxH;AACA,iBAAO;AAAA,QACR;AAAA,MACD;AAEA,YAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAI,SAAS;AACZ,eAAO;AAAA,MACR;AAEA,YAAM,IAAI,QAAc,CAAC,YAAY,WAAW,WAAW,SAAS,QAAQ,CAAC;AAAA,IAC9E;AAEA,WAAO;AAAA,EACR;AACD;;;AC7YA,SAAS,SAAAA,cAAsD;AAC/D,SAAS,kBAAkB;;;ACO3B,eAAsB,sBACrB,eACkB;AAClB,QAAM,iBAAiB,MAAM,qBAAqB,aAAa;AAE/D,MAAI;AAEJ,UAAQ,gBAAgB;AAAA,IACvB,KAAK;AACJ,mBAAa;AACb;AAAA,IACD,KAAK;AACJ,mBAAa;AACb;AAAA,IACD,KAAK;AACJ,mBAAa;AACb;AAAA,IACD;AAEC,aAAO,KAAK,2CAA2C,cAAc,qBAAqB;AAC1F,mBAAa;AAAA,EACf;AAEA,SAAO,MAAM,uBAAuB,UAAU,EAAE;AAChD,SAAO;AACR;;;ADnBO,IAAM,0BAAN,MAA2D;AAAA,EAMjE,YACC,gBACA,gBACA,eACC;AANF,SAAQ,iBAAiD,oBAAI,IAAI;AAOhE,SAAK,iBAAiB;AACtB,SAAK,iBAAiB;AACtB,SAAK,gBAAgB;AAAA,EACtB;AAAA,EAEA,MAAM,UAAU,MAAgC;AAC/C,UAAMC,WAAU,MAAM,KAAK,eAAe,gBAAgB,IAAI;AAC9D,WAAOA,aAAY;AAAA,EACpB;AAAA,EAEA,MAAM,gBACL,cACA,MACA,cACgB;AAEhB,UAAM,UAAU,MAAM,kBAAkB,YAAY;AACpD,QAAI,CAAC,QAAQ,KAAK,GAAG;AACpB,aAAO,KAAK,kFAAkF;AAC9F;AAAA,IACD;AAGA,UAAM,aAAa,MAAM,sBAAsB,YAAY;AAC3D,WAAO,MAAM,qCAAqC,UAAU,EAAE;AAG9D,UAAM,gBAAgBC,OAAM,MAAM,CAAC,MAAM,UAAU,GAAG;AAAA,MACrD,KAAK;AAAA,MACL,KAAK;AAAA,QACJ,GAAG,QAAQ;AAAA,QACX,GAAG;AAAA,QACH,MAAM,KAAK,SAAS;AAAA,MACrB;AAAA;AAAA,MAEA,OAAO;AAAA;AAAA,MAEP,UAAU;AAAA,IACX,CAAC;AAGD,SAAK,eAAe,IAAI,MAAM,aAAa;AAG3C,kBAAc,GAAG,QAAQ,MAAM;AAC9B,WAAK,eAAe,OAAO,IAAI;AAAA,IAChC,CAAC;AAGD,kBAAc,MAAM;AAGpB,WAAO,KAAK,2CAA2C,IAAI,KAAK;AAChE,UAAM,QAAQ,MAAM,KAAK,aAAa,MAAM,aAAa;AAEzD,QAAI,CAAC,OAAO;AACX,YAAM,IAAI;AAAA,QACT,qCAAqC,KAAK,cAAc;AAAA,MACzD;AAAA,IACD;AAEA,WAAO,QAAQ,2CAA2C,IAAI,EAAE;AAAA,EACjE;AAAA,EAEA,MAAM,gBACL,cACA,MACA,MAC4B;AAC5B,UAAM,EAAE,mBAAmB,OAAO,kBAAkB,aAAa,IAAI;AAErE,WAAO,MAAM,6CAA6C,IAAI,EAAE;AAEhE,QAAI,kBAAkB;AAErB,YAAM,aAAa,MAAM,sBAAsB,YAAY;AAC3D,aAAO,MAAM,qCAAqC,UAAU,EAAE;AAE9D,YAAM,gBAAgBA,OAAM,MAAM,CAAC,MAAM,UAAU,GAAG;AAAA,QACrD,KAAK;AAAA,QACL,KAAK;AAAA,UACJ,GAAG,QAAQ;AAAA,UACX,GAAG;AAAA,UACH,MAAM,KAAK,SAAS;AAAA,QACrB;AAAA,QACA,OAAO,CAAC,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,MAAM;AAAA,MACtD,CAAC;AAED,YAAM,cACL,cAAc,QAAQ,SAAY,EAAE,KAAK,cAAc,IAAI,IAAI,CAAC;AAEjE,UAAI,kBAAkB;AACrB,yBAAiB,YAAY,GAAG;AAAA,MACjC;AAIA,YAAM,WAAW,MAAY;AAAA,MAAC;AAC9B,cAAQ,GAAG,UAAU,QAAQ;AAE7B,UAAI;AACH,cAAM;AAAA,MACP,SAAS,OAAO;AACf,cAAM,aAAa;AAEnB,YAAI,WAAW,WAAW,UAAU;AACnC,gBAAM;AAAA,QACP;AAAA,MACD,UAAE;AACD,gBAAQ,eAAe,UAAU,QAAQ;AACzC,6BAAqB;AAAA,MACtB;AAEA,aAAO;AAAA,IACR;AAGA,WAAO,MAAM,UAAU,OAAO,cAAc,CAAC,GAAG;AAAA,MAC/C,KAAK;AAAA,QACJ,GAAG;AAAA,QACH,MAAM,KAAK,SAAS;AAAA,MACrB;AAAA,MACA,YAAY;AAAA,MACZ,GAAI,oBAAoB,EAAE,SAAS,iBAAiB;AAAA,MACpD,MAAM;AAAA;AAAA,IACP,CAAC;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,MAAgC;AAC1C,UAAM,gBAAgB,KAAK,eAAe,IAAI,IAAI;AAClD,QAAI,CAAC,eAAe;AACnB,aAAO;AAAA,IACR;AAEA,QAAI;AAKH,UAAI,cAAc,KAAK;AACtB,gBAAQ,KAAK,CAAC,cAAc,KAAK,SAAS;AAAA,MAC3C,OAAO;AACN,sBAAc,KAAK;AAAA,MACpB;AACA,WAAK,eAAe,OAAO,IAAI;AAC/B,aAAO;AAAA,IACR,SAAS,OAAO;AACf,aAAO;AAAA,QACN,yCAAyC,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MAC3G;AACA,aAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAyB;AAC9B,eAAW,CAAC,IAAI,KAAK,KAAK,eAAe,QAAQ,GAAG;AACnD,YAAM,KAAK,KAAK,IAAI;AAAA,IACrB;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,aAAa,MAAc,YAAkD;AAClF,UAAM,YAAY,KAAK,IAAI;AAC3B,QAAI,WAAW;AAEf,WAAO,KAAK,IAAI,IAAI,YAAY,KAAK,gBAAgB;AACpD;AAIA,UAAI,cAAc,WAAW,YAAY,MAAM;AAC9C,eAAO;AAAA,UACN,uCAAuC,WAAW,QAAQ,iCAAiC,QAAQ,cAAc,KAAK,IAAI,IAAI,SAAS;AAAA,QACxI;AACA,eAAO;AAAA,MACR;AAEA,YAAM,cAAc,MAAM,KAAK,eAAe,gBAAgB,IAAI;AAElE,UAAI,aAAa;AAChB,eAAO;AAAA,UACN,2BAA2B,IAAI,UAAU,QAAQ,cAAc,KAAK,IAAI,IAAI,SAAS;AAAA,QACtF;AACA,eAAO;AAAA,MACR;AAEA,YAAM,WAAW,KAAK,aAAa;AAAA,IACpC;AAEA,WAAO;AAAA,MACN,gCAAgC,IAAI,UAAU,KAAK,cAAc,OAAO,QAAQ;AAAA,IACjF;AACA,WAAO;AAAA,EACR;AACD;;;AF1NA,IAAM,0BAA0B;AAMhC,IAAM,cAA2B;AAAA,EAChC,uBAAuB,CAAC,aAAqB,cAAc,0BAA0B,QAAQ;AAAA,EAC7F,mBAAmB,CAAC,cAAsB,cAAc,kBAAkB,SAAS;AAAA,EACnF,oBAAoB,CAAC,OAAwB,cAAc,mBAAmB,EAAE;AAAA,EAChF,gBAAgB,CAAC,OAAwB,cAAc,eAAe,EAAE;AAAA,EACxE,uBAAuB,MAAM,cAAc,gBAAgB;AAC5D;AAEA,SAAS,oBAA4B;AACpC,QAAM,aAAa,QAAQ,IAAI;AAC/B,MAAI,YAAY;AACf,UAAM,SAAS,SAAS,YAAY,EAAE;AACtC,QAAI,CAAC,MAAM,MAAM,KAAK,SAAS,GAAG;AACjC,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AACR;AAwBA,SAAS,iBAAiB,QAA4C;AACrE,SAAO;AAAA,IACN,YAAY,OAAO;AAAA,IACnB,eAAe,OAAO;AAAA,IACtB,WAAW,OAAO;AAAA,IAClB,SAAS,OAAO;AAAA,IAChB,YAAY,OAAO;AAAA,EACpB;AACD;AAUO,IAAM,mBAAN,MAAuB;AAAA,EAM7B,YACC,gBACA,UAAmC,CAAC,GACnC;AALF,SAAQ,0BAA+C,oBAAI,IAAI;AAM9D,SAAK,iBAAiB,kBAAkB,IAAI,eAAe;AAC3D,SAAK,UAAU;AAAA,MACd,gBAAgB,QAAQ,kBAAkB,kBAAkB;AAAA,MAC5D,eAAe,QAAQ,iBAAiB;AAAA,IACzC;AACA,SAAK,iBAAiB,IAAI;AAAA,MACzB,KAAK;AAAA,MACL,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,IACd;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,qBAAqB,cAAqD;AACjF,WAAO,IAAI,wBAAwB,iBAAiB,YAAY,GAAG,WAAW;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,oBAAoB,cAAsB,MAAc,cAA+C;AAC5G,WAAO,MAAM,6CAA6C,IAAI,KAAK;AAGnE,QAAI,cAAc;AACjB,YAAM,WAAW,KAAK,qBAAqB,YAAY;AACvD,YAAM,gBAAgB,YAAY,mBAAmB,aAAa,UAAU;AAC5E,YAAM,YAAY,MAAM,SAAS,mBAAmB,aAAa;AACjE,UAAI,WAAW;AACd,eAAO,MAAM,qBAAqB,aAAa,6BAA6B,IAAI,EAAE;AAClF,eAAO;AAAA,MACR;AAEA,aAAO,KAAK,yCAAyC,IAAI,eAAe;AACxE,UAAI;AACH,cAAM,KAAK,kBAAkB,cAAc,MAAM,cAAc,QAAQ;AACvE,eAAO;AAAA,MACR,SAAS,OAAO;AACf,eAAO;AAAA,UACN,sCAAsC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAC/F;AACA,eAAO;AAAA,MACR;AAAA,IACD;AAGA,UAAM,kBAAkB,MAAM,KAAK,eAAe,gBAAgB,IAAI;AACtE,QAAI,iBAAiB;AACpB,aAAO;AAAA,QACN,sCAAsC,IAAI,UAAU,gBAAgB,GAAG;AAAA,MACxE;AACA,aAAO;AAAA,IACR;AAGA,WAAO,KAAK,kCAAkC,IAAI,eAAe;AAEjE,QAAI;AACH,YAAM,KAAK,eAAe,gBAAgB,cAAc,IAAI;AAC5D,aAAO;AAAA,IACR,SAAS,OAAO;AACf,aAAO;AAAA,QACN,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACxF;AACA,aAAO;AAAA,IACR;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,kBACb,cACA,MACA,cACA,UACgB;AAChB,UAAM,iBAAiB,iBAAiB,YAAY;AACpD,UAAM,YAAY,YAAY,eAAe,aAAa,UAAU;AACpE,UAAM,iBAAiB,KAAK,QAAQ,cAAc,aAAa,UAAU;AAGzE,UAAM,SAAS,WAAW,cAAc,cAAc;AAGtD,UAAM,gBAAgB,MAAM,SAAS;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAGA,UAAM,gBAAgB,MAAM,SAAS;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAGA,SAAK,wBAAwB,IAAI,MAAM,aAAa;AAIpD,WAAO,KAAK,kDAAkD,IAAI,KAAK;AACvE,UAAM,QAAQ,MAAM,SAAS;AAAA,MAC5B;AAAA,MACA,KAAK,QAAQ;AAAA,MACb,KAAK,QAAQ;AAAA,MACb;AAAA,IACD;AAEA,QAAI,CAAC,OAAO;AAEX,YAAM,SAAS,cAAc,aAAa;AAC1C,WAAK,wBAAwB,OAAO,IAAI;AACxC,YAAM,IAAI;AAAA,QACT,4CAA4C,KAAK,QAAQ,cAAc;AAAA,MACxE;AAAA,IACD;AAEA,WAAO,QAAQ,kDAAkD,IAAI,EAAE;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,gBAAgB,MAAc,cAA+C;AAClF,QAAI,cAAc;AACjB,YAAM,WAAW,KAAK,qBAAqB,YAAY;AACvD,YAAM,gBAAgB,YAAY,mBAAmB,aAAa,UAAU;AAC5E,aAAO,SAAS,mBAAmB,aAAa;AAAA,IACjD;AACA,UAAM,kBAAkB,MAAM,KAAK,eAAe,gBAAgB,IAAI;AACtE,WAAO,oBAAoB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,oBACL,cACA,MACA,mBAAmB,OACnB,kBACA,cACA,cAC4B;AAE5B,QAAI,cAAc;AACjB,aAAO,MAAM,oDAAoD,IAAI,EAAE;AAEvE,YAAM,WAAW,KAAK,qBAAqB,YAAY;AACvD,YAAM,iBAAiB,iBAAiB,YAAY;AACpD,YAAM,YAAY,YAAY,eAAe,aAAa,UAAU;AACpE,YAAM,gBAAgB,YAAY,mBAAmB,aAAa,UAAU;AAC5E,YAAM,iBAAiB,KAAK,QAAQ,cAAc,aAAa,UAAU;AAGzE,YAAM,SAAS,WAAW,cAAc,cAAc;AAGtD,YAAM,gBAAgB,MAAM,SAAS;AAAA,QACpC;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAEA,UAAI,kBAAkB;AACrB,yBAAiB,MAAS;AAAA,MAC3B;AAGA,WAAK,wBAAwB,IAAI,MAAM,aAAa;AACpD,UAAI;AAGH,cAAM,SAAS;AAAA,UACd;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,EAAE,kBAAkB,aAAa;AAAA,QAClC;AAAA,MACD,UAAE;AACD,aAAK,wBAAwB,OAAO,IAAI;AAAA,MACzC;AAEA,aAAO,CAAC;AAAA,IACT;AAGA,WAAO,KAAK,eAAe,gBAAgB,cAAc,MAAM;AAAA,MAC9D;AAAA,MACA,GAAI,qBAAqB,UAAa,EAAE,iBAAiB;AAAA,MACzD,GAAI,iBAAiB,UAAa,EAAE,aAAa;AAAA,IAClD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAyB;AAE9B,UAAM,KAAK,eAAe,QAAQ;AAGlC,eAAW,CAAC,MAAM,aAAa,KAAK,KAAK,wBAAwB,QAAQ,GAAG;AAC3E,UAAI;AACH,eAAO,MAAM,iCAAiC,aAAa,aAAa,IAAI,EAAE;AAE9E,cAAM,WAAW,IAAI,wBAAwB,CAAC,GAAG,WAAW;AAC5D,cAAM,SAAS,cAAc,aAAa;AAAA,MAC3C,SAAS,OAAO;AACf,eAAO;AAAA,UACN,oCAAoC,aAAa,aAAa,IAAI,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QAChI;AAAA,MACD;AAAA,IACD;AACA,SAAK,wBAAwB,MAAM;AAAA,EACpC;AACD;","names":["execa","process","execa"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
GitWorktreeManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4VQXMEEP.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VRPPI6GU.js";
|
|
8
8
|
|
|
9
9
|
// src/lib/ShellCompletion.ts
|
|
10
10
|
import omelette from "omelette";
|
|
@@ -299,4 +299,4 @@ Please consult your shell's documentation for setting up custom completions.
|
|
|
299
299
|
export {
|
|
300
300
|
ShellCompletion
|
|
301
301
|
};
|
|
302
|
-
//# sourceMappingURL=chunk-
|
|
302
|
+
//# sourceMappingURL=chunk-QXGM32TO.js.map
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
IssueTrackerFactory
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NUUFP53X.js";
|
|
5
5
|
import {
|
|
6
6
|
getLinearIssueDependencies
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DMSL5BAP.js";
|
|
8
8
|
import {
|
|
9
9
|
getIssueDependencies
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-KV4NU3RP.js";
|
|
11
11
|
import {
|
|
12
12
|
getLogger
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-FTYWGQFM.js";
|
|
14
14
|
import {
|
|
15
15
|
logger
|
|
16
|
-
} from "./chunk-
|
|
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-
|
|
207
|
+
//# sourceMappingURL=chunk-RFCAPHL5.js.map
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
archiveRecap
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3XEXT35Z.js";
|
|
5
5
|
import {
|
|
6
6
|
removeClaudeTrust
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7UBEHQTP.js";
|
|
8
8
|
import {
|
|
9
|
-
|
|
10
|
-
} from "./chunk-
|
|
9
|
+
DockerManager
|
|
10
|
+
} from "./chunk-AYLC633W.js";
|
|
11
|
+
import {
|
|
12
|
+
getWorkspacePort
|
|
13
|
+
} from "./chunk-ZUIFO7B4.js";
|
|
11
14
|
import {
|
|
12
15
|
checkRemoteBranchStatus,
|
|
13
16
|
executeGitCommand,
|
|
@@ -17,16 +20,16 @@ import {
|
|
|
17
20
|
getMergeTargetBranch,
|
|
18
21
|
hasUncommittedChanges,
|
|
19
22
|
isBranchMergedIntoMain
|
|
20
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-QNPJXO53.js";
|
|
21
24
|
import {
|
|
22
25
|
SettingsManager
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-WGUGB54H.js";
|
|
24
27
|
import {
|
|
25
28
|
MetadataManager
|
|
26
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-4JZEQBWV.js";
|
|
27
30
|
import {
|
|
28
31
|
getLogger
|
|
29
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-FTYWGQFM.js";
|
|
30
33
|
|
|
31
34
|
// src/lib/ResourceCleanup.ts
|
|
32
35
|
import path from "path";
|
|
@@ -47,42 +50,11 @@ var ResourceCleanup = class {
|
|
|
47
50
|
* @param options - Cleanup options
|
|
48
51
|
*/
|
|
49
52
|
async cleanupWorktree(parsed, options = {}) {
|
|
50
|
-
var _a, _b, _c;
|
|
53
|
+
var _a, _b, _c, _d, _e, _f;
|
|
51
54
|
const operations = [];
|
|
52
55
|
const errors = [];
|
|
53
56
|
const displayIdentifier = parsed.branchName ?? ((_a = parsed.number) == null ? void 0 : _a.toString()) ?? parsed.originalInput;
|
|
54
57
|
getLogger().info(`Starting cleanup for: ${displayIdentifier}`);
|
|
55
|
-
const number = parsed.number;
|
|
56
|
-
if (number !== void 0) {
|
|
57
|
-
const settings = await this.settingsManager.loadSettings();
|
|
58
|
-
const basePort = ((_c = (_b = settings == null ? void 0 : settings.capabilities) == null ? void 0 : _b.web) == null ? void 0 : _c.basePort) ?? 3e3;
|
|
59
|
-
const port = calculatePortFromIdentifier(number, basePort);
|
|
60
|
-
if (options.dryRun) {
|
|
61
|
-
operations.push({
|
|
62
|
-
type: "dev-server",
|
|
63
|
-
success: true,
|
|
64
|
-
message: `[DRY RUN] Would check for dev server on port ${port}`
|
|
65
|
-
});
|
|
66
|
-
} else {
|
|
67
|
-
try {
|
|
68
|
-
const terminated = await this.terminateDevServer(port);
|
|
69
|
-
operations.push({
|
|
70
|
-
type: "dev-server",
|
|
71
|
-
success: true,
|
|
72
|
-
message: terminated ? `Dev server on port ${port} terminated` : `No dev server running on port ${port}`
|
|
73
|
-
});
|
|
74
|
-
} catch (error) {
|
|
75
|
-
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
76
|
-
errors.push(err);
|
|
77
|
-
operations.push({
|
|
78
|
-
type: "dev-server",
|
|
79
|
-
success: false,
|
|
80
|
-
message: `Failed to terminate dev server`,
|
|
81
|
-
error: err.message
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
58
|
let worktree = null;
|
|
87
59
|
try {
|
|
88
60
|
if (options.worktree) {
|
|
@@ -123,6 +95,42 @@ var ResourceCleanup = class {
|
|
|
123
95
|
rollbackRequired: false
|
|
124
96
|
};
|
|
125
97
|
}
|
|
98
|
+
{
|
|
99
|
+
const settings = await this.settingsManager.loadSettings();
|
|
100
|
+
const port = await getWorkspacePort({
|
|
101
|
+
worktreePath: worktree.path,
|
|
102
|
+
worktreeBranch: worktree.branch,
|
|
103
|
+
basePort: (_c = (_b = settings == null ? void 0 : settings.capabilities) == null ? void 0 : _b.web) == null ? void 0 : _c.basePort,
|
|
104
|
+
checkEnvFile: true
|
|
105
|
+
});
|
|
106
|
+
const devServerMode = ((_e = (_d = settings == null ? void 0 : settings.capabilities) == null ? void 0 : _d.web) == null ? void 0 : _e.devServer) ?? "process";
|
|
107
|
+
const dockerIdentifier = devServerMode === "docker" ? ((_f = parsed.number) == null ? void 0 : _f.toString()) ?? parsed.branchName ?? parsed.originalInput : void 0;
|
|
108
|
+
if (options.dryRun) {
|
|
109
|
+
operations.push({
|
|
110
|
+
type: "dev-server",
|
|
111
|
+
success: true,
|
|
112
|
+
message: `[DRY RUN] Would check for dev server on port ${port}`
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
try {
|
|
116
|
+
const terminated = await this.terminateDevServer(port, dockerIdentifier);
|
|
117
|
+
operations.push({
|
|
118
|
+
type: "dev-server",
|
|
119
|
+
success: true,
|
|
120
|
+
message: terminated ? `Dev server on port ${port} terminated` : `No dev server running on port ${port}`
|
|
121
|
+
});
|
|
122
|
+
} catch (error) {
|
|
123
|
+
const err = error instanceof Error ? error : new Error("Unknown error");
|
|
124
|
+
errors.push(err);
|
|
125
|
+
operations.push({
|
|
126
|
+
type: "dev-server",
|
|
127
|
+
success: false,
|
|
128
|
+
message: `Failed to terminate dev server`,
|
|
129
|
+
error: err.message
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
126
134
|
let safetyCheckPassed = false;
|
|
127
135
|
if (!options.force) {
|
|
128
136
|
const shouldCheckMergeSafety = options.checkMergeSafety ?? options.deleteBranch === true;
|
|
@@ -491,10 +499,25 @@ ${blockerMessage}`);
|
|
|
491
499
|
};
|
|
492
500
|
}
|
|
493
501
|
/**
|
|
494
|
-
* Terminate dev server on specified port
|
|
502
|
+
* Terminate dev server on specified port.
|
|
503
|
+
* When a dockerIdentifier is provided, attempts Docker container cleanup first
|
|
504
|
+
* before falling back to process-based detection.
|
|
505
|
+
*
|
|
506
|
+
* @param port - Port the dev server is running on
|
|
507
|
+
* @param dockerIdentifier - Optional identifier for Docker container lookup (issue number, branch name, etc.)
|
|
495
508
|
*/
|
|
496
|
-
async terminateDevServer(port) {
|
|
509
|
+
async terminateDevServer(port, dockerIdentifier) {
|
|
497
510
|
getLogger().debug(`Checking for dev server on port ${port}`);
|
|
511
|
+
if (dockerIdentifier !== void 0) {
|
|
512
|
+
const containerName = DockerManager.buildContainerName(dockerIdentifier);
|
|
513
|
+
const isRunning = await DockerManager.isContainerRunning(containerName);
|
|
514
|
+
if (isRunning) {
|
|
515
|
+
getLogger().info(`Terminating Docker container: ${containerName}`);
|
|
516
|
+
await DockerManager.stopAndRemoveContainer(containerName);
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
getLogger().debug(`No Docker container found with name "${containerName}", falling back to process detection`);
|
|
520
|
+
}
|
|
498
521
|
const processInfo = await this.processManager.detectDevServer(port);
|
|
499
522
|
if (!processInfo) {
|
|
500
523
|
getLogger().debug(`No process found on port ${port}`);
|
|
@@ -807,4 +830,4 @@ Please resolve before cleanup - you have some options:
|
|
|
807
830
|
export {
|
|
808
831
|
ResourceCleanup
|
|
809
832
|
};
|
|
810
|
-
//# sourceMappingURL=chunk-
|
|
833
|
+
//# sourceMappingURL=chunk-SA446KA2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/ResourceCleanup.ts"],"sourcesContent":["import path from 'path'\nimport { GitWorktreeManager } from './GitWorktreeManager.js'\nimport { DatabaseManager } from './DatabaseManager.js'\nimport { ProcessManager } from './process/ProcessManager.js'\nimport { CLIIsolationManager } from './CLIIsolationManager.js'\nimport { SettingsManager } from './SettingsManager.js'\nimport { MetadataManager } from './MetadataManager.js'\nimport { DockerManager } from './DockerManager.js'\nimport { getLogger } from '../utils/logger-context.js'\nimport { hasUncommittedChanges, executeGitCommand, findMainWorktreePathWithSettings, extractIssueNumber, isBranchMergedIntoMain, checkRemoteBranchStatus, getMergeTargetBranch, findWorktreeForBranch, type RemoteBranchStatus } from '../utils/git.js'\nimport { removeClaudeTrust } from '../utils/claude-trust.js'\nimport { getWorkspacePort } from '../utils/port.js'\nimport { archiveRecap } from '../utils/recap-archiver.js'\n\nimport type {\n\tResourceCleanupOptions,\n\tCleanupResult,\n\tOperationResult,\n\tSafetyCheck,\n\tBranchDeleteOptions,\n} from '../types/cleanup.js'\nimport type { GitWorktree } from '../types/worktree.js'\nimport type { ParsedInput } from '../commands/start.js'\n\n/**\n * Manages resource cleanup for worktrees\n * Provides shared cleanup functionality for finish and cleanup commands\n */\nexport class ResourceCleanup {\n\tprivate settingsManager: SettingsManager\n\tprivate metadataManager: MetadataManager\n\n\tconstructor(\n\t\tprivate gitWorktree: GitWorktreeManager,\n\t\tprivate processManager: ProcessManager,\n\t\tprivate database?: DatabaseManager,\n\t\tprivate cliIsolation?: CLIIsolationManager,\n\t\tsettingsManager?: SettingsManager\n\t) {\n\t\tthis.settingsManager = settingsManager ?? new SettingsManager()\n\t\tthis.metadataManager = new MetadataManager()\n\t}\n\n\t/**\n\t * Cleanup a worktree and associated resources\n\t * Main orchestration method\n\t *\n\t * @param parsed - ParsedInput from IdentifierParser with type information\n\t * @param options - Cleanup options\n\t */\n\tasync cleanupWorktree(\n\t\tparsed: ParsedInput,\n\t\toptions: ResourceCleanupOptions = {}\n\t): Promise<CleanupResult> {\n\t\tconst operations: OperationResult[] = []\n\t\tconst errors: Error[] = []\n\n\t\tconst displayIdentifier = parsed.branchName ?? parsed.number?.toString() ?? parsed.originalInput\n\t\tgetLogger().info(`Starting cleanup for: ${displayIdentifier}`)\n\n\t\t// Step 1: Find worktree using specific methods based on type\n\t\tlet worktree: GitWorktree | null = null\n\t\ttry {\n\t\t\t// Use pre-resolved worktree if provided (skips the search step)\n\t\t\tif (options.worktree) {\n\t\t\t\tworktree = {\n\t\t\t\t\tpath: options.worktree.path,\n\t\t\t\t\tbranch: options.worktree.branch,\n\t\t\t\t\tcommit: '',\n\t\t\t\t\tbare: false,\n\t\t\t\t\tdetached: false,\n\t\t\t\t\tlocked: false,\n\t\t\t\t}\n\t\t\t\tgetLogger().debug(`Using pre-resolved worktree: path=\"${worktree.path}\", branch=\"${worktree.branch}\"`)\n\t\t\t} else {\n\t\t\t\t// Use specific finding methods based on parsed type for precision\n\t\t\t\tif (parsed.type === 'pr' && parsed.number !== undefined) {\n\t\t\t\t\t// For PRs, ensure the number is numeric (PRs are always numeric per GitHub)\n\t\t\t\t\tconst prNumber = typeof parsed.number === 'number' ? parsed.number : Number(parsed.number)\n\t\t\t\t\tif (isNaN(prNumber) || !isFinite(prNumber)) {\n\t\t\t\t\t\tthrow new Error(`Invalid PR number: ${parsed.number}. PR numbers must be numeric.`)\n\t\t\t\t\t}\n\t\t\t\t\t// For PRs, pass empty string for branchName since we're detecting from path pattern\n\t\t\t\t\tworktree = await this.gitWorktree.findWorktreeForPR(prNumber, '')\n\t\t\t\t} else if (parsed.type === 'issue' && parsed.number !== undefined) {\n\t\t\t\t\tworktree = await this.gitWorktree.findWorktreeForIssue(parsed.number)\n\t\t\t\t} else if (parsed.type === 'branch' && parsed.branchName) {\n\t\t\t\t\tworktree = await this.gitWorktree.findWorktreeForBranch(parsed.branchName)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!worktree) {\n\t\t\t\tthrow new Error(`No worktree found for identifier: ${displayIdentifier}`)\n\t\t\t}\n\n\t\t\tgetLogger().debug(`Found worktree: path=\"${worktree.path}\", branch=\"${worktree.branch}\"`)\n\t\t} catch (error) {\n\t\t\tconst err = error instanceof Error ? error : new Error('Unknown error')\n\t\t\terrors.push(err)\n\n\t\t\treturn {\n\t\t\t\tidentifier: displayIdentifier,\n\t\t\t\tsuccess: false,\n\t\t\t\toperations,\n\t\t\t\terrors,\n\t\t\t\trollbackRequired: false,\n\t\t\t}\n\t\t}\n\n\t\t// Step 1.5: Terminate dev server if applicable\n\t\t// Done after worktree is found so we can use getWorkspacePort which checks .env PORT overrides\n\t\t{\n\t\t\tconst settings = await this.settingsManager.loadSettings()\n\t\t\tconst port = await getWorkspacePort({\n\t\t\t\tworktreePath: worktree.path,\n\t\t\t\tworktreeBranch: worktree.branch,\n\t\t\t\tbasePort: settings?.capabilities?.web?.basePort,\n\t\t\t\tcheckEnvFile: true,\n\t\t\t})\n\t\t\tconst devServerMode = settings?.capabilities?.web?.devServer ?? 'process'\n\t\t\tconst dockerIdentifier = devServerMode === 'docker'\n\t\t\t\t? (parsed.number?.toString() ?? parsed.branchName ?? parsed.originalInput)\n\t\t\t\t: undefined\n\n\t\t\tif (options.dryRun) {\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'dev-server',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: `[DRY RUN] Would check for dev server on port ${port}`,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst terminated = await this.terminateDevServer(port, dockerIdentifier)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'dev-server',\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: terminated\n\t\t\t\t\t\t\t? `Dev server on port ${port} terminated`\n\t\t\t\t\t\t\t: `No dev server running on port ${port}`,\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst err = error instanceof Error ? error : new Error('Unknown error')\n\t\t\t\t\terrors.push(err)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'dev-server',\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: `Failed to terminate dev server`,\n\t\t\t\t\t\terror: err.message,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Step 2.5: Validate safety before proceeding with cleanup (unless force flag is set)\n\t\t// Check merge safety if: deleteBranch is true AND checkMergeSafety is not explicitly false\n\t\t// This prevents the scenario where worktree is deleted but branch deletion fails\n\t\tlet safetyCheckPassed = false\n\t\tif (!options.force) {\n\t\t\tconst shouldCheckMergeSafety = options.checkMergeSafety ?? (options.deleteBranch === true)\n\t\t\tconst shouldCheckRemoteBranch = options.checkRemoteBranch ?? false\n\t\t\tconst safety = await this.validateWorktreeSafety(worktree, parsed.originalInput, shouldCheckMergeSafety, shouldCheckRemoteBranch)\n\n\t\t\tif (!safety.isSafe) {\n\t\t\t\t// Format blocker messages for error output\n\t\t\t\tconst blockerMessage = safety.blockers.join('\\n\\n')\n\t\t\t\tthrow new Error(`Cannot cleanup:\\n\\n${blockerMessage}`)\n\t\t\t}\n\n\t\t\tsafetyCheckPassed = true\n\n\t\t\t// Log warnings if any\n\t\t\tif (safety.warnings.length > 0) {\n\t\t\t\tsafety.warnings.forEach(warning => {\n\t\t\t\t\tgetLogger().warn(warning)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Step 3: Pre-fetch database configuration before worktree removal\n\t\t// This config is used AFTER worktree deletion when env file no longer exists\n\t\tlet databaseConfig: { shouldCleanup: boolean; envFilePath: string } | null = null\n\t\tif (!options.keepDatabase && worktree) {\n\t\t\tconst envFilePath = path.join(worktree.path, '.env')\n\t\t\ttry {\n\t\t\t\t// Pre-check if database cleanup should happen by reading .env file now\n\t\t\t\tconst shouldCleanup = this.database\n\t\t\t\t\t? await this.database.shouldUseDatabaseBranching(envFilePath)\n\t\t\t\t\t: false\n\t\t\t\tdatabaseConfig = { shouldCleanup, envFilePath }\n\t\t\t} catch (error) {\n\t\t\t\t// If we can't read the config, we'll skip database cleanup\n\t\t\t\tgetLogger().warn(\n\t\t\t\t\t`Failed to read database config from ${envFilePath}, skipping database cleanup: ${\n\t\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t\t}`\n\t\t\t\t)\n\t\t\t\tdatabaseConfig = { shouldCleanup: false, envFilePath }\n\t\t\t}\n\t\t}\n\n\t\t// Step 3.5: Find main worktree path before deletion (needed for branch and database operations)\n\t\tlet mainWorktreePath: string | null = null\n\t\tif (!options.dryRun) {\n\t\t\ttry {\n\t\t\t\tmainWorktreePath = await findMainWorktreePathWithSettings(worktree.path, this.settingsManager)\n\t\t\t} catch (error) {\n\t\t\t\tgetLogger().warn(\n\t\t\t\t\t`Failed to find main worktree path: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Step 3.6: Pre-fetch merge target branch before worktree deletion\n\t\t// This is needed because deleteBranch() needs to know the merge target (parent branch for child looms)\n\t\t// but the worktree metadata won't be readable after deletion in Step 4\n\t\tlet mergeTargetBranch: string | null = null\n\t\tif (options.deleteBranch && worktree && !options.dryRun) {\n\t\t\ttry {\n\t\t\t\tmergeTargetBranch = await getMergeTargetBranch(worktree.path, {\n\t\t\t\t\tsettingsManager: this.settingsManager,\n\t\t\t\t\tmetadataManager: this.metadataManager,\n\t\t\t\t})\n\t\t\t\tgetLogger().debug(`Pre-fetched merge target branch: ${mergeTargetBranch}`)\n\t\t\t} catch (error) {\n\t\t\t\tgetLogger().warn(\n\t\t\t\t\t`Failed to pre-fetch merge target branch: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Step 4: Remove worktree\n\t\tif (options.dryRun) {\n\t\t\toperations.push({\n\t\t\t\ttype: 'worktree',\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: `[DRY RUN] Would remove worktree: ${worktree.path}`,\n\t\t\t})\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tconst worktreeOptions: { force?: boolean; removeDirectory: true; removeBranch: false } =\n\t\t\t\t\t{\n\t\t\t\t\t\tremoveDirectory: true,\n\t\t\t\t\t\tremoveBranch: false, // Handle branch separately\n\t\t\t\t\t}\n\t\t\t\tif (options.force !== undefined) {\n\t\t\t\t\tworktreeOptions.force = options.force\n\t\t\t\t}\n\t\t\t\tawait this.gitWorktree.removeWorktree(worktree.path, worktreeOptions)\n\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'worktree',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: `Worktree removed: ${worktree.path}`,\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error instanceof Error ? error : new Error('Unknown error')\n\t\t\t\terrors.push(err)\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'worktree',\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: `Failed to remove worktree`,\n\t\t\t\t\terror: err.message,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t// Step 4.5: Archive recap file\n\t\tif (worktree) {\n\t\t\tif (options.dryRun) {\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'recap',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: `[DRY RUN] Would archive recap file for: ${worktree.path}`,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tawait archiveRecap(worktree.path)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'recap',\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: `Recap file archived`,\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Non-fatal: log warning but don't add to errors\n\t\t\t\t\tconst err = error instanceof Error ? error : new Error('Unknown error')\n\t\t\t\t\tgetLogger().warn(`Recap archival failed: ${err.message}`)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'recap',\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: 'Recap archival failed (non-fatal)',\n\t\t\t\t\t\terror: err.message,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Step 5: Delete branch if requested\n\t\tif (options.deleteBranch && worktree) {\n\t\t\tif (options.dryRun) {\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'branch',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: `[DRY RUN] Would delete branch: ${worktree.branch}`,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst branchOptions: BranchDeleteOptions = {\n\t\t\t\t\t\tdryRun: false,\n\t\t\t\t\t\tsafetyVerified: safetyCheckPassed,\n\t\t\t\t\t}\n\t\t\t\t\t// Pass pre-fetched merge target (fetched in Step 3.6 before worktree deletion)\n\t\t\t\t\tif (mergeTargetBranch !== null) {\n\t\t\t\t\t\tbranchOptions.mergeTargetBranch = mergeTargetBranch\n\t\t\t\t\t}\n\t\t\t\t\tif (options.force !== undefined) {\n\t\t\t\t\t\tbranchOptions.force = options.force\n\t\t\t\t\t}\n\t\t\t\t\t// Pass main worktree path to ensure we can execute git commands\n\t\t\t\t\tawait this.deleteBranch(worktree.branch, branchOptions, mainWorktreePath ?? undefined)\n\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'branch',\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: `Branch deleted: ${worktree.branch}`,\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst err = error instanceof Error ? error : new Error('Unknown error')\n\t\t\t\t\terrors.push(err)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'branch',\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: `Failed to delete branch`,\n\t\t\t\t\t\terror: err.message,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Step 5.5: Cleanup CLI symlinks if CLI isolation is available\n\t\t// Derive identifier from parsed input (number for issue/PR, branchName for branch)\n\t\tconst cliIdentifier = parsed.number ?? parsed.branchName\n\t\tif (this.cliIsolation && cliIdentifier !== undefined) {\n\t\t\tif (options.dryRun) {\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'cli-symlinks',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: `[DRY RUN] Would cleanup CLI symlinks for: ${cliIdentifier}`,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst removed = await this.cliIsolation.cleanupVersionedExecutables(cliIdentifier)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'cli-symlinks',\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: removed.length > 0\n\t\t\t\t\t\t\t? `CLI symlinks removed: ${removed.length}`\n\t\t\t\t\t\t\t: 'No CLI symlinks to cleanup',\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Log warning but don't fail\n\t\t\t\t\tconst err = error instanceof Error ? error : new Error('Unknown error')\n\t\t\t\t\terrors.push(err)\n\t\t\t\t\tgetLogger().warn(\n\t\t\t\t\t\t`CLI symlink cleanup failed: ${err.message}`\n\t\t\t\t\t)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'cli-symlinks',\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: 'CLI symlink cleanup failed (non-fatal)',\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Step 6: Cleanup database after worktree and branch removal (using pre-read config)\n\t\tif (databaseConfig && worktree) {\n\t\t\tif (options.dryRun) {\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'database',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: `[DRY RUN] Would cleanup database branch for: ${worktree.branch}`,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tif (databaseConfig.shouldCleanup && this.database) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Call database deletion with pre-fetched shouldCleanup value and main worktree path\n\t\t\t\t\t\t\t// This avoids reading the already-deleted env file and running commands from deleted directories\n\t\t\t\t\t\t\tconst deletionResult = await this.database.deleteBranchIfConfigured(\n\t\t\t\t\t\t\t\tworktree.branch,\n\t\t\t\t\t\t\t\tdatabaseConfig.shouldCleanup,\n\t\t\t\t\t\t\t\tfalse, // isPreview\n\t\t\t\t\t\t\t\tmainWorktreePath ?? undefined\n\t\t\t\t\t\t\t)\n\n\t\t\t\t\t\t\t// Create operation result based on what actually happened\n\t\t\t\t\t\t\tif (deletionResult.deleted) {\n\t\t\t\t\t\t\t\t// Branch was actually deleted\n\t\t\t\t\t\t\t\tgetLogger().info(`Database branch deleted: ${worktree.branch}`)\n\t\t\t\t\t\t\t\toperations.push({\n\t\t\t\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\t\tmessage: `Database branch deleted`,\n\t\t\t\t\t\t\t\t\tdeleted: true,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} else if (deletionResult.notFound) {\n\t\t\t\t\t\t\t\t// Branch didn't exist - not an error, just nothing to delete\n\t\t\t\t\t\t\t\tgetLogger().debug(`No database branch found for: ${worktree.branch}`)\n\t\t\t\t\t\t\t\toperations.push({\n\t\t\t\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\t\tmessage: `No database branch found (skipped)`,\n\t\t\t\t\t\t\t\t\tdeleted: false,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} else if (deletionResult.userDeclined) {\n\t\t\t\t\t\t\t\t// User declined preview database deletion\n\t\t\t\t\t\t\t\tgetLogger().info('Preview database deletion declined by user')\n\t\t\t\t\t\t\t\toperations.push({\n\t\t\t\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\t\tmessage: `Database cleanup skipped (user declined)`,\n\t\t\t\t\t\t\t\t\tdeleted: false,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} else if (!deletionResult.success) {\n\t\t\t\t\t\t\t\t// Deletion failed with error\n\t\t\t\t\t\t\t\tconst errorMsg = deletionResult.error ?? 'Unknown error'\n\t\t\t\t\t\t\t\terrors.push(new Error(errorMsg))\n\t\t\t\t\t\t\t\tgetLogger().warn(`Database cleanup failed: ${errorMsg}`)\n\t\t\t\t\t\t\t\toperations.push({\n\t\t\t\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\t\t\t\tsuccess: false, // Non-fatal, but report error\n\t\t\t\t\t\t\t\t\tmessage: `Database cleanup failed`,\n\t\t\t\t\t\t\t\t\terror: errorMsg,\n\t\t\t\t\t\t\t\t\tdeleted: false,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Unexpected state - log for debugging\n\t\t\t\t\t\t\t\terrors.push(new Error('Database cleanup in an unknown state'))\n\t\t\t\t\t\t\t\tgetLogger().warn('Database deletion returned unexpected result state')\n\t\t\t\t\t\t\t\toperations.push({\n\t\t\t\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\t\tmessage: `Database cleanup in an unknown state`,\n\t\t\t\t\t\t\t\t\tdeleted: false,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t// Unexpected exception (shouldn't happen with result object pattern)\n\t\t\t\t\t\t\terrors.push(error instanceof Error ? error : new Error(String(error)))\n\t\t\t\t\t\t\tgetLogger().warn(\n\t\t\t\t\t\t\t\t`Unexpected database cleanup exception: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\toperations.push({\n\t\t\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\t\t\tmessage: `Database cleanup failed`,\n\t\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t\t\tdeleted: false,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Database manager not available or not configured\n\t\t\t\t\t\toperations.push({\n\t\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tmessage: `Database cleanup skipped (not available)`,\n\t\t\t\t\t\t\tdeleted: false,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// This catch block is for any unexpected errors in the outer logic\n\t\t\t\t\tconst err = error instanceof Error ? error : new Error('Unknown error')\n\t\t\t\t\terrors.push(err)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'database',\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: `Database cleanup failed`,\n\t\t\t\t\t\terror: err.message,\n\t\t\t\t\t\tdeleted: false,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Step 7: Delete or archive metadata file\n\t\tif (worktree) {\n\t\t\tif (options.dryRun) {\n\t\t\t\tconst action = options.archive ? 'archive' : 'delete'\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'metadata',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: `[DRY RUN] Would ${action} metadata for worktree: ${worktree.path}`,\n\t\t\t\t})\n\t\t\t} else if (options.archive) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.metadataManager.archiveMetadata(worktree.path)\n\t\t\t\t\tgetLogger().info(`Metadata archived for worktree: ${worktree.path}`)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'metadata',\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: 'Metadata archived',\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error))\n\t\t\t\t\terrors.push(err)\n\t\t\t\t\tgetLogger().warn(`Metadata archival failed: ${err.message}`)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'metadata',\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: 'Metadata archival failed (non-fatal)',\n\t\t\t\t\t\terror: err.message,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.metadataManager.deleteMetadata(worktree.path)\n\t\t\t\t\tgetLogger().info(`Metadata deleted for worktree: ${worktree.path}`)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'metadata',\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tmessage: 'Metadata deleted',\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error))\n\t\t\t\t\terrors.push(err)\n\t\t\t\t\tgetLogger().warn(`Metadata deletion failed: ${err.message}`)\n\t\t\t\t\toperations.push({\n\t\t\t\t\t\ttype: 'metadata',\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tmessage: 'Metadata deletion failed (non-fatal)',\n\t\t\t\t\t\terror: err.message,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Step 7.5: Remove Claude trust entry for the worktree\n\t\tif (worktree && !options.dryRun) {\n\t\t\ttry {\n\t\t\t\tawait removeClaudeTrust(worktree.path)\n\t\t\t\tgetLogger().debug(`Claude trust entry removed for worktree: ${worktree.path}`)\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'trust',\n\t\t\t\t\tsuccess: true,\n\t\t\t\t\tmessage: 'Claude trust entry removed',\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\t// Non-fatal: trust removal failure should not block cleanup\n\t\t\t\tconst err = error instanceof Error ? error : new Error(String(error))\n\t\t\t\tgetLogger().warn(`Claude trust removal failed (non-fatal): ${err.message}`)\n\t\t\t\toperations.push({\n\t\t\t\t\ttype: 'trust',\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tmessage: 'Claude trust removal failed (non-fatal)',\n\t\t\t\t\terror: err.message,\n\t\t\t\t})\n\t\t\t}\n\t\t} else if (worktree && options.dryRun) {\n\t\t\toperations.push({\n\t\t\t\ttype: 'trust',\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: `[DRY RUN] Would remove Claude trust entry for: ${worktree.path}`,\n\t\t\t})\n\t\t}\n\n\t\t// Calculate overall success\n\t\tconst success = errors.length === 0\n\n\t\treturn {\n\t\t\tidentifier: displayIdentifier,\n\t\t\tbranchName: worktree?.branch,\n\t\t\tsuccess,\n\t\t\toperations,\n\t\t\terrors,\n\t\t\trollbackRequired: false, // Cleanup operations are generally not reversible\n\t\t}\n\t}\n\n\t/**\n\t * Terminate dev server on specified port.\n\t * When a dockerIdentifier is provided, attempts Docker container cleanup first\n\t * before falling back to process-based detection.\n\t *\n\t * @param port - Port the dev server is running on\n\t * @param dockerIdentifier - Optional identifier for Docker container lookup (issue number, branch name, etc.)\n\t */\n\tasync terminateDevServer(port: number, dockerIdentifier?: string | number): Promise<boolean> {\n\t\tgetLogger().debug(`Checking for dev server on port ${port}`)\n\n\t\t// Try Docker container cleanup first if identifier provided\n\t\tif (dockerIdentifier !== undefined) {\n\t\t\tconst containerName = DockerManager.buildContainerName(dockerIdentifier)\n\t\t\tconst isRunning = await DockerManager.isContainerRunning(containerName)\n\t\t\tif (isRunning) {\n\t\t\t\tgetLogger().info(`Terminating Docker container: ${containerName}`)\n\t\t\t\tawait DockerManager.stopAndRemoveContainer(containerName)\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tgetLogger().debug(`No Docker container found with name \"${containerName}\", falling back to process detection`)\n\t\t}\n\n\t\t// Existing process-based detection\n\t\tconst processInfo = await this.processManager.detectDevServer(port)\n\n\t\tif (!processInfo) {\n\t\t\tgetLogger().debug(`No process found on port ${port}`)\n\t\t\treturn false\n\t\t}\n\n\t\tif (!processInfo.isDevServer) {\n\t\t\tgetLogger().warn(\n\t\t\t\t`Process on port ${port} (${processInfo.name}) doesn't appear to be a dev server, skipping`\n\t\t\t)\n\t\t\treturn false\n\t\t}\n\n\t\tgetLogger().info(`Terminating dev server: ${processInfo.name} (PID: ${processInfo.pid})`)\n\n\t\tawait this.processManager.terminateProcess(processInfo.pid)\n\n\t\t// Verify termination\n\t\tconst isFree = await this.processManager.verifyPortFree(port)\n\t\tif (!isFree) {\n\t\t\tthrow new Error(`Dev server may still be running on port ${port}`)\n\t\t}\n\n\t\treturn true\n\t}\n\n\t/**\n\t * Delete a Git branch with safety checks\n\t *\n\t * @param branchName - Name of the branch to delete\n\t * @param options - Delete options (force, dryRun)\n\t * @param cwd - Working directory to execute git command from (defaults to finding main worktree)\n\t */\n\tasync deleteBranch(\n\t\tbranchName: string,\n\t\toptions: BranchDeleteOptions = {},\n\t\tcwd?: string\n\t): Promise<boolean> {\n\t\t// Get protected branches list from centralized method\n\t\tconst protectedBranches = await this.settingsManager.getProtectedBranches(cwd)\n\n\t\t// Check for protected branches\n\t\tif (protectedBranches.includes(branchName)) {\n\t\t\tthrow new Error(`Cannot delete protected branch: ${branchName}`)\n\t\t}\n\n\t\t// Use provided cwd, or find main worktree path as fallback\n\t\t// This ensures we're not running git commands from a deleted directory\n\t\tconst workingDir = cwd ?? await findMainWorktreePathWithSettings(undefined, this.settingsManager)\n\n\t\t// Check if branch exists before attempting deletion (idempotent behavior)\n\t\ttry {\n\t\t\tawait executeGitCommand(['rev-parse', '--verify', `refs/heads/${branchName}`], {\n\t\t\t\tcwd: workingDir\n\t\t\t})\n\t\t} catch {\n\t\t\t// Branch doesn't exist - already deleted, return success\n\t\t\tgetLogger().debug(`Branch ${branchName} does not exist, skipping deletion`)\n\t\t\treturn true\n\t\t}\n\n\t\tif (options.dryRun) {\n\t\t\tgetLogger().info(`[DRY RUN] Would delete branch: ${branchName}`)\n\t\t\treturn true\n\t\t}\n\n\t\t// Execute git branch deletion\n\t\t// deleteCwd is declared outside try so it's accessible in the catch block for safetyVerified retry\n\t\tlet deleteCwd = workingDir // Default: main worktree\n\t\ttry {\n\t\t\t// Determine the correct delete flag and working directory\n\t\t\tlet deleteFlag = '-d' // Default: safe delete\n\n\t\t\tif (options.force) {\n\t\t\t\t// User explicitly requested force delete\n\t\t\t\tdeleteFlag = '-D'\n\t\t\t} else if (options.mergeTargetBranch) {\n\t\t\t\t// Use pre-fetched merge target (from Step 3.6, fetched before worktree deletion)\n\t\t\t\t// For child looms, git branch -d checks against HEAD, which may not be the correct target\n\t\t\t\t// Instead of using -D (force), we run git branch -d from the worktree where the\n\t\t\t\t// parent branch is checked out. This lets git do its own safety verification.\n\t\t\t\tconst mergeTarget = options.mergeTargetBranch\n\n\t\t\t\t// Find the worktree where the merge target (parent branch) is checked out\n\t\t\t\ttry {\n\t\t\t\t\tconst targetWorktreePath = await findWorktreeForBranch(mergeTarget, workingDir)\n\t\t\t\t\t// Run git branch -d from that worktree - HEAD will be the correct branch\n\t\t\t\t\t// and git will correctly verify the merge itself\n\t\t\t\t\tgetLogger().debug(`Running branch delete from worktree where '${mergeTarget}' is checked out: ${targetWorktreePath}`)\n\t\t\t\t\tdeleteCwd = targetWorktreePath\n\t\t\t\t} catch {\n\t\t\t\t\t// If we can't find the worktree for the target branch, fall back to checking merge status\n\t\t\t\t\t// and using -D if merged (the previous behavior)\n\t\t\t\t\tgetLogger().debug(`Could not find worktree for branch '${mergeTarget}', falling back to merge check`)\n\t\t\t\t\tconst isMerged = await isBranchMergedIntoMain(branchName, mergeTarget, workingDir)\n\n\t\t\t\t\tif (isMerged) {\n\t\t\t\t\t\tgetLogger().debug(`Branch '${branchName}' verified merged into '${mergeTarget}', using force delete`)\n\t\t\t\t\t\tdeleteFlag = '-D'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (options.worktreePath) {\n\t\t\t\t// DEPRECATED: Fall back to reading from worktree path if mergeTargetBranch not provided\n\t\t\t\t// This path should not be used when called from cleanupWorktree() since the worktree\n\t\t\t\t// has already been deleted by the time deleteBranch() is called\n\t\t\t\tgetLogger().warn('deleteBranch called with worktreePath but no mergeTargetBranch - this may fail if worktree was deleted')\n\t\t\t\ttry {\n\t\t\t\t\tconst mergeTarget = await getMergeTargetBranch(options.worktreePath, {\n\t\t\t\t\t\tsettingsManager: this.settingsManager,\n\t\t\t\t\t\tmetadataManager: this.metadataManager,\n\t\t\t\t\t})\n\n\t\t\t\t\t// Find the worktree where the merge target (parent branch) is checked out\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst targetWorktreePath = await findWorktreeForBranch(mergeTarget, workingDir)\n\t\t\t\t\t\tgetLogger().debug(`Running branch delete from worktree where '${mergeTarget}' is checked out: ${targetWorktreePath}`)\n\t\t\t\t\t\tdeleteCwd = targetWorktreePath\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tgetLogger().debug(`Could not find worktree for branch '${mergeTarget}', falling back to merge check`)\n\t\t\t\t\t\tconst isMerged = await isBranchMergedIntoMain(branchName, mergeTarget, workingDir)\n\n\t\t\t\t\t\tif (isMerged) {\n\t\t\t\t\t\t\tgetLogger().debug(`Branch '${branchName}' verified merged into '${mergeTarget}', using force delete`)\n\t\t\t\t\t\t\tdeleteFlag = '-D'\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// If we can't read the merge target (e.g., worktree deleted), just use safe delete\n\t\t\t\t\tgetLogger().debug(`Could not read merge target from worktreePath: ${error instanceof Error ? error.message : String(error)}`)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait executeGitCommand(['branch', deleteFlag, branchName], {\n\t\t\t\tcwd: deleteCwd\n\t\t\t})\n\n\t\t\tgetLogger().info(`Branch deleted: ${branchName}`)\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\n\t\t\t// Handle \"branch not found\" - may occur in race conditions\n\t\t\tif (errorMessage.includes('not found') || errorMessage.includes('does not exist')) {\n\t\t\t\tgetLogger().debug(`Branch ${branchName} already deleted`)\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tif (options.force) {\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\t// Git error for unmerged branch typically contains \"not fully merged\"\n\t\t\tif (errorMessage.includes('not fully merged')) {\n\t\t\t\tif (options.safetyVerified) {\n\t\t\t\t\t// Safety check already confirmed no data loss - retry with force delete\n\t\t\t\t\tgetLogger().info(`Branch '${branchName}' not merged into HEAD but safety verified - using force delete`)\n\t\t\t\t\tawait executeGitCommand(['branch', '-D', branchName], { cwd: deleteCwd })\n\t\t\t\t\tgetLogger().info(`Branch deleted: ${branchName}`)\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Cannot delete unmerged branch '${branchName}'. Use --force to delete anyway.`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// For other errors, show the actual git error\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Cleanup database branch\n\t * Gracefully handles missing DatabaseManager\n\t *\n\t * @deprecated This method is deprecated and should not be used for post-deletion cleanup.\n\t * Use the pre-fetch mechanism in cleanupWorktree() instead.\n\t * This method will fail if called after worktree deletion because\n\t * it attempts to read the .env file which has been deleted.\n\t *\n\t * @param branchName - Name of the branch to delete\n\t * @param worktreePath - Path to worktree (must still exist with .env file)\n\t */\n\tasync cleanupDatabase(branchName: string, worktreePath: string): Promise<boolean> {\n\t\tif (!this.database) {\n\t\t\tgetLogger().debug('Database manager not available, skipping database cleanup')\n\t\t\treturn false\n\t\t}\n\n\t\ttry {\n\t\t\t// Pre-fetch configuration before deletion\n\t\t\tconst envFilePath = path.join(worktreePath, '.env')\n\t\t\tconst shouldCleanup = await this.database.shouldUseDatabaseBranching(envFilePath)\n\n\t\t\t// Find main worktree path to avoid running commands from potentially deleted directories\n\t\t\tlet cwd: string | undefined\n\t\t\ttry {\n\t\t\t\tcwd = await findMainWorktreePathWithSettings(worktreePath, this.settingsManager)\n\t\t\t} catch (error) {\n\t\t\t\t// If we can't find main worktree, commands will run from current directory\n\t\t\t\tgetLogger().debug(\n\t\t\t\t\t`Could not find main worktree path, using current directory: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst result = await this.database.deleteBranchIfConfigured(\n\t\t\t\tbranchName,\n\t\t\t\tshouldCleanup,\n\t\t\t\tfalse, // isPreview\n\t\t\t\tcwd\n\t\t\t)\n\n\t\t\t// Only return true if deletion actually occurred\n\t\t\tif (result.deleted) {\n\t\t\t\tgetLogger().info(`Database branch deleted: ${branchName}`)\n\t\t\t\treturn true\n\t\t\t} else if (result.notFound) {\n\t\t\t\tgetLogger().debug(`No database branch found for: ${branchName}`)\n\t\t\t\treturn false\n\t\t\t} else if (result.userDeclined) {\n\t\t\t\tgetLogger().info('Preview database deletion declined by user')\n\t\t\t\treturn false\n\t\t\t} else if (!result.success) {\n\t\t\t\tgetLogger().warn(`Database cleanup failed: ${result.error ?? 'Unknown error'}`)\n\t\t\t\treturn false\n\t\t\t} else {\n\t\t\t\t// Unexpected state\n\t\t\t\tgetLogger().debug('Database deletion returned unexpected result')\n\t\t\t\treturn false\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Unexpected exception\n\t\t\tgetLogger().warn(\n\t\t\t\t`Unexpected database cleanup error: ${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 * Cleanup multiple worktrees\n\t */\n\tasync cleanupMultipleWorktrees(\n\t\tidentifiers: string[],\n\t\toptions: ResourceCleanupOptions = {}\n\t): Promise<CleanupResult[]> {\n\t\tconst results: CleanupResult[] = []\n\n\t\tfor (const identifier of identifiers) {\n\t\t\t// Parse the identifier to get ParsedInput format\n\t\t\tconst parsed = this.parseIdentifier(identifier)\n\t\t\tconst result = await this.cleanupWorktree(parsed, options)\n\t\t\tresults.push(result)\n\t\t}\n\n\t\treturn results\n\t}\n\n\t/**\n\t * Validate worktree safety given a worktree object\n\t * Private method used internally when worktree is already known\n\t *\n\t * @param worktree - The worktree to validate\n\t * @param identifier - The original identifier used (for error messages)\n\t * @param checkBranchMerge - Whether to check if branch is merged into main (for branch deletion)\n\t * @param checkRemoteBranch - Whether to check if branch exists on remote (for GitHub-PR mode)\n\t */\n\tprivate async validateWorktreeSafety(\n\t\tworktree: GitWorktree,\n\t\tidentifier: string,\n\t\tcheckBranchMerge: boolean = false,\n\t\tcheckRemoteBranch: boolean = false\n\t): Promise<SafetyCheck> {\n\t\tconst warnings: string[] = []\n\t\tconst blockers: string[] = []\n\n\t\t// Check if main worktree\n\t\tconst isMain = await this.gitWorktree.isMainWorktree(worktree, this.settingsManager)\n\t\tif (isMain) {\n\t\t\tblockers.push(`Cannot cleanup main worktree: \"${worktree.branch}\" @ \"${worktree.path}\"`)\n\t\t}\n\n\t\t// Check for uncommitted changes\n\t\tconst hasChanges = await hasUncommittedChanges(worktree.path)\n\t\tif (hasChanges) {\n\t\t\t// Create simple blocker message with actionable guidance\n\t\t\tconst blockerMessage =\n\t\t\t\t`Worktree has uncommitted changes.\\n\\n` +\n\t\t\t\t`Please resolve before cleanup - you have some options:\\n` +\n\t\t\t\t` • Commit changes: cd ${worktree.path} && git commit -am \"message\"\\n` +\n\t\t\t\t` • Stash changes: cd ${worktree.path} && git stash\\n` +\n\t\t\t\t` • Force cleanup: il cleanup ${identifier} --force (WARNING: will discard changes)`\n\n\t\t\tblockers.push(blockerMessage)\n\t\t}\n\n\t\t// 5-point safety check for branch deletion\n\t\t// The key insight: we care about DATA LOSS, not about remote state\n\t\t// - Remote ahead of local is SAFE (commits exist on remote, no data loss)\n\t\t// - Local ahead of remote is DANGEROUS (unpushed commits would be lost)\n\t\t//\n\t\t// 1. Network error -> BLOCK (can't verify safety)\n\t\t// 2. Remote ahead of local -> OK (no data loss - commits exist on remote)\n\t\t// 3. Local ahead of remote (unpushed commits) -> BLOCK (data loss risk)\n\t\t// 4. No remote, merged to main -> OK (work is in main)\n\t\t// 5. No remote, NOT merged to main -> BLOCK (unmerged work would be lost)\n\t\tif ((checkBranchMerge || checkRemoteBranch) && worktree.branch) {\n\t\t\t// Use shared utility to get merge target (parent branch for child looms, main for others)\n\t\t\tconst mainBranch = await getMergeTargetBranch(worktree.path, {\n\t\t\t\tsettingsManager: this.settingsManager,\n\t\t\t\tmetadataManager: this.metadataManager,\n\t\t\t})\n\n\t\t\t// Check remote branch status\n\t\t\tconst remoteStatus: RemoteBranchStatus = await checkRemoteBranchStatus(worktree.branch, worktree.path)\n\n\t\t\t// Scenario 1: Network error checking remote -> Block\n\t\t\tif (remoteStatus.networkError) {\n\t\t\t\tconst blockerMessage =\n\t\t\t\t\t`Cannot verify remote branch status due to network error.\\n\\n` +\n\t\t\t\t\t`Error: ${remoteStatus.errorMessage ?? 'Unknown network error'}\\n\\n` +\n\t\t\t\t\t`Unable to determine if branch '${worktree.branch}' is safely backed up.\\n` +\n\t\t\t\t\t`Use --force to proceed without verification.`\n\n\t\t\t\tblockers.push(blockerMessage)\n\t\t\t}\n\t\t\t// Scenario 3: Local ahead of remote (unpushed commits) -> Block (data loss risk)\n\t\t\telse if (remoteStatus.exists && remoteStatus.localAhead) {\n\t\t\t\tconst blockerMessage =\n\t\t\t\t\t`Branch '${worktree.branch}' has unpushed commits that would be lost.\\n` +\n\t\t\t\t\t`The remote branch exists but your local branch is ahead.\\n\\n` +\n\t\t\t\t\t`Please resolve before cleanup:\\n` +\n\t\t\t\t\t` • Push your commits: git push origin ${worktree.branch}\\n` +\n\t\t\t\t\t` • Force cleanup: il cleanup ${identifier} --force (WARNING: will lose commits)`\n\n\t\t\t\tblockers.push(blockerMessage)\n\t\t\t}\n\t\t\t// Scenario 2: Remote ahead of local OR same commits -> Safe (work is on remote)\n\t\t\telse if (remoteStatus.exists && !remoteStatus.localAhead) {\n\t\t\t\t// Work is safely on remote (either remote is ahead or same commits)\n\t\t\t\t// No blocker needed\n\t\t\t}\n\t\t\t// Remote doesn't exist - need to check merge status\n\t\t\telse if (!remoteStatus.exists) {\n\t\t\t\tconst isMerged = await isBranchMergedIntoMain(worktree.branch, mainBranch, worktree.path)\n\n\t\t\t\tif (isMerged) {\n\t\t\t\t\t// Scenario 4: Remote doesn't exist, but merged to main -> Safe\n\t\t\t\t\t// No blocker needed\n\t\t\t\t} else {\n\t\t\t\t\t// Scenario 5: Remote doesn't exist AND not merged to main -> Block\n\t\t\t\t\tconst blockerMessage =\n\t\t\t\t\t\t`Branch '${worktree.branch}' has not been pushed to remote and is not merged into '${mainBranch}'.\\n` +\n\t\t\t\t\t\t`Deleting this branch would result in data loss.\\n\\n` +\n\t\t\t\t\t\t`Please resolve before cleanup - you have some options:\\n` +\n\t\t\t\t\t\t` • Push to remote: git push -u origin ${worktree.branch}\\n` +\n\t\t\t\t\t\t` • Merge to ${mainBranch}: git checkout ${mainBranch} && git merge ${worktree.branch}\\n` +\n\t\t\t\t\t\t` • Force cleanup: il cleanup ${identifier} --force (WARNING: will lose commits)`\n\n\t\t\t\t\tblockers.push(blockerMessage)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tisSafe: blockers.length === 0,\n\t\t\twarnings,\n\t\t\tblockers,\n\t\t}\n\t}\n\n\t/**\n\t * Validate cleanup safety\n\t */\n\tasync validateCleanupSafety(identifier: string): Promise<SafetyCheck> {\n\t\tconst warnings: string[] = []\n\t\tconst blockers: string[] = []\n\n\t\t// Find worktree\n\t\tconst worktrees = await this.gitWorktree.findWorktreesByIdentifier(identifier)\n\n\t\tif (worktrees.length === 0) {\n\t\t\tblockers.push(`No worktree found for: ${identifier}`)\n\t\t\treturn { isSafe: false, warnings, blockers }\n\t\t}\n\n\t\tconst worktree = worktrees[0]\n\t\tif (!worktree) {\n\t\t\tblockers.push(`No worktree found for: ${identifier}`)\n\t\t\treturn { isSafe: false, warnings, blockers }\n\t\t}\n\n\t\t// Delegate to private method that validates the worktree\n\t\treturn await this.validateWorktreeSafety(worktree, identifier)\n\t}\n\n\t/**\n\t * Parse identifier to determine type and extract number\n\t * Helper method for port calculation\n\t */\n\tprivate parseIdentifier(identifier: string): ParsedInput {\n\t\t// Check for issue pattern\n\t\tconst issueId = extractIssueNumber(identifier)\n\t\tif (issueId !== null) {\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: issueId,\n\t\t\t\toriginalInput: identifier\n\t\t\t}\n\t\t}\n\n\t\t// Check for PR pattern\n\t\tconst prMatch = identifier.match(/(?:pr|PR)[/-](\\d+)/)\n\t\tif (prMatch?.[1]) {\n\t\t\treturn {\n\t\t\t\ttype: 'pr',\n\t\t\t\tnumber: parseInt(prMatch[1], 10),\n\t\t\t\toriginalInput: identifier\n\t\t\t}\n\t\t}\n\n\t\t// Check for numeric identifier\n\t\tconst numericMatch = identifier.match(/^#?(\\d+)$/)\n\t\tif (numericMatch?.[1]) {\n\t\t\t// Assume issue for numeric identifiers\n\t\t\treturn {\n\t\t\t\ttype: 'issue',\n\t\t\t\tnumber: parseInt(numericMatch[1], 10),\n\t\t\t\toriginalInput: identifier\n\t\t\t}\n\t\t}\n\n\t\t// Treat as branch name\n\t\treturn {\n\t\t\ttype: 'branch',\n\t\t\tbranchName: identifier,\n\t\t\toriginalInput: identifier\n\t\t}\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
extractIssueNumber,
|
|
4
4
|
extractPRNumber
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QNPJXO53.js";
|
|
6
6
|
|
|
7
7
|
// src/utils/IdentifierParser.ts
|
|
8
8
|
function matchIssueIdentifier(input) {
|
|
@@ -108,4 +108,4 @@ export {
|
|
|
108
108
|
matchIssueIdentifier,
|
|
109
109
|
IdentifierParser
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=chunk-
|
|
111
|
+
//# sourceMappingURL=chunk-SN4S5CWL.js.map
|
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
import {
|
|
3
3
|
detectPackageManager,
|
|
4
4
|
runScript
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VIQOQ463.js";
|
|
6
6
|
import {
|
|
7
7
|
getPackageConfig,
|
|
8
8
|
hasScript
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-K3QGG4O2.js";
|
|
10
10
|
import {
|
|
11
11
|
promptCommitAction
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-NPVA65KS.js";
|
|
13
13
|
import {
|
|
14
14
|
detectClaudeCli,
|
|
15
15
|
launchClaude
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-DDHWZNGL.js";
|
|
17
17
|
import {
|
|
18
18
|
executeGitCommand
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-QNPJXO53.js";
|
|
20
20
|
import {
|
|
21
21
|
getLogger
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-FTYWGQFM.js";
|
|
23
23
|
import {
|
|
24
24
|
logger
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-VRPPI6GU.js";
|
|
26
26
|
|
|
27
27
|
// src/lib/ValidationRunner.ts
|
|
28
28
|
var ValidationRunner = class {
|
|
@@ -828,4 +828,4 @@ export {
|
|
|
828
828
|
UserAbortedCommitError,
|
|
829
829
|
CommitManager
|
|
830
830
|
};
|
|
831
|
-
//# sourceMappingURL=chunk-
|
|
831
|
+
//# sourceMappingURL=chunk-TAEVA4QR.js.map
|