@ken-jo/agent-connector 0.4.95 → 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.
Files changed (378) hide show
  1. package/LICENSE +202 -202
  2. package/NOTICE +6 -6
  3. package/README.md +605 -599
  4. package/dist/{action-Q7GGO4PA.js → action-IPFDPOZU.js} +16 -16
  5. package/dist/action-IPFDPOZU.js.map +1 -0
  6. package/dist/{amazon-q-ETMAGY3D.js → amazon-q-IT44LEWV.js} +6 -6
  7. package/dist/amazon-q-IT44LEWV.js.map +1 -0
  8. package/dist/{amp-BQZOL5GR.js → amp-CEWOSWQO.js} +4 -4
  9. package/dist/amp-CEWOSWQO.js.map +1 -0
  10. package/dist/{amp-67BZONGF.js → amp-P35FRU2Z.js} +7 -7
  11. package/dist/amp-P35FRU2Z.js.map +1 -0
  12. package/dist/{antigravity-EA4L225L.js → antigravity-LHFEFNMC.js} +5 -5
  13. package/dist/antigravity-LHFEFNMC.js.map +1 -0
  14. package/dist/antigravity-TWIWXTQH.js +18 -0
  15. package/dist/{antigravity-cli-B2HXZFYQ.js → antigravity-cli-MOKFSWOU.js} +5 -5
  16. package/dist/antigravity-cli-MOKFSWOU.js.map +1 -0
  17. package/dist/{antigravity-cli-OM6SC3PE.js → antigravity-cli-MPE27LPI.js} +9 -9
  18. package/dist/antigravity-cli-MPE27LPI.js.map +1 -0
  19. package/dist/audit-3E5JAOP2.js +311 -0
  20. package/dist/audit-3E5JAOP2.js.map +1 -0
  21. package/dist/{chunk-PW42ZXCB.js → chunk-3EP5V2F4.js} +3 -3
  22. package/dist/chunk-3EP5V2F4.js.map +1 -0
  23. package/dist/{chunk-MGTDQLJJ.js → chunk-3FINQ2ZF.js} +4 -4
  24. package/dist/chunk-3FINQ2ZF.js.map +1 -0
  25. package/dist/{chunk-KHO5WNTP.js → chunk-4GH2KA7V.js} +1 -1
  26. package/dist/chunk-4GH2KA7V.js.map +1 -0
  27. package/dist/{chunk-2Y2MZRLP.js → chunk-7C2IPIIB.js} +3 -3
  28. package/dist/chunk-7C2IPIIB.js.map +1 -0
  29. package/dist/{chunk-NLE2J5P4.js → chunk-7HHW23AC.js} +29 -29
  30. package/dist/chunk-7HHW23AC.js.map +1 -0
  31. package/dist/{chunk-XD7MY6HB.js → chunk-7PSNXUFK.js} +1 -1
  32. package/dist/chunk-7PSNXUFK.js.map +1 -0
  33. package/dist/{chunk-5IOTP7LQ.js → chunk-7ZFK2WEO.js} +7 -5
  34. package/dist/chunk-7ZFK2WEO.js.map +1 -0
  35. package/dist/{chunk-XC5SJ35F.js → chunk-C63AAXK7.js} +5 -5
  36. package/dist/chunk-C63AAXK7.js.map +1 -0
  37. package/dist/{chunk-UM5S7DKK.js → chunk-C747DYNT.js} +1 -1
  38. package/dist/chunk-C747DYNT.js.map +1 -0
  39. package/dist/{chunk-YPAXJ7EW.js → chunk-FHYR5Q5T.js} +13 -13
  40. package/dist/chunk-FHYR5Q5T.js.map +1 -0
  41. package/dist/{chunk-I5UXHIDT.js → chunk-GCPEPUD7.js} +8 -8
  42. package/dist/chunk-GCPEPUD7.js.map +1 -0
  43. package/dist/{chunk-ISEJWBFF.js → chunk-GZZCHJDP.js} +2 -2
  44. package/dist/chunk-GZZCHJDP.js.map +1 -0
  45. package/dist/{chunk-UMQ6NBQR.js → chunk-ILWHLGIC.js} +2 -2
  46. package/dist/chunk-ILWHLGIC.js.map +1 -0
  47. package/dist/{chunk-IVAWP6HH.js → chunk-IOJDZJ72.js} +2 -2
  48. package/dist/chunk-IOJDZJ72.js.map +1 -0
  49. package/dist/{chunk-NBYKLUF6.js → chunk-KFPSJRHR.js} +2 -2
  50. package/dist/chunk-KFPSJRHR.js.map +1 -0
  51. package/dist/{chunk-O7SDRBVB.js → chunk-KM2YXO6V.js} +1 -1
  52. package/dist/chunk-KM2YXO6V.js.map +1 -0
  53. package/dist/{chunk-7F5KHLEP.js → chunk-L2C5UMKW.js} +4 -4
  54. package/dist/chunk-L2C5UMKW.js.map +1 -0
  55. package/dist/{chunk-OP4KBXUO.js → chunk-LFWYYWLV.js} +1 -1
  56. package/dist/chunk-LFWYYWLV.js.map +1 -0
  57. package/dist/{chunk-APZDTY76.js → chunk-LQ55E7QI.js} +7 -7
  58. package/dist/chunk-LQ55E7QI.js.map +1 -0
  59. package/dist/{chunk-PAPMUAR5.js → chunk-MLU7NDAZ.js} +12 -12
  60. package/dist/chunk-MLU7NDAZ.js.map +1 -0
  61. package/dist/{chunk-H33M77DD.js → chunk-N4ENLZEU.js} +22 -19
  62. package/dist/chunk-N4ENLZEU.js.map +1 -0
  63. package/dist/{chunk-D4ELPBB5.js → chunk-NDMNMAKP.js} +43 -43
  64. package/dist/chunk-NDMNMAKP.js.map +1 -0
  65. package/dist/{chunk-H53QZQJI.js → chunk-PSGTHJQU.js} +1 -1
  66. package/dist/chunk-PSGTHJQU.js.map +1 -0
  67. package/dist/{chunk-FBJQGRET.js → chunk-Q4ISQHUQ.js} +1 -1
  68. package/dist/chunk-Q4ISQHUQ.js.map +1 -0
  69. package/dist/{chunk-6TF7MHG5.js → chunk-Q7PR2WGT.js} +2 -2
  70. package/dist/chunk-Q7PR2WGT.js.map +1 -0
  71. package/dist/{chunk-GZGLCCEE.js → chunk-QYOUQCC6.js} +1 -1
  72. package/dist/chunk-QYOUQCC6.js.map +1 -0
  73. package/dist/{chunk-Z2MRSS2I.js → chunk-SLJI5BOM.js} +2 -2
  74. package/dist/chunk-SLJI5BOM.js.map +1 -0
  75. package/dist/{chunk-JKKU2WKG.js → chunk-TGZFDXNH.js} +4 -4
  76. package/dist/chunk-TGZFDXNH.js.map +1 -0
  77. package/dist/{chunk-FJCUKXGX.js → chunk-THI4PI4H.js} +2 -2
  78. package/dist/chunk-THI4PI4H.js.map +1 -0
  79. package/dist/{chunk-MQPNU2CY.js → chunk-UZZTWWGG.js} +1 -1
  80. package/dist/chunk-UZZTWWGG.js.map +1 -0
  81. package/dist/{chunk-3NH2ARIS.js → chunk-WPTNMYYM.js} +2 -2
  82. package/dist/chunk-WPTNMYYM.js.map +1 -0
  83. package/dist/{chunk-OPXAP3AC.js → chunk-XN7S44U4.js} +1 -1
  84. package/dist/chunk-XN7S44U4.js.map +1 -0
  85. package/dist/{chunk-6WZODR3Z.js → chunk-XVEJAFKW.js} +5 -5
  86. package/dist/chunk-XVEJAFKW.js.map +1 -0
  87. package/dist/{chunk-BEFVJ2OE.js → chunk-XXLCMSD3.js} +1 -1
  88. package/dist/chunk-XXLCMSD3.js.map +1 -0
  89. package/dist/{chunk-YT43MUSJ.js → chunk-XZWMJLIT.js} +1 -1
  90. package/dist/chunk-XZWMJLIT.js.map +1 -0
  91. package/dist/{chunk-4NHXLXSD.js → chunk-Y3K6KJMS.js} +2 -2
  92. package/dist/chunk-Y3K6KJMS.js.map +1 -0
  93. package/dist/{chunk-RK6VBLXP.js → chunk-ZSOS2KOR.js} +1 -1
  94. package/dist/chunk-ZSOS2KOR.js.map +1 -0
  95. package/dist/{claude-code-NMRKTAP7.js → claude-code-FS42PXZO.js} +4 -4
  96. package/dist/claude-code-FS42PXZO.js.map +1 -0
  97. package/dist/{claude-code-GRWO6XBZ.js → claude-code-QBWDT5RT.js} +11 -11
  98. package/dist/claude-code-QBWDT5RT.js.map +1 -0
  99. package/dist/cli/sdk.js +9 -8
  100. package/dist/cli/sdk.js.map +1 -1
  101. package/dist/cli.js +1 -1
  102. package/dist/cli.js.map +1 -1
  103. package/dist/{cline-25KW25IN.js → cline-JKEAYWVR.js} +6 -6
  104. package/dist/cline-JKEAYWVR.js.map +1 -0
  105. package/dist/{codebuddy-ZNYQACMF.js → codebuddy-EB6EYPC3.js} +7 -7
  106. package/dist/codebuddy-EB6EYPC3.js.map +1 -0
  107. package/dist/{codebuff-VR6JUDIY.js → codebuff-5RSXFU6G.js} +6 -6
  108. package/dist/codebuff-5RSXFU6G.js.map +1 -0
  109. package/dist/{codebuff-ETYT5UBL.js → codebuff-6KWBW6CT.js} +4 -4
  110. package/dist/codebuff-6KWBW6CT.js.map +1 -0
  111. package/dist/{codex-CPNKTXG3.js → codex-ART46CDD.js} +9 -9
  112. package/dist/codex-ART46CDD.js.map +1 -0
  113. package/dist/{codex-YAORPCOD.js → codex-DKBAAUCO.js} +4 -4
  114. package/dist/codex-DKBAAUCO.js.map +1 -0
  115. package/dist/{continue-WU2IB5KS.js → continue-JHZCMSPH.js} +8 -8
  116. package/dist/continue-JHZCMSPH.js.map +1 -0
  117. package/dist/{copilot-cli-MZTAWMPW.js → copilot-cli-CLBJACQ5.js} +4 -4
  118. package/dist/copilot-cli-CLBJACQ5.js.map +1 -0
  119. package/dist/{copilot-cli-PAP377OM.js → copilot-cli-QVAU5CFM.js} +7 -7
  120. package/dist/copilot-cli-QVAU5CFM.js.map +1 -0
  121. package/dist/{crush-3AVQA4YU.js → crush-7TORBYUL.js} +7 -7
  122. package/dist/crush-7TORBYUL.js.map +1 -0
  123. package/dist/{crush-QBXLNN7T.js → crush-A5C5USRL.js} +4 -4
  124. package/dist/crush-A5C5USRL.js.map +1 -0
  125. package/dist/{cursor-DIW43TRZ.js → cursor-D5SWDVSW.js} +3 -3
  126. package/dist/cursor-D5SWDVSW.js.map +1 -0
  127. package/dist/cursor-W7I4QUFO.js +22 -0
  128. package/dist/{detect-6V4LC3MA.js → detect-JHSA3G3U.js} +4 -4
  129. package/dist/detect-JHSA3G3U.js.map +1 -0
  130. package/dist/{devin-QMEM3OFA.js → devin-SSR7S4WX.js} +7 -7
  131. package/dist/devin-SSR7S4WX.js.map +1 -0
  132. package/dist/{doctor-2YDUVSAU.js → doctor-CQJ7TZPA.js} +26 -26
  133. package/dist/doctor-CQJ7TZPA.js.map +1 -0
  134. package/dist/{droid-MOKV53J4.js → droid-45PJ7JGF.js} +7 -7
  135. package/dist/droid-45PJ7JGF.js.map +1 -0
  136. package/dist/{droid-U3ZBLQFO.js → droid-PFQ2PZSF.js} +4 -4
  137. package/dist/droid-PFQ2PZSF.js.map +1 -0
  138. package/dist/{gemini-cli-47ZHCOZR.js → gemini-cli-24PFDK7D.js} +8 -8
  139. package/dist/gemini-cli-24PFDK7D.js.map +1 -0
  140. package/dist/{gemini-cli-NMVVBO3K.js → gemini-cli-Y6RJMU24.js} +4 -4
  141. package/dist/gemini-cli-Y6RJMU24.js.map +1 -0
  142. package/dist/{goose-64V46Y2W.js → goose-K2HKUTBK.js} +4 -4
  143. package/dist/goose-K2HKUTBK.js.map +1 -0
  144. package/dist/{goose-4EI5MYTI.js → goose-U5D3LCPC.js} +9 -9
  145. package/dist/goose-U5D3LCPC.js.map +1 -0
  146. package/dist/{grok-cli-QYQPDSVB.js → grok-cli-L2MHAPBY.js} +7 -7
  147. package/dist/grok-cli-L2MHAPBY.js.map +1 -0
  148. package/dist/{hermes-F75OSK3Y.js → hermes-2S5JUTTJ.js} +7 -7
  149. package/dist/hermes-2S5JUTTJ.js.map +1 -0
  150. package/dist/{hermes-F3EGTK6N.js → hermes-MF3NX4ZY.js} +4 -4
  151. package/dist/hermes-MF3NX4ZY.js.map +1 -0
  152. package/dist/{hook-OEVRDMXD.js → hook-VHICXHXL.js} +16 -16
  153. package/dist/hook-VHICXHXL.js.map +1 -0
  154. package/dist/index.js +5 -5
  155. package/dist/{install-5NMCUDG5.js → install-WLENR4KF.js} +192 -28
  156. package/dist/install-WLENR4KF.js.map +1 -0
  157. package/dist/{jetbrains-copilot-ZGIWI6YV.js → jetbrains-copilot-Z4FC3RM3.js} +6 -6
  158. package/dist/jetbrains-copilot-Z4FC3RM3.js.map +1 -0
  159. package/dist/{junie-DIFN2P22.js → junie-ULGJJIHB.js} +6 -6
  160. package/dist/junie-ULGJJIHB.js.map +1 -0
  161. package/dist/{kilo-SW7BH6EG.js → kilo-SMHPOHJ5.js} +4 -4
  162. package/dist/kilo-SMHPOHJ5.js.map +1 -0
  163. package/dist/{kilo-EMZJBEBB.js → kilo-WWIJOVWD.js} +8 -8
  164. package/dist/kilo-WWIJOVWD.js.map +1 -0
  165. package/dist/{kilo-cli-S3GXBPAE.js → kilo-cli-QKE2EQLS.js} +8 -8
  166. package/dist/kilo-cli-QKE2EQLS.js.map +1 -0
  167. package/dist/{kilo-cli-ZF272ZHN.js → kilo-cli-T2SRRRJS.js} +5 -5
  168. package/dist/kilo-cli-T2SRRRJS.js.map +1 -0
  169. package/dist/{kimi-IQJOIY6B.js → kimi-JMUFTVSF.js} +7 -7
  170. package/dist/kimi-JMUFTVSF.js.map +1 -0
  171. package/dist/{kimi-5FHEXGZD.js → kimi-MSIDEMCI.js} +4 -4
  172. package/dist/kimi-MSIDEMCI.js.map +1 -0
  173. package/dist/{kiro-WGOI5CGT.js → kiro-NYRRBIKW.js} +4 -4
  174. package/dist/kiro-NYRRBIKW.js.map +1 -0
  175. package/dist/{kiro-BYX4HEAJ.js → kiro-UWUCRKR3.js} +7 -7
  176. package/dist/kiro-UWUCRKR3.js.map +1 -0
  177. package/dist/{leaderboard-XEKS7B3H.js → leaderboard-NJWKGMXP.js} +7 -7
  178. package/dist/leaderboard-NJWKGMXP.js.map +1 -0
  179. package/dist/{mimo-code-7R53QDHB.js → mimo-code-BPNYYIVM.js} +7 -7
  180. package/dist/mimo-code-BPNYYIVM.js.map +1 -0
  181. package/dist/{mistral-vibe-LHJ55FSB.js → mistral-vibe-LT3DAJ3L.js} +6 -6
  182. package/dist/mistral-vibe-LT3DAJ3L.js.map +1 -0
  183. package/dist/{mux-XM6AP35L.js → mux-7PIJ7HUQ.js} +4 -4
  184. package/dist/mux-7PIJ7HUQ.js.map +1 -0
  185. package/dist/{mux-NYCNGL43.js → mux-AHNUAY5Z.js} +6 -6
  186. package/dist/mux-AHNUAY5Z.js.map +1 -0
  187. package/dist/{nemoclaw-WSIPSE7U.js → nemoclaw-RE5RZASZ.js} +7 -7
  188. package/dist/nemoclaw-RE5RZASZ.js.map +1 -0
  189. package/dist/{omp-562NK5BJ.js → omp-D2EXEPH7.js} +7 -7
  190. package/dist/omp-D2EXEPH7.js.map +1 -0
  191. package/dist/{open-interpreter-I2CNOEXY.js → open-interpreter-SSGBEUKX.js} +6 -6
  192. package/dist/open-interpreter-SSGBEUKX.js.map +1 -0
  193. package/dist/openclaw-IJ33K45M.js +17 -0
  194. package/dist/{openclaw-5EQFGOWL.js → openclaw-KAFTNLR2.js} +4 -4
  195. package/dist/openclaw-KAFTNLR2.js.map +1 -0
  196. package/dist/{opencode-YS4WX2E2.js → opencode-YKUKZY3J.js} +7 -7
  197. package/dist/opencode-YKUKZY3J.js.map +1 -0
  198. package/dist/{opencode-QGP4ALQY.js → opencode-Z65JYILL.js} +4 -4
  199. package/dist/opencode-Z65JYILL.js.map +1 -0
  200. package/dist/{openhands-QMYIKNOS.js → openhands-SEZMCUC3.js} +7 -7
  201. package/dist/openhands-SEZMCUC3.js.map +1 -0
  202. package/dist/{package-G25GVTH2.js → package-JECVQEFT.js} +15 -15
  203. package/dist/package-JECVQEFT.js.map +1 -0
  204. package/dist/{pi-GGDQREVG.js → pi-DLKCPOJE.js} +4 -4
  205. package/dist/pi-DLKCPOJE.js.map +1 -0
  206. package/dist/{pi-644FIN3A.js → pi-YPYV2ULH.js} +6 -6
  207. package/dist/pi-YPYV2ULH.js.map +1 -0
  208. package/dist/{qwen-code-GQILBJ5B.js → qwen-code-26CSFDX6.js} +4 -4
  209. package/dist/qwen-code-26CSFDX6.js.map +1 -0
  210. package/dist/{qwen-code-STDMX7EM.js → qwen-code-ZHCLCYMC.js} +9 -9
  211. package/dist/qwen-code-ZHCLCYMC.js.map +1 -0
  212. package/dist/{roo-code-DLPIHHQ6.js → roo-code-7F4HYB34.js} +6 -6
  213. package/dist/roo-code-7F4HYB34.js.map +1 -0
  214. package/dist/{roo-code-SUWI4BBN.js → roo-code-HSAE2CJU.js} +4 -4
  215. package/dist/roo-code-HSAE2CJU.js.map +1 -0
  216. package/dist/runtime/index.js +14 -14
  217. package/dist/sdk/index.js +6 -6
  218. package/dist/sdk/index.js.map +1 -1
  219. package/dist/sdk/test.js +11 -11
  220. package/dist/{serve-XTMIUHKK.js → serve-LYSBH43G.js} +16 -16
  221. package/dist/serve-LYSBH43G.js.map +1 -0
  222. package/dist/{status-VJAGO4Z7.js → status-PHKKGEW5.js} +11 -11
  223. package/dist/status-PHKKGEW5.js.map +1 -0
  224. package/dist/{statusline-EY2E2UGF.js → statusline-ZDD4OZ4F.js} +15 -15
  225. package/dist/statusline-ZDD4OZ4F.js.map +1 -0
  226. package/dist/{synthetic-6FRA7P5Q.js → synthetic-LUT6V6SD.js} +4 -4
  227. package/dist/synthetic-LUT6V6SD.js.map +1 -0
  228. package/dist/{telemetry-OLZQBADT.js → telemetry-HDGMI2BK.js} +10 -10
  229. package/dist/telemetry-HDGMI2BK.js.map +1 -0
  230. package/dist/{trae-CPPYASR2.js → trae-SIQI3C66.js} +4 -4
  231. package/dist/trae-SIQI3C66.js.map +1 -0
  232. package/dist/{trae-UOYD6JZZ.js → trae-Y67HSDOW.js} +6 -6
  233. package/dist/trae-Y67HSDOW.js.map +1 -0
  234. package/dist/{uninstall-AZEUPAND.js → uninstall-RWO2GM2I.js} +21 -21
  235. package/dist/uninstall-RWO2GM2I.js.map +1 -0
  236. package/dist/{upgrade-CAUUHSSC.js → upgrade-YJCXNUEE.js} +21 -21
  237. package/dist/upgrade-YJCXNUEE.js.map +1 -0
  238. package/dist/{usage-3KHZ4RYZ.js → usage-IWO4RQN6.js} +4 -4
  239. package/dist/usage-IWO4RQN6.js.map +1 -0
  240. package/dist/{usage-event-TZWOZPRJ.js → usage-event-AFFKCLHE.js} +15 -15
  241. package/dist/usage-event-AFFKCLHE.js.map +1 -0
  242. package/dist/{vscode-copilot-NIMH2DGU.js → vscode-copilot-5CI5B3X6.js} +7 -7
  243. package/dist/vscode-copilot-5CI5B3X6.js.map +1 -0
  244. package/dist/{warp-NRBBJQR2.js → warp-5YBSP7FP.js} +4 -4
  245. package/dist/warp-5YBSP7FP.js.map +1 -0
  246. package/dist/{warp-QYJGKURM.js → warp-INAKVGBV.js} +6 -6
  247. package/dist/warp-INAKVGBV.js.map +1 -0
  248. package/dist/{windsurf-75LLZ37C.js → windsurf-4HM57QAY.js} +6 -6
  249. package/dist/windsurf-4HM57QAY.js.map +1 -0
  250. package/dist/{zed-XJFOOKCO.js → zed-XXCNYOIN.js} +4 -4
  251. package/dist/zed-XXCNYOIN.js.map +1 -0
  252. package/dist/{zed-HKAZXEJW.js → zed-YN5X37PQ.js} +7 -7
  253. package/dist/zed-YN5X37PQ.js.map +1 -0
  254. package/package.json +92 -88
  255. package/dist/action-Q7GGO4PA.js.map +0 -1
  256. package/dist/amazon-q-ETMAGY3D.js.map +0 -1
  257. package/dist/amp-67BZONGF.js.map +0 -1
  258. package/dist/amp-BQZOL5GR.js.map +0 -1
  259. package/dist/antigravity-EA4L225L.js.map +0 -1
  260. package/dist/antigravity-VXLDLTO7.js +0 -18
  261. package/dist/antigravity-cli-B2HXZFYQ.js.map +0 -1
  262. package/dist/antigravity-cli-OM6SC3PE.js.map +0 -1
  263. package/dist/chunk-2Y2MZRLP.js.map +0 -1
  264. package/dist/chunk-3NH2ARIS.js.map +0 -1
  265. package/dist/chunk-4NHXLXSD.js.map +0 -1
  266. package/dist/chunk-5IOTP7LQ.js.map +0 -1
  267. package/dist/chunk-6TF7MHG5.js.map +0 -1
  268. package/dist/chunk-6WZODR3Z.js.map +0 -1
  269. package/dist/chunk-7F5KHLEP.js.map +0 -1
  270. package/dist/chunk-APZDTY76.js.map +0 -1
  271. package/dist/chunk-BEFVJ2OE.js.map +0 -1
  272. package/dist/chunk-D4ELPBB5.js.map +0 -1
  273. package/dist/chunk-FBJQGRET.js.map +0 -1
  274. package/dist/chunk-FJCUKXGX.js.map +0 -1
  275. package/dist/chunk-GZGLCCEE.js.map +0 -1
  276. package/dist/chunk-H33M77DD.js.map +0 -1
  277. package/dist/chunk-H53QZQJI.js.map +0 -1
  278. package/dist/chunk-I5UXHIDT.js.map +0 -1
  279. package/dist/chunk-ISEJWBFF.js.map +0 -1
  280. package/dist/chunk-IVAWP6HH.js.map +0 -1
  281. package/dist/chunk-JKKU2WKG.js.map +0 -1
  282. package/dist/chunk-KHO5WNTP.js.map +0 -1
  283. package/dist/chunk-MGTDQLJJ.js.map +0 -1
  284. package/dist/chunk-MQPNU2CY.js.map +0 -1
  285. package/dist/chunk-NBYKLUF6.js.map +0 -1
  286. package/dist/chunk-NLE2J5P4.js.map +0 -1
  287. package/dist/chunk-O7SDRBVB.js.map +0 -1
  288. package/dist/chunk-OP4KBXUO.js.map +0 -1
  289. package/dist/chunk-OPXAP3AC.js.map +0 -1
  290. package/dist/chunk-PAPMUAR5.js.map +0 -1
  291. package/dist/chunk-PW42ZXCB.js.map +0 -1
  292. package/dist/chunk-RK6VBLXP.js.map +0 -1
  293. package/dist/chunk-UM5S7DKK.js.map +0 -1
  294. package/dist/chunk-UMQ6NBQR.js.map +0 -1
  295. package/dist/chunk-XC5SJ35F.js.map +0 -1
  296. package/dist/chunk-XD7MY6HB.js.map +0 -1
  297. package/dist/chunk-YPAXJ7EW.js.map +0 -1
  298. package/dist/chunk-YT43MUSJ.js.map +0 -1
  299. package/dist/chunk-Z2MRSS2I.js.map +0 -1
  300. package/dist/claude-code-GRWO6XBZ.js.map +0 -1
  301. package/dist/claude-code-NMRKTAP7.js.map +0 -1
  302. package/dist/cline-25KW25IN.js.map +0 -1
  303. package/dist/codebuddy-ZNYQACMF.js.map +0 -1
  304. package/dist/codebuff-ETYT5UBL.js.map +0 -1
  305. package/dist/codebuff-VR6JUDIY.js.map +0 -1
  306. package/dist/codex-CPNKTXG3.js.map +0 -1
  307. package/dist/codex-YAORPCOD.js.map +0 -1
  308. package/dist/continue-WU2IB5KS.js.map +0 -1
  309. package/dist/copilot-cli-MZTAWMPW.js.map +0 -1
  310. package/dist/copilot-cli-PAP377OM.js.map +0 -1
  311. package/dist/crush-3AVQA4YU.js.map +0 -1
  312. package/dist/crush-QBXLNN7T.js.map +0 -1
  313. package/dist/cursor-DIW43TRZ.js.map +0 -1
  314. package/dist/cursor-GSLUET3V.js +0 -22
  315. package/dist/detect-6V4LC3MA.js.map +0 -1
  316. package/dist/devin-QMEM3OFA.js.map +0 -1
  317. package/dist/doctor-2YDUVSAU.js.map +0 -1
  318. package/dist/droid-MOKV53J4.js.map +0 -1
  319. package/dist/droid-U3ZBLQFO.js.map +0 -1
  320. package/dist/gemini-cli-47ZHCOZR.js.map +0 -1
  321. package/dist/gemini-cli-NMVVBO3K.js.map +0 -1
  322. package/dist/goose-4EI5MYTI.js.map +0 -1
  323. package/dist/goose-64V46Y2W.js.map +0 -1
  324. package/dist/grok-cli-QYQPDSVB.js.map +0 -1
  325. package/dist/hermes-F3EGTK6N.js.map +0 -1
  326. package/dist/hermes-F75OSK3Y.js.map +0 -1
  327. package/dist/hook-OEVRDMXD.js.map +0 -1
  328. package/dist/install-5NMCUDG5.js.map +0 -1
  329. package/dist/jetbrains-copilot-ZGIWI6YV.js.map +0 -1
  330. package/dist/junie-DIFN2P22.js.map +0 -1
  331. package/dist/kilo-EMZJBEBB.js.map +0 -1
  332. package/dist/kilo-SW7BH6EG.js.map +0 -1
  333. package/dist/kilo-cli-S3GXBPAE.js.map +0 -1
  334. package/dist/kilo-cli-ZF272ZHN.js.map +0 -1
  335. package/dist/kimi-5FHEXGZD.js.map +0 -1
  336. package/dist/kimi-IQJOIY6B.js.map +0 -1
  337. package/dist/kiro-BYX4HEAJ.js.map +0 -1
  338. package/dist/kiro-WGOI5CGT.js.map +0 -1
  339. package/dist/leaderboard-XEKS7B3H.js.map +0 -1
  340. package/dist/mimo-code-7R53QDHB.js.map +0 -1
  341. package/dist/mistral-vibe-LHJ55FSB.js.map +0 -1
  342. package/dist/mux-NYCNGL43.js.map +0 -1
  343. package/dist/mux-XM6AP35L.js.map +0 -1
  344. package/dist/nemoclaw-WSIPSE7U.js.map +0 -1
  345. package/dist/omp-562NK5BJ.js.map +0 -1
  346. package/dist/open-interpreter-I2CNOEXY.js.map +0 -1
  347. package/dist/openclaw-5EQFGOWL.js.map +0 -1
  348. package/dist/openclaw-7EYBQS4R.js +0 -17
  349. package/dist/opencode-QGP4ALQY.js.map +0 -1
  350. package/dist/opencode-YS4WX2E2.js.map +0 -1
  351. package/dist/openhands-QMYIKNOS.js.map +0 -1
  352. package/dist/package-G25GVTH2.js.map +0 -1
  353. package/dist/pi-644FIN3A.js.map +0 -1
  354. package/dist/pi-GGDQREVG.js.map +0 -1
  355. package/dist/qwen-code-GQILBJ5B.js.map +0 -1
  356. package/dist/qwen-code-STDMX7EM.js.map +0 -1
  357. package/dist/roo-code-DLPIHHQ6.js.map +0 -1
  358. package/dist/roo-code-SUWI4BBN.js.map +0 -1
  359. package/dist/serve-XTMIUHKK.js.map +0 -1
  360. package/dist/status-VJAGO4Z7.js.map +0 -1
  361. package/dist/statusline-EY2E2UGF.js.map +0 -1
  362. package/dist/synthetic-6FRA7P5Q.js.map +0 -1
  363. package/dist/telemetry-OLZQBADT.js.map +0 -1
  364. package/dist/trae-CPPYASR2.js.map +0 -1
  365. package/dist/trae-UOYD6JZZ.js.map +0 -1
  366. package/dist/uninstall-AZEUPAND.js.map +0 -1
  367. package/dist/upgrade-CAUUHSSC.js.map +0 -1
  368. package/dist/usage-3KHZ4RYZ.js.map +0 -1
  369. package/dist/usage-event-TZWOZPRJ.js.map +0 -1
  370. package/dist/vscode-copilot-NIMH2DGU.js.map +0 -1
  371. package/dist/warp-NRBBJQR2.js.map +0 -1
  372. package/dist/warp-QYJGKURM.js.map +0 -1
  373. package/dist/windsurf-75LLZ37C.js.map +0 -1
  374. package/dist/zed-HKAZXEJW.js.map +0 -1
  375. package/dist/zed-XJFOOKCO.js.map +0 -1
  376. /package/dist/{antigravity-VXLDLTO7.js.map → antigravity-TWIWXTQH.js.map} +0 -0
  377. /package/dist/{cursor-GSLUET3V.js.map → cursor-W7I4QUFO.js.map} +0 -0
  378. /package/dist/{openclaw-7EYBQS4R.js.map → openclaw-IJ33K45M.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/hermes/index.ts"],"sourcesContent":["/**\n * adapters/hermes — Hermes Agent platform adapter for agent-connector.\n *\n * Hermes is a json-stdio host whose ENTIRE configuration — both the MCP servers\n * and the lifecycle hooks — lives in a single user-scope YAML file:\n *\n * ~/.hermes/config.yaml\n *\n * Because the file is YAML, the BaseAdapter JSON helpers do not apply; this\n * adapter merges via core/yaml's readYaml/writeYaml, preserving any unrelated\n * config the user has authored.\n *\n * - MCP servers: top-level snake_case root key `mcp_servers`. The stdio entry\n * uses the portable field names { command, args, env } (unlike Goose's\n * cmd/envs). Hermes has no native env interpolation, so `${env:VAR}` refs are\n * resolved to literals at install time.\n *\n * - Hooks: a top-level `hooks` map keyed by Hermes' NATIVE snake_case event\n * names (pre_tool_call / post_tool_call / on_session_start / on_session_end /\n * subagent_stop — NOT the canonical PascalCase names; see EVENT_TO_HERMES).\n * Each value is a\n * list of shell-hook entries { matcher, command:\"<homeBin> hook …\", timeout }.\n * The command keeps the canonical event token so the runtime dispatcher\n * (parseEvent/formatReply) stays consistent. Hermes shell hooks pipe the\n * event JSON to the command on stdin and read the reply JSON from stdout —\n * the same wire protocol as Claude Code, so the runtime parse/format mirror\n * the Claude adapter (a Claude-like JSON shape; the exact Hermes field map is\n * documented inline where it could vary).\n *\n * Since hooks are external shell commands (not an in-process plugin), Hermes\n * cannot let a hook rewrite tool arguments — canModifyArgs is false. Hermes has\n * no SSE transport, so only stdio + http are advertised.\n */\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, MemoryTarget, NormalizedEvent } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n NotificationEvent,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PostCompactEvent,\n PreCompactEvent,\n PreToolUseEvent,\n SessionEndEvent,\n SessionStartEvent,\n ServerDef,\n StopEvent,\n SubagentStopEvent,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { removeFromObjectMap, upsertInObjectMap } from \"../../core/object-map.js\";\nimport { readYaml, writeYaml, yamlObjectMapCodec } from \"../../core/yaml.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildHomeBinHookCommand,\n buildWrappedStdio,\n isHomeBinActionCommand,\n isHomeBinHookCommand,\n} from \"../../core/spawn.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\n\nconst HOST: PlatformId = \"hermes\";\n/** Root key under which Hermes stores MCP servers in config.yaml (snake_case). */\nconst MCP_ROOT_KEY = \"mcp_servers\";\n/** Top-level key under which Hermes stores shell hooks in config.yaml. */\nconst HOOKS_KEY = \"hooks\";\n/**\n * Top-level map under which Hermes stores `/<id>` slash commands. A\n * `{ type: \"exec\", command }` entry runs the shell command directly, bypassing\n * the LLM — the action emitter's target.\n */\nconst QUICK_COMMANDS_KEY = \"quick_commands\";\n/** Default per-hook timeout (seconds) when the connector declares none. */\nconst DEFAULT_HOOK_TIMEOUT = 60;\n/**\n * Documented per-hook timeout bounds (seconds). Hermes' hooks.md states\n * `timeout: <seconds>` is \"default 60, capped at 300\" and that `timeout > 300`\n * is clamped with a warning by the host. There is no documented minimum; the\n * 1s floor is defensive so a sub-second connector timeoutMs never rounds to 0.\n */\nconst HOOK_TIMEOUT_MAX = 300;\nconst HOOK_TIMEOUT_MIN = 1;\n\n/** One Hermes quick-command entry (a `/<id>` slash command). */\ninterface HermesQuickCommand {\n type: \"exec\";\n command: string;\n}\n\n/**\n * Canonical → Hermes native hook event name. Hermes keys its `hooks:` block by\n * its OWN snake_case lifecycle names (pre_tool_call / post_tool_call /\n * on_session_start / on_session_end — see docs/research/platform-research.json),\n * NOT the canonical PascalCase names. A connector event is only wired when it\n * appears here AND is declared by the connector; everything else is reported as\n * a warn/skip at install time.\n */\nconst EVENT_TO_HERMES: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"pre_tool_call\",\n PostToolUse: \"post_tool_call\",\n SessionStart: \"on_session_start\",\n SessionEnd: \"on_session_end\",\n // Hermes is a STOP-ONLY subagent host: subagent_stop fires when a\n // delegate_task child exits (child_status ∈ completed/failed/interrupted/\n // error); there is NO subagent_start analog. PermissionRequest is also\n // deliberately ABSENT: Hermes' pre_approval_request/post_approval_response\n // hooks OBSERVE the approval prompt but carry no decision control, so a\n // PermissionRequest handler could never be honored — install skip-warns it.\n SubagentStop: \"subagent_stop\",\n};\n\n/** Hermes stdio MCP entry — portable field names (command/args/env). */\ninterface HermesStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n/**\n * Hermes remote HTTP MCP entry — `{ url, headers? }` under the SAME mcp_servers\n * key (no transport/type discriminator). Per the Hermes Agent docs\n * (website/docs/user-guide/features/mcp.md \"HTTP servers\"); OAuth servers add\n * `auth: oauth`, which AC's static-header model does not express.\n */\ninterface HermesHttpServer {\n url: string;\n headers?: Record<string, string>;\n}\n\n/** One Hermes shell-hook entry. */\ninterface HermesHookEntry {\n /** Tool-name matcher (empty = all). Tool events only; \"\" elsewhere. */\n matcher: string;\n /** The home-bin hook command Hermes invokes (event JSON on stdin). */\n command: string;\n /** Hook timeout in seconds. */\n timeout: number;\n}\n\n/**\n * Raw Hermes hook stdin payload — the ACTUAL wire shape emitted by Hermes'\n * `agent/shell_hooks.py::_serialize_payload` (NousResearch/hermes-agent), NOT a\n * Claude-like guess. The serializer keeps ONLY these top-level keys:\n *\n * { hook_event_name, tool_name, tool_input, session_id, cwd, extra }\n *\n * where `tool_name`/`tool_input` come from the invoke kwargs `tool_name`/`args`,\n * `session_id` from `session_id` ?? `parent_session_id`, and EVERY other kwarg\n * is nested under `extra` (see `_TOP_LEVEL_PAYLOAD_KEYS` = {tool_name, args,\n * session_id, parent_session_id}). So all per-event result/status/child fields\n * are read from `extra.*` — top-level reads for them are always undefined.\n */\ninterface HermesWireInput {\n session_id?: string;\n cwd?: string;\n hook_event_name?: string;\n tool_name?: string;\n /** Top-level: the serializer lifts the `args` kwarg here (PreToolUse). */\n tool_input?: Record<string, unknown>;\n /**\n * Every non-allowlisted invoke kwarg nests here. Per-event contents (verified\n * against the host source):\n * - post_tool_call: result, status (\"ok\"|\"error\"), error_type, error_message,\n * duration_ms, task_id, tool_call_id, turn_id, api_request_id, middleware_trace\n * - subagent_stop: child_session_id, child_role, child_summary, child_status\n * (\"completed\"|\"failed\"|\"interrupted\"|\"error\"), duration_ms, parent_turn_id\n * - on_session_start: model, platform\n * - on_session_end: completed (bool), interrupted (bool), task_id, turn_id,\n * model, platform\n */\n extra?: HermesExtra;\n /** Injected by the entrypoint so the runtime knows which connector to dispatch. */\n connector?: string;\n}\n\n/** The `extra` envelope — non-allowlisted invoke kwargs, by event (see above). */\ninterface HermesExtra {\n // post_tool_call\n result?: unknown;\n status?: string;\n error_type?: string;\n error_message?: string;\n // subagent_stop\n child_session_id?: string;\n child_role?: string;\n child_summary?: string;\n child_status?: string;\n // on_session_end\n completed?: boolean;\n interrupted?: boolean;\n // on_session_start / on_session_end\n model?: string;\n platform?: string;\n // ── Defensive only ──────────────────────────────────────────────────────\n // Hermes does NOT fire UserPromptSubmit / PreCompact / PostCompact / Stop /\n // Notification (the matching capabilities are false; install warn-skips them).\n // Were any ever mis-routed here, the serializer would still nest its kwargs\n // under `extra`, so these defensive parse arms read from extra — they never\n // resurface as invented top-level fields.\n prompt?: string;\n trigger?: string;\n stop_hook_active?: boolean;\n message?: string;\n}\n\nexport class HermesAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Hermes Agent\";\n readonly paradigm: HookParadigm = \"json-stdio\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block. memoryTargets below probes\n // for .hermes.md / HERMES.md (first context category wins on hermes —\n // AGENTS.md is ignored when they exist); ~/.hermes holds identity/volatile\n // files (SOUL.md, MEMORY.md), not a rules surface → user-scope skip-warn.\n supportsMemory: true,\n preToolUse: true,\n postToolUse: true,\n preCompact: false,\n // Hermes exposes on_session_start / on_session_end lifecycle hooks.\n sessionStart: true,\n sessionEnd: true,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n // Newer events: Hermes ships subagent_stop (stop-only — no subagent_start\n // analog). permissionRequest stays unset because pre_approval_request is\n // observe-only (no decision control); postToolUseFailure stays unset (a\n // tool failure arrives merged into post_tool_call's result, not as a\n // dedicated event). Install reports the standard skip-warn for those.\n subagentStop: true,\n // Shell hooks cannot rewrite tool args/output in-process.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: true,\n // Hermes has no SSE transport.\n transports: [\"stdio\", \"http\"],\n // Content surface: Hermes auto-discovers dir-per-skill SKILL.md from its\n // LOCAL skills root ~/.hermes/skills — the \"single source of truth,\n // read-write\" dir (hermes-agent.nousresearch.com/docs/user-guide/features/\n // skills, fetched 2026-06-16). The directory name becomes the skill's\n // install slug; frontmatter is { name, description } + optional\n // metadata.hermes.*. USER scope only — there is no documented hermes-owned\n // project skills dir (~/.agents/skills is the cross-tool external dir, not\n // ours), so a project-scope install skip-warns via the base default.\n supportsSkills: true,\n // Native passthrough hooks: Hermes documents many host-specific lifecycle\n // events with NO canonical analog — pre_llm_call / post_llm_call /\n // on_session_finalize / on_session_reset / pre_gateway_dispatch /\n // pre_approval_request / post_approval_response / transform_tool_result\n // (docs/research/platform-research.json). They are host-specific (below the\n // >=3-host core bar; docs/research/host-specific-hook-events-design.md). A\n // connector reaches them by declaring platforms[\"hermes\"].nativeHooks;\n // installHooks files those event-name keys verbatim into the YAML hooks map,\n // and the generic uninstall reverses them.\n supportsNativeHooks: true,\n // Actions surface: Hermes ships `quick_commands.<id>: { type: \"exec\",\n // command }` — a `/<id>` slash command that runs the shell command directly,\n // bypassing the LLM (hermes-agent.nousresearch.com/docs/user-guide/cli:\n // \"custom commands that run shell commands instantly without invoking the\n // LLM\"). We emit one per declared action bound to the home-bin action verb.\n supportsActions: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(_projectDir: string): DetectedPlatform {\n const configPath = this.userConfigPath();\n const configDir = dirname(configPath);\n const installed = existsSync(configDir) || existsSync(configPath);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope: \"user\",\n reason: installed\n ? `found Hermes config at ${configPath}`\n : `no Hermes config at ${configPath}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Memory surface: .hermes.md / HERMES.md shadow probe (project) ────────\n // Hermes assembles project context by FIRST CATEGORY WINS: .hermes.md or\n // HERMES.md (cwd walking up to the git root) → AGENTS.md (cwd only) →\n // CLAUDE.md (cwd only). When a hermes-native file exists our block must live\n // there or it is never loaded. Reason strings note the cwd-only AGENTS.md\n // read and hermes' ~20k-chars-per-file truncation.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n if (this.memoryOverride(ctx)?.path || ctx.scope !== \"project\") {\n return super.memoryTargets(ctx); // user scope: no rules surface → skip-warn\n }\n for (const name of [\".hermes.md\", \"HERMES.md\"]) {\n const candidate = join(ctx.projectDir, name);\n if (existsSync(candidate)) {\n return [\n {\n path: candidate,\n reason: `${name} shadows AGENTS.md on hermes (first context category wins)`,\n budgetBytes: 18 * 1024, // hermes truncates each context file at ~20k chars\n },\n ];\n }\n }\n return [\n {\n path: join(ctx.projectDir, \"AGENTS.md\"),\n reason:\n \"AGENTS.md (hermes reads it from the cwd only — run from the project root; ~20k chars/file truncation)\",\n budgetBytes: 18 * 1024,\n },\n ];\n }\n\n // ── Native paths (server + hooks share the SAME file) ─────────────────────\n\n override getConfigDir(_ctx: InstallContext): string {\n return dirname(this.userConfigPath());\n }\n\n override getServerConfigPath(_ctx: InstallContext): string {\n return this.userConfigPath();\n }\n\n /** Same file as the server config — Hermes hooks live in config.yaml. */\n override getHookConfigPath(_ctx: InstallContext): string {\n return this.userConfigPath();\n }\n\n private userConfigPath(): string {\n return join(homedir(), \".hermes\", \"config.yaml\");\n }\n\n // ── MCP server install / uninstall (YAML mcp_servers) ─────────────────────\n\n override installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n const server = this.effectiveServer(ctx);\n\n if (!server) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: connector.server\n ? \"server registration disabled for hermes\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n // Hermes registers stdio sidecars ({command,args,env}) AND remote HTTP\n // servers ({url,headers}) under the same mcp_servers key. It has no SSE\n // transport (docs: website/docs/user-guide/features/mcp.md), so anything\n // else is reported, never silently dropped.\n const isStdio = server.transport === \"stdio\" && !!server.command;\n const isHttp = server.transport === \"http\" && !!server.url;\n if (!isStdio && !isHttp) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: `transport \"${server.transport}\" not registrable in ${MCP_ROOT_KEY} (stdio + http only)`,\n },\n ];\n }\n\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\n\n const entry = this.renderServerEntry(ctx, server);\n\n return [\n upsertInObjectMap({\n codec: yamlObjectMapCodec(),\n rootKey: MCP_ROOT_KEY,\n policy: \"coerce\",\n platform: this.id,\n configPath: path,\n entryId: connector.id,\n entry,\n dryRun,\n }),\n ];\n }\n\n override uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\n\n return [\n removeFromObjectMap({\n codec: yamlObjectMapCodec(),\n rootKey: MCP_ROOT_KEY,\n policy: \"coerce\",\n platform: this.id,\n configPath: path,\n entryId: connector.id,\n dryRun,\n }),\n ];\n }\n\n /**\n * Render the MCP entry — a remote HTTP `{ url, headers? }` or a stdio sidecar\n * `{ command, args, env }`. Hermes has no native interpolation, so env-refs\n * resolve to literals here. The stdio path honors the telemetry serve-wrapper.\n */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): HermesStdioServer | HermesHttpServer {\n // Remote HTTP — { url, headers? }. Never telemetry-wrapped (a URL has no\n // local command to route through the serve proxy). Hermes has no native env\n // token, so ${env:VAR} refs in url/headers resolve to literals.\n if (server.transport === \"http\") {\n const entry: HermesHttpServer = { url: resolveEnvRefsDeep(server.url ?? \"\") };\n if (server.headers && Object.keys(server.headers).length > 0) {\n const headers: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.headers))) {\n headers[k] = String(v);\n }\n entry.headers = headers;\n }\n return entry;\n }\n\n let command = server.command as string;\n let args = [...(server.args ?? [])];\n\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n command = resolveEnvRefsDeep(command);\n args = resolveEnvRefsDeep(args);\n\n const entry: HermesStdioServer = { command };\n if (args.length > 0) entry.args = args;\n if (server.env && Object.keys(server.env).length > 0) {\n const env: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.env))) {\n env[k] = String(v);\n }\n entry.env = env;\n }\n return entry;\n }\n\n // ── Hook install / uninstall (YAML hooks map in the SAME config.yaml) ─────\n\n override installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getHookConfigPath(ctx);\n const override = connector.platforms[HOST];\n\n // `hooks: false` disables only the NORMALIZED events. nativeHooks is a\n // sibling, hermes-scoped declaration on the same override and installs\n // regardless.\n const events = override?.hooks === false ? [] : connector.hookEvents;\n const nativeHooks = override?.nativeHooks ?? {};\n const nativeEvents = Object.keys(nativeHooks);\n\n if (events.length === 0 && nativeEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: override?.hooks === false ? \"hooks disabled for hermes\" : \"connector declares no hooks\",\n },\n ];\n }\n\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\n\n const cfg = readYaml<Record<string, unknown>>(path) ?? {};\n const hooks = this.hooksBucket(cfg);\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const event of events) {\n const hermesEvent = EVENT_TO_HERMES[event];\n if (!hermesEvent) {\n // No Hermes equivalent for this canonical event — report and skip.\n changes.push({\n platform: this.id,\n action: \"warn\",\n path,\n detail: `${event} has no Hermes hook equivalent — skipped`,\n });\n continue;\n }\n\n // The hook command keeps the CANONICAL event token so the runtime\n // dispatcher (parseEvent/formatReply) stays consistent; only the YAML KEY\n // the entry is filed under is the native Hermes name.\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\n const matcher = connector.hooks[event]?.matcher ?? \"\";\n const timeout = this.hookTimeout(connector.server);\n const desired: HermesHookEntry = { matcher, command, timeout };\n\n const bucket = Array.isArray(hooks[hermesEvent])\n ? (hooks[hermesEvent] as HermesHookEntry[])\n : (hooks[hermesEvent] = [] as HermesHookEntry[]);\n const idx = bucket.findIndex((e) => this.isOurCommand(e?.command, ctx));\n\n if (idx >= 0) {\n if (JSON.stringify(bucket[idx]) === JSON.stringify(desired)) {\n changes.push({ platform: this.id, action: \"skip\", path, detail: `${HOOKS_KEY}.${hermesEvent}` });\n continue;\n }\n bucket[idx] = desired;\n changes.push({ platform: this.id, action: \"update\", path, detail: `${HOOKS_KEY}.${hermesEvent}` });\n } else {\n bucket.push(desired);\n changes.push({ platform: this.id, action: \"create\", path, detail: `${HOOKS_KEY}.${hermesEvent}` });\n }\n mutated = true;\n }\n\n // NATIVE passthrough events: Hermes-native event-name keys (e.g. pre_llm_call,\n // transform_tool_result) filed VERBATIM into the YAML hooks map — no\n // EVENT_TO_HERMES mapping, since they ARE Hermes events. Same entry shape +\n // idempotency, matched by EXACT command so a native key coinciding with a\n // mapped canonical key never clobbers it.\n for (const event of nativeEvents) {\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\n const matcher = nativeHooks[event]?.matcher ?? \"\";\n const timeout = this.hookTimeout(connector.server);\n const desired: HermesHookEntry = { matcher, command, timeout };\n const bucket = Array.isArray(hooks[event])\n ? (hooks[event] as HermesHookEntry[])\n : (hooks[event] = [] as HermesHookEntry[]);\n const idx = bucket.findIndex((e) => e?.command === command);\n if (idx >= 0) {\n if (JSON.stringify(bucket[idx]) === JSON.stringify(desired)) {\n changes.push({ platform: this.id, action: \"skip\", path, detail: `${HOOKS_KEY}.${event} (native)` });\n } else {\n bucket[idx] = desired;\n changes.push({ platform: this.id, action: \"update\", path, detail: `${HOOKS_KEY}.${event} (native)` });\n mutated = true;\n }\n } else {\n bucket.push(desired);\n changes.push({ platform: this.id, action: \"create\", path, detail: `${HOOKS_KEY}.${event} (native)` });\n mutated = true;\n }\n }\n\n if (mutated) writeYaml(path, cfg, dryRun);\n return changes;\n }\n\n override uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\n\n const cfg = readYaml<Record<string, unknown>>(path);\n const hooksRaw = cfg?.[HOOKS_KEY];\n if (\n !cfg ||\n !hooksRaw ||\n typeof hooksRaw !== \"object\" ||\n Array.isArray(hooksRaw)\n ) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks section present\" }];\n }\n const hooks = hooksRaw as Record<string, unknown>;\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n for (const event of Object.keys(hooks)) {\n const bucket = hooks[event];\n if (!Array.isArray(bucket)) continue;\n const kept = (bucket as HermesHookEntry[]).filter(\n (e) => !this.isOurCommand(e?.command, ctx),\n );\n if (kept.length === bucket.length) continue;\n mutated = true;\n if (kept.length > 0) hooks[event] = kept;\n else delete hooks[event];\n changes.push({\n platform: this.id,\n action: \"remove\",\n path,\n detail: `${HOOKS_KEY}.${event} (${bucket.length - kept.length})`,\n });\n }\n\n if (mutated) writeYaml(path, cfg, ctx.dryRun);\n if (changes.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no matching hook entries\" }];\n }\n return changes;\n }\n\n // ── Action surface (quick_commands map in the SAME config.yaml) ───────────\n // Each declared action emits `quick_commands.<id>: { type: \"exec\", command }`\n // where command is the home-bin action verb — a `/<id>` slash command that\n // runs it directly, bypassing the LLM. MERGE-preserve: never clobber another\n // entry. Set-if-absent per id; if `quick_commands.<id>` exists and is NOT\n // ours, skip-warn (the configPatch ownership semantics).\n\n override installActions(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getHookConfigPath(ctx);\n\n if (connector.platforms[HOST]?.actions === false) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"actions disabled for hermes\" }];\n }\n const triggers = this.actionTriggers(ctx);\n if (triggers.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"connector declares no actions\" }];\n }\n\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\n\n const cfg = readYaml<Record<string, unknown>>(path) ?? {};\n const bucket = this.objectBucket(cfg, QUICK_COMMANDS_KEY);\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const trigger of triggers) {\n const desired: HermesQuickCommand = { type: \"exec\", command: trigger.command };\n const existing = bucket[trigger.id];\n if (existing !== undefined) {\n // Set-if-absent: only re-write an entry that is already OURS (an\n // exec entry whose command is our action verb for this connector).\n if (!this.isOurQuickCommand(existing, ctx)) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n path,\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id} exists and is not ours — skipped`,\n });\n continue;\n }\n if (JSON.stringify(existing) === JSON.stringify(desired)) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path,\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id}`,\n });\n continue;\n }\n bucket[trigger.id] = desired;\n changes.push({\n platform: this.id,\n action: \"update\",\n path,\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id}`,\n });\n } else {\n bucket[trigger.id] = desired;\n changes.push({\n platform: this.id,\n action: \"create\",\n path,\n detail: `${QUICK_COMMANDS_KEY}.${trigger.id}`,\n });\n }\n mutated = true;\n }\n\n if (mutated) writeYaml(path, cfg, dryRun);\n return changes;\n }\n\n override uninstallActions(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\n\n const cfg = readYaml<Record<string, unknown>>(path);\n const bucketRaw = cfg?.[QUICK_COMMANDS_KEY];\n if (\n !cfg ||\n !bucketRaw ||\n typeof bucketRaw !== \"object\" ||\n Array.isArray(bucketRaw)\n ) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no quick_commands section present\" }];\n }\n const bucket = bucketRaw as Record<string, unknown>;\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n // Remove ONLY our exec entries; leave foreign entries (and the map itself\n // when any remain) untouched.\n for (const id of Object.keys(bucket)) {\n if (!this.isOurQuickCommand(bucket[id], ctx)) continue;\n delete bucket[id];\n mutated = true;\n changes.push({\n platform: this.id,\n action: \"remove\",\n path,\n detail: `${QUICK_COMMANDS_KEY}.${id}`,\n });\n }\n\n if (mutated) {\n // Drop an emptied map so we leave no orphan key behind.\n if (Object.keys(bucket).length === 0) delete cfg[QUICK_COMMANDS_KEY];\n writeYaml(path, cfg, ctx.dryRun);\n }\n if (changes.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no matching quick_commands entries\" }];\n }\n return changes;\n }\n\n /** True when a quick-command entry is OUR exec action verb for this connector. */\n private isOurQuickCommand(entry: unknown, ctx: InstallContext): boolean {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) return false;\n const e = entry as Partial<HermesQuickCommand>;\n if (e.type !== \"exec\" || typeof e.command !== \"string\") return false;\n return isHomeBinActionCommand(e.command, ctx.homeBinPath, ctx.connector.id);\n }\n\n /** True when a hook command is ours (anchored home-bin + connector id). */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\n }\n\n private hookTimeout(server: ServerDef | undefined): number {\n const ms = server?.timeoutMs;\n if (typeof ms === \"number\" && ms > 0) {\n // Hermes documents `timeout: <seconds>` as \"default 60, capped at 300\";\n // a value > 300 is clamped with a warning by Hermes itself (see hooks.md\n // on NousResearch/hermes-agent). Clamp here so we never emit a value the\n // host would reject/cap. No documented minimum, but a positive timeoutMs\n // must not round down to 0 (an undocumented, ambiguous \"no/instant\"\n // timeout), so floor at 1s. In-range values (1000–300000ms) are unchanged.\n return Math.min(HOOK_TIMEOUT_MAX, Math.max(HOOK_TIMEOUT_MIN, Math.round(ms / 1000)));\n }\n return DEFAULT_HOOK_TIMEOUT;\n }\n\n // ── Content surface: skills (dir-per-skill SKILL.md) ─────────────────────\n // CONTENT-ONLY: pure native-file writers, mirroring goose/openclaw. No\n // runtime dispatch, no home-bin pointer, no telemetry wrap. Idempotent\n // (byte-identical → skip) via writeContentFile and reversible via\n // removeContentFile + removeDirIfEmpty. Honors platforms[\"hermes\"].skills\n // === false. No config.yaml entry — Hermes auto-discovers ~/.hermes/skills.\n //\n // USER scope only: ~/.hermes/skills/<name>/SKILL.md (the documented local,\n // read-write \"single source of truth\"). Project scope skip-warns — there is\n // no hermes-owned project skills dir documented.\n\n /** The user-scope skills ROOT dir (~/.hermes/skills). */\n private skillsDir(): string {\n return join(dirname(this.userConfigPath()), \"skills\");\n }\n\n /** Per-skill directory: ~/.hermes/skills/<name>. */\n private skillDir(name: string): string {\n return join(this.skillsDir(), name);\n }\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for hermes\" }];\n }\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n if (ctx.scope !== \"user\") {\n // Hermes documents only the user-scope ~/.hermes/skills root; there is no\n // hermes-owned project skills dir. Report rather than guess a path.\n return [\n {\n platform: this.id,\n action: \"warn\",\n detail:\n `no project-scope skills dir on hermes (~/.hermes/skills is user-scope only); ` +\n `${connector.skills.length} skipped`,\n },\n ];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(skill.name);\n // Guard a skills path occupied by a regular FILE (would throw ENOTDIR on\n // mkdir): skip-warn rather than crash (the cline `.clinerules`-is-a-file\n // precedent). The skills root or the per-skill dir is the likely culprit.\n const blockingFile = this.firstFileOnSkillPath(dir);\n if (blockingFile !== null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n path: blockingFile,\n detail: `${blockingFile} is a file, not a directory; skill \"${skill.name}\" skipped`,\n });\n continue;\n }\n changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), renderSkillMd(skill), ctx.dryRun),\n );\n // Bundle any resource files beside SKILL.md (relative path → contents).\n // Defense-in-depth: skip+warn on any key that escapes the skill dir\n // (config-time validation already rejects these, but never trust input).\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n }\n return changes;\n }\n\n /**\n * Walk from the skills root (~/.hermes/skills) down to `leaf` and return the\n * FIRST segment that exists as a regular file (a mkdir there throws ENOTDIR),\n * else null — so installSkills can skip-warn instead of crashing.\n */\n private firstFileOnSkillPath(leaf: string): string | null {\n const root = this.skillsDir();\n const segments: string[] = [];\n let cur = leaf;\n while (cur.length >= root.length) {\n segments.unshift(cur);\n if (cur === root) break;\n const parent = dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n for (const p of segments) {\n if (!existsSync(p)) return null;\n try {\n if (statSync(p).isFile()) return p;\n } catch {\n return null;\n }\n }\n return null;\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n if (ctx.scope !== \"user\") {\n // Nothing is written at project scope (install skip-warned), so nothing\n // to clean — report the same scope reason as install for symmetry.\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"no project-scope skills dir on hermes (user-scope only); nothing to remove\",\n },\n ];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(skill.name);\n // Remove only the files we wrote (SKILL.md + declared resources), then the\n // skill dir itself when we own its full contents.\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue; // never delete outside the skill dir\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n // Only remove the skill dir when WE own its full contents — never rm -rf a\n // dir that still holds user-added / sibling-tool / shared files.\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const path = this.getServerConfigPath(ctx);\n const id = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = ctx.connector.hookEvents;\n return [\n {\n name: `${this.name}: config.yaml present`,\n check: () =>\n existsSync(path)\n ? { status: \"OK\", detail: path }\n : { status: \"FAIL\", detail: `not found: ${path}` },\n },\n {\n name: `${this.name}: ${MCP_ROOT_KEY}.${id} registered`,\n check: () => {\n // Only assert what the connector declares: a server-less connector\n // never writes an mcp entry, so its absence is healthy.\n if (!ctx.connector.server) return { status: \"OK\", detail: \"no MCP server declared\" };\n const cfg = readYaml<Record<string, unknown>>(path);\n const bucket = cfg?.[MCP_ROOT_KEY];\n const present =\n typeof bucket === \"object\" &&\n bucket !== null &&\n !Array.isArray(bucket) &&\n id in (bucket as Record<string, unknown>);\n return present\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${id}` }\n : { status: \"FAIL\", detail: `${MCP_ROOT_KEY}.${id} not found in ${path}` };\n },\n },\n {\n name: `${this.name}: hook command registered`,\n check: () => {\n if (hookEvents.length === 0) return { status: \"OK\", detail: \"no hooks declared\" };\n const cfg = readYaml<Record<string, unknown>>(path);\n const hooks = cfg?.[HOOKS_KEY];\n if (!hooks || typeof hooks !== \"object\" || Array.isArray(hooks)) {\n return { status: \"FAIL\", detail: `no ${HOOKS_KEY} section in ${path}` };\n }\n const registered = Object.values(hooks as Record<string, unknown>).some(\n (bucket) =>\n Array.isArray(bucket) &&\n (bucket as HermesHookEntry[]).some((e) =>\n isHomeBinHookCommand(e?.command, homeBin, id),\n ),\n );\n return registered\n ? { status: \"OK\", detail: \"hook command present\" }\n : { status: \"FAIL\", detail: `no hook for ${id} in ${path}` };\n },\n },\n ];\n }\n\n // ── Runtime: parse Hermes stdin JSON → normalized event ──────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as HermesWireInput;\n const base = {\n hostPlatform: HOST,\n connectorId: typeof input.connector === \"string\" ? input.connector : \"\",\n sessionId: typeof input.session_id === \"string\" ? input.session_id : \"\",\n ...(typeof input.cwd === \"string\" ? { projectDir: input.cwd } : {}),\n raw,\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n // VERIFIED (NousResearch/hermes-agent model_tools.py:856-871 +\n // shell_hooks.py::_serialize_payload): post_tool_call's `result` kwarg is\n // NOT allowlisted, so it lands at extra.result — top-level tool_output/\n // tool_response are NEVER emitted. Read extra.result for the output.\n const extra = input.extra ?? {};\n const out = toStringOrUndefined(extra.result);\n // VERIFIED: there is no `is_error` boolean. The host emits status\n // (\"ok\"|\"error\") + error_type/error_message (model_tools.py:815-821,\n // _tool_result_observer_fields), all under extra. Derive isError from a\n // non-ok status or a present error_type; emit only when determinable.\n const isError =\n typeof extra.status === \"string\"\n ? extra.status !== \"ok\"\n : typeof extra.error_type === \"string\"\n ? true\n : undefined;\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n ...(out !== undefined ? { toolOutput: out } : {}),\n ...(typeof isError === \"boolean\" ? { isError } : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n // VERIFIED (NousResearch/hermes-agent conversation_loop.py:340-344):\n // on_session_start is invoked with { session_id, model, platform } only —\n // there is NO `source`/start-reason kwarg (model/platform land under\n // extra). Hermes fires on_session_start ONLY for a brand-new session (not\n // on continuation), so the canonical \"startup\" is the single honest\n // value; there is no compact/resume/clear discriminator to normalize.\n const ev: SessionStartEvent = { ...base, source: \"startup\" };\n return ev;\n }\n case \"SessionEnd\": {\n // VERIFIED (NousResearch/hermes-agent turn_finalizer.py:415-423):\n // on_session_end is invoked with completed:bool / interrupted:bool (both\n // under extra) — there is NO top-level `reason` kwarg. Derive a reason\n // string from the two booleans (interrupted wins; else completed).\n const extra = input.extra ?? {};\n const reason =\n extra.interrupted === true\n ? \"interrupted\"\n : extra.completed === true\n ? \"completed\"\n : undefined;\n const ev: SessionEndEvent = {\n ...base,\n ...(reason !== undefined ? { reason } : {}),\n };\n return ev;\n }\n // The five arms below parse events Hermes does NOT fire (userPromptSubmit/\n // preCompact/stop/notification capabilities are false; PostCompact unset).\n // They stay as defensive normalizers for a manual/mis-routed dispatch, and\n // read from `extra` because that is the only envelope Hermes' serializer\n // produces — never an invented top-level field.\n case \"UserPromptSubmit\": {\n const extra = input.extra ?? {};\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof extra.prompt === \"string\" ? extra.prompt : \"\",\n };\n return ev;\n }\n case \"PreCompact\": {\n const extra = input.extra ?? {};\n const ev: PreCompactEvent = {\n ...base,\n ...(extra.trigger === \"auto\" || extra.trigger === \"manual\"\n ? { trigger: extra.trigger }\n : {}),\n };\n return ev;\n }\n case \"PostCompact\": {\n // Hermes does not fire PostCompact natively (postCompact unset →\n // warn-skip at install). Parsed defensively, mirroring PreCompact, so a\n // manual/mis-routed dispatch normalizes instead of hitting the guard.\n const extra = input.extra ?? {};\n const ev: PostCompactEvent = {\n ...base,\n ...(extra.trigger === \"auto\" || extra.trigger === \"manual\"\n ? { trigger: extra.trigger }\n : {}),\n };\n return ev;\n }\n case \"Stop\": {\n const extra = input.extra ?? {};\n const ev: StopEvent = {\n ...base,\n ...(typeof extra.stop_hook_active === \"boolean\"\n ? { stopHookActive: extra.stop_hook_active }\n : {}),\n };\n return ev;\n }\n case \"Notification\": {\n const extra = input.extra ?? {};\n const ev: NotificationEvent = {\n ...base,\n message: typeof extra.message === \"string\" ? extra.message : \"\",\n };\n return ev;\n }\n case \"SubagentStop\": {\n // VERIFIED (NousResearch/hermes-agent delegate_tool.py:2520-2529): the\n // subagent_stop invoke passes parent_session_id, child_session_id,\n // child_role, child_summary, child_status, duration_ms. Only\n // parent_session_id is allowlisted (→ top-level session_id); EVERY child_*\n // field nests under extra. So the id/role/output all come from extra.* —\n // top-level agent_id/agent_type/child_id/last_assistant_message/\n // stop_hook_active are NEVER emitted by Hermes. child_status (∈ completed/\n // failed/interrupted/error) stays accessible via `raw`.\n const extra = input.extra ?? {};\n const ev: SubagentStopEvent = {\n ...base,\n ...(typeof extra.child_session_id === \"string\"\n ? { agentId: extra.child_session_id }\n : {}),\n ...(typeof extra.child_role === \"string\"\n ? { agentType: extra.child_role }\n : {}),\n ...(typeof extra.child_summary === \"string\"\n ? { lastAssistantMessage: extra.child_summary }\n : {}),\n };\n return ev;\n }\n case \"PermissionRequest\":\n case \"PostToolUseFailure\":\n case \"SubagentStart\": {\n // No Hermes analog: pre_approval_request is observe-only (no decision\n // control), tool failures arrive merged into post_tool_call, and there\n // is no subagent_start. Install already skip-warns these; a runtime\n // dispatch is a mis-route — fail loudly.\n throw new Error(`unsupported hermes hook event: ${String(event)}`);\n }\n default: {\n const _never: never = event;\n throw new Error(`unsupported hermes hook event: ${String(_never)}`);\n }\n }\n }\n\n // ── Runtime: normalized response → Hermes native hook reply ──────────────\n // Hermes shell hooks read a JSON reply from stdout (exit 0 = allow). We emit a\n // Claude-like `hookSpecificOutput` wrapper; if Hermes' exact reply schema\n // differs, this is the single place to adjust the mapping.\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n const decision = response.decision ?? \"allow\";\n\n if (decision === \"deny\") {\n // SubagentStop deny carries Stop semantics — it keeps the subagent\n // running with `reason` as its next instruction — and (like Claude's\n // Stop class) is honored only as the TOP-LEVEL {\"decision\":\"block\",\n // \"reason\"}, not as a permissionDecision envelope.\n if (event === \"SubagentStop\") {\n return this.stdout({\n decision: \"block\",\n reason: response.reason ?? \"Blocked by hook\",\n });\n }\n return this.stdout({\n hookSpecificOutput: {\n hookEventName: event,\n permissionDecision: \"deny\",\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\n },\n });\n }\n\n if (decision === \"ask\") {\n return this.stdout({\n hookSpecificOutput: {\n hookEventName: event,\n permissionDecision: \"ask\",\n permissionDecisionReason: response.reason ?? \"Confirmation required by hook\",\n },\n });\n }\n\n if (decision === \"context\" && response.additionalContext) {\n return this.stdout({\n hookSpecificOutput: { hookEventName: event, additionalContext: response.additionalContext },\n });\n }\n\n // allow / modify (unsupported — shell hooks can't rewrite args) / void.\n return { exitCode: 0 };\n }\n\n private stdout(payload: unknown): HookReply {\n return { exitCode: 0, stdout: JSON.stringify(payload) };\n }\n\n // ── Internal helpers ──────────────────────────────────────────────────────\n\n /** Resolve the per-platform server override into an effective ServerDef. */\n private effectiveServer(ctx: InstallContext): ServerDef | undefined {\n const override = ctx.connector.platforms[this.id]?.server;\n if (override === false) return undefined;\n const base = ctx.connector.server;\n if (!base) return undefined;\n return override && typeof override === \"object\" ? { ...base, ...override } : base;\n }\n\n /** Get-or-create an object bucket (map) at `cfg[key]`. */\n private objectBucket(cfg: Record<string, unknown>, key: string): Record<string, unknown> {\n const existing = cfg[key];\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n return existing as Record<string, unknown>;\n }\n const fresh: Record<string, unknown> = {};\n cfg[key] = fresh;\n return fresh;\n }\n\n /** Get-or-create the hooks map at `cfg.hooks`. */\n private hooksBucket(cfg: Record<string, unknown>): Record<string, unknown> {\n return this.objectBucket(cfg, HOOKS_KEY);\n }\n}\n\n/** Coerce an unknown value into a string for the normalized event. */\nfunction toStringOrUndefined(value: unknown): string | undefined {\n if (value == null) return undefined;\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport const adapter = new HermesAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/commands/hook.ts"],"sourcesContent":["/**\n * cli/commands/hook — the universal json-stdio hook entrypoint.\n *\n * agent-connector hook <platform> <event> --connector <id>\n *\n * This is the single command every host's hook config points at (via the stable\n * home binary). It reads the ENTIRE host payload from stdin, dispatches through\n * runHook, writes any stdout/stderr the adapter produced, and exits with the\n * adapter's exit code (the host interprets it as allow/deny/etc.).\n *\n * Fail-open is the runtime's contract: runHook never rejects, so a framework or\n * handler bug can't wedge a host's tool call.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport type { HookEventName } from \"../../core/types.js\";\nimport { isNativeHookDeclared, runHook, runNativeHook } from \"../../runtime/index.js\";\nimport type { RunHookResult } from \"../../runtime/index.js\";\nimport { fail } from \"../app.js\";\n\n// The CLI hook-dispatch gate: every normalized HookEventName the entrypoint\n// accepts. MUST stay in sync with HookEventName / define-connector ALL_EVENTS —\n// a missing member silently rejects an installed hook at runtime. The\n// hook-dispatch-events test pins this set ⊇ ALL_EVENTS so it cannot drift.\nexport const HOOK_EVENTS: ReadonlySet<string> = new Set<HookEventName>([\n \"SessionStart\",\n \"SessionEnd\",\n \"UserPromptSubmit\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"Stop\",\n \"Notification\",\n \"PermissionRequest\",\n \"PostToolUseFailure\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PostCompact\",\n]);\n\n/** Read all of a readable stream to a UTF-8 string. */\nasync function readAll(stream: NodeJS.ReadStream): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n connector: { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const platformId = positionals[0];\n const event = positionals[1];\n if (!platformId || !event) {\n return fail(\"usage: agent-connector hook <platform> <event> --connector <id>\");\n }\n const connectorId = values.connector;\n if (!connectorId || connectorId.trim() === \"\") {\n return fail(\"hook requires --connector <id>\");\n }\n\n // NATIVE PASSTHROUGH: a non-union event name is accepted ONLY when the\n // resolved connector declares it under platforms[<platform>].nativeHooks —\n // dispatch then bypasses the normalized parse/format entirely (raw stdin →\n // handler → verbatim JSON stdout). Undeclared names keep the strict error.\n if (!HOOK_EVENTS.has(event)) {\n if (!(await isNativeHookDeclared(platformId, event, connectorId))) {\n return fail(`unknown hook event \"${event}\"`);\n }\n const stdin = await readAll(process.stdin);\n const reply = await runNativeHook({ platformId, event, connectorId, stdin });\n return exitWithReply(reply);\n }\n\n // Read the entire host payload before dispatching.\n const stdin = await readAll(process.stdin);\n\n const reply = await runHook({\n platformId,\n event: event as HookEventName,\n connectorId,\n stdin,\n });\n\n return exitWithReply(reply);\n}\n\n/** Write a hook reply's stdout/stderr and exit with its code. */\nfunction exitWithReply(reply: RunHookResult): never {\n if (reply.stdout !== undefined && reply.stdout !== \"\") {\n process.stdout.write(reply.stdout);\n }\n if (reply.stderr !== undefined && reply.stderr !== \"\") {\n process.stderr.write(reply.stderr.endsWith(\"\\n\") ? reply.stderr : `${reply.stderr}\\n`);\n }\n process.exit(reply.exitCode);\n}\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"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/commands/install.ts","../src/core/fetch-source.ts"],"sourcesContent":["/**\n * cli/commands/install — deploy a connector across its target platforms.\n *\n * Resolves the connector config (--connector <path>, else findConnectorConfig\n * walking up from the project dir), loads it into a live ResolvedConnector, and\n * hands it to the chosen DELIVERY METHOD's orchestration:\n *\n * --method direct (default) — the installer renders each host's native\n * MCP + hook + content config in place (zero behavior\n * change for existing scripts).\n * --method marketplace — stage the connector's plugin bundle under the\n * data-root and DRIVE the host's own plugin/marketplace\n * install flow (v1 driver: claude-code; other hosts get\n * never-silent skip/warn records with manual commands).\n *\n * Both methods emit the same ChangeRecords, rendered as a readable diff;\n * --dry-run renders the plan without writing or spawning. A double-install\n * guard (both directions) enforces exactly one method per (connector, host,\n * scope) — a refusal is a `warn` record, so the exit-1-on-warn convention\n * carries over.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport { installConnector } from \"../../core/installer.js\";\nimport { installViaMarketplace, parseInstallMethod } from \"../../core/marketplace.js\";\nimport { findConnectorConfig, loadConnectorFromPath } from \"../../core/load-connector.js\";\nimport { classifySource, resolveRemoteSource } from \"../../core/fetch-source.js\";\nimport {\n buildConnectorSummary,\n fail,\n maybePrintBanner,\n parseScope,\n parseTargets,\n print,\n renderInstallResult,\n} from \"../app.js\";\n\nexport async function run(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n method: { type: \"string\", default: \"direct\" },\n scope: { type: \"string\", default: \"user\" },\n targets: { type: \"string\" },\n connector: { type: \"string\" },\n project: { type: \"string\" },\n \"dry-run\": { type: \"boolean\", default: false },\n // Memory surface: overwrite USER-EDITED managed blocks (hash drift).\n // Default behavior is warn-and-leave; --force backs the file up first.\n force: { type: \"boolean\", default: false },\n // Decorative-banner suppressor (no effect on command output bytes).\n quiet: { type: \"boolean\", default: false },\n },\n // A single positional <source> (local path OR remote GitHub spec) is the\n // ergonomic alias of --connector; either may be remote.\n allowPositionals: true,\n });\n\n maybePrintBanner({ quiet: values.quiet });\n\n const method = parseInstallMethod(values.method);\n if (method == null) {\n return fail(`invalid --method \"${values.method}\" (use direct|marketplace)`);\n }\n\n const projectDir = values.project ?? process.cwd();\n\n // A connector source may arrive as the first positional or via --connector,\n // and may be a LOCAL path (today's behavior) or a REMOTE GitHub spec\n // (owner/repo[/sub][#ref], a github URL, git@…, github:…). The positional and\n // the flag are equivalent; reject ambiguity when both name a source.\n const positionalSource = positionals[0];\n if (positionalSource != null && values.connector != null) {\n return fail(\"pass a connector source as EITHER the positional <source> OR --connector, not both.\");\n }\n const source = positionalSource ?? values.connector;\n\n const scope = parseScope(values.scope);\n if (scope == null) return fail(`invalid --scope \"${values.scope}\" (use user|project)`);\n if (method === \"marketplace\" && scope !== \"user\") {\n return fail(\n \"--method marketplace supports --scope user only (project-scope plugin installs are deferred)\",\n );\n }\n\n // Resolve the source to a loadable connector. A REMOTE spec is fetched into a\n // STABLE cache dir under the data-root and GATED (must be an agent-connector\n // package) before handing off to the existing install flow. A LOCAL source —\n // or no source at all — keeps today's path-discovery behavior unchanged.\n let connector: Awaited<ReturnType<typeof loadConnectorFromPath>>[\"connector\"];\n let modulePath: string;\n const spec = source != null ? classifySource(source) : null;\n if (source != null && spec == null) {\n return fail(\n `\"${source}\" is not a local path or a recognizable GitHub source ` +\n \"(owner/repo[/subpath][#ref], a github.com URL, git@github.com:…, or github:owner/repo).\",\n );\n }\n if (spec != null && spec.kind === \"remote\") {\n try {\n const resolved = await resolveRemoteSource(spec.remote);\n ({ connector, modulePath } = resolved);\n } catch (err) {\n return fail(err instanceof Error ? err.message : String(err));\n }\n } else {\n const configPath = source ?? findConnectorConfig(projectDir);\n if (!configPath) {\n return fail(\n \"no connector config found. Pass a <source> (local path or owner/repo) or \" +\n \"--connector <path>, or add an agent-connector.config.{mjs,js,json} to your project.\",\n );\n }\n ({ connector, modulePath } = await loadConnectorFromPath(configPath));\n }\n\n const targets = parseTargets(values.targets);\n\n const result =\n method === \"marketplace\"\n ? await installViaMarketplace({\n connector,\n modulePath,\n scope,\n projectDir,\n dryRun: values[\"dry-run\"],\n ...(targets ? { targets } : {}),\n })\n : await installConnector({\n connector,\n modulePath,\n scope,\n projectDir,\n dryRun: values[\"dry-run\"],\n force: values.force,\n ...(targets ? { targets } : {}),\n });\n\n result.connector = buildConnectorSummary(connector);\n print(renderInstallResult(result, \"install\"));\n return result.changes.some((c) => c.action === \"warn\") ? 1 : 0;\n}\n","/**\n * core/fetch-source — resolve an `install <source>` argument that may be a\n * LOCAL path OR a REMOTE GitHub spec into a local connector-config path.\n *\n * Responsibilities (MVP):\n * 1. CLASSIFY a source string as local-path vs. remote GitHub spec. A value\n * that exists on disk, or that looks like a filesystem path (starts with\n * `.`, `/`, `~`, a `file://` URL, or a Windows drive/UNC), stays LOCAL and\n * keeps today's behavior. Everything else is parsed as a remote spec.\n * 2. PARSE the supported GitHub forms into { owner, repo, ref?, subpath? }:\n * owner/repo · owner/repo#ref · owner/repo/sub · owner/repo/sub#ref\n * github:owner/repo · https://github.com/owner/repo[/tree/ref/sub]\n * git@github.com:owner/repo.git · the .git suffix on any of the above.\n * 3. FETCH + PERSIST the repo to a STABLE cache dir under the data-root\n * (`sources/<owner>__<repo>[__<ref>]/`), NOT a temp dir, so a connector\n * with a local stdio server keeps resolving after install. Re-fetch updates\n * it. `git clone --depth 1` is preferred; a codeload tarball is the\n * fallback when `git` is unavailable.\n * 4. GATE: the fetched (sub)dir MUST contain an `agent-connector.config.*`\n * that loads — otherwise the target is not an agent-connector connector.\n *\n * The actual fetch is injected via a {@link Fetcher} seam so tests can drive the\n * pipeline against a `file://` git fixture without any real network/GitHub hit.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { isAbsolute, join, relative, resolve } from \"node:path\";\n\nimport { findConnectorConfig, loadConnectorFromPath } from \"./load-connector.js\";\nimport { sourcesDir } from \"./paths.js\";\nimport type { ResolvedConnector } from \"./types.js\";\n\n/** A parsed remote source to fetch (a GitHub spec, or a raw git clone URL such\n * as `file://`/`ssh://`/`git@…`). `ref` is a branch/tag/sha; `subpath` is the\n * directory within the repo that holds the connector config. */\nexport interface RemoteSource {\n owner: string;\n repo: string;\n /** Branch / tag / commit. Undefined → the repo default branch. */\n ref?: string;\n /** Sub-directory inside the repo holding the connector config. */\n subpath?: string;\n /**\n * A raw clone URL (file://, ssh://, git@host:…, https://non-github) when the\n * source is NOT a github.com owner/repo we can derive a URL for. Present → the\n * tarball fallback is unavailable (we can only `git clone` it).\n */\n cloneUrl?: string;\n}\n\n/** The classification of an `install <source>` argument. */\nexport type SourceSpec =\n | { kind: \"local\"; value: string }\n | { kind: \"remote\"; remote: RemoteSource };\n\nconst GITHUB_SEG = /^[A-Za-z0-9._-]+$/;\n\n/**\n * True when `value` should be treated as a LOCAL path (existing behavior),\n * before any remote-spec parse is attempted. Conservative on purpose: a path\n * that exists wins, and the common path sigils (`.`, `/`, `~`, `file://`, a\n * Windows drive letter or UNC) are local even when nothing is on disk yet.\n */\nexport function looksLocal(value: string): boolean {\n if (value === \"\") return true;\n if (existsSync(value)) return true;\n if (\n value.startsWith(\"./\") ||\n value.startsWith(\"../\") ||\n value === \".\" ||\n value === \"..\" ||\n value.startsWith(\"/\") ||\n value.startsWith(\"~\") ||\n value.startsWith(\"file://\")\n ) {\n return true;\n }\n // Windows drive (C:\\ or C:/) or UNC (\\\\server\\share).\n if (/^[A-Za-z]:[\\\\/]/.test(value) || value.startsWith(\"\\\\\\\\\")) return true;\n return false;\n}\n\n/**\n * Parse a remote GitHub spec into a {@link RemoteSource}, or null when `value`\n * is not a recognizable GitHub source. Supports the bare `owner/repo[/sub][#ref]`\n * shorthand, `github:owner/repo`, full `https://github.com/...` (incl.\n * `/tree/<ref>/<subpath>`), and `git@github.com:owner/repo.git`.\n */\nexport function parseRemoteSource(value: string): RemoteSource | null {\n const raw = value.trim();\n if (raw === \"\") return null;\n\n // ── git@github.com:owner/repo(.git) ───────────────────────────────────────\n const scp = raw.match(/^git@github\\.com:([^/]+)\\/(.+?)(?:\\.git)?$/);\n if (scp) {\n return finalizeFromPath(scp[1]!, scp[2]!, undefined);\n }\n\n // ── https://github.com/owner/repo[/tree/<ref>/<subpath>][.git][#ref] ───────\n if (/^https?:\\/\\//i.test(raw) || raw.startsWith(\"git://\")) {\n let url: URL;\n try {\n url = new URL(raw.replace(/^git:\\/\\//, \"https://\"));\n } catch {\n return null;\n }\n if (!/(^|\\.)github\\.com$/i.test(url.hostname)) return null;\n const segs = url.pathname.replace(/^\\/+/, \"\").split(\"/\").filter(Boolean);\n if (segs.length < 2) return null;\n const owner = segs[0]!;\n let repo = segs[1]!.replace(/\\.git$/, \"\");\n let ref: string | undefined;\n let subpath: string | undefined;\n // /tree/<ref>/<subpath...> selects a ref + sub-directory.\n if (segs[2] === \"tree\" || segs[2] === \"blob\") {\n ref = segs[3];\n if (segs.length > 4) subpath = segs.slice(4).join(\"/\");\n } else if (segs.length > 2) {\n subpath = segs.slice(2).join(\"/\");\n }\n const hash = url.hash.replace(/^#/, \"\");\n if (hash) ref = hash;\n if (!GITHUB_SEG.test(owner) || !GITHUB_SEG.test(repo)) return null;\n return cleanRemote({ owner, repo, ref, subpath });\n }\n\n // ── github:owner/repo[...] ────────────────────────────────────────────────\n const shorthand = raw.startsWith(\"github:\") ? raw.slice(\"github:\".length) : raw;\n\n // ── owner/repo[/subpath][#ref] ────────────────────────────────────────────\n // Reject anything that doesn't look like the bare `owner/repo` shape (a single\n // path segment, or a leading slash) so we never misread a stray token.\n const [pathPart, refPart] = splitHash(shorthand);\n const segs = pathPart.split(\"/\").filter(Boolean);\n if (segs.length < 2) return null;\n const owner = segs[0]!;\n const repo = segs[1]!.replace(/\\.git$/, \"\");\n const subpath = segs.length > 2 ? segs.slice(2).join(\"/\") : undefined;\n if (!GITHUB_SEG.test(owner) || !GITHUB_SEG.test(repo)) return null;\n return cleanRemote({ owner, repo, ref: refPart, subpath });\n}\n\n/** Split a \"<path>#<ref>\" into [path, ref?]. */\nfunction splitHash(value: string): [string, string | undefined] {\n const i = value.indexOf(\"#\");\n if (i === -1) return [value, undefined];\n const ref = value.slice(i + 1).trim();\n return [value.slice(0, i), ref === \"\" ? undefined : ref];\n}\n\n/** scp-form helper: the repo half may itself carry `/sub` and `#ref`. */\nfunction finalizeFromPath(owner: string, repoAndRest: string, _ref: undefined): RemoteSource | null {\n const [pathPart, ref] = splitHash(repoAndRest);\n const segs = pathPart.split(\"/\").filter(Boolean);\n const repo = (segs[0] ?? \"\").replace(/\\.git$/, \"\");\n const subpath = segs.length > 1 ? segs.slice(1).join(\"/\") : undefined;\n if (!GITHUB_SEG.test(owner) || !GITHUB_SEG.test(repo)) return null;\n return cleanRemote({ owner, repo, ref, subpath });\n}\n\n/**\n * A git-refname-safe ref charset: branch/tag/sha names plus the `/`, `.`, `_`,\n * `-` they may contain. A LEADING `-` is rejected so a ref can never be read as\n * a git flag (e.g. `--upload-pack=…`) when passed to `git clone --branch`, and\n * the constrained charset keeps cache-dir names clean. Empty is invalid.\n */\nconst REF_RE = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;\n\n/** True when `ref` is a safe git refname (defense-in-depth before exec). */\nexport function isSafeRef(ref: string): boolean {\n return REF_RE.test(ref);\n}\n\n/**\n * Drop empty optional fields so equality/snapshot comparisons stay clean.\n * Returns null when a present `ref` is not git-refname-safe (defense-in-depth:\n * never pass an attacker-shaped ref to `git clone --branch`).\n */\nfunction cleanRemote(r: RemoteSource): RemoteSource | null {\n if (r.ref !== undefined && !isSafeRef(r.ref)) return null;\n const out: RemoteSource = { owner: r.owner, repo: r.repo };\n if (r.ref) out.ref = r.ref;\n if (r.subpath && r.subpath !== \"\") out.subpath = r.subpath;\n return out;\n}\n\n/**\n * Parse a RAW git clone URL (NOT a github.com owner/repo): `file://…`,\n * `ssh://…`, `git@host:owner/repo`, or `https://<non-github>/…`. These are\n * `git clone`-able directly. A trailing `#ref` selects a branch/tag/sha. These\n * forms point at a repo root (no in-URL subpath). Returns null for anything\n * that isn't a clone URL.\n */\nexport function parseGitUrl(value: string): RemoteSource | null {\n const [urlPart, ref] = splitHash(value.trim());\n const isScheme =\n urlPart.startsWith(\"file://\") ||\n urlPart.startsWith(\"ssh://\") ||\n urlPart.startsWith(\"git://\") ||\n /^https?:\\/\\//i.test(urlPart);\n const isScp = /^[^@\\s]+@[^:\\s]+:.+/.test(urlPart) && !urlPart.startsWith(\"git@github.com:\");\n if (!isScheme && !isScp) return null;\n // Reject an unsafe ref (e.g. a leading-dash flag) before it reaches git.\n if (ref !== undefined && !isSafeRef(ref)) return null;\n\n // Derive a stable owner/repo cache key from the URL's last two path segments.\n const stripped = urlPart.replace(/\\.git$/, \"\").replace(/\\/+$/, \"\");\n const segs = stripped.split(/[/:]/).filter(Boolean);\n const repo = segs[segs.length - 1] ?? \"repo\";\n const owner = segs[segs.length - 2] ?? \"git\";\n const out: RemoteSource = { owner, repo, cloneUrl: urlPart };\n if (ref) out.ref = ref;\n return out;\n}\n\n/**\n * Classify an `install <source>` argument. A raw git clone URL (file://, ssh://,\n * git@…) or a GitHub spec is REMOTE (a fetch); a local FILESYSTEM path (existing\n * or path-shaped, EXCLUDING file:// which is a clone URL) keeps today's\n * behavior. Returns null when a non-local value is NOT a recognizable remote.\n */\nexport function classifySource(value: string): SourceSpec | null {\n // A raw git clone URL (incl. file://) is always a FETCH, never a config path —\n // even though file:// is \"path-shaped\" it names a clonable repo, not a config.\n const gitUrl = parseGitUrl(value);\n if (gitUrl) return { kind: \"remote\", remote: gitUrl };\n if (looksLocal(value)) return { kind: \"local\", value };\n const remote = parseRemoteSource(value);\n return remote ? { kind: \"remote\", remote } : null;\n}\n\n/** The clone URL for a remote source (its raw cloneUrl, else the github URL). */\nexport function cloneUrl(r: RemoteSource): string {\n return r.cloneUrl ?? `https://github.com/${r.owner}/${r.repo}.git`;\n}\n\n/** The codeload tarball URL for a github source (default branch when no ref). */\nexport function tarballUrl(r: RemoteSource): string {\n const ref = r.ref ?? \"HEAD\";\n return `https://codeload.github.com/${r.owner}/${r.repo}/tar.gz/${ref}`;\n}\n\n/** The STABLE cache directory a remote source is fetched into. */\nexport function sourceCacheDir(r: RemoteSource): string {\n const safe = (s: string) => s.replace(/[^A-Za-z0-9._-]/g, \"-\");\n // A raw clone URL hashes its full URL into the key so two different file://\n // repos that share an owner/repo basename never collide in the cache.\n const base = r.cloneUrl\n ? `${safe(r.owner)}__${safe(r.repo)}__${shortHash(r.cloneUrl)}`\n : `${safe(r.owner)}__${safe(r.repo)}`;\n const name = r.ref ? `${base}__${safe(r.ref)}` : base;\n return join(sourcesDir(), name);\n}\n\n/** A short, filename-safe hash for disambiguating raw clone URLs in the cache. */\nfunction shortHash(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 8);\n}\n\n/**\n * A fetcher fetches `remote` into the stable directory `dest`. Injected so tests\n * can drive the resolve pipeline against a `file://` git fixture (no network).\n * The default {@link gitFetcher} clones over HTTPS.\n */\nexport type Fetcher = (remote: RemoteSource, dest: string) => void | Promise<void>;\n\n/** True when a usable `git` is on PATH (probed once per process via a cheap call). */\nfunction gitAvailable(): boolean {\n try {\n execFileSync(\"git\", [\"--version\"], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * The default fetcher: `git clone --depth 1 [--branch <ref>] <url> <dest>`.\n * Re-fetch replaces the cache dir so the clone reflects the requested ref. The\n * caller may override the clone URL via `urlFor` (tests pass a `file://` repo).\n */\nexport function makeGitFetcher(urlFor: (r: RemoteSource) => string = cloneUrl): Fetcher {\n return (remote, dest) => {\n if (!gitAvailable()) {\n throw new Error(\n \"git is required to fetch a remote connector source but was not found on PATH. \" +\n \"Install git, or pass a local --connector <path>.\",\n );\n }\n rmSync(dest, { recursive: true, force: true });\n mkdirSync(dest, { recursive: true });\n const args = [\"clone\", \"--depth\", \"1\"];\n if (remote.ref) args.push(\"--branch\", remote.ref);\n args.push(urlFor(remote), dest);\n try {\n execFileSync(\"git\", args, { stdio: \"ignore\" });\n } catch (err) {\n throw new Error(\n `failed to clone ${urlFor(remote)}${remote.ref ? ` (ref ${remote.ref})` : \"\"}: ` +\n `${err instanceof Error ? err.message : String(err)}`,\n );\n }\n };\n}\n\n/**\n * Tarball fallback: download the GitHub codeload `tar.gz` and extract it with\n * the system `tar` (present on Linux, macOS, and Windows 10+). codeload nests\n * everything under a single `<repo>-<ref>/` top dir, which we flatten into\n * `dest`. Used only when `git` is unavailable.\n */\nasync function tarballFetch(remote: RemoteSource, dest: string): Promise<void> {\n const url = tarballUrl(remote);\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`failed to download ${url}: HTTP ${res.status} ${res.statusText}`);\n }\n const buf = Buffer.from(await res.arrayBuffer());\n\n const work = join(tmpdir(), `ac-src-${process.pid}-${Date.now()}`);\n mkdirSync(work, { recursive: true });\n const tarPath = join(work, \"source.tar.gz\");\n writeFileSync(tarPath, buf);\n try {\n execFileSync(\"tar\", [\"-xzf\", tarPath, \"-C\", work], { stdio: \"ignore\" });\n } catch (err) {\n rmSync(work, { recursive: true, force: true });\n throw new Error(\n \"neither git nor a usable `tar` is available to fetch a remote connector \" +\n `source (${err instanceof Error ? err.message : String(err)}). Install git ` +\n \"or tar, or pass a local --connector <path>.\",\n );\n }\n // codeload nests under a single `<repo>-<ref>/` directory — flatten it.\n const entries = readdirSync(work).filter((e) => e !== \"source.tar.gz\");\n const top = entries.length === 1 ? join(work, entries[0]!) : work;\n rmSync(dest, { recursive: true, force: true });\n renameSync(top, dest);\n rmSync(work, { recursive: true, force: true });\n}\n\n/**\n * The default network fetcher: `git clone` when git is on PATH, otherwise the\n * codeload tarball fallback (github.com sources only — a raw clone URL can only\n * be `git clone`d, so it requires git). A clear error is thrown when neither\n * applicable path works.\n */\nexport const gitFetcher: Fetcher = async (remote, dest) => {\n if (gitAvailable()) {\n makeGitFetcher()(remote, dest);\n return;\n }\n if (remote.cloneUrl) {\n throw new Error(\n `git is required to fetch ${remote.cloneUrl} but was not found on PATH. ` +\n \"Install git, or pass a local --connector <path>.\",\n );\n }\n await tarballFetch(remote, dest);\n};\n\n/** The resolved output of {@link resolveRemoteSource}. */\nexport interface ResolvedSource {\n /** Absolute path to the agent-connector.config.* found inside the fetch. */\n configPath: string;\n /** The directory the source was fetched into (stable, under the data-root). */\n sourceDir: string;\n /** The (sub)directory the config was found in. */\n connectorDir: string;\n /** The live connector + its absolute module path (ready for the install flow). */\n connector: ResolvedConnector;\n modulePath: string;\n}\n\n/** Options for {@link resolveRemoteSource}. */\nexport interface ResolveOptions {\n /** Override the fetch (tests). Defaults to {@link gitFetcher}. */\n fetcher?: Fetcher;\n}\n\n/**\n * Fetch a remote source into its stable cache dir, honor the subpath, and GATE\n * it as a real agent-connector package: `findConnectorConfig` must locate an\n * `agent-connector.config.{mjs,js,json}` that `loadConnectorFromPath` can load.\n * Throws a clear, specific error when the target is not an agent-connector\n * connector. Returns everything the install flow needs.\n */\nexport async function resolveRemoteSource(\n remote: RemoteSource,\n opts: ResolveOptions = {},\n): Promise<ResolvedSource> {\n const fetcher = opts.fetcher ?? gitFetcher;\n const sourceDir = sourceCacheDir(remote);\n mkdirSync(sourcesDir(), { recursive: true });\n await fetcher(remote, sourceDir);\n\n const label = describeRemote(remote);\n if (!existsSync(sourceDir)) {\n throw new Error(`failed to fetch ${label}: nothing was written to ${sourceDir}`);\n }\n\n // Honor the subpath; guard against a `..` escape out of the fetched dir.\n // Containment is checked with path.relative (NOT a bare string prefix, which\n // a sibling dir sharing the cache-key prefix would defeat) — mirroring the\n // connectorDir() guard in paths.ts: reject when the relative path is empty,\n // starts with \"..\", or is absolute.\n const root = resolve(sourceDir);\n const searchDir = remote.subpath ? resolve(root, remote.subpath) : root;\n if (remote.subpath) {\n const rel = relative(root, searchDir);\n if (rel === \"\" || rel.startsWith(\"..\") || isAbsolute(rel)) {\n throw new Error(`subpath escapes the fetched source: ${remote.subpath}`);\n }\n }\n if (!existsSync(searchDir)) {\n throw new Error(\n `${label}: subpath \"${remote.subpath}\" does not exist in the repository.`,\n );\n }\n\n // ── PACKAGE GATE ──────────────────────────────────────────────────────────\n // Search only WITHIN the fetched (sub)dir. findConnectorConfig walks UPWARD to\n // the filesystem root, so confine the start dir and verify the hit is inside.\n const configPath = findConfigWithin(searchDir);\n if (!configPath) {\n throw new Error(\n `${label} is not an agent-connector connector — no ` +\n `agent-connector.config.{mjs,js,json} found in the repo` +\n (remote.subpath ? ` at subpath \"${remote.subpath}\"` : \"\") +\n \". The target must be a package built with agent-connector (defineConnector).\",\n );\n }\n\n let connector: ResolvedConnector;\n let modulePath: string;\n try {\n ({ connector, modulePath } = await loadConnectorFromPath(configPath));\n } catch (err) {\n throw new Error(\n `${label}: found ${configPath} but it failed to load as an agent-connector ` +\n `connector (${err instanceof Error ? err.message : String(err)}). The target ` +\n \"must be a package built with agent-connector (defineConnector).\",\n );\n }\n\n return {\n configPath,\n sourceDir,\n connectorDir: searchDir,\n connector,\n modulePath,\n };\n}\n\n/**\n * Locate `agent-connector.config.*` strictly within `dir` (not its ancestors).\n * `findConnectorConfig` walks upward, so we scope the result by asserting the\n * hit is in `dir` itself.\n */\nfunction findConfigWithin(dir: string): string | null {\n const hit = findConnectorConfig(dir);\n if (!hit) return null;\n // Must live directly in the (sub)dir we were pointed at — reject an ancestor\n // hit so a parent dir's config can't masquerade as the repo's.\n const dirAbs = resolve(dir);\n const hitDir = resolve(hit, \"..\");\n return hitDir === dirAbs ? hit : null;\n}\n\n/** A human label for a remote source used in error messages. */\nexport function describeRemote(r: RemoteSource): string {\n let s = r.cloneUrl ?? `${r.owner}/${r.repo}`;\n if (r.subpath) s += `/${r.subpath}`;\n if (r.ref) s += `#${r.ref}`;\n return s;\n}\n"],"mappings":"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","names":["segs","owner","repo","subpath"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/jetbrains-copilot/index.ts"],"sourcesContent":["/**\n * adapters/jetbrains-copilot — JetBrains Copilot platform adapter for agent-connector.\n *\n * JetBrains Copilot shares the Copilot hook paradigm with VS Code Copilot\n * (Claude-compatible json-stdio), but diverges on MCP registration:\n *\n * - MCP servers: JetBrains stores MCP server registration via the IDE Settings\n * UI (Settings > Tools > GitHub Copilot > MCP > Configure), NOT in any file\n * we can reliably write — the runtime owns the `servers` key behind the UI.\n * So `installServer` writes NOTHING and returns a \"warn\" ChangeRecord telling\n * the user to add the server via the JetBrains MCP settings UI. Writing a\n * bogus file would be ignored at best and corrupt real UI state at worst.\n * `getHealthChecks` surfaces this as a WARN (not FAIL).\n *\n * - Hooks (Copilot Preview hooks): file-based and identical in shape to VS Code\n * Copilot. We write one per-connector file at\n * <projectDir>/.github/hooks/<connector-id>.json shaped as:\n * { \"version\": 1, \"hooks\": { <Event>: [ { \"type\": \"command\", \"command\" } ] } }\n * The top-level `version: 1` is REQUIRED — the Copilot hooks runtime rejects a\n * version-less file and no hooks fire. Each entry is a FLAT { type, command }\n * object (no Claude-style { matcher, hooks:[...] } wrapper). JetBrains parses\n * matchers but IGNORES them — ALL hooks fire on ALL tools — so we omit the\n * matcher entirely rather than persist an advisory one that never applies.\n *\n * - Reply: Claude-compatible JSON on stdout (exit 0), a `hookSpecificOutput`\n * object keyed by the PascalCase `hookEventName` carrying permissionDecision\n * (deny|ask) + permissionDecisionReason and additionalContext. This mirrors\n * vscode-copilot/claude-code exactly EXCEPT JetBrains cannot rewrite tool\n * input (canModifyArgs:false), so a \"modify\" decision degrades to allow.\n *\n * Env interpolation: GitHub Copilot does not document a portable native env\n * token for the hooks file, and the hooks file only ever carries our home-bin\n * hook command (no secrets), so there is nothing to interpolate here. MCP env\n * interpolation is moot because we never write the MCP file.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, NormalizedEvent } from \"../spi.js\";\nimport type {\n ChangeRecord,\n CommandDef,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n NotificationEvent,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PostCompactEvent,\n PreCompactEvent,\n PreToolUseEvent,\n SessionEndEvent,\n SessionStartEvent,\n StopEvent,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport {\n buildHomeBinHookCommand,\n isHomeBinHookCommand,\n} from \"../../core/spawn.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\nimport { normalizeSessionSource } from \"../claude-code/wire.js\";\n\nconst HOST: PlatformId = \"jetbrains-copilot\";\n\n/** Top-level version the Copilot hooks runtime requires; a version-less file is rejected. */\nconst JETBRAINS_HOOKS_VERSION = 1;\n\n/**\n * JetBrains Copilot reads PascalCase hook event names from its hooks file —\n * identical to VS Code Copilot / Claude Code. Only the events JetBrains actually\n * delivers are registered; everything else has no Copilot equivalent and is\n * reported as a warn/skip at install time.\n */\nconst EVENT_MAP: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"PreToolUse\",\n PostToolUse: \"PostToolUse\",\n PreCompact: \"PreCompact\",\n SessionStart: \"SessionStart\",\n SessionEnd: \"SessionEnd\",\n UserPromptSubmit: \"UserPromptSubmit\",\n};\n\nconst WORKSPACE_SCOPE_DETAIL =\n \"JetBrains Copilot hooks and content are workspace-scoped (.github); rerun with --scope project to install them.\";\n\n/** A single JetBrains Copilot native hook entry — a flat command object. */\ninterface JetBrainsHookEntry {\n type: \"command\";\n command: string;\n}\n\n/** The shape of a JetBrains Copilot .github/hooks/<connector>.json file. */\ninterface JetBrainsHooksFile {\n version?: number;\n hooks?: Record<string, JetBrainsHookEntry[]>;\n}\n\n/**\n * Raw JetBrains Copilot hook stdin payload (Claude-compatible snake_case fields).\n *\n * Common input fields (every event): session_id, transcript_path, cwd,\n * hook_event_name. There is NO `workspace_roots` field — JetBrains aliases the\n * VS Code `.github/hooks` surface which sends only `cwd` (workspace_roots was a\n * dead fallback; removed — getProjectDir now relies on `cwd` only, matching\n * vscode-copilot #211).\n */\ninterface JetBrainsWireInput {\n session_id?: string;\n transcript_path?: string;\n cwd?: string;\n hook_event_name?: string;\n\n // tool events. PostToolUse fires ONLY after a tool completes SUCCESSFULLY and\n // sends { tool_name, tool_input, tool_use_id, tool_response } — the VS Code\n // `.github/hooks` dialect this host ALIASES (vscode-copilot), NOT copilot-cli's\n // `tool_result`. `tool_response` is the sole result field; there is NO\n // `tool_output` and NO `error_message`, so those reads are dead here.\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_response?: unknown;\n\n // SessionStart\n source?: string;\n // SessionEnd\n reason?: string;\n // UserPromptSubmit\n prompt?: string;\n // PreCompact\n trigger?: string;\n // Stop\n stop_hook_active?: boolean;\n // Notification\n message?: string;\n\n /** Injected by the entrypoint so the runtime knows which connector to dispatch. */\n connector?: string;\n}\n\nexport class JetBrainsCopilotAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"JetBrains Copilot\";\n readonly paradigm: HookParadigm = \"json-stdio\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block via the BaseAdapter default\n // (memoryTargets: project <projectDir>/AGENTS.md; user scope where documented).\n supportsMemory: true,\n // JetBrains Copilot's Preview hooks runtime delivers Pre/PostToolUse,\n // PreCompact, SessionStart, SessionEnd, and UserPromptSubmit (GitHub's\n // hooks-reference) — same surface as VS Code Copilot, whose reply contract\n // this adapter mirrors exactly (see formatReply: UserPromptSubmit/PostToolUse\n // deny → top-level {decision:block}). Stop stays unwired (refuted for\n // JetBrains: an unimplemented feature request, not in the documented schema).\n preToolUse: true,\n postToolUse: true,\n preCompact: true,\n sessionStart: true,\n sessionEnd: true,\n userPromptSubmit: true,\n stop: false,\n notification: false,\n // Newer events: the JetBrains Copilot Preview hooks runtime documents no\n // permission-dialog, tool-failure, or subagent lifecycle events, so\n // permissionRequest / postToolUseFailure / subagentStart / subagentStop\n // stay unset — install reports the standard skip-warn for them.\n // Per the JetBrains spec this host is deny/ask-only: a PreToolUse hook\n // CANNOT rewrite tool input, and PostToolUse cannot rewrite tool output.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: true,\n // MCP is managed via the IDE Settings UI (Settings > Tools > GitHub Copilot\n // > MCP). The UI accepts local stdio servers AND remote Streamable HTTP / SSE\n // servers; AC writes no file, so this list only describes what the UI accepts\n // (install reports a UI-managed warn for every transport).\n transports: [\"stdio\", \"http\", \"sse\"],\n // Content surfaces: JetBrains Copilot consumes the GitHub Copilot .github/\n // files (it has no distinct authoring location), so it is an ALIAS of the\n // vscode-copilot writer for prompt files and Agent Skills. It has no native\n // subagent/chat-mode surface, so subagents stay unsupported (BaseAdapter\n // returns the skip/warn default).\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: false,\n // Native passthrough: GitHub's JetBrains-Copilot changelog documents an\n // errorOccurred / ErrorOccurred lifecycle event with NO canonical\n // HookEventName analog (PostToolUseFailure is tool-scoped, not a session-wide\n // error event). A connector reaches it via platforms[\"jetbrains-copilot\"].\n // nativeHooks; installHooks files the event-name key VERBATIM and the generic\n // uninstall reverses it. PascalCase ErrorOccurred matches the adapter's\n // Claude-compatible payload dialect (GitHub hooks-reference accepts both).\n supportsNativeHooks: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n // JetBrains Copilot integration is observable through two markers:\n // • the project hooks tree (<projectDir>/.github/hooks) we write to, and\n // • our per-connector hooks file specifically.\n // There is no reliable user-profile MCP file to probe (the UI owns it), so\n // detection is project-scoped and keyed on the hooks footprint.\n const githubDir = join(projectDir, \".github\");\n const hooksDir = join(githubDir, \"hooks\");\n const installed = existsSync(hooksDir) || existsSync(githubDir);\n const configPath = hooksDir;\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope: \"project\",\n reason: installed\n ? `found JetBrains Copilot hooks tree at ${hooksDir}`\n : `no JetBrains Copilot hooks tree at ${hooksDir}`,\n confidence: installed ? \"medium\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n /** Hooks live under the workspace .github tree for both scopes. */\n getConfigDir(ctx: InstallContext): string {\n return join(ctx.projectDir, \".github\");\n }\n\n /**\n * MCP server registration has NO writable file on JetBrains — the IDE owns it\n * behind the Settings UI. We still return a stable path (the hooks file) so the\n * base-adapter `doctor`/`backupSettings` helpers have a sensible target rather\n * than a nonexistent/bogus MCP path. `installServer` never writes here.\n */\n getServerConfigPath(ctx: InstallContext): string {\n return this.getHookConfigPath(ctx);\n }\n\n /**\n * Hook registration lives in the workspace-discovered .github/hooks tree, which\n * JetBrains Copilot scans for *.json hook files. We write one file per connector\n * so installs/uninstalls never clobber another connector's hooks. Anchored on\n * projectDir for both scopes — .github/hooks is a workspace concept (there is no\n * user-profile equivalent in the Copilot hooks schema).\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(ctx.projectDir, \".github\", \"hooks\", `${ctx.connector.id}.json`);\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n /**\n * JetBrains MCP registration is UI-only. We never write a file: a bogus file is\n * ignored at best and corrupts real UI-managed state at worst. Emit a \"warn\"\n * ChangeRecord that tells the user exactly where to add the server by hand.\n */\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for jetbrains-copilot\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n return [\n {\n platform: this.id,\n action: \"warn\",\n detail:\n `JetBrains Copilot manages MCP servers via the IDE Settings UI — ` +\n `add \"${connector.id}\" manually under Settings > Tools > GitHub Copilot ` +\n `> MCP > Configure (no file is written here).`,\n },\n ];\n }\n\n /**\n * Nothing was written for the MCP server, so there is nothing to remove. Mirror\n * the install-time guidance as a \"warn\" so an uninstall report is honest about\n * the UI-managed entry the user may still want to remove by hand.\n */\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (!connector.server || connector.platforms[HOST]?.server === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"no MCP server was registered for jetbrains-copilot\",\n },\n ];\n }\n return [\n {\n platform: this.id,\n action: \"warn\",\n detail:\n `JetBrains Copilot MCP servers are UI-managed — if \"${connector.id}\" was ` +\n `added manually, remove it under Settings > Tools > GitHub Copilot > MCP.`,\n },\n ];\n }\n\n // ── Hook install / uninstall ─────────────────────────────────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST];\n const hooksDisabled = override?.hooks === false;\n // `hooks: false` disables only the NORMALIZED events; nativeHooks is a\n // sibling, jetbrains-copilot-scoped declaration that installs regardless.\n const normalizedEvents = hooksDisabled ? [] : connector.hookEvents;\n const nativeHooks = override?.nativeHooks ?? {};\n const nativeEvents = Object.keys(nativeHooks);\n\n if (normalizedEvents.length === 0 && nativeEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: hooksDisabled\n ? \"hooks disabled for jetbrains-copilot\"\n : \"connector declares no hooks\",\n },\n ];\n }\n if (ctx.scope === \"user\") {\n return [{ platform: this.id, action: \"warn\", detail: WORKSPACE_SCOPE_DETAIL }];\n }\n\n const hooksPath = this.getHookConfigPath(ctx);\n const symlink = this.symlinkPathWarning(hooksPath);\n if (symlink) return [symlink];\n\n const file = this.readJson<JetBrainsHooksFile>(hooksPath) ?? {};\n const __skip = this.malformedHookRootSkip(hooksPath, (file as Record<string, unknown>).hooks);\n if (__skip) return [__skip];\n const hooks = (file.hooks ??= {});\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const event of normalizedEvents) {\n const jetbrainsEvent = EVENT_MAP[event];\n if (!jetbrainsEvent) {\n // No JetBrains Copilot equivalent for this normalized event — report+skip.\n changes.push({\n platform: this.id,\n action: \"warn\",\n path: hooksPath,\n detail: `${event} has no JetBrains Copilot hook equivalent — skipped`,\n });\n continue;\n }\n\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\n // Matchers are IGNORED by JetBrains (all hooks fire on all tools), so we omit\n // the matcher entirely — a flat { type, command } entry.\n const entry: JetBrainsHookEntry = { type: \"command\", command };\n\n const bucket = (hooks[jetbrainsEvent] ??= []);\n const existingIdx = bucket.findIndex((e) => this.isOurCommand(e.command, ctx));\n\n if (existingIdx >= 0) {\n if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent} already registered`,\n });\n continue;\n }\n bucket[existingIdx] = entry;\n changes.push({\n platform: this.id,\n action: \"update\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent}`,\n });\n } else {\n bucket.push(entry);\n changes.push({\n platform: this.id,\n action: \"create\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent}`,\n });\n }\n mutated = true;\n }\n\n // NATIVE passthrough events: jetbrains-copilot-native event-name keys (e.g.\n // ErrorOccurred) filed VERBATIM into the hooks map — no EVENT_MAP, since they\n // ARE Copilot events. Flat { type, command } entry (matchers are ignored);\n // matched by EXACT command so a native key coinciding with a normalized one\n // never clobbers it.\n for (const nativeEvent of nativeEvents) {\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, nativeEvent, connector.id);\n const entry: JetBrainsHookEntry = { type: \"command\", command };\n const bucket = (hooks[nativeEvent] ??= []);\n const existingIdx = bucket.findIndex((e) => e.command === command);\n if (existingIdx >= 0) {\n if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: `hooks.${nativeEvent} (native) already registered`,\n });\n continue;\n }\n bucket[existingIdx] = entry;\n changes.push({\n platform: this.id,\n action: \"update\",\n path: hooksPath,\n detail: `hooks.${nativeEvent} (native)`,\n });\n } else {\n bucket.push(entry);\n changes.push({\n platform: this.id,\n action: \"create\",\n path: hooksPath,\n detail: `hooks.${nativeEvent} (native)`,\n });\n }\n mutated = true;\n }\n\n if (mutated) {\n // The top-level version is REQUIRED — a version-less file is rejected and\n // no hooks fire. Always (re)assert it when we write.\n file.version = JETBRAINS_HOOKS_VERSION;\n this.writeJson(hooksPath, file, ctx.dryRun);\n }\n return changes;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const hooksPath = this.getHookConfigPath(ctx);\n const symlink = this.symlinkPathWarning(hooksPath);\n if (symlink) return [symlink];\n\n const file = this.readJson<JetBrainsHooksFile>(hooksPath);\n const hooks = file?.hooks;\n if (!file || !hooks) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: \"no hooks section present\",\n },\n ];\n }\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const jetbrainsEvent of Object.keys(hooks)) {\n const bucket = hooks[jetbrainsEvent];\n if (!Array.isArray(bucket)) continue;\n\n const before = bucket.length;\n // Only strip OUR connector's home-bin commands — never another connector's\n // (isHomeBinHookCommand is id-anchored against a shared-prefix collision).\n const next = bucket.filter((e) => !this.isOurCommand(e.command, ctx));\n const removed = before - next.length;\n if (removed > 0) {\n if (next.length > 0) hooks[jetbrainsEvent] = next;\n else delete hooks[jetbrainsEvent];\n changes.push({\n platform: this.id,\n action: \"remove\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent} (${removed})`,\n });\n mutated = true;\n }\n }\n\n if (mutated) {\n // The hooks file is connector-OWNED (<connector-id>.json), so when our\n // strip leaves it with NO hooks we must DELETE the whole file rather than\n // rewrite a `{ \"hooks\": {}, \"version\": 1 }` shell — an empty shell is an\n // orphan per-connector file that lingers after uninstall. A non-empty\n // result still belongs to us, so we rewrite it as before. dryRun reports\n // the would-be remove without mutating the filesystem.\n if (Object.keys(hooks).length === 0) {\n changes.push(\n this.removeManagedFile(\n hooksPath,\n ctx.dryRun,\n \"removed empty connector hooks file\",\n \"no hooks file present\",\n ),\n );\n // Clean up the parent .github/hooks dir only when it is now empty (it is\n // a per-connector tree; leave it in place if other connectors' files\n // remain).\n changes.push(this.removeDirIfEmpty(dirname(hooksPath), ctx.dryRun));\n } else {\n this.writeJson(hooksPath, file, ctx.dryRun);\n }\n }\n if (changes.length === 0) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: \"no matching hook entries\",\n });\n }\n return changes;\n }\n\n /** True when a hook command references our home binary AND this connector id\n * (anchored so a shared-prefix id can't collide — see isHomeBinHookCommand). */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\n }\n\n // ── Content surfaces: commands / skills ──────────────────────────────────\n // CONTENT-ONLY: pure native-file writers under the workspace .github/ tree\n // ({prompts,skills}). No runtime dispatch, no home-bin pointer, no telemetry\n // wrap. Each method is idempotent (byte-identical → skip) via\n // BaseAdapter.writeContentFile and reversible via removeContentFile. Honors\n // platforms[\"jetbrains-copilot\"] per-surface false to skip.\n //\n // ALIAS of vscode-copilot: JetBrains consumes the GitHub Copilot .github/\n // files and has no distinct authoring location, so the rendered content +\n // paths here are IDENTICAL to the vscode-copilot writer.\n //\n // SHARED .github TREE: vscode-copilot, copilot-cli, and jetbrains-copilot all\n // write under the SAME project <projectDir>/.github tree. The rendered content\n // is identical and idempotent across those connectors, and uninstall here only\n // removes the files THIS connector declared — never another writer's files.\n //\n // SCOPE NOTE: .github is a workspace concept and this adapter is project-\n // scoped (no user-profile .github authoring location exists in the Copilot\n // prompt/skill discovery), so the content root is always the project .github\n // tree — the same dir getConfigDir already anchors on.\n\n /** Root of the content tree — the project .github tree (see getConfigDir). */\n private contentRootDir(ctx: InstallContext): string {\n return this.getConfigDir(ctx);\n }\n\n private promptsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"prompts\");\n }\n private skillsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"skills\");\n }\n\n /** Native command file path: <ghDir>/prompts/<name>.prompt.md. */\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.promptsDir(ctx), `${name}.prompt.md`);\n }\n /** Native skill dir: <ghDir>/skills/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\n }\n\n // ── Commands ──────────────────────────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for jetbrains-copilot\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n if (ctx.scope === \"user\") {\n return [{ platform: this.id, action: \"warn\", detail: WORKSPACE_SCOPE_DETAIL }];\n }\n return connector.commands.map((cmd) =>\n this.writeContentFile(\n this.commandPath(ctx, cmd.name),\n this.renderCommand(cmd),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun),\n );\n }\n\n /** Render a Copilot prompt file: md+frontmatter(description, tools, model, argument-hint). */\n private renderCommand(cmd: CommandDef): string {\n const frontmatter: Record<string, unknown> = {};\n if (cmd.description !== undefined) frontmatter.description = cmd.description;\n // Copilot prompt files express tool access as a `tools` array, sourced from\n // the portable tools.allow policy.\n const allow = cmd.tools?.allow;\n if (allow && allow.length > 0) frontmatter.tools = [...allow];\n if (cmd.model !== undefined) frontmatter.model = cmd.model;\n if (cmd.argumentHint !== undefined) frontmatter[\"argument-hint\"] = cmd.argumentHint;\n if (cmd.extra) Object.assign(frontmatter, cmd.extra);\n return this.renderFrontmatterMd(frontmatter, cmd.prompt);\n }\n\n // ── Skills ────────────────────────────────────────────────────────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for jetbrains-copilot\" }];\n }\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n if (ctx.scope === \"user\") {\n return [{ platform: this.id, action: \"warn\", detail: WORKSPACE_SCOPE_DETAIL }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), renderSkillMd(skill), ctx.dryRun),\n );\n // Bundle any resource files beside SKILL.md (relative path → contents).\n // Defense-in-depth: skip+warn on any key that escapes the skill dir\n // (config-time validation already rejects these, but never trust input).\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n }\n return changes;\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n // Remove only the files we wrote (SKILL.md + declared resources), then the\n // skill dir itself when we own its full contents.\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue; // never delete outside the skill dir\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n // Only remove the skill dir when WE own its full contents — never rm -rf a\n // dir that still holds user-added / sibling-tool / shared files.\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const hooksPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = ctx.connector.hookEvents;\n const hasServer =\n ctx.connector.server != null &&\n ctx.connector.platforms[HOST]?.server !== false;\n const checks: HealthCheck[] = [\n {\n // MCP cannot be verified from disk — JetBrains owns it behind the UI.\n // BaseAdapter.doctor maps != OK to a hard FAIL, but an unverifiable\n // UI-managed surface must NOT hard-fail doctor (that contradicts the\n // install-time WARN). Return OK with a verify-in-UI detail instead.\n name: `${this.name}: MCP server (UI-managed)`,\n check: () =>\n hasServer\n ? {\n status: \"OK\",\n detail:\n \"MCP is UI-managed — verify in Settings > Tools > GitHub Copilot > MCP\",\n }\n : { status: \"OK\", detail: \"connector declares no MCP server\" },\n },\n {\n name: `${this.name}: hook command registered`,\n check: () => {\n if (hookEvents.length === 0) {\n return { status: \"OK\", detail: \"no hooks declared\" };\n }\n if (ctx.scope === \"user\") {\n return {\n status: \"OK\",\n detail: \"hooks are workspace-scoped; install them with --scope project\",\n };\n }\n const file = this.readJson<JetBrainsHooksFile>(hooksPath);\n if (!file) return { status: \"FAIL\", detail: `not found: ${hooksPath}` };\n if (file.version !== JETBRAINS_HOOKS_VERSION) {\n return {\n status: \"FAIL\",\n detail: `${hooksPath} missing required \"version\": ${JETBRAINS_HOOKS_VERSION} — Copilot rejects it`,\n };\n }\n const registered = Object.values(file.hooks ?? {}).some((entries) =>\n (entries ?? []).some((e) =>\n isHomeBinHookCommand(e.command, homeBin, connectorId),\n ),\n );\n return registered\n ? { status: \"OK\", detail: \"hook command present\" }\n : { status: \"FAIL\", detail: `no hook for ${connectorId} in ${hooksPath}` };\n },\n },\n ];\n\n // Content-surface checks: only assert presence of the files this connector\n // declares (skip silently for surfaces it never asked for). Subagents are\n // unsupported here, so they are never checked.\n for (const cmd of ctx.connector.commands) {\n const p = this.commandPath(ctx, cmd.name);\n checks.push({\n name: `${this.name}: command ${cmd.name} present`,\n check: () =>\n ctx.scope === \"user\"\n ? { status: \"OK\", detail: \"commands are workspace-scoped; install them with --scope project\" }\n : existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const skill of ctx.connector.skills) {\n const p = join(this.skillDir(ctx, skill.name), \"SKILL.md\");\n checks.push({\n name: `${this.name}: skill ${skill.name} present`,\n check: () =>\n ctx.scope === \"user\"\n ? { status: \"OK\", detail: \"skills are workspace-scoped; install them with --scope project\" }\n : existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n return checks;\n }\n\n // ── Runtime: parse JetBrains Copilot stdin JSON → normalized event ────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as JetBrainsWireInput;\n const connectorId = typeof input.connector === \"string\" ? input.connector : \"\";\n const sessionId = extractSessionId(input);\n const projectDir = this.getProjectDir(input);\n\n const base = {\n hostPlatform: HOST,\n connectorId,\n sessionId,\n raw,\n ...(projectDir !== undefined ? { projectDir } : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n // PRIMARY SOURCE (VS Code Copilot hooks docs, \"PostToolUse input\"):\n // JetBrains aliases the VS Code `.github/hooks` surface, which fires\n // PostToolUse only after a tool completes SUCCESSFULLY and serializes a\n // single result field, `tool_response`. There is NO `tool_output` and NO\n // `error_message` in this dialect, so the old fallback legs read\n // host-nonexistent fields and the `error_message`-driven `isError` could\n // never become true. Read only `tool_response`; a tool-failure event\n // (PostToolUseFailure) is not part of this surface and is not wired.\n const toolOutput = toolResponseToString(input.tool_response);\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n ...(toolOutput !== undefined ? { toolOutput } : {}),\n };\n return ev;\n }\n case \"PreCompact\": {\n const ev: PreCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"PostCompact\": {\n // JetBrains Copilot does not fire PostCompact natively (postCompact\n // unset → warn-skip at install). Parsed defensively, mirroring\n // PreCompact, so a manual/mis-routed dispatch normalizes instead of\n // hitting the guard.\n const ev: PostCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = {\n ...base,\n source: normalizeSessionSource(input.source ?? input.trigger),\n };\n return ev;\n }\n case \"SessionEnd\": {\n const ev: SessionEndEvent = {\n ...base,\n ...(typeof input.reason === \"string\" ? { reason: input.reason } : {}),\n };\n return ev;\n }\n case \"UserPromptSubmit\": {\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.prompt === \"string\" ? input.prompt : \"\",\n };\n return ev;\n }\n case \"Stop\": {\n const ev: StopEvent = {\n ...base,\n ...(typeof input.stop_hook_active === \"boolean\"\n ? { stopHookActive: input.stop_hook_active }\n : {}),\n };\n return ev;\n }\n case \"Notification\": {\n const ev: NotificationEvent = {\n ...base,\n message: typeof input.message === \"string\" ? input.message : \"\",\n };\n return ev;\n }\n case \"PermissionRequest\":\n case \"PostToolUseFailure\":\n case \"SubagentStart\":\n case \"SubagentStop\": {\n // No JetBrains Copilot analog — its Preview hooks runtime documents no\n // permission-dialog, tool-failure, or subagent lifecycle events.\n // Install already skip-warns these via EVENT_MAP; a runtime dispatch is\n // a mis-route — fail loudly.\n throw new Error(`unsupported jetbrains-copilot hook event: ${String(event)}`);\n }\n default: {\n // Exhaustive guard — every HookEventName is handled above. (JetBrains only\n // delivers the four it declares; the rest are handled defensively so a\n // mis-dispatch stays inert rather than crashing.)\n const _never: never = event;\n throw new Error(`unsupported jetbrains-copilot hook event: ${String(_never)}`);\n }\n }\n }\n\n /**\n * Resolve the project dir from the wire payload. PRIMARY SOURCE (VS Code\n * `.github/hooks` dialect this host aliases): the only working-directory field\n * sent is `cwd`. There is no `workspace_roots` field — the old\n * `?? workspace_roots[0]` fallback read a host-nonexistent field and is removed\n * (parity with vscode-copilot #211).\n */\n private getProjectDir(input: JetBrainsWireInput): string | undefined {\n return typeof input.cwd === \"string\" ? input.cwd : undefined;\n }\n\n // ── Runtime: normalized response → JetBrains Copilot native hook reply ────\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n const hookEventName = event;\n const decision = response.decision ?? \"allow\";\n\n // deny → block the action with a reason (exit 0; JSON carries the decision).\n // JetBrains Copilot's reply is Claude-compatible, identical to vscode-copilot:\n // `hookSpecificOutput.permissionDecision` is read ONLY for the pre-execution\n // PreToolUse permission event. The post-execution / turn-control events —\n // PostToolUse, UserPromptSubmit, Stop, SubagentStop — block via the TOP-LEVEL\n // {\"decision\":\"block\",\"reason\"} instead (PostToolUse runs AFTER the tool, so a\n // permissionDecision there is silently ignored). Mirrors vscode-copilot #56/#58.\n if (decision === \"deny\") {\n if (\n event === \"PostToolUse\" ||\n event === \"UserPromptSubmit\" ||\n event === \"Stop\" ||\n event === \"SubagentStop\"\n ) {\n return this.stdout({\n decision: \"block\",\n reason: response.reason ?? \"Blocked by hook\",\n });\n }\n return this.stdout({\n hookSpecificOutput: {\n hookEventName,\n permissionDecision: \"deny\",\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\n },\n });\n }\n\n // ask → prompt the user to confirm.\n if (decision === \"ask\") {\n return this.stdout({\n hookSpecificOutput: {\n hookEventName,\n permissionDecision: \"ask\",\n permissionDecisionReason:\n response.reason ?? \"Confirmation required by hook\",\n },\n });\n }\n\n // modify → unsupported on JetBrains (canModifyArgs:false): a PreToolUse hook\n // cannot rewrite tool input here, so degrade to allow rather than emit an\n // updatedInput the host will ignore.\n\n // context → inject soft guidance (also the SessionStart context path).\n if (decision === \"context\" && response.additionalContext) {\n return this.stdout({\n hookSpecificOutput: { hookEventName, additionalContext: response.additionalContext },\n });\n }\n\n // allow / void / modify-degradation / unsupported → pass through with exit 0.\n return { exitCode: 0 };\n }\n\n private stdout(payload: unknown): HookReply {\n return { exitCode: 0, stdout: JSON.stringify(payload) };\n }\n}\n\n/**\n * Extract a stable session id from a JetBrains Copilot wire payload. Priority\n * mirrors the Claude-compatible wire: transcript UUID > session_id > \"\" (the\n * framework uses \"\" when no id is available — no ppid fabrication here).\n */\nfunction extractSessionId(input: JetBrainsWireInput): string {\n if (typeof input.transcript_path === \"string\") {\n const m = input.transcript_path.match(/([a-f0-9-]{36})\\.jsonl$/);\n if (m && m[1]) return m[1];\n }\n if (typeof input.session_id === \"string\" && input.session_id !== \"\") {\n return input.session_id;\n }\n return \"\";\n}\n\n/** Coerce a Claude-compatible PostToolUse `tool_response` into a string. */\nfunction toolResponseToString(value: unknown): string | undefined {\n if (value == null) return undefined;\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport const adapter = new JetBrainsCopilotAdapter();\nexport default adapter;\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/junie/index.ts"],"sourcesContent":["/**\n * adapters/junie — Junie (JetBrains' own LLM-agnostic coding agent) adapter.\n *\n * Junie is JetBrains' OWN coding agent (\"An LLM-agnostic coding agent built for\n * real-world development — by JetBrains\", github.com/JetBrains/junie). It is\n * DISTINCT from the `jetbrains-copilot` adapter, which targets GitHub Copilot\n * running inside JetBrains IDEs. Junie ships as a terminal CLI (`junie`,\n * installed via junie.jetbrains.com/install.sh, Homebrew, or\n * `npm i -g @jetbrains/junie`) and also runs inside JetBrains IDEs / CI.\n *\n * From agent-connector's hook-paradigm perspective Junie is **mcp-only**: the\n * first-party docs (junie.jetbrains.com/docs) document NO user-installable\n * lifecycle hook / event-callback surface — only MCP server registration,\n * Agent Skills, subagents, custom slash commands, and guidelines/memory. So MCP\n * registration is the only runtime surface this adapter installs and every hook\n * capability is reported false. (Content surfaces exist natively but are not\n * wired here — see the capabilities note.)\n *\n * MCP config (BYTE-CONFIRMED — junie.jetbrains.com/docs/junie-cli-mcp-configuration.html,\n * \"Junie CLI uses the same MCP JSON configuration as Junie in JetBrains IDEs\"):\n * - PROJECT scope → <projectDir>/.junie/mcp/mcp.json (\"can be checked into\n * version control and shared across all team members\").\n * - USER scope → ~/.junie/mcp/mcp.json (\"available across all projects on\n * your machine while remaining private to your user account\").\n * - root key \"mcpServers\" — a JSON object/map keyed by server name.\n *\n * Server entry shapes (BYTE-CONFIRMED from the docs' verbatim JSON example):\n * - stdio: { command, args?, env? }\n * - remote: { url, headers? } — the key is `url` (NOT `serverUrl`); there is\n * NO `type` discriminator and NO `disabled` field. stdio vs remote is\n * distinguished by `command` vs `url`. `headers` is emitted only when the\n * connector's remote server provides them.\n *\n * Env interpolation: the docs example carries literal `env` values and document\n * no portable native `${env:VAR}` token for the MCP file, so every `${env:VAR}`\n * reference is resolved to a literal at install time (the safe path, same as\n * cline / windsurf / droid).\n *\n * The hook \"config path\" is aliased to the MCP file (no separate hook file) so\n * the generic doctor/backup helpers behave sensibly (the windsurf/cline idiom).\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, InstallContext } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookParadigm,\n PlatformCapabilities,\n PlatformId,\n ServerDef,\n Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport { buildWrappedStdio } from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"junie\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/**\n * Native MCP server entry shapes Junie accepts under `mcpServers` (an OBJECT map\n * keyed by server name):\n * - stdio: { command, args?, env? } — transport inferred from `command`.\n * - remote: { url, headers? } — `url` (NOT `serverUrl`); NO `type`\n * discriminator and NO `disabled` flag. `headers` only when provided.\n */\ninterface JunieStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface JunieRemoteServer {\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class JunieAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Junie\";\n readonly paradigm: HookParadigm = \"mcp-only\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: BaseAdapter AGENTS.md-first default. Junie documents its\n // own guidelines/memory surface; AC's AGENTS.md default lands in the open\n // standard file Junie also reads. (Junie-specific guideline files are not\n // wired here — the AGENTS.md default is the host-agnostic baseline.)\n supportsMemory: true,\n //\n // mcp-only: Junie documents NO user-installable lifecycle hook / event-\n // callback surface (junie.jetbrains.com/docs). Every hook flag is false.\n preToolUse: false,\n postToolUse: false,\n preCompact: false,\n sessionStart: false,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n // No hook layer → no arg/output rewrite, no context injection.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n // Junie registers stdio MCP servers (Local: Docker/npx/binary) and remote\n // (HTTP/HTTPS) servers — the remote entry is distinguished by `url` (vs\n // stdio's `command`).\n transports: [\"stdio\", \"http\"],\n // Content surfaces (Agent Skills, subagents, custom slash commands) exist\n // natively in Junie but are NOT wired by this adapter — the initial scope is\n // MCP-only. They stay UNSET so the base skip-warns; this is an honest\n // CEILING, not a host gap.\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".junie\");\n const userMcp = join(userDir, \"mcp\", \"mcp.json\");\n // ~/.junie/allowlist.json is Junie CLI's action-allowlist file\n // (byte-confirmed — junie.jetbrains.com/docs/junie-cli.html), so the dir's\n // presence is a strong CLI-installed marker.\n const projectDirJunie = join(projectDir, \".junie\");\n const installed = existsSync(userDir) || existsSync(projectDirJunie);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath: userMcp,\n scope: \"user\",\n reason: installed\n ? `found Junie config under ${userDir}`\n : `no Junie config at ${userDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n /**\n * Junie's MCP config dir is `<scope-root>/.junie/mcp`: project scope at\n * <projectDir>/.junie/mcp, user scope at ~/.junie/mcp (BYTE-CONFIRMED —\n * junie.jetbrains.com/docs/junie-cli-mcp-configuration.html).\n */\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".junie\", \"mcp\")\n : join(homedir(), \".junie\", \"mcp\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp.json\");\n }\n\n /**\n * Junie has no separate hook file — the hook config path aliases the MCP file\n * so the generic doctor/backup helpers behave sensibly (windsurf/cline idiom).\n */\n getHookConfigPath(ctx: InstallContext): string {\n return this.getServerConfigPath(ctx);\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for junie\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n // Shallow-merge any per-platform server override into the base ServerDef.\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const serverPath = this.getServerConfigPath(ctx);\n\n // NEVER clobber a malformed `mcpServers`. The base upsert tolerates a\n // missing file / missing key (it creates the object), but a PRESENT-but-\n // non-object `mcpServers` (e.g. an array or string from a hand-edit) would\n // get a named property bolted on and silently corrupted — so skip-and-warn.\n const malformed = this.malformedRootKey(serverPath);\n if (malformed) return [malformed];\n\n const entry = this.renderServerEntry(ctx, server);\n\n return [\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n const malformed = this.malformedRootKey(serverPath);\n if (malformed) return [malformed];\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /**\n * Guard for a PRESENT-but-non-object `mcpServers` root key: returns a\n * skip-warn ChangeRecord when the existing config parses but its `mcpServers`\n * value is not a plain object (an array / string / number / null). Returns\n * undefined when the file is absent, unparseable (the base upsert's own\n * overwrite guard handles that), or `mcpServers` is absent / a plain object.\n */\n private malformedRootKey(configPath: string): ChangeRecord | undefined {\n const cfg = this.readJson<Record<string, unknown>>(configPath);\n if (!cfg || !(MCP_ROOT_KEY in cfg)) return undefined;\n const root = cfg[MCP_ROOT_KEY];\n if (root !== null && typeof root === \"object\" && !Array.isArray(root)) {\n return undefined;\n }\n return {\n platform: this.id,\n action: \"warn\",\n path: configPath,\n detail: `existing ${MCP_ROOT_KEY} in ${configPath} is not an object map; left untouched (back it up / fix it, then re-run)`,\n };\n }\n\n /** Render a normalized ServerDef into Junie's native mcpServers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): JunieStdioServer | JunieRemoteServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route the real command through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n // Junie documents no native interpolation token for the MCP file, so\n // resolve every ${env:VAR} to a literal at install time.\n const entry: JunieStdioServer = {\n command: resolveEnvRefsDeep(command),\n };\n if (args.length > 0) entry.args = resolveEnvRefsDeep(args);\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // http (and any other remote transport we surface) — Junie registers a\n // remote URL under `url` (NOT `serverUrl`). NO `type` discriminator, NO\n // `disabled`. `headers` only when the connector's remote server provides them.\n const entry: JunieRemoteServer = {\n url: resolveEnvRefsDeep(server.url ?? \"\"),\n };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Junie documents no native interpolation token, so\n * resolve `${env:VAR}` references to literals at install time.\n */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Hooks (unavailable — Junie is mcp-only) ──────────────────────────────\n\n installHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Junie is mcp-only)\",\n },\n ];\n }\n\n uninstallHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Junie is mcp-only)\",\n },\n ];\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const mcpPath = this.getServerConfigPath(ctx);\n const connectorId = ctx.connector.id;\n return [\n {\n name: `${this.name}: mcp.json present`,\n check: () =>\n existsSync(mcpPath)\n ? { status: \"OK\", detail: mcpPath }\n : { status: \"FAIL\", detail: `not found: ${mcpPath}` },\n },\n {\n name: `${this.name}: server entry registered`,\n check: () => {\n // Only assert what the connector declares: a server-less connector\n // never writes an mcpServers entry, so its absence is healthy.\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readJson<{ [k: string]: Record<string, unknown> }>(mcpPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };\n }\n return connectorId in bucket\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${connectorId} present` }\n : {\n status: \"FAIL\",\n detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${mcpPath}`,\n };\n },\n },\n ];\n }\n}\n\nexport const adapter = new JunieAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}