@ken-jo/agent-connector 0.4.8 → 0.4.26

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 (225) hide show
  1. package/README.md +36 -24
  2. package/dist/{action-RWPRIZIC.js → action-AZRZ3V7E.js} +12 -12
  3. package/dist/amazon-q-BWSOHTW5.js +571 -0
  4. package/dist/amazon-q-BWSOHTW5.js.map +1 -0
  5. package/dist/{amp-TULUPXXL.js → amp-BQZOL5GR.js} +2 -2
  6. package/dist/{amp-PU4LFSY6.js → amp-TF5X6OGH.js} +4 -4
  7. package/dist/{antigravity-DWW35HZO.js → antigravity-3XHBPXZK.js} +5 -5
  8. package/dist/{antigravity-STHZWMP3.js → antigravity-EA4L225L.js} +2 -2
  9. package/dist/{antigravity-cli-P6HADOAO.js → antigravity-cli-B2HXZFYQ.js} +2 -2
  10. package/dist/{antigravity-cli-VTQ6DNWL.js → antigravity-cli-TJGOBUPK.js} +5 -5
  11. package/dist/{chunk-A2T4Q7RM.js → chunk-25BNMXPP.js} +18 -18
  12. package/dist/{chunk-NLFPH4S2.js → chunk-2RPHDVHW.js} +2 -2
  13. package/dist/{chunk-KG6T3YNJ.js → chunk-3I7UG52L.js} +23 -4
  14. package/dist/chunk-3I7UG52L.js.map +1 -0
  15. package/dist/{chunk-BCHWFTV4.js → chunk-F4DSMVZ7.js} +2 -2
  16. package/dist/{chunk-XQUUNAGC.js → chunk-HU6DZZBG.js} +36 -36
  17. package/dist/{chunk-CDVOBKSG.js → chunk-HZDU3J4U.js} +8 -3
  18. package/dist/chunk-HZDU3J4U.js.map +1 -0
  19. package/dist/{chunk-SCVBYSF7.js → chunk-IRUYJD23.js} +28 -28
  20. package/dist/{chunk-VRKTVCYJ.js → chunk-IW46JIQM.js} +33 -43
  21. package/dist/chunk-IW46JIQM.js.map +1 -0
  22. package/dist/{chunk-OZ5EXXQV.js → chunk-JLMD3IGK.js} +2 -2
  23. package/dist/{chunk-YS2NYJ6R.js → chunk-KD4BE5MW.js} +2 -2
  24. package/dist/{chunk-FAHIMJRU.js → chunk-L7ESV37V.js} +2 -2
  25. package/dist/{chunk-JNM3TPLX.js → chunk-LETB5HCK.js} +2 -2
  26. package/dist/{chunk-7TVBFRVI.js → chunk-M3H7PQWT.js} +2 -2
  27. package/dist/{chunk-JWNT5KW7.js → chunk-O7SDRBVB.js} +3 -1
  28. package/dist/chunk-O7SDRBVB.js.map +1 -0
  29. package/dist/{chunk-MOW2RKHX.js → chunk-OLI5SD6I.js} +8 -4
  30. package/dist/chunk-OLI5SD6I.js.map +1 -0
  31. package/dist/{chunk-NYR55UT7.js → chunk-Q5HR4ADS.js} +2 -2
  32. package/dist/{chunk-TRQKHP7D.js → chunk-QY42WGBX.js} +23 -2
  33. package/dist/chunk-QY42WGBX.js.map +1 -0
  34. package/dist/{chunk-HOE2MN36.js → chunk-YEJCNOET.js} +4 -4
  35. package/dist/{chunk-WI6YSXOC.js → chunk-YKVNI44Y.js} +51 -28
  36. package/dist/chunk-YKVNI44Y.js.map +1 -0
  37. package/dist/{chunk-CENEXP7K.js → chunk-YRBFSZ2G.js} +10 -3
  38. package/dist/chunk-YRBFSZ2G.js.map +1 -0
  39. package/dist/{chunk-YYISBXOM.js → chunk-ZVTPSV5Z.js} +9 -8
  40. package/dist/{chunk-YYISBXOM.js.map → chunk-ZVTPSV5Z.js.map} +1 -1
  41. package/dist/{chunk-N6HH7K6P.js → chunk-ZY25RG4Y.js} +2 -2
  42. package/dist/{claude-code-64X6RR2S.js → claude-code-JLPFUZ4V.js} +8 -8
  43. package/dist/{claude-code-W74MNTAC.js → claude-code-NMRKTAP7.js} +2 -2
  44. package/dist/cli/sdk.js +7 -7
  45. package/dist/cli.js +1 -1
  46. package/dist/{cline-T7ZDJYZQ.js → cline-GBP3EVSX.js} +4 -4
  47. package/dist/{codebuff-3PMZJJHP.js → codebuff-ETYT5UBL.js} +2 -2
  48. package/dist/{codebuff-PPPY3SJV.js → codebuff-WMKFUVER.js} +4 -4
  49. package/dist/{codex-EEVN43C2.js → codex-5CZR5XKX.js} +4 -4
  50. package/dist/{codex-Q3ATRRX3.js → codex-YAORPCOD.js} +2 -2
  51. package/dist/{continue-VLLZO4PM.js → continue-3AGXWM5W.js} +5 -5
  52. package/dist/{copilot-cli-A7G5WB4N.js → copilot-cli-IH4P3GRZ.js} +4 -4
  53. package/dist/{copilot-cli-SJGIXVSD.js → copilot-cli-MZTAWMPW.js} +2 -2
  54. package/dist/{crush-AH24GDDB.js → crush-FDBL3JEK.js} +4 -4
  55. package/dist/{crush-LN5QFFR2.js → crush-QBXLNN7T.js} +2 -2
  56. package/dist/{cursor-QZ6MTO74.js → cursor-DIW43TRZ.js} +2 -2
  57. package/dist/{cursor-GJBSMXI6.js → cursor-R5QB4YR4.js} +4 -4
  58. package/dist/{detect-YDCZNV4W.js → detect-L5OZPVFO.js} +4 -4
  59. package/dist/{doctor-DGC7P3P7.js → doctor-WDIQ2YFE.js} +12 -12
  60. package/dist/{droid-W5WF5XEX.js → droid-U3ZBLQFO.js} +2 -2
  61. package/dist/{droid-RBWCFKL3.js → droid-X2QHQL7D.js} +4 -4
  62. package/dist/{gemini-cli-CFPFEJEA.js → gemini-cli-HCN7XKSX.js} +4 -4
  63. package/dist/{gemini-cli-CIRW37TU.js → gemini-cli-NMVVBO3K.js} +2 -2
  64. package/dist/{goose-A3M5GODH.js → goose-64V46Y2W.js} +2 -2
  65. package/dist/{goose-UBJVQFUE.js → goose-ILMM76JP.js} +5 -5
  66. package/dist/{hermes-ZYLMOFLZ.js → hermes-F3EGTK6N.js} +2 -2
  67. package/dist/{hermes-6FXGXLNL.js → hermes-YX2ODUZL.js} +5 -5
  68. package/dist/{hook-CDGSCASQ.js → hook-JRDQ56BN.js} +12 -12
  69. package/dist/index.d.ts +2 -2
  70. package/dist/index.js +5 -5
  71. package/dist/{install-2D3UKEME.js → install-HRCVPRAQ.js} +12 -12
  72. package/dist/{introspect-Cn3MSA4_.d.ts → introspect-B164-hj3.d.ts} +1 -1
  73. package/dist/{jetbrains-copilot-K26KMA3U.js → jetbrains-copilot-QESFUN6W.js} +4 -4
  74. package/dist/{kilo-BKZJ26RM.js → kilo-POTCYIRG.js} +4 -4
  75. package/dist/{kilo-NSWAVP6P.js → kilo-SW7BH6EG.js} +2 -2
  76. package/dist/{kilo-cli-6UVWCXQD.js → kilo-cli-MO6FSMH2.js} +4 -4
  77. package/dist/{kilo-cli-EVBKUODA.js → kilo-cli-ZF272ZHN.js} +2 -2
  78. package/dist/{kimi-EI3UM3ZV.js → kimi-5FHEXGZD.js} +72 -13
  79. package/dist/kimi-5FHEXGZD.js.map +1 -0
  80. package/dist/{kimi-QALYPSRR.js → kimi-RXS36OJP.js} +28 -21
  81. package/dist/kimi-RXS36OJP.js.map +1 -0
  82. package/dist/{kiro-J5J42I5Z.js → kiro-VTLX7CMF.js} +4 -4
  83. package/dist/{kiro-UCLSLBW2.js → kiro-WGOI5CGT.js} +2 -2
  84. package/dist/{leaderboard-VZQXNWTX.js → leaderboard-ASGR3E2U.js} +6 -6
  85. package/dist/{mimo-code-BEE622P2.js → mimo-code-F4BWMESO.js} +37 -6
  86. package/dist/mimo-code-F4BWMESO.js.map +1 -0
  87. package/dist/{mux-5HTNKK4K.js → mux-2YFCYFM7.js} +4 -4
  88. package/dist/{mux-ZMLVAXOO.js → mux-XM6AP35L.js} +2 -2
  89. package/dist/{nemoclaw-DNFIZFDF.js → nemoclaw-QDB6O22A.js} +5 -5
  90. package/dist/{omp-I3UTRBNP.js → omp-P2JNAEPN.js} +4 -4
  91. package/dist/{openclaw-QE2LMWIF.js → openclaw-3UMBSSZM.js} +5 -5
  92. package/dist/{openclaw-IYA7ASL6.js → openclaw-5EQFGOWL.js} +2 -2
  93. package/dist/{opencode-ZFSUYJXI.js → opencode-Q6H4YT66.js} +4 -4
  94. package/dist/{opencode-HWT3RSMN.js → opencode-QGP4ALQY.js} +2 -2
  95. package/dist/{package-BSCCMW4E.js → package-IXBSG7HD.js} +9 -9
  96. package/dist/{pi-UFX2OYFV.js → pi-GGDQREVG.js} +2 -2
  97. package/dist/{pi-H2KBBDDJ.js → pi-GW25LPC3.js} +4 -4
  98. package/dist/{qwen-code-W7NUCDEN.js → qwen-code-GQILBJ5B.js} +2 -2
  99. package/dist/{qwen-code-5LE34FNE.js → qwen-code-R6XXEEHJ.js} +5 -5
  100. package/dist/{roo-code-XH4GCYIS.js → roo-code-EZPNFC5V.js} +4 -4
  101. package/dist/{roo-code-ZLKH4A7N.js → roo-code-SUWI4BBN.js} +2 -2
  102. package/dist/runtime/index.d.ts +1 -1
  103. package/dist/runtime/index.js +10 -10
  104. package/dist/sdk/index.d.ts +3 -3
  105. package/dist/sdk/index.js +6 -6
  106. package/dist/sdk/test.d.ts +2 -2
  107. package/dist/sdk/test.js +9 -9
  108. package/dist/{serve-MQNGPY2H.js → serve-CFBQYKRB.js} +12 -12
  109. package/dist/{status-MRHVRDFY.js → status-ASBFEFQQ.js} +10 -10
  110. package/dist/{statusline-IYWA75TR.js → statusline-WKLWSM7I.js} +11 -11
  111. package/dist/{synthetic-UKR6SMGS.js → synthetic-6FRA7P5Q.js} +2 -2
  112. package/dist/{telemetry-IONIOMLC.js → telemetry-64GCGNIW.js} +10 -10
  113. package/dist/{trae-RVNRSV7X.js → trae-6VQW2UVP.js} +4 -4
  114. package/dist/{trae-PA26DPBW.js → trae-CPPYASR2.js} +2 -2
  115. package/dist/{types-_6arHbX9.d.ts → types-COSBYpKs.d.ts} +7 -5
  116. package/dist/{uninstall-ESLSVCLE.js → uninstall-KDJYE5ET.js} +12 -12
  117. package/dist/{upgrade-VICY5T64.js → upgrade-YQRVYR5U.js} +12 -12
  118. package/dist/{usage-TCUWV2YZ.js → usage-OV2BDZKF.js} +3 -3
  119. package/dist/{usage-event-CBZZP37Q.js → usage-event-KPI3NEX3.js} +11 -11
  120. package/dist/{vscode-copilot-B2QBBHJW.js → vscode-copilot-UOEEV4P3.js} +4 -4
  121. package/dist/{warp-5R54ST3N.js → warp-LUK2BPCU.js} +4 -4
  122. package/dist/{warp-JNQA7PBU.js → warp-NRBBJQR2.js} +2 -2
  123. package/dist/{windsurf-L32UEOLY.js → windsurf-NZ3G42NQ.js} +4 -4
  124. package/dist/{zed-FDJHJZKD.js → zed-LGWGZ4EO.js} +4 -4
  125. package/dist/{zed-NNNX5MNT.js → zed-XJFOOKCO.js} +2 -2
  126. package/package.json +7 -2
  127. package/dist/amazon-q-5LJOB5L3.js +0 -264
  128. package/dist/amazon-q-5LJOB5L3.js.map +0 -1
  129. package/dist/chunk-CDVOBKSG.js.map +0 -1
  130. package/dist/chunk-CENEXP7K.js.map +0 -1
  131. package/dist/chunk-JWNT5KW7.js.map +0 -1
  132. package/dist/chunk-KG6T3YNJ.js.map +0 -1
  133. package/dist/chunk-MOW2RKHX.js.map +0 -1
  134. package/dist/chunk-TRQKHP7D.js.map +0 -1
  135. package/dist/chunk-VRKTVCYJ.js.map +0 -1
  136. package/dist/chunk-WI6YSXOC.js.map +0 -1
  137. package/dist/kimi-EI3UM3ZV.js.map +0 -1
  138. package/dist/kimi-QALYPSRR.js.map +0 -1
  139. package/dist/mimo-code-BEE622P2.js.map +0 -1
  140. /package/dist/{action-RWPRIZIC.js.map → action-AZRZ3V7E.js.map} +0 -0
  141. /package/dist/{amp-TULUPXXL.js.map → amp-BQZOL5GR.js.map} +0 -0
  142. /package/dist/{amp-PU4LFSY6.js.map → amp-TF5X6OGH.js.map} +0 -0
  143. /package/dist/{antigravity-DWW35HZO.js.map → antigravity-3XHBPXZK.js.map} +0 -0
  144. /package/dist/{antigravity-STHZWMP3.js.map → antigravity-EA4L225L.js.map} +0 -0
  145. /package/dist/{antigravity-cli-P6HADOAO.js.map → antigravity-cli-B2HXZFYQ.js.map} +0 -0
  146. /package/dist/{antigravity-cli-VTQ6DNWL.js.map → antigravity-cli-TJGOBUPK.js.map} +0 -0
  147. /package/dist/{chunk-A2T4Q7RM.js.map → chunk-25BNMXPP.js.map} +0 -0
  148. /package/dist/{chunk-NLFPH4S2.js.map → chunk-2RPHDVHW.js.map} +0 -0
  149. /package/dist/{chunk-BCHWFTV4.js.map → chunk-F4DSMVZ7.js.map} +0 -0
  150. /package/dist/{chunk-XQUUNAGC.js.map → chunk-HU6DZZBG.js.map} +0 -0
  151. /package/dist/{chunk-SCVBYSF7.js.map → chunk-IRUYJD23.js.map} +0 -0
  152. /package/dist/{chunk-OZ5EXXQV.js.map → chunk-JLMD3IGK.js.map} +0 -0
  153. /package/dist/{chunk-YS2NYJ6R.js.map → chunk-KD4BE5MW.js.map} +0 -0
  154. /package/dist/{chunk-FAHIMJRU.js.map → chunk-L7ESV37V.js.map} +0 -0
  155. /package/dist/{chunk-JNM3TPLX.js.map → chunk-LETB5HCK.js.map} +0 -0
  156. /package/dist/{chunk-7TVBFRVI.js.map → chunk-M3H7PQWT.js.map} +0 -0
  157. /package/dist/{chunk-NYR55UT7.js.map → chunk-Q5HR4ADS.js.map} +0 -0
  158. /package/dist/{chunk-HOE2MN36.js.map → chunk-YEJCNOET.js.map} +0 -0
  159. /package/dist/{chunk-N6HH7K6P.js.map → chunk-ZY25RG4Y.js.map} +0 -0
  160. /package/dist/{claude-code-64X6RR2S.js.map → claude-code-JLPFUZ4V.js.map} +0 -0
  161. /package/dist/{claude-code-W74MNTAC.js.map → claude-code-NMRKTAP7.js.map} +0 -0
  162. /package/dist/{cline-T7ZDJYZQ.js.map → cline-GBP3EVSX.js.map} +0 -0
  163. /package/dist/{codebuff-3PMZJJHP.js.map → codebuff-ETYT5UBL.js.map} +0 -0
  164. /package/dist/{codebuff-PPPY3SJV.js.map → codebuff-WMKFUVER.js.map} +0 -0
  165. /package/dist/{codex-EEVN43C2.js.map → codex-5CZR5XKX.js.map} +0 -0
  166. /package/dist/{codex-Q3ATRRX3.js.map → codex-YAORPCOD.js.map} +0 -0
  167. /package/dist/{continue-VLLZO4PM.js.map → continue-3AGXWM5W.js.map} +0 -0
  168. /package/dist/{copilot-cli-A7G5WB4N.js.map → copilot-cli-IH4P3GRZ.js.map} +0 -0
  169. /package/dist/{copilot-cli-SJGIXVSD.js.map → copilot-cli-MZTAWMPW.js.map} +0 -0
  170. /package/dist/{crush-AH24GDDB.js.map → crush-FDBL3JEK.js.map} +0 -0
  171. /package/dist/{crush-LN5QFFR2.js.map → crush-QBXLNN7T.js.map} +0 -0
  172. /package/dist/{cursor-QZ6MTO74.js.map → cursor-DIW43TRZ.js.map} +0 -0
  173. /package/dist/{cursor-GJBSMXI6.js.map → cursor-R5QB4YR4.js.map} +0 -0
  174. /package/dist/{detect-YDCZNV4W.js.map → detect-L5OZPVFO.js.map} +0 -0
  175. /package/dist/{doctor-DGC7P3P7.js.map → doctor-WDIQ2YFE.js.map} +0 -0
  176. /package/dist/{droid-W5WF5XEX.js.map → droid-U3ZBLQFO.js.map} +0 -0
  177. /package/dist/{droid-RBWCFKL3.js.map → droid-X2QHQL7D.js.map} +0 -0
  178. /package/dist/{gemini-cli-CFPFEJEA.js.map → gemini-cli-HCN7XKSX.js.map} +0 -0
  179. /package/dist/{gemini-cli-CIRW37TU.js.map → gemini-cli-NMVVBO3K.js.map} +0 -0
  180. /package/dist/{goose-A3M5GODH.js.map → goose-64V46Y2W.js.map} +0 -0
  181. /package/dist/{goose-UBJVQFUE.js.map → goose-ILMM76JP.js.map} +0 -0
  182. /package/dist/{hermes-ZYLMOFLZ.js.map → hermes-F3EGTK6N.js.map} +0 -0
  183. /package/dist/{hermes-6FXGXLNL.js.map → hermes-YX2ODUZL.js.map} +0 -0
  184. /package/dist/{hook-CDGSCASQ.js.map → hook-JRDQ56BN.js.map} +0 -0
  185. /package/dist/{install-2D3UKEME.js.map → install-HRCVPRAQ.js.map} +0 -0
  186. /package/dist/{jetbrains-copilot-K26KMA3U.js.map → jetbrains-copilot-QESFUN6W.js.map} +0 -0
  187. /package/dist/{kilo-BKZJ26RM.js.map → kilo-POTCYIRG.js.map} +0 -0
  188. /package/dist/{kilo-NSWAVP6P.js.map → kilo-SW7BH6EG.js.map} +0 -0
  189. /package/dist/{kilo-cli-6UVWCXQD.js.map → kilo-cli-MO6FSMH2.js.map} +0 -0
  190. /package/dist/{kilo-cli-EVBKUODA.js.map → kilo-cli-ZF272ZHN.js.map} +0 -0
  191. /package/dist/{kiro-J5J42I5Z.js.map → kiro-VTLX7CMF.js.map} +0 -0
  192. /package/dist/{kiro-UCLSLBW2.js.map → kiro-WGOI5CGT.js.map} +0 -0
  193. /package/dist/{leaderboard-VZQXNWTX.js.map → leaderboard-ASGR3E2U.js.map} +0 -0
  194. /package/dist/{mux-5HTNKK4K.js.map → mux-2YFCYFM7.js.map} +0 -0
  195. /package/dist/{mux-ZMLVAXOO.js.map → mux-XM6AP35L.js.map} +0 -0
  196. /package/dist/{nemoclaw-DNFIZFDF.js.map → nemoclaw-QDB6O22A.js.map} +0 -0
  197. /package/dist/{omp-I3UTRBNP.js.map → omp-P2JNAEPN.js.map} +0 -0
  198. /package/dist/{openclaw-QE2LMWIF.js.map → openclaw-3UMBSSZM.js.map} +0 -0
  199. /package/dist/{openclaw-IYA7ASL6.js.map → openclaw-5EQFGOWL.js.map} +0 -0
  200. /package/dist/{opencode-ZFSUYJXI.js.map → opencode-Q6H4YT66.js.map} +0 -0
  201. /package/dist/{opencode-HWT3RSMN.js.map → opencode-QGP4ALQY.js.map} +0 -0
  202. /package/dist/{package-BSCCMW4E.js.map → package-IXBSG7HD.js.map} +0 -0
  203. /package/dist/{pi-UFX2OYFV.js.map → pi-GGDQREVG.js.map} +0 -0
  204. /package/dist/{pi-H2KBBDDJ.js.map → pi-GW25LPC3.js.map} +0 -0
  205. /package/dist/{qwen-code-W7NUCDEN.js.map → qwen-code-GQILBJ5B.js.map} +0 -0
  206. /package/dist/{qwen-code-5LE34FNE.js.map → qwen-code-R6XXEEHJ.js.map} +0 -0
  207. /package/dist/{roo-code-XH4GCYIS.js.map → roo-code-EZPNFC5V.js.map} +0 -0
  208. /package/dist/{roo-code-ZLKH4A7N.js.map → roo-code-SUWI4BBN.js.map} +0 -0
  209. /package/dist/{serve-MQNGPY2H.js.map → serve-CFBQYKRB.js.map} +0 -0
  210. /package/dist/{status-MRHVRDFY.js.map → status-ASBFEFQQ.js.map} +0 -0
  211. /package/dist/{statusline-IYWA75TR.js.map → statusline-WKLWSM7I.js.map} +0 -0
  212. /package/dist/{synthetic-UKR6SMGS.js.map → synthetic-6FRA7P5Q.js.map} +0 -0
  213. /package/dist/{telemetry-IONIOMLC.js.map → telemetry-64GCGNIW.js.map} +0 -0
  214. /package/dist/{trae-RVNRSV7X.js.map → trae-6VQW2UVP.js.map} +0 -0
  215. /package/dist/{trae-PA26DPBW.js.map → trae-CPPYASR2.js.map} +0 -0
  216. /package/dist/{uninstall-ESLSVCLE.js.map → uninstall-KDJYE5ET.js.map} +0 -0
  217. /package/dist/{upgrade-VICY5T64.js.map → upgrade-YQRVYR5U.js.map} +0 -0
  218. /package/dist/{usage-TCUWV2YZ.js.map → usage-OV2BDZKF.js.map} +0 -0
  219. /package/dist/{usage-event-CBZZP37Q.js.map → usage-event-KPI3NEX3.js.map} +0 -0
  220. /package/dist/{vscode-copilot-B2QBBHJW.js.map → vscode-copilot-UOEEV4P3.js.map} +0 -0
  221. /package/dist/{warp-5R54ST3N.js.map → warp-LUK2BPCU.js.map} +0 -0
  222. /package/dist/{warp-JNQA7PBU.js.map → warp-NRBBJQR2.js.map} +0 -0
  223. /package/dist/{windsurf-L32UEOLY.js.map → windsurf-NZ3G42NQ.js.map} +0 -0
  224. /package/dist/{zed-FDJHJZKD.js.map → zed-LGWGZ4EO.js.map} +0 -0
  225. /package/dist/{zed-NNNX5MNT.js.map → zed-XJFOOKCO.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/telemetry-accessor.ts","../src/telemetry/measure.ts","../src/runtime/hook-entrypoint.ts"],"sourcesContent":["/**\n * runtime/telemetry-accessor — build the handler-facing {@link TelemetryAccessor}.\n *\n * Every runtime entrypoint (hook / statusline / action) stamps `ctx.telemetry`\n * (or `evt.telemetry`) with the accessor built here so a connector handler can\n * read ITS OWN recorded usage on demand (`await ctx.telemetry?.()`), without the\n * handler reaching into the telemetry store directly.\n *\n * The accessor is LAZY (it opens the store only when called) and DEFENSIVE:\n * - AGENT_CONNECTOR_TELEMETRY=0 → resolves zeros without touching disk;\n * - any read error → resolves zeros (NEVER throws into a handler — the hook\n * runtime is fail-open, the statusline fail-safe, and even the action\n * surface must not have a usage read crash an otherwise-fine run).\n *\n * COST: each call reads the connector's telemetry file in full (the NDJSON\n * store has no since/limit bound) and linear-scans it. Cheap for normal stores,\n * but a handler on a HOT path (e.g. a status line rendered every refresh) should\n * call it sparingly and cache the result rather than invoking it per render.\n */\n\nimport type { TelemetryAccessor, TelemetryUsageSummary } from \"../core/types.js\";\nimport { openStore } from \"../telemetry/store.js\";\n\n/** The empty summary returned when telemetry is off or a read fails. */\nconst ZERO: TelemetryUsageSummary = {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n calls: 0,\n};\n\n/**\n * Build a {@link TelemetryAccessor} bound to `connectorId`. The returned async\n * function sums every stored row's inputTokens/outputTokens for the connector\n * and counts the rows (`calls`). Honors the AGENT_CONNECTOR_TELEMETRY=0 kill\n * switch (zeros, no disk touch) and swallows any error (zeros) — it never throws.\n */\nexport function buildTelemetryAccessor(connectorId: string): TelemetryAccessor {\n return async (): Promise<TelemetryUsageSummary> => {\n if (process.env.AGENT_CONNECTOR_TELEMETRY === \"0\") return { ...ZERO };\n try {\n const store = openStore({});\n try {\n let inputTokens = 0;\n let outputTokens = 0;\n let calls = 0;\n // COERCE each addend to a finite number: query() tolerates malformed\n // LINES but does not validate field shapes, so a legacy/hand-edited row\n // with a missing (→ NaN) or string (→ concat) token field must not\n // poison the summary's numeric contract. A non-finite token reads as 0.\n for (const row of store.query({ connectorId })) {\n inputTokens += Number.isFinite(row.inputTokens) ? row.inputTokens : 0;\n outputTokens += Number.isFinite(row.outputTokens) ? row.outputTokens : 0;\n calls += 1;\n }\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n calls,\n };\n } finally {\n store.close();\n }\n } catch {\n // Never throw into a handler — a usage read failure resolves to zeros.\n return { ...ZERO };\n }\n };\n}\n","/**\n * telemetry/measure — pure measurement helpers over a single MCP tool call.\n *\n * The framework tokenizes its OWN bytes: the tool-call arguments going in, the\n * tool result coming out, and the fixed tool-definition schemas. These helpers\n * turn those into {@link TokenCount}s using the default {@link Tokenizer}.\n *\n * Honesty rules:\n * • Binary modalities (image/audio/resource blobs) are NOT tokenized — base64\n * would massively over-count. Each gets a flat per-modality estimate, and\n * because that estimate is itself an approximation the combined confidence\n * is pulled down to at least \"tokenizer-approx\".\n * • When combining several counts, the reported confidence is the WORST\n * (least-confident) of the inputs — never report \"exact\" for a mixed bag.\n *\n * Everything here is pure: no IO, no mutation of inputs.\n */\n\nimport { getTokenizer } from \"./tokenizer.js\";\nimport { worstConfidence } from \"./types.js\";\nimport type {\n ConfidenceSource,\n ModelFamily,\n TokenCount,\n Tokenizer,\n} from \"./types.js\";\n\n/** Per-call measurement: tokens in, tokens out, and combined confidence. */\nexport interface ToolCallMeasurement {\n inputTokens: number;\n outputTokens: number;\n source: ConfidenceSource;\n}\n\n/**\n * Flat token estimates for non-text content blocks. These mirror common host\n * accounting (an image tile is roughly ~85 tokens at low detail); they are\n * deliberately coarse — we never tokenize the underlying base64 payload.\n */\nconst MODALITY_ESTIMATE: Record<string, number> = {\n image: 85,\n audio: 85,\n resource: 85,\n};\n/** Fallback estimate for an unknown non-text block type. */\nconst UNKNOWN_BLOCK_ESTIMATE = 85;\n\n// Confidence ordering + the worst-of comparison live in ./types (the single\n// source of truth, imported as `worstConfidence` above). Re-exported here so\n// callers that already import `worstConfidence` from this module keep working\n// as a new ConfidenceSource value (e.g. tokenizer-calibrated) slots into the\n// shared ordering.\nexport { worstConfidence };\n\n/** Reduce a list of sources to the single worst (least-confident) one. */\nfunction combineSources(sources: readonly ConfidenceSource[]): ConfidenceSource {\n // Default to the most-confident floor so an empty list combines to the only\n // other source it is paired with; in practice callers always pass ≥1 source.\n let worst: ConfidenceSource = \"host-native\";\n for (const s of sources) worst = worstConfidence(worst, s);\n return worst;\n}\n\n// ── Structural shapes we read from a tool result (kept local + narrow) ───────\n\n/** A text content block: `{ type: \"text\", text: \"...\" }`. */\ninterface TextBlock {\n type: \"text\";\n text?: unknown;\n}\n/** Any content block; only text blocks expose a `text` field we tokenize. */\ninterface ContentBlock {\n type?: unknown;\n text?: unknown;\n}\n/** The portion of an MCP tool result we measure. */\ninterface ToolResultLike {\n content?: unknown;\n structuredContent?: unknown;\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n\nfunction isTextBlock(block: ContentBlock): block is TextBlock {\n return block.type === \"text\";\n}\n\n/**\n * Measure one tool call.\n *\n * Input = canonical JSON of `args`.\n * Output = tokens over the TEXTUAL parts of `result`:\n * • If `result.content` is an array of blocks, text blocks are tokenized via\n * their `text` field and non-text blocks add a flat per-modality estimate\n * (no base64 tokenization).\n * • `result.structuredContent`, when present, is tokenized as canonical JSON.\n * • Anything else (string / arbitrary object) is tokenized as canonical JSON.\n *\n * The reported `source` is the worst of the input and output sources.\n */\nexport function measureToolCall(\n args: unknown,\n result: unknown,\n family: ModelFamily,\n tok: Tokenizer = getTokenizer(),\n): ToolCallMeasurement {\n const input = tok.countValue(args, family);\n const output = measureResult(result, family, tok);\n return {\n inputTokens: input.tokens,\n outputTokens: output.tokens,\n source: worstConfidence(input.source, output.source),\n };\n}\n\n/** Tokenize the textual + structured parts of a tool result. */\nfunction measureResult(\n result: unknown,\n family: ModelFamily,\n tok: Tokenizer,\n): TokenCount {\n if (!isObject(result)) {\n // Plain string or scalar result — count its canonical form directly.\n return tok.countValue(result, family);\n }\n\n const res = result as ToolResultLike;\n const sources: ConfidenceSource[] = [];\n let tokens = 0;\n\n if (Array.isArray(res.content)) {\n for (const raw of res.content) {\n if (!isObject(raw)) continue;\n const block = raw as ContentBlock;\n if (isTextBlock(block)) {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n const c = tok.count(text, family);\n tokens += c.tokens;\n sources.push(c.source);\n } else {\n // image / audio / resource / unknown → flat estimate, no base64 BPE.\n const key = typeof block.type === \"string\" ? block.type : \"\";\n tokens += MODALITY_ESTIMATE[key] ?? UNKNOWN_BLOCK_ESTIMATE;\n // A flat estimate is an approximation, never \"exact\".\n sources.push(\"tokenizer-approx\");\n }\n }\n } else if (res.content !== undefined) {\n // content present but not an array (e.g. a bare string) → count it whole.\n const c = tok.countValue(res.content, family);\n tokens += c.tokens;\n sources.push(c.source);\n }\n\n if (res.structuredContent !== undefined) {\n const c = tok.countValue(res.structuredContent, family);\n tokens += c.tokens;\n sources.push(c.source);\n }\n\n // Nothing measurable found → count the whole object as a fallback so we never\n // silently report zero for a non-empty result.\n if (sources.length === 0) {\n return tok.countValue(result, family);\n }\n\n return { tokens, source: combineSources(sources) };\n}\n\n/**\n * Measure the fixed tool-definition overhead: tokenize the JSON of the entire\n * `tools/list` array once. `tools` is the raw array of tool descriptors as the\n * server advertises them (shape is host/SDK-specific, so it is treated as\n * opaque JSON here).\n */\nexport function measureToolDefs(\n tools: readonly unknown[],\n family: ModelFamily,\n tok: Tokenizer = getTokenizer(),\n): TokenCount {\n return tok.countValue(tools, family);\n}\n\n/**\n * Measure one RUNTIME hook dispatch (the new `hook` developer-axis surface).\n *\n * Input = canonical JSON of the inbound normalized event payload the handler\n * reads (the host-provided fields: toolInput / prompt / raw / etc.).\n * Output = canonical JSON of what the handler RETURNS that becomes context or a\n * decision the host consumes (additionalContext / updatedInput / reason\n * and the rest of the normalized {@link HookResponse}).\n *\n * Uses the SAME tokenizer + worst-of confidence combination as the proxy. Pure:\n * no IO, no mutation. The two values are tokenized whole (a hook payload has no\n * binary content blocks to special-case, unlike a tool result).\n */\nexport function measureHook(\n eventPayload: unknown,\n handlerReturn: unknown,\n family: ModelFamily,\n tok: Tokenizer = getTokenizer(),\n): ToolCallMeasurement {\n const input = tok.countValue(eventPayload, family);\n const output = tok.countValue(handlerReturn, family);\n return {\n inputTokens: input.tokens,\n outputTokens: output.tokens,\n source: worstConfidence(input.source, output.source),\n };\n}\n","/**\n * runtime/hook-entrypoint — the universal json-stdio hook dispatcher.\n *\n * Every json-stdio host points its hook config at the single stable home binary\n * (`<homeBin> hook <platformId> <event> --connector <id>`, built by\n * core/spawn.buildHomeBinHookCommand). The CLI reads stdin and calls\n * {@link runHook} with the parsed flags + the raw stdin string. This module:\n *\n * 1. Loads the registered connector (live handlers) and the host adapter.\n * 2. Parses the host's stdin payload into a normalized event via the adapter.\n * 3. Finds the connector's handler for the event, honoring the tool matcher.\n * 4. Runs the handler, normalizes its return, and formats the adapter's native\n * reply.\n *\n * Fail-open is the safety contract: ANY error degrades to exit 0 (\"allow\") so a\n * framework or handler bug can never wedge a host's tool call — EXCEPT when the\n * event is PreToolUse or PermissionRequest and the handler explicitly denied,\n * in which case the deny (a deliberate security decision) is preserved rather\n * than swallowed.\n */\n\nimport type {\n HookEventName,\n HookResponse,\n NativeHookDef,\n NativeHookEvent,\n PlatformId,\n ResolvedConnector,\n} from \"../core/types.js\";\nimport { log } from \"../core/logger.js\";\nimport {\n loadRegisteredConnector,\n readRegisteredMeta,\n} from \"../core/load-connector.js\";\nimport { loadAdapter, REGISTERED_PLATFORM_IDS } from \"../adapters/registry.js\";\nimport { buildTelemetryAccessor } from \"./telemetry-accessor.js\";\nimport type { NormalizedEvent } from \"../adapters/spi.js\";\nimport { projectIdentity } from \"../core/paths.js\";\nimport { measureHook } from \"../telemetry/measure.js\";\nimport { openStore, newRecordId } from \"../telemetry/store.js\";\nimport { getTokenizer, inferModelFamily } from \"../telemetry/tokenizer.js\";\n\n/** Flags + stdin the CLI hands to {@link runHook}. */\nexport interface RunHookOptions {\n /** Host platform id from the hook command (`hook <platformId> ...`). */\n platformId: string;\n /** Canonical lifecycle event name from the hook command. */\n event: HookEventName;\n /** Connector id from `--connector <id>`. */\n connectorId: string;\n /** Raw stdin payload (host-native JSON). Empty string is tolerated → `{}`. */\n stdin: string;\n}\n\n/** Process-level result the CLI translates into exit code + stdout/stderr. */\nexport interface RunHookResult {\n exitCode: number;\n stdout?: string;\n stderr?: string;\n}\n\n/** A pass-through \"allow\" reply with exit 0 and no payload. */\nconst ALLOW: RunHookResult = { exitCode: 0 };\n\n/**\n * The string a connector matcher filters on, when the event carries one:\n * tool events (PreToolUse / PostToolUse / PermissionRequest /\n * PostToolUseFailure) expose `toolName`; subagent events expose `agentType`.\n * Returns undefined when the event has neither (no filtering) — including a\n * SubagentStop arriving WITHOUT agent_type, which some hosts fail to populate;\n * filtering out such an event would silently drop a real stop, so we run the\n * handler instead (fail-open).\n */\nexport function eventMatcherSubject(evt: NormalizedEvent): string | undefined {\n const name = (evt as { toolName?: unknown }).toolName;\n if (typeof name === \"string\") return name;\n const agentType = (evt as { agentType?: unknown }).agentType;\n if (typeof agentType === \"string\") return agentType;\n return undefined;\n}\n\n/**\n * Tolerantly parse the host's stdin payload. Empty / whitespace-only input is a\n * legitimate \"no payload\" signal from some hosts and resolves to `{}`. Malformed\n * JSON also degrades to `{}` rather than throwing — fail-open is the contract.\n */\nfunction parseStdin(stdin: string): unknown {\n const trimmed = stdin.trim();\n if (trimmed === \"\") return {};\n try {\n return JSON.parse(trimmed);\n } catch {\n return {};\n }\n}\n\n/**\n * Compile the connector's matcher (a regex string) for a tool event. A missing\n * or empty matcher matches everything (returns null → no filtering). An invalid\n * regex degrades to \"match everything\" so a typo never blocks tool calls.\n */\nexport function compileMatcher(matcher: string | undefined): RegExp | null {\n if (!matcher || matcher === \"\") return null;\n try {\n return new RegExp(matcher);\n } catch {\n return null;\n }\n}\n\n/**\n * Normalize a handler return into a concrete HookResponse. A void/non-object\n * return becomes `{}` — NO decision — which every adapter formats as\n * pass-through allow (`response.decision ?? \"allow\"`). Deliberately NOT\n * `{decision:\"allow\"}`: on PermissionRequest an explicit \"allow\" is an ACTIVE\n * grant that suppresses the host's permission dialog, and a handler that\n * returns nothing must fall through to the dialog, never silently grant.\n */\nfunction normalizeResponse(value: HookResponse | void): HookResponse {\n if (value == null || typeof value !== \"object\") return {};\n return value;\n}\n\n/**\n * Resolve the host platform to stamp on a hook telemetry row. Mirrors the serve\n * `--host` plumbing: the install-target platform id is baked into the hook\n * command (`hook <platformId> <event> …`) so `opts.platformId` is authoritative,\n * but an explicit env override (AGENT_CONNECTOR_HOST) wins when it names a known\n * platform. Falls back to the event's adapter-stamped hostPlatform, then\n * \"unknown\" — never throws.\n */\nfunction resolveHookHostPlatform(\n platformId: string,\n evt: NormalizedEvent | NativeHookEvent,\n): PlatformId {\n const override = process.env.AGENT_CONNECTOR_HOST;\n if (\n override !== undefined &&\n REGISTERED_PLATFORM_IDS.has(override as PlatformId)\n ) {\n return override as PlatformId;\n }\n if (REGISTERED_PLATFORM_IDS.has(platformId as PlatformId)) {\n return platformId as PlatformId;\n }\n const fromEvent = (evt as { hostPlatform?: unknown }).hostPlatform;\n if (\n typeof fromEvent === \"string\" &&\n REGISTERED_PLATFORM_IDS.has(fromEvent as PlatformId)\n ) {\n return fromEvent as PlatformId;\n }\n return \"unknown\";\n}\n\n/**\n * Record one RUNTIME hook dispatch as a `hook` developer-axis telemetry row.\n *\n * input = the inbound event payload the handler reads (normalized event, or\n * the {@link NativeHookEvent} envelope for native passthrough hooks);\n * output = what the handler returned (a normalized {@link HookResponse}, or the\n * verbatim native reply object). Tokenized with the SAME tokenizer the\n * proxy uses. For a native hook `opts.event` is the host-native name.\n *\n * MUST be fail-open (the hook runtime is fail-open by contract): any error here\n * is swallowed so a measurement bug can NEVER break a host's hook. Honors the\n * AGENT_CONNECTOR_TELEMETRY=0 kill switch (skips entirely; the store's append is\n * already a no-op under it, but we also skip the tokenize work).\n */\nfunction recordHookTelemetry(\n opts: { platformId: string; event: string; connectorId: string },\n connector: ResolvedConnector,\n evt: NormalizedEvent | NativeHookEvent,\n response: unknown,\n): void {\n if (process.env.AGENT_CONNECTOR_TELEMETRY === \"0\") return;\n try {\n const family = inferModelFamily(\"\", connector.telemetry.modelFamilyHint);\n const measurement = measureHook(evt, response, family, getTokenizer());\n\n const sessionId =\n typeof (evt as { sessionId?: unknown }).sessionId === \"string\"\n ? ((evt as { sessionId: string }).sessionId)\n : \"\";\n const evtProjectDir = (evt as { projectDir?: unknown }).projectDir;\n const projectDir =\n typeof evtProjectDir === \"string\" && evtProjectDir !== \"\"\n ? evtProjectDir\n : process.cwd();\n const id = projectIdentity(projectDir);\n\n const store = openStore({});\n try {\n store.append({\n id: newRecordId(0),\n ts: Date.now(),\n connectorId: opts.connectorId,\n toolName: opts.event, // for a hook row the per-item name IS the event\n scope: \"hook\",\n surfaceKind: \"hook\",\n hostPlatform: resolveHookHostPlatform(opts.platformId, evt),\n sessionId,\n projectKey: id.key,\n projectDir: id.dir,\n inputTokens: measurement.inputTokens,\n outputTokens: measurement.outputTokens,\n confidenceSource: measurement.source,\n isError: false,\n });\n } finally {\n store.close();\n }\n } catch {\n // Fail-open: a telemetry error must NEVER break the hook runtime.\n }\n}\n\n/**\n * Dispatch one host hook invocation. Always resolves (never rejects): every\n * failure path returns a concrete {@link RunHookResult} so the CLI can exit\n * cleanly. See the module header for the fail-open contract.\n */\nexport async function runHook(opts: RunHookOptions): Promise<RunHookResult> {\n const { platformId, event, connectorId, stdin } = opts;\n\n try {\n const connector = await loadRegisteredConnector(connectorId);\n const adapter = await loadAdapter(platformId);\n\n // mcp-only hosts (and any adapter without runtime dispatch) cannot parse a\n // hook payload — nothing to do, allow.\n if (!adapter || !adapter.parseEvent || !adapter.formatReply) {\n return ALLOW;\n }\n\n const raw = parseStdin(stdin);\n const evt = adapter.parseEvent(event, raw);\n // The hook command carries the authoritative connector id; stamp it on the\n // event so handlers see the connector they were dispatched for.\n evt.connectorId = connectorId;\n // Unify the hook event with HostCtx: the adapter's parseEvent has no\n // capabilities/scope/telemetry at parse time (they are runtime-only), so the\n // runtime ALWAYS backfills them before the handler runs. capabilities comes\n // from the adapter; scope is recovered from the registered metadata (sync);\n // telemetry is the lazy per-connector usage accessor. The SAME three\n // assignments run on the error path (failOpenOrPreserveDeny) for symmetry.\n evt.capabilities = adapter.capabilities;\n evt.scope = readRegisteredMeta(connectorId)?.scope;\n evt.telemetry = buildTelemetryAccessor(connectorId);\n\n const definition = connector.hooks[event];\n if (!definition || typeof definition.handler !== \"function\") {\n // The connector declares no handler for this event — allow.\n return ALLOW;\n }\n\n // Per-host handler override: when dispatching for host X, `hosts[X].handler`\n // wins over the top-level handler; a host not listed (or a per-host entry\n // that is somehow not a function) falls back to the top-level handler.\n // Selection NEVER throws — fail-open is preserved.\n // NOTE: keyed on the RAW install-baked platformId (the host this entrypoint\n // was registered for), NOT resolveHookHostPlatform's AGENT_CONNECTOR_HOST\n // override — that override only re-labels the telemetry row. The error path\n // (failOpenOrPreserveDeny) resolves the IDENTICAL handler the same way, so a\n // per-host deny is preserved consistently.\n const perHost = definition.hosts?.[platformId as PlatformId]?.handler;\n const handler = typeof perHost === \"function\" ? perHost : definition.handler;\n\n // Matcher: if set and the event's subject (tool name, or agent type for\n // Subagent* events) does not match, allow (the hook is simply not\n // interested in this tool/agent). The matcher is the definition's — a\n // per-host handler shares the top-level matcher.\n const subject = eventMatcherSubject(evt);\n if (subject !== undefined) {\n const re = compileMatcher(definition.matcher);\n if (re && !re.test(subject)) return ALLOW;\n }\n\n // Run the resolved handler. Its return is normalized (void → allow) and\n // handed to the adapter to render the host-native reply.\n const handlerResult = await handler(\n // The adapter parsed `evt` as exactly this event's payload type; the\n // HooksConfig handler for the same event expects that payload.\n evt as never,\n );\n const response = normalizeResponse(handlerResult);\n\n // Developer-axis telemetry for the RUNTIME `hook` surface. Fail-open: never\n // lets a measurement error break the hook (handled inside the helper).\n recordHookTelemetry(opts, connector, evt, response);\n\n const reply = adapter.formatReply(event, response);\n return {\n exitCode: reply.exitCode,\n ...(reply.stdout !== undefined ? { stdout: reply.stdout } : {}),\n ...(reply.stderr !== undefined ? { stderr: reply.stderr } : {}),\n };\n } catch (err) {\n // Fail-open: a framework/handler error must not wedge the host's tool call.\n // The ONE exception is a PreToolUse / PermissionRequest deny — a deliberate\n // block we honor even if a later step threw. We re-derive that decision\n // defensively from the adapter so a throw AFTER the deny still surfaces it.\n const message = err instanceof Error ? err.message : String(err);\n log.error(`hook ${platformId}/${event} (${connectorId}) failed:`, message);\n return failOpenOrPreserveDeny(opts, message);\n }\n}\n\n/**\n * Events whose explicit deny survives the fail-open error path. Both are\n * permission gates — a deny there is a deliberate security decision that must\n * never be silently downgraded to allow. (Stop-class denies are persistence\n * conveniences, not security boundaries, so they stay fail-open.)\n */\nconst DENY_PRESERVE_EVENTS: ReadonlySet<HookEventName> = new Set([\n \"PreToolUse\",\n \"PermissionRequest\",\n]);\n\n/**\n * Error path. Returns fail-open allow, UNLESS this is a deny-preserving event\n * (PreToolUse / PermissionRequest) whose handler explicitly denied — in which\n * case the deny is reconstructed and preserved (a security decision is never\n * silently downgraded to allow).\n *\n * Best-effort: if anything in the deny reconstruction itself throws, we fall\n * back to allow (we never escalate an error into a spurious block).\n */\nasync function failOpenOrPreserveDeny(\n opts: RunHookOptions,\n errorMessage: string,\n): Promise<RunHookResult> {\n if (!DENY_PRESERVE_EVENTS.has(opts.event)) return ALLOW;\n try {\n const connector = await loadRegisteredConnector(opts.connectorId);\n const adapter = await loadAdapter(opts.platformId);\n if (!adapter?.parseEvent || !adapter.formatReply) return ALLOW;\n\n const definition = connector.hooks[opts.event];\n if (!definition || typeof definition.handler !== \"function\") return ALLOW;\n\n // Reconstruct the deny from the SAME handler the main path would have run —\n // the per-host override if one is declared for this host, else the top-level\n // handler. Otherwise a per-host deny could be silently downgraded on the\n // error path.\n const perHost = definition.hosts?.[opts.platformId as PlatformId]?.handler;\n const handler = typeof perHost === \"function\" ? perHost : definition.handler;\n\n const raw = parseStdin(opts.stdin);\n const evt = adapter.parseEvent(opts.event, raw);\n evt.connectorId = opts.connectorId;\n // Backfill the HostCtx fields here too (symmetry with the main path), so a\n // per-host deny reconstructed on the error path still carries capabilities/\n // scope/telemetry — a handler that branches on them denies identically.\n evt.capabilities = adapter.capabilities;\n evt.scope = readRegisteredMeta(opts.connectorId)?.scope;\n evt.telemetry = buildTelemetryAccessor(opts.connectorId);\n\n const subject = eventMatcherSubject(evt);\n if (subject !== undefined) {\n const re = compileMatcher(definition.matcher);\n if (re && !re.test(subject)) return ALLOW;\n }\n\n const response = normalizeResponse(await handler(evt as never));\n if (response.decision !== \"deny\") return ALLOW;\n\n const reply = adapter.formatReply(opts.event, response);\n return {\n exitCode: reply.exitCode,\n ...(reply.stdout !== undefined ? { stdout: reply.stdout } : {}),\n ...(reply.stderr !== undefined\n ? { stderr: reply.stderr }\n : { stderr: errorMessage }),\n };\n } catch {\n // Reconstruction failed — never escalate an internal error into a block.\n return ALLOW;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Native (passthrough) hooks — host events OUTSIDE the normalized union\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Flags + stdin for {@link runNativeHook}. `event` is HOST-NATIVE (non-union). */\nexport interface RunNativeHookOptions {\n /** Host platform id from the hook command (`hook <platformId> ...`). */\n platformId: string;\n /** Host-native event name, verbatim (e.g. \"TaskCreated\"). */\n event: string;\n /** Connector id from `--connector <id>`. */\n connectorId: string;\n /** Raw stdin payload (host-native JSON). Empty string is tolerated → `{}`. */\n stdin: string;\n}\n\n/** The connector's native hook definition for `platformId`/`event`, if any. */\nfunction nativeHookDef(\n connector: ResolvedConnector,\n platformId: string,\n event: string,\n): NativeHookDef | undefined {\n return connector.platforms[platformId as PlatformId]?.nativeHooks?.[event];\n}\n\n/**\n * True when the registered connector declares `event` under\n * `platforms[platformId].nativeHooks` with a live handler. Used by the hook CLI\n * to decide whether a non-union event name is accepted (declared → dispatch via\n * {@link runNativeHook}) or rejected with the strict unknown-event error.\n * Fail-safe: any load error reads as \"not declared\".\n */\nexport async function isNativeHookDeclared(\n platformId: string,\n event: string,\n connectorId: string,\n): Promise<boolean> {\n try {\n const connector = await loadRegisteredConnector(connectorId);\n return typeof nativeHookDef(connector, platformId, event)?.handler === \"function\";\n } catch {\n return false;\n }\n}\n\n/**\n * Dispatch one NATIVE (passthrough) hook invocation. No normalized parse, no\n * HookResponse mapping, no runtime matcher evaluation (the host's own matcher\n * already filtered — the def's matcher string was written verbatim into the\n * host config at install):\n *\n * stdin JSON → NativeHookEvent{raw} → handler → VERBATIM JSON stdout (exit 0).\n *\n * void/undefined return → exit 0 with no output. Fail-open: ANY throw degrades\n * to exit 0 with no output — exit-2 blocking semantics are not modeled in v1.\n * Telemetry: records the same scope:\"hook\" developer-axis row as normalized\n * hooks, with the NATIVE event name as the per-item name.\n */\nexport async function runNativeHook(\n opts: RunNativeHookOptions,\n): Promise<RunHookResult> {\n const { platformId, event, connectorId, stdin } = opts;\n try {\n const connector = await loadRegisteredConnector(connectorId);\n const def = nativeHookDef(connector, platformId, event);\n if (!def || typeof def.handler !== \"function\") {\n // Not declared for this platform — nothing to do, allow.\n return ALLOW;\n }\n\n const raw = parseStdin(stdin);\n // Best-effort session/project extraction from the json-stdio common shape\n // (Claude Code: session_id / cwd). Everything else stays in `raw` untouched.\n const sessionId =\n typeof (raw as { session_id?: unknown })?.session_id === \"string\"\n ? (raw as { session_id: string }).session_id\n : \"\";\n const cwd = (raw as { cwd?: unknown })?.cwd;\n const evt: NativeHookEvent = {\n event,\n hostPlatform: REGISTERED_PLATFORM_IDS.has(platformId as PlatformId)\n ? (platformId as PlatformId)\n : \"unknown\",\n sessionId,\n ...(typeof cwd === \"string\" && cwd !== \"\" ? { projectDir: cwd } : {}),\n raw,\n };\n\n const result = await def.handler(evt);\n\n // Same scope:\"hook\" telemetry row as normalized hooks (fail-open inside).\n recordHookTelemetry(opts, connector, evt, result === undefined ? {} : result);\n\n if (result === undefined) return ALLOW; // void → exit 0, no output\n const json = JSON.stringify(result);\n // Non-JSON-serializable returns (functions/symbols) degrade to silence.\n if (json === undefined) return ALLOW;\n return { exitCode: 0, stdout: json };\n } catch (err) {\n // Fail-open, unconditionally: native hooks have no deny-preserve carve-out\n // (there is no normalized decision to reconstruct).\n const message = err instanceof Error ? err.message : String(err);\n log.error(\n `native hook ${platformId}/${event} (${connectorId}) failed:`,\n message,\n );\n return ALLOW;\n }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/usage/readers/kimi.ts"],"sourcesContent":["/**\n * usage/readers/kimi — Kimi CLI (Moonshot) native session-log reader.\n *\n * Faithful port of tokscale sessions/kimi.rs. Reads the wire protocol log at\n * ~/.kimi/sessions/<GROUP_ID>/<SESSION_UUID>/wire.jsonl\n * (the model name is read from the sibling ~/.kimi/config.json). Each line is a\n * timestamped wire frame; only frames whose `message.type === \"StatusUpdate\"`\n * carry a `payload.token_usage` block:\n * input_other → input\n * output → output\n * input_cache_read → cacheRead\n * input_cache_creation → cacheWrite (cache CREATION cost, not a read)\n * reasoning is always 0 (the wire protocol folds reasoning into output).\n *\n * The first line (`{\"type\":\"metadata\", …}`) and every non-StatusUpdate frame\n * (TurnBegin / ContentPart / ToolCall / StepBegin …) are skipped. Zero-token\n * StatusUpdates are dropped.\n *\n * DEDUP (the double-counting hazard): Kimi emits PROGRESSIVE StatusUpdates for a\n * single assistant message as generation streams (e.g. message_id \"msg-x\" at\n * 100→10 tokens, then 120→30). We dedup by `payload.message_id`, keeping the row\n * with the MAX total tokens (tie-break: the later timestamp). Records WITHOUT a\n * (non-empty) message_id are never merged — each passes through as its own row,\n * exactly as the Rust push_or_replace_status_update does. The kept row's\n * `dedupKey` is its message_id (absent for un-keyed rows).\n *\n * Storage root: ~/.kimi/sessions, with two overrides honored on top of the fixed\n * paths.ts resolution — the AGENT_CONNECTOR_KIMI_DIR override (via\n * firstExistingRoot) and $KIMI_CODE_HOME, which relocates the Kimi home (the\n * config.json lookup is path-relative, so it transparently handles a `.kimi-code`\n * home as well as `.kimi`).\n *\n * Model: `.model` from <home>/config.json (fallback \"kimi-for-coding\"); provider\n * is hard-coded \"moonshot\". Session id is the SESSION_UUID directory name. Kimi's\n * wire log carries no cwd, so there is no project attribution. Confidence is\n * \"host-reported\" (real host token counts).\n *\n * Fail-open: no root → []; an unreadable/malformed file or line → skipped.\n */\n\nimport { basename, dirname, join } from \"node:path\";\n\nimport type { TokenBreakdown, UsageReader, UsageRecord } from \"../types.js\";\nimport { emptyTokens } from \"../aggregate.js\";\nimport { fileMtimeMs, readJsonFile, readJsonlLines } from \"../jsonl.js\";\nimport { expandHome, firstExistingRoot, isDir, walkFiles } from \"../paths.js\";\n\nconst PLATFORM_ID = \"kimi\" as const;\nconst DEFAULT_MODEL = \"kimi-for-coding\";\nconst DEFAULT_PROVIDER = \"moonshot\";\n\n/** A wire.jsonl line: metadata header OR a timestamped message frame. */\ninterface WireLine {\n type?: unknown;\n timestamp?: unknown;\n message?: {\n type?: unknown;\n payload?: {\n token_usage?: {\n input_other?: unknown;\n output?: unknown;\n input_cache_read?: unknown;\n input_cache_creation?: unknown;\n };\n message_id?: unknown;\n };\n };\n}\n\n/** Coerce an unknown to a non-negative integer (0 on absence/garbage). */\nfunction toNonNegInt(v: unknown): number {\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\n if (!Number.isFinite(n)) return 0;\n return Math.max(0, Math.trunc(n));\n}\n\n/**\n * Convert the wire `timestamp` (Unix seconds, often fractional like\n * 1770983426.420942) to epoch ms. Returns null when unusable so the caller can\n * fall back to the file mtime (port of `timestamp * 1000.0 as i64`).\n */\nfunction parseWireTs(v: unknown): number | null {\n if (typeof v === \"number\" && Number.isFinite(v) && v > 0) {\n return Math.trunc(v * 1000);\n }\n return null;\n}\n\n/**\n * Read the model name from the Kimi home's config.json (port of\n * read_model_from_config). The wire path is\n * <home>/sessions/<GROUP_ID>/<SESSION_UUID>/wire.jsonl\n * so the home dir is four `dirname` hops up, and config.json sits beside the\n * sessions dir. Fail-open to DEFAULT_MODEL on any missing/garbage value.\n */\nfunction readModelFromConfig(wirePath: string): string {\n // wire.jsonl → SESSION_UUID → GROUP_ID → sessions → <home>\n const sessionDir = dirname(wirePath);\n const groupDir = dirname(sessionDir);\n const sessionsDir = dirname(groupDir);\n const homeDir = dirname(sessionsDir);\n const configPath = join(homeDir, \"config.json\");\n\n const parsed = readJsonFile(configPath);\n if (typeof parsed === \"object\" && parsed !== null) {\n const model = (parsed as { model?: unknown }).model;\n if (typeof model === \"string\" && model !== \"\") return model;\n }\n return DEFAULT_MODEL;\n}\n\n/**\n * Session id from the wire path: the SESSION_UUID directory name (the immediate\n * parent of wire.jsonl). Port of extract_session_id.\n */\nfunction extractSessionId(wirePath: string): string {\n const dir = basename(dirname(wirePath));\n return dir === \"\" ? \"unknown\" : dir;\n}\n\n/** Sum of the five token dimensions (port of TokenBreakdown::total). */\nfunction tokenTotal(t: TokenBreakdown): number {\n return t.input + t.output + t.cacheRead + t.cacheWrite + t.reasoning;\n}\n\n/**\n * Whether `candidate` should replace `existing` for the same message_id. Port of\n * should_replace_status_update: a strictly larger total wins; on an equal total\n * the later-or-equal timestamp wins (so the freshest progressive update is kept).\n */\nfunction shouldReplace(existing: UsageRecord, candidate: UsageRecord): boolean {\n const existingTotal = tokenTotal(existing.tokens);\n const candidateTotal = tokenTotal(candidate.tokens);\n return (\n candidateTotal > existingTotal ||\n (candidateTotal === existingTotal && candidate.ts >= existing.ts)\n );\n}\n\n/** Parse one Kimi wire.jsonl file into usage records (port of parse_kimi_file). */\nfunction parseKimiFile(path: string): UsageRecord[] {\n const lines = readJsonlLines(path);\n if (lines.length === 0) return [];\n\n const model = readModelFromConfig(path);\n const sessionId = extractSessionId(path);\n const mtime = fileMtimeMs(path);\n\n const out: UsageRecord[] = [];\n // message_id → index into `out`, for progressive-StatusUpdate dedup.\n const keyedIndices = new Map<string, number>();\n\n for (const raw of lines) {\n if (typeof raw !== \"object\" || raw === null) continue;\n const wire = raw as WireLine;\n\n // Skip the metadata header line.\n if (wire.type === \"metadata\") continue;\n\n const message = wire.message;\n if (typeof message !== \"object\" || message === null) continue;\n\n // Only StatusUpdate frames carry token usage.\n if (message.type !== \"StatusUpdate\") continue;\n\n const payload = message.payload;\n if (typeof payload !== \"object\" || payload === null) continue;\n\n const usage = payload.token_usage;\n if (typeof usage !== \"object\" || usage === null) continue;\n\n const input = toNonNegInt(usage.input_other);\n const output = toNonNegInt(usage.output);\n const cacheRead = toNonNegInt(usage.input_cache_read);\n const cacheWrite = toNonNegInt(usage.input_cache_creation);\n\n // Skip zero-token entries.\n if (input + output + cacheRead + cacheWrite === 0) continue;\n\n const ts = parseWireTs(wire.timestamp) ?? mtime;\n\n const tokens = emptyTokens();\n tokens.input = input;\n tokens.output = output;\n tokens.cacheRead = cacheRead;\n tokens.cacheWrite = cacheWrite;\n // reasoning stays 0 — the Kimi wire protocol folds reasoning into output.\n\n const messageId = payload.message_id;\n const dedupKey =\n typeof messageId === \"string\" && messageId !== \"\" ? messageId : undefined;\n\n const record: UsageRecord = {\n platformId: PLATFORM_ID,\n modelId: model,\n providerId: DEFAULT_PROVIDER,\n sessionId,\n tokens,\n ts,\n messageCount: 1,\n confidence: \"host-reported\",\n };\n if (dedupKey !== undefined) record.dedupKey = dedupKey;\n\n if (dedupKey === undefined) {\n // Un-keyed StatusUpdates are never merged — each is its own row.\n out.push(record);\n continue;\n }\n\n const existingIndex = keyedIndices.get(dedupKey);\n if (existingIndex !== undefined) {\n const existing = out[existingIndex];\n if (existing !== undefined && shouldReplace(existing, record)) {\n out[existingIndex] = record;\n }\n continue;\n }\n\n keyedIndices.set(dedupKey, out.length);\n out.push(record);\n }\n\n return out;\n}\n\n/**\n * Candidate Kimi session roots, most-preferred first. Honors the fixed paths.ts\n * resolution (AGENT_CONNECTOR_KIMI_DIR override → ~/.kimi/sessions) plus\n * $KIMI_CODE_HOME, which relocates the Kimi home directory.\n */\nfunction kimiSessionRoots(): string[] {\n const roots: string[] = [];\n\n const codeHome = process.env.KIMI_CODE_HOME;\n if (codeHome != null && codeHome.trim() !== \"\") {\n roots.push(join(expandHome(codeHome.trim()), \"sessions\"));\n }\n\n const standard = firstExistingRoot(PLATFORM_ID);\n if (standard !== undefined) roots.push(standard);\n\n return roots;\n}\n\n/** The Kimi CLI usage reader singleton. */\nconst kimiReader: UsageReader = {\n platformId: PLATFORM_ID,\n kind: \"local\",\n async read({ sinceMs }: { sinceMs?: number }): Promise<UsageRecord[]> {\n const roots = kimiSessionRoots().filter((r) => isDir(r));\n if (roots.length === 0) return []; // no ~/.kimi/sessions → fail-open\n\n // <root>/<GROUP_ID>/<SESSION_UUID>/wire.jsonl\n const seen = new Set<string>();\n const records: UsageRecord[] = [];\n for (const root of roots) {\n const files = walkFiles(root, (name) => name === \"wire.jsonl\");\n for (const file of files) {\n if (seen.has(file)) continue; // de-overlap if KIMI_CODE_HOME == ~/.kimi\n seen.add(file);\n const rows = parseKimiFile(file);\n for (const row of rows) {\n if (sinceMs !== undefined && row.ts < sinceMs) continue;\n records.push(row);\n }\n }\n }\n return records;\n },\n};\n\nexport default kimiReader;\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/kimi/index.ts"],"sourcesContent":["/**\n * adapters/kimi — Kimi CLI (Moonshot) platform adapter for agent-connector.\n *\n * Kimi CLI is a json-stdio host: the runner pipes a JSON payload to a command on\n * stdin and reads an exit code (and optional reason) back. Two native config\n * files live under the Kimi base dir (`$KIMI_HOME` || `$KIMI_CODE_HOME` || `~/.kimi`):\n * - mcp.json → `mcpServers.<id>` MCP registration (JSON, stdio shape:\n * {command,args,env}). Handled via BaseAdapter's JSON helpers.\n * - config.toml → `[[hooks]]` array-of-tables (TOML), each table\n * { event, matcher, command }. Parsed/serialized with @iarna/toml: every\n * config VALUE (unrelated sections, sibling hooks, scalars) is preserved,\n * but a parse→stringify round-trip does NOT preserve user COMMENTS or the\n * original key ordering/formatting in config.toml (values survive; comments\n * and layout do not).\n *\n * Hook surface is intentionally narrow: Kimi CLI only honors a PreToolUse DENY.\n * It cannot rewrite tool args, rewrite tool output, or inject session context —\n * so every other decision degrades to a silent allow (exit 0). Kimi Code uses\n * the Claude/Codex reply shape: a PreToolUse deny is signalled with EXIT 0 plus\n * a `hookSpecificOutput` JSON object on stdout carrying\n * permissionDecision:\"deny\" + permissionDecisionReason — that is how Kimi's\n * runner blocks the pending tool call. An allow is exit 0 with empty stdout.\n *\n * E1 extension events (verified against moonshotai.github.io/kimi-cli hooks):\n * - PostToolUseFailure — native (tool_name, tool_input, error; tool-name\n * matcher). Feedback-only: Kimi's exit-0 protocol adds non-empty stdout to\n * context, so \"context\" (and a degraded \"deny\") emit plain-text stdout.\n * - SubagentStart / SubagentStop — native, but with Kimi-specific wire\n * fields: agent_name (→ normalized agentType; there is no agent_id) plus\n * prompt (start) / response (stop → lastAssistantMessage). SubagentStop\n * deny uses Kimi's generic block protocol: EXIT 2 with the reason on\n * stderr (fed back to the model as correction).\n * - PermissionRequest — fired just before Kimi waits for user approval\n * (observation only). Wired; its return value does not affect the flow.\n * - The remaining canonical events (PostToolUse, UserPromptSubmit, Stop,\n * SessionStart, SessionEnd, PreCompact, PostCompact, Notification) are all\n * documented Kimi hooks and now wired 1:1 (PascalCase). Of these only\n * UserPromptSubmit + Stop are BLOCKABLE — they share SubagentStop's exit-2\n * block protocol (deny → EXIT 2 + stderr reason); the rest are observation\n * only. Verified against the kimi-code hooks docs (kimi.com/code/docs/en/\n * kimi-code-cli/customization/hooks.html): \"Only blockable events\n * (PreToolUse, Stop, UserPromptSubmit) have return values that affect the\n * main flow. All other events are observation-only.\"\n *\n * Path confidence: the `~/.kimi` base + mcp.json (`mcpServers`) layout is\n * LIVE-CONFIRMED against the real Moonshot Kimi CLI (v1.46.0, `pip install\n * kimi-cli`) via a `kimi mcp` probe. We still install + doctor-report presence\n * so a future path move surfaces as a FAIL rather than silently misbehaving.\n *\n * NOT YET COVERED: three observation-only Kimi-only events — StopFailure,\n * PermissionResult, Interrupt — are documented but NOT promoted to the core\n * normalized model (each is below the ≥3-host bar for a core HookEventName).\n * A connector that needs them on Kimi can declare them via the nativeHooks\n * passthrough. Kimi also has a PLUGIN system (`<base>/plugins/<name>/\n * kimi.plugin.json`), not yet surfaced.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, NormalizedEvent } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n NotificationEvent,\n PermissionRequestEvent,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PostToolUseFailureEvent,\n PostCompactEvent,\n PreCompactEvent,\n PreToolUseEvent,\n SessionEndEvent,\n SessionStartEvent,\n ServerDef,\n SkillDef,\n StopEvent,\n SubagentStartEvent,\n SubagentStopEvent,\n Transport,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\nimport { ensureDir } from \"../../core/paths.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildHomeBinHookCommand,\n buildWrappedStdio,\n isHomeBinHookCommand,\n} from \"../../core/spawn.js\";\nimport { normalizeSessionSource } from \"../claude-code/wire.js\";\n\nconst HOST: PlatformId = \"kimi\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Native shapes\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Raw Kimi CLI hook payload (Claude-style: PascalCase event, snake_case fields). */\ninterface KimiHookInput {\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_response?: unknown;\n session_id?: string;\n cwd?: string;\n hook_event_name?: string;\n source?: string;\n prompt?: string;\n is_error?: boolean;\n stop_hook_active?: boolean;\n trigger?: string;\n message?: string;\n reason?: string;\n // PostToolUseFailure — the failure message.\n error?: string;\n // SubagentStart / SubagentStop — Kimi sends agent_name (NOT agent_id /\n // agent_type) plus prompt (start) / response (stop).\n agent_name?: string;\n response?: string;\n connector?: string;\n}\n\n/** One `[[hooks]]` array-of-tables entry as Kimi stores it in config.toml. */\ninterface KimiTomlHook {\n event: string;\n matcher?: string;\n command: string;\n [key: string]: unknown;\n}\n\n/** Parsed config.toml shape we care about (rest preserved verbatim). */\ninterface KimiConfigToml {\n hooks?: KimiTomlHook[];\n [key: string]: unknown;\n}\n\n/** Native stdio MCP server entry under `mcpServers`. */\ninterface KimiStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n/** Native remote MCP server entry under `mcpServers`. */\ninterface KimiHttpServer {\n url: string;\n /**\n * Present only for a legacy SSE endpoint. Per the kimi mcp docs a bare `url`\n * (no transport) IS an HTTP server; `transport:\"sse\"` selects the older\n * HTTP+SSE transport.\n */\n transport?: \"sse\";\n headers?: Record<string, string>;\n}\n\n/**\n * Kimi CLI hook events agent-connector registers: every canonical event in the\n * core model — Kimi documents all of them as native hooks (PascalCase 1:1). The\n * PreToolUse matcher below is charset-clean (Rust-regex safe: no look-around) so\n * Kimi's matcher accepts it; copied in spirit from the Codex/context-mode\n * matchers. Order mirrors the core ALL_EVENTS sequence.\n */\nconst KIMI_HOOK_EVENTS = [\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] as const;\ntype KimiHookEventName = (typeof KIMI_HOOK_EVENTS)[number];\n\n/**\n * Canonical events with NO Kimi analog. Kimi documents a native hook for EVERY\n * current core event, so this is empty today. It stays as the seam: if a future\n * core HookEventName lands that Kimi cannot fire, add it here and declared hooks\n * for it warn-skip at install — the degradation is reported, never silent.\n */\nconst WARN_SKIP_EVENTS: ReadonlySet<HookEventName> = new Set<HookEventName>([]);\n\nconst PRE_TOOL_USE_MATCHER =\n \"Bash|Shell|shell|exec_command|Read|Edit|Write|WebFetch|Agent|mcp__\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Adapter\n// ─────────────────────────────────────────────────────────────────────────\n\nexport class KimiAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Kimi CLI\";\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 // Kimi documents a native hook for EVERY canonical event. BLOCKABLE decisions\n // (deny that affects the flow) are honored only for PreToolUse, Stop and\n // UserPromptSubmit per the docs; the rest fire observation-only, but we still\n // register them so a connector's handler runs (e.g. for telemetry/context).\n preToolUse: true,\n postToolUse: true,\n preCompact: true,\n sessionStart: true,\n sessionEnd: true,\n userPromptSubmit: true,\n stop: true,\n notification: true,\n permissionRequest: true,\n postToolUseFailure: true,\n subagentStart: true,\n subagentStop: true,\n postCompact: true,\n // Kimi cannot rewrite args/output nor inject session context — deny-only.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n // Kimi documents three MCP transports: stdio, HTTP and (legacy) SSE — a\n // url entry with transport:\"sse\" (kimi.com/code/docs/en/kimi-code-cli/\n // customization/mcp.html: \"supports three MCP server connection methods\").\n transports: [\"stdio\", \"http\", \"sse\"],\n // Skills surface: Kimi reads SKILL.md from ~/.kimi/skills/<name>/SKILL.md\n // (user scope) and .kimi/skills/<name>/SKILL.md (project scope).\n // Confirmed: kilo-pi-ground-truth.md § \"Already-known skills gaps\".\n supportsSkills: true,\n // Native passthrough hooks: Kimi's observation-only single-host events —\n // StopFailure, PermissionResult, Interrupt — have NO normalized HookEventName\n // (below the >=3-host core bar; see\n // docs/research/host-specific-hook-events-design.md). A connector reaches them\n // by declaring platforms[\"kimi\"].nativeHooks; installHooks writes those\n // event-name [[hooks]] entries verbatim, and the generic uninstall reverses them.\n supportsNativeHooks: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(_projectDir: string): DetectedPlatform {\n const baseDir = this.baseDir();\n const mcpPath = join(baseDir, \"mcp.json\");\n const configPath = join(baseDir, \"config.toml\");\n const installed = existsSync(baseDir) || existsSync(mcpPath) || existsSync(configPath);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath: mcpPath,\n scope: \"user\",\n reason: installed\n ? `found Kimi CLI config under ${baseDir}`\n : `no Kimi CLI config at ${baseDir}`,\n // Path confidence is medium even when present: the ~/.kimi-code layout is the\n // documented shape but less battle-tested than Claude/Codex.\n confidence: \"medium\",\n };\n }\n\n // ── Native paths ───────────────────────────────────────────────────────\n\n getConfigDir(_ctx: InstallContext): string {\n return this.baseDir();\n }\n\n /** MCP registration file (JSON). */\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp.json\");\n }\n\n /** Hook registration file (TOML) — distinct from the MCP file. */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"config.toml\");\n }\n\n /**\n * `$KIMI_HOME` || `$KIMI_CODE_HOME` (with `~` expansion) || `~/.kimi`.\n * The real Moonshot Kimi CLI (v1.46.0) keeps its config under `~/.kimi`\n * (mcp.json · mcpServers) — verified by a live `kimi mcp` probe; the legacy\n * `~/.kimi-code` guess was wrong. `$KIMI_CODE_HOME` is still honored as an\n * override for back-compat alongside the newer `$KIMI_HOME`.\n */\n private baseDir(): string {\n const env = process.env.KIMI_HOME ?? process.env.KIMI_CODE_HOME;\n if (env && env.trim() !== \"\") {\n if (env.startsWith(\"~\")) {\n return join(homedir(), env.replace(/^~[/\\\\]?/, \"\"));\n }\n return env;\n }\n return join(homedir(), \".kimi\");\n }\n\n // ── MCP server install / uninstall (mcp.json → mcpServers.<id>) ──────────\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 kimi\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const changes: ChangeRecord[] = [];\n // Honesty: Kimi documents only stdio/http/sse. A connector declaring another\n // transport (e.g. the non-spec \"ws\") is still rendered best-effort as a bare\n // URL entry, but the mismatch is REPORTED rather than silently misregistered\n // — same \"degradation is never silent\" posture as the hook warn-skips.\n if (!this.capabilities.transports.includes(server.transport)) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `transport \"${server.transport}\" is not a Kimi MCP transport (stdio/http/sse); registered best-effort as a URL entry`,\n });\n }\n\n const serverPath = this.getServerConfigPath(ctx);\n const entry = this.renderServerEntry(ctx, server);\n changes.push(\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n );\n return changes;\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /**\n * Render a normalized ServerDef into Kimi's native mcpServers entry. Kimi's\n * mcp.json has no documented native interpolation, so `${env:VAR}` refs are\n * resolved to literals at install time (same posture as the TOML hosts).\n */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): KimiStdioServer | KimiHttpServer {\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 through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n command = resolveEnvRefsDeep(command);\n args = resolveEnvRefsDeep(args);\n\n const entry: KimiStdioServer = { command };\n if (args.length > 0) entry.args = args;\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // Remote transports — Kimi registers a URL entry. A bare `url` is an HTTP\n // server; a legacy HTTP+SSE endpoint needs transport:\"sse\". (ws is not a\n // Kimi-documented transport — it falls through as a plain url, best-effort.)\n const entry: KimiHttpServer = { url: resolveEnvRefsDeep(server.url ?? \"\") };\n if (transport === \"sse\") entry.transport = \"sse\";\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /** Resolve env/header values to literals (no native interpolation on Kimi). */\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 const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(env))) {\n out[k] = String(v);\n }\n return out;\n }\n\n // ── Skills surface ────────────────────────────────────────────────────────\n // Kimi reads SKILL.md from <baseDir>/skills/<name>/SKILL.md.\n // user scope: ~/.kimi/skills/<name>/SKILL.md\n // project scope: <projectDir>/.kimi/skills/<name>/SKILL.md\n // Confirmed: kilo-pi-ground-truth.md § \"Already-known skills gaps\".\n\n private skillsDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kimi\", \"skills\")\n : join(this.baseDir(), \"skills\");\n }\n\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), 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 kimi\" }];\n }\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 changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), this.renderSkill(skill), ctx.dryRun),\n );\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 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;\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n private renderSkill(skill: SkillDef): string {\n return renderSkillMd(skill);\n }\n\n // ── Hook install / uninstall (config.toml → [[hooks]]) ───────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST];\n\n // `hooks: false` disables only the NORMALIZED events (effectiveHookEvents /\n // warnSkipHookEvents already return [] for it). nativeHooks is a sibling,\n // kimi-scoped declaration on the same override and installs regardless.\n const events = this.effectiveHookEvents(ctx);\n const dropped = this.warnSkipHookEvents(ctx);\n const nativeHooks = override?.nativeHooks ?? {};\n const nativeEvents = Object.keys(nativeHooks);\n const path = this.getHookConfigPath(ctx);\n\n if (events.length === 0 && dropped.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 kimi\" : \"no hooks declared\",\n },\n ];\n }\n\n const cfg = this.readToml(path);\n // Kimi's `hooks` is an ARRAY-of-tables ([[hooks]]); the BaseAdapter object-map\n // guard would mis-flag it. Inverse guard: a present-but-non-array `hooks`\n // (hand-edited to an object/primitive) cannot take `.push`/`.findIndex` — warn\n // and skip so the user's malformed value is preserved untouched.\n if (cfg.hooks !== undefined && !Array.isArray(cfg.hooks)) {\n return [\n {\n platform: this.id,\n action: \"warn\",\n path,\n detail: `existing \"hooks\" in ${path} is not an array; left untouched (fix it, then re-run)`,\n },\n ];\n }\n const hooks = (cfg.hooks ??= []);\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n // Declared events Kimi cannot fire are reported, never silently dropped.\n for (const event of dropped) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n path,\n detail: `${event} has no Kimi CLI hook equivalent — skipped`,\n });\n }\n\n for (const event of events) {\n const desired = this.renderHook(ctx, event);\n // Match our entry FOR THIS EVENT — isOurHook alone would find whichever\n // of our entries comes first and clobber a sibling event's registration.\n const idx = hooks.findIndex((h) => this.isOurHook(ctx, h) && h?.event === event);\n if (idx < 0) {\n hooks.push(desired);\n changes.push({ platform: this.id, action: \"create\", path, detail: `hooks.${event}` });\n mutated = true;\n } else if (JSON.stringify(hooks[idx]) !== JSON.stringify(desired)) {\n hooks[idx] = desired;\n changes.push({ platform: this.id, action: \"update\", path, detail: `hooks.${event}` });\n mutated = true;\n } else {\n changes.push({ platform: this.id, action: \"skip\", path, detail: `hooks.${event}` });\n }\n }\n\n // NATIVE passthrough events: Kimi-native event names (e.g. StopFailure,\n // PermissionResult, Interrupt) written VERBATIM as [[hooks]] entries — no\n // canonical mapping, same command shape + idempotency. Matched by EXACT\n // command so a native name that coincides with a canonical event never\n // clobbers it.\n for (const event of nativeEvents) {\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\n const desired = { event, matcher: nativeHooks[event]?.matcher ?? \"\", command };\n const idx = hooks.findIndex((h) => h?.event === event && h?.command === command);\n if (idx < 0) {\n hooks.push(desired);\n changes.push({ platform: this.id, action: \"create\", path, detail: `hooks.${event} (native)` });\n mutated = true;\n } else if (JSON.stringify(hooks[idx]) !== JSON.stringify(desired)) {\n hooks[idx] = desired;\n changes.push({ platform: this.id, action: \"update\", path, detail: `hooks.${event} (native)` });\n mutated = true;\n } else {\n changes.push({ platform: this.id, action: \"skip\", path, detail: `hooks.${event} (native)` });\n }\n }\n\n if (mutated) this.writeToml(path, cfg, ctx.dryRun);\n return changes;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n if (!existsSync(path)) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no config.toml\" }];\n }\n const cfg = this.readToml(path);\n const hooks = cfg.hooks;\n if (!Array.isArray(hooks) || hooks.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks present\" }];\n }\n\n const kept = hooks.filter((h) => !this.isOurHook(ctx, h));\n const removed = hooks.length - kept.length;\n if (removed === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no agent-connector hooks present\" }];\n }\n\n if (kept.length > 0) cfg.hooks = kept;\n else delete cfg.hooks;\n this.writeToml(path, cfg, ctx.dryRun);\n return [{ platform: this.id, action: \"remove\", path, detail: `hooks (${removed})` }];\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const serverPath = this.getServerConfigPath(ctx);\n const hookPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = this.effectiveHookEvents(ctx);\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: mcp.json present`,\n check: () =>\n existsSync(serverPath)\n ? { status: \"OK\", detail: serverPath }\n : { status: \"FAIL\", detail: `not found: ${serverPath}` },\n },\n {\n name: `${this.name}: mcpServers.${connectorId} registered`,\n check: () => {\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readJson<Record<string, Record<string, unknown>>>(serverPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n const present =\n typeof bucket === \"object\" && bucket !== null && connectorId in bucket;\n return present\n ? { status: \"OK\", detail: `mcpServers.${connectorId}` }\n : { status: \"FAIL\", detail: `mcpServers.${connectorId} not found in ${serverPath}` };\n },\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 (!existsSync(hookPath)) {\n return { status: \"FAIL\", detail: `not found: ${hookPath}` };\n }\n const cfg = this.readToml(hookPath);\n const registered = (cfg.hooks ?? []).some((h) =>\n isHomeBinHookCommand(h?.command, homeBin, connectorId),\n );\n return registered\n ? { status: \"OK\", detail: \"hook command present\" }\n : { status: \"FAIL\", detail: `no hook for ${connectorId} in ${hookPath}` };\n },\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 existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n return checks;\n }\n\n // ── Runtime: parse Kimi stdin JSON → normalized event ────────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as KimiHookInput;\n const connectorId = typeof input.connector === \"string\" ? input.connector : \"\";\n const sessionId = input.session_id ?? `pid-${process.ppid}`;\n const projectDir = input.cwd ?? process.env.KIMI_PROJECT_DIR ?? process.cwd();\n\n const base = {\n hostPlatform: HOST,\n connectorId,\n sessionId,\n projectDir,\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 const ev: PostToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n ...(toolResponseToString(input.tool_response) !== undefined\n ? { toolOutput: toolResponseToString(input.tool_response) }\n : {}),\n isError: input.is_error ?? false,\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = {\n ...base,\n source: normalizeSessionSource(input.source),\n };\n return ev;\n }\n case \"SessionEnd\": {\n const ev: SessionEndEvent = {\n ...base,\n ...(typeof input.message === \"string\" ? { reason: input.message } : {}),\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 \"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 // Kimi fires PostCompact after compaction completes (observation only),\n // payload `trigger`: manual|auto — mirrors PreCompact.\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 \"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 // Kimi fires PermissionRequest just before waiting for user approval\n // (observation only); payload subject is the tool name.\n const ev: PermissionRequestEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n return ev;\n }\n case \"PostToolUseFailure\": {\n // Kimi documents tool_name/tool_input/error only (no tool_use_id /\n // is_interrupt / duration_ms) — the optionals stay unset.\n const ev: PostToolUseFailureEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n error: typeof input.error === \"string\" ? input.error : \"\",\n };\n return ev;\n }\n case \"SubagentStart\": {\n // Kimi sends agent_name (the matcher subject) — normalize it as\n // agentType; there is no agent_id. The start prompt rides in `raw`.\n const ev: SubagentStartEvent = {\n ...base,\n ...(typeof input.agent_name === \"string\"\n ? { agentType: input.agent_name }\n : {}),\n };\n return ev;\n }\n case \"SubagentStop\": {\n const ev: SubagentStopEvent = {\n ...base,\n ...(typeof input.agent_name === \"string\"\n ? { agentType: input.agent_name }\n : {}),\n ...(typeof input.response === \"string\"\n ? { lastAssistantMessage: input.response }\n : {}),\n };\n return ev;\n }\n default: {\n const _never: never = event;\n throw new Error(`unsupported kimi hook event: ${String(_never)}`);\n }\n }\n }\n\n // ── Runtime: normalized response → Kimi native hook reply ────────────────\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n const decision = response.decision ?? \"allow\";\n\n // deny → block the pending tool call. Kimi Code uses the Claude/Codex reply\n // shape: EXIT 0 + a `hookSpecificOutput` JSON object on stdout carrying\n // permissionDecision:\"deny\". PreToolUse is the only event using this\n // structured reply; the other blockable events (Stop, UserPromptSubmit,\n // SubagentStop) use the generic exit-2 protocol below.\n if (decision === \"deny\" && event === \"PreToolUse\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\n },\n }),\n };\n }\n\n // PostToolUseFailure (feedback beside the error) and SubagentStart (context\n // for the subagent) are observe/context-only: Kimi's documented protocol\n // adds non-empty stdout on exit 0 to context, so \"context\" emits the text\n // PLAIN (no JSON envelope) and a \"deny\" DEGRADES to the same shape carrying\n // the reason (the tool already failed / the spawn is not blockable).\n if (event === \"PostToolUseFailure\" || event === \"SubagentStart\") {\n const context =\n decision === \"context\"\n ? response.additionalContext\n : decision === \"deny\"\n ? response.reason ?? response.additionalContext\n : undefined;\n if (context) return { exitCode: 0, stdout: context };\n return { exitCode: 0 };\n }\n\n // BLOCKABLE events via Kimi's generic block protocol: deny → EXIT 2 with the\n // reason on stderr (fed back to the model). Per the kimi-code docs the\n // blockable events are PreToolUse (handled above with its structured reply),\n // Stop and UserPromptSubmit; SubagentStop reuses the same Stop semantics. For\n // Stop the stderr reason lets the model continue; for UserPromptSubmit EXIT 2\n // blocks the turn (the model is not called). \"context\" rides the exit-0\n // stdout channel (Kimi appends non-empty stdout to context).\n if (event === \"SubagentStop\" || event === \"Stop\" || event === \"UserPromptSubmit\") {\n if (decision === \"deny\") {\n return { exitCode: 2, stderr: response.reason ?? \"Blocked by hook\" };\n }\n if (decision === \"context\" && response.additionalContext) {\n return { exitCode: 0, stdout: response.additionalContext };\n }\n return { exitCode: 0 };\n }\n\n // allow / modify / context / ask / unsupported-event → passthrough (exit 0,\n // empty stdout). Kimi cannot rewrite args/output or inject context, so those\n // are dropped.\n return { exitCode: 0 };\n }\n\n // ── Internal helpers ───────────────────────────────────────────────────\n\n /** Which canonical hook events to register for Kimi, honoring overrides. */\n private effectiveHookEvents(ctx: InstallContext): KimiHookEventName[] {\n if (ctx.connector.platforms[HOST]?.hooks === false) return [];\n return KIMI_HOOK_EVENTS.filter((e) => ctx.connector.hookEvents.includes(e));\n }\n\n /** Declared events Kimi has no analog for — install reports a warn-skip. */\n private warnSkipHookEvents(ctx: InstallContext): HookEventName[] {\n if (ctx.connector.platforms[HOST]?.hooks === false) return [];\n return ctx.connector.hookEvents.filter((e) => WARN_SKIP_EVENTS.has(e));\n }\n\n /**\n * Render one `[[hooks]]` entry pointing at the stable home binary. Only the\n * PreToolUse deny gate carries the native tool matcher; the E1 events register\n * \"\" (match every tool failure / agent name) and the universal entrypoint\n * applies the connector's own matcher at runtime.\n */\n private renderHook(ctx: InstallContext, event: KimiHookEventName): KimiTomlHook {\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, ctx.connector.id);\n return {\n event,\n matcher: event === \"PreToolUse\" ? PRE_TOOL_USE_MATCHER : \"\",\n command,\n };\n }\n\n /**\n * Does this `[[hooks]]` entry belong to this connector? Anchored on the\n * home-bin + connector-id token (isHomeBinHookCommand) so uninstalling a\n * shared-prefix connector id never strips a sibling's hook.\n */\n private isOurHook(ctx: InstallContext, hook: KimiTomlHook | undefined): boolean {\n if (!hook || typeof hook !== \"object\") return false;\n return isHomeBinHookCommand(hook.command, ctx.homeBinPath, ctx.connector.id);\n }\n\n // ── TOML config IO (config.toml is TOML; MCP stays JSON via BaseAdapter) ──\n\n private readToml(path: string): KimiConfigToml {\n if (!existsSync(path)) return {};\n try {\n return TOML.parse(readFileSync(path, \"utf8\")) as unknown as KimiConfigToml;\n } catch {\n return {};\n }\n }\n\n private writeToml(path: string, data: KimiConfigToml, dryRun: boolean): void {\n if (dryRun) return;\n ensureDir(dirname(path));\n // NOTE: a @iarna/toml parse→stringify round-trip preserves config VALUES but\n // NOT user comments or the original key ordering/formatting in config.toml.\n // Values are safe; comments authored by the user are not preserved.\n writeFileSync(path, TOML.stringify(data as never), \"utf8\");\n }\n}\n\n/** Best-effort stringify of Kimi's tool_response into a normalized toolOutput. */\nfunction toolResponseToString(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return undefined;\n }\n}\n\nexport const adapter = new KimiAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/mimo-code/index.ts"],"sourcesContent":["/**\n * adapters/mimo-code — Xiaomi MiMoCode platform adapter for agent-connector.\n *\n * MiMoCode (github.com/XiaomiMiMo/MiMo-Code, MIT) is Xiaomi's open-source\n * terminal AI coding agent — a FORK OF OpenCode (anomalyco/opencode) that adds\n * cross-session memory, checkpoints, subagents, etc. Official npm `@mimo-ai/cli`\n * (bin: `mimo`). NOTE: `@xiaomi-mimo/cli` is an UNOFFICIAL squatter (GPL) — not\n * referenced here; the bin is `mimo`, NOT `mimo-code`.\n *\n * DESIGN — STANDALONE (mirrors OpenCode's render logic with mimocode paths),\n * NOT `extends OpenCodeAdapter`. The OpenCode adapter binds the host string in\n * several places that a subclass cannot cleanly override:\n * - a module-level `const HOST = \"opencode\"` used for the per-platform server/\n * hooks override lookup (`ctx.connector.platforms[HOST]`) and stamped as\n * `hostPlatform` on every parsed event — extending would read\n * `platforms[\"opencode\"]` overrides and mis-stamp events as opencode;\n * - the PRIVATE `buildPluginSource` hardcodes `[\"hook\", \"opencode\", event, …]`\n * in the GENERATED bridge, so an inherited plugin would dispatch the runtime\n * hook to the opencode adapter (`hook opencode`) instead of mimo-code;\n * - the config/plugin/content directory builders hardcode \"opencode\" /\n * \".opencode\" / \"opencode.json\".\n * Overriding all of that means re-implementing the private render core anyway,\n * so this adapter mirrors OpenCode's logic with a `HOST = \"mimo-code\"` constant\n * and the mimocode paths — a clean standalone that routes detection, the runtime\n * bridge, and per-platform overrides to its own id.\n *\n * MiMoCode IS OpenCode's config dialect, so the render shapes are IDENTICAL:\n * - config file `mimocode.json`\n * user scope → ~/.config/mimocode/mimocode.json\n * project scope → <projectDir>/mimocode.json\n * (the dir is `.mimocode` / `~/.config/mimocode` — NO hyphen; the committed\n * example is `.mimocode/mimocode.jsonc`).\n * - MCP root key \"mcp\" (the OpenCode shape, NOT \"mcpServers\"); each server\n * keyed by name; stdio → { type:\"local\", command:[exe,…args], environment },\n * remote → { type:\"remote\", url }.\n * - ts-plugin hooks: a self-contained ESM bridge module auto-loaded from the\n * user scope → ~/.config/mimocode/plugin/<id>.js\n * project scope → <projectDir>/.mimocode/plugin/<id>.js\n * plugin dir (writing the file IS the registration; no config array edit).\n * - content surfaces under <mcDir>/{commands,skills,agent} (singular `agent/`,\n * matching OpenCode).\n *\n * Event mapping (OpenCode's, unchanged):\n * PreToolUse → \"tool.execute.before\" (mutate output.args; throw to deny)\n * PostToolUse → \"tool.execute.after\" (mutate output.output)\n * SessionStart → \"experimental.chat.system.transform\" (inject into output.system)\n *\n * SOURCES: github.com/XiaomiMiMo/MiMo-Code (README, .mimocode/mimocode.jsonc,\n * packages/opencode/src/config/{config.ts,mcp.ts,plugin.ts}). npm @mimo-ai/cli.\n * mimo.xiaomi.com/en/mimocode.\n */\n\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type {\n Adapter,\n GeneratedPluginFile,\n HookReply,\n InstallContext,\n MemoryTarget,\n NormalizedEvent,\n} from \"../spi.js\";\nimport type {\n ChangeRecord,\n CommandDef,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PreToolUseEvent,\n ServerDef,\n SessionStartEvent,\n Transport,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport { renderBridgePrelude } from \"../../core/ts-plugin-bridge.js\";\nimport {\n buildWrappedStdio,\n} from \"../../core/spawn.js\";\nimport { renderOpenCodeSubagentMd, renderSkillMd } from \"../claude-code/render.js\";\n\nconst HOST: PlatformId = \"mimo-code\";\nconst MCP_ROOT_KEY = \"mcp\";\n\n/** The config dir name (NO hyphen): `.mimocode` / `~/.config/mimocode`. */\nconst CONFIG_DIR_NAME = \"mimocode\";\n/** The config file name: `mimocode.json`. */\nconst CONFIG_FILE_NAME = \"mimocode.json\";\n\n/**\n * Canonical → MiMoCode (OpenCode-shaped) event name map. A connector hook event\n * is only emitted by the generated plugin when it appears here AND is declared\n * by the connector.\n */\nconst EVENT_TO_MIMOCODE: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"tool.execute.before\",\n PostToolUse: \"tool.execute.after\",\n // No real SessionStart hook (inherited from OpenCode #14808 / #5409). The\n // verified surrogate is experimental.chat.system.transform.\n SessionStart: \"experimental.chat.system.transform\",\n // chat.message fires on the user's prompt submission; the handler mutates\n // output (pushes a text part) to inject context. No documented block/abort.\n UserPromptSubmit: \"chat.message\",\n};\n\n/** Raw payload the generated plugin posts to the universal hook entrypoint. */\ninterface MiMoCodeBridgePayload {\n toolName?: string;\n toolInput?: Record<string, unknown>;\n toolOutput?: string;\n isError?: boolean;\n prompt?: string;\n sessionId?: string;\n projectDir?: string;\n}\n\n/** Native MCP server entry shapes MiMoCode accepts under the \"mcp\" key. */\ninterface MiMoCodeLocalServer {\n type: \"local\";\n command: string[];\n environment?: Record<string, string>;\n enabled?: boolean;\n}\ninterface MiMoCodeRemoteServer {\n type: \"remote\";\n url: string;\n enabled?: boolean;\n}\n\nexport class MiMoCodeAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"MiMoCode\";\n readonly paradigm: HookParadigm = \"ts-plugin\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block (CLAUDE.md fallback, like\n // OpenCode — MiMoCode keeps OpenCode's CLAUDE.md import + AGENTS.md reading).\n supportsMemory: true,\n preToolUse: true,\n postToolUse: true,\n preCompact: false,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: true,\n stop: false,\n notification: false,\n // tool.execute.before mutates output.args → input rewrite supported.\n canModifyArgs: true,\n // tool.execute.after mutates output.output → output rewrite supported.\n canModifyOutput: true,\n // injected via experimental.chat.system.transform at session start.\n canInjectSessionContext: true,\n transports: [\"stdio\", \"sse\", \"http\"],\n // Content surfaces: MiMoCode authors all three natively under <mcDir>\n // (inherited from OpenCode's commands/skills/agent layout).\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: true,\n };\n\n // ── Detection ──────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userConfigDir = join(homedir(), \".config\", CONFIG_DIR_NAME);\n const userConfig = join(userConfigDir, CONFIG_FILE_NAME);\n const projectConfig = join(projectDir, CONFIG_FILE_NAME);\n\n const userInstalled = existsSync(userConfigDir) || existsSync(userConfig);\n const projInstalled = existsSync(projectConfig);\n const installed = userInstalled || projInstalled;\n\n // Report the marker that actually matched so a project-only install isn't\n // misreported as a (non-existent) user install.\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projectConfig : userConfig;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? scope === \"project\"\n ? `found project MiMoCode config at ${projectConfig}`\n : `found MiMoCode config under ${userConfigDir}`\n : `no MiMoCode config at ${userConfigDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Memory surface: AGENTS.md / CLAUDE.md-fallback probe (project) ──────\n // Mirrors OpenCode: project AGENTS.md, falling back to CLAUDE.md ONLY when no\n // AGENTS.md exists (creating AGENTS.md beside a relied-on CLAUDE.md would\n // shadow the user's rules). User scope stays on the BaseAdapter default.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n if (this.memoryOverride(ctx)?.path || ctx.scope !== \"project\") {\n return super.memoryTargets(ctx);\n }\n const agentsMd = join(ctx.projectDir, \"AGENTS.md\");\n if (existsSync(agentsMd)) {\n return [{ path: agentsMd, reason: \"AGENTS.md (mimocode's primary project rules file)\" }];\n }\n const claudeMd = join(ctx.projectDir, \"CLAUDE.md\");\n if (existsSync(claudeMd)) {\n return [\n {\n path: claudeMd,\n reason:\n \"CLAUDE.md (mimocode's fallback rules file — creating AGENTS.md would shadow it)\",\n },\n ];\n }\n return [{ path: agentsMd, reason: \"AGENTS.md standard (created; no mimocode rules file yet)\" }];\n }\n\n // ── Native paths ───────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? ctx.projectDir\n : join(homedir(), \".config\", CONFIG_DIR_NAME);\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), CONFIG_FILE_NAME);\n }\n\n /**\n * For ts-plugin hosts the \"hook config path\" is the generated plugin FILE.\n * MiMoCode (like OpenCode) auto-loads every file in the plugin dir; writing\n * this file IS the registration.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.pluginDir(ctx), this.pluginFileName(ctx));\n }\n\n /** Plugin directory MiMoCode auto-loads modules from, per scope. */\n private pluginDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, `.${CONFIG_DIR_NAME}`, \"plugin\")\n : join(homedir(), \".config\", CONFIG_DIR_NAME, \"plugin\");\n }\n\n /** Plugin module file name (one per connector, kebab-case id). */\n private pluginFileName(ctx: InstallContext): string {\n return `${ctx.connector.id}.js`;\n }\n\n // ── MCP server install / uninstall ─────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const server = this.effectiveServer(ctx);\n const serverPath = this.getServerConfigPath(ctx);\n\n if (!server) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: serverPath,\n detail: ctx.connector.server\n ? \"server registration disabled for mimo-code\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n const entry = this.renderServerEntry(ctx, server);\n return [\n this.upsertServerInJson(\n serverPath,\n MCP_ROOT_KEY,\n ctx.connector.id,\n entry,\n ctx.dryRun,\n ),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(\n serverPath,\n MCP_ROOT_KEY,\n ctx.connector.id,\n ctx.dryRun,\n ),\n ];\n }\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[HOST]?.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 /**\n * Render a normalized ServerDef into MiMoCode's native \"mcp\" entry (OpenCode\n * dialect).\n *\n * stdio → { type: \"local\", command: [exe, ...args], environment }\n * remote → { type: \"remote\", url }\n *\n * MiMoCode flattens command+args into a single ARRAY. When telemetry wrapping\n * applies, the wrapper's command+args (which already include the real command\n * tail after `--`) become the head of that array. No native interpolation\n * token → resolve every ${env:VAR} reference to a literal at install time.\n */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): MiMoCodeLocalServer | MiMoCodeRemoteServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n const commandArray = resolveEnvRefsDeep([command, ...args]).filter(\n (s) => s !== \"\",\n );\n const entry: MiMoCodeLocalServer = {\n type: \"local\",\n command: commandArray,\n };\n const environment = this.renderEnv(server.env);\n if (environment) entry.environment = environment;\n if (server.enabled === false) entry.enabled = false;\n return entry;\n }\n\n // sse / http / ws (any remote transport) — MiMoCode registers a URL.\n const entry: MiMoCodeRemoteServer = {\n type: \"remote\",\n url: resolveEnvRefsDeep(server.url ?? \"\"),\n };\n if (server.enabled === false) entry.enabled = false;\n return entry;\n }\n\n /** Render env values, resolving every ${env:VAR} reference to a literal. */\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 // ── Hook install / uninstall (ts-plugin) ───────────────────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n\n if (ctx.connector.platforms[HOST]?.hooks === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"hooks disabled for mimo-code\",\n },\n ];\n }\n if (ctx.connector.hookEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"connector declares no hooks\",\n },\n ];\n }\n\n const files = this.synthesizePlugin(ctx);\n const changes: ChangeRecord[] = [];\n\n for (const file of files) {\n const before = existsSync(file.path)\n ? this.safeRead(file.path)\n : undefined;\n let action: ChangeRecord[\"action\"];\n if (before === undefined) action = \"create\";\n else if (before === file.contents) action = \"skip\";\n else action = \"update\";\n\n if (action !== \"skip\" && !ctx.dryRun) {\n ensureDir(dirname(file.path));\n writeFileSync(file.path, file.contents, \"utf8\");\n chmodSync(file.path, file.executable ? 0o755 : 0o644);\n }\n\n changes.push({\n platform: this.id,\n action,\n path: file.path,\n detail: `mimo-code plugin module (${this.hookDetail(ctx)})`,\n });\n }\n\n return changes;\n }\n\n /**\n * Human-facing summary of which declared events the synthesized module\n * ACTUALLY wires. Only events present in EVENT_TO_MIMOCODE are mapped/wired;\n * any declared event with no mapping is reported separately as \"unsupported\n * here\" so the detail never overstates coverage.\n */\n private hookDetail(ctx: InstallContext): string {\n const declared = ctx.connector.hookEvents;\n const mapped = declared.filter((e) => EVENT_TO_MIMOCODE[e] !== undefined);\n const unsupported = declared.filter((e) => EVENT_TO_MIMOCODE[e] === undefined);\n const base = mapped.join(\",\");\n return unsupported.length > 0\n ? `${base}; unsupported here: ${unsupported.join(\",\")}`\n : base;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n if (!existsSync(pluginPath)) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"no mimo-code plugin module present\",\n },\n ];\n }\n if (!ctx.dryRun) rmSync(pluginPath, { force: true });\n return [\n {\n platform: this.id,\n action: \"remove\",\n path: pluginPath,\n detail: \"mimo-code plugin module\",\n },\n ];\n }\n\n // ── Content surfaces: commands / skills / subagents ──────────────────────\n // CONTENT-ONLY: pure native-file writers under <mcDir>/{commands,skills,\n // agent}. No runtime dispatch, no home-bin pointer, no telemetry wrap. Each\n // method is idempotent (byte-identical → skip) and reversible. Mirrors\n // OpenCode's layout: commands/<name>.md, skills/<name>/SKILL.md, and the\n // SINGULAR agent/<name>.md dir for subagents. For project scope the content\n // root is <projectDir>/.mimocode (NOT the project root where mimocode.json\n // lives).\n\n private contentRootDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, `.${CONFIG_DIR_NAME}`)\n : this.getConfigDir(ctx);\n }\n private commandsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"commands\");\n }\n private skillsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"skills\");\n }\n private agentDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"agent\");\n }\n\n /** Native command file path: <mcDir>/commands/<name>.md. */\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.commandsDir(ctx), `${name}.md`);\n }\n /** Native skill dir: <mcDir>/skills/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\n }\n /** Native subagent file path: <mcDir>/agent/<name>.md (SINGULAR dir). */\n private subagentPath(ctx: InstallContext, name: string): string {\n return join(this.agentDir(ctx), `${name}.md`);\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 mimo-code\" }];\n }\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.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 command to md+frontmatter (description, model, subtask). */\n private renderCommand(cmd: CommandDef): string {\n const frontmatter: Record<string, unknown> = {};\n if (cmd.description !== undefined) frontmatter.description = cmd.description;\n if (cmd.model !== undefined) frontmatter.model = cmd.model;\n if (cmd.subtask !== undefined) frontmatter.subtask = cmd.subtask;\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 mimo-code\" }];\n }\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 changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), renderSkillMd(skill), ctx.dryRun),\n );\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 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;\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Subagents ───────────────────────────────────────────────────────────────\n\n override installSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.subagents === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"subagents disabled for mimo-code\" }];\n }\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.writeContentFile(\n this.subagentPath(ctx, agent.name),\n renderOpenCodeSubagentMd(agent),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.removeContentFile(this.subagentPath(ctx, agent.name), ctx.dryRun),\n );\n }\n\n // ── ts-plugin synthesis ────────────────────────────────────────────────\n\n /**\n * Build ONE self-contained ESM bridge module for MiMoCode. The module imports\n * nothing from agent-connector; it embeds the home-bin path + connector id and\n * a `bridge()` helper that shells out to the universal hook entrypoint\n * (`<homeBin> hook mimo-code <event> --connector <id>`), feeding the payload on\n * stdin and JSON.parsing the normalized HookResponse from stdout (fail-open).\n */\n synthesizePlugin(ctx: InstallContext): GeneratedPluginFile[] {\n const path = this.getHookConfigPath(ctx);\n const contents = this.buildPluginSource(ctx);\n return [{ path, contents, executable: false }];\n }\n\n /** Compose the generated plugin source with plain string concatenation. */\n private buildPluginSource(ctx: InstallContext): string {\n const events = ctx.connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_MIMOCODE[e] !== undefined,\n );\n const has = (e: HookEventName) => events.includes(e);\n\n const header = `/**\n * AUTO-GENERATED by agent-connector — DO NOT EDIT.\n *\n * Self-contained MiMoCode plugin bridge for connector ${ctx.connector.id}.\n * It imports nothing from agent-connector: every hook invocation shells out to\n * the stable home binary's universal entrypoint and JSON-parses the normalized\n * response. Fail-open: any bridge error degrades to \"allow\".\n */\nimport { execFileSync, execSync } from \"node:child_process\";\n\n${renderBridgePrelude({\n homeBin: ctx.homeBinPath,\n connectorId: ctx.connector.id,\n hookSlug: \"mimo-code\",\n payloadNoun: \"MiMoCode\",\n eventDoc: \" (PreToolUse|PostToolUse|SessionStart)\",\n failOpenComment: \"Fail-open — never wedge a tool call on a bridge error.\",\n})}\n`;\n\n const handlers: string[] = [];\n\n if (has(\"PreToolUse\")) {\n handlers.push(` // PreToolUse → block (throw) / rewrite args (mutate output.args).\n \"tool.execute.before\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: (output && output.args) ?? {},\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PreToolUse\", payload);\n if (!res) return;\n // MiMoCode has no \"ask\" gate — degrade \"ask\" to a block (safe direction).\n if (res.decision === \"deny\" || res.decision === \"ask\") {\n throw new Error(res.reason || \"Blocked by ${ctx.connector.id}\");\n }\n if (res.updatedInput && output && output.args) {\n Object.assign(output.args, res.updatedInput);\n }\n },`);\n }\n\n if (has(\"PostToolUse\")) {\n handlers.push(` // PostToolUse → observe / rewrite tool output (mutate output.output).\n \"tool.execute.after\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: input.args ?? {},\n toolOutput: output ? output.output : undefined,\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PostToolUse\", payload);\n if (!res) return;\n if (typeof res.updatedOutput === \"string\" && output) {\n output.output = res.updatedOutput;\n }\n },`);\n }\n\n if (has(\"SessionStart\")) {\n handlers.push(` // SessionStart surrogate → inject context into the system prompt.\n // MiMoCode has no real SessionStart hook (inherited from OpenCode\n // #14808 / #5409); experimental.chat.system.transform is the injection point.\n \"experimental.chat.system.transform\": async (input, output) => {\n const payload = {\n sessionId: (input && input.sessionID) ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"SessionStart\", payload);\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.system)) {\n // Insert at index 1 (after the header) to preserve the prompt-cache\n // fold (header must remain system[0]).\n output.system.splice(1, 0, res.additionalContext);\n }\n },`);\n }\n\n if (has(\"UserPromptSubmit\")) {\n handlers.push(` // UserPromptSubmit → context injection on prompt submission.\n // chat.message fires on the USER's prompt; output.message is a UserMessage\n // and output.parts holds the prompt parts. Inject context by PUSHING a text\n // part onto output.parts. chat.message has NO documented block/abort\n // mechanism, so a \"deny\" decision degrades to a NO-OP (best-effort) — same\n // way the tool/system handlers degrade decisions this host cannot honor.\n \"chat.message\": async (input, output) => {\n const promptText =\n output && Array.isArray(output.parts)\n ? output.parts\n .filter((p) => p && p.type === \"text\" && typeof p.text === \"string\")\n .map((p) => p.text)\n .join(\"\\\\n\")\n : \"\";\n const res = bridge(\"UserPromptSubmit\", {\n prompt: promptText,\n sessionId: (input && input.sessionID) || \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.parts)) {\n output.parts.push({ type: \"text\", text: res.additionalContext });\n }\n },`);\n }\n\n const factory = `\nexport default async function (ctx) {\n // ctx.directory is the MiMoCode project root; fall back to cwd.\n const PROJECT_DIR =\n (ctx && (ctx.directory || (ctx.worktree && ctx.worktree.path))) ||\n process.cwd();\n\n return {\n${handlers.join(\"\\n\")}\n };\n}\n`;\n\n return header + factory;\n }\n\n // ── Runtime: parse OUR bridge payload → normalized event ───────────────\n\n /**\n * `raw` is the payload OUR generated plugin posts (NOT a host-native shape):\n * { toolName, toolInput, toolOutput?, isError?, sessionId, projectDir }\n * so this maps straight through.\n */\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as MiMoCodeBridgePayload;\n const base = {\n hostPlatform: HOST,\n connectorId: \"\",\n sessionId: typeof input.sessionId === \"string\" ? input.sessionId : \"\",\n raw,\n ...(typeof input.projectDir === \"string\"\n ? { projectDir: input.projectDir }\n : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n ...(typeof input.toolOutput === \"string\"\n ? { toolOutput: input.toolOutput }\n : {}),\n ...(typeof input.isError === \"boolean\"\n ? { isError: input.isError }\n : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = { ...base, source: \"startup\" };\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 default:\n // Other canonical events are not surfaced by MiMoCode; treat as a\n // session-start-shaped no-op so the dispatcher fails open gracefully.\n return { ...base, source: \"startup\" } satisfies SessionStartEvent;\n }\n }\n\n // ── Runtime: normalized response → reply the generated bridge parses ───\n\n /**\n * Our generated bridge consumes this stdout directly, so the reply body is the\n * NORMALIZED HookResponse itself — the bridge JSON.parses it and reads\n * decision / updatedInput / updatedOutput / additionalContext.\n */\n formatReply(_event: HookEventName, response: HookResponse): HookReply {\n return {\n exitCode: 0,\n stdout: JSON.stringify(response ?? { decision: \"allow\" }),\n };\n }\n\n // ── Diagnostics ────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const serverPath = this.getServerConfigPath(ctx);\n const pluginPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const hasHooks = ctx.connector.hookEvents.length > 0;\n\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: mimocode.json present`,\n check: () =>\n existsSync(serverPath)\n ? { status: \"OK\", detail: serverPath }\n : { status: \"FAIL\", detail: `not found: ${serverPath}` },\n },\n {\n name: `${this.name}: mcp.${connectorId} registered`,\n check: () => {\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> }>(\n serverPath,\n );\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${serverPath}` };\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 ${serverPath}`,\n };\n },\n },\n {\n name: `${this.name}: plugin module present`,\n check: () => {\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n return existsSync(pluginPath)\n ? { status: \"OK\", detail: pluginPath }\n : { status: \"FAIL\", detail: `not found: ${pluginPath}` };\n },\n },\n ];\n\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 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 existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const agent of ctx.connector.subagents) {\n const p = this.subagentPath(ctx, agent.name);\n checks.push({\n name: `${this.name}: subagent ${agent.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n return checks;\n }\n\n /** Read a file, returning undefined on any error (idempotency compare). */\n private safeRead(path: string): string | undefined {\n try {\n return readFileSync(path, \"utf8\");\n } catch {\n return undefined;\n }\n }\n}\n\n/** Create a directory (recursive) if it does not already exist. */\nfunction ensureDir(dir: string): void {\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\nexport const adapter = new MiMoCodeAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
File without changes
File without changes