@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usage/readers/hermes.ts"],"sourcesContent":["/**\r\n * usage/readers/hermes — Hermes Agent usage reader (SQLite, sessions table).\r\n *\r\n * Faithful port of tokscale sessions/hermes.rs. Hermes stores one aggregated row\r\n * per session in a `sessions` table inside a single SQLite database:\r\n * • ~/.hermes/state.db\r\n * • $HERMES_HOME/state.db (when HERMES_HOME is set, non-empty)\r\n * (the AGENT_CONNECTOR_HERMES_DIR override + the ~/.hermes default are resolved by\r\n * paths.ts hostRoots(\"hermes\"); HERMES_HOME is honored here, ahead of those, to\r\n * match the Rust storage-path spec which the fixed paths.ts does not encode.)\r\n *\r\n * One SELECT pulls every session that carries a model and at least one token/cost\r\n * signal (port of the Rust query verbatim):\r\n * SELECT id, model, billing_provider, started_at, message_count,\r\n * input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,\r\n * reasoning_tokens, estimated_cost_usd, actual_cost_usd\r\n * FROM sessions\r\n * WHERE model IS NOT NULL AND TRIM(model) != ''\r\n * AND ( COALESCE(input_tokens,0) > 0\r\n * OR COALESCE(output_tokens,0) > 0\r\n * OR COALESCE(cache_read_tokens,0) > 0\r\n * OR COALESCE(cache_write_tokens,0) > 0\r\n * OR COALESCE(reasoning_tokens,0) > 0\r\n * OR COALESCE(actual_cost_usd, estimated_cost_usd, 0) > 0 )\r\n *\r\n * Token extraction (flat columns, no JSON nesting — each NULL → 0, clamped ≥ 0):\r\n * input = input_tokens\r\n * output = output_tokens\r\n * cacheRead = cache_read_tokens\r\n * cacheWrite = cache_write_tokens\r\n * reasoning = reasoning_tokens\r\n * Cost = actual_cost_usd ?? estimated_cost_usd ?? 0 (clamped ≥ 0, prefer actual).\r\n *\r\n * Model: the `model` column (the WHERE already drops null/blank). Provider (port of\r\n * resolved_provider): canonical_provider() of a non-blank `billing_provider`, else\r\n * inferProvider(model), else \"hermes\". Timestamp: `started_at` (f64) disambiguated\r\n * seconds-vs-milliseconds (> 1e12 → ms as-is, else × 1000). Session id = the `id`\r\n * column, which is also the dedup key (one row per session). messageCount =\r\n * `message_count` (clamped ≥ 0). agent fixed to \"Hermes Agent\". No project/workspace\r\n * in the schema. Confidence is \"host-reported\".\r\n *\r\n * Fail-open: db missing/locked/unreadable → openSqlite returns null → []; a bad row\r\n * is skipped, never thrown.\r\n */\r\n\r\nimport { join } from \"node:path\";\r\n\r\nimport type { UsageReader, UsageRecord } from \"../types.js\";\r\nimport { emptyTokens } from \"../aggregate.js\";\r\nimport { inferProvider } from \"../normalize.js\";\r\nimport { firstExistingRoot } from \"../paths.js\";\r\nimport { openSqlite } from \"../sqlite.js\";\r\n\r\nconst PLATFORM_ID = \"hermes\" as const;\r\nconst DEFAULT_PROVIDER = \"hermes\";\r\nconst HERMES_AGENT_NAME = \"Hermes Agent\";\r\n\r\n/** The session columns we read (everything optional / unknown off the row). */\r\ninterface HermesRow {\r\n id?: unknown;\r\n model?: unknown;\r\n billing_provider?: unknown;\r\n started_at?: unknown;\r\n message_count?: unknown;\r\n input_tokens?: unknown;\r\n output_tokens?: unknown;\r\n cache_read_tokens?: unknown;\r\n cache_write_tokens?: unknown;\r\n reasoning_tokens?: unknown;\r\n estimated_cost_usd?: unknown;\r\n actual_cost_usd?: unknown;\r\n}\r\n\r\nconst QUERY = `\r\n SELECT\r\n id,\r\n model,\r\n billing_provider,\r\n started_at,\r\n message_count,\r\n input_tokens,\r\n output_tokens,\r\n cache_read_tokens,\r\n cache_write_tokens,\r\n reasoning_tokens,\r\n estimated_cost_usd,\r\n actual_cost_usd\r\n FROM sessions\r\n WHERE model IS NOT NULL\r\n AND TRIM(model) != ''\r\n AND (\r\n COALESCE(input_tokens, 0) > 0 OR\r\n COALESCE(output_tokens, 0) > 0 OR\r\n COALESCE(cache_read_tokens, 0) > 0 OR\r\n COALESCE(cache_write_tokens, 0) > 0 OR\r\n COALESCE(reasoning_tokens, 0) > 0 OR\r\n COALESCE(actual_cost_usd, estimated_cost_usd, 0) > 0\r\n )\r\n`;\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// DB path resolution (honor $HERMES_HOME, ahead of paths.ts defaults)\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Resolve the Hermes state DB. The Rust spec lists both `~/.hermes/state.db` and\r\n * `$HERMES_HOME/state.db`; the fixed paths.ts only encodes the former (+ the\r\n * AGENT_CONNECTOR_HERMES_DIR override), so we honor HERMES_HOME first here.\r\n * Returns the first existing candidate, or undefined when none is present.\r\n */\r\nfunction resolveDbPath(): string | undefined {\r\n const home = process.env.HERMES_HOME;\r\n if (home != null && home.trim() !== \"\") {\r\n const candidate = join(home.trim(), \"state.db\");\r\n // existsSync is checked by openSqlite (returns null on a missing file), but we\r\n // still need an explicit candidate; let firstExistingRoot cover the default.\r\n return candidate;\r\n }\r\n return firstExistingRoot(PLATFORM_ID);\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Provider resolution (port of provider_identity.rs canonical_provider)\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Canonicalize a single provider segment (port of canonicalize_provider_segment):\r\n * trim, drop a trailing slash, lowercase, `-`→`_`; reject `<…>` placeholders, the\r\n * empty/`unknown` segment, and unknown segments that contain a digit (those are\r\n * model-name fragments). Returns the canonical id or undefined.\r\n */\r\nfunction canonicalizeProviderSegment(segment: string): string | undefined {\r\n const normalized = segment.trim().replace(/\\/+$/, \"\").toLowerCase().replace(/-/g, \"_\");\r\n if (normalized.startsWith(\"<\") && normalized.endsWith(\">\")) return undefined;\r\n switch (normalized) {\r\n case \"\":\r\n case \"unknown\":\r\n return undefined;\r\n case \"x_ai\":\r\n case \"xai\":\r\n return \"xai\";\r\n case \"z_ai\":\r\n case \"zai\":\r\n return \"zai\";\r\n case \"moonshot\":\r\n case \"moonshotai\":\r\n return \"moonshotai\";\r\n case \"meta\":\r\n case \"meta_llama\":\r\n return \"meta_llama\";\r\n case \"azure\":\r\n case \"azure_ai\":\r\n return \"azure_ai\";\r\n case \"anthropic\":\r\n case \"vertex\":\r\n case \"vertex_ai\":\r\n return \"anthropic\";\r\n case \"together\":\r\n case \"together_ai\":\r\n return \"together_ai\";\r\n case \"fireworks\":\r\n case \"fireworks_ai\":\r\n return \"fireworks_ai\";\r\n case \"google\":\r\n case \"gemini\":\r\n return \"google\";\r\n case \"openai\":\r\n case \"openai_codex\":\r\n return \"openai\";\r\n case \"minimax\":\r\n case \"minimaxai\":\r\n case \"minimax_ai\":\r\n return \"minimax\";\r\n case \"mistral\":\r\n case \"mistralai\":\r\n return \"mistralai\";\r\n case \"ai21\":\r\n return \"ai21\";\r\n default:\r\n if (/[0-9]/.test(normalized)) return undefined;\r\n return normalized;\r\n }\r\n}\r\n\r\n/**\r\n * Port of canonical_provider: the first canonical tag from `provider_tags(raw)`\r\n * (split on '/', and for any dotted segment also try its dot-parts), or undefined\r\n * when no segment canonicalizes — so the resolver can fall through to model\r\n * inference, matching the Rust `Option<String>` semantics.\r\n */\r\nfunction canonicalProvider(raw: string): string | undefined {\r\n for (const segment of raw.trim().replace(/\\/+$/, \"\").split(\"/\")) {\r\n const tag = canonicalizeProviderSegment(segment);\r\n if (tag !== undefined) return tag;\r\n if (segment.includes(\".\")) {\r\n for (const dotted of segment.split(\".\")) {\r\n const dottedTag = canonicalizeProviderSegment(dotted);\r\n if (dottedTag !== undefined) return dottedTag;\r\n }\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Resolve the provider (port of resolved_provider): canonical_provider of a\r\n * non-blank `billing_provider`, else inferProvider(model), else \"hermes\".\r\n */\r\nfunction resolvedProvider(billingProvider: unknown, modelId: string): string {\r\n if (typeof billingProvider === \"string\") {\r\n const trimmed = billingProvider.trim();\r\n if (trimmed !== \"\") {\r\n const canonical = canonicalProvider(trimmed);\r\n if (canonical !== undefined) return canonical;\r\n }\r\n }\r\n return inferProvider(modelId) ?? DEFAULT_PROVIDER;\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Numbers & timestamps\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/** Coerce an unknown SQLite cell to an integer ≥ 0 (port of `Option<i64>?.unwrap_or(0).max(0)`). */\r\nfunction tokenCell(v: unknown): number {\r\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\r\n if (!Number.isFinite(n)) return 0;\r\n return Math.max(0, Math.trunc(n));\r\n}\r\n\r\n/** Coerce an unknown SQLite cell to a finite float, or null when absent/garbage. */\r\nfunction floatOrNull(v: unknown): number | null {\r\n const n = typeof v === \"number\" ? v : typeof v === \"string\" ? Number(v) : NaN;\r\n return Number.isFinite(n) ? n : null;\r\n}\r\n\r\n/**\r\n * Disambiguate `started_at` (f64) seconds-vs-milliseconds (port of\r\n * timestamp_secs_to_ms): values already in ms (> 1e12) pass through truncated to\r\n * an integer; smaller values are treated as seconds and scaled × 1000.\r\n */\r\nfunction timestampSecsToMs(timestamp: number): number {\r\n return timestamp > 1e12 ? Math.trunc(timestamp) : Math.trunc(timestamp * 1000);\r\n}\r\n\r\n// ─────────────────────────────────────────────────────────────────────────\r\n// Reader\r\n// ─────────────────────────────────────────────────────────────────────────\r\n\r\n/** The Hermes Agent usage reader singleton. */\r\nconst hermesReader: UsageReader = {\r\n platformId: PLATFORM_ID,\r\n kind: \"local\",\r\n async read({ sinceMs }: { sinceMs?: number }): Promise<UsageRecord[]> {\r\n const dbPath = resolveDbPath();\r\n if (dbPath === undefined) return []; // no state.db → fail-open\r\n\r\n const db = await openSqlite(dbPath);\r\n if (db === null) return []; // missing / locked / unreadable / non-sqlite → fail-open\r\n\r\n try {\r\n const rows = db.all(QUERY); // bad SQL / schema mismatch → [] (fail-open)\r\n const records: UsageRecord[] = [];\r\n\r\n for (const raw of rows) {\r\n const row = raw as HermesRow;\r\n\r\n // id and model are read as non-null strings in the Rust decode; the WHERE\r\n // clause already enforces a non-blank model, but we mirror the decode by\r\n // skipping any row whose id/model is not a usable string.\r\n const sessionId = row.id;\r\n if (typeof sessionId !== \"string\" || sessionId === \"\") continue;\r\n\r\n const modelId = row.model;\r\n if (typeof modelId !== \"string\" || modelId.trim() === \"\") continue;\r\n\r\n const startedAt = floatOrNull(row.started_at) ?? 0;\r\n const ts = timestampSecsToMs(startedAt);\r\n if (sinceMs !== undefined && ts < sinceMs) continue;\r\n\r\n const providerId = resolvedProvider(row.billing_provider, modelId);\r\n\r\n const tokens = emptyTokens();\r\n tokens.input = tokenCell(row.input_tokens);\r\n tokens.output = tokenCell(row.output_tokens);\r\n tokens.cacheRead = tokenCell(row.cache_read_tokens);\r\n tokens.cacheWrite = tokenCell(row.cache_write_tokens);\r\n tokens.reasoning = tokenCell(row.reasoning_tokens);\r\n\r\n // Cost: prefer actual, fall back to estimated, default 0 — clamped ≥ 0.\r\n const actual = floatOrNull(row.actual_cost_usd);\r\n const estimated = floatOrNull(row.estimated_cost_usd);\r\n const cost = Math.max(0, actual ?? estimated ?? 0);\r\n\r\n // message_count: Option<i32>.unwrap_or(0).max(0).\r\n const messageCount = tokenCell(row.message_count);\r\n\r\n const record: UsageRecord = {\r\n platformId: PLATFORM_ID,\r\n modelId,\r\n providerId,\r\n sessionId,\r\n tokens,\r\n cost,\r\n ts,\r\n messageCount,\r\n dedupKey: sessionId, // one row per session → session id is the dedup key\r\n confidence: \"host-reported\",\r\n agent: HERMES_AGENT_NAME,\r\n };\r\n records.push(record);\r\n }\r\n\r\n return records;\r\n } finally {\r\n db.close();\r\n }\r\n },\r\n};\r\n\r\nexport default hermesReader;\r\n"],"mappings":"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","names":[]}
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fail
4
- } from "./chunk-H33M77DD.js";
5
- import "./chunk-YPAXJ7EW.js";
6
- import "./chunk-OP4KBXUO.js";
7
- import "./chunk-Z2MRSS2I.js";
8
- import "./chunk-ISEJWBFF.js";
4
+ } from "./chunk-HATCOSQT.js";
5
+ import "./chunk-7VSZXOXJ.js";
6
+ import "./chunk-LFWYYWLV.js";
7
+ import "./chunk-RNVIK5YJ.js";
8
+ import "./chunk-B6PKHS5I.js";
9
9
  import {
10
10
  isNativeHookDeclared,
11
11
  runHook,
12
12
  runNativeHook
13
- } from "./chunk-I5UXHIDT.js";
14
- import "./chunk-KHO5WNTP.js";
15
- import "./chunk-IVAWP6HH.js";
16
- import "./chunk-PW42ZXCB.js";
17
- import "./chunk-5IOTP7LQ.js";
18
- import "./chunk-D4ELPBB5.js";
19
- import "./chunk-NBYKLUF6.js";
20
- import "./chunk-4NHXLXSD.js";
21
- import "./chunk-UMQ6NBQR.js";
22
- import "./chunk-GZGLCCEE.js";
13
+ } from "./chunk-DWZ5IWF4.js";
14
+ import "./chunk-IOJDZJ72.js";
15
+ import "./chunk-4GH2KA7V.js";
16
+ import "./chunk-DOPFBUCX.js";
17
+ import "./chunk-KWC5DQ5Z.js";
18
+ import "./chunk-TOSNS2BY.js";
19
+ import "./chunk-KFPSJRHR.js";
20
+ import "./chunk-W7AGWAMH.js";
21
+ import "./chunk-ILWHLGIC.js";
22
+ import "./chunk-QYOUQCC6.js";
23
23
 
