@ken-jo/agent-connector 0.4.7 → 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 (271) hide show
  1. package/README.md +36 -24
  2. package/dist/{action-YCU53FNE.js → action-AZRZ3V7E.js} +14 -14
  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-JPBQJJVM.js → amp-TF5X6OGH.js} +18 -50
  7. package/dist/amp-TF5X6OGH.js.map +1 -0
  8. package/dist/antigravity-3XHBPXZK.js +19 -0
  9. package/dist/{antigravity-STHZWMP3.js → antigravity-EA4L225L.js} +2 -2
  10. package/dist/{antigravity-cli-P6HADOAO.js → antigravity-cli-B2HXZFYQ.js} +2 -2
  11. package/dist/{antigravity-cli-D4PCCUG2.js → antigravity-cli-TJGOBUPK.js} +8 -7
  12. package/dist/{antigravity-cli-D4PCCUG2.js.map → antigravity-cli-TJGOBUPK.js.map} +1 -1
  13. package/dist/{chunk-CYOAH23F.js → chunk-25BNMXPP.js} +18 -18
  14. package/dist/{chunk-NLFPH4S2.js → chunk-2RPHDVHW.js} +2 -2
  15. package/dist/{chunk-PFDUGDOA.js → chunk-3I7UG52L.js} +25 -6
  16. package/dist/chunk-3I7UG52L.js.map +1 -0
  17. package/dist/{chunk-F5RX62T7.js → chunk-7QRUZAUG.js} +2 -2
  18. package/dist/{chunk-BCHWFTV4.js → chunk-F4DSMVZ7.js} +2 -2
  19. package/dist/chunk-FBJQGRET.js +38 -0
  20. package/dist/chunk-FBJQGRET.js.map +1 -0
  21. package/dist/{chunk-WZA4CSGJ.js → chunk-H53QZQJI.js} +15 -2
  22. package/dist/chunk-H53QZQJI.js.map +1 -0
  23. package/dist/{chunk-2F5QH3D4.js → chunk-HU6DZZBG.js} +36 -36
  24. package/dist/{chunk-7ECYDK5T.js → chunk-HZDU3J4U.js} +10 -5
  25. package/dist/chunk-HZDU3J4U.js.map +1 -0
  26. package/dist/{chunk-7L6ITC4T.js → chunk-IEGR4TP3.js} +22 -6
  27. package/dist/chunk-IEGR4TP3.js.map +1 -0
  28. package/dist/{chunk-SCVBYSF7.js → chunk-IRUYJD23.js} +28 -28
  29. package/dist/{chunk-6RYPUR6O.js → chunk-IW46JIQM.js} +34 -44
  30. package/dist/chunk-IW46JIQM.js.map +1 -0
  31. package/dist/{chunk-WFXWJITA.js → chunk-JLMD3IGK.js} +2 -2
  32. package/dist/{chunk-TZQBASI7.js → chunk-KD4BE5MW.js} +13 -49
  33. package/dist/chunk-KD4BE5MW.js.map +1 -0
  34. package/dist/{chunk-FAHIMJRU.js → chunk-L7ESV37V.js} +2 -2
  35. package/dist/{chunk-JNM3TPLX.js → chunk-LETB5HCK.js} +2 -2
  36. package/dist/{chunk-G5CQHVQG.js → chunk-M3H7PQWT.js} +13 -16
  37. package/dist/chunk-M3H7PQWT.js.map +1 -0
  38. package/dist/{chunk-JWNT5KW7.js → chunk-O7SDRBVB.js} +3 -1
  39. package/dist/chunk-O7SDRBVB.js.map +1 -0
  40. package/dist/{chunk-YQLQJZ7S.js → chunk-OLI5SD6I.js} +8 -4
  41. package/dist/chunk-OLI5SD6I.js.map +1 -0
  42. package/dist/{chunk-SDPIT4HW.js → chunk-Q5HR4ADS.js} +2 -2
  43. package/dist/{chunk-TRQKHP7D.js → chunk-QY42WGBX.js} +23 -2
  44. package/dist/chunk-QY42WGBX.js.map +1 -0
  45. package/dist/{chunk-I5MLE6S7.js → chunk-TO57WYBB.js} +15 -1
  46. package/dist/chunk-TO57WYBB.js.map +1 -0
  47. package/dist/chunk-UM5S7DKK.js +33 -0
  48. package/dist/chunk-UM5S7DKK.js.map +1 -0
  49. package/dist/{chunk-MDNX7HTN.js → chunk-YEJCNOET.js} +4 -4
  50. package/dist/{chunk-HAIMYUEY.js → chunk-YKVNI44Y.js} +51 -28
  51. package/dist/chunk-YKVNI44Y.js.map +1 -0
  52. package/dist/{chunk-DT6Y7XBI.js → chunk-YRBFSZ2G.js} +17 -39
  53. package/dist/chunk-YRBFSZ2G.js.map +1 -0
  54. package/dist/{chunk-SPWFUHHK.js → chunk-ZVTPSV5Z.js} +11 -10
  55. package/dist/{chunk-SPWFUHHK.js.map → chunk-ZVTPSV5Z.js.map} +1 -1
  56. package/dist/{chunk-N6HH7K6P.js → chunk-ZY25RG4Y.js} +2 -2
  57. package/dist/{claude-code-ROSIILTM.js → claude-code-JLPFUZ4V.js} +18 -41
  58. package/dist/claude-code-JLPFUZ4V.js.map +1 -0
  59. package/dist/{claude-code-W74MNTAC.js → claude-code-NMRKTAP7.js} +2 -2
  60. package/dist/cli/sdk.js +7 -7
  61. package/dist/cli.js +1 -1
  62. package/dist/{cline-JUTO4V27.js → cline-GBP3EVSX.js} +17 -49
  63. package/dist/cline-GBP3EVSX.js.map +1 -0
  64. package/dist/{codebuff-3PMZJJHP.js → codebuff-ETYT5UBL.js} +2 -2
  65. package/dist/{codebuff-2QUHL6HO.js → codebuff-WMKFUVER.js} +11 -42
  66. package/dist/codebuff-WMKFUVER.js.map +1 -0
  67. package/dist/{codex-YBBTIDD4.js → codex-5CZR5XKX.js} +28 -64
  68. package/dist/codex-5CZR5XKX.js.map +1 -0
  69. package/dist/{codex-Q3ATRRX3.js → codex-YAORPCOD.js} +2 -2
  70. package/dist/{continue-W4TU4JSB.js → continue-3AGXWM5W.js} +12 -35
  71. package/dist/continue-3AGXWM5W.js.map +1 -0
  72. package/dist/{copilot-cli-Y74SOP5G.js → copilot-cli-IH4P3GRZ.js} +17 -66
  73. package/dist/copilot-cli-IH4P3GRZ.js.map +1 -0
  74. package/dist/{copilot-cli-SJGIXVSD.js → copilot-cli-MZTAWMPW.js} +2 -2
  75. package/dist/{crush-GMEWLXK5.js → crush-FDBL3JEK.js} +17 -44
  76. package/dist/crush-FDBL3JEK.js.map +1 -0
  77. package/dist/{crush-LN5QFFR2.js → crush-QBXLNN7T.js} +2 -2
  78. package/dist/{cursor-QZ6MTO74.js → cursor-DIW43TRZ.js} +2 -2
  79. package/dist/{cursor-JBS4B3Q4.js → cursor-R5QB4YR4.js} +15 -53
  80. package/dist/cursor-R5QB4YR4.js.map +1 -0
  81. package/dist/{detect-2NIXILMZ.js → detect-L5OZPVFO.js} +4 -4
  82. package/dist/{doctor-QWJBWALA.js → doctor-WDIQ2YFE.js} +16 -15
  83. package/dist/{doctor-QWJBWALA.js.map → doctor-WDIQ2YFE.js.map} +1 -1
  84. package/dist/{droid-W5WF5XEX.js → droid-U3ZBLQFO.js} +2 -2
  85. package/dist/{droid-TJMTNCQE.js → droid-X2QHQL7D.js} +19 -42
  86. package/dist/droid-X2QHQL7D.js.map +1 -0
  87. package/dist/{gemini-cli-RAONGZRG.js → gemini-cli-HCN7XKSX.js} +17 -65
  88. package/dist/gemini-cli-HCN7XKSX.js.map +1 -0
  89. package/dist/{gemini-cli-CIRW37TU.js → gemini-cli-NMVVBO3K.js} +2 -2
  90. package/dist/{goose-A3M5GODH.js → goose-64V46Y2W.js} +2 -2
  91. package/dist/{goose-G4KKM6YU.js → goose-ILMM76JP.js} +21 -57
  92. package/dist/goose-ILMM76JP.js.map +1 -0
  93. package/dist/{hermes-ZYLMOFLZ.js → hermes-F3EGTK6N.js} +2 -2
  94. package/dist/{hermes-PJDTJE6F.js → hermes-YX2ODUZL.js} +17 -55
  95. package/dist/hermes-YX2ODUZL.js.map +1 -0
  96. package/dist/{hook-FDGIQPRC.js → hook-JRDQ56BN.js} +14 -14
  97. package/dist/index.d.ts +2 -2
  98. package/dist/index.js +5 -5
  99. package/dist/{install-TLG3QVP3.js → install-HRCVPRAQ.js} +16 -15
  100. package/dist/{install-TLG3QVP3.js.map → install-HRCVPRAQ.js.map} +1 -1
  101. package/dist/{introspect-Cn3MSA4_.d.ts → introspect-B164-hj3.d.ts} +1 -1
  102. package/dist/{jetbrains-copilot-DNXSLQE5.js → jetbrains-copilot-QESFUN6W.js} +12 -39
  103. package/dist/jetbrains-copilot-QESFUN6W.js.map +1 -0
  104. package/dist/{kilo-FERJ3X46.js → kilo-POTCYIRG.js} +28 -92
  105. package/dist/kilo-POTCYIRG.js.map +1 -0
  106. package/dist/{kilo-NSWAVP6P.js → kilo-SW7BH6EG.js} +2 -2
  107. package/dist/{kilo-cli-TDCONH5G.js → kilo-cli-MO6FSMH2.js} +19 -50
  108. package/dist/kilo-cli-MO6FSMH2.js.map +1 -0
  109. package/dist/{kilo-cli-EVBKUODA.js → kilo-cli-ZF272ZHN.js} +2 -2
  110. package/dist/{kimi-EI3UM3ZV.js → kimi-5FHEXGZD.js} +72 -13
  111. package/dist/kimi-5FHEXGZD.js.map +1 -0
  112. package/dist/{kimi-RIRD4J5J.js → kimi-RXS36OJP.js} +36 -50
  113. package/dist/kimi-RXS36OJP.js.map +1 -0
  114. package/dist/{kiro-X7JVLAN7.js → kiro-VTLX7CMF.js} +12 -33
  115. package/dist/kiro-VTLX7CMF.js.map +1 -0
  116. package/dist/{kiro-UCLSLBW2.js → kiro-WGOI5CGT.js} +2 -2
  117. package/dist/{leaderboard-MXGENYXN.js → leaderboard-ASGR3E2U.js} +6 -6
  118. package/dist/{mimo-code-RFLQ727H.js → mimo-code-F4BWMESO.js} +57 -91
  119. package/dist/mimo-code-F4BWMESO.js.map +1 -0
  120. package/dist/{mux-D77HBSBU.js → mux-2YFCYFM7.js} +11 -41
  121. package/dist/mux-2YFCYFM7.js.map +1 -0
  122. package/dist/{mux-ZMLVAXOO.js → mux-XM6AP35L.js} +2 -2
  123. package/dist/{nemoclaw-LXUTMR56.js → nemoclaw-QDB6O22A.js} +7 -7
  124. package/dist/{omp-CO7IXURG.js → omp-P2JNAEPN.js} +18 -50
  125. package/dist/omp-P2JNAEPN.js.map +1 -0
  126. package/dist/openclaw-3UMBSSZM.js +18 -0
  127. package/dist/{openclaw-IYA7ASL6.js → openclaw-5EQFGOWL.js} +2 -2
  128. package/dist/{opencode-QKZ5EIYU.js → opencode-Q6H4YT66.js} +24 -90
  129. package/dist/opencode-Q6H4YT66.js.map +1 -0
  130. package/dist/{opencode-HWT3RSMN.js → opencode-QGP4ALQY.js} +2 -2
  131. package/dist/{package-IA56LSC3.js → package-IXBSG7HD.js} +11 -11
  132. package/dist/{pi-UFX2OYFV.js → pi-GGDQREVG.js} +2 -2
  133. package/dist/{pi-YGBXYWY5.js → pi-GW25LPC3.js} +6 -6
  134. package/dist/{qwen-code-W7NUCDEN.js → qwen-code-GQILBJ5B.js} +2 -2
  135. package/dist/{qwen-code-E2MSEZK6.js → qwen-code-R6XXEEHJ.js} +13 -34
  136. package/dist/qwen-code-R6XXEEHJ.js.map +1 -0
  137. package/dist/{roo-code-AGGJ473T.js → roo-code-EZPNFC5V.js} +17 -54
  138. package/dist/roo-code-EZPNFC5V.js.map +1 -0
  139. package/dist/{roo-code-ZLKH4A7N.js → roo-code-SUWI4BBN.js} +2 -2
  140. package/dist/runtime/index.d.ts +1 -1
  141. package/dist/runtime/index.js +12 -12
  142. package/dist/sdk/index.d.ts +3 -3
  143. package/dist/sdk/index.js +6 -6
  144. package/dist/sdk/test.d.ts +2 -2
  145. package/dist/sdk/test.js +9 -9
  146. package/dist/{serve-RNUCK5F7.js → serve-CFBQYKRB.js} +14 -14
  147. package/dist/{status-JOX6RLJU.js → status-ASBFEFQQ.js} +11 -10
  148. package/dist/{status-JOX6RLJU.js.map → status-ASBFEFQQ.js.map} +1 -1
  149. package/dist/{statusline-ZVFI5DRT.js → statusline-WKLWSM7I.js} +13 -13
  150. package/dist/{synthetic-UKR6SMGS.js → synthetic-6FRA7P5Q.js} +2 -2
  151. package/dist/{telemetry-3FN6HDVU.js → telemetry-64GCGNIW.js} +10 -10
  152. package/dist/{trae-6L226ZDU.js → trae-6VQW2UVP.js} +12 -41
  153. package/dist/trae-6VQW2UVP.js.map +1 -0
  154. package/dist/{trae-PA26DPBW.js → trae-CPPYASR2.js} +2 -2
  155. package/dist/{types-_6arHbX9.d.ts → types-COSBYpKs.d.ts} +7 -5
  156. package/dist/{uninstall-SCKZYB4J.js → uninstall-KDJYE5ET.js} +16 -15
  157. package/dist/{uninstall-SCKZYB4J.js.map → uninstall-KDJYE5ET.js.map} +1 -1
  158. package/dist/{upgrade-WU3KZWR4.js → upgrade-YQRVYR5U.js} +16 -15
  159. package/dist/{upgrade-WU3KZWR4.js.map → upgrade-YQRVYR5U.js.map} +1 -1
  160. package/dist/{usage-G72SF7JG.js → usage-OV2BDZKF.js} +3 -3
  161. package/dist/{usage-event-DHSEBO5T.js → usage-event-KPI3NEX3.js} +13 -13
  162. package/dist/{vscode-copilot-6EOZDLXC.js → vscode-copilot-UOEEV4P3.js} +17 -67
  163. package/dist/vscode-copilot-UOEEV4P3.js.map +1 -0
  164. package/dist/{warp-N5YYN5BF.js → warp-LUK2BPCU.js} +9 -21
  165. package/dist/warp-LUK2BPCU.js.map +1 -0
  166. package/dist/{warp-JNQA7PBU.js → warp-NRBBJQR2.js} +2 -2
  167. package/dist/{windsurf-4TGSJIVV.js → windsurf-NZ3G42NQ.js} +8 -20
  168. package/dist/windsurf-NZ3G42NQ.js.map +1 -0
  169. package/dist/{zed-6P2UFWXU.js → zed-LGWGZ4EO.js} +13 -23
  170. package/dist/zed-LGWGZ4EO.js.map +1 -0
  171. package/dist/{zed-NNNX5MNT.js → zed-XJFOOKCO.js} +2 -2
  172. package/package.json +7 -2
  173. package/dist/amazon-q-W574ZX35.js +0 -276
  174. package/dist/amazon-q-W574ZX35.js.map +0 -1
  175. package/dist/amp-JPBQJJVM.js.map +0 -1
  176. package/dist/antigravity-VK2Y3FGV.js +0 -18
  177. package/dist/chunk-6RYPUR6O.js.map +0 -1
  178. package/dist/chunk-7ECYDK5T.js.map +0 -1
  179. package/dist/chunk-7L6ITC4T.js.map +0 -1
  180. package/dist/chunk-DT6Y7XBI.js.map +0 -1
  181. package/dist/chunk-G5CQHVQG.js.map +0 -1
  182. package/dist/chunk-HAIMYUEY.js.map +0 -1
  183. package/dist/chunk-I5MLE6S7.js.map +0 -1
  184. package/dist/chunk-JWNT5KW7.js.map +0 -1
  185. package/dist/chunk-PFDUGDOA.js.map +0 -1
  186. package/dist/chunk-TRQKHP7D.js.map +0 -1
  187. package/dist/chunk-TZQBASI7.js.map +0 -1
  188. package/dist/chunk-WZA4CSGJ.js.map +0 -1
  189. package/dist/chunk-YQLQJZ7S.js.map +0 -1
  190. package/dist/claude-code-ROSIILTM.js.map +0 -1
  191. package/dist/cline-JUTO4V27.js.map +0 -1
  192. package/dist/codebuff-2QUHL6HO.js.map +0 -1
  193. package/dist/codex-YBBTIDD4.js.map +0 -1
  194. package/dist/continue-W4TU4JSB.js.map +0 -1
  195. package/dist/copilot-cli-Y74SOP5G.js.map +0 -1
  196. package/dist/crush-GMEWLXK5.js.map +0 -1
  197. package/dist/cursor-JBS4B3Q4.js.map +0 -1
  198. package/dist/droid-TJMTNCQE.js.map +0 -1
  199. package/dist/gemini-cli-RAONGZRG.js.map +0 -1
  200. package/dist/goose-G4KKM6YU.js.map +0 -1
  201. package/dist/hermes-PJDTJE6F.js.map +0 -1
  202. package/dist/jetbrains-copilot-DNXSLQE5.js.map +0 -1
  203. package/dist/kilo-FERJ3X46.js.map +0 -1
  204. package/dist/kilo-cli-TDCONH5G.js.map +0 -1
  205. package/dist/kimi-EI3UM3ZV.js.map +0 -1
  206. package/dist/kimi-RIRD4J5J.js.map +0 -1
  207. package/dist/kiro-X7JVLAN7.js.map +0 -1
  208. package/dist/mimo-code-RFLQ727H.js.map +0 -1
  209. package/dist/mux-D77HBSBU.js.map +0 -1
  210. package/dist/omp-CO7IXURG.js.map +0 -1
  211. package/dist/openclaw-XWJLEW35.js +0 -18
  212. package/dist/opencode-QKZ5EIYU.js.map +0 -1
  213. package/dist/qwen-code-E2MSEZK6.js.map +0 -1
  214. package/dist/roo-code-AGGJ473T.js.map +0 -1
  215. package/dist/trae-6L226ZDU.js.map +0 -1
  216. package/dist/vscode-copilot-6EOZDLXC.js.map +0 -1
  217. package/dist/warp-N5YYN5BF.js.map +0 -1
  218. package/dist/windsurf-4TGSJIVV.js.map +0 -1
  219. package/dist/zed-6P2UFWXU.js.map +0 -1
  220. /package/dist/{action-YCU53FNE.js.map → action-AZRZ3V7E.js.map} +0 -0
  221. /package/dist/{amp-TULUPXXL.js.map → amp-BQZOL5GR.js.map} +0 -0
  222. /package/dist/{antigravity-VK2Y3FGV.js.map → antigravity-3XHBPXZK.js.map} +0 -0
  223. /package/dist/{antigravity-STHZWMP3.js.map → antigravity-EA4L225L.js.map} +0 -0
  224. /package/dist/{antigravity-cli-P6HADOAO.js.map → antigravity-cli-B2HXZFYQ.js.map} +0 -0
  225. /package/dist/{chunk-CYOAH23F.js.map → chunk-25BNMXPP.js.map} +0 -0
  226. /package/dist/{chunk-NLFPH4S2.js.map → chunk-2RPHDVHW.js.map} +0 -0
  227. /package/dist/{chunk-F5RX62T7.js.map → chunk-7QRUZAUG.js.map} +0 -0
  228. /package/dist/{chunk-BCHWFTV4.js.map → chunk-F4DSMVZ7.js.map} +0 -0
  229. /package/dist/{chunk-2F5QH3D4.js.map → chunk-HU6DZZBG.js.map} +0 -0
  230. /package/dist/{chunk-SCVBYSF7.js.map → chunk-IRUYJD23.js.map} +0 -0
  231. /package/dist/{chunk-WFXWJITA.js.map → chunk-JLMD3IGK.js.map} +0 -0
  232. /package/dist/{chunk-FAHIMJRU.js.map → chunk-L7ESV37V.js.map} +0 -0
  233. /package/dist/{chunk-JNM3TPLX.js.map → chunk-LETB5HCK.js.map} +0 -0
  234. /package/dist/{chunk-SDPIT4HW.js.map → chunk-Q5HR4ADS.js.map} +0 -0
  235. /package/dist/{chunk-MDNX7HTN.js.map → chunk-YEJCNOET.js.map} +0 -0
  236. /package/dist/{chunk-N6HH7K6P.js.map → chunk-ZY25RG4Y.js.map} +0 -0
  237. /package/dist/{claude-code-W74MNTAC.js.map → claude-code-NMRKTAP7.js.map} +0 -0
  238. /package/dist/{codebuff-3PMZJJHP.js.map → codebuff-ETYT5UBL.js.map} +0 -0
  239. /package/dist/{codex-Q3ATRRX3.js.map → codex-YAORPCOD.js.map} +0 -0
  240. /package/dist/{copilot-cli-SJGIXVSD.js.map → copilot-cli-MZTAWMPW.js.map} +0 -0
  241. /package/dist/{crush-LN5QFFR2.js.map → crush-QBXLNN7T.js.map} +0 -0
  242. /package/dist/{cursor-QZ6MTO74.js.map → cursor-DIW43TRZ.js.map} +0 -0
  243. /package/dist/{detect-2NIXILMZ.js.map → detect-L5OZPVFO.js.map} +0 -0
  244. /package/dist/{droid-W5WF5XEX.js.map → droid-U3ZBLQFO.js.map} +0 -0
  245. /package/dist/{gemini-cli-CIRW37TU.js.map → gemini-cli-NMVVBO3K.js.map} +0 -0
  246. /package/dist/{goose-A3M5GODH.js.map → goose-64V46Y2W.js.map} +0 -0
  247. /package/dist/{hermes-ZYLMOFLZ.js.map → hermes-F3EGTK6N.js.map} +0 -0
  248. /package/dist/{hook-FDGIQPRC.js.map → hook-JRDQ56BN.js.map} +0 -0
  249. /package/dist/{kilo-NSWAVP6P.js.map → kilo-SW7BH6EG.js.map} +0 -0
  250. /package/dist/{kilo-cli-EVBKUODA.js.map → kilo-cli-ZF272ZHN.js.map} +0 -0
  251. /package/dist/{kiro-UCLSLBW2.js.map → kiro-WGOI5CGT.js.map} +0 -0
  252. /package/dist/{leaderboard-MXGENYXN.js.map → leaderboard-ASGR3E2U.js.map} +0 -0
  253. /package/dist/{mux-ZMLVAXOO.js.map → mux-XM6AP35L.js.map} +0 -0
  254. /package/dist/{nemoclaw-LXUTMR56.js.map → nemoclaw-QDB6O22A.js.map} +0 -0
  255. /package/dist/{openclaw-XWJLEW35.js.map → openclaw-3UMBSSZM.js.map} +0 -0
  256. /package/dist/{openclaw-IYA7ASL6.js.map → openclaw-5EQFGOWL.js.map} +0 -0
  257. /package/dist/{opencode-HWT3RSMN.js.map → opencode-QGP4ALQY.js.map} +0 -0
  258. /package/dist/{package-IA56LSC3.js.map → package-IXBSG7HD.js.map} +0 -0
  259. /package/dist/{pi-UFX2OYFV.js.map → pi-GGDQREVG.js.map} +0 -0
  260. /package/dist/{pi-YGBXYWY5.js.map → pi-GW25LPC3.js.map} +0 -0
  261. /package/dist/{qwen-code-W7NUCDEN.js.map → qwen-code-GQILBJ5B.js.map} +0 -0
  262. /package/dist/{roo-code-ZLKH4A7N.js.map → roo-code-SUWI4BBN.js.map} +0 -0
  263. /package/dist/{serve-RNUCK5F7.js.map → serve-CFBQYKRB.js.map} +0 -0
  264. /package/dist/{statusline-ZVFI5DRT.js.map → statusline-WKLWSM7I.js.map} +0 -0
  265. /package/dist/{synthetic-UKR6SMGS.js.map → synthetic-6FRA7P5Q.js.map} +0 -0
  266. /package/dist/{telemetry-3FN6HDVU.js.map → telemetry-64GCGNIW.js.map} +0 -0
  267. /package/dist/{trae-PA26DPBW.js.map → trae-CPPYASR2.js.map} +0 -0
  268. /package/dist/{usage-G72SF7JG.js.map → usage-OV2BDZKF.js.map} +0 -0
  269. /package/dist/{usage-event-DHSEBO5T.js.map → usage-event-KPI3NEX3.js.map} +0 -0
  270. /package/dist/{warp-JNQA7PBU.js.map → warp-NRBBJQR2.js.map} +0 -0
  271. /package/dist/{zed-NNNX5MNT.js.map → zed-XJFOOKCO.js.map} +0 -0
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  allAdapters,
4
4
  loadAdapter
