@iloom/cli 0.10.2 → 0.11.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 +4 -2
- package/dist/{BranchNamingService-4OP6LOH6.js → BranchNamingService-XBCO747L.js} +4 -4
- package/dist/ClaudeContextManager-SXDCWDJA.js +14 -0
- package/dist/ClaudeService-6E6MCGJE.js +13 -0
- package/dist/GitHubService-2R5GQG4K.js +12 -0
- package/dist/IssueTrackerFactory-XN6MQ4UN.js +14 -0
- package/dist/{LoomLauncher-FRECYMXS.js → LoomLauncher-5AZU2F5I.js} +15 -12
- package/dist/LoomLauncher-5AZU2F5I.js.map +1 -0
- package/dist/MetadataManager-CMQQTFLQ.js +10 -0
- package/dist/ProjectCapabilityDetector-IC6NAFGY.js +11 -0
- package/dist/{PromptTemplateManager-YOE2SIPG.js → PromptTemplateManager-T5VTLJP3.js} +3 -3
- package/dist/README.md +4 -2
- package/dist/{SettingsManager-FNKCOZMQ.js → SettingsManager-WQ5NSGAH.js} +3 -3
- package/dist/SettingsMigrationManager-S6J7OHUH.js +10 -0
- package/dist/agents/iloom-code-reviewer.md +50 -8
- package/dist/agents/iloom-issue-analyze-and-plan.md +10 -0
- package/dist/agents/iloom-issue-analyzer.md +13 -0
- package/dist/agents/iloom-issue-complexity-evaluator.md +8 -1
- package/dist/agents/iloom-issue-enhancer.md +8 -1
- package/dist/agents/iloom-issue-planner.md +5 -0
- package/dist/build-OLS6J5KZ.js +27 -0
- package/dist/{chunk-WWKOVDWC.js → chunk-3GTUXW26.js} +3 -3
- package/dist/{chunk-4FGEGQW4.js → chunk-3RXYOBME.js} +5 -5
- package/dist/{chunk-HEXKPKCK.js → chunk-5LTID2AF.js} +6 -6
- package/dist/{chunk-G5V75JD5.js → chunk-5PNZBH6V.js} +2 -2
- package/dist/{chunk-SKSYYBCU.js → chunk-5UFGO4ZT.js} +24 -3
- package/dist/{chunk-SKSYYBCU.js.map → chunk-5UFGO4ZT.js.map} +1 -1
- package/dist/{chunk-XE4BDRZD.js → chunk-6YVJVUR4.js} +3 -3
- package/dist/{chunk-RJ3VBUFK.js → chunk-7FIXNAUO.js} +36 -7
- package/dist/chunk-7FIXNAUO.js.map +1 -0
- package/dist/{chunk-QFTDZ5E3.js → chunk-7NFCGKZT.js} +3 -3
- package/dist/{chunk-433MOLAU.js → chunk-7OCGBJLR.js} +2 -2
- package/dist/{chunk-2VEWSM34.js → chunk-ABVMUNCD.js} +8 -8
- package/dist/{chunk-7JDMYTFZ.js → chunk-CV47VCMQ.js} +2 -2
- package/dist/{chunk-7VHJNVLF.js → chunk-ET6A2JR4.js} +8 -6
- package/dist/chunk-ET6A2JR4.js.map +1 -0
- package/dist/{chunk-MORRVYPT.js → chunk-G2MNSPA4.js} +2 -2
- package/dist/{chunk-RSYT7MVI.js → chunk-GMDSYLI6.js} +36 -3
- package/dist/chunk-GMDSYLI6.js.map +1 -0
- package/dist/{chunk-VT4PDUYT.js → chunk-H2SSF24U.js} +284 -209
- package/dist/chunk-H2SSF24U.js.map +1 -0
- package/dist/{chunk-LLHXQS3C.js → chunk-HLDY5S4C.js} +3 -3
- package/dist/{chunk-BYUMEDDD.js → chunk-IDCE26KD.js} +3 -3
- package/dist/{chunk-ZGM2FE2R.js → chunk-IR74O2F6.js} +221 -86
- package/dist/chunk-IR74O2F6.js.map +1 -0
- package/dist/{chunk-O7VL5N6S.js → chunk-K7R5QY6C.js} +2 -2
- package/dist/{chunk-BU53XIGY.js → chunk-KQFIGI37.js} +5 -5
- package/dist/{chunk-I5T677EA.js → chunk-LE2NOUTN.js} +3 -3
- package/dist/{chunk-KXDRI47U.js → chunk-LHDD4JHC.js} +6 -6
- package/dist/{chunk-2YZCWAVZ.js → chunk-LL6TOX3G.js} +9 -9
- package/dist/{chunk-YQ57ORTV.js → chunk-NCPZYQ4B.js} +2 -2
- package/dist/{chunk-EWJFUFPT.js → chunk-NDSGJZI2.js} +2 -2
- package/dist/{chunk-VG45TUYK.js → chunk-NH3QZYE5.js} +2 -2
- package/dist/{chunk-BFLMCE2U.js → chunk-NN5RYWXA.js} +7 -7
- package/dist/chunk-NOMQ5RFG.js +118 -0
- package/dist/chunk-NOMQ5RFG.js.map +1 -0
- package/dist/{chunk-KIK2ZFAL.js → chunk-QNHZM5ZV.js} +3 -3
- package/dist/{chunk-V3SVMFDQ.js → chunk-QR4FU53I.js} +8 -8
- package/dist/{chunk-FXDYIV3K.js → chunk-QVAA5KHK.js} +2 -2
- package/dist/{chunk-NGJZ4TOU.js → chunk-RBYTXYGD.js} +2 -2
- package/dist/{chunk-SWSJWA2S.js → chunk-RMLADZRY.js} +12 -9
- package/dist/chunk-RMLADZRY.js.map +1 -0
- package/dist/{chunk-CVCTIDDK.js → chunk-RVI6C2H5.js} +5 -5
- package/dist/{chunk-Q7POFB5Q.js → chunk-SQYHPBFP.js} +2 -2
- package/dist/{chunk-BFHDVFSK.js → chunk-TEJAGQX2.js} +64 -40
- package/dist/chunk-TEJAGQX2.js.map +1 -0
- package/dist/{chunk-QZWEJVWV.js → chunk-TZNNJLGT.js} +6 -6
- package/dist/{chunk-63QWFWH3.js → chunk-UDCI3QTS.js} +2 -2
- package/dist/{chunk-UKBAJ2QQ.js → chunk-UHIBKD73.js} +7 -7
- package/dist/{chunk-WXIM2WS7.js → chunk-V4STTBQD.js} +10 -10
- package/dist/{chunk-P4O6EH46.js → chunk-VMZG66UV.js} +5 -5
- package/dist/{chunk-C6HNNJIV.js → chunk-VNYWBHKR.js} +34 -4
- package/dist/chunk-VNYWBHKR.js.map +1 -0
- package/dist/{chunk-HYGUPUV5.js → chunk-VUUN3KE4.js} +10 -10
- package/dist/chunk-VUUN3KE4.js.map +1 -0
- package/dist/{chunk-UUEW5KWB.js → chunk-WG4MLJ6J.js} +15 -10
- package/dist/chunk-WG4MLJ6J.js.map +1 -0
- package/dist/{chunk-3F27M7ZD.js → chunk-XFQGI2E3.js} +66 -43
- package/dist/chunk-XFQGI2E3.js.map +1 -0
- package/dist/{chunk-LUKXJSRI.js → chunk-XXFSOVL3.js} +4 -4
- package/dist/{chunk-PZ5WSR5Z.js → chunk-Y3RX7LZT.js} +8 -5
- package/dist/chunk-Y3RX7LZT.js.map +1 -0
- package/dist/{chunk-KB64WNBZ.js → chunk-YRCEOQPX.js} +4 -2
- package/dist/chunk-YRCEOQPX.js.map +1 -0
- package/dist/{chunk-6MLEBAYZ.js → chunk-ZAXRQLK3.js} +2 -2
- package/dist/{claude-LN7OWVNI.js → claude-ONQTDWV3.js} +4 -4
- package/dist/{cleanup-4ZM2AJDC.js → cleanup-YOM6PQCN.js} +35 -34
- package/dist/{cleanup-4ZM2AJDC.js.map → cleanup-YOM6PQCN.js.map} +1 -1
- package/dist/cli.js +227 -152
- package/dist/cli.js.map +1 -1
- package/dist/{color-4TJ4P5EY.js → color-VQD52LOI.js} +3 -3
- package/dist/{commit-4CFLXRZ3.js → commit-DC2Q5CDY.js} +15 -15
- package/dist/{compile-7ALJHZ4N.js → compile-4NCQECKE.js} +11 -11
- package/dist/{contribute-5GKLK3BQ.js → contribute-M5UWXCAV.js} +12 -12
- package/dist/darwin-5BHWRJ7D.js +10 -0
- package/dist/{dev-server-7SMIB7OF.js → dev-server-CYRP6M73.js} +19 -19
- package/dist/{feedback-EZWF5CAL.js → feedback-BMAZGKRW.js} +16 -16
- package/dist/{git-GTLKAZRJ.js → git-BXUD6CL5.js} +6 -6
- package/dist/ignite-IO4LXVXJ.js +35 -0
- package/dist/index.d.ts +39 -65
- package/dist/index.js +634 -107
- package/dist/index.js.map +1 -1
- package/dist/{init-ZB2RITW6.js → init-CI43GJHV.js} +17 -17
- package/dist/{init-ZB2RITW6.js.map → init-CI43GJHV.js.map} +1 -1
- package/dist/{install-deps-RLSGSHH7.js → install-deps-SRTM5U7D.js} +11 -11
- package/dist/{installation-detector-MMFWLJYN.js → installation-detector-HF6QN7KP.js} +3 -3
- package/dist/{issues-4UUAQ5K6.js → issues-DMRQJH7E.js} +15 -15
- package/dist/lint-BSWRMGPZ.js +27 -0
- package/dist/linux-RYLOP2LY.js +103 -0
- package/dist/linux-RYLOP2LY.js.map +1 -0
- package/dist/mcp/chunk-PIIRD4LO.js +373 -0
- package/dist/mcp/chunk-PIIRD4LO.js.map +1 -0
- package/dist/mcp/darwin-3JFFE3W2.js +10 -0
- package/dist/mcp/issue-management-server.js +23 -127
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/mcp/linux-JBVS4R3A.js +103 -0
- package/dist/mcp/linux-JBVS4R3A.js.map +1 -0
- package/dist/mcp/tmux-RYBLEHUZ.js +156 -0
- package/dist/mcp/tmux-RYBLEHUZ.js.map +1 -0
- package/dist/mcp/wsl-4QZIQLLE.js +78 -0
- package/dist/mcp/wsl-4QZIQLLE.js.map +1 -0
- package/dist/neon-helpers-HWIYRKOW.js +11 -0
- package/dist/{open-FXWW3VI4.js → open-2Y7GSUTJ.js} +19 -19
- package/dist/{plan-D3KSN5MU.js → plan-SWFPLNJE.js} +47 -46
- package/dist/{plan-D3KSN5MU.js.map → plan-SWFPLNJE.js.map} +1 -1
- package/dist/{projects-2UOXFLNZ.js → projects-IUSUXD5D.js} +6 -6
- package/dist/{prompt-ONNPSNKM.js → prompt-7LZB4PAT.js} +3 -3
- package/dist/prompts/init-prompt.txt +56 -107
- package/dist/prompts/issue-prompt.txt +57 -11
- package/dist/prompts/pr-prompt.txt +154 -4
- package/dist/prompts/regular-prompt.txt +20 -3
- package/dist/prompts/swarm-orchestrator-prompt.txt +114 -8
- package/dist/{rebase-62FDLIH4.js → rebase-S6OHAOOF.js} +12 -12
- package/dist/{recap-OMBOKJST.js → recap-GGVCG5VH.js} +9 -9
- package/dist/{remote-IJAMOEAP.js → remote-MZTFHHTU.js} +3 -3
- package/dist/remote-MZTFHHTU.js.map +1 -0
- package/dist/{run-BBXLRIZB.js → run-ST3FR75O.js} +19 -19
- package/dist/schema/settings.schema.json +8 -49
- package/dist/{shell-RF7LTND5.js → shell-W4SBQPTE.js} +8 -8
- package/dist/{summary-YZI25KW4.js → summary-P2JCIIJO.js} +17 -17
- package/dist/test-6JH4FE2X.js +27 -0
- package/dist/{test-git-XM4TM65W.js → test-git-2KFFAQ6B.js} +6 -6
- package/dist/{test-jira-LDTOYFSD.js → test-jira-FKDKG6CD.js} +8 -8
- package/dist/{test-prefix-GBO37XCN.js → test-prefix-GP2DAX37.js} +11 -11
- package/dist/test-prefix-GP2DAX37.js.map +1 -0
- package/dist/{test-tabs-D3POYOJ5.js → test-tabs-YDWMWTVA.js} +3 -3
- package/dist/{test-webserver-NZ3JTVLL.js → test-webserver-QI3QQFZ3.js} +8 -8
- package/dist/tmux-7ZTA3BDI.js +156 -0
- package/dist/tmux-7ZTA3BDI.js.map +1 -0
- package/dist/{update-HJKDYA3F.js → update-XLW7R7FL.js} +4 -4
- package/dist/{update-notifier-LBAUOOLM.js → update-notifier-EYLAXZAA.js} +3 -3
- package/dist/update-notifier-EYLAXZAA.js.map +1 -0
- package/dist/{vscode-6XUGHJKL.js → vscode-TOGE5N67.js} +13 -13
- package/dist/{vscode-announcement-EQ2SKK3T.js → vscode-announcement-NIX7O2MG.js} +3 -3
- package/dist/wsl-Y4GUTOQ7.js +78 -0
- package/dist/wsl-Y4GUTOQ7.js.map +1 -0
- package/package.json +4 -2
- package/dist/ClaudeContextManager-ZKTUVQB2.js +0 -14
- package/dist/ClaudeService-TRWOYQ6O.js +0 -13
- package/dist/GitHubService-MEHKHUQP.js +0 -12
- package/dist/IssueTrackerFactory-NG53YX5S.js +0 -14
- package/dist/LoomLauncher-FRECYMXS.js.map +0 -1
- package/dist/MetadataManager-5QZSTKNN.js +0 -10
- package/dist/ProjectCapabilityDetector-5KSYUTBJ.js +0 -11
- package/dist/SettingsMigrationManager-LEBMJP3B.js +0 -10
- package/dist/build-VHGEMXBA.js +0 -27
- package/dist/chunk-3F27M7ZD.js.map +0 -1
- package/dist/chunk-7VHJNVLF.js.map +0 -1
- package/dist/chunk-BFHDVFSK.js.map +0 -1
- package/dist/chunk-C6HNNJIV.js.map +0 -1
- package/dist/chunk-HYGUPUV5.js.map +0 -1
- package/dist/chunk-KB64WNBZ.js.map +0 -1
- package/dist/chunk-PZ5WSR5Z.js.map +0 -1
- package/dist/chunk-RJ3VBUFK.js.map +0 -1
- package/dist/chunk-RSYT7MVI.js.map +0 -1
- package/dist/chunk-SWSJWA2S.js.map +0 -1
- package/dist/chunk-UUEW5KWB.js.map +0 -1
- package/dist/chunk-VT4PDUYT.js.map +0 -1
- package/dist/chunk-ZGM2FE2R.js.map +0 -1
- package/dist/ignite-MQETGFNA.js +0 -34
- package/dist/lint-AAN2NZWG.js +0 -27
- package/dist/neon-helpers-CQN2PB4S.js +0 -11
- package/dist/test-SGO6I5Z7.js +0 -27
- package/dist/test-prefix-GBO37XCN.js.map +0 -1
- /package/dist/{BranchNamingService-4OP6LOH6.js.map → BranchNamingService-XBCO747L.js.map} +0 -0
- /package/dist/{ClaudeContextManager-ZKTUVQB2.js.map → ClaudeContextManager-SXDCWDJA.js.map} +0 -0
- /package/dist/{ClaudeService-TRWOYQ6O.js.map → ClaudeService-6E6MCGJE.js.map} +0 -0
- /package/dist/{GitHubService-MEHKHUQP.js.map → GitHubService-2R5GQG4K.js.map} +0 -0
- /package/dist/{IssueTrackerFactory-NG53YX5S.js.map → IssueTrackerFactory-XN6MQ4UN.js.map} +0 -0
- /package/dist/{MetadataManager-5QZSTKNN.js.map → MetadataManager-CMQQTFLQ.js.map} +0 -0
- /package/dist/{ProjectCapabilityDetector-5KSYUTBJ.js.map → ProjectCapabilityDetector-IC6NAFGY.js.map} +0 -0
- /package/dist/{PromptTemplateManager-YOE2SIPG.js.map → PromptTemplateManager-T5VTLJP3.js.map} +0 -0
- /package/dist/{SettingsManager-FNKCOZMQ.js.map → SettingsManager-WQ5NSGAH.js.map} +0 -0
- /package/dist/{SettingsMigrationManager-LEBMJP3B.js.map → SettingsMigrationManager-S6J7OHUH.js.map} +0 -0
- /package/dist/{build-VHGEMXBA.js.map → build-OLS6J5KZ.js.map} +0 -0
- /package/dist/{chunk-WWKOVDWC.js.map → chunk-3GTUXW26.js.map} +0 -0
- /package/dist/{chunk-4FGEGQW4.js.map → chunk-3RXYOBME.js.map} +0 -0
- /package/dist/{chunk-HEXKPKCK.js.map → chunk-5LTID2AF.js.map} +0 -0
- /package/dist/{chunk-G5V75JD5.js.map → chunk-5PNZBH6V.js.map} +0 -0
- /package/dist/{chunk-XE4BDRZD.js.map → chunk-6YVJVUR4.js.map} +0 -0
- /package/dist/{chunk-QFTDZ5E3.js.map → chunk-7NFCGKZT.js.map} +0 -0
- /package/dist/{chunk-433MOLAU.js.map → chunk-7OCGBJLR.js.map} +0 -0
- /package/dist/{chunk-2VEWSM34.js.map → chunk-ABVMUNCD.js.map} +0 -0
- /package/dist/{chunk-7JDMYTFZ.js.map → chunk-CV47VCMQ.js.map} +0 -0
- /package/dist/{chunk-MORRVYPT.js.map → chunk-G2MNSPA4.js.map} +0 -0
- /package/dist/{chunk-LLHXQS3C.js.map → chunk-HLDY5S4C.js.map} +0 -0
- /package/dist/{chunk-BYUMEDDD.js.map → chunk-IDCE26KD.js.map} +0 -0
- /package/dist/{chunk-O7VL5N6S.js.map → chunk-K7R5QY6C.js.map} +0 -0
- /package/dist/{chunk-BU53XIGY.js.map → chunk-KQFIGI37.js.map} +0 -0
- /package/dist/{chunk-I5T677EA.js.map → chunk-LE2NOUTN.js.map} +0 -0
- /package/dist/{chunk-KXDRI47U.js.map → chunk-LHDD4JHC.js.map} +0 -0
- /package/dist/{chunk-2YZCWAVZ.js.map → chunk-LL6TOX3G.js.map} +0 -0
- /package/dist/{chunk-YQ57ORTV.js.map → chunk-NCPZYQ4B.js.map} +0 -0
- /package/dist/{chunk-EWJFUFPT.js.map → chunk-NDSGJZI2.js.map} +0 -0
- /package/dist/{chunk-VG45TUYK.js.map → chunk-NH3QZYE5.js.map} +0 -0
- /package/dist/{chunk-BFLMCE2U.js.map → chunk-NN5RYWXA.js.map} +0 -0
- /package/dist/{chunk-KIK2ZFAL.js.map → chunk-QNHZM5ZV.js.map} +0 -0
- /package/dist/{chunk-V3SVMFDQ.js.map → chunk-QR4FU53I.js.map} +0 -0
- /package/dist/{chunk-FXDYIV3K.js.map → chunk-QVAA5KHK.js.map} +0 -0
- /package/dist/{chunk-NGJZ4TOU.js.map → chunk-RBYTXYGD.js.map} +0 -0
- /package/dist/{chunk-CVCTIDDK.js.map → chunk-RVI6C2H5.js.map} +0 -0
- /package/dist/{chunk-Q7POFB5Q.js.map → chunk-SQYHPBFP.js.map} +0 -0
- /package/dist/{chunk-QZWEJVWV.js.map → chunk-TZNNJLGT.js.map} +0 -0
- /package/dist/{chunk-63QWFWH3.js.map → chunk-UDCI3QTS.js.map} +0 -0
- /package/dist/{chunk-UKBAJ2QQ.js.map → chunk-UHIBKD73.js.map} +0 -0
- /package/dist/{chunk-WXIM2WS7.js.map → chunk-V4STTBQD.js.map} +0 -0
- /package/dist/{chunk-P4O6EH46.js.map → chunk-VMZG66UV.js.map} +0 -0
- /package/dist/{chunk-LUKXJSRI.js.map → chunk-XXFSOVL3.js.map} +0 -0
- /package/dist/{chunk-6MLEBAYZ.js.map → chunk-ZAXRQLK3.js.map} +0 -0
- /package/dist/{claude-LN7OWVNI.js.map → claude-ONQTDWV3.js.map} +0 -0
- /package/dist/{color-4TJ4P5EY.js.map → color-VQD52LOI.js.map} +0 -0
- /package/dist/{commit-4CFLXRZ3.js.map → commit-DC2Q5CDY.js.map} +0 -0
- /package/dist/{compile-7ALJHZ4N.js.map → compile-4NCQECKE.js.map} +0 -0
- /package/dist/{contribute-5GKLK3BQ.js.map → contribute-M5UWXCAV.js.map} +0 -0
- /package/dist/{git-GTLKAZRJ.js.map → darwin-5BHWRJ7D.js.map} +0 -0
- /package/dist/{dev-server-7SMIB7OF.js.map → dev-server-CYRP6M73.js.map} +0 -0
- /package/dist/{feedback-EZWF5CAL.js.map → feedback-BMAZGKRW.js.map} +0 -0
- /package/dist/{ignite-MQETGFNA.js.map → git-BXUD6CL5.js.map} +0 -0
- /package/dist/{installation-detector-MMFWLJYN.js.map → ignite-IO4LXVXJ.js.map} +0 -0
- /package/dist/{install-deps-RLSGSHH7.js.map → install-deps-SRTM5U7D.js.map} +0 -0
- /package/dist/{neon-helpers-CQN2PB4S.js.map → installation-detector-HF6QN7KP.js.map} +0 -0
- /package/dist/{issues-4UUAQ5K6.js.map → issues-DMRQJH7E.js.map} +0 -0
- /package/dist/{lint-AAN2NZWG.js.map → lint-BSWRMGPZ.js.map} +0 -0
- /package/dist/{prompt-ONNPSNKM.js.map → mcp/darwin-3JFFE3W2.js.map} +0 -0
- /package/dist/{remote-IJAMOEAP.js.map → neon-helpers-HWIYRKOW.js.map} +0 -0
- /package/dist/{open-FXWW3VI4.js.map → open-2Y7GSUTJ.js.map} +0 -0
- /package/dist/{projects-2UOXFLNZ.js.map → projects-IUSUXD5D.js.map} +0 -0
- /package/dist/{update-notifier-LBAUOOLM.js.map → prompt-7LZB4PAT.js.map} +0 -0
- /package/dist/{rebase-62FDLIH4.js.map → rebase-S6OHAOOF.js.map} +0 -0
- /package/dist/{recap-OMBOKJST.js.map → recap-GGVCG5VH.js.map} +0 -0
- /package/dist/{run-BBXLRIZB.js.map → run-ST3FR75O.js.map} +0 -0
- /package/dist/{shell-RF7LTND5.js.map → shell-W4SBQPTE.js.map} +0 -0
- /package/dist/{summary-YZI25KW4.js.map → summary-P2JCIIJO.js.map} +0 -0
- /package/dist/{test-SGO6I5Z7.js.map → test-6JH4FE2X.js.map} +0 -0
- /package/dist/{test-git-XM4TM65W.js.map → test-git-2KFFAQ6B.js.map} +0 -0
- /package/dist/{test-jira-LDTOYFSD.js.map → test-jira-FKDKG6CD.js.map} +0 -0
- /package/dist/{test-tabs-D3POYOJ5.js.map → test-tabs-YDWMWTVA.js.map} +0 -0
- /package/dist/{test-webserver-NZ3JTVLL.js.map → test-webserver-QI3QQFZ3.js.map} +0 -0
- /package/dist/{update-HJKDYA3F.js.map → update-XLW7R7FL.js.map} +0 -0
- /package/dist/{vscode-6XUGHJKL.js.map → vscode-TOGE5N67.js.map} +0 -0
- /package/dist/{vscode-announcement-EQ2SKK3T.js.map → vscode-announcement-NIX7O2MG.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -8,6 +8,54 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
// src/utils/platform-detect.ts
|
|
12
|
+
import { readFileSync } from "fs";
|
|
13
|
+
function isWSL() {
|
|
14
|
+
if (cachedIsWSL !== void 0) {
|
|
15
|
+
return cachedIsWSL;
|
|
16
|
+
}
|
|
17
|
+
if (process.platform !== "linux") {
|
|
18
|
+
cachedIsWSL = false;
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (process.env.WSL_DISTRO_NAME) {
|
|
22
|
+
cachedIsWSL = true;
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const procVersion = readFileSync("/proc/version", "utf-8");
|
|
27
|
+
cachedIsWSL = /microsoft|wsl/i.test(procVersion);
|
|
28
|
+
return cachedIsWSL;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
31
|
+
cachedIsWSL = false;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
cachedIsWSL = false;
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function detectTerminalEnvironment() {
|
|
39
|
+
const platform = process.platform;
|
|
40
|
+
if (platform === "darwin") return "darwin";
|
|
41
|
+
if (platform === "win32") return "win32";
|
|
42
|
+
if (platform === "linux") {
|
|
43
|
+
return isWSL() ? "wsl" : "linux";
|
|
44
|
+
}
|
|
45
|
+
return "unsupported";
|
|
46
|
+
}
|
|
47
|
+
function detectWSLDistro() {
|
|
48
|
+
const distro = process.env.WSL_DISTRO_NAME;
|
|
49
|
+
if (!distro) return void 0;
|
|
50
|
+
return distro;
|
|
51
|
+
}
|
|
52
|
+
var cachedIsWSL;
|
|
53
|
+
var init_platform_detect = __esm({
|
|
54
|
+
"src/utils/platform-detect.ts"() {
|
|
55
|
+
"use strict";
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
11
59
|
// src/utils/env.ts
|
|
12
60
|
import path from "path";
|
|
13
61
|
import dotenvFlow from "dotenv-flow";
|
|
@@ -110,65 +158,19 @@ var init_env = __esm({
|
|
|
110
158
|
}
|
|
111
159
|
});
|
|
112
160
|
|
|
113
|
-
// src/utils/terminal.ts
|
|
114
|
-
import { execa } from "execa";
|
|
161
|
+
// src/utils/terminal-backends/command-builder.ts
|
|
115
162
|
import { existsSync } from "fs";
|
|
116
|
-
function
|
|
117
|
-
const platform = process.platform;
|
|
118
|
-
if (platform === "darwin") return "darwin";
|
|
119
|
-
if (platform === "linux") return "linux";
|
|
120
|
-
if (platform === "win32") return "win32";
|
|
121
|
-
return "unsupported";
|
|
122
|
-
}
|
|
123
|
-
async function detectDarkMode() {
|
|
124
|
-
const platform = detectPlatform();
|
|
125
|
-
if (platform !== "darwin") {
|
|
126
|
-
return "light";
|
|
127
|
-
}
|
|
128
|
-
try {
|
|
129
|
-
const result = await execa("defaults", ["read", "-g", "AppleInterfaceStyle"]);
|
|
130
|
-
return result.stdout.trim().toLowerCase() === "dark" ? "dark" : "light";
|
|
131
|
-
} catch {
|
|
132
|
-
return "light";
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
async function detectITerm2() {
|
|
136
|
-
const platform = detectPlatform();
|
|
137
|
-
if (platform !== "darwin") return false;
|
|
138
|
-
return existsSync("/Applications/iTerm.app");
|
|
139
|
-
}
|
|
140
|
-
async function openTerminalWindow(options) {
|
|
141
|
-
const platform = detectPlatform();
|
|
142
|
-
if (platform !== "darwin") {
|
|
143
|
-
throw new Error(
|
|
144
|
-
`Terminal window launching not yet supported on ${platform}. Currently only macOS is supported.`
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
const hasITerm2 = await detectITerm2();
|
|
148
|
-
const applescript = hasITerm2 ? await buildITerm2SingleTabScript(options) : await buildAppleScript(options);
|
|
149
|
-
try {
|
|
150
|
-
await execa("osascript", ["-e", applescript]);
|
|
151
|
-
if (!hasITerm2) {
|
|
152
|
-
await execa("osascript", ["-e", 'tell application "Terminal" to activate']);
|
|
153
|
-
}
|
|
154
|
-
} catch (error) {
|
|
155
|
-
throw new Error(
|
|
156
|
-
`Failed to open terminal window: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
async function buildAppleScript(options) {
|
|
163
|
+
async function buildCommandSequence(options) {
|
|
161
164
|
const {
|
|
162
165
|
workspacePath,
|
|
163
166
|
command,
|
|
164
|
-
backgroundColor,
|
|
165
167
|
port,
|
|
166
168
|
includeEnvSetup,
|
|
167
169
|
includePortExport
|
|
168
170
|
} = options;
|
|
169
171
|
const commands = [];
|
|
170
172
|
if (workspacePath) {
|
|
171
|
-
commands.push(`cd '${
|
|
173
|
+
commands.push(`cd '${escapeSingleQuotes(workspacePath)}'`);
|
|
172
174
|
}
|
|
173
175
|
if (includeEnvSetup && workspacePath) {
|
|
174
176
|
const sourceCommands = await buildEnvSourceCommands(
|
|
@@ -184,25 +186,50 @@ async function buildAppleScript(options) {
|
|
|
184
186
|
commands.push(command);
|
|
185
187
|
}
|
|
186
188
|
const fullCommand = commands.join(" && ");
|
|
187
|
-
|
|
189
|
+
return ` ${fullCommand}`;
|
|
190
|
+
}
|
|
191
|
+
function escapeSingleQuotes(s) {
|
|
192
|
+
return s.replace(/'/g, "'\\''");
|
|
193
|
+
}
|
|
194
|
+
function rgbToHex(rgb) {
|
|
195
|
+
const toHex = (n) => Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, "0");
|
|
196
|
+
return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
|
|
197
|
+
}
|
|
198
|
+
var init_command_builder = __esm({
|
|
199
|
+
"src/utils/terminal-backends/command-builder.ts"() {
|
|
200
|
+
"use strict";
|
|
201
|
+
init_env();
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// src/utils/terminal-backends/darwin.ts
|
|
206
|
+
var darwin_exports = {};
|
|
207
|
+
__export(darwin_exports, {
|
|
208
|
+
DarwinBackend: () => DarwinBackend,
|
|
209
|
+
detectITerm2: () => detectITerm2
|
|
210
|
+
});
|
|
211
|
+
import { execa } from "execa";
|
|
212
|
+
import { existsSync as existsSync2 } from "fs";
|
|
213
|
+
function detectITerm2() {
|
|
214
|
+
return existsSync2("/Applications/iTerm.app");
|
|
215
|
+
}
|
|
216
|
+
function escapeForAppleScript(command) {
|
|
217
|
+
return command.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
218
|
+
}
|
|
219
|
+
async function buildTerminalAppScript(options) {
|
|
220
|
+
const command = await buildCommandSequence(options);
|
|
188
221
|
let script = `tell application "Terminal"
|
|
189
222
|
`;
|
|
190
|
-
script += ` set newTab to do script "${escapeForAppleScript(
|
|
223
|
+
script += ` set newTab to do script "${escapeForAppleScript(command)}"
|
|
191
224
|
`;
|
|
192
|
-
if (backgroundColor) {
|
|
193
|
-
const { r, g, b } = backgroundColor;
|
|
225
|
+
if (options.backgroundColor) {
|
|
226
|
+
const { r, g, b } = options.backgroundColor;
|
|
194
227
|
script += ` set background color of newTab to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
|
|
195
228
|
`;
|
|
196
229
|
}
|
|
197
230
|
script += `end tell`;
|
|
198
231
|
return script;
|
|
199
232
|
}
|
|
200
|
-
function escapePathForAppleScript(path8) {
|
|
201
|
-
return path8.replace(/'/g, "'\\''");
|
|
202
|
-
}
|
|
203
|
-
function escapeForAppleScript(command) {
|
|
204
|
-
return command.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
205
|
-
}
|
|
206
233
|
async function buildITerm2SingleTabScript(options) {
|
|
207
234
|
const command = await buildCommandSequence(options);
|
|
208
235
|
let script = 'tell application id "com.googlecode.iterm2"\n';
|
|
@@ -225,38 +252,531 @@ async function buildITerm2SingleTabScript(options) {
|
|
|
225
252
|
script += "end tell";
|
|
226
253
|
return script;
|
|
227
254
|
}
|
|
228
|
-
async function
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
command,
|
|
232
|
-
port,
|
|
233
|
-
includeEnvSetup,
|
|
234
|
-
includePortExport
|
|
235
|
-
} = options;
|
|
236
|
-
const commands = [];
|
|
237
|
-
if (workspacePath) {
|
|
238
|
-
commands.push(`cd '${escapePathForAppleScript(workspacePath)}'`);
|
|
255
|
+
async function buildITerm2MultiTabScript(optionsArray) {
|
|
256
|
+
if (optionsArray.length < 2) {
|
|
257
|
+
throw new Error("buildITerm2MultiTabScript requires at least 2 terminal options");
|
|
239
258
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
259
|
+
let script = 'tell application id "com.googlecode.iterm2"\n';
|
|
260
|
+
script += " create window with default profile\n";
|
|
261
|
+
script += " set newWindow to current window\n";
|
|
262
|
+
const options1 = optionsArray[0];
|
|
263
|
+
if (!options1) {
|
|
264
|
+
throw new Error("First terminal option is undefined");
|
|
265
|
+
}
|
|
266
|
+
const command1 = await buildCommandSequence(options1);
|
|
267
|
+
script += " set s1 to current session of newWindow\n\n";
|
|
268
|
+
if (options1.backgroundColor) {
|
|
269
|
+
const { r, g, b } = options1.backgroundColor;
|
|
270
|
+
script += ` set background color of s1 to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
|
|
271
|
+
`;
|
|
246
272
|
}
|
|
247
|
-
|
|
248
|
-
|
|
273
|
+
script += ` tell s1 to write text "${escapeForAppleScript(command1)}"
|
|
274
|
+
|
|
275
|
+
`;
|
|
276
|
+
if (options1.title) {
|
|
277
|
+
script += ` set name of s1 to "${escapeForAppleScript(options1.title)}"
|
|
278
|
+
|
|
279
|
+
`;
|
|
249
280
|
}
|
|
250
|
-
|
|
251
|
-
|
|
281
|
+
for (let i = 1; i < optionsArray.length; i++) {
|
|
282
|
+
const options = optionsArray[i];
|
|
283
|
+
if (!options) {
|
|
284
|
+
throw new Error(`Terminal option at index ${i} is undefined`);
|
|
285
|
+
}
|
|
286
|
+
const command = await buildCommandSequence(options);
|
|
287
|
+
const sessionVar = `s${i + 1}`;
|
|
288
|
+
script += " tell newWindow\n";
|
|
289
|
+
script += ` set newTab${i} to (create tab with default profile)
|
|
290
|
+
`;
|
|
291
|
+
script += " end tell\n";
|
|
292
|
+
script += ` set ${sessionVar} to current session of newTab${i}
|
|
293
|
+
|
|
294
|
+
`;
|
|
295
|
+
if (options.backgroundColor) {
|
|
296
|
+
const { r, g, b } = options.backgroundColor;
|
|
297
|
+
script += ` set background color of ${sessionVar} to {${Math.round(r * 257)}, ${Math.round(g * 257)}, ${Math.round(b * 257)}}
|
|
298
|
+
`;
|
|
299
|
+
}
|
|
300
|
+
script += ` tell ${sessionVar} to write text "${escapeForAppleScript(command)}"
|
|
301
|
+
|
|
302
|
+
`;
|
|
303
|
+
if (options.title) {
|
|
304
|
+
script += ` set name of ${sessionVar} to "${escapeForAppleScript(options.title)}"
|
|
305
|
+
|
|
306
|
+
`;
|
|
307
|
+
}
|
|
252
308
|
}
|
|
253
|
-
|
|
254
|
-
|
|
309
|
+
script += " activate\n";
|
|
310
|
+
script += "end tell";
|
|
311
|
+
return script;
|
|
312
|
+
}
|
|
313
|
+
var DarwinBackend;
|
|
314
|
+
var init_darwin = __esm({
|
|
315
|
+
"src/utils/terminal-backends/darwin.ts"() {
|
|
316
|
+
"use strict";
|
|
317
|
+
init_command_builder();
|
|
318
|
+
DarwinBackend = class {
|
|
319
|
+
constructor() {
|
|
320
|
+
this.name = "darwin";
|
|
321
|
+
}
|
|
322
|
+
async openSingle(options) {
|
|
323
|
+
const hasITerm2 = detectITerm2();
|
|
324
|
+
const applescript = hasITerm2 ? await buildITerm2SingleTabScript(options) : await buildTerminalAppScript(options);
|
|
325
|
+
try {
|
|
326
|
+
await execa("osascript", ["-e", applescript]);
|
|
327
|
+
if (!hasITerm2) {
|
|
328
|
+
await execa("osascript", ["-e", 'tell application "Terminal" to activate']);
|
|
329
|
+
}
|
|
330
|
+
} catch (error) {
|
|
331
|
+
throw new Error(
|
|
332
|
+
`Failed to open terminal window: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async openMultiple(optionsArray) {
|
|
337
|
+
const hasITerm2 = detectITerm2();
|
|
338
|
+
if (hasITerm2) {
|
|
339
|
+
const applescript = await buildITerm2MultiTabScript(optionsArray);
|
|
340
|
+
try {
|
|
341
|
+
await execa("osascript", ["-e", applescript]);
|
|
342
|
+
} catch (error) {
|
|
343
|
+
throw new Error(
|
|
344
|
+
`Failed to open iTerm2 window: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
for (let i = 0; i < optionsArray.length; i++) {
|
|
349
|
+
const options = optionsArray[i];
|
|
350
|
+
if (!options) {
|
|
351
|
+
throw new Error(`Terminal option at index ${i} is undefined`);
|
|
352
|
+
}
|
|
353
|
+
await this.openSingle(options);
|
|
354
|
+
if (i < optionsArray.length - 1) {
|
|
355
|
+
await new Promise((resolve) => globalThis.setTimeout(resolve, 1e3));
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
// src/utils/terminal-backends/wsl.ts
|
|
365
|
+
var wsl_exports = {};
|
|
366
|
+
__export(wsl_exports, {
|
|
367
|
+
WSLBackend: () => WSLBackend
|
|
368
|
+
});
|
|
369
|
+
import { execa as execa2 } from "execa";
|
|
370
|
+
function buildTabArgs(shellCommand, options, distro) {
|
|
371
|
+
const args = ["new-tab"];
|
|
372
|
+
if (options.title) {
|
|
373
|
+
args.push("--title", options.title);
|
|
374
|
+
}
|
|
375
|
+
if (options.backgroundColor) {
|
|
376
|
+
args.push("--tabColor", rgbToHex(options.backgroundColor));
|
|
377
|
+
}
|
|
378
|
+
args.push("wsl.exe");
|
|
379
|
+
if (distro) {
|
|
380
|
+
args.push("-d", distro);
|
|
381
|
+
}
|
|
382
|
+
args.push("-e", "bash", "-lic", shellCommand);
|
|
383
|
+
return args;
|
|
384
|
+
}
|
|
385
|
+
var WSLBackend;
|
|
386
|
+
var init_wsl = __esm({
|
|
387
|
+
"src/utils/terminal-backends/wsl.ts"() {
|
|
388
|
+
"use strict";
|
|
389
|
+
init_command_builder();
|
|
390
|
+
init_platform_detect();
|
|
391
|
+
WSLBackend = class {
|
|
392
|
+
constructor() {
|
|
393
|
+
this.name = "wsl";
|
|
394
|
+
}
|
|
395
|
+
async openSingle(options) {
|
|
396
|
+
const rawCommand = (await buildCommandSequence(options)).trim();
|
|
397
|
+
const shellCommand = rawCommand ? `${rawCommand}; exec bash` : "exec bash";
|
|
398
|
+
const distro = detectWSLDistro();
|
|
399
|
+
const args = buildTabArgs(shellCommand, options, distro);
|
|
400
|
+
try {
|
|
401
|
+
await execa2("wt.exe", args);
|
|
402
|
+
} catch (error) {
|
|
403
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
404
|
+
if (message.includes("ENOENT") || message.includes("not found")) {
|
|
405
|
+
throw new Error(
|
|
406
|
+
"Windows Terminal (wt.exe) is not available. Install Windows Terminal from the Microsoft Store: https://aka.ms/terminal"
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
throw new Error(`Failed to open Windows Terminal tab: ${message}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async openMultiple(optionsArray) {
|
|
413
|
+
const distro = detectWSLDistro();
|
|
414
|
+
const allArgs = [];
|
|
415
|
+
for (let i = 0; i < optionsArray.length; i++) {
|
|
416
|
+
const options = optionsArray[i];
|
|
417
|
+
if (!options) {
|
|
418
|
+
throw new Error(`Terminal option at index ${i} is undefined`);
|
|
419
|
+
}
|
|
420
|
+
const rawCommand = (await buildCommandSequence(options)).trim();
|
|
421
|
+
const shellCommand = rawCommand ? `${rawCommand}; exec bash` : "exec bash";
|
|
422
|
+
const tabArgs = buildTabArgs(shellCommand, options, distro);
|
|
423
|
+
if (i > 0) {
|
|
424
|
+
allArgs.push(";");
|
|
425
|
+
}
|
|
426
|
+
allArgs.push(...tabArgs);
|
|
427
|
+
}
|
|
428
|
+
try {
|
|
429
|
+
await execa2("wt.exe", allArgs);
|
|
430
|
+
} catch (error) {
|
|
431
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
432
|
+
if (message.includes("ENOENT") || message.includes("not found")) {
|
|
433
|
+
throw new Error(
|
|
434
|
+
"Windows Terminal (wt.exe) is not available. Install Windows Terminal from the Microsoft Store: https://aka.ms/terminal"
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
throw new Error(`Failed to open Windows Terminal tabs: ${message}`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// src/utils/terminal-backends/linux.ts
|
|
445
|
+
var linux_exports = {};
|
|
446
|
+
__export(linux_exports, {
|
|
447
|
+
LinuxBackend: () => LinuxBackend,
|
|
448
|
+
detectLinuxTerminal: () => detectLinuxTerminal
|
|
449
|
+
});
|
|
450
|
+
import { execa as execa3 } from "execa";
|
|
451
|
+
async function detectLinuxTerminal() {
|
|
452
|
+
for (const terminal of TERMINAL_EMULATORS) {
|
|
453
|
+
try {
|
|
454
|
+
await execa3("which", [terminal]);
|
|
455
|
+
return terminal;
|
|
456
|
+
} catch (error) {
|
|
457
|
+
if (error instanceof Error && "exitCode" in error) {
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
var TERMINAL_EMULATORS, LinuxBackend;
|
|
466
|
+
var init_linux = __esm({
|
|
467
|
+
"src/utils/terminal-backends/linux.ts"() {
|
|
468
|
+
"use strict";
|
|
469
|
+
init_command_builder();
|
|
470
|
+
init_logger();
|
|
471
|
+
TERMINAL_EMULATORS = ["gnome-terminal", "konsole", "xterm"];
|
|
472
|
+
LinuxBackend = class {
|
|
473
|
+
constructor() {
|
|
474
|
+
this.name = "linux";
|
|
475
|
+
}
|
|
476
|
+
async openSingle(options) {
|
|
477
|
+
const terminal = await this.resolveTerminal();
|
|
478
|
+
await this.openSingleWithTerminal(options, terminal);
|
|
479
|
+
}
|
|
480
|
+
async openMultiple(optionsArray) {
|
|
481
|
+
const terminal = await this.resolveTerminal();
|
|
482
|
+
for (let i = 0; i < optionsArray.length; i++) {
|
|
483
|
+
const options = optionsArray[i];
|
|
484
|
+
if (!options) {
|
|
485
|
+
throw new Error(`Terminal option at index ${i} is undefined`);
|
|
486
|
+
}
|
|
487
|
+
await this.openSingleWithTerminal(options, terminal);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
async resolveTerminal() {
|
|
491
|
+
const terminal = await detectLinuxTerminal();
|
|
492
|
+
if (!terminal) {
|
|
493
|
+
throw new Error(
|
|
494
|
+
"No supported GUI terminal emulator found. Install gnome-terminal, konsole, or xterm \u2014 or use tmux for headless environments."
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
return terminal;
|
|
498
|
+
}
|
|
499
|
+
async openSingleWithTerminal(options, terminal) {
|
|
500
|
+
if (options.backgroundColor) {
|
|
501
|
+
logger.debug(
|
|
502
|
+
"Terminal background colors are not supported via CLI on Linux terminal emulators."
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
const shellCommand = (await buildCommandSequence(options)).trim();
|
|
506
|
+
const keepAliveCommand = shellCommand ? `${shellCommand}; exec bash` : "exec bash";
|
|
507
|
+
await this.execTerminal(terminal, keepAliveCommand, options.title);
|
|
508
|
+
}
|
|
509
|
+
async execTerminal(terminal, command, title) {
|
|
510
|
+
try {
|
|
511
|
+
switch (terminal) {
|
|
512
|
+
case "gnome-terminal": {
|
|
513
|
+
const args = ["--tab"];
|
|
514
|
+
if (title) {
|
|
515
|
+
args.push("--title", title);
|
|
516
|
+
}
|
|
517
|
+
args.push("--", "bash", "-lic", command);
|
|
518
|
+
await execa3("gnome-terminal", args);
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
case "konsole": {
|
|
522
|
+
const args = ["--new-tab"];
|
|
523
|
+
if (title) {
|
|
524
|
+
args.push("-p", `tabtitle=${title}`);
|
|
525
|
+
}
|
|
526
|
+
args.push("-e", "bash", "-lic", command);
|
|
527
|
+
await execa3("konsole", args);
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
case "xterm": {
|
|
531
|
+
const args = [];
|
|
532
|
+
if (title) {
|
|
533
|
+
args.push("-title", title);
|
|
534
|
+
}
|
|
535
|
+
args.push("-e", "bash", "-lic", command);
|
|
536
|
+
await execa3("xterm", args);
|
|
537
|
+
break;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
} catch (error) {
|
|
541
|
+
throw new Error(
|
|
542
|
+
`Failed to open ${terminal}: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// src/utils/terminal-backends/tmux.ts
|
|
551
|
+
var tmux_exports = {};
|
|
552
|
+
__export(tmux_exports, {
|
|
553
|
+
TmuxBackend: () => TmuxBackend,
|
|
554
|
+
isTmuxAvailable: () => isTmuxAvailable
|
|
555
|
+
});
|
|
556
|
+
import { execa as execa4 } from "execa";
|
|
557
|
+
async function isTmuxAvailable() {
|
|
558
|
+
try {
|
|
559
|
+
await execa4("which", ["tmux"]);
|
|
560
|
+
return true;
|
|
561
|
+
} catch (error) {
|
|
562
|
+
if (error instanceof Error && "exitCode" in error) {
|
|
563
|
+
return false;
|
|
564
|
+
}
|
|
565
|
+
throw error;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
function sanitizeSessionName(title) {
|
|
569
|
+
return title.replace(/[.:]/g, "-").replace(/\s+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").substring(0, 64);
|
|
570
|
+
}
|
|
571
|
+
function sanitizeWindowName(title) {
|
|
572
|
+
return title.replace(/[.:]/g, "-").substring(0, 32);
|
|
573
|
+
}
|
|
574
|
+
async function sessionExists(sessionName) {
|
|
575
|
+
try {
|
|
576
|
+
await execa4("tmux", ["has-session", "-t", sessionName]);
|
|
577
|
+
return true;
|
|
578
|
+
} catch (error) {
|
|
579
|
+
if (error instanceof Error && "exitCode" in error) {
|
|
580
|
+
return false;
|
|
581
|
+
}
|
|
582
|
+
throw error;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
var TmuxBackend;
|
|
586
|
+
var init_tmux = __esm({
|
|
587
|
+
"src/utils/terminal-backends/tmux.ts"() {
|
|
588
|
+
"use strict";
|
|
589
|
+
init_command_builder();
|
|
590
|
+
init_logger();
|
|
591
|
+
TmuxBackend = class {
|
|
592
|
+
constructor() {
|
|
593
|
+
this.name = "tmux";
|
|
594
|
+
}
|
|
595
|
+
async openSingle(options) {
|
|
596
|
+
const shellCommand = (await buildCommandSequence(options)).trim();
|
|
597
|
+
const command = shellCommand ? `${shellCommand}; exec bash` : "bash";
|
|
598
|
+
if (options.backgroundColor) {
|
|
599
|
+
logger.debug("Terminal background colors are not supported in tmux sessions.");
|
|
600
|
+
}
|
|
601
|
+
const sessionName = options.title ? sanitizeSessionName(`iloom-${options.title}`) : `iloom-${Date.now()}`;
|
|
602
|
+
const windowName = options.title ? sanitizeWindowName(options.title) : "main";
|
|
603
|
+
const iloomSession = await this.findIloomSession();
|
|
604
|
+
if (iloomSession) {
|
|
605
|
+
const args = ["new-window", "-t", iloomSession, "-n", windowName, "bash", "-lic", command];
|
|
606
|
+
try {
|
|
607
|
+
await execa4("tmux", args);
|
|
608
|
+
logger.info(`Added tmux window "${windowName}" to session "${iloomSession}"`);
|
|
609
|
+
} catch (error) {
|
|
610
|
+
throw new Error(
|
|
611
|
+
`Failed to add tmux window: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
} else {
|
|
615
|
+
const args = ["new-session", "-d", "-s", sessionName, "-n", windowName, "bash", "-lic", command];
|
|
616
|
+
try {
|
|
617
|
+
await execa4("tmux", args);
|
|
618
|
+
logger.info(`Created tmux session "${sessionName}" \u2014 attach with: tmux attach -t ${sessionName}`);
|
|
619
|
+
} catch (error) {
|
|
620
|
+
throw new Error(
|
|
621
|
+
`Failed to create tmux session: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
async openMultiple(optionsArray) {
|
|
627
|
+
if (optionsArray.length === 0) return;
|
|
628
|
+
const firstOptions = optionsArray[0];
|
|
629
|
+
if (!firstOptions) {
|
|
630
|
+
throw new Error("First terminal option is undefined");
|
|
631
|
+
}
|
|
632
|
+
const sessionName = firstOptions.title ? sanitizeSessionName(`iloom-${firstOptions.title}`) : `iloom-${Date.now()}`;
|
|
633
|
+
const finalSessionName = await sessionExists(sessionName) ? `${sessionName}-${Date.now()}` : sessionName;
|
|
634
|
+
if (firstOptions.backgroundColor) {
|
|
635
|
+
logger.debug("Terminal background colors are not supported in tmux sessions.");
|
|
636
|
+
}
|
|
637
|
+
const firstShellCommand = (await buildCommandSequence(firstOptions)).trim();
|
|
638
|
+
const firstCommand = firstShellCommand ? `${firstShellCommand}; exec bash` : "bash";
|
|
639
|
+
const firstName = firstOptions.title ? sanitizeWindowName(firstOptions.title) : "window-1";
|
|
640
|
+
try {
|
|
641
|
+
await execa4("tmux", [
|
|
642
|
+
"new-session",
|
|
643
|
+
"-d",
|
|
644
|
+
"-s",
|
|
645
|
+
finalSessionName,
|
|
646
|
+
"-n",
|
|
647
|
+
firstName,
|
|
648
|
+
"bash",
|
|
649
|
+
"-lic",
|
|
650
|
+
firstCommand
|
|
651
|
+
]);
|
|
652
|
+
} catch (error) {
|
|
653
|
+
throw new Error(
|
|
654
|
+
`Failed to create tmux session: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
for (let i = 1; i < optionsArray.length; i++) {
|
|
658
|
+
const options = optionsArray[i];
|
|
659
|
+
if (!options) {
|
|
660
|
+
throw new Error(`Terminal option at index ${i} is undefined`);
|
|
661
|
+
}
|
|
662
|
+
if (options.backgroundColor) {
|
|
663
|
+
logger.debug("Terminal background colors are not supported in tmux sessions.");
|
|
664
|
+
}
|
|
665
|
+
const shellCommand = (await buildCommandSequence(options)).trim();
|
|
666
|
+
const command = shellCommand ? `${shellCommand}; exec bash` : "bash";
|
|
667
|
+
const windowName = options.title ? sanitizeWindowName(options.title) : `window-${i + 1}`;
|
|
668
|
+
try {
|
|
669
|
+
await execa4("tmux", [
|
|
670
|
+
"new-window",
|
|
671
|
+
"-t",
|
|
672
|
+
finalSessionName,
|
|
673
|
+
"-n",
|
|
674
|
+
windowName,
|
|
675
|
+
"bash",
|
|
676
|
+
"-lic",
|
|
677
|
+
command
|
|
678
|
+
]);
|
|
679
|
+
} catch (error) {
|
|
680
|
+
throw new Error(
|
|
681
|
+
`Failed to add tmux window "${windowName}": ${error instanceof Error ? error.message : "Unknown error"}`
|
|
682
|
+
);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
logger.info(
|
|
686
|
+
`Created tmux session "${finalSessionName}" with ${optionsArray.length} windows \u2014 attach with: tmux attach -t ${finalSessionName}`
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Look for an existing iloom tmux session to add windows to.
|
|
691
|
+
* Returns the session name if found, null otherwise.
|
|
692
|
+
*/
|
|
693
|
+
async findIloomSession() {
|
|
694
|
+
try {
|
|
695
|
+
const result = await execa4("tmux", ["list-sessions", "-F", "#{session_name}"]);
|
|
696
|
+
const sessions = result.stdout.split("\n").filter(Boolean);
|
|
697
|
+
return sessions.find((s) => s.startsWith("iloom-")) ?? null;
|
|
698
|
+
} catch (error) {
|
|
699
|
+
if (error instanceof Error && "exitCode" in error) {
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
throw error;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// src/utils/terminal-backends/index.ts
|
|
710
|
+
async function getTerminalBackend() {
|
|
711
|
+
const env = detectTerminalEnvironment();
|
|
712
|
+
switch (env) {
|
|
713
|
+
case "darwin": {
|
|
714
|
+
const { DarwinBackend: DarwinBackend2 } = await Promise.resolve().then(() => (init_darwin(), darwin_exports));
|
|
715
|
+
return new DarwinBackend2();
|
|
716
|
+
}
|
|
717
|
+
case "wsl": {
|
|
718
|
+
const { WSLBackend: WSLBackend2 } = await Promise.resolve().then(() => (init_wsl(), wsl_exports));
|
|
719
|
+
return new WSLBackend2();
|
|
720
|
+
}
|
|
721
|
+
case "linux": {
|
|
722
|
+
const hasDisplay = !!(process.env.DISPLAY ?? process.env.WAYLAND_DISPLAY);
|
|
723
|
+
if (hasDisplay) {
|
|
724
|
+
const { detectLinuxTerminal: detectLinuxTerminal2 } = await Promise.resolve().then(() => (init_linux(), linux_exports));
|
|
725
|
+
if (await detectLinuxTerminal2()) {
|
|
726
|
+
const { LinuxBackend: LinuxBackend2 } = await Promise.resolve().then(() => (init_linux(), linux_exports));
|
|
727
|
+
return new LinuxBackend2();
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
const { isTmuxAvailable: isTmuxAvailable2, TmuxBackend: TmuxBackend2 } = await Promise.resolve().then(() => (init_tmux(), tmux_exports));
|
|
731
|
+
if (await isTmuxAvailable2()) {
|
|
732
|
+
return new TmuxBackend2();
|
|
733
|
+
}
|
|
734
|
+
throw new Error(
|
|
735
|
+
"No supported terminal found on Linux. Install tmux for headless environments, or set DISPLAY and install a GUI terminal (gnome-terminal, konsole, xterm)."
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
default:
|
|
739
|
+
throw new Error(
|
|
740
|
+
`Terminal window launching is not supported on ${env}. Supported platforms: macOS, WSL (Windows Terminal), Linux (GUI terminals or tmux).`
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
var init_terminal_backends = __esm({
|
|
745
|
+
"src/utils/terminal-backends/index.ts"() {
|
|
746
|
+
"use strict";
|
|
747
|
+
init_platform_detect();
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
// src/utils/terminal.ts
|
|
752
|
+
import { execa as execa5 } from "execa";
|
|
753
|
+
function detectPlatform() {
|
|
754
|
+
const env = detectTerminalEnvironment();
|
|
755
|
+
if (env === "wsl") return "linux";
|
|
756
|
+
return env;
|
|
757
|
+
}
|
|
758
|
+
async function detectDarkMode() {
|
|
759
|
+
const platform = detectPlatform();
|
|
760
|
+
if (platform !== "darwin") {
|
|
761
|
+
return "light";
|
|
762
|
+
}
|
|
763
|
+
try {
|
|
764
|
+
const result = await execa5("defaults", ["read", "-g", "AppleInterfaceStyle"]);
|
|
765
|
+
return result.stdout.trim().toLowerCase() === "dark" ? "dark" : "light";
|
|
766
|
+
} catch {
|
|
767
|
+
return "light";
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
async function openTerminalWindow(options) {
|
|
771
|
+
const backend = await getTerminalBackend();
|
|
772
|
+
await backend.openSingle(options);
|
|
255
773
|
}
|
|
256
774
|
var init_terminal = __esm({
|
|
257
775
|
"src/utils/terminal.ts"() {
|
|
258
776
|
"use strict";
|
|
259
|
-
|
|
777
|
+
init_terminal_backends();
|
|
778
|
+
init_darwin();
|
|
779
|
+
init_platform_detect();
|
|
260
780
|
}
|
|
261
781
|
});
|
|
262
782
|
|
|
@@ -527,15 +1047,16 @@ var init_SettingsManager = __esm({
|
|
|
527
1047
|
z.enum(["claude", "gemini", "codex"]),
|
|
528
1048
|
z.string()
|
|
529
1049
|
).optional().describe('Map of review providers to model names. Keys: claude, gemini, codex. Values: model name strings (e.g., "sonnet", "gemini-3-pro-preview", "gpt-5.2-codex")'),
|
|
530
|
-
review: z.boolean().optional().describe("Whether artifacts from this agent should be reviewed before posting (defaults to false)")
|
|
1050
|
+
review: z.boolean().optional().describe("Whether artifacts from this agent should be reviewed before posting (defaults to false)"),
|
|
1051
|
+
swarmReview: z.boolean().optional().describe("Whether artifacts from this agent should be reviewed in swarm mode. Defaults to false if not set (review is off in swarm mode for speed and cost unless explicitly enabled).")
|
|
531
1052
|
});
|
|
532
1053
|
AgentSettingsSchema = BaseAgentSettingsSchema.extend({
|
|
533
|
-
agents: z.record(z.string(), BaseAgentSettingsSchema).optional().describe("Nested per-agent settings. Only meaningful under the iloom-swarm-worker agent entry for sub-agent timeout configuration."),
|
|
534
1054
|
subAgentTimeout: z.number().min(1, "Sub-agent timeout must be at least 1 minute").max(120, "Sub-agent timeout cannot exceed 120 minutes").default(10).describe("Timeout in minutes for sub-agent claude -p invocations in swarm mode. Applies to each phase agent (evaluator, analyzer, planner, implementer) when invoked via the Bash tool. Default: 10 minutes. Only meaningful under the iloom-swarm-worker agent entry.")
|
|
535
1055
|
});
|
|
536
1056
|
SpinAgentSettingsSchema = z.object({
|
|
537
1057
|
model: z.enum(["sonnet", "opus", "haiku"]).default("opus").describe("Claude model shorthand for spin orchestrator"),
|
|
538
|
-
swarmModel: z.enum(["sonnet", "opus", "haiku"]).optional().describe("Model for the spin orchestrator when running in swarm mode. Overrides spin.model for swarm workflows.")
|
|
1058
|
+
swarmModel: z.enum(["sonnet", "opus", "haiku"]).optional().describe("Model for the spin orchestrator when running in swarm mode. Overrides spin.model for swarm workflows."),
|
|
1059
|
+
postSwarmReview: z.boolean().default(true).describe("Run a full code review after swarm completion, auto-fixing issues with confidence 80+. Defaults to true.")
|
|
539
1060
|
});
|
|
540
1061
|
PlanCommandSettingsSchema = z.object({
|
|
541
1062
|
model: z.enum(["sonnet", "opus", "haiku"]).default("opus").describe("Claude model shorthand for plan command"),
|
|
@@ -730,7 +1251,8 @@ var init_SettingsManager = __esm({
|
|
|
730
1251
|
),
|
|
731
1252
|
spin: z.object({
|
|
732
1253
|
model: z.enum(["sonnet", "opus", "haiku"]).optional(),
|
|
733
|
-
swarmModel: z.enum(["sonnet", "opus", "haiku"]).optional()
|
|
1254
|
+
swarmModel: z.enum(["sonnet", "opus", "haiku"]).optional(),
|
|
1255
|
+
postSwarmReview: z.boolean().optional()
|
|
734
1256
|
}).optional().describe("Spin orchestrator configuration"),
|
|
735
1257
|
plan: z.object({
|
|
736
1258
|
model: z.enum(["sonnet", "opus", "haiku"]).optional(),
|
|
@@ -1071,7 +1593,7 @@ __export(color_exports, {
|
|
|
1071
1593
|
getDarkColorPalette: () => getDarkColorPalette,
|
|
1072
1594
|
hexToRgb: () => hexToRgb,
|
|
1073
1595
|
lightenColor: () => lightenColor,
|
|
1074
|
-
rgbToHex: () =>
|
|
1596
|
+
rgbToHex: () => rgbToHex2,
|
|
1075
1597
|
saturateColor: () => saturateColor,
|
|
1076
1598
|
selectDistinctColor: () => selectDistinctColor
|
|
1077
1599
|
});
|
|
@@ -1148,7 +1670,7 @@ function getDarkColorPalette() {
|
|
|
1148
1670
|
// 15: Dark rust
|
|
1149
1671
|
];
|
|
1150
1672
|
}
|
|
1151
|
-
function
|
|
1673
|
+
function rgbToHex2(r, g, b) {
|
|
1152
1674
|
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
|
|
1153
1675
|
throw new Error("RGB values must be between 0 and 255");
|
|
1154
1676
|
}
|
|
@@ -1178,7 +1700,7 @@ function generateColorFromBranchName(branchName, themeMode = "light") {
|
|
|
1178
1700
|
if (!rgb) {
|
|
1179
1701
|
throw new Error(`Invalid color index: ${index}`);
|
|
1180
1702
|
}
|
|
1181
|
-
const hex =
|
|
1703
|
+
const hex = rgbToHex2(rgb.r, rgb.g, rgb.b);
|
|
1182
1704
|
return {
|
|
1183
1705
|
rgb,
|
|
1184
1706
|
hex,
|
|
@@ -1222,7 +1744,7 @@ function selectDistinctColor(branchName, usedHexColors, themeMode = "light") {
|
|
|
1222
1744
|
if (isDistinct) {
|
|
1223
1745
|
return {
|
|
1224
1746
|
rgb: candidateRgb,
|
|
1225
|
-
hex:
|
|
1747
|
+
hex: rgbToHex2(candidateRgb.r, candidateRgb.g, candidateRgb.b),
|
|
1226
1748
|
index: i
|
|
1227
1749
|
};
|
|
1228
1750
|
}
|
|
@@ -1279,7 +1801,7 @@ import fs2 from "fs-extra";
|
|
|
1279
1801
|
// src/utils/git.ts
|
|
1280
1802
|
init_SettingsManager();
|
|
1281
1803
|
import path4 from "path";
|
|
1282
|
-
import { execa as
|
|
1804
|
+
import { execa as execa6 } from "execa";
|
|
1283
1805
|
|
|
1284
1806
|
// src/lib/MetadataManager.ts
|
|
1285
1807
|
import path3 from "path";
|
|
@@ -1321,6 +1843,7 @@ var MetadataManager = class {
|
|
|
1321
1843
|
prUrls: data.prUrls ?? {},
|
|
1322
1844
|
draftPrNumber: data.draftPrNumber ?? null,
|
|
1323
1845
|
oneShot: data.oneShot ?? null,
|
|
1846
|
+
complexity: data.complexity ?? null,
|
|
1324
1847
|
capabilities: data.capabilities ?? [],
|
|
1325
1848
|
state: data.state ?? null,
|
|
1326
1849
|
childIssueNumbers: data.childIssueNumbers ?? [],
|
|
@@ -1392,6 +1915,7 @@ var MetadataManager = class {
|
|
|
1392
1915
|
capabilities: input.capabilities,
|
|
1393
1916
|
...input.draftPrNumber && { draftPrNumber: input.draftPrNumber },
|
|
1394
1917
|
...input.oneShot && { oneShot: input.oneShot },
|
|
1918
|
+
...input.complexity && { complexity: input.complexity },
|
|
1395
1919
|
...input.state && { state: input.state },
|
|
1396
1920
|
...input.childIssueNumbers && input.childIssueNumbers.length > 0 && { childIssueNumbers: input.childIssueNumbers },
|
|
1397
1921
|
...input.parentLoom && { parentLoom: input.parentLoom },
|
|
@@ -1624,7 +2148,7 @@ var GitCommandError = class extends Error {
|
|
|
1624
2148
|
};
|
|
1625
2149
|
async function executeGitCommand(args, options) {
|
|
1626
2150
|
try {
|
|
1627
|
-
const result = await
|
|
2151
|
+
const result = await execa6("git", args, {
|
|
1628
2152
|
cwd: (options == null ? void 0 : options.cwd) ?? process.cwd(),
|
|
1629
2153
|
timeout: (options == null ? void 0 : options.timeout) ?? 3e4,
|
|
1630
2154
|
encoding: "utf8",
|
|
@@ -2686,9 +3210,9 @@ var GitHubError = class extends Error {
|
|
|
2686
3210
|
|
|
2687
3211
|
// src/utils/github.ts
|
|
2688
3212
|
init_logger();
|
|
2689
|
-
import { execa as
|
|
3213
|
+
import { execa as execa7 } from "execa";
|
|
2690
3214
|
async function executeGhCommand(args, options) {
|
|
2691
|
-
const result = await
|
|
3215
|
+
const result = await execa7("gh", args, {
|
|
2692
3216
|
cwd: (options == null ? void 0 : options.cwd) ?? process.cwd(),
|
|
2693
3217
|
timeout: (options == null ? void 0 : options.timeout) ?? 3e4,
|
|
2694
3218
|
encoding: "utf8"
|
|
@@ -2854,7 +3378,7 @@ async function createIssue(title, body, options) {
|
|
|
2854
3378
|
if (!repo) {
|
|
2855
3379
|
execaOptions.cwd = process.cwd();
|
|
2856
3380
|
}
|
|
2857
|
-
const result = await
|
|
3381
|
+
const result = await execa7("gh", args, execaOptions);
|
|
2858
3382
|
const urlMatch = result.stdout.trim().match(/https:\/\/github\.com\/[^/]+\/[^/]+\/issues\/(\d+)/);
|
|
2859
3383
|
if (!(urlMatch == null ? void 0 : urlMatch[1])) {
|
|
2860
3384
|
throw new Error(`Failed to parse issue URL from gh output: ${result.stdout}`);
|
|
@@ -5039,14 +5563,14 @@ var DatabaseManager = class {
|
|
|
5039
5563
|
|
|
5040
5564
|
// src/utils/claude.ts
|
|
5041
5565
|
init_logger();
|
|
5042
|
-
import { execa as
|
|
5043
|
-
import { existsSync as
|
|
5566
|
+
import { execa as execa8 } from "execa";
|
|
5567
|
+
import { existsSync as existsSync3 } from "fs";
|
|
5044
5568
|
import { join } from "path";
|
|
5045
5569
|
import { createHash as createHash3, randomUUID } from "crypto";
|
|
5046
5570
|
init_terminal();
|
|
5047
5571
|
async function detectClaudeCli() {
|
|
5048
5572
|
try {
|
|
5049
|
-
await
|
|
5573
|
+
await execa8("command", ["-v", "claude"], {
|
|
5050
5574
|
shell: true,
|
|
5051
5575
|
timeout: 5e3
|
|
5052
5576
|
});
|
|
@@ -5076,7 +5600,7 @@ function parseJsonStreamOutput(output) {
|
|
|
5076
5600
|
}
|
|
5077
5601
|
}
|
|
5078
5602
|
async function launchClaude(prompt, options = {}) {
|
|
5079
|
-
const { model, permissionMode, addDir, headless = false, appendSystemPrompt, mcpConfig, allowedTools, disallowedTools, agents, sessionId, noSessionPersistence, outputFormat, verbose, jsonMode, passthroughStdout, env: extraEnv, signal } = options;
|
|
5603
|
+
const { model, permissionMode, addDir, headless = false, appendSystemPrompt, mcpConfig, allowedTools, disallowedTools, agents, pluginDir, sessionId, noSessionPersistence, outputFormat, verbose, jsonMode, passthroughStdout, env: extraEnv, signal } = options;
|
|
5080
5604
|
const log = getLogger();
|
|
5081
5605
|
const args = [];
|
|
5082
5606
|
if (headless) {
|
|
@@ -5114,6 +5638,9 @@ async function launchClaude(prompt, options = {}) {
|
|
|
5114
5638
|
if (agents) {
|
|
5115
5639
|
args.push("--agents", JSON.stringify(agents));
|
|
5116
5640
|
}
|
|
5641
|
+
if (pluginDir) {
|
|
5642
|
+
args.push("--plugin-dir", pluginDir);
|
|
5643
|
+
}
|
|
5117
5644
|
if (sessionId) {
|
|
5118
5645
|
args.push("--session-id", sessionId);
|
|
5119
5646
|
}
|
|
@@ -5133,7 +5660,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
5133
5660
|
}
|
|
5134
5661
|
try {
|
|
5135
5662
|
if (headless && passthroughStdout) {
|
|
5136
|
-
const subprocess =
|
|
5663
|
+
const subprocess = execa8("claude", args, {
|
|
5137
5664
|
input: prompt,
|
|
5138
5665
|
timeout: 0,
|
|
5139
5666
|
...addDir && { cwd: addDir },
|
|
@@ -5165,7 +5692,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
5165
5692
|
...isDebugMode && { stdio: ["pipe", "pipe", "pipe"] }
|
|
5166
5693
|
// Enable streaming in debug mode
|
|
5167
5694
|
};
|
|
5168
|
-
const subprocess =
|
|
5695
|
+
const subprocess = execa8("claude", args, execaOptions);
|
|
5169
5696
|
attachAbortSignal(subprocess);
|
|
5170
5697
|
const isJsonStreamFormat = args.includes("--output-format") && args.includes("stream-json");
|
|
5171
5698
|
let outputBuffer = "";
|
|
@@ -5219,7 +5746,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
5219
5746
|
}
|
|
5220
5747
|
} else {
|
|
5221
5748
|
try {
|
|
5222
|
-
const interactiveSubprocess =
|
|
5749
|
+
const interactiveSubprocess = execa8("claude", [...args, "--", prompt], {
|
|
5223
5750
|
...addDir && { cwd: addDir },
|
|
5224
5751
|
stdio: ["inherit", "inherit", "pipe"],
|
|
5225
5752
|
// Capture stderr to detect session conflicts
|
|
@@ -5251,7 +5778,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
5251
5778
|
return true;
|
|
5252
5779
|
});
|
|
5253
5780
|
resumeArgs.push("--resume", conflictSessionId);
|
|
5254
|
-
const resumeSubprocess =
|
|
5781
|
+
const resumeSubprocess = execa8("claude", resumeArgs, {
|
|
5255
5782
|
...addDir && { cwd: addDir },
|
|
5256
5783
|
stdio: "inherit",
|
|
5257
5784
|
timeout: 0,
|
|
@@ -5295,7 +5822,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
5295
5822
|
env: claudeEnv,
|
|
5296
5823
|
...isDebugMode && { stdio: ["pipe", "pipe", "pipe"] }
|
|
5297
5824
|
};
|
|
5298
|
-
const subprocess =
|
|
5825
|
+
const subprocess = execa8("claude", resumeArgs, execaOptions);
|
|
5299
5826
|
const isJsonStreamFormat = resumeArgs.includes("--output-format") && resumeArgs.includes("stream-json");
|
|
5300
5827
|
let outputBuffer = "";
|
|
5301
5828
|
let isStreaming = false;
|
|
@@ -5341,7 +5868,7 @@ async function launchClaude(prompt, options = {}) {
|
|
|
5341
5868
|
return isJsonStreamFormat ? parseJsonStreamOutput(rawOutput) : rawOutput;
|
|
5342
5869
|
}
|
|
5343
5870
|
} else {
|
|
5344
|
-
await
|
|
5871
|
+
await execa8("claude", resumeArgs, {
|
|
5345
5872
|
...addDir && { cwd: addDir },
|
|
5346
5873
|
stdio: "inherit",
|
|
5347
5874
|
timeout: 0,
|
|
@@ -5386,7 +5913,7 @@ async function launchClaudeInNewTerminalWindow(_prompt, options) {
|
|
|
5386
5913
|
);
|
|
5387
5914
|
}
|
|
5388
5915
|
}
|
|
5389
|
-
const hasEnvFile =
|
|
5916
|
+
const hasEnvFile = existsSync3(join(workspacePath, ".env"));
|
|
5390
5917
|
await openTerminalWindow({
|
|
5391
5918
|
workspacePath,
|
|
5392
5919
|
command: launchCommand,
|