@ken-jo/agent-connector 0.4.97 → 0.4.99
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 +202 -202
- package/NOTICE +6 -6
- package/README.md +604 -596
- package/dist/{action-IPFDPOZU.js → action-5OEM3QC4.js} +17 -16
- package/dist/action-5OEM3QC4.js.map +1 -0
- package/dist/{amazon-q-IT44LEWV.js → amazon-q-7DPVJXJN.js} +6 -6
- package/dist/amazon-q-7DPVJXJN.js.map +1 -0
- package/dist/{amp-CEWOSWQO.js → amp-BQZOL5GR.js} +4 -4
- package/dist/amp-BQZOL5GR.js.map +1 -0
- package/dist/{amp-P35FRU2Z.js → amp-VYXZWHXW.js} +7 -7
- package/dist/amp-VYXZWHXW.js.map +1 -0
- package/dist/{antigravity-LHFEFNMC.js → antigravity-EA4L225L.js} +5 -5
- package/dist/antigravity-EA4L225L.js.map +1 -0
- package/dist/antigravity-VXHL6ZPM.js +18 -0
- package/dist/{antigravity-cli-MOKFSWOU.js → antigravity-cli-B2HXZFYQ.js} +5 -5
- package/dist/antigravity-cli-B2HXZFYQ.js.map +1 -0
- package/dist/{antigravity-cli-MPE27LPI.js → antigravity-cli-JHQ7JGNX.js} +10 -9
- package/dist/antigravity-cli-JHQ7JGNX.js.map +1 -0
- package/dist/{audit-3E5JAOP2.js → audit-BO7JQYIH.js} +8 -8
- package/dist/{chunk-7C2IPIIB.js → chunk-2Y2MZRLP.js} +3 -3
- package/dist/chunk-2Y2MZRLP.js.map +1 -0
- package/dist/{chunk-GZZCHJDP.js → chunk-4KIXXJ7B.js} +2 -2
- package/dist/chunk-4KIXXJ7B.js.map +1 -0
- package/dist/chunk-4NFDNY3C.js +34 -0
- package/dist/chunk-4NFDNY3C.js.map +1 -0
- package/dist/{chunk-C63AAXK7.js → chunk-4QXCNZMD.js} +5 -5
- package/dist/chunk-4QXCNZMD.js.map +1 -0
- package/dist/{chunk-Q7PR2WGT.js → chunk-6TF7MHG5.js} +2 -2
- package/dist/chunk-6TF7MHG5.js.map +1 -0
- package/dist/{chunk-7ZFK2WEO.js → chunk-6WN37NVN.js} +113 -10
- package/dist/chunk-6WN37NVN.js.map +1 -0
- package/dist/{chunk-GCPEPUD7.js → chunk-6XMV2OOA.js} +6 -6
- package/dist/chunk-6XMV2OOA.js.map +1 -0
- package/dist/{chunk-XXLCMSD3.js → chunk-BEFVJ2OE.js} +1 -1
- package/dist/chunk-BEFVJ2OE.js.map +1 -0
- package/dist/{chunk-N4ENLZEU.js → chunk-BV5WK6VQ.js} +19 -19
- package/dist/chunk-BV5WK6VQ.js.map +1 -0
- package/dist/{chunk-WPTNMYYM.js → chunk-BXPSDNIB.js} +6 -6
- package/dist/chunk-BXPSDNIB.js.map +1 -0
- package/dist/{chunk-Q4ISQHUQ.js → chunk-FBJQGRET.js} +1 -1
- package/dist/chunk-FBJQGRET.js.map +1 -0
- package/dist/{chunk-THI4PI4H.js → chunk-FJCUKXGX.js} +2 -2
- package/dist/chunk-FJCUKXGX.js.map +1 -0
- package/dist/{chunk-L2C5UMKW.js → chunk-FKW5A6HE.js} +23 -7
- package/dist/chunk-FKW5A6HE.js.map +1 -0
- package/dist/{chunk-NDMNMAKP.js → chunk-G5HAIYRM.js} +43 -43
- package/dist/chunk-G5HAIYRM.js.map +1 -0
- package/dist/{chunk-SLJI5BOM.js → chunk-GDIAHWNY.js} +2 -2
- package/dist/chunk-GDIAHWNY.js.map +1 -0
- package/dist/{chunk-QYOUQCC6.js → chunk-GZGLCCEE.js} +1 -1
- package/dist/chunk-GZGLCCEE.js.map +1 -0
- package/dist/{chunk-PSGTHJQU.js → chunk-H53QZQJI.js} +1 -1
- package/dist/chunk-H53QZQJI.js.map +1 -0
- package/dist/{chunk-7HHW23AC.js → chunk-IRUYJD23.js} +29 -29
- package/dist/chunk-IRUYJD23.js.map +1 -0
- package/dist/{chunk-IOJDZJ72.js → chunk-IVAWP6HH.js} +2 -2
- package/dist/chunk-IVAWP6HH.js.map +1 -0
- package/dist/{chunk-3FINQ2ZF.js → chunk-JTN3AKZO.js} +30 -20
- package/dist/chunk-JTN3AKZO.js.map +1 -0
- package/dist/{chunk-4GH2KA7V.js → chunk-KHO5WNTP.js} +1 -1
- package/dist/chunk-KHO5WNTP.js.map +1 -0
- package/dist/{chunk-MLU7NDAZ.js → chunk-KLZBRNFP.js} +12 -12
- package/dist/chunk-KLZBRNFP.js.map +1 -0
- package/dist/{chunk-3EP5V2F4.js → chunk-M6OS4OLU.js} +3 -3
- package/dist/chunk-M6OS4OLU.js.map +1 -0
- package/dist/{chunk-UZZTWWGG.js → chunk-MQPNU2CY.js} +1 -1
- package/dist/chunk-MQPNU2CY.js.map +1 -0
- package/dist/{chunk-LQ55E7QI.js → chunk-N4STCQGP.js} +7 -7
- package/dist/chunk-N4STCQGP.js.map +1 -0
- package/dist/{chunk-KFPSJRHR.js → chunk-NBYKLUF6.js} +2 -2
- package/dist/chunk-NBYKLUF6.js.map +1 -0
- package/dist/{chunk-KM2YXO6V.js → chunk-O7SDRBVB.js} +1 -1
- package/dist/chunk-O7SDRBVB.js.map +1 -0
- package/dist/{chunk-LFWYYWLV.js → chunk-OP4KBXUO.js} +1 -1
- package/dist/chunk-OP4KBXUO.js.map +1 -0
- package/dist/{chunk-XN7S44U4.js → chunk-OPXAP3AC.js} +1 -1
- package/dist/chunk-OPXAP3AC.js.map +1 -0
- package/dist/{chunk-TGZFDXNH.js → chunk-PWCBWAM4.js} +6 -4
- package/dist/chunk-PWCBWAM4.js.map +1 -0
- package/dist/{chunk-Y3K6KJMS.js → chunk-QSY74NAP.js} +2 -2
- package/dist/chunk-QSY74NAP.js.map +1 -0
- package/dist/{chunk-ZSOS2KOR.js → chunk-RK6VBLXP.js} +1 -1
- package/dist/chunk-RK6VBLXP.js.map +1 -0
- package/dist/{chunk-FHYR5Q5T.js → chunk-SFY6YLVK.js} +19 -12
- package/dist/chunk-SFY6YLVK.js.map +1 -0
- package/dist/{chunk-C747DYNT.js → chunk-UM5S7DKK.js} +1 -1
- package/dist/chunk-UM5S7DKK.js.map +1 -0
- package/dist/{chunk-ILWHLGIC.js → chunk-UMQ6NBQR.js} +2 -2
- package/dist/chunk-UMQ6NBQR.js.map +1 -0
- package/dist/{chunk-7PSNXUFK.js → chunk-XD7MY6HB.js} +1 -1
- package/dist/chunk-XD7MY6HB.js.map +1 -0
- package/dist/{chunk-XVEJAFKW.js → chunk-XY3N2U6L.js} +5 -5
- package/dist/chunk-XY3N2U6L.js.map +1 -0
- package/dist/{chunk-XZWMJLIT.js → chunk-YT43MUSJ.js} +1 -1
- package/dist/chunk-YT43MUSJ.js.map +1 -0
- package/dist/{claude-code-QBWDT5RT.js → claude-code-LJ6DVXWQ.js} +24 -14
- package/dist/claude-code-LJ6DVXWQ.js.map +1 -0
- package/dist/{claude-code-FS42PXZO.js → claude-code-NMRKTAP7.js} +4 -4
- package/dist/claude-code-NMRKTAP7.js.map +1 -0
- package/dist/cli/sdk.js +7 -7
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{cline-JKEAYWVR.js → cline-JAPJNOZQ.js} +6 -6
- package/dist/cline-JAPJNOZQ.js.map +1 -0
- package/dist/{codebuddy-EB6EYPC3.js → codebuddy-GC7VAE2Y.js} +7 -7
- package/dist/codebuddy-GC7VAE2Y.js.map +1 -0
- package/dist/{codebuff-5RSXFU6G.js → codebuff-3VODFPD4.js} +6 -6
- package/dist/codebuff-3VODFPD4.js.map +1 -0
- package/dist/{codebuff-6KWBW6CT.js → codebuff-ETYT5UBL.js} +4 -4
- package/dist/codebuff-ETYT5UBL.js.map +1 -0
- package/dist/{codex-ART46CDD.js → codex-RXIS5BHM.js} +9 -9
- package/dist/codex-RXIS5BHM.js.map +1 -0
- package/dist/{codex-DKBAAUCO.js → codex-YAORPCOD.js} +4 -4
- package/dist/codex-YAORPCOD.js.map +1 -0
- package/dist/{continue-JHZCMSPH.js → continue-MECVDV4Z.js} +8 -8
- package/dist/continue-MECVDV4Z.js.map +1 -0
- package/dist/{copilot-cli-CLBJACQ5.js → copilot-cli-MZTAWMPW.js} +4 -4
- package/dist/copilot-cli-MZTAWMPW.js.map +1 -0
- package/dist/{copilot-cli-QVAU5CFM.js → copilot-cli-WVWAWNSM.js} +7 -7
- package/dist/copilot-cli-WVWAWNSM.js.map +1 -0
- package/dist/{crush-A5C5USRL.js → crush-QBXLNN7T.js} +4 -4
- package/dist/crush-QBXLNN7T.js.map +1 -0
- package/dist/{crush-7TORBYUL.js → crush-YB3SK6NK.js} +7 -7
- package/dist/crush-YB3SK6NK.js.map +1 -0
- package/dist/{cursor-D5SWDVSW.js → cursor-DIW43TRZ.js} +3 -3
- package/dist/cursor-DIW43TRZ.js.map +1 -0
- package/dist/cursor-RSLHA2CY.js +22 -0
- package/dist/{define-connector-DTWb46UB.d.ts → define-connector-odRHEC4H.d.ts} +1 -1
- package/dist/{detect-JHSA3G3U.js → detect-ALP4G7WG.js} +4 -4
- package/dist/detect-ALP4G7WG.js.map +1 -0
- package/dist/{devin-SSR7S4WX.js → devin-WPDN3MXE.js} +7 -7
- package/dist/devin-WPDN3MXE.js.map +1 -0
- package/dist/{doctor-CQJ7TZPA.js → doctor-YEQWCWZJ.js} +27 -26
- package/dist/doctor-YEQWCWZJ.js.map +1 -0
- package/dist/{droid-45PJ7JGF.js → droid-HS6MX3IL.js} +10 -8
- package/dist/droid-HS6MX3IL.js.map +1 -0
- package/dist/{droid-PFQ2PZSF.js → droid-U3ZBLQFO.js} +4 -4
- package/dist/droid-U3ZBLQFO.js.map +1 -0
- package/dist/{gemini-cli-Y6RJMU24.js → gemini-cli-NMVVBO3K.js} +4 -4
- package/dist/gemini-cli-NMVVBO3K.js.map +1 -0
- package/dist/{gemini-cli-24PFDK7D.js → gemini-cli-VJ6X5DNF.js} +8 -8
- package/dist/gemini-cli-VJ6X5DNF.js.map +1 -0
- package/dist/{goose-U5D3LCPC.js → goose-3X7ID7YW.js} +9 -9
- package/dist/goose-3X7ID7YW.js.map +1 -0
- package/dist/{goose-K2HKUTBK.js → goose-64V46Y2W.js} +4 -4
- package/dist/goose-64V46Y2W.js.map +1 -0
- package/dist/{grok-cli-L2MHAPBY.js → grok-cli-4VFVF2CQ.js} +7 -7
- package/dist/grok-cli-4VFVF2CQ.js.map +1 -0
- package/dist/{hermes-2S5JUTTJ.js → hermes-AIVUE7LX.js} +10 -8
- package/dist/hermes-AIVUE7LX.js.map +1 -0
- package/dist/{hermes-MF3NX4ZY.js → hermes-F3EGTK6N.js} +4 -4
- package/dist/hermes-F3EGTK6N.js.map +1 -0
- package/dist/{hook-VHICXHXL.js → hook-F63I3SD5.js} +17 -16
- package/dist/hook-F63I3SD5.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -5
- package/dist/{install-WLENR4KF.js → install-23WRRFBY.js} +21 -21
- package/dist/install-23WRRFBY.js.map +1 -0
- package/dist/{introspect-dNekqPDY.d.ts → introspect-gTx6GzpW.d.ts} +1 -1
- package/dist/{jetbrains-copilot-Z4FC3RM3.js → jetbrains-copilot-XBO2JZRO.js} +6 -6
- package/dist/jetbrains-copilot-XBO2JZRO.js.map +1 -0
- package/dist/{junie-ULGJJIHB.js → junie-UCOS6Q37.js} +6 -6
- package/dist/junie-UCOS6Q37.js.map +1 -0
- package/dist/{kilo-SMHPOHJ5.js → kilo-SW7BH6EG.js} +4 -4
- package/dist/kilo-SW7BH6EG.js.map +1 -0
- package/dist/{kilo-WWIJOVWD.js → kilo-T4OXNUYY.js} +8 -8
- package/dist/kilo-T4OXNUYY.js.map +1 -0
- package/dist/{kilo-cli-QKE2EQLS.js → kilo-cli-I2S3W245.js} +8 -8
- package/dist/kilo-cli-I2S3W245.js.map +1 -0
- package/dist/{kilo-cli-T2SRRRJS.js → kilo-cli-ZF272ZHN.js} +5 -5
- package/dist/kilo-cli-ZF272ZHN.js.map +1 -0
- package/dist/{kimi-MSIDEMCI.js → kimi-5FHEXGZD.js} +4 -4
- package/dist/kimi-5FHEXGZD.js.map +1 -0
- package/dist/{kimi-JMUFTVSF.js → kimi-VLSUFLYV.js} +7 -7
- package/dist/kimi-VLSUFLYV.js.map +1 -0
- package/dist/{kiro-UWUCRKR3.js → kiro-AQFXGOJX.js} +10 -8
- package/dist/kiro-AQFXGOJX.js.map +1 -0
- package/dist/{kiro-NYRRBIKW.js → kiro-WGOI5CGT.js} +4 -4
- package/dist/kiro-WGOI5CGT.js.map +1 -0
- package/dist/{leaderboard-NJWKGMXP.js → leaderboard-YBD3IKC2.js} +7 -7
- package/dist/leaderboard-YBD3IKC2.js.map +1 -0
- package/dist/{mimo-code-BPNYYIVM.js → mimo-code-KETL7W7D.js} +7 -7
- package/dist/mimo-code-KETL7W7D.js.map +1 -0
- package/dist/{mistral-vibe-LT3DAJ3L.js → mistral-vibe-3AU7N2CA.js} +6 -6
- package/dist/mistral-vibe-3AU7N2CA.js.map +1 -0
- package/dist/{mux-AHNUAY5Z.js → mux-BO2L5CTW.js} +6 -6
- package/dist/mux-BO2L5CTW.js.map +1 -0
- package/dist/{mux-7PIJ7HUQ.js → mux-XM6AP35L.js} +4 -4
- package/dist/mux-XM6AP35L.js.map +1 -0
- package/dist/{nemoclaw-RE5RZASZ.js → nemoclaw-WA7RSKF2.js} +7 -7
- package/dist/nemoclaw-WA7RSKF2.js.map +1 -0
- package/dist/{omp-D2EXEPH7.js → omp-UDYJ2PYY.js} +9 -7
- package/dist/omp-UDYJ2PYY.js.map +1 -0
- package/dist/{open-interpreter-SSGBEUKX.js → open-interpreter-WMBNM4MQ.js} +6 -6
- package/dist/open-interpreter-WMBNM4MQ.js.map +1 -0
- package/dist/openclaw-3DHVHX5P.js +17 -0
- package/dist/{openclaw-KAFTNLR2.js → openclaw-5EQFGOWL.js} +4 -4
- package/dist/openclaw-5EQFGOWL.js.map +1 -0
- package/dist/{opencode-YKUKZY3J.js → opencode-IKMI3RI7.js} +7 -7
- package/dist/opencode-IKMI3RI7.js.map +1 -0
- package/dist/{opencode-Z65JYILL.js → opencode-QGP4ALQY.js} +4 -4
- package/dist/opencode-QGP4ALQY.js.map +1 -0
- package/dist/{openhands-SEZMCUC3.js → openhands-QGXMQR6I.js} +7 -7
- package/dist/openhands-QGXMQR6I.js.map +1 -0
- package/dist/{package-JECVQEFT.js → package-TAUTPP7Z.js} +15 -15
- package/dist/package-TAUTPP7Z.js.map +1 -0
- package/dist/{pi-YPYV2ULH.js → pi-A2HCGRJG.js} +9 -7
- package/dist/pi-A2HCGRJG.js.map +1 -0
- package/dist/{pi-DLKCPOJE.js → pi-GGDQREVG.js} +4 -4
- package/dist/pi-GGDQREVG.js.map +1 -0
- package/dist/{qwen-code-ZHCLCYMC.js → qwen-code-DNQTGJOF.js} +35 -17
- package/dist/qwen-code-DNQTGJOF.js.map +1 -0
- package/dist/{qwen-code-26CSFDX6.js → qwen-code-GQILBJ5B.js} +4 -4
- package/dist/qwen-code-GQILBJ5B.js.map +1 -0
- package/dist/{roo-code-HSAE2CJU.js → roo-code-SUWI4BBN.js} +4 -4
- package/dist/roo-code-SUWI4BBN.js.map +1 -0
- package/dist/{roo-code-7F4HYB34.js → roo-code-VI2ZKTZC.js} +6 -6
- package/dist/roo-code-VI2ZKTZC.js.map +1 -0
- package/dist/runtime/index.d.ts +9 -8
- package/dist/runtime/index.js +15 -14
- package/dist/sdk/index.d.ts +4 -4
- package/dist/sdk/index.js +6 -6
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +12 -11
- package/dist/{serve-LYSBH43G.js → serve-6MDLRQS2.js} +17 -16
- package/dist/serve-6MDLRQS2.js.map +1 -0
- package/dist/{status-PHKKGEW5.js → status-IUP75XHP.js} +11 -11
- package/dist/status-IUP75XHP.js.map +1 -0
- package/dist/{statusline-ZDD4OZ4F.js → statusline-PRODZV2J.js} +16 -15
- package/dist/statusline-PRODZV2J.js.map +1 -0
- package/dist/{synthetic-LUT6V6SD.js → synthetic-6FRA7P5Q.js} +4 -4
- package/dist/synthetic-6FRA7P5Q.js.map +1 -0
- package/dist/{telemetry-HDGMI2BK.js → telemetry-X4PLZEDB.js} +10 -10
- package/dist/telemetry-X4PLZEDB.js.map +1 -0
- package/dist/{trae-SIQI3C66.js → trae-CPPYASR2.js} +4 -4
- package/dist/trae-CPPYASR2.js.map +1 -0
- package/dist/{trae-Y67HSDOW.js → trae-VOJXUYRN.js} +6 -6
- package/dist/trae-VOJXUYRN.js.map +1 -0
- package/dist/{types-JyhpJHJa.d.ts → types-DWXnnx-N.d.ts} +96 -22
- package/dist/{uninstall-RWO2GM2I.js → uninstall-BSIJ4QXN.js} +21 -21
- package/dist/uninstall-BSIJ4QXN.js.map +1 -0
- package/dist/{upgrade-YJCXNUEE.js → upgrade-ZSICU3NE.js} +21 -21
- package/dist/upgrade-ZSICU3NE.js.map +1 -0
- package/dist/{usage-IWO4RQN6.js → usage-EQUNVSCT.js} +4 -4
- package/dist/usage-EQUNVSCT.js.map +1 -0
- package/dist/{usage-event-AFFKCLHE.js → usage-event-J5CQ6LNT.js} +16 -15
- package/dist/usage-event-J5CQ6LNT.js.map +1 -0
- package/dist/{vscode-copilot-5CI5B3X6.js → vscode-copilot-ZBXRPKGG.js} +7 -7
- package/dist/vscode-copilot-ZBXRPKGG.js.map +1 -0
- package/dist/{warp-5YBSP7FP.js → warp-NRBBJQR2.js} +4 -4
- package/dist/warp-NRBBJQR2.js.map +1 -0
- package/dist/{warp-INAKVGBV.js → warp-S444B2S3.js} +9 -7
- package/dist/warp-S444B2S3.js.map +1 -0
- package/dist/{windsurf-4HM57QAY.js → windsurf-R6D2JUTN.js} +6 -6
- package/dist/windsurf-R6D2JUTN.js.map +1 -0
- package/dist/{zed-YN5X37PQ.js → zed-DQV3ZUCU.js} +10 -8
- package/dist/zed-DQV3ZUCU.js.map +1 -0
- package/dist/{zed-XXCNYOIN.js → zed-XJFOOKCO.js} +4 -4
- package/dist/zed-XJFOOKCO.js.map +1 -0
- package/package.json +88 -88
- package/dist/action-IPFDPOZU.js.map +0 -1
- package/dist/amazon-q-IT44LEWV.js.map +0 -1
- package/dist/amp-CEWOSWQO.js.map +0 -1
- package/dist/amp-P35FRU2Z.js.map +0 -1
- package/dist/antigravity-LHFEFNMC.js.map +0 -1
- package/dist/antigravity-TWIWXTQH.js +0 -18
- package/dist/antigravity-cli-MOKFSWOU.js.map +0 -1
- package/dist/antigravity-cli-MPE27LPI.js.map +0 -1
- package/dist/chunk-3EP5V2F4.js.map +0 -1
- package/dist/chunk-3FINQ2ZF.js.map +0 -1
- package/dist/chunk-4GH2KA7V.js.map +0 -1
- package/dist/chunk-7C2IPIIB.js.map +0 -1
- package/dist/chunk-7HHW23AC.js.map +0 -1
- package/dist/chunk-7PSNXUFK.js.map +0 -1
- package/dist/chunk-7ZFK2WEO.js.map +0 -1
- package/dist/chunk-C63AAXK7.js.map +0 -1
- package/dist/chunk-C747DYNT.js.map +0 -1
- package/dist/chunk-FHYR5Q5T.js.map +0 -1
- package/dist/chunk-GCPEPUD7.js.map +0 -1
- package/dist/chunk-GZZCHJDP.js.map +0 -1
- package/dist/chunk-ILWHLGIC.js.map +0 -1
- package/dist/chunk-IOJDZJ72.js.map +0 -1
- package/dist/chunk-KFPSJRHR.js.map +0 -1
- package/dist/chunk-KM2YXO6V.js.map +0 -1
- package/dist/chunk-L2C5UMKW.js.map +0 -1
- package/dist/chunk-LFWYYWLV.js.map +0 -1
- package/dist/chunk-LQ55E7QI.js.map +0 -1
- package/dist/chunk-MLU7NDAZ.js.map +0 -1
- package/dist/chunk-N4ENLZEU.js.map +0 -1
- package/dist/chunk-NDMNMAKP.js.map +0 -1
- package/dist/chunk-PSGTHJQU.js.map +0 -1
- package/dist/chunk-Q4ISQHUQ.js.map +0 -1
- package/dist/chunk-Q7PR2WGT.js.map +0 -1
- package/dist/chunk-QYOUQCC6.js.map +0 -1
- package/dist/chunk-SLJI5BOM.js.map +0 -1
- package/dist/chunk-TGZFDXNH.js.map +0 -1
- package/dist/chunk-THI4PI4H.js.map +0 -1
- package/dist/chunk-UZZTWWGG.js.map +0 -1
- package/dist/chunk-WPTNMYYM.js.map +0 -1
- package/dist/chunk-XN7S44U4.js.map +0 -1
- package/dist/chunk-XVEJAFKW.js.map +0 -1
- package/dist/chunk-XXLCMSD3.js.map +0 -1
- package/dist/chunk-XZWMJLIT.js.map +0 -1
- package/dist/chunk-Y3K6KJMS.js.map +0 -1
- package/dist/chunk-ZSOS2KOR.js.map +0 -1
- package/dist/claude-code-FS42PXZO.js.map +0 -1
- package/dist/claude-code-QBWDT5RT.js.map +0 -1
- package/dist/cline-JKEAYWVR.js.map +0 -1
- package/dist/codebuddy-EB6EYPC3.js.map +0 -1
- package/dist/codebuff-5RSXFU6G.js.map +0 -1
- package/dist/codebuff-6KWBW6CT.js.map +0 -1
- package/dist/codex-ART46CDD.js.map +0 -1
- package/dist/codex-DKBAAUCO.js.map +0 -1
- package/dist/continue-JHZCMSPH.js.map +0 -1
- package/dist/copilot-cli-CLBJACQ5.js.map +0 -1
- package/dist/copilot-cli-QVAU5CFM.js.map +0 -1
- package/dist/crush-7TORBYUL.js.map +0 -1
- package/dist/crush-A5C5USRL.js.map +0 -1
- package/dist/cursor-D5SWDVSW.js.map +0 -1
- package/dist/cursor-W7I4QUFO.js +0 -22
- package/dist/detect-JHSA3G3U.js.map +0 -1
- package/dist/devin-SSR7S4WX.js.map +0 -1
- package/dist/doctor-CQJ7TZPA.js.map +0 -1
- package/dist/droid-45PJ7JGF.js.map +0 -1
- package/dist/droid-PFQ2PZSF.js.map +0 -1
- package/dist/gemini-cli-24PFDK7D.js.map +0 -1
- package/dist/gemini-cli-Y6RJMU24.js.map +0 -1
- package/dist/goose-K2HKUTBK.js.map +0 -1
- package/dist/goose-U5D3LCPC.js.map +0 -1
- package/dist/grok-cli-L2MHAPBY.js.map +0 -1
- package/dist/hermes-2S5JUTTJ.js.map +0 -1
- package/dist/hermes-MF3NX4ZY.js.map +0 -1
- package/dist/hook-VHICXHXL.js.map +0 -1
- package/dist/install-WLENR4KF.js.map +0 -1
- package/dist/jetbrains-copilot-Z4FC3RM3.js.map +0 -1
- package/dist/junie-ULGJJIHB.js.map +0 -1
- package/dist/kilo-SMHPOHJ5.js.map +0 -1
- package/dist/kilo-WWIJOVWD.js.map +0 -1
- package/dist/kilo-cli-QKE2EQLS.js.map +0 -1
- package/dist/kilo-cli-T2SRRRJS.js.map +0 -1
- package/dist/kimi-JMUFTVSF.js.map +0 -1
- package/dist/kimi-MSIDEMCI.js.map +0 -1
- package/dist/kiro-NYRRBIKW.js.map +0 -1
- package/dist/kiro-UWUCRKR3.js.map +0 -1
- package/dist/leaderboard-NJWKGMXP.js.map +0 -1
- package/dist/mimo-code-BPNYYIVM.js.map +0 -1
- package/dist/mistral-vibe-LT3DAJ3L.js.map +0 -1
- package/dist/mux-7PIJ7HUQ.js.map +0 -1
- package/dist/mux-AHNUAY5Z.js.map +0 -1
- package/dist/nemoclaw-RE5RZASZ.js.map +0 -1
- package/dist/omp-D2EXEPH7.js.map +0 -1
- package/dist/open-interpreter-SSGBEUKX.js.map +0 -1
- package/dist/openclaw-IJ33K45M.js +0 -17
- package/dist/openclaw-KAFTNLR2.js.map +0 -1
- package/dist/opencode-YKUKZY3J.js.map +0 -1
- package/dist/opencode-Z65JYILL.js.map +0 -1
- package/dist/openhands-SEZMCUC3.js.map +0 -1
- package/dist/package-JECVQEFT.js.map +0 -1
- package/dist/pi-DLKCPOJE.js.map +0 -1
- package/dist/pi-YPYV2ULH.js.map +0 -1
- package/dist/qwen-code-26CSFDX6.js.map +0 -1
- package/dist/qwen-code-ZHCLCYMC.js.map +0 -1
- package/dist/roo-code-7F4HYB34.js.map +0 -1
- package/dist/roo-code-HSAE2CJU.js.map +0 -1
- package/dist/serve-LYSBH43G.js.map +0 -1
- package/dist/status-PHKKGEW5.js.map +0 -1
- package/dist/statusline-ZDD4OZ4F.js.map +0 -1
- package/dist/synthetic-LUT6V6SD.js.map +0 -1
- package/dist/telemetry-HDGMI2BK.js.map +0 -1
- package/dist/trae-SIQI3C66.js.map +0 -1
- package/dist/trae-Y67HSDOW.js.map +0 -1
- package/dist/uninstall-RWO2GM2I.js.map +0 -1
- package/dist/upgrade-YJCXNUEE.js.map +0 -1
- package/dist/usage-IWO4RQN6.js.map +0 -1
- package/dist/usage-event-AFFKCLHE.js.map +0 -1
- package/dist/vscode-copilot-5CI5B3X6.js.map +0 -1
- package/dist/warp-5YBSP7FP.js.map +0 -1
- package/dist/warp-INAKVGBV.js.map +0 -1
- package/dist/windsurf-4HM57QAY.js.map +0 -1
- package/dist/zed-XXCNYOIN.js.map +0 -1
- package/dist/zed-YN5X37PQ.js.map +0 -1
- /package/dist/{antigravity-TWIWXTQH.js.map → antigravity-VXHL6ZPM.js.map} +0 -0
- /package/dist/{audit-3E5JAOP2.js.map → audit-BO7JQYIH.js.map} +0 -0
- /package/dist/{cursor-W7I4QUFO.js.map → cursor-RSLHA2CY.js.map} +0 -0
- /package/dist/{openclaw-IJ33K45M.js.map → openclaw-3DHVHX5P.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/app.ts","../src/cli/banner.ts"],"sourcesContent":["/**\r\n * cli/app — shared CLI helpers + command dispatch (NO side effects).\r\n *\r\n * Command modules import the shared helpers (print, fail, parse-flags,\r\n * renderInstallResult) from here, and main() dispatches the first positional to a\r\n * command module.\r\n * This module never auto-runs — `cli/index.ts` is the thin bin entry that calls\r\n * `main()`. Keeping the auto-run out of here is what prevents a dispatch recursion\r\n * (a command module importing a helper must not re-trigger the program) and makes\r\n * it robust to bundler entry-splitting (the old import.meta.url entry-guard broke\r\n * once tsup hoisted this code into a shared chunk).\r\n */\r\n\r\nimport { createRequire } from \"node:module\";\r\nimport { homedir } from \"node:os\";\r\n\r\nimport { PALETTES, renderBrandBanner, resolveColorMode, shouldShowBanner } from \"./banner.js\";\r\nimport type {\r\n ChangeRecord,\r\n ConnectorSummary,\r\n InstallResult,\r\n InstallScope,\r\n PlatformId,\r\n ResolvedConnector,\r\n} from \"../core/types.js\";\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Shared helpers (imported by the command modules)\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/** Print a line to stdout (machine-readable payloads must stay on stdout). */\r\nexport function print(line: string): void {\r\n process.stdout.write(`${line}\\n`);\r\n}\r\n\r\n/**\r\n * The brand active for THIS invocation. main() sets it from\r\n * {@link MainOptions.programName} before dispatch, so error messages printed by\r\n * command modules via {@link fail} read as the embedding tool (e.g. `acme-db:`)\r\n * instead of always `agent-connector:`.\r\n */\r\nlet activeProgramName = \"agent-connector\";\r\n\r\n/** Print an error to stderr (branded) and return a non-zero exit code (default 2). */\r\nexport function fail(message: string, code = 2): number {\r\n process.stderr.write(`${activeProgramName}: ${message}\\n`);\r\n return code;\r\n}\r\n\r\n/**\r\n * The brand active for THIS invocation (what the banner renders in ASCII art).\r\n * main() sets it from {@link MainOptions.programName} before dispatch; reading it\r\n * here keeps the banner branded for an embedding SDK CLI without each command\r\n * module needing the program name threaded through.\r\n */\r\nexport function getActiveProgramName(): string {\r\n return activeProgramName;\r\n}\r\n\r\n/**\r\n * Print the branded ASCII banner once, atop install / uninstall / upgrade /\r\n * doctor — but ONLY for an interactive TTY (suppressed when piped/redirected,\r\n * under --json, or under --quiet) so scripts and pipelines see byte-identical\r\n * command output. The pure render lives in cli/banner; this thin wrapper reads\r\n * the real stdout/env and feeds it in.\r\n */\r\nexport function maybePrintBanner(flags: { json?: boolean; quiet?: boolean }): void {\r\n const isTTY = process.stdout.isTTY === true;\r\n const noColor = process.env.NO_COLOR != null && process.env.NO_COLOR !== \"\";\r\n if (!shouldShowBanner({ isTTY, noColor, json: flags.json === true, quiet: flags.quiet === true })) {\r\n return;\r\n }\r\n const color = resolveColorMode({\r\n noColor,\r\n colorterm: process.env.COLORTERM,\r\n term: process.env.TERM,\r\n });\r\n // Coerce an unknown/zero width to a conservative 80 so an unknown-width TTY\r\n // shows the safe one-line title rather than the 129-col block art.\r\n const c = process.stdout.columns;\r\n const columns = typeof c === \"number\" && c > 0 ? c : 80;\r\n // Rotate the gradient per run so each real invocation reads differently. The\r\n // random pick lives HERE (the impure wrapper) so the pure renderer stays\r\n // deterministic for tests/direct callers.\r\n const palette = PALETTES[Math.floor(Math.random() * PALETTES.length)]!;\r\n print(renderBrandBanner(activeProgramName, { color, columns, palette }));\r\n print(\"\");\r\n}\r\n\r\n/**\r\n * Resolve agent-connector's own package version at runtime. Works from both the\r\n * bundled dist layout (dist/*.js → ../package.json) and the src layout under\r\n * tsx/vitest (src/cli/ → ../../package.json); the name check guards against\r\n * accidentally reading some other package.json on the walk.\r\n */\r\nexport function resolveOwnVersion(): string {\r\n const req = createRequire(import.meta.url);\r\n for (const rel of [\"../package.json\", \"../../package.json\", \"../../../package.json\"]) {\r\n try {\r\n const pkg = req(rel) as { name?: string; version?: string };\r\n if (pkg.name === \"@ken-jo/agent-connector\" && typeof pkg.version === \"string\") {\r\n return pkg.version;\r\n }\r\n } catch {\r\n /* keep walking */\r\n }\r\n }\r\n return \"0.0.0\";\r\n}\r\n\r\n/** Parse a --scope value the CLI accepts (user|project) into an InstallScope. */\r\nexport function parseScope(value: string | undefined): InstallScope | null {\r\n if (value === \"user\" || value === \"project\") return value;\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse a comma-separated --targets value into PlatformId[]. Returns undefined\r\n * when the flag is absent/empty so callers can fall back to connector/detection.\r\n */\r\nexport function parseTargets(value: string | undefined): PlatformId[] | undefined {\r\n if (value == null || value.trim() === \"\") return undefined;\r\n const ids = value\r\n .split(\",\")\r\n .map((s) => s.trim())\r\n .filter((s) => s !== \"\") as PlatformId[];\r\n return ids.length > 0 ? ids : undefined;\r\n}\r\n\r\n/**\r\n * Build the render-only {@link ConnectorSummary} from a resolved connector. The\r\n * command modules call this on the {@link ResolvedConnector} they already loaded\r\n * and attach the result to {@link InstallResult.connector}, so the friendly\r\n * renderer can print a header describing WHAT was deployed without importing the\r\n * heavyweight connector type or its live handlers.\r\n */\r\nexport function buildConnectorSummary(connector: ResolvedConnector): ConnectorSummary {\r\n let server: ConnectorSummary[\"server\"];\r\n if (connector.server) {\r\n const s = connector.server;\r\n // stdio → \"node server.mjs\"; remote → the URL (best-effort one-liner).\r\n // HOME-relativize each part so a bundled absolute server path reads short.\r\n const cmd =\r\n s.transport === \"stdio\"\r\n ? [s.command, ...(s.args ?? [])]\r\n .filter((p): p is string => p != null && p !== \"\")\r\n .map((p) => tildify(p))\r\n .join(\" \")\r\n : (s.url ?? \"\");\r\n server = { transport: s.transport, command: cmd };\r\n }\r\n return {\r\n id: connector.id,\r\n version: connector.version,\r\n displayName: connector.displayName,\r\n server,\r\n hookEvents: [...connector.hookEvents],\r\n telemetryEnabled: connector.telemetry.enabled,\r\n commands: connector.commands.length,\r\n skills: connector.skills.length,\r\n subagents: connector.subagents.length,\r\n memory: connector.memory.length,\r\n hasStatusline: connector.statusline != null,\r\n actions: connector.actions.length,\r\n };\r\n}\r\n\r\n/**\r\n * Rewrite an absolute path under the user's home dir to a leading `~/…` so the\r\n * per-host paths read short. Leaves non-home and relative paths untouched.\r\n */\r\nfunction tildify(path: string): string {\r\n // Normalize both to forward slashes so the home-prefix check is separator-\r\n // robust (Windows mixes `\\` and `/`) and the displayed path reads `~/…`\r\n // consistently on every platform (Windows terminals accept `/` fine).\r\n const home = homedir().replace(/\\\\/g, \"/\");\r\n const np = path.replace(/\\\\/g, \"/\");\r\n if (home && (np === home || np.startsWith(home + \"/\"))) {\r\n return \"~\" + np.slice(home.length);\r\n }\r\n return np;\r\n}\r\n\r\n/** Truncate a long single-line command for the header (keeps it scannable). */\r\nfunction truncateCommand(cmd: string, max = 64): string {\r\n if (cmd.length <= max) return cmd;\r\n return cmd.slice(0, max - 1) + \"…\";\r\n}\r\n\r\n/**\r\n * The surface a ChangeRecord touched, derived from its detail (primary signal)\r\n * then its path (fallback for content files whose detail is a bare basename).\r\n */\r\ntype Surface = \"mcp\" | \"hooks\" | \"commands\" | \"skills\" | \"subagents\" | \"memory\" | \"statusline\" | \"actions\" | \"backup\" | \"other\";\r\n\r\nfunction classifySurface(c: ChangeRecord): Surface {\r\n const detail = c.detail.toLowerCase();\r\n // A safety backup the installer wrote before a destructive change.\r\n if (detail.startsWith(\"backed up\") || detail.includes(\"backup\")) return \"backup\";\r\n // MCP server entry: mcpServers.<id> / mcp_servers.<id> / mcp.servers.<id>.\r\n if (/^mcp[._]?servers?\\./.test(detail) || detail.startsWith(\"mcp.\")) return \"mcp\";\r\n // Normalized + native hook entries: hooks.<Event> (case varies per host).\r\n if (detail.startsWith(\"hooks.\") || detail.startsWith(\"hook \")) return \"hooks\";\r\n if (detail.includes(\"nativehooks\")) return \"hooks\";\r\n if (detail.startsWith(\"memory\")) return \"memory\";\r\n if (detail.startsWith(\"statusline\")) return \"statusline\";\r\n if (detail.startsWith(\"actions\") || detail.startsWith(\"action \")) return \"actions\";\r\n if (detail.includes(\"configpatch\")) return \"other\";\r\n // Path-based fallback for content-file surfaces (detail is a bare basename).\r\n const p = (c.path ?? \"\").replace(/\\\\/g, \"/\").toLowerCase();\r\n if (/\\/commands?\\//.test(p)) return \"commands\";\r\n if (/\\/skills?\\//.test(p)) return \"skills\";\r\n if (/\\/(subagents?|agents?)\\//.test(p)) return \"subagents\";\r\n // Detail mentions a surface noun (skip/warn lines like \"no skills\").\r\n if (/\\bcommands?\\b/.test(detail)) return \"commands\";\r\n if (/\\bskills?\\b/.test(detail)) return \"skills\";\r\n if (/\\bsubagents?\\b/.test(detail)) return \"subagents\";\r\n return \"other\";\r\n}\r\n\r\nconst SURFACE_LABEL_SINGULAR: Record<Surface, string> = {\r\n mcp: \"MCP server\",\r\n hooks: \"hook\",\r\n commands: \"command\",\r\n skills: \"skill\",\r\n subagents: \"subagent\",\r\n memory: \"memory block\",\r\n statusline: \"status line\",\r\n actions: \"action\",\r\n backup: \"backup\",\r\n other: \"change\",\r\n};\r\n\r\n/** Pluralize a surface count, e.g. (2,\"hooks\") → \"2 hooks\". */\r\nfunction countLabel(n: number, surface: Surface): string {\r\n const base = SURFACE_LABEL_SINGULAR[surface];\r\n if (surface === \"mcp\") return \"MCP server\"; // singular by construction\r\n return n === 1 ? `1 ${base}` : `${n} ${base}s`;\r\n}\r\n\r\n/** Verb-appropriate glyph for a host's NET status. */\r\nfunction hostGlyph(status: \"ok\" | \"skip\" | \"warn\"): string {\r\n return status === \"warn\" ? \"!\" : status === \"skip\" ? \"=\" : \"✓\";\r\n}\r\n\r\n/**\r\n * One host's collapsed view: its net status, a surface summary line, the\r\n * deduped HOME-relativized paths it touched, and any inline warnings.\r\n */\r\ninterface HostGroup {\r\n platform: PlatformId;\r\n status: \"ok\" | \"skip\" | \"warn\";\r\n summary: string;\r\n paths: string[];\r\n warnings: string[];\r\n}\r\n\r\n/**\r\n * Collapse the per-(host,surface) ChangeRecords into ONE entry per host:\r\n * - status: warn if any record warned; ok if any created/updated/removed;\r\n * else skip (everything was a no-op).\r\n * - summary: the active (non-skip) surfaces, joined (\"MCP server + 2 hooks\").\r\n * When every record skipped, the reason is surfaced instead.\r\n */\r\nfunction groupByHost(changes: ChangeRecord[], verb: Verb): HostGroup[] {\r\n const order: PlatformId[] = [];\r\n const byHost = new Map<PlatformId, ChangeRecord[]>();\r\n for (const c of changes) {\r\n if (!byHost.has(c.platform)) {\r\n byHost.set(c.platform, []);\r\n order.push(c.platform);\r\n }\r\n byHost.get(c.platform)!.push(c);\r\n }\r\n\r\n const groups: HostGroup[] = [];\r\n for (const platform of order) {\r\n const recs = byHost.get(platform)!;\r\n // A safety backup the installer wrote is INCIDENTAL, not an installed\r\n // surface: it must not flip an otherwise-no-op host to \"changed\" (an\r\n // idempotent re-install that only re-backs-up should still read \"already\r\n // current\"). It is shown only ALONGSIDE a real surface change.\r\n const written = recs.filter((c) => c.action !== \"skip\" && c.action !== \"warn\");\r\n const realChanges = written.filter((c) => classifySurface(c) !== \"backup\");\r\n const warned = recs.filter((c) => c.action === \"warn\");\r\n const status: HostGroup[\"status\"] =\r\n warned.length > 0 ? \"warn\" : realChanges.length > 0 ? \"ok\" : \"skip\";\r\n\r\n // Surface summary from the written records (created/updated/removed),\r\n // preserving a stable surface order and collapsing per-surface counts. The\r\n // incidental `backup` surface is included ONLY when a real surface changed.\r\n const SURFACE_ORDER: Surface[] = [\r\n \"mcp\",\r\n \"hooks\",\r\n \"commands\",\r\n \"skills\",\r\n \"subagents\",\r\n \"memory\",\r\n \"statusline\",\r\n \"actions\",\r\n \"backup\",\r\n \"other\",\r\n ];\r\n const counts = new Map<Surface, number>();\r\n const summarySource = realChanges.length > 0 ? written : realChanges;\r\n for (const c of summarySource) {\r\n const s = classifySurface(c);\r\n counts.set(s, (counts.get(s) ?? 0) + 1);\r\n }\r\n const parts = SURFACE_ORDER.filter((s) => counts.has(s)).map((s) =>\r\n countLabel(counts.get(s)!, s),\r\n );\r\n\r\n let summary: string;\r\n if (parts.length > 0) {\r\n summary = parts.join(\" + \");\r\n } else if (status === \"warn\") {\r\n // No real surface change but a warning — the warning line carries detail.\r\n summary = \"\";\r\n } else {\r\n // Nothing real changed: surface a skip reason (or note the incidental\r\n // backup) for context.\r\n const reason =\r\n recs.find((c) => c.action === \"skip\")?.detail ??\r\n (written.length > 0 ? \"already current (re-backed-up only)\" : \"no changes\");\r\n summary = verb === \"uninstall\" ? `nothing to remove (${reason})` : `unchanged (${reason})`;\r\n }\r\n\r\n const paths = [\r\n ...new Set(\r\n recs\r\n .filter((c) => c.path != null && c.path !== \"\")\r\n .map((c) => tildify(c.path!)),\r\n ),\r\n ];\r\n const warnings = warned.map((c) => c.detail);\r\n\r\n groups.push({ platform, status, summary, paths, warnings });\r\n }\r\n return groups;\r\n}\r\n\r\ntype Verb = \"install\" | \"upgrade\" | \"uninstall\";\r\n\r\n/**\r\n * Render an InstallResult as a friendly, grouped report (the DEFAULT output):\r\n * 1. a connector header (id/version/displayName + server/hooks/telemetry +\r\n * one line per shipped content surface), when the summary is threaded in;\r\n * 2. one line per host (net glyph + surface summary + deduped ~/… paths),\r\n * with any host warnings inline beneath it;\r\n * 3. a friendly closing line + restart hint + doctor/uninstall next steps.\r\n *\r\n * Used by install / upgrade / uninstall. The exit-non-zero-on-warn convention\r\n * is enforced by the callers (this function only renders).\r\n */\r\nexport function renderInstallResult(result: InstallResult, verb: Verb): string {\r\n const lines: string[] = [];\r\n const summary = result.connector;\r\n\r\n // ── 1. Connector header ───────────────────────────────────────────────────\r\n if (summary) {\r\n const head = [`${summary.id} v${summary.version}`];\r\n if (summary.displayName && summary.displayName !== summary.id) {\r\n head.push(summary.displayName);\r\n }\r\n lines.push(head.join(\" · \"));\r\n\r\n if (summary.server) {\r\n lines.push(\r\n ` server ${summary.server.transport} · ${truncateCommand(summary.server.command)}`,\r\n );\r\n } else {\r\n lines.push(\" server (hooks-only)\");\r\n }\r\n if (summary.hookEvents.length > 0) {\r\n lines.push(` hooks ${summary.hookEvents.join(\", \")}`);\r\n }\r\n lines.push(` telemetry ${summary.telemetryEnabled ? \"on\" : \"off\"}`);\r\n if (summary.commands > 0)\r\n lines.push(` commands ${summary.commands}`);\r\n if (summary.skills > 0) lines.push(` skills ${summary.skills}`);\r\n if (summary.subagents > 0)\r\n lines.push(` subagents ${summary.subagents}`);\r\n if (summary.memory > 0) lines.push(` memory ${summary.memory}`);\r\n if (summary.hasStatusline) lines.push(` statusline 1`);\r\n if (summary.actions > 0) lines.push(` actions ${summary.actions}`);\r\n lines.push(\"\");\r\n } else {\r\n // No summary threaded (back-compat): keep a minimal verb header.\r\n const mode = result.dryRun ? \" (dry-run — nothing written)\" : \"\";\r\n lines.push(`${verb} \"${result.connectorId}\"${mode}`);\r\n }\r\n\r\n // ── 2. Per-host grouping ──────────────────────────────────────────────────\r\n const groups = groupByHost(result.changes, verb);\r\n if (groups.length === 0) {\r\n lines.push(\"(no changes)\");\r\n } else {\r\n const verbed = verb === \"uninstall\" ? \"removed from\" : verb === \"upgrade\" ? \"synced to\" : \"detected\";\r\n lines.push(`→ ${groups.length} agent ${groups.length === 1 ? \"CLI\" : \"CLIs\"} ${verbed}:`);\r\n // Width-align the platform column for a scannable table; the summary column\r\n // gets a fixed min width but always keeps a 2-space gap before the paths\r\n // even when an unusually long summary overflows it.\r\n const pad = Math.max(...groups.map((g) => g.platform.length));\r\n for (const g of groups) {\r\n const glyph = hostGlyph(g.status);\r\n const name = g.platform.padEnd(pad);\r\n const pathsCol = g.paths.join(\", \");\r\n const gap = pathsCol === \"\" ? \"\" : \" \";\r\n const summaryCol = pathsCol === \"\" ? g.summary : g.summary.padEnd(26) + gap;\r\n lines.push(` ${glyph} ${name} ${summaryCol}${pathsCol}`.trimEnd());\r\n for (const w of g.warnings) lines.push(` ! ${w}`);\r\n }\r\n }\r\n\r\n // ── 3. Closing summary + next steps ───────────────────────────────────────\r\n // The headline file tally counts only REAL surface writes — an incidental\r\n // safety backup must not masquerade as an installed file, so a re-install\r\n // whose only write was a backup honestly reports 0 files / \"already current\".\r\n const tally = result.changes.reduce(\r\n (acc, c) => {\r\n const isWrite = c.action === \"create\" || c.action === \"update\" || c.action === \"remove\";\r\n if (isWrite && classifySurface(c) !== \"backup\") acc.files += 1;\r\n if (c.action === \"warn\") acc.warns += 1;\r\n return acc;\r\n },\r\n { files: 0, warns: 0 },\r\n );\r\n const cliCount = groups.length;\r\n const cliWord = cliCount === 1 ? \"CLI\" : \"CLIs\";\r\n const fileWord = tally.files === 1 ? \"file\" : \"files\";\r\n\r\n lines.push(\"\");\r\n if (verb === \"uninstall\") {\r\n if (result.dryRun) {\r\n lines.push(`✓ Would remove ${summary?.id ?? result.connectorId} from ${cliCount} ${cliWord} · ${tally.files} ${fileWord} (dry-run — nothing written).`);\r\n } else if (tally.files === 0 && tally.warns === 0) {\r\n lines.push(`✓ Nothing to remove — ${summary?.id ?? result.connectorId} was not installed (zero residue).`);\r\n } else {\r\n lines.push(`✓ Removed ${summary?.id ?? result.connectorId} from ${cliCount} ${cliWord} · ${tally.files} ${fileWord} cleaned${tally.warns === 0 ? \" (zero residue)\" : \"\"}.`);\r\n }\r\n } else {\r\n const what = verb === \"upgrade\" ? \"Synced\" : \"Installed\";\r\n const wouldWhat = verb === \"upgrade\" ? \"sync\" : \"install\";\r\n if (result.dryRun) {\r\n lines.push(`✓ Would ${wouldWhat} ${summary?.id ?? result.connectorId} to ${cliCount} ${cliWord} · ${tally.files} ${fileWord} (dry-run — nothing written).`);\r\n } else if (tally.files === 0) {\r\n lines.push(`✓ ${summary?.id ?? result.connectorId}: already current on ${cliCount} ${cliWord} — nothing to write.`);\r\n } else {\r\n lines.push(`✓ ${what} ${summary?.id ?? result.connectorId} to ${cliCount} ${cliWord} · ${tally.files} ${fileWord}. Restart each CLI to load it.`);\r\n }\r\n }\r\n\r\n // Warnings block (kept explicit — callers exit non-zero on any warn). A\r\n // remote-transport connector pushes the SAME string to both a warn\r\n // ChangeRecord (already shown inline on its host line) and result.warnings, so\r\n // skip any bottom-block entry already surfaced inline to show each warning ONCE.\r\n const inlineWarnings = new Set(groups.flatMap((g) => g.warnings));\r\n const blockWarnings = result.warnings.filter((w) => !inlineWarnings.has(w));\r\n if (blockWarnings.length > 0) {\r\n lines.push(\"\");\r\n lines.push(\"warnings:\");\r\n for (const w of blockWarnings) lines.push(` ! ${w}`);\r\n }\r\n\r\n // Next-step hints (the verbs read as the active brand).\r\n if (verb === \"uninstall\") {\r\n lines.push(` Verify it's gone: ${activeProgramName} doctor`);\r\n } else {\r\n lines.push(\r\n ` Verify: ${activeProgramName} doctor · Remove: ${activeProgramName} uninstall`,\r\n );\r\n }\r\n\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Command dispatch\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/** A command module: takes the post-command argv slice, returns an exit code. */\r\ntype CommandModule = { run: (argv: string[]) => Promise<number> | number };\r\n\r\n/** Lazy command loaders — keyed by the first positional. Imported on demand. */\r\nconst COMMANDS: Record<string, () => Promise<CommandModule>> = {\r\n detect: () => import(\"./commands/detect.js\"),\r\n install: () => import(\"./commands/install.js\"),\r\n uninstall: () => import(\"./commands/uninstall.js\"),\r\n // `upgrade` is the single \"bring everything current\" verb (re-render host\r\n // config + refresh the home pointer + managed channel guidance). `sync` and\r\n // `update` are kept as back-compat aliases that route to the same module so\r\n // existing scripts/docs keep working without a second concept to learn.\r\n upgrade: () => import(\"./commands/upgrade.js\"),\r\n sync: () => import(\"./commands/upgrade.js\"),\r\n update: () => import(\"./commands/upgrade.js\"),\r\n package: () => import(\"./commands/package.js\"),\n audit: () => import(\"./commands/audit.js\"),\n doctor: () => import(\"./commands/doctor.js\"),\n status: () => import(\"./commands/status.js\"),\r\n telemetry: () => import(\"./commands/telemetry.js\"),\r\n usage: () => import(\"./commands/usage.js\"),\r\n leaderboard: () => import(\"./commands/leaderboard.js\"),\r\n hook: () => import(\"./commands/hook.js\"),\r\n // Internal (omitted from USAGE): the statusline (HUD) entrypoint a host's\r\n // status line config points at. Fail-safe: always exits 0 with at most a\r\n // rendered line. See cli/commands/statusline.ts.\r\n statusline: () => import(\"./commands/statusline.js\"),\r\n // Internal (omitted from USAGE): the user-invokable action entrypoint a future\r\n // host affordance points at. USER-TRIGGERED: surfaces errors (exit 1 + stderr),\r\n // unlike the fail-open hook / fail-safe statusline. See cli/commands/action.ts.\r\n action: () => import(\"./commands/action.js\"),\r\n serve: () => import(\"./commands/serve.js\"),\r\n // Hidden (omitted from USAGE): the opt-in host-native turn-usage entrypoint an\r\n // AfterModel / PostInvocation hook points at. Always exits 0; records a\r\n // distinct `model_turn` row. See cli/commands/usage-event.ts.\r\n \"usage-event\": () => import(\"./commands/usage-event.js\"),\r\n};\r\n\r\n/** Default program name; an embedding SDK CLI overrides it via {@link MainOptions}. */\r\nexport const DEFAULT_PROGRAM_NAME = \"agent-connector\";\r\n\r\n/**\r\n * One-line usage signature per command — the single central copy behind\r\n * `<command> --help` and the friendly bad-flag error. Command modules use\r\n * node:util parseArgs (strict), which THROWS on an unknown flag; without the\r\n * dispatcher-level handling in {@link main}, `agent-connector install --help`\r\n * would die with a raw ERR_PARSE_ARGS stack trace — the very invocation the\r\n * root help tells users to run.\r\n */\r\nconst COMMAND_USAGE: Record<string, string> = {\r\n detect: \"detect [--json] [--project <dir>]\",\r\n install:\n \"install [<source>] [--method direct|marketplace] [--connector <source>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--force] [--quiet]\\n\" +\n \" <source> a local path OR a remote connector source: owner/repo[/subpath][#ref], a github.com URL (incl. /tree/<ref>/<sub>), git@github.com:owner/repo, github:owner/repo, npm:<package>[@version], archive:<path-or-url>, or a direct .tgz/.tar.gz URL/path. Remote sources are fetched to ~/.agent-connector/sources/ and must be an agent-connector package (have an agent-connector.config.{mjs,js,json}).\",\n uninstall:\r\n \"uninstall [--method auto|direct|marketplace] [--connector <path>] [--connector-id <id>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--purge] [--quiet]\",\r\n upgrade:\r\n \"upgrade [--method direct|marketplace] [--channel stable|latest] [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--quiet]\",\r\n sync: \"sync — alias of upgrade (see `upgrade --help`)\",\r\n update: \"update — alias of upgrade (see `upgrade --help`)\",\r\n package:\n \"package [--connector <path>] [--format <fmt>|all] [--out <dir>] [--project <dir>] [--dry-run]\",\n audit:\n \"audit [--connector <path>] [--package-json <path>] [--project <dir>] [--json] [--strict]\",\n doctor:\n \"doctor [--targets a,b] [--connector <path>] [--scope user|project] [--project <dir>] [--probe] [--explain] [--json] [--heal] [--dry-run] [--quiet]\\n\" +\r\n \" --explain per-(host,event) hook honor matrix (honored/degraded/dropped). Exit non-zero ONLY when an explicitly-targeted host DEGRADES a declared event (fires it but silently won't honor the reply); dropped/mcp-only hosts and fleet-wide (targets:auto) gaps are informational (exit 0).\",\r\n status: \"status [--connector <path>] [--scope user|project] [--project <dir>] [--json]\",\r\n telemetry:\r\n \"telemetry report|export|leaderboard [--by <dim>] [--since <dur>] [--connector <id>] [--scope <slice>] [--format csv|json] [--out <file>] [--json]\",\r\n usage:\r\n \"usage report|export|leaderboard [--by <dim>] [--since <dur>] [--platform <id>] [--format csv|json] [--out <file>] [--json]\",\r\n leaderboard: \"leaderboard [--since <dur>] [--connector <id>] [--scope <slice>] [--json]\",\r\n hook: \"hook <platform> <event> --connector <id> (internal — host hook configs point here)\",\r\n statusline:\r\n \"statusline <platform> --connector <id> (internal — host status line configs point here)\",\r\n action:\r\n \"action <platform> <actionId> --connector <id> (internal — host action affordances point here)\",\r\n serve:\r\n \"serve --connector <id> [--scope user|project] [--host <platformId>] -- <command> [args...] (internal — host MCP entries point here)\",\r\n};\r\n\r\n/**\r\n * Build the top-level usage string for a given program name. The brand replaces\r\n * \"agent-connector\" in the title, the `usage:` line, and the per-command help\r\n * footer so an embedded CLI (e.g. `acme-db`) reads as its own tool.\r\n */\r\nfunction buildUsage(programName: string): string {\r\n return `${programName} — write your MCP server + hooks once, install everywhere.\r\n\r\nusage: ${programName} <command> [flags]\r\n\r\ncommands:\r\n detect List the AI-agent platforms installed on this machine.\r\n install Deploy a connector across its target platforms (--method direct writes host config; --method marketplace drives the host's plugin install).\r\n uninstall Remove a connector's registrations (--method auto reverses whichever method is actually installed).\r\n upgrade Bring everything current: re-render host config + heal the home pointer + managed update guidance (alias: update, sync).\n package Emit a marketplace/extension bundle (10 host formats, or the standard artifacts mcp-server-json | mcpb).\n audit Check branded package identity before install/publish.\n doctor Health-check every detected platform; non-zero exit on any failure.\n status Light install-state summary: which connectors are present on which hosts (always exits 0).\r\n telemetry Inspect local per-tool token telemetry (report | export | leaderboard).\r\n usage Inspect host-native token usage from agent CLI logs (report | export | leaderboard).\r\n leaderboard Three leaderboards: 🔌 MCP/plugin (mcp-self) + 🖥️ host/user (host-scan-logs) + 🛰️ host-native turns (host-native-live) — never summed.\r\n hook Universal json-stdio hook entrypoint (hosts call this).\r\n serve Telemetry-wrapping MCP stdio proxy (wraps a real server command).\r\n\r\nRun \\`${programName} <command> --help\\` for command-specific flags.`;\r\n}\r\n\r\n/** Options accepted by {@link main}. */\r\nexport interface MainOptions {\r\n /**\r\n * The brand shown in usage/help text. Defaults to {@link DEFAULT_PROGRAM_NAME}.\r\n * An embedding SDK CLI (see cli/sdk.ts) passes its own bin name so every\r\n * subcommand's help reads as the developer's tool.\r\n */\r\n programName?: string;\r\n /**\r\n * Version shown by --version. Defaults to agent-connector's own package version.\r\n * Embedded branded CLIs pass their package.json version.\r\n */\r\n programVersion?: string;\r\n}\r\n\r\nexport async function main(argv: string[], opts: MainOptions = {}): Promise<number> {\r\n const programName = opts.programName ?? DEFAULT_PROGRAM_NAME;\r\n activeProgramName = programName; // brand every fail() in this invocation\r\n const usage = buildUsage(programName);\r\n const command = argv[0];\r\n\r\n if (command == null || command === \"--help\" || command === \"-h\" || command === \"help\") {\r\n print(usage);\r\n return command == null ? 1 : 0;\r\n }\r\n if (command === \"--version\" || command === \"-v\") {\r\n print(`${programName} ${opts.programVersion ?? resolveOwnVersion()}`);\r\n return 0;\r\n }\r\n\r\n const loader = COMMANDS[command];\r\n if (!loader) {\r\n process.stderr.write(`${programName}: unknown command \"${command}\"\\n\\n`);\r\n process.stderr.write(`${usage}\\n`);\r\n return 2;\r\n }\r\n\r\n // Per-command help: no command module defines a --help flag (strict parseArgs\r\n // would throw on it), so answer it centrally from COMMAND_USAGE.\r\n const rest = argv.slice(1);\r\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\r\n const sig = COMMAND_USAGE[command];\r\n if (sig) {\r\n print(`usage: ${programName} ${sig}`);\r\n return 0;\r\n }\r\n }\r\n\r\n const mod = await loader();\r\n try {\r\n return await mod.run(rest);\r\n } catch (err) {\r\n // Friendly bad-flag errors: strict parseArgs throws ERR_PARSE_ARGS_* for an\r\n // unknown/malformed option — print the message + the usage line instead of\r\n // letting a raw stack trace reach the user. Everything else still rethrows\r\n // (the bin entry reports those as fatal).\r\n const code = (err as { code?: string }).code;\r\n if (typeof code === \"string\" && code.startsWith(\"ERR_PARSE_ARGS\")) {\r\n const message = err instanceof Error ? err.message : String(err);\r\n const sig = COMMAND_USAGE[command];\r\n if (sig) process.stderr.write(`usage: ${programName} ${sig}\\n`);\r\n return fail(message);\r\n }\r\n throw err;\r\n }\r\n}\r\n","/**\r\n * cli/banner — the branded ASCII-art header shown once atop install / uninstall\r\n * / upgrade / doctor.\r\n *\r\n * Two PURE functions drive everything (no process.* reads here — the command\r\n * wiring injects the real env so tests can call these directly without a TTY):\r\n *\r\n * renderBrandBanner(name, { color, columns, palette }) → the banner string\r\n * shouldShowBanner({ isTTY, noColor, json, quiet }) → whether to show it\r\n *\r\n * RESPONSIVE (one line, NEVER stacked), two forms:\r\n * • WIDE — a 6-row \"ANSI Shadow\" block font (solid `█` + `╗╔╝╚║═` shadow,\r\n * ~8 cols/char, hand-transcribed + fixed-width so it tiles cleanly) when its\r\n * render fits the terminal width.\r\n * • NARROW — a single-line gradient TITLE `◆ AGENT-CONNECTOR` (the brand\r\n * uppercased, each char colored along the palette + bold). ~18 cols, so it\r\n * fits any real terminal; it is the universal narrow form.\r\n * The WIDE font covers the connector-id charset [A-Za-z0-9 ._-].\r\n *\r\n * COLOR: a palette gradient (three RGB stops, a {@link Palette}) — swept per\r\n * column across the block art, or per character across the title. The render is\r\n * PURE and palette-parameterized — the caller picks the palette (the impure\r\n * app.ts wrapper rotates {@link PALETTES} per run). truecolor→256→16→none tiers\r\n * all honor the palette; NO_COLOR = zero ANSI.\r\n */\r\n\r\n/** Color capability the host terminal advertises, highest → lowest. */\r\nexport type ColorMode = \"truecolor\" | \"ansi256\" | \"ansi16\" | \"none\";\r\n\r\n/** A 24-bit RGB triple. */\r\nexport type RGB = readonly [number, number, number];\r\n\r\n/** A 3-stop gradient: the sweep lerps stop0 → stop1 → stop2 across the columns. */\r\nexport type Palette = readonly [RGB, RGB, RGB];\r\n\r\n/**\r\n * The 10 rotation palettes. The impure {@link maybePrintBanner} wrapper picks one\r\n * at random per run so each real invocation shows a different color; the pure\r\n * renderer defaults to PALETTES[0] so direct callers + tests stay deterministic.\r\n */\r\nexport const PALETTES: readonly Palette[] = [\r\n [[255, 210, 0], [255, 110, 10], [220, 30, 25]], // Sunset\r\n [[255, 225, 90], [255, 120, 0], [200, 20, 20]], // Lava\r\n [[230, 30, 30], [255, 120, 0], [255, 220, 0]], // Fire\r\n [[255, 225, 120], [255, 170, 40], [225, 110, 20]], // Amber gold\r\n [[255, 205, 150], [255, 150, 130], [255, 120, 175]], // Peach pastel\r\n [[255, 80, 170], [200, 40, 200], [100, 60, 210]], // Berry\r\n [[0, 220, 180], [0, 160, 230], [60, 90, 230]], // Ocean\r\n [[80, 230, 140], [0, 200, 210], [150, 90, 235]], // Aurora\r\n [[170, 230, 90], [60, 200, 120], [20, 150, 140]], // Forest\r\n [[0, 200, 200], [40, 80, 230], [200, 40, 200]], // Synthwave\r\n] as const;\r\n\r\n/** Inputs to {@link renderBrandBanner} — all injected, never read from process. */\r\nexport interface BannerOptions {\r\n /** Color capability to render at. \"none\" emits zero ANSI codes. */\r\n color: ColorMode;\r\n /** Terminal width in columns; selects the form (wide block art → one-line title). */\r\n columns: number;\r\n /** The 3-stop gradient. Defaults to {@link PALETTES}[0] (Sunset) when omitted. */\r\n palette?: Palette;\r\n}\r\n\r\n/** Inputs to {@link shouldShowBanner} — the real env, injected by the caller. */\r\nexport interface BannerGate {\r\n /** process.stdout.isTTY (banner is suppressed entirely when not a TTY). */\r\n isTTY: boolean;\r\n /** NO_COLOR is set (the banner still shows, but with zero color codes). */\r\n noColor: boolean;\r\n /** A machine-readable --json was requested (suppress entirely). */\r\n json: boolean;\r\n /** An explicit --quiet was passed (suppress entirely). */\r\n quiet: boolean;\r\n}\r\n\r\n/**\r\n * Whether to print the banner at all. The banner is decorative, so it shows ONLY\r\n * for an interactive TTY and never when output is being consumed by a script or\r\n * pipeline: not when piped/redirected (`!isTTY`), not under `--json`, and not\r\n * under `--quiet`. `NO_COLOR` does NOT suppress it — the banner renders without\r\n * color in that case (handled by {@link resolveColorMode}).\r\n */\r\nexport function shouldShowBanner(gate: BannerGate): boolean {\r\n return gate.isTTY && !gate.json && !gate.quiet;\r\n}\r\n\r\n/**\r\n * Resolve the color tier from the (injected) terminal env. 24-bit when the\r\n * terminal advertises it (COLORTERM=truecolor|24bit), 256-color when TERM names\r\n * a 256 palette, else 16-color — and PLAIN (no color) under NO_COLOR or a dumb /\r\n * absent TERM.\r\n */\r\nexport function resolveColorMode(env: {\r\n noColor: boolean;\r\n colorterm?: string | undefined;\r\n term?: string | undefined;\r\n}): ColorMode {\r\n if (env.noColor) return \"none\";\r\n const term = (env.term ?? \"\").toLowerCase();\r\n if (term === \"\" || term === \"dumb\") return \"none\";\r\n const colorterm = (env.colorterm ?? \"\").toLowerCase();\r\n if (colorterm === \"truecolor\" || colorterm === \"24bit\") return \"truecolor\";\r\n if (term.includes(\"256\")) return \"ansi256\";\r\n return \"ansi16\";\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// WIDE font — \"ANSI Shadow\" (6 rows). Hand-transcribed bold figlet glyphs —\r\n// solid `█` with a `╗╔╝╚║═` 3D shadow — fixed-width per glyph so they TILE\r\n// cleanly when concatenated (~8 cols/char → \"agent-connector\" ≈ 126 cols on\r\n// one line). Used only when the terminal is wide enough.\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\nconst WIDE_FONT: Record<string, readonly string[]> = {\r\n A: [\" █████╗ \", \"██╔══██╗\", \"███████║\", \"██╔══██║\", \"██║ ██║\", \"╚═╝ ╚═╝\"],\r\n B: [\"██████╗ \", \"██╔══██╗\", \"██████╔╝\", \"██╔══██╗\", \"██████╔╝\", \"╚═════╝ \"],\r\n C: [\" ██████╗\", \"██╔════╝\", \"██║ \", \"██║ \", \"╚██████╗\", \" ╚═════╝\"],\r\n D: [\"██████╗ \", \"██╔══██╗\", \"██║ ██║\", \"██║ ██║\", \"██████╔╝\", \"╚═════╝ \"],\r\n E: [\"███████╗\", \"██╔════╝\", \"█████╗ \", \"██╔══╝ \", \"███████╗\", \"╚══════╝\"],\r\n F: [\"███████╗\", \"██╔════╝\", \"█████╗ \", \"██╔══╝ \", \"██║ \", \"╚═╝ \"],\r\n G: [\" ██████╗ \", \"██╔════╝ \", \"██║ ███╗\", \"██║ ██║\", \"╚██████╔╝\", \" ╚═════╝ \"],\r\n H: [\"██╗ ██╗\", \"██║ ██║\", \"███████║\", \"██╔══██║\", \"██║ ██║\", \"╚═╝ ╚═╝\"],\r\n I: [\"██╗\", \"██║\", \"██║\", \"██║\", \"██║\", \"╚═╝\"],\r\n J: [\" ██╗\", \" ██║\", \" ██║\", \"██ ██║\", \"╚█████╔╝\", \" ╚════╝ \"],\r\n K: [\"██╗ ██╗\", \"██║ ██╔╝\", \"█████╔╝ \", \"██╔═██╗ \", \"██║ ██╗\", \"╚═╝ ╚═╝\"],\r\n L: [\"██╗ \", \"██║ \", \"██║ \", \"██║ \", \"███████╗\", \"╚══════╝\"],\r\n M: [\"███╗ ███╗\", \"████╗ ████║\", \"██╔████╔██║\", \"██║╚██╔╝██║\", \"██║ ╚═╝ ██║\", \"╚═╝ ╚═╝\"],\r\n N: [\"███╗ ██╗\", \"████╗ ██║\", \"██╔██╗ ██║\", \"██║╚██╗██║\", \"██║ ╚████║\", \"╚═╝ ╚═══╝\"],\r\n O: [\" ██████╗ \", \"██╔═══██╗\", \"██║ ██║\", \"██║ ██║\", \"╚██████╔╝\", \" ╚═════╝ \"],\r\n P: [\"██████╗ \", \"██╔══██╗\", \"██████╔╝\", \"██╔═══╝ \", \"██║ \", \"╚═╝ \"],\r\n Q: [\" ██████╗ \", \"██╔═══██╗\", \"██║ ██║\", \"██║▄▄ ██║\", \"╚██████╔╝\", \" ╚══▀▀═╝ \"],\r\n R: [\"██████╗ \", \"██╔══██╗\", \"██████╔╝\", \"██╔══██╗\", \"██║ ██║\", \"╚═╝ ╚═╝\"],\r\n S: [\"███████╗\", \"██╔════╝\", \"███████╗\", \"╚════██║\", \"███████║\", \"╚══════╝\"],\r\n T: [\"████████╗\", \"╚══██╔══╝\", \" ██║ \", \" ██║ \", \" ██║ \", \" ╚═╝ \"],\r\n U: [\"██╗ ██╗\", \"██║ ██║\", \"██║ ██║\", \"██║ ██║\", \"╚██████╔╝\", \" ╚═════╝ \"],\r\n V: [\"██╗ ██╗\", \"██║ ██║\", \"██║ ██║\", \"╚██╗ ██╔╝\", \" ╚████╔╝ \", \" ╚═══╝ \"],\r\n W: [\"██╗ ██╗\", \"██║ ██║\", \"██║ █╗ ██║\", \"██║███╗██║\", \"╚███╔███╔╝\", \" ╚══╝╚══╝ \"],\r\n X: [\"██╗ ██╗\", \"╚██╗██╔╝\", \" ╚███╔╝ \", \" ██╔██╗ \", \"██╔╝ ██╗\", \"╚═╝ ╚═╝\"],\r\n Y: [\"██╗ ██╗\", \"╚██╗ ██╔╝\", \" ╚████╔╝ \", \" ╚██╔╝ \", \" ██║ \", \" ╚═╝ \"],\r\n Z: [\"███████╗\", \"╚══███╔╝\", \" ███╔╝ \", \" ███╔╝ \", \"███████╗\", \"╚══════╝\"],\r\n \"0\": [\" ██████╗ \", \"██╔═████╗\", \"██║██╔██║\", \"████╔╝██║\", \"╚██████╔╝\", \" ╚═════╝ \"],\r\n \"1\": [\" ██╗\", \"███║\", \"╚██║\", \" ██║\", \" ██║\", \" ╚═╝\"],\r\n \"2\": [\"██████╗ \", \"╚════██╗\", \" █████╔╝\", \"██╔═══╝ \", \"███████╗\", \"╚══════╝\"],\r\n \"3\": [\"██████╗ \", \"╚════██╗\", \" █████╔╝\", \" ╚═══██╗\", \"██████╔╝\", \"╚═════╝ \"],\r\n \"4\": [\"██╗ ██╗\", \"██║ ██║\", \"███████║\", \"╚════██║\", \" ██║\", \" ╚═╝\"],\r\n \"5\": [\"███████╗\", \"██╔════╝\", \"███████╗\", \"╚════██║\", \"███████║\", \"╚══════╝\"],\r\n \"6\": [\" ██████╗ \", \"██╔════╝ \", \"███████╗ \", \"██╔═══██╗\", \"╚██████╔╝\", \" ╚═════╝ \"],\r\n \"7\": [\"███████╗\", \"╚════██║\", \" ██╔╝\", \" ██╔╝ \", \" ██║ \", \" ╚═╝ \"],\r\n \"8\": [\" █████╗ \", \"██╔══██╗\", \"╚█████╔╝\", \"██╔══██╗\", \"╚█████╔╝\", \" ╚════╝ \"],\r\n \"9\": [\" █████╗ \", \"██╔══██╗\", \"╚██████║\", \" ╚═══██║\", \" █████╔╝\", \" ╚════╝ \"],\r\n \"-\": [\" \", \" \", \"█████╗\", \"╚════╝\", \" \", \" \"],\r\n \"_\": [\" \", \" \", \" \", \" \", \"███████╗\", \"╚══════╝\"],\r\n \".\": [\" \", \" \", \" \", \" \", \"██╗\", \"╚═╝\"],\r\n \" \": [\" \", \" \", \" \", \" \", \" \", \" \"],\r\n};\r\n\r\nconst GLYPH_ROWS = 6;\r\n\r\n/** Visible column count of a string (full-block + box-drawing are 1 cell each). */\r\nfunction vlen(s: string): number {\r\n return [...s].length;\r\n}\r\n\r\n/**\r\n * Render `name` into the fixed-width `font` as GLYPH_ROWS lines. The ANSI-Shadow\r\n * glyphs already carry their own trailing shadow column and tile cleanly with NO\r\n * inter-glyph gap. Returns null when the name has no renderable characters; the\r\n * glyphs are width-consistent per glyph, so the rows stay aligned.\r\n */\r\nfunction renderWithFont(name: string, font: Record<string, readonly string[]>): string[] | null {\r\n const chars = [...name];\r\n if (chars.length === 0) return null;\r\n const blank = font[\" \"]!;\r\n const rows: string[] = Array.from({ length: GLYPH_ROWS }, () => \"\");\r\n for (const ch of chars) {\r\n const glyph = font[ch.toUpperCase()] ?? blank;\r\n for (let r = 0; r < GLYPH_ROWS; r++) {\r\n rows[r] += glyph[r] ?? \"\";\r\n }\r\n }\r\n // Drop any fully-blank bottom rows so a name built from narrower glyphs (e.g.\r\n // \".\" / \"_\") never pads the banner with trailing empty lines.\r\n while (rows.length > 1 && rows[rows.length - 1]!.trim() === \"\") rows.pop();\r\n return rows;\r\n}\r\n\r\n/** Max visible width across an art block's rows. */\r\nfunction blockWidth(rows: string[]): number {\r\n return rows.length === 0 ? 0 : Math.max(...rows.map(vlen));\r\n}\r\n\r\n/**\r\n * The WIDE ANSI-Shadow block art for `name` when it fits `columns` (ONE line,\r\n * never stacked); else null so the caller renders the narrow one-line title.\r\n * `columns <= 0` means \"no constraint\" → always the WIDE art.\r\n */\r\nfunction selectWideArt(name: string, columns: number): string[] | null {\r\n const limit = columns > 0 ? columns : Infinity;\r\n const wide = renderWithFont(name, WIDE_FONT);\r\n return wide != null && blockWidth(wide) <= limit ? wide : null;\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Palette-parameterized gradient. The sweep lerps the three palette stops\r\n// across each row's columns (t∈[0,1]). truecolor uses the exact RGB; 256 and 16\r\n// derive the nearest representable code FROM the same RGB, so every palette\r\n// works in every tier. \"none\" emits the bare char.\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/** The interpolated RGB of `palette` at gradient position t∈[0,1]. */\r\nfunction gradientRGB(t: number, palette: Palette): RGB {\r\n const clamp = Math.max(0, Math.min(1, t));\r\n const seg = clamp >= 0.5 ? 1 : 0;\r\n const local = (clamp - seg * 0.5) / 0.5;\r\n const a = palette[seg]!;\r\n const b = palette[seg + 1]!;\r\n return [\r\n Math.round(a[0] + (b[0] - a[0]) * local),\r\n Math.round(a[1] + (b[1] - a[1]) * local),\r\n Math.round(a[2] + (b[2] - a[2]) * local),\r\n ];\r\n}\r\n\r\n/** Nearest xterm-256 cube index (16..231) for an RGB triple. */\r\nfunction rgbTo256(r: number, g: number, b: number): number {\r\n const q = (v: number): number => (v < 48 ? 0 : v < 115 ? 1 : Math.round((v - 35) / 40));\r\n return 16 + 36 * q(r) + 6 * q(g) + q(b);\r\n}\r\n\r\n/** Nearest of the 8 bright 16-color fg codes (90..97) for an RGB triple. */\r\nfunction rgbTo16(r: number, g: number, b: number): number {\r\n // Threshold each channel; map the on/off triple to its bright SGR code.\r\n const hi = (v: number): number => (v >= 128 ? 1 : 0);\r\n const key = (hi(r) << 2) | (hi(g) << 1) | hi(b);\r\n // index: RGB bits → code. 0:black(90) 1:blue(94) 2:green(92) 3:cyan(96)\r\n // 4:red(91) 5:magenta(95) 6:yellow(93) 7:white(97)\r\n return [90, 94, 92, 96, 91, 95, 93, 97][key]!;\r\n}\r\n\r\nconst RESET = \"\\x1b[0m\";\r\n\r\n/**\r\n * Wrap a single grapheme `ch` at gradient position `t` in the SGR escape for the\r\n * given color tier + palette. Whitespace is never colored (no point paying for\r\n * an escape around a space) and \"none\" returns the bare char.\r\n */\r\nfunction colorChar(ch: string, t: number, color: ColorMode, palette: Palette): string {\r\n if (color === \"none\" || ch.trim() === \"\") return ch;\r\n const [r, g, b] = gradientRGB(t, palette);\r\n if (color === \"truecolor\") return `\\x1b[38;2;${r};${g};${b}m${ch}${RESET}`;\r\n if (color === \"ansi256\") return `\\x1b[38;5;${rgbTo256(r, g, b)}m${ch}${RESET}`;\r\n return `\\x1b[${rgbTo16(r, g, b)}m${ch}${RESET}`;\r\n}\r\n\r\n/** Apply the left-to-right gradient across one art row (by visible column). */\r\nfunction colorizeRow(row: string, color: ColorMode, palette: Palette): string {\r\n if (color === \"none\") return row;\r\n const chars = [...row];\r\n const width = Math.max(1, chars.length - 1);\r\n let out = \"\";\r\n for (let i = 0; i < chars.length; i++) {\r\n out += colorChar(chars[i]!, i / width, color, palette);\r\n }\r\n return out;\r\n}\r\n\r\n/** A single BOLD grapheme at gradient position `t` (used by the narrow title). */\r\nfunction boldColorChar(ch: string, t: number, color: ColorMode, palette: Palette): string {\r\n if (color === \"none\") return ch;\r\n const [r, g, b] = gradientRGB(t, palette);\r\n const fg =\r\n color === \"truecolor\"\r\n ? `38;2;${r};${g};${b}`\r\n : color === \"ansi256\"\r\n ? `38;5;${rgbTo256(r, g, b)}`\r\n : `${rgbTo16(r, g, b)}`;\r\n return `\\x1b[1;${fg}m${ch}${RESET}`;\r\n}\r\n\r\n/**\r\n * The NARROW one-line title `◆ AGENT-CONNECTOR`: a colored leading diamond (the\r\n * palette mid stop), two spaces, then the UPPERCASED brand with each character\r\n * colored along the palette gradient (i → t = i/(len-1)) and bold. Under \"none\"\r\n * it is the plain text with ZERO ANSI. ~18 cols for \"agent-connector\", so it\r\n * fits any real terminal.\r\n */\r\nfunction renderTitle(name: string, color: ColorMode, palette: Palette): string {\r\n const upper = name.toUpperCase();\r\n if (color === \"none\") return `◆ ${upper}`;\r\n const diamond = boldColorChar(\"◆\", 0.5, color, palette);\r\n const chars = [...upper];\r\n const span = Math.max(1, chars.length - 1);\r\n let title = \"\";\r\n for (let i = 0; i < chars.length; i++) {\r\n title += boldColorChar(chars[i]!, i / span, color, palette);\r\n }\r\n return `${diamond} ${title}`;\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Footer (engine attribution). Shown on BOTH the global and branded CLIs — the\r\n// \"powered by\" wording is intentional.\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\nconst FOOTER_LINES = [\r\n \"powered by @ken-jo/agent-connector\",\r\n \"more → https://github.com/ken-jo/agent-connector\",\r\n] as const;\r\n\r\n/** Dim (de-emphasized) footer line; plain under \"none\". */\r\nfunction dim(text: string, color: ColorMode): string {\r\n return color === \"none\" ? text : `\\x1b[2m${text}${RESET}`;\r\n}\r\n\r\n/**\r\n * Render the full banner: a responsive brand title with a palette-driven\r\n * gradient, then a two-line dim footer directly below.\r\n *\r\n * • WIDE — the ANSI-Shadow block art when it fits `columns` (ONE line, never\r\n * stacked; `columns <= 0` = no constraint).\r\n * • NARROW — the one-line `◆ AGENT-CONNECTOR` gradient title (the universal\r\n * narrow form, ~18 cols) when the block art would overflow.\r\n * • `palette` defaults to PALETTES[0] so direct callers + tests are\r\n * deterministic; the impure app.ts wrapper rotates the palettes per run.\r\n * • Under `color: \"none\"` (NO_COLOR / dumb term) the output carries zero ANSI\r\n * escape codes — only the raw art/title + footer text.\r\n *\r\n * The result has NO trailing newline; the caller prints it with one.\r\n */\r\nexport function renderBrandBanner(name: string, opts: BannerOptions): string {\r\n const { color, columns } = opts;\r\n const palette = opts.palette ?? PALETTES[0]!;\r\n const footer = FOOTER_LINES.map((l) => dim(l, color)).join(\"\\n\");\r\n\r\n const art = selectWideArt(name, columns);\r\n const body =\r\n art != null\r\n ? art.map((row) => colorizeRow(row, color, palette)).join(\"\\n\")\r\n : renderTitle(name, color, palette);\r\n return `${body}\\n${footer}`;\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/registry.ts"],"sourcesContent":["/**\r\n * adapters/registry — single source of truth for the platforms agent-connector\r\n * targets. Generalized from context-mode's `ADAPTER_REGISTRY` pattern, adapted\r\n * to our `Adapter` / `AdapterFactory` contract (adapters/spi.ts).\r\n *\r\n * In context-mode the same platform set was redeclared in four places (env-var\r\n * detection, session-dir lookup, the lazy adapter loader, and per-adapter base\r\n * constructors); adding a platform meant editing all of them and missing one\r\n * was silent. Here the list lives ONCE below: each platform is one entry with a\r\n * lazy `load()` thunk that resolves the adapter singleton. Adding a platform is\r\n * a single new entry — `getFactory` / `loadAdapter` / `allAdapters` and the\r\n * detection cascade in detect.ts all derive from this list.\r\n *\r\n * `load()` returns the module's default export, which every adapter file is\r\n * required to provide as its singleton (`export default adapter;`). It is a\r\n * function (not an eager import) so module loading stays lazy: an adapter is\r\n * only imported when it is actually needed, keeping startup cheap.\r\n *\r\n * Order is load-bearing for runtime host detection (detect.ts iterates env\r\n * markers in registry order): forks MUST precede their parent so a session\r\n * running inside a derived shell is not misclassified as the parent. For the\r\n * three Phase-1 adapters this is moot, but the ordering convention is fixed now\r\n * so later additions (cursor is a VS Code fork, etc.) slot in correctly.\r\n */\r\n\r\nimport type { PlatformId } from \"../core/types.js\";\r\nimport type { Adapter, AdapterFactory } from \"./spi.js\";\r\n\r\n/**\r\n * Authoritative list of installable platforms. One entry per platform; the\r\n * `load` thunk lazily imports the adapter module and returns its default-export\r\n * singleton. To add a platform: drop its `src/adapters/<id>/index.ts` in place\r\n * (default-exporting an `Adapter`) and add one entry here.\r\n */\r\nexport const ADAPTER_REGISTRY: readonly AdapterFactory[] = [\r\n // codebuddy (Tencent CodeBuddy) is a Claude Code fork that ALSO exports\r\n // CLAUDE_SESSION_ID at runtime (its bundle sets both CODEBUDDY_SESSION_ID and\r\n // CLAUDE_SESSION_ID), so it must precede claude-code: the fork's exclusive\r\n // runtime markers are checked first during host detection (fork-before-parent).\r\n {\r\n id: \"codebuddy\",\r\n load: () => import(\"./codebuddy/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"claude-code\",\r\n load: () => import(\"./claude-code/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"codex\",\r\n load: () => import(\"./codex/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"cursor\",\r\n load: () => import(\"./cursor/index.js\").then((m) => m.default),\r\n },\r\n // vscode-copilot after cursor: cursor is a VS Code fork, so the fork's runtime\r\n // markers must be checked first during host detection.\r\n {\r\n id: \"vscode-copilot\",\r\n load: () => import(\"./vscode-copilot/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"copilot-cli\",\r\n load: () => import(\"./copilot-cli/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"gemini-cli\",\r\n load: () => import(\"./gemini-cli/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"warp\",\r\n load: () => import(\"./warp/index.js\").then((m) => m.default),\r\n },\r\n // ts-plugin paradigm: OpenCode loads a generated plugin module that bridges\r\n // its in-process events to the universal hook entrypoint.\r\n {\r\n id: \"opencode\",\r\n load: () => import(\"./opencode/index.js\").then((m) => m.default),\r\n },\r\n // mimo-code is Xiaomi's MiMoCode (@mimo-ai/cli, bin `mimo`) — an OpenCode FORK\r\n // (ts-plugin, MCP root key \"mcp\", ~/.config/mimocode/mimocode.json). Grouped\r\n // beside the OpenCode family whose config dialect + plugin contract it shares;\r\n // detected via the DISTINCT ~/.config/mimocode dir, so there is no fork-ordering\r\n // constraint vs opencode (no shared config file to disambiguate).\r\n {\r\n id: \"mimo-code\",\r\n load: () => import(\"./mimo-code/index.js\").then((m) => m.default),\r\n },\r\n // kilo-cli is the SQLite-backed OpenCode FORK command-line product (ts-plugin,\r\n // loads @kilocode/plugin modules registered in kilo.jsonc's \"plugin\" array;\r\n // MCP root key \"mcp\", ~/.config/kilo/kilo.jsonc). Grouped beside the OpenCode\r\n // family whose plugin contract + config dialect it shares; distinct host from\r\n // the \"kilo\" extension so there is no fork-ordering constraint between them.\r\n {\r\n id: \"kilo-cli\",\r\n load: () => import(\"./kilo-cli/index.js\").then((m) => m.default),\r\n },\r\n // Wave 1 — mcp-only adapters (no lifecycle hooks; MCP registration only).\r\n {\r\n id: \"droid\",\r\n load: () => import(\"./droid/index.js\").then((m) => m.default),\r\n },\r\n // openhands is the All-Hands-AI OpenHands CLI (`openhands`, ex-OpenDevin) —\r\n // a standalone json-stdio host: MCP at ~/.openhands/mcp.json (\"mcpServers\",\r\n // FastMCP entry shape) + a SEPARATE .openhands/hooks.json carrying the\r\n // Claude-Code-plugin-compatible nested-rule hooks (6 events). Its persistence\r\n // dir (~/.openhands) is distinct, so there is no fork-ordering constraint.\r\n {\r\n id: \"openhands\",\r\n load: () => import(\"./openhands/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"roo-code\",\r\n load: () => import(\"./roo-code/index.js\").then((m) => m.default),\r\n },\r\n // kilo is the Kilo Code VS Code extension (kilocode.kilo-code) — a Roo/Cline\r\n // fork, so it sits beside roo-code (mcp-only, root key \"mcpServers\", VS Code\r\n // globalStorage / .kilocode project scope). Distinct host from \"kilo-cli\".\r\n {\r\n id: \"kilo\",\r\n load: () => import(\"./kilo/index.js\").then((m) => m.default),\r\n },\r\n // cline is the Cline VS Code extension (saoudrizwan.claude-dev) — the most-\r\n // installed AI coding extension and the PARENT that roo-code and kilo forked.\r\n // mcp-only (no hook layer); MCP at the globalStorage cline_mcp_settings.json\r\n // (\"mcpServers\"); content lives in the .clinerules tree + ~/Documents/Cline.\r\n // NO runtime-marker collision with roo-code (rooveterinaryinc.roo-cline / .roo)\r\n // or kilo (kilocode.kilo-code / .kilo) — distinct ext ids + dotdirs — so there\r\n // is NO fork-before-parent ordering constraint here; it simply sits beside them.\r\n {\r\n id: \"cline\",\r\n load: () => import(\"./cline/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"trae\",\r\n load: () => import(\"./trae/index.js\").then((m) => m.default),\r\n },\r\n // antigravity-cli BEFORE antigravity: the `agy` CLI is a fork of the IDE\r\n // adapter with its own runtime markers (the universal hook command tags the\r\n // host as \"antigravity-cli\"), so the more-specific CLI marker must be checked\r\n // before the IDE/parent during host detection.\r\n {\r\n id: \"antigravity-cli\",\r\n load: () => import(\"./antigravity-cli/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"antigravity\",\r\n load: () => import(\"./antigravity/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"zed\",\r\n load: () => import(\"./zed/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"amp\",\r\n load: () => import(\"./amp/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"codebuff\",\r\n load: () => import(\"./codebuff/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"mux\",\r\n load: () => import(\"./mux/index.js\").then((m) => m.default),\r\n },\r\n // Pi — mcp-only host with no writable MCP config; drives the Agent Skills\r\n // surface only (writes <piDir>/skills/<name>/SKILL.md).\r\n {\r\n id: \"pi\",\r\n load: () => import(\"./pi/index.js\").then((m) => m.default),\r\n },\r\n // Wave 2 — json-stdio adapters (full hook dispatch via the universal entrypoint).\r\n // jetbrains-copilot before vscode-copilot is unnecessary (distinct hosts); grouped here.\r\n {\r\n id: \"jetbrains-copilot\",\r\n load: () => import(\"./jetbrains-copilot/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"qwen-code\",\r\n load: () => import(\"./qwen-code/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"kiro\",\r\n load: () => import(\"./kiro/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"kimi\",\r\n load: () => import(\"./kimi/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"crush\",\r\n load: () => import(\"./crush/index.js\").then((m) => m.default),\r\n },\r\n // Wave 3 — json-stdio adapters with YAML config (MCP in YAML; hooks per host).\r\n {\r\n id: \"goose\",\r\n load: () => import(\"./goose/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"hermes\",\r\n load: () => import(\"./hermes/index.js\").then((m) => m.default),\r\n },\r\n // Wave 4 — ts-plugin adapters (generate a bridge module to the universal entrypoint).\r\n {\r\n id: \"omp\",\r\n load: () => import(\"./omp/index.js\").then((m) => m.default),\r\n },\r\n // nemoclaw BEFORE openclaw (fork-before-parent convention). NVIDIA NemoClaw\r\n // wraps OpenClaw and DRIVES the SAME ~/.openclaw/openclaw.json, so a NemoClaw\r\n // box carries BOTH the ~/.nemoclaw/ and ~/.openclaw/ markers. Exclusivity is\r\n // enforced at the SOURCE: OpenClawAdapter.detectInstalled BOWS OUT when\r\n // ~/.nemoclaw/ is present, so the shared config is never double-targeted as two\r\n // platforms. This ordering is the deterministic tie-break (matching the\r\n // antigravity-cli/antigravity precedent). nemoclaw extends OpenClawAdapter\r\n // (id/name/detection overridden), so inherited server/hook registration still\r\n // lands in the wrapped openclaw.json.\r\n {\r\n id: \"nemoclaw\",\r\n load: () => import(\"./nemoclaw/index.js\").then((m) => m.default),\r\n },\r\n {\r\n id: \"openclaw\",\r\n load: () => import(\"./openclaw/index.js\").then((m) => m.default),\r\n },\r\n // Wave 5 — mcp-only: Amazon Q Developer CLI. JSON MCP config under ~/.aws/amazonq/\r\n // (user) and .amazonq/ (project); root key \"mcpServers\"; bare stdio entry\r\n // { command, args, env, timeout? } or remote entry { type: \"http\", url } (no\r\n // headers) for http. The agent-format hooks layer (cli-agents/*.json) +\r\n // agents/prompts content surfaces are separate, not-yet-wired surfaces; this\r\n // adapter installs MCP entries + the .amazonq/rules memory surface.\r\n {\r\n id: \"amazon-q\",\r\n load: () => import(\"./amazon-q/index.js\").then((m) => m.default),\r\n },\r\n // Continue (the `cn` terminal agent / Continue.dev, npm @continuedev/cli) —\r\n // json-stdio (Claude-compatible hooks). MCP config is YAML at ~/.continue/config.yaml (user) and\r\n // <projectDir>/.continue/config.yaml (project); root key \"mcpServers\" is a\r\n // YAML ARRAY of { name, command, type?, args?, env?, cwd?, url } entries (NOT a\r\n // keyed map). Hooks: a Claude-compatible json-stdio layer in settings.json\r\n // (~/.continue/settings.json — separate from the MCP config.yaml; PR #11029) +\r\n // nativeHooks for the host-specific events. Distinct ~/.continue marker — no\r\n // fork-ordering constraint vs any sibling.\r\n {\r\n id: \"continue\",\r\n load: () => import(\"./continue/index.js\").then((m) => m.default),\r\n },\r\n // Windsurf (Codeium / Cognition's Cascade agent) — mcp-only. USER/GLOBAL scope\r\n // ONLY: MCP config is JSON at ~/.codeium/windsurf/mcp_config.json (the docs\r\n // document no project/workspace path), root key \"mcpServers\" is a Claude-\r\n // Desktop-style OBJECT map keyed by server name (like cursor). stdio entry\r\n // { command, args?, env? }; remote entry { serverUrl, headers? } (NOT `url`;\r\n // no type/disabled). No user-installable hook/plugin layer (GUI editor), so it\r\n // stays mcp-only paradigm — but content surfaces ARE wired: workflows\r\n // (.windsurf/workflows + ~/.codeium/windsurf/global_workflows), skills\r\n // (.windsurf/skills + ~/.codeium/windsurf/skills), and the .windsurf/rules\r\n // memory surface. Distinct ~/.codeium marker — no fork-ordering constraint.\r\n {\r\n id: \"windsurf\",\r\n load: () => import(\"./windsurf/index.js\").then((m) => m.default),\r\n },\r\n // Grok CLI (the community superagent-ai/grok-cli, npm `grok-dev`, bin `grok`,\r\n // MIT) — json-stdio. Id is `grok-cli` (NOT `grok`) to stay distinct from xAI's\r\n // separate \"Grok Build\" product. USER-SCOPE ONLY: both MCP servers (nested\r\n // `mcp.servers` JSON ARRAY, keyed by `id`) and hooks (top-level `hooks`,\r\n // Claude nested-rule shape) live in ~/.grok/user-settings.json (project\r\n // .grok/settings.json holds neither — Grok excludes project hooks for\r\n // security). Distinct ~/.grok marker — no fork-ordering constraint vs any\r\n // sibling.\r\n {\r\n id: \"grok-cli\",\r\n load: () => import(\"./grok-cli/index.js\").then((m) => m.default),\r\n },\r\n // Devin CLI (Cognition) — json-stdio. A Rust binary (`devin`, installed via\r\n // `curl cli.devin.ai/install.sh` → ~/.local/bin/devin). MCP + hooks live in\r\n // ONE config.json per scope: user ~/.config/devin/config.json\r\n // (%APPDATA%\\devin\\config.json on Windows) / project <projectDir>/.devin/\r\n // config.json. MCP root key \"mcpServers\" (object map; stdio { command, args?,\r\n // env? }, remote { url, transport?, headers? }; native ${env:VAR}). Hooks\r\n // under the same file's \"hooks\" key (Claude-compatible NESTED-rule shape; reply\r\n // is the SIMPLE top-level {decision:\"approve\"|\"block\"|\"deny\", reason}). Distinct\r\n // ~/.config/devin / .devin marker — no fork-ordering constraint.\r\n {\r\n id: \"devin\",\r\n load: () => import(\"./devin/index.js\").then((m) => m.default),\r\n },\r\n // Open Interpreter (the new Rust `interpreter` / `i` CLI) — mcp-only. It is a\r\n // FORK of OpenAI's Codex (README: \"Open Interpreter is a fork of OpenAI's\r\n // Codex\"), so its native config is Codex's: a TOML `config.toml` carrying\r\n // `[mcp_servers.<id>]` tables (command/args/env stdio; url/bearer_token_env_var/\r\n // http_headers streamable-HTTP). The config home is DELIBERATELY isolated from\r\n // Codex — the `interpreter` binary honors ONLY `$INTERPRETER_HOME` (NOT\r\n // `$CODEX_HOME`, which it explicitly ignores) and defaults to ~/.openinterpreter\r\n // (codex-rs/utils/home-dir/src/lib.rs). That distinct dir means there is NO\r\n // fork-ordering constraint vs codex — the two never target the same file — so\r\n // it simply sits at the end of the registry. Kept mcp-only (the codex hook\r\n // subsystem is present in the fork, but the `interpreter` product's live hook\r\n // wire contract is not first-party-verified, so hooks are not claimed).\r\n {\r\n id: \"open-interpreter\",\r\n load: () => import(\"./open-interpreter/index.js\").then((m) => m.default),\r\n },\r\n // Junie (JetBrains' OWN LLM-agnostic coding agent — DISTINCT from\r\n // jetbrains-copilot, which is GitHub Copilot in JetBrains IDEs) — mcp-only.\r\n // The `junie` CLI (npm @jetbrains/junie, github.com/JetBrains/junie) shares its\r\n // MCP JSON config with Junie in JetBrains IDEs: object map \"mcpServers\" at\r\n // <projectDir>/.junie/mcp/mcp.json (project) and ~/.junie/mcp/mcp.json (user);\r\n // stdio { command, args?, env? }, remote { url, headers? }. No documented\r\n // user-installable hook surface → mcp-only. Distinct ~/.junie marker — no\r\n // fork-ordering constraint vs any sibling.\r\n {\r\n id: \"junie\",\r\n load: () => import(\"./junie/index.js\").then((m) => m.default),\r\n },\r\n // mistral-vibe is Mistral's coding-agent CLI — an mcp-only host. MCP config is\r\n // TOML at <projectDir>/.vibe/config.toml (project, precedence) → ~/.vibe/\r\n // config.toml (user); root key `mcp_servers` is a TOML ARRAY-OF-TABLES\r\n // ([[mcp_servers]], each entry carries a `name` short alias — distinct from\r\n // codex's table-keyed [mcp_servers.<name>]). Distinct ~/.vibe / .vibe marker —\r\n // no fork-ordering constraint.\r\n {\r\n id: \"mistral-vibe\",\r\n load: () => import(\"./mistral-vibe/index.js\").then((m) => m.default),\r\n },\r\n];\r\n\r\n/** O(1) lookup index, built once at module-load time. */\r\nconst REGISTRY_BY_ID: ReadonlyMap<PlatformId, AdapterFactory> = new Map(\r\n ADAPTER_REGISTRY.map((factory) => [factory.id, factory] as const),\r\n);\r\n\r\n/** Every platform id present in the registry (useful for matrix tests). */\r\nexport const REGISTERED_PLATFORM_IDS: ReadonlySet<PlatformId> = new Set(\r\n ADAPTER_REGISTRY.map((factory) => factory.id),\r\n);\r\n\r\n/**\r\n * Look up the lazy factory for a platform id. Returns `undefined` for ids that\r\n * are not registered (including `\"unknown\"` and typos) so callers can fall back\r\n * deliberately rather than crash.\r\n */\r\nexport function getFactory(id: PlatformId | string): AdapterFactory | undefined {\r\n return REGISTRY_BY_ID.get(id as PlatformId);\r\n}\r\n\r\n/**\r\n * Resolve a platform id to its adapter singleton. Returns `undefined` when the\r\n * id is not registered — callers decide whether to skip or fall back.\r\n */\r\nexport async function loadAdapter(id: PlatformId | string): Promise<Adapter | undefined> {\r\n const factory = getFactory(id);\r\n return factory ? factory.load() : undefined;\r\n}\r\n\r\n/**\r\n * Load every registered adapter. Imports run in parallel; the result preserves\r\n * registry order so downstream detection/install logic sees forks before\r\n * parents.\r\n */\r\nexport async function allAdapters(): Promise<Adapter[]> {\r\n return Promise.all(ADAPTER_REGISTRY.map((factory) => factory.load()));\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/claude-code/wire.ts"],"sourcesContent":["/**\r\n * adapters/claude-code/wire — Claude Code hook wire protocol.\r\n *\r\n * Claude Code pipes a JSON object to a hook command on stdin and reads a JSON\r\n * object (or empty) from stdout, interpreting the exit code as well. This module\r\n * captures the exact stdin shape and the canonical reply shape so the adapter's\r\n * parse/format methods are a single source of truth.\r\n *\r\n * Stdin (documented Claude Code hook input):\r\n * {\r\n * session_id, transcript_path, cwd, hook_event_name,\r\n * tool_name, tool_input, tool_response, // tool events\r\n * permission_suggestions, // PermissionRequest\r\n * tool_use_id, error, is_interrupt, duration_ms, // PostToolUseFailure\r\n * agent_id, agent_type, // SubagentStart/Stop\r\n * agent_transcript_path, last_assistant_message, // SubagentStop\r\n * source, // SessionStart\r\n * reason, // SessionEnd\r\n * prompt, // UserPromptSubmit\r\n * trigger, // PreCompact\r\n * stop_hook_active, // Stop / SubagentStop\r\n * message // Notification\r\n * }\r\n *\r\n * Stdout (canonical reply): a `hookSpecificOutput` object keyed by\r\n * `hookEventName`, carrying `permissionDecision` (allow|deny|ask) +\r\n * `permissionDecisionReason`, `additionalContext`, and (PreToolUse)\r\n * `updatedInput`; PermissionRequest instead takes a nested\r\n * `decision: { behavior: \"allow\"|\"deny\", ... }`; Stop-class blocks\r\n * (Stop / SubagentStop / UserPromptSubmit / PostToolUse) take the TOP-LEVEL\r\n * `{\"decision\":\"block\",\"reason\"}`. Exit 0 = proceed; the JSON refines the\r\n * decision.\r\n */\r\n\r\nimport type { SessionStartEvent } from \"../../core/types.js\";\r\n\r\n/** Canonical Claude Code hook event names (the values of `hook_event_name`). */\r\nexport const CLAUDE_HOOK_EVENTS = [\r\n \"PreToolUse\",\r\n \"PostToolUse\",\r\n \"PreCompact\",\r\n \"SessionStart\",\r\n \"SessionEnd\",\r\n \"UserPromptSubmit\",\r\n \"Stop\",\r\n \"Notification\",\r\n \"PermissionRequest\",\r\n \"PostToolUseFailure\",\r\n \"SubagentStart\",\r\n \"SubagentStop\",\r\n] as const;\r\n\r\nexport type ClaudeHookEvent = (typeof CLAUDE_HOOK_EVENTS)[number];\r\n\r\n/**\r\n * Raw Claude Code hook stdin payload. Every field is optional — a given event\r\n * only populates the subset relevant to it. `connector` is NOT a Claude field;\r\n * it is threaded in by the universal entrypoint so parseEvent can recover the\r\n * connector id (the home binary passes `--connector <id>` and may inject it).\r\n */\r\nexport interface ClaudeWireInput {\r\n session_id?: string;\r\n transcript_path?: string;\r\n cwd?: string;\r\n hook_event_name?: string;\r\n\r\n // tool events\r\n tool_name?: string;\r\n tool_input?: Record<string, unknown>;\r\n /** PostToolUse result payload (string or structured). */\r\n tool_response?: unknown;\r\n\r\n // PermissionRequest — permission-update entries the dialog would offer.\r\n // NOTE: the docs explicitly state PermissionRequest has NO tool_use_id.\r\n permission_suggestions?: unknown[];\r\n\r\n // PostToolUseFailure\r\n tool_use_id?: string;\r\n error?: string;\r\n is_interrupt?: boolean;\r\n duration_ms?: number;\r\n\r\n // SubagentStart / SubagentStop — agent_type is unreliable on SubagentStop\r\n // (the SDK may not populate it); treat both as optional everywhere.\r\n agent_id?: string;\r\n agent_type?: string;\r\n // SubagentStop — the subagent's OWN transcript (transcript_path stays the\r\n // parent session's) + the text of its final response.\r\n agent_transcript_path?: string;\r\n last_assistant_message?: string;\r\n\r\n // SessionStart\r\n source?: string;\r\n // SessionEnd\r\n reason?: string;\r\n // UserPromptSubmit\r\n prompt?: string;\r\n // PreCompact\r\n trigger?: string;\r\n // Stop / SubagentStop\r\n stop_hook_active?: boolean;\r\n // Notification\r\n message?: string;\r\n\r\n /** Injected by the entrypoint so the runtime knows which connector to dispatch. */\r\n connector?: string;\r\n}\r\n\r\n/**\r\n * Extract a stable session id from a Claude wire payload.\r\n * Priority mirrors the proven adapter: transcript UUID > session_id > \"\".\r\n * (The framework's normalized event uses \"\" when no id is available, per\r\n * core/types BaseEvent.sessionId docstring — no ppid fabrication here.)\r\n */\r\nexport function extractSessionId(input: ClaudeWireInput): string {\r\n if (typeof input.transcript_path === \"string\") {\r\n const m = input.transcript_path.match(/([a-f0-9-]{36})\\.jsonl$/);\r\n if (m && m[1]) return m[1];\r\n }\r\n if (typeof input.session_id === \"string\" && input.session_id !== \"\") {\r\n return input.session_id;\r\n }\r\n return \"\";\r\n}\r\n\r\n/** Coerce a Claude PostToolUse `tool_response` into a string for the normalized event. */\r\nexport function toolResponseToString(value: unknown): string | undefined {\r\n if (value == null) return undefined;\r\n if (typeof value === \"string\") return value;\r\n try {\r\n return JSON.stringify(value);\r\n } catch {\r\n return String(value);\r\n }\r\n}\r\n\r\n/** Map a host's raw session-start \"source\" to the canonical SessionStart source. */\r\nexport function normalizeSessionSource(source: string | undefined): SessionStartEvent[\"source\"] {\r\n switch (source) {\r\n case \"compact\":\r\n return \"compact\";\r\n case \"resume\":\r\n return \"resume\";\r\n case \"clear\":\r\n return \"clear\";\r\n default:\r\n return \"startup\";\r\n }\r\n}\r\n"],"mappings":";;;AAkHO,SAAS,iBAAiB,OAAgC;AAC/D,MAAI,OAAO,MAAM,oBAAoB,UAAU;AAC7C,UAAM,IAAI,MAAM,gBAAgB,MAAM,yBAAyB;AAC/D,QAAI,KAAK,EAAE,CAAC,EAAG,QAAO,EAAE,CAAC;AAAA,EAC3B;AACA,MAAI,OAAO,MAAM,eAAe,YAAY,MAAM,eAAe,IAAI;AACnE,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;AAGO,SAAS,qBAAqB,OAAoC;AACvE,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACF,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAGO,SAAS,uBAAuB,QAAyD;AAC9F,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/ts-plugin-bridge.ts"],"sourcesContent":["/**\r\n * Pure string-builder for the byte-identical HEAD of every ts-plugin host's\r\n * generated plugin module: the `HOME_BIN`/`CONNECTOR_ID` consts plus the\r\n * cross-OS `bridge(event, payload)` entrypoint (win32 `execSync`-quoted vs\r\n * POSIX `execFileSync`, fail-open `JSON.parse`).\r\n *\r\n * This module emits SOURCE TEXT only — it imports nothing at runtime and is\r\n * never loaded by a generated plugin. The 6 adopting hosts (amp, kilo,\r\n * kilo-cli, mimo-code, omp, opencode) differ in this region by exactly four\r\n * host-specific tokens, captured below. Changing the emitted bytes here changes\r\n * every host's generated plugin in lockstep; each host's adapter suite runs the\r\n * generated plugin live and asserts source substrings, so it is the byte oracle.\r\n */\r\n\r\nexport interface BridgePreludeOptions {\r\n /** Absolute home-bin path (raw — JSON.stringified inside). */\r\n homeBin: string;\r\n /** Connector id (raw — JSON.stringified inside). */\r\n connectorId: string;\r\n /** Host hook subcommand slug used in the `hook <slug>` argv (e.g. \"opencode\", \"amp\"). */\r\n hookSlug: string;\r\n /** Host noun for the jsdoc `@param payload <noun>-shaped …` line (e.g. \"OpenCode\", \"amp\", \"OMP\"). */\r\n payloadNoun: string;\r\n /** Optional suffix on the jsdoc `@param event canonical event name<eventDoc>` line (e.g. \" (PreToolUse|PostToolUse|SessionStart)\"). Default \"\". */\r\n eventDoc?: string;\r\n /** The exact fail-open catch-comment line (host wording differs). */\r\n failOpenComment: string;\r\n}\r\n\r\n/**\r\n * Render the HOME_BIN/CONNECTOR_ID consts + the universal-entrypoint bridge() —\r\n * the byte-identical head of every ts-plugin host's generated plugin module.\r\n */\r\nexport function renderBridgePrelude(opts: BridgePreludeOptions): string {\r\n return `const HOME_BIN = ${JSON.stringify(opts.homeBin)};\r\nconst CONNECTOR_ID = ${JSON.stringify(opts.connectorId)};\r\n\r\n/**\r\n * Invoke the universal hook entrypoint for one event.\r\n * @param {string} event canonical event name${opts.eventDoc ?? \"\"}\r\n * @param {object} payload ${opts.payloadNoun}-shaped payload posted on stdin\r\n * @returns {object|null} normalized HookResponse, or null on any failure\r\n */\r\nfunction bridge(event, payload) {\r\n try {\r\n // On Windows HOME_BIN is the agent-connector.cmd launcher: Node cannot\r\n // execFile a batch file, and shell+args is deprecated (DEP0190), so run one\r\n // quoted command line via a shell. POSIX keeps the direct execFile (no shell).\r\n const args = [\"hook\", ${JSON.stringify(opts.hookSlug)}, event, \"--connector\", CONNECTOR_ID];\r\n const opts = { input: JSON.stringify(payload), encoding: \"utf8\" };\r\n const stdout =\r\n process.platform === \"win32\"\r\n ? execSync([HOME_BIN, ...args].map((a) => '\"' + a + '\"').join(\" \"), opts)\r\n : execFileSync(HOME_BIN, args, opts);\r\n const text = (stdout || \"\").trim();\r\n if (text === \"\") return { decision: \"allow\" };\r\n return JSON.parse(text);\r\n } catch {\r\n // ${opts.failOpenComment}\r\n return null;\r\n }\r\n}`;\r\n}\r\n"],"mappings":";;;AAiCO,SAAS,oBAAoB,MAAoC;AACtE,SAAO,oBAAoB,KAAK,UAAU,KAAK,OAAO,CAAC;AAAA,uBAClC,KAAK,UAAU,KAAK,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA,+CAIR,KAAK,YAAY,EAAE;AAAA,6BACrC,KAAK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAQjB,KAAK,UAAU,KAAK,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAUhD,KAAK,eAAe;AAAA;AAAA;AAAA;AAI7B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/telemetry/surface-footprint.ts","../src/telemetry/leaderboard.ts"],"sourcesContent":["/**\r\n * telemetry/surface-footprint — the STATIC developer-axis surfaces.\r\n *\r\n * Commands, skills, and subagents are NOT runtime-intercepted: the host loads\r\n * them as context (slash-command bodies, SKILL.md + resources, subagent system\r\n * prompts) and we never sit in the byte path the way the serve-proxy does for a\r\n * server or the hook runtime does for a hook. So we do NOT (and must not) write\r\n * fake usage rows for them. Instead we compute a deterministic STATIC FOOTPRINT:\r\n * the token cost the surface IMPOSES on a host that loads it, tokenized with the\r\n * SAME shared tokenizer the proxy + hook runtime use.\r\n *\r\n * This is pure: the only input is the passed {@link ResolvedConnector}; there is\r\n * no IO beyond reading that object's already-loaded fields.\r\n */\r\n\r\nimport type { ResolvedConnector } from \"../core/types.js\";\r\nimport { getTokenizer, inferModelFamily } from \"./tokenizer.js\";\r\nimport type { ModelFamily, SurfaceKind, Tokenizer } from \"./types.js\";\r\n\r\n/**\r\n * One static surface footprint: a content surface (command/skill/subagent) and\r\n * the token cost it imposes on a host that loads it. `kind` is the surface kind\r\n * (never `server`/`hook` — those are runtime-measured), `name` is the surface's\r\n * declared name, and `tokens` is the tokenized whole-surface footprint.\r\n */\r\nexport interface SurfaceFootprint {\r\n surfaceKind: Extract<SurfaceKind, \"command\" | \"skill\" | \"subagent\">;\r\n name: string;\r\n tokens: number;\r\n}\r\n\r\n/** Tokenize a list of text fragments (joined with \"\\n\") under `family`. */\r\nfunction countParts(\r\n parts: readonly string[],\r\n family: ModelFamily,\r\n tok: Tokenizer,\r\n): number {\r\n // A surface's footprint is its concatenated content — joining with a newline\r\n // mirrors how the host renders the fields together as one context blob.\r\n return tok.count(parts.join(\"\\n\"), family).tokens;\r\n}\r\n\r\n/**\r\n * Compute the STATIC footprints of every content surface declared on a\r\n * connector, deterministically (same input → same output) and without IO.\r\n *\r\n * • command → description + prompt + argumentHint\r\n * • skill → description + body + every resource value (sorted by path for\r\n * deterministic ordering, so the joined text is stable)\r\n * • subagent → description + prompt\r\n *\r\n * The shared {@link Tokenizer} is used so a command/skill/subagent footprint is\r\n * directly comparable with the runtime `server`/`hook` token counts. The model\r\n * family is inferred from the connector's telemetry hint (no host context here).\r\n */\r\nexport function computeSurfaceFootprints(\r\n connector: ResolvedConnector,\r\n tok: Tokenizer = getTokenizer(),\r\n): SurfaceFootprint[] {\r\n const family = inferModelFamily(\"\", connector.telemetry.modelFamilyHint);\r\n const out: SurfaceFootprint[] = [];\r\n\r\n for (const cmd of connector.commands) {\r\n const parts: string[] = [];\r\n if (cmd.description !== undefined) parts.push(cmd.description);\r\n parts.push(cmd.prompt);\r\n if (cmd.argumentHint !== undefined) parts.push(cmd.argumentHint);\r\n out.push({\r\n surfaceKind: \"command\",\r\n name: cmd.name,\r\n tokens: countParts(parts, family, tok),\r\n });\r\n }\r\n\r\n for (const skill of connector.skills) {\r\n const parts: string[] = [skill.description, skill.body];\r\n if (skill.resources !== undefined) {\r\n // Sort by resource path so the joined text (and thus the count) is stable\r\n // regardless of object key insertion order.\r\n const paths = Object.keys(skill.resources).sort();\r\n for (const p of paths) {\r\n const value = skill.resources[p];\r\n if (value !== undefined) parts.push(value);\r\n }\r\n }\r\n out.push({\r\n surfaceKind: \"skill\",\r\n name: skill.name,\r\n tokens: countParts(parts, family, tok),\r\n });\r\n }\r\n\r\n for (const agent of connector.subagents) {\r\n out.push({\r\n surfaceKind: \"subagent\",\r\n name: agent.name,\r\n tokens: countParts([agent.description, agent.prompt], family, tok),\r\n });\r\n }\r\n\r\n return out;\r\n}\r\n","/**\r\n * telemetry/leaderboard — the PLUGIN / MCP leaderboard, derived from the per-MCP\r\n * serve-proxy telemetry store (src/telemetry/*).\r\n *\r\n * This is the signature MCP-dev metric: of the MCP servers WE wrap, which one\r\n * costs the most tokens — platform-independent, because it measures the server's\r\n * OWN bytes (tool args in, tool result out, tool-defs schemas) tokenized locally,\r\n * the only signal identical across every host. Origin is always `mcp-self`; it is\r\n * NEVER summed with host-native usage (src/usage/*), which measures a different\r\n * thing (whole-conversation tokens).\r\n *\r\n * Pure aggregation + pure formatting over {@link TelemetryStore.query}. The scope\r\n * dimension (installScope/launchMethod) is OPTIONAL on each row — rows written\r\n * before those fields existed are read as \"unknown\" and are honestly labeled.\r\n */\r\n\r\nimport type { ResolvedConnector } from \"../core/types.js\";\r\nimport { openStore } from \"./store.js\";\r\nimport { computeSurfaceFootprints } from \"./surface-footprint.js\";\r\nimport { worstConfidence } from \"./types.js\";\r\nimport type {\r\n ConfidenceSource,\r\n LaunchMethod,\r\n QueryFilter,\r\n SurfaceKind,\r\n TelemetryInstallScope,\r\n TelemetryStore,\r\n ToolEventRecord,\r\n} from \"./types.js\";\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Options + scope filter\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * A scope filter value the leaderboards accept. The two install buckets\r\n * (`user`/`project`) and the launch methods (`npx`/`bunx`/`uvx`/`node`/`binary`/\r\n * `http`) plus the honest `unknown` fallback. A record matches a `user`/`project`\r\n * value by its `installScope`, and a launch-method value by its `launchMethod`.\r\n */\r\nexport type ScopeFilter =\r\n | TelemetryInstallScope\r\n | LaunchMethod;\r\n\r\n/** Every accepted {@link ScopeFilter} string, for CLI validation. */\r\nexport const SCOPE_FILTER_VALUES: readonly ScopeFilter[] = [\r\n \"user\",\r\n \"project\",\r\n \"npx\",\r\n \"bunx\",\r\n \"uvx\",\r\n \"node\",\r\n \"binary\",\r\n \"http\",\r\n \"unknown\",\r\n] as const;\r\n\r\n/** Options shared by every leaderboard query. */\r\nexport interface LeaderboardOptions {\r\n /** An open store to read from. Defaults to {@link openStore} on the data-root. */\r\n store?: TelemetryStore;\r\n /** Lower-bound epoch ms (inclusive) — forwarded as the store's sinceMs filter. */\r\n sinceMs?: number;\r\n /** Restrict to one connector. */\r\n connectorId?: string;\r\n /** Slice by install scope (user|project) or launch method (npx|binary|http|…). */\r\n scope?: ScopeFilter;\r\n}\r\n\r\n/** Is `value` one of the accepted scope-filter strings? */\r\nexport function isScopeFilter(value: string): value is ScopeFilter {\r\n return (SCOPE_FILTER_VALUES as readonly string[]).includes(value);\r\n}\r\n\r\n/** The install/launch values a `user`/`project` scope filter matches against. */\r\nconst INSTALL_SCOPES: ReadonlySet<string> = new Set<string>([\"user\", \"project\"]);\r\n\r\n/**\r\n * Does a record satisfy the requested scope slice? `user`/`project` match the\r\n * record's `installScope`; any concrete launch method matches the record's\r\n * `launchMethod`. The honest `unknown` filter is special: it matches ONLY a\r\n * record that lacks BOTH dimensions (a truly pre-scope row) — a record carrying\r\n * a known installScope but no launchMethod (or vice-versa) is NOT \"unknown\" and\r\n * must not be swept into that bucket.\r\n */\r\nfunction matchesScope(record: ToolEventRecord, scope: ScopeFilter): boolean {\r\n if (scope === \"unknown\") {\r\n return record.installScope === undefined && record.launchMethod === undefined;\r\n }\r\n if (INSTALL_SCOPES.has(scope)) {\r\n return record.installScope === scope;\r\n }\r\n return record.launchMethod === scope;\r\n}\r\n\r\n/** Build the store {@link QueryFilter} from the shared options. */\r\nfunction toFilter(opts: LeaderboardOptions): QueryFilter {\r\n const filter: QueryFilter = {};\r\n if (opts.sinceMs !== undefined) filter.sinceMs = opts.sinceMs;\r\n if (opts.connectorId !== undefined && opts.connectorId !== \"\") {\r\n filter.connectorId = opts.connectorId;\r\n }\r\n return filter;\r\n}\r\n\r\n/**\r\n * Query the store and apply the (in-memory) scope slice the store cannot. By\r\n * default EXCLUDES the host-native `model_turn` rows: this selector feeds the\r\n * per-MCP/plugin views (mcp/tool/scope), which measure per-MCP `call` + the\r\n * `tool_defs` overhead and must NEVER sum the whole-conversation host-native\r\n * turns. Pass `includeModelTurn: true` to read those rows instead (used by\r\n * {@link hostNativeTurns}).\r\n */\r\nfunction selectRecords(\r\n opts: LeaderboardOptions,\r\n includeModelTurn = false,\r\n): ToolEventRecord[] {\r\n const store = opts.store ?? openStore({});\r\n const owned = opts.store === undefined;\r\n try {\r\n let rows = store.query(toFilter(opts));\r\n rows = includeModelTurn\r\n ? rows.filter((r) => r.scope === \"model_turn\")\r\n : rows.filter((r) => r.scope !== \"model_turn\");\r\n if (opts.scope === undefined) return rows;\r\n const scope = opts.scope;\r\n return rows.filter((r) => matchesScope(r, scope));\r\n } finally {\r\n if (owned) store.close();\r\n }\r\n}\r\n\r\n// Confidence ranking + worst-of comparison live in ./types (the single source\r\n// of truth, imported as worstConfidence above) so a new ConfidenceSource value\r\n// orders correctly here as well.\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Leaderboard rows\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * One row of the MCP/plugin leaderboard — a connector ranked by total measured\r\n * tokens. `tools` is the count of distinct tool names seen (excluding the\r\n * tool-defs `*` pseudo-tool); `hostPlatforms` is the distinct set of hosts that\r\n * ran this server, evidence that the count aggregates across machines.\r\n */\r\nexport interface McpLeaderboardRow {\r\n connectorId: string;\r\n calls: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n /** Count of distinct real tool names (the tool-defs `*` row is excluded). */\r\n tools: number;\r\n /** Distinct host platforms that produced records, sorted for stable output. */\r\n hostPlatforms: string[];\r\n /** Worst (least-confident) source in the group, for honest labeling. */\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/**\r\n * One row of the per-tool leaderboard — a (connector, tool) pair ranked by total\r\n * measured tokens. The tool-defs pseudo-tool (`*`, scope `tool_defs`) is kept as\r\n * its own row so the fixed schema overhead is visible rather than hidden.\r\n */\r\nexport interface ToolLeaderboardRow {\r\n connectorId: string;\r\n toolName: string;\r\n /** \"call\" round-trips vs the one-time \"tool_defs\" overhead measurement. */\r\n scope: ToolEventRecord[\"scope\"];\r\n calls: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/**\r\n * One row of the scope breakdown — usage grouped by (installScope, launchMethod),\r\n * both honestly reported as \"unknown\" when the underlying record lacks the field.\r\n */\r\nexport interface ScopeBreakdownRow {\r\n installScope: TelemetryInstallScope | \"unknown\";\r\n launchMethod: LaunchMethod;\r\n calls: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/**\r\n * One row of the host-native turns aggregation — a (host, session) pair ranked by\r\n * total host-reported tokens for that whole-conversation turn stream. This is the\r\n * THIRD origin (`host-native-live`): it comes from the opt-in AfterModel /\r\n * PostInvocation usage hook (scope `model_turn`, confidence `host-native`) and is\r\n * NEVER summed with the per-MCP `call` rows or the usage-reader host-scan numbers.\r\n */\r\nexport interface HostNativeTurnsRow {\r\n hostPlatform: string;\r\n sessionId: string;\r\n /** Number of recorded model turns (scope `model_turn` rows) in this group. */\r\n turns: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n /** Distinct connector ids that produced turns under this host/session. */\r\n connectors: string[];\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/** Mutable accumulator for the host-native turns fold (set finalized to count). */\r\ninterface HostNativeAcc {\r\n hostPlatform: string;\r\n sessionId: string;\r\n turns: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n connectors: Set<string>;\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/** Mutable accumulator for the MCP leaderboard fold (sets finalized to counts). */\r\ninterface McpAcc {\r\n connectorId: string;\r\n calls: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n tools: Set<string>;\r\n hostPlatforms: Set<string>;\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/**\r\n * The PLUGIN / MCP leaderboard: rank connectors by total measured tokens desc\r\n * (ties broken by recency). This is the headline \"which MCP server costs the\r\n * most\" metric, platform-independent by construction.\r\n */\r\nexport function mcpLeaderboard(opts: LeaderboardOptions = {}): McpLeaderboardRow[] {\r\n const groups = new Map<string, McpAcc>();\r\n\r\n for (const r of selectRecords(opts)) {\r\n let g = groups.get(r.connectorId);\r\n if (g === undefined) {\r\n g = {\r\n connectorId: r.connectorId,\r\n calls: 0,\r\n inputTokens: 0,\r\n outputTokens: 0,\r\n totalTokens: 0,\r\n tools: new Set<string>(),\r\n hostPlatforms: new Set<string>(),\r\n confidence: r.confidenceSource,\r\n lastTs: r.ts,\r\n };\r\n groups.set(r.connectorId, g);\r\n }\r\n // A tool_defs row is a one-time schema overhead, not a call: count its\r\n // tokens but do not inflate the call count or the distinct-tool count.\r\n if (r.scope === \"call\") {\r\n g.calls += 1;\r\n g.tools.add(r.toolName);\r\n }\r\n g.inputTokens += r.inputTokens;\r\n g.outputTokens += r.outputTokens;\r\n g.totalTokens += r.inputTokens + r.outputTokens;\r\n g.hostPlatforms.add(r.hostPlatform);\r\n g.confidence = worstConfidence(g.confidence, r.confidenceSource);\r\n if (r.ts > g.lastTs) g.lastTs = r.ts;\r\n }\r\n\r\n const rows: McpLeaderboardRow[] = [];\r\n for (const g of groups.values()) {\r\n rows.push({\r\n connectorId: g.connectorId,\r\n calls: g.calls,\r\n inputTokens: g.inputTokens,\r\n outputTokens: g.outputTokens,\r\n totalTokens: g.totalTokens,\r\n tools: g.tools.size,\r\n hostPlatforms: [...g.hostPlatforms].sort(),\r\n confidence: g.confidence,\r\n lastTs: g.lastTs,\r\n });\r\n }\r\n rows.sort((a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs);\r\n return rows;\r\n}\r\n\r\n/**\r\n * The per-tool leaderboard: rank (connector, tool) pairs by total tokens desc\r\n * (ties broken by recency). Drills the MCP leaderboard down to which individual\r\n * tool is the expensive one.\r\n */\r\nexport function toolLeaderboard(opts: LeaderboardOptions = {}): ToolLeaderboardRow[] {\r\n const groups = new Map<string, ToolLeaderboardRow>();\r\n\r\n for (const r of selectRecords(opts)) {\r\n const key = `${r.connectorId}\\u0000${r.toolName}\\u0000${r.scope}`;\r\n const g = groups.get(key);\r\n if (g === undefined) {\r\n groups.set(key, {\r\n connectorId: r.connectorId,\r\n toolName: r.toolName,\r\n scope: r.scope,\r\n calls: r.scope === \"call\" ? 1 : 0,\r\n inputTokens: r.inputTokens,\r\n outputTokens: r.outputTokens,\r\n totalTokens: r.inputTokens + r.outputTokens,\r\n confidence: r.confidenceSource,\r\n lastTs: r.ts,\r\n });\r\n } else {\r\n if (r.scope === \"call\") g.calls += 1;\r\n g.inputTokens += r.inputTokens;\r\n g.outputTokens += r.outputTokens;\r\n g.totalTokens += r.inputTokens + r.outputTokens;\r\n g.confidence = worstConfidence(g.confidence, r.confidenceSource);\r\n if (r.ts > g.lastTs) g.lastTs = r.ts;\r\n }\r\n }\r\n\r\n const rows = [...groups.values()];\r\n rows.sort((a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs);\r\n return rows;\r\n}\r\n\r\n/**\r\n * The scope breakdown: group usage by (installScope, launchMethod). Both\r\n * dimensions read \"unknown\" when the source row lacks the field, so a pre-scope\r\n * row is honestly bucketed rather than dropped or mis-attributed.\r\n */\r\nexport function scopeBreakdown(opts: LeaderboardOptions = {}): ScopeBreakdownRow[] {\r\n const groups = new Map<string, ScopeBreakdownRow>();\r\n\r\n for (const r of selectRecords(opts)) {\r\n const installScope: TelemetryInstallScope | \"unknown\" = r.installScope ?? \"unknown\";\r\n const launchMethod: LaunchMethod = r.launchMethod ?? \"unknown\";\r\n const key = `${installScope}\\u0000${launchMethod}`;\r\n const g = groups.get(key);\r\n if (g === undefined) {\r\n groups.set(key, {\r\n installScope,\r\n launchMethod,\r\n calls: r.scope === \"call\" ? 1 : 0,\r\n inputTokens: r.inputTokens,\r\n outputTokens: r.outputTokens,\r\n totalTokens: r.inputTokens + r.outputTokens,\r\n confidence: r.confidenceSource,\r\n lastTs: r.ts,\r\n });\r\n } else {\r\n if (r.scope === \"call\") g.calls += 1;\r\n g.inputTokens += r.inputTokens;\r\n g.outputTokens += r.outputTokens;\r\n g.totalTokens += r.inputTokens + r.outputTokens;\r\n g.confidence = worstConfidence(g.confidence, r.confidenceSource);\r\n if (r.ts > g.lastTs) g.lastTs = r.ts;\r\n }\r\n }\r\n\r\n const rows = [...groups.values()];\r\n rows.sort((a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs);\r\n return rows;\r\n}\r\n\r\n/**\r\n * The THIRD origin: host-native turns. Aggregates ONLY the `model_turn` rows (the\r\n * opt-in AfterModel / PostInvocation host-native usage hook) by (host, session),\r\n * ranked by total host-reported tokens desc. This is whole-conversation usage the\r\n * host itself reported — exact, but a DIFFERENT thing than the per-MCP `call`\r\n * rows; it is surfaced separately and NEVER summed with the other two origins.\r\n */\r\nexport function hostNativeTurns(opts: LeaderboardOptions = {}): HostNativeTurnsRow[] {\r\n const groups = new Map<string, HostNativeAcc>();\r\n\r\n for (const r of selectRecords(opts, /* includeModelTurn */ true)) {\r\n const key = `${r.hostPlatform}\\u0000${r.sessionId}`;\r\n let g = groups.get(key);\r\n if (g === undefined) {\r\n g = {\r\n hostPlatform: r.hostPlatform,\r\n sessionId: r.sessionId,\r\n turns: 0,\r\n inputTokens: 0,\r\n outputTokens: 0,\r\n totalTokens: 0,\r\n connectors: new Set<string>(),\r\n confidence: r.confidenceSource,\r\n lastTs: r.ts,\r\n };\r\n groups.set(key, g);\r\n }\r\n g.turns += 1;\r\n g.inputTokens += r.inputTokens;\r\n g.outputTokens += r.outputTokens;\r\n g.totalTokens += r.inputTokens + r.outputTokens;\r\n g.connectors.add(r.connectorId);\r\n g.confidence = worstConfidence(g.confidence, r.confidenceSource);\r\n if (r.ts > g.lastTs) g.lastTs = r.ts;\r\n }\r\n\r\n const rows: HostNativeTurnsRow[] = [];\r\n for (const g of groups.values()) {\r\n rows.push({\r\n hostPlatform: g.hostPlatform,\r\n sessionId: g.sessionId,\r\n turns: g.turns,\r\n inputTokens: g.inputTokens,\r\n outputTokens: g.outputTokens,\r\n totalTokens: g.totalTokens,\r\n connectors: [...g.connectors].sort(),\r\n confidence: g.confidence,\r\n lastTs: g.lastTs,\r\n });\r\n }\r\n rows.sort((a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs);\r\n return rows;\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Per-surface leaderboard (the FIVE developer-axis surfaces)\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * One row of the per-surface developer breakdown — a (surfaceKind, name) pair.\r\n * Combines the RUNTIME-measured surfaces (server `call`+`tool_defs` rows and the\r\n * new `hook` rows from the telemetry store) with the STATIC content footprints\r\n * (command/skill/subagent) from {@link computeSurfaceFootprints}.\r\n *\r\n * • `kind` distinguishes RUNTIME (measured live) from STATIC (footprint of\r\n * context the host loads — never an intercepted usage row).\r\n * • For static rows `calls` is 0, `outputTokens` is 0, the cost sits in\r\n * `inputTokens`/`totalTokens`, and `confidence` is the tokenizer source for\r\n * the connector's family. For runtime rows everything aggregates the store.\r\n */\r\nexport interface SurfaceLeaderboardRow {\r\n surfaceKind: SurfaceKind;\r\n /** Per-item name: the tool name (server), the event name (hook), or the\r\n * command/skill/subagent name (static surfaces). */\r\n name: string;\r\n /** RUNTIME (server/hook store rows) vs STATIC (command/skill/subagent footprint). */\r\n kind: \"runtime\" | \"static\";\r\n calls: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/** Mutable accumulator for the runtime side of the per-surface fold. */\r\ninterface SurfaceAcc {\r\n surfaceKind: SurfaceKind;\r\n name: string;\r\n calls: number;\r\n inputTokens: number;\r\n outputTokens: number;\r\n totalTokens: number;\r\n confidence: ConfidenceSource;\r\n lastTs: number;\r\n}\r\n\r\n/**\r\n * A record's developer-axis surface kind, backward-compatibly. Rows written\r\n * before `surfaceKind` existed (every legacy serve-proxy `call`/`tool_defs` row)\r\n * lack it and are read as `server`; the `hook` runtime stamps it explicitly.\r\n */\r\nfunction recordSurfaceKind(r: ToolEventRecord): SurfaceKind {\r\n if (r.surfaceKind !== undefined) return r.surfaceKind;\r\n // No explicit kind → it predates this field → it is a serve-proxy server row.\r\n return \"server\";\r\n}\r\n\r\n/** Options for {@link surfaceLeaderboard}: the shared query opts + the connectors\r\n * whose STATIC footprints are folded in. */\r\nexport interface SurfaceLeaderboardOptions extends LeaderboardOptions {\r\n /** Registered connectors to compute static command/skill/subagent footprints\r\n * over. Omit/empty → only the runtime (server/hook) rows are reported. */\r\n connectors?: readonly ResolvedConnector[];\r\n}\r\n\r\n/**\r\n * The PER-SURFACE developer leaderboard across all FIVE surfaces.\r\n *\r\n * RUNTIME side: the store's `call`/`tool_defs` rows (surface `server`) and the\r\n * `hook` rows (surface `hook`), grouped by (surfaceKind, name) with IN/OUT/TOTAL\r\n * and a call count. (`model_turn` rows are excluded by `selectRecords`, exactly\r\n * as the per-MCP views exclude them.)\r\n *\r\n * STATIC side: one row per command/skill/subagent from\r\n * {@link computeSurfaceFootprints} over each passed connector, deduped by\r\n * (surfaceKind, name) and summed when the same surface is declared by more than\r\n * one connector. Static rows carry the footprint in `inputTokens` (the cost the\r\n * host pays to load that context); `outputTokens`/`calls` are 0.\r\n *\r\n * Sorted by total tokens desc, ties broken by recency (static rows have lastTs 0\r\n * so they sort after equal-token runtime rows).\r\n */\r\nexport function surfaceLeaderboard(\r\n opts: SurfaceLeaderboardOptions = {},\r\n): SurfaceLeaderboardRow[] {\r\n // ── RUNTIME: aggregate server + hook store rows by (surfaceKind, name) ──\r\n const runtime = new Map<string, SurfaceAcc>();\r\n for (const r of selectRecords(opts)) {\r\n const surfaceKind = recordSurfaceKind(r);\r\n const key = `${surfaceKind} ${r.toolName}`;\r\n let g = runtime.get(key);\r\n if (g === undefined) {\r\n g = {\r\n surfaceKind,\r\n name: r.toolName,\r\n calls: 0,\r\n inputTokens: 0,\r\n outputTokens: 0,\r\n totalTokens: 0,\r\n confidence: r.confidenceSource,\r\n lastTs: r.ts,\r\n };\r\n runtime.set(key, g);\r\n }\r\n // tool_defs is a one-time schema overhead, not a call — count tokens only.\r\n if (r.scope === \"call\" || r.scope === \"hook\") g.calls += 1;\r\n g.inputTokens += r.inputTokens;\r\n g.outputTokens += r.outputTokens;\r\n g.totalTokens += r.inputTokens + r.outputTokens;\r\n g.confidence = worstConfidence(g.confidence, r.confidenceSource);\r\n if (r.ts > g.lastTs) g.lastTs = r.ts;\r\n }\r\n\r\n const rows: SurfaceLeaderboardRow[] = [];\r\n for (const g of runtime.values()) {\r\n rows.push({\r\n surfaceKind: g.surfaceKind,\r\n name: g.name,\r\n kind: \"runtime\",\r\n calls: g.calls,\r\n inputTokens: g.inputTokens,\r\n outputTokens: g.outputTokens,\r\n totalTokens: g.totalTokens,\r\n confidence: g.confidence,\r\n lastTs: g.lastTs,\r\n });\r\n }\r\n\r\n // ── STATIC: fold in command/skill/subagent footprints per connector ──────\r\n const staticRows = new Map<\r\n string,\r\n { surfaceKind: SurfaceKind; name: string; tokens: number }\r\n >();\r\n for (const connector of opts.connectors ?? []) {\r\n for (const fp of computeSurfaceFootprints(connector)) {\r\n const key = `${fp.surfaceKind} ${fp.name}`;\r\n const existing = staticRows.get(key);\r\n if (existing === undefined) {\r\n staticRows.set(key, { surfaceKind: fp.surfaceKind, name: fp.name, tokens: fp.tokens });\r\n } else {\r\n existing.tokens += fp.tokens;\r\n }\r\n }\r\n }\r\n // A pure tokenizer footprint carries no host-reported truth — label it with the\r\n // tokenizer source the connector's family would yield. We derive that once via\r\n // a throwaway count so the static confidence is honest (approx vs exact).\r\n const staticConfidence: ConfidenceSource = staticFootprintConfidence(opts.connectors ?? []);\r\n for (const s of staticRows.values()) {\r\n rows.push({\r\n surfaceKind: s.surfaceKind,\r\n name: s.name,\r\n kind: \"static\",\r\n calls: 0,\r\n inputTokens: s.tokens,\r\n outputTokens: 0,\r\n totalTokens: s.tokens,\r\n confidence: staticConfidence,\r\n lastTs: 0,\r\n });\r\n }\r\n\r\n rows.sort((a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs);\r\n return rows;\r\n}\r\n\r\n/**\r\n * The confidence label for the static footprints: the tokenizer source for the\r\n * first connector's family (exact for openai, approx otherwise). Defaults to\r\n * `tokenizer-approx` when no connector is supplied — an honest estimate label.\r\n */\r\nfunction staticFootprintConfidence(\r\n connectors: readonly ResolvedConnector[],\r\n): ConfidenceSource {\r\n const first = connectors[0];\r\n if (first === undefined) return \"tokenizer-approx\";\r\n // openai family → exact BPE; everything else → approx. Mirrors tokenizer.bpeSource.\r\n return first.telemetry.modelFamilyHint === \"openai\"\r\n ? \"tokenizer-exact\"\r\n : \"tokenizer-approx\";\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Formatting (mirrors telemetry/report.ts: aligned table + honesty legend)\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Sources whose counts are estimates (vs real / host-reported numbers).\r\n * `tokenizer-calibrated` is still an estimate — an approximation nudged toward\r\n * truth by a sampled Anthropic count_tokens factor — so it belongs here too.\r\n */\r\nconst ESTIMATE_SOURCES: ReadonlySet<ConfidenceSource> = new Set<ConfidenceSource>([\r\n \"heuristic\",\r\n \"tokenizer-approx\",\r\n \"tokenizer-calibrated\",\r\n]);\r\n\r\n/** Compact integer formatting with thousands separators. */\r\nfunction fmtInt(n: number): string {\r\n return n.toLocaleString(\"en-US\");\r\n}\r\n\r\n/** Right-pad (left-aligned columns). */\r\nfunction padRight(s: string, width: number): string {\r\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\r\n}\r\n\r\n/** Left-pad (right-aligned numeric columns). */\r\nfunction padLeft(s: string, width: number): string {\r\n return s.length >= width ? s : \" \".repeat(width - s.length) + s;\r\n}\r\n\r\n/**\r\n * Render an aligned table given headers, the data cells, and which columns are\r\n * left-aligned (text) vs right-aligned (numbers). Adds rule lines and a TOTAL\r\n * footer. Shared by every leaderboard formatter for one consistent style.\r\n */\r\nfunction renderTable(\r\n headers: string[],\r\n dataRows: string[][],\r\n leftAlignedCols: ReadonlySet<number>,\r\n totalRow: string[],\r\n emptyMessage: string,\r\n): string[] {\r\n const widths = headers.map((h, col) => {\r\n let w = h.length;\r\n for (const row of dataRows) w = Math.max(w, (row[col] ?? \"\").length);\r\n w = Math.max(w, (totalRow[col] ?? \"\").length);\r\n return w;\r\n });\r\n\r\n const renderRow = (cells: string[]): string =>\r\n cells\r\n .map((c, col) =>\r\n leftAlignedCols.has(col)\r\n ? padRight(c, widths[col] ?? 0)\r\n : padLeft(c, widths[col] ?? 0),\r\n )\r\n .join(\" \")\r\n .trimEnd();\r\n\r\n const ruleWidth = widths.reduce((a, b) => a + b, 0) + 2 * (widths.length - 1);\r\n const rule = \"-\".repeat(ruleWidth);\r\n\r\n const lines: string[] = [];\r\n lines.push(renderRow(headers));\r\n lines.push(rule);\r\n if (dataRows.length === 0) {\r\n lines.push(emptyMessage);\r\n } else {\r\n for (const row of dataRows) lines.push(renderRow(row));\r\n }\r\n lines.push(rule);\r\n lines.push(renderRow(totalRow));\r\n return lines;\r\n}\r\n\r\n/** Append the estimate legend when any row carries an estimate confidence. */\r\nfunction appendEstimateLegend(\r\n lines: string[],\r\n confidences: ConfidenceSource[],\r\n): void {\r\n if (confidences.some((c) => ESTIMATE_SOURCES.has(c))) {\r\n lines.push(\"\");\r\n lines.push(\r\n \"note: heuristic and tokenizer-approx token counts are estimates, \" +\r\n \"not exact host-reported usage.\",\r\n );\r\n if (confidences.some((c) => c === \"tokenizer-calibrated\")) {\r\n lines.push(\r\n \"note: tokenizer-calibrated = local approx adjusted by a sampled \" +\r\n \"Anthropic count_tokens factor (opt-in; content sampled off-box only \" +\r\n \"when AGENT_CONNECTOR_CALIBRATE=anthropic).\",\r\n );\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Format the MCP/plugin leaderboard as an aligned table:\r\n * RANK | CONNECTOR | CALLS | TOOLS | IN | OUT | TOTAL | HOSTS | CONFIDENCE\r\n * sorted by total tokens desc, with a TOTAL footer and the honesty legend.\r\n */\r\nexport function formatMcpLeaderboard(rows: McpLeaderboardRow[]): string {\r\n const sorted = [...rows].sort(\r\n (a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs,\r\n );\r\n const headers = [\r\n \"RANK\",\r\n \"CONNECTOR\",\r\n \"CALLS\",\r\n \"TOOLS\",\r\n \"IN\",\r\n \"OUT\",\r\n \"TOTAL\",\r\n \"HOSTS\",\r\n \"CONFIDENCE\",\r\n ];\r\n const dataRows = sorted.map((r, i) => [\r\n `${i + 1}`,\r\n r.connectorId,\r\n fmtInt(r.calls),\r\n fmtInt(r.tools),\r\n fmtInt(r.inputTokens),\r\n fmtInt(r.outputTokens),\r\n fmtInt(r.totalTokens),\r\n r.hostPlatforms.length === 0 ? \"-\" : r.hostPlatforms.join(\",\"),\r\n r.confidence,\r\n ]);\r\n\r\n const totals = sorted.reduce(\r\n (acc, r) => {\r\n acc.calls += r.calls;\r\n acc.inputTokens += r.inputTokens;\r\n acc.outputTokens += r.outputTokens;\r\n acc.totalTokens += r.totalTokens;\r\n return acc;\r\n },\r\n { calls: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 },\r\n );\r\n const totalRow = [\r\n \"\",\r\n \"TOTAL\",\r\n fmtInt(totals.calls),\r\n \"\",\r\n fmtInt(totals.inputTokens),\r\n fmtInt(totals.outputTokens),\r\n fmtInt(totals.totalTokens),\r\n \"\",\r\n \"\",\r\n ];\r\n\r\n // Left-align RANK (0), CONNECTOR (1), HOSTS (7), CONFIDENCE (8); numbers right.\r\n const leftCols = new Set<number>([0, 1, 7, 8]);\r\n const lines = renderTable(\r\n headers,\r\n dataRows,\r\n leftCols,\r\n totalRow,\r\n \"(no MCP telemetry recorded)\",\r\n );\r\n appendEstimateLegend(\r\n lines,\r\n sorted.map((r) => r.confidence),\r\n );\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Format the per-tool leaderboard:\r\n * RANK | CONNECTOR | TOOL | SCOPE | CALLS | IN | OUT | TOTAL | CONFIDENCE\r\n * sorted by total tokens desc, with a TOTAL footer and the honesty legend.\r\n */\r\nexport function formatToolLeaderboard(rows: ToolLeaderboardRow[]): string {\r\n const sorted = [...rows].sort(\r\n (a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs,\r\n );\r\n const headers = [\r\n \"RANK\",\r\n \"CONNECTOR\",\r\n \"TOOL\",\r\n \"SCOPE\",\r\n \"CALLS\",\r\n \"IN\",\r\n \"OUT\",\r\n \"TOTAL\",\r\n \"CONFIDENCE\",\r\n ];\r\n const dataRows = sorted.map((r, i) => [\r\n `${i + 1}`,\r\n r.connectorId,\r\n r.toolName,\r\n r.scope,\r\n fmtInt(r.calls),\r\n fmtInt(r.inputTokens),\r\n fmtInt(r.outputTokens),\r\n fmtInt(r.totalTokens),\r\n r.confidence,\r\n ]);\r\n\r\n const totals = sorted.reduce(\r\n (acc, r) => {\r\n acc.calls += r.calls;\r\n acc.inputTokens += r.inputTokens;\r\n acc.outputTokens += r.outputTokens;\r\n acc.totalTokens += r.totalTokens;\r\n return acc;\r\n },\r\n { calls: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 },\r\n );\r\n const totalRow = [\r\n \"\",\r\n \"TOTAL\",\r\n \"\",\r\n \"\",\r\n fmtInt(totals.calls),\r\n fmtInt(totals.inputTokens),\r\n fmtInt(totals.outputTokens),\r\n fmtInt(totals.totalTokens),\r\n \"\",\r\n ];\r\n\r\n // Left-align RANK (0), CONNECTOR (1), TOOL (2), SCOPE (3), CONFIDENCE (8).\r\n const leftCols = new Set<number>([0, 1, 2, 3, 8]);\r\n const lines = renderTable(\r\n headers,\r\n dataRows,\r\n leftCols,\r\n totalRow,\r\n \"(no MCP telemetry recorded)\",\r\n );\r\n appendEstimateLegend(\r\n lines,\r\n sorted.map((r) => r.confidence),\r\n );\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Format the scope breakdown:\r\n * INSTALL | LAUNCH | CALLS | IN | OUT | TOTAL | CONFIDENCE\r\n * with a TOTAL footer and the honesty legend.\r\n */\r\nexport function formatScopeBreakdown(rows: ScopeBreakdownRow[]): string {\r\n const sorted = [...rows].sort(\r\n (a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs,\r\n );\r\n const headers = [\"INSTALL\", \"LAUNCH\", \"CALLS\", \"IN\", \"OUT\", \"TOTAL\", \"CONFIDENCE\"];\r\n const dataRows = sorted.map((r) => [\r\n r.installScope,\r\n r.launchMethod,\r\n fmtInt(r.calls),\r\n fmtInt(r.inputTokens),\r\n fmtInt(r.outputTokens),\r\n fmtInt(r.totalTokens),\r\n r.confidence,\r\n ]);\r\n\r\n const totals = sorted.reduce(\r\n (acc, r) => {\r\n acc.calls += r.calls;\r\n acc.inputTokens += r.inputTokens;\r\n acc.outputTokens += r.outputTokens;\r\n acc.totalTokens += r.totalTokens;\r\n return acc;\r\n },\r\n { calls: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 },\r\n );\r\n const totalRow = [\r\n \"TOTAL\",\r\n \"\",\r\n fmtInt(totals.calls),\r\n fmtInt(totals.inputTokens),\r\n fmtInt(totals.outputTokens),\r\n fmtInt(totals.totalTokens),\r\n \"\",\r\n ];\r\n\r\n // Left-align INSTALL (0), LAUNCH (1), CONFIDENCE (6); numbers right-aligned.\r\n const leftCols = new Set<number>([0, 1, 6]);\r\n const lines = renderTable(\r\n headers,\r\n dataRows,\r\n leftCols,\r\n totalRow,\r\n \"(no MCP telemetry recorded)\",\r\n );\r\n appendEstimateLegend(\r\n lines,\r\n sorted.map((r) => r.confidence),\r\n );\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Format the host-native turns aggregation (the THIRD origin):\r\n * RANK | HOST | SESSION | TURNS | IN | OUT | TOTAL | CONNECTORS | CONFIDENCE\r\n * sorted by total tokens desc, with a TOTAL footer. These are whole-conversation,\r\n * host-reported (exact) counts — a DIFFERENT thing than the per-MCP rows, so the\r\n * footer total is for THIS section alone and is never added to the others.\r\n */\r\nexport function formatHostNativeTurns(rows: HostNativeTurnsRow[]): string {\r\n const sorted = [...rows].sort(\r\n (a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs,\r\n );\r\n const headers = [\r\n \"RANK\",\r\n \"HOST\",\r\n \"SESSION\",\r\n \"TURNS\",\r\n \"IN\",\r\n \"OUT\",\r\n \"TOTAL\",\r\n \"CONNECTORS\",\r\n \"CONFIDENCE\",\r\n ];\r\n const dataRows = sorted.map((r, i) => [\r\n `${i + 1}`,\r\n r.hostPlatform,\r\n r.sessionId === \"\" ? \"-\" : r.sessionId,\r\n fmtInt(r.turns),\r\n fmtInt(r.inputTokens),\r\n fmtInt(r.outputTokens),\r\n fmtInt(r.totalTokens),\r\n r.connectors.length === 0 ? \"-\" : r.connectors.join(\",\"),\r\n r.confidence,\r\n ]);\r\n\r\n const totals = sorted.reduce(\r\n (acc, r) => {\r\n acc.turns += r.turns;\r\n acc.inputTokens += r.inputTokens;\r\n acc.outputTokens += r.outputTokens;\r\n acc.totalTokens += r.totalTokens;\r\n return acc;\r\n },\r\n { turns: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 },\r\n );\r\n const totalRow = [\r\n \"\",\r\n \"TOTAL\",\r\n \"\",\r\n fmtInt(totals.turns),\r\n fmtInt(totals.inputTokens),\r\n fmtInt(totals.outputTokens),\r\n fmtInt(totals.totalTokens),\r\n \"\",\r\n \"\",\r\n ];\r\n\r\n // Left-align RANK (0), HOST (1), SESSION (2), CONNECTORS (7), CONFIDENCE (8).\r\n const leftCols = new Set<number>([0, 1, 2, 7, 8]);\r\n const lines = renderTable(\r\n headers,\r\n dataRows,\r\n leftCols,\r\n totalRow,\r\n \"(no host-native turns recorded — enable opt-in host-native usage)\",\r\n );\r\n return lines.join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Format the per-surface developer breakdown:\r\n * SURFACE | NAME | IN | OUT | TOTAL | KIND\r\n * one row per (surfaceKind, name) across all FIVE surfaces — server + hook\r\n * (runtime, measured from the store) and command/skill/subagent (static\r\n * footprints). Sorted by total tokens desc, with a TOTAL footer and the honesty\r\n * legend (static footprints + any estimate-confidence runtime rows).\r\n *\r\n * NOTE: the TOTAL footer sums BOTH runtime and static tokens for at-a-glance\r\n * scale; the KIND column keeps the distinction explicit so the two are never\r\n * silently conflated (runtime = live usage; static = context-load footprint).\r\n */\r\nexport function formatSurfaceLeaderboard(rows: SurfaceLeaderboardRow[]): string {\r\n const sorted = [...rows].sort(\r\n (a, b) => b.totalTokens - a.totalTokens || b.lastTs - a.lastTs,\r\n );\r\n const headers = [\"SURFACE\", \"NAME\", \"IN\", \"OUT\", \"TOTAL\", \"KIND\"];\r\n const dataRows = sorted.map((r) => [\r\n r.surfaceKind,\r\n r.name,\r\n fmtInt(r.inputTokens),\r\n fmtInt(r.outputTokens),\r\n fmtInt(r.totalTokens),\r\n r.kind,\r\n ]);\r\n\r\n const totals = sorted.reduce(\r\n (acc, r) => {\r\n acc.inputTokens += r.inputTokens;\r\n acc.outputTokens += r.outputTokens;\r\n acc.totalTokens += r.totalTokens;\r\n return acc;\r\n },\r\n { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\r\n );\r\n const totalRow = [\r\n \"TOTAL\",\r\n \"\",\r\n fmtInt(totals.inputTokens),\r\n fmtInt(totals.outputTokens),\r\n fmtInt(totals.totalTokens),\r\n \"\",\r\n ];\r\n\r\n // Left-align SURFACE (0), NAME (1), KIND (5); numbers right-aligned.\r\n const leftCols = new Set<number>([0, 1, 5]);\r\n const lines = renderTable(\r\n headers,\r\n dataRows,\r\n leftCols,\r\n totalRow,\r\n \"(no developer surfaces recorded)\",\r\n );\r\n if (sorted.some((r) => r.kind === \"static\")) {\r\n lines.push(\"\");\r\n lines.push(\r\n \"note: KIND=static rows are the tokenized FOOTPRINT a command/skill/subagent \" +\r\n \"imposes on a host that loads it as context — not intercepted usage rows.\",\r\n );\r\n }\r\n appendEstimateLegend(\r\n lines,\r\n sorted.map((r) => r.confidence),\r\n );\r\n return lines.join(\"\\n\");\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/ids.ts","../src/core/paths.ts"],"sourcesContent":["/** Shared connector-id grammar for author-time configs and runtime ids. */\r\nexport const CONNECTOR_ID_RE = /^[a-z0-9][a-z0-9-]*$/;\r\n\r\nexport function isValidConnectorId(id: unknown): id is string {\r\n return typeof id === \"string\" && CONNECTOR_ID_RE.test(id);\r\n}\r\n\r\nexport function assertConnectorId(id: unknown, label = \"connector id\"): string {\r\n if (isValidConnectorId(id)) return id;\r\n throw new Error(\r\n `${label} must be kebab-case matching ${CONNECTOR_ID_RE} (got ${JSON.stringify(id)})`,\r\n );\r\n}\r\n","/**\r\n * core/paths — home data-root, stable home binary, and project identity.\r\n *\r\n * Operating model (docs/ARCHITECTURE.md §3):\r\n * • One home data-root holds the single binary + shared telemetry + state.\r\n * Override with AGENT_CONNECTOR_DATA_DIR (the cross-agent shared-DB key).\r\n * This relocates FRAMEWORK state only — never platform-native config files.\r\n * • The home binary lives at a STABLE path so every host's pointer config\r\n * keeps working across updates (no versioned cache dir → no cache-heal bug).\r\n * • Per-project data is keyed by a stable project identity (git remote ||\r\n * normalized absolute path), hashed — not by code location.\r\n */\r\n\r\nimport { createHash } from \"node:crypto\";\r\nimport {\r\n chmodSync,\r\n existsSync,\r\n lstatSync,\r\n mkdirSync,\r\n readFileSync,\r\n writeFileSync,\r\n} from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport { basename, isAbsolute, join, parse, relative, resolve, sep } from \"node:path\";\r\n\r\nimport { assertConnectorId } from \"./ids.js\";\r\n\r\n/** The built-in default framework data-root (`~/.agent-connector`), ignoring\r\n * any AGENT_CONNECTOR_DATA_DIR override. */\r\nexport function defaultDataRoot(): string {\r\n return join(homedir(), \".agent-connector\");\r\n}\r\n\r\n/** Framework data-root: AGENT_CONNECTOR_DATA_DIR || ~/.agent-connector. */\r\nexport function dataRoot(): string {\r\n const override = process.env.AGENT_CONNECTOR_DATA_DIR;\r\n if (override && override.trim() !== \"\") return resolve(override);\r\n return defaultDataRoot();\r\n}\r\n\r\n/**\r\n * True when `root` is a NON-DEFAULT data root — i.e. it differs from the\r\n * built-in `~/.agent-connector`. Compared after `resolve()` so two spellings of\r\n * the same dir read as equal. Used at install time to decide whether the\r\n * telemetry serve-wrap must carry an explicit `--data-dir` flag: a default-root\r\n * install relies on the (correct) fallback and stays flag-free, but an overridden\r\n * root must be passed explicitly because some hosts (codex) strip the child env,\r\n * so the spawned `serve` would otherwise resolve the default root and fail to\r\n * find the connector record written under the overridden one.\r\n */\r\nexport function isNonDefaultDataRoot(root: string): boolean {\r\n return resolve(root) !== resolve(defaultDataRoot());\r\n}\r\n\r\nexport function connectorsDir(): string {\r\n return join(dataRoot(), \"connectors\");\r\n}\r\n/**\r\n * Stable cache root for REMOTE connector sources fetched by `install <source>`\r\n * (one subdir per `<owner>__<repo>[__<ref>]`). Lives under the data-root — NOT a\r\n * temp dir — so a fetched connector whose server is a LOCAL stdio command\r\n * (`node <path-in-the-clone>`) keeps resolving after install across reboots.\r\n */\r\nexport function sourcesDir(): string {\r\n return join(dataRoot(), \"sources\");\r\n}\r\nexport function connectorDir(id: string): string {\r\n const root = resolve(connectorsDir());\r\n const safeId = assertConnectorId(id);\r\n const dir = resolve(root, safeId);\r\n const rel = relative(root, dir);\r\n if (rel === \"\" || rel.startsWith(\"..\") || isAbsolute(rel)) {\r\n throw new Error(`connector record path escapes ${root}: ${id}`);\r\n }\r\n return dir;\r\n}\r\nexport function backupsDir(): string {\r\n return join(dataRoot(), \"backups\");\r\n}\r\nexport function logsDir(): string {\r\n return join(dataRoot(), \"logs\");\r\n}\r\n\r\n/** Telemetry store path for the selected backend. */\r\nexport function telemetryPath(store: \"ndjson\" | \"sqlite\" = \"ndjson\"): string {\r\n return join(dataRoot(), store === \"sqlite\" ? \"telemetry.db\" : \"telemetry.ndjson\");\r\n}\r\n\r\n/** Stable, OS-correct path to the single home binary pointer. */\r\nexport function homeBinPath(): string {\r\n const name = process.platform === \"win32\" ? \"agent-connector.cmd\" : \"agent-connector\";\r\n return join(dataRoot(), \"bin\", name);\r\n}\r\n\r\nexport function ensureDir(dir: string): void {\r\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\r\n}\r\n\r\n/**\r\n * Return the first existing symbolic-link component in `path`, or null when the\r\n * existing prefix is symlink-free. Stops at the first missing component so new\r\n * directories/files can still be created normally.\r\n */\r\nexport function firstSymlinkInPath(path: string): string | null {\r\n const abs = resolve(path);\r\n const root = parse(abs).root;\r\n const rest = relative(root, abs);\r\n if (rest === \"\") return null;\r\n\r\n let cur = root;\r\n for (const part of rest.split(sep)) {\r\n if (part === \"\") continue;\r\n cur = join(cur, part);\r\n try {\r\n if (lstatSync(cur).isSymbolicLink()) return cur;\r\n } catch (err) {\r\n const code = (err as NodeJS.ErrnoException).code;\r\n if (code === \"ENOENT\") return null;\r\n throw err;\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nexport function assertNoSymlinkInPath(path: string): void {\r\n const symlink = firstSymlinkInPath(path);\r\n if (symlink !== null) {\r\n throw new Error(`${basename(path)} skipped: symbolic link in path (${symlink})`);\r\n }\r\n}\r\n\r\n/**\r\n * Write a stable launcher at homeBinPath() that execs the real CLI entry.\r\n * Avoids symlinks (Windows constraint) and versioned paths. Idempotent.\r\n *\r\n * @param cliEntry absolute path to the installed cli.js\r\n * @param nodePath node runtime to exec with (defaults to current process.execPath)\r\n * @returns the stable launcher path\r\n */\r\nexport function ensureHomeBin(cliEntry: string, nodePath: string = process.execPath): string {\r\n const binPath = homeBinPath();\r\n assertNoSymlinkInPath(binPath);\r\n ensureDir(join(dataRoot(), \"bin\"));\r\n const node = nodePath.replace(/\\\\/g, \"/\");\r\n const cli = cliEntry.replace(/\\\\/g, \"/\");\r\n if (process.platform === \"win32\") {\r\n writeFileSync(binPath, `@echo off\\r\\n\"${node}\" \"${cli}\" %*\\r\\n`, \"utf8\");\r\n } else {\r\n writeFileSync(binPath, `#!/bin/sh\\nexec \"${node}\" \"${cli}\" \"$@\"\\n`, \"utf8\");\r\n chmodSync(binPath, 0o755);\r\n }\r\n return binPath;\r\n}\r\n\r\n/** Read remote.origin.url from a project's .git/config without spawning git. */\r\nfunction gitRemoteUrl(projectDir: string): string | null {\r\n const cfg = join(projectDir, \".git\", \"config\");\r\n if (!existsSync(cfg)) return null;\r\n try {\r\n const text = readFileSync(cfg, \"utf8\");\r\n // Find [remote \"origin\"] ... url = X\r\n const lines = text.split(/\\r?\\n/);\r\n let inOrigin = false;\r\n for (const line of lines) {\r\n const s = line.trim();\r\n if (s.startsWith(\"[\")) inOrigin = /^\\[remote\\s+\"origin\"\\]$/.test(s);\r\n else if (inOrigin) {\r\n const m = s.match(/^url\\s*=\\s*(.+)$/);\r\n if (m && m[1]) return m[1].trim();\r\n }\r\n }\r\n } catch {\r\n /* ignore */\r\n }\r\n return null;\r\n}\r\n\r\nexport interface ProjectIdentity {\r\n /** Hashed stable key used to partition telemetry/state. */\r\n key: string;\r\n /** Human-readable label (git remote or directory name). */\r\n label: string;\r\n /** Absolute project directory. */\r\n dir: string;\r\n}\r\n\r\n/**\r\n * Derive a stable project identity. Prefers the git origin URL (stable across\r\n * clones/locations); falls back to the normalized absolute path.\r\n */\r\nexport function projectIdentity(projectDir: string): ProjectIdentity {\r\n const dir = resolve(projectDir);\r\n const remote = gitRemoteUrl(dir);\r\n const basis = remote ?? dir;\r\n const key = createHash(\"sha256\").update(basis).digest(\"hex\").slice(0, 16);\r\n return { key, label: remote ?? basename(dir), dir };\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/spawn-child.ts"],"sourcesContent":["/**\r\n * core/spawn-child — the cross-platform child_process.spawn wrapper.\r\n *\r\n * Kept SEPARATE from core/spawn.ts (pure string/path helpers, imported widely\r\n * and early) so that pulling in `node:child_process` here does not perturb the\r\n * module-eval order of test suites that vi.mock(\"node:child_process\").\r\n */\r\n\r\nimport { type ChildProcess, type SpawnOptions, spawn } from \"node:child_process\";\r\n\r\nimport { resolveSpawnCommand } from \"./spawn.js\";\r\n\r\n/**\r\n * Quote one token for a cmd.exe command line: wrap in double quotes, doubling any\r\n * embedded double quote. Sufficient for the paths / package names / flags we\r\n * spawn (connector config, not untrusted end-user input) — we intentionally do\r\n * not escape cmd metacharacters (& | ^ %), which never appear in those tokens.\r\n */\r\nfunction winQuoteArg(s: string): string {\r\n return `\"${s.replace(/\"/g, '\"\"')}\"`;\r\n}\r\n\r\n/**\r\n * Cross-platform child spawn that fixes native-Windows package-runner launches.\r\n * Direct spawn on macOS/Linux. On win32 it routes through\r\n * {@link resolveSpawnCommand}; an `.exe` runs directly, while a `.cmd`/`.bat`\r\n * (npx.cmd, the agent-connector.cmd launcher) is launched via a SINGLE quoted\r\n * command line with `shell: true` — a string rather than an args array, which\r\n * Node requires for a batch file AND which avoids the DEP0190 deprecation that\r\n * `shell: true` + an args array triggers on Node ≥ 24.\r\n */\r\nexport function spawnChild(\r\n command: string,\r\n args: string[],\r\n options: SpawnOptions,\r\n): ChildProcess {\r\n const resolved = resolveSpawnCommand(command);\r\n if (!resolved.needsShell) return spawn(resolved.file, args, options);\r\n const line = [resolved.file, ...args].map(winQuoteArg).join(\" \");\r\n return spawn(line, { ...options, shell: true });\r\n}\r\n"],"mappings":";;;;;;AAQA,SAA+C,aAAa;AAU5D,SAAS,YAAY,GAAmB;AACtC,SAAO,IAAI,EAAE,QAAQ,MAAM,IAAI,CAAC;AAClC;AAWO,SAAS,WACd,SACA,MACA,SACc;AACd,QAAM,WAAW,oBAAoB,OAAO;AAC5C,MAAI,CAAC,SAAS,WAAY,QAAO,MAAM,SAAS,MAAM,MAAM,OAAO;AACnE,QAAM,OAAO,CAAC,SAAS,MAAM,GAAG,IAAI,EAAE,IAAI,WAAW,EAAE,KAAK,GAAG;AAC/D,SAAO,MAAM,MAAM,EAAE,GAAG,SAAS,OAAO,KAAK,CAAC;AAChD;","names":[]}
|