5
- } from "./chunk-2F5QH3D4.js";
5
+ } from "./chunk-HU6DZZBG.js";
6
6
 
7
7
  // src/sdk/introspect.ts
8
8
  var SURFACE_PREDICATES = {
@@ -41,4 +41,4 @@ export {
41
41
  hostsSupporting,
42
42
  surfaceSupport
43
43
  };
44
- //# sourceMappingURL=chunk-WFXWJITA.js.map
44
+ //# sourceMappingURL=chunk-JLMD3IGK.js.map
@@ -1,19 +1,24 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ normalizeSessionSource
4
+ } from "./chunk-H53QZQJI.js";
2
5
  import {
3
6
  resolveEnvRefsDeep
4
7
  } from "./chunk-DBQMX75U.js";
5
8
  import {
6
9
  BaseAdapter
7
- } from "./chunk-PFDUGDOA.js";
10
+ } from "./chunk-3I7UG52L.js";
11
+ import {
12
+ renderSkillMd
13
+ } from "./chunk-IEGR4TP3.js";
8
14
  import {
9
15
  buildHomeBinHookCommand,
10
- buildServeWrapperCommand,
11
16
  buildUsageEventCommand,
17
+ buildWrappedStdio,
12
18
  isHomeBinHookCommand,
13
19
  isHostNativeUsageEnabled,
14
- isUsageEventCommand,
15
- shouldWrapForTelemetry
16
- } from "./chunk-I5MLE6S7.js";
20
+ isUsageEventCommand
21
+ } from "./chunk-TO57WYBB.js";
17
22
 
18
23
  // src/adapters/antigravity/index.ts
19
24
  import { existsSync } from "fs";
@@ -201,18 +206,7 @@ var AntigravityAdapter = class extends BaseAdapter {
201
206
  if (transport === "stdio") {
202
207
  let command = server.command ?? "";
203
208
  let args = [...server.args ?? []];
204
- if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {
205
- const wrapped = buildServeWrapperCommand(
206
- ctx.homeBinPath,
207
- ctx.connector.id,
208
- command,
209
- args,
210
- ctx.scope,
211
- this.id
212
- );
213
- command = wrapped.command;
214
- args = wrapped.args;
215
- }
209
+ ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));
216
210
  const entry2 = { command: resolveEnvRefsDeep(command) };
217
211
  if (args.length > 0) entry2.args = resolveEnvRefsDeep(args);
218
212
  const env = this.renderEnv(server.env);
@@ -484,7 +478,7 @@ ${body}`;
484
478
  for (const skill of connector.skills) {
485
479
  const dir = this.skillDir(ctx, skill.name);
486
480
  changes.push(
487
- this.writeContentFile(join(dir, "SKILL.md"), this.renderSkill(skill), ctx.dryRun)
481
+ this.writeContentFile(join(dir, "SKILL.md"), renderSkillMd(skill), ctx.dryRun)
488
482
  );
489
483
  for (const [rel, contents] of Object.entries(skill.resources ?? {})) {
490
484
  const target = this.resolveWithin(dir, rel);
@@ -519,24 +513,6 @@ ${body}`;
519
513
  }
520
514
  return changes;
521
515
  }
522
- /**
523
- * Render a skill's SKILL.md: frontmatter (name, description + optional model,
524
- * allowed-tools, disable-model-invocation) + body. Uniform across platforms.
525
- */
526
- renderSkill(skill) {
527
- const frontmatter = {
528
- name: skill.name,
529
- description: skill.description
530
- };
531
- if (skill.model !== void 0) frontmatter.model = skill.model;
532
- const allow = skill.tools?.allow;
533
- if (allow && allow.length > 0) frontmatter["allowed-tools"] = allow.join(", ");
534
- if (skill.disableModelInvocation !== void 0) {
535
- frontmatter["disable-model-invocation"] = skill.disableModelInvocation;
536
- }
537
- if (skill.extra) Object.assign(frontmatter, skill.extra);
538
- return this.renderFrontmatterMd(frontmatter, skill.body);
539
- }
540
516
  // ── Diagnostics ──────────────────────────────────────────────────────────