24
24
  // src/cli/commands/hook.ts
25
25
  import { parseArgs } from "util";
@@ -93,4 +93,4 @@ export {
93
93
  HOOK_EVENTS,
94
94
  run
95
95
  };
96
- //# sourceMappingURL=hook-OEVRDMXD.js.map
96
+ //# sourceMappingURL=hook-PVGBQUQI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/hook.ts"],"sourcesContent":["/**\r\n * cli/commands/hook — the universal json-stdio hook entrypoint.\r\n *\r\n * agent-connector hook <platform> <event> --connector <id>\r\n *\r\n * This is the single command every host's hook config points at (via the stable\r\n * home binary). It reads the ENTIRE host payload from stdin, dispatches through\r\n * runHook, writes any stdout/stderr the adapter produced, and exits with the\r\n * adapter's exit code (the host interprets it as allow/deny/etc.).\r\n *\r\n * Fail-open is the runtime's contract: runHook never rejects, so a framework or\r\n * handler bug can't wedge a host's tool call.\r\n */\r\n\r\nimport { parseArgs } from \"node:util\";\r\n\r\nimport type { HookEventName } from \"../../core/types.js\";\r\nimport { isNativeHookDeclared, runHook, runNativeHook } from \"../../runtime/index.js\";\r\nimport type { RunHookResult } from \"../../runtime/index.js\";\r\nimport { fail } from \"../app.js\";\r\n\r\n// The CLI hook-dispatch gate: every normalized HookEventName the entrypoint\r\n// accepts. MUST stay in sync with HookEventName / define-connector ALL_EVENTS —\r\n// a missing member silently rejects an installed hook at runtime. The\r\n// hook-dispatch-events test pins this set ⊇ ALL_EVENTS so it cannot drift.\r\nexport const HOOK_EVENTS: ReadonlySet<string> = new Set<HookEventName>([\r\n \"SessionStart\",\r\n \"SessionEnd\",\r\n \"UserPromptSubmit\",\r\n \"PreToolUse\",\r\n \"PostToolUse\",\r\n \"PreCompact\",\r\n \"Stop\",\r\n \"Notification\",\r\n \"PermissionRequest\",\r\n \"PostToolUseFailure\",\r\n \"SubagentStart\",\r\n \"SubagentStop\",\r\n \"PostCompact\",\r\n]);\r\n\r\n/** Read all of a readable stream to a UTF-8 string. */\r\nasync function readAll(stream: NodeJS.ReadStream): Promise<string> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stream) {\r\n chunks.push(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\r\n }\r\n return Buffer.concat(chunks).toString(\"utf8\");\r\n}\r\n\r\nexport async function run(argv: string[]): Promise<number> {\r\n const { values, positionals } = parseArgs({\r\n args: argv,\r\n options: {\r\n connector: { type: \"string\" },\r\n },\r\n allowPositionals: true,\r\n });\r\n\r\n const platformId = positionals[0];\r\n const event = positionals[1];\r\n if (!platformId || !event) {\r\n return fail(\"usage: agent-connector hook <platform> <event> --connector <id>\");\r\n }\r\n const connectorId = values.connector;\r\n if (!connectorId || connectorId.trim() === \"\") {\r\n return fail(\"hook requires --connector <id>\");\r\n }\r\n\r\n // NATIVE PASSTHROUGH: a non-union event name is accepted ONLY when the\r\n // resolved connector declares it under platforms[<platform>].nativeHooks —\r\n // dispatch then bypasses the normalized parse/format entirely (raw stdin →\r\n // handler → verbatim JSON stdout). Undeclared names keep the strict error.\r\n if (!HOOK_EVENTS.has(event)) {\r\n if (!(await isNativeHookDeclared(platformId, event, connectorId))) {\r\n return fail(`unknown hook event \"${event}\"`);\r\n }\r\n const stdin = await readAll(process.stdin);\r\n const reply = await runNativeHook({ platformId, event, connectorId, stdin });\r\n return exitWithReply(reply);\r\n }\r\n\r\n // Read the entire host payload before dispatching.\r\n const stdin = await readAll(process.stdin);\r\n\r\n const reply = await runHook({\r\n platformId,\r\n event: event as HookEventName,\r\n connectorId,\r\n stdin,\r\n });\r\n\r\n return exitWithReply(reply);\r\n}\r\n\r\n/** Write a hook reply's stdout/stderr and exit with its code. */\r\nfunction exitWithReply(reply: RunHookResult): never {\r\n if (reply.stdout !== undefined && reply.stdout !== \"\") {\r\n process.stdout.write(reply.stdout);\r\n }\r\n if (reply.stderr !== undefined && reply.stderr !== \"\") {\r\n process.stderr.write(reply.stderr.endsWith(\"\\n\") ? reply.stderr : `${reply.stderr}\\n`);\r\n }\r\n process.exit(reply.exitCode);\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAcA,SAAS,iBAAiB;AAWnB,IAAM,cAAmC,oBAAI,IAAmB;AAAA,EACrE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,eAAe,QAAQ,QAA4C;AACjE,QAAM,SAAmB,CAAC;AAC1B,mBAAiB,SAAS,QAAQ;AAChC,WAAO,KAAK,OAAO,UAAU,WAAW,OAAO,KAAK,KAAK,IAAI,KAAK;AAAA,EACpE;AACA,SAAO,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM;AAC9C;AAEA,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,QAAQ,YAAY,IAAI,UAAU;AAAA,IACxC,MAAM;AAAA,IACN,SAAS;AAAA,MACP,WAAW,EAAE,MAAM,SAAS;AAAA,IAC9B;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,aAAa,YAAY,CAAC;AAChC,QAAM,QAAQ,YAAY,CAAC;AAC3B,MAAI,CAAC,cAAc,CAAC,OAAO;AACzB,WAAO,KAAK,iEAAiE;AAAA,EAC/E;AACA,QAAM,cAAc,OAAO;AAC3B,MAAI,CAAC,eAAe,YAAY,KAAK,MAAM,IAAI;AAC7C,WAAO,KAAK,gCAAgC;AAAA,EAC9C;AAMA,MAAI,CAAC,YAAY,IAAI,KAAK,GAAG;AAC3B,QAAI,CAAE,MAAM,qBAAqB,YAAY,OAAO,WAAW,GAAI;AACjE,aAAO,KAAK,uBAAuB,KAAK,GAAG;AAAA,IAC7C;AACA,UAAMA,SAAQ,MAAM,QAAQ,QAAQ,KAAK;AACzC,UAAMC,SAAQ,MAAM,cAAc,EAAE,YAAY,OAAO,aAAa,OAAAD,OAAM,CAAC;AAC3E,WAAO,cAAcC,MAAK;AAAA,EAC5B;AAGA,QAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK;AAEzC,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,cAAc,KAAK;AAC5B;AAGA,SAAS,cAAc,OAA6B;AAClD,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,MAAM;AAAA,EACnC;AACA,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,SAAS,GAAG,MAAM,MAAM;AAAA,CAAI;AAAA,EACvF;AACA,UAAQ,KAAK,MAAM,QAAQ;AAC7B;","names":["stdin","reply"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { C as ConnectorConfigError, d as defineAction, a as defineCommand, b as defineConfigPatch, c as defineConnector, e as defineHook, f as defineMemory, g as defineNativeHook, h as defineSkill, i as defineStatusline, j as defineSubagent } from './define-connector-DTWb46UB.js';
2
- import { S as ServerDef, M as McpPackageIdentity, R as ResolvedMcpPackageIdentity } from './types-JyhpJHJa.js';
3
- export { A as ActionDef, a as ActionResult, b as AuthSpec, C as ChangeRecord, c as ConnectorConfig, D as DetectedPlatform, d as DiagnosticResult, E as EventPayloadMap, H as HookDefinition, e as HookEventName, f as HookParadigm, g as HookResponse, h as HooksConfig, i as HostCtx, I as InstallResult, j as InstallScope, k as MemoryDef, N as NativeHookDef, l as NativeHookEvent, m as NotificationEvent, P as PermissionRequestEvent, n as PlatformCapabilities, o as PlatformId, p as PlatformMemoryOverride, q as PlatformOverride, r as PostToolUseEvent, s as PostToolUseFailureEvent, t as PreCompactEvent, u as PreToolUseEvent, v as ResolvedConnector, w as SessionEndEvent, x as SessionStartEvent, y as StatuslineContext, z as StatuslineDef, B as StopEvent, F as SubagentStartEvent, G as SubagentStopEvent, T as TelemetryAccessor, J as TelemetryConfig, K as TelemetryUsageSummary, L as ToolFilter, O as Transport, U as UserPromptSubmitEvent } from './types-JyhpJHJa.js';
1
+ export { C as ConnectorConfigError, d as defineAction, a as defineCommand, b as defineConfigPatch, c as defineConnector, e as defineHook, f as defineMemory, g as defineNativeHook, h as defineSkill, i as defineStatusline, j as defineSubagent } from './define-connector-B7tLHVnx.js';
2
+ import { S as ServerDef, M as McpPackageIdentity, R as ResolvedMcpPackageIdentity } from './types-C6j18a6R.js';
3
+ export { A as ActionDef, a as ActionResult, b as AuthSpec, C as ChangeRecord, c as ConnectorConfig, D as DetectedPlatform, d as DiagnosticResult, E as EventPayloadMap, H as HookDefinition, e as HookEventName, f as HookParadigm, g as HookResponse, h as HooksConfig, i as HostCtx, I as InstallResult, j as InstallScope, k as MemoryDef, N as NativeHookDef, l as NativeHookEvent, m as NotificationEvent, P as PermissionRequestEvent, n as PlatformCapabilities, o as PlatformId, p as PlatformMemoryOverride, q as PlatformOverride, r as PostToolUseEvent, s as PostToolUseFailureEvent, t as PreCompactEvent, u as PreToolUseEvent, v as ResolvedConnector, w as SessionEndEvent, x as SessionStartEvent, y as StatuslineContext, z as StatuslineDef, B as StopEvent, F as SubagentStartEvent, G as SubagentStopEvent, T as TelemetryAccessor, J as TelemetryConfig, K as TelemetryUsageSummary, L as ToolFilter, O as Transport, U as UserPromptSubmitEvent } from './types-C6j18a6R.js';
4
4
 
5
5
  /** Derive the host-facing MCP server key from a package name. */
6
6
  declare function deriveHostAliasFromPackageName(packageName: string): string | undefined;
