@ken-jo/agent-connector 0.4.95 → 0.4.98

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 (385) hide show
  1. package/LICENSE +202 -202
  2. package/NOTICE +6 -6
  3. package/README.md +605 -599
  4. package/dist/{action-Q7GGO4PA.js → action-5JM23CFJ.js} +16 -16
  5. package/dist/action-5JM23CFJ.js.map +1 -0
  6. package/dist/{amazon-q-ETMAGY3D.js → amazon-q-LFZNGN27.js} +6 -6
  7. package/dist/amazon-q-LFZNGN27.js.map +1 -0
  8. package/dist/{amp-BQZOL5GR.js → amp-CEWOSWQO.js} +4 -4
  9. package/dist/amp-CEWOSWQO.js.map +1 -0
  10. package/dist/{amp-67BZONGF.js → amp-S22XTPEQ.js} +7 -7
  11. package/dist/amp-S22XTPEQ.js.map +1 -0
  12. package/dist/{antigravity-EA4L225L.js → antigravity-LHFEFNMC.js} +5 -5
  13. package/dist/antigravity-LHFEFNMC.js.map +1 -0
  14. package/dist/antigravity-PZXYAO3X.js +18 -0
  15. package/dist/{antigravity-cli-B2HXZFYQ.js → antigravity-cli-MOKFSWOU.js} +5 -5
  16. package/dist/antigravity-cli-MOKFSWOU.js.map +1 -0
  17. package/dist/{antigravity-cli-OM6SC3PE.js → antigravity-cli-PN474FXM.js} +9 -9
  18. package/dist/antigravity-cli-PN474FXM.js.map +1 -0
  19. package/dist/audit-2H7E3Z4N.js +311 -0
  20. package/dist/audit-2H7E3Z4N.js.map +1 -0
  21. package/dist/{chunk-KHO5WNTP.js → chunk-4GH2KA7V.js} +1 -1
  22. package/dist/chunk-4GH2KA7V.js.map +1 -0
  23. package/dist/{chunk-7F5KHLEP.js → chunk-6XWORQM6.js} +4 -4
  24. package/dist/chunk-6XWORQM6.js.map +1 -0
  25. package/dist/{chunk-2Y2MZRLP.js → chunk-7C2IPIIB.js} +3 -3
  26. package/dist/chunk-7C2IPIIB.js.map +1 -0
  27. package/dist/{chunk-NLE2J5P4.js → chunk-7HHW23AC.js} +29 -29
  28. package/dist/chunk-7HHW23AC.js.map +1 -0
  29. package/dist/{chunk-XD7MY6HB.js → chunk-7PSNXUFK.js} +1 -1
  30. package/dist/chunk-7PSNXUFK.js.map +1 -0
  31. package/dist/{chunk-YPAXJ7EW.js → chunk-7VSZXOXJ.js} +13 -13
  32. package/dist/chunk-7VSZXOXJ.js.map +1 -0
  33. package/dist/{chunk-ISEJWBFF.js → chunk-B6PKHS5I.js} +2 -2
  34. package/dist/chunk-B6PKHS5I.js.map +1 -0
  35. package/dist/{chunk-UM5S7DKK.js → chunk-C747DYNT.js} +1 -1
  36. package/dist/chunk-C747DYNT.js.map +1 -0
  37. package/dist/{chunk-PW42ZXCB.js → chunk-DOPFBUCX.js} +3 -3
  38. package/dist/chunk-DOPFBUCX.js.map +1 -0
  39. package/dist/{chunk-I5UXHIDT.js → chunk-DWZ5IWF4.js} +8 -8
  40. package/dist/chunk-DWZ5IWF4.js.map +1 -0
  41. package/dist/{chunk-6WZODR3Z.js → chunk-FJ6F5U3W.js} +5 -5
  42. package/dist/chunk-FJ6F5U3W.js.map +1 -0
  43. package/dist/{chunk-H33M77DD.js → chunk-HATCOSQT.js} +22 -19
  44. package/dist/chunk-HATCOSQT.js.map +1 -0
  45. package/dist/{chunk-UMQ6NBQR.js → chunk-ILWHLGIC.js} +2 -2
  46. package/dist/chunk-ILWHLGIC.js.map +1 -0
  47. package/dist/{chunk-IVAWP6HH.js → chunk-IOJDZJ72.js} +2 -2
  48. package/dist/chunk-IOJDZJ72.js.map +1 -0
  49. package/dist/{chunk-NBYKLUF6.js → chunk-KFPSJRHR.js} +2 -2
  50. package/dist/chunk-KFPSJRHR.js.map +1 -0
  51. package/dist/{chunk-O7SDRBVB.js → chunk-KM2YXO6V.js} +1 -1
  52. package/dist/chunk-KM2YXO6V.js.map +1 -0
  53. package/dist/{chunk-3NH2ARIS.js → chunk-KTBAB556.js} +6 -6
  54. package/dist/chunk-KTBAB556.js.map +1 -0
  55. package/dist/{chunk-5IOTP7LQ.js → chunk-KWC5DQ5Z.js} +7 -5
  56. package/dist/chunk-KWC5DQ5Z.js.map +1 -0
  57. package/dist/{chunk-JKKU2WKG.js → chunk-LD5HAN6O.js} +4 -4
  58. package/dist/chunk-LD5HAN6O.js.map +1 -0
  59. package/dist/{chunk-OP4KBXUO.js → chunk-LFWYYWLV.js} +1 -1
  60. package/dist/chunk-LFWYYWLV.js.map +1 -0
  61. package/dist/{chunk-APZDTY76.js → chunk-LZL2YITN.js} +7 -7
  62. package/dist/chunk-LZL2YITN.js.map +1 -0
  63. package/dist/{chunk-H53QZQJI.js → chunk-PSGTHJQU.js} +1 -1
  64. package/dist/chunk-PSGTHJQU.js.map +1 -0
  65. package/dist/{chunk-FBJQGRET.js → chunk-Q4ISQHUQ.js} +1 -1
  66. package/dist/chunk-Q4ISQHUQ.js.map +1 -0
  67. package/dist/{chunk-6TF7MHG5.js → chunk-Q7PR2WGT.js} +2 -2
  68. package/dist/chunk-Q7PR2WGT.js.map +1 -0
  69. package/dist/{chunk-GZGLCCEE.js → chunk-QYOUQCC6.js} +1 -1
  70. package/dist/chunk-QYOUQCC6.js.map +1 -0
  71. package/dist/{chunk-Z2MRSS2I.js → chunk-RNVIK5YJ.js} +2 -2
  72. package/dist/chunk-RNVIK5YJ.js.map +1 -0
  73. package/dist/{chunk-XC5SJ35F.js → chunk-RPWD5H6Y.js} +5 -5
  74. package/dist/chunk-RPWD5H6Y.js.map +1 -0
  75. package/dist/{chunk-PAPMUAR5.js → chunk-S25MVWBP.js} +12 -12
  76. package/dist/chunk-S25MVWBP.js.map +1 -0
  77. package/dist/{chunk-FJCUKXGX.js → chunk-THI4PI4H.js} +2 -2
  78. package/dist/chunk-THI4PI4H.js.map +1 -0
  79. package/dist/{chunk-D4ELPBB5.js → chunk-TOSNS2BY.js} +43 -43
  80. package/dist/chunk-TOSNS2BY.js.map +1 -0
  81. package/dist/{chunk-MGTDQLJJ.js → chunk-UNU2KPYJ.js} +11 -9
  82. package/dist/chunk-UNU2KPYJ.js.map +1 -0
  83. package/dist/{chunk-MQPNU2CY.js → chunk-UZZTWWGG.js} +1 -1
  84. package/dist/chunk-UZZTWWGG.js.map +1 -0
  85. package/dist/{chunk-4NHXLXSD.js → chunk-W7AGWAMH.js} +2 -2
  86. package/dist/chunk-W7AGWAMH.js.map +1 -0
  87. package/dist/{chunk-OPXAP3AC.js → chunk-XN7S44U4.js} +1 -1
  88. package/dist/chunk-XN7S44U4.js.map +1 -0
  89. package/dist/{chunk-BEFVJ2OE.js → chunk-XXLCMSD3.js} +1 -1
  90. package/dist/chunk-XXLCMSD3.js.map +1 -0
  91. package/dist/{chunk-YT43MUSJ.js → chunk-XZWMJLIT.js} +1 -1
  92. package/dist/chunk-XZWMJLIT.js.map +1 -0
  93. package/dist/{chunk-RK6VBLXP.js → chunk-ZSOS2KOR.js} +1 -1
  94. package/dist/chunk-ZSOS2KOR.js.map +1 -0
  95. package/dist/{claude-code-NMRKTAP7.js → claude-code-FS42PXZO.js} +4 -4
  96. package/dist/claude-code-FS42PXZO.js.map +1 -0
  97. package/dist/{claude-code-GRWO6XBZ.js → claude-code-TA53454O.js} +13 -13
  98. package/dist/claude-code-TA53454O.js.map +1 -0
  99. package/dist/cli/sdk.js +9 -8
  100. package/dist/cli/sdk.js.map +1 -1
  101. package/dist/cli.js +1 -1
  102. package/dist/cli.js.map +1 -1
  103. package/dist/{cline-25KW25IN.js → cline-GZFN32BM.js} +6 -6
  104. package/dist/cline-GZFN32BM.js.map +1 -0
  105. package/dist/{codebuddy-ZNYQACMF.js → codebuddy-IYS3TQZ3.js} +7 -7
  106. package/dist/codebuddy-IYS3TQZ3.js.map +1 -0
  107. package/dist/{codebuff-ETYT5UBL.js → codebuff-6KWBW6CT.js} +4 -4
  108. package/dist/codebuff-6KWBW6CT.js.map +1 -0
  109. package/dist/{codebuff-VR6JUDIY.js → codebuff-D3MIKJHC.js} +6 -6
  110. package/dist/codebuff-D3MIKJHC.js.map +1 -0
  111. package/dist/{codex-YAORPCOD.js → codex-DKBAAUCO.js} +4 -4
  112. package/dist/codex-DKBAAUCO.js.map +1 -0
  113. package/dist/{codex-CPNKTXG3.js → codex-ZKLP5IXZ.js} +9 -9
  114. package/dist/codex-ZKLP5IXZ.js.map +1 -0
  115. package/dist/{continue-WU2IB5KS.js → continue-I34FNSTJ.js} +8 -8
  116. package/dist/continue-I34FNSTJ.js.map +1 -0
  117. package/dist/{copilot-cli-MZTAWMPW.js → copilot-cli-CLBJACQ5.js} +4 -4
  118. package/dist/copilot-cli-CLBJACQ5.js.map +1 -0
  119. package/dist/{copilot-cli-PAP377OM.js → copilot-cli-NWPM5GE6.js} +7 -7
  120. package/dist/copilot-cli-NWPM5GE6.js.map +1 -0
  121. package/dist/{crush-QBXLNN7T.js → crush-A5C5USRL.js} +4 -4
  122. package/dist/crush-A5C5USRL.js.map +1 -0
  123. package/dist/{crush-3AVQA4YU.js → crush-MDGPZSZU.js} +7 -7
  124. package/dist/crush-MDGPZSZU.js.map +1 -0
  125. package/dist/{cursor-DIW43TRZ.js → cursor-D5SWDVSW.js} +3 -3
  126. package/dist/cursor-D5SWDVSW.js.map +1 -0
  127. package/dist/cursor-JRVK56QA.js +22 -0
  128. package/dist/{define-connector-DTWb46UB.d.ts → define-connector-B7tLHVnx.d.ts} +1 -1
  129. package/dist/{detect-6V4LC3MA.js → detect-FKJC36P4.js} +4 -4
  130. package/dist/detect-FKJC36P4.js.map +1 -0
  131. package/dist/{devin-QMEM3OFA.js → devin-TZMRC57O.js} +7 -7
  132. package/dist/devin-TZMRC57O.js.map +1 -0
  133. package/dist/{doctor-2YDUVSAU.js → doctor-PGVYUQYG.js} +26 -26
  134. package/dist/doctor-PGVYUQYG.js.map +1 -0
  135. package/dist/{droid-U3ZBLQFO.js → droid-PFQ2PZSF.js} +4 -4
  136. package/dist/droid-PFQ2PZSF.js.map +1 -0
  137. package/dist/{droid-MOKV53J4.js → droid-SCFWDJR4.js} +7 -7
  138. package/dist/droid-SCFWDJR4.js.map +1 -0
  139. package/dist/{gemini-cli-47ZHCOZR.js → gemini-cli-MLDGOR2L.js} +8 -8
  140. package/dist/gemini-cli-MLDGOR2L.js.map +1 -0
  141. package/dist/{gemini-cli-NMVVBO3K.js → gemini-cli-Y6RJMU24.js} +4 -4
  142. package/dist/gemini-cli-Y6RJMU24.js.map +1 -0
  143. package/dist/{goose-4EI5MYTI.js → goose-5DBHDSJW.js} +9 -9
  144. package/dist/goose-5DBHDSJW.js.map +1 -0
  145. package/dist/{goose-64V46Y2W.js → goose-K2HKUTBK.js} +4 -4
  146. package/dist/goose-K2HKUTBK.js.map +1 -0
  147. package/dist/{grok-cli-QYQPDSVB.js → grok-cli-LX6Q6RUY.js} +7 -7
  148. package/dist/grok-cli-LX6Q6RUY.js.map +1 -0
  149. package/dist/{hermes-F75OSK3Y.js → hermes-LJB3SJKB.js} +7 -7
  150. package/dist/hermes-LJB3SJKB.js.map +1 -0
  151. package/dist/{hermes-F3EGTK6N.js → hermes-MF3NX4ZY.js} +4 -4
  152. package/dist/hermes-MF3NX4ZY.js.map +1 -0
  153. package/dist/{hook-OEVRDMXD.js → hook-PVGBQUQI.js} +16 -16
  154. package/dist/hook-PVGBQUQI.js.map +1 -0
  155. package/dist/index.d.ts +3 -3
  156. package/dist/index.js +5 -5
  157. package/dist/{install-5NMCUDG5.js → install-HPDIK7F6.js} +192 -28
  158. package/dist/install-HPDIK7F6.js.map +1 -0
  159. package/dist/{introspect-dNekqPDY.d.ts → introspect-DWCu0Krk.d.ts} +1 -1
  160. package/dist/{jetbrains-copilot-ZGIWI6YV.js → jetbrains-copilot-2DSVAJMJ.js} +6 -6
  161. package/dist/jetbrains-copilot-2DSVAJMJ.js.map +1 -0
  162. package/dist/{junie-DIFN2P22.js → junie-GUBDRADP.js} +6 -6
  163. package/dist/junie-GUBDRADP.js.map +1 -0
  164. package/dist/{kilo-EMZJBEBB.js → kilo-HRLWMENX.js} +8 -8
  165. package/dist/kilo-HRLWMENX.js.map +1 -0
  166. package/dist/{kilo-SW7BH6EG.js → kilo-SMHPOHJ5.js} +4 -4
  167. package/dist/kilo-SMHPOHJ5.js.map +1 -0
  168. package/dist/{kilo-cli-S3GXBPAE.js → kilo-cli-IQMFMYZF.js} +8 -8
  169. package/dist/kilo-cli-IQMFMYZF.js.map +1 -0
  170. package/dist/{kilo-cli-ZF272ZHN.js → kilo-cli-T2SRRRJS.js} +5 -5
  171. package/dist/kilo-cli-T2SRRRJS.js.map +1 -0
  172. package/dist/{kimi-IQJOIY6B.js → kimi-EPD46UJK.js} +7 -7
  173. package/dist/kimi-EPD46UJK.js.map +1 -0
  174. package/dist/{kimi-5FHEXGZD.js → kimi-MSIDEMCI.js} +4 -4
  175. package/dist/kimi-MSIDEMCI.js.map +1 -0
  176. package/dist/{kiro-BYX4HEAJ.js → kiro-A7DL52FX.js} +7 -7
  177. package/dist/kiro-A7DL52FX.js.map +1 -0
  178. package/dist/{kiro-WGOI5CGT.js → kiro-NYRRBIKW.js} +4 -4
  179. package/dist/kiro-NYRRBIKW.js.map +1 -0
  180. package/dist/{leaderboard-XEKS7B3H.js → leaderboard-KCT7XPCI.js} +7 -7
  181. package/dist/leaderboard-KCT7XPCI.js.map +1 -0
  182. package/dist/{mimo-code-7R53QDHB.js → mimo-code-NDGLBXNC.js} +7 -7
  183. package/dist/mimo-code-NDGLBXNC.js.map +1 -0
  184. package/dist/{mistral-vibe-LHJ55FSB.js → mistral-vibe-LLWASF5X.js} +6 -6
  185. package/dist/mistral-vibe-LLWASF5X.js.map +1 -0
  186. package/dist/{mux-XM6AP35L.js → mux-7PIJ7HUQ.js} +4 -4
  187. package/dist/mux-7PIJ7HUQ.js.map +1 -0
  188. package/dist/{mux-NYCNGL43.js → mux-ON4QK3OC.js} +6 -6
  189. package/dist/mux-ON4QK3OC.js.map +1 -0
  190. package/dist/{nemoclaw-WSIPSE7U.js → nemoclaw-45R5MFBF.js} +7 -7
  191. package/dist/nemoclaw-45R5MFBF.js.map +1 -0
  192. package/dist/{omp-562NK5BJ.js → omp-ROCTFV3A.js} +7 -7
  193. package/dist/omp-ROCTFV3A.js.map +1 -0
  194. package/dist/{open-interpreter-I2CNOEXY.js → open-interpreter-V6CN542J.js} +6 -6
  195. package/dist/open-interpreter-V6CN542J.js.map +1 -0
  196. package/dist/openclaw-AOKFJGRQ.js +17 -0
  197. package/dist/{openclaw-5EQFGOWL.js → openclaw-KAFTNLR2.js} +4 -4
  198. package/dist/openclaw-KAFTNLR2.js.map +1 -0
  199. package/dist/{opencode-YS4WX2E2.js → opencode-YYWQ45LF.js} +7 -7
  200. package/dist/opencode-YYWQ45LF.js.map +1 -0
  201. package/dist/{opencode-QGP4ALQY.js → opencode-Z65JYILL.js} +4 -4
  202. package/dist/opencode-Z65JYILL.js.map +1 -0
  203. package/dist/{openhands-QMYIKNOS.js → openhands-OFFMWCQW.js} +7 -7
  204. package/dist/openhands-OFFMWCQW.js.map +1 -0
  205. package/dist/{package-G25GVTH2.js → package-TALOSRQ4.js} +15 -15
  206. package/dist/package-TALOSRQ4.js.map +1 -0
  207. package/dist/{pi-644FIN3A.js → pi-4W74ETTI.js} +6 -6
  208. package/dist/pi-4W74ETTI.js.map +1 -0
  209. package/dist/{pi-GGDQREVG.js → pi-DLKCPOJE.js} +4 -4
  210. package/dist/pi-DLKCPOJE.js.map +1 -0
  211. package/dist/{qwen-code-GQILBJ5B.js → qwen-code-26CSFDX6.js} +4 -4
  212. package/dist/qwen-code-26CSFDX6.js.map +1 -0
  213. package/dist/{qwen-code-STDMX7EM.js → qwen-code-JOBFNEVT.js} +16 -16
  214. package/dist/qwen-code-JOBFNEVT.js.map +1 -0
  215. package/dist/{roo-code-SUWI4BBN.js → roo-code-HSAE2CJU.js} +4 -4
  216. package/dist/roo-code-HSAE2CJU.js.map +1 -0
  217. package/dist/{roo-code-DLPIHHQ6.js → roo-code-RHIGJZNY.js} +6 -6
  218. package/dist/roo-code-RHIGJZNY.js.map +1 -0
  219. package/dist/runtime/index.d.ts +9 -8
  220. package/dist/runtime/index.js +14 -14
  221. package/dist/sdk/index.d.ts +4 -4
  222. package/dist/sdk/index.js +6 -6
  223. package/dist/sdk/index.js.map +1 -1
  224. package/dist/sdk/test.d.ts +2 -2
  225. package/dist/sdk/test.js +11 -11
  226. package/dist/{serve-XTMIUHKK.js → serve-4TEHK726.js} +16 -16
  227. package/dist/serve-4TEHK726.js.map +1 -0
  228. package/dist/{status-VJAGO4Z7.js → status-DVD4EHMX.js} +11 -11
  229. package/dist/status-DVD4EHMX.js.map +1 -0
  230. package/dist/{statusline-EY2E2UGF.js → statusline-ZVNH7XBK.js} +15 -15
  231. package/dist/statusline-ZVNH7XBK.js.map +1 -0
  232. package/dist/{synthetic-6FRA7P5Q.js → synthetic-LUT6V6SD.js} +4 -4
  233. package/dist/synthetic-LUT6V6SD.js.map +1 -0
  234. package/dist/{telemetry-OLZQBADT.js → telemetry-NWUJPIK3.js} +10 -10
  235. package/dist/telemetry-NWUJPIK3.js.map +1 -0
  236. package/dist/{trae-CPPYASR2.js → trae-SIQI3C66.js} +4 -4
  237. package/dist/trae-SIQI3C66.js.map +1 -0
  238. package/dist/{trae-UOYD6JZZ.js → trae-TLAFSQRQ.js} +6 -6
  239. package/dist/trae-TLAFSQRQ.js.map +1 -0
  240. package/dist/{types-JyhpJHJa.d.ts → types-C6j18a6R.d.ts} +13 -14
  241. package/dist/{uninstall-AZEUPAND.js → uninstall-DZVFV7KE.js} +21 -21
  242. package/dist/uninstall-DZVFV7KE.js.map +1 -0
  243. package/dist/{upgrade-CAUUHSSC.js → upgrade-OUE4ED52.js} +21 -21
  244. package/dist/upgrade-OUE4ED52.js.map +1 -0
  245. package/dist/{usage-3KHZ4RYZ.js → usage-NT3ZXALZ.js} +4 -4
  246. package/dist/usage-NT3ZXALZ.js.map +1 -0
  247. package/dist/{usage-event-TZWOZPRJ.js → usage-event-IELZE6WO.js} +15 -15
  248. package/dist/usage-event-IELZE6WO.js.map +1 -0
  249. package/dist/{vscode-copilot-NIMH2DGU.js → vscode-copilot-VZ5XYSTK.js} +7 -7
  250. package/dist/vscode-copilot-VZ5XYSTK.js.map +1 -0
  251. package/dist/{warp-NRBBJQR2.js → warp-5YBSP7FP.js} +4 -4
  252. package/dist/warp-5YBSP7FP.js.map +1 -0
  253. package/dist/{warp-QYJGKURM.js → warp-P2HWXIKT.js} +6 -6
  254. package/dist/warp-P2HWXIKT.js.map +1 -0
  255. package/dist/{windsurf-75LLZ37C.js → windsurf-3JC73GZK.js} +6 -6
  256. package/dist/windsurf-3JC73GZK.js.map +1 -0
  257. package/dist/{zed-HKAZXEJW.js → zed-6CMUKXLI.js} +7 -7
  258. package/dist/zed-6CMUKXLI.js.map +1 -0
  259. package/dist/{zed-XJFOOKCO.js → zed-XXCNYOIN.js} +4 -4
  260. package/dist/zed-XXCNYOIN.js.map +1 -0
  261. package/package.json +92 -88
  262. package/dist/action-Q7GGO4PA.js.map +0 -1
  263. package/dist/amazon-q-ETMAGY3D.js.map +0 -1
  264. package/dist/amp-67BZONGF.js.map +0 -1
  265. package/dist/amp-BQZOL5GR.js.map +0 -1
  266. package/dist/antigravity-EA4L225L.js.map +0 -1
  267. package/dist/antigravity-VXLDLTO7.js +0 -18
  268. package/dist/antigravity-cli-B2HXZFYQ.js.map +0 -1
  269. package/dist/antigravity-cli-OM6SC3PE.js.map +0 -1
  270. package/dist/chunk-2Y2MZRLP.js.map +0 -1
  271. package/dist/chunk-3NH2ARIS.js.map +0 -1
  272. package/dist/chunk-4NHXLXSD.js.map +0 -1
  273. package/dist/chunk-5IOTP7LQ.js.map +0 -1
  274. package/dist/chunk-6TF7MHG5.js.map +0 -1
  275. package/dist/chunk-6WZODR3Z.js.map +0 -1
  276. package/dist/chunk-7F5KHLEP.js.map +0 -1
  277. package/dist/chunk-APZDTY76.js.map +0 -1
  278. package/dist/chunk-BEFVJ2OE.js.map +0 -1
  279. package/dist/chunk-D4ELPBB5.js.map +0 -1
  280. package/dist/chunk-FBJQGRET.js.map +0 -1
  281. package/dist/chunk-FJCUKXGX.js.map +0 -1
  282. package/dist/chunk-GZGLCCEE.js.map +0 -1
  283. package/dist/chunk-H33M77DD.js.map +0 -1
  284. package/dist/chunk-H53QZQJI.js.map +0 -1
  285. package/dist/chunk-I5UXHIDT.js.map +0 -1
  286. package/dist/chunk-ISEJWBFF.js.map +0 -1
  287. package/dist/chunk-IVAWP6HH.js.map +0 -1
  288. package/dist/chunk-JKKU2WKG.js.map +0 -1
  289. package/dist/chunk-KHO5WNTP.js.map +0 -1
  290. package/dist/chunk-MGTDQLJJ.js.map +0 -1
  291. package/dist/chunk-MQPNU2CY.js.map +0 -1
  292. package/dist/chunk-NBYKLUF6.js.map +0 -1
  293. package/dist/chunk-NLE2J5P4.js.map +0 -1
  294. package/dist/chunk-O7SDRBVB.js.map +0 -1
  295. package/dist/chunk-OP4KBXUO.js.map +0 -1
  296. package/dist/chunk-OPXAP3AC.js.map +0 -1
  297. package/dist/chunk-PAPMUAR5.js.map +0 -1
  298. package/dist/chunk-PW42ZXCB.js.map +0 -1
  299. package/dist/chunk-RK6VBLXP.js.map +0 -1
  300. package/dist/chunk-UM5S7DKK.js.map +0 -1
  301. package/dist/chunk-UMQ6NBQR.js.map +0 -1
  302. package/dist/chunk-XC5SJ35F.js.map +0 -1
  303. package/dist/chunk-XD7MY6HB.js.map +0 -1
  304. package/dist/chunk-YPAXJ7EW.js.map +0 -1
  305. package/dist/chunk-YT43MUSJ.js.map +0 -1
  306. package/dist/chunk-Z2MRSS2I.js.map +0 -1
  307. package/dist/claude-code-GRWO6XBZ.js.map +0 -1
  308. package/dist/claude-code-NMRKTAP7.js.map +0 -1
  309. package/dist/cline-25KW25IN.js.map +0 -1
  310. package/dist/codebuddy-ZNYQACMF.js.map +0 -1
  311. package/dist/codebuff-ETYT5UBL.js.map +0 -1
  312. package/dist/codebuff-VR6JUDIY.js.map +0 -1
  313. package/dist/codex-CPNKTXG3.js.map +0 -1
  314. package/dist/codex-YAORPCOD.js.map +0 -1
  315. package/dist/continue-WU2IB5KS.js.map +0 -1
  316. package/dist/copilot-cli-MZTAWMPW.js.map +0 -1
  317. package/dist/copilot-cli-PAP377OM.js.map +0 -1
  318. package/dist/crush-3AVQA4YU.js.map +0 -1
  319. package/dist/crush-QBXLNN7T.js.map +0 -1
  320. package/dist/cursor-DIW43TRZ.js.map +0 -1
  321. package/dist/cursor-GSLUET3V.js +0 -22
  322. package/dist/detect-6V4LC3MA.js.map +0 -1
  323. package/dist/devin-QMEM3OFA.js.map +0 -1
  324. package/dist/doctor-2YDUVSAU.js.map +0 -1
  325. package/dist/droid-MOKV53J4.js.map +0 -1
  326. package/dist/droid-U3ZBLQFO.js.map +0 -1
  327. package/dist/gemini-cli-47ZHCOZR.js.map +0 -1
  328. package/dist/gemini-cli-NMVVBO3K.js.map +0 -1
  329. package/dist/goose-4EI5MYTI.js.map +0 -1
  330. package/dist/goose-64V46Y2W.js.map +0 -1
  331. package/dist/grok-cli-QYQPDSVB.js.map +0 -1
  332. package/dist/hermes-F3EGTK6N.js.map +0 -1
  333. package/dist/hermes-F75OSK3Y.js.map +0 -1
  334. package/dist/hook-OEVRDMXD.js.map +0 -1
  335. package/dist/install-5NMCUDG5.js.map +0 -1
  336. package/dist/jetbrains-copilot-ZGIWI6YV.js.map +0 -1
  337. package/dist/junie-DIFN2P22.js.map +0 -1
  338. package/dist/kilo-EMZJBEBB.js.map +0 -1
  339. package/dist/kilo-SW7BH6EG.js.map +0 -1
  340. package/dist/kilo-cli-S3GXBPAE.js.map +0 -1
  341. package/dist/kilo-cli-ZF272ZHN.js.map +0 -1
  342. package/dist/kimi-5FHEXGZD.js.map +0 -1
  343. package/dist/kimi-IQJOIY6B.js.map +0 -1
  344. package/dist/kiro-BYX4HEAJ.js.map +0 -1
  345. package/dist/kiro-WGOI5CGT.js.map +0 -1
  346. package/dist/leaderboard-XEKS7B3H.js.map +0 -1
  347. package/dist/mimo-code-7R53QDHB.js.map +0 -1
  348. package/dist/mistral-vibe-LHJ55FSB.js.map +0 -1
  349. package/dist/mux-NYCNGL43.js.map +0 -1
  350. package/dist/mux-XM6AP35L.js.map +0 -1
  351. package/dist/nemoclaw-WSIPSE7U.js.map +0 -1
  352. package/dist/omp-562NK5BJ.js.map +0 -1
  353. package/dist/open-interpreter-I2CNOEXY.js.map +0 -1
  354. package/dist/openclaw-5EQFGOWL.js.map +0 -1
  355. package/dist/openclaw-7EYBQS4R.js +0 -17
  356. package/dist/opencode-QGP4ALQY.js.map +0 -1
  357. package/dist/opencode-YS4WX2E2.js.map +0 -1
  358. package/dist/openhands-QMYIKNOS.js.map +0 -1
  359. package/dist/package-G25GVTH2.js.map +0 -1
  360. package/dist/pi-644FIN3A.js.map +0 -1
  361. package/dist/pi-GGDQREVG.js.map +0 -1
  362. package/dist/qwen-code-GQILBJ5B.js.map +0 -1
  363. package/dist/qwen-code-STDMX7EM.js.map +0 -1
  364. package/dist/roo-code-DLPIHHQ6.js.map +0 -1
  365. package/dist/roo-code-SUWI4BBN.js.map +0 -1
  366. package/dist/serve-XTMIUHKK.js.map +0 -1
  367. package/dist/status-VJAGO4Z7.js.map +0 -1
  368. package/dist/statusline-EY2E2UGF.js.map +0 -1
  369. package/dist/synthetic-6FRA7P5Q.js.map +0 -1
  370. package/dist/telemetry-OLZQBADT.js.map +0 -1
  371. package/dist/trae-CPPYASR2.js.map +0 -1
  372. package/dist/trae-UOYD6JZZ.js.map +0 -1
  373. package/dist/uninstall-AZEUPAND.js.map +0 -1
  374. package/dist/upgrade-CAUUHSSC.js.map +0 -1
  375. package/dist/usage-3KHZ4RYZ.js.map +0 -1
  376. package/dist/usage-event-TZWOZPRJ.js.map +0 -1
  377. package/dist/vscode-copilot-NIMH2DGU.js.map +0 -1
  378. package/dist/warp-NRBBJQR2.js.map +0 -1
  379. package/dist/warp-QYJGKURM.js.map +0 -1
  380. package/dist/windsurf-75LLZ37C.js.map +0 -1
  381. package/dist/zed-HKAZXEJW.js.map +0 -1
  382. package/dist/zed-XJFOOKCO.js.map +0 -1
  383. /package/dist/{antigravity-VXLDLTO7.js.map → antigravity-PZXYAO3X.js.map} +0 -0
  384. /package/dist/{cursor-GSLUET3V.js.map → cursor-JRVK56QA.js.map} +0 -0
  385. /package/dist/{openclaw-7EYBQS4R.js.map → openclaw-AOKFJGRQ.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/cursor/index.ts"],"sourcesContent":["/**\n * adapters/cursor — Cursor platform adapter for agent-connector.\n *\n * Generalized from context-mode's proven Cursor adapter: the served identity is\n * now `ctx.connector` (not a hardcoded \"context-mode\"), and every hook command\n * points at the single stable home binary (the shared hook-merge engine builds\n * the command) so one framework update propagates everywhere.\n *\n * Cursor is a json-stdio host:\n * - MCP servers: user scope → ~/.cursor/mcp.json (\"mcpServers\"); project scope\n * → <projectDir>/.cursor/mcp.json (\"mcpServers\").\n * - Hooks: <configDir>/hooks.json with shape `{ version, hooks: { <cursorEvent>:\n * [ { command, matcher? } ] } }`. Unlike Claude, each entry is a FLAT command\n * object (no `{ matcher, hooks:[...] }` wrapper).\n * - Reply: a JSON object on stdout (exit 0). deny/ask carry `permission` +\n * `user_message`; modify carries `updated_input`; context injects via\n * `agent_message` (PreToolUse) or `additional_context` (Post/SessionStart).\n *\n * Cursor supports its own `${env:VAR}` native interpolation, so env/header/url\n * values are rewritten to that native token rather than baked into the file.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter, type HookMergeDescriptor } 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 PostToolUseFailureEvent,\n PreCompactEvent,\n PreToolUseEvent,\n ServerDef,\n SessionEndEvent,\n SessionStartEvent,\n StopEvent,\n SubagentDef,\n SubagentStartEvent,\n SubagentStopEvent,\n Transport,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { rewriteEnvRefs } from \"../../core/interpolate.js\";\nimport {\n buildWrappedStdio,\n isHomeBinHookCommand,\n} from \"../../core/spawn.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\nimport { normalizeSessionSource } from \"../claude-code/wire.js\";\n\nconst HOST: PlatformId = \"cursor\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/**\n * Native hooks.json version Cursor expects. Exported as the SINGLE source of\n * truth for Cursor's hooks-file version, shared with the `cursor-plugin`\n * package emitter so the live install + the packaged bundle can never stamp\n * different versions (see core/package-formats/cursor.ts).\n */\nexport const CURSOR_HOOKS_VERSION = 1;\n\n/**\n * Cursor-native hook event names, in the lower-camel form Cursor reads from\n * hooks.json. The first four are the events the proven context-mode adapter\n * registers; postToolUseFailure / subagentStart / subagentStop are Cursor's\n * documented \"Subagent (Task tool) lifecycle\" + tool-failure hooks.\n */\nconst CURSOR_EVENT = {\n PreToolUse: \"preToolUse\",\n PostToolUse: \"postToolUse\",\n SessionStart: \"sessionStart\",\n Stop: \"stop\",\n PostToolUseFailure: \"postToolUseFailure\",\n SubagentStart: \"subagentStart\",\n SubagentStop: \"subagentStop\",\n // Lifecycle/prompt events Cursor 1.7+ documents (cursor.com/docs/hooks):\n // sessionEnd is fire-and-forget; preCompact is observational (cannot block);\n // beforeSubmitPrompt fires before a prompt is sent and CAN prevent submission\n // (Cursor itself matches beforeSubmitPrompt against the value \"UserPromptSubmit\").\n SessionEnd: \"sessionEnd\",\n PreCompact: \"preCompact\",\n UserPromptSubmit: \"beforeSubmitPrompt\",\n} as const;\n\n/**\n * Map our normalized event names to Cursor's native hook event names. Only the\n * events Cursor actually supports are present; everything else has no Cursor\n * equivalent and is reported as a skip/warn at install time.\n *\n * PermissionRequest is deliberately ABSENT: Cursor has no permission-dialog\n * event — its permission gate is the OUTPUT field `permission: \"allow\"|\"deny\"|\n * \"ask\"` of the before* hooks (beforeShellExecution / beforeMCPExecution /\n * beforeReadFile / preToolUse), not an observable event. Install reports the\n * standard skip-warn for it.\n *\n * Exported as the SINGLE source of truth for canonical→Cursor-native event\n * mapping, shared with the `cursor-plugin` package emitter (see\n * core/package-formats/cursor.ts) so the packaged bundle's hooks.json keys can\n * never silently diverge from the live install adapter's.\n */\nexport const CURSOR_EVENT_MAP: Partial<Record<HookEventName, string>> = {\n PreToolUse: CURSOR_EVENT.PreToolUse,\n PostToolUse: CURSOR_EVENT.PostToolUse,\n SessionStart: CURSOR_EVENT.SessionStart,\n Stop: CURSOR_EVENT.Stop,\n PostToolUseFailure: CURSOR_EVENT.PostToolUseFailure,\n SubagentStart: CURSOR_EVENT.SubagentStart,\n SubagentStop: CURSOR_EVENT.SubagentStop,\n SessionEnd: CURSOR_EVENT.SessionEnd,\n PreCompact: CURSOR_EVENT.PreCompact,\n UserPromptSubmit: CURSOR_EVENT.UserPromptSubmit,\n};\n\n/** A single Cursor native hook entry — a flat command object. */\ninterface CursorHookEntry {\n command: string;\n matcher?: string;\n}\n\n/** Native MCP server entry shapes Cursor accepts under `mcpServers`. */\ninterface CursorStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\ninterface CursorHttpServer {\n url: string;\n headers?: Record<string, string>;\n}\n\n/** Raw Cursor hook stdin payload (snake_case wire fields). */\ninterface CursorWireInput {\n connector?: unknown;\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_output?: string;\n error_message?: string;\n cwd?: string;\n workspace_roots?: string[];\n conversation_id?: string;\n session_id?: string;\n generation_id?: string;\n trigger?: string;\n status?: string;\n loop_count?: number;\n stop_hook_active?: boolean;\n\n // sessionStart — Cursor's stdin is EXACTLY { session_id, is_background_agent,\n // composer_mode } (cursor.com/docs/hooks ~1278-1297): there is NO source/trigger\n // start-source discriminator. composer_mode is the editor MODE (agent|ask|edit),\n // NOT our normalized SessionStart.source enum (startup|compact|resume|clear), so\n // it does not map; surfaced here only so the host shape is documented (no\n // normalized field exists for either — see core/types.ts SessionStartEvent).\n is_background_agent?: boolean;\n composer_mode?: string;\n\n // beforeSubmitPrompt (UserPromptSubmit) — the submitted prompt text.\n // sessionEnd — the documented end reason. Both field names are taken\n // verbatim from cursor.com/docs/hooks (snake_case wire).\n prompt?: string;\n reason?: string;\n\n // postToolUseFailure — Cursor's existing error vocabulary is error_message;\n // the Claude-compatible names are accepted defensively (unverified wire).\n error?: string;\n tool_use_id?: string;\n is_interrupt?: boolean;\n // postToolUse / postToolUseFailure carry a BARE `duration` (ms), not\n // `duration_ms` (cursor.com/docs/hooks ~870,883,904,918). `duration_ms` is the\n // distinct field on sessionEnd (~1315) and subagentStop (~973,994), kept below.\n duration?: number;\n duration_ms?: number;\n\n // subagentStart / subagentStop (Task-tool lifecycle). Both name families are\n // parsed defensively: agent_* (Claude-compatible) and subagent_* (Cursor-ish).\n agent_id?: string;\n agent_type?: string;\n subagent_id?: string;\n subagent_type?: string;\n // subagentStop carries the subagent's output text under `summary`, NOT\n // last_assistant_message (cursor.com/docs/hooks ~972,993). This is read into\n // the normalized lastAssistantMessage.\n summary?: string;\n}\n\nexport class CursorAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Cursor\";\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 // Cursor natively supports pre/post tool-use, session start/end, prompt\n // submission, context compaction, and stop (cursor.com/docs/hooks, v1.7+).\n preToolUse: true,\n postToolUse: true,\n preCompact: true,\n sessionStart: true,\n sessionEnd: true,\n userPromptSubmit: true,\n stop: true,\n notification: false,\n // Newer events: Cursor has dedicated postToolUseFailure + subagentStart/\n // subagentStop hooks. permissionRequest stays unset — Cursor's permission\n // gate is an OUTPUT field of its before* hooks, not an observable event\n // (see the EVENT_MAP note).\n postToolUseFailure: true,\n subagentStart: true,\n subagentStop: true,\n // Cursor's preToolUse can rewrite tool input (updated_input) but cannot\n // rewrite already-emitted tool output.\n canModifyArgs: true,\n canModifyOutput: false,\n canInjectSessionContext: true,\n transports: [\"stdio\", \"http\"],\n // Server env/url use Cursor's NATIVE ${env:VAR} interpolation (rewriteEnvRefs)\n // — the token survives into mcp.json, never a baked literal — so the\n // installer's unset-env-ref bake warn does not apply here.\n nativeServerEnvInterpolation: true,\n // Content surfaces: Cursor supports all three (commands, skills, subagents).\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: true,\n // Native passthrough hooks: Cursor documents many granular hooks with NO\n // canonical analog — beforeShellExecution / afterShellExecution /\n // beforeMCPExecution / afterMCPExecution / beforeReadFile / afterFileEdit /\n // beforeTabFileRead / afterTabFileEdit / workspaceOpen / afterAgentResponse /\n // afterAgentThought (cursor.com/docs/hooks). They are\n // host-specific (below the >=3-host core bar; see\n // docs/research/host-specific-hook-events-design.md). A connector reaches them\n // by declaring platforms[\"cursor\"].nativeHooks; installHooks writes those\n // event-name keys verbatim into hooks.json, and the generic uninstall reverses\n // them.\n supportsNativeHooks: true,\n // Cursor has a command-driven status line (`/statusline` → `statusLine` in\n // ~/.cursor/cli-config.json, GLOBAL scope only) per the Cursor changelog, but\n // the config-key shape + the Claude-parity stdin payload are sourced from a\n // community tool (agent-status-pills), not first-party Cursor docs — payload\n // field names unverified. Deferred pending a live cursor-agent capture; not a\n // permanent gap; user-scope only when wired.\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".cursor\");\n const userMcp = join(userDir, \"mcp.json\");\n const userHooks = join(userDir, \"hooks.json\");\n const projectDirCursor = join(projectDir, \".cursor\");\n const installed =\n existsSync(userDir) ||\n existsSync(userMcp) ||\n existsSync(userHooks) ||\n existsSync(projectDirCursor);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath: userMcp,\n scope: \"user\",\n reason: installed\n ? `found Cursor config under ${userDir}`\n : `no Cursor config at ${userDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".cursor\")\n : join(homedir(), \".cursor\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp.json\");\n }\n\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"hooks.json\");\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for cursor\"\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 Cursor's native mcpServers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): CursorStdioServer | CursorHttpServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route the real command through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n const entry: CursorStdioServer = { command: this.rewrite(command) };\n if (args.length > 0) entry.args = args.map((a) => this.rewrite(a));\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n if (server.cwd) entry.cwd = this.rewrite(server.cwd);\n return entry;\n }\n\n // http (and any other remote transport we surface) — Cursor registers a URL.\n const entry: CursorHttpServer = { url: this.rewrite(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. Cursor supports its own `${env:VAR}` native\n * interpolation, so translate `${env:VAR}` refs to that native token rather\n * than baking secrets into the file. Literals pass through unchanged.\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 const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(env)) out[k] = this.rewrite(v);\n return out;\n }\n\n /** Translate `${env:VAR(:-default)}` to Cursor's native `${env:VAR}` token. */\n private rewrite(value: string): string {\n return rewriteEnvRefs(value, cursorEnvToken);\n }\n\n // ── Hook install / uninstall ─────────────────────────────────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST];\n\n // `hooks: false` disables only the NORMALIZED events. nativeHooks is a\n // sibling, cursor-scoped declaration on the same override and installs\n // regardless.\n const normalizedEvents = override?.hooks === false ? [] : connector.hookEvents;\n const nativeHooks = override?.nativeHooks ?? {};\n const nativeEvents = Object.keys(nativeHooks);\n\n if (normalizedEvents.length === 0 && nativeEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: override?.hooks === false ? \"hooks disabled for cursor\" : \"connector declares no hooks\",\n },\n ];\n }\n\n // Normalized events go through the engine's mapEvent/warn path; native\n // event-name keys ride the separate `native` pass (verbatim keys, EXACT\n // command, the `(native)` detail) — see the descriptor + base.upsertHookEntries.\n const pending = normalizedEvents.map((event) => ({\n event,\n matcher: connector.hooks[event]?.matcher ?? \"\",\n }));\n const native = nativeEvents.map((event) => ({\n event,\n matcher: nativeHooks[event]?.matcher ?? \"\",\n }));\n return this.upsertHookEntries(\n ctx,\n this.getHookConfigPath(ctx),\n pending,\n this.hookDescriptor(ctx),\n native,\n );\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n return this.removeHookEntries(ctx, this.getHookConfigPath(ctx), this.hookDescriptor(ctx));\n }\n\n /**\n * Cursor's hook-merge descriptor (FLAT shape `{ command, matcher? }`):\n * - mapEvent renames canonical → Cursor's lower-camel native key\n * (CURSOR_EVENT_MAP); an unmapped event warn-skips (no Cursor equivalent).\n * - renderEntry omits the `matcher` key when the matcher is falsy — this\n * `{command}` vs `{command,matcher}` distinction is load-bearing on-disk\n * bytes (Cursor's flat entry shape), reproduced exactly here.\n * - install find is connector-generic (ANY of our commands at the flat\n * `entry.command`); uninstall drops whole owned entries (flat — NO\n * stripInner). The version stamp is install-only via onMutate.\n * - the native pass uses EXACT-command ownership so a native key coinciding\n * with a normalized event's mapped key adds a SECOND distinct command\n * rather than clobbering the normalized entry.\n */\n private hookDescriptor(ctx: InstallContext): HookMergeDescriptor<CursorHookEntry> {\n return {\n mapEvent: (e) => CURSOR_EVENT_MAP[e as HookEventName],\n unmappedWarnDetail: (e) => `${e} has no Cursor hook equivalent — skipped`,\n renderEntry: (_event, matcher, command) =>\n matcher ? { command, matcher } : { command },\n entryOwnsCommand: (entry, _command) => this.isOurCommand(entry.command, ctx),\n ownsEntryForRemove: (c) => (entry) => this.isOurCommand(entry.command, c),\n skipDetail: (e) => `hooks.${e} already registered`,\n removeDetail: (e, n) => `hooks.${e} (${n})`,\n absentDetail: \"no hooks section present\",\n noMatchDetail: \"no matching hook entries\",\n onMutate: (file) => {\n (file as { version?: number }).version = CURSOR_HOOKS_VERSION;\n },\n nativeOwnsCommand: (entry, command) => entry.command === command,\n nativeSkipDetail: (e) => `hooks.${e} (native) already registered`,\n nativeMutateDetail: (e) => `hooks.${e} (native)`,\n };\n }\n\n /** True when a hook command references our home binary AND this connector id\n * (anchored so a shared-prefix id can't collide — see isHomeBinHookCommand). */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\n }\n\n // ── Content surfaces: commands / skills / subagents ──────────────────────\n // CONTENT-ONLY: pure native-file writers under <configDir>/{commands,skills,\n // agents}. 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[\"cursor\"] per-surface\n // false to skip. Cursor commands are BODY-ONLY markdown (no frontmatter);\n // skills are the uniform <name>/SKILL.md + resources; subagents are md+fm.\n\n private commandsDir(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"commands\");\n }\n private skillsDir(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"skills\");\n }\n private agentsDir(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"agents\");\n }\n\n /** Native command file path: <configDir>/commands/<name>.md. */\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.commandsDir(ctx), `${name}.md`);\n }\n /** Native skill dir: <configDir>/skills/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\n }\n /** Native subagent file path: <configDir>/agents/<name>.md. */\n private subagentPath(ctx: InstallContext, name: string): string {\n return join(this.agentsDir(ctx), `${name}.md`);\n }\n\n // ── Commands ──────────────────────────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for cursor\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.writeContentFile(\n this.commandPath(ctx, cmd.name),\n this.renderCommand(cmd),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun),\n );\n }\n\n /**\n * Render a Cursor command: BODY-ONLY markdown (no frontmatter). Cursor reads\n * the file as the command prompt verbatim. We prepend the one-line description\n * as an HTML comment header when present so authoring intent survives the\n * round-trip without leaking into the rendered prompt. A description containing\n * \"-->\" would prematurely CLOSE the HTML comment and leak the remainder into\n * the prompt, so we neutralize that sequence before embedding it.\n */\n private renderCommand(cmd: CommandDef): string {\n if (!cmd.description) return `${cmd.prompt}\\n`;\n // Break any literal comment-close so it cannot terminate our header early.\n const safe = cmd.description.replace(/--+>/g, (m) => m.replace(/>/g, \"&gt;\"));\n return `<!-- ${safe} -->\\n\\n${cmd.prompt}\\n`;\n }\n\n // ── Skills ────────────────────────────────────────────────────────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for cursor\" }];\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 // (config-time validation already rejects these, but never trust input).\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n }\n return changes;\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n // Remove only the files we wrote (SKILL.md + declared resources), then the\n // skill dir itself when we own its full contents.\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue; // never delete outside the skill dir\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n // Only remove the skill dir when WE own its full contents — never rm -rf a\n // dir that still holds user-added / sibling-tool / shared files.\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Subagents ───────────────────────────────────────────────────────────────\n\n override installSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.subagents === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"subagents disabled for cursor\" }];\n }\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.writeContentFile(\n this.subagentPath(ctx, agent.name),\n this.renderSubagent(agent),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.removeContentFile(this.subagentPath(ctx, agent.name), ctx.dryRun),\n );\n }\n\n /** Render a Cursor subagent to md+frontmatter (name, description, model, readonly) + prompt body. */\n private renderSubagent(agent: SubagentDef): string {\n const frontmatter: Record<string, unknown> = {\n name: agent.name,\n description: agent.description,\n };\n if (agent.model !== undefined) frontmatter.model = agent.model;\n if (agent.readonly !== undefined) frontmatter.readonly = agent.readonly;\n if (agent.extra) Object.assign(frontmatter, agent.extra);\n return this.renderFrontmatterMd(frontmatter, agent.prompt);\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 checks: HealthCheck[] = [\n {\n name: `${this.name}: mcp.json present`,\n check: () =>\n existsSync(mcpPath)\n ? { status: \"OK\", detail: mcpPath }\n : { status: \"FAIL\", detail: `not found: ${mcpPath}` },\n },\n {\n name: `${this.name}: hooks.json present`,\n check: () => {\n // Same \"only assert what the connector declares\" rule as the\n // content-surface checks below: a hookless connector never writes\n // hooks.json, so its absence is healthy, not a failure.\n if (ctx.connector.hookEvents.length === 0) {\n return { status: \"OK\", detail: \"no hooks declared\" };\n }\n return existsSync(hooksPath)\n ? { status: \"OK\", detail: hooksPath }\n : { status: \"FAIL\", detail: `not found: ${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).\n for (const cmd of ctx.connector.commands) {\n const p = this.commandPath(ctx, cmd.name);\n checks.push({\n name: `${this.name}: command ${cmd.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const skill of ctx.connector.skills) {\n const p = join(this.skillDir(ctx, skill.name), \"SKILL.md\");\n checks.push({\n name: `${this.name}: skill ${skill.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const agent of ctx.connector.subagents) {\n const p = this.subagentPath(ctx, agent.name);\n checks.push({\n name: `${this.name}: subagent ${agent.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n return checks;\n }\n\n // ── Runtime: parse Cursor stdin JSON → normalized event ──────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as CursorWireInput;\n const connectorId = typeof input.connector === \"string\" ? input.connector : \"\";\n const sessionId = extractSessionId(input);\n const projectDir = this.getProjectDir(input);\n\n const base = {\n hostPlatform: HOST,\n connectorId,\n sessionId,\n raw,\n ...(projectDir !== undefined ? { projectDir } : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n const toolOutput = input.tool_output ?? input.error_message;\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n ...(toolOutput !== undefined ? { toolOutput } : {}),\n ...(input.error_message ? { isError: true } : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n // Cursor's sessionStart stdin is exactly { session_id, is_background_agent,\n // composer_mode } — there is NO source/trigger start-source discriminator\n // (cursor.com/docs/hooks ~1278-1297). composer_mode is the editor MODE\n // (agent|ask|edit), a different concept from our normalized source enum\n // (startup|compact|resume|clear), so it does NOT map. With no discriminator\n // available, the normalized source stays at its 'startup' default (via\n // normalizeSessionSource(undefined)). is_background_agent / composer_mode\n // ride along on base.raw; there is no normalized field for either.\n const ev: SessionStartEvent = {\n ...base,\n source: normalizeSessionSource(undefined),\n };\n return ev;\n }\n case \"Stop\": {\n const ev: StopEvent = {\n ...base,\n ...(typeof input.stop_hook_active === \"boolean\"\n ? { stopHookActive: input.stop_hook_active }\n : {}),\n };\n return ev;\n }\n case \"SessionEnd\": {\n // Cursor sessionEnd: { session_id, reason, duration_ms, ... }. session_id\n // is already folded into base.sessionId via extractSessionId; only the\n // documented `reason` enum maps onto the normalized SessionEnd shape.\n const ev: SessionEndEvent = {\n ...base,\n ...(typeof input.reason === \"string\" ? { reason: input.reason } : {}),\n };\n return ev;\n }\n case \"UserPromptSubmit\": {\n // Cursor beforeSubmitPrompt: { prompt, attachments }. attachments has no\n // normalized field and is preserved via base.raw; only `prompt` maps.\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.prompt === \"string\" ? input.prompt : \"\",\n };\n return ev;\n }\n case \"PreCompact\": {\n // Cursor preCompact: { trigger: \"auto\"|\"manual\", context_*… }. Only the\n // documented `trigger` enum maps onto the normalized PreCompact shape.\n const ev: PreCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"PostToolUseFailure\": {\n // Cursor's established error field is error_message; fall back to the\n // Claude-compatible `error` defensively.\n const error = input.error_message ?? input.error ?? \"\";\n const ev: PostToolUseFailureEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n error,\n ...(typeof input.tool_use_id === \"string\"\n ? { toolUseId: input.tool_use_id }\n : {}),\n ...(typeof input.is_interrupt === \"boolean\"\n ? { isInterrupt: input.is_interrupt }\n : {}),\n // postToolUseFailure reports a BARE `duration` (ms), not `duration_ms`\n // (cursor.com/docs/hooks ~904,918). duration_ms only exists on\n // sessionEnd/subagentStop.\n ...(typeof input.duration === \"number\"\n ? { durationMs: input.duration }\n : {}),\n };\n return ev;\n }\n case \"SubagentStart\": {\n const agentId = input.agent_id ?? input.subagent_id;\n const agentType = input.agent_type ?? input.subagent_type;\n const ev: SubagentStartEvent = {\n ...base,\n ...(typeof agentId === \"string\" ? { agentId } : {}),\n ...(typeof agentType === \"string\" ? { agentType } : {}),\n };\n return ev;\n }\n case \"SubagentStop\": {\n const agentId = input.agent_id ?? input.subagent_id;\n const agentType = input.agent_type ?? input.subagent_type;\n const ev: SubagentStopEvent = {\n ...base,\n ...(typeof agentId === \"string\" ? { agentId } : {}),\n ...(typeof agentType === \"string\" ? { agentType } : {}),\n // Cursor's subagentStop carries the subagent's output text under\n // `summary`, NOT last_assistant_message (cursor.com/docs/hooks ~972,993).\n ...(typeof input.summary === \"string\"\n ? { lastAssistantMessage: input.summary }\n : {}),\n ...(typeof input.stop_hook_active === \"boolean\"\n ? { stopHookActive: input.stop_hook_active }\n : {}),\n };\n return ev;\n }\n default: {\n // Cursor never delivers Notification / PermissionRequest (no native\n // equivalent — permission is an OUTPUT field of its before* hooks, not\n // an event). If the runtime dispatches one anyway, fail loudly.\n throw new Error(`unsupported cursor hook event: ${String(event)}`);\n }\n }\n }\n\n private getProjectDir(input: CursorWireInput): string | undefined {\n return input.cwd ?? input.workspace_roots?.[0] ?? undefined;\n }\n\n // ── Runtime: normalized response → Cursor native hook reply ──────────────\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n const decision = response.decision ?? \"allow\";\n\n // postToolUseFailure (feedback beside the error) and subagentStart (context\n // injected into the SUBAGENT's conversation) are observe/context-only on\n // Cursor: \"context\" emits additional_context, and a \"deny\" DEGRADES to the\n // same shape carrying the reason (the tool already failed / the spawn is\n // not blockable). Everything else is a minimal no-op payload (Cursor\n // rejects empty stdout as \"no valid response\").\n if (event === \"PostToolUseFailure\" || event === \"SubagentStart\") {\n const context =\n decision === \"context\"\n ? response.additionalContext\n : decision === \"deny\"\n ? response.reason ?? response.additionalContext\n : undefined;\n return this.stdout({ additional_context: context ?? \"\" });\n }\n\n // beforeSubmitPrompt (UserPromptSubmit) is a BLOCK gate, not a permission/\n // context surface: its only documented output is { continue, user_message }\n // (cursor.com/docs/hooks). A \"deny\" prevents submission (continue:false +\n // reason); it cannot inject context (no additional_context/agent_message\n // field), so every non-deny decision is a no-op continue:true.\n if (event === \"UserPromptSubmit\") {\n if (decision === \"deny\") {\n return this.stdout({\n continue: false,\n user_message: response.reason ?? \"Blocked by hook\",\n });\n }\n return this.stdout({ continue: true });\n }\n\n // sessionEnd is fire-and-forget (the response is logged but not used) and\n // preCompact is observational (cannot block or modify compaction) per\n // cursor.com/docs/hooks — neither carries a decision Cursor honors, so both\n // are an unconditional no-op passthrough (mirrors Stop).\n if (event === \"SessionEnd\" || event === \"PreCompact\") {\n return { exitCode: 0 };\n }\n\n // deny → block the action with a user-facing message. (On SubagentStop\n // this follows the adapter's Stop idiom — the deny carries Stop semantics.)\n if (decision === \"deny\") {\n return this.stdout({\n permission: \"deny\",\n user_message: response.reason ?? \"Blocked by hook\",\n });\n }\n\n // ask → prompt the user to confirm.\n if (decision === \"ask\") {\n return this.stdout({\n permission: \"ask\",\n user_message: response.reason ?? \"Confirmation required by hook\",\n });\n }\n\n // modify → rewrite PreToolUse input (only where Cursor supports it).\n if (decision === \"modify\") {\n if (event === \"PreToolUse\" && response.updatedInput) {\n return this.stdout({ updated_input: response.updatedInput });\n }\n // Output rewrite is unsupported on Cursor; fall through to allow.\n }\n\n // context → inject soft guidance. PreToolUse uses `agent_message`; Post and\n // SessionStart use `additional_context`.\n if (decision === \"context\" && response.additionalContext) {\n return event === \"PreToolUse\"\n ? this.stdout({ agent_message: response.additionalContext })\n : this.stdout({ additional_context: response.additionalContext });\n }\n\n // SessionStart always emits valid JSON even on a no-op (Cursor rejects empty\n // stdout as \"no valid response\").\n if (event === \"SessionStart\") {\n return this.stdout({ additional_context: response.additionalContext ?? \"\" });\n }\n\n // allow / void → minimal no-op payload (Cursor rejects empty stdout).\n if (event === \"PreToolUse\") return this.stdout({ agent_message: \"\" });\n if (event === \"PostToolUse\") return this.stdout({ additional_context: \"\" });\n return { exitCode: 0 };\n }\n\n private stdout(payload: unknown): HookReply {\n return { exitCode: 0, stdout: JSON.stringify(payload) };\n }\n}\n\n/** Cursor native interpolation token: `${env:VAR}` → `${env:VAR}` (passthrough). */\nfunction cursorEnvToken(name: string): string {\n return `\\${env:${name}}`;\n}\n\nfunction extractSessionId(input: CursorWireInput): string {\n if (typeof input.conversation_id === \"string\") return input.conversation_id;\n if (typeof input.session_id === \"string\") return input.session_id;\n return \"\";\n}\n\nexport const adapter = new CursorAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sdk/test-harness.ts"],"sourcesContent":["/**\n * sdk/test-harness — the SHIPPED, OFFLINE behavioral harness.\n *\n * Two read-only tools a connector author runs WITHOUT installing anything or\n * touching the host's filesystem:\n *\n * • `explain(connector)` — the static per-host × per-DECLARED-surface matrix:\n * for every registered host and every surface the connector actually ships,\n * is it `native` (the host can honor it), `disabled` (the connector opted\n * out for that host via `platforms[host].<surface> === false`), or\n * `skip-warn` (the host cannot honor it → install would skip-warn)?\n *\n * • `simulate(connector, opts)` — runs the REAL adapter parse → handler →\n * format chain INLINE against a host-shaped raw payload and reports whether\n * the host actually HONORS the connector's response (the trustworthy part:\n * it surfaces the documented degradations, e.g. Codex silently dropping a\n * UserPromptSubmit \"context\" injection that has no stdout path).\n *\n * It deliberately does NOT import the runtime entrypoints (runHook /\n * runStatusline) — those load the REGISTERED connector from disk and record\n * telemetry. The harness instead re-implements the tiny parse→handler→format\n * chain against the in-memory connector + the adapter, mirroring the runtime's\n * input tolerance (empty/malformed payload → `{}`) and its fail-safe envelope.\n */\n\nimport type {\n HookEventName,\n HookResponse,\n PlatformCapabilities,\n PlatformId,\n PlatformOverride,\n ResolvedConnector,\n} from \"../core/types.js\";\nimport { allAdapters, loadAdapter } from \"../adapters/registry.js\";\nimport type { NormalizedEvent } from \"../adapters/spi.js\";\nimport {\n compileMatcher,\n eventMatcherSubject,\n} from \"../runtime/hook-entrypoint.js\";\nimport type { SurfaceName } from \"./introspect.js\";\nimport { hostCanFireEvent, SURFACE_PREDICATES } from \"./introspect.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// explain — the static per-host × per-declared-surface matrix\n// ─────────────────────────────────────────────────────────────────────────\n\n/** One cell of the {@link explain} matrix: a host × a declared surface. */\nexport interface ExplainRow {\n host: PlatformId;\n surface: SurfaceName;\n /**\n * - \"native\" — the host's capabilities pass the surface predicate.\n * - \"disabled\" — the connector opted out for this host\n * (`platforms[host].<surface> === false`).\n * - \"skip-warn\" — the host cannot honor it; install would skip-warn.\n */\n support: \"native\" | \"skip-warn\" | \"disabled\";\n reason: string;\n}\n\n/**\n * The GLOBAL surfaces a connector declares (these apply to every host — only\n * declared surfaces get a matrix row). The two platform-scoped surfaces\n * (`configPatch` / `nativeHooks`) are deliberately EXCLUDED here: they are\n * declared under one specific `platforms[host]`, so each is added PER HOST in\n * {@link explain} (see {@link platformScopedSurfacesFor}) — adding them globally\n * would falsely promise a configPatch row on hosts that never declared it.\n */\nfunction declaredGlobalSurfaces(connector: ResolvedConnector): SurfaceName[] {\n const out: SurfaceName[] = [];\n if (connector.server) out.push(\"server\");\n if (Object.keys(connector.hooks).length > 0) out.push(\"hooks\");\n if (connector.commands.length > 0) out.push(\"commands\");\n if (connector.skills.length > 0) out.push(\"skills\");\n if (connector.subagents.length > 0) out.push(\"subagents\");\n if (connector.memory.length > 0) out.push(\"memory\");\n if (connector.statusline) out.push(\"statusline\");\n if (connector.actions.length > 0) out.push(\"actions\");\n return out;\n}\n\n/**\n * The platform-scoped surfaces (`configPatch` / `nativeHooks`) THIS host\n * actually declares — keyed off the host's own `platforms[host]` override, so a\n * configPatch declared under claude-code never shows up as a row for codex.\n */\nfunction platformScopedSurfacesFor(\n override: PlatformOverride | undefined,\n): SurfaceName[] {\n const out: SurfaceName[] = [];\n if (!override) return out;\n if ((override.configPatch?.length ?? 0) > 0) out.push(\"configPatch\");\n if (override.nativeHooks != null && Object.keys(override.nativeHooks).length > 0) {\n out.push(\"nativeHooks\");\n }\n return out;\n}\n\n/**\n * Is the surface explicitly DISABLED for this host? Mirrors the per-host opt-out\n * the installer honors: a boolean-or-object surface override is \"disabled\" only\n * when set to the literal `false` (the object form is a tuning, not an opt-out).\n * `configPatch` / `nativeHooks` have no boolean opt-out form — declaring them is\n * the opt-in, so they are never \"disabled\".\n */\nfunction isDisabledForHost(\n connector: ResolvedConnector,\n host: PlatformId,\n surface: SurfaceName,\n): boolean {\n const override = connector.platforms[host];\n if (!override) return false;\n switch (surface) {\n case \"server\":\n return override.server === false;\n case \"hooks\":\n return override.hooks === false;\n case \"commands\":\n return override.commands === false;\n case \"skills\":\n return override.skills === false;\n case \"subagents\":\n return override.subagents === false;\n case \"memory\":\n return override.memory === false;\n case \"statusline\":\n return override.statusline === false;\n case \"actions\":\n case \"configPatch\":\n case \"nativeHooks\":\n // No per-host boolean opt-out form (declaring them is the opt-in).\n return false;\n }\n}\n\n/**\n * The static support matrix: every registered host × every surface the\n * connector declares. Rows are sorted by host then surface for stable output.\n * Pure read of the adapter capabilities — installs nothing, writes nothing.\n */\nexport async function explain(connector: ResolvedConnector): Promise<ExplainRow[]> {\n const globalSurfaces = declaredGlobalSurfaces(connector);\n const adapters = await allAdapters();\n const rows: ExplainRow[] = [];\n\n for (const adapter of adapters) {\n // Per-host surface set = the global surfaces every host gets a row for, plus\n // the platform-scoped surfaces THIS host actually declares (configPatch /\n // nativeHooks live under platforms[host], so they are host-local).\n const override = connector.platforms[adapter.id];\n const surfaces = [\n ...globalSurfaces,\n ...platformScopedSurfacesFor(override),\n ];\n for (const surface of surfaces) {\n if (isDisabledForHost(connector, adapter.id, surface)) {\n rows.push({\n host: adapter.id,\n surface,\n support: \"disabled\",\n reason: `connector opted out for ${adapter.id} (platforms.${adapter.id}.${surface} = false)`,\n });\n continue;\n }\n // The hooks surface is judged against the connector's SPECIFIC declared\n // events, not the coarse \"host has a hook runtime\" predicate — otherwise a\n // Stop-only connector falsely shows `native` on a PreToolUse-only host\n // (the host CAN fire a hook, just not the one this connector declared).\n if (surface === \"hooks\") {\n rows.push(hooksRow(connector, adapter.id, adapter.capabilities));\n continue;\n }\n const native = SURFACE_PREDICATES[surface](adapter.capabilities);\n rows.push({\n host: adapter.id,\n surface,\n support: native ? \"native\" : \"skip-warn\",\n reason: explainReason(adapter.id, surface, native),\n });\n }\n }\n\n rows.sort((a, b) =>\n a.host === b.host ? a.surface.localeCompare(b.surface) : a.host.localeCompare(b.host),\n );\n return rows;\n}\n\n/**\n * The per-DECLARED-event hooks verdict for one host. A connector's hooks surface\n * is `native` only when EVERY event it declares can fire on the host; if any\n * declared event has no native equivalent the row is `skip-warn` and the reason\n * names the specific dead events (the same events install skip-warns). This is\n * the fix for the OR-across-all-events false green: a Stop-only connector on a\n * host that cannot fire Stop now reports skip-warn, not native.\n *\n * Reuses {@link hostCanFireEvent} — the single per-event source of truth shared\n * with {@link SURFACE_PREDICATES} and simulate's runtime verdict — so explain\n * never re-derives the per-event rules.\n */\nfunction hooksRow(\n connector: ResolvedConnector,\n host: PlatformId,\n capabilities: PlatformCapabilities,\n): ExplainRow {\n const declared = connector.hookEvents;\n const dead = declared.filter((e) => !hostCanFireEvent(capabilities, e));\n if (dead.length === 0) {\n return {\n host,\n surface: \"hooks\",\n support: \"native\",\n reason: `${host} can fire every declared hook event (${declared.join(\", \")})`,\n };\n }\n const fireable = declared.filter((e) => hostCanFireEvent(capabilities, e));\n const reason =\n fireable.length === 0\n ? `${host} cannot fire any declared hook event (${dead.join(\", \")}); install skip-warns each`\n : `${host} cannot fire ${dead.join(\", \")} (install skip-warns these); honors ${fireable.join(\", \")}`;\n return { host, surface: \"hooks\", support: \"skip-warn\", reason };\n}\n\n/**\n * The human-readable reason for a native/skip-warn cell. `server` is a special\n * case: the predicate is CAPABILITY-based (the host advertises ≥1 MCP\n * transport), but advertising a transport does NOT guarantee a writable\n * registration — e.g. jetbrains-copilot advertises stdio yet its installServer\n * skip-warns because MCP is managed in IDE settings. So the server reason states\n * the verdict is capability-based and registration may be host-managed, rather\n * than promising a write. (A precise per-adapter installServer dry-run is a\n * Phase-2 enhancement — until then this avoids over-promising.)\n */\nfunction explainReason(host: PlatformId, surface: SurfaceName, native: boolean): string {\n if (surface === \"server\") {\n return native\n ? `${host} advertises an MCP transport (capability-based; registration may be host-managed)`\n : `${host} advertises no MCP transport; install skip-warns`;\n }\n return native\n ? `${host} natively supports ${surface}`\n : `${host} cannot honor ${surface}; install skip-warns`;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// simulate — the real adapter parse → handler → format chain, inline\n// ─────────────────────────────────────────────────────────────────────────\n\n/** What to drive through the harness: one host, one surface, one raw payload. */\nexport interface SimulateOptions {\n surface: \"hooks\" | \"statusline\";\n host: PlatformId | string;\n /** REQUIRED when `surface === \"hooks\"`: which normalized lifecycle event. */\n event?: HookEventName;\n /** The host-shaped RAW payload (what the host would pipe in on stdin). */\n input: unknown;\n}\n\n/** The harness verdict: did the host actually honor the connector's response? */\nexport interface SimulateResult {\n /** True when the host's native reply carries the connector's intent. */\n honored: boolean;\n /** The host-native stdout the adapter would emit (when there is one). */\n hostReply?: string;\n /** Human-readable why — names the documented degradation when honored:false. */\n reason: string;\n}\n\n/**\n * Tolerantly coerce the raw payload, mirroring the runtime's parseStdin: a\n * string is JSON-parsed (empty/malformed → `{}`); a nullish value → `{}`; any\n * other value (already-parsed object) is passed through untouched.\n */\nfunction coerceInput(input: unknown): unknown {\n if (input == null) return {};\n if (typeof input === \"string\") {\n const trimmed = input.trim();\n if (trimmed === \"\") return {};\n try {\n return JSON.parse(trimmed);\n } catch {\n return {};\n }\n }\n return input;\n}\n\n/** Normalize a handler's return into a concrete response (void/non-object → `{}`). */\nfunction normalizeResponse(value: HookResponse | void): HookResponse {\n if (value == null || typeof value !== \"object\") return {};\n return value;\n}\n\n/**\n * The decoded shape of a host's native hook reply on stdout. Every json-stdio\n * adapter writes a SUBSET of these fields (claude-code / codex share the\n * `hookSpecificOutput` envelope; Stop-class continuation uses the TOP-LEVEL\n * `decision:\"block\"`). We read the DECODED fields — never substring-match the\n * serialized JSON, which a path/newline/quote in the payload would break.\n */\ninterface ParsedReply {\n /** Top-level Stop-class continuation: {\"decision\":\"block\",\"reason\"}. */\n decision?: unknown;\n reason?: unknown;\n /** Top-level Claude context channel (no adapter emits it yet; future-proofing). */\n systemMessage?: unknown;\n hookSpecificOutput?: {\n hookEventName?: unknown;\n additionalContext?: unknown;\n permissionDecision?: unknown;\n permissionDecisionReason?: unknown;\n updatedInput?: unknown;\n /** PermissionRequest nested envelope: decision:{behavior:\"allow\"|\"deny\", updatedInput?}. */\n decision?: { behavior?: unknown; updatedInput?: unknown };\n };\n}\n\n/**\n * Tolerantly decode a reply's stdout into {@link ParsedReply}. Empty / absent /\n * unparseable stdout is a legitimate \"no payload\" signal (the adapter wrote a\n * bare exit-0) → `undefined`, the honest \"this decision had no stdout path\"\n * verdict input.\n */\nfunction parseReplyStdout(stdout: string | undefined): ParsedReply | undefined {\n if (stdout == null || stdout.trim() === \"\") return undefined;\n try {\n const value = JSON.parse(stdout);\n return value != null && typeof value === \"object\"\n ? (value as ParsedReply)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Structural deep-equal for plain JSON values (objects/arrays/primitives). */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b || a == null || b == null) return false;\n if (typeof a !== \"object\") return false;\n const aArr = Array.isArray(a);\n if (aArr !== Array.isArray(b)) return false;\n if (aArr) {\n const x = a as unknown[];\n const y = b as unknown[];\n return x.length === y.length && x.every((v, i) => deepEqual(v, y[i]));\n }\n const x = a as Record<string, unknown>;\n const y = b as Record<string, unknown>;\n const xk = Object.keys(x);\n const yk = Object.keys(y);\n return xk.length === yk.length && xk.every((k) => deepEqual(x[k], y[k]));\n}\n\n/**\n * Decide whether the host HONORED a decision-bearing response, judging the\n * PARSED reply against each adapter's ACTUAL (event, decision) contract — never\n * by substring-matching the serialized JSON. `allow`/no-decision is always\n * pass-through honored; every other decision is honored only when the decoded\n * reply carries that exact intent, and the verdict names the documented\n * degradation when it does not.\n */\nfunction judgeHookHonor(\n host: string,\n event: HookEventName,\n response: HookResponse,\n stdout: string | undefined,\n): { honored: boolean; reason: string } {\n const decision = response.decision;\n if (decision === undefined || decision === \"allow\") {\n return { honored: true, reason: \"pass-through allow\" };\n }\n\n const reply = parseReplyStdout(stdout);\n const hso = reply?.hookSpecificOutput;\n\n if (decision === \"context\") {\n // Honored only when the DECODED additionalContext equals what the handler\n // asked to inject (claude-code's hookSpecificOutput.additionalContext, or a\n // future top-level systemMessage). codex only emits this on\n // SessionStart/PostToolUse — every other event silently drops it.\n const want = response.additionalContext;\n const got = hso?.additionalContext ?? reply?.systemMessage;\n if (reply && got === want) {\n return { honored: true, reason: `${host} injects context on ${event}` };\n }\n return {\n honored: false,\n reason: `${host} drops context on ${event} (no stdout path)`,\n };\n }\n\n if (decision === \"deny\") {\n if (!reply) {\n return {\n honored: false,\n reason: `${host} drops deny on ${event} (deny not honored; fails open to allow)`,\n };\n }\n // A real block: PreToolUse's permissionDecision:\"deny\", or the\n // PermissionRequest nested decision.behavior:\"deny\".\n if (hso?.permissionDecision === \"deny\" || hso?.decision?.behavior === \"deny\") {\n return { honored: true, reason: `${host} blocks ${event}` };\n }\n // Stop-class continuation: top-level decision:\"block\" KEEPS the session /\n // subagent running (persistence) — the SEMANTIC OPPOSITE of a block. Honored\n // (the reply carried the intent), but the reason must not say \"blocks\".\n if (reply.decision === \"block\") {\n return {\n honored: true,\n reason: `${host} continues the session/subagent on ${event} (persistence) — NOT a block`,\n };\n }\n // SubagentStart / PostToolUseFailure DEGRADE a deny to a context note — the\n // spawn/failure is not actually blocked.\n if (hso?.additionalContext != null) {\n return {\n honored: false,\n reason: `${host} degrades deny to a context note on ${event}; spawn/failure not blocked`,\n };\n }\n return {\n honored: false,\n reason: `${host} drops deny on ${event} (deny not honored; fails open to allow)`,\n };\n }\n\n if (decision === \"ask\") {\n if (hso?.permissionDecision === \"ask\") {\n return { honored: true, reason: `${host} asks on ${event}` };\n }\n // On PermissionRequest, ask/void falls through to the host's NATIVE dialog\n // (the dialog IS the ask), which the adapter expresses as a bare exit-0.\n if (event === \"PermissionRequest\" && !reply) {\n return {\n honored: true,\n reason: `${host} shows the native confirmation dialog on ${event} (the ask)`,\n };\n }\n return {\n honored: false,\n reason: `${host} drops ask on ${event} (no ask path)`,\n };\n }\n\n // decision === \"modify\": honored only when the decoded updatedInput deep-equals\n // what the handler asked to write (hookSpecificOutput.updatedInput, or the\n // PermissionRequest nested decision.updatedInput).\n const wrote = hso?.updatedInput ?? hso?.decision?.updatedInput;\n if (reply && wrote !== undefined && deepEqual(wrote, response.updatedInput)) {\n return { honored: true, reason: `${host} rewrites tool input on ${event}` };\n }\n return {\n honored: false,\n reason: `${host} drops modify on ${event} (modify not honored)`,\n };\n}\n\n/**\n * Run the connector against ONE host-shaped payload through the REAL adapter\n * path and report whether the host honors the response. Self-contained (does not\n * touch the registered-connector loader or telemetry) and fail-safe: any throw\n * in the chain degrades to `honored:false` with the error message, never rejects.\n */\nexport async function simulate(\n connector: ResolvedConnector,\n opts: SimulateOptions,\n): Promise<SimulateResult> {\n try {\n const adapter = await loadAdapter(opts.host);\n if (!adapter) {\n return { honored: false, reason: `unknown host \"${opts.host}\"` };\n }\n\n if (opts.surface === \"statusline\") {\n if (\n !(adapter.capabilities.supportsStatusline ?? false) ||\n !adapter.parseStatusInput ||\n !adapter.formatStatusOutput\n ) {\n return { honored: false, reason: `${opts.host} has no statusline surface` };\n }\n // Guarding on the TOP-LEVEL render is sufficient: a `hosts`-only statusline\n // (a hosts: map with no top-level render) is rejected at defineConnector, so\n // a connector that targets `opts.host` only via hosts[] still has a top-level\n // render here. (If that author-time invariant ever relaxes, revisit this.)\n if (!connector.statusline || typeof connector.statusline.render !== \"function\") {\n return { honored: false, reason: \"connector declares no statusline\" };\n }\n const ctx = adapter.parseStatusInput(coerceInput(opts.input));\n ctx.connectorId = connector.id;\n // Defensive: parseStatusInput now sets ctx.capabilities (it is required on\n // StatuslineContext), but a future adapter could omit it — backfill from\n // the adapter so render() can always read ctx.capabilities.\n if (ctx.capabilities == null) ctx.capabilities = adapter.capabilities;\n // Per-host render override, mirroring the runtime: hosts[host].render wins\n // over the top-level render; an unlisted host falls back to top-level.\n const perHost = connector.statusline.hosts?.[opts.host as PlatformId]?.render;\n const render =\n typeof perHost === \"function\" ? perHost : connector.statusline.render;\n const rendered = await render(ctx);\n const line = rendered == null ? \"\" : String(rendered);\n const reply = adapter.formatStatusOutput(line);\n return {\n honored: true,\n ...(reply.stdout !== undefined ? { hostReply: reply.stdout } : {}),\n reason: \"rendered\",\n };\n }\n\n // surface === \"hooks\"\n const event = opts.event;\n if (!event) {\n return { honored: false, reason: \"event is required when surface === \\\"hooks\\\"\" };\n }\n if (!adapter.parseEvent || !adapter.formatReply) {\n return { honored: false, reason: `${opts.host} has no hook runtime (mcp-only)` };\n }\n\n const evt = adapter.parseEvent(event, coerceInput(opts.input));\n evt.connectorId = connector.id;\n // Mirror the runtime: runHook backfills evt.capabilities from the adapter so\n // a handler reading evt.capabilities behaves the same here. (scope/telemetry\n // are runtime-only — recovered from the registered meta / store, which the\n // offline harness deliberately never touches — so they stay undefined.)\n evt.capabilities = adapter.capabilities;\n\n // Guarding on the TOP-LEVEL handler is sufficient: a `hosts`-only hook (a\n // hosts: map with no top-level handler) is rejected at defineConnector, so a\n // host targeted only via hosts[] still has a top-level handler here. (If that\n // author-time invariant ever relaxes, revisit this.)\n const definition = connector.hooks[event];\n if (!definition || typeof definition.handler !== \"function\") {\n return { honored: false, reason: `connector declares no ${event} handler` };\n }\n\n // Matcher filtering, in lockstep with runHook: when the connector's matcher\n // is set and the event's subject (tool name, or agent type for Subagent*\n // events) does not match, the host never runs the handler — so the harness\n // must NOT run it either, and reports the (honored) exclusion. Reuses the\n // runtime helpers directly so the two stay byte-for-byte aligned.\n const subject = eventMatcherSubject(evt as NormalizedEvent);\n if (subject !== undefined) {\n const re = compileMatcher(definition.matcher);\n if (re && !re.test(subject)) {\n return {\n honored: true,\n reason: `matcher excludes ${subject} (handler not run)`,\n };\n }\n }\n\n // Per-host handler override, mirroring runHook: hosts[host].handler wins\n // over the top-level handler; an unlisted host falls back to top-level.\n const perHost = definition.hosts?.[opts.host as PlatformId]?.handler;\n const handler = typeof perHost === \"function\" ? perHost : definition.handler;\n const response = normalizeResponse(\n await handler(evt as never),\n );\n const reply = adapter.formatReply(event, response);\n const verdict = judgeHookHonor(String(opts.host), event, response, reply.stdout);\n return {\n honored: verdict.honored,\n ...(reply.stdout !== undefined ? { hostReply: reply.stdout } : {}),\n reason: verdict.reason,\n };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const verb = opts.surface === \"statusline\" ? \"render\" : \"handler\";\n return { honored: false, reason: `${verb} threw: ${message}` };\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// explainHooks — the per-(host, event) honor verdict (powers doctor --explain)\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * One per-(host, event) cell of {@link explainHooks}.\n *\n * - \"honored\" — the host fires the event AND carries the connector's response\n * intent (simulate's runtime verdict, e.g. a real deny/block).\n * - \"degraded\" — the host fires the event but silently DROPS the response's\n * decision (e.g. codex fires UserPromptSubmit but has no stdout\n * path for a context injection, so the injection vanishes).\n * - \"dropped\" — the host cannot fire the event at all (no native equivalent /\n * mcp-only host); install skip-warns it and it never runs.\n */\nexport interface HookEventVerdict {\n host: PlatformId;\n event: HookEventName;\n verdict: \"honored\" | \"degraded\" | \"dropped\";\n /** The simulate()-grade reason string (names the documented degradation). */\n reason: string;\n}\n\n/**\n * A subject (tool name / agent type) that SATISFIES the connector's matcher for\n * this event, so a matcher-gated hook actually runs and the verdict reflects the\n * real honor — not a spurious \"matcher excludes my arbitrary synthetic tool\".\n * A plain-literal matcher (no regex metacharacters — the common case, e.g.\n * `acme_query`) IS the subject. A missing/empty matcher matches everything, and\n * a complex regex falls back to the generic subject (then an honest \"matcher\n * excludes\" verdict surfaces — the dev's matcher genuinely would not fire here).\n */\nfunction matchingSubject(matcher: string | undefined, fallback: string): string {\n if (!matcher || matcher === \"\") return fallback;\n return /^[\\w.-]+$/.test(matcher) ? matcher : fallback;\n}\n\n/**\n * A minimal host-shaped synthetic payload so the real parse→handler→format\n * chain has something to run on. The harness coerces a `{}` to a valid event,\n * but tool/subagent events read a subject (tool name / agent type) the connector\n * matcher may filter on — so we plant a subject that SATISFIES the connector's\n * declared matcher ({@link matchingSubject}) to exercise the honor path.\n */\nfunction syntheticPayloadFor(\n event: HookEventName,\n matcher: string | undefined,\n): Record<string, unknown> {\n switch (event) {\n case \"PreToolUse\":\n case \"PostToolUse\":\n case \"PostToolUseFailure\":\n case \"PermissionRequest\": {\n const tool = matchingSubject(matcher, \"Bash\");\n return { tool_name: tool, tool_input: { command: \"echo hi\" } };\n }\n case \"SubagentStart\":\n case \"SubagentStop\": {\n const agent = matchingSubject(matcher, \"general\");\n return { agent_type: agent, subagent_type: agent };\n }\n case \"UserPromptSubmit\":\n return { prompt: \"hello\" };\n default:\n return {};\n }\n}\n\n/**\n * The per-(host, event) hook honor matrix for the connector's DECLARED events\n * across `hosts` — the trustworthy detail behind `doctor --explain`.\n *\n * For each (host, declared event): when the host cannot fire the event\n * ({@link hostCanFireEvent} is false, OR the host has no hook runtime at all)\n * the cell is `dropped`; otherwise it RUNS the real chain via {@link simulate}\n * and reports `honored` (simulate honored the response) or `degraded` (the host\n * fired but dropped the decision). Reuses the per-event signal + simulate's\n * verdict — no per-event honor logic is re-derived here.\n */\nexport async function explainHooks(\n connector: ResolvedConnector,\n hosts: (PlatformId | string)[],\n): Promise<HookEventVerdict[]> {\n const events = connector.hookEvents;\n const rows: HookEventVerdict[] = [];\n\n for (const host of hosts) {\n const adapter = await loadAdapter(host);\n if (!adapter) {\n for (const event of events) {\n rows.push({\n host: host as PlatformId,\n event,\n verdict: \"dropped\",\n reason: `unknown host \"${host}\"`,\n });\n }\n continue;\n }\n\n // An mcp-only host (no hook runtime) drops every declared event.\n const hasHookRuntime = !!adapter.parseEvent && !!adapter.formatReply;\n\n for (const event of events) {\n if (!hasHookRuntime) {\n rows.push({\n host: adapter.id,\n event,\n verdict: \"dropped\",\n reason: `${adapter.id} has no hook runtime (mcp-only) — ${event} never fires`,\n });\n continue;\n }\n if (!hostCanFireEvent(adapter.capabilities, event)) {\n rows.push({\n host: adapter.id,\n event,\n verdict: \"dropped\",\n reason: `${adapter.id} has no ${event} equivalent — install skip-warns it; never fires`,\n });\n continue;\n }\n const sim = await simulate(connector, {\n surface: \"hooks\",\n host: adapter.id,\n event,\n input: syntheticPayloadFor(event, connector.hooks[event]?.matcher),\n });\n rows.push({\n host: adapter.id,\n event,\n verdict: sim.honored ? \"honored\" : \"degraded\",\n reason: sim.reason,\n });\n }\n }\n\n rows.sort((a, b) =>\n a.host === b.host ? a.event.localeCompare(b.event) : a.host.localeCompare(b.host),\n );\n return rows;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAoEA,SAAS,uBAAuB,WAA6C;AAC3E,QAAM,MAAqB,CAAC;AAC5B,MAAI,UAAU,OAAQ,KAAI,KAAK,QAAQ;AACvC,MAAI,OAAO,KAAK,UAAU,KAAK,EAAE,SAAS,EAAG,KAAI,KAAK,OAAO;AAC7D,MAAI,UAAU,SAAS,SAAS,EAAG,KAAI,KAAK,UAAU;AACtD,MAAI,UAAU,OAAO,SAAS,EAAG,KAAI,KAAK,QAAQ;AAClD,MAAI,UAAU,UAAU,SAAS,EAAG,KAAI,KAAK,WAAW;AACxD,MAAI,UAAU,OAAO,SAAS,EAAG,KAAI,KAAK,QAAQ;AAClD,MAAI,UAAU,WAAY,KAAI,KAAK,YAAY;AAC/C,MAAI,UAAU,QAAQ,SAAS,EAAG,KAAI,KAAK,SAAS;AACpD,SAAO;AACT;AAOA,SAAS,0BACP,UACe;AACf,QAAM,MAAqB,CAAC;AAC5B,MAAI,CAAC,SAAU,QAAO;AACtB,OAAK,SAAS,aAAa,UAAU,KAAK,EAAG,KAAI,KAAK,aAAa;AACnE,MAAI,SAAS,eAAe,QAAQ,OAAO,KAAK,SAAS,WAAW,EAAE,SAAS,GAAG;AAChF,QAAI,KAAK,aAAa;AAAA,EACxB;AACA,SAAO;AACT;AASA,SAAS,kBACP,WACA,MACA,SACS;AACT,QAAM,WAAW,UAAU,UAAU,IAAI;AACzC,MAAI,CAAC,SAAU,QAAO;AACtB,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,SAAS,WAAW;AAAA,IAC7B,KAAK;AACH,aAAO,SAAS,UAAU;AAAA,IAC5B,KAAK;AACH,aAAO,SAAS,aAAa;AAAA,IAC/B,KAAK;AACH,aAAO,SAAS,WAAW;AAAA,IAC7B,KAAK;AACH,aAAO,SAAS,cAAc;AAAA,IAChC,KAAK;AACH,aAAO,SAAS,WAAW;AAAA,IAC7B,KAAK;AACH,aAAO,SAAS,eAAe;AAAA,IACjC,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAEH,aAAO;AAAA,EACX;AACF;AAOA,eAAsB,QAAQ,WAAqD;AACjF,QAAM,iBAAiB,uBAAuB,SAAS;AACvD,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,OAAqB,CAAC;AAE5B,aAAW,WAAW,UAAU;AAI9B,UAAM,WAAW,UAAU,UAAU,QAAQ,EAAE;AAC/C,UAAM,WAAW;AAAA,MACf,GAAG;AAAA,MACH,GAAG,0BAA0B,QAAQ;AAAA,IACvC;AACA,eAAW,WAAW,UAAU;AAC9B,UAAI,kBAAkB,WAAW,QAAQ,IAAI,OAAO,GAAG;AACrD,aAAK,KAAK;AAAA,UACR,MAAM,QAAQ;AAAA,UACd;AAAA,UACA,SAAS;AAAA,UACT,QAAQ,2BAA2B,QAAQ,EAAE,eAAe,QAAQ,EAAE,IAAI,OAAO;AAAA,QACnF,CAAC;AACD;AAAA,MACF;AAKA,UAAI,YAAY,SAAS;AACvB,aAAK,KAAK,SAAS,WAAW,QAAQ,IAAI,QAAQ,YAAY,CAAC;AAC/D;AAAA,MACF;AACA,YAAM,SAAS,mBAAmB,OAAO,EAAE,QAAQ,YAAY;AAC/D,WAAK,KAAK;AAAA,QACR,MAAM,QAAQ;AAAA,QACd;AAAA,QACA,SAAS,SAAS,WAAW;AAAA,QAC7B,QAAQ,cAAc,QAAQ,IAAI,SAAS,MAAM;AAAA,MACnD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,OAAK;AAAA,IAAK,CAAC,GAAG,MACZ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,cAAc,EAAE,OAAO,IAAI,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,EACtF;AACA,SAAO;AACT;AAcA,SAAS,SACP,WACA,MACA,cACY;AACZ,QAAM,WAAW,UAAU;AAC3B,QAAM,OAAO,SAAS,OAAO,CAAC,MAAM,CAAC,iBAAiB,cAAc,CAAC,CAAC;AACtE,MAAI,KAAK,WAAW,GAAG;AACrB,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,SAAS;AAAA,MACT,QAAQ,GAAG,IAAI,wCAAwC,SAAS,KAAK,IAAI,CAAC;AAAA,IAC5E;AAAA,EACF;AACA,QAAM,WAAW,SAAS,OAAO,CAAC,MAAM,iBAAiB,cAAc,CAAC,CAAC;AACzE,QAAM,SACJ,SAAS,WAAW,IAChB,GAAG,IAAI,yCAAyC,KAAK,KAAK,IAAI,CAAC,+BAC/D,GAAG,IAAI,gBAAgB,KAAK,KAAK,IAAI,CAAC,uCAAuC,SAAS,KAAK,IAAI,CAAC;AACtG,SAAO,EAAE,MAAM,SAAS,SAAS,SAAS,aAAa,OAAO;AAChE;AAYA,SAAS,cAAc,MAAkB,SAAsB,QAAyB;AACtF,MAAI,YAAY,UAAU;AACxB,WAAO,SACH,GAAG,IAAI,sFACP,GAAG,IAAI;AAAA,EACb;AACA,SAAO,SACH,GAAG,IAAI,sBAAsB,OAAO,KACpC,GAAG,IAAI,iBAAiB,OAAO;AACrC;AA+BA,SAAS,YAAY,OAAyB;AAC5C,MAAI,SAAS,KAAM,QAAO,CAAC;AAC3B,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,YAAY,GAAI,QAAO,CAAC;AAC5B,QAAI;AACF,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,kBAAkB,OAA0C;AACnE,MAAI,SAAS,QAAQ,OAAO,UAAU,SAAU,QAAO,CAAC;AACxD,SAAO;AACT;AAgCA,SAAS,iBAAiB,QAAqD;AAC7E,MAAI,UAAU,QAAQ,OAAO,KAAK,MAAM,GAAI,QAAO;AACnD,MAAI;AACF,UAAM,QAAQ,KAAK,MAAM,MAAM;AAC/B,WAAO,SAAS,QAAQ,OAAO,UAAU,WACpC,QACD;AAAA,EACN,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAAS,UAAU,GAAY,GAAqB;AAClD,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,OAAO,MAAM,OAAO,KAAK,KAAK,QAAQ,KAAK,KAAM,QAAO;AAC5D,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,MAAI,SAAS,MAAM,QAAQ,CAAC,EAAG,QAAO;AACtC,MAAI,MAAM;AACR,UAAMA,KAAI;AACV,UAAMC,KAAI;AACV,WAAOD,GAAE,WAAWC,GAAE,UAAUD,GAAE,MAAM,CAAC,GAAG,MAAM,UAAU,GAAGC,GAAE,CAAC,CAAC,CAAC;AAAA,EACtE;AACA,QAAM,IAAI;AACV,QAAM,IAAI;AACV,QAAM,KAAK,OAAO,KAAK,CAAC;AACxB,QAAM,KAAK,OAAO,KAAK,CAAC;AACxB,SAAO,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC,MAAM,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACzE;AAUA,SAAS,eACP,MACA,OACA,UACA,QACsC;AACtC,QAAM,WAAW,SAAS;AAC1B,MAAI,aAAa,UAAa,aAAa,SAAS;AAClD,WAAO,EAAE,SAAS,MAAM,QAAQ,qBAAqB;AAAA,EACvD;AAEA,QAAM,QAAQ,iBAAiB,MAAM;AACrC,QAAM,MAAM,OAAO;AAEnB,MAAI,aAAa,WAAW;AAK1B,UAAM,OAAO,SAAS;AACtB,UAAM,MAAM,KAAK,qBAAqB,OAAO;AAC7C,QAAI,SAAS,QAAQ,MAAM;AACzB,aAAO,EAAE,SAAS,MAAM,QAAQ,GAAG,IAAI,uBAAuB,KAAK,GAAG;AAAA,IACxE;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,GAAG,IAAI,qBAAqB,KAAK;AAAA,IAC3C;AAAA,EACF;AAEA,MAAI,aAAa,QAAQ;AACvB,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,GAAG,IAAI,kBAAkB,KAAK;AAAA,MACxC;AAAA,IACF;AAGA,QAAI,KAAK,uBAAuB,UAAU,KAAK,UAAU,aAAa,QAAQ;AAC5E,aAAO,EAAE,SAAS,MAAM,QAAQ,GAAG,IAAI,WAAW,KAAK,GAAG;AAAA,IAC5D;AAIA,QAAI,MAAM,aAAa,SAAS;AAC9B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,GAAG,IAAI,sCAAsC,KAAK;AAAA,MAC5D;AAAA,IACF;AAGA,QAAI,KAAK,qBAAqB,MAAM;AAClC,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,GAAG,IAAI,uCAAuC,KAAK;AAAA,MAC7D;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,GAAG,IAAI,kBAAkB,KAAK;AAAA,IACxC;AAAA,EACF;AAEA,MAAI,aAAa,OAAO;AACtB,QAAI,KAAK,uBAAuB,OAAO;AACrC,aAAO,EAAE,SAAS,MAAM,QAAQ,GAAG,IAAI,YAAY,KAAK,GAAG;AAAA,IAC7D;AAGA,QAAI,UAAU,uBAAuB,CAAC,OAAO;AAC3C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,GAAG,IAAI,4CAA4C,KAAK;AAAA,MAClE;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,GAAG,IAAI,iBAAiB,KAAK;AAAA,IACvC;AAAA,EACF;AAKA,QAAM,QAAQ,KAAK,gBAAgB,KAAK,UAAU;AAClD,MAAI,SAAS,UAAU,UAAa,UAAU,OAAO,SAAS,YAAY,GAAG;AAC3E,WAAO,EAAE,SAAS,MAAM,QAAQ,GAAG,IAAI,2BAA2B,KAAK,GAAG;AAAA,EAC5E;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,GAAG,IAAI,oBAAoB,KAAK;AAAA,EAC1C;AACF;AAQA,eAAsB,SACpB,WACA,MACyB;AACzB,MAAI;AACF,UAAM,UAAU,MAAM,YAAY,KAAK,IAAI;AAC3C,QAAI,CAAC,SAAS;AACZ,aAAO,EAAE,SAAS,OAAO,QAAQ,iBAAiB,KAAK,IAAI,IAAI;AAAA,IACjE;AAEA,QAAI,KAAK,YAAY,cAAc;AACjC,UACE,EAAE,QAAQ,aAAa,sBAAsB,UAC7C,CAAC,QAAQ,oBACT,CAAC,QAAQ,oBACT;AACA,eAAO,EAAE,SAAS,OAAO,QAAQ,GAAG,KAAK,IAAI,6BAA6B;AAAA,MAC5E;AAKA,UAAI,CAAC,UAAU,cAAc,OAAO,UAAU,WAAW,WAAW,YAAY;AAC9E,eAAO,EAAE,SAAS,OAAO,QAAQ,mCAAmC;AAAA,MACtE;AACA,YAAM,MAAM,QAAQ,iBAAiB,YAAY,KAAK,KAAK,CAAC;AAC5D,UAAI,cAAc,UAAU;AAI5B,UAAI,IAAI,gBAAgB,KAAM,KAAI,eAAe,QAAQ;AAGzD,YAAMC,WAAU,UAAU,WAAW,QAAQ,KAAK,IAAkB,GAAG;AACvE,YAAM,SACJ,OAAOA,aAAY,aAAaA,WAAU,UAAU,WAAW;AACjE,YAAM,WAAW,MAAM,OAAO,GAAG;AACjC,YAAM,OAAO,YAAY,OAAO,KAAK,OAAO,QAAQ;AACpD,YAAMC,SAAQ,QAAQ,mBAAmB,IAAI;AAC7C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,GAAIA,OAAM,WAAW,SAAY,EAAE,WAAWA,OAAM,OAAO,IAAI,CAAC;AAAA,QAChE,QAAQ;AAAA,MACV;AAAA,IACF;AAGA,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,OAAO;AACV,aAAO,EAAE,SAAS,OAAO,QAAQ,6CAA+C;AAAA,IAClF;AACA,QAAI,CAAC,QAAQ,cAAc,CAAC,QAAQ,aAAa;AAC/C,aAAO,EAAE,SAAS,OAAO,QAAQ,GAAG,KAAK,IAAI,kCAAkC;AAAA,IACjF;AAEA,UAAM,MAAM,QAAQ,WAAW,OAAO,YAAY,KAAK,KAAK,CAAC;AAC7D,QAAI,cAAc,UAAU;AAK5B,QAAI,eAAe,QAAQ;AAM3B,UAAM,aAAa,UAAU,MAAM,KAAK;AACxC,QAAI,CAAC,cAAc,OAAO,WAAW,YAAY,YAAY;AAC3D,aAAO,EAAE,SAAS,OAAO,QAAQ,yBAAyB,KAAK,WAAW;AAAA,IAC5E;AAOA,UAAM,UAAU,oBAAoB,GAAsB;AAC1D,QAAI,YAAY,QAAW;AACzB,YAAM,KAAK,eAAe,WAAW,OAAO;AAC5C,UAAI,MAAM,CAAC,GAAG,KAAK,OAAO,GAAG;AAC3B,eAAO;AAAA,UACL,SAAS;AAAA,UACT,QAAQ,oBAAoB,OAAO;AAAA,QACrC;AAAA,MACF;AAAA,IACF;AAIA,UAAM,UAAU,WAAW,QAAQ,KAAK,IAAkB,GAAG;AAC7D,UAAM,UAAU,OAAO,YAAY,aAAa,UAAU,WAAW;AACrE,UAAM,WAAW;AAAA,MACf,MAAM,QAAQ,GAAY;AAAA,IAC5B;AACA,UAAM,QAAQ,QAAQ,YAAY,OAAO,QAAQ;AACjD,UAAM,UAAU,eAAe,OAAO,KAAK,IAAI,GAAG,OAAO,UAAU,MAAM,MAAM;AAC/E,WAAO;AAAA,MACL,SAAS,QAAQ;AAAA,MACjB,GAAI,MAAM,WAAW,SAAY,EAAE,WAAW,MAAM,OAAO,IAAI,CAAC;AAAA,MAChE,QAAQ,QAAQ;AAAA,IAClB;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAM,OAAO,KAAK,YAAY,eAAe,WAAW;AACxD,WAAO,EAAE,SAAS,OAAO,QAAQ,GAAG,IAAI,WAAW,OAAO,GAAG;AAAA,EAC/D;AACF;AAkCA,SAAS,gBAAgB,SAA6B,UAA0B;AAC9E,MAAI,CAAC,WAAW,YAAY,GAAI,QAAO;AACvC,SAAO,YAAY,KAAK,OAAO,IAAI,UAAU;AAC/C;AASA,SAAS,oBACP,OACA,SACyB;AACzB,UAAQ,OAAO;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,qBAAqB;AACxB,YAAM,OAAO,gBAAgB,SAAS,MAAM;AAC5C,aAAO,EAAE,WAAW,MAAM,YAAY,EAAE,SAAS,UAAU,EAAE;AAAA,IAC/D;AAAA,IACA,KAAK;AAAA,IACL,KAAK,gBAAgB;AACnB,YAAM,QAAQ,gBAAgB,SAAS,SAAS;AAChD,aAAO,EAAE,YAAY,OAAO,eAAe,MAAM;AAAA,IACnD;AAAA,IACA,KAAK;AACH,aAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAaA,eAAsB,aACpB,WACA,OAC6B;AAC7B,QAAM,SAAS,UAAU;AACzB,QAAM,OAA2B,CAAC;AAElC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,MAAM,YAAY,IAAI;AACtC,QAAI,CAAC,SAAS;AACZ,iBAAW,SAAS,QAAQ;AAC1B,aAAK,KAAK;AAAA,UACR;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT,QAAQ,iBAAiB,IAAI;AAAA,QAC/B,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAGA,UAAM,iBAAiB,CAAC,CAAC,QAAQ,cAAc,CAAC,CAAC,QAAQ;AAEzD,eAAW,SAAS,QAAQ;AAC1B,UAAI,CAAC,gBAAgB;AACnB,aAAK,KAAK;AAAA,UACR,MAAM,QAAQ;AAAA,UACd;AAAA,UACA,SAAS;AAAA,UACT,QAAQ,GAAG,QAAQ,EAAE,0CAAqC,KAAK;AAAA,QACjE,CAAC;AACD;AAAA,MACF;AACA,UAAI,CAAC,iBAAiB,QAAQ,cAAc,KAAK,GAAG;AAClD,aAAK,KAAK;AAAA,UACR,MAAM,QAAQ;AAAA,UACd;AAAA,UACA,SAAS;AAAA,UACT,QAAQ,GAAG,QAAQ,EAAE,WAAW,KAAK;AAAA,QACvC,CAAC;AACD;AAAA,MACF;AACA,YAAM,MAAM,MAAM,SAAS,WAAW;AAAA,QACpC,SAAS;AAAA,QACT,MAAM,QAAQ;AAAA,QACd;AAAA,QACA,OAAO,oBAAoB,OAAO,UAAU,MAAM,KAAK,GAAG,OAAO;AAAA,MACnE,CAAC;AACD,WAAK,KAAK;AAAA,QACR,MAAM,QAAQ;AAAA,QACd;AAAA,QACA,SAAS,IAAI,UAAU,YAAY;AAAA,QACnC,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAEA,OAAK;AAAA,IAAK,CAAC,GAAG,MACZ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,cAAc,EAAE,KAAK,IAAI,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,EAClF;AACA,SAAO;AACT;","names":["x","y","perHost","reply"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/package.ts","../src/core/package-formats/claude-family.ts","../src/core/package-formats/shared.ts","../src/core/package-formats/cursor.ts","../src/core/package-formats/gemini.ts","../src/core/package-formats/agy.ts","../src/core/package-formats/kimi.ts","../src/core/package-formats/npm.ts","../src/core/package-formats/mcp-server.ts","../src/core/package-formats/mcpb.ts"],"sourcesContent":["/**\n * core/package — emit a marketplace/extension-installable connector bundle.\n *\n * Turns a {@link ResolvedConnector} into a self-contained plugin/extension bundle\n * for ANY of the emit-feasible plugin/marketplace formats the agent ecosystem\n * supports. The format-specific emitters live under `package-formats/<family>.ts`,\n * each conforming to the shared {@link FormatEmitter} signature; this module is\n * the single, consistent dispatch over them.\n *\n * Supported formats (PackageFormat):\n * • claude-plugin — Claude Code / codex / vscode-copilot / openclaw / omp\n * • codex-plugin — Codex `.codex-plugin/` manifest variant of claude-plugin\n * • copilot-plugin — GitHub Copilot CLI (claude-plugin bundle, --host copilot-cli)\n * • factory-plugin — droid `.factory-plugin/` (droids/, mcp.json) variant\n * • gemini-extension — Gemini CLI extension (gemini-extension.json + TOML commands)\n * • qwen-extension — Qwen Code extension (qwen-extension.json + Markdown commands)\n * • agy-plugin — Antigravity CLI/IDE (root plugin.json + mcp_config.json)\n * • cursor-plugin — Cursor (.cursor-plugin/ + pointer fields + marketplace.json)\n * • kimi-plugin — Kimi (skills + MCP only; hooks/commands/subagents dropped)\n * • npm-plugin — opencode / kilo-cli / pi (publishable npm package + bridge)\n *\n * The command / skill / subagent markdown is rendered through the SAME shared\n * claude-code renderers the live adapters write with (where the target uses\n * markdown), hooks via buildHomeBinHookCommand, and MCP via buildServeWrapperCommand\n * with `--host <platform>` — so telemetry-wrap + the universal home-bin pointer\n * carry through every bundle exactly as an `agent-connector install` would.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\n\nimport type { ResolvedConnector } from \"./types.js\";\nimport { homeBinPath as defaultHomeBinPath } from \"./paths.js\";\nimport type { EmitContext, FormatEmitter, PackageResult } from \"./package-formats/shared.js\";\nimport {\n emitClaudePlugin,\n emitCodexPlugin,\n emitCopilotPlugin,\n emitFactoryPlugin,\n} from \"./package-formats/claude-family.js\";\nimport { emitCursorPlugin } from \"./package-formats/cursor.js\";\nimport {\n emitGeminiExtension,\n emitQwenExtension,\n} from \"./package-formats/gemini.js\";\nimport { emitAgyPlugin } from \"./package-formats/agy.js\";\nimport { emitKimiPlugin } from \"./package-formats/kimi.js\";\nimport { emitNpmPlugin } from \"./package-formats/npm.js\";\nimport { emitMcpServerJson } from \"./package-formats/mcp-server.js\";\nimport { emitMcpbBundle } from \"./package-formats/mcpb.js\";\n\nexport type { PackageResult } from \"./package-formats/shared.js\";\n\n/** Every packaging format `package` can emit. */\nexport type PackageFormat =\n | \"claude-plugin\"\n | \"codex-plugin\"\n | \"copilot-plugin\"\n | \"factory-plugin\"\n | \"gemini-extension\"\n | \"qwen-extension\"\n | \"agy-plugin\"\n | \"cursor-plugin\"\n | \"kimi-plugin\"\n | \"npm-plugin\"\n // Official MCP standard artifacts (describe the dev's REAL upstream server,\n // not our serve wrapper; require `publish` metadata, so they are opt-in and\n // excluded from `--format all`).\n | \"mcp-server-json\"\n | \"mcpb\";\n\n/** The single consistent dispatch map: format → emitter. */\nconst EMITTERS: Record<PackageFormat, FormatEmitter> = {\n \"claude-plugin\": emitClaudePlugin,\n \"codex-plugin\": emitCodexPlugin,\n \"copilot-plugin\": emitCopilotPlugin,\n \"factory-plugin\": emitFactoryPlugin,\n \"gemini-extension\": emitGeminiExtension,\n \"qwen-extension\": emitQwenExtension,\n \"agy-plugin\": emitAgyPlugin,\n \"cursor-plugin\": emitCursorPlugin,\n \"kimi-plugin\": emitKimiPlugin,\n \"npm-plugin\": emitNpmPlugin,\n \"mcp-server-json\": emitMcpServerJson,\n mcpb: emitMcpbBundle,\n};\n\n/** All formats, in a stable, documented order. */\nexport const ALL_FORMATS: readonly PackageFormat[] = [\n \"claude-plugin\",\n \"codex-plugin\",\n \"copilot-plugin\",\n \"factory-plugin\",\n \"gemini-extension\",\n \"qwen-extension\",\n \"agy-plugin\",\n \"cursor-plugin\",\n \"kimi-plugin\",\n \"npm-plugin\",\n \"mcp-server-json\",\n \"mcpb\",\n] as const;\n\n/**\n * The formats `--format all` emits — the host plugin/marketplace bundles that\n * work for ANY connector. The official MCP standard artifacts (mcp-server-json,\n * and the MCPB bundle) are deliberately EXCLUDED: they require `publish`\n * metadata (a namespace the dev owns, their published package) and would error\n * for a connector that has not opted into publishing, so they are emitted only\n * when requested explicitly by name.\n */\nexport const FEASIBLE_FORMATS: readonly PackageFormat[] = [\n \"claude-plugin\",\n \"codex-plugin\",\n \"copilot-plugin\",\n \"factory-plugin\",\n \"gemini-extension\",\n \"qwen-extension\",\n \"agy-plugin\",\n \"cursor-plugin\",\n \"kimi-plugin\",\n \"npm-plugin\",\n] as const;\n\n/** Type guard: is `s` a supported {@link PackageFormat}? */\nexport function isPackageFormat(s: string): s is PackageFormat {\n return Object.prototype.hasOwnProperty.call(EMITTERS, s);\n}\n\nexport interface PackageOptions {\n /** Directory the bundle is written under (the format root). */\n outDir: string;\n /** Output format. Defaults to \"claude-plugin\". */\n format?: PackageFormat;\n /**\n * Absolute path to agent-connector's stable home-bin that hooks + the MCP\n * serve-wrapper point at. Defaults to {@link defaultHomeBinPath}.\n */\n homeBinPath?: string;\n /** Compute the file list without writing anything. */\n dryRun?: boolean;\n}\n\n/**\n * Emit a bundle for `connector` in a single `format` (default claude-plugin).\n *\n * Writes (or, for dryRun, only enumerates) the bundle under `opts.outDir`.\n * Returns the absolute file list, the plugin root dir, an optional marketplace\n * path, and optional drop notes (for lossy formats like kimi-plugin).\n */\n/**\n * Host-bundle formats whose hooks/MCP entries embed the ABSOLUTE home-bin path\n * of the machine that ran `package`. They install fine locally, but on another\n * machine/user the baked path points at nothing — so every emit carries a note.\n * (npm-plugin resolves the CLI by name on PATH; mcp-server-json/mcpb describe\n * the dev's real upstream server — none of those embed a local path.)\n */\nconst HOME_BIN_EMBED_FORMATS: ReadonlySet<PackageFormat> = new Set([\n \"claude-plugin\",\n \"codex-plugin\",\n \"copilot-plugin\",\n \"factory-plugin\",\n \"gemini-extension\",\n \"qwen-extension\",\n \"agy-plugin\",\n \"cursor-plugin\",\n \"kimi-plugin\",\n]);\n\nexport function packageConnector(\n connector: ResolvedConnector,\n opts: PackageOptions,\n): PackageResult {\n const format = opts.format ?? \"claude-plugin\";\n const emitter = EMITTERS[format];\n if (!emitter) {\n throw new Error(`unsupported package format: ${format}`);\n }\n\n const ctx: EmitContext = {\n outDir: resolve(opts.outDir),\n homeBinPath: opts.homeBinPath ?? defaultHomeBinPath(),\n dryRun: opts.dryRun ?? false,\n };\n const result = emitter(connector, ctx);\n if (HOME_BIN_EMBED_FORMATS.has(format)) {\n const note =\n `bundle embeds this machine's agent-connector launcher path (${ctx.homeBinPath}) — ` +\n \"valid for LOCAL install; for a shared marketplace, consumers need agent-connector \" +\n \"at the same home path (run `agent-connector upgrade` there) or re-run `package` per machine\";\n result.notes = [...(result.notes ?? []), note];\n }\n return result;\n}\n\n/** One entry in a multi-format ({@link packageConnectorAll}) emit. */\nexport interface MultiPackageResult {\n format: PackageFormat;\n result: PackageResult;\n}\n\n/**\n * Emit EVERY feasible format, each into its own `<outDir>/<format>/` subdir, so a\n * single `package --format all` produces the whole matrix without collisions.\n */\nexport function packageConnectorAll(\n connector: ResolvedConnector,\n opts: { outDir: string; homeBinPath?: string; dryRun?: boolean },\n): MultiPackageResult[] {\n const base = resolve(opts.outDir);\n const homeBin = opts.homeBinPath ?? defaultHomeBinPath();\n const dryRun = opts.dryRun ?? false;\n return FEASIBLE_FORMATS.map((format) => ({\n format,\n result: packageConnector(connector, {\n outDir: resolve(base, format),\n format,\n homeBinPath: homeBin,\n dryRun,\n }),\n }));\n}\n\n/**\n * Per-format MANUAL install commands (the accurate two-step add+install where\n * applicable). Lives in core (not the CLI) so both `package`'s printed\n * instructions and the marketplace method's skip-warn records for non-drivable\n * hosts quote the SAME commands — one copy, no drift.\n */\nexport function installInstructions(\n format: PackageFormat,\n id: string,\n outDir: string,\n): string[] {\n switch (format) {\n case \"claude-plugin\":\n return [\n `/plugin marketplace add ${outDir}`,\n `/plugin install ${id}@agent-connector`,\n `(CLI: claude plugin marketplace add ${outDir} && claude plugin install ${id}@agent-connector)`,\n ];\n case \"codex-plugin\":\n return [\n `codex plugin marketplace add ${outDir}`,\n `codex plugin add ${id}@agent-connector`,\n ];\n case \"copilot-plugin\":\n return [\n `copilot plugin marketplace add ${outDir}`,\n `copilot plugin install ${id}@agent-connector`,\n ];\n case \"factory-plugin\":\n return [\n `droid plugin marketplace add ${outDir}`,\n `droid plugin install ${id}@agent-connector`,\n ];\n case \"gemini-extension\":\n return [`gemini extensions install ${join(outDir, id)}`];\n case \"qwen-extension\":\n return [`qwen extensions install ${join(outDir, id)}`];\n case \"agy-plugin\":\n return [\n `agy plugin install ${join(outDir, id)}`,\n `(validate: agy plugin validate ${join(outDir, id)})`,\n ];\n case \"cursor-plugin\":\n return [\n `link ${join(outDir, id)} into ~/.cursor/plugins/local/${id}/ then Developer: Reload Window`,\n `(or publish ${outDir} as a Cursor marketplace repo)`,\n ];\n case \"kimi-plugin\":\n return [`kimi plugin install ${join(outDir, id)}`];\n case \"npm-plugin\":\n return [\n `npm publish ${join(outDir, id)} (then: opencode plugin install <pkg> | kilo plugin <pkg> | pi install npm:<pkg>)`,\n ];\n case \"mcp-server-json\":\n return [\n `mcp-publisher login <github|dns|http> (prove ownership of your namespace once)`,\n `cd ${outDir} && mcp-publisher publish (uploads server.json to the official MCP Registry)`,\n ];\n case \"mcpb\":\n return [\n `vendor your built server under ${join(outDir, \"server\")}/ (see the emitted README)`,\n `npx @anthropic-ai/mcpb pack ${outDir} (then optionally: mcpb sign)`,\n ];\n default:\n return [];\n }\n}\n\n/** Read + parse a JSON file (used by callers/tests). Returns null on absence/parse error. */\nexport function readPackagedJson<T = unknown>(path: string): T | null {\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as T;\n } catch {\n return null;\n }\n}\n","/**\n * core/package-formats/claude-family — the claude-plugin emitter + its\n * manifest-rename / host-restamp siblings (codex-plugin, factory-plugin,\n * copilot-plugin).\n *\n * All share ONE component tree (commands/ agents-or-droids/ skills/<n>/\n * SKILL.md + hooks/hooks.json + an MCP json) and differ only in:\n * • the manifest DIR + filename (.claude-plugin/ | .codex-plugin/ | .factory-plugin/)\n * • the subagent dir name (agents/ vs droids/ for factory)\n * • the MCP filename (.mcp.json vs mcp.json for factory)\n * • the manifest extra fields (claude adds $schema; factory pins version+author)\n * • the marketplace catalog shape (claude/codex object-owner; factory git-repo catalog)\n * • the platform stamped into hooks/MCP (--host, so telemetry routes per host)\n *\n * copilot-plugin is the claude-plugin bundle EXACTLY (GitHub Copilot CLI 1.0.63\n * accepts a Claude-shaped `.claude-plugin/` bundle byte-for-byte — live-verified:\n * `copilot plugin marketplace add <dir>` + `copilot plugin install <id>@<mkt>`\n * succeed and `copilot plugin list` shows it), differing ONLY in the --host\n * stamp (`copilot-cli`) so the wrapped MCP server + hook commands route telemetry\n * to the copilot host instead of claude.\n *\n * The command / skill / subagent markdown is rendered through the SAME shared\n * claude-code renderers the live adapter writes with, so an installed plugin and\n * an `agent-connector install` produce byte-identical content files. Hooks use\n * the universal home-bin command (telemetry-routed) and the MCP entry is\n * serve-wrapped with `--host <platform>` so telemetry carries through.\n */\n\nimport { join } from \"node:path\";\n\nimport type { PlatformId, ResolvedConnector } from \"../types.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n buildClaudeHooksJson,\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\n/** Per-variant layout + manifest knobs for a Claude-family bundle. */\ninterface ClaudeFamilySpec {\n /** Host platform stamped into the serve-wrapper + hook command (--host). */\n platformId: PlatformId;\n /** Manifest directory under the plugin root (e.g. \".claude-plugin\"). */\n manifestDir: string;\n /** Subagent directory name (claude/codex: \"agents\"; factory: \"droids\"). */\n subagentDir: string;\n /** MCP filename at the plugin root (claude/codex: \".mcp.json\"; factory: \"mcp.json\"). */\n mcpFile: string;\n /** Add `$schema` to plugin.json (claude only). */\n schemaUrl?: string;\n /** Always carry a version in plugin.json, defaulting placeholder to \"0.0.1\" (factory requires it). */\n requireVersion?: boolean;\n /** Always carry an `author` object in plugin.json (factory pins it). */\n alwaysAuthor?: boolean;\n /**\n * Where to write the marketplace catalog, relative to outDir, and which shape.\n * \"claude\": <outDir>/.claude-plugin/marketplace.json (object owner).\n * \"codex\": <outDir>/.agents/plugins/marketplace.json (same object-owner\n * catalog; codex's documented location — `codex plugin marketplace\n * add` REJECTS a `.codex-plugin/` catalog with \"marketplace root\n * does not contain a supported manifest\"; live-verified 0.139.0).\n * \"factory\":<outDir>/marketplace.json (git-repo catalog at the repo root).\n */\n marketplace: { dir: string | null; file: string; shape: \"claude\" | \"factory\" };\n}\n\nconst SPECS: Record<string, ClaudeFamilySpec> = {\n \"claude-plugin\": {\n platformId: \"claude-code\",\n manifestDir: \".claude-plugin\",\n subagentDir: \"agents\",\n mcpFile: \".mcp.json\",\n schemaUrl: \"https://json.schemastore.org/claude-code-plugin-manifest.json\",\n marketplace: { dir: \".claude-plugin\", file: \"marketplace.json\", shape: \"claude\" },\n },\n \"codex-plugin\": {\n platformId: \"codex\",\n manifestDir: \".codex-plugin\",\n subagentDir: \"agents\",\n mcpFile: \".mcp.json\",\n marketplace: {\n dir: join(\".agents\", \"plugins\"),\n file: \"marketplace.json\",\n shape: \"claude\",\n },\n },\n \"copilot-plugin\": {\n // copilot-cli accepts a Claude-shaped bundle as-is; the ONLY difference from\n // claude-plugin is the --host stamp so the wrapped MCP + hook commands route\n // telemetry to the copilot host. Same `.claude-plugin/` manifest dir + schema\n // + `.claude-plugin/marketplace.json` catalog (live-verified on CLI 1.0.63).\n platformId: \"copilot-cli\",\n manifestDir: \".claude-plugin\",\n subagentDir: \"agents\",\n mcpFile: \".mcp.json\",\n schemaUrl: \"https://json.schemastore.org/claude-code-plugin-manifest.json\",\n marketplace: { dir: \".claude-plugin\", file: \"marketplace.json\", shape: \"claude\" },\n },\n \"factory-plugin\": {\n platformId: \"droid\",\n manifestDir: \".factory-plugin\",\n subagentDir: \"droids\",\n mcpFile: \"mcp.json\",\n requireVersion: true,\n alwaysAuthor: true,\n // droid marketplaces are Git-repo catalogs; the catalog sits at the repo root.\n marketplace: { dir: null, file: \"marketplace.json\", shape: \"factory\" },\n },\n};\n\n/** Build the plugin manifest for a Claude-family variant. */\nfunction buildManifest(\n connector: ResolvedConnector,\n spec: ClaudeFamilySpec,\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {};\n if (spec.schemaUrl) manifest.$schema = spec.schemaUrl;\n manifest.name = connector.id;\n manifest.description = `${connector.displayName} — connector emitted by agent-connector`;\n\n const hasRealVersion = connector.version && connector.version !== \"0.0.0\";\n if (hasRealVersion) {\n manifest.version = connector.version;\n } else if (spec.requireVersion) {\n // factory requires a semver version; supply a sane default when unpinned.\n manifest.version = \"0.0.1\";\n }\n // Attribute the bundle to the connector developer when they declared an\n // author (publish.author); the framework name is only the fallback.\n if (spec.alwaysAuthor) {\n manifest.author = { name: connector.publish?.author?.name ?? \"agent-connector\" };\n }\n return manifest;\n}\n\n/** Build the marketplace catalog for a Claude-family variant. */\nfunction buildMarketplace(connector: ResolvedConnector): Record<string, unknown> {\n // Both the claude/codex object-owner catalog and the droid git-repo catalog\n // use the same minimal { name, owner, plugins:[{name,source,description}] }\n // shape — droid reads source as a path relative to the marketplace repo root.\n // The catalog NAME stays \"agent-connector\" (the printed install instructions\n // `<id>@agent-connector` key on it); the OWNER is the developer when known.\n return {\n name: \"agent-connector\",\n owner: { name: connector.publish?.author?.name ?? \"agent-connector\" },\n plugins: [\n {\n name: connector.id,\n source: `./${connector.id}`,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n },\n ],\n };\n}\n\n/** Emit a Claude-family bundle (claude-plugin | codex-plugin | factory-plugin). */\nfunction emitClaudeFamily(\n connector: ResolvedConnector,\n ctx: EmitContext,\n format: keyof typeof SPECS,\n): PackageResult {\n const spec = SPECS[format];\n if (!spec) throw new Error(`unknown claude-family format: ${format}`);\n\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n // ── plugin.json (the ONLY file inside the manifest dir) ───────────────────\n emit(\n join(pluginDir, spec.manifestDir, \"plugin.json\"),\n json(buildManifest(connector, spec)),\n );\n\n // ── commands/<name>.md ────────────────────────────────────────────────────\n for (const cmd of connector.commands) {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n\n // ── agents|droids/<name>.md ───────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(\n join(pluginDir, spec.subagentDir, `${agent.name}.md`),\n renderSubagentMd(agent),\n );\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue; // never write outside the skill dir\n emit(target, contents);\n }\n }\n\n // ── hooks/hooks.json (mapped events only) ─────────────────────────────────\n const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, spec.platformId);\n if (hooksJson) emit(join(pluginDir, \"hooks\", \"hooks.json\"), json(hooksJson));\n\n // ── MCP json (serve-wrapped stdio server) ─────────────────────────────────\n const mcp = buildMcpEntry(connector, ctx.homeBinPath, spec.platformId);\n if (mcp) {\n emit(\n join(pluginDir, spec.mcpFile),\n json({ mcpServers: { [mcp.serverName]: mcp.entry } }),\n );\n }\n\n // ── marketplace catalog ───────────────────────────────────────────────────\n const marketplacePath = spec.marketplace.dir\n ? join(ctx.outDir, spec.marketplace.dir, spec.marketplace.file)\n : join(ctx.outDir, spec.marketplace.file);\n emit(marketplacePath, json(buildMarketplace(connector)));\n\n return { files, pluginDir, marketplacePath };\n}\n\nexport const emitClaudePlugin: FormatEmitter = (connector, ctx) =>\n emitClaudeFamily(connector, ctx, \"claude-plugin\");\n\nexport const emitCodexPlugin: FormatEmitter = (connector, ctx) =>\n emitClaudeFamily(connector, ctx, \"codex-plugin\");\n\nexport const emitFactoryPlugin: FormatEmitter = (connector, ctx) =>\n emitClaudeFamily(connector, ctx, \"factory-plugin\");\n\nexport const emitCopilotPlugin: FormatEmitter = (connector, ctx) =>\n emitClaudeFamily(connector, ctx, \"copilot-plugin\");\n","/**\n * core/package-formats/shared — the common emitter contract + helpers every\n * format family is built on.\n *\n * A format emitter is a pure function conforming to {@link FormatEmitter}: it\n * takes a {@link ResolvedConnector} plus an {@link EmitContext} ({outDir,\n * homeBinPath, dryRun}) and either writes the bundle (dryRun=false) or only\n * enumerates the files it WOULD write (dryRun=true), returning a\n * {@link PackageResult} ({pluginDir, files[], marketplacePath?, notes?}).\n *\n * Everything below is shared across families so each emitter file is just the\n * format-specific manifest + layout, never a re-implementation of file writing,\n * JSON serialization, traversal-safe resource placement, the home-bin hooks\n * block, or the serve-wrapper MCP entry. Reusing these keeps telemetry-wrap +\n * the universal home-bin hook command byte-identical to the live adapters.\n */\n\nimport { dirname, relative, resolve, sep } from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\n\nimport type {\n HookEventName,\n PlatformId,\n ResolvedConnector,\n} from \"../types.js\";\nimport { ensureDir, firstSymlinkInPath } from \"../paths.js\";\nimport {\n buildHomeBinHookCommand,\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../spawn.js\";\n\n/** Inputs every format emitter receives. */\nexport interface EmitContext {\n /** Directory the bundle is written under (the format root). */\n outDir: string;\n /** Absolute path to agent-connector's stable home-bin (hooks + serve wrapper point here). */\n homeBinPath: string;\n /** Enumerate the file list without writing anything. */\n dryRun: boolean;\n}\n\n/** What every format emitter returns. */\nexport interface PackageResult {\n /** Absolute paths of every file the bundle comprises (written, or planned for dryRun). */\n files: string[];\n /** Absolute path to the plugin/extension root directory. */\n pluginDir: string;\n /** Absolute path to the emitted marketplace catalog, when the format has one. */\n marketplacePath?: string;\n /**\n * Human-readable notes about surfaces the format intentionally DROPS (e.g.\n * Kimi ignores hooks/commands/subagents). The CLI surfaces these so a lossy\n * bundle is never silent. Empty when nothing was dropped.\n */\n notes?: string[];\n}\n\n/** The shared signature every `package-formats/<family>.ts` exports. */\nexport type FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n) => PackageResult;\n\n/** A small file-collecting writer bound to one emit run (honors dryRun). */\nexport interface Emitter {\n /** Write `contents` to `path` (skipped under dryRun) and record it. */\n emit(path: string, contents: string): void;\n /** The accumulated absolute file list (in emit order). */\n readonly files: string[];\n}\n\n/** Build a dryRun-aware {@link Emitter} that records every (would-be) write. */\nexport function createEmitter(dryRun: boolean): Emitter {\n const files: string[] = [];\n return {\n files,\n emit(path: string, contents: string): void {\n if (!dryRun) {\n const symlink = firstSymlinkInPath(path);\n if (symlink !== null) {\n throw new Error(`refusing to emit through symbolic link: ${path} (${symlink})`);\n }\n ensureDir(dirname(path));\n writeFileSync(path, contents, \"utf8\");\n }\n files.push(path);\n },\n };\n}\n\n/** Pretty-print a value as 2-space JSON with a trailing newline. */\nexport function json(value: unknown): string {\n return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\n/**\n * Resolve a skill-resource relative key against `baseDir`, returning the\n * absolute target ONLY when it stays inside the dir (defense-in-depth — config\n * validation already rejects traversal, but never trust input). Null otherwise.\n */\nexport function resolveWithin(baseDir: string, rel: string): string | null {\n const base = resolve(baseDir);\n const target = resolve(base, rel);\n if (target === base) return null;\n const rind = relative(base, target);\n if (rind === \"\" || rind.startsWith(\"..\") || resolve(base, rind) !== target) {\n return null;\n }\n if (rind === \"..\" || rind.startsWith(`..${sep}`)) return null;\n return target;\n}\n\n/** Pass env through unchanged when present, else undefined (drops empty objects). */\nexport function renderEnv(\n env: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return { ...env };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Hooks — the Claude-shaped hooks.json block, shared by every format whose\n// hooks file mirrors Claude Code's `{ type:\"command\", command:\"<string>\" }`.\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Claude event names a Claude-style plugin's hooks.json may key on. */\nexport const CLAUDE_MAPPED_EVENTS: ReadonlySet<HookEventName> =\n new Set<HookEventName>([\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"SessionStart\",\n \"SessionEnd\",\n \"UserPromptSubmit\",\n \"Stop\",\n \"Notification\",\n \"PermissionRequest\",\n \"PostToolUseFailure\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PostCompact\",\n ]);\n\n/** A single hooks.json entry (identical in shape to a settings.json hooks block). */\nexport interface PluginHookEntry {\n matcher?: string;\n hooks: Array<{ type: \"command\"; command: string }>;\n}\n\n/**\n * Build the Claude-shaped hooks.json body for the MAPPED events the connector\n * declares. Each command is the SAME single-string home-bin form the live\n * adapters write (via buildHomeBinHookCommand). `platformId` lets a format point\n * the hook at the right host (e.g. \"cursor\", \"claude-code\"). Returns null when\n * the connector declares no mapped events.\n */\nexport function buildClaudeHooksJson(\n connector: ResolvedConnector,\n homeBin: string,\n platformId: PlatformId,\n): { hooks: Record<string, PluginHookEntry[]> } | null {\n const events = connector.hookEvents.filter((e) => CLAUDE_MAPPED_EVENTS.has(e));\n if (events.length === 0) return null;\n\n const hooks: Record<string, PluginHookEntry[]> = {};\n for (const event of events) {\n const matcher = connector.hooks[event]?.matcher ?? \"\";\n const command = {\n type: \"command\" as const,\n command: buildHomeBinHookCommand(homeBin, platformId, event, connector.id),\n };\n hooks[event] = [matcher ? { matcher, hooks: [command] } : { hooks: [command] }];\n }\n return { hooks };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// MCP — the serve-wrapped stdio server entry, shared by every format whose MCP\n// file carries a launchable { command, args, env?, cwd? } (the Claude .mcp.json\n// dialect). Remote/non-stdio servers are out of scope for a launchable bundle.\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Native MCP server entry shape a Claude-dialect mcpServers map accepts. */\nexport interface PluginMcpEntry {\n command: string;\n args: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\n/**\n * Render the connector's ServerDef into a serve-wrapped MCP entry for\n * `platformId`, so per-tool telemetry carries through the bundle exactly as the\n * live adapter's install does. Returns null when there is no stdio command to\n * launch (remote / server-less connectors). The returned `serverName` is the\n * connector id (the conventional single-server key).\n */\nexport function buildMcpEntry(\n connector: ResolvedConnector,\n homeBin: string,\n platformId: PlatformId,\n): { serverName: string; entry: PluginMcpEntry } | null {\n const server = connector.server;\n if (!server) return null;\n // A launchable bundle entry can only carry stdio servers; remote (http/sse/ws)\n // servers register a URL elsewhere, out of scope for the bundled plugin.\n if (server.transport !== \"stdio\") return null;\n\n const realCommand = server.command ?? \"\";\n if (realCommand === \"\") return null;\n const realArgs = [...(server.args ?? [])];\n\n let entry: PluginMcpEntry;\n if (shouldWrapForTelemetry(server, connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(\n homeBin,\n connector.id,\n realCommand,\n realArgs,\n undefined,\n platformId,\n );\n entry = { command: wrapped.command, args: wrapped.args };\n } else {\n entry = { command: realCommand, args: realArgs };\n }\n\n const env = renderEnv(server.env);\n if (env) entry.env = env;\n if (server.cwd) entry.cwd = server.cwd;\n\n return { serverName: connector.id, entry };\n}\n","/**\n * core/package-formats/cursor — the `cursor-plugin` emitter.\n *\n * Cursor's bundle is near-isomorphic to claude-plugin: manifest at\n * `.cursor-plugin/plugin.json` (only `name` required) with the surface fields\n * declared as POINTERS (\"skills\":\"./skills/\", \"hooks\":\"./hooks/hooks.json\",\n * \"mcpServers\":\"./mcp.json\") so a validator/IDE finds each dir; components live\n * at the plugin root: commands/<n>.md, agents/<n>.md, skills/<n>/SKILL.md,\n * mcp.json, hooks/hooks.json. A multi-plugin repo adds .cursor-plugin/\n * marketplace.json { name, owner:{name,email?}, plugins:[{name,source,description}] }.\n *\n * Markdown reuses the shared claude-code renderers (Cursor reads the same md +\n * frontmatter command/agent/skill documents). MCP uses the shared serve-wrap\n * builder with --host cursor so serve-wrapper telemetry carries through. Hooks\n * use Cursor's OWN flat hooks.json shape (NOT the Claude shape) via the cursor\n * install adapter's shared event-map + version — see buildCursorHooksJson.\n *\n * (Cursor also supports `rules/*.mdc`, but a connector declares no rules surface,\n * so no rules/ dir is emitted and the manifest omits the `rules` pointer.)\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { HookEventName, PlatformId, ResolvedConnector } from \"../types.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n CURSOR_EVENT_MAP,\n CURSOR_HOOKS_VERSION,\n} from \"../../adapters/cursor/index.js\";\nimport { buildHomeBinHookCommand } from \"../spawn.js\";\nimport {\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\nconst PLATFORM: PlatformId = \"cursor\";\n\n/** A single Cursor native hook entry — a FLAT command object (matcher optional). */\ninterface CursorHookEntry {\n command: string;\n matcher?: string;\n}\n\n/**\n * Build Cursor's native hooks.json body for the connector's declared events.\n *\n * Unlike the Claude shape (PascalCase keys, nested `{ matcher?, hooks:[{type,\n * command}] }`, no version), Cursor reads `{ version, hooks: { <cursorEvent>:\n * [ { command, matcher? } ] } }` — lower-camel native keys, FLAT command\n * entries, and a top-level version stamp. The event-map + version are imported\n * from the cursor INSTALL adapter (the repo authority on Cursor's schema) so a\n * packaged bundle and a live install can never diverge: only the events Cursor\n * actually maps are emitted, with the exact keys/version the adapter writes.\n *\n * The home-bin command STRING is the same single-string form the install\n * adapter writes (buildHomeBinHookCommand); only the envelope shape differs.\n *\n * Scope: this operates on the connector-level declared `hookEvents` only. Per-\n * platform override state (`platforms.cursor.hooks: false` / `nativeHooks`) is\n * intentionally NOT applied — a portable package bundle is platform-agnostic,\n * matching the Claude-family emitters. The consistency test covers the no-\n * override case (bundle bytes === a vanilla install).\n * Returns null when the connector declares no Cursor-mapped events.\n */\nfunction buildCursorHooksJson(\n connector: ResolvedConnector,\n homeBin: string,\n): { version: number; hooks: Record<string, CursorHookEntry[]> } | null {\n const hooks: Record<string, CursorHookEntry[]> = {};\n for (const event of connector.hookEvents) {\n const cursorEvent = CURSOR_EVENT_MAP[event as HookEventName];\n if (cursorEvent === undefined) continue; // no Cursor equivalent — skipped\n const command = buildHomeBinHookCommand(homeBin, PLATFORM, event, connector.id);\n const matcher = connector.hooks[event]?.matcher ?? \"\";\n hooks[cursorEvent] = [matcher ? { command, matcher } : { command }];\n }\n if (Object.keys(hooks).length === 0) return null;\n return { version: CURSOR_HOOKS_VERSION, hooks };\n}\n\n/** Build .cursor-plugin/plugin.json with pointer surface fields for what exists. */\nfunction buildManifest(\n connector: ResolvedConnector,\n has: { commands: boolean; agents: boolean; skills: boolean; hooks: boolean; mcp: boolean },\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {\n name: connector.id,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n if (connector.version && connector.version !== \"0.0.0\") {\n manifest.version = connector.version;\n }\n // Pointer fields: only declare a surface that actually ships in the bundle.\n if (has.commands) manifest.commands = \"./commands/\";\n if (has.agents) manifest.agents = \"./agents/\";\n if (has.skills) manifest.skills = \"./skills/\";\n if (has.hooks) manifest.hooks = \"./hooks/hooks.json\";\n if (has.mcp) manifest.mcpServers = \"./mcp.json\";\n return manifest;\n}\n\n/** Build .cursor-plugin/marketplace.json (owner object carries name; email optional). */\nfunction buildMarketplace(connector: ResolvedConnector): Record<string, unknown> {\n // Catalog NAME stays \"agent-connector\" (install instructions key on it); the\n // OWNER is the connector developer when publish.author is declared.\n return {\n name: \"agent-connector\",\n owner: { name: connector.publish?.author?.name ?? \"agent-connector\" },\n plugins: [\n {\n name: connector.id,\n source: `./${connector.id}`,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n },\n ],\n };\n}\n\nexport const emitCursorPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n const hooksJson = buildCursorHooksJson(connector, ctx.homeBinPath);\n const mcp = buildMcpEntry(connector, ctx.homeBinPath, PLATFORM);\n\n const has = {\n commands: connector.commands.length > 0,\n agents: connector.subagents.length > 0,\n skills: connector.skills.length > 0,\n hooks: hooksJson !== null,\n mcp: mcp !== null,\n };\n\n // ── .cursor-plugin/plugin.json (ONLY file under .cursor-plugin/) ───────────\n emit(\n join(pluginDir, \".cursor-plugin\", \"plugin.json\"),\n json(buildManifest(connector, has)),\n );\n\n // ── commands/<name>.md ────────────────────────────────────────────────────\n for (const cmd of connector.commands) {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n\n // ── agents/<name>.md ──────────────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(join(pluginDir, \"agents\", `${agent.name}.md`), renderSubagentMd(agent));\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── hooks/hooks.json ──────────────────────────────────────────────────────\n if (hooksJson) emit(join(pluginDir, \"hooks\", \"hooks.json\"), json(hooksJson));\n\n // ── mcp.json (Cursor's MCP filename, no leading dot) ──────────────────────\n if (mcp) {\n emit(\n join(pluginDir, \"mcp.json\"),\n json({ mcpServers: { [mcp.serverName]: mcp.entry } }),\n );\n }\n\n // ── .cursor-plugin/marketplace.json ───────────────────────────────────────\n const marketplacePath = join(ctx.outDir, \".cursor-plugin\", \"marketplace.json\");\n emit(marketplacePath, json(buildMarketplace(connector)));\n\n return { files, pluginDir, marketplacePath };\n};\n\n/** True when a local install of this plugin already exists (used by the CLI hint). */\nexport function cursorLocalInstallExists(name: string, home: string): boolean {\n return existsSync(join(home, \".cursor\", \"plugins\", \"local\", name));\n}\n","/**\n * core/package-formats/gemini — the `gemini-extension` emitter + its `qwen-extension`\n * variant.\n *\n * A Gemini CLI extension is a directory with `gemini-extension.json` at its root\n * carrying `{ name, version, description, mcpServers, contextFileName }` plus the\n * component dirs: commands/<n>.toml (slash commands), skills/<n>/SKILL.md,\n * agents/<n>.md, hooks/hooks.json, and a GEMINI.md context file. UNLIKE the\n * Claude family, MCP is declared INLINE in the manifest's `mcpServers` map (not a\n * separate .mcp.json) — we still serve-wrap it so telemetry carries through.\n *\n * Qwen Code is a Gemini-CLI fork with its own `qwen-extension.json` (same shape)\n * but two differences captured here: commands are MARKDOWN (commands/<n>.md) not\n * TOML, and the context file is QWEN.md.\n *\n * Commands render to Gemini's native TOML `{ description, prompt }` (the same\n * shape the live gemini-cli adapter writes); skills/subagents reuse the shared\n * claude-code renderers (Gemini/Qwen read the same SKILL.md + md+frontmatter).\n * Hooks use the universal home-bin command; the MCP entry is serve-wrapped with\n * --host gemini-cli | qwen-code.\n */\n\nimport { join } from \"node:path\";\n\nimport type { CommandDef, PlatformId, ResolvedConnector } from \"../types.js\";\nimport { writeTomlString } from \"../toml.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n buildClaudeHooksJson,\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\n/** Per-variant knobs for a Gemini-family extension. */\ninterface GeminiFamilySpec {\n platformId: PlatformId;\n /** Manifest filename at the extension root. */\n manifestFile: string;\n /** Context file name (GEMINI.md | QWEN.md). */\n contextFile: string;\n /** Command file format: TOML (gemini) or Markdown (qwen). */\n commandFormat: \"toml\" | \"md\";\n}\n\nconst SPECS: Record<string, GeminiFamilySpec> = {\n \"gemini-extension\": {\n platformId: \"gemini-cli\",\n manifestFile: \"gemini-extension.json\",\n contextFile: \"GEMINI.md\",\n commandFormat: \"toml\",\n },\n \"qwen-extension\": {\n platformId: \"qwen-code\",\n manifestFile: \"qwen-extension.json\",\n contextFile: \"QWEN.md\",\n commandFormat: \"md\",\n },\n};\n\n/** Render a command to Gemini's native TOML `{ description, prompt }`. */\nfunction renderCommandToml(cmd: CommandDef): string {\n const obj: Record<string, unknown> = {};\n if (cmd.description !== undefined) obj.description = cmd.description;\n obj.prompt = cmd.prompt;\n return writeTomlString(obj);\n}\n\n/** Build gemini-extension.json | qwen-extension.json (with optional inline mcpServers). */\nfunction buildManifest(\n connector: ResolvedConnector,\n spec: GeminiFamilySpec,\n homeBin: string,\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {\n name: connector.id,\n // gemini requires a version; default a placeholder to a real semver.\n version:\n connector.version && connector.version !== \"0.0.0\"\n ? connector.version\n : \"0.0.1\",\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n\n const mcp = buildMcpEntry(connector, homeBin, spec.platformId);\n if (mcp) {\n manifest.mcpServers = { [mcp.serverName]: mcp.entry };\n }\n manifest.contextFileName = spec.contextFile;\n return manifest;\n}\n\nfunction emitGeminiFamily(\n connector: ResolvedConnector,\n ctx: EmitContext,\n format: keyof typeof SPECS,\n): PackageResult {\n const spec = SPECS[format];\n if (!spec) throw new Error(`unknown gemini-family format: ${format}`);\n\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n // ── gemini-extension.json | qwen-extension.json (MCP is inline here) ──────\n emit(\n join(pluginDir, spec.manifestFile),\n json(buildManifest(connector, spec, ctx.homeBinPath)),\n );\n\n // ── context file (GEMINI.md | QWEN.md) ────────────────────────────────────\n emit(\n join(pluginDir, spec.contextFile),\n `# ${connector.displayName}\\n\\nConnector context emitted by agent-connector.\\n`,\n );\n\n // ── commands/<name>.{toml|md} ─────────────────────────────────────────────\n for (const cmd of connector.commands) {\n if (spec.commandFormat === \"toml\") {\n emit(join(pluginDir, \"commands\", `${cmd.name}.toml`), renderCommandToml(cmd));\n } else {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n }\n\n // ── agents/<name>.md ──────────────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(join(pluginDir, \"agents\", `${agent.name}.md`), renderSubagentMd(agent));\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── hooks/hooks.json ──────────────────────────────────────────────────────\n const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, spec.platformId);\n if (hooksJson) emit(join(pluginDir, \"hooks\", \"hooks.json\"), json(hooksJson));\n\n // A Gemini/Qwen extension has no separate marketplace catalog (it installs by\n // URL/path); marketplacePath is left undefined.\n return { files, pluginDir };\n}\n\nexport const emitGeminiExtension: FormatEmitter = (connector, ctx) =>\n emitGeminiFamily(connector, ctx, \"gemini-extension\");\n\nexport const emitQwenExtension: FormatEmitter = (connector, ctx) =>\n emitGeminiFamily(connector, ctx, \"qwen-extension\");\n","/**\n * core/package-formats/agy — the `agy plugin` bundle emitter (Antigravity CLI +\n * Antigravity IDE, which share the bundle).\n *\n * Live-confirmed layout (`agy plugin validate`):\n * • REQUIRED root `plugin.json` marker { name, version, description } — its\n * absence is the one hard error the validator reports.\n * • MCP MUST be a SEPARATE `mcp_config.json` { mcpServers:{...} } — an inline\n * `mcpServers` in plugin.json is NOT picked up. (This is the one structural\n * difference from the Claude family.)\n * • hooks.json at the BUNDLE ROOT keyed { hooks:{ <Event>:[{matcher,hooks:[{type,command}]}] } }\n * — agy 1.0.7 NEVER reads hooks/hooks.json: validate+install report\n * \"hooks: skipped (not found)\" and copy the file unprocessed. The root\n * location was fix-proven live (\"hooks: 1 processed\", components +hooks).\n * • skills/<n>/SKILL.md, agents/<n>.md, commands/<n>.md (commands are converted\n * to skills on validate — still emitted as Markdown command files).\n *\n * Markdown reuses the shared claude-code renderers; hooks use the universal\n * home-bin command; the MCP entry is serve-wrapped with --host antigravity-cli so\n * telemetry carries through. No marketplace catalog ships in the bundle (agy\n * installs by target / plugin@marketplace).\n */\n\nimport { join } from \"node:path\";\n\nimport type { PlatformId, ResolvedConnector } from \"../types.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n buildClaudeHooksJson,\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\nconst PLATFORM: PlatformId = \"antigravity-cli\";\n\n/** Build the required root plugin.json marker. */\nfunction buildManifest(connector: ResolvedConnector): Record<string, unknown> {\n return {\n name: connector.id,\n // agy expects a version on the marker; default a placeholder to a real semver.\n version:\n connector.version && connector.version !== \"0.0.0\"\n ? connector.version\n : \"0.0.1\",\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n}\n\nexport const emitAgyPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n // ── plugin.json (REQUIRED root marker) ────────────────────────────────────\n emit(join(pluginDir, \"plugin.json\"), json(buildManifest(connector)));\n\n // ── commands/<name>.md (validator converts these to skills) ───────────────\n for (const cmd of connector.commands) {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n\n // ── agents/<name>.md ──────────────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(join(pluginDir, \"agents\", `${agent.name}.md`), renderSubagentMd(agent));\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── hooks.json (bundle ROOT — agy silently ignores hooks/hooks.json) ──────\n const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, PLATFORM);\n if (hooksJson) emit(join(pluginDir, \"hooks.json\"), json(hooksJson));\n\n // ── mcp_config.json (SEPARATE file — inline mcpServers is NOT read by agy) ─\n const mcp = buildMcpEntry(connector, ctx.homeBinPath, PLATFORM);\n if (mcp) {\n emit(\n join(pluginDir, \"mcp_config.json\"),\n json({ mcpServers: { [mcp.serverName]: mcp.entry } }),\n );\n }\n\n return { files, pluginDir };\n};\n","/**\n * core/package-formats/kimi — the `kimi-plugin` emitter (skills + MCP ONLY).\n *\n * A Kimi plugin is a directory whose manifest is `kimi.plugin.json` at the root\n * carrying { name, version, description, skills, mcpServers }. Kimi plugins carry\n * exactly TWO functional surfaces:\n * • skills/<n>/SKILL.md (declared via the `skills` pointer)\n * • mcpServers (a standard MCP map, stdio + http)\n *\n * Kimi EXPLICITLY ignores `tools`, `commands`, `hooks`, `apps`, `inject`,\n * `configFile` (they surface as diagnostics). So when the connector declares\n * commands, subagents, or hooks, those surfaces are DROPPED — and a note is\n * returned so the lossy bundle is never silent. The MCP entry is still\n * serve-wrapped with --host kimi so telemetry carries through; hooks are NOT\n * emitted because Kimi has no hooks surface.\n */\n\nimport { join } from \"node:path\";\n\nimport type { PlatformId, ResolvedConnector } from \"../types.js\";\nimport { renderSkillMd } from \"../../adapters/claude-code/render.js\";\nimport {\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\nconst PLATFORM: PlatformId = \"kimi\";\n\n/** Build kimi.plugin.json (skills pointer + inline mcpServers when present). */\nfunction buildManifest(\n connector: ResolvedConnector,\n hasSkills: boolean,\n homeBin: string,\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {\n name: connector.id,\n version:\n connector.version && connector.version !== \"0.0.0\"\n ? connector.version\n : \"0.0.1\",\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n if (hasSkills) manifest.skills = \"./skills/\";\n const mcp = buildMcpEntry(connector, homeBin, PLATFORM);\n if (mcp) manifest.mcpServers = { [mcp.serverName]: mcp.entry };\n return manifest;\n}\n\nexport const emitKimiPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n const notes: string[] = [];\n\n const hasSkills = connector.skills.length > 0;\n\n // ── kimi.plugin.json (root manifest; MCP inline; hooks/commands ignored) ──\n emit(join(pluginDir, \"kimi.plugin.json\"), json(buildManifest(connector, hasSkills, ctx.homeBinPath)));\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── Surfaces Kimi cannot carry → DROPPED, with an explicit note ───────────\n if (connector.commands.length > 0) {\n notes.push(\n `kimi-plugin: dropped ${connector.commands.length} command(s) — Kimi plugins ignore commands`,\n );\n }\n if (connector.subagents.length > 0) {\n notes.push(\n `kimi-plugin: dropped ${connector.subagents.length} subagent(s) — Kimi plugins ignore subagents`,\n );\n }\n if (connector.hookEvents.length > 0) {\n notes.push(\n `kimi-plugin: dropped ${connector.hookEvents.length} hook event(s) — Kimi plugins ignore hooks`,\n );\n }\n\n return { files, pluginDir, ...(notes.length > 0 ? { notes } : {}) };\n};\n","/**\n * core/package-formats/npm — the `npm-plugin` emitter (opencode + kilo-cli + pi).\n *\n * This is the one genuinely NET-NEW artifact: a publishable npm package whose\n * default export is a plugin module. It is emitted ONLY in its clean form — a\n * real package.json + an ESM `index.js` bridge — never a\n * half-baked stub. The surface limit (documented, and returned as notes) is\n * inherent to the opencode/kilo plugin contract: ONLY hook code rides inside the\n * npm package; commands/skills/subagents are native host dirs and MCP is a\n * config key, so they do NOT ride inside the published module.\n *\n * Layout:\n * <outDir>/<id>/\n * ├── package.json (type:module, exports \".\", keywords incl. \"opencode-plugin\"\n * │ + \"pi-package\", engines.node)\n * ├── index.js (default-export plugin fn; bridges each declared hook event\n * │ to `<homeBin> hook opencode <event> --connector <id>`)\n * ├── skills/<n>/SKILL.md (pi packages DO bundle skills; opencode ignores them)\n * └── README.md\n *\n * The bridge shells out to the framework runtime bundled as this plugin's npm\n * dependency, then falls back to a PATH `agent-connector` binary for hand-built\n * bundles. The SAME universal json-stdio dispatcher every other host uses serves\n * the npm host too. (MCP wrapping is NOT inlined here: opencode's MCP is the\n * opencode.json \"mcp\" key, out of band for the npm package; a note records this.)\n */\n\nimport { createRequire } from \"node:module\";\nimport { join } from \"node:path\";\n\nimport type { HookEventName, ResolvedConnector } from \"../types.js\";\nimport { renderSkillMd } from \"../../adapters/claude-code/render.js\";\nimport {\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\nconst AGENT_CONNECTOR_PACKAGE_NAME = \"@ken-jo/agent-connector\";\n\n/** OpenCode event keys this connector can bridge (PreToolUse/PostToolUse/SessionStart). */\nconst EVENT_TO_OPENCODE: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"tool.execute.before\",\n PostToolUse: \"tool.execute.after\",\n SessionStart: \"experimental.chat.system.transform\",\n};\n\nfunction resolveFrameworkDependencyRange(): string {\n const req = createRequire(import.meta.url);\n for (const rel of [\"../../../package.json\", \"../../package.json\", \"../package.json\"]) {\n try {\n const pkg = req(rel) as { name?: string; version?: string };\n if (\n pkg.name === AGENT_CONNECTOR_PACKAGE_NAME &&\n typeof pkg.version === \"string\" &&\n /^\\d+\\.\\d+\\.\\d+/.test(pkg.version)\n ) {\n return `^${pkg.version}`;\n }\n } catch {\n /* keep walking */\n }\n }\n return \"*\";\n}\n\n/** Build the publishable package.json for an opencode/kilo/pi plugin package. */\nfunction buildPackageJson(connector: ResolvedConnector): Record<string, unknown> {\n // Use an opencode- name prefix (the discovery-confirmed convention) so the\n // package is discoverable; keywords cover opencode + pi-package.\n const pkgName = connector.id.startsWith(\"opencode-\")\n ? connector.id\n : `opencode-${connector.id}`;\n const version =\n connector.version && connector.version !== \"0.0.0\" ? connector.version : \"0.0.1\";\n const pkg: Record<string, unknown> = {\n name: pkgName,\n version,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n type: \"module\",\n main: \"index.js\",\n exports: { \".\": \"./index.js\" },\n keywords: [\"opencode\", \"opencode-plugin\", \"pi-package\", \"agent-connector\"],\n dependencies: { [AGENT_CONNECTOR_PACKAGE_NAME]: resolveFrameworkDependencyRange() },\n // pi reads skills/prompts/themes/extensions from the package.json \"pi\" key.\n pi: { extensions: [\"./index.js\"], skills: [\"./skills\"] },\n engines: { node: \">=18.17\", opencode: \">=1.0.0\" },\n // NOTE: no hardcoded license — this is the DEVELOPER'S publishable package\n // and agent-connector has no authority to license it. The emitter returns a\n // note telling the dev to set license (and author) before `npm publish`.\n };\n if (connector.publish?.author?.name) {\n pkg.author = connector.publish.author.name;\n }\n return pkg;\n}\n\n/** Compose the self-contained ESM plugin bridge (default-export plugin fn). */\nfunction buildIndexJs(connector: ResolvedConnector): string {\n const frameworkPackageName = JSON.stringify(AGENT_CONNECTOR_PACKAGE_NAME);\n const connectorId = JSON.stringify(connector.id);\n\n const events = connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_OPENCODE[e] !== undefined,\n );\n const has = (e: HookEventName): boolean => events.includes(e);\n\n const header = `/**\n * AUTO-GENERATED by agent-connector — DO NOT EDIT.\n *\n * Publishable OpenCode/Kilo/Pi plugin for connector ${connector.id}. It imports\n * no public framework APIs: every hook invocation shells out to the bundled\n * framework runtime's universal entrypoint and JSON-parses the normalized response.\n * Fail-open: any bridge error degrades to \"allow\".\n */\nimport { execFileSync, execSync } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nconst FRAMEWORK_PACKAGE_NAME = ${frameworkPackageName};\nconst CONNECTOR_ID = ${connectorId};\nconst require = createRequire(import.meta.url);\n\nfunction resolveBridgeCommand() {\n try {\n const pkgJson = require.resolve(FRAMEWORK_PACKAGE_NAME + \"/package.json\");\n return { command: process.execPath, prefix: [join(dirname(pkgJson), \"dist\", \"cli.js\")] };\n } catch {\n return { command: \"agent-connector\", prefix: [] };\n }\n}\n\nconst BRIDGE_COMMAND = resolveBridgeCommand();\n\nfunction bridge(event, payload) {\n try {\n // Prefer the runtime bundled as this plugin's dependency. The bare\n // agent-connector command is only a recovery fallback for hand-built bundles.\n const args = [...BRIDGE_COMMAND.prefix, \"hook\", \"opencode\", event, \"--connector\", CONNECTOR_ID];\n const opts = { input: JSON.stringify(payload), encoding: \"utf8\" };\n const stdout =\n process.platform === \"win32\" && BRIDGE_COMMAND.command === \"agent-connector\"\n ? execSync([BRIDGE_COMMAND.command, ...args].map((a) => '\"' + a + '\"').join(\" \"), opts)\n : execFileSync(BRIDGE_COMMAND.command, args, opts);\n const text = (stdout || \"\").trim();\n if (text === \"\") return { decision: \"allow\" };\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n`;\n\n const handlers: string[] = [];\n if (has(\"PreToolUse\")) {\n handlers.push(` \"tool.execute.before\": async (input, output) => {\n const res = bridge(\"PreToolUse\", {\n toolName: input.tool ?? \"\",\n toolInput: (output && output.args) ?? {},\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (res.decision === \"deny\" || res.decision === \"ask\") {\n throw new Error(res.reason || \"Blocked by ${connector.id}\");\n }\n if (res.updatedInput && output && output.args) Object.assign(output.args, res.updatedInput);\n },`);\n }\n if (has(\"PostToolUse\")) {\n handlers.push(` \"tool.execute.after\": async (input, output) => {\n const res = bridge(\"PostToolUse\", {\n toolName: input.tool ?? \"\",\n toolInput: input.args ?? {},\n toolOutput: output ? output.output : undefined,\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (typeof res.updatedOutput === \"string\" && output) output.output = res.updatedOutput;\n },`);\n }\n if (has(\"SessionStart\")) {\n handlers.push(` \"experimental.chat.system.transform\": async (input, output) => {\n const res = bridge(\"SessionStart\", {\n sessionId: (input && input.sessionID) ?? \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.system)) {\n output.system.splice(1, 0, res.additionalContext);\n }\n },`);\n }\n\n const factory = `\nexport default async function (ctx) {\n const PROJECT_DIR =\n (ctx && (ctx.directory || (ctx.worktree && ctx.worktree.path))) || process.cwd();\n return {\n${handlers.join(\"\\n\")}\n };\n}\n`;\n return header + factory;\n}\n\nexport const emitNpmPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n const notes: string[] = [];\n\n // ── package.json (publishable) ────────────────────────────────────────────\n emit(join(pluginDir, \"package.json\"), json(buildPackageJson(connector)));\n\n // ── index.js (the default-export plugin bridge) ───────────────────────────\n emit(join(pluginDir, \"index.js\"), buildIndexJs(connector));\n\n // ── skills/<name>/SKILL.md (+ resources) — pi bundles skills ──────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── README.md ─────────────────────────────────────────────────────────────\n emit(\n join(pluginDir, \"README.md\"),\n `# ${connector.displayName}\\n\\nOpenCode / Kilo / Pi plugin package emitted by agent-connector.\\n\\n` +\n \"Install with `opencode plugin install <pkg>` / `kilo plugin <pkg>` / `pi install <pkg>`.\\n\\n\" +\n \"Local install (no npm publish needed — live-verified on opencode 1.17.0 / kilo 7.3.16):\\n\" +\n \"`opencode plugin --global file:///<abs-dir>` or `kilo plugin --global file:///<abs-dir>`\\n\" +\n \"(bare absolute paths work too; the entry lands in the config `plugin` array —\\n\" +\n \"there is no uninstall verb, remove it by editing that array).\\n\\n\" +\n \"## Prerequisite\\n\\n\" +\n \"The generated package depends on `@ken-jo/agent-connector` and hooks resolve that\\n\" +\n \"local runtime first. A global `agent-connector` binary is only a recovery fallback\\n\" +\n \"for hand-built bundles; hooks silently no-op, fail-open, if neither runtime exists.\\n\\n\" +\n \"## Before you publish\\n\\n\" +\n \"The emitted package.json carries **no `license` and no `author`** unless your\\n\" +\n \"connector declared `publish.author` — set them to YOUR terms before `npm publish`.\\n\",\n );\n\n notes.push(\n \"npm-plugin: hooks resolve the bundled @ken-jo/agent-connector dependency first; a global agent-connector binary is only a recovery fallback, and hooks silently fail-open without either runtime\",\n );\n notes.push(\n \"npm-plugin: set license/author in the emitted package.json before `npm publish` — agent-connector does not license your plugin for you\",\n );\n\n // Surface the inherent limits of the npm-plugin contract.\n if (connector.commands.length > 0) {\n notes.push(\n `npm-plugin: ${connector.commands.length} command(s) NOT bundled — opencode/kilo commands are native host dirs`,\n );\n }\n if (connector.subagents.length > 0) {\n notes.push(\n `npm-plugin: ${connector.subagents.length} subagent(s) NOT bundled — opencode/kilo subagents are native host dirs`,\n );\n }\n if (connector.server) {\n notes.push(\n `npm-plugin: MCP server NOT bundled inside the package — register it via the opencode.json \"mcp\" key`,\n );\n }\n\n return { files, pluginDir, ...(notes.length > 0 ? { notes } : {}) };\n};\n","/**\n * core/package-formats/mcp-server — emit an official MCP Registry `server.json`.\n *\n * Unlike the host plugin/marketplace bundles, server.json is a DISCOVERY +\n * PUBLISH artifact: it describes the developer's REAL upstream MCP server (what\n * a registry installer runs DIRECTLY), so it must NOT carry agent-connector's\n * `serve` telemetry wrapper. It is emitted from the connector's `publish`\n * metadata (the namespace the dev proved ownership of + their published package)\n * and conforms to the pinned 2025-12-11 schema:\n * • name = `${publish.registryNamespace}/${connector.id}` (one '/', regex-checked)\n * • version = concrete SemVer (ranges are rejected by the registry)\n * • stdio → packages[] { registryType:\"npm\", identifier:<dev pkg>, transport:{type:\"stdio\"} }\n * • remote → remotes[] { type:\"streamable-http\"|\"sse\", url, headers }\n * • token env vars are marked isSecret.\n *\n * agent-connector EMITS a conformant server.json; the dev runs the publish-time\n * ownership proof + upload themselves with the official `mcp-publisher` CLI.\n */\n\nimport { resolve } from \"node:path\";\n\nimport type { ResolvedConnector, ServerDef } from \"../types.js\";\nimport {\n MCP_SERVER_SCHEMA_URL,\n NPM_REGISTRY_BASE_URL,\n REGISTRY_NAME_RE,\n isConcreteSemver,\n isPlaceholderVersion,\n registryTransportType,\n} from \"../mcp-standard.js\";\nimport type { EmitContext, FormatEmitter, PackageResult } from \"./shared.js\";\nimport { createEmitter, json } from \"./shared.js\";\n\n/** A server.json KeyValueInput (environmentVariables[] / headers[] entry). */\ninterface KeyValueInput {\n name: string;\n isSecret?: boolean;\n isRequired?: boolean;\n}\n\n/** Build environmentVariables[] from a stdio ServerDef, marking the bearer token secret. */\nfunction buildEnvVars(server: ServerDef): KeyValueInput[] {\n const vars: KeyValueInput[] = [];\n const byName = new Map<string, KeyValueInput>();\n for (const key of Object.keys(server.env ?? {})) {\n const v: KeyValueInput = { name: key };\n vars.push(v);\n byName.set(key, v);\n }\n if (server.auth?.type === \"bearerEnv\" && server.auth.bearerEnvVar) {\n const name = server.auth.bearerEnvVar;\n const existing = byName.get(name);\n if (existing) {\n existing.isSecret = true;\n existing.isRequired = true;\n } else {\n vars.push({ name, isSecret: true, isRequired: true });\n }\n }\n return vars;\n}\n\n/** Build the conformant server.json object (throws a clear error on missing inputs). */\nfunction buildServerJson(\n connector: ResolvedConnector,\n notes: string[],\n): Record<string, unknown> {\n const publish = connector.publish ?? {};\n\n if (!publish.registryNamespace) {\n throw new Error(\n 'package --format mcp-server-json needs publish.registryNamespace — a reverse-DNS ' +\n 'namespace you OWN (e.g. \"io.github.<your-handle>\" or \"com.<your-domain>\"). ' +\n \"agent-connector never publishes under a namespace it owns; set it in your connector config.\",\n );\n }\n const name = `${publish.registryNamespace}/${connector.id}`;\n if (!REGISTRY_NAME_RE.test(name)) {\n throw new Error(\n `server.json name \"${name}\" must match ${REGISTRY_NAME_RE} (exactly one \"/\").`,\n );\n }\n if (!isConcreteSemver(connector.version)) {\n throw new Error(\n `server.json version must be a concrete SemVer (the registry rejects ranges); got \"${connector.version}\".`,\n );\n }\n if (isPlaceholderVersion(connector.version)) {\n notes.push(\n 'version is the unset placeholder \"0.0.0\" — set a real version before publishing to the registry.',\n );\n }\n\n const out: Record<string, unknown> = {\n $schema: MCP_SERVER_SCHEMA_URL,\n name,\n description: connector.displayName,\n version: connector.version,\n };\n\n const server = connector.server;\n if (!server) {\n notes.push(\n \"connector declares no server — emitted server.json carries neither packages nor remotes \" +\n \"(a hooks/commands-only connector is not a registry server).\",\n );\n return out;\n }\n\n const tt = registryTransportType(server.transport);\n if (tt === null) {\n notes.push(\n `transport \"${server.transport}\" is not an MCP spec transport and cannot be represented in ` +\n \"server.json; emitted server metadata without a package/remote entry.\",\n );\n return out;\n }\n\n if (server.transport === \"stdio\") {\n if (!publish.packageName) {\n throw new Error(\n \"package --format mcp-server-json needs publish.packageName — your REAL published npm \" +\n 'package that runs the MCP server (e.g. \"@acme/acme-db-mcp\"). The registry runs that ' +\n \"package directly, not agent-connector's serve wrapper.\",\n );\n }\n const pkg: Record<string, unknown> = {\n registryType: \"npm\",\n registryBaseUrl: publish.registryBaseUrl ?? NPM_REGISTRY_BASE_URL,\n identifier: publish.packageName,\n version: connector.version,\n transport: { type: \"stdio\" },\n };\n const envVars = buildEnvVars(server);\n if (envVars.length > 0) pkg.environmentVariables = envVars;\n out.packages = [pkg];\n } else {\n // streamable-http | sse → remotes[]\n const remote: Record<string, unknown> = { type: tt, url: server.url };\n const headers = Object.keys(server.headers ?? {}).map((k): KeyValueInput => ({ name: k }));\n if (headers.length > 0) remote.headers = headers;\n if (server.auth && server.auth.type !== \"none\") {\n notes.push(\n `remote server uses auth \"${server.auth.type}\" — add the credential header (isSecret) to ` +\n \"the emitted remotes[].headers before publishing.\",\n );\n }\n out.remotes = [remote];\n }\n\n return out;\n}\n\n/** Emit a registry-conformant server.json for `connector` into ctx.outDir. */\nexport const emitMcpServerJson: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const emitter = createEmitter(ctx.dryRun);\n const notes: string[] = [];\n const serverJson = buildServerJson(connector, notes);\n const path = resolve(ctx.outDir, \"server.json\");\n emitter.emit(path, json(serverJson));\n return {\n files: emitter.files,\n pluginDir: ctx.outDir,\n ...(notes.length > 0 ? { notes } : {}),\n };\n};\n","/**\n * core/package-formats/mcpb — emit an MCPB (.mcpb, formerly DXT) bundle manifest.\n *\n * MCPB is the official cross-client one-click LOCAL-install bundle (Claude\n * Desktop + any MCPB host). A real .mcpb is a SELF-CONTAINED zip (manifest.json\n * + the server + vendored node_modules), which agent-connector cannot assemble\n * at emit time — we do not have the developer's built server tree. So, per the\n * conformance analysis, we emit a CONFORMANT manifest.json describing a\n * self-contained node bundle (NOT an out-of-spec `npx` command-reference, which\n * would assume network + node on PATH at launch and break offline/signing) plus\n * a packaging RECIPE, and leave the `mcpb pack`/`mcpb sign` to the developer —\n * mirroring how server.json defers the publish-time ownership proof.\n *\n * Secrets (the bearer token / sensitive env) are routed through `user_config`\n * (sensitive:true) and referenced as `${user_config.<key>}` in mcp_config.env,\n * so credentials are collected by the host keychain, never inlined.\n */\n\nimport { resolve } from \"node:path\";\n\nimport type { ResolvedConnector, ServerDef } from \"../types.js\";\nimport {\n MCPB_MANIFEST_VERSION,\n isConcreteSemver,\n isPlaceholderVersion,\n} from \"../mcp-standard.js\";\nimport type { EmitContext, FormatEmitter, PackageResult } from \"./shared.js\";\nimport { createEmitter, json } from \"./shared.js\";\n\n/** \"ACME_DB_TOKEN\" → \"Acme Db Token\" for a user_config field title. */\nfunction titleize(s: string): string {\n return s\n .toLowerCase()\n .split(/[_-]+/)\n .filter(Boolean)\n .map((w) => w[0]!.toUpperCase() + w.slice(1))\n .join(\" \");\n}\n\n/** The names of env vars that hold secrets (the bearer token). */\nfunction secretEnvNames(server: ServerDef): Set<string> {\n const names = new Set<string>();\n if (server.auth?.type === \"bearerEnv\" && server.auth.bearerEnvVar) {\n names.add(server.auth.bearerEnvVar);\n }\n return names;\n}\n\nfunction recipeReadme(connector: ResolvedConnector): string {\n return `# ${connector.displayName} — MCPB bundle\n\n\\`agent-connector package --format mcpb\\` emitted the conformant **manifest.json**\n(manifest_version ${MCPB_MANIFEST_VERSION}) for this connector. It does NOT build\nthe \\`.mcpb\\` zip — that step vendors your server and is yours to run, so the\nbundle stays self-contained and signable.\n\n## Finish the bundle\n\n1. Put your built, self-contained MCP server at \\`server/index.js\\`\n (the manifest's \\`entry_point\\` / \\`mcp_config\\`).\n2. Vendor production dependencies into the bundle:\n\n \\`\\`\\`bash\n cd server && npm install --omit=dev && cd ..\n \\`\\`\\`\n\n3. Pack (and optionally sign) with the official MCPB CLI:\n\n \\`\\`\\`bash\n npx @anthropic-ai/mcpb pack . # → ${connector.id}.mcpb\n npx @anthropic-ai/mcpb sign ${connector.id}.mcpb\n \\`\\`\\`\n\nThe resulting \\`.mcpb\\` installs one-click into Claude Desktop and any MCPB host.\nSecrets are declared under \\`user_config\\` and collected by the host keychain at\ninstall time — never inline them in the manifest.\n`;\n}\n\n/** Emit a conformant MCPB manifest.json + packaging recipe for `connector`. */\nexport const emitMcpbBundle: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const publish = connector.publish ?? {};\n if (!publish.author?.name) {\n throw new Error(\n \"package --format mcpb needs publish.author.name — the MCPB manifest requires an author.\",\n );\n }\n if (!isConcreteSemver(connector.version)) {\n throw new Error(\n `mcpb manifest version must be a concrete SemVer; got \"${connector.version}\".`,\n );\n }\n\n const server = connector.server;\n if (!server) {\n throw new Error(\"package --format mcpb needs a server (an MCPB bundle packages an MCP server).\");\n }\n if (server.transport !== \"stdio\") {\n throw new Error(\n `package --format mcpb supports stdio servers; \"${server.transport}\" is a remote server — ` +\n \"publish it via the registry (--format mcp-server-json) instead.\",\n );\n }\n\n const notes: string[] = [];\n if (isPlaceholderVersion(connector.version)) {\n notes.push('version is the unset placeholder \"0.0.0\" — set a real version before packing.');\n }\n\n // Route secret env vars through user_config; pass the rest through verbatim.\n const secrets = secretEnvNames(server);\n const env: Record<string, string> = {};\n const userConfig: Record<string, Record<string, unknown>> = {};\n for (const [k, v] of Object.entries(server.env ?? {})) {\n if (secrets.has(k)) {\n const key = k.toLowerCase();\n userConfig[key] = {\n type: \"string\",\n title: titleize(k),\n description: `Value for ${k}`,\n sensitive: true,\n required: true,\n };\n env[k] = `\\${user_config.${key}}`;\n } else {\n env[k] = v;\n }\n }\n // A bearer-token env not already present in server.env still needs a field.\n for (const name of secrets) {\n if (!(name in env)) {\n const key = name.toLowerCase();\n userConfig[key] = {\n type: \"string\",\n title: titleize(name),\n description: `Value for ${name}`,\n sensitive: true,\n required: true,\n };\n env[name] = `\\${user_config.${key}}`;\n }\n }\n\n const author: Record<string, string> = { name: publish.author.name };\n if (publish.author.email) author.email = publish.author.email;\n if (publish.author.url) author.url = publish.author.url;\n\n const mcpConfig: Record<string, unknown> = {\n command: \"node\",\n args: [\"${__dirname}/server/index.js\"],\n };\n if (Object.keys(env).length > 0) mcpConfig.env = env;\n\n const manifest: Record<string, unknown> = {\n manifest_version: MCPB_MANIFEST_VERSION,\n name: connector.id,\n version: connector.version,\n description: connector.displayName,\n author,\n server: {\n type: \"node\",\n entry_point: \"server/index.js\",\n mcp_config: mcpConfig,\n },\n };\n if (Object.keys(userConfig).length > 0) manifest.user_config = userConfig;\n\n // If the dev's real command is not node-ish, the node template needs adjusting.\n if (server.command && !/\\b(node|npx)\\b/.test(server.command)) {\n notes.push(\n `your server command is \"${server.command}\" — the emitted manifest assumes a node ` +\n \"server (server.type:node); adjust server.type/entry_point for your runtime (python|binary).\",\n );\n }\n notes.push(\n \"emitted manifest.json + README recipe; this format does NOT build the .mcpb zip. \" +\n \"Place your self-contained server at server/index.js, vendor deps, then run `mcpb pack` (see README).\",\n );\n\n const emitter = createEmitter(ctx.dryRun);\n emitter.emit(resolve(ctx.outDir, \"manifest.json\"), json(manifest));\n emitter.emit(resolve(ctx.outDir, \"README.md\"), recipeReadme(connector));\n return { files: emitter.files, pluginDir: ctx.outDir, notes };\n};\n"],"mappings":"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","names":["existsSync","join","resolve","join","buildManifest","buildMarketplace","join","join","SPECS","buildManifest","join","join","PLATFORM","buildManifest","join","join","PLATFORM","buildManifest","join","join","join","resolve","resolve","resolve","resolve","resolve","join"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/interpolate.ts"],"sourcesContent":["/**\n * core/interpolate — universal ${env:VAR} interpolation.\n *\n * The developer writes one portable syntax in their connector config:\n * \"${env:ACME_KEY}\" → value of process.env.ACME_KEY\n * \"${env:ACME_URL:-https://x}\" → value, or the default after \":-\" if unset/empty\n *\n * Two consumers:\n * • resolveEnvRefs / resolveEnvRefsDeep — resolve to literals at INSTALL time,\n * for hosts with NO native interpolation (e.g. Codex TOML).\n * • rewriteEnvRefs — translate to a host's NATIVE interpolation token (e.g.\n * Cursor/VS Code \"${env:VAR}\", Claude \"${VAR}\") so secrets are never baked\n * into config files. Adapters choose which to use.\n */\n\n/** Matches ${env:NAME} and ${env:NAME:-default}. NAME is [A-Za-z_][A-Za-z0-9_]*. */\nexport const ENV_REF_RE = /\\$\\{env:([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\\}/g;\n\n/** Resolve every ${env:VAR} in `input` to a literal from `env`. */\nexport function resolveEnvRefs(\n input: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n return input.replace(ENV_REF_RE, (_m, name: string, def?: string) => {\n const v = env[name];\n if (v != null && v !== \"\") return v;\n return def ?? \"\";\n });\n}\n\n/** Recursively resolve ${env:VAR} in all strings of a JSON-ish value. */\nexport function resolveEnvRefsDeep<T>(value: T, env: NodeJS.ProcessEnv = process.env): T {\n if (typeof value === \"string\") return resolveEnvRefs(value, env) as unknown as T;\n if (Array.isArray(value)) {\n return value.map((v) => resolveEnvRefsDeep(v, env)) as unknown as T;\n }\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) out[k] = resolveEnvRefsDeep(v, env);\n return out as T;\n }\n return value;\n}\n\n/**\n * Translate every ${env:VAR(:-default)} via `render` into a host-native token.\n * The renderer receives the var name and optional default and returns the\n * replacement string (e.g. `(name) => \"${\" + name + \"}\"` for Claude).\n */\nexport function rewriteEnvRefs(\n input: string,\n render: (name: string, def?: string) => string,\n): string {\n return input.replace(ENV_REF_RE, (_m, name: string, def?: string) =>\n render(name, def),\n );\n}\n\n/** True if the string contains at least one ${env:...} reference. */\nexport function hasEnvRef(input: string): boolean {\n ENV_REF_RE.lastIndex = 0;\n return ENV_REF_RE.test(input);\n}\n\n/**\n * Names of every ${env:VAR} reference in a JSON-ish value that\n * {@link resolveEnvRefsDeep} would bake to an EMPTY literal — i.e. the var is\n * unset/empty in `env` AND the reference carries no `:-default`. These are the\n * silent-empty-secret bakes on hosts WITHOUT native interpolation: the install\n * succeeds but writes `\"\"` where a secret was meant, surfacing only as a\n * runtime auth failure inside the MCP server. Returns deduped names in\n * first-seen order; uses the SAME unset/default semantics as resolveEnvRefs so\n * the two can never disagree. A ref WITH a `:-default` is intentional and never\n * reported (even when the default itself is empty — the dev opted into \"\").\n */\nexport function findUnsetEnvRefs<T>(\n value: T,\n env: NodeJS.ProcessEnv = process.env,\n): string[] {\n const seen = new Set<string>();\n const order: string[] = [];\n const scanString = (input: string): void => {\n // A FRESH regex per scan — the shared ENV_REF_RE carries /g lastIndex state\n // (hasEnvRef / matchAll would otherwise start mid-string and miss matches).\n const re = new RegExp(ENV_REF_RE.source, \"g\");\n for (const m of input.matchAll(re)) {\n const name = m[1] as string;\n const def = m[2] as string | undefined;\n // Mirrors resolveEnvRefs: a present, non-empty value resolves to itself;\n // otherwise the default is used (no bake of \"\"). Only an unset/empty var\n // WITHOUT a default bakes \"\" — the case we report.\n const v = env[name];\n if (v != null && v !== \"\") continue;\n if (def !== undefined) continue;\n if (!seen.has(name)) {\n seen.add(name);\n order.push(name);\n }\n }\n };\n const walk = (v: unknown): void => {\n if (typeof v === \"string\") scanString(v);\n else if (Array.isArray(v)) v.forEach(walk);\n else if (v && typeof v === \"object\") Object.values(v).forEach(walk);\n };\n walk(value);\n return order;\n}\n"],"mappings":";;;AAgBO,IAAM,aAAa;AAGnB,SAAS,eACd,OACA,MAAyB,QAAQ,KACzB;AACR,SAAO,MAAM,QAAQ,YAAY,CAAC,IAAI,MAAc,QAAiB;AACnE,UAAM,IAAI,IAAI,IAAI;AAClB,QAAI,KAAK,QAAQ,MAAM,GAAI,QAAO;AAClC,WAAO,OAAO;AAAA,EAChB,CAAC;AACH;AAGO,SAAS,mBAAsB,OAAU,MAAyB,QAAQ,KAAQ;AACvF,MAAI,OAAO,UAAU,SAAU,QAAO,eAAe,OAAO,GAAG;AAC/D,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAAA,EACpD;AACA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,MAA+B,CAAC;AACtC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,EAAG,KAAI,CAAC,IAAI,mBAAmB,GAAG,GAAG;AAC9E,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOO,SAAS,eACd,OACA,QACQ;AACR,SAAO,MAAM;AAAA,IAAQ;AAAA,IAAY,CAAC,IAAI,MAAc,QAClD,OAAO,MAAM,GAAG;AAAA,EAClB;AACF;AAmBO,SAAS,iBACd,OACA,MAAyB,QAAQ,KACvB;AACV,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,QAAkB,CAAC;AACzB,QAAM,aAAa,CAAC,UAAwB;AAG1C,UAAM,KAAK,IAAI,OAAO,WAAW,QAAQ,GAAG;AAC5C,eAAW,KAAK,MAAM,SAAS,EAAE,GAAG;AAClC,YAAM,OAAO,EAAE,CAAC;AAChB,YAAM,MAAM,EAAE,CAAC;AAIf,YAAM,IAAI,IAAI,IAAI;AAClB,UAAI,KAAK,QAAQ,MAAM,GAAI;AAC3B,UAAI,QAAQ,OAAW;AACvB,UAAI,CAAC,KAAK,IAAI,IAAI,GAAG;AACnB,aAAK,IAAI,IAAI;AACb,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACA,QAAM,OAAO,CAAC,MAAqB;AACjC,QAAI,OAAO,MAAM,SAAU,YAAW,CAAC;AAAA,aAC9B,MAAM,QAAQ,CAAC,EAAG,GAAE,QAAQ,IAAI;AAAA,aAChC,KAAK,OAAO,MAAM,SAAU,QAAO,OAAO,CAAC,EAAE,QAAQ,IAAI;AAAA,EACpE;AACA,OAAK,KAAK;AACV,SAAO;AACT;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/registry.ts"],"sourcesContent":["/**\n * adapters/registry — single source of truth for the platforms agent-connector\n * targets. Generalized from context-mode's `ADAPTER_REGISTRY` pattern, adapted\n * to our `Adapter` / `AdapterFactory` contract (adapters/spi.ts).\n *\n * In context-mode the same platform set was redeclared in four places (env-var\n * detection, session-dir lookup, the lazy adapter loader, and per-adapter base\n * constructors); adding a platform meant editing all of them and missing one\n * was silent. Here the list lives ONCE below: each platform is one entry with a\n * lazy `load()` thunk that resolves the adapter singleton. Adding a platform is\n * a single new entry — `getFactory` / `loadAdapter` / `allAdapters` and the\n * detection cascade in detect.ts all derive from this list.\n *\n * `load()` returns the module's default export, which every adapter file is\n * required to provide as its singleton (`export default adapter;`). It is a\n * function (not an eager import) so module loading stays lazy: an adapter is\n * only imported when it is actually needed, keeping startup cheap.\n *\n * Order is load-bearing for runtime host detection (detect.ts iterates env\n * markers in registry order): forks MUST precede their parent so a session\n * running inside a derived shell is not misclassified as the parent. For the\n * three Phase-1 adapters this is moot, but the ordering convention is fixed now\n * so later additions (cursor is a VS Code fork, etc.) slot in correctly.\n */\n\nimport type { PlatformId } from \"../core/types.js\";\nimport type { Adapter, AdapterFactory } from \"./spi.js\";\n\n/**\n * Authoritative list of installable platforms. One entry per platform; the\n * `load` thunk lazily imports the adapter module and returns its default-export\n * singleton. To add a platform: drop its `src/adapters/<id>/index.ts` in place\n * (default-exporting an `Adapter`) and add one entry here.\n */\nexport const ADAPTER_REGISTRY: readonly AdapterFactory[] = [\n // codebuddy (Tencent CodeBuddy) is a Claude Code fork that ALSO exports\n // CLAUDE_SESSION_ID at runtime (its bundle sets both CODEBUDDY_SESSION_ID and\n // CLAUDE_SESSION_ID), so it must precede claude-code: the fork's exclusive\n // runtime markers are checked first during host detection (fork-before-parent).\n {\n id: \"codebuddy\",\n load: () => import(\"./codebuddy/index.js\").then((m) => m.default),\n },\n {\n id: \"claude-code\",\n load: () => import(\"./claude-code/index.js\").then((m) => m.default),\n },\n {\n id: \"codex\",\n load: () => import(\"./codex/index.js\").then((m) => m.default),\n },\n {\n id: \"cursor\",\n load: () => import(\"./cursor/index.js\").then((m) => m.default),\n },\n // vscode-copilot after cursor: cursor is a VS Code fork, so the fork's runtime\n // markers must be checked first during host detection.\n {\n id: \"vscode-copilot\",\n load: () => import(\"./vscode-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"copilot-cli\",\n load: () => import(\"./copilot-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"gemini-cli\",\n load: () => import(\"./gemini-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"warp\",\n load: () => import(\"./warp/index.js\").then((m) => m.default),\n },\n // ts-plugin paradigm: OpenCode loads a generated plugin module that bridges\n // its in-process events to the universal hook entrypoint.\n {\n id: \"opencode\",\n load: () => import(\"./opencode/index.js\").then((m) => m.default),\n },\n // mimo-code is Xiaomi's MiMoCode (@mimo-ai/cli, bin `mimo`) — an OpenCode FORK\n // (ts-plugin, MCP root key \"mcp\", ~/.config/mimocode/mimocode.json). Grouped\n // beside the OpenCode family whose config dialect + plugin contract it shares;\n // detected via the DISTINCT ~/.config/mimocode dir, so there is no fork-ordering\n // constraint vs opencode (no shared config file to disambiguate).\n {\n id: \"mimo-code\",\n load: () => import(\"./mimo-code/index.js\").then((m) => m.default),\n },\n // kilo-cli is the SQLite-backed OpenCode FORK command-line product (ts-plugin,\n // loads @kilocode/plugin modules registered in kilo.jsonc's \"plugin\" array;\n // MCP root key \"mcp\", ~/.config/kilo/kilo.jsonc). Grouped beside the OpenCode\n // family whose plugin contract + config dialect it shares; distinct host from\n // the \"kilo\" extension so there is no fork-ordering constraint between them.\n {\n id: \"kilo-cli\",\n load: () => import(\"./kilo-cli/index.js\").then((m) => m.default),\n },\n // Wave 1 — mcp-only adapters (no lifecycle hooks; MCP registration only).\n {\n id: \"droid\",\n load: () => import(\"./droid/index.js\").then((m) => m.default),\n },\n // openhands is the All-Hands-AI OpenHands CLI (`openhands`, ex-OpenDevin) —\n // a standalone json-stdio host: MCP at ~/.openhands/mcp.json (\"mcpServers\",\n // FastMCP entry shape) + a SEPARATE .openhands/hooks.json carrying the\n // Claude-Code-plugin-compatible nested-rule hooks (6 events). Its persistence\n // dir (~/.openhands) is distinct, so there is no fork-ordering constraint.\n {\n id: \"openhands\",\n load: () => import(\"./openhands/index.js\").then((m) => m.default),\n },\n {\n id: \"roo-code\",\n load: () => import(\"./roo-code/index.js\").then((m) => m.default),\n },\n // kilo is the Kilo Code VS Code extension (kilocode.kilo-code) — a Roo/Cline\n // fork, so it sits beside roo-code (mcp-only, root key \"mcpServers\", VS Code\n // globalStorage / .kilocode project scope). Distinct host from \"kilo-cli\".\n {\n id: \"kilo\",\n load: () => import(\"./kilo/index.js\").then((m) => m.default),\n },\n // cline is the Cline VS Code extension (saoudrizwan.claude-dev) — the most-\n // installed AI coding extension and the PARENT that roo-code and kilo forked.\n // mcp-only (no hook layer); MCP at the globalStorage cline_mcp_settings.json\n // (\"mcpServers\"); content lives in the .clinerules tree + ~/Documents/Cline.\n // NO runtime-marker collision with roo-code (rooveterinaryinc.roo-cline / .roo)\n // or kilo (kilocode.kilo-code / .kilo) — distinct ext ids + dotdirs — so there\n // is NO fork-before-parent ordering constraint here; it simply sits beside them.\n {\n id: \"cline\",\n load: () => import(\"./cline/index.js\").then((m) => m.default),\n },\n {\n id: \"trae\",\n load: () => import(\"./trae/index.js\").then((m) => m.default),\n },\n // antigravity-cli BEFORE antigravity: the `agy` CLI is a fork of the IDE\n // adapter with its own runtime markers (the universal hook command tags the\n // host as \"antigravity-cli\"), so the more-specific CLI marker must be checked\n // before the IDE/parent during host detection.\n {\n id: \"antigravity-cli\",\n load: () => import(\"./antigravity-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"antigravity\",\n load: () => import(\"./antigravity/index.js\").then((m) => m.default),\n },\n {\n id: \"zed\",\n load: () => import(\"./zed/index.js\").then((m) => m.default),\n },\n {\n id: \"amp\",\n load: () => import(\"./amp/index.js\").then((m) => m.default),\n },\n {\n id: \"codebuff\",\n load: () => import(\"./codebuff/index.js\").then((m) => m.default),\n },\n {\n id: \"mux\",\n load: () => import(\"./mux/index.js\").then((m) => m.default),\n },\n // Pi — mcp-only host with no writable MCP config; drives the Agent Skills\n // surface only (writes <piDir>/skills/<name>/SKILL.md).\n {\n id: \"pi\",\n load: () => import(\"./pi/index.js\").then((m) => m.default),\n },\n // Wave 2 — json-stdio adapters (full hook dispatch via the universal entrypoint).\n // jetbrains-copilot before vscode-copilot is unnecessary (distinct hosts); grouped here.\n {\n id: \"jetbrains-copilot\",\n load: () => import(\"./jetbrains-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"qwen-code\",\n load: () => import(\"./qwen-code/index.js\").then((m) => m.default),\n },\n {\n id: \"kiro\",\n load: () => import(\"./kiro/index.js\").then((m) => m.default),\n },\n {\n id: \"kimi\",\n load: () => import(\"./kimi/index.js\").then((m) => m.default),\n },\n {\n id: \"crush\",\n load: () => import(\"./crush/index.js\").then((m) => m.default),\n },\n // Wave 3 — json-stdio adapters with YAML config (MCP in YAML; hooks per host).\n {\n id: \"goose\",\n load: () => import(\"./goose/index.js\").then((m) => m.default),\n },\n {\n id: \"hermes\",\n load: () => import(\"./hermes/index.js\").then((m) => m.default),\n },\n // Wave 4 — ts-plugin adapters (generate a bridge module to the universal entrypoint).\n {\n id: \"omp\",\n load: () => import(\"./omp/index.js\").then((m) => m.default),\n },\n // nemoclaw BEFORE openclaw (fork-before-parent convention). NVIDIA NemoClaw\n // wraps OpenClaw and DRIVES the SAME ~/.openclaw/openclaw.json, so a NemoClaw\n // box carries BOTH the ~/.nemoclaw/ and ~/.openclaw/ markers. Exclusivity is\n // enforced at the SOURCE: OpenClawAdapter.detectInstalled BOWS OUT when\n // ~/.nemoclaw/ is present, so the shared config is never double-targeted as two\n // platforms. This ordering is the deterministic tie-break (matching the\n // antigravity-cli/antigravity precedent). nemoclaw extends OpenClawAdapter\n // (id/name/detection overridden), so inherited server/hook registration still\n // lands in the wrapped openclaw.json.\n {\n id: \"nemoclaw\",\n load: () => import(\"./nemoclaw/index.js\").then((m) => m.default),\n },\n {\n id: \"openclaw\",\n load: () => import(\"./openclaw/index.js\").then((m) => m.default),\n },\n // Wave 5 — mcp-only: Amazon Q Developer CLI. JSON MCP config under ~/.aws/amazonq/\n // (user) and .amazonq/ (project); root key \"mcpServers\"; bare stdio entry\n // { command, args, env, timeout? } or remote entry { type: \"http\", url } (no\n // headers) for http. The agent-format hooks layer (cli-agents/*.json) +\n // agents/prompts content surfaces are separate, not-yet-wired surfaces; this\n // adapter installs MCP entries + the .amazonq/rules memory surface.\n {\n id: \"amazon-q\",\n load: () => import(\"./amazon-q/index.js\").then((m) => m.default),\n },\n // Continue (the `cn` terminal agent / Continue.dev, npm @continuedev/cli) —\n // json-stdio (Claude-compatible hooks). MCP config is YAML at ~/.continue/config.yaml (user) and\n // <projectDir>/.continue/config.yaml (project); root key \"mcpServers\" is a\n // YAML ARRAY of { name, command, type?, args?, env?, cwd?, url } entries (NOT a\n // keyed map). Hooks: a Claude-compatible json-stdio layer in settings.json\n // (~/.continue/settings.json — separate from the MCP config.yaml; PR #11029) +\n // nativeHooks for the host-specific events. Distinct ~/.continue marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"continue\",\n load: () => import(\"./continue/index.js\").then((m) => m.default),\n },\n // Windsurf (Codeium / Cognition's Cascade agent) — mcp-only. USER/GLOBAL scope\n // ONLY: MCP config is JSON at ~/.codeium/windsurf/mcp_config.json (the docs\n // document no project/workspace path), root key \"mcpServers\" is a Claude-\n // Desktop-style OBJECT map keyed by server name (like cursor). stdio entry\n // { command, args?, env? }; remote entry { serverUrl, headers? } (NOT `url`;\n // no type/disabled). No user-installable hook/plugin layer (GUI editor), so it\n // stays mcp-only paradigm — but content surfaces ARE wired: workflows\n // (.windsurf/workflows + ~/.codeium/windsurf/global_workflows), skills\n // (.windsurf/skills + ~/.codeium/windsurf/skills), and the .windsurf/rules\n // memory surface. Distinct ~/.codeium marker — no fork-ordering constraint.\n {\n id: \"windsurf\",\n load: () => import(\"./windsurf/index.js\").then((m) => m.default),\n },\n // Grok CLI (the community superagent-ai/grok-cli, npm `grok-dev`, bin `grok`,\n // MIT) — json-stdio. Id is `grok-cli` (NOT `grok`) to stay distinct from xAI's\n // separate \"Grok Build\" product. USER-SCOPE ONLY: both MCP servers (nested\n // `mcp.servers` JSON ARRAY, keyed by `id`) and hooks (top-level `hooks`,\n // Claude nested-rule shape) live in ~/.grok/user-settings.json (project\n // .grok/settings.json holds neither — Grok excludes project hooks for\n // security). Distinct ~/.grok marker — no fork-ordering constraint vs any\n // sibling.\n {\n id: \"grok-cli\",\n load: () => import(\"./grok-cli/index.js\").then((m) => m.default),\n },\n // Devin CLI (Cognition) — json-stdio. A Rust binary (`devin`, installed via\n // `curl cli.devin.ai/install.sh` → ~/.local/bin/devin). MCP + hooks live in\n // ONE config.json per scope: user ~/.config/devin/config.json\n // (%APPDATA%\\devin\\config.json on Windows) / project <projectDir>/.devin/\n // config.json. MCP root key \"mcpServers\" (object map; stdio { command, args?,\n // env? }, remote { url, transport?, headers? }; native ${env:VAR}). Hooks\n // under the same file's \"hooks\" key (Claude-compatible NESTED-rule shape; reply\n // is the SIMPLE top-level {decision:\"approve\"|\"block\"|\"deny\", reason}). Distinct\n // ~/.config/devin / .devin marker — no fork-ordering constraint.\n {\n id: \"devin\",\n load: () => import(\"./devin/index.js\").then((m) => m.default),\n },\n // Open Interpreter (the new Rust `interpreter` / `i` CLI) — mcp-only. It is a\n // FORK of OpenAI's Codex (README: \"Open Interpreter is a fork of OpenAI's\n // Codex\"), so its native config is Codex's: a TOML `config.toml` carrying\n // `[mcp_servers.<id>]` tables (command/args/env stdio; url/bearer_token_env_var/\n // http_headers streamable-HTTP). The config home is DELIBERATELY isolated from\n // Codex — the `interpreter` binary honors ONLY `$INTERPRETER_HOME` (NOT\n // `$CODEX_HOME`, which it explicitly ignores) and defaults to ~/.openinterpreter\n // (codex-rs/utils/home-dir/src/lib.rs). That distinct dir means there is NO\n // fork-ordering constraint vs codex — the two never target the same file — so\n // it simply sits at the end of the registry. Kept mcp-only (the codex hook\n // subsystem is present in the fork, but the `interpreter` product's live hook\n // wire contract is not first-party-verified, so hooks are not claimed).\n {\n id: \"open-interpreter\",\n load: () => import(\"./open-interpreter/index.js\").then((m) => m.default),\n },\n // Junie (JetBrains' OWN LLM-agnostic coding agent — DISTINCT from\n // jetbrains-copilot, which is GitHub Copilot in JetBrains IDEs) — mcp-only.\n // The `junie` CLI (npm @jetbrains/junie, github.com/JetBrains/junie) shares its\n // MCP JSON config with Junie in JetBrains IDEs: object map \"mcpServers\" at\n // <projectDir>/.junie/mcp/mcp.json (project) and ~/.junie/mcp/mcp.json (user);\n // stdio { command, args?, env? }, remote { url, headers? }. No documented\n // user-installable hook surface → mcp-only. Distinct ~/.junie marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"junie\",\n load: () => import(\"./junie/index.js\").then((m) => m.default),\n },\n // mistral-vibe is Mistral's coding-agent CLI — an mcp-only host. MCP config is\n // TOML at <projectDir>/.vibe/config.toml (project, precedence) → ~/.vibe/\n // config.toml (user); root key `mcp_servers` is a TOML ARRAY-OF-TABLES\n // ([[mcp_servers]], each entry carries a `name` short alias — distinct from\n // codex's table-keyed [mcp_servers.<name>]). Distinct ~/.vibe / .vibe marker —\n // no fork-ordering constraint.\n {\n id: \"mistral-vibe\",\n load: () => import(\"./mistral-vibe/index.js\").then((m) => m.default),\n },\n];\n\n/** O(1) lookup index, built once at module-load time. */\nconst REGISTRY_BY_ID: ReadonlyMap<PlatformId, AdapterFactory> = new Map(\n ADAPTER_REGISTRY.map((factory) => [factory.id, factory] as const),\n);\n\n/** Every platform id present in the registry (useful for matrix tests). */\nexport const REGISTERED_PLATFORM_IDS: ReadonlySet<PlatformId> = new Set(\n ADAPTER_REGISTRY.map((factory) => factory.id),\n);\n\n/**\n * Look up the lazy factory for a platform id. Returns `undefined` for ids that\n * are not registered (including `\"unknown\"` and typos) so callers can fall back\n * deliberately rather than crash.\n */\nexport function getFactory(id: PlatformId | string): AdapterFactory | undefined {\n return REGISTRY_BY_ID.get(id as PlatformId);\n}\n\n/**\n * Resolve a platform id to its adapter singleton. Returns `undefined` when the\n * id is not registered — callers decide whether to skip or fall back.\n */\nexport async function loadAdapter(id: PlatformId | string): Promise<Adapter | undefined> {\n const factory = getFactory(id);\n return factory ? factory.load() : undefined;\n}\n\n/**\n * Load every registered adapter. Imports run in parallel; the result preserves\n * registry order so downstream detection/install logic sees forks before\n * parents.\n */\nexport async function allAdapters(): Promise<Adapter[]> {\n return Promise.all(ADAPTER_REGISTRY.map((factory) => factory.load()));\n}\n"],"mappings":";;;AAkCO,IAAM,mBAA8C;AAAA;AAAA;AAAA;AAAA;AAAA,EAKzD;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,yBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAClE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,2BAAwB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACpE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC9D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,sBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC/D;AAAA;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,8BAA2B,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACvE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,2BAAwB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACpE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,0BAAuB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACnE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,oBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC7D;AAAA;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,yBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA,EAEA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,yBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAClE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,oBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC9D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,oBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,+BAA4B,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACxE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,2BAAwB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACpE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,mBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC5D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,mBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC5D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,mBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC5D;AAAA;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,kBAAe,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC3D;AAAA;AAAA;AAAA,EAGA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,iCAA8B,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC1E;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,yBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAClE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,oBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC7D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,oBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC7D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC9D;AAAA;AAAA,EAEA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC9D;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,sBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC/D;AAAA;AAAA,EAEA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,mBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA,EACA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,wBAAqB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,gCAA6B,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,qBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EAC9D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA,IACE,IAAI;AAAA,IACJ,MAAM,MAAM,OAAO,4BAAyB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,EACrE;AACF;AAGA,IAAM,iBAA0D,IAAI;AAAA,EAClE,iBAAiB,IAAI,CAAC,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAU;AAClE;AAGO,IAAM,0BAAmD,IAAI;AAAA,EAClE,iBAAiB,IAAI,CAAC,YAAY,QAAQ,EAAE;AAC9C;AAOO,SAAS,WAAW,IAAqD;AAC9E,SAAO,eAAe,IAAI,EAAgB;AAC5C;AAMA,eAAsB,YAAY,IAAuD;AACvF,QAAM,UAAU,WAAW,EAAE;AAC7B,SAAO,UAAU,QAAQ,KAAK,IAAI;AACpC;AAOA,eAAsB,cAAkC;AACtD,SAAO,QAAQ,IAAI,iBAAiB,IAAI,CAAC,YAAY,QAAQ,KAAK,CAAC,CAAC;AACtE;","names":[]}