541
517
  getHealthChecks(ctx) {
542
518
  const mcpPath = this.getServerConfigPath(ctx);
@@ -692,18 +668,6 @@ ${body}`;
692
668
  return { exitCode: 0, stdout: JSON.stringify(payload) };
693
669
  }
694
670
  };
695
- function normalizeSessionSource(source) {
696
- switch (source) {
697
- case "compact":
698
- return "compact";
699
- case "resume":
700
- return "resume";
701
- case "clear":
702
- return "clear";
703
- default:
704
- return "startup";
705
- }
706
- }
707
671
  var adapter = new AntigravityAdapter();
708
672
  var antigravity_default = adapter;
709
673
 
@@ -712,4 +676,4 @@ export {
712
676
  adapter,
713
677
  antigravity_default
714
678
  };
715
- //# sourceMappingURL=chunk-TZQBASI7.js.map
679
+ //# sourceMappingURL=chunk-KD4BE5MW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/antigravity/index.ts"],"sourcesContent":["/**\n * adapters/antigravity — Google Antigravity (IDE) platform adapter.\n *\n * Antigravity is a Gemini-family host that, as of the 2.0 line, exposes a real\n * lifecycle-hook system on top of MCP — so this adapter is `json-stdio` (not the\n * old `mcp-only` framing): the host pipes a JSON payload to a hook command on\n * stdin and reads a JSON control object back, the same paradigm as Claude Code /\n * Gemini CLI. It installs the MCP server, lifecycle hooks, slash-command\n * Workflows, and Agent Skills.\n *\n * CONFIRMED-BY-INSTALL (2026-06-03, docs/research/antigravity-paths-confirmed.md):\n * a real machine with Antigravity IDE + `agy` CLI v1.0.0 shows the canonical user\n * customization root is `~/.gemini/antigravity/` — `~/.gemini/antigravity/mcp_config.json`\n * EXISTS and `~/.gemini/config/mcp_config.json` does NOT. So the fresh-install\n * default user MCP path is `~/.gemini/antigravity/mcp_config.json` (candidate[0]);\n * the `config/` and `antigravity-cli/` paths remain probed fallbacks only (honored\n * when a pre-existing config is found there, never the fresh default).\n *\n * STILL MEDIUM-CONFIDENCE / PATH-PROBING: hooks.json and the global skills dir were\n * NOT present on the observed install, so those locations stay corroborated-but-not-\n * byte-verified. Every user-scope path is PROBED at runtime — prefer a candidate\n * that already exists on disk, else fall back to the canonical path — and the doctor\n * flags each probed path with \"verify for your Antigravity version.\" We NEVER\n * hard-code a single guessed path, and any unsupported event or surface warn-skips\n * (never throws) at install time.\n *\n * Native config formats:\n * - MCP config (JSONC; we WRITE plain JSON), root key \"mcpServers\". stdio is\n * `{ command, args, env }`; a remote server is `{ serverUrl, headers }`\n * (NOTE: the key is `serverUrl`, NOT `url` and NOT Gemini CLI's `httpUrl`).\n * user scope → prefer existing of:\n * ~/.gemini/antigravity/mcp_config.json (CONFIRMED canonical)\n * ~/.gemini/config/mcp_config.json (probed fallback)\n * ~/.gemini/antigravity-cli/mcp_config.json (probed fallback)\n * else default to candidate[0] (antigravity/).\n * project scope → <projectDir>/.agents/mcp_config.json\n * - Hooks: a SEPARATE hooks.json in the customization dir (NOT the mcp_config),\n * project → <projectDir>/.agents/hooks.json\n * user → <resolvedUserConfigDir>/hooks.json\n * Shape: { hooks: { <Event>: [ { matcher, hooks:[{ type:\"command\", command }] } ] } }.\n * Supported events: PreToolUse, PostToolUse, SessionStart, Stop. All other\n * normalized events warn-skip. I/O fields are camelCase (see parse/format).\n * - Commands = \"Workflows\": markdown `.md` (body = the prompt; an optional\n * leading description line). Project prefer existing <proj>/.agent/workflows\n * or <proj>/.agents/workflows (default .agent/workflows per launch docs);\n * user ~/.gemini/antigravity/global_workflows.\n * - Skills = Agent Skills (uniform SKILL.md). Project\n * <proj>/.agents/skills/<name>/SKILL.md; user PROBE\n * ~/.gemini/antigravity-cli/skills then ~/.gemini/skills (NEVER\n * ~/.gemini/antigravity/skills — reportedly broken). NOTE: the global skills\n * dir was NOT present on the confirmed install, so it stays medium-confidence\n * + doctor \"verify for your version.\"\n * - Subagents: declarative subagents exist only inside a plugin bundle, which\n * agent-connector does not emit; supportsSubagents is false and the\n * BaseAdapter skip/warn default applies.\n *\n * Env handling: Antigravity (Gemini family) documents no `${env:VAR}` token of\n * the framework's syntax, so env/header/url refs are resolved to literals at\n * install time via resolveEnvRefsDeep — the safe default matching the Gemini CLI\n * adapter.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, NormalizedEvent } 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 StopEvent,\n Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildHomeBinHookCommand,\n buildWrappedStdio,\n buildUsageEventCommand,\n isHomeBinHookCommand,\n isHostNativeUsageEnabled,\n isUsageEventCommand,\n} from \"../../core/spawn.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\nimport { normalizeSessionSource } from \"../claude-code/wire.js\";\n\nconst HOST: PlatformId = \"antigravity\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/**\n * Known user-scope MCP config candidates, in preference order. We pick the first\n * that already exists on disk; otherwise we default to candidate[0]\n * (~/.gemini/antigravity/mcp_config.json — CONFIRMED canonical on a real install:\n * docs/research/antigravity-paths-confirmed.md). The `config/` and CLI-only\n * `antigravity-cli/` paths are kept ONLY as probed fallbacks so a pre-existing\n * config in either is still honored, but neither is ever the fresh-install default.\n */\nconst USER_CONFIG_CANDIDATES = [\n [\".gemini\", \"antigravity\", \"mcp_config.json\"],\n [\".gemini\", \"config\", \"mcp_config.json\"],\n [\".gemini\", \"antigravity-cli\", \"mcp_config.json\"],\n] as const;\n\n/**\n * Antigravity's supported lifecycle hook events. These happen to share the\n * normalized PascalCase names 1:1; everything else has no Antigravity equivalent\n * and is reported as a warn/skip at install time.\n */\nconst SUPPORTED_EVENTS: ReadonlySet<HookEventName> = new Set<HookEventName>([\n \"PreToolUse\",\n \"PostToolUse\",\n \"SessionStart\",\n \"Stop\",\n]);\n\n/**\n * Native hooks.json key for the OPT-IN host-native turn-usage hook (enricher 4a).\n * Antigravity shares the Gemini-family `AfterModel` model-turn hook, whose payload\n * carries `usageMetadata`. This is a host-native-only sink (no connector handler);\n * it is installed ONLY when host-native capture is enabled and records a DISTINCT\n * `model_turn` telemetry row that is never summed with the per-MCP `serve` rows.\n */\nconst USAGE_HOOK_EVENT = \"AfterModel\";\n\n/** A single Antigravity native hook registration entry (nested, Claude-shaped). */\ninterface AntigravityHookEntry {\n matcher: string;\n hooks: Array<{ type: \"command\"; command: string }>;\n}\n\n/** The shape of Antigravity's hooks.json (only the parts we touch). */\ninterface AntigravityHooksFile {\n hooks?: Record<string, AntigravityHookEntry[]>;\n [key: string]: unknown;\n}\n\n/**\n * Native MCP server entry shapes Antigravity accepts under `mcpServers`.\n * A stdio server is `{ command, args, env }`; a remote server is\n * `{ serverUrl, headers }` — the key is `serverUrl` (NOT `url`).\n */\ninterface AntigravityStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface AntigravityHttpServer {\n serverUrl: string;\n headers?: Record<string, string>;\n}\n\n/** Raw Antigravity hook stdin payload (camelCase wire fields). */\ninterface AntigravityWireInput {\n connector?: unknown;\n toolName?: string;\n toolInput?: Record<string, unknown>;\n toolOutput?: string;\n isError?: boolean;\n sessionId?: string;\n cwd?: string;\n source?: string;\n reason?: string;\n stopHookActive?: boolean;\n}\n\nexport class AntigravityAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name: string = \"Google Antigravity\";\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 // Antigravity 2.0 fires PreToolUse / PostToolUse / SessionStart / Stop.\n preToolUse: true,\n postToolUse: true,\n sessionStart: true,\n stop: true,\n // No documented equivalents — kept false; the corresponding normalized\n // events warn-skip at install time.\n preCompact: false,\n sessionEnd: false,\n userPromptSubmit: false,\n notification: false,\n // Newer events: no documented permission-dialog, tool-failure, or subagent\n // lifecycle hooks on Antigravity (IDE or `agy` CLI — the CLI adapter\n // inherits this surface), so permissionRequest / postToolUseFailure /\n // subagentStart / subagentStop stay unset — install reports the standard\n // skip-warn for them.\n // Transform-category hooks can rewrite tool input and tool output; the\n // SessionStart hook can inject additional context.\n canModifyArgs: true,\n canModifyOutput: true,\n canInjectSessionContext: true,\n // Antigravity registers stdio, SSE, and Streamable HTTP MCP servers.\n transports: [\"stdio\", \"sse\", \"http\"],\n // Content surfaces: Workflows (markdown commands) + Agent Skills (SKILL.md).\n // Declarative subagents exist only inside a plugin bundle (not emitted), so\n // subagents are unsupported and inherit the BaseAdapter skip/warn default.\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: false,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userConfig = this.resolveUserConfigPath();\n const userDir = join(homedir(), \".gemini\");\n const projectConfig = join(projectDir, \".agents\", \"mcp_config.json\");\n\n const userInstalled =\n existsSync(userDir) ||\n this.userConfigCandidates().some((parts) => existsSync(join(homedir(), ...parts)));\n const projInstalled = existsSync(projectConfig);\n const installed = userInstalled || projInstalled;\n\n // Report the scope/path that actually matched, so a project-only install\n // isn't 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 Antigravity config at ${projectConfig}`\n : `found Antigravity config under ${userDir}`\n : `no Antigravity config at ${userDir} or ${projectConfig}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n if (ctx.scope === \"project\") return join(ctx.projectDir, \".agents\");\n // User scope: parent dir of the resolved user mcp_config.json.\n return dirname(this.resolveUserConfigPath());\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".agents\", \"mcp_config.json\")\n : this.resolveUserConfigPath();\n }\n\n /**\n * Hooks live in a SEPARATE hooks.json in the customization dir — NOT the\n * mcp_config.json. Project → <proj>/.agents/hooks.json; user →\n * <resolvedUserConfigDir>/hooks.json (the dir holding the resolved user MCP\n * config). Path is medium-confidence and surfaced by the doctor.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"hooks.json\");\n }\n\n /**\n * The user-scope MCP config candidates, in preference order. Overridable by\n * forks (e.g. the Antigravity CLI) that resolve a different user-scope root\n * while reusing resolveUserConfigPath's prefer-existing-else-candidate[0] logic.\n */\n protected userConfigCandidates(): ReadonlyArray<readonly string[]> {\n return USER_CONFIG_CANDIDATES;\n }\n\n /**\n * Pick the user-scope mcp_config.json: prefer a candidate that already exists,\n * else default to candidate[0] (the CONFIRMED canonical ~/.gemini/antigravity path).\n */\n protected resolveUserConfigPath(): string {\n const home = homedir();\n const candidates = this.userConfigCandidates();\n for (const parts of candidates) {\n const p = join(home, ...parts);\n if (existsSync(p)) return p;\n }\n const fallback = candidates[0];\n if (fallback === undefined) {\n // Defensive: a non-empty candidate list is an invariant, but never throw.\n return join(home, \".gemini\", \"antigravity\", \"mcp_config.json\");\n }\n return join(home, ...fallback);\n }\n\n /**\n * Resolve the Workflows (slash-command) dir, prefer-existing-else-canonical.\n * project → prefer existing <proj>/.agent/workflows or <proj>/.agents/workflows;\n * default .agent/workflows (launch-era singular `.agent`).\n * user → ~/.gemini/antigravity/global_workflows.\n */\n protected resolveWorkflowsDir(ctx: InstallContext): string {\n if (ctx.scope === \"project\") {\n const singular = join(ctx.projectDir, \".agent\", \"workflows\");\n const plural = join(ctx.projectDir, \".agents\", \"workflows\");\n if (existsSync(singular)) return singular;\n if (existsSync(plural)) return plural;\n return singular;\n }\n return join(homedir(), \".gemini\", \"antigravity\", \"global_workflows\");\n }\n\n /**\n * Resolve the Agent Skills dir, prefer-existing-else-canonical.\n * project → <proj>/.agents/skills (plural — matches mcp/skills convention).\n * user → prefer existing ~/.gemini/antigravity-cli/skills, else\n * ~/.gemini/skills. NEVER ~/.gemini/antigravity/skills\n * (reportedly broken), so it is not a candidate.\n */\n protected resolveSkillsDir(ctx: InstallContext): string {\n if (ctx.scope === \"project\") {\n return join(ctx.projectDir, \".agents\", \"skills\");\n }\n const home = homedir();\n const cliSkills = join(home, \".gemini\", \"antigravity-cli\", \"skills\");\n const sharedSkills = join(home, \".gemini\", \"skills\");\n if (existsSync(cliSkills)) return cliSkills;\n if (existsSync(sharedSkills)) return sharedSkills;\n return cliSkills;\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[this.id]?.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 ${this.id}`\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n // Shallow-merge any per-platform server override into the base ServerDef.\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const serverPath = this.getServerConfigPath(ctx);\n const entry = this.renderServerEntry(ctx, server);\n\n return [\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /** Render a normalized ServerDef into Antigravity's native mcpServers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): AntigravityStdioServer | AntigravityHttpServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route the real command through\n // `<homeBin> serve --connector <id> --scope <scope> -- <command> <args...>`.\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n // Antigravity (Gemini family) has no documented native interpolation token,\n // so resolve every ${env:VAR} to a literal at install time.\n const entry: AntigravityStdioServer = { command: resolveEnvRefsDeep(command) };\n if (args.length > 0) entry.args = resolveEnvRefsDeep(args);\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // sse / http (and any other remote transport) — Antigravity registers a URL\n // under the `serverUrl` key (NOT `url`).\n const entry: AntigravityHttpServer = { serverUrl: resolveEnvRefsDeep(server.url ?? \"\") };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Antigravity documents no native interpolation\n * token, so resolve `${env:VAR}` references to literals at install time.\n */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Hook install / uninstall ─────────────────────────────────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.hooks === false) {\n return [{ platform: this.id, action: \"skip\", detail: `hooks disabled for ${this.id}` }];\n }\n // The opt-in host-native usage hook (4a) needs no connector handler, so it may\n // be installed even when the connector declares no normalized hook events.\n const hostNative = isHostNativeUsageEnabled(connector.telemetry);\n if (connector.hookEvents.length === 0 && !hostNative) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no hooks\" }];\n }\n\n const hooksPath = this.getHookConfigPath(ctx);\n // OVERWRITE GUARD: never clobber a present-but-unparseable hooks.json.\n if (this.isPresentButUnparseable(hooksPath)) {\n return [\n {\n platform: this.id,\n action: \"warn\",\n path: hooksPath,\n detail: `existing ${hooksPath} is not parseable; left untouched (back it up / fix it, then re-run)`,\n },\n ];\n }\n\n const file = this.readJson<AntigravityHooksFile>(hooksPath) ?? {};\n const __skip = this.malformedHookRootSkip(hooksPath, (file as Record<string, unknown>).hooks);\n if (__skip) return [__skip];\n const hooks = (file.hooks ??= {});\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const event of connector.hookEvents) {\n if (!SUPPORTED_EVENTS.has(event)) {\n // No Antigravity equivalent for this normalized event — report.\n changes.push({\n platform: this.id,\n action: \"warn\",\n path: hooksPath,\n detail: `${event} has no Antigravity hook equivalent — skipped`,\n });\n continue;\n }\n\n const command = buildHomeBinHookCommand(ctx.homeBinPath, this.id, event, connector.id);\n const matcher = connector.hooks[event]?.matcher ?? \"\";\n const entry: AntigravityHookEntry = {\n matcher,\n hooks: [{ type: \"command\", command }],\n };\n\n const bucket = (hooks[event] ??= []);\n const existingIdx = bucket.findIndex((e) => this.entryHasOurCommand(e, ctx));\n\n if (existingIdx >= 0) {\n if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: `hooks.${event} already registered`,\n });\n continue;\n }\n bucket[existingIdx] = entry;\n changes.push({\n platform: this.id,\n action: \"update\",\n path: hooksPath,\n detail: `hooks.${event}`,\n });\n } else {\n bucket.push(entry);\n changes.push({\n platform: this.id,\n action: \"create\",\n path: hooksPath,\n detail: `hooks.${event}`,\n });\n }\n mutated = true;\n }\n\n // OPT-IN host-native usage hook (4a): register the AfterModel `usage-event`\n // sink when enabled. Records a DISTINCT `model_turn` row (whole-conversation),\n // never summed with the per-MCP `serve`-proxy rows.\n if (hostNative) {\n if (this.installUsageHook(hooks, ctx, hooksPath, changes)) mutated = true;\n }\n\n if (mutated) this.writeJson(hooksPath, file, ctx.dryRun);\n return changes;\n }\n\n /**\n * Register the opt-in AfterModel host-native usage hook (4a) into `hooks`.\n * Idempotent (byte-identical → skip, drift → update); returns true on mutation.\n * The command is the hidden `usage-event` entrypoint (NOT a connector hook), so\n * it carries an empty matcher. Reads `this.id` so the CLI fork installs its own\n * `usage-event antigravity-cli …` variant.\n */\n private installUsageHook(\n hooks: Record<string, AntigravityHookEntry[]>,\n ctx: InstallContext,\n hooksPath: string,\n changes: ChangeRecord[],\n ): boolean {\n const command = buildUsageEventCommand(ctx.homeBinPath, this.id, ctx.connector.id);\n const entry: AntigravityHookEntry = {\n matcher: \"\",\n hooks: [{ type: \"command\", command }],\n };\n const bucket = (hooks[USAGE_HOOK_EVENT] ??= []);\n const existingIdx = bucket.findIndex((e) =>\n (e.hooks ?? []).some((h) => isUsageEventCommand(h.command, ctx.homeBinPath, ctx.connector.id)),\n );\n\n if (existingIdx >= 0) {\n if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: `hooks.${USAGE_HOOK_EVENT} (host-native usage) already registered`,\n });\n return false;\n }\n bucket[existingIdx] = entry;\n changes.push({\n platform: this.id,\n action: \"update\",\n path: hooksPath,\n detail: `hooks.${USAGE_HOOK_EVENT} (host-native usage)`,\n });\n } else {\n bucket.push(entry);\n changes.push({\n platform: this.id,\n action: \"create\",\n path: hooksPath,\n detail: `hooks.${USAGE_HOOK_EVENT} (host-native usage)`,\n });\n }\n return true;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const hooksPath = this.getHookConfigPath(ctx);\n const file = this.readJson<AntigravityHooksFile>(hooksPath);\n const hooks = file?.hooks;\n if (!file || !hooks) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: \"no hooks section present\",\n },\n ];\n }\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const event of Object.keys(hooks)) {\n const bucket = hooks[event];\n if (!Array.isArray(bucket)) continue;\n\n // Strip our hook command from each entry; drop entries left empty so we\n // never remove another connector's (or the user's own) hook commands.\n const next: AntigravityHookEntry[] = [];\n let removed = 0;\n for (const e of bucket) {\n const innerBefore = e.hooks?.length ?? 0;\n const inner = (e.hooks ?? []).filter((h) => !this.isOurCommand(h.command, ctx));\n removed += innerBefore - inner.length;\n if (inner.length > 0) next.push({ matcher: e.matcher ?? \"\", hooks: inner });\n }\n\n if (removed > 0) {\n if (next.length > 0) hooks[event] = next;\n else delete hooks[event];\n changes.push({\n platform: this.id,\n action: \"remove\",\n path: hooksPath,\n detail: `hooks.${event} (${removed})`,\n });\n mutated = true;\n }\n }\n\n if (mutated) this.writeJson(hooksPath, file, ctx.dryRun);\n if (changes.length === 0) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: \"no matching hook entries\",\n });\n }\n return changes;\n }\n\n private entryHasOurCommand(entry: AntigravityHookEntry, ctx: InstallContext): boolean {\n return (entry.hooks ?? []).some((h) => this.isOurCommand(h.command, ctx));\n }\n\n /**\n * True when a hook command is ONE OF OURS for this connector — the universal\n * `hook` dispatcher OR the opt-in `usage-event` sink. Both are anchored on the\n * connector id (see isHomeBinHookCommand) so a shared-prefix id can't collide,\n * and so uninstall reverses the AfterModel usage hook too.\n */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return (\n isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id) ||\n isUsageEventCommand(command, ctx.homeBinPath, ctx.connector.id)\n );\n }\n\n // ── Content surfaces: commands (Workflows) / skills ───────────────────────\n // CONTENT-ONLY: pure native-file writers under the probed workflows / skills\n // dirs. No runtime dispatch, no home-bin pointer, no telemetry wrap. Each\n // method is idempotent (byte-identical → skip) via BaseAdapter.writeContentFile\n // and reversible via removeContentFile. Honors platforms[\"antigravity\"]\n // per-surface false to skip. Commands are markdown Workflows (NOT TOML, unlike\n // gemini-cli); skills are the uniform Claude-compatible SKILL.md. Subagents are\n // unsupported (plugin-bundle-only) and inherit the BaseAdapter skip/warn.\n\n /** Native Workflow file path: <workflowsDir>/<name>.md. */\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.resolveWorkflowsDir(ctx), `${name}.md`);\n }\n /** Native skill dir: <skillsDir>/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.resolveSkillsDir(ctx), name);\n }\n\n // ── Commands (Workflows) ──────────────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: `commands disabled for ${this.id}` }];\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(this.commandPath(ctx, cmd.name), this.renderCommand(cmd), ctx.dryRun),\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 /**\n * Render a command to an Antigravity Workflow: a plain markdown `.md` whose\n * body is the command prompt, optionally preceded by a leading description\n * line. No frontmatter / TOML (unlike gemini-cli).\n */\n private renderCommand(cmd: CommandDef): string {\n const body = cmd.prompt.endsWith(\"\\n\") ? cmd.prompt : `${cmd.prompt}\\n`;\n if (cmd.description !== undefined && cmd.description !== \"\") {\n return `${cmd.description}\\n\\n${body}`;\n }\n return body;\n }\n\n // ── Skills ────────────────────────────────────────────────────────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: `skills disabled for ${this.id}` }];\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 // Bundle any resource files beside SKILL.md (relative path → contents).\n // Defense-in-depth: skip+warn on any key that escapes the skill dir.\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n }\n return changes;\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n // Remove only the files we wrote (SKILL.md + declared resources), then the\n // skill dir itself when we own its full contents.\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue; // never delete outside the skill dir\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n // Only remove the skill dir when WE own its full contents — never rm -rf a\n // dir that still holds user-added / sibling-tool / shared files.\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const mcpPath = this.getServerConfigPath(ctx);\n const hooksPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = ctx.connector.hookEvents;\n const workflowsDir = this.resolveWorkflowsDir(ctx);\n const skillsDir = this.resolveSkillsDir(ctx);\n\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: mcp_config.json present`,\n check: () =>\n existsSync(mcpPath)\n ? { status: \"OK\", detail: `${mcpPath} (path probed; verify for your Antigravity version)` }\n : { status: \"FAIL\", detail: `not found: ${mcpPath} (path probed; verify for your Antigravity version)` },\n },\n {\n name: `${this.name}: server entry 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> }>(mcpPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };\n }\n return connectorId in bucket\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${connectorId} present` }\n : {\n status: \"FAIL\",\n detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${mcpPath}`,\n };\n },\n },\n {\n name: `${this.name}: hooks.json hook command registered`,\n check: () => {\n if (hookEvents.length === 0) {\n return { status: \"OK\", detail: \"no hooks declared\" };\n }\n const file = this.readJson<AntigravityHooksFile>(hooksPath);\n if (!file) {\n return {\n status: \"FAIL\",\n detail: `not found: ${hooksPath} (path probed; verify for your Antigravity version)`,\n };\n }\n const hooks = file.hooks ?? {};\n const registered = Object.values(hooks).some((entries) =>\n (entries ?? []).some((e) =>\n (e.hooks ?? []).some((h) =>\n isHomeBinHookCommand(h.command, homeBin, connectorId),\n ),\n ),\n );\n return registered\n ? { status: \"OK\", detail: `hook command present in ${hooksPath}` }\n : { status: \"FAIL\", detail: `no hook for ${connectorId} in ${hooksPath}` };\n },\n },\n ];\n\n // Content-surface checks: only assert presence of the files this connector\n // declares (skip silently for surfaces it never asked for). The probed dirs\n // are noted so doctor output makes the medium-confidence path explicit.\n for (const cmd of ctx.connector.commands) {\n const p = join(workflowsDir, `${cmd.name}.md`);\n checks.push({\n name: `${this.name}: workflow ${cmd.name} present`,\n check: () =>\n existsSync(p)\n ? { status: \"OK\", detail: `${p} (workflows dir probed; verify for your version)` }\n : { status: \"FAIL\", detail: `not found: ${p} (workflows dir probed; verify for your version)` },\n });\n }\n for (const skill of ctx.connector.skills) {\n const p = join(skillsDir, skill.name, \"SKILL.md\");\n checks.push({\n name: `${this.name}: skill ${skill.name} present`,\n check: () =>\n existsSync(p)\n ? { status: \"OK\", detail: `${p} (skills dir probed; verify for your version)` }\n : { status: \"FAIL\", detail: `not found: ${p} (skills dir probed; verify for your version)` },\n });\n }\n return checks;\n }\n\n // ── Runtime: parse Antigravity stdin JSON → normalized event ──────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as AntigravityWireInput;\n const connectorId = typeof input.connector === \"string\" ? input.connector : \"\";\n const sessionId = typeof input.sessionId === \"string\" ? input.sessionId : \"\";\n const projectDir = typeof input.cwd === \"string\" ? input.cwd : undefined;\n\n const base = {\n hostPlatform: this.id,\n connectorId,\n sessionId,\n raw,\n ...(projectDir !== undefined ? { projectDir } : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.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 ...(input.toolOutput !== undefined ? { toolOutput: input.toolOutput } : {}),\n ...(input.isError === true ? { isError: true } : {}),\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 \"Stop\": {\n const ev: StopEvent = {\n ...base,\n ...(typeof input.stopHookActive === \"boolean\"\n ? { stopHookActive: input.stopHookActive }\n : {}),\n };\n return ev;\n }\n default: {\n // Antigravity only delivers the four SUPPORTED_EVENTS. If the runtime\n // dispatches anything else, surface it loudly rather than mis-parse.\n throw new Error(`unsupported ${this.id} hook event: ${String(event)}`);\n }\n }\n }\n\n // ── Runtime: normalized response → Antigravity native hook reply ──────────\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n const decision = response.decision ?? \"allow\";\n\n // deny → Antigravity blocks the action via a top-level `decision:\"deny\"` +\n // reason (the Decide category).\n if (decision === \"deny\") {\n return this.stdout({\n decision: \"deny\",\n reason: response.reason ?? \"Blocked by hook\",\n });\n }\n\n // ask → Antigravity has no native \"ask\"; degrade to deny to stay fail-safe.\n if (decision === \"ask\") {\n return this.stdout({\n decision: \"deny\",\n reason: response.reason ?? \"Action requires user confirmation (security policy)\",\n });\n }\n\n // modify → Transform category. camelCase: rewrite PreToolUse input via\n // updatedInput; rewrite PostToolUse output via updatedOutput.\n if (decision === \"modify\") {\n if (event === \"PreToolUse\" && response.updatedInput) {\n return this.stdout({ updatedInput: response.updatedInput });\n }\n if (event === \"PostToolUse\" && response.updatedOutput !== undefined) {\n return this.stdout({ updatedOutput: response.updatedOutput });\n }\n // Nothing to apply; fall through to allow.\n }\n\n // context → inject soft guidance via additionalContext (the SessionStart\n // context-injection path).\n if (decision === \"context\" && response.additionalContext) {\n return this.stdout({ additionalContext: response.additionalContext });\n }\n\n // allow / void / unsupported-degradation → pass through with exit 0.\n return { exitCode: 0 };\n }\n\n private stdout(payload: unknown): HookReply {\n return { exitCode: 0, stdout: JSON.stringify(payload) };\n }\n}\n\nexport const adapter = new AntigravityAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ensureDir
4
- } from "./chunk-TRQKHP7D.js";
4
+ } from "./chunk-QY42WGBX.js";
5
5
 