package/dist/index.js CHANGED
@@ -15,11 +15,11 @@ import {
15
15
  deriveHostAliasFromPackageName,
16
16
  inferNpmPackageFromServer,
17
17
  resolveMcpPackageIdentity
18
- } from "./chunk-5IOTP7LQ.js";
19
- import "./chunk-D4ELPBB5.js";
20
- import "./chunk-NBYKLUF6.js";
21
- import "./chunk-UMQ6NBQR.js";
22
- import "./chunk-GZGLCCEE.js";
18
+ } from "./chunk-KWC5DQ5Z.js";
19
+ import "./chunk-TOSNS2BY.js";
20
+ import "./chunk-KFPSJRHR.js";
21
+ import "./chunk-ILWHLGIC.js";
22
+ import "./chunk-QYOUQCC6.js";
23
23
  export {
24
24
  ConnectorConfigError,
25
25
  defineAction,
@@ -3,12 +3,12 @@ import {
3
3
  installConnector,
4
4
  installViaMarketplace,
5
5
  parseInstallMethod
6
- } from "./chunk-PAPMUAR5.js";
7
- import "./chunk-APZDTY76.js";
8
- import "./chunk-2Y2MZRLP.js";
9
- import "./chunk-UM5S7DKK.js";
10
- import "./chunk-6WZODR3Z.js";
11
- import "./chunk-OPXAP3AC.js";
6
+ } from "./chunk-S25MVWBP.js";
7
+ import "./chunk-LZL2YITN.js";
8
+ import "./chunk-7C2IPIIB.js";
9
+ import "./chunk-C747DYNT.js";
10
+ import "./chunk-FJ6F5U3W.js";
11
+ import "./chunk-XN7S44U4.js";
12
12
  import {
13
13
  buildConnectorSummary,
14
14
  fail,
@@ -17,25 +17,25 @@ import {
17
17
  parseTargets,
18
18
  print,
19
19
  renderInstallResult
20
- } from "./chunk-H33M77DD.js";
21
- import "./chunk-Z2MRSS2I.js";
22
- import "./chunk-ISEJWBFF.js";
23
- import "./chunk-KHO5WNTP.js";
20
+ } from "./chunk-HATCOSQT.js";
21
+ import "./chunk-RNVIK5YJ.js";
22
+ import "./chunk-B6PKHS5I.js";
23
+ import "./chunk-4GH2KA7V.js";
24
24
  import {
25
25
  findConnectorConfig,
26
26
  loadConnectorFromPath
27
- } from "./chunk-PW42ZXCB.js";
28
- import "./chunk-5IOTP7LQ.js";
29
- import "./chunk-D4ELPBB5.js";
30
- import "./chunk-NBYKLUF6.js";
31
- import "./chunk-H53QZQJI.js";
32
- import "./chunk-BEFVJ2OE.js";
33
- import "./chunk-MGTDQLJJ.js";
34
- import "./chunk-4NHXLXSD.js";
35
- import "./chunk-UMQ6NBQR.js";
27
+ } from "./chunk-DOPFBUCX.js";
28
+ import "./chunk-KWC5DQ5Z.js";
29
+ import "./chunk-TOSNS2BY.js";
30
+ import "./chunk-KFPSJRHR.js";
31
+ import "./chunk-PSGTHJQU.js";
32
+ import "./chunk-XXLCMSD3.js";
33
+ import "./chunk-UNU2KPYJ.js";
34
+ import "./chunk-W7AGWAMH.js";
35
+ import "./chunk-ILWHLGIC.js";
36
36
  import {
37
37
  sourcesDir
38
- } from "./chunk-GZGLCCEE.js";
38
+ } from "./chunk-QYOUQCC6.js";
39
39
 
40
40
  // src/cli/commands/install.ts
41
41
  import { parseArgs } from "util";
@@ -47,13 +47,24 @@ import {
47
47
  existsSync,
48
48
  mkdirSync,
49
49
  readdirSync,
50
+ readFileSync,
50
51
  renameSync,
51
52
  rmSync,
52
53
  writeFileSync
53
54
  } from "fs";
54
55
  import { tmpdir } from "os";
55
- import { isAbsolute, join, relative, resolve } from "path";
56
+ import { basename, isAbsolute, join, relative, resolve } from "path";
57
+ import { fileURLToPath } from "url";
56
58
  var GITHUB_SEG = /^[A-Za-z0-9._-]+$/;
