@ken-jo/agent-connector 0.4.94 → 0.4.97
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 +605 -485
- package/dist/{action-VW5SACXY.js → action-IPFDPOZU.js} +16 -16
- package/dist/action-IPFDPOZU.js.map +1 -0
- package/dist/{amazon-q-ETMAGY3D.js → amazon-q-IT44LEWV.js} +6 -6
- package/dist/amazon-q-IT44LEWV.js.map +1 -0
- package/dist/{amp-BQZOL5GR.js → amp-CEWOSWQO.js} +4 -4
- package/dist/amp-CEWOSWQO.js.map +1 -0
- package/dist/{amp-67BZONGF.js → amp-P35FRU2Z.js} +7 -7
- package/dist/amp-P35FRU2Z.js.map +1 -0
- package/dist/{antigravity-EA4L225L.js → antigravity-LHFEFNMC.js} +5 -5
- package/dist/antigravity-LHFEFNMC.js.map +1 -0
- package/dist/antigravity-TWIWXTQH.js +18 -0
- package/dist/{antigravity-cli-B2HXZFYQ.js → antigravity-cli-MOKFSWOU.js} +5 -5
- package/dist/antigravity-cli-MOKFSWOU.js.map +1 -0
- package/dist/{antigravity-cli-OM6SC3PE.js → antigravity-cli-MPE27LPI.js} +9 -9
- package/dist/antigravity-cli-MPE27LPI.js.map +1 -0
- package/dist/audit-3E5JAOP2.js +311 -0
- package/dist/audit-3E5JAOP2.js.map +1 -0
- package/dist/{chunk-KSPMSRVU.js → chunk-3EP5V2F4.js} +3 -3
- package/dist/chunk-3EP5V2F4.js.map +1 -0
- package/dist/{chunk-MGTDQLJJ.js → chunk-3FINQ2ZF.js} +4 -4
- package/dist/chunk-3FINQ2ZF.js.map +1 -0
- package/dist/{chunk-KHO5WNTP.js → chunk-4GH2KA7V.js} +1 -1
- package/dist/chunk-4GH2KA7V.js.map +1 -0
- package/dist/{chunk-2Y2MZRLP.js → chunk-7C2IPIIB.js} +3 -3
- package/dist/chunk-7C2IPIIB.js.map +1 -0
- package/dist/{chunk-NLE2J5P4.js → chunk-7HHW23AC.js} +29 -29
- package/dist/chunk-7HHW23AC.js.map +1 -0
- package/dist/{chunk-XD7MY6HB.js → chunk-7PSNXUFK.js} +1 -1
- package/dist/chunk-7PSNXUFK.js.map +1 -0
- package/dist/{chunk-KJLFGQQM.js → chunk-7ZFK2WEO.js} +8 -6
- package/dist/chunk-7ZFK2WEO.js.map +1 -0
- package/dist/{chunk-XC5SJ35F.js → chunk-C63AAXK7.js} +5 -5
- package/dist/chunk-C63AAXK7.js.map +1 -0
- package/dist/{chunk-UM5S7DKK.js → chunk-C747DYNT.js} +1 -1
- package/dist/chunk-C747DYNT.js.map +1 -0
- package/dist/{chunk-EHP7WISI.js → chunk-FHYR5Q5T.js} +19 -14
- package/dist/chunk-FHYR5Q5T.js.map +1 -0
- package/dist/{chunk-I5TO42QC.js → chunk-GCPEPUD7.js} +8 -8
- package/dist/chunk-GCPEPUD7.js.map +1 -0
- package/dist/{chunk-ZMAJ2XFD.js → chunk-GZZCHJDP.js} +2 -2
- package/dist/chunk-GZZCHJDP.js.map +1 -0
- package/dist/{chunk-UMQ6NBQR.js → chunk-ILWHLGIC.js} +2 -2
- package/dist/chunk-ILWHLGIC.js.map +1 -0
- package/dist/{chunk-IVAWP6HH.js → chunk-IOJDZJ72.js} +2 -2
- package/dist/chunk-IOJDZJ72.js.map +1 -0
- package/dist/{chunk-NBYKLUF6.js → chunk-KFPSJRHR.js} +2 -2
- package/dist/chunk-KFPSJRHR.js.map +1 -0
- package/dist/{chunk-O7SDRBVB.js → chunk-KM2YXO6V.js} +1 -1
- package/dist/chunk-KM2YXO6V.js.map +1 -0
- package/dist/{chunk-P23RVIUY.js → chunk-L2C5UMKW.js} +4 -4
- package/dist/chunk-L2C5UMKW.js.map +1 -0
- package/dist/{chunk-OP4KBXUO.js → chunk-LFWYYWLV.js} +1 -1
- package/dist/chunk-LFWYYWLV.js.map +1 -0
- package/dist/{chunk-B5W3RHTI.js → chunk-LQ55E7QI.js} +7 -7
- package/dist/chunk-LQ55E7QI.js.map +1 -0
- package/dist/{chunk-TTKSYJRY.js → chunk-MLU7NDAZ.js} +12 -12
- package/dist/chunk-MLU7NDAZ.js.map +1 -0
- package/dist/{chunk-TQRLMA2C.js → chunk-N4ENLZEU.js} +22 -19
- package/dist/chunk-N4ENLZEU.js.map +1 -0
- package/dist/{chunk-SILKSP2Y.js → chunk-NDMNMAKP.js} +43 -43
- package/dist/chunk-NDMNMAKP.js.map +1 -0
- package/dist/{chunk-H53QZQJI.js → chunk-PSGTHJQU.js} +1 -1
- package/dist/chunk-PSGTHJQU.js.map +1 -0
- package/dist/{chunk-FBJQGRET.js → chunk-Q4ISQHUQ.js} +1 -1
- package/dist/chunk-Q4ISQHUQ.js.map +1 -0
- package/dist/{chunk-6TF7MHG5.js → chunk-Q7PR2WGT.js} +2 -2
- package/dist/chunk-Q7PR2WGT.js.map +1 -0
- package/dist/{chunk-GZGLCCEE.js → chunk-QYOUQCC6.js} +1 -1
- package/dist/chunk-QYOUQCC6.js.map +1 -0
- package/dist/{chunk-Z2MRSS2I.js → chunk-SLJI5BOM.js} +2 -2
- package/dist/chunk-SLJI5BOM.js.map +1 -0
- package/dist/{chunk-JKKU2WKG.js → chunk-TGZFDXNH.js} +4 -4
- package/dist/chunk-TGZFDXNH.js.map +1 -0
- package/dist/{chunk-FJCUKXGX.js → chunk-THI4PI4H.js} +2 -2
- package/dist/chunk-THI4PI4H.js.map +1 -0
- package/dist/{chunk-MQPNU2CY.js → chunk-UZZTWWGG.js} +1 -1
- package/dist/chunk-UZZTWWGG.js.map +1 -0
- package/dist/{chunk-2RIFORQS.js → chunk-WPTNMYYM.js} +2 -2
- package/dist/chunk-WPTNMYYM.js.map +1 -0
- package/dist/{chunk-OPXAP3AC.js → chunk-XN7S44U4.js} +1 -1
- package/dist/chunk-XN7S44U4.js.map +1 -0
- package/dist/{chunk-6WZODR3Z.js → chunk-XVEJAFKW.js} +5 -5
- package/dist/chunk-XVEJAFKW.js.map +1 -0
- package/dist/{chunk-BEFVJ2OE.js → chunk-XXLCMSD3.js} +1 -1
- package/dist/chunk-XXLCMSD3.js.map +1 -0
- package/dist/{chunk-YT43MUSJ.js → chunk-XZWMJLIT.js} +1 -1
- package/dist/chunk-XZWMJLIT.js.map +1 -0
- package/dist/{chunk-4NHXLXSD.js → chunk-Y3K6KJMS.js} +2 -2
- package/dist/chunk-Y3K6KJMS.js.map +1 -0
- package/dist/{chunk-RK6VBLXP.js → chunk-ZSOS2KOR.js} +1 -1
- package/dist/chunk-ZSOS2KOR.js.map +1 -0
- package/dist/{claude-code-NMRKTAP7.js → claude-code-FS42PXZO.js} +4 -4
- package/dist/claude-code-FS42PXZO.js.map +1 -0
- package/dist/{claude-code-DUZNOAS2.js → claude-code-QBWDT5RT.js} +11 -11
- package/dist/claude-code-QBWDT5RT.js.map +1 -0
- package/dist/cli/sdk.js +9 -8
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{cline-25KW25IN.js → cline-JKEAYWVR.js} +6 -6
- package/dist/cline-JKEAYWVR.js.map +1 -0
- package/dist/{codebuddy-ZNYQACMF.js → codebuddy-EB6EYPC3.js} +7 -7
- package/dist/codebuddy-EB6EYPC3.js.map +1 -0
- package/dist/{codebuff-VR6JUDIY.js → codebuff-5RSXFU6G.js} +6 -6
- package/dist/codebuff-5RSXFU6G.js.map +1 -0
- package/dist/{codebuff-ETYT5UBL.js → codebuff-6KWBW6CT.js} +4 -4
- package/dist/codebuff-6KWBW6CT.js.map +1 -0
- package/dist/{codex-CPNKTXG3.js → codex-ART46CDD.js} +9 -9
- package/dist/codex-ART46CDD.js.map +1 -0
- package/dist/{codex-YAORPCOD.js → codex-DKBAAUCO.js} +4 -4
- package/dist/codex-DKBAAUCO.js.map +1 -0
- package/dist/{continue-WU2IB5KS.js → continue-JHZCMSPH.js} +8 -8
- package/dist/continue-JHZCMSPH.js.map +1 -0
- package/dist/{copilot-cli-MZTAWMPW.js → copilot-cli-CLBJACQ5.js} +4 -4
- package/dist/copilot-cli-CLBJACQ5.js.map +1 -0
- package/dist/{copilot-cli-PAP377OM.js → copilot-cli-QVAU5CFM.js} +7 -7
- package/dist/copilot-cli-QVAU5CFM.js.map +1 -0
- package/dist/{crush-3AVQA4YU.js → crush-7TORBYUL.js} +7 -7
- package/dist/crush-7TORBYUL.js.map +1 -0
- package/dist/{crush-QBXLNN7T.js → crush-A5C5USRL.js} +4 -4
- package/dist/crush-A5C5USRL.js.map +1 -0
- package/dist/{cursor-DIW43TRZ.js → cursor-D5SWDVSW.js} +3 -3
- package/dist/cursor-D5SWDVSW.js.map +1 -0
- package/dist/cursor-W7I4QUFO.js +22 -0
- package/dist/{define-connector-LQFJL_at.d.ts → define-connector-DTWb46UB.d.ts} +1 -1
- package/dist/{detect-P5OA5UYM.js → detect-JHSA3G3U.js} +4 -4
- package/dist/detect-JHSA3G3U.js.map +1 -0
- package/dist/{devin-QMEM3OFA.js → devin-SSR7S4WX.js} +7 -7
- package/dist/devin-SSR7S4WX.js.map +1 -0
- package/dist/{doctor-2O2Q6MIB.js → doctor-CQJ7TZPA.js} +26 -26
- package/dist/doctor-CQJ7TZPA.js.map +1 -0
- package/dist/{droid-MOKV53J4.js → droid-45PJ7JGF.js} +7 -7
- package/dist/droid-45PJ7JGF.js.map +1 -0
- package/dist/{droid-U3ZBLQFO.js → droid-PFQ2PZSF.js} +4 -4
- package/dist/droid-PFQ2PZSF.js.map +1 -0
- package/dist/{gemini-cli-47ZHCOZR.js → gemini-cli-24PFDK7D.js} +8 -8
- package/dist/gemini-cli-24PFDK7D.js.map +1 -0
- package/dist/{gemini-cli-NMVVBO3K.js → gemini-cli-Y6RJMU24.js} +4 -4
- package/dist/gemini-cli-Y6RJMU24.js.map +1 -0
- package/dist/{goose-64V46Y2W.js → goose-K2HKUTBK.js} +4 -4
- package/dist/goose-K2HKUTBK.js.map +1 -0
- package/dist/{goose-4EI5MYTI.js → goose-U5D3LCPC.js} +9 -9
- package/dist/goose-U5D3LCPC.js.map +1 -0
- package/dist/{grok-cli-QYQPDSVB.js → grok-cli-L2MHAPBY.js} +7 -7
- package/dist/grok-cli-L2MHAPBY.js.map +1 -0
- package/dist/{hermes-F75OSK3Y.js → hermes-2S5JUTTJ.js} +7 -7
- package/dist/hermes-2S5JUTTJ.js.map +1 -0
- package/dist/{hermes-F3EGTK6N.js → hermes-MF3NX4ZY.js} +4 -4
- package/dist/hermes-MF3NX4ZY.js.map +1 -0
- package/dist/{hook-4N3BMKIK.js → hook-VHICXHXL.js} +16 -16
- package/dist/hook-VHICXHXL.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -5
- package/dist/{install-NPN77N3S.js → install-WLENR4KF.js} +192 -28
- package/dist/install-WLENR4KF.js.map +1 -0
- package/dist/{introspect-D4fEGuhN.d.ts → introspect-dNekqPDY.d.ts} +1 -1
- package/dist/{jetbrains-copilot-ZGIWI6YV.js → jetbrains-copilot-Z4FC3RM3.js} +6 -6
- package/dist/jetbrains-copilot-Z4FC3RM3.js.map +1 -0
- package/dist/{junie-DIFN2P22.js → junie-ULGJJIHB.js} +6 -6
- package/dist/junie-ULGJJIHB.js.map +1 -0
- package/dist/{kilo-SW7BH6EG.js → kilo-SMHPOHJ5.js} +4 -4
- package/dist/kilo-SMHPOHJ5.js.map +1 -0
- package/dist/{kilo-EMZJBEBB.js → kilo-WWIJOVWD.js} +8 -8
- package/dist/kilo-WWIJOVWD.js.map +1 -0
- package/dist/{kilo-cli-S3GXBPAE.js → kilo-cli-QKE2EQLS.js} +8 -8
- package/dist/kilo-cli-QKE2EQLS.js.map +1 -0
- package/dist/{kilo-cli-ZF272ZHN.js → kilo-cli-T2SRRRJS.js} +5 -5
- package/dist/kilo-cli-T2SRRRJS.js.map +1 -0
- package/dist/{kimi-IQJOIY6B.js → kimi-JMUFTVSF.js} +7 -7
- package/dist/kimi-JMUFTVSF.js.map +1 -0
- package/dist/{kimi-5FHEXGZD.js → kimi-MSIDEMCI.js} +4 -4
- package/dist/kimi-MSIDEMCI.js.map +1 -0
- package/dist/{kiro-WGOI5CGT.js → kiro-NYRRBIKW.js} +4 -4
- package/dist/kiro-NYRRBIKW.js.map +1 -0
- package/dist/{kiro-BYX4HEAJ.js → kiro-UWUCRKR3.js} +7 -7
- package/dist/kiro-UWUCRKR3.js.map +1 -0
- package/dist/{leaderboard-QKB36OBR.js → leaderboard-NJWKGMXP.js} +7 -7
- package/dist/leaderboard-NJWKGMXP.js.map +1 -0
- package/dist/{mimo-code-7R53QDHB.js → mimo-code-BPNYYIVM.js} +7 -7
- package/dist/mimo-code-BPNYYIVM.js.map +1 -0
- package/dist/{mistral-vibe-LHJ55FSB.js → mistral-vibe-LT3DAJ3L.js} +6 -6
- package/dist/mistral-vibe-LT3DAJ3L.js.map +1 -0
- package/dist/{mux-XM6AP35L.js → mux-7PIJ7HUQ.js} +4 -4
- package/dist/mux-7PIJ7HUQ.js.map +1 -0
- package/dist/{mux-NYCNGL43.js → mux-AHNUAY5Z.js} +6 -6
- package/dist/mux-AHNUAY5Z.js.map +1 -0
- package/dist/{nemoclaw-WSIPSE7U.js → nemoclaw-RE5RZASZ.js} +7 -7
- package/dist/nemoclaw-RE5RZASZ.js.map +1 -0
- package/dist/{omp-562NK5BJ.js → omp-D2EXEPH7.js} +7 -7
- package/dist/omp-D2EXEPH7.js.map +1 -0
- package/dist/{open-interpreter-I2CNOEXY.js → open-interpreter-SSGBEUKX.js} +6 -6
- package/dist/open-interpreter-SSGBEUKX.js.map +1 -0
- package/dist/openclaw-IJ33K45M.js +17 -0
- package/dist/{openclaw-5EQFGOWL.js → openclaw-KAFTNLR2.js} +4 -4
- package/dist/openclaw-KAFTNLR2.js.map +1 -0
- package/dist/{opencode-YS4WX2E2.js → opencode-YKUKZY3J.js} +7 -7
- package/dist/opencode-YKUKZY3J.js.map +1 -0
- package/dist/{opencode-QGP4ALQY.js → opencode-Z65JYILL.js} +4 -4
- package/dist/opencode-Z65JYILL.js.map +1 -0
- package/dist/{openhands-QMYIKNOS.js → openhands-SEZMCUC3.js} +7 -7
- package/dist/openhands-SEZMCUC3.js.map +1 -0
- package/dist/{package-Q6DV5247.js → package-JECVQEFT.js} +15 -15
- package/dist/package-JECVQEFT.js.map +1 -0
- package/dist/{pi-GGDQREVG.js → pi-DLKCPOJE.js} +4 -4
- package/dist/pi-DLKCPOJE.js.map +1 -0
- package/dist/{pi-644FIN3A.js → pi-YPYV2ULH.js} +6 -6
- package/dist/pi-YPYV2ULH.js.map +1 -0
- package/dist/{qwen-code-GQILBJ5B.js → qwen-code-26CSFDX6.js} +4 -4
- package/dist/qwen-code-26CSFDX6.js.map +1 -0
- package/dist/{qwen-code-STDMX7EM.js → qwen-code-ZHCLCYMC.js} +9 -9
- package/dist/qwen-code-ZHCLCYMC.js.map +1 -0
- package/dist/{roo-code-DLPIHHQ6.js → roo-code-7F4HYB34.js} +6 -6
- package/dist/roo-code-7F4HYB34.js.map +1 -0
- package/dist/{roo-code-SUWI4BBN.js → roo-code-HSAE2CJU.js} +4 -4
- package/dist/roo-code-HSAE2CJU.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +14 -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 +11 -11
- package/dist/{serve-MJTTXDX4.js → serve-LYSBH43G.js} +16 -16
- package/dist/serve-LYSBH43G.js.map +1 -0
- package/dist/{status-Q3UY4NZU.js → status-PHKKGEW5.js} +11 -11
- package/dist/status-PHKKGEW5.js.map +1 -0
- package/dist/{statusline-QF4G724E.js → statusline-ZDD4OZ4F.js} +15 -15
- package/dist/statusline-ZDD4OZ4F.js.map +1 -0
- package/dist/{synthetic-6FRA7P5Q.js → synthetic-LUT6V6SD.js} +4 -4
- package/dist/synthetic-LUT6V6SD.js.map +1 -0
- package/dist/{telemetry-JHVRDDNK.js → telemetry-HDGMI2BK.js} +10 -10
- package/dist/telemetry-HDGMI2BK.js.map +1 -0
- package/dist/{trae-CPPYASR2.js → trae-SIQI3C66.js} +4 -4
- package/dist/trae-SIQI3C66.js.map +1 -0
- package/dist/{trae-UOYD6JZZ.js → trae-Y67HSDOW.js} +6 -6
- package/dist/trae-Y67HSDOW.js.map +1 -0
- package/dist/{types-BhcUEIJJ.d.ts → types-JyhpJHJa.d.ts} +4 -2
- package/dist/{uninstall-H2SOV3AP.js → uninstall-RWO2GM2I.js} +21 -21
- package/dist/uninstall-RWO2GM2I.js.map +1 -0
- package/dist/{upgrade-UCSG7L5U.js → upgrade-YJCXNUEE.js} +21 -21
- package/dist/upgrade-YJCXNUEE.js.map +1 -0
- package/dist/{usage-4EGIJ4TM.js → usage-IWO4RQN6.js} +4 -4
- package/dist/usage-IWO4RQN6.js.map +1 -0
- package/dist/{usage-event-GRQE7XWT.js → usage-event-AFFKCLHE.js} +15 -15
- package/dist/usage-event-AFFKCLHE.js.map +1 -0
- package/dist/{vscode-copilot-NIMH2DGU.js → vscode-copilot-5CI5B3X6.js} +7 -7
- package/dist/vscode-copilot-5CI5B3X6.js.map +1 -0
- package/dist/{warp-NRBBJQR2.js → warp-5YBSP7FP.js} +4 -4
- package/dist/warp-5YBSP7FP.js.map +1 -0
- package/dist/{warp-QYJGKURM.js → warp-INAKVGBV.js} +6 -6
- package/dist/warp-INAKVGBV.js.map +1 -0
- package/dist/{windsurf-75LLZ37C.js → windsurf-4HM57QAY.js} +6 -6
- package/dist/windsurf-4HM57QAY.js.map +1 -0
- package/dist/{zed-XJFOOKCO.js → zed-XXCNYOIN.js} +4 -4
- package/dist/zed-XXCNYOIN.js.map +1 -0
- package/dist/{zed-HKAZXEJW.js → zed-YN5X37PQ.js} +7 -7
- package/dist/zed-YN5X37PQ.js.map +1 -0
- package/package.json +92 -88
- package/dist/action-VW5SACXY.js.map +0 -1
- package/dist/amazon-q-ETMAGY3D.js.map +0 -1
- package/dist/amp-67BZONGF.js.map +0 -1
- package/dist/amp-BQZOL5GR.js.map +0 -1
- package/dist/antigravity-EA4L225L.js.map +0 -1
- package/dist/antigravity-VXLDLTO7.js +0 -18
- package/dist/antigravity-cli-B2HXZFYQ.js.map +0 -1
- package/dist/antigravity-cli-OM6SC3PE.js.map +0 -1
- package/dist/chunk-2RIFORQS.js.map +0 -1
- package/dist/chunk-2Y2MZRLP.js.map +0 -1
- package/dist/chunk-4NHXLXSD.js.map +0 -1
- package/dist/chunk-6TF7MHG5.js.map +0 -1
- package/dist/chunk-6WZODR3Z.js.map +0 -1
- package/dist/chunk-B5W3RHTI.js.map +0 -1
- package/dist/chunk-BEFVJ2OE.js.map +0 -1
- package/dist/chunk-EHP7WISI.js.map +0 -1
- package/dist/chunk-FBJQGRET.js.map +0 -1
- package/dist/chunk-FJCUKXGX.js.map +0 -1
- package/dist/chunk-GZGLCCEE.js.map +0 -1
- package/dist/chunk-H53QZQJI.js.map +0 -1
- package/dist/chunk-I5TO42QC.js.map +0 -1
- package/dist/chunk-IVAWP6HH.js.map +0 -1
- package/dist/chunk-JKKU2WKG.js.map +0 -1
- package/dist/chunk-KHO5WNTP.js.map +0 -1
- package/dist/chunk-KJLFGQQM.js.map +0 -1
- package/dist/chunk-KSPMSRVU.js.map +0 -1
- package/dist/chunk-MGTDQLJJ.js.map +0 -1
- package/dist/chunk-MQPNU2CY.js.map +0 -1
- package/dist/chunk-NBYKLUF6.js.map +0 -1
- package/dist/chunk-NLE2J5P4.js.map +0 -1
- package/dist/chunk-O7SDRBVB.js.map +0 -1
- package/dist/chunk-OP4KBXUO.js.map +0 -1
- package/dist/chunk-OPXAP3AC.js.map +0 -1
- package/dist/chunk-P23RVIUY.js.map +0 -1
- package/dist/chunk-RK6VBLXP.js.map +0 -1
- package/dist/chunk-SILKSP2Y.js.map +0 -1
- package/dist/chunk-TQRLMA2C.js.map +0 -1
- package/dist/chunk-TTKSYJRY.js.map +0 -1
- package/dist/chunk-UM5S7DKK.js.map +0 -1
- package/dist/chunk-UMQ6NBQR.js.map +0 -1
- package/dist/chunk-XC5SJ35F.js.map +0 -1
- package/dist/chunk-XD7MY6HB.js.map +0 -1
- package/dist/chunk-YT43MUSJ.js.map +0 -1
- package/dist/chunk-Z2MRSS2I.js.map +0 -1
- package/dist/chunk-ZMAJ2XFD.js.map +0 -1
- package/dist/claude-code-DUZNOAS2.js.map +0 -1
- package/dist/claude-code-NMRKTAP7.js.map +0 -1
- package/dist/cline-25KW25IN.js.map +0 -1
- package/dist/codebuddy-ZNYQACMF.js.map +0 -1
- package/dist/codebuff-ETYT5UBL.js.map +0 -1
- package/dist/codebuff-VR6JUDIY.js.map +0 -1
- package/dist/codex-CPNKTXG3.js.map +0 -1
- package/dist/codex-YAORPCOD.js.map +0 -1
- package/dist/continue-WU2IB5KS.js.map +0 -1
- package/dist/copilot-cli-MZTAWMPW.js.map +0 -1
- package/dist/copilot-cli-PAP377OM.js.map +0 -1
- package/dist/crush-3AVQA4YU.js.map +0 -1
- package/dist/crush-QBXLNN7T.js.map +0 -1
- package/dist/cursor-DIW43TRZ.js.map +0 -1
- package/dist/cursor-GSLUET3V.js +0 -22
- package/dist/detect-P5OA5UYM.js.map +0 -1
- package/dist/devin-QMEM3OFA.js.map +0 -1
- package/dist/doctor-2O2Q6MIB.js.map +0 -1
- package/dist/droid-MOKV53J4.js.map +0 -1
- package/dist/droid-U3ZBLQFO.js.map +0 -1
- package/dist/gemini-cli-47ZHCOZR.js.map +0 -1
- package/dist/gemini-cli-NMVVBO3K.js.map +0 -1
- package/dist/goose-4EI5MYTI.js.map +0 -1
- package/dist/goose-64V46Y2W.js.map +0 -1
- package/dist/grok-cli-QYQPDSVB.js.map +0 -1
- package/dist/hermes-F3EGTK6N.js.map +0 -1
- package/dist/hermes-F75OSK3Y.js.map +0 -1
- package/dist/hook-4N3BMKIK.js.map +0 -1
- package/dist/install-NPN77N3S.js.map +0 -1
- package/dist/jetbrains-copilot-ZGIWI6YV.js.map +0 -1
- package/dist/junie-DIFN2P22.js.map +0 -1
- package/dist/kilo-EMZJBEBB.js.map +0 -1
- package/dist/kilo-SW7BH6EG.js.map +0 -1
- package/dist/kilo-cli-S3GXBPAE.js.map +0 -1
- package/dist/kilo-cli-ZF272ZHN.js.map +0 -1
- package/dist/kimi-5FHEXGZD.js.map +0 -1
- package/dist/kimi-IQJOIY6B.js.map +0 -1
- package/dist/kiro-BYX4HEAJ.js.map +0 -1
- package/dist/kiro-WGOI5CGT.js.map +0 -1
- package/dist/leaderboard-QKB36OBR.js.map +0 -1
- package/dist/mimo-code-7R53QDHB.js.map +0 -1
- package/dist/mistral-vibe-LHJ55FSB.js.map +0 -1
- package/dist/mux-NYCNGL43.js.map +0 -1
- package/dist/mux-XM6AP35L.js.map +0 -1
- package/dist/nemoclaw-WSIPSE7U.js.map +0 -1
- package/dist/omp-562NK5BJ.js.map +0 -1
- package/dist/open-interpreter-I2CNOEXY.js.map +0 -1
- package/dist/openclaw-5EQFGOWL.js.map +0 -1
- package/dist/openclaw-7EYBQS4R.js +0 -17
- package/dist/opencode-QGP4ALQY.js.map +0 -1
- package/dist/opencode-YS4WX2E2.js.map +0 -1
- package/dist/openhands-QMYIKNOS.js.map +0 -1
- package/dist/package-Q6DV5247.js.map +0 -1
- package/dist/pi-644FIN3A.js.map +0 -1
- package/dist/pi-GGDQREVG.js.map +0 -1
- package/dist/qwen-code-GQILBJ5B.js.map +0 -1
- package/dist/qwen-code-STDMX7EM.js.map +0 -1
- package/dist/roo-code-DLPIHHQ6.js.map +0 -1
- package/dist/roo-code-SUWI4BBN.js.map +0 -1
- package/dist/serve-MJTTXDX4.js.map +0 -1
- package/dist/status-Q3UY4NZU.js.map +0 -1
- package/dist/statusline-QF4G724E.js.map +0 -1
- package/dist/synthetic-6FRA7P5Q.js.map +0 -1
- package/dist/telemetry-JHVRDDNK.js.map +0 -1
- package/dist/trae-CPPYASR2.js.map +0 -1
- package/dist/trae-UOYD6JZZ.js.map +0 -1
- package/dist/uninstall-H2SOV3AP.js.map +0 -1
- package/dist/upgrade-UCSG7L5U.js.map +0 -1
- package/dist/usage-4EGIJ4TM.js.map +0 -1
- package/dist/usage-event-GRQE7XWT.js.map +0 -1
- package/dist/vscode-copilot-NIMH2DGU.js.map +0 -1
- package/dist/warp-NRBBJQR2.js.map +0 -1
- package/dist/warp-QYJGKURM.js.map +0 -1
- package/dist/windsurf-75LLZ37C.js.map +0 -1
- package/dist/zed-HKAZXEJW.js.map +0 -1
- package/dist/zed-XJFOOKCO.js.map +0 -1
- /package/dist/{antigravity-VXLDLTO7.js.map → antigravity-TWIWXTQH.js.map} +0 -0
- /package/dist/{cursor-GSLUET3V.js.map → cursor-W7I4QUFO.js.map} +0 -0
- /package/dist/{openclaw-7EYBQS4R.js.map → openclaw-IJ33K45M.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/hermes/index.ts"],"sourcesContent":["/**\r\n * adapters/hermes — Hermes Agent platform adapter for agent-connector.\r\n *\r\n * Hermes is a json-stdio host whose ENTIRE configuration — both the MCP servers\r\n * and the lifecycle hooks — lives in a single user-scope YAML file:\r\n *\r\n * ~/.hermes/config.yaml\r\n *\r\n * Because the file is YAML, the BaseAdapter JSON helpers do not apply; this\r\n * adapter merges via core/yaml's readYaml/writeYaml, preserving any unrelated\r\n * config the user has authored.\r\n *\r\n * - MCP servers: top-level snake_case root key `mcp_servers`. The stdio entry\r\n * uses the portable field names { command, args, env } (unlike Goose's\r\n * cmd/envs). Hermes has no native env interpolation, so `${env:VAR}` refs are\r\n * resolved to literals at install time.\r\n *\r\n * - Hooks: a top-level `hooks` map keyed by Hermes' NATIVE snake_case event\r\n * names (pre_tool_call / post_tool_call / on_session_start / on_session_end /\r\n * subagent_stop — NOT the canonical PascalCase names; see EVENT_TO_HERMES).\r\n * Each value is a\r\n * list of shell-hook entries { matcher, command:\"<homeBin> hook …\", timeout }.\r\n * The command keeps the canonical event token so the runtime dispatcher\r\n * (parseEvent/formatReply) stays consistent. Hermes shell hooks pipe the\r\n * event JSON to the command on stdin and read the reply JSON from stdout —\r\n * the same wire protocol as Claude Code, so the runtime parse/format mirror\r\n * the Claude adapter (a Claude-like JSON shape; the exact Hermes field map is\r\n * documented inline where it could vary).\r\n *\r\n * Since hooks are external shell commands (not an in-process plugin), Hermes\r\n * cannot let a hook rewrite tool arguments — canModifyArgs is false. Hermes has\r\n * no SSE transport, so only stdio + http are advertised.\r\n */\r\n\r\nimport { existsSync, statSync } from \"node:fs\";\r\nimport { homedir } from \"node:os\";\r\nimport { dirname, join } from \"node:path\";\r\n\r\nimport { BaseAdapter } from \"../base.js\";\r\nimport type { Adapter, HookReply, InstallContext, MemoryTarget, NormalizedEvent } from \"../spi.js\";\r\nimport type {\r\n ChangeRecord,\r\n DetectedPlatform,\r\n HealthCheck,\r\n HookEventName,\r\n HookParadigm,\r\n HookResponse,\r\n NotificationEvent,\r\n PlatformCapabilities,\r\n PlatformId,\r\n PostToolUseEvent,\r\n PostCompactEvent,\r\n PreCompactEvent,\r\n PreToolUseEvent,\r\n SessionEndEvent,\r\n SessionStartEvent,\r\n ServerDef,\r\n StopEvent,\r\n SubagentStopEvent,\r\n UserPromptSubmitEvent,\r\n} from \"../../core/types.js\";\r\nimport { removeFromObjectMap, upsertInObjectMap } from \"../../core/object-map.js\";\r\nimport { readYaml, writeYaml, yamlObjectMapCodec } from \"../../core/yaml.js\";\r\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\r\nimport {\r\n buildHomeBinHookCommand,\r\n buildWrappedStdio,\r\n isHomeBinActionCommand,\r\n isHomeBinHookCommand,\r\n} from \"../../core/spawn.js\";\r\nimport { renderSkillMd } from \"../claude-code/render.js\";\r\n\r\nconst HOST: PlatformId = \"hermes\";\r\n/** Root key under which Hermes stores MCP servers in config.yaml (snake_case). */\r\nconst MCP_ROOT_KEY = \"mcp_servers\";\r\n/** Top-level key under which Hermes stores shell hooks in config.yaml. */\r\nconst HOOKS_KEY = \"hooks\";\r\n/**\r\n * Top-level map under which Hermes stores `/<id>` slash commands. A\r\n * `{ type: \"exec\", command }` entry runs the shell command directly, bypassing\r\n * the LLM — the action emitter's target.\r\n */\r\nconst QUICK_COMMANDS_KEY = \"quick_commands\";\r\n/** Default per-hook timeout (seconds) when the connector declares none. */\r\nconst DEFAULT_HOOK_TIMEOUT = 60;\r\n/**\r\n * Documented per-hook timeout bounds (seconds). Hermes' hooks.md states\r\n * `timeout: <seconds>` is \"default 60, capped at 300\" and that `timeout > 300`\r\n * is clamped with a warning by the host. There is no documented minimum; the\r\n * 1s floor is defensive so a sub-second connector timeoutMs never rounds to 0.\r\n */\r\nconst HOOK_TIMEOUT_MAX = 300;\r\nconst HOOK_TIMEOUT_MIN = 1;\r\n\r\n/** One Hermes quick-command entry (a `/<id>` slash command). */\r\ninterface HermesQuickCommand {\r\n type: \"exec\";\r\n command: string;\r\n}\r\n\r\n/**\r\n * Canonical → Hermes native hook event name. Hermes keys its `hooks:` block by\r\n * its OWN snake_case lifecycle names (pre_tool_call / post_tool_call /\r\n * on_session_start / on_session_end — see docs/research/platform-research.json),\r\n * NOT the canonical PascalCase names. A connector event is only wired when it\r\n * appears here AND is declared by the connector; everything else is reported as\r\n * a warn/skip at install time.\r\n */\r\nconst EVENT_TO_HERMES: Partial<Record<HookEventName, string>> = {\r\n PreToolUse: \"pre_tool_call\",\r\n PostToolUse: \"post_tool_call\",\r\n SessionStart: \"on_session_start\",\r\n SessionEnd: \"on_session_end\",\r\n // Hermes is a STOP-ONLY subagent host: subagent_stop fires when a\r\n // delegate_task child exits (child_status ∈ completed/failed/interrupted/\r\n // error); there is NO subagent_start analog. PermissionRequest is also\r\n // deliberately ABSENT: Hermes' pre_approval_request/post_approval_response\r\n // hooks OBSERVE the approval prompt but carry no decision control, so a\r\n // PermissionRequest handler could never be honored — install skip-warns it.\r\n SubagentStop: \"subagent_stop\",\r\n};\r\n\r\n/** Hermes stdio MCP entry — portable field names (command/args/env). */\r\ninterface HermesStdioServer {\r\n command: string;\r\n args?: string[];\r\n env?: Record<string, string>;\r\n}\r\n\r\n/**\r\n * Hermes remote HTTP MCP entry — `{ url, headers? }` under the SAME mcp_servers\r\n * key (no transport/type discriminator). Per the Hermes Agent docs\r\n * (website/docs/user-guide/features/mcp.md \"HTTP servers\"); OAuth servers add\r\n * `auth: oauth`, which AC's static-header model does not express.\r\n */\r\ninterface HermesHttpServer {\r\n url: string;\r\n headers?: Record<string, string>;\r\n}\r\n\r\n/** One Hermes shell-hook entry. */\r\ninterface HermesHookEntry {\r\n /** Tool-name matcher (empty = all). Tool events only; \"\" elsewhere. */\r\n matcher: string;\r\n /** The home-bin hook command Hermes invokes (event JSON on stdin). */\r\n command: string;\r\n /** Hook timeout in seconds. */\r\n timeout: number;\r\n}\r\n\r\n/**\r\n * Raw Hermes hook stdin payload — the ACTUAL wire shape emitted by Hermes'\r\n * `agent/shell_hooks.py::_serialize_payload` (NousResearch/hermes-agent), NOT a\r\n * Claude-like guess. The serializer keeps ONLY these top-level keys:\r\n *\r\n * { hook_event_name, tool_name, tool_input, session_id, cwd, extra }\r\n *\r\n * where `tool_name`/`tool_input` come from the invoke kwargs `tool_name`/`args`,\r\n * `session_id` from `session_id` ?? `parent_session_id`, and EVERY other kwarg\r\n * is nested under `extra` (see `_TOP_LEVEL_PAYLOAD_KEYS` = {tool_name, args,\r\n * session_id, parent_session_id}). So all per-event result/status/child fields\r\n * are read from `extra.*` — top-level reads for them are always undefined.\r\n */\r\ninterface HermesWireInput {\r\n session_id?: string;\r\n cwd?: string;\r\n hook_event_name?: string;\r\n tool_name?: string;\r\n /** Top-level: the serializer lifts the `args` kwarg here (PreToolUse). */\r\n tool_input?: Record<string, unknown>;\r\n /**\r\n * Every non-allowlisted invoke kwarg nests here. Per-event contents (verified\r\n * against the host source):\r\n * - post_tool_call: result, status (\"ok\"|\"error\"), error_type, error_message,\r\n * duration_ms, task_id, tool_call_id, turn_id, api_request_id, middleware_trace\r\n * - subagent_stop: child_session_id, child_role, child_summary, child_status\r\n * (\"completed\"|\"failed\"|\"interrupted\"|\"error\"), duration_ms, parent_turn_id\r\n * - on_session_start: model, platform\r\n * - on_session_end: completed (bool), interrupted (bool), task_id, turn_id,\r\n * model, platform\r\n */\r\n extra?: HermesExtra;\r\n /** Injected by the entrypoint so the runtime knows which connector to dispatch. */\r\n connector?: string;\r\n}\r\n\r\n/** The `extra` envelope — non-allowlisted invoke kwargs, by event (see above). */\r\ninterface HermesExtra {\r\n // post_tool_call\r\n result?: unknown;\r\n status?: string;\r\n error_type?: string;\r\n error_message?: string;\r\n // subagent_stop\r\n child_session_id?: string;\r\n child_role?: string;\r\n child_summary?: string;\r\n child_status?: string;\r\n // on_session_end\r\n completed?: boolean;\r\n interrupted?: boolean;\r\n // on_session_start / on_session_end\r\n model?: string;\r\n platform?: string;\r\n // ── Defensive only ──────────────────────────────────────────────────────\r\n // Hermes does NOT fire UserPromptSubmit / PreCompact / PostCompact / Stop /\r\n // Notification (the matching capabilities are false; install warn-skips them).\r\n // Were any ever mis-routed here, the serializer would still nest its kwargs\r\n // under `extra`, so these defensive parse arms read from extra — they never\r\n // resurface as invented top-level fields.\r\n prompt?: string;\r\n trigger?: string;\r\n stop_hook_active?: boolean;\r\n message?: string;\r\n}\r\n\r\nexport class HermesAdapter extends BaseAdapter implements Adapter {\r\n readonly id: PlatformId = HOST;\r\n readonly name = \"Hermes Agent\";\r\n readonly paradigm: HookParadigm = \"json-stdio\";\r\n\r\n readonly capabilities: PlatformCapabilities = {\r\n // Memory surface: AGENTS.md-first managed block. memoryTargets below probes\r\n // for .hermes.md / HERMES.md (first context category wins on hermes —\r\n // AGENTS.md is ignored when they exist); ~/.hermes holds identity/volatile\r\n // files (SOUL.md, MEMORY.md), not a rules surface → user-scope skip-warn.\r\n supportsMemory: true,\r\n preToolUse: true,\r\n postToolUse: true,\r\n preCompact: false,\r\n // Hermes exposes on_session_start / on_session_end lifecycle hooks.\r\n sessionStart: true,\r\n sessionEnd: true,\r\n userPromptSubmit: false,\r\n stop: false,\r\n notification: false,\r\n // Newer events: Hermes ships subagent_stop (stop-only — no subagent_start\r\n // analog). permissionRequest stays unset because pre_approval_request is\r\n // observe-only (no decision control); postToolUseFailure stays unset (a\r\n // tool failure arrives merged into post_tool_call's result, not as a\r\n // dedicated event). Install reports the standard skip-warn for those.\r\n subagentStop: true,\r\n // Shell hooks cannot rewrite tool args/output in-process.\r\n canModifyArgs: false,\r\n canModifyOutput: false,\r\n canInjectSessionContext: true,\r\n // Hermes has no SSE transport.\r\n transports: [\"stdio\", \"http\"],\r\n // Content surface: Hermes auto-discovers dir-per-skill SKILL.md from its\r\n // LOCAL skills root ~/.hermes/skills — the \"single source of truth,\r\n // read-write\" dir (hermes-agent.nousresearch.com/docs/user-guide/features/\r\n // skills, fetched 2026-06-16). The directory name becomes the skill's\r\n // install slug; frontmatter is { name, description } + optional\r\n // metadata.hermes.*. USER scope only — there is no documented hermes-owned\r\n // project skills dir (~/.agents/skills is the cross-tool external dir, not\r\n // ours), so a project-scope install skip-warns via the base default.\r\n supportsSkills: true,\r\n // Native passthrough hooks: Hermes documents many host-specific lifecycle\r\n // events with NO canonical analog — pre_llm_call / post_llm_call /\r\n // on_session_finalize / on_session_reset / pre_gateway_dispatch /\r\n // pre_approval_request / post_approval_response / transform_tool_result\r\n // (docs/research/platform-research.json). They are host-specific (below the\r\n // >=3-host core bar; docs/research/host-specific-hook-events-design.md). A\r\n // connector reaches them by declaring platforms[\"hermes\"].nativeHooks;\r\n // installHooks files those event-name keys verbatim into the YAML hooks map,\r\n // and the generic uninstall reverses them.\r\n supportsNativeHooks: true,\r\n // Actions surface: Hermes ships `quick_commands.<id>: { type: \"exec\",\r\n // command }` — a `/<id>` slash command that runs the shell command directly,\r\n // bypassing the LLM (hermes-agent.nousresearch.com/docs/user-guide/cli:\r\n // \"custom commands that run shell commands instantly without invoking the\r\n // LLM\"). We emit one per declared action bound to the home-bin action verb.\r\n supportsActions: true,\r\n };\r\n\r\n // ── Detection ────────────────────────────────────────────────────────────\r\n\r\n detectInstalled(_projectDir: string): DetectedPlatform {\r\n const configPath = this.userConfigPath();\r\n const configDir = dirname(configPath);\r\n const installed = existsSync(configDir) || existsSync(configPath);\r\n return {\r\n id: this.id,\r\n name: this.name,\r\n installed,\r\n paradigm: this.paradigm,\r\n capabilities: this.capabilities,\r\n configPath,\r\n scope: \"user\",\r\n reason: installed\r\n ? `found Hermes config at ${configPath}`\r\n : `no Hermes config at ${configPath}`,\r\n confidence: installed ? \"high\" : \"low\",\r\n };\r\n }\r\n\r\n // ── Memory surface: .hermes.md / HERMES.md shadow probe (project) ────────\r\n // Hermes assembles project context by FIRST CATEGORY WINS: .hermes.md or\r\n // HERMES.md (cwd walking up to the git root) → AGENTS.md (cwd only) →\r\n // CLAUDE.md (cwd only). When a hermes-native file exists our block must live\r\n // there or it is never loaded. Reason strings note the cwd-only AGENTS.md\r\n // read and hermes' ~20k-chars-per-file truncation.\r\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\r\n if (this.memoryOverride(ctx)?.path || ctx.scope !== \"project\") {\r\n return super.memoryTargets(ctx); // user scope: no rules surface → skip-warn\r\n }\r\n for (const name of [\".hermes.md\", \"HERMES.md\"]) {\r\n const candidate = join(ctx.projectDir, name);\r\n if (existsSync(candidate)) {\r\n return [\r\n {\r\n path: candidate,\r\n reason: `${name} shadows AGENTS.md on hermes (first context category wins)`,\r\n budgetBytes: 18 * 1024, // hermes truncates each context file at ~20k chars\r\n },\r\n ];\r\n }\r\n }\r\n return [\r\n {\r\n path: join(ctx.projectDir, \"AGENTS.md\"),\r\n reason:\r\n \"AGENTS.md (hermes reads it from the cwd only — run from the project root; ~20k chars/file truncation)\",\r\n budgetBytes: 18 * 1024,\r\n },\r\n ];\r\n }\r\n\r\n // ── Native paths (server + hooks share the SAME file) ─────────────────────\r\n\r\n override getConfigDir(_ctx: InstallContext): string {\r\n return dirname(this.userConfigPath());\r\n }\r\n\r\n override getServerConfigPath(_ctx: InstallContext): string {\r\n return this.userConfigPath();\r\n }\r\n\r\n /** Same file as the server config — Hermes hooks live in config.yaml. */\r\n override getHookConfigPath(_ctx: InstallContext): string {\r\n return this.userConfigPath();\r\n }\r\n\r\n private userConfigPath(): string {\r\n return join(homedir(), \".hermes\", \"config.yaml\");\r\n }\r\n\r\n // ── MCP server install / uninstall (YAML mcp_servers) ─────────────────────\r\n\r\n override installServer(ctx: InstallContext): ChangeRecord[] {\r\n const { connector, dryRun } = ctx;\r\n const path = this.getServerConfigPath(ctx);\r\n const server = this.effectiveServer(ctx);\r\n\r\n if (!server) {\r\n return [\r\n {\r\n platform: this.id,\r\n action: \"skip\",\r\n path,\r\n detail: connector.server\r\n ? \"server registration disabled for hermes\"\r\n : \"connector declares no MCP server\",\r\n },\r\n ];\r\n }\r\n // Hermes registers stdio sidecars ({command,args,env}) AND remote HTTP\r\n // servers ({url,headers}) under the same mcp_servers key. It has no SSE\r\n // transport (docs: website/docs/user-guide/features/mcp.md), so anything\r\n // else is reported, never silently dropped.\r\n const isStdio = server.transport === \"stdio\" && !!server.command;\r\n const isHttp = server.transport === \"http\" && !!server.url;\r\n if (!isStdio && !isHttp) {\r\n return [\r\n {\r\n platform: this.id,\r\n action: \"skip\",\r\n path,\r\n detail: `transport \"${server.transport}\" not registrable in ${MCP_ROOT_KEY} (stdio + http only)`,\r\n },\r\n ];\r\n }\r\n\r\n const symlink = this.symlinkPathWarning(path);\r\n if (symlink) return [symlink];\r\n\r\n const entry = this.renderServerEntry(ctx, server);\r\n\r\n return [\r\n upsertInObjectMap({\r\n codec: yamlObjectMapCodec(),\r\n rootKey: MCP_ROOT_KEY,\r\n policy: \"coerce\",\r\n platform: this.id,\r\n configPath: path,\r\n entryId: connector.id,\r\n entry,\r\n dryRun,\r\n }),\r\n ];\r\n }\r\n\r\n override uninstallServer(ctx: InstallContext): ChangeRecord[] {\r\n const { connector, dryRun } = ctx;\r\n const path = this.getServerConfigPath(ctx);\r\n const symlink = this.symlinkPathWarning(path);\r\n if (symlink) return [symlink];\r\n\r\n return [\r\n removeFromObjectMap({\r\n codec: yamlObjectMapCodec(),\r\n rootKey: MCP_ROOT_KEY,\r\n policy: \"coerce\",\r\n platform: this.id,\r\n configPath: path,\r\n entryId: connector.id,\r\n dryRun,\r\n }),\r\n ];\r\n }\r\n\r\n /**\r\n * Render the MCP entry — a remote HTTP `{ url, headers? }` or a stdio sidecar\r\n * `{ command, args, env }`. Hermes has no native interpolation, so env-refs\r\n * resolve to literals here. The stdio path honors the telemetry serve-wrapper.\r\n */\r\n private renderServerEntry(\r\n ctx: InstallContext,\r\n server: ServerDef,\r\n ): HermesStdioServer | HermesHttpServer {\r\n // Remote HTTP — { url, headers? }. Never telemetry-wrapped (a URL has no\r\n // local command to route through the serve proxy). Hermes has no native env\r\n // token, so ${env:VAR} refs in url/headers resolve to literals.\r\n if (server.transport === \"http\") {\r\n const entry: HermesHttpServer = { url: resolveEnvRefsDeep(server.url ?? \"\") };\r\n if (server.headers && Object.keys(server.headers).length > 0) {\r\n const headers: Record<string, string> = {};\r\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.headers))) {\r\n headers[k] = String(v);\r\n }\r\n entry.headers = headers;\r\n }\r\n return entry;\r\n }\r\n\r\n let command = server.command as string;\r\n let args = [...(server.args ?? [])];\r\n\r\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\r\n\r\n command = resolveEnvRefsDeep(command);\r\n args = resolveEnvRefsDeep(args);\r\n\r\n const entry: HermesStdioServer = { command };\r\n if (args.length > 0) entry.args = args;\r\n if (server.env && Object.keys(server.env).length > 0) {\r\n const env: Record<string, string> = {};\r\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.env))) {\r\n env[k] = String(v);\r\n }\r\n entry.env = env;\r\n }\r\n return entry;\r\n }\r\n\r\n // ── Hook install / uninstall (YAML hooks map in the SAME config.yaml) ─────\r\n\r\n override installHooks(ctx: InstallContext): ChangeRecord[] {\r\n const { connector, dryRun } = ctx;\r\n const path = this.getHookConfigPath(ctx);\r\n const override = connector.platforms[HOST];\r\n\r\n // `hooks: false` disables only the NORMALIZED events. nativeHooks is a\r\n // sibling, hermes-scoped declaration on the same override and installs\r\n // regardless.\r\n const events = override?.hooks === false ? [] : connector.hookEvents;\r\n const nativeHooks = override?.nativeHooks ?? {};\r\n const nativeEvents = Object.keys(nativeHooks);\r\n\r\n if (events.length === 0 && nativeEvents.length === 0) {\r\n return [\r\n {\r\n platform: this.id,\r\n action: \"skip\",\r\n path,\r\n detail: override?.hooks === false ? \"hooks disabled for hermes\" : \"connector declares no hooks\",\r\n },\r\n ];\r\n }\r\n\r\n const symlink = this.symlinkPathWarning(path);\r\n if (symlink) return [symlink];\r\n\r\n const cfg = readYaml<Record<string, unknown>>(path) ?? {};\r\n const hooks = this.hooksBucket(cfg);\r\n const changes: ChangeRecord[] = [];\r\n let mutated = false;\r\n\r\n for (const event of events) {\r\n const hermesEvent = EVENT_TO_HERMES[event];\r\n if (!hermesEvent) {\r\n // No Hermes equivalent for this canonical event — report and skip.\r\n changes.push({\r\n platform: this.id,\r\n action: \"warn\",\r\n path,\r\n detail: `${event} has no Hermes hook equivalent — skipped`,\r\n });\r\n continue;\r\n }\r\n\r\n // The hook command keeps the CANONICAL event token so the runtime\r\n // dispatcher (parseEvent/formatReply) stays consistent; only the YAML KEY\r\n // the entry is filed under is the native Hermes name.\r\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\r\n const matcher = connector.hooks[event]?.matcher ?? \"\";\r\n const timeout = this.hookTimeout(connector.server);\r\n const desired: HermesHookEntry = { matcher, command, timeout };\r\n\r\n const bucket = Array.isArray(hooks[hermesEvent])\r\n ? (hooks[hermesEvent] as HermesHookEntry[])\r\n : (hooks[hermesEvent] = [] as HermesHookEntry[]);\r\n const idx = bucket.findIndex((e) => this.isOurCommand(e?.command, ctx));\r\n\r\n if (idx >= 0) {\r\n if (JSON.stringify(bucket[idx]) === JSON.stringify(desired)) {\r\n changes.push({ platform: this.id, action: \"skip\", path, detail: `${HOOKS_KEY}.${hermesEvent}` });\r\n continue;\r\n }\r\n bucket[idx] = desired;\r\n changes.push({ platform: this.id, action: \"update\", path, detail: `${HOOKS_KEY}.${hermesEvent}` });\r\n } else {\r\n bucket.push(desired);\r\n changes.push({ platform: this.id, action: \"create\", path, detail: `${HOOKS_KEY}.${hermesEvent}` });\r\n }\r\n mutated = true;\r\n }\r\n\r\n // NATIVE passthrough events: Hermes-native event-name keys (e.g. pre_llm_call,\r\n // transform_tool_result) filed VERBATIM into the YAML hooks map — no\r\n // EVENT_TO_HERMES mapping, since they ARE Hermes events. Same entry shape +\r\n // idempotency, matched by EXACT command so a native key coinciding with a\r\n // mapped canonical key never clobbers it.\r\n for (const event of nativeEvents) {\r\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\r\n const matcher = nativeHooks[event]?.matcher ?? \"\";\r\n const timeout = this.hookTimeout(connector.server);\r\n const desired: HermesHookEntry = { matcher, command, timeout };\r\n const bucket = Array.isArray(hooks[event])\r\n ? (hooks[event] as HermesHookEntry[])\r\n : (hooks[event] = [] as HermesHookEntry[]);\r\n const idx = bucket.findIndex((e) => e?.command === command);\r\n if (idx >= 0) {\r\n if (JSON.stringify(bucket[idx]) === JSON.stringify(desired)) {\r\n changes.push({ platform: this.id, action: \"skip\", path, detail: `${HOOKS_KEY}.${event} (native)` });\r\n } else {\r\n bucket[idx] = desired;\r\n changes.push({ platform: this.id, action: \"update\", path, detail: `${HOOKS_KEY}.${event} (native)` });\r\n mutated = true;\r\n }\r\n } else {\r\n bucket.push(desired);\r\n changes.push({ platform: this.id, action: \"create\", path, detail: `${HOOKS_KEY}.${event} (native)` });\r\n mutated = true;\r\n }\r\n }\r\n\r\n if (mutated) writeYaml(path, cfg, dryRun);\r\n return changes;\r\n }\r\n\r\n override uninstallHooks(ctx: InstallContext): ChangeRecord[] {\r\n const path = this.getHookConfigPath(ctx);\r\n const symlink = this.symlinkPathWarning(path);\r\n if (symlink) return [symlink];\r\n\r\n const cfg = readYaml<Record<string, unknown>>(path);\r\n const hooksRaw = cfg?.[HOOKS_KEY];\r\n if (\r\n !cfg ||\r\n !hooksRaw ||\r\n typeof hooksRaw !== \"object\" ||\r\n Array.isArray(hooksRaw)\r\n ) {\r\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks section present\" }];\r\n }\r\n const hooks = hooksRaw as Record<string, unknown>;\r\n\r\n const changes: ChangeRecord[] = [];\r\n let mutated = false;\r\n for (const event of Object.keys(hooks)) {\r\n const bucket = hooks[event];\r\n if (!Array.isArray(bucket)) continue;\r\n const kept = (bucket as HermesHookEntry[]).filter(\r\n (e) => !this.isOurCommand(e?.command, ctx),\r\n );\r\n if (kept.length === bucket.length) continue;\r\n mutated = true;\r\n if (kept.length > 0) hooks[event] = kept;\r\n else delete hooks[event];\r\n changes.push({\r\n platform: this.id,\r\n action: \"remove\",\r\n path,\r\n detail: `${HOOKS_KEY}.${event} (${bucket.length - kept.length})`,\r\n });\r\n }\r\n\r\n if (mutated) writeYaml(path, cfg, ctx.dryRun);\r\n if (changes.length === 0) {\r\n return [{ platform: this.id, action: \"skip\", path, detail: \"no matching hook entries\" }];\r\n }\r\n return changes;\r\n }\r\n\r\n // ── Action surface (quick_commands map in the SAME config.yaml) ───────────\r\n // Each declared action emits `quick_commands.<id>: { type: \"exec\", command }`\r\n // where command is the home-bin action verb — a `/<id>` slash command that\r\n // runs it directly, bypassing the LLM. MERGE-preserve: never clobber another\r\n // entry. Set-if-absent per id; if `quick_commands.<id>` exists and is NOT\r\n // ours, skip-warn (the configPatch ownership semantics).\r\n\r\n override installActions(ctx: InstallContext): ChangeRecord[] {\r\n const { connector, dryRun } = ctx;\r\n const path = this.getHookConfigPath(ctx);\r\n\r\n if (connector.platforms[HOST]?.actions === false) {\r\n return [{ platform: this.id, action: \"skip\", path, detail: \"actions disabled for hermes\" }];\r\n }\r\n const triggers = this.actionTriggers(ctx);\r\n if (triggers.length === 0) {\r\n return [{ platform: this.id, action: \"skip\", path, detail: \"connector declares no actions\" }];\r\n }\r\n\r\n const symlink = this.symlinkPathWarning(path);\r\n if (symlink) return [symlink];\r\n\r\n const cfg = readYaml<Record<string, unknown>>(path) ?? {};\r\n const bucket = this.objectBucket(cfg, QUICK_COMMANDS_KEY);\r\n const changes: ChangeRecord[] = [];\r\n let mutated = false;\r\n\r\n for (const trigger of triggers) {\r\n const desired: HermesQuickCommand = { type: \"exec\", command: trigger.command };\r\n const existing = bucket[trigger.id];\r\n if (existing !== undefined) {\r\n // Set-if-absent: only re-write an entry that is already OURS (an\r\n // exec entry whose command is our action verb for this connector).\r\n if (!this.isOurQuickCommand(existing, ctx)) {\r\n changes.push({\r\n platform: this.id,\r\n action: \"warn\",\r\n path,\r\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id} exists and is not ours — skipped`,\r\n });\r\n continue;\r\n }\r\n if (JSON.stringify(existing) === JSON.stringify(desired)) {\r\n changes.push({\r\n platform: this.id,\r\n action: \"skip\",\r\n path,\r\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id}`,\r\n });\r\n continue;\r\n }\r\n bucket[trigger.id] = desired;\r\n changes.push({\r\n platform: this.id,\r\n action: \"update\",\r\n path,\r\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id}`,\r\n });\r\n } else {\r\n bucket[trigger.id] = desired;\r\n changes.push({\r\n platform: this.id,\r\n action: \"create\",\r\n path,\r\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id}`,\r\n });\r\n }\r\n mutated = true;\r\n }\r\n\r\n if (mutated) writeYaml(path, cfg, dryRun);\r\n return changes;\r\n }\r\n\r\n override uninstallActions(ctx: InstallContext): ChangeRecord[] {\r\n const path = this.getHookConfigPath(ctx);\r\n const symlink = this.symlinkPathWarning(path);\r\n if (symlink) return [symlink];\r\n\r\n const cfg = readYaml<Record<string, unknown>>(path);\r\n const bucketRaw = cfg?.[QUICK_COMMANDS_KEY];\r\n if (\r\n !cfg ||\r\n !bucketRaw ||\r\n typeof bucketRaw !== \"object\" ||\r\n Array.isArray(bucketRaw)\r\n ) {\r\n return [{ platform: this.id, action: \"skip\", path, detail: \"no quick_commands section present\" }];\r\n }\r\n const bucket = bucketRaw as Record<string, unknown>;\r\n\r\n const changes: ChangeRecord[] = [];\r\n let mutated = false;\r\n // Remove ONLY our exec entries; leave foreign entries (and the map itself\r\n // when any remain) untouched.\r\n for (const id of Object.keys(bucket)) {\r\n if (!this.isOurQuickCommand(bucket[id], ctx)) continue;\r\n delete bucket[id];\r\n mutated = true;\r\n changes.push({\r\n platform: this.id,\r\n action: \"remove\",\r\n path,\r\n detail: `${QUICK_COMMANDS_KEY}.${id}`,\r\n });\r\n }\r\n\r\n if (mutated) {\r\n // Drop an emptied map so we leave no orphan key behind.\r\n if (Object.keys(bucket).length === 0) delete cfg[QUICK_COMMANDS_KEY];\r\n writeYaml(path, cfg, ctx.dryRun);\r\n }\r\n if (changes.length === 0) {\r\n return [{ platform: this.id, action: \"skip\", path, detail: \"no matching quick_commands entries\" }];\r\n }\r\n return changes;\r\n }\r\n\r\n /** True when a quick-command entry is OUR exec action verb for this connector. */\r\n private isOurQuickCommand(entry: unknown, ctx: InstallContext): boolean {\r\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) return false;\r\n const e = entry as Partial<HermesQuickCommand>;\r\n if (e.type !== \"exec\" || typeof e.command !== \"string\") return false;\r\n return isHomeBinActionCommand(e.command, ctx.homeBinPath, ctx.connector.id);\r\n }\r\n\r\n /** True when a hook command is ours (anchored home-bin + connector id). */\r\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\r\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\r\n }\r\n\r\n private hookTimeout(server: ServerDef | undefined): number {\r\n const ms = server?.timeoutMs;\r\n if (typeof ms === \"number\" && ms > 0) {\r\n // Hermes documents `timeout: <seconds>` as \"default 60, capped at 300\";\r\n // a value > 300 is clamped with a warning by Hermes itself (see hooks.md\r\n // on NousResearch/hermes-agent). Clamp here so we never emit a value the\r\n // host would reject/cap. No documented minimum, but a positive timeoutMs\r\n // must not round down to 0 (an undocumented, ambiguous \"no/instant\"\r\n // timeout), so floor at 1s. In-range values (1000–300000ms) are unchanged.\r\n return Math.min(HOOK_TIMEOUT_MAX, Math.max(HOOK_TIMEOUT_MIN, Math.round(ms / 1000)));\r\n }\r\n return DEFAULT_HOOK_TIMEOUT;\r\n }\r\n\r\n // ── Content surface: skills (dir-per-skill SKILL.md) ─────────────────────\r\n // CONTENT-ONLY: pure native-file writers, mirroring goose/openclaw. No\r\n // runtime dispatch, no home-bin pointer, no telemetry wrap. Idempotent\r\n // (byte-identical → skip) via writeContentFile and reversible via\r\n // removeContentFile + removeDirIfEmpty. Honors platforms[\"hermes\"].skills\r\n // === false. No config.yaml entry — Hermes auto-discovers ~/.hermes/skills.\r\n //\r\n // USER scope only: ~/.hermes/skills/<name>/SKILL.md (the documented local,\r\n // read-write \"single source of truth\"). Project scope skip-warns — there is\r\n // no hermes-owned project skills dir documented.\r\n\r\n /** The user-scope skills ROOT dir (~/.hermes/skills). */\r\n private skillsDir(): string {\r\n return join(dirname(this.userConfigPath()), \"skills\");\r\n }\r\n\r\n /** Per-skill directory: ~/.hermes/skills/<name>. */\r\n private skillDir(name: string): string {\r\n return join(this.skillsDir(), name);\r\n }\r\n\r\n override installSkills(ctx: InstallContext): ChangeRecord[] {\r\n const { connector } = ctx;\r\n if (connector.platforms[HOST]?.skills === false) {\r\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for hermes\" }];\r\n }\r\n if (connector.skills.length === 0) {\r\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\r\n }\r\n if (ctx.scope !== \"user\") {\r\n // Hermes documents only the user-scope ~/.hermes/skills root; there is no\r\n // hermes-owned project skills dir. Report rather than guess a path.\r\n return [\r\n {\r\n platform: this.id,\r\n action: \"warn\",\r\n detail:\r\n `no project-scope skills dir on hermes (~/.hermes/skills is user-scope only); ` +\r\n `${connector.skills.length} skipped`,\r\n },\r\n ];\r\n }\r\n const changes: ChangeRecord[] = [];\r\n for (const skill of connector.skills) {\r\n const dir = this.skillDir(skill.name);\r\n // Guard a skills path occupied by a regular FILE (would throw ENOTDIR on\r\n // mkdir): skip-warn rather than crash (the cline `.clinerules`-is-a-file\r\n // precedent). The skills root or the per-skill dir is the likely culprit.\r\n const blockingFile = this.firstFileOnSkillPath(dir);\r\n if (blockingFile !== null) {\r\n changes.push({\r\n platform: this.id,\r\n action: \"warn\",\r\n path: blockingFile,\r\n detail: `${blockingFile} is a file, not a directory; skill \"${skill.name}\" skipped`,\r\n });\r\n continue;\r\n }\r\n changes.push(\r\n this.writeContentFile(join(dir, \"SKILL.md\"), renderSkillMd(skill), ctx.dryRun),\r\n );\r\n // Bundle any resource files beside SKILL.md (relative path → contents).\r\n // Defense-in-depth: skip+warn on any key that escapes the skill dir\r\n // (config-time validation already rejects these, but never trust input).\r\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\r\n const target = this.resolveWithin(dir, rel);\r\n if (target === null) {\r\n changes.push({\r\n platform: this.id,\r\n action: \"warn\",\r\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\r\n });\r\n continue;\r\n }\r\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\r\n }\r\n }\r\n return changes;\r\n }\r\n\r\n /**\r\n * Walk from the skills root (~/.hermes/skills) down to `leaf` and return the\r\n * FIRST segment that exists as a regular file (a mkdir there throws ENOTDIR),\r\n * else null — so installSkills can skip-warn instead of crashing.\r\n */\r\n private firstFileOnSkillPath(leaf: string): string | null {\r\n const root = this.skillsDir();\r\n const segments: string[] = [];\r\n let cur = leaf;\r\n while (cur.length >= root.length) {\r\n segments.unshift(cur);\r\n if (cur === root) break;\r\n const parent = dirname(cur);\r\n if (parent === cur) break;\r\n cur = parent;\r\n }\r\n for (const p of segments) {\r\n if (!existsSync(p)) return null;\r\n try {\r\n if (statSync(p).isFile()) return p;\r\n } catch {\r\n return null;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\r\n const { connector } = ctx;\r\n if (connector.skills.length === 0) {\r\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\r\n }\r\n if (ctx.scope !== \"user\") {\r\n // Nothing is written at project scope (install skip-warned), so nothing\r\n // to clean — report the same scope reason as install for symmetry.\r\n return [\r\n {\r\n platform: this.id,\r\n action: \"skip\",\r\n detail: \"no project-scope skills dir on hermes (user-scope only); nothing to remove\",\r\n },\r\n ];\r\n }\r\n const changes: ChangeRecord[] = [];\r\n for (const skill of connector.skills) {\r\n const dir = this.skillDir(skill.name);\r\n // Remove only the files we wrote (SKILL.md + declared resources), then the\r\n // skill dir itself when we own its full contents.\r\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\r\n for (const rel of Object.keys(skill.resources ?? {})) {\r\n const target = this.resolveWithin(dir, rel);\r\n if (target === null) continue; // never delete outside the skill dir\r\n changes.push(this.removeContentFile(target, ctx.dryRun));\r\n }\r\n // Only remove the skill dir when WE own its full contents — never rm -rf a\r\n // dir that still holds user-added / sibling-tool / shared files.\r\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\r\n }\r\n return changes;\r\n }\r\n\r\n // ── Diagnostics ──────────────────────────────────────────────────────────\r\n\r\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\r\n const path = this.getServerConfigPath(ctx);\r\n const id = ctx.connector.id;\r\n const homeBin = ctx.homeBinPath;\r\n const hookEvents = ctx.connector.hookEvents;\r\n return [\r\n {\r\n name: `${this.name}: config.yaml present`,\r\n check: () =>\r\n existsSync(path)\r\n ? { status: \"OK\", detail: path }\r\n : { status: \"FAIL\", detail: `not found: ${path}` },\r\n },\r\n {\r\n name: `${this.name}: ${MCP_ROOT_KEY}.${id} registered`,\r\n check: () => {\r\n // Only assert what the connector declares: a server-less connector\r\n // never writes an mcp entry, so its absence is healthy.\r\n if (!ctx.connector.server) return { status: \"OK\", detail: \"no MCP server declared\" };\r\n const cfg = readYaml<Record<string, unknown>>(path);\r\n const bucket = cfg?.[MCP_ROOT_KEY];\r\n const present =\r\n typeof bucket === \"object\" &&\r\n bucket !== null &&\r\n !Array.isArray(bucket) &&\r\n id in (bucket as Record<string, unknown>);\r\n return present\r\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${id}` }\r\n : { status: \"FAIL\", detail: `${MCP_ROOT_KEY}.${id} not found in ${path}` };\r\n },\r\n },\r\n {\r\n name: `${this.name}: hook command registered`,\r\n check: () => {\r\n if (hookEvents.length === 0) return { status: \"OK\", detail: \"no hooks declared\" };\r\n const cfg = readYaml<Record<string, unknown>>(path);\r\n const hooks = cfg?.[HOOKS_KEY];\r\n if (!hooks || typeof hooks !== \"object\" || Array.isArray(hooks)) {\r\n return { status: \"FAIL\", detail: `no ${HOOKS_KEY} section in ${path}` };\r\n }\r\n const registered = Object.values(hooks as Record<string, unknown>).some(\r\n (bucket) =>\r\n Array.isArray(bucket) &&\r\n (bucket as HermesHookEntry[]).some((e) =>\r\n isHomeBinHookCommand(e?.command, homeBin, id),\r\n ),\r\n );\r\n return registered\r\n ? { status: \"OK\", detail: \"hook command present\" }\r\n : { status: \"FAIL\", detail: `no hook for ${id} in ${path}` };\r\n },\r\n },\r\n ];\r\n }\r\n\r\n // ── Runtime: parse Hermes stdin JSON → normalized event ──────────────────\r\n\r\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\r\n const input = (raw ?? {}) as HermesWireInput;\r\n const base = {\r\n hostPlatform: HOST,\r\n connectorId: typeof input.connector === \"string\" ? input.connector : \"\",\r\n sessionId: typeof input.session_id === \"string\" ? input.session_id : \"\",\r\n ...(typeof input.cwd === \"string\" ? { projectDir: input.cwd } : {}),\r\n raw,\r\n } as const;\r\n\r\n switch (event) {\r\n case \"PreToolUse\": {\r\n const ev: PreToolUseEvent = {\r\n ...base,\r\n toolName: input.tool_name ?? \"\",\r\n toolInput: input.tool_input ?? {},\r\n };\r\n return ev;\r\n }\r\n case \"PostToolUse\": {\r\n // VERIFIED (NousResearch/hermes-agent model_tools.py:856-871 +\r\n // shell_hooks.py::_serialize_payload): post_tool_call's `result` kwarg is\r\n // NOT allowlisted, so it lands at extra.result — top-level tool_output/\r\n // tool_response are NEVER emitted. Read extra.result for the output.\r\n const extra = input.extra ?? {};\r\n const out = toStringOrUndefined(extra.result);\r\n // VERIFIED: there is no `is_error` boolean. The host emits status\r\n // (\"ok\"|\"error\") + error_type/error_message (model_tools.py:815-821,\r\n // _tool_result_observer_fields), all under extra. Derive isError from a\r\n // non-ok status or a present error_type; emit only when determinable.\r\n const isError =\r\n typeof extra.status === \"string\"\r\n ? extra.status !== \"ok\"\r\n : typeof extra.error_type === \"string\"\r\n ? true\r\n : undefined;\r\n const ev: PostToolUseEvent = {\r\n ...base,\r\n toolName: input.tool_name ?? \"\",\r\n toolInput: input.tool_input ?? {},\r\n ...(out !== undefined ? { toolOutput: out } : {}),\r\n ...(typeof isError === \"boolean\" ? { isError } : {}),\r\n };\r\n return ev;\r\n }\r\n case \"SessionStart\": {\r\n // VERIFIED (NousResearch/hermes-agent conversation_loop.py:340-344):\r\n // on_session_start is invoked with { session_id, model, platform } only —\r\n // there is NO `source`/start-reason kwarg (model/platform land under\r\n // extra). Hermes fires on_session_start ONLY for a brand-new session (not\r\n // on continuation), so the canonical \"startup\" is the single honest\r\n // value; there is no compact/resume/clear discriminator to normalize.\r\n const ev: SessionStartEvent = { ...base, source: \"startup\" };\r\n return ev;\r\n }\r\n case \"SessionEnd\": {\r\n // VERIFIED (NousResearch/hermes-agent turn_finalizer.py:415-423):\r\n // on_session_end is invoked with completed:bool / interrupted:bool (both\r\n // under extra) — there is NO top-level `reason` kwarg. Derive a reason\r\n // string from the two booleans (interrupted wins; else completed).\r\n const extra = input.extra ?? {};\r\n const reason =\r\n extra.interrupted === true\r\n ? \"interrupted\"\r\n : extra.completed === true\r\n ? \"completed\"\r\n : undefined;\r\n const ev: SessionEndEvent = {\r\n ...base,\r\n ...(reason !== undefined ? { reason } : {}),\r\n };\r\n return ev;\r\n }\r\n // The five arms below parse events Hermes does NOT fire (userPromptSubmit/\r\n // preCompact/stop/notification capabilities are false; PostCompact unset).\r\n // They stay as defensive normalizers for a manual/mis-routed dispatch, and\r\n // read from `extra` because that is the only envelope Hermes' serializer\r\n // produces — never an invented top-level field.\r\n case \"UserPromptSubmit\": {\r\n const extra = input.extra ?? {};\r\n const ev: UserPromptSubmitEvent = {\r\n ...base,\r\n prompt: typeof extra.prompt === \"string\" ? extra.prompt : \"\",\r\n };\r\n return ev;\r\n }\r\n case \"PreCompact\": {\r\n const extra = input.extra ?? {};\r\n const ev: PreCompactEvent = {\r\n ...base,\r\n ...(extra.trigger === \"auto\" || extra.trigger === \"manual\"\r\n ? { trigger: extra.trigger }\r\n : {}),\r\n };\r\n return ev;\r\n }\r\n case \"PostCompact\": {\r\n // Hermes does not fire PostCompact natively (postCompact unset →\r\n // warn-skip at install). Parsed defensively, mirroring PreCompact, so a\r\n // manual/mis-routed dispatch normalizes instead of hitting the guard.\r\n const extra = input.extra ?? {};\r\n const ev: PostCompactEvent = {\r\n ...base,\r\n ...(extra.trigger === \"auto\" || extra.trigger === \"manual\"\r\n ? { trigger: extra.trigger }\r\n : {}),\r\n };\r\n return ev;\r\n }\r\n case \"Stop\": {\r\n const extra = input.extra ?? {};\r\n const ev: StopEvent = {\r\n ...base,\r\n ...(typeof extra.stop_hook_active === \"boolean\"\r\n ? { stopHookActive: extra.stop_hook_active }\r\n : {}),\r\n };\r\n return ev;\r\n }\r\n case \"Notification\": {\r\n const extra = input.extra ?? {};\r\n const ev: NotificationEvent = {\r\n ...base,\r\n message: typeof extra.message === \"string\" ? extra.message : \"\",\r\n };\r\n return ev;\r\n }\r\n case \"SubagentStop\": {\r\n // VERIFIED (NousResearch/hermes-agent delegate_tool.py:2520-2529): the\r\n // subagent_stop invoke passes parent_session_id, child_session_id,\r\n // child_role, child_summary, child_status, duration_ms. Only\r\n // parent_session_id is allowlisted (→ top-level session_id); EVERY child_*\r\n // field nests under extra. So the id/role/output all come from extra.* —\r\n // top-level agent_id/agent_type/child_id/last_assistant_message/\r\n // stop_hook_active are NEVER emitted by Hermes. child_status (∈ completed/\r\n // failed/interrupted/error) stays accessible via `raw`.\r\n const extra = input.extra ?? {};\r\n const ev: SubagentStopEvent = {\r\n ...base,\r\n ...(typeof extra.child_session_id === \"string\"\r\n ? { agentId: extra.child_session_id }\r\n : {}),\r\n ...(typeof extra.child_role === \"string\"\r\n ? { agentType: extra.child_role }\r\n : {}),\r\n ...(typeof extra.child_summary === \"string\"\r\n ? { lastAssistantMessage: extra.child_summary }\r\n : {}),\r\n };\r\n return ev;\r\n }\r\n case \"PermissionRequest\":\r\n case \"PostToolUseFailure\":\r\n case \"SubagentStart\": {\r\n // No Hermes analog: pre_approval_request is observe-only (no decision\r\n // control), tool failures arrive merged into post_tool_call, and there\r\n // is no subagent_start. Install already skip-warns these; a runtime\r\n // dispatch is a mis-route — fail loudly.\r\n throw new Error(`unsupported hermes hook event: ${String(event)}`);\r\n }\r\n default: {\r\n const _never: never = event;\r\n throw new Error(`unsupported hermes hook event: ${String(_never)}`);\r\n }\r\n }\r\n }\r\n\r\n // ── Runtime: normalized response → Hermes native hook reply ──────────────\r\n // Hermes shell hooks read a JSON reply from stdout (exit 0 = allow). We emit a\r\n // Claude-like `hookSpecificOutput` wrapper; if Hermes' exact reply schema\r\n // differs, this is the single place to adjust the mapping.\r\n\r\n formatReply(event: HookEventName, response: HookResponse): HookReply {\r\n const decision = response.decision ?? \"allow\";\r\n\r\n if (decision === \"deny\") {\r\n // SubagentStop deny carries Stop semantics — it keeps the subagent\r\n // running with `reason` as its next instruction — and (like Claude's\r\n // Stop class) is honored only as the TOP-LEVEL {\"decision\":\"block\",\r\n // \"reason\"}, not as a permissionDecision envelope.\r\n if (event === \"SubagentStop\") {\r\n return this.stdout({\r\n decision: \"block\",\r\n reason: response.reason ?? \"Blocked by hook\",\r\n });\r\n }\r\n return this.stdout({\r\n hookSpecificOutput: {\r\n hookEventName: event,\r\n permissionDecision: \"deny\",\r\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\r\n },\r\n });\r\n }\r\n\r\n if (decision === \"ask\") {\r\n return this.stdout({\r\n hookSpecificOutput: {\r\n hookEventName: event,\r\n permissionDecision: \"ask\",\r\n permissionDecisionReason: response.reason ?? \"Confirmation required by hook\",\r\n },\r\n });\r\n }\r\n\r\n if (decision === \"context\" && response.additionalContext) {\r\n return this.stdout({\r\n hookSpecificOutput: { hookEventName: event, additionalContext: response.additionalContext },\r\n });\r\n }\r\n\r\n // allow / modify (unsupported — shell hooks can't rewrite args) / void.\r\n return { exitCode: 0 };\r\n }\r\n\r\n private stdout(payload: unknown): HookReply {\r\n return { exitCode: 0, stdout: JSON.stringify(payload) };\r\n }\r\n\r\n // ── Internal helpers ──────────────────────────────────────────────────────\r\n\r\n /** Resolve the per-platform server override into an effective ServerDef. */\r\n private effectiveServer(ctx: InstallContext): ServerDef | undefined {\r\n const override = ctx.connector.platforms[this.id]?.server;\r\n if (override === false) return undefined;\r\n const base = ctx.connector.server;\r\n if (!base) return undefined;\r\n return override && typeof override === \"object\" ? { ...base, ...override } : base;\r\n }\r\n\r\n /** Get-or-create an object bucket (map) at `cfg[key]`. */\r\n private objectBucket(cfg: Record<string, unknown>, key: string): Record<string, unknown> {\r\n const existing = cfg[key];\r\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\r\n return existing as Record<string, unknown>;\r\n }\r\n const fresh: Record<string, unknown> = {};\r\n cfg[key] = fresh;\r\n return fresh;\r\n }\r\n\r\n /** Get-or-create the hooks map at `cfg.hooks`. */\r\n private hooksBucket(cfg: Record<string, unknown>): Record<string, unknown> {\r\n return this.objectBucket(cfg, HOOKS_KEY);\r\n }\r\n}\r\n\r\n/** Coerce an unknown value into a string for the normalized event. */\r\nfunction toStringOrUndefined(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\nexport const adapter = new HermesAdapter();\r\nexport default adapter;\r\n"],"mappings":"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","names":["entry"]}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
openSqlite
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-XZWMJLIT.js";
|
|
5
5
|
import {
|
|
6
6
|
firstExistingRoot
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KM2YXO6V.js";
|
|
8
8
|
import {
|
|
9
9
|
emptyTokens,
|
|
10
10
|
inferProvider
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-7PSNXUFK.js";
|
|
12
12
|
|
|
13
13
|
// src/usage/readers/hermes.ts
|
|
14
14
|
import { join } from "path";
|
|
@@ -193,4 +193,4 @@ var hermes_default = hermesReader;
|
|
|
193
193
|
export {
|
|
194
194
|
hermes_default as default
|
|
195
195
|
};
|
|
196
|
-
//# sourceMappingURL=hermes-
|
|
196
|
+
//# sourceMappingURL=hermes-MF3NX4ZY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/usage/readers/hermes.ts"],"sourcesContent":["/**\r\n * usage/readers/hermes — Hermes Agent usage reader (SQLite, sessions table).\r\n *\r\n * Faithful port of tokscale sessions/hermes.rs. Hermes stores one aggregated row\r\n * per session in a `sessions` table inside a single SQLite database:\r\n * • ~/.hermes/state.db\r\n * • $HERMES_HOME/state.db (when HERMES_HOME is set, non-empty)\r\n * (the AGENT_CONNECTOR_HERMES_DIR override + the ~/.hermes default are resolved by\r\n * paths.ts hostRoots(\"hermes\"); HERMES_HOME is honored here, ahead of those, to\r\n * match the Rust storage-path spec which the fixed paths.ts does not encode.)\r\n *\r\n * One SELECT pulls every session that carries a model and at least one token/cost\r\n * signal (port of the Rust query verbatim):\r\n * SELECT id, model, billing_provider, started_at, message_count,\r\n * input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,\r\n * reasoning_tokens, estimated_cost_usd, actual_cost_usd\r\n * FROM sessions\r\n * WHERE model IS NOT NULL AND TRIM(model) != ''\r\n * AND ( COALESCE(input_tokens,0) > 0\r\n * OR COALESCE(output_tokens,0) > 0\r\n * OR COALESCE(cache_read_tokens,0) > 0\r\n * OR COALESCE(cache_write_tokens,0) > 0\r\n * OR COALESCE(reasoning_tokens,0) > 0\r\n * OR COALESCE(actual_cost_usd, estimated_cost_usd, 0) > 0 )\r\n *\r\n * Token extraction (flat columns, no JSON nesting — each NULL → 0, clamped ≥ 0):\r\n * input = input_tokens\r\n * output = output_tokens\r\n * cacheRead = cache_read_tokens\r\n * cacheWrite = cache_write_tokens\r\n * reasoning = reasoning_tokens\r\n * Cost = actual_cost_usd ?? estimated_cost_usd ?? 0 (clamped ≥ 0, prefer actual).\r\n *\r\n * Model: the `model` column (the WHERE already drops null/blank). Provider (port of\r\n * resolved_provider): canonical_provider() of a non-blank `billing_provider`, else\r\n * inferProvider(model), else \"hermes\". Timestamp: `started_at` (f64) disambiguated\r\n * seconds-vs-milliseconds (> 1e12 → ms as-is, else × 1000). Session id = the `id`\r\n * column, which is also the dedup key (one row per session). messageCount =\r\n * `message_count` (clamped ≥ 0). agent fixed to \"Hermes Agent\". No project/workspace\r\n * in the schema. Confidence is \"host-reported\".\r\n *\r\n * Fail-open: db missing/locked/unreadable → openSqlite returns null → []; a bad row\r\n * is skipped, never thrown.\r\n */\r\n\r\nimport { join } from \"node:path\";\r\n\r\nimport type { UsageReader, UsageRecord } from \"../types.js\";\r\nimport { emptyTokens } from \"../aggregate.js\";\r\nimport { inferProvider } from \"../normalize.js\";\r\nimport { firstExistingRoot } from \"../paths.js\";\r\nimport { openSqlite } from \"../sqlite.js\";\r\n\r\nconst PLATFORM_ID = \"hermes\" as const;\r\nconst DEFAULT_PROVIDER = \"hermes\";\r\nconst HERMES_AGENT_NAME = \"Hermes Agent\";\r\n\r\n/** The session columns we read (everything optional / unknown off the row). */\r\ninterface HermesRow {\r\n id?: unknown;\r\n model?: unknown;\r\n billing_provider?: unknown;\r\n started_at?: unknown;\r\n message_count?: unknown;\r\n input_tokens?: unknown;\r\n output_tokens?: unknown;\r\n cache_read_tokens?: unknown;\r\n cache_write_tokens?: unknown;\r\n reasoning_tokens?: unknown;\r\n estimated_cost_usd?: unknown;\r\n actual_cost_usd?: unknown;\r\n}\r\n\r\nconst QUERY = `\r\n SELECT\r\n id,\r\n model,\r\n billing_provider,\r\n started_at,\r\n message_count,\r\n input_tokens,\r\n output_tokens,\r\n cache_read_tokens,\r\n cache_write_tokens,\r\n reasoning_tokens,\r\n estimated_cost_usd,\r\n actual_cost_usd\r\n FROM sessions\r\n WHERE model IS NOT NULL\r\n AND TRIM(model) != ''\r\n AND (\r\n COALESCE(input_tokens, 0) > 0 OR\r\n COALESCE(output_tokens, 0) > 0 OR\r\n COALESCE(cache_read_tokens, 0) > 0 OR\r\n COALESCE(cache_write_tokens, 0) > 0 OR\r\n COALESCE(reasoning_tokens, 0) > 0 OR\r\n COALESCE(actual_cost_usd, estimated_cost_usd, 0) > 0\r\n )\r\n`;\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// DB path resolution (honor $HERMES_HOME, ahead of paths.ts defaults)\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Resolve the Hermes state DB. The Rust spec lists both `~/.hermes/state.db` and\r\n * `$HERMES_HOME/state.db`; the fixed paths.ts only encodes the former (+ the\r\n * AGENT_CONNECTOR_HERMES_DIR override), so we honor HERMES_HOME first here.\r\n * Returns the first existing candidate, or undefined when none is present.\r\n */\r\nfunction resolveDbPath(): string | undefined {\r\n const home = process.env.HERMES_HOME;\r\n if (home != null && home.trim() !== \"\") {\r\n const candidate = join(home.trim(), \"state.db\");\r\n // existsSync is checked by openSqlite (returns null on a missing file), but we\r\n // still need an explicit candidate; let firstExistingRoot cover the default.\r\n return candidate;\r\n }\r\n return firstExistingRoot(PLATFORM_ID);\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Provider resolution (port of provider_identity.rs canonical_provider)\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Canonicalize a single provider segment (port of canonicalize_provider_segment):\r\n * trim, drop a trailing slash, lowercase, `-`→`_`; reject `<…>` placeholders, the\r\n * empty/`unknown` segment, and unknown segments that contain a digit (those are\r\n * model-name fragments). Returns the canonical id or undefined.\r\n */\r\nfunction canonicalizeProviderSegment(segment: string): string | undefined {\r\n const normalized = segment.trim().replace(/\\/+$/, \"\").toLowerCase().replace(/-/g, \"_\");\r\n if (normalized.startsWith(\"<\") && normalized.endsWith(\">\")) return undefined;\r\n switch (normalized) {\r\n case \"\":\r\n case \"unknown\":\r\n return undefined;\r\n case \"x_ai\":\r\n case \"xai\":\r\n return \"xai\";\r\n case \"z_ai\":\r\n case \"zai\":\r\n return \"zai\";\r\n case \"moonshot\":\r\n case \"moonshotai\":\r\n return \"moonshotai\";\r\n case \"meta\":\r\n case \"meta_llama\":\r\n return \"meta_llama\";\r\n case \"azure\":\r\n case \"azure_ai\":\r\n return \"azure_ai\";\r\n case \"anthropic\":\r\n case \"vertex\":\r\n case \"vertex_ai\":\r\n return \"anthropic\";\r\n case \"together\":\r\n case \"together_ai\":\r\n return \"together_ai\";\r\n case \"fireworks\":\r\n case \"fireworks_ai\":\r\n return \"fireworks_ai\";\r\n case \"google\":\r\n case \"gemini\":\r\n return \"google\";\r\n case \"openai\":\r\n case \"openai_codex\":\r\n return \"openai\";\r\n case \"minimax\":\r\n case \"minimaxai\":\r\n case \"minimax_ai\":\r\n return \"minimax\";\r\n case \"mistral\":\r\n case \"mistralai\":\r\n return \"mistralai\";\r\n case \"ai21\":\r\n return \"ai21\";\r\n default:\r\n if (/[0-9]/.test(normalized)) return undefined;\r\n return normalized;\r\n }\r\n}\r\n\r\n/**\r\n * Port of canonical_provider: the first canonical tag from `provider_tags(raw)`\r\n * (split on '/', and for any dotted segment also try its dot-parts), or undefined\r\n * when no segment canonicalizes — so the resolver can fall through to model\r\n * inference, matching the Rust `Option<String>` semantics.\r\n */\r\nfunction canonicalProvider(raw: string): string | undefined {\r\n for (const segment of raw.trim().replace(/\\/+$/, \"\").split(\"/\")) {\r\n const tag = canonicalizeProviderSegment(segment);\r\n if (tag !== undefined) return tag;\r\n if (segment.includes(\".\")) {\r\n for (const dotted of segment.split(\".\")) {\r\n const dottedTag = canonicalizeProviderSegment(dotted);\r\n if (dottedTag !== undefined) return dottedTag;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Resolve the provider (port of resolved_provider): canonical_provider of a\r\n * non-blank `billing_provider`, else inferProvider(model), else \"hermes\".\r\n */\r\nfunction resolvedProvider(billingProvider: unknown, modelId: string): string {\r\n if (typeof billingProvider === \"string\") {\r\n const trimmed = billingProvider.trim();\r\n if (trimmed !== \"\") {\r\n const canonical = canonicalProvider(trimmed);\r\n if (canonical !== undefined) return canonical;\r\n }\r\n }\r\n return inferProvider(modelId) ?? DEFAULT_PROVIDER;\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Numbers & timestamps\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/** Coerce an unknown SQLite cell to an integer ≥ 0 (port of `Option<i64>?.unwrap_or(0).max(0)`). */\r\nfunction tokenCell(v: unknown): number {\r\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\r\n if (!Number.isFinite(n)) return 0;\r\n return Math.max(0, Math.trunc(n));\r\n}\r\n\r\n/** Coerce an unknown SQLite cell to a finite float, or null when absent/garbage. */\r\nfunction floatOrNull(v: unknown): number | null {\r\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\r\n return Number.isFinite(n) ? n : null;\r\n}\r\n\r\n/**\r\n * Disambiguate `started_at` (f64) seconds-vs-milliseconds (port of\r\n * timestamp_secs_to_ms): values already in ms (> 1e12) pass through truncated to\r\n * an integer; smaller values are treated as seconds and scaled × 1000.\r\n */\r\nfunction timestampSecsToMs(timestamp: number): number {\r\n return timestamp > 1e12 ? Math.trunc(timestamp) : Math.trunc(timestamp * 1000);\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Reader\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/** The Hermes Agent usage reader singleton. */\r\nconst hermesReader: UsageReader = {\r\n platformId: PLATFORM_ID,\r\n kind: \"local\",\r\n async read({ sinceMs }: { sinceMs?: number }): Promise<UsageRecord[]> {\r\n const dbPath = resolveDbPath();\r\n if (dbPath === undefined) return []; // no state.db → fail-open\r\n\r\n const db = await openSqlite(dbPath);\r\n if (db === null) return []; // missing / locked / unreadable / non-sqlite → fail-open\r\n\r\n try {\r\n const rows = db.all(QUERY); // bad SQL / schema mismatch → [] (fail-open)\r\n const records: UsageRecord[] = [];\r\n\r\n for (const raw of rows) {\r\n const row = raw as HermesRow;\r\n\r\n // id and model are read as non-null strings in the Rust decode; the WHERE\r\n // clause already enforces a non-blank model, but we mirror the decode by\r\n // skipping any row whose id/model is not a usable string.\r\n const sessionId = row.id;\r\n if (typeof sessionId !== \"string\" || sessionId === \"\") continue;\r\n\r\n const modelId = row.model;\r\n if (typeof modelId !== \"string\" || modelId.trim() === \"\") continue;\r\n\r\n const startedAt = floatOrNull(row.started_at) ?? 0;\r\n const ts = timestampSecsToMs(startedAt);\r\n if (sinceMs !== undefined && ts < sinceMs) continue;\r\n\r\n const providerId = resolvedProvider(row.billing_provider, modelId);\r\n\r\n const tokens = emptyTokens();\r\n tokens.input = tokenCell(row.input_tokens);\r\n tokens.output = tokenCell(row.output_tokens);\r\n tokens.cacheRead = tokenCell(row.cache_read_tokens);\r\n tokens.cacheWrite = tokenCell(row.cache_write_tokens);\r\n tokens.reasoning = tokenCell(row.reasoning_tokens);\r\n\r\n // Cost: prefer actual, fall back to estimated, default 0 — clamped ≥ 0.\r\n const actual = floatOrNull(row.actual_cost_usd);\r\n const estimated = floatOrNull(row.estimated_cost_usd);\r\n const cost = Math.max(0, actual ?? estimated ?? 0);\r\n\r\n // message_count: Option<i32>.unwrap_or(0).max(0).\r\n const messageCount = tokenCell(row.message_count);\r\n\r\n const record: UsageRecord = {\r\n platformId: PLATFORM_ID,\r\n modelId,\r\n providerId,\r\n sessionId,\r\n tokens,\r\n cost,\r\n ts,\r\n messageCount,\r\n dedupKey: sessionId, // one row per session → session id is the dedup key\r\n confidence: \"host-reported\",\r\n agent: HERMES_AGENT_NAME,\r\n };\r\n records.push(record);\r\n }\r\n\r\n return records;\r\n } finally {\r\n db.close();\r\n }\r\n },\r\n};\r\n\r\nexport default hermesReader;\r\n"],"mappings":"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","names":[]}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
fail
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-N4ENLZEU.js";
|
|
5
|
+
import "./chunk-FHYR5Q5T.js";
|
|
6
|
+
import "./chunk-LFWYYWLV.js";
|
|
7
|
+
import "./chunk-SLJI5BOM.js";
|
|
8
|
+
import "./chunk-GZZCHJDP.js";
|
|
9
9
|
import {
|
|
10
10
|
isNativeHookDeclared,
|
|
11
11
|
runHook,
|
|
12
12
|
runNativeHook
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-GCPEPUD7.js";
|
|
14
|
+
import "./chunk-IOJDZJ72.js";
|
|
15
|
+
import "./chunk-4GH2KA7V.js";
|
|
16
|
+
import "./chunk-3EP5V2F4.js";
|
|
17
|
+
import "./chunk-7ZFK2WEO.js";
|
|
18
|
+
import "./chunk-NDMNMAKP.js";
|
|
19
|
+
import "./chunk-KFPSJRHR.js";
|
|
20
|
+
import "./chunk-Y3K6KJMS.js";
|
|
21
|
+
import "./chunk-ILWHLGIC.js";
|
|
22
|
+
import "./chunk-QYOUQCC6.js";
|
|
23
23
|
|
|
24
24
|
// src/cli/commands/hook.ts
|
|
25
25
|
import { parseArgs } from "util";
|
|
@@ -93,4 +93,4 @@ export {
|
|
|
93
93
|
HOOK_EVENTS,
|
|
94
94
|
run
|
|
95
95
|
};
|
|
96
|
-
//# sourceMappingURL=hook-
|
|
96
|
+
//# sourceMappingURL=hook-VHICXHXL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/hook.ts"],"sourcesContent":["/**\r\n * cli/commands/hook — the universal json-stdio hook entrypoint.\r\n *\r\n * agent-connector hook <platform> <event> --connector <id>\r\n *\r\n * This is the single command every host's hook config points at (via the stable\r\n * home binary). It reads the ENTIRE host payload from stdin, dispatches through\r\n * runHook, writes any stdout/stderr the adapter produced, and exits with the\r\n * adapter's exit code (the host interprets it as allow/deny/etc.).\r\n *\r\n * Fail-open is the runtime's contract: runHook never rejects, so a framework or\r\n * handler bug can't wedge a host's tool call.\r\n */\r\n\r\nimport { parseArgs } from \"node:util\";\r\n\r\nimport type { HookEventName } from \"../../core/types.js\";\r\nimport { isNativeHookDeclared, runHook, runNativeHook } from \"../../runtime/index.js\";\r\nimport type { RunHookResult } from \"../../runtime/index.js\";\r\nimport { fail } from \"../app.js\";\r\n\r\n// The CLI hook-dispatch gate: every normalized HookEventName the entrypoint\r\n// accepts. MUST stay in sync with HookEventName / define-connector ALL_EVENTS —\r\n// a missing member silently rejects an installed hook at runtime. The\r\n// hook-dispatch-events test pins this set ⊇ ALL_EVENTS so it cannot drift.\r\nexport const HOOK_EVENTS: ReadonlySet<string> = new Set<HookEventName>([\r\n \"SessionStart\",\r\n \"SessionEnd\",\r\n \"UserPromptSubmit\",\r\n \"PreToolUse\",\r\n \"PostToolUse\",\r\n \"PreCompact\",\r\n \"Stop\",\r\n \"Notification\",\r\n \"PermissionRequest\",\r\n \"PostToolUseFailure\",\r\n \"SubagentStart\",\r\n \"SubagentStop\",\r\n \"PostCompact\",\r\n]);\r\n\r\n/** Read all of a readable stream to a UTF-8 string. */\r\nasync function readAll(stream: NodeJS.ReadStream): Promise<string> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\r\n }\r\n return Buffer.concat(chunks).toString(\"utf8\");\r\n}\r\n\r\nexport async function run(argv: string[]): Promise<number> {\r\n const { values, positionals } = parseArgs({\r\n args: argv,\r\n options: {\r\n connector: { type: \"string\" },\r\n },\r\n allowPositionals: true,\r\n });\r\n\r\n const platformId = positionals[0];\r\n const event = positionals[1];\r\n if (!platformId || !event) {\r\n return fail(\"usage: agent-connector hook <platform> <event> --connector <id>\");\r\n }\r\n const connectorId = values.connector;\r\n if (!connectorId || connectorId.trim() === \"\") {\r\n return fail(\"hook requires --connector <id>\");\r\n }\r\n\r\n // NATIVE PASSTHROUGH: a non-union event name is accepted ONLY when the\r\n // resolved connector declares it under platforms[<platform>].nativeHooks —\r\n // dispatch then bypasses the normalized parse/format entirely (raw stdin →\r\n // handler → verbatim JSON stdout). Undeclared names keep the strict error.\r\n if (!HOOK_EVENTS.has(event)) {\r\n if (!(await isNativeHookDeclared(platformId, event, connectorId))) {\r\n return fail(`unknown hook event \"${event}\"`);\r\n }\r\n const stdin = await readAll(process.stdin);\r\n const reply = await runNativeHook({ platformId, event, connectorId, stdin });\r\n return exitWithReply(reply);\r\n }\r\n\r\n // Read the entire host payload before dispatching.\r\n const stdin = await readAll(process.stdin);\r\n\r\n const reply = await runHook({\r\n platformId,\r\n event: event as HookEventName,\r\n connectorId,\r\n stdin,\r\n });\r\n\r\n return exitWithReply(reply);\r\n}\r\n\r\n/** Write a hook reply's stdout/stderr and exit with its code. */\r\nfunction exitWithReply(reply: RunHookResult): never {\r\n if (reply.stdout !== undefined && reply.stdout !== \"\") {\r\n process.stdout.write(reply.stdout);\r\n }\r\n if (reply.stderr !== undefined && reply.stderr !== \"\") {\r\n process.stderr.write(reply.stderr.endsWith(\"\\n\") ? reply.stderr : `${reply.stderr}\\n`);\r\n }\r\n process.exit(reply.exitCode);\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAcA,SAAS,iBAAiB;AAWnB,IAAM,cAAmC,oBAAI,IAAmB;AAAA,EACrE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,eAAe,QAAQ,QAA4C;AACjE,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,OAAO,UAAU,WAAW,OAAO,KAAK,KAAK,IAAI,KAAK;AAAA,EACpE;AACA,SAAO,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AAC9C;AAEA,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,QAAQ,YAAY,IAAI,UAAU;AAAA,IACxC,MAAM;AAAA,IACN,SAAS;AAAA,MACP,WAAW,EAAE,MAAM,SAAS;AAAA,IAC9B;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,aAAa,YAAY,CAAC;AAChC,QAAM,QAAQ,YAAY,CAAC;AAC3B,MAAI,CAAC,cAAc,CAAC,OAAO;AACzB,WAAO,KAAK,iEAAiE;AAAA,EAC/E;AACA,QAAM,cAAc,OAAO;AAC3B,MAAI,CAAC,eAAe,YAAY,KAAK,MAAM,IAAI;AAC7C,WAAO,KAAK,gCAAgC;AAAA,EAC9C;AAMA,MAAI,CAAC,YAAY,IAAI,KAAK,GAAG;AAC3B,QAAI,CAAE,MAAM,qBAAqB,YAAY,OAAO,WAAW,GAAI;AACjE,aAAO,KAAK,uBAAuB,KAAK,GAAG;AAAA,IAC7C;AACA,UAAMA,SAAQ,MAAM,QAAQ,QAAQ,KAAK;AACzC,UAAMC,SAAQ,MAAM,cAAc,EAAE,YAAY,OAAO,aAAa,OAAAD,OAAM,CAAC;AAC3E,WAAO,cAAcC,MAAK;AAAA,EAC5B;AAGA,QAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK;AAEzC,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,cAAc,KAAK;AAC5B;AAGA,SAAS,cAAc,OAA6B;AAClD,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,MAAM;AAAA,EACnC;AACA,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,SAAS,GAAG,MAAM,MAAM;AAAA,CAAI;AAAA,EACvF;AACA,UAAQ,KAAK,MAAM,QAAQ;AAC7B;","names":["stdin","reply"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { C as ConnectorConfigError, d as defineAction, a as defineCommand, b as defineConfigPatch, c as defineConnector, e as defineHook, f as defineMemory, g as defineNativeHook, h as defineSkill, i as defineStatusline, j as defineSubagent } from './define-connector-
|
|
2
|
-
import { S as ServerDef, M as McpPackageIdentity, R as ResolvedMcpPackageIdentity } from './types-
|
|
3
|
-
export { A as ActionDef, a as ActionResult, b as AuthSpec, C as ChangeRecord, c as ConnectorConfig, D as DetectedPlatform, d as DiagnosticResult, E as EventPayloadMap, H as HookDefinition, e as HookEventName, f as HookParadigm, g as HookResponse, h as HooksConfig, i as HostCtx, I as InstallResult, j as InstallScope, k as MemoryDef, N as NativeHookDef, l as NativeHookEvent, m as NotificationEvent, P as PermissionRequestEvent, n as PlatformCapabilities, o as PlatformId, p as PlatformMemoryOverride, q as PlatformOverride, r as PostToolUseEvent, s as PostToolUseFailureEvent, t as PreCompactEvent, u as PreToolUseEvent, v as ResolvedConnector, w as SessionEndEvent, x as SessionStartEvent, y as StatuslineContext, z as StatuslineDef, B as StopEvent, F as SubagentStartEvent, G as SubagentStopEvent, T as TelemetryAccessor, J as TelemetryConfig, K as TelemetryUsageSummary, L as ToolFilter, O as Transport, U as UserPromptSubmitEvent } from './types-
|
|
1
|
+
export { C as ConnectorConfigError, d as defineAction, a as defineCommand, b as defineConfigPatch, c as defineConnector, e as defineHook, f as defineMemory, g as defineNativeHook, h as defineSkill, i as defineStatusline, j as defineSubagent } from './define-connector-DTWb46UB.js';
|
|
2
|
+
import { S as ServerDef, M as McpPackageIdentity, R as ResolvedMcpPackageIdentity } from './types-JyhpJHJa.js';
|
|
3
|
+
export { A as ActionDef, a as ActionResult, b as AuthSpec, C as ChangeRecord, c as ConnectorConfig, D as DetectedPlatform, d as DiagnosticResult, E as EventPayloadMap, H as HookDefinition, e as HookEventName, f as HookParadigm, g as HookResponse, h as HooksConfig, i as HostCtx, I as InstallResult, j as InstallScope, k as MemoryDef, N as NativeHookDef, l as NativeHookEvent, m as NotificationEvent, P as PermissionRequestEvent, n as PlatformCapabilities, o as PlatformId, p as PlatformMemoryOverride, q as PlatformOverride, r as PostToolUseEvent, s as PostToolUseFailureEvent, t as PreCompactEvent, u as PreToolUseEvent, v as ResolvedConnector, w as SessionEndEvent, x as SessionStartEvent, y as StatuslineContext, z as StatuslineDef, B as StopEvent, F as SubagentStartEvent, G as SubagentStopEvent, T as TelemetryAccessor, J as TelemetryConfig, K as TelemetryUsageSummary, L as ToolFilter, O as Transport, U as UserPromptSubmitEvent } from './types-JyhpJHJa.js';
|
|
4
4
|
|
|
5
5
|
/** Derive the host-facing MCP server key from a package name. */
|
|
6
6
|
declare function deriveHostAliasFromPackageName(packageName: string): string | undefined;
|
package/dist/index.js
CHANGED
|
@@ -15,11 +15,11 @@ import {
|
|
|
15
15
|
deriveHostAliasFromPackageName,
|
|
16
16
|
inferNpmPackageFromServer,
|
|
17
17
|
resolveMcpPackageIdentity
|
|
18
|
-
} from "./chunk-
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
18
|
+
} from "./chunk-7ZFK2WEO.js";
|
|
19
|
+
import "./chunk-NDMNMAKP.js";
|
|
20
|
+
import "./chunk-KFPSJRHR.js";
|
|
21
|
+
import "./chunk-ILWHLGIC.js";
|
|
22
|
+
import "./chunk-QYOUQCC6.js";
|
|
23
23
|
export {
|
|
24
24
|
ConnectorConfigError,
|
|
25
25
|
defineAction,
|