6
6
  // src/core/config-patch-ledger.ts
7
7
  import { createHash, randomBytes } from "crypto";
@@ -174,4 +174,4 @@ export {
174
174
  removeLedgerOwner,
175
175
  dropLedgerEntry
176
176
  };
177
- //# sourceMappingURL=chunk-FAHIMJRU.js.map
177
+ //# sourceMappingURL=chunk-L7ESV37V.js.map
@@ -4,7 +4,7 @@ import {
4
4
  inferModelFamily,
5
5
  openStore,
6
6
  worstConfidence
7
- } from "./chunk-BCHWFTV4.js";
7
+ } from "./chunk-F4DSMVZ7.js";
8
8
 
9
9
  // src/telemetry/surface-footprint.ts
10
10
  function countParts(parts, family, tok) {
@@ -590,4 +590,4 @@ export {
590
590
  formatHostNativeTurns,
591
591
  formatSurfaceLeaderboard
592
592
  };
593
- //# sourceMappingURL=chunk-JNM3TPLX.js.map
593
+ //# sourceMappingURL=chunk-LETB5HCK.js.map
@@ -1,10 +1,14 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ codexConfigHome,
4
+ xdgConfigHome
5
+ } from "./chunk-UM5S7DKK.js";
2
6
  import {
3
7
  connectorDir,
4
8
  connectorsDir,
5
9
  dataRoot,
6
10
  ensureDir
7
- } from "./chunk-TRQKHP7D.js";
11
+ } from "./chunk-QY42WGBX.js";
8
12
 
9
13
  // src/core/marketplace-state.ts
10
14
  import { createHash } from "crypto";
@@ -136,14 +140,6 @@ function claudeKnownMarketplacePath(name) {
136
140
  const sourcePath = e.source?.path;
137
141
  return typeof sourcePath === "string" ? sourcePath : null;
138
142
  }