59
+ var NPM_UNSCOPED_NAME_RE = /^[a-z0-9][a-z0-9._~-]*$/i;
60
+ var NPM_SCOPE_RE = /^@[a-z0-9][a-z0-9._~-]*$/i;
61
+ function isSafeGitHubSegment(segment) {
62
+ return GITHUB_SEG.test(segment) && segment !== "." && segment !== "..";
63
+ }
64
+ function isSafeSubpath(subpath) {
65
+ if (subpath === void 0 || subpath === "") return true;
66
+ return subpath.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..");
67
+ }
57
68
  function looksLocal(value) {
58
69
  if (value === "") return true;
59
70
  if (existsSync(value)) return true;
@@ -92,7 +103,7 @@ function parseRemoteSource(value) {
92
103
  }
93
104
  const hash = url.hash.replace(/^#/, "");
94
105
  if (hash) ref = hash;
95
- if (!GITHUB_SEG.test(owner2) || !GITHUB_SEG.test(repo2)) return null;
106
+ if (!isSafeGitHubSegment(owner2) || !isSafeGitHubSegment(repo2)) return null;
96
107
  return cleanRemote({ owner: owner2, repo: repo2, ref, subpath: subpath2 });
97
108
  }
98
109
  const shorthand = raw.startsWith("github:") ? raw.slice("github:".length) : raw;
@@ -102,7 +113,7 @@ function parseRemoteSource(value) {
102
113
  const owner = segs[0];
103
114
  const repo = segs[1].replace(/\.git$/, "");
104
115
  const subpath = segs.length > 2 ? segs.slice(2).join("/") : void 0;
105
- if (!GITHUB_SEG.test(owner) || !GITHUB_SEG.test(repo)) return null;
116
+ if (!isSafeGitHubSegment(owner) || !isSafeGitHubSegment(repo)) return null;
106
117
  return cleanRemote({ owner, repo, ref: refPart, subpath });
107
118
  }
108
119
  function splitHash(value) {
@@ -116,7 +127,7 @@ function finalizeFromPath(owner, repoAndRest, _ref) {
116
127
  const segs = pathPart.split("/").filter(Boolean);
117
128
  const repo = (segs[0] ?? "").replace(/\.git$/, "");
118
129
  const subpath = segs.length > 1 ? segs.slice(1).join("/") : void 0;
119
- if (!GITHUB_SEG.test(owner) || !GITHUB_SEG.test(repo)) return null;
130
+ if (!isSafeGitHubSegment(owner) || !isSafeGitHubSegment(repo)) return null;
120
131
  return cleanRemote({ owner, repo, ref, subpath });
121
132
  }
122
133
  var REF_RE = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;
@@ -125,6 +136,7 @@ function isSafeRef(ref) {
125
136
  }
126
137
  function cleanRemote(r) {
127
138
  if (r.ref !== void 0 && !isSafeRef(r.ref)) return null;
139
+ if (!isSafeSubpath(r.subpath)) return null;
128
140
  const out = { owner: r.owner, repo: r.repo };
129
141
  if (r.ref) out.ref = r.ref;
130
142
  if (r.subpath && r.subpath !== "") out.subpath = r.subpath;
@@ -144,7 +156,75 @@ function parseGitUrl(value) {
144
156
  if (ref) out.ref = ref;
145
157
  return out;
146
158
  }
159
+ function parseNpmSource(value) {
160
+ const raw = value.trim();
161
+ if (!raw.startsWith("npm:")) return null;
162
+ const spec = raw.slice("npm:".length).trim();
163
+ if (spec === "" || /\s/.test(spec) || spec.startsWith("-")) return null;
164
+ let packageName;
165
+ if (spec.startsWith("@")) {
166
+ const match = spec.match(/^(@[^/@\s]+\/[^/@\s]+)(?:@([^/\s]+))?$/);
167
+ if (!match) return null;
168
+ packageName = match[1];
169
+ } else {
170
+ const match = spec.match(/^([^/@\s]+)(?:@([^/\s]+))?$/);
171
+ if (!match) return null;
172
+ packageName = match[1];
173
+ }
174
+ const parts = packageName.startsWith("@") ? packageName.split("/") : [packageName];
175
+ if (parts.length === 2) {
176
+ if (!NPM_SCOPE_RE.test(parts[0]) || !NPM_UNSCOPED_NAME_RE.test(parts[1])) {
177
+ return null;
178
+ }
179
+ } else if (parts.length === 1) {
180
+ if (!NPM_UNSCOPED_NAME_RE.test(parts[0])) return null;
181
+ } else {
182
+ return null;
183
+ }
184
+ return {
185
+ sourceKind: "npm",
186
+ owner: "npm",
187
+ repo: packageName.replace(/^@/, "").replace(/\//g, "__"),
188
+ packageName,
189
+ packageSpec: spec
190
+ };
191
+ }
192
+ function stripQueryAndHash(value) {
193
+ return value.split(/[?#]/, 1)[0] ?? value;
194
+ }
195
+ function archivePathname(value) {
196
+ try {
197
+ const url = new URL(value);
198
+ return url.pathname;
199
+ } catch {
200
+ return value;
201
+ }
202
+ }
203
+ function isTarballLike(value) {
204
+ const p = stripQueryAndHash(archivePathname(value)).toLowerCase();
205
+ return p.endsWith(".tgz") || p.endsWith(".tar.gz");
206
+ }
207
+ function parseArchiveSource(value) {
208
+ const raw = value.trim();
209
+ const explicit = raw.startsWith("archive:");
210
+ const source = explicit ? raw.slice("archive:".length).trim() : raw;
211
+ if (source === "") return null;
212
+ if (!explicit && !isTarballLike(source)) return null;
213
+ const pathish = stripQueryAndHash(archivePathname(source));
214
+ const base = basename(pathish).replace(/\.tar\.gz$/i, "").replace(/\.tgz$/i, "");
215
+ const repo = base || "source";
216
+ return {
217
+ sourceKind: "archive",
218
+ owner: "archive",
219
+ repo,
220
+ archiveUrl: source
221
+ };
222
+ }
147
223
  function classifySource(value) {
224
+ const npm = parseNpmSource(value);
225
+ if (npm) return { kind: "remote", remote: npm };
226
+ const archive = parseArchiveSource(value);
227
+ if (archive) return { kind: "remote", remote: archive };
148
228
  const gitUrl = parseGitUrl(value);
149
229
  if (gitUrl) return { kind: "remote", remote: gitUrl };
150
230
  if (looksLocal(value)) return { kind: "local", value };
@@ -152,6 +232,9 @@ function classifySource(value) {
152
232
  return remote ? { kind: "remote", remote } : null;
153
233
  }
154
234
  function cloneUrl(r) {
235
+ if (r.sourceKind === "npm" || r.sourceKind === "archive") {
236
+ throw new Error(`${describeRemote(r)} is not a git clone source`);
237
+ }
155
238
  return r.cloneUrl ?? `https://github.com/${r.owner}/${r.repo}.git`;
156
239
  }
157
240
  function tarballUrl(r) {
@@ -160,6 +243,12 @@ function tarballUrl(r) {
160
243
  }
161
244
  function sourceCacheDir(r) {
162
245
  const safe = (s) => s.replace(/[^A-Za-z0-9._-]/g, "-");
246
+ if (r.sourceKind === "npm") {
247
+ return join(sourcesDir(), `npm__${safe(r.packageName ?? r.repo)}__${shortHash(r.packageSpec ?? r.repo)}`);
248
+ }
249
+ if (r.sourceKind === "archive") {
250
+ return join(sourcesDir(), `archive__${safe(r.repo)}__${shortHash(r.archiveUrl ?? r.repo)}`);
251
+ }
163
252
  const base = r.cloneUrl ? `${safe(r.owner)}__${safe(r.repo)}__${shortHash(r.cloneUrl)}` : `${safe(r.owner)}__${safe(r.repo)}`;
164
253
  const name = r.ref ? `${base}__${safe(r.ref)}` : base;
165
254
  return join(sourcesDir(), name);
@@ -177,6 +266,9 @@ function gitAvailable() {
177
266
  }
178
267
  function makeGitFetcher(urlFor = cloneUrl) {
179
268
  return (remote, dest) => {
269
+ if (remote.sourceKind === "npm" || remote.sourceKind === "archive") {
270
+ throw new Error(`${describeRemote(remote)} is not a git clone source`);
271
+ }
180
272
  if (!gitAvailable()) {
181
273
  throw new Error(
182
274
  "git is required to fetch a remote connector source but was not found on PATH. Install git, or pass a local --connector <path>."
@@ -202,7 +294,9 @@ async function tarballFetch(remote, dest) {
202
294
  if (!res.ok) {
203
295
  throw new Error(`failed to download ${url}: HTTP ${res.status} ${res.statusText}`);
204
296
  }
205
- const buf = Buffer.from(await res.arrayBuffer());
297
+ await extractTarballBuffer(Buffer.from(await res.arrayBuffer()), dest);
298
+ }
299
+ function extractTarballBuffer(buf, dest) {
206
300
  const work = join(tmpdir(), `ac-src-${process.pid}-${Date.now()}`);
207
301
  mkdirSync(work, { recursive: true });
208
302
  const tarPath = join(work, "source.tar.gz");
@@ -221,7 +315,75 @@ async function tarballFetch(remote, dest) {
221
315
  renameSync(top, dest);
222
316
  rmSync(work, { recursive: true, force: true });
223
317
  }
318
+ async function archiveFetch(remote, dest) {
319
+ const source = remote.archiveUrl;
320
+ if (!source) throw new Error("archive source is missing archiveUrl");
321
+ if (/^https?:\/\//i.test(source)) {
322
+ const res = await fetch(source);
323
+ if (!res.ok) {
324
+ throw new Error(`failed to download ${source}: HTTP ${res.status} ${res.statusText}`);
325
+ }
326
+ await extractTarballBuffer(Buffer.from(await res.arrayBuffer()), dest);
327
+ return;
328
+ }
329
+ const archivePath = source.startsWith("file://") ? fileURLToPath(source) : source;
330
+ if (!existsSync(archivePath)) {
331
+ throw new Error(`archive source not found: ${source}`);
332
+ }
333
+ extractTarballBuffer(readFileSync(archivePath), dest);
334
+ }
335
+ function npmAvailable() {
336
+ try {
337
+ execFileSync("npm", ["--version"], { stdio: "ignore" });
338
+ return true;
339
+ } catch {
340
+ return false;
341
+ }
342
+ }
343
+ async function npmFetch(remote, dest) {
344
+ const spec = remote.packageSpec;
345
+ if (!spec) throw new Error("npm source is missing packageSpec");
346
+ if (!npmAvailable()) {
347
+ throw new Error(
348
+ `npm is required to fetch npm:${spec} but was not found on PATH. Install npm, or pass a local --connector <path>.`
349
+ );
350
+ }
351
+ const work = join(tmpdir(), `ac-npm-${process.pid}-${Date.now()}`);
352
+ mkdirSync(work, { recursive: true });
353
+ let stdout;
354
+ try {
355
+ stdout = execFileSync(
356
+ "npm",
357
+ ["pack", spec, "--pack-destination", work, "--silent"],
358
+ { encoding: "utf8" }
359
+ );
360
+ } catch (err) {
361
+ rmSync(work, { recursive: true, force: true });
362
+ throw new Error(
363
+ `failed to fetch npm:${spec}: ${err instanceof Error ? err.message : String(err)}`
364
+ );
365
+ }
366
+ const packed = stdout.trim().split(/\r?\n/).filter(Boolean).pop();
367
+ if (!packed) {
368
+ rmSync(work, { recursive: true, force: true });
369
+ throw new Error(`failed to fetch npm:${spec}: npm pack produced no tarball`);
370
+ }
371
+ const tarPath = isAbsolute(packed) ? packed : join(work, packed);
372
+ try {
373
+ extractTarballBuffer(readFileSync(tarPath), dest);
374
+ } finally {
375
+ rmSync(work, { recursive: true, force: true });
376
+ }
377
+ }
224
378
  var gitFetcher = async (remote, dest) => {
379
+ if (remote.sourceKind === "npm") {
380
+ await npmFetch(remote, dest);
381
+ return;
382
+ }
383
+ if (remote.sourceKind === "archive") {
384
+ await archiveFetch(remote, dest);
385
+ return;
386
+ }
225
387
  if (gitAvailable()) {
226
388
  makeGitFetcher()(remote, dest);
227
389
  return;
@@ -286,6 +448,8 @@ function findConfigWithin(dir) {
286
448
  return hitDir === dirAbs ? hit : null;
287
449
  }
288
450
  function describeRemote(r) {
451
+ if (r.sourceKind === "npm") return `npm:${r.packageSpec ?? r.repo}`;
452
+ if (r.sourceKind === "archive") return `archive:${r.archiveUrl ?? r.repo}`;
289
453
  let s = r.cloneUrl ?? `${r.owner}/${r.repo}`;
290
454
  if (r.subpath) s += `/${r.subpath}`;
291
455
  if (r.ref) s += `#${r.ref}`;
@@ -336,7 +500,7 @@ async function run(argv) {
336
500
  const spec = source != null ? classifySource(source) : null;
337
501
  if (source != null && spec == null) {
338
502
  return fail(
339
- `"${source}" is not a local path or a recognizable GitHub source (owner/repo[/subpath][#ref], a github.com URL, git@github.com:\u2026, or github:owner/repo).`
503
+ `"${source}" is not a local path or a recognizable connector source (owner/repo[/subpath][#ref], github URL, git URL, npm:<package>[@version], archive:<path-or-url>, or .tgz/.tar.gz).`
340
504
  );
341
505
  }
342
506
  if (spec != null && spec.kind === "remote") {
@@ -350,7 +514,7 @@ async function run(argv) {
350
514
  const configPath = source ?? findConnectorConfig(projectDir);
351
515
  if (!configPath) {
352
516
  return fail(
353
- "no connector config found. Pass a <source> (local path or owner/repo) or --connector <path>, or add an agent-connector.config.{mjs,js,json} to your project."
517
+ "no connector config found. Pass a <source> (local path, owner/repo, npm:<package>, or archive tarball) or --connector <path>, or add an agent-connector.config.{mjs,js,json} to your project."
354
518
  );
355
519
  }
356
520
  ({ connector, modulePath } = await loadConnectorFromPath(configPath));
@@ -379,4 +543,4 @@ async function run(argv) {
379
543
  export {
380
544
  run
381
545
  };
382
- //# sourceMappingURL=install-5NMCUDG5.js.map
546
+ //# sourceMappingURL=install-HPDIK7F6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/install.ts","../src/core/fetch-source.ts"],"sourcesContent":["/**\r\n * cli/commands/install — deploy a connector across its target platforms.\r\n *\r\n * Resolves the connector config (--connector <path>, else findConnectorConfig\r\n * walking up from the project dir), loads it into a live ResolvedConnector, and\r\n * hands it to the chosen DELIVERY METHOD's orchestration:\r\n *\r\n * --method direct (default) — the installer renders each host's native\r\n * MCP + hook + content config in place (zero behavior\r\n * change for existing scripts).\r\n * --method marketplace — stage the connector's plugin bundle under the\r\n * data-root and DRIVE the host's own plugin/marketplace\r\n * install flow (v1 driver: claude-code; other hosts get\r\n * never-silent skip/warn records with manual commands).\r\n *\r\n * Both methods emit the same ChangeRecords, rendered as a readable diff;\r\n * --dry-run renders the plan without writing or spawning. A double-install\r\n * guard (both directions) enforces exactly one method per (connector, host,\r\n * scope) — a refusal is a `warn` record, so the exit-1-on-warn convention\r\n * carries over.\r\n */\r\n\r\nimport { parseArgs } from \"node:util\";\r\n\r\nimport { installConnector } from \"../../core/installer.js\";\r\nimport { installViaMarketplace, parseInstallMethod } from \"../../core/marketplace.js\";\r\nimport { findConnectorConfig, loadConnectorFromPath } from \"../../core/load-connector.js\";\r\nimport { classifySource, resolveRemoteSource } from \"../../core/fetch-source.js\";\r\nimport {\r\n buildConnectorSummary,\r\n fail,\r\n maybePrintBanner,\r\n parseScope,\r\n parseTargets,\r\n print,\r\n renderInstallResult,\r\n} from \"../app.js\";\r\n\r\nexport async function run(argv: string[]): Promise<number> {\r\n const { values, positionals } = parseArgs({\r\n args: argv,\r\n options: {\r\n method: { type: \"string\", default: \"direct\" },\r\n scope: { type: \"string\", default: \"user\" },\r\n targets: { type: \"string\" },\r\n connector: { type: \"string\" },\r\n project: { type: \"string\" },\r\n \"dry-run\": { type: \"boolean\", default: false },\r\n // Memory surface: overwrite USER-EDITED managed blocks (hash drift).\r\n // Default behavior is warn-and-leave; --force backs the file up first.\r\n force: { type: \"boolean\", default: false },\r\n // Decorative-banner suppressor (no effect on command output bytes).\r\n quiet: { type: \"boolean\", default: false },\r\n },\r\n // A single positional <source> (local path OR remote GitHub spec) is the\r\n // ergonomic alias of --connector; either may be remote.\r\n allowPositionals: true,\r\n });\r\n\r\n maybePrintBanner({ quiet: values.quiet });\r\n\r\n const method = parseInstallMethod(values.method);\r\n if (method == null) {\r\n return fail(`invalid --method \"${values.method}\" (use direct|marketplace)`);\r\n }\r\n\r\n const projectDir = values.project ?? process.cwd();\r\n\r\n // A connector source may arrive as the first positional or via --connector,\n // and may be a LOCAL path or a REMOTE source spec (GitHub/raw git, npm:, or\n // archive tarball). The positional and the flag are equivalent; reject\n // ambiguity when both name a source.\n const positionalSource = positionals[0];\r\n if (positionalSource != null && values.connector != null) {\r\n return fail(\"pass a connector source as EITHER the positional <source> OR --connector, not both.\");\r\n }\r\n const source = positionalSource ?? values.connector;\r\n\r\n const scope = parseScope(values.scope);\r\n if (scope == null) return fail(`invalid --scope \"${values.scope}\" (use user|project)`);\r\n if (method === \"marketplace\" && scope !== \"user\") {\r\n return fail(\r\n \"--method marketplace supports --scope user only (project-scope plugin installs are deferred)\",\r\n );\r\n }\r\n\r\n // Resolve the source to a loadable connector. A REMOTE spec is fetched into a\r\n // STABLE cache dir under the data-root and GATED (must be an agent-connector\r\n // package) before handing off to the existing install flow. A LOCAL source —\r\n // or no source at all — keeps today's path-discovery behavior unchanged.\r\n let connector: Awaited<ReturnType<typeof loadConnectorFromPath>>[\"connector\"];\r\n let modulePath: string;\r\n const spec = source != null ? classifySource(source) : null;\r\n if (source != null && spec == null) {\n return fail(\n `\"${source}\" is not a local path or a recognizable connector source ` +\n \"(owner/repo[/subpath][#ref], github URL, git URL, npm:<package>[@version], archive:<path-or-url>, or .tgz/.tar.gz).\",\n );\n }\n if (spec != null && spec.kind === \"remote\") {\r\n try {\r\n const resolved = await resolveRemoteSource(spec.remote);\r\n ({ connector, modulePath } = resolved);\r\n } catch (err) {\r\n return fail(err instanceof Error ? err.message : String(err));\r\n }\r\n } else {\r\n const configPath = source ?? findConnectorConfig(projectDir);\r\n if (!configPath) {\n return fail(\n \"no connector config found. Pass a <source> (local path, owner/repo, npm:<package>, or archive tarball) or \" +\n \"--connector <path>, or add an agent-connector.config.{mjs,js,json} to your project.\",\n );\n }\n ({ connector, modulePath } = await loadConnectorFromPath(configPath));\r\n }\r\n\r\n const targets = parseTargets(values.targets);\r\n\r\n const result =\r\n method === \"marketplace\"\r\n ? await installViaMarketplace({\r\n connector,\r\n modulePath,\r\n scope,\r\n projectDir,\r\n dryRun: values[\"dry-run\"],\r\n ...(targets ? { targets } : {}),\r\n })\r\n : await installConnector({\r\n connector,\r\n modulePath,\r\n scope,\r\n projectDir,\r\n dryRun: values[\"dry-run\"],\r\n force: values.force,\r\n ...(targets ? { targets } : {}),\r\n });\r\n\r\n result.connector = buildConnectorSummary(connector);\r\n print(renderInstallResult(result, \"install\"));\r\n return result.changes.some((c) => c.action === \"warn\") ? 1 : 0;\r\n}\r\n","/**\r\n * core/fetch-source — resolve an `install <source>` argument that may be a\r\n * LOCAL path OR a REMOTE package/source spec into a local connector-config path.\n *\r\n * Responsibilities (MVP):\r\n * 1. CLASSIFY a source string as local-path vs. remote GitHub spec. A value\r\n * that exists on disk, or that looks like a filesystem path (starts with\r\n * `.`, `/`, `~`, a `file://` URL, or a Windows drive/UNC), stays LOCAL and\r\n * keeps today's behavior. Everything else is parsed as a remote spec.\r\n * 2. PARSE the supported remote forms:\n * owner/repo · owner/repo#ref · owner/repo/sub · owner/repo/sub#ref\n * github:owner/repo · https://github.com/owner/repo[/tree/ref/sub]\n * git@github.com:owner/repo.git · the .git suffix on any of the above.\n * npm:<package>[@version] · archive:<path-or-url> · *.tgz / *.tar.gz\n * 3. FETCH + PERSIST the repo to a STABLE cache dir under the data-root\r\n * (`sources/<owner>__<repo>[__<ref>]/`), NOT a temp dir, so a connector\r\n * with a local stdio server keeps resolving after install. Re-fetch updates\r\n * it. `git clone --depth 1` is preferred; a codeload tarball is the\r\n * fallback when `git` is unavailable.\r\n * 4. GATE: the fetched (sub)dir MUST contain an `agent-connector.config.*`\r\n * that loads — otherwise the target is not an agent-connector connector.\r\n *\r\n * The actual fetch is injected via a {@link Fetcher} seam so tests can drive the\r\n * pipeline against a `file://` git fixture without any real network/GitHub hit.\r\n */\r\n\r\nimport { execFileSync } from \"node:child_process\";\r\nimport { createHash } from \"node:crypto\";\r\nimport {\r\n existsSync,\r\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { basename, isAbsolute, join, relative, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\r\nimport { findConnectorConfig, loadConnectorFromPath } from \"./load-connector.js\";\r\nimport { sourcesDir } from \"./paths.js\";\r\nimport type { ResolvedConnector } from \"./types.js\";\r\n\r\n/** A parsed remote source to fetch (a GitHub spec, or a raw git clone URL such\r\n * as `file://`/`ssh://`/`git@…`). `ref` is a branch/tag/sha; `subpath` is the\r\n * directory within the repo that holds the connector config. */\r\nexport interface RemoteSource {\n owner: string;\n repo: string;\n /**\n * Non-git source kind. Omitted for GitHub/raw-git sources to preserve the\n * original object shape used by tests and callers.\n */\n sourceKind?: \"npm\" | \"archive\";\n /** Branch / tag / commit. Undefined → the repo default branch. */\n ref?: string;\n /** Sub-directory inside the repo holding the connector config. */\n subpath?: string;\n /**\r\n * A raw clone URL (file://, ssh://, git@host:…, https://non-github) when the\r\n * source is NOT a github.com owner/repo we can derive a URL for. Present → the\r\n * tarball fallback is unavailable (we can only `git clone` it).\r\n */\n cloneUrl?: string;\n /** npm package spec for sourceKind:\"npm\", e.g. \"@acme/db-mcp@1.2.3\". */\n packageSpec?: string;\n /** npm package name without version/tag, e.g. \"@acme/db-mcp\". */\n packageName?: string;\n /** Tarball path or URL for sourceKind:\"archive\". */\n archiveUrl?: string;\n}\n\r\n/** The classification of an `install <source>` argument. */\r\nexport type SourceSpec =\r\n | { kind: \"local\"; value: string }\r\n | { kind: \"remote\"; remote: RemoteSource };\r\n\r\nconst GITHUB_SEG = /^[A-Za-z0-9._-]+$/;\nconst NPM_UNSCOPED_NAME_RE = /^[a-z0-9][a-z0-9._~-]*$/i;\nconst NPM_SCOPE_RE = /^@[a-z0-9][a-z0-9._~-]*$/i;\n\r\nfunction isSafeGitHubSegment(segment: string): boolean {\r\n return GITHUB_SEG.test(segment) && segment !== \".\" && segment !== \"..\";\r\n}\r\n\r\nfunction isSafeSubpath(subpath: string | undefined): boolean {\r\n if (subpath === undefined || subpath === \"\") return true;\r\n return subpath\r\n .split(\"/\")\r\n .every((segment) => segment !== \"\" && segment !== \".\" && segment !== \"..\");\r\n}\r\n\r\n/**\r\n * True when `value` should be treated as a LOCAL path (existing behavior),\r\n * before any remote-spec parse is attempted. Conservative on purpose: a path\r\n * that exists wins, and the common path sigils (`.`, `/`, `~`, `file://`, a\r\n * Windows drive letter or UNC) are local even when nothing is on disk yet.\r\n */\r\nexport function looksLocal(value: string): boolean {\r\n if (value === \"\") return true;\r\n if (existsSync(value)) return true;\r\n if (\r\n value.startsWith(\"./\") ||\r\n value.startsWith(\"../\") ||\r\n value === \".\" ||\r\n value === \"..\" ||\r\n value.startsWith(\"/\") ||\r\n value.startsWith(\"~\") ||\r\n value.startsWith(\"file://\")\r\n ) {\r\n return true;\r\n }\r\n // Windows drive (C:\\ or C:/) or UNC (\\\\server\\share).\r\n if (/^[A-Za-z]:[\\\\/]/.test(value) || value.startsWith(\"\\\\\\\\\")) return true;\r\n return false;\r\n}\r\n\r\n/**\r\n * Parse a remote GitHub spec into a {@link RemoteSource}, or null when `value`\r\n * is not a recognizable GitHub source. Supports the bare `owner/repo[/sub][#ref]`\r\n * shorthand, `github:owner/repo`, full `https://github.com/...` (incl.\r\n * `/tree/<ref>/<subpath>`), and `git@github.com:owner/repo.git`.\r\n */\r\nexport function parseRemoteSource(value: string): RemoteSource | null {\r\n const raw = value.trim();\r\n if (raw === \"\") return null;\r\n\r\n // ── git@github.com:owner/repo(.git) ───────────────────────────────────────\r\n const scp = raw.match(/^git@github\\.com:([^/]+)\\/(.+?)(?:\\.git)?$/);\r\n if (scp) {\r\n return finalizeFromPath(scp[1]!, scp[2]!, undefined);\r\n }\r\n\r\n // ── https://github.com/owner/repo[/tree/<ref>/<subpath>][.git][#ref] ───────\r\n if (/^https?:\\/\\//i.test(raw) || raw.startsWith(\"git://\")) {\r\n let url: URL;\r\n try {\r\n url = new URL(raw.replace(/^git:\\/\\//, \"https://\"));\r\n } catch {\r\n return null;\r\n }\r\n if (!/(^|\\.)github\\.com$/i.test(url.hostname)) return null;\r\n const segs = url.pathname.replace(/^\\/+/, \"\").split(\"/\").filter(Boolean);\r\n if (segs.length < 2) return null;\r\n const owner = segs[0]!;\r\n let repo = segs[1]!.replace(/\\.git$/, \"\");\r\n let ref: string | undefined;\r\n let subpath: string | undefined;\r\n // /tree/<ref>/<subpath...> selects a ref + sub-directory.\r\n if (segs[2] === \"tree\" || segs[2] === \"blob\") {\r\n ref = segs[3];\r\n if (segs.length > 4) subpath = segs.slice(4).join(\"/\");\r\n } else if (segs.length > 2) {\r\n subpath = segs.slice(2).join(\"/\");\r\n }\r\n const hash = url.hash.replace(/^#/, \"\");\r\n if (hash) ref = hash;\r\n if (!isSafeGitHubSegment(owner) || !isSafeGitHubSegment(repo)) return null;\r\n return cleanRemote({ owner, repo, ref, subpath });\r\n }\r\n\r\n // ── github:owner/repo[...] ────────────────────────────────────────────────\r\n const shorthand = raw.startsWith(\"github:\") ? raw.slice(\"github:\".length) : raw;\r\n\r\n // ── owner/repo[/subpath][#ref] ────────────────────────────────────────────\r\n // Reject anything that doesn't look like the bare `owner/repo` shape (a single\r\n // path segment, or a leading slash) so we never misread a stray token.\r\n const [pathPart, refPart] = splitHash(shorthand);\r\n const segs = pathPart.split(\"/\").filter(Boolean);\r\n if (segs.length < 2) return null;\r\n const owner = segs[0]!;\r\n const repo = segs[1]!.replace(/\\.git$/, \"\");\r\n const subpath = segs.length > 2 ? segs.slice(2).join(\"/\") : undefined;\r\n if (!isSafeGitHubSegment(owner) || !isSafeGitHubSegment(repo)) return null;\r\n return cleanRemote({ owner, repo, ref: refPart, subpath });\r\n}\r\n\r\n/** Split a \"<path>#<ref>\" into [path, ref?]. */\r\nfunction splitHash(value: string): [string, string | undefined] {\r\n const i = value.indexOf(\"#\");\r\n if (i === -1) return [value, undefined];\r\n const ref = value.slice(i + 1).trim();\r\n return [value.slice(0, i), ref === \"\" ? undefined : ref];\r\n}\r\n\r\n/** scp-form helper: the repo half may itself carry `/sub` and `#ref`. */\r\nfunction finalizeFromPath(owner: string, repoAndRest: string, _ref: undefined): RemoteSource | null {\r\n const [pathPart, ref] = splitHash(repoAndRest);\r\n const segs = pathPart.split(\"/\").filter(Boolean);\r\n const repo = (segs[0] ?? \"\").replace(/\\.git$/, \"\");\r\n const subpath = segs.length > 1 ? segs.slice(1).join(\"/\") : undefined;\r\n if (!isSafeGitHubSegment(owner) || !isSafeGitHubSegment(repo)) return null;\r\n return cleanRemote({ owner, repo, ref, subpath });\r\n}\r\n\r\n/**\r\n * A git-refname-safe ref charset: branch/tag/sha names plus the `/`, `.`, `_`,\r\n * `-` they may contain. A LEADING `-` is rejected so a ref can never be read as\r\n * a git flag (e.g. `--upload-pack=…`) when passed to `git clone --branch`, and\r\n * the constrained charset keeps cache-dir names clean. Empty is invalid.\r\n */\r\nconst REF_RE = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;\r\n\r\n/** True when `ref` is a safe git refname (defense-in-depth before exec). */\r\nexport function isSafeRef(ref: string): boolean {\r\n return REF_RE.test(ref);\r\n}\r\n\r\n/**\r\n * Drop empty optional fields so equality/snapshot comparisons stay clean.\r\n * Returns null when a present `ref` is not git-refname-safe (defense-in-depth:\r\n * never pass an attacker-shaped ref to `git clone --branch`).\r\n */\r\nfunction cleanRemote(r: RemoteSource): RemoteSource | null {\r\n if (r.ref !== undefined && !isSafeRef(r.ref)) return null;\r\n if (!isSafeSubpath(r.subpath)) return null;\r\n const out: RemoteSource = { owner: r.owner, repo: r.repo };\r\n if (r.ref) out.ref = r.ref;\r\n if (r.subpath && r.subpath !== \"\") out.subpath = r.subpath;\r\n return out;\r\n}\r\n\r\n/**\r\n * Parse a RAW git clone URL (NOT a github.com owner/repo): `file://…`,\r\n * `ssh://…`, `git@host:owner/repo`, or `https://<non-github>/…`. These are\r\n * `git clone`-able directly. A trailing `#ref` selects a branch/tag/sha. These\r\n * forms point at a repo root (no in-URL subpath). Returns null for anything\r\n * that isn't a clone URL.\r\n */\r\nexport function parseGitUrl(value: string): RemoteSource | null {\n const [urlPart, ref] = splitHash(value.trim());\r\n const isScheme =\r\n urlPart.startsWith(\"file://\") ||\r\n urlPart.startsWith(\"ssh://\") ||\r\n urlPart.startsWith(\"git://\") ||\r\n /^https?:\\/\\//i.test(urlPart);\r\n const isScp = /^[^@\\s]+@[^:\\s]+:.+/.test(urlPart) && !urlPart.startsWith(\"git@github.com:\");\r\n if (!isScheme && !isScp) return null;\r\n // Reject an unsafe ref (e.g. a leading-dash flag) before it reaches git.\r\n if (ref !== undefined && !isSafeRef(ref)) return null;\r\n\r\n // Derive a stable owner/repo cache key from the URL's last two path segments.\r\n const stripped = urlPart.replace(/\\.git$/, \"\").replace(/\\/+$/, \"\");\r\n const segs = stripped.split(/[/:]/).filter(Boolean);\r\n const repo = segs[segs.length - 1] ?? \"repo\";\r\n const owner = segs[segs.length - 2] ?? \"git\";\r\n const out: RemoteSource = { owner, repo, cloneUrl: urlPart };\r\n if (ref) out.ref = ref;\r\n return out;\r\n}\n\n/** Parse an explicit npm source: npm:<package>[@version-or-tag]. */\nexport function parseNpmSource(value: string): RemoteSource | null {\n const raw = value.trim();\n if (!raw.startsWith(\"npm:\")) return null;\n const spec = raw.slice(\"npm:\".length).trim();\n if (spec === \"\" || /\\s/.test(spec) || spec.startsWith(\"-\")) return null;\n\n let packageName: string;\n if (spec.startsWith(\"@\")) {\n const match = spec.match(/^(@[^/@\\s]+\\/[^/@\\s]+)(?:@([^/\\s]+))?$/);\n if (!match) return null;\n packageName = match[1]!;\n } else {\n const match = spec.match(/^([^/@\\s]+)(?:@([^/\\s]+))?$/);\n if (!match) return null;\n packageName = match[1]!;\n }\n\n const parts = packageName.startsWith(\"@\") ? packageName.split(\"/\") : [packageName];\n if (parts.length === 2) {\n if (!NPM_SCOPE_RE.test(parts[0]!) || !NPM_UNSCOPED_NAME_RE.test(parts[1]!)) {\n return null;\n }\n } else if (parts.length === 1) {\n if (!NPM_UNSCOPED_NAME_RE.test(parts[0]!)) return null;\n } else {\n return null;\n }\n\n return {\n sourceKind: \"npm\",\n owner: \"npm\",\n repo: packageName.replace(/^@/, \"\").replace(/\\//g, \"__\"),\n packageName,\n packageSpec: spec,\n };\n}\n\nfunction stripQueryAndHash(value: string): string {\n return value.split(/[?#]/, 1)[0] ?? value;\n}\n\nfunction archivePathname(value: string): string {\n try {\n const url = new URL(value);\n return url.pathname;\n } catch {\n return value;\n }\n}\n\nfunction isTarballLike(value: string): boolean {\n const p = stripQueryAndHash(archivePathname(value)).toLowerCase();\n return p.endsWith(\".tgz\") || p.endsWith(\".tar.gz\");\n}\n\n/** Parse a tarball archive source: archive:<path-or-url> or direct *.tgz/*.tar.gz. */\nexport function parseArchiveSource(value: string): RemoteSource | null {\n const raw = value.trim();\n const explicit = raw.startsWith(\"archive:\");\n const source = explicit ? raw.slice(\"archive:\".length).trim() : raw;\n if (source === \"\") return null;\n if (!explicit && !isTarballLike(source)) return null;\n\n const pathish = stripQueryAndHash(archivePathname(source));\n const base = basename(pathish).replace(/\\.tar\\.gz$/i, \"\").replace(/\\.tgz$/i, \"\");\n const repo = base || \"source\";\n return {\n sourceKind: \"archive\",\n owner: \"archive\",\n repo,\n archiveUrl: source,\n };\n}\n\r\n/**\r\n * Classify an `install <source>` argument. A raw git clone URL (file://, ssh://,\r\n * git@…) or a GitHub spec is REMOTE (a fetch); a local FILESYSTEM path (existing\r\n * or path-shaped, EXCLUDING file:// which is a clone URL) keeps today's\r\n * behavior. Returns null when a non-local value is NOT a recognizable remote.\r\n */\r\nexport function classifySource(value: string): SourceSpec | null {\n const npm = parseNpmSource(value);\n if (npm) return { kind: \"remote\", remote: npm };\n const archive = parseArchiveSource(value);\n if (archive) return { kind: \"remote\", remote: archive };\n // A raw git clone URL (incl. file://) is always a FETCH, never a config path —\n // even though file:// is \"path-shaped\" it names a clonable repo, not a config.\n const gitUrl = parseGitUrl(value);\r\n if (gitUrl) return { kind: \"remote\", remote: gitUrl };\r\n if (looksLocal(value)) return { kind: \"local\", value };\r\n const remote = parseRemoteSource(value);\r\n return remote ? { kind: \"remote\", remote } : null;\r\n}\r\n\r\n/** The clone URL for a remote source (its raw cloneUrl, else the github URL). */\r\nexport function cloneUrl(r: RemoteSource): string {\n if (r.sourceKind === \"npm\" || r.sourceKind === \"archive\") {\n throw new Error(`${describeRemote(r)} is not a git clone source`);\n }\n return r.cloneUrl ?? `https://github.com/${r.owner}/${r.repo}.git`;\n}\n\r\n/** The codeload tarball URL for a github source (default branch when no ref). */\r\nexport function tarballUrl(r: RemoteSource): string {\r\n const ref = r.ref ?? \"HEAD\";\r\n return `https://codeload.github.com/${r.owner}/${r.repo}/tar.gz/${ref}`;\r\n}\r\n\r\n/** The STABLE cache directory a remote source is fetched into. */\r\nexport function sourceCacheDir(r: RemoteSource): string {\n const safe = (s: string) => s.replace(/[^A-Za-z0-9._-]/g, \"-\");\n if (r.sourceKind === \"npm\") {\n return join(sourcesDir(), `npm__${safe(r.packageName ?? r.repo)}__${shortHash(r.packageSpec ?? r.repo)}`);\n }\n if (r.sourceKind === \"archive\") {\n return join(sourcesDir(), `archive__${safe(r.repo)}__${shortHash(r.archiveUrl ?? r.repo)}`);\n }\n // A raw clone URL hashes its full URL into the key so two different file://\n // repos that share an owner/repo basename never collide in the cache.\n const base = r.cloneUrl\r\n ? `${safe(r.owner)}__${safe(r.repo)}__${shortHash(r.cloneUrl)}`\r\n : `${safe(r.owner)}__${safe(r.repo)}`;\r\n const name = r.ref ? `${base}__${safe(r.ref)}` : base;\r\n return join(sourcesDir(), name);\r\n}\r\n\r\n/** A short, filename-safe hash for disambiguating raw clone URLs in the cache. */\r\nfunction shortHash(value: string): string {\r\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 8);\r\n}\r\n\r\n/**\r\n * A fetcher fetches `remote` into the stable directory `dest`. Injected so tests\r\n * can drive the resolve pipeline against a `file://` git fixture (no network).\r\n * The default {@link gitFetcher} clones over HTTPS.\r\n */\r\nexport type Fetcher = (remote: RemoteSource, dest: string) => void | Promise<void>;\r\n\r\n/** True when a usable `git` is on PATH (probed once per process via a cheap call). */\r\nfunction gitAvailable(): boolean {\r\n try {\r\n execFileSync(\"git\", [\"--version\"], { stdio: \"ignore\" });\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * The default fetcher: `git clone --depth 1 [--branch <ref>] <url> <dest>`.\r\n * Re-fetch replaces the cache dir so the clone reflects the requested ref. The\r\n * caller may override the clone URL via `urlFor` (tests pass a `file://` repo).\r\n */\r\nexport function makeGitFetcher(urlFor: (r: RemoteSource) => string = cloneUrl): Fetcher {\n return (remote, dest) => {\n if (remote.sourceKind === \"npm\" || remote.sourceKind === \"archive\") {\n throw new Error(`${describeRemote(remote)} is not a git clone source`);\n }\n if (!gitAvailable()) {\n throw new Error(\r\n \"git is required to fetch a remote connector source but was not found on PATH. \" +\r\n \"Install git, or pass a local --connector <path>.\",\r\n );\r\n }\r\n rmSync(dest, { recursive: true, force: true });\r\n mkdirSync(dest, { recursive: true });\r\n const args = [\"clone\", \"--depth\", \"1\"];\r\n if (remote.ref) args.push(\"--branch\", remote.ref);\r\n args.push(urlFor(remote), dest);\r\n try {\r\n execFileSync(\"git\", args, { stdio: \"ignore\" });\r\n } catch (err) {\r\n throw new Error(\r\n `failed to clone ${urlFor(remote)}${remote.ref ? ` (ref ${remote.ref})` : \"\"}: ` +\r\n `${err instanceof Error ? err.message : String(err)}`,\r\n );\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Tarball fallback: download the GitHub codeload `tar.gz` and extract it with\r\n * the system `tar` (present on Linux, macOS, and Windows 10+). codeload nests\r\n * everything under a single `<repo>-<ref>/` top dir, which we flatten into\r\n * `dest`. Used only when `git` is unavailable.\r\n */\r\nasync function tarballFetch(remote: RemoteSource, dest: string): Promise<void> {\n const url = tarballUrl(remote);\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`failed to download ${url}: HTTP ${res.status} ${res.statusText}`);\n }\n await extractTarballBuffer(Buffer.from(await res.arrayBuffer()), dest);\n}\n\nfunction extractTarballBuffer(buf: Buffer, dest: string): void {\n const work = join(tmpdir(), `ac-src-${process.pid}-${Date.now()}`);\n mkdirSync(work, { recursive: true });\n const tarPath = join(work, \"source.tar.gz\");\r\n writeFileSync(tarPath, buf);\r\n try {\r\n execFileSync(\"tar\", [\"-xzf\", tarPath, \"-C\", work], { stdio: \"ignore\" });\r\n } catch (err) {\r\n rmSync(work, { recursive: true, force: true });\r\n throw new Error(\r\n \"neither git nor a usable `tar` is available to fetch a remote connector \" +\r\n `source (${err instanceof Error ? err.message : String(err)}). Install git ` +\r\n \"or tar, or pass a local --connector <path>.\",\r\n );\r\n }\r\n // codeload nests under a single `<repo>-<ref>/` directory — flatten it.\r\n const entries = readdirSync(work).filter((e) => e !== \"source.tar.gz\");\r\n const top = entries.length === 1 ? join(work, entries[0]!) : work;\r\n rmSync(dest, { recursive: true, force: true });\r\n renameSync(top, dest);\n rmSync(work, { recursive: true, force: true });\n}\n\nasync function archiveFetch(remote: RemoteSource, dest: string): Promise<void> {\n const source = remote.archiveUrl;\n if (!source) throw new Error(\"archive source is missing archiveUrl\");\n\n if (/^https?:\\/\\//i.test(source)) {\n const res = await fetch(source);\n if (!res.ok) {\n throw new Error(`failed to download ${source}: HTTP ${res.status} ${res.statusText}`);\n }\n await extractTarballBuffer(Buffer.from(await res.arrayBuffer()), dest);\n return;\n }\n\n const archivePath = source.startsWith(\"file://\") ? fileURLToPath(source) : source;\n if (!existsSync(archivePath)) {\n throw new Error(`archive source not found: ${source}`);\n }\n extractTarballBuffer(readFileSync(archivePath), dest);\n}\n\nfunction npmAvailable(): boolean {\n try {\n execFileSync(\"npm\", [\"--version\"], { stdio: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n}\n\nasync function npmFetch(remote: RemoteSource, dest: string): Promise<void> {\n const spec = remote.packageSpec;\n if (!spec) throw new Error(\"npm source is missing packageSpec\");\n if (!npmAvailable()) {\n throw new Error(\n `npm is required to fetch npm:${spec} but was not found on PATH. ` +\n \"Install npm, or pass a local --connector <path>.\",\n );\n }\n\n const work = join(tmpdir(), `ac-npm-${process.pid}-${Date.now()}`);\n mkdirSync(work, { recursive: true });\n let stdout: string;\n try {\n stdout = execFileSync(\n \"npm\",\n [\"pack\", spec, \"--pack-destination\", work, \"--silent\"],\n { encoding: \"utf8\" },\n );\n } catch (err) {\n rmSync(work, { recursive: true, force: true });\n throw new Error(\n `failed to fetch npm:${spec}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n const packed = stdout.trim().split(/\\r?\\n/).filter(Boolean).pop();\n if (!packed) {\n rmSync(work, { recursive: true, force: true });\n throw new Error(`failed to fetch npm:${spec}: npm pack produced no tarball`);\n }\n const tarPath = isAbsolute(packed) ? packed : join(work, packed);\n try {\n extractTarballBuffer(readFileSync(tarPath), dest);\n } finally {\n rmSync(work, { recursive: true, force: true });\n }\n}\n\r\n/**\r\n * The default network fetcher: `git clone` when git is on PATH, otherwise the\r\n * codeload tarball fallback (github.com sources only — a raw clone URL can only\r\n * be `git clone`d, so it requires git). A clear error is thrown when neither\r\n * applicable path works.\r\n */\r\nexport const gitFetcher: Fetcher = async (remote, dest) => {\n if (remote.sourceKind === \"npm\") {\n await npmFetch(remote, dest);\n return;\n }\n if (remote.sourceKind === \"archive\") {\n await archiveFetch(remote, dest);\n return;\n }\n if (gitAvailable()) {\n makeGitFetcher()(remote, dest);\r\n return;\r\n }\r\n if (remote.cloneUrl) {\r\n throw new Error(\r\n `git is required to fetch ${remote.cloneUrl} but was not found on PATH. ` +\r\n \"Install git, or pass a local --connector <path>.\",\r\n );\r\n }\r\n await tarballFetch(remote, dest);\r\n};\r\n\r\n/** The resolved output of {@link resolveRemoteSource}. */\r\nexport interface ResolvedSource {\r\n /** Absolute path to the agent-connector.config.* found inside the fetch. */\r\n configPath: string;\r\n /** The directory the source was fetched into (stable, under the data-root). */\r\n sourceDir: string;\r\n /** The (sub)directory the config was found in. */\r\n connectorDir: string;\r\n /** The live connector + its absolute module path (ready for the install flow). */\r\n connector: ResolvedConnector;\r\n modulePath: string;\r\n}\r\n\r\n/** Options for {@link resolveRemoteSource}. */\r\nexport interface ResolveOptions {\r\n /** Override the fetch (tests). Defaults to {@link gitFetcher}. */\r\n fetcher?: Fetcher;\r\n}\r\n\r\n/**\r\n * Fetch a remote source into its stable cache dir, honor the subpath, and GATE\r\n * it as a real agent-connector package: `findConnectorConfig` must locate an\r\n * `agent-connector.config.{mjs,js,json}` that `loadConnectorFromPath` can load.\r\n * Throws a clear, specific error when the target is not an agent-connector\r\n * connector. Returns everything the install flow needs.\r\n */\r\nexport async function resolveRemoteSource(\r\n remote: RemoteSource,\r\n opts: ResolveOptions = {},\r\n): Promise<ResolvedSource> {\r\n const fetcher = opts.fetcher ?? gitFetcher;\r\n const sourceDir = sourceCacheDir(remote);\r\n mkdirSync(sourcesDir(), { recursive: true });\r\n await fetcher(remote, sourceDir);\r\n\r\n const label = describeRemote(remote);\r\n if (!existsSync(sourceDir)) {\r\n throw new Error(`failed to fetch ${label}: nothing was written to ${sourceDir}`);\r\n }\r\n\r\n // Honor the subpath; guard against a `..` escape out of the fetched dir.\r\n // Containment is checked with path.relative (NOT a bare string prefix, which\r\n // a sibling dir sharing the cache-key prefix would defeat) — mirroring the\r\n // connectorDir() guard in paths.ts: reject when the relative path is empty,\r\n // starts with \"..\", or is absolute.\r\n const root = resolve(sourceDir);\r\n const searchDir = remote.subpath ? resolve(root, remote.subpath) : root;\r\n if (remote.subpath) {\r\n const rel = relative(root, searchDir);\r\n if (rel === \"\" || rel.startsWith(\"..\") || isAbsolute(rel)) {\r\n throw new Error(`subpath escapes the fetched source: ${remote.subpath}`);\r\n }\r\n }\r\n if (!existsSync(searchDir)) {\r\n throw new Error(\r\n `${label}: subpath \"${remote.subpath}\" does not exist in the repository.`,\r\n );\r\n }\r\n\r\n // ── PACKAGE GATE ──────────────────────────────────────────────────────────\r\n // Search only WITHIN the fetched (sub)dir. findConnectorConfig walks UPWARD to\r\n // the filesystem root, so confine the start dir and verify the hit is inside.\r\n const configPath = findConfigWithin(searchDir);\r\n if (!configPath) {\r\n throw new Error(\r\n `${label} is not an agent-connector connector — no ` +\r\n `agent-connector.config.{mjs,js,json} found in the repo` +\r\n (remote.subpath ? ` at subpath \"${remote.subpath}\"` : \"\") +\r\n \". The target must be a package built with agent-connector (defineConnector).\",\r\n );\r\n }\r\n\r\n let connector: ResolvedConnector;\r\n let modulePath: string;\r\n try {\r\n ({ connector, modulePath } = await loadConnectorFromPath(configPath));\r\n } catch (err) {\r\n throw new Error(\r\n `${label}: found ${configPath} but it failed to load as an agent-connector ` +\r\n `connector (${err instanceof Error ? err.message : String(err)}). The target ` +\r\n \"must be a package built with agent-connector (defineConnector).\",\r\n );\r\n }\r\n\r\n return {\r\n configPath,\r\n sourceDir,\r\n connectorDir: searchDir,\r\n connector,\r\n modulePath,\r\n };\r\n}\r\n\r\n/**\r\n * Locate `agent-connector.config.*` strictly within `dir` (not its ancestors).\r\n * `findConnectorConfig` walks upward, so we scope the result by asserting the\r\n * hit is in `dir` itself.\r\n */\r\nfunction findConfigWithin(dir: string): string | null {\r\n const hit = findConnectorConfig(dir);\r\n if (!hit) return null;\r\n // Must live directly in the (sub)dir we were pointed at — reject an ancestor\r\n // hit so a parent dir's config can't masquerade as the repo's.\r\n const dirAbs = resolve(dir);\r\n const hitDir = resolve(hit, \"..\");\r\n return hitDir === dirAbs ? hit : null;\r\n}\r\n\r\n/** A human label for a remote source used in error messages. */\r\nexport function describeRemote(r: RemoteSource): string {\n if (r.sourceKind === \"npm\") return `npm:${r.packageSpec ?? r.repo}`;\n if (r.sourceKind === \"archive\") return `archive:${r.archiveUrl ?? r.repo}`;\n let s = r.cloneUrl ?? `${r.owner}/${r.repo}`;\n if (r.subpath) s += `/${r.subpath}`;\n if (r.ref) s += `#${r.ref}`;\r\n return s;\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAS,iBAAiB;;;ACI1B,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,SAAS,UAAU,YAAY,MAAM,UAAU,eAAe;AAC9D,SAAS,qBAAqB;AAwC9B,IAAM,aAAa;AACnB,IAAM,uBAAuB;AAC7B,IAAM,eAAe;AAErB,SAAS,oBAAoB,SAA0B;AACrD,SAAO,WAAW,KAAK,OAAO,KAAK,YAAY,OAAO,YAAY;AACpE;AAEA,SAAS,cAAc,SAAsC;AAC3D,MAAI,YAAY,UAAa,YAAY,GAAI,QAAO;AACpD,SAAO,QACJ,MAAM,GAAG,EACT,MAAM,CAAC,YAAY,YAAY,MAAM,YAAY,OAAO,YAAY,IAAI;AAC7E;AAQO,SAAS,WAAW,OAAwB;AACjD,MAAI,UAAU,GAAI,QAAO;AACzB,MAAI,WAAW,KAAK,EAAG,QAAO;AAC9B,MACE,MAAM,WAAW,IAAI,KACrB,MAAM,WAAW,KAAK,KACtB,UAAU,OACV,UAAU,QACV,MAAM,WAAW,GAAG,KACpB,MAAM,WAAW,GAAG,KACpB,MAAM,WAAW,SAAS,GAC1B;AACA,WAAO;AAAA,EACT;AAEA,MAAI,kBAAkB,KAAK,KAAK,KAAK,MAAM,WAAW,MAAM,EAAG,QAAO;AACtE,SAAO;AACT;AAQO,SAAS,kBAAkB,OAAoC;AACpE,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,QAAQ,GAAI,QAAO;AAGvB,QAAM,MAAM,IAAI,MAAM,4CAA4C;AAClE,MAAI,KAAK;AACP,WAAO,iBAAiB,IAAI,CAAC,GAAI,IAAI,CAAC,GAAI,MAAS;AAAA,EACrD;AAGA,MAAI,gBAAgB,KAAK,GAAG,KAAK,IAAI,WAAW,QAAQ,GAAG;AACzD,QAAI;AACJ,QAAI;AACF,YAAM,IAAI,IAAI,IAAI,QAAQ,aAAa,UAAU,CAAC;AAAA,IACpD,QAAQ;AACN,aAAO;AAAA,IACT;AACA,QAAI,CAAC,sBAAsB,KAAK,IAAI,QAAQ,EAAG,QAAO;AACtD,UAAMA,QAAO,IAAI,SAAS,QAAQ,QAAQ,EAAE,EAAE,MAAM,GAAG,EAAE,OAAO,OAAO;AACvE,QAAIA,MAAK,SAAS,EAAG,QAAO;AAC5B,UAAMC,SAAQD,MAAK,CAAC;AACpB,QAAIE,QAAOF,MAAK,CAAC,EAAG,QAAQ,UAAU,EAAE;AACxC,QAAI;AACJ,QAAIG;AAEJ,QAAIH,MAAK,CAAC,MAAM,UAAUA,MAAK,CAAC,MAAM,QAAQ;AAC5C,YAAMA,MAAK,CAAC;AACZ,UAAIA,MAAK,SAAS,EAAG,CAAAG,WAAUH,MAAK,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,IACvD,WAAWA,MAAK,SAAS,GAAG;AAC1B,MAAAG,WAAUH,MAAK,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,IAClC;AACA,UAAM,OAAO,IAAI,KAAK,QAAQ,MAAM,EAAE;AACtC,QAAI,KAAM,OAAM;AAChB,QAAI,CAAC,oBAAoBC,MAAK,KAAK,CAAC,oBAAoBC,KAAI,EAAG,QAAO;AACtE,WAAO,YAAY,EAAE,OAAAD,QAAO,MAAAC,OAAM,KAAK,SAAAC,SAAQ,CAAC;AAAA,EAClD;AAGA,QAAM,YAAY,IAAI,WAAW,SAAS,IAAI,IAAI,MAAM,UAAU,MAAM,IAAI;AAK5E,QAAM,CAAC,UAAU,OAAO,IAAI,UAAU,SAAS;AAC/C,QAAM,OAAO,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/C,MAAI,KAAK,SAAS,EAAG,QAAO;AAC5B,QAAM,QAAQ,KAAK,CAAC;AACpB,QAAM,OAAO,KAAK,CAAC,EAAG,QAAQ,UAAU,EAAE;AAC1C,QAAM,UAAU,KAAK,SAAS,IAAI,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;AAC5D,MAAI,CAAC,oBAAoB,KAAK,KAAK,CAAC,oBAAoB,IAAI,EAAG,QAAO;AACtE,SAAO,YAAY,EAAE,OAAO,MAAM,KAAK,SAAS,QAAQ,CAAC;AAC3D;AAGA,SAAS,UAAU,OAA6C;AAC9D,QAAM,IAAI,MAAM,QAAQ,GAAG;AAC3B,MAAI,MAAM,GAAI,QAAO,CAAC,OAAO,MAAS;AACtC,QAAM,MAAM,MAAM,MAAM,IAAI,CAAC,EAAE,KAAK;AACpC,SAAO,CAAC,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,KAAK,SAAY,GAAG;AACzD;AAGA,SAAS,iBAAiB,OAAe,aAAqB,MAAsC;AAClG,QAAM,CAAC,UAAU,GAAG,IAAI,UAAU,WAAW;AAC7C,QAAM,OAAO,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/C,QAAM,QAAQ,KAAK,CAAC,KAAK,IAAI,QAAQ,UAAU,EAAE;AACjD,QAAM,UAAU,KAAK,SAAS,IAAI,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI;AAC5D,MAAI,CAAC,oBAAoB,KAAK,KAAK,CAAC,oBAAoB,IAAI,EAAG,QAAO;AACtE,SAAO,YAAY,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC;AAClD;AAQA,IAAM,SAAS;AAGR,SAAS,UAAU,KAAsB;AAC9C,SAAO,OAAO,KAAK,GAAG;AACxB;AAOA,SAAS,YAAY,GAAsC;AACzD,MAAI,EAAE,QAAQ,UAAa,CAAC,UAAU,EAAE,GAAG,EAAG,QAAO;AACrD,MAAI,CAAC,cAAc,EAAE,OAAO,EAAG,QAAO;AACtC,QAAM,MAAoB,EAAE,OAAO,EAAE,OAAO,MAAM,EAAE,KAAK;AACzD,MAAI,EAAE,IAAK,KAAI,MAAM,EAAE;AACvB,MAAI,EAAE,WAAW,EAAE,YAAY,GAAI,KAAI,UAAU,EAAE;AACnD,SAAO;AACT;AASO,SAAS,YAAY,OAAoC;AAC9D,QAAM,CAAC,SAAS,GAAG,IAAI,UAAU,MAAM,KAAK,CAAC;AAC7C,QAAM,WACJ,QAAQ,WAAW,SAAS,KAC5B,QAAQ,WAAW,QAAQ,KAC3B,QAAQ,WAAW,QAAQ,KAC3B,gBAAgB,KAAK,OAAO;AAC9B,QAAM,QAAQ,sBAAsB,KAAK,OAAO,KAAK,CAAC,QAAQ,WAAW,iBAAiB;AAC1F,MAAI,CAAC,YAAY,CAAC,MAAO,QAAO;AAEhC,MAAI,QAAQ,UAAa,CAAC,UAAU,GAAG,EAAG,QAAO;AAGjD,QAAM,WAAW,QAAQ,QAAQ,UAAU,EAAE,EAAE,QAAQ,QAAQ,EAAE;AACjE,QAAM,OAAO,SAAS,MAAM,MAAM,EAAE,OAAO,OAAO;AAClD,QAAM,OAAO,KAAK,KAAK,SAAS,CAAC,KAAK;AACtC,QAAM,QAAQ,KAAK,KAAK,SAAS,CAAC,KAAK;AACvC,QAAM,MAAoB,EAAE,OAAO,MAAM,UAAU,QAAQ;AAC3D,MAAI,IAAK,KAAI,MAAM;AACnB,SAAO;AACT;AAGO,SAAS,eAAe,OAAoC;AACjE,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,CAAC,IAAI,WAAW,MAAM,EAAG,QAAO;AACpC,QAAM,OAAO,IAAI,MAAM,OAAO,MAAM,EAAE,KAAK;AAC3C,MAAI,SAAS,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,WAAW,GAAG,EAAG,QAAO;AAEnE,MAAI;AACJ,MAAI,KAAK,WAAW,GAAG,GAAG;AACxB,UAAM,QAAQ,KAAK,MAAM,wCAAwC;AACjE,QAAI,CAAC,MAAO,QAAO;AACnB,kBAAc,MAAM,CAAC;AAAA,EACvB,OAAO;AACL,UAAM,QAAQ,KAAK,MAAM,6BAA6B;AACtD,QAAI,CAAC,MAAO,QAAO;AACnB,kBAAc,MAAM,CAAC;AAAA,EACvB;AAEA,QAAM,QAAQ,YAAY,WAAW,GAAG,IAAI,YAAY,MAAM,GAAG,IAAI,CAAC,WAAW;AACjF,MAAI,MAAM,WAAW,GAAG;AACtB,QAAI,CAAC,aAAa,KAAK,MAAM,CAAC,CAAE,KAAK,CAAC,qBAAqB,KAAK,MAAM,CAAC,CAAE,GAAG;AAC1E,aAAO;AAAA,IACT;AAAA,EACF,WAAW,MAAM,WAAW,GAAG;AAC7B,QAAI,CAAC,qBAAqB,KAAK,MAAM,CAAC,CAAE,EAAG,QAAO;AAAA,EACpD,OAAO;AACL,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,MAAM,YAAY,QAAQ,MAAM,EAAE,EAAE,QAAQ,OAAO,IAAI;AAAA,IACvD;AAAA,IACA,aAAa;AAAA,EACf;AACF;AAEA,SAAS,kBAAkB,OAAuB;AAChD,SAAO,MAAM,MAAM,QAAQ,CAAC,EAAE,CAAC,KAAK;AACtC;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK;AACzB,WAAO,IAAI;AAAA,EACb,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAAc,OAAwB;AAC7C,QAAM,IAAI,kBAAkB,gBAAgB,KAAK,CAAC,EAAE,YAAY;AAChE,SAAO,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,SAAS;AACnD;AAGO,SAAS,mBAAmB,OAAoC;AACrE,QAAM,MAAM,MAAM,KAAK;AACvB,QAAM,WAAW,IAAI,WAAW,UAAU;AAC1C,QAAM,SAAS,WAAW,IAAI,MAAM,WAAW,MAAM,EAAE,KAAK,IAAI;AAChE,MAAI,WAAW,GAAI,QAAO;AAC1B,MAAI,CAAC,YAAY,CAAC,cAAc,MAAM,EAAG,QAAO;AAEhD,QAAM,UAAU,kBAAkB,gBAAgB,MAAM,CAAC;AACzD,QAAM,OAAO,SAAS,OAAO,EAAE,QAAQ,eAAe,EAAE,EAAE,QAAQ,WAAW,EAAE;AAC/E,QAAM,OAAO,QAAQ;AACrB,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,OAAO;AAAA,IACP;AAAA,IACA,YAAY;AAAA,EACd;AACF;AAQO,SAAS,eAAe,OAAkC;AAC/D,QAAM,MAAM,eAAe,KAAK;AAChC,MAAI,IAAK,QAAO,EAAE,MAAM,UAAU,QAAQ,IAAI;AAC9C,QAAM,UAAU,mBAAmB,KAAK;AACxC,MAAI,QAAS,QAAO,EAAE,MAAM,UAAU,QAAQ,QAAQ;AAGtD,QAAM,SAAS,YAAY,KAAK;AAChC,MAAI,OAAQ,QAAO,EAAE,MAAM,UAAU,QAAQ,OAAO;AACpD,MAAI,WAAW,KAAK,EAAG,QAAO,EAAE,MAAM,SAAS,MAAM;AACrD,QAAM,SAAS,kBAAkB,KAAK;AACtC,SAAO,SAAS,EAAE,MAAM,UAAU,OAAO,IAAI;AAC/C;AAGO,SAAS,SAAS,GAAyB;AAChD,MAAI,EAAE,eAAe,SAAS,EAAE,eAAe,WAAW;AACxD,UAAM,IAAI,MAAM,GAAG,eAAe,CAAC,CAAC,4BAA4B;AAAA,EAClE;AACA,SAAO,EAAE,YAAY,sBAAsB,EAAE,KAAK,IAAI,EAAE,IAAI;AAC9D;AAGO,SAAS,WAAW,GAAyB;AAClD,QAAM,MAAM,EAAE,OAAO;AACrB,SAAO,+BAA+B,EAAE,KAAK,IAAI,EAAE,IAAI,WAAW,GAAG;AACvE;AAGO,SAAS,eAAe,GAAyB;AACtD,QAAM,OAAO,CAAC,MAAc,EAAE,QAAQ,oBAAoB,GAAG;AAC7D,MAAI,EAAE,eAAe,OAAO;AAC1B,WAAO,KAAK,WAAW,GAAG,QAAQ,KAAK,EAAE,eAAe,EAAE,IAAI,CAAC,KAAK,UAAU,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE;AAAA,EAC1G;AACA,MAAI,EAAE,eAAe,WAAW;AAC9B,WAAO,KAAK,WAAW,GAAG,YAAY,KAAK,EAAE,IAAI,CAAC,KAAK,UAAU,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;AAAA,EAC5F;AAGA,QAAM,OAAO,EAAE,WACX,GAAG,KAAK,EAAE,KAAK,CAAC,KAAK,KAAK,EAAE,IAAI,CAAC,KAAK,UAAU,EAAE,QAAQ,CAAC,KAC3D,GAAG,KAAK,EAAE,KAAK,CAAC,KAAK,KAAK,EAAE,IAAI,CAAC;AACrC,QAAM,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,KAAK,EAAE,GAAG,CAAC,KAAK;AACjD,SAAO,KAAK,WAAW,GAAG,IAAI;AAChC;AAGA,SAAS,UAAU,OAAuB;AACxC,SAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AACpE;AAUA,SAAS,eAAwB;AAC/B,MAAI;AACF,iBAAa,OAAO,CAAC,WAAW,GAAG,EAAE,OAAO,SAAS,CAAC;AACtD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOO,SAAS,eAAe,SAAsC,UAAmB;AACtF,SAAO,CAAC,QAAQ,SAAS;AACvB,QAAI,OAAO,eAAe,SAAS,OAAO,eAAe,WAAW;AAClE,YAAM,IAAI,MAAM,GAAG,eAAe,MAAM,CAAC,4BAA4B;AAAA,IACvE;AACA,QAAI,CAAC,aAAa,GAAG;AACnB,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,WAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC7C,cAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACnC,UAAM,OAAO,CAAC,SAAS,WAAW,GAAG;AACrC,QAAI,OAAO,IAAK,MAAK,KAAK,YAAY,OAAO,GAAG;AAChD,SAAK,KAAK,OAAO,MAAM,GAAG,IAAI;AAC9B,QAAI;AACF,mBAAa,OAAO,MAAM,EAAE,OAAO,SAAS,CAAC;AAAA,IAC/C,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,mBAAmB,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM,SAAS,OAAO,GAAG,MAAM,EAAE,KACvE,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AACF;AAQA,eAAe,aAAa,QAAsB,MAA6B;AAC7E,QAAM,MAAM,WAAW,MAAM;AAC7B,QAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,sBAAsB,GAAG,UAAU,IAAI,MAAM,IAAI,IAAI,UAAU,EAAE;AAAA,EACnF;AACA,QAAM,qBAAqB,OAAO,KAAK,MAAM,IAAI,YAAY,CAAC,GAAG,IAAI;AACvE;AAEA,SAAS,qBAAqB,KAAa,MAAoB;AAC7D,QAAM,OAAO,KAAK,OAAO,GAAG,UAAU,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,EAAE;AACjE,YAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACnC,QAAM,UAAU,KAAK,MAAM,eAAe;AAC1C,gBAAc,SAAS,GAAG;AAC1B,MAAI;AACF,iBAAa,OAAO,CAAC,QAAQ,SAAS,MAAM,IAAI,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,EACxE,SAAS,KAAK;AACZ,WAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC7C,UAAM,IAAI;AAAA,MACR,qFACa,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAE/D;AAAA,EACF;AAEA,QAAM,UAAU,YAAY,IAAI,EAAE,OAAO,CAAC,MAAM,MAAM,eAAe;AACrE,QAAM,MAAM,QAAQ,WAAW,IAAI,KAAK,MAAM,QAAQ,CAAC,CAAE,IAAI;AAC7D,SAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC7C,aAAW,KAAK,IAAI;AACpB,SAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC/C;AAEA,eAAe,aAAa,QAAsB,MAA6B;AAC7E,QAAM,SAAS,OAAO;AACtB,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sCAAsC;AAEnE,MAAI,gBAAgB,KAAK,MAAM,GAAG;AAChC,UAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,MAAM,sBAAsB,MAAM,UAAU,IAAI,MAAM,IAAI,IAAI,UAAU,EAAE;AAAA,IACtF;AACA,UAAM,qBAAqB,OAAO,KAAK,MAAM,IAAI,YAAY,CAAC,GAAG,IAAI;AACrE;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,WAAW,SAAS,IAAI,cAAc,MAAM,IAAI;AAC3E,MAAI,CAAC,WAAW,WAAW,GAAG;AAC5B,UAAM,IAAI,MAAM,6BAA6B,MAAM,EAAE;AAAA,EACvD;AACA,uBAAqB,aAAa,WAAW,GAAG,IAAI;AACtD;AAEA,SAAS,eAAwB;AAC/B,MAAI;AACF,iBAAa,OAAO,CAAC,WAAW,GAAG,EAAE,OAAO,SAAS,CAAC;AACtD,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,SAAS,QAAsB,MAA6B;AACzE,QAAM,OAAO,OAAO;AACpB,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,mCAAmC;AAC9D,MAAI,CAAC,aAAa,GAAG;AACnB,UAAM,IAAI;AAAA,MACR,gCAAgC,IAAI;AAAA,IAEtC;AAAA,EACF;AAEA,QAAM,OAAO,KAAK,OAAO,GAAG,UAAU,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC,EAAE;AACjE,YAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACnC,MAAI;AACJ,MAAI;AACF,aAAS;AAAA,MACP;AAAA,MACA,CAAC,QAAQ,MAAM,sBAAsB,MAAM,UAAU;AAAA,MACrD,EAAE,UAAU,OAAO;AAAA,IACrB;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC7C,UAAM,IAAI;AAAA,MACR,uBAAuB,IAAI,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAClF;AAAA,EACF;AACA,QAAM,SAAS,OAAO,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,OAAO,EAAE,IAAI;AAChE,MAAI,CAAC,QAAQ;AACX,WAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAC7C,UAAM,IAAI,MAAM,uBAAuB,IAAI,gCAAgC;AAAA,EAC7E;AACA,QAAM,UAAU,WAAW,MAAM,IAAI,SAAS,KAAK,MAAM,MAAM;AAC/D,MAAI;AACF,yBAAqB,aAAa,OAAO,GAAG,IAAI;AAAA,EAClD,UAAE;AACA,WAAO,MAAM,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EAC/C;AACF;AAQO,IAAM,aAAsB,OAAO,QAAQ,SAAS;AACzD,MAAI,OAAO,eAAe,OAAO;AAC/B,UAAM,SAAS,QAAQ,IAAI;AAC3B;AAAA,EACF;AACA,MAAI,OAAO,eAAe,WAAW;AACnC,UAAM,aAAa,QAAQ,IAAI;AAC/B;AAAA,EACF;AACA,MAAI,aAAa,GAAG;AAClB,mBAAe,EAAE,QAAQ,IAAI;AAC7B;AAAA,EACF;AACA,MAAI,OAAO,UAAU;AACnB,UAAM,IAAI;AAAA,MACR,4BAA4B,OAAO,QAAQ;AAAA,IAE7C;AAAA,EACF;AACA,QAAM,aAAa,QAAQ,IAAI;AACjC;AA4BA,eAAsB,oBACpB,QACA,OAAuB,CAAC,GACC;AACzB,QAAM,UAAU,KAAK,WAAW;AAChC,QAAM,YAAY,eAAe,MAAM;AACvC,YAAU,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;AAC3C,QAAM,QAAQ,QAAQ,SAAS;AAE/B,QAAM,QAAQ,eAAe,MAAM;AACnC,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,UAAM,IAAI,MAAM,mBAAmB,KAAK,4BAA4B,SAAS,EAAE;AAAA,EACjF;AAOA,QAAM,OAAO,QAAQ,SAAS;AAC9B,QAAM,YAAY,OAAO,UAAU,QAAQ,MAAM,OAAO,OAAO,IAAI;AACnE,MAAI,OAAO,SAAS;AAClB,UAAM,MAAM,SAAS,MAAM,SAAS;AACpC,QAAI,QAAQ,MAAM,IAAI,WAAW,IAAI,KAAK,WAAW,GAAG,GAAG;AACzD,YAAM,IAAI,MAAM,uCAAuC,OAAO,OAAO,EAAE;AAAA,IACzE;AAAA,EACF;AACA,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR,GAAG,KAAK,cAAc,OAAO,OAAO;AAAA,IACtC;AAAA,EACF;AAKA,QAAM,aAAa,iBAAiB,SAAS;AAC7C,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR,GAAG,KAAK,2GAEL,OAAO,UAAU,gBAAgB,OAAO,OAAO,MAAM,MACtD;AAAA,IACJ;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,KAAC,EAAE,WAAW,WAAW,IAAI,MAAM,sBAAsB,UAAU;AAAA,EACrE,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,GAAG,KAAK,WAAW,UAAU,2DACb,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAElE;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,EACF;AACF;AAOA,SAAS,iBAAiB,KAA4B;AACpD,QAAM,MAAM,oBAAoB,GAAG;AACnC,MAAI,CAAC,IAAK,QAAO;AAGjB,QAAM,SAAS,QAAQ,GAAG;AAC1B,QAAM,SAAS,QAAQ,KAAK,IAAI;AAChC,SAAO,WAAW,SAAS,MAAM;AACnC;AAGO,SAAS,eAAe,GAAyB;AACtD,MAAI,EAAE,eAAe,MAAO,QAAO,OAAO,EAAE,eAAe,EAAE,IAAI;AACjE,MAAI,EAAE,eAAe,UAAW,QAAO,WAAW,EAAE,cAAc,EAAE,IAAI;AACxE,MAAI,IAAI,EAAE,YAAY,GAAG,EAAE,KAAK,IAAI,EAAE,IAAI;AAC1C,MAAI,EAAE,QAAS,MAAK,IAAI,EAAE,OAAO;AACjC,MAAI,EAAE,IAAK,MAAK,IAAI,EAAE,GAAG;AACzB,SAAO;AACT;;;ADroBA,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,QAAQ,YAAY,IAAI,UAAU;AAAA,IACxC,MAAM;AAAA,IACN,SAAS;AAAA,MACP,QAAQ,EAAE,MAAM,UAAU,SAAS,SAAS;AAAA,MAC5C,OAAO,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,MACzC,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,WAAW,EAAE,MAAM,SAAS;AAAA,MAC5B,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,WAAW,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA;AAAA;AAAA,MAG7C,OAAO,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA;AAAA,MAEzC,OAAO,EAAE,MAAM,WAAW,SAAS,MAAM;AAAA,IAC3C;AAAA;AAAA;AAAA,IAGA,kBAAkB;AAAA,EACpB,CAAC;AAED,mBAAiB,EAAE,OAAO,OAAO,MAAM,CAAC;AAExC,QAAM,SAAS,mBAAmB,OAAO,MAAM;AAC/C,MAAI,UAAU,MAAM;AAClB,WAAO,KAAK,qBAAqB,OAAO,MAAM,4BAA4B;AAAA,EAC5E;AAEA,QAAM,aAAa,OAAO,WAAW,QAAQ,IAAI;AAMjD,QAAM,mBAAmB,YAAY,CAAC;AACtC,MAAI,oBAAoB,QAAQ,OAAO,aAAa,MAAM;AACxD,WAAO,KAAK,qFAAqF;AAAA,EACnG;AACA,QAAM,SAAS,oBAAoB,OAAO;AAE1C,QAAM,QAAQ,WAAW,OAAO,KAAK;AACrC,MAAI,SAAS,KAAM,QAAO,KAAK,oBAAoB,OAAO,KAAK,sBAAsB;AACrF,MAAI,WAAW,iBAAiB,UAAU,QAAQ;AAChD,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAMA,MAAI;AACJ,MAAI;AACJ,QAAM,OAAO,UAAU,OAAO,eAAe,MAAM,IAAI;AACvD,MAAI,UAAU,QAAQ,QAAQ,MAAM;AAClC,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,IAEZ;AAAA,EACF;AACA,MAAI,QAAQ,QAAQ,KAAK,SAAS,UAAU;AAC1C,QAAI;AACF,YAAM,WAAW,MAAM,oBAAoB,KAAK,MAAM;AACtD,OAAC,EAAE,WAAW,WAAW,IAAI;AAAA,IAC/B,SAAS,KAAK;AACZ,aAAO,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,IAC9D;AAAA,EACF,OAAO;AACL,UAAM,aAAa,UAAU,oBAAoB,UAAU;AAC3D,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,QACL;AAAA,MAEF;AAAA,IACF;AACA,KAAC,EAAE,WAAW,WAAW,IAAI,MAAM,sBAAsB,UAAU;AAAA,EACrE;AAEA,QAAM,UAAU,aAAa,OAAO,OAAO;AAE3C,QAAM,SACJ,WAAW,gBACP,MAAM,sBAAsB;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,SAAS;AAAA,IACxB,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/B,CAAC,IACD,MAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,SAAS;AAAA,IACxB,OAAO,OAAO;AAAA,IACd,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/B,CAAC;AAEP,SAAO,YAAY,sBAAsB,SAAS;AAClD,QAAM,oBAAoB,QAAQ,SAAS,CAAC;AAC5C,SAAO,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM,IAAI,IAAI;AAC/D;","names":["segs","owner","repo","subpath"]}
@@ -1,4 +1,4 @@
1
- import { n as PlatformCapabilities, o as PlatformId } from './types-JyhpJHJa.js';
1
+ import { n as PlatformCapabilities, o as PlatformId } from './types-C6j18a6R.js';
2
2
 
3
3
  /**
4
4
  * sdk/introspect — host-capability introspection over the adapter registry.
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  normalizeSessionSource
4
- } from "./chunk-H53QZQJI.js";
4
+ } from "./chunk-PSGTHJQU.js";
5
5
  import {
6
6
  BaseAdapter,
7
7
  renderSkillMd
8
- } from "./chunk-MGTDQLJJ.js";
8
+ } from "./chunk-UNU2KPYJ.js";
9
9
  import {
10
10
  buildHomeBinHookCommand,
11
11
  isHomeBinHookCommand
12
- } from "./chunk-4NHXLXSD.js";
13
- import "./chunk-UMQ6NBQR.js";
14
- import "./chunk-GZGLCCEE.js";
12
+ } from "./chunk-W7AGWAMH.js";
13
+ import "./chunk-ILWHLGIC.js";
14
+ import "./chunk-QYOUQCC6.js";
15
15
 
16
16
  // src/adapters/jetbrains-copilot/index.ts
17
17
  import { existsSync } from "fs";
@@ -710,4 +710,4 @@ export {
710
710
  adapter,
711
711
  jetbrains_copilot_default as default
712
712
  };
713
- //# sourceMappingURL=jetbrains-copilot-ZGIWI6YV.js.map
713
+ //# sourceMappingURL=jetbrains-copilot-2DSVAJMJ.js.map