139
- function codexConfigHome() {
140
- const env = process.env.CODEX_HOME;
141
- if (env && env.trim() !== "") {
142
- if (env.startsWith("~")) return join(homedir(), env.replace(/^~[/\\]?/, ""));
143
- return resolve(env);
144
- }
145
- return join(homedir(), ".codex");
146
- }
147
143
  function codexPluginKey(connectorId) {
148
144
  return `${connectorId}@${MARKETPLACE_NAME}`;
149
145
  }
@@ -265,10 +261,6 @@ function qwenExtensionInstalled(connectorId) {
265
261
  join(qwenConfigDir(), "extensions", connectorId, "qwen-extension.json")
266
262
  );
267
263
  }
268
- function xdgConfigHome() {
269
- const xdg = process.env.XDG_CONFIG_HOME;
270
- return xdg && xdg.trim() !== "" ? resolve(xdg) : join(homedir(), ".config");
271
- }
272
264
  function opencodeConfigDir() {
273
265
  return join(xdgConfigHome(), "opencode");
274
266
  }
@@ -428,8 +420,13 @@ function marketplaceEvidence(connectorId, platform) {
428
420
  case "kilo-cli":
429
421
  return npmPluginInstalled(platform, connectorId) ? `${connectorId} listed in ${platform}'s config plugin array` : null;
430
422
  case "codex": {
431
- const codexHome = process.env.CODEX_HOME && process.env.CODEX_HOME.trim() !== "" ? resolve(process.env.CODEX_HOME) : join(homedir(), ".codex");
432
- const dir = join(codexHome, "plugins", "cache", MARKETPLACE_NAME, connectorId);
423
+ const dir = join(
424
+ codexConfigHome(),
425
+ "plugins",
426
+ "cache",
427
+ MARKETPLACE_NAME,
428
+ connectorId
429
+ );
433
430
  return existsSync(dir) ? `codex plugin cache ${dir} exists` : null;
434
431
  }
435
432
  default:
@@ -508,4 +505,4 @@ export {
508
505
  marketplaceEvidence,
509
506
  hashDirectory
510
507
  };
511
- //# sourceMappingURL=chunk-G5CQHVQG.js.map
508
+ //# sourceMappingURL=chunk-M3H7PQWT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/marketplace-state.ts"],"sourcesContent":["/**\n * core/marketplace-state — pure read/write helpers for MARKETPLACE-method\n * install state. A LEAF module (fs + paths only, no adapters, no spawning) so\n * the installer, the marketplace orchestration, doctor, and status can all\n * import it without cycles.\n *\n * Two kinds of state live here:\n *\n * 1. The per-connector state record `connectorDir(id)/marketplace-installs.json`\n * — one entry per platform a connector was marketplace-installed on\n * ({ format, bundleDir, marketplace, scope, version, contentHash,\n * installedAt }). It drives `uninstall --method auto`, upgrade staleness\n * warnings, doctor, and the double-install guard.\n *\n * 2. Read-only fs EVIDENCE probes of the hosts' own plugin state (e.g.\n * Claude Code's `$CLAUDE_CONFIG_DIR/plugins/installed_plugins.json`).\n * These catch installs the user performed manually from `package`'s\n * printed instructions, which the state record alone would miss. Probes\n * read undocumented host internals, so every reader degrades to null/false\n * on absence or parse failure — the guard convention is \"refuse only on\n * positive evidence\" (docs: design risk 4).\n */\n\nimport { createHash } from \"node:crypto\";\nimport {\n existsSync,\n readdirSync,\n readFileSync,\n realpathSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport TOML from \"@iarna/toml\";\n\nimport type { InstallScope, PlatformId } from \"./types.js\";\nimport type { PackageFormat } from \"./package.js\";\nimport { connectorDir, connectorsDir, dataRoot, ensureDir } from \"./paths.js\";\nimport { codexConfigHome, xdgConfigHome } from \"./host-paths.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// State record: connectorDir(id)/marketplace-installs.json\n// ─────────────────────────────────────────────────────────────────────────\n\n/** The catalog name every staged local marketplace is registered under. */\nexport const MARKETPLACE_NAME = \"agent-connector\";\n\n/** One marketplace install of one connector on one platform. */\nexport interface MarketplaceInstallRecord {\n /** Bundle format that was staged + installed (e.g. \"claude-plugin\"). */\n format: PackageFormat;\n /** Absolute path of the staged plugin dir the host references/copied. */\n bundleDir: string;\n /** Marketplace/catalog name the install is keyed under ({@link MARKETPLACE_NAME}). */\n marketplace: string;\n /** Install scope (v1: always \"user\"). */\n scope: InstallScope;\n /** connector.version at install time (staleness warnings key off this). */\n version: string;\n /** sha256 over the staged plugin dir at install time (drift detection). */\n contentHash: string;\n /** ISO timestamp of the recorded install. */\n installedAt: string;\n}\n\n/** platform → record map persisted per connector. */\nexport type MarketplaceInstalls = Partial<\n Record<PlatformId, MarketplaceInstallRecord>\n>;\n\n/** Path of the per-connector marketplace state record. */\nexport function marketplaceInstallsPath(connectorId: string): string {\n return join(connectorDir(connectorId), \"marketplace-installs.json\");\n}\n\n/** Read the state record ({} on absence/parse failure — never throws). */\nexport function readMarketplaceInstalls(connectorId: string): MarketplaceInstalls {\n try {\n const raw = readFileSync(marketplaceInstallsPath(connectorId), \"utf8\");\n const parsed = JSON.parse(raw) as unknown;\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as MarketplaceInstalls;\n }\n } catch {\n /* absent / unreadable → empty */\n }\n return {};\n}\n\n/** Write the state record; an empty map DELETES the file (uninstall leaves no husk). */\nexport function writeMarketplaceInstalls(\n connectorId: string,\n installs: MarketplaceInstalls,\n): void {\n const path = marketplaceInstallsPath(connectorId);\n if (Object.keys(installs).length === 0) {\n rmSync(path, { force: true });\n return;\n }\n ensureDir(dirname(path));\n writeFileSync(path, `${JSON.stringify(installs, null, 2)}\\n`, \"utf8\");\n}\n\n/** True when THIS connector has any recorded marketplace install. */\nexport function connectorHasMarketplaceRecords(connectorId: string): boolean {\n return Object.keys(readMarketplaceInstalls(connectorId)).length > 0;\n}\n\n/**\n * True when ANY registered connector (optionally excluding one) still records a\n * marketplace install. Guards home-bin removal on purge: an installed plugin's\n * hooks exec the home-bin OUTSIDE any adapter-managed config, so removing the\n * launcher while a marketplace install survives would silently kill its hooks.\n */\nexport function anyMarketplaceRecordsRemain(excludeConnectorId?: string): boolean {\n const dir = connectorsDir();\n if (!existsSync(dir)) return false;\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return false;\n }\n return entries.some(\n (id) => id !== excludeConnectorId && connectorHasMarketplaceRecords(id),\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Staging roots — bundles staged by-reference must survive cwd changes and\n// `rm -rf dist-plugin`, so they live under the data-root, one shared root per\n// host family, holding every marketplace-installed connector's bundle plus ONE\n// regenerated catalog named \"agent-connector\" listing them all.\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Root for every marketplace staging tree: <dataRoot>/marketplace. */\nexport function marketplaceRoot(): string {\n return join(dataRoot(), \"marketplace\");\n}\n\n/** Shared Claude-family staging root: <dataRoot>/marketplace/claude. */\nexport function claudeStagingRoot(): string {\n return join(marketplaceRoot(), \"claude\");\n}\n\n/** Shared Codex-family staging root: <dataRoot>/marketplace/codex. */\nexport function codexStagingRoot(): string {\n return join(marketplaceRoot(), \"codex\");\n}\n\n/** Shared agy (Antigravity) staging root: <dataRoot>/marketplace/agy. */\nexport function agyStagingRoot(): string {\n return join(marketplaceRoot(), \"agy\");\n}\n\n/** Shared Gemini-CLI staging root: <dataRoot>/marketplace/gemini. */\nexport function geminiStagingRoot(): string {\n return join(marketplaceRoot(), \"gemini\");\n}\n\n/** Shared Qwen-Code staging root: <dataRoot>/marketplace/qwen. */\nexport function qwenStagingRoot(): string {\n return join(marketplaceRoot(), \"qwen\");\n}\n\n/** Shared droid (Factory) staging root: <dataRoot>/marketplace/droid. */\nexport function droidStagingRoot(): string {\n return join(marketplaceRoot(), \"droid\");\n}\n\n/**\n * Shared npm-local staging root: <dataRoot>/marketplace/npm. Every npm-plugin\n * host (opencode / kilo / kilo-cli) stages here; the host config's `plugin`\n * array references the bundle by `file://<this>/<id>`, so it MUST live under the\n * stable data-root (it survives cwd changes and `rm -rf dist-plugin`).\n */\nexport function npmStagingRoot(): string {\n return join(marketplaceRoot(), \"npm\");\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Claude Code host-state readers ($CLAUDE_CONFIG_DIR || ~/.claude)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Claude Code's config dir, honoring the CLAUDE_CONFIG_DIR override. */\nexport function claudeConfigDir(): string {\n const override = process.env.CLAUDE_CONFIG_DIR;\n if (override && override.trim() !== \"\") return resolve(override);\n return join(homedir(), \".claude\");\n}\n\n/** The installed_plugins.json key our marketplace install creates for `id`. */\nexport function claudePluginKey(connectorId: string): string {\n return `${connectorId}@${MARKETPLACE_NAME}`;\n}\n\nfunction readJsonFile(path: string): Record<string, unknown> | null {\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n /* absent / unreadable → null */\n }\n return null;\n}\n\n/** The `plugins` map from Claude's installed_plugins.json (null when unreadable). */\nexport function readClaudeInstalledPlugins(): Record<string, unknown> | null {\n const file = join(claudeConfigDir(), \"plugins\", \"installed_plugins.json\");\n const parsed = readJsonFile(file);\n const plugins = parsed?.plugins;\n if (plugins && typeof plugins === \"object\" && !Array.isArray(plugins)) {\n return plugins as Record<string, unknown>;\n }\n return null;\n}\n\n/** True when Claude's own state lists `<id>@agent-connector` as installed. */\nexport function claudePluginInstalled(connectorId: string): boolean {\n const plugins = readClaudeInstalledPlugins();\n if (!plugins) return false;\n const entry = plugins[claudePluginKey(connectorId)];\n return Array.isArray(entry) ? entry.length > 0 : entry != null;\n}\n\n/** True when ANY `*@agent-connector` plugin remains in Claude's state. */\nexport function anyClaudeAgentConnectorPlugins(): boolean {\n const plugins = readClaudeInstalledPlugins();\n if (!plugins) return false;\n return Object.entries(plugins).some(\n ([key, entry]) =>\n key.endsWith(`@${MARKETPLACE_NAME}`) &&\n (Array.isArray(entry) ? entry.length > 0 : entry != null),\n );\n}\n\n/**\n * The directory Claude's known_marketplaces.json records for `name`, or null\n * when not registered / unreadable. Used both as a presence probe and as the\n * NAME-COLLISION check: a registration pointing somewhere other than our\n * staging root belongs to the user and must never be touched.\n */\nexport function claudeKnownMarketplacePath(name: string): string | null {\n const file = join(claudeConfigDir(), \"plugins\", \"known_marketplaces.json\");\n const parsed = readJsonFile(file);\n const entry = parsed?.[name];\n if (!entry || typeof entry !== \"object\") return null;\n const e = entry as { installLocation?: unknown; source?: { path?: unknown } };\n if (typeof e.installLocation === \"string\") return e.installLocation;\n const sourcePath = e.source?.path;\n return typeof sourcePath === \"string\" ? sourcePath : null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Codex host-state readers ($CODEX_HOME || ~/.codex → config.toml)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** The config.toml key our marketplace install creates for `id` (== claude's). */\nexport function codexPluginKey(connectorId: string): string {\n return `${connectorId}@${MARKETPLACE_NAME}`;\n}\n\n/** Parse <CODEX_HOME>/config.toml ({} on absence/parse failure — never throws). */\nfunction readCodexConfig(): Record<string, unknown> {\n const file = join(codexConfigHome(), \"config.toml\");\n try {\n return TOML.parse(readFileSync(file, \"utf8\")) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/**\n * True when Codex's config.toml carries the `[plugins.\"<id>@agent-connector\"]`\n * table. The DEFINITIVE install probe — empty `plugins/cache/...` dirs linger\n * after uninstall, so the cache dir must NOT be used (docs: codex quirk).\n */\nexport function codexPluginInstalled(connectorId: string): boolean {\n const cfg = readCodexConfig();\n const plugins = cfg[\"plugins\"];\n if (!plugins || typeof plugins !== \"object\" || Array.isArray(plugins)) return false;\n return codexPluginKey(connectorId) in (plugins as Record<string, unknown>);\n}\n\n/** True when ANY `*@agent-connector` plugin remains in Codex's config.toml. */\nexport function anyCodexAgentConnectorPlugins(): boolean {\n const cfg = readCodexConfig();\n const plugins = cfg[\"plugins\"];\n if (!plugins || typeof plugins !== \"object\" || Array.isArray(plugins)) return false;\n return Object.keys(plugins as Record<string, unknown>).some((k) =>\n k.endsWith(`@${MARKETPLACE_NAME}`),\n );\n}\n\n/**\n * The directory config.toml records as `[marketplaces.agent-connector].source`,\n * or null when not registered / unreadable. Both a presence probe and the\n * NAME-COLLISION check: a registration pointing somewhere other than our\n * staging root belongs to the user and must never be touched.\n */\nexport function codexMarketplaceSource(name: string): string | null {\n const cfg = readCodexConfig();\n const marketplaces = cfg[\"marketplaces\"];\n if (!marketplaces || typeof marketplaces !== \"object\" || Array.isArray(marketplaces)) {\n return null;\n }\n const entry = (marketplaces as Record<string, unknown>)[name];\n if (!entry || typeof entry !== \"object\") return null;\n const source = (entry as { source?: unknown }).source;\n return typeof source === \"string\" ? source : null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// droid (Factory) host-state readers (~/.factory/settings.json, JSON, NO env)\n//\n// DOCS-ONLY: no droid binary is present on this box. The settings.json key\n// shapes below (`enabledPlugins[\"<id>@agent-connector\"] === true` +\n// `extraKnownMarketplaces[\"agent-connector\"].source`) follow the documented\n// factory plugin model — confirm the exact JSON shapes live when a droid binary\n// is available. Both readers read defensively (refuse only on positive evidence).\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Factory's settings file: ~/.factory/settings.json (NO dedicated env). */\nexport function factorySettingsPath(): string {\n return join(homedir(), \".factory\", \"settings.json\");\n}\n\n/** The settings.json key our marketplace install creates for `id` (== codex's). */\nexport function droidPluginKey(connectorId: string): string {\n return `${connectorId}@${MARKETPLACE_NAME}`;\n}\n\n/** The `enabledPlugins` map from droid's settings.json (null when unreadable). */\nfunction readDroidEnabledPlugins(): Record<string, unknown> | null {\n const parsed = readJsonFile(factorySettingsPath());\n const plugins = parsed?.enabledPlugins;\n if (plugins && typeof plugins === \"object\" && !Array.isArray(plugins)) {\n return plugins as Record<string, unknown>;\n }\n return null;\n}\n\n/**\n * True when droid's settings.json carries\n * `enabledPlugins[\"<id>@agent-connector\"] === true`. DOCS-only: the strict\n * `=== true` value shape is unverified live (a future droid may store an object).\n */\nexport function droidPluginInstalled(connectorId: string): boolean {\n const plugins = readDroidEnabledPlugins();\n if (!plugins) return false;\n return plugins[droidPluginKey(connectorId)] === true;\n}\n\n/** True when ANY `*@agent-connector` plugin remains enabled in droid's settings. */\nexport function anyDroidAgentConnectorPlugins(): boolean {\n const plugins = readDroidEnabledPlugins();\n if (!plugins) return false;\n return Object.entries(plugins).some(\n ([key, value]) => key.endsWith(`@${MARKETPLACE_NAME}`) && value === true,\n );\n}\n\n/**\n * The directory droid's settings.json records as\n * `extraKnownMarketplaces[\"<name>\"].source`, or null when not registered /\n * unreadable. Both a presence probe and the NAME-COLLISION check (a registration\n * pointing somewhere other than our staging root belongs to the user). DOCS-only:\n * the local-path `source` field shape is undocumented, so this reads defensively\n * — accepts either a bare string source or an object carrying a `path`/`source`\n * string, and NORMALIZES to a single string for the samePath compare.\n */\nexport function droidMarketplaceSource(name: string): string | null {\n const parsed = readJsonFile(factorySettingsPath());\n const known = parsed?.extraKnownMarketplaces;\n if (!known || typeof known !== \"object\" || Array.isArray(known)) return null;\n const entry = (known as Record<string, unknown>)[name];\n if (entry == null) return null;\n if (typeof entry === \"string\") return entry;\n if (typeof entry === \"object\" && !Array.isArray(entry)) {\n const e = entry as { source?: unknown; path?: unknown };\n if (typeof e.source === \"string\") return e.source;\n if (typeof e.path === \"string\") return e.path;\n }\n return null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// agy (Antigravity) host-state readers (~/.gemini/config/plugins, NO env)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** agy's config dir: ~/.gemini/config (NO dedicated env — HOME isolation). */\nexport function agyConfigDir(): string {\n return join(homedir(), \".gemini\", \"config\");\n}\n\n/** agy's plugins dir: ~/.gemini/config/plugins. */\nexport function agyPluginsDir(): string {\n return join(agyConfigDir(), \"plugins\");\n}\n\n/**\n * Candidate `import_manifest.json` locations. agy 1.0.7 records the manifest at\n * `<config>/plugins/import_manifest.json` on POSIX but at\n * `<config>/import_manifest.json` on Windows (live-confirmed on the my-window\n * box) — both are probed, then the copied plugin dir is the final fallback.\n */\nexport function agyImportManifestPaths(): string[] {\n return [\n join(agyConfigDir(), \"import_manifest.json\"), // win32 location\n join(agyPluginsDir(), \"import_manifest.json\"), // posix location\n ];\n}\n\n/** @deprecated single-location accessor — prefer {@link agyImportManifestPaths}. */\nexport function agyImportManifestPath(): string {\n return join(agyPluginsDir(), \"import_manifest.json\");\n}\n\n/**\n * True when `id` is installed per agy's import manifest (`imports[].name`),\n * checking BOTH the win32 and posix manifest locations, with a fallback probe of\n * the copied plugin dir's plugin.json. agy's uninstall removes the plugin dir\n * and clears the manifest entry (live-verified on Windows: install → dir +\n * manifest present, uninstall → both gone, re-install idempotent).\n */\nexport function agyPluginInstalled(connectorId: string): boolean {\n for (const manifest of agyImportManifestPaths()) {\n try {\n const parsed = JSON.parse(readFileSync(manifest, \"utf8\")) as {\n imports?: unknown;\n };\n const imports = parsed.imports;\n if (\n Array.isArray(imports) &&\n imports.some(\n (e) =>\n e != null &&\n typeof e === \"object\" &&\n (e as { name?: unknown }).name === connectorId,\n )\n ) {\n return true;\n }\n } catch {\n /* absent / unreadable manifest → try the next candidate */\n }\n }\n return existsSync(join(agyPluginsDir(), connectorId, \"plugin.json\"));\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Gemini CLI host-state readers (~/.gemini/extensions, NO env — HOME isolation)\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Gemini CLI's config dir: ~/.gemini (NO dedicated config-dir env — isolation is\n * via HOME, live-confirmed on gemini 0.36.0). DISTINCT from agy's ~/.gemini/config\n * tree: gemini extensions land under ~/.gemini/extensions/<id>/.\n */\nexport function geminiConfigDir(): string {\n return join(homedir(), \".gemini\");\n}\n\n/**\n * True when `id` is installed per Gemini's own extension store: the marker file\n * ~/.gemini/extensions/<id>/gemini-extension.json exists. Gemini exits 0 even on\n * a logical failure, so this fs probe — not the exit code — is the source of\n * truth (the driver re-probes after every spawn).\n */\nexport function geminiExtensionInstalled(connectorId: string): boolean {\n return existsSync(\n join(geminiConfigDir(), \"extensions\", connectorId, \"gemini-extension.json\"),\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Qwen Code host-state readers (~/.qwen/extensions, NO env — HOME isolation)\n//\n// DOCS-ONLY: no qwen binary is present on this box. qwen-code is a gemini-cli\n// fork, so the extension store SHAPE (~/.qwen/extensions/<id>/qwen-extension.json)\n// mirrors gemini's — confirm the marker filename live when a qwen binary lands.\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Qwen Code's config dir: ~/.qwen (NO dedicated config-dir env — isolation is\n * via HOME, like its gemini-cli parent). DOCS-only: confirm live when a qwen\n * binary is available. DISTINCT from ~/.gemini (the gemini-cli store).\n */\nexport function qwenConfigDir(): string {\n return join(homedir(), \".qwen\");\n}\n\n/**\n * True when `id` is installed per Qwen's own extension store: the marker file\n * ~/.qwen/extensions/<id>/qwen-extension.json exists. Mirrors gemini's fs probe\n * (qwen is a gemini fork); the driver re-probes after every spawn. DOCS-only:\n * the marker filename (`qwen-extension.json`) is unverified live.\n */\nexport function qwenExtensionInstalled(connectorId: string): boolean {\n return existsSync(\n join(qwenConfigDir(), \"extensions\", connectorId, \"qwen-extension.json\"),\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// npm-local host-state readers (opencode / kilo / kilo-cli — XDG_CONFIG_HOME)\n//\n// These hosts have NO uninstall verb; installs are recorded as `file://<dir>`\n// entries in a `plugin` array inside an opencode-style config file, which the\n// driver EDITS to remove. This module is a spawn/shared-free LEAF, so a tiny\n// posix-resolve path comparison is inlined here rather than importing\n// shared.ts's samePath (and samePath does not strip the `file://` scheme).\n// ─────────────────────────────────────────────────────────────────────────\n\n/** opencode's config dir: $XDG_CONFIG_HOME/opencode (or ~/.config/opencode). */\nexport function opencodeConfigDir(): string {\n return join(xdgConfigHome(), \"opencode\");\n}\n\n/** kilo / kilo-cli's config dir: $XDG_CONFIG_HOME/kilo (or ~/.config/kilo). */\nexport function kiloConfigDir(): string {\n return join(xdgConfigHome(), \"kilo\");\n}\n\n/**\n * Candidate config filenames per npm-local host, most-preferred first. opencode\n * accepts opencode.jsonc / opencode.json / config.json (JSONC — comments\n * tolerated); kilo / kilo-cli use opencode.json (plain JSON).\n */\nfunction npmConfigCandidates(platform: PlatformId): string[] {\n return platform === \"opencode\"\n ? [\"opencode.jsonc\", \"opencode.json\", \"config.json\"]\n : [\"opencode.json\"];\n}\n\n/** The config DIR for an npm-local host (opencode vs kilo/kilo-cli). */\nfunction npmConfigDir(platform: PlatformId): string {\n return platform === \"opencode\" ? opencodeConfigDir() : kiloConfigDir();\n}\n\n/**\n * The config FILE path for `platform`: the first existing candidate, else the\n * most-preferred candidate (the path a fresh install would write). Never throws.\n */\nexport function npmConfigFilePath(platform: PlatformId): string {\n const dir = npmConfigDir(platform);\n const candidates = npmConfigCandidates(platform);\n for (const name of candidates) {\n if (existsSync(join(dir, name))) return join(dir, name);\n }\n return join(dir, candidates[0]!);\n}\n\n/** Strip a single leading `file://` (and `file://localhost/`) scheme prefix. */\nexport function stripFileScheme(entry: string): string {\n let s = entry;\n if (s.startsWith(\"file://localhost/\")) s = s.slice(\"file://localhost\".length);\n else if (s.startsWith(\"file://\")) s = s.slice(\"file://\".length);\n return s;\n}\n\n/**\n * Strip `//` line and `/* *​/` block comments from JSONC, STRING-AWARE: a `//`\n * or `/*` inside a JSON string literal (e.g. the `file://` in a plugin entry) is\n * left intact. Scans char-by-char tracking string + escape state — a naive\n * regex would corrupt `\"file:///dir\"` by eating from the embedded `//`.\n */\nfunction stripJsoncComments(text: string): string {\n let out = \"\";\n let inString = false;\n let inLine = false;\n let inBlock = false;\n for (let i = 0; i < text.length; i++) {\n const c = text[i]!;\n const next = i + 1 < text.length ? text[i + 1]! : \"\";\n if (inLine) {\n if (c === \"\\n\") {\n inLine = false;\n out += c;\n }\n continue;\n }\n if (inBlock) {\n if (c === \"*\" && next === \"/\") {\n inBlock = false;\n i++;\n }\n continue;\n }\n if (inString) {\n out += c;\n if (c === \"\\\\\") {\n // Copy the escaped char verbatim (covers \\\" and \\\\).\n if (next !== \"\") {\n out += next;\n i++;\n }\n } else if (c === '\"') {\n inString = false;\n }\n continue;\n }\n if (c === '\"') {\n inString = true;\n out += c;\n continue;\n }\n if (c === \"/\" && next === \"/\") {\n inLine = true;\n i++;\n continue;\n }\n if (c === \"/\" && next === \"*\") {\n inBlock = true;\n i++;\n continue;\n }\n out += c;\n }\n return out;\n}\n\n/** Tolerant JSONC → object: strip // line and block comments, then JSON.parse. */\nfunction parseJsonc(text: string): Record<string, unknown> | null {\n // A parse failure degrades to null (the \"refuse only on positive evidence\"\n // convention) rather than throwing.\n try {\n const parsed = JSON.parse(stripJsoncComments(text)) as unknown;\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n /* unreadable / not JSONC → null */\n }\n return null;\n}\n\n/** Read + parse an npm-local host's config file ({}-shaped or null). Never throws. */\nexport function readNpmConfig(platform: PlatformId): Record<string, unknown> | null {\n const file = npmConfigFilePath(platform);\n try {\n return parseJsonc(readFileSync(file, \"utf8\"));\n } catch {\n return null;\n }\n}\n\n/**\n * Convert an npm `plugin`-array entry to a native absolute path. opencode/kilo\n * record a proper `file://` URL — on Windows that is `file:///C:/Users/…` (drive\n * letter + forward slashes), which a textual `file://`-strip leaves as the broken\n * `/C:/Users/…`. `fileURLToPath` does the correct cross-platform decode\n * (`file:///C:/x`→`C:\\x`, `file:///tmp/x`→`/tmp/x`). Bare-path entries (also\n * accepted by the hosts) and any malformed URL fall back to a textual strip.\n */\nfunction npmEntryToPath(entry: string): string {\n if (/^file:\\/\\//i.test(entry)) {\n try {\n return fileURLToPath(entry);\n } catch {\n /* malformed file URL (e.g. backslashes) → manual strip below */\n }\n }\n return stripFileScheme(entry);\n}\n\n/**\n * Path equality for the npm probe. Resolve symlinks with `realpathSync.native`\n * when the path exists (catches macOS `/var/folders`→`/private/var/folders` and\n * win32 8.3 short paths — the host records the realpath, we hold the symlink),\n * else lexical `resolve()`; case-fold on win32. Inlined here (leaf module)\n * rather than importing shared.ts's samePath, which pulls in the spawn layer.\n */\nfunction npmPathEquals(a: string, b: string): boolean {\n const norm = (p: string): string => {\n let s: string;\n try {\n s = realpathSync.native(p);\n } catch {\n s = resolve(p);\n }\n return process.platform === \"win32\" ? s.toLowerCase() : s;\n };\n return norm(a) === norm(b);\n}\n\n/**\n * The `plugin`-array ENTRY (the raw string, including any `file://`) whose value\n * — after stripping a leading `file://` — path-equals `id`'s staged bundle dir,\n * or null when no entry references it. Used both as the install probe and to\n * locate the exact entry the uninstall edit must drop.\n */\nexport function npmPluginArrayEntry(\n platform: PlatformId,\n connectorId: string,\n): string | null {\n const cfg = readNpmConfig(platform);\n if (!cfg) return null;\n const arr = cfg[\"plugin\"];\n if (!Array.isArray(arr)) return null;\n const target = join(npmStagingRoot(), connectorId);\n for (const raw of arr) {\n if (typeof raw !== \"string\") continue;\n if (npmPathEquals(npmEntryToPath(raw), target)) return raw;\n }\n return null;\n}\n\n/** True when `platform`'s config `plugin` array references `id`'s staged bundle. */\nexport function npmPluginInstalled(platform: PlatformId, connectorId: string): boolean {\n return npmPluginArrayEntry(platform, connectorId) != null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Cross-host marketplace-install EVIDENCE (the double-install guard's probe)\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Read-only evidence that `connectorId` is marketplace/plugin-installed on\n * `platform`: the state record first, then a cheap fs probe of the host's own\n * plugin state (catches manual installs from `package`'s printed instructions).\n * Returns a human-readable description of the evidence, or null when none.\n */\nexport function marketplaceEvidence(\n connectorId: string,\n platform: PlatformId,\n): string | null {\n if (readMarketplaceInstalls(connectorId)[platform]) {\n return \"recorded in marketplace-installs.json\";\n }\n switch (platform) {\n case \"claude-code\":\n if (claudePluginInstalled(connectorId)) {\n return `${claudePluginKey(connectorId)} listed in Claude's installed_plugins.json`;\n }\n return null;\n case \"gemini-cli\":\n return geminiExtensionInstalled(connectorId)\n ? `extension ${connectorId} listed in Gemini's extensions store`\n : null;\n case \"qwen-code\":\n return qwenExtensionInstalled(connectorId)\n ? `extension ${connectorId} listed in Qwen's extensions store`\n : null;\n case \"droid\":\n return droidPluginInstalled(connectorId)\n ? `${droidPluginKey(connectorId)} enabled in droid's settings.json`\n : null;\n case \"antigravity\":\n case \"antigravity-cli\": {\n const dir = join(homedir(), \".gemini\", \"config\", \"plugins\", connectorId);\n return existsSync(dir) ? `plugin dir ${dir} exists` : null;\n }\n case \"opencode\":\n case \"kilo\":\n case \"kilo-cli\":\n return npmPluginInstalled(platform, connectorId)\n ? `${connectorId} listed in ${platform}'s config plugin array`\n : null;\n case \"codex\": {\n const dir = join(\n codexConfigHome(),\n \"plugins\",\n \"cache\",\n MARKETPLACE_NAME,\n connectorId,\n );\n return existsSync(dir) ? `codex plugin cache ${dir} exists` : null;\n }\n default:\n return null;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Content hashing — staged-bundle drift detection\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Deterministic sha256 over every file under `dir` (sorted relative paths +\n * bytes). Empty string when the dir is missing/unreadable. Used to record the\n * staged bundle's content at install time and detect drift later (claude caches\n * a versioned COPY, so an edited connector goes silently stale without this).\n */\nexport function hashDirectory(dir: string): string {\n if (!existsSync(dir)) return \"\";\n const files: string[] = [];\n const walk = (d: string): void => {\n let entries: string[];\n try {\n entries = readdirSync(d);\n } catch {\n return;\n }\n for (const name of entries.sort()) {\n const full = join(d, name);\n let st;\n try {\n st = statSync(full);\n } catch {\n continue;\n }\n if (st.isDirectory()) walk(full);\n else if (st.isFile()) files.push(full);\n }\n };\n walk(dir);\n const hash = createHash(\"sha256\");\n for (const file of files.sort()) {\n hash.update(relative(dir, file).split(\"\\\\\").join(\"/\"));\n hash.update(\"\\0\");\n try {\n hash.update(readFileSync(file));\n } catch {\n /* unreadable file contributes only its path */\n }\n hash.update(\"\\0\");\n }\n return hash.digest(\"hex\");\n}\n"],"mappings":"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","names":[]}
@@ -73,6 +73,7 @@ function hostRoots(platformId) {
73
73
  out.push(join(homedir(), ".pi", "agent", "sessions"));
74
74
  break;
75
75
  case "kimi":
76
+ out.push(join(homedir(), ".kimi-code", "sessions"));
76
77
  out.push(join(homedir(), ".kimi", "sessions"));
77
78
  break;
78
79
  case "copilot-cli":
@@ -188,10 +189,11 @@ function listSubdirs(dir) {
188
189
 
189
190
  export {
190
191
  expandHome,
192
+ hostRoots,
191
193
  firstExistingRoot,
192
194
  isDir,
193
195
  isFile,
194
196
  walkFiles,
195
197
  listSubdirs
196
198
  };
197
- //# sourceMappingURL=chunk-JWNT5KW7.js.map
199
+ //# sourceMappingURL=chunk-O7SDRBVB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usage/paths.ts"],"sourcesContent":["/**\n * usage/paths — per-platform HOST storage-root resolution + small fs walkers.\n *\n * This is the read-only complement to core/paths.ts: where that module resolves\n * the FRAMEWORK data-root (~/.agent-connector), this one resolves each agent\n * CLI's OWN native storage roots (~/.qwen, ~/.claude, …) so the usage readers\n * can parse them. It NEVER writes; it only enumerates files.\n *\n * Ported from tokscale paths.rs (the tokscale cache dir) and from each reader's\n * storage-path spec (docs/research/usage-readers.json). Resolution order is\n * uniform across platforms:\n * 1. an explicit AGENT_CONNECTOR_<PLATFORM>_DIR env override (verbatim, when\n * non-empty — an empty string is treated as unset so we never resolve to \"\");\n * 2. the platform-specific default for the current OS.\n *\n * The \"tokscale cache dir\" (~/.config/tokscale, or AGENT_CONNECTOR_TOKSCALE_DIR)\n * is where synced readers (cursor/antigravity/antigravity-cli/trae/warp) look for\n * a local cache that a separate tokscale run may have produced — we read it if\n * present, but we never create or sync it. (Antigravity's own native store is\n * protobuf .pb with no public schema, so it too is synced-cache-or-skip.)\n */\n\nimport {\n existsSync,\n readdirSync,\n statSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join, resolve } from \"node:path\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Home / env helpers\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Expand a leading \"~\" (and \"~/\") to the user's home directory. */\nexport function expandHome(p: string): string {\n if (p === \"~\") return homedir();\n if (p.startsWith(\"~/\") || p.startsWith(\"~\\\\\")) {\n return join(homedir(), p.slice(2));\n }\n return p;\n}\n\n/**\n * Read an env override, treating empty/blank as unset (mirrors tokscale's\n * is_config_dir_overridden contract: an empty override must NOT resolve to \"\").\n * Relative paths are resolved against the process CWD; \"~\" is expanded.\n */\nfunction envOverride(name: string): string | undefined {\n const raw = process.env[name];\n if (raw == null || raw.trim() === \"\") return undefined;\n const expanded = expandHome(raw.trim());\n return isAbsolute(expanded) ? expanded : resolve(expanded);\n}\n\n/** $XDG_DATA_HOME (when set & non-empty) else ~/.local/share. */\nfunction xdgDataHome(): string {\n const xdg = process.env.XDG_DATA_HOME;\n if (xdg && xdg.trim() !== \"\") return resolve(expandHome(xdg.trim()));\n return join(homedir(), \".local\", \"share\");\n}\n\n/** $XDG_CONFIG_HOME (when set & non-empty) else ~/.config. */\nfunction xdgConfigHome(): string {\n const xdg = process.env.XDG_CONFIG_HOME;\n if (xdg && xdg.trim() !== \"\") return resolve(expandHome(xdg.trim()));\n return join(homedir(), \".config\");\n}\n\n/** Windows %LOCALAPPDATA% else ~/AppData/Local. */\nfunction localAppData(): string {\n const v = process.env.LOCALAPPDATA;\n if (v && v.trim() !== \"\") return resolve(v.trim());\n return join(homedir(), \"AppData\", \"Local\");\n}\n\nconst isMac = process.platform === \"darwin\";\nconst isWin = process.platform === \"win32\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// tokscale cache dir (for synced readers)\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Resolve the tokscale config dir (where synced caches live). Ported from\n * tokscale paths.rs get_config_dir():\n * 1. AGENT_CONNECTOR_TOKSCALE_DIR override (verbatim, non-empty);\n * 2. macOS: $HOME/.config/tokscale (NOT ~/Library/Application Support);\n * 3. Linux: $XDG_CONFIG_HOME/tokscale or ~/.config/tokscale;\n * 4. Windows: %APPDATA%/tokscale (config_dir equivalent) else ~/.config/tokscale.\n *\n * We use AGENT_CONNECTOR_TOKSCALE_DIR (not TOKSCALE_CONFIG_DIR) so the framework\n * never accidentally couples to a tokscale install's hermetic test env.\n */\nexport function tokscaleConfigDir(): string {\n const override = envOverride(\"AGENT_CONNECTOR_TOKSCALE_DIR\");\n if (override) return override;\n if (isMac) return join(homedir(), \".config\", \"tokscale\");\n if (isWin) {\n const appData = process.env.APPDATA;\n if (appData && appData.trim() !== \"\") return join(resolve(appData.trim()), \"tokscale\");\n return join(homedir(), \".config\", \"tokscale\");\n }\n return join(xdgConfigHome(), \"tokscale\");\n}\n\n/** The directory a synced platform's local cache lives under, e.g. `<tokscale>/cursor-cache`. */\nexport function tokscaleCacheDir(name: string): string {\n return join(tokscaleConfigDir(), name);\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Antigravity native store roots (DETECTION ONLY — not parsed for usage)\n//\n// CONFIRMED-BY-INSTALL (2026-06-03, docs/research/antigravity-paths-confirmed.md):\n// the native Antigravity store is `~/.gemini/antigravity/conversations/<uuid>.pb`\n// — PROTOBUF with no public schema — and `brain/<uuid>/` holds only media +\n// `*.metadata.json`. There are NO `transcript*.jsonl` files. The `agy` CLI shares\n// this SAME `~/.gemini/antigravity/` dir (no separate config/storage dir). So the\n// native dir is used only for platform DETECTION (in the adapters); the usage\n// readers do NOT parse it (protobuf, unreadable) — they are SYNCED readers that\n// read the tokscale synced-cache instead (see hostRoots → antigravity-cache).\n//\n// These helpers are retained for any detection caller and honor the standard\n// AGENT_CONNECTOR_<PLATFORM>_DIR override (prepended, preferred when set).\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * The native Antigravity store root for DETECTION: `~/.gemini/antigravity/`\n * (CONFIRMED). Its `conversations/<uuid>.pb` payloads are protobuf with no public\n * schema, so this dir is NOT parsed for usage — only its presence is a signal.\n *\n * Honors AGENT_CONNECTOR_ANTIGRAVITY_DIR (verbatim, when set) as the override.\n */\nexport function antigravityNativeRoots(): string[] {\n const out: string[] = [];\n const override = envOverride(\"AGENT_CONNECTOR_ANTIGRAVITY_DIR\");\n if (override) out.push(override);\n out.push(join(homedir(), \".gemini\", \"antigravity\"));\n return out;\n}\n\n/**\n * The native store root for the Antigravity CLI (`agy`) for DETECTION. CONFIRMED:\n * `agy` has NO separate dir — it SHARES the IDE's `~/.gemini/antigravity/` (also\n * protobuf, not parsed for usage).\n *\n * Honors AGENT_CONNECTOR_ANTIGRAVITY_CLI_DIR (verbatim, when set) as the override.\n */\nexport function antigravityCliNativeRoots(): string[] {\n const out: string[] = [];\n const override = envOverride(\"AGENT_CONNECTOR_ANTIGRAVITY_CLI_DIR\");\n if (override) out.push(override);\n out.push(join(homedir(), \".gemini\", \"antigravity\"));\n return out;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Per-platform host roots\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Candidate host storage roots for a platform, most-preferred first. Readers\n * iterate the returned list and use the first that exists (each variant is the\n * OS-correct default; the env override, when present, is prepended).\n *\n * Only the platforms this subsystem currently ships a reader for are listed in\n * detail; the table is structured so a new platform is one new case. Returning\n * `[]` (no candidate root) makes a reader fail-open to zero records.\n */\nexport function hostRoots(platformId: string): string[] {\n const out: string[] = [];\n const override = envOverride(`AGENT_CONNECTOR_${platformId.toUpperCase().replace(/-/g, \"_\")}_DIR`);\n if (override) out.push(override);\n\n switch (platformId) {\n case \"qwen-code\":\n // ~/.qwen/projects/*/chats/*.jsonl\n out.push(join(homedir(), \".qwen\", \"projects\"));\n break;\n case \"claude-code\":\n out.push(join(homedir(), \".claude\", \"projects\"));\n break;\n case \"codex\":\n out.push(join(homedir(), \".codex\", \"sessions\"));\n break;\n case \"gemini-cli\":\n out.push(join(homedir(), \".gemini\", \"tmp\"));\n break;\n case \"pi\":\n out.push(join(homedir(), \".pi\", \"agent\", \"sessions\"));\n break;\n case \"kimi\":\n // TWO Moonshot products share the \"kimi\" id with DIFFERENT session trees:\n // - Kimi Code (newer, @moonshot-ai/kimi-code): ~/.kimi-code/sessions/...\n // (deeper tree, see readers/kimi.ts) — the product our adapter targets.\n // - Kimi CLI (older): ~/.kimi/sessions/<GROUP>/<UUID>/wire.jsonl\n // Both are scanned (Kimi Code preferred first). $KIMI_CODE_HOME relocates\n // the Kimi Code home and is honored ahead of these in readers/kimi.ts.\n out.push(join(homedir(), \".kimi-code\", \"sessions\"));\n out.push(join(homedir(), \".kimi\", \"sessions\"));\n break;\n case \"copilot-cli\":\n out.push(join(xdgDataHome(), \"Copilot\", \"telemetry\"));\n out.push(join(xdgConfigHome(), \"copilot\", \"telemetry\"));\n break;\n case \"amp\":\n out.push(join(xdgDataHome(), \"amp\", \"threads\"));\n break;\n case \"droid\":\n out.push(join(homedir(), \".factory\", \"sessions\"));\n break;\n case \"mux\":\n out.push(join(homedir(), \".mux\", \"sessions\"));\n break;\n case \"kiro\":\n out.push(join(homedir(), \".kiro\", \"sessions\", \"cli\"));\n break;\n case \"opencode\":\n out.push(join(xdgDataHome(), \"opencode\", \"opencode.db\"));\n break;\n case \"goose\":\n if (isMac) out.push(join(homedir(), \"Library\", \"Application Support\", \"goose\", \"sessions\", \"sessions.db\"));\n out.push(join(xdgDataHome(), \"goose\", \"sessions\", \"sessions.db\"));\n out.push(join(xdgDataHome(), \"Block\", \"goose\", \"sessions\", \"sessions.db\"));\n break;\n case \"hermes\":\n out.push(join(homedir(), \".hermes\", \"state.db\"));\n break;\n case \"kilo-cli\":\n out.push(join(xdgDataHome(), \"kilo\", \"kilo.db\"));\n break;\n case \"crush\":\n out.push(join(homedir(), \".cache\", \"crush\", \"crush.db\"));\n break;\n case \"zed\":\n if (isMac) out.push(join(homedir(), \"Library\", \"Application Support\", \"Zed\", \"threads\", \"threads.db\"));\n else if (isWin) out.push(join(localAppData(), \"Zed\", \"threads\", \"threads.db\"));\n else out.push(join(xdgDataHome(), \"zed\", \"threads\", \"threads.db\"));\n break;\n // Synced platforms: local cache under the tokscale config dir.\n case \"cursor\":\n out.push(tokscaleCacheDir(\"cursor-cache\"));\n break;\n case \"antigravity\":\n // SYNCED: the native store is protobuf (.pb, no public schema) and NOT\n // parseable, so the reader reads only the tokscale synced-cache mirror if a\n // separate tokscale run produced one (else [] → \"requires sync\"). The\n // native `~/.gemini/antigravity/` dir is used only for detection.\n out.push(tokscaleCacheDir(\"antigravity-cache\"));\n break;\n case \"antigravity-cli\":\n // SYNCED: `agy` shares the IDE's protobuf (.pb) store (no schema), so the\n // reader reads only the tokscale synced-cache mirror if present (else [] →\n // \"requires sync\"). Shares the IDE's antigravity-cache name (same data).\n out.push(tokscaleCacheDir(\"antigravity-cache\"));\n break;\n case \"trae\":\n out.push(tokscaleCacheDir(\"trae-cache\"));\n break;\n case \"warp\":\n out.push(tokscaleCacheDir(\"warp-cache\"));\n break;\n default:\n break;\n }\n return out;\n}\n\n/** First existing host root for a platform, or undefined when none is present. */\nexport function firstExistingRoot(platformId: string): string | undefined {\n for (const root of hostRoots(platformId)) {\n if (existsSync(root)) return root;\n }\n return undefined;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Directory / glob walkers (tolerant — never throw)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Is the path an existing directory? Tolerant (false on any stat error). */\nexport function isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** Is the path an existing regular file? Tolerant (false on any stat error). */\nexport function isFile(p: string): boolean {\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Recursively list every file under `root` whose name matches `predicate`.\n * Tolerant: an unreadable directory is skipped, never thrown. Returns absolute\n * paths in directory-walk order. A non-existent root yields [].\n */\nexport function walkFiles(\n root: string,\n predicate: (name: string, absPath: string) => boolean,\n maxDepth = 12,\n): string[] {\n const out: string[] = [];\n if (!isDir(root)) return out;\n\n const stack: Array<{ dir: string; depth: number }> = [{ dir: root, depth: 0 }];\n while (stack.length > 0) {\n const { dir, depth } = stack.pop() as { dir: string; depth: number };\n let entries: import(\"node:fs\").Dirent[];\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n continue; // unreadable dir → skip\n }\n for (const entry of entries) {\n const abs = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (depth < maxDepth) stack.push({ dir: abs, depth: depth + 1 });\n } else if (entry.isFile() && predicate(entry.name, abs)) {\n out.push(abs);\n }\n }\n }\n return out;\n}\n\n/**\n * List immediate subdirectory names of `dir` (not recursive). Tolerant: returns\n * [] for a missing/unreadable directory.\n */\nexport function listSubdirs(dir: string): string[] {\n if (!isDir(dir)) return [];\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => join(dir, e.name));\n } catch {\n return [];\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  defineConnector
4
- } from "./chunk-MDNX7HTN.js";
4
+ } from "./chunk-YEJCNOET.js";
5
5
  import {
6
6
  connectorDir,
7
7
  connectorsDir,
8
8
  ensureDir
9
- } from "./chunk-TRQKHP7D.js";
9
+ } from "./chunk-QY42WGBX.js";
10
10
 
11
11
  // src/core/load-connector.ts
12
12
  import { existsSync, readdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "fs";
@@ -45,7 +45,11 @@ async function loadConnectorFromPath(path) {
45
45
  const connector2 = defineConnector(config);
46
46
  return { connector: connector2, modulePath };
47
47
  }
48
- const mod = await import(pathToFileURL(modulePath).href);
48
+ const moduleUrl = pathToFileURL(modulePath).href;
49
+ const mod = await import(
50
+ /* @vite-ignore */
51
+ moduleUrl
52
+ );
49
53
  const exported = mod.default;
50
54
  if (exported == null) {
51
55
  throw new Error(
@@ -174,4 +178,4 @@ export {
174
178
  connectorFromMeta,
175
179
  listRegisteredConnectors
176
180
  };
177
- //# sourceMappingURL=chunk-YQLQJZ7S.js.map
181
+ //# sourceMappingURL=chunk-OLI5SD6I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/load-connector.ts"],"sourcesContent":["/**\n * core/load-connector — discover, load, and register connector definitions.\n *\n * Responsibilities:\n * 1. Locate the developer's `agent-connector.config.{mjs,js,json}` by walking\n * upward from a start directory (the project root convention).\n * 2. Load a config from a path into a LIVE ResolvedConnector (with handlers).\n * 3. Register a connector by persisting SERIALIZABLE metadata (no functions)\n * to `connectorDir(id)/connector.json`, pointing at the source module so\n * live handlers can be re-imported at runtime from a stable record.\n *\n * Why split live vs. serialized? Hook handlers are functions and cannot survive\n * JSON. The registry stores only what JSON can hold plus an absolute\n * `modulePath`; the runtime re-imports that module to recover the live handlers.\n */\n\nimport { existsSync, readdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport type {\n CommandDef,\n HookEventName,\n InstallScope,\n MemoryDef,\n PlatformId,\n PlatformOverride,\n ResolvedConnector,\n ServerDef,\n SkillDef,\n SubagentDef,\n} from \"./types.js\";\nimport { defineConnector } from \"./define-connector.js\";\nimport { connectorDir, connectorsDir, ensureDir } from \"./paths.js\";\n\n/** Candidate config filenames, in resolution-precedence order. */\nconst CONFIG_FILENAMES = [\n \"agent-connector.config.mjs\",\n \"agent-connector.config.js\",\n \"agent-connector.config.json\",\n] as const;\n\n/**\n * The serializable subset of a connector persisted to `connector.json`.\n * Hook handler functions are intentionally absent — only the absolute\n * `modulePath` is stored so the live ResolvedConnector can be re-imported.\n */\nexport interface RegisteredMeta {\n id: string;\n displayName: string;\n version: string;\n /** Absolute path to the source module that produced this connector. */\n modulePath: string;\n telemetry: ResolvedConnector[\"telemetry\"];\n /** Canonical event names the connector handles (handlers themselves stripped). */\n hookEvents: HookEventName[];\n hasServer: boolean;\n server: ServerDef | null;\n /**\n * Content surfaces (commands/skills/subagents). These are JSON-serializable\n * (no functions) so they persist cleanly and let uninstall locate the files\n * to remove even when the source module is gone.\n */\n commands: CommandDef[];\n skills: SkillDef[];\n subagents: SubagentDef[];\n /**\n * Memory entries (managed-block content surface). Plain content, persisted\n * whole so uninstall normally has the full entry list even when the source\n * module is gone (the marker prefix-scan is the fallback beyond that).\n */\n memory: MemoryDef[];\n targets: ResolvedConnector[\"targets\"];\n /** Per-platform overrides with any hook handler functions stripped. */\n platforms: Partial<Record<PlatformId, PlatformOverride>>;\n /**\n * The install scope this connector was registered under, persisted so the\n * runtime entrypoints (hook/statusline/action) can recover it cheaply (sync)\n * and stamp it onto the HostCtx/event — scope is an install-time property the\n * runtime otherwise has no access to. OPTIONAL: absent for an ad-hoc register\n * that passed no scope, or a record written before this field existed.\n * This is the install's RUN-WIDE DEFAULT scope; it can differ from the\n * effective per-host scope when a `platforms[host].scope` override is set (the\n * record is keyed by connector id only and holds no per-host scope map).\n */\n scope?: InstallScope;\n}\n\n/**\n * Search `startDir` and each ancestor for a connector config file. Returns the\n * absolute path to the first match (filesystem-root-stopping), or null.\n */\nexport function findConnectorConfig(startDir: string): string | null {\n let dir = resolve(startDir);\n // Walk upward until `dirname(dir) === dir` (filesystem root).\n for (;;) {\n for (const name of CONFIG_FILENAMES) {\n const candidate = join(dir, name);\n if (existsSync(candidate)) return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\n/** True if a value already looks like a ResolvedConnector (vs. a raw config). */\nfunction isResolvedConnector(value: unknown): value is ResolvedConnector {\n return (\n typeof value === \"object\" &&\n value !== null &&\n Array.isArray((value as { hookEvents?: unknown }).hookEvents)\n );\n}\n\n/**\n * Load a connector from an absolute or relative path.\n * - `.json` → JSON.parse, then defineConnector().\n * - `.mjs` / `.js` → dynamic import (via pathToFileURL, Windows-safe),\n * take the default export. If it already looks like a\n * ResolvedConnector use it as-is; otherwise treat it as\n * a ConnectorConfig and run it through defineConnector().\n * Returns the live connector plus the absolute module path it came from.\n */\nexport async function loadConnectorFromPath(\n path: string,\n): Promise<{ connector: ResolvedConnector; modulePath: string }> {\n let modulePath = isAbsolute(path) ? path : resolve(path);\n // Canonicalize before building the file:// URL for dynamic import. On Windows a\n // short (8.3) temp path like C:\\Users\\RUNNER~1\\...\\x.mjs round-trips the \"~\" as\n // %7E and fails to load; realpathSync.native expands it to the real long path.\n // It also resolves symlinked temp roots (e.g. macOS /var -> /private/var).\n // If the file does not exist yet, fall through with the resolve()'d path so the\n // subsequent read/import throws the real not-found error.\n try {\n modulePath = realpathSync.native(modulePath);\n } catch {\n /* keep the resolve()'d path */\n }\n\n if (modulePath.endsWith(\".json\")) {\n const text = readFileSync(modulePath, \"utf8\");\n const config = JSON.parse(text) as unknown;\n const connector = defineConnector(config as Parameters<typeof defineConnector>[0]);\n return { connector, modulePath };\n }\n\n // .mjs / .js — dynamic ESM import. pathToFileURL keeps Windows paths valid.\n const moduleUrl = pathToFileURL(modulePath).href;\n const mod = (await import(/* @vite-ignore */ moduleUrl)) as {\n default?: unknown;\n };\n const exported = mod.default;\n if (exported == null) {\n throw new Error(\n `Connector module has no default export: ${modulePath}`,\n );\n }\n const connector = isResolvedConnector(exported)\n ? exported\n : defineConnector(exported as Parameters<typeof defineConnector>[0]);\n return { connector, modulePath };\n}\n\n/**\n * Strip any function-valued `hooks` from per-platform overrides so the result\n * is JSON-serializable. A boolean `hooks` override is preserved; an object\n * override is dropped (it can only carry handler functions, which are not\n * serializable). `nativeHooks` declarations are persisted HANDLER-LESS (event\n * name + matcher only) so meta-based inspection (doctor / health checks / the\n * hook CLI) can still see WHICH native events were declared — the live handlers\n * are re-imported from `modulePath` at runtime, exactly like normalized hooks.\n * Everything else on the override is kept verbatim — notably `configPatch`\n * declarations, which are pure JSON (key/value/reason/docsUrl, no functions)\n * and persist WHOLE so uninstall/doctor can reason about them even when the\n * source module is gone.\n */\nfunction serializablePlatforms(\n platforms: Partial<Record<PlatformId, PlatformOverride>>,\n): Partial<Record<PlatformId, PlatformOverride>> {\n const out: Partial<Record<PlatformId, PlatformOverride>> = {};\n for (const [id, override] of Object.entries(platforms) as [\n PlatformId,\n PlatformOverride | undefined,\n ][]) {\n if (!override) continue;\n const { hooks, nativeHooks, ...rest } = override;\n const clean: PlatformOverride = { ...rest };\n // Keep only a boolean hooks flag; object hooks carry handler functions.\n if (typeof hooks === \"boolean\") clean.hooks = hooks;\n if (nativeHooks && typeof nativeHooks === \"object\") {\n const stripped: Record<string, { matcher?: string }> = {};\n for (const [event, def] of Object.entries(nativeHooks)) {\n stripped[event] =\n typeof def?.matcher === \"string\" ? { matcher: def.matcher } : {};\n }\n // Cast: the persisted record deliberately omits the (non-serializable)\n // handler; consumers of meta-derived connectors never dispatch handlers.\n clean.nativeHooks = stripped as PlatformOverride[\"nativeHooks\"];\n }\n out[id] = clean;\n }\n return out;\n}\n\n/**\n * Persist a connector's serializable metadata to `connectorDir(id)/connector.json`.\n * Handlers are NOT serialized — they are re-imported from `modulePath` at runtime.\n * The optional `scope` (the install scope the caller deployed under) is persisted\n * so the runtime entrypoints can recover it and stamp it onto the HostCtx/event.\n * Returns the absolute path of the written record.\n */\nexport function registerConnector(\n connector: ResolvedConnector,\n modulePath: string,\n scope?: InstallScope,\n): string {\n const meta: RegisteredMeta = {\n id: connector.id,\n displayName: connector.displayName,\n version: connector.version,\n modulePath: resolve(modulePath),\n telemetry: connector.telemetry,\n hookEvents: connector.hookEvents,\n hasServer: !!connector.server,\n server: connector.server ?? null,\n commands: connector.commands,\n skills: connector.skills,\n subagents: connector.subagents,\n memory: connector.memory,\n targets: connector.targets,\n platforms: serializablePlatforms(connector.platforms),\n // Persist the install scope when the caller supplied one (the installer\n // passes its install scope). Omitted from the record when undefined so an\n // ad-hoc register stays minimal and round-trips as \"no scope known\".\n ...(scope !== undefined ? { scope } : {}),\n };\n\n const dir = connectorDir(connector.id);\n ensureDir(dir);\n const outPath = join(dir, \"connector.json\");\n writeFileSync(outPath, `${JSON.stringify(meta, null, 2)}\\n`, \"utf8\");\n return outPath;\n}\n\n/**\n * Deregister a connector by removing its DATA-dir record directory\n * (`connectorDir(id)`) recursively. This is the inverse of {@link registerConnector}:\n * registerConnector writes `connectorDir(id)/connector.json`, but per-target\n * uninstall only strips host-native registrations — it never removes this record,\n * leaving an orphan behind. Best-effort + guarded: returns the directory path and\n * whether it existed before removal.\n */\nexport function deregisterConnector(id: string): {\n removed: boolean;\n path: string;\n} {\n const dir = connectorDir(id);\n const existed = existsSync(dir);\n if (existed) rmSync(dir, { recursive: true, force: true });\n return { removed: existed, path: dir };\n}\n\n/**\n * Read the registered metadata record for `id`, or null if not registered or\n * the record is unreadable/corrupt.\n */\nexport function readRegisteredMeta(id: string): RegisteredMeta | null {\n const recordPath = join(connectorDir(id), \"connector.json\");\n if (!existsSync(recordPath)) return null;\n try {\n return JSON.parse(readFileSync(recordPath, \"utf8\")) as RegisteredMeta;\n } catch {\n return null;\n }\n}\n\n/**\n * Load the LIVE ResolvedConnector (with hook handlers) for a registered id by\n * re-importing its source module. Throws a clear error when the connector is\n * not registered or its source module no longer resolves to it.\n */\nexport async function loadRegisteredConnector(\n id: string,\n): Promise<ResolvedConnector> {\n const meta = readRegisteredMeta(id);\n if (!meta) {\n throw new Error(\n `Connector \"${id}\" is not registered (no record at ${join(connectorDir(id), \"connector.json\")}). ` +\n `Run an install/register step first.`,\n );\n }\n if (!meta.modulePath || !existsSync(meta.modulePath)) {\n throw new Error(\n `Connector \"${id}\" record points at a missing module: ${meta.modulePath}`,\n );\n }\n const { connector } = await loadConnectorFromPath(meta.modulePath);\n return connector;\n}\n\n/**\n * Build a handler-less ResolvedConnector from stored metadata. Suitable for\n * inspection/doctor where live hook handlers are not needed (and where the\n * source module may even be gone). `hooks` is empty; `hookEvents` is preserved.\n */\nexport function connectorFromMeta(meta: RegisteredMeta): ResolvedConnector {\n return {\n id: meta.id,\n displayName: meta.displayName,\n version: meta.version,\n ...(meta.server ? { server: meta.server } : {}),\n hooks: {},\n hookEvents: meta.hookEvents ?? [],\n telemetry: meta.telemetry,\n commands: meta.commands ?? [],\n skills: meta.skills ?? [],\n subagents: meta.subagents ?? [],\n memory: meta.memory ?? [],\n // Actions carry live `run` handlers, so they are NOT serialized into the\n // record (like the statusline render). A handler-less meta-derived connector\n // gets [] — inspection/uninstall never dispatch action handlers, and the\n // BaseAdapter action default already tolerates an empty list.\n actions: [],\n platforms: meta.platforms ?? {},\n targets: meta.targets,\n };\n}\n\n/**\n * List every registered connector as a handler-less ResolvedConnector (read\n * from `connectorsDir()`). Used by doctor to health-check what is actually\n * installed, rather than guessing from the local working directory.\n */\nexport function listRegisteredConnectors(): ResolvedConnector[] {\n const dir = connectorsDir();\n if (!existsSync(dir)) return [];\n const out: ResolvedConnector[] = [];\n for (const entry of readdirSync(dir)) {\n const meta = readRegisteredMeta(entry);\n if (meta) out.push(connectorFromMeta(meta));\n }\n return out;\n}\n"],"mappings":"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","names":["connector"]}