synurex 2026.2.19-1

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 (1944) hide show
  1. package/CHANGELOG.md +1594 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +547 -0
  5. package/THIRD_PARTY_LICENSES.txt +27 -0
  6. package/assets/avatar-placeholder.svg +19 -0
  7. package/assets/chrome-extension/README.md +22 -0
  8. package/assets/chrome-extension/background.js +438 -0
  9. package/assets/chrome-extension/icons/icon128.png +0 -0
  10. package/assets/chrome-extension/icons/icon16.png +0 -0
  11. package/assets/chrome-extension/icons/icon32.png +0 -0
  12. package/assets/chrome-extension/icons/icon48.png +0 -0
  13. package/assets/chrome-extension/manifest.json +25 -0
  14. package/assets/chrome-extension/options.html +196 -0
  15. package/assets/chrome-extension/options.js +59 -0
  16. package/assets/dmg-background-small.png +0 -0
  17. package/assets/dmg-background.png +0 -0
  18. package/dist/Synurex-root-CbEdPwLE.js +84 -0
  19. package/dist/Synurex-root-CwTH98Xq.js +84 -0
  20. package/dist/accounts-B6AkTILW.js +250 -0
  21. package/dist/accounts-BqN2SY0Z.js +251 -0
  22. package/dist/acp-cli-C1jHGRAm.js +926 -0
  23. package/dist/acp-cli-C3a9o7M2.js +923 -0
  24. package/dist/agent-9DtpfYJk.js +704 -0
  25. package/dist/agent-N2Qtra36.js +704 -0
  26. package/dist/agent-scope-CRRhJ7Hf.js +370 -0
  27. package/dist/agent-scope-CpSMNwey.js +611 -0
  28. package/dist/agent-scope-DNmzkYn4.js +370 -0
  29. package/dist/archive-Dy3Ezb-5.js +85 -0
  30. package/dist/archive-ccN9aDgq.js +85 -0
  31. package/dist/audit--oGM5x0J.js +1853 -0
  32. package/dist/audit-CM8pyctg.js +1853 -0
  33. package/dist/auth-3NYeRZYb.js +192 -0
  34. package/dist/auth-CVOB8Q9A.js +192 -0
  35. package/dist/auth-health-BSF-YNSl.js +149 -0
  36. package/dist/auth-health-BrChJQW-.js +149 -0
  37. package/dist/auth-profiles-xwZAMwdh.js +2981 -0
  38. package/dist/boolean-BgXe2hyu.js +30 -0
  39. package/dist/brew-CAcErcKz.js +46 -0
  40. package/dist/brew-CcZV0dSS.js +46 -0
  41. package/dist/call-BJsfB_NC.js +280 -0
  42. package/dist/call-mnjMMyVJ.js +280 -0
  43. package/dist/channel-options-BXpm2xHl.js +32 -0
  44. package/dist/channel-options-Bjh17Z08.js +62 -0
  45. package/dist/channel-selection-D2iDbzGy.js +51 -0
  46. package/dist/channel-selection-i-6yBKAk.js +51 -0
  47. package/dist/channel-summary-Cw9cmi4M.js +1216 -0
  48. package/dist/channel-summary-D7joKboS.js +1216 -0
  49. package/dist/channels-cli-8HUWD1_p.js +1415 -0
  50. package/dist/channels-cli-DFia3kGl.js +1413 -0
  51. package/dist/channels-status-issues-CT6Q1t1h.js +18 -0
  52. package/dist/channels-status-issues-CgVNTMMz.js +18 -0
  53. package/dist/chrome-CXlGlG3I.js +1953 -0
  54. package/dist/chrome-D0V3Ybil.js +1973 -0
  55. package/dist/clack-prompter-B9yLhyOm.js +92 -0
  56. package/dist/clack-prompter-C7J7X7j7.js +92 -0
  57. package/dist/cli-1b35n5Cc.js +86 -0
  58. package/dist/cli-BYL7Dz_4.js +89 -0
  59. package/dist/cli-utils-BkRQdAoC.js +43 -0
  60. package/dist/cli-utils-DzrdzskQ.js +43 -0
  61. package/dist/client-atZzP6kK.js +1814 -0
  62. package/dist/command-format-CEnDvS9q.js +56 -0
  63. package/dist/command-format-DUskR3Ej.js +42 -0
  64. package/dist/command-format-rFzrPj6c.js +56 -0
  65. package/dist/command-options-BnW-e302.js +33 -0
  66. package/dist/commands-U_88HsqX.js +230 -0
  67. package/dist/completion-cli-Bh3ds9Rv.js +773 -0
  68. package/dist/completion-cli-BhVl7J3C.js +434 -0
  69. package/dist/config-AFzxllYx.js +4924 -0
  70. package/dist/config-BBxxzNm-.js +4923 -0
  71. package/dist/config-UB10lGn3.js +5664 -0
  72. package/dist/config-guard-BCvAEaxA.js +5484 -0
  73. package/dist/configure-0W-OLHK1.js +895 -0
  74. package/dist/configure-D4ci8KU6.js +896 -0
  75. package/dist/constants-Cf-Zsiqd.js +65 -0
  76. package/dist/constants-CpnpJcmu.js +65 -0
  77. package/dist/control-service-BLzGkUMf.js +61 -0
  78. package/dist/control-service-DpyCNhOa.js +61 -0
  79. package/dist/cron-cli-2W0wnKNI.js +457 -0
  80. package/dist/cron-cli-BGc0ZmXl.js +454 -0
  81. package/dist/daemon-cli-C4IIRXZr.js +758 -0
  82. package/dist/daemon-cli-RFrEzOyc.js +757 -0
  83. package/dist/daemon-runtime-BlKOqOPH.js +517 -0
  84. package/dist/daemon-runtime-CRdmLdkD.js +517 -0
  85. package/dist/deliver-B0C5m0kU.js +2587 -0
  86. package/dist/deliver-BUV-sfaF.js +2557 -0
  87. package/dist/deliver-CQQ0e2eM.js +2587 -0
  88. package/dist/deps-D1eiWUgD.js +27 -0
  89. package/dist/deps-DgFrcXzw.js +27 -0
  90. package/dist/devices-cli-CUYqlUBU.js +207 -0
  91. package/dist/devices-cli-De1Q_0ob.js +204 -0
  92. package/dist/directory-cli-DYkFHmO6.js +244 -0
  93. package/dist/directory-cli-DoquUzqm.js +247 -0
  94. package/dist/dispatcher-BLeixzBZ.js +160 -0
  95. package/dist/dns-cli-C5dXU6Nk.js +198 -0
  96. package/dist/dns-cli-rkR0HJpi.js +201 -0
  97. package/dist/docs-cli-CqtgkhfC.js +161 -0
  98. package/dist/docs-cli-DrFTuzUe.js +159 -0
  99. package/dist/doctor-Cakg6jea.js +2577 -0
  100. package/dist/doctor-Cuk5zryG.js +2579 -0
  101. package/dist/entry.js +1336 -0
  102. package/dist/env-DgIs6BZg.js +32 -0
  103. package/dist/errors-C8t2PjW_.js +1952 -0
  104. package/dist/exec-B8JKbXKW.js +246 -0
  105. package/dist/exec-Dloa-d0d.js +246 -0
  106. package/dist/exec-EqLC5sqa.js +1103 -0
  107. package/dist/exec-approvals-B-sykLIC.js +1043 -0
  108. package/dist/exec-approvals-Ff_p0CYa.js +1043 -0
  109. package/dist/exec-approvals-cli-CfSTGR7F.js +388 -0
  110. package/dist/exec-approvals-cli-DBgnm_6P.js +385 -0
  111. package/dist/extensionAPI.js +68185 -0
  112. package/dist/format-8citvr_1.js +34 -0
  113. package/dist/format-tlvh4-cQ.js +34 -0
  114. package/dist/gateway-cli-BKJbSNiq.js +17878 -0
  115. package/dist/gateway-cli-DMbgzP3o.js +17877 -0
  116. package/dist/gateway-rpc-CFkdcw9l.js +28 -0
  117. package/dist/gateway-rpc-CJljb7MY.js +28 -0
  118. package/dist/github-copilot-auth-BGWtD7lK.js +1256 -0
  119. package/dist/github-copilot-auth-Bog6I9WM.js +1256 -0
  120. package/dist/github-copilot-token-BOoCTERW.js +103 -0
  121. package/dist/github-copilot-token-SLWintYd.js +103 -0
  122. package/dist/github-copilot-token-_jdpoYjM.js +103 -0
  123. package/dist/gmail-setup-utils-C97cHaGd.js +428 -0
  124. package/dist/gmail-setup-utils-n354D0jO.js +428 -0
  125. package/dist/health-format-CLSugjQl.js +1383 -0
  126. package/dist/health-format-KsXnqZiA.js +1382 -0
  127. package/dist/help-format-DuMTLWZ-.js +17 -0
  128. package/dist/help-format-GYRujDx9.js +17 -0
  129. package/dist/helpers-BiyEksaK.js +25 -0
  130. package/dist/helpers-DMlRCrD6.js +10 -0
  131. package/dist/helpers-azbX_hrI.js +25 -0
  132. package/dist/helpers-yjIEMzi8.js +10 -0
  133. package/dist/hooks-cli-DXs2Jiyd.js +1061 -0
  134. package/dist/hooks-cli-Dsah_Ryz.js +1058 -0
  135. package/dist/hooks-status-CpkHFMVY.js +443 -0
  136. package/dist/hooks-status-DQRtaH38.js +443 -0
  137. package/dist/image-C6SHcuJM.js +1421 -0
  138. package/dist/image-Cyv4Hr2t.js +629 -0
  139. package/dist/image-DXuHvpqC.js +629 -0
  140. package/dist/index.js +5667 -0
  141. package/dist/installs-BvY-yqDY.js +425 -0
  142. package/dist/installs-Snp4gUlG.js +425 -0
  143. package/dist/is-main-B6kCyqsv.js +25 -0
  144. package/dist/is-main-PYGa3tDA.js +25 -0
  145. package/dist/links-B79LZSNJ.js +15 -0
  146. package/dist/links-iCD68SwJ.js +15 -0
  147. package/dist/loader-ysGIXyYq.js +64701 -0
  148. package/dist/logging-BWRYHvLp.js +1 -0
  149. package/dist/logging-CzN9OPmT.js +15 -0
  150. package/dist/logging-awp_aUN6.js +15 -0
  151. package/dist/logging-pqyrk15z.js +1 -0
  152. package/dist/login-qr-BEXsF0Oj.js +475 -0
  153. package/dist/login-qr-D823w1Qv.js +478 -0
  154. package/dist/login-qr-wnUfVUoC.js +478 -0
  155. package/dist/logs-cli-D912P9Qo.js +230 -0
  156. package/dist/logs-cli-DHYl4Nfl.js +227 -0
  157. package/dist/manager-DORkoiXy.js +3216 -0
  158. package/dist/manager-MLoKmXjg.js +3218 -0
  159. package/dist/manager-e20ne1Ai.js +3216 -0
  160. package/dist/manifest-registry-D8FEq9qs.js +668 -0
  161. package/dist/manifest-registry-DjRSe72U.js +668 -0
  162. package/dist/message-channel-DJEeCAZD.js +110 -0
  163. package/dist/message-channel-DcxF0eJh.js +110 -0
  164. package/dist/model-selection-CjYymzT8.js +2983 -0
  165. package/dist/model-selection-Cz_VcpX5.js +2734 -0
  166. package/dist/models-cli-CURq5BOw.js +2542 -0
  167. package/dist/models-cli-_y06d7uQ.js +2545 -0
  168. package/dist/net-MZzhgr1g.js +1814 -0
  169. package/dist/node-cli-BkEdPem3.js +1456 -0
  170. package/dist/node-cli-PesFC8YY.js +1459 -0
  171. package/dist/node-service-CmyQuldc.js +67 -0
  172. package/dist/node-service-DB0Rp9Fr.js +67 -0
  173. package/dist/nodes-cli-BV7z71Ke.js +1207 -0
  174. package/dist/nodes-cli-D-pPXmLu.js +1210 -0
  175. package/dist/nodes-screen-B240wNB8.js +157 -0
  176. package/dist/nodes-screen-CGLXLco9.js +157 -0
  177. package/dist/note-_C44YfAQ.js +73 -0
  178. package/dist/note-rStT8AJi.js +73 -0
  179. package/dist/onboard-channels-CSGrNeHm.js +671 -0
  180. package/dist/onboard-channels-CyYMvXjh.js +671 -0
  181. package/dist/onboard-skills-BzZrWnt3.js +3452 -0
  182. package/dist/onboard-skills-Z3OoXEqp.js +3452 -0
  183. package/dist/onboarding--5CEtfSX.js +3269 -0
  184. package/dist/pairing-cli-BrPmwezL.js +114 -0
  185. package/dist/pairing-cli-CN183i69.js +117 -0
  186. package/dist/pairing-labels-CrJtLbMY.js +9 -0
  187. package/dist/pairing-labels-DXioxZ5X.js +9 -0
  188. package/dist/pairing-store-D_NP0mJs.js +391 -0
  189. package/dist/pairing-store-pdzxfI5n.js +391 -0
  190. package/dist/parse-BZz5lHzQ.js +23 -0
  191. package/dist/parse-DqAvJRIf.js +23 -0
  192. package/dist/parse-log-line-BnB7770k.js +44 -0
  193. package/dist/parse-log-line-DSvJi17i.js +44 -0
  194. package/dist/parse-timeout-DV8NQQWk.js +16 -0
  195. package/dist/parse-timeout-Du-wHHNi.js +16 -0
  196. package/dist/path-env-Bc8ZqjfY.js +77 -0
  197. package/dist/path-env-DwZUJC_M.js +77 -0
  198. package/dist/paths-8P2BYpvK.js +156 -0
  199. package/dist/paths-Cn5vXlEi.js +43 -0
  200. package/dist/paths-D4TjaAs9.js +40 -0
  201. package/dist/paths-Drx5WZ13.js +172 -0
  202. package/dist/paths-mzsdSoO2.js +43 -0
  203. package/dist/pi-embedded-helpers-Dpu3lm3V.js +1303 -0
  204. package/dist/pi-embedded-helpers-N_L31uhW.js +1303 -0
  205. package/dist/pi-embedded-helpers-dkrwwXev.js +8481 -0
  206. package/dist/pi-model-discovery-CV2V1HHz.js +20 -0
  207. package/dist/pi-model-discovery-DzEIEgHL.js +20 -0
  208. package/dist/pi-model-discovery-EhM2JAQo.js +20 -0
  209. package/dist/pi-tools.policy-m0G0As1p.js +230 -0
  210. package/dist/plugin-auto-enable-Bu3hK0U6.js +460 -0
  211. package/dist/plugin-auto-enable-Ca3Ou67i.js +460 -0
  212. package/dist/plugin-sdk/index.js +24446 -0
  213. package/dist/plugin-sdk/pi-model-discovery-Dw3A6oXH.js +37 -0
  214. package/dist/plugins-Bng3p5bC.js +496 -0
  215. package/dist/plugins-C1mc_xWv.js +495 -0
  216. package/dist/plugins-cli-B8FonfqG.js +441 -0
  217. package/dist/plugins-cli-B9q0wqUI.js +444 -0
  218. package/dist/ports-DKGBzWgI.js +96 -0
  219. package/dist/program-_5hB5I-4.js +191 -0
  220. package/dist/progress-Bcjniu7m.js +133 -0
  221. package/dist/progress-DWODVbwW.js +133 -0
  222. package/dist/prompt-style-CFsleyxV.js +9 -0
  223. package/dist/prompt-style-DZli5767.js +9 -0
  224. package/dist/prompts-CudpZgTI.js +10 -0
  225. package/dist/prompts-FbZThK8w.js +10 -0
  226. package/dist/pw-ai-BUeSOvm-.js +1649 -0
  227. package/dist/pw-ai-GjX4Az_L.js +1649 -0
  228. package/dist/pw-ai-bugVLPkL.js +1651 -0
  229. package/dist/qmd-manager-C1JB3Owf.js +677 -0
  230. package/dist/qmd-manager-TkF_5Pm-.js +676 -0
  231. package/dist/qmd-manager-t9qHekRb.js +674 -0
  232. package/dist/redact-BIMJ3ntQ.js +94 -0
  233. package/dist/redact-Bt-krp_b.js +97 -0
  234. package/dist/redact-DJCFY628.js +97 -0
  235. package/dist/register.subclis-CZG20DZj.js +348 -0
  236. package/dist/reply-8T1JOF0R.js +64704 -0
  237. package/dist/rolldown-runtime-Cbj13DAv.js +20 -0
  238. package/dist/routes-BxFcXB4m.js +2411 -0
  239. package/dist/routes-Dw3vw8Re.js +2411 -0
  240. package/dist/rpc-DgcF4XNR.js +95 -0
  241. package/dist/rpc-f-LmE9z_.js +95 -0
  242. package/dist/run-main-_bbXf2vQ.js +194 -0
  243. package/dist/sandbox-BcOPJhQv.js +2945 -0
  244. package/dist/sandbox-DfBaWfDh.js +2944 -0
  245. package/dist/sandbox-cli-BRcke02J.js +460 -0
  246. package/dist/sandbox-cli-CbUgIVf2.js +463 -0
  247. package/dist/security-cli-76hHzPsz.js +505 -0
  248. package/dist/security-cli-CQ6iSAev.js +508 -0
  249. package/dist/server-context-BuV65eg5.js +740 -0
  250. package/dist/server-context-CFielb4y.js +740 -0
  251. package/dist/server-node-events-CkLBKtGs.js +216 -0
  252. package/dist/server-node-events-D_3bg9qE.js +219 -0
  253. package/dist/service-CZFM7dlu.js +680 -0
  254. package/dist/service-audit-DBdadurs.js +537 -0
  255. package/dist/service-audit-DptlZVXP.js +537 -0
  256. package/dist/service-sZqtAG53.js +680 -0
  257. package/dist/session-cost-usage-CPvtWzot.js +692 -0
  258. package/dist/session-cost-usage-lYVH5MAy.js +692 -0
  259. package/dist/session-key-DrNCyvP1.js +182 -0
  260. package/dist/session-key-n2HVbrj0.js +182 -0
  261. package/dist/shared-Bl4lcfSF.js +74 -0
  262. package/dist/shared-C79dnas0.js +74 -0
  263. package/dist/shared-CDe5yKDd.js +152 -0
  264. package/dist/shared-Cpd7X2eE.js +152 -0
  265. package/dist/skill-scanner-BoGjHXUZ.js +255 -0
  266. package/dist/skill-scanner-COatt01v.js +255 -0
  267. package/dist/skills-CrYcs9jK.js +694 -0
  268. package/dist/skills-DxzXqcWw.js +693 -0
  269. package/dist/skills-cli-BWqUiFIC.js +287 -0
  270. package/dist/skills-cli-C2rWGqKQ.js +290 -0
  271. package/dist/skills-status-Bhe2beiQ.js +187 -0
  272. package/dist/skills-status-DQyBTrvU.js +187 -0
  273. package/dist/sqlite-BjBQdG8T.js +239 -0
  274. package/dist/sqlite-BjhYBODp.js +221 -0
  275. package/dist/sqlite-CbZh0dx1.js +239 -0
  276. package/dist/status-BF8IVV7c.js +21 -0
  277. package/dist/status-BHPh7bCk.js +27 -0
  278. package/dist/status-CWDof7Cn.js +21 -0
  279. package/dist/status-DyjCSdtm.js +27 -0
  280. package/dist/status-RJGk9wHW.js +3177 -0
  281. package/dist/subsystem-DPYBJG7C.js +838 -0
  282. package/dist/system-cli-BY3oOcLX.js +83 -0
  283. package/dist/system-cli-pg7MxYKd.js +80 -0
  284. package/dist/systemd-DerMq_3Y.js +438 -0
  285. package/dist/systemd-Gt0riLnX.js +438 -0
  286. package/dist/systemd-hints-C6JS-A6Y.js +19 -0
  287. package/dist/systemd-hints-Db4JjAxJ.js +19 -0
  288. package/dist/systemd-linger-CRL7Xf4C.js +75 -0
  289. package/dist/systemd-linger-DS0IcHsk.js +75 -0
  290. package/dist/table-BzJyfJCd.js +279 -0
  291. package/dist/table-DCcFNw6e.js +279 -0
  292. package/dist/tailnet-Byp3obcc.js +42 -0
  293. package/dist/tailnet-DLDGNuH2.js +42 -0
  294. package/dist/tailscale-9MusRvOi.js +225 -0
  295. package/dist/tailscale-CGhNcgVS.js +252 -0
  296. package/dist/tool-display-C9u4CdQu.js +795 -0
  297. package/dist/tool-display-D_HGmnfa.js +795 -0
  298. package/dist/transcript-events-Bv_eRVym.js +17 -0
  299. package/dist/transcript-events-ChU6IQwp.js +17 -0
  300. package/dist/transcript-events-JLH5W4He.js +17 -0
  301. package/dist/tui-BPqDn4Jf.js +3090 -0
  302. package/dist/tui-BniTBjBP.js +3089 -0
  303. package/dist/tui-cli-AeeP52_J.js +58 -0
  304. package/dist/tui-cli-DrWl0dkQ.js +55 -0
  305. package/dist/update-BKGU5x_o.js +317 -0
  306. package/dist/update-CZqqbW73.js +317 -0
  307. package/dist/update-cli-DTXxX27F.js +1036 -0
  308. package/dist/update-cli-j0POazuO.js +1034 -0
  309. package/dist/update-runner-BY-i_k4L.js +1458 -0
  310. package/dist/update-runner-CmdPxJg5.js +1458 -0
  311. package/dist/usage-format-BcU1flOY.js +36 -0
  312. package/dist/usage-format-DvowRSs-.js +36 -0
  313. package/dist/utils-C7NsUvD1.js +192 -0
  314. package/dist/utils-DBu98aoz.js +188 -0
  315. package/dist/webhooks-cli-BBw-pRTs.js +309 -0
  316. package/dist/webhooks-cli-BXxSGFuL.js +312 -0
  317. package/dist/widearea-dns-C2mRm6hu.js +127 -0
  318. package/dist/widearea-dns-DbdWF6kP.js +127 -0
  319. package/dist/ws-CEcdsnN9.js +13 -0
  320. package/dist/ws-D091yo4M.js +13 -0
  321. package/dist/ws-log-Bpm8rpoP.js +267 -0
  322. package/dist/ws-log-vBkmxf4_.js +267 -0
  323. package/dist/wsl-QYB9yGZN.js +160 -0
  324. package/docs/.i18n/README.md +31 -0
  325. package/docs/.i18n/glossary.zh-CN.json +210 -0
  326. package/docs/.i18n/zh-CN.tm.jsonl +1329 -0
  327. package/docs/CNAME +1 -0
  328. package/docs/assets/macos-onboarding/01-macos-warning.jpeg +0 -0
  329. package/docs/assets/macos-onboarding/02-local-networks.jpeg +0 -0
  330. package/docs/assets/macos-onboarding/03-security-notice.png +0 -0
  331. package/docs/assets/macos-onboarding/04-choose-gateway.png +0 -0
  332. package/docs/assets/macos-onboarding/05-permissions.png +0 -0
  333. package/docs/assets/openclaw-logo-text-dark.png +0 -0
  334. package/docs/assets/openclaw-logo-text.png +0 -0
  335. package/docs/assets/pixel-lobster.svg +60 -0
  336. package/docs/assets/showcase/agents-ui.jpg +0 -0
  337. package/docs/assets/showcase/bambu-cli.png +0 -0
  338. package/docs/assets/showcase/codexmonitor.png +0 -0
  339. package/docs/assets/showcase/gohome-grafana.png +0 -0
  340. package/docs/assets/showcase/ios-testflight.jpg +0 -0
  341. package/docs/assets/showcase/oura-health.png +0 -0
  342. package/docs/assets/showcase/padel-cli.svg +11 -0
  343. package/docs/assets/showcase/padel-screenshot.jpg +0 -0
  344. package/docs/assets/showcase/papla-tts.jpg +0 -0
  345. package/docs/assets/showcase/pr-review-telegram.jpg +0 -0
  346. package/docs/assets/showcase/roborock-screenshot.jpg +0 -0
  347. package/docs/assets/showcase/roborock-status.svg +13 -0
  348. package/docs/assets/showcase/roof-camera-sky.jpg +0 -0
  349. package/docs/assets/showcase/snag.png +0 -0
  350. package/docs/assets/showcase/tesco-shop.jpg +0 -0
  351. package/docs/assets/showcase/wienerlinien.png +0 -0
  352. package/docs/assets/showcase/wine-cellar-skill.jpg +0 -0
  353. package/docs/assets/showcase/winix-air-purifier.jpg +0 -0
  354. package/docs/assets/showcase/xuezh-pronunciation.jpeg +0 -0
  355. package/docs/automation/auth-monitoring.md +44 -0
  356. package/docs/automation/cron-jobs.md +471 -0
  357. package/docs/automation/cron-vs-heartbeat.md +282 -0
  358. package/docs/automation/gmail-pubsub.md +256 -0
  359. package/docs/automation/hooks.md +916 -0
  360. package/docs/automation/poll.md +69 -0
  361. package/docs/automation/troubleshooting.md +122 -0
  362. package/docs/automation/webhook.md +163 -0
  363. package/docs/brave-search.md +41 -0
  364. package/docs/channels/bluebubbles.md +340 -0
  365. package/docs/channels/broadcast-groups.md +442 -0
  366. package/docs/channels/channel-routing.md +114 -0
  367. package/docs/channels/discord.md +476 -0
  368. package/docs/channels/feishu.md +579 -0
  369. package/docs/channels/googlechat.md +252 -0
  370. package/docs/channels/grammy.md +31 -0
  371. package/docs/channels/group-messages.md +84 -0
  372. package/docs/channels/groups.md +374 -0
  373. package/docs/channels/imessage.md +321 -0
  374. package/docs/channels/index.md +46 -0
  375. package/docs/channels/line.md +186 -0
  376. package/docs/channels/location.md +56 -0
  377. package/docs/channels/matrix.md +259 -0
  378. package/docs/channels/mattermost.md +138 -0
  379. package/docs/channels/msteams.md +769 -0
  380. package/docs/channels/nextcloud-talk.md +138 -0
  381. package/docs/channels/nostr.md +233 -0
  382. package/docs/channels/pairing.md +86 -0
  383. package/docs/channels/signal.md +228 -0
  384. package/docs/channels/slack.md +574 -0
  385. package/docs/channels/telegram.md +770 -0
  386. package/docs/channels/tlon.md +132 -0
  387. package/docs/channels/troubleshooting.md +116 -0
  388. package/docs/channels/twitch.md +379 -0
  389. package/docs/channels/whatsapp.md +406 -0
  390. package/docs/channels/zalo.md +189 -0
  391. package/docs/channels/zalouser.md +140 -0
  392. package/docs/cli/acp.md +170 -0
  393. package/docs/cli/agent.md +24 -0
  394. package/docs/cli/agents.md +75 -0
  395. package/docs/cli/approvals.md +50 -0
  396. package/docs/cli/browser.md +107 -0
  397. package/docs/cli/channels.md +79 -0
  398. package/docs/cli/config.md +50 -0
  399. package/docs/cli/configure.md +33 -0
  400. package/docs/cli/cron.md +42 -0
  401. package/docs/cli/dashboard.md +16 -0
  402. package/docs/cli/devices.md +70 -0
  403. package/docs/cli/directory.md +63 -0
  404. package/docs/cli/dns.md +23 -0
  405. package/docs/cli/docs.md +15 -0
  406. package/docs/cli/doctor.md +41 -0
  407. package/docs/cli/gateway.md +202 -0
  408. package/docs/cli/health.md +21 -0
  409. package/docs/cli/hooks.md +304 -0
  410. package/docs/cli/index.md +1031 -0
  411. package/docs/cli/logs.md +24 -0
  412. package/docs/cli/memory.md +45 -0
  413. package/docs/cli/message.md +239 -0
  414. package/docs/cli/models.md +79 -0
  415. package/docs/cli/node.md +112 -0
  416. package/docs/cli/nodes.md +73 -0
  417. package/docs/cli/onboard.md +43 -0
  418. package/docs/cli/pairing.md +21 -0
  419. package/docs/cli/plugins.md +62 -0
  420. package/docs/cli/reset.md +17 -0
  421. package/docs/cli/sandbox.md +152 -0
  422. package/docs/cli/security.md +26 -0
  423. package/docs/cli/sessions.md +16 -0
  424. package/docs/cli/setup.md +29 -0
  425. package/docs/cli/skills.md +26 -0
  426. package/docs/cli/status.md +26 -0
  427. package/docs/cli/system.md +60 -0
  428. package/docs/cli/tui.md +23 -0
  429. package/docs/cli/uninstall.md +17 -0
  430. package/docs/cli/update.md +98 -0
  431. package/docs/cli/voicecall.md +34 -0
  432. package/docs/cli/webhooks.md +25 -0
  433. package/docs/concepts/agent-loop.md +146 -0
  434. package/docs/concepts/agent-workspace.md +233 -0
  435. package/docs/concepts/agent.md +123 -0
  436. package/docs/concepts/architecture.md +131 -0
  437. package/docs/concepts/compaction.md +61 -0
  438. package/docs/concepts/context.md +161 -0
  439. package/docs/concepts/features.md +53 -0
  440. package/docs/concepts/markdown-formatting.md +130 -0
  441. package/docs/concepts/memory.md +556 -0
  442. package/docs/concepts/messages.md +154 -0
  443. package/docs/concepts/model-failover.md +149 -0
  444. package/docs/concepts/model-providers.md +316 -0
  445. package/docs/concepts/models.md +208 -0
  446. package/docs/concepts/multi-agent.md +376 -0
  447. package/docs/concepts/oauth.md +145 -0
  448. package/docs/concepts/presence.md +102 -0
  449. package/docs/concepts/queue.md +89 -0
  450. package/docs/concepts/retry.md +69 -0
  451. package/docs/concepts/session-pruning.md +122 -0
  452. package/docs/concepts/session-tool.md +193 -0
  453. package/docs/concepts/session.md +204 -0
  454. package/docs/concepts/sessions.md +10 -0
  455. package/docs/concepts/streaming.md +135 -0
  456. package/docs/concepts/system-prompt.md +115 -0
  457. package/docs/concepts/timezone.md +91 -0
  458. package/docs/concepts/typebox.md +289 -0
  459. package/docs/concepts/typing-indicators.md +68 -0
  460. package/docs/concepts/usage-tracking.md +35 -0
  461. package/docs/date-time.md +128 -0
  462. package/docs/debug/node-issue.md +85 -0
  463. package/docs/diagnostics/flags.md +91 -0
  464. package/docs/docs.json +1802 -0
  465. package/docs/experiments/onboarding-config-protocol.md +40 -0
  466. package/docs/experiments/plans/cron-add-hardening.md +63 -0
  467. package/docs/experiments/plans/group-policy-hardening.md +40 -0
  468. package/docs/experiments/plans/openresponses-gateway.md +123 -0
  469. package/docs/experiments/proposals/model-config.md +36 -0
  470. package/docs/experiments/research/memory.md +228 -0
  471. package/docs/gateway/authentication.md +145 -0
  472. package/docs/gateway/background-process.md +93 -0
  473. package/docs/gateway/bonjour.md +170 -0
  474. package/docs/gateway/bridge-protocol.md +89 -0
  475. package/docs/gateway/cli-backends.md +225 -0
  476. package/docs/gateway/configuration-examples.md +606 -0
  477. package/docs/gateway/configuration.md +3416 -0
  478. package/docs/gateway/discovery.md +116 -0
  479. package/docs/gateway/doctor.md +282 -0
  480. package/docs/gateway/gateway-lock.md +34 -0
  481. package/docs/gateway/health.md +35 -0
  482. package/docs/gateway/heartbeat.md +364 -0
  483. package/docs/gateway/index.md +330 -0
  484. package/docs/gateway/local-models.md +150 -0
  485. package/docs/gateway/logging.md +113 -0
  486. package/docs/gateway/multiple-gateways.md +112 -0
  487. package/docs/gateway/network-model.md +17 -0
  488. package/docs/gateway/openai-http-api.md +118 -0
  489. package/docs/gateway/openresponses-http-api.md +317 -0
  490. package/docs/gateway/pairing.md +99 -0
  491. package/docs/gateway/protocol.md +221 -0
  492. package/docs/gateway/remote-gateway-readme.md +157 -0
  493. package/docs/gateway/remote.md +129 -0
  494. package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +128 -0
  495. package/docs/gateway/sandboxing.md +193 -0
  496. package/docs/gateway/security/index.md +829 -0
  497. package/docs/gateway/tailscale.md +127 -0
  498. package/docs/gateway/tools-invoke-http-api.md +85 -0
  499. package/docs/gateway/troubleshooting.md +318 -0
  500. package/docs/help/debugging.md +162 -0
  501. package/docs/help/environment.md +81 -0
  502. package/docs/help/faq.md +2848 -0
  503. package/docs/help/index.md +21 -0
  504. package/docs/help/scripts.md +28 -0
  505. package/docs/help/submitting-a-pr.md +398 -0
  506. package/docs/help/submitting-an-issue.md +152 -0
  507. package/docs/help/testing.md +368 -0
  508. package/docs/help/troubleshooting.md +265 -0
  509. package/docs/hooks/soul-evil.md +69 -0
  510. package/docs/images/feishu-step2-create-app.png +0 -0
  511. package/docs/images/feishu-step3-credentials.png +0 -0
  512. package/docs/images/feishu-step4-permissions.png +0 -0
  513. package/docs/images/feishu-step5-bot-capability.png +0 -0
  514. package/docs/images/feishu-step6-event-subscription.png +0 -0
  515. package/docs/images/groups-flow.svg +52 -0
  516. package/docs/images/mobile-ui-screenshot.png +0 -0
  517. package/docs/index.md +192 -0
  518. package/docs/install/ansible.md +208 -0
  519. package/docs/install/bun.md +59 -0
  520. package/docs/install/development-channels.md +75 -0
  521. package/docs/install/docker.md +567 -0
  522. package/docs/install/exe-dev.md +126 -0
  523. package/docs/install/fly.md +486 -0
  524. package/docs/install/gcp.md +504 -0
  525. package/docs/install/hetzner.md +330 -0
  526. package/docs/install/index.md +203 -0
  527. package/docs/install/installer.md +385 -0
  528. package/docs/install/macos-vm.md +281 -0
  529. package/docs/install/migrating.md +192 -0
  530. package/docs/install/nix.md +96 -0
  531. package/docs/install/node.md +138 -0
  532. package/docs/install/northflank.mdx +53 -0
  533. package/docs/install/railway.mdx +99 -0
  534. package/docs/install/render.mdx +159 -0
  535. package/docs/install/uninstall.md +128 -0
  536. package/docs/install/updating.md +231 -0
  537. package/docs/logging.md +350 -0
  538. package/docs/network.md +54 -0
  539. package/docs/nodes/audio.md +114 -0
  540. package/docs/nodes/camera.md +156 -0
  541. package/docs/nodes/images.md +72 -0
  542. package/docs/nodes/index.md +342 -0
  543. package/docs/nodes/location-command.md +113 -0
  544. package/docs/nodes/media-understanding.md +379 -0
  545. package/docs/nodes/talk.md +90 -0
  546. package/docs/nodes/troubleshooting.md +112 -0
  547. package/docs/nodes/voicewake.md +65 -0
  548. package/docs/perplexity.md +80 -0
  549. package/docs/pi-dev.md +70 -0
  550. package/docs/pi.md +612 -0
  551. package/docs/platforms/android.md +151 -0
  552. package/docs/platforms/digitalocean.md +262 -0
  553. package/docs/platforms/index.md +53 -0
  554. package/docs/platforms/ios.md +107 -0
  555. package/docs/platforms/linux.md +94 -0
  556. package/docs/platforms/mac/bundled-gateway.md +73 -0
  557. package/docs/platforms/mac/canvas.md +125 -0
  558. package/docs/platforms/mac/child-process.md +69 -0
  559. package/docs/platforms/mac/dev-setup.md +104 -0
  560. package/docs/platforms/mac/health.md +34 -0
  561. package/docs/platforms/mac/icon.md +31 -0
  562. package/docs/platforms/mac/logging.md +57 -0
  563. package/docs/platforms/mac/menu-bar.md +81 -0
  564. package/docs/platforms/mac/peekaboo.md +65 -0
  565. package/docs/platforms/mac/permissions.md +50 -0
  566. package/docs/platforms/mac/release.md +85 -0
  567. package/docs/platforms/mac/remote.md +83 -0
  568. package/docs/platforms/mac/signing.md +47 -0
  569. package/docs/platforms/mac/skills.md +33 -0
  570. package/docs/platforms/mac/voice-overlay.md +60 -0
  571. package/docs/platforms/mac/voicewake.md +67 -0
  572. package/docs/platforms/mac/webchat.md +43 -0
  573. package/docs/platforms/mac/xpc.md +61 -0
  574. package/docs/platforms/macos.md +203 -0
  575. package/docs/platforms/oracle.md +303 -0
  576. package/docs/platforms/raspberry-pi.md +358 -0
  577. package/docs/platforms/windows.md +159 -0
  578. package/docs/plugins/agent-tools.md +99 -0
  579. package/docs/plugins/manifest.md +71 -0
  580. package/docs/plugins/voice-call.md +284 -0
  581. package/docs/plugins/zalouser.md +81 -0
  582. package/docs/prose.md +134 -0
  583. package/docs/providers/anthropic.md +152 -0
  584. package/docs/providers/bedrock.md +176 -0
  585. package/docs/providers/claude-max-api-proxy.md +148 -0
  586. package/docs/providers/cloudflare-ai-gateway.md +71 -0
  587. package/docs/providers/deepgram.md +93 -0
  588. package/docs/providers/github-copilot.md +72 -0
  589. package/docs/providers/glm.md +33 -0
  590. package/docs/providers/index.md +64 -0
  591. package/docs/providers/minimax.md +208 -0
  592. package/docs/providers/models.md +52 -0
  593. package/docs/providers/moonshot.md +142 -0
  594. package/docs/providers/ollama.md +277 -0
  595. package/docs/providers/openai.md +62 -0
  596. package/docs/providers/opencode.md +36 -0
  597. package/docs/providers/openrouter.md +37 -0
  598. package/docs/providers/qianfan.md +38 -0
  599. package/docs/providers/qwen.md +53 -0
  600. package/docs/providers/synthetic.md +99 -0
  601. package/docs/providers/venice.md +267 -0
  602. package/docs/providers/vercel-ai-gateway.md +50 -0
  603. package/docs/providers/xiaomi.md +64 -0
  604. package/docs/providers/zai.md +36 -0
  605. package/docs/refactor/clawnet.md +417 -0
  606. package/docs/refactor/exec-host.md +316 -0
  607. package/docs/refactor/outbound-session-mirroring.md +85 -0
  608. package/docs/refactor/plugin-sdk.md +214 -0
  609. package/docs/refactor/strict-config.md +93 -0
  610. package/docs/reference/AGENTS.default.md +123 -0
  611. package/docs/reference/RELEASING.md +120 -0
  612. package/docs/reference/api-usage-costs.md +138 -0
  613. package/docs/reference/credits.md +27 -0
  614. package/docs/reference/device-models.md +47 -0
  615. package/docs/reference/rpc.md +43 -0
  616. package/docs/reference/session-management-compaction.md +285 -0
  617. package/docs/reference/templates/AGENTS.dev.md +83 -0
  618. package/docs/reference/templates/AGENTS.md +218 -0
  619. package/docs/reference/templates/BOOT.md +10 -0
  620. package/docs/reference/templates/BOOTSTRAP.md +61 -0
  621. package/docs/reference/templates/HEARTBEAT.md +11 -0
  622. package/docs/reference/templates/IDENTITY.dev.md +47 -0
  623. package/docs/reference/templates/IDENTITY.md +29 -0
  624. package/docs/reference/templates/SOUL.dev.md +76 -0
  625. package/docs/reference/templates/SOUL.md +42 -0
  626. package/docs/reference/templates/TOOLS.dev.md +24 -0
  627. package/docs/reference/templates/TOOLS.md +46 -0
  628. package/docs/reference/templates/USER.dev.md +18 -0
  629. package/docs/reference/templates/USER.md +23 -0
  630. package/docs/reference/test.md +50 -0
  631. package/docs/reference/token-use.md +112 -0
  632. package/docs/reference/transcript-hygiene.md +129 -0
  633. package/docs/reference/wizard.md +269 -0
  634. package/docs/security/formal-verification.md +164 -0
  635. package/docs/start/bootstrapping.md +41 -0
  636. package/docs/start/docs-directory.md +64 -0
  637. package/docs/start/getting-started.md +120 -0
  638. package/docs/start/hubs.md +197 -0
  639. package/docs/start/lore.md +219 -0
  640. package/docs/start/onboarding.md +80 -0
  641. package/docs/start/openclaw.md +224 -0
  642. package/docs/start/quickstart.md +22 -0
  643. package/docs/start/setup.md +162 -0
  644. package/docs/start/showcase.md +416 -0
  645. package/docs/start/wizard-cli-automation.md +141 -0
  646. package/docs/start/wizard-cli-reference.md +247 -0
  647. package/docs/start/wizard.md +108 -0
  648. package/docs/style.css +3 -0
  649. package/docs/tools/agent-send.md +53 -0
  650. package/docs/tools/apply-patch.md +50 -0
  651. package/docs/tools/browser-linux-troubleshooting.md +139 -0
  652. package/docs/tools/browser-login.md +67 -0
  653. package/docs/tools/browser.md +576 -0
  654. package/docs/tools/chrome-extension.md +178 -0
  655. package/docs/tools/clawhub.md +257 -0
  656. package/docs/tools/creating-skills.md +54 -0
  657. package/docs/tools/elevated.md +57 -0
  658. package/docs/tools/exec-approvals.md +246 -0
  659. package/docs/tools/exec.md +179 -0
  660. package/docs/tools/firecrawl.md +61 -0
  661. package/docs/tools/index.md +512 -0
  662. package/docs/tools/llm-task.md +115 -0
  663. package/docs/tools/lobster.md +342 -0
  664. package/docs/tools/multi-agent-sandbox-tools.md +396 -0
  665. package/docs/tools/plugin.md +664 -0
  666. package/docs/tools/reactions.md +22 -0
  667. package/docs/tools/skills-config.md +76 -0
  668. package/docs/tools/skills.md +300 -0
  669. package/docs/tools/slash-commands.md +198 -0
  670. package/docs/tools/subagents.md +151 -0
  671. package/docs/tools/thinking.md +74 -0
  672. package/docs/tools/web.md +261 -0
  673. package/docs/tts.md +396 -0
  674. package/docs/vps.md +43 -0
  675. package/docs/web/control-ui.md +223 -0
  676. package/docs/web/dashboard.md +46 -0
  677. package/docs/web/index.md +116 -0
  678. package/docs/web/tui.md +162 -0
  679. package/docs/web/webchat.md +49 -0
  680. package/docs/whatsapp-openclaw-ai-zh.jpg +0 -0
  681. package/docs/whatsapp-openclaw.jpg +0 -0
  682. package/docs/zh-CN/AGENTS.md +59 -0
  683. package/docs/zh-CN/automation/auth-monitoring.md +47 -0
  684. package/docs/zh-CN/automation/cron-jobs.md +424 -0
  685. package/docs/zh-CN/automation/cron-vs-heartbeat.md +286 -0
  686. package/docs/zh-CN/automation/gmail-pubsub.md +249 -0
  687. package/docs/zh-CN/automation/hooks.md +919 -0
  688. package/docs/zh-CN/automation/poll.md +76 -0
  689. package/docs/zh-CN/automation/troubleshooting.md +8 -0
  690. package/docs/zh-CN/automation/webhook.md +163 -0
  691. package/docs/zh-CN/brave-search.md +48 -0
  692. package/docs/zh-CN/channels/bluebubbles.md +271 -0
  693. package/docs/zh-CN/channels/broadcast-groups.md +449 -0
  694. package/docs/zh-CN/channels/channel-routing.md +117 -0
  695. package/docs/zh-CN/channels/discord.md +468 -0
  696. package/docs/zh-CN/channels/feishu.md +629 -0
  697. package/docs/zh-CN/channels/googlechat.md +257 -0
  698. package/docs/zh-CN/channels/grammy.md +38 -0
  699. package/docs/zh-CN/channels/group-messages.md +91 -0
  700. package/docs/zh-CN/channels/groups.md +379 -0
  701. package/docs/zh-CN/channels/imessage.md +302 -0
  702. package/docs/zh-CN/channels/index.md +53 -0
  703. package/docs/zh-CN/channels/line.md +180 -0
  704. package/docs/zh-CN/channels/location.md +63 -0
  705. package/docs/zh-CN/channels/matrix.md +221 -0
  706. package/docs/zh-CN/channels/mattermost.md +144 -0
  707. package/docs/zh-CN/channels/msteams.md +775 -0
  708. package/docs/zh-CN/channels/nextcloud-talk.md +142 -0
  709. package/docs/zh-CN/channels/nostr.md +240 -0
  710. package/docs/zh-CN/channels/pairing.md +89 -0
  711. package/docs/zh-CN/channels/signal.md +209 -0
  712. package/docs/zh-CN/channels/slack.md +531 -0
  713. package/docs/zh-CN/channels/telegram.md +751 -0
  714. package/docs/zh-CN/channels/tlon.md +136 -0
  715. package/docs/zh-CN/channels/troubleshooting.md +36 -0
  716. package/docs/zh-CN/channels/twitch.md +385 -0
  717. package/docs/zh-CN/channels/whatsapp.md +411 -0
  718. package/docs/zh-CN/channels/zalo.md +196 -0
  719. package/docs/zh-CN/channels/zalouser.md +147 -0
  720. package/docs/zh-CN/cli/acp.md +173 -0
  721. package/docs/zh-CN/cli/agent.md +30 -0
  722. package/docs/zh-CN/cli/agents.md +82 -0
  723. package/docs/zh-CN/cli/approvals.md +57 -0
  724. package/docs/zh-CN/cli/browser.md +114 -0
  725. package/docs/zh-CN/cli/channels.md +86 -0
  726. package/docs/zh-CN/cli/config.md +57 -0
  727. package/docs/zh-CN/cli/configure.md +38 -0
  728. package/docs/zh-CN/cli/cron.md +43 -0
  729. package/docs/zh-CN/cli/dashboard.md +23 -0
  730. package/docs/zh-CN/cli/devices.md +74 -0
  731. package/docs/zh-CN/cli/directory.md +70 -0
  732. package/docs/zh-CN/cli/dns.md +30 -0
  733. package/docs/zh-CN/cli/docs.md +22 -0
  734. package/docs/zh-CN/cli/doctor.md +48 -0
  735. package/docs/zh-CN/cli/gateway.md +206 -0
  736. package/docs/zh-CN/cli/health.md +28 -0
  737. package/docs/zh-CN/cli/hooks.md +311 -0
  738. package/docs/zh-CN/cli/index.md +1032 -0
  739. package/docs/zh-CN/cli/logs.md +31 -0
  740. package/docs/zh-CN/cli/memory.md +52 -0
  741. package/docs/zh-CN/cli/message.md +246 -0
  742. package/docs/zh-CN/cli/models.md +85 -0
  743. package/docs/zh-CN/cli/node.md +115 -0
  744. package/docs/zh-CN/cli/nodes.md +80 -0
  745. package/docs/zh-CN/cli/onboard.md +36 -0
  746. package/docs/zh-CN/cli/pairing.md +28 -0
  747. package/docs/zh-CN/cli/plugins.md +66 -0
  748. package/docs/zh-CN/cli/reset.md +24 -0
  749. package/docs/zh-CN/cli/sandbox.md +158 -0
  750. package/docs/zh-CN/cli/security.md +33 -0
  751. package/docs/zh-CN/cli/sessions.md +23 -0
  752. package/docs/zh-CN/cli/setup.md +36 -0
  753. package/docs/zh-CN/cli/skills.md +33 -0
  754. package/docs/zh-CN/cli/status.md +33 -0
  755. package/docs/zh-CN/cli/system.md +63 -0
  756. package/docs/zh-CN/cli/tui.md +30 -0
  757. package/docs/zh-CN/cli/uninstall.md +24 -0
  758. package/docs/zh-CN/cli/update.md +101 -0
  759. package/docs/zh-CN/cli/voicecall.md +41 -0
  760. package/docs/zh-CN/cli/webhooks.md +32 -0
  761. package/docs/zh-CN/concepts/agent-loop.md +146 -0
  762. package/docs/zh-CN/concepts/agent-workspace.md +219 -0
  763. package/docs/zh-CN/concepts/agent.md +115 -0
  764. package/docs/zh-CN/concepts/architecture.md +123 -0
  765. package/docs/zh-CN/concepts/compaction.md +67 -0
  766. package/docs/zh-CN/concepts/context.md +168 -0
  767. package/docs/zh-CN/concepts/features.md +59 -0
  768. package/docs/zh-CN/concepts/markdown-formatting.md +117 -0
  769. package/docs/zh-CN/concepts/memory.md +412 -0
  770. package/docs/zh-CN/concepts/messages.md +141 -0
  771. package/docs/zh-CN/concepts/model-failover.md +145 -0
  772. package/docs/zh-CN/concepts/model-providers.md +320 -0
  773. package/docs/zh-CN/concepts/models.md +196 -0
  774. package/docs/zh-CN/concepts/multi-agent.md +372 -0
  775. package/docs/zh-CN/concepts/oauth.md +151 -0
  776. package/docs/zh-CN/concepts/presence.md +99 -0
  777. package/docs/zh-CN/concepts/queue.md +94 -0
  778. package/docs/zh-CN/concepts/retry.md +76 -0
  779. package/docs/zh-CN/concepts/session-pruning.md +129 -0
  780. package/docs/zh-CN/concepts/session-tool.md +200 -0
  781. package/docs/zh-CN/concepts/session.md +166 -0
  782. package/docs/zh-CN/concepts/sessions.md +17 -0
  783. package/docs/zh-CN/concepts/streaming.md +133 -0
  784. package/docs/zh-CN/concepts/system-prompt.md +101 -0
  785. package/docs/zh-CN/concepts/timezone.md +96 -0
  786. package/docs/zh-CN/concepts/typebox.md +284 -0
  787. package/docs/zh-CN/concepts/typing-indicators.md +74 -0
  788. package/docs/zh-CN/concepts/usage-tracking.md +42 -0
  789. package/docs/zh-CN/date-time.md +129 -0
  790. package/docs/zh-CN/debug/node-issue.md +90 -0
  791. package/docs/zh-CN/diagnostics/flags.md +98 -0
  792. package/docs/zh-CN/experiments/onboarding-config-protocol.md +47 -0
  793. package/docs/zh-CN/experiments/plans/cron-add-hardening.md +70 -0
  794. package/docs/zh-CN/experiments/plans/group-policy-hardening.md +45 -0
  795. package/docs/zh-CN/experiments/plans/openresponses-gateway.md +121 -0
  796. package/docs/zh-CN/experiments/proposals/model-config.md +42 -0
  797. package/docs/zh-CN/experiments/research/memory.md +235 -0
  798. package/docs/zh-CN/gateway/authentication.md +142 -0
  799. package/docs/zh-CN/gateway/background-process.md +100 -0
  800. package/docs/zh-CN/gateway/bonjour.md +174 -0
  801. package/docs/zh-CN/gateway/bridge-protocol.md +86 -0
  802. package/docs/zh-CN/gateway/cli-backends.md +213 -0
  803. package/docs/zh-CN/gateway/configuration-examples.md +587 -0
  804. package/docs/zh-CN/gateway/configuration.md +3332 -0
  805. package/docs/zh-CN/gateway/discovery.md +123 -0
  806. package/docs/zh-CN/gateway/doctor.md +238 -0
  807. package/docs/zh-CN/gateway/gateway-lock.md +41 -0
  808. package/docs/zh-CN/gateway/health.md +42 -0
  809. package/docs/zh-CN/gateway/heartbeat.md +274 -0
  810. package/docs/zh-CN/gateway/index.md +335 -0
  811. package/docs/zh-CN/gateway/local-models.md +157 -0
  812. package/docs/zh-CN/gateway/logging.md +114 -0
  813. package/docs/zh-CN/gateway/multiple-gateways.md +119 -0
  814. package/docs/zh-CN/gateway/network-model.md +23 -0
  815. package/docs/zh-CN/gateway/openai-http-api.md +125 -0
  816. package/docs/zh-CN/gateway/openresponses-http-api.md +317 -0
  817. package/docs/zh-CN/gateway/pairing.md +99 -0
  818. package/docs/zh-CN/gateway/protocol.md +220 -0
  819. package/docs/zh-CN/gateway/remote-gateway-readme.md +164 -0
  820. package/docs/zh-CN/gateway/remote.md +133 -0
  821. package/docs/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated.md +135 -0
  822. package/docs/zh-CN/gateway/sandboxing.md +188 -0
  823. package/docs/zh-CN/gateway/security/index.md +777 -0
  824. package/docs/zh-CN/gateway/tailscale.md +124 -0
  825. package/docs/zh-CN/gateway/tools-invoke-http-api.md +92 -0
  826. package/docs/zh-CN/gateway/troubleshooting.md +771 -0
  827. package/docs/zh-CN/help/debugging.md +160 -0
  828. package/docs/zh-CN/help/environment.md +88 -0
  829. package/docs/zh-CN/help/faq.md +2628 -0
  830. package/docs/zh-CN/help/index.md +28 -0
  831. package/docs/zh-CN/help/scripts.md +35 -0
  832. package/docs/zh-CN/help/submitting-a-pr.md +8 -0
  833. package/docs/zh-CN/help/submitting-an-issue.md +8 -0
  834. package/docs/zh-CN/help/testing.md +375 -0
  835. package/docs/zh-CN/help/troubleshooting.md +104 -0
  836. package/docs/zh-CN/hooks/soul-evil.md +72 -0
  837. package/docs/zh-CN/index.md +186 -0
  838. package/docs/zh-CN/install/ansible.md +215 -0
  839. package/docs/zh-CN/install/bun.md +65 -0
  840. package/docs/zh-CN/install/development-channels.md +81 -0
  841. package/docs/zh-CN/install/docker.md +532 -0
  842. package/docs/zh-CN/install/exe-dev.md +127 -0
  843. package/docs/zh-CN/install/fly.md +490 -0
  844. package/docs/zh-CN/install/gcp.md +510 -0
  845. package/docs/zh-CN/install/hetzner.md +337 -0
  846. package/docs/zh-CN/install/index.md +193 -0
  847. package/docs/zh-CN/install/installer.md +128 -0
  848. package/docs/zh-CN/install/macos-vm.md +288 -0
  849. package/docs/zh-CN/install/migrating.md +199 -0
  850. package/docs/zh-CN/install/nix.md +99 -0
  851. package/docs/zh-CN/install/node.md +8 -0
  852. package/docs/zh-CN/install/northflank.mdx +60 -0
  853. package/docs/zh-CN/install/railway.mdx +106 -0
  854. package/docs/zh-CN/install/render.mdx +169 -0
  855. package/docs/zh-CN/install/uninstall.md +135 -0
  856. package/docs/zh-CN/install/updating.md +233 -0
  857. package/docs/zh-CN/logging.md +329 -0
  858. package/docs/zh-CN/network.md +59 -0
  859. package/docs/zh-CN/nodes/audio.md +120 -0
  860. package/docs/zh-CN/nodes/camera.md +162 -0
  861. package/docs/zh-CN/nodes/images.md +79 -0
  862. package/docs/zh-CN/nodes/index.md +348 -0
  863. package/docs/zh-CN/nodes/location-command.md +120 -0
  864. package/docs/zh-CN/nodes/media-understanding.md +380 -0
  865. package/docs/zh-CN/nodes/talk.md +97 -0
  866. package/docs/zh-CN/nodes/troubleshooting.md +8 -0
  867. package/docs/zh-CN/nodes/voicewake.md +72 -0
  868. package/docs/zh-CN/perplexity.md +84 -0
  869. package/docs/zh-CN/pi-dev.md +77 -0
  870. package/docs/zh-CN/pi.md +619 -0
  871. package/docs/zh-CN/platforms/android.md +155 -0
  872. package/docs/zh-CN/platforms/digitalocean.md +269 -0
  873. package/docs/zh-CN/platforms/index.md +60 -0
  874. package/docs/zh-CN/platforms/ios.md +114 -0
  875. package/docs/zh-CN/platforms/linux.md +101 -0
  876. package/docs/zh-CN/platforms/mac/bundled-gateway.md +75 -0
  877. package/docs/zh-CN/platforms/mac/canvas.md +128 -0
  878. package/docs/zh-CN/platforms/mac/child-process.md +73 -0
  879. package/docs/zh-CN/platforms/mac/dev-setup.md +109 -0
  880. package/docs/zh-CN/platforms/mac/health.md +41 -0
  881. package/docs/zh-CN/platforms/mac/icon.md +38 -0
  882. package/docs/zh-CN/platforms/mac/logging.md +64 -0
  883. package/docs/zh-CN/platforms/mac/menu-bar.md +88 -0
  884. package/docs/zh-CN/platforms/mac/peekaboo.md +62 -0
  885. package/docs/zh-CN/platforms/mac/permissions.md +46 -0
  886. package/docs/zh-CN/platforms/mac/release.md +92 -0
  887. package/docs/zh-CN/platforms/mac/remote.md +90 -0
  888. package/docs/zh-CN/platforms/mac/signing.md +54 -0
  889. package/docs/zh-CN/platforms/mac/skills.md +40 -0
  890. package/docs/zh-CN/platforms/mac/voice-overlay.md +67 -0
  891. package/docs/zh-CN/platforms/mac/voicewake.md +74 -0
  892. package/docs/zh-CN/platforms/mac/webchat.md +43 -0
  893. package/docs/zh-CN/platforms/mac/xpc.md +68 -0
  894. package/docs/zh-CN/platforms/macos.md +193 -0
  895. package/docs/zh-CN/platforms/oracle.md +310 -0
  896. package/docs/zh-CN/platforms/raspberry-pi.md +365 -0
  897. package/docs/zh-CN/platforms/windows.md +156 -0
  898. package/docs/zh-CN/plugins/agent-tools.md +99 -0
  899. package/docs/zh-CN/plugins/manifest.md +68 -0
  900. package/docs/zh-CN/plugins/voice-call.md +250 -0
  901. package/docs/zh-CN/plugins/zalouser.md +88 -0
  902. package/docs/zh-CN/prose.md +141 -0
  903. package/docs/zh-CN/providers/anthropic.md +159 -0
  904. package/docs/zh-CN/providers/bedrock.md +170 -0
  905. package/docs/zh-CN/providers/claude-max-api-proxy.md +155 -0
  906. package/docs/zh-CN/providers/deepgram.md +97 -0
  907. package/docs/zh-CN/providers/github-copilot.md +67 -0
  908. package/docs/zh-CN/providers/glm.md +39 -0
  909. package/docs/zh-CN/providers/index.md +68 -0
  910. package/docs/zh-CN/providers/minimax.md +206 -0
  911. package/docs/zh-CN/providers/models.md +55 -0
  912. package/docs/zh-CN/providers/moonshot.md +145 -0
  913. package/docs/zh-CN/providers/ollama.md +230 -0
  914. package/docs/zh-CN/providers/openai.md +68 -0
  915. package/docs/zh-CN/providers/opencode.md +41 -0
  916. package/docs/zh-CN/providers/openrouter.md +43 -0
  917. package/docs/zh-CN/providers/qianfan.md +8 -0
  918. package/docs/zh-CN/providers/qwen.md +55 -0
  919. package/docs/zh-CN/providers/synthetic.md +102 -0
  920. package/docs/zh-CN/providers/venice.md +274 -0
  921. package/docs/zh-CN/providers/vercel-ai-gateway.md +57 -0
  922. package/docs/zh-CN/providers/xiaomi.md +68 -0
  923. package/docs/zh-CN/providers/zai.md +41 -0
  924. package/docs/zh-CN/refactor/clawnet.md +424 -0
  925. package/docs/zh-CN/refactor/exec-host.md +323 -0
  926. package/docs/zh-CN/refactor/outbound-session-mirroring.md +92 -0
  927. package/docs/zh-CN/refactor/plugin-sdk.md +221 -0
  928. package/docs/zh-CN/refactor/strict-config.md +100 -0
  929. package/docs/zh-CN/reference/AGENTS.default.md +131 -0
  930. package/docs/zh-CN/reference/RELEASING.md +123 -0
  931. package/docs/zh-CN/reference/api-usage-costs.md +136 -0
  932. package/docs/zh-CN/reference/credits.md +34 -0
  933. package/docs/zh-CN/reference/device-models.md +54 -0
  934. package/docs/zh-CN/reference/rpc.md +48 -0
  935. package/docs/zh-CN/reference/session-management-compaction.md +287 -0
  936. package/docs/zh-CN/reference/templates/AGENTS.dev.md +89 -0
  937. package/docs/zh-CN/reference/templates/AGENTS.md +225 -0
  938. package/docs/zh-CN/reference/templates/BOOT.md +17 -0
  939. package/docs/zh-CN/reference/templates/BOOTSTRAP.md +68 -0
  940. package/docs/zh-CN/reference/templates/HEARTBEAT.md +18 -0
  941. package/docs/zh-CN/reference/templates/IDENTITY.dev.md +54 -0
  942. package/docs/zh-CN/reference/templates/IDENTITY.md +36 -0
  943. package/docs/zh-CN/reference/templates/SOUL.dev.md +83 -0
  944. package/docs/zh-CN/reference/templates/SOUL.md +49 -0
  945. package/docs/zh-CN/reference/templates/TOOLS.dev.md +31 -0
  946. package/docs/zh-CN/reference/templates/TOOLS.md +53 -0
  947. package/docs/zh-CN/reference/templates/USER.dev.md +25 -0
  948. package/docs/zh-CN/reference/templates/USER.md +30 -0
  949. package/docs/zh-CN/reference/test.md +57 -0
  950. package/docs/zh-CN/reference/token-use.md +119 -0
  951. package/docs/zh-CN/reference/transcript-hygiene.md +109 -0
  952. package/docs/zh-CN/reference/wizard.md +9 -0
  953. package/docs/zh-CN/security/formal-verification.md +171 -0
  954. package/docs/zh-CN/start/bootstrapping.md +9 -0
  955. package/docs/zh-CN/start/docs-directory.md +70 -0
  956. package/docs/zh-CN/start/getting-started.md +206 -0
  957. package/docs/zh-CN/start/hubs.md +200 -0
  958. package/docs/zh-CN/start/lore.md +226 -0
  959. package/docs/zh-CN/start/onboarding.md +105 -0
  960. package/docs/zh-CN/start/openclaw.md +248 -0
  961. package/docs/zh-CN/start/quickstart.md +88 -0
  962. package/docs/zh-CN/start/setup.md +153 -0
  963. package/docs/zh-CN/start/showcase.md +423 -0
  964. package/docs/zh-CN/start/wizard.md +331 -0
  965. package/docs/zh-CN/tools/agent-send.md +59 -0
  966. package/docs/zh-CN/tools/apply-patch.md +57 -0
  967. package/docs/zh-CN/tools/browser-linux-troubleshooting.md +144 -0
  968. package/docs/zh-CN/tools/browser-login.md +75 -0
  969. package/docs/zh-CN/tools/browser.md +553 -0
  970. package/docs/zh-CN/tools/chrome-extension.md +183 -0
  971. package/docs/zh-CN/tools/clawhub.md +209 -0
  972. package/docs/zh-CN/tools/creating-skills.md +61 -0
  973. package/docs/zh-CN/tools/elevated.md +64 -0
  974. package/docs/zh-CN/tools/exec-approvals.md +234 -0
  975. package/docs/zh-CN/tools/exec.md +169 -0
  976. package/docs/zh-CN/tools/firecrawl.md +68 -0
  977. package/docs/zh-CN/tools/index.md +515 -0
  978. package/docs/zh-CN/tools/llm-task.md +117 -0
  979. package/docs/zh-CN/tools/lobster.md +349 -0
  980. package/docs/zh-CN/tools/multi-agent-sandbox-tools.md +401 -0
  981. package/docs/zh-CN/tools/plugin.md +639 -0
  982. package/docs/zh-CN/tools/reactions.md +29 -0
  983. package/docs/zh-CN/tools/skills-config.md +78 -0
  984. package/docs/zh-CN/tools/skills.md +279 -0
  985. package/docs/zh-CN/tools/slash-commands.md +205 -0
  986. package/docs/zh-CN/tools/subagents.md +156 -0
  987. package/docs/zh-CN/tools/thinking.md +80 -0
  988. package/docs/zh-CN/tools/web.md +257 -0
  989. package/docs/zh-CN/tts.md +375 -0
  990. package/docs/zh-CN/vps.md +47 -0
  991. package/docs/zh-CN/web/control-ui.md +191 -0
  992. package/docs/zh-CN/web/dashboard.md +53 -0
  993. package/docs/zh-CN/web/index.md +118 -0
  994. package/docs/zh-CN/web/tui.md +166 -0
  995. package/docs/zh-CN/web/webchat.md +56 -0
  996. package/extensions/bluebubbles/README.md +45 -0
  997. package/extensions/bluebubbles/index.ts +19 -0
  998. package/extensions/bluebubbles/node_modules/.bin/clawdbot +21 -0
  999. package/extensions/bluebubbles/node_modules/.bin/clawdbot.CMD +12 -0
  1000. package/extensions/bluebubbles/node_modules/.bin/clawdbot.ps1 +41 -0
  1001. package/extensions/bluebubbles/node_modules/.bin/openclaw +21 -0
  1002. package/extensions/bluebubbles/node_modules/.bin/openclaw.CMD +12 -0
  1003. package/extensions/bluebubbles/node_modules/.bin/openclaw.ps1 +41 -0
  1004. package/extensions/bluebubbles/node_modules/.bin/synurex +21 -0
  1005. package/extensions/bluebubbles/node_modules/.bin/synurex.CMD +12 -0
  1006. package/extensions/bluebubbles/node_modules/.bin/synurex.ps1 +41 -0
  1007. package/extensions/bluebubbles/package.json +36 -0
  1008. package/extensions/bluebubbles/src/accounts.ts +88 -0
  1009. package/extensions/bluebubbles/src/actions.test.ts +650 -0
  1010. package/extensions/bluebubbles/src/actions.ts +438 -0
  1011. package/extensions/bluebubbles/src/attachments.test.ts +345 -0
  1012. package/extensions/bluebubbles/src/attachments.ts +302 -0
  1013. package/extensions/bluebubbles/src/channel.ts +414 -0
  1014. package/extensions/bluebubbles/src/chat.test.ts +461 -0
  1015. package/extensions/bluebubbles/src/chat.ts +382 -0
  1016. package/extensions/bluebubbles/src/config-schema.ts +51 -0
  1017. package/extensions/bluebubbles/src/media-send.ts +174 -0
  1018. package/extensions/bluebubbles/src/monitor.test.ts +2384 -0
  1019. package/extensions/bluebubbles/src/monitor.ts +2517 -0
  1020. package/extensions/bluebubbles/src/onboarding.ts +352 -0
  1021. package/extensions/bluebubbles/src/probe.ts +144 -0
  1022. package/extensions/bluebubbles/src/reactions.test.ts +392 -0
  1023. package/extensions/bluebubbles/src/reactions.ts +188 -0
  1024. package/extensions/bluebubbles/src/runtime.ts +14 -0
  1025. package/extensions/bluebubbles/src/send.test.ts +889 -0
  1026. package/extensions/bluebubbles/src/send.ts +474 -0
  1027. package/extensions/bluebubbles/src/targets.test.ts +183 -0
  1028. package/extensions/bluebubbles/src/targets.ts +422 -0
  1029. package/extensions/bluebubbles/src/types.ts +127 -0
  1030. package/extensions/bluebubbles/synurex.plugin.json +9 -0
  1031. package/extensions/copilot-proxy/README.md +24 -0
  1032. package/extensions/copilot-proxy/index.ts +149 -0
  1033. package/extensions/copilot-proxy/node_modules/.bin/clawdbot +21 -0
  1034. package/extensions/copilot-proxy/node_modules/.bin/clawdbot.CMD +12 -0
  1035. package/extensions/copilot-proxy/node_modules/.bin/clawdbot.ps1 +41 -0
  1036. package/extensions/copilot-proxy/node_modules/.bin/openclaw +21 -0
  1037. package/extensions/copilot-proxy/node_modules/.bin/openclaw.CMD +12 -0
  1038. package/extensions/copilot-proxy/node_modules/.bin/openclaw.ps1 +41 -0
  1039. package/extensions/copilot-proxy/node_modules/.bin/synurex +21 -0
  1040. package/extensions/copilot-proxy/node_modules/.bin/synurex.CMD +12 -0
  1041. package/extensions/copilot-proxy/node_modules/.bin/synurex.ps1 +41 -0
  1042. package/extensions/copilot-proxy/package.json +14 -0
  1043. package/extensions/copilot-proxy/synurex.plugin.json +9 -0
  1044. package/extensions/diagnostics-otel/index.ts +15 -0
  1045. package/extensions/diagnostics-otel/node_modules/.bin/clawdbot +21 -0
  1046. package/extensions/diagnostics-otel/node_modules/.bin/clawdbot.CMD +12 -0
  1047. package/extensions/diagnostics-otel/node_modules/.bin/clawdbot.ps1 +41 -0
  1048. package/extensions/diagnostics-otel/node_modules/.bin/openclaw +21 -0
  1049. package/extensions/diagnostics-otel/node_modules/.bin/openclaw.CMD +12 -0
  1050. package/extensions/diagnostics-otel/node_modules/.bin/openclaw.ps1 +41 -0
  1051. package/extensions/diagnostics-otel/node_modules/.bin/synurex +21 -0
  1052. package/extensions/diagnostics-otel/node_modules/.bin/synurex.CMD +12 -0
  1053. package/extensions/diagnostics-otel/node_modules/.bin/synurex.ps1 +41 -0
  1054. package/extensions/diagnostics-otel/package.json +27 -0
  1055. package/extensions/diagnostics-otel/src/service.test.ts +226 -0
  1056. package/extensions/diagnostics-otel/src/service.ts +635 -0
  1057. package/extensions/diagnostics-otel/synurex.plugin.json +8 -0
  1058. package/extensions/discord/index.ts +17 -0
  1059. package/extensions/discord/node_modules/.bin/clawdbot +21 -0
  1060. package/extensions/discord/node_modules/.bin/clawdbot.CMD +12 -0
  1061. package/extensions/discord/node_modules/.bin/clawdbot.ps1 +41 -0
  1062. package/extensions/discord/node_modules/.bin/openclaw +21 -0
  1063. package/extensions/discord/node_modules/.bin/openclaw.CMD +12 -0
  1064. package/extensions/discord/node_modules/.bin/openclaw.ps1 +41 -0
  1065. package/extensions/discord/node_modules/.bin/synurex +21 -0
  1066. package/extensions/discord/node_modules/.bin/synurex.CMD +12 -0
  1067. package/extensions/discord/node_modules/.bin/synurex.ps1 +41 -0
  1068. package/extensions/discord/package.json +14 -0
  1069. package/extensions/discord/src/channel.ts +422 -0
  1070. package/extensions/discord/src/runtime.ts +14 -0
  1071. package/extensions/discord/synurex.plugin.json +9 -0
  1072. package/extensions/feishu/index.ts +63 -0
  1073. package/extensions/feishu/node_modules/.bin/clawdbot +21 -0
  1074. package/extensions/feishu/node_modules/.bin/clawdbot.CMD +12 -0
  1075. package/extensions/feishu/node_modules/.bin/clawdbot.ps1 +41 -0
  1076. package/extensions/feishu/node_modules/.bin/openclaw +21 -0
  1077. package/extensions/feishu/node_modules/.bin/openclaw.CMD +12 -0
  1078. package/extensions/feishu/node_modules/.bin/openclaw.ps1 +41 -0
  1079. package/extensions/feishu/node_modules/.bin/synurex +21 -0
  1080. package/extensions/feishu/node_modules/.bin/synurex.CMD +12 -0
  1081. package/extensions/feishu/node_modules/.bin/synurex.ps1 +41 -0
  1082. package/extensions/feishu/package.json +37 -0
  1083. package/extensions/feishu/skills/feishu-doc/SKILL.md +105 -0
  1084. package/extensions/feishu/skills/feishu-doc/references/block-types.md +103 -0
  1085. package/extensions/feishu/skills/feishu-drive/SKILL.md +97 -0
  1086. package/extensions/feishu/skills/feishu-perm/SKILL.md +119 -0
  1087. package/extensions/feishu/skills/feishu-wiki/SKILL.md +111 -0
  1088. package/extensions/feishu/src/accounts.ts +144 -0
  1089. package/extensions/feishu/src/bitable.ts +459 -0
  1090. package/extensions/feishu/src/bot.ts +871 -0
  1091. package/extensions/feishu/src/channel.ts +341 -0
  1092. package/extensions/feishu/src/client.ts +118 -0
  1093. package/extensions/feishu/src/config-schema.ts +172 -0
  1094. package/extensions/feishu/src/directory.ts +177 -0
  1095. package/extensions/feishu/src/doc-schema.ts +47 -0
  1096. package/extensions/feishu/src/docx.ts +521 -0
  1097. package/extensions/feishu/src/drive-schema.ts +46 -0
  1098. package/extensions/feishu/src/drive.ts +227 -0
  1099. package/extensions/feishu/src/media.ts +527 -0
  1100. package/extensions/feishu/src/mention.ts +126 -0
  1101. package/extensions/feishu/src/monitor.ts +190 -0
  1102. package/extensions/feishu/src/onboarding.ts +356 -0
  1103. package/extensions/feishu/src/outbound.ts +40 -0
  1104. package/extensions/feishu/src/perm-schema.ts +52 -0
  1105. package/extensions/feishu/src/perm.ts +173 -0
  1106. package/extensions/feishu/src/policy.ts +104 -0
  1107. package/extensions/feishu/src/probe.ts +44 -0
  1108. package/extensions/feishu/src/reactions.ts +160 -0
  1109. package/extensions/feishu/src/reply-dispatcher.ts +184 -0
  1110. package/extensions/feishu/src/runtime.ts +14 -0
  1111. package/extensions/feishu/src/send.ts +358 -0
  1112. package/extensions/feishu/src/targets.ts +78 -0
  1113. package/extensions/feishu/src/tools-config.ts +21 -0
  1114. package/extensions/feishu/src/types.ts +75 -0
  1115. package/extensions/feishu/src/typing.ts +80 -0
  1116. package/extensions/feishu/src/wiki-schema.ts +55 -0
  1117. package/extensions/feishu/src/wiki.ts +232 -0
  1118. package/extensions/feishu/synurex.plugin.json +10 -0
  1119. package/extensions/google-antigravity-auth/README.md +24 -0
  1120. package/extensions/google-antigravity-auth/index.ts +461 -0
  1121. package/extensions/google-antigravity-auth/node_modules/.bin/clawdbot +21 -0
  1122. package/extensions/google-antigravity-auth/node_modules/.bin/clawdbot.CMD +12 -0
  1123. package/extensions/google-antigravity-auth/node_modules/.bin/clawdbot.ps1 +41 -0
  1124. package/extensions/google-antigravity-auth/node_modules/.bin/openclaw +21 -0
  1125. package/extensions/google-antigravity-auth/node_modules/.bin/openclaw.CMD +12 -0
  1126. package/extensions/google-antigravity-auth/node_modules/.bin/openclaw.ps1 +41 -0
  1127. package/extensions/google-antigravity-auth/node_modules/.bin/synurex +21 -0
  1128. package/extensions/google-antigravity-auth/node_modules/.bin/synurex.CMD +12 -0
  1129. package/extensions/google-antigravity-auth/node_modules/.bin/synurex.ps1 +41 -0
  1130. package/extensions/google-antigravity-auth/package.json +14 -0
  1131. package/extensions/google-antigravity-auth/synurex.plugin.json +9 -0
  1132. package/extensions/google-gemini-cli-auth/README.md +35 -0
  1133. package/extensions/google-gemini-cli-auth/index.ts +88 -0
  1134. package/extensions/google-gemini-cli-auth/node_modules/.bin/clawdbot +21 -0
  1135. package/extensions/google-gemini-cli-auth/node_modules/.bin/clawdbot.CMD +12 -0
  1136. package/extensions/google-gemini-cli-auth/node_modules/.bin/clawdbot.ps1 +41 -0
  1137. package/extensions/google-gemini-cli-auth/node_modules/.bin/openclaw +21 -0
  1138. package/extensions/google-gemini-cli-auth/node_modules/.bin/openclaw.CMD +12 -0
  1139. package/extensions/google-gemini-cli-auth/node_modules/.bin/openclaw.ps1 +41 -0
  1140. package/extensions/google-gemini-cli-auth/node_modules/.bin/synurex +21 -0
  1141. package/extensions/google-gemini-cli-auth/node_modules/.bin/synurex.CMD +12 -0
  1142. package/extensions/google-gemini-cli-auth/node_modules/.bin/synurex.ps1 +41 -0
  1143. package/extensions/google-gemini-cli-auth/oauth.test.ts +240 -0
  1144. package/extensions/google-gemini-cli-auth/oauth.ts +662 -0
  1145. package/extensions/google-gemini-cli-auth/package.json +14 -0
  1146. package/extensions/google-gemini-cli-auth/synurex.plugin.json +9 -0
  1147. package/extensions/googlechat/index.ts +19 -0
  1148. package/extensions/googlechat/node_modules/.bin/clawdbot +21 -0
  1149. package/extensions/googlechat/node_modules/.bin/clawdbot.CMD +12 -0
  1150. package/extensions/googlechat/node_modules/.bin/clawdbot.ps1 +41 -0
  1151. package/extensions/googlechat/node_modules/.bin/openclaw +21 -0
  1152. package/extensions/googlechat/node_modules/.bin/openclaw.CMD +12 -0
  1153. package/extensions/googlechat/node_modules/.bin/openclaw.ps1 +41 -0
  1154. package/extensions/googlechat/node_modules/.bin/synurex +21 -0
  1155. package/extensions/googlechat/node_modules/.bin/synurex.CMD +12 -0
  1156. package/extensions/googlechat/node_modules/.bin/synurex.ps1 +41 -0
  1157. package/extensions/googlechat/package.json +39 -0
  1158. package/extensions/googlechat/src/accounts.ts +147 -0
  1159. package/extensions/googlechat/src/actions.ts +181 -0
  1160. package/extensions/googlechat/src/api.test.ts +61 -0
  1161. package/extensions/googlechat/src/api.ts +282 -0
  1162. package/extensions/googlechat/src/auth.ts +137 -0
  1163. package/extensions/googlechat/src/channel.ts +583 -0
  1164. package/extensions/googlechat/src/monitor.test.ts +22 -0
  1165. package/extensions/googlechat/src/monitor.ts +960 -0
  1166. package/extensions/googlechat/src/onboarding.ts +269 -0
  1167. package/extensions/googlechat/src/runtime.ts +14 -0
  1168. package/extensions/googlechat/src/targets.test.ts +32 -0
  1169. package/extensions/googlechat/src/targets.ts +65 -0
  1170. package/extensions/googlechat/src/types.config.ts +3 -0
  1171. package/extensions/googlechat/src/types.ts +73 -0
  1172. package/extensions/googlechat/synurex.plugin.json +9 -0
  1173. package/extensions/imessage/index.ts +17 -0
  1174. package/extensions/imessage/node_modules/.bin/clawdbot +21 -0
  1175. package/extensions/imessage/node_modules/.bin/clawdbot.CMD +12 -0
  1176. package/extensions/imessage/node_modules/.bin/clawdbot.ps1 +41 -0
  1177. package/extensions/imessage/node_modules/.bin/openclaw +21 -0
  1178. package/extensions/imessage/node_modules/.bin/openclaw.CMD +12 -0
  1179. package/extensions/imessage/node_modules/.bin/openclaw.ps1 +41 -0
  1180. package/extensions/imessage/node_modules/.bin/synurex +21 -0
  1181. package/extensions/imessage/node_modules/.bin/synurex.CMD +12 -0
  1182. package/extensions/imessage/node_modules/.bin/synurex.ps1 +41 -0
  1183. package/extensions/imessage/package.json +14 -0
  1184. package/extensions/imessage/src/channel.ts +294 -0
  1185. package/extensions/imessage/src/runtime.ts +14 -0
  1186. package/extensions/imessage/synurex.plugin.json +9 -0
  1187. package/extensions/line/index.ts +19 -0
  1188. package/extensions/line/node_modules/.bin/clawdbot +21 -0
  1189. package/extensions/line/node_modules/.bin/clawdbot.CMD +12 -0
  1190. package/extensions/line/node_modules/.bin/clawdbot.ps1 +41 -0
  1191. package/extensions/line/node_modules/.bin/openclaw +21 -0
  1192. package/extensions/line/node_modules/.bin/openclaw.CMD +12 -0
  1193. package/extensions/line/node_modules/.bin/openclaw.ps1 +41 -0
  1194. package/extensions/line/node_modules/.bin/synurex +21 -0
  1195. package/extensions/line/node_modules/.bin/synurex.CMD +12 -0
  1196. package/extensions/line/node_modules/.bin/synurex.ps1 +41 -0
  1197. package/extensions/line/package.json +29 -0
  1198. package/extensions/line/src/card-command.ts +344 -0
  1199. package/extensions/line/src/channel.logout.test.ts +99 -0
  1200. package/extensions/line/src/channel.sendPayload.test.ts +306 -0
  1201. package/extensions/line/src/channel.ts +780 -0
  1202. package/extensions/line/src/runtime.ts +14 -0
  1203. package/extensions/line/synurex.plugin.json +9 -0
  1204. package/extensions/llm-task/README.md +97 -0
  1205. package/extensions/llm-task/index.ts +6 -0
  1206. package/extensions/llm-task/node_modules/.bin/clawdbot +21 -0
  1207. package/extensions/llm-task/node_modules/.bin/clawdbot.CMD +12 -0
  1208. package/extensions/llm-task/node_modules/.bin/clawdbot.ps1 +41 -0
  1209. package/extensions/llm-task/node_modules/.bin/openclaw +21 -0
  1210. package/extensions/llm-task/node_modules/.bin/openclaw.CMD +12 -0
  1211. package/extensions/llm-task/node_modules/.bin/openclaw.ps1 +41 -0
  1212. package/extensions/llm-task/node_modules/.bin/synurex +21 -0
  1213. package/extensions/llm-task/node_modules/.bin/synurex.CMD +12 -0
  1214. package/extensions/llm-task/node_modules/.bin/synurex.ps1 +41 -0
  1215. package/extensions/llm-task/package.json +14 -0
  1216. package/extensions/llm-task/src/llm-task-tool.test.ts +138 -0
  1217. package/extensions/llm-task/src/llm-task-tool.ts +245 -0
  1218. package/extensions/llm-task/synurex.plugin.json +21 -0
  1219. package/extensions/lobster/README.md +75 -0
  1220. package/extensions/lobster/SKILL.md +97 -0
  1221. package/extensions/lobster/index.ts +14 -0
  1222. package/extensions/lobster/node_modules/.bin/clawdbot +21 -0
  1223. package/extensions/lobster/node_modules/.bin/clawdbot.CMD +12 -0
  1224. package/extensions/lobster/node_modules/.bin/clawdbot.ps1 +41 -0
  1225. package/extensions/lobster/node_modules/.bin/openclaw +21 -0
  1226. package/extensions/lobster/node_modules/.bin/openclaw.CMD +12 -0
  1227. package/extensions/lobster/node_modules/.bin/openclaw.ps1 +41 -0
  1228. package/extensions/lobster/node_modules/.bin/synurex +21 -0
  1229. package/extensions/lobster/node_modules/.bin/synurex.CMD +12 -0
  1230. package/extensions/lobster/node_modules/.bin/synurex.ps1 +41 -0
  1231. package/extensions/lobster/package.json +14 -0
  1232. package/extensions/lobster/src/lobster-tool.test.ts +247 -0
  1233. package/extensions/lobster/src/lobster-tool.ts +328 -0
  1234. package/extensions/lobster/synurex.plugin.json +10 -0
  1235. package/extensions/matrix/CHANGELOG.md +111 -0
  1236. package/extensions/matrix/index.ts +17 -0
  1237. package/extensions/matrix/node_modules/.bin/clawdbot +21 -0
  1238. package/extensions/matrix/node_modules/.bin/clawdbot.CMD +12 -0
  1239. package/extensions/matrix/node_modules/.bin/clawdbot.ps1 +41 -0
  1240. package/extensions/matrix/node_modules/.bin/markdown-it +21 -0
  1241. package/extensions/matrix/node_modules/.bin/markdown-it.CMD +12 -0
  1242. package/extensions/matrix/node_modules/.bin/markdown-it.ps1 +41 -0
  1243. package/extensions/matrix/node_modules/.bin/openclaw +21 -0
  1244. package/extensions/matrix/node_modules/.bin/openclaw.CMD +12 -0
  1245. package/extensions/matrix/node_modules/.bin/openclaw.ps1 +41 -0
  1246. package/extensions/matrix/node_modules/.bin/synurex +21 -0
  1247. package/extensions/matrix/node_modules/.bin/synurex.CMD +12 -0
  1248. package/extensions/matrix/node_modules/.bin/synurex.ps1 +41 -0
  1249. package/extensions/matrix/package.json +36 -0
  1250. package/extensions/matrix/src/actions.ts +195 -0
  1251. package/extensions/matrix/src/channel.directory.test.ts +64 -0
  1252. package/extensions/matrix/src/channel.ts +439 -0
  1253. package/extensions/matrix/src/config-schema.ts +63 -0
  1254. package/extensions/matrix/src/directory-live.ts +188 -0
  1255. package/extensions/matrix/src/group-mentions.ts +66 -0
  1256. package/extensions/matrix/src/matrix/accounts.test.ts +82 -0
  1257. package/extensions/matrix/src/matrix/accounts.ts +65 -0
  1258. package/extensions/matrix/src/matrix/actions/client.ts +57 -0
  1259. package/extensions/matrix/src/matrix/actions/messages.ts +128 -0
  1260. package/extensions/matrix/src/matrix/actions/pins.ts +76 -0
  1261. package/extensions/matrix/src/matrix/actions/reactions.ts +96 -0
  1262. package/extensions/matrix/src/matrix/actions/room.ts +85 -0
  1263. package/extensions/matrix/src/matrix/actions/summary.ts +75 -0
  1264. package/extensions/matrix/src/matrix/actions/types.ts +84 -0
  1265. package/extensions/matrix/src/matrix/actions.ts +15 -0
  1266. package/extensions/matrix/src/matrix/active-client.ts +11 -0
  1267. package/extensions/matrix/src/matrix/client/config.ts +160 -0
  1268. package/extensions/matrix/src/matrix/client/create-client.ts +123 -0
  1269. package/extensions/matrix/src/matrix/client/logging.ts +36 -0
  1270. package/extensions/matrix/src/matrix/client/runtime.ts +4 -0
  1271. package/extensions/matrix/src/matrix/client/shared.ts +170 -0
  1272. package/extensions/matrix/src/matrix/client/storage.ts +131 -0
  1273. package/extensions/matrix/src/matrix/client/types.ts +34 -0
  1274. package/extensions/matrix/src/matrix/client.test.ts +56 -0
  1275. package/extensions/matrix/src/matrix/client.ts +5 -0
  1276. package/extensions/matrix/src/matrix/credentials.ts +105 -0
  1277. package/extensions/matrix/src/matrix/deps.ts +60 -0
  1278. package/extensions/matrix/src/matrix/format.test.ts +33 -0
  1279. package/extensions/matrix/src/matrix/format.ts +22 -0
  1280. package/extensions/matrix/src/matrix/index.ts +11 -0
  1281. package/extensions/matrix/src/matrix/monitor/allowlist.test.ts +45 -0
  1282. package/extensions/matrix/src/matrix/monitor/allowlist.ts +103 -0
  1283. package/extensions/matrix/src/matrix/monitor/auto-join.ts +71 -0
  1284. package/extensions/matrix/src/matrix/monitor/direct.ts +104 -0
  1285. package/extensions/matrix/src/matrix/monitor/events.ts +101 -0
  1286. package/extensions/matrix/src/matrix/monitor/handler.ts +665 -0
  1287. package/extensions/matrix/src/matrix/monitor/index.ts +338 -0
  1288. package/extensions/matrix/src/matrix/monitor/location.ts +100 -0
  1289. package/extensions/matrix/src/matrix/monitor/media.test.ts +102 -0
  1290. package/extensions/matrix/src/matrix/monitor/media.ts +113 -0
  1291. package/extensions/matrix/src/matrix/monitor/mentions.ts +31 -0
  1292. package/extensions/matrix/src/matrix/monitor/replies.ts +97 -0
  1293. package/extensions/matrix/src/matrix/monitor/room-info.ts +55 -0
  1294. package/extensions/matrix/src/matrix/monitor/rooms.test.ts +39 -0
  1295. package/extensions/matrix/src/matrix/monitor/rooms.ts +47 -0
  1296. package/extensions/matrix/src/matrix/monitor/threads.ts +68 -0
  1297. package/extensions/matrix/src/matrix/monitor/types.ts +39 -0
  1298. package/extensions/matrix/src/matrix/poll-types.test.ts +21 -0
  1299. package/extensions/matrix/src/matrix/poll-types.ts +166 -0
  1300. package/extensions/matrix/src/matrix/probe.ts +70 -0
  1301. package/extensions/matrix/src/matrix/send/client.ts +66 -0
  1302. package/extensions/matrix/src/matrix/send/formatting.ts +89 -0
  1303. package/extensions/matrix/src/matrix/send/media.ts +229 -0
  1304. package/extensions/matrix/src/matrix/send/targets.test.ts +98 -0
  1305. package/extensions/matrix/src/matrix/send/targets.ts +147 -0
  1306. package/extensions/matrix/src/matrix/send/types.ts +109 -0
  1307. package/extensions/matrix/src/matrix/send.test.ts +171 -0
  1308. package/extensions/matrix/src/matrix/send.ts +260 -0
  1309. package/extensions/matrix/src/onboarding.ts +449 -0
  1310. package/extensions/matrix/src/outbound.ts +52 -0
  1311. package/extensions/matrix/src/resolve-targets.test.ts +48 -0
  1312. package/extensions/matrix/src/resolve-targets.ts +135 -0
  1313. package/extensions/matrix/src/runtime.ts +14 -0
  1314. package/extensions/matrix/src/tool-actions.ts +164 -0
  1315. package/extensions/matrix/src/types.ts +97 -0
  1316. package/extensions/matrix/synurex.plugin.json +9 -0
  1317. package/extensions/mattermost/index.ts +17 -0
  1318. package/extensions/mattermost/node_modules/.bin/clawdbot +21 -0
  1319. package/extensions/mattermost/node_modules/.bin/clawdbot.CMD +12 -0
  1320. package/extensions/mattermost/node_modules/.bin/clawdbot.ps1 +41 -0
  1321. package/extensions/mattermost/node_modules/.bin/openclaw +21 -0
  1322. package/extensions/mattermost/node_modules/.bin/openclaw.CMD +12 -0
  1323. package/extensions/mattermost/node_modules/.bin/openclaw.ps1 +41 -0
  1324. package/extensions/mattermost/node_modules/.bin/synurex +21 -0
  1325. package/extensions/mattermost/node_modules/.bin/synurex.CMD +12 -0
  1326. package/extensions/mattermost/node_modules/.bin/synurex.ps1 +41 -0
  1327. package/extensions/mattermost/package.json +28 -0
  1328. package/extensions/mattermost/src/channel.test.ts +72 -0
  1329. package/extensions/mattermost/src/channel.ts +337 -0
  1330. package/extensions/mattermost/src/config-schema.ts +56 -0
  1331. package/extensions/mattermost/src/group-mentions.ts +15 -0
  1332. package/extensions/mattermost/src/mattermost/accounts.ts +128 -0
  1333. package/extensions/mattermost/src/mattermost/client.ts +220 -0
  1334. package/extensions/mattermost/src/mattermost/index.ts +9 -0
  1335. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +166 -0
  1336. package/extensions/mattermost/src/mattermost/monitor.ts +991 -0
  1337. package/extensions/mattermost/src/mattermost/probe.ts +74 -0
  1338. package/extensions/mattermost/src/mattermost/send.ts +231 -0
  1339. package/extensions/mattermost/src/normalize.ts +46 -0
  1340. package/extensions/mattermost/src/onboarding-helpers.ts +44 -0
  1341. package/extensions/mattermost/src/onboarding.ts +186 -0
  1342. package/extensions/mattermost/src/runtime.ts +14 -0
  1343. package/extensions/mattermost/src/types.ts +52 -0
  1344. package/extensions/mattermost/synurex.plugin.json +9 -0
  1345. package/extensions/memory-core/index.ts +38 -0
  1346. package/extensions/memory-core/node_modules/.bin/clawdbot +21 -0
  1347. package/extensions/memory-core/node_modules/.bin/clawdbot.CMD +12 -0
  1348. package/extensions/memory-core/node_modules/.bin/clawdbot.ps1 +41 -0
  1349. package/extensions/memory-core/node_modules/.bin/openclaw +21 -0
  1350. package/extensions/memory-core/node_modules/.bin/openclaw.CMD +12 -0
  1351. package/extensions/memory-core/node_modules/.bin/openclaw.ps1 +41 -0
  1352. package/extensions/memory-core/node_modules/.bin/synurex +21 -0
  1353. package/extensions/memory-core/node_modules/.bin/synurex.CMD +12 -0
  1354. package/extensions/memory-core/node_modules/.bin/synurex.ps1 +41 -0
  1355. package/extensions/memory-core/package.json +17 -0
  1356. package/extensions/memory-core/synurex.plugin.json +9 -0
  1357. package/extensions/memory-lancedb/config.ts +139 -0
  1358. package/extensions/memory-lancedb/index.test.ts +253 -0
  1359. package/extensions/memory-lancedb/index.ts +622 -0
  1360. package/extensions/memory-lancedb/node_modules/.bin/clawdbot +21 -0
  1361. package/extensions/memory-lancedb/node_modules/.bin/clawdbot.CMD +12 -0
  1362. package/extensions/memory-lancedb/node_modules/.bin/clawdbot.ps1 +41 -0
  1363. package/extensions/memory-lancedb/node_modules/.bin/openai +21 -0
  1364. package/extensions/memory-lancedb/node_modules/.bin/openai.CMD +12 -0
  1365. package/extensions/memory-lancedb/node_modules/.bin/openai.ps1 +41 -0
  1366. package/extensions/memory-lancedb/node_modules/.bin/openclaw +21 -0
  1367. package/extensions/memory-lancedb/node_modules/.bin/openclaw.CMD +12 -0
  1368. package/extensions/memory-lancedb/node_modules/.bin/openclaw.ps1 +41 -0
  1369. package/extensions/memory-lancedb/node_modules/.bin/synurex +21 -0
  1370. package/extensions/memory-lancedb/node_modules/.bin/synurex.CMD +12 -0
  1371. package/extensions/memory-lancedb/node_modules/.bin/synurex.ps1 +41 -0
  1372. package/extensions/memory-lancedb/package.json +19 -0
  1373. package/extensions/memory-lancedb/synurex.plugin.json +60 -0
  1374. package/extensions/minimax-portal-auth/README.md +33 -0
  1375. package/extensions/minimax-portal-auth/index.ts +155 -0
  1376. package/extensions/minimax-portal-auth/node_modules/.bin/clawdbot +21 -0
  1377. package/extensions/minimax-portal-auth/node_modules/.bin/clawdbot.CMD +12 -0
  1378. package/extensions/minimax-portal-auth/node_modules/.bin/clawdbot.ps1 +41 -0
  1379. package/extensions/minimax-portal-auth/node_modules/.bin/openclaw +21 -0
  1380. package/extensions/minimax-portal-auth/node_modules/.bin/openclaw.CMD +12 -0
  1381. package/extensions/minimax-portal-auth/node_modules/.bin/openclaw.ps1 +41 -0
  1382. package/extensions/minimax-portal-auth/node_modules/.bin/synurex +21 -0
  1383. package/extensions/minimax-portal-auth/node_modules/.bin/synurex.CMD +12 -0
  1384. package/extensions/minimax-portal-auth/node_modules/.bin/synurex.ps1 +41 -0
  1385. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  1386. package/extensions/minimax-portal-auth/package.json +14 -0
  1387. package/extensions/minimax-portal-auth/synurex.plugin.json +9 -0
  1388. package/extensions/msteams/CHANGELOG.md +107 -0
  1389. package/extensions/msteams/index.ts +17 -0
  1390. package/extensions/msteams/node_modules/.bin/clawdbot +21 -0
  1391. package/extensions/msteams/node_modules/.bin/clawdbot.CMD +12 -0
  1392. package/extensions/msteams/node_modules/.bin/clawdbot.ps1 +41 -0
  1393. package/extensions/msteams/node_modules/.bin/openclaw +21 -0
  1394. package/extensions/msteams/node_modules/.bin/openclaw.CMD +12 -0
  1395. package/extensions/msteams/node_modules/.bin/openclaw.ps1 +41 -0
  1396. package/extensions/msteams/node_modules/.bin/synurex +21 -0
  1397. package/extensions/msteams/node_modules/.bin/synurex.CMD +12 -0
  1398. package/extensions/msteams/node_modules/.bin/synurex.ps1 +41 -0
  1399. package/extensions/msteams/package.json +39 -0
  1400. package/extensions/msteams/src/attachments/download.ts +283 -0
  1401. package/extensions/msteams/src/attachments/graph.ts +353 -0
  1402. package/extensions/msteams/src/attachments/html.ts +90 -0
  1403. package/extensions/msteams/src/attachments/payload.ts +22 -0
  1404. package/extensions/msteams/src/attachments/shared.ts +291 -0
  1405. package/extensions/msteams/src/attachments/types.ts +37 -0
  1406. package/extensions/msteams/src/attachments.test.ts +459 -0
  1407. package/extensions/msteams/src/attachments.ts +18 -0
  1408. package/extensions/msteams/src/channel.directory.test.ts +48 -0
  1409. package/extensions/msteams/src/channel.ts +459 -0
  1410. package/extensions/msteams/src/conversation-store-fs.test.ts +88 -0
  1411. package/extensions/msteams/src/conversation-store-fs.ts +165 -0
  1412. package/extensions/msteams/src/conversation-store-memory.ts +47 -0
  1413. package/extensions/msteams/src/conversation-store.ts +41 -0
  1414. package/extensions/msteams/src/directory-live.ts +205 -0
  1415. package/extensions/msteams/src/errors.test.ts +45 -0
  1416. package/extensions/msteams/src/errors.ts +190 -0
  1417. package/extensions/msteams/src/file-consent-helpers.test.ts +243 -0
  1418. package/extensions/msteams/src/file-consent-helpers.ts +73 -0
  1419. package/extensions/msteams/src/file-consent.ts +126 -0
  1420. package/extensions/msteams/src/graph-chat.ts +53 -0
  1421. package/extensions/msteams/src/graph-upload.ts +453 -0
  1422. package/extensions/msteams/src/inbound.test.ts +66 -0
  1423. package/extensions/msteams/src/inbound.ts +48 -0
  1424. package/extensions/msteams/src/index.ts +4 -0
  1425. package/extensions/msteams/src/media-helpers.test.ts +189 -0
  1426. package/extensions/msteams/src/media-helpers.ts +86 -0
  1427. package/extensions/msteams/src/messenger.test.ts +248 -0
  1428. package/extensions/msteams/src/messenger.ts +495 -0
  1429. package/extensions/msteams/src/monitor-handler/inbound-media.ts +128 -0
  1430. package/extensions/msteams/src/monitor-handler/message-handler.ts +641 -0
  1431. package/extensions/msteams/src/monitor-handler.ts +162 -0
  1432. package/extensions/msteams/src/monitor-types.ts +5 -0
  1433. package/extensions/msteams/src/monitor.ts +295 -0
  1434. package/extensions/msteams/src/onboarding.ts +431 -0
  1435. package/extensions/msteams/src/outbound.ts +46 -0
  1436. package/extensions/msteams/src/pending-uploads.ts +89 -0
  1437. package/extensions/msteams/src/policy.test.ts +209 -0
  1438. package/extensions/msteams/src/policy.ts +273 -0
  1439. package/extensions/msteams/src/polls-store-memory.ts +32 -0
  1440. package/extensions/msteams/src/polls-store.test.ts +38 -0
  1441. package/extensions/msteams/src/polls.test.ts +72 -0
  1442. package/extensions/msteams/src/polls.ts +315 -0
  1443. package/extensions/msteams/src/probe.test.ts +58 -0
  1444. package/extensions/msteams/src/probe.ts +107 -0
  1445. package/extensions/msteams/src/reply-dispatcher.ts +132 -0
  1446. package/extensions/msteams/src/resolve-allowlist.ts +297 -0
  1447. package/extensions/msteams/src/runtime.ts +14 -0
  1448. package/extensions/msteams/src/sdk-types.ts +19 -0
  1449. package/extensions/msteams/src/sdk.ts +33 -0
  1450. package/extensions/msteams/src/send-context.ts +164 -0
  1451. package/extensions/msteams/src/send.ts +519 -0
  1452. package/extensions/msteams/src/sent-message-cache.test.ts +15 -0
  1453. package/extensions/msteams/src/sent-message-cache.ts +47 -0
  1454. package/extensions/msteams/src/storage.ts +25 -0
  1455. package/extensions/msteams/src/store-fs.ts +83 -0
  1456. package/extensions/msteams/src/token.ts +19 -0
  1457. package/extensions/msteams/synurex.plugin.json +9 -0
  1458. package/extensions/nextcloud-talk/index.ts +17 -0
  1459. package/extensions/nextcloud-talk/node_modules/.bin/clawdbot +21 -0
  1460. package/extensions/nextcloud-talk/node_modules/.bin/clawdbot.CMD +12 -0
  1461. package/extensions/nextcloud-talk/node_modules/.bin/clawdbot.ps1 +41 -0
  1462. package/extensions/nextcloud-talk/node_modules/.bin/openclaw +21 -0
  1463. package/extensions/nextcloud-talk/node_modules/.bin/openclaw.CMD +12 -0
  1464. package/extensions/nextcloud-talk/node_modules/.bin/openclaw.ps1 +41 -0
  1465. package/extensions/nextcloud-talk/node_modules/.bin/synurex +21 -0
  1466. package/extensions/nextcloud-talk/node_modules/.bin/synurex.CMD +12 -0
  1467. package/extensions/nextcloud-talk/node_modules/.bin/synurex.ps1 +41 -0
  1468. package/extensions/nextcloud-talk/package.json +33 -0
  1469. package/extensions/nextcloud-talk/src/accounts.ts +174 -0
  1470. package/extensions/nextcloud-talk/src/channel.ts +409 -0
  1471. package/extensions/nextcloud-talk/src/config-schema.ts +79 -0
  1472. package/extensions/nextcloud-talk/src/format.ts +79 -0
  1473. package/extensions/nextcloud-talk/src/inbound.ts +327 -0
  1474. package/extensions/nextcloud-talk/src/monitor.ts +246 -0
  1475. package/extensions/nextcloud-talk/src/normalize.ts +39 -0
  1476. package/extensions/nextcloud-talk/src/onboarding.ts +343 -0
  1477. package/extensions/nextcloud-talk/src/policy.test.ts +33 -0
  1478. package/extensions/nextcloud-talk/src/policy.ts +180 -0
  1479. package/extensions/nextcloud-talk/src/room-info.ts +125 -0
  1480. package/extensions/nextcloud-talk/src/runtime.ts +14 -0
  1481. package/extensions/nextcloud-talk/src/send.ts +215 -0
  1482. package/extensions/nextcloud-talk/src/signature.ts +72 -0
  1483. package/extensions/nextcloud-talk/src/types.ts +181 -0
  1484. package/extensions/nextcloud-talk/synurex.plugin.json +9 -0
  1485. package/extensions/nostr/CHANGELOG.md +98 -0
  1486. package/extensions/nostr/README.md +136 -0
  1487. package/extensions/nostr/index.ts +68 -0
  1488. package/extensions/nostr/node_modules/.bin/clawdbot +21 -0
  1489. package/extensions/nostr/node_modules/.bin/clawdbot.CMD +12 -0
  1490. package/extensions/nostr/node_modules/.bin/clawdbot.ps1 +41 -0
  1491. package/extensions/nostr/node_modules/.bin/openclaw +21 -0
  1492. package/extensions/nostr/node_modules/.bin/openclaw.CMD +12 -0
  1493. package/extensions/nostr/node_modules/.bin/openclaw.ps1 +41 -0
  1494. package/extensions/nostr/node_modules/.bin/synurex +21 -0
  1495. package/extensions/nostr/node_modules/.bin/synurex.CMD +12 -0
  1496. package/extensions/nostr/node_modules/.bin/synurex.ps1 +41 -0
  1497. package/extensions/nostr/package.json +34 -0
  1498. package/extensions/nostr/src/channel.test.ts +151 -0
  1499. package/extensions/nostr/src/channel.ts +353 -0
  1500. package/extensions/nostr/src/config-schema.ts +90 -0
  1501. package/extensions/nostr/src/metrics.ts +478 -0
  1502. package/extensions/nostr/src/nostr-bus.fuzz.test.ts +533 -0
  1503. package/extensions/nostr/src/nostr-bus.integration.test.ts +448 -0
  1504. package/extensions/nostr/src/nostr-bus.test.ts +199 -0
  1505. package/extensions/nostr/src/nostr-bus.ts +715 -0
  1506. package/extensions/nostr/src/nostr-profile-http.test.ts +378 -0
  1507. package/extensions/nostr/src/nostr-profile-http.ts +546 -0
  1508. package/extensions/nostr/src/nostr-profile-import.test.ts +119 -0
  1509. package/extensions/nostr/src/nostr-profile-import.ts +262 -0
  1510. package/extensions/nostr/src/nostr-profile.fuzz.test.ts +477 -0
  1511. package/extensions/nostr/src/nostr-profile.test.ts +410 -0
  1512. package/extensions/nostr/src/nostr-profile.ts +277 -0
  1513. package/extensions/nostr/src/nostr-state-store.test.ts +131 -0
  1514. package/extensions/nostr/src/nostr-state-store.ts +226 -0
  1515. package/extensions/nostr/src/runtime.ts +14 -0
  1516. package/extensions/nostr/src/seen-tracker.ts +303 -0
  1517. package/extensions/nostr/src/types.test.ts +157 -0
  1518. package/extensions/nostr/src/types.ts +101 -0
  1519. package/extensions/nostr/synurex.plugin.json +9 -0
  1520. package/extensions/nostr/test/setup.ts +5 -0
  1521. package/extensions/open-prose/README.md +25 -0
  1522. package/extensions/open-prose/index.ts +5 -0
  1523. package/extensions/open-prose/node_modules/.bin/clawdbot +21 -0
  1524. package/extensions/open-prose/node_modules/.bin/clawdbot.CMD +12 -0
  1525. package/extensions/open-prose/node_modules/.bin/clawdbot.ps1 +41 -0
  1526. package/extensions/open-prose/node_modules/.bin/openclaw +21 -0
  1527. package/extensions/open-prose/node_modules/.bin/openclaw.CMD +12 -0
  1528. package/extensions/open-prose/node_modules/.bin/openclaw.ps1 +41 -0
  1529. package/extensions/open-prose/node_modules/.bin/synurex +21 -0
  1530. package/extensions/open-prose/node_modules/.bin/synurex.CMD +12 -0
  1531. package/extensions/open-prose/node_modules/.bin/synurex.ps1 +41 -0
  1532. package/extensions/open-prose/package.json +14 -0
  1533. package/extensions/open-prose/skills/prose/LICENSE +21 -0
  1534. package/extensions/open-prose/skills/prose/SKILL.md +323 -0
  1535. package/extensions/open-prose/skills/prose/alt-borges.md +141 -0
  1536. package/extensions/open-prose/skills/prose/alts/arabian-nights.md +358 -0
  1537. package/extensions/open-prose/skills/prose/alts/borges.md +360 -0
  1538. package/extensions/open-prose/skills/prose/alts/folk.md +322 -0
  1539. package/extensions/open-prose/skills/prose/alts/homer.md +346 -0
  1540. package/extensions/open-prose/skills/prose/alts/kafka.md +373 -0
  1541. package/extensions/open-prose/skills/prose/compiler.md +2971 -0
  1542. package/extensions/open-prose/skills/prose/examples/01-hello-world.prose +4 -0
  1543. package/extensions/open-prose/skills/prose/examples/02-research-and-summarize.prose +6 -0
  1544. package/extensions/open-prose/skills/prose/examples/03-code-review.prose +17 -0
  1545. package/extensions/open-prose/skills/prose/examples/04-write-and-refine.prose +14 -0
  1546. package/extensions/open-prose/skills/prose/examples/05-debug-issue.prose +20 -0
  1547. package/extensions/open-prose/skills/prose/examples/06-explain-codebase.prose +17 -0
  1548. package/extensions/open-prose/skills/prose/examples/07-refactor.prose +20 -0
  1549. package/extensions/open-prose/skills/prose/examples/08-blog-post.prose +20 -0
  1550. package/extensions/open-prose/skills/prose/examples/09-research-with-agents.prose +25 -0
  1551. package/extensions/open-prose/skills/prose/examples/10-code-review-agents.prose +32 -0
  1552. package/extensions/open-prose/skills/prose/examples/11-skills-and-imports.prose +27 -0
  1553. package/extensions/open-prose/skills/prose/examples/12-secure-agent-permissions.prose +43 -0
  1554. package/extensions/open-prose/skills/prose/examples/13-variables-and-context.prose +51 -0
  1555. package/extensions/open-prose/skills/prose/examples/14-composition-blocks.prose +48 -0
  1556. package/extensions/open-prose/skills/prose/examples/15-inline-sequences.prose +23 -0
  1557. package/extensions/open-prose/skills/prose/examples/16-parallel-reviews.prose +19 -0
  1558. package/extensions/open-prose/skills/prose/examples/17-parallel-research.prose +19 -0
  1559. package/extensions/open-prose/skills/prose/examples/18-mixed-parallel-sequential.prose +36 -0
  1560. package/extensions/open-prose/skills/prose/examples/19-advanced-parallel.prose +71 -0
  1561. package/extensions/open-prose/skills/prose/examples/20-fixed-loops.prose +20 -0
  1562. package/extensions/open-prose/skills/prose/examples/21-pipeline-operations.prose +35 -0
  1563. package/extensions/open-prose/skills/prose/examples/22-error-handling.prose +51 -0
  1564. package/extensions/open-prose/skills/prose/examples/23-retry-with-backoff.prose +63 -0
  1565. package/extensions/open-prose/skills/prose/examples/24-choice-blocks.prose +86 -0
  1566. package/extensions/open-prose/skills/prose/examples/25-conditionals.prose +114 -0
  1567. package/extensions/open-prose/skills/prose/examples/26-parameterized-blocks.prose +100 -0
  1568. package/extensions/open-prose/skills/prose/examples/27-string-interpolation.prose +105 -0
  1569. package/extensions/open-prose/skills/prose/examples/28-automated-pr-review.prose +37 -0
  1570. package/extensions/open-prose/skills/prose/examples/28-gas-town.prose +1572 -0
  1571. package/extensions/open-prose/skills/prose/examples/29-captains-chair.prose +218 -0
  1572. package/extensions/open-prose/skills/prose/examples/30-captains-chair-simple.prose +42 -0
  1573. package/extensions/open-prose/skills/prose/examples/31-captains-chair-with-memory.prose +145 -0
  1574. package/extensions/open-prose/skills/prose/examples/33-pr-review-autofix.prose +168 -0
  1575. package/extensions/open-prose/skills/prose/examples/34-content-pipeline.prose +204 -0
  1576. package/extensions/open-prose/skills/prose/examples/35-feature-factory.prose +296 -0
  1577. package/extensions/open-prose/skills/prose/examples/36-bug-hunter.prose +237 -0
  1578. package/extensions/open-prose/skills/prose/examples/37-the-forge.prose +1474 -0
  1579. package/extensions/open-prose/skills/prose/examples/38-skill-scan.prose +455 -0
  1580. package/extensions/open-prose/skills/prose/examples/39-architect-by-simulation.prose +277 -0
  1581. package/extensions/open-prose/skills/prose/examples/40-rlm-self-refine.prose +32 -0
  1582. package/extensions/open-prose/skills/prose/examples/41-rlm-divide-conquer.prose +38 -0
  1583. package/extensions/open-prose/skills/prose/examples/42-rlm-filter-recurse.prose +46 -0
  1584. package/extensions/open-prose/skills/prose/examples/43-rlm-pairwise.prose +50 -0
  1585. package/extensions/open-prose/skills/prose/examples/44-run-endpoint-ux-test.prose +261 -0
  1586. package/extensions/open-prose/skills/prose/examples/45-plugin-release.prose +159 -0
  1587. package/extensions/open-prose/skills/prose/examples/45-run-endpoint-ux-test-with-remediation.prose +637 -0
  1588. package/extensions/open-prose/skills/prose/examples/46-run-endpoint-ux-test-fast.prose +148 -0
  1589. package/extensions/open-prose/skills/prose/examples/46-workflow-crystallizer.prose +225 -0
  1590. package/extensions/open-prose/skills/prose/examples/47-language-self-improvement.prose +356 -0
  1591. package/extensions/open-prose/skills/prose/examples/48-habit-miner.prose +445 -0
  1592. package/extensions/open-prose/skills/prose/examples/49-prose-run-retrospective.prose +210 -0
  1593. package/extensions/open-prose/skills/prose/examples/README.md +391 -0
  1594. package/extensions/open-prose/skills/prose/examples/roadmap/README.md +22 -0
  1595. package/extensions/open-prose/skills/prose/examples/roadmap/iterative-refinement.prose +20 -0
  1596. package/extensions/open-prose/skills/prose/examples/roadmap/parallel-review.prose +18 -0
  1597. package/extensions/open-prose/skills/prose/examples/roadmap/simple-pipeline.prose +17 -0
  1598. package/extensions/open-prose/skills/prose/examples/roadmap/syntax/open-prose-syntax.prose +223 -0
  1599. package/extensions/open-prose/skills/prose/guidance/antipatterns.md +951 -0
  1600. package/extensions/open-prose/skills/prose/guidance/patterns.md +700 -0
  1601. package/extensions/open-prose/skills/prose/guidance/system-prompt.md +180 -0
  1602. package/extensions/open-prose/skills/prose/help.md +144 -0
  1603. package/extensions/open-prose/skills/prose/lib/README.md +108 -0
  1604. package/extensions/open-prose/skills/prose/lib/calibrator.prose +215 -0
  1605. package/extensions/open-prose/skills/prose/lib/cost-analyzer.prose +174 -0
  1606. package/extensions/open-prose/skills/prose/lib/error-forensics.prose +250 -0
  1607. package/extensions/open-prose/skills/prose/lib/inspector.prose +196 -0
  1608. package/extensions/open-prose/skills/prose/lib/profiler.prose +460 -0
  1609. package/extensions/open-prose/skills/prose/lib/program-improver.prose +275 -0
  1610. package/extensions/open-prose/skills/prose/lib/project-memory.prose +118 -0
  1611. package/extensions/open-prose/skills/prose/lib/user-memory.prose +93 -0
  1612. package/extensions/open-prose/skills/prose/lib/vm-improver.prose +243 -0
  1613. package/extensions/open-prose/skills/prose/primitives/session.md +593 -0
  1614. package/extensions/open-prose/skills/prose/prose.md +1237 -0
  1615. package/extensions/open-prose/skills/prose/state/filesystem.md +498 -0
  1616. package/extensions/open-prose/skills/prose/state/in-context.md +384 -0
  1617. package/extensions/open-prose/skills/prose/state/postgres.md +880 -0
  1618. package/extensions/open-prose/skills/prose/state/sqlite.md +574 -0
  1619. package/extensions/open-prose/synurex.plugin.json +11 -0
  1620. package/extensions/qwen-portal-auth/README.md +24 -0
  1621. package/extensions/qwen-portal-auth/index.ts +130 -0
  1622. package/extensions/qwen-portal-auth/oauth.ts +190 -0
  1623. package/extensions/qwen-portal-auth/synurex.plugin.json +9 -0
  1624. package/extensions/signal/index.ts +17 -0
  1625. package/extensions/signal/node_modules/.bin/clawdbot +21 -0
  1626. package/extensions/signal/node_modules/.bin/clawdbot.CMD +12 -0
  1627. package/extensions/signal/node_modules/.bin/clawdbot.ps1 +41 -0
  1628. package/extensions/signal/node_modules/.bin/openclaw +21 -0
  1629. package/extensions/signal/node_modules/.bin/openclaw.CMD +12 -0
  1630. package/extensions/signal/node_modules/.bin/openclaw.ps1 +41 -0
  1631. package/extensions/signal/node_modules/.bin/synurex +21 -0
  1632. package/extensions/signal/node_modules/.bin/synurex.CMD +12 -0
  1633. package/extensions/signal/node_modules/.bin/synurex.ps1 +41 -0
  1634. package/extensions/signal/package.json +14 -0
  1635. package/extensions/signal/src/channel.ts +315 -0
  1636. package/extensions/signal/src/runtime.ts +14 -0
  1637. package/extensions/signal/synurex.plugin.json +9 -0
  1638. package/extensions/slack/index.ts +17 -0
  1639. package/extensions/slack/node_modules/.bin/clawdbot +21 -0
  1640. package/extensions/slack/node_modules/.bin/clawdbot.CMD +12 -0
  1641. package/extensions/slack/node_modules/.bin/clawdbot.ps1 +41 -0
  1642. package/extensions/slack/node_modules/.bin/openclaw +21 -0
  1643. package/extensions/slack/node_modules/.bin/openclaw.CMD +12 -0
  1644. package/extensions/slack/node_modules/.bin/openclaw.ps1 +41 -0
  1645. package/extensions/slack/node_modules/.bin/synurex +21 -0
  1646. package/extensions/slack/node_modules/.bin/synurex.CMD +12 -0
  1647. package/extensions/slack/node_modules/.bin/synurex.ps1 +41 -0
  1648. package/extensions/slack/package.json +14 -0
  1649. package/extensions/slack/src/channel.ts +604 -0
  1650. package/extensions/slack/src/runtime.ts +14 -0
  1651. package/extensions/slack/synurex.plugin.json +9 -0
  1652. package/extensions/telegram/index.ts +17 -0
  1653. package/extensions/telegram/node_modules/.bin/clawdbot +21 -0
  1654. package/extensions/telegram/node_modules/.bin/clawdbot.CMD +12 -0
  1655. package/extensions/telegram/node_modules/.bin/clawdbot.ps1 +41 -0
  1656. package/extensions/telegram/node_modules/.bin/openclaw +21 -0
  1657. package/extensions/telegram/node_modules/.bin/openclaw.CMD +12 -0
  1658. package/extensions/telegram/node_modules/.bin/openclaw.ps1 +41 -0
  1659. package/extensions/telegram/node_modules/.bin/synurex +21 -0
  1660. package/extensions/telegram/node_modules/.bin/synurex.CMD +12 -0
  1661. package/extensions/telegram/node_modules/.bin/synurex.ps1 +41 -0
  1662. package/extensions/telegram/package.json +14 -0
  1663. package/extensions/telegram/src/channel.ts +482 -0
  1664. package/extensions/telegram/src/runtime.ts +14 -0
  1665. package/extensions/telegram/synurex.plugin.json +9 -0
  1666. package/extensions/tlon/README.md +5 -0
  1667. package/extensions/tlon/index.ts +17 -0
  1668. package/extensions/tlon/node_modules/.bin/clawdbot +21 -0
  1669. package/extensions/tlon/node_modules/.bin/clawdbot.CMD +12 -0
  1670. package/extensions/tlon/node_modules/.bin/clawdbot.ps1 +41 -0
  1671. package/extensions/tlon/node_modules/.bin/openclaw +21 -0
  1672. package/extensions/tlon/node_modules/.bin/openclaw.CMD +12 -0
  1673. package/extensions/tlon/node_modules/.bin/openclaw.ps1 +41 -0
  1674. package/extensions/tlon/node_modules/.bin/synurex +21 -0
  1675. package/extensions/tlon/node_modules/.bin/synurex.CMD +12 -0
  1676. package/extensions/tlon/node_modules/.bin/synurex.ps1 +41 -0
  1677. package/extensions/tlon/package.json +33 -0
  1678. package/extensions/tlon/src/channel.ts +392 -0
  1679. package/extensions/tlon/src/config-schema.test.ts +31 -0
  1680. package/extensions/tlon/src/config-schema.ts +45 -0
  1681. package/extensions/tlon/src/monitor/discovery.ts +76 -0
  1682. package/extensions/tlon/src/monitor/history.ts +90 -0
  1683. package/extensions/tlon/src/monitor/index.ts +580 -0
  1684. package/extensions/tlon/src/monitor/processed-messages.test.ts +23 -0
  1685. package/extensions/tlon/src/monitor/processed-messages.ts +46 -0
  1686. package/extensions/tlon/src/monitor/utils.ts +106 -0
  1687. package/extensions/tlon/src/onboarding.ts +214 -0
  1688. package/extensions/tlon/src/runtime.ts +14 -0
  1689. package/extensions/tlon/src/targets.ts +89 -0
  1690. package/extensions/tlon/src/types.ts +92 -0
  1691. package/extensions/tlon/src/urbit/auth.ts +18 -0
  1692. package/extensions/tlon/src/urbit/http-api.ts +38 -0
  1693. package/extensions/tlon/src/urbit/send.test.ts +38 -0
  1694. package/extensions/tlon/src/urbit/send.ts +131 -0
  1695. package/extensions/tlon/src/urbit/sse-client.test.ts +40 -0
  1696. package/extensions/tlon/src/urbit/sse-client.ts +395 -0
  1697. package/extensions/tlon/synurex.plugin.json +9 -0
  1698. package/extensions/twitch/CHANGELOG.md +69 -0
  1699. package/extensions/twitch/README.md +89 -0
  1700. package/extensions/twitch/index.ts +20 -0
  1701. package/extensions/twitch/node_modules/.bin/clawdbot +21 -0
  1702. package/extensions/twitch/node_modules/.bin/clawdbot.CMD +12 -0
  1703. package/extensions/twitch/node_modules/.bin/clawdbot.ps1 +41 -0
  1704. package/extensions/twitch/node_modules/.bin/openclaw +21 -0
  1705. package/extensions/twitch/node_modules/.bin/openclaw.CMD +12 -0
  1706. package/extensions/twitch/node_modules/.bin/openclaw.ps1 +41 -0
  1707. package/extensions/twitch/node_modules/.bin/synurex +21 -0
  1708. package/extensions/twitch/node_modules/.bin/synurex.CMD +12 -0
  1709. package/extensions/twitch/node_modules/.bin/synurex.ps1 +41 -0
  1710. package/extensions/twitch/package.json +20 -0
  1711. package/extensions/twitch/src/access-control.test.ts +489 -0
  1712. package/extensions/twitch/src/access-control.ts +166 -0
  1713. package/extensions/twitch/src/actions.ts +173 -0
  1714. package/extensions/twitch/src/client-manager-registry.ts +115 -0
  1715. package/extensions/twitch/src/config-schema.ts +84 -0
  1716. package/extensions/twitch/src/config.test.ts +87 -0
  1717. package/extensions/twitch/src/config.ts +116 -0
  1718. package/extensions/twitch/src/monitor.ts +272 -0
  1719. package/extensions/twitch/src/onboarding.test.ts +311 -0
  1720. package/extensions/twitch/src/onboarding.ts +417 -0
  1721. package/extensions/twitch/src/outbound.test.ts +373 -0
  1722. package/extensions/twitch/src/outbound.ts +184 -0
  1723. package/extensions/twitch/src/plugin.test.ts +39 -0
  1724. package/extensions/twitch/src/plugin.ts +274 -0
  1725. package/extensions/twitch/src/probe.test.ts +195 -0
  1726. package/extensions/twitch/src/probe.ts +120 -0
  1727. package/extensions/twitch/src/resolver.ts +137 -0
  1728. package/extensions/twitch/src/runtime.ts +14 -0
  1729. package/extensions/twitch/src/send.test.ts +289 -0
  1730. package/extensions/twitch/src/send.ts +136 -0
  1731. package/extensions/twitch/src/status.test.ts +270 -0
  1732. package/extensions/twitch/src/status.ts +178 -0
  1733. package/extensions/twitch/src/token.test.ts +171 -0
  1734. package/extensions/twitch/src/token.ts +91 -0
  1735. package/extensions/twitch/src/twitch-client.test.ts +589 -0
  1736. package/extensions/twitch/src/twitch-client.ts +277 -0
  1737. package/extensions/twitch/src/types.ts +143 -0
  1738. package/extensions/twitch/src/utils/markdown.ts +98 -0
  1739. package/extensions/twitch/src/utils/twitch.ts +78 -0
  1740. package/extensions/twitch/synurex.plugin.json +9 -0
  1741. package/extensions/twitch/test/setup.ts +7 -0
  1742. package/extensions/voice-call/CHANGELOG.md +133 -0
  1743. package/extensions/voice-call/README.md +139 -0
  1744. package/extensions/voice-call/index.ts +493 -0
  1745. package/extensions/voice-call/node_modules/.bin/clawdbot +21 -0
  1746. package/extensions/voice-call/node_modules/.bin/clawdbot.CMD +12 -0
  1747. package/extensions/voice-call/node_modules/.bin/clawdbot.ps1 +41 -0
  1748. package/extensions/voice-call/node_modules/.bin/openclaw +21 -0
  1749. package/extensions/voice-call/node_modules/.bin/openclaw.CMD +12 -0
  1750. package/extensions/voice-call/node_modules/.bin/openclaw.ps1 +41 -0
  1751. package/extensions/voice-call/node_modules/.bin/synurex +21 -0
  1752. package/extensions/voice-call/node_modules/.bin/synurex.CMD +12 -0
  1753. package/extensions/voice-call/node_modules/.bin/synurex.ps1 +41 -0
  1754. package/extensions/voice-call/package.json +19 -0
  1755. package/extensions/voice-call/src/allowlist.ts +19 -0
  1756. package/extensions/voice-call/src/cli.ts +279 -0
  1757. package/extensions/voice-call/src/config.test.ts +234 -0
  1758. package/extensions/voice-call/src/config.ts +523 -0
  1759. package/extensions/voice-call/src/core-bridge.ts +159 -0
  1760. package/extensions/voice-call/src/manager/context.ts +21 -0
  1761. package/extensions/voice-call/src/manager/events.ts +188 -0
  1762. package/extensions/voice-call/src/manager/lookup.ts +35 -0
  1763. package/extensions/voice-call/src/manager/outbound.ts +275 -0
  1764. package/extensions/voice-call/src/manager/state.ts +48 -0
  1765. package/extensions/voice-call/src/manager/store.ts +91 -0
  1766. package/extensions/voice-call/src/manager/timers.ts +89 -0
  1767. package/extensions/voice-call/src/manager/twiml.ts +9 -0
  1768. package/extensions/voice-call/src/manager.test.ts +224 -0
  1769. package/extensions/voice-call/src/manager.ts +887 -0
  1770. package/extensions/voice-call/src/media-stream.test.ts +96 -0
  1771. package/extensions/voice-call/src/media-stream.ts +411 -0
  1772. package/extensions/voice-call/src/providers/base.ts +67 -0
  1773. package/extensions/voice-call/src/providers/index.ts +10 -0
  1774. package/extensions/voice-call/src/providers/mock.ts +165 -0
  1775. package/extensions/voice-call/src/providers/plivo.test.ts +27 -0
  1776. package/extensions/voice-call/src/providers/plivo.ts +515 -0
  1777. package/extensions/voice-call/src/providers/stt-openai-realtime.ts +311 -0
  1778. package/extensions/voice-call/src/providers/telnyx.ts +371 -0
  1779. package/extensions/voice-call/src/providers/tts-openai.ts +259 -0
  1780. package/extensions/voice-call/src/providers/twilio/api.ts +42 -0
  1781. package/extensions/voice-call/src/providers/twilio/webhook.ts +32 -0
  1782. package/extensions/voice-call/src/providers/twilio.test.ts +60 -0
  1783. package/extensions/voice-call/src/providers/twilio.ts +626 -0
  1784. package/extensions/voice-call/src/response-generator.ts +158 -0
  1785. package/extensions/voice-call/src/runtime.ts +212 -0
  1786. package/extensions/voice-call/src/telephony-audio.ts +90 -0
  1787. package/extensions/voice-call/src/telephony-tts.ts +104 -0
  1788. package/extensions/voice-call/src/tunnel.ts +314 -0
  1789. package/extensions/voice-call/src/types.ts +272 -0
  1790. package/extensions/voice-call/src/utils.ts +14 -0
  1791. package/extensions/voice-call/src/voice-mapping.ts +67 -0
  1792. package/extensions/voice-call/src/webhook-security.test.ts +377 -0
  1793. package/extensions/voice-call/src/webhook-security.ts +689 -0
  1794. package/extensions/voice-call/src/webhook.ts +516 -0
  1795. package/extensions/voice-call/synurex.plugin.json +559 -0
  1796. package/extensions/whatsapp/index.ts +17 -0
  1797. package/extensions/whatsapp/node_modules/.bin/clawdbot +21 -0
  1798. package/extensions/whatsapp/node_modules/.bin/clawdbot.CMD +12 -0
  1799. package/extensions/whatsapp/node_modules/.bin/clawdbot.ps1 +41 -0
  1800. package/extensions/whatsapp/node_modules/.bin/openclaw +21 -0
  1801. package/extensions/whatsapp/node_modules/.bin/openclaw.CMD +12 -0
  1802. package/extensions/whatsapp/node_modules/.bin/openclaw.ps1 +41 -0
  1803. package/extensions/whatsapp/node_modules/.bin/synurex +21 -0
  1804. package/extensions/whatsapp/node_modules/.bin/synurex.CMD +12 -0
  1805. package/extensions/whatsapp/node_modules/.bin/synurex.ps1 +41 -0
  1806. package/extensions/whatsapp/package.json +14 -0
  1807. package/extensions/whatsapp/src/channel.ts +508 -0
  1808. package/extensions/whatsapp/src/runtime.ts +14 -0
  1809. package/extensions/whatsapp/synurex.plugin.json +9 -0
  1810. package/extensions/zalo/CHANGELOG.md +113 -0
  1811. package/extensions/zalo/README.md +50 -0
  1812. package/extensions/zalo/index.ts +19 -0
  1813. package/extensions/zalo/node_modules/.bin/clawdbot +21 -0
  1814. package/extensions/zalo/node_modules/.bin/clawdbot.CMD +12 -0
  1815. package/extensions/zalo/node_modules/.bin/clawdbot.ps1 +41 -0
  1816. package/extensions/zalo/node_modules/.bin/openclaw +21 -0
  1817. package/extensions/zalo/node_modules/.bin/openclaw.CMD +12 -0
  1818. package/extensions/zalo/node_modules/.bin/openclaw.ps1 +41 -0
  1819. package/extensions/zalo/node_modules/.bin/synurex +21 -0
  1820. package/extensions/zalo/node_modules/.bin/synurex.CMD +12 -0
  1821. package/extensions/zalo/node_modules/.bin/synurex.ps1 +41 -0
  1822. package/extensions/zalo/package.json +36 -0
  1823. package/extensions/zalo/src/accounts.ts +80 -0
  1824. package/extensions/zalo/src/actions.ts +67 -0
  1825. package/extensions/zalo/src/api.ts +208 -0
  1826. package/extensions/zalo/src/channel.directory.test.ts +43 -0
  1827. package/extensions/zalo/src/channel.ts +414 -0
  1828. package/extensions/zalo/src/config-schema.ts +25 -0
  1829. package/extensions/zalo/src/monitor.ts +764 -0
  1830. package/extensions/zalo/src/monitor.webhook.test.ts +73 -0
  1831. package/extensions/zalo/src/onboarding.ts +401 -0
  1832. package/extensions/zalo/src/probe.ts +46 -0
  1833. package/extensions/zalo/src/proxy.ts +21 -0
  1834. package/extensions/zalo/src/runtime.ts +14 -0
  1835. package/extensions/zalo/src/send.ts +124 -0
  1836. package/extensions/zalo/src/status-issues.ts +53 -0
  1837. package/extensions/zalo/src/token.ts +63 -0
  1838. package/extensions/zalo/src/types.ts +44 -0
  1839. package/extensions/zalo/synurex.plugin.json +9 -0
  1840. package/extensions/zalouser/CHANGELOG.md +85 -0
  1841. package/extensions/zalouser/README.md +225 -0
  1842. package/extensions/zalouser/index.ts +31 -0
  1843. package/extensions/zalouser/node_modules/.bin/clawdbot +21 -0
  1844. package/extensions/zalouser/node_modules/.bin/clawdbot.CMD +12 -0
  1845. package/extensions/zalouser/node_modules/.bin/clawdbot.ps1 +41 -0
  1846. package/extensions/zalouser/node_modules/.bin/openclaw +21 -0
  1847. package/extensions/zalouser/node_modules/.bin/openclaw.CMD +12 -0
  1848. package/extensions/zalouser/node_modules/.bin/openclaw.ps1 +41 -0
  1849. package/extensions/zalouser/node_modules/.bin/synurex +21 -0
  1850. package/extensions/zalouser/node_modules/.bin/synurex.CMD +12 -0
  1851. package/extensions/zalouser/node_modules/.bin/synurex.ps1 +41 -0
  1852. package/extensions/zalouser/package.json +36 -0
  1853. package/extensions/zalouser/src/accounts.ts +135 -0
  1854. package/extensions/zalouser/src/channel.test.ts +18 -0
  1855. package/extensions/zalouser/src/channel.ts +686 -0
  1856. package/extensions/zalouser/src/config-schema.ts +28 -0
  1857. package/extensions/zalouser/src/monitor.ts +601 -0
  1858. package/extensions/zalouser/src/onboarding.ts +504 -0
  1859. package/extensions/zalouser/src/probe.ts +28 -0
  1860. package/extensions/zalouser/src/runtime.ts +14 -0
  1861. package/extensions/zalouser/src/send.ts +160 -0
  1862. package/extensions/zalouser/src/status-issues.test.ts +57 -0
  1863. package/extensions/zalouser/src/status-issues.ts +89 -0
  1864. package/extensions/zalouser/src/tool.ts +164 -0
  1865. package/extensions/zalouser/src/types.ts +110 -0
  1866. package/extensions/zalouser/src/zca.ts +202 -0
  1867. package/extensions/zalouser/synurex.plugin.json +9 -0
  1868. package/package.json +263 -0
  1869. package/skills/1password/SKILL.md +70 -0
  1870. package/skills/1password/references/cli-examples.md +29 -0
  1871. package/skills/1password/references/get-started.md +17 -0
  1872. package/skills/apple-notes/SKILL.md +77 -0
  1873. package/skills/apple-reminders/SKILL.md +96 -0
  1874. package/skills/bear-notes/SKILL.md +107 -0
  1875. package/skills/blogwatcher/SKILL.md +69 -0
  1876. package/skills/blucli/SKILL.md +47 -0
  1877. package/skills/bluebubbles/SKILL.md +131 -0
  1878. package/skills/camsnap/SKILL.md +45 -0
  1879. package/skills/canvas/SKILL.md +198 -0
  1880. package/skills/clawhub/SKILL.md +77 -0
  1881. package/skills/coding-agent/SKILL.md +284 -0
  1882. package/skills/discord/SKILL.md +578 -0
  1883. package/skills/eightctl/SKILL.md +50 -0
  1884. package/skills/food-order/SKILL.md +48 -0
  1885. package/skills/gemini/SKILL.md +43 -0
  1886. package/skills/gifgrep/SKILL.md +79 -0
  1887. package/skills/github/SKILL.md +77 -0
  1888. package/skills/gog/SKILL.md +116 -0
  1889. package/skills/goplaces/SKILL.md +52 -0
  1890. package/skills/healthcheck/SKILL.md +245 -0
  1891. package/skills/himalaya/SKILL.md +257 -0
  1892. package/skills/himalaya/references/configuration.md +184 -0
  1893. package/skills/himalaya/references/message-composition.md +199 -0
  1894. package/skills/imsg/SKILL.md +74 -0
  1895. package/skills/local-places/SERVER_README.md +101 -0
  1896. package/skills/local-places/SKILL.md +102 -0
  1897. package/skills/local-places/pyproject.toml +21 -0
  1898. package/skills/local-places/src/local_places/__init__.py +2 -0
  1899. package/skills/local-places/src/local_places/google_places.py +314 -0
  1900. package/skills/local-places/src/local_places/main.py +65 -0
  1901. package/skills/local-places/src/local_places/schemas.py +107 -0
  1902. package/skills/mcporter/SKILL.md +61 -0
  1903. package/skills/model-usage/SKILL.md +69 -0
  1904. package/skills/model-usage/references/codexbar-cli.md +33 -0
  1905. package/skills/model-usage/scripts/model_usage.py +310 -0
  1906. package/skills/nano-banana-pro/SKILL.md +58 -0
  1907. package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
  1908. package/skills/nano-pdf/SKILL.md +38 -0
  1909. package/skills/notion/SKILL.md +172 -0
  1910. package/skills/obsidian/SKILL.md +81 -0
  1911. package/skills/openai-image-gen/SKILL.md +89 -0
  1912. package/skills/openai-image-gen/scripts/gen.py +240 -0
  1913. package/skills/openai-whisper/SKILL.md +38 -0
  1914. package/skills/openai-whisper-api/SKILL.md +52 -0
  1915. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  1916. package/skills/openhue/SKILL.md +51 -0
  1917. package/skills/oracle/SKILL.md +125 -0
  1918. package/skills/ordercli/SKILL.md +78 -0
  1919. package/skills/peekaboo/SKILL.md +190 -0
  1920. package/skills/sag/SKILL.md +87 -0
  1921. package/skills/session-logs/SKILL.md +115 -0
  1922. package/skills/sherpa-onnx-tts/SKILL.md +103 -0
  1923. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
  1924. package/skills/skill-creator/SKILL.md +370 -0
  1925. package/skills/skill-creator/license.txt +202 -0
  1926. package/skills/skill-creator/scripts/init_skill.py +378 -0
  1927. package/skills/skill-creator/scripts/package_skill.py +111 -0
  1928. package/skills/skill-creator/scripts/quick_validate.py +101 -0
  1929. package/skills/slack/SKILL.md +144 -0
  1930. package/skills/songsee/SKILL.md +49 -0
  1931. package/skills/sonoscli/SKILL.md +46 -0
  1932. package/skills/spotify-player/SKILL.md +64 -0
  1933. package/skills/summarize/SKILL.md +87 -0
  1934. package/skills/things-mac/SKILL.md +86 -0
  1935. package/skills/tmux/SKILL.md +135 -0
  1936. package/skills/tmux/scripts/find-sessions.sh +112 -0
  1937. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  1938. package/skills/trello/SKILL.md +95 -0
  1939. package/skills/video-frames/SKILL.md +46 -0
  1940. package/skills/video-frames/scripts/frame.sh +81 -0
  1941. package/skills/voice-call/SKILL.md +45 -0
  1942. package/skills/wacli/SKILL.md +72 -0
  1943. package/skills/weather/SKILL.md +54 -0
  1944. package/synurex.mjs +33 -0
@@ -0,0 +1,3452 @@
1
+ import { Er as loadModelCatalog, Et as openUrl, jt as resolveNodeManagerOptions, vt as detectBinary } from "./reply-8T1JOF0R.js";
2
+ import { f as resolveConfigDir, h as resolveUserPath, s as ensureDir, t as CONFIG_DIR } from "./utils-C7NsUvD1.js";
3
+ import { t as runCommandWithTimeout } from "./exec-Dloa-d0d.js";
4
+ import { a as resolveAgentModelPrimary, c as resolveDefaultAgentId, r as resolveAgentDir, s as resolveAgentWorkspaceDir, w as resolveDefaultAgentWorkspaceDir } from "./agent-scope-CRRhJ7Hf.js";
5
+ import { Ct as DEFAULT_PROVIDER, D as VENICE_DEFAULT_MODEL_REF, F as getCustomProviderApiKey, St as DEFAULT_MODEL, Z as resolveAuthProfileOrder, _t as resolveSynurexAgentDir, at as generateChutesPkce, ct as listProfilesForProvider, d as resolveConfiguredModelRef, dt as upsertAuthProfile, ft as ensureAuthProfileStore, it as exchangeChutesCodeForTokens, j as SYNTHETIC_DEFAULT_MODEL_REF, o as modelKey, ot as parseOAuthCallbackInput, q as CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, r as buildModelAliasIndex, rt as CHUTES_AUTHORIZE_ENDPOINT, s as normalizeProviderId, t as buildAllowedModelSet, u as resolveAllowlistModelKey, z as resolveEnvApiKey } from "./model-selection-CjYymzT8.js";
6
+ import { t as formatCliCommand } from "./command-format-CEnDvS9q.js";
7
+ import { _ as resolveSkillKey, d as hasBinary, i as loadWorkspaceSkillEntries, t as resolveSkillsInstallPreferences } from "./skills-CrYcs9jK.js";
8
+ import { Y as fetchWithSsrFGuard } from "./deliver-B0C5m0kU.js";
9
+ import { t as resolveBrewExecutable } from "./brew-CAcErcKz.js";
10
+ import { $ as setOpenrouterApiKey, A as applyQianfanProviderConfig, B as applyXiaomiProviderConfig, C as applyMoonshotConfig, D as applyOpenrouterConfig, E as applyMoonshotProviderConfigCn, F as applyVercelAiGatewayConfig, G as ZAI_DEFAULT_MODEL_REF, H as OPENROUTER_DEFAULT_MODEL_REF, I as applyVercelAiGatewayProviderConfig, J as setGeminiApiKey, K as setAnthropicApiKey, L as applyXaiConfig, M as applySyntheticProviderConfig, N as applyVeniceConfig, O as applyOpenrouterProviderConfig, P as applyVeniceProviderConfig, Q as setOpencodeZenApiKey, R as applyXaiProviderConfig, S as applyKimiCodeProviderConfig, T as applyMoonshotProviderConfig, U as VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, V as applyZaiConfig, W as XIAOMI_DEFAULT_MODEL_REF, X as setMinimaxApiKey, Y as setKimiCodingApiKey, Z as setMoonshotApiKey, _ as applyMinimaxProviderConfig, at as setXiaomiApiKey, b as applyCloudflareAiGatewayProviderConfig, ct as KIMI_CODING_MODEL_REF, d as resolvePluginProviders, dt as XAI_DEFAULT_MODEL_REF, et as setQianfanApiKey, f as applyOpencodeZenConfig, ft as buildTokenProfileId, g as applyMinimaxConfig, h as applyMinimaxApiProviderConfig, i as formatTokenK, it as setXaiApiKey, j as applySyntheticConfig, k as applyQianfanConfig, l as createVpsAwareOAuthHandlers, lt as MOONSHOT_DEFAULT_MODEL_REF, m as applyMinimaxApiConfig, nt as setVeniceApiKey, ot as setZaiApiKey, p as applyOpencodeZenProviderConfig, pt as validateAnthropicSetupToken, q as setCloudflareAiGatewayConfig, rt as setVercelAiGatewayApiKey, st as writeOAuthCredentials, t as githubCopilotLoginCommand, tt as setSyntheticApiKey, u as isRemoteEnvironment, ut as QIANFAN_DEFAULT_MODEL_REF, v as applyAuthProfileConfig, w as applyMoonshotConfigCn, x as applyKimiCodeConfig, y as applyCloudflareAiGatewayConfig, z as applyXiaomiConfig } from "./github-copilot-auth-Bog6I9WM.js";
11
+ import { a as enablePluginInConfig } from "./onboard-channels-CyYMvXjh.js";
12
+ import { t as scanDirectoryWithSummary } from "./skill-scanner-BoGjHXUZ.js";
13
+ import { t as buildWorkspaceSkillStatus } from "./skills-status-Bhe2beiQ.js";
14
+ import { n as resolveWideAreaDiscoveryDomain } from "./widearea-dns-C2mRm6hu.js";
15
+ import path from "node:path";
16
+ import fs from "node:fs";
17
+ import { randomBytes } from "node:crypto";
18
+ import { loginOpenAICodex } from "@mariozechner/pi-ai";
19
+ import { createServer } from "node:http";
20
+ import { pipeline } from "node:stream/promises";
21
+ import { Readable } from "node:stream";
22
+
23
+ //#region src/commands/auth-choice-options.ts
24
+ const AUTH_CHOICE_GROUP_DEFS = [
25
+ {
26
+ value: "openai",
27
+ label: "OpenAI",
28
+ hint: "Codex OAuth + API key",
29
+ choices: ["openai-codex", "openai-api-key"]
30
+ },
31
+ {
32
+ value: "anthropic",
33
+ label: "Anthropic",
34
+ hint: "setup-token + API key",
35
+ choices: ["token", "apiKey"]
36
+ },
37
+ {
38
+ value: "minimax",
39
+ label: "MiniMax",
40
+ hint: "M2.1 (recommended)",
41
+ choices: [
42
+ "minimax-portal",
43
+ "minimax-api",
44
+ "minimax-api-lightning"
45
+ ]
46
+ },
47
+ {
48
+ value: "moonshot",
49
+ label: "Moonshot AI (Kimi K2.5)",
50
+ hint: "Kimi K2.5 + Kimi Coding",
51
+ choices: [
52
+ "moonshot-api-key",
53
+ "moonshot-api-key-cn",
54
+ "kimi-code-api-key"
55
+ ]
56
+ },
57
+ {
58
+ value: "google",
59
+ label: "Google",
60
+ hint: "Gemini API key + OAuth",
61
+ choices: [
62
+ "gemini-api-key",
63
+ "google-antigravity",
64
+ "google-gemini-cli"
65
+ ]
66
+ },
67
+ {
68
+ value: "xai",
69
+ label: "xAI (Grok)",
70
+ hint: "API key",
71
+ choices: ["xai-api-key"]
72
+ },
73
+ {
74
+ value: "openrouter",
75
+ label: "OpenRouter",
76
+ hint: "API key",
77
+ choices: ["openrouter-api-key"]
78
+ },
79
+ {
80
+ value: "qwen",
81
+ label: "Qwen",
82
+ hint: "OAuth",
83
+ choices: ["qwen-portal"]
84
+ },
85
+ {
86
+ value: "zai",
87
+ label: "Z.AI (GLM 4.7)",
88
+ hint: "API key",
89
+ choices: ["zai-api-key"]
90
+ },
91
+ {
92
+ value: "qianfan",
93
+ label: "Qianfan",
94
+ hint: "API key",
95
+ choices: ["qianfan-api-key"]
96
+ },
97
+ {
98
+ value: "copilot",
99
+ label: "Copilot",
100
+ hint: "GitHub + local proxy",
101
+ choices: ["github-copilot", "copilot-proxy"]
102
+ },
103
+ {
104
+ value: "ai-gateway",
105
+ label: "Vercel AI Gateway",
106
+ hint: "API key",
107
+ choices: ["ai-gateway-api-key"]
108
+ },
109
+ {
110
+ value: "opencode-zen",
111
+ label: "OpenCode Zen",
112
+ hint: "API key",
113
+ choices: ["opencode-zen"]
114
+ },
115
+ {
116
+ value: "xiaomi",
117
+ label: "Xiaomi",
118
+ hint: "API key",
119
+ choices: ["xiaomi-api-key"]
120
+ },
121
+ {
122
+ value: "synthetic",
123
+ label: "Synthetic",
124
+ hint: "Anthropic-compatible (multi-model)",
125
+ choices: ["synthetic-api-key"]
126
+ },
127
+ {
128
+ value: "venice",
129
+ label: "Venice AI",
130
+ hint: "Privacy-focused (uncensored models)",
131
+ choices: ["venice-api-key"]
132
+ },
133
+ {
134
+ value: "cloudflare-ai-gateway",
135
+ label: "Cloudflare AI Gateway",
136
+ hint: "Account ID + Gateway ID + API key",
137
+ choices: ["cloudflare-ai-gateway-api-key"]
138
+ }
139
+ ];
140
+ function buildAuthChoiceOptions(params) {
141
+ params.store;
142
+ const options = [];
143
+ options.push({
144
+ value: "token",
145
+ label: "Anthropic token (paste setup-token)",
146
+ hint: "run `claude setup-token` elsewhere, then paste the token here"
147
+ });
148
+ options.push({
149
+ value: "openai-codex",
150
+ label: "OpenAI Codex (ChatGPT OAuth)"
151
+ });
152
+ options.push({
153
+ value: "chutes",
154
+ label: "Chutes (OAuth)"
155
+ });
156
+ options.push({
157
+ value: "openai-api-key",
158
+ label: "OpenAI API key"
159
+ });
160
+ options.push({
161
+ value: "xai-api-key",
162
+ label: "xAI (Grok) API key"
163
+ });
164
+ options.push({
165
+ value: "qianfan-api-key",
166
+ label: "Qianfan API key"
167
+ });
168
+ options.push({
169
+ value: "openrouter-api-key",
170
+ label: "OpenRouter API key"
171
+ });
172
+ options.push({
173
+ value: "ai-gateway-api-key",
174
+ label: "Vercel AI Gateway API key"
175
+ });
176
+ options.push({
177
+ value: "cloudflare-ai-gateway-api-key",
178
+ label: "Cloudflare AI Gateway",
179
+ hint: "Account ID + Gateway ID + API key"
180
+ });
181
+ options.push({
182
+ value: "moonshot-api-key",
183
+ label: "Kimi API key (.ai)"
184
+ });
185
+ options.push({
186
+ value: "moonshot-api-key-cn",
187
+ label: "Kimi API key (.cn)"
188
+ });
189
+ options.push({
190
+ value: "kimi-code-api-key",
191
+ label: "Kimi Code API key (subscription)"
192
+ });
193
+ options.push({
194
+ value: "synthetic-api-key",
195
+ label: "Synthetic API key"
196
+ });
197
+ options.push({
198
+ value: "venice-api-key",
199
+ label: "Venice AI API key",
200
+ hint: "Privacy-focused inference (uncensored models)"
201
+ });
202
+ options.push({
203
+ value: "github-copilot",
204
+ label: "GitHub Copilot (GitHub device login)",
205
+ hint: "Uses GitHub device flow"
206
+ });
207
+ options.push({
208
+ value: "gemini-api-key",
209
+ label: "Google Gemini API key"
210
+ });
211
+ options.push({
212
+ value: "google-antigravity",
213
+ label: "Google Antigravity OAuth",
214
+ hint: "Uses the bundled Antigravity auth plugin"
215
+ });
216
+ options.push({
217
+ value: "google-gemini-cli",
218
+ label: "Google Gemini CLI OAuth",
219
+ hint: "Uses the bundled Gemini CLI auth plugin"
220
+ });
221
+ options.push({
222
+ value: "zai-api-key",
223
+ label: "Z.AI (GLM 4.7) API key"
224
+ });
225
+ options.push({
226
+ value: "xiaomi-api-key",
227
+ label: "Xiaomi API key"
228
+ });
229
+ options.push({
230
+ value: "minimax-portal",
231
+ label: "MiniMax OAuth",
232
+ hint: "Oauth plugin for MiniMax"
233
+ });
234
+ options.push({
235
+ value: "qwen-portal",
236
+ label: "Qwen OAuth"
237
+ });
238
+ options.push({
239
+ value: "copilot-proxy",
240
+ label: "Copilot Proxy (local)",
241
+ hint: "Local proxy for VS Code Copilot models"
242
+ });
243
+ options.push({
244
+ value: "apiKey",
245
+ label: "Anthropic API key"
246
+ });
247
+ options.push({
248
+ value: "opencode-zen",
249
+ label: "OpenCode Zen (multi-model proxy)",
250
+ hint: "Claude, GPT, Gemini via opencode.ai/zen"
251
+ });
252
+ options.push({
253
+ value: "minimax-api",
254
+ label: "MiniMax M2.1"
255
+ });
256
+ options.push({
257
+ value: "minimax-api-lightning",
258
+ label: "MiniMax M2.1 Lightning",
259
+ hint: "Faster, higher output cost"
260
+ });
261
+ if (params.includeSkip) options.push({
262
+ value: "skip",
263
+ label: "Skip for now"
264
+ });
265
+ return options;
266
+ }
267
+ function buildAuthChoiceGroups(params) {
268
+ const options = buildAuthChoiceOptions({
269
+ ...params,
270
+ includeSkip: false
271
+ });
272
+ const optionByValue = new Map(options.map((opt) => [opt.value, opt]));
273
+ return {
274
+ groups: AUTH_CHOICE_GROUP_DEFS.map((group) => ({
275
+ ...group,
276
+ options: group.choices.map((choice) => optionByValue.get(choice)).filter((opt) => Boolean(opt))
277
+ })),
278
+ skipOption: params.includeSkip ? {
279
+ value: "skip",
280
+ label: "Skip for now"
281
+ } : void 0
282
+ };
283
+ }
284
+
285
+ //#endregion
286
+ //#region src/commands/auth-choice-prompt.ts
287
+ const BACK_VALUE = "__back";
288
+ async function promptAuthChoiceGrouped(params) {
289
+ const { groups, skipOption } = buildAuthChoiceGroups(params);
290
+ const availableGroups = groups.filter((group) => group.options.length > 0);
291
+ while (true) {
292
+ const providerOptions = [...availableGroups.map((group) => ({
293
+ value: group.value,
294
+ label: group.label,
295
+ hint: group.hint
296
+ })), ...skipOption ? [skipOption] : []];
297
+ const providerSelection = await params.prompter.select({
298
+ message: "Model/auth provider",
299
+ options: providerOptions
300
+ });
301
+ if (providerSelection === "skip") return "skip";
302
+ const group = availableGroups.find((candidate) => candidate.value === providerSelection);
303
+ if (!group || group.options.length === 0) {
304
+ await params.prompter.note("No auth methods available for that provider.", "Model/auth choice");
305
+ continue;
306
+ }
307
+ const methodSelection = await params.prompter.select({
308
+ message: `${group.label} auth method`,
309
+ options: [...group.options, {
310
+ value: BACK_VALUE,
311
+ label: "Back"
312
+ }]
313
+ });
314
+ if (methodSelection === BACK_VALUE) continue;
315
+ return methodSelection;
316
+ }
317
+ }
318
+
319
+ //#endregion
320
+ //#region src/commands/auth-choice.api-key.ts
321
+ const DEFAULT_KEY_PREVIEW = {
322
+ head: 4,
323
+ tail: 4
324
+ };
325
+ function normalizeApiKeyInput(raw) {
326
+ const trimmed = String(raw ?? "").trim();
327
+ if (!trimmed) return "";
328
+ const assignmentMatch = trimmed.match(/^(?:export\s+)?[A-Za-z_][A-Za-z0-9_]*\s*=\s*(.+)$/);
329
+ const valuePart = assignmentMatch ? assignmentMatch[1].trim() : trimmed;
330
+ const unquoted = valuePart.length >= 2 && (valuePart.startsWith("\"") && valuePart.endsWith("\"") || valuePart.startsWith("'") && valuePart.endsWith("'") || valuePart.startsWith("`") && valuePart.endsWith("`")) ? valuePart.slice(1, -1) : valuePart;
331
+ return (unquoted.endsWith(";") ? unquoted.slice(0, -1) : unquoted).trim();
332
+ }
333
+ const validateApiKeyInput = (value) => normalizeApiKeyInput(value).length > 0 ? void 0 : "Required";
334
+ function formatApiKeyPreview(raw, opts = {}) {
335
+ const trimmed = raw.trim();
336
+ if (!trimmed) return "…";
337
+ const head = opts.head ?? DEFAULT_KEY_PREVIEW.head;
338
+ const tail = opts.tail ?? DEFAULT_KEY_PREVIEW.tail;
339
+ if (trimmed.length <= head + tail) {
340
+ const shortHead = Math.min(2, trimmed.length);
341
+ const shortTail = Math.min(2, trimmed.length - shortHead);
342
+ if (shortTail <= 0) return `${trimmed.slice(0, shortHead)}…`;
343
+ return `${trimmed.slice(0, shortHead)}…${trimmed.slice(-shortTail)}`;
344
+ }
345
+ return `${trimmed.slice(0, head)}…${trimmed.slice(-tail)}`;
346
+ }
347
+
348
+ //#endregion
349
+ //#region src/commands/auth-choice.apply.anthropic.ts
350
+ async function applyAuthChoiceAnthropic(params) {
351
+ if (params.authChoice === "setup-token" || params.authChoice === "oauth" || params.authChoice === "token") {
352
+ let nextConfig = params.config;
353
+ await params.prompter.note(["Run `claude setup-token` in your terminal.", "Then paste the generated token below."].join("\n"), "Anthropic setup-token");
354
+ const tokenRaw = await params.prompter.text({
355
+ message: "Paste Anthropic setup-token",
356
+ validate: (value) => validateAnthropicSetupToken(String(value ?? ""))
357
+ });
358
+ const token = String(tokenRaw).trim();
359
+ const profileNameRaw = await params.prompter.text({
360
+ message: "Token name (blank = default)",
361
+ placeholder: "default"
362
+ });
363
+ const provider = "anthropic";
364
+ const namedProfileId = buildTokenProfileId({
365
+ provider,
366
+ name: String(profileNameRaw ?? "")
367
+ });
368
+ upsertAuthProfile({
369
+ profileId: namedProfileId,
370
+ agentDir: params.agentDir,
371
+ credential: {
372
+ type: "token",
373
+ provider,
374
+ token
375
+ }
376
+ });
377
+ nextConfig = applyAuthProfileConfig(nextConfig, {
378
+ profileId: namedProfileId,
379
+ provider,
380
+ mode: "token"
381
+ });
382
+ return { config: nextConfig };
383
+ }
384
+ if (params.authChoice === "apiKey") {
385
+ if (params.opts?.tokenProvider && params.opts.tokenProvider !== "anthropic") return null;
386
+ let nextConfig = params.config;
387
+ let hasCredential = false;
388
+ const envKey = process.env.ANTHROPIC_API_KEY?.trim();
389
+ if (params.opts?.token) {
390
+ await setAnthropicApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
391
+ hasCredential = true;
392
+ }
393
+ if (!hasCredential && envKey) {
394
+ if (await params.prompter.confirm({
395
+ message: `Use existing ANTHROPIC_API_KEY (env, ${formatApiKeyPreview(envKey)})?`,
396
+ initialValue: true
397
+ })) {
398
+ await setAnthropicApiKey(envKey, params.agentDir);
399
+ hasCredential = true;
400
+ }
401
+ }
402
+ if (!hasCredential) {
403
+ const key = await params.prompter.text({
404
+ message: "Enter Anthropic API key",
405
+ validate: validateApiKeyInput
406
+ });
407
+ await setAnthropicApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
408
+ }
409
+ nextConfig = applyAuthProfileConfig(nextConfig, {
410
+ profileId: "anthropic:default",
411
+ provider: "anthropic",
412
+ mode: "api_key"
413
+ });
414
+ return { config: nextConfig };
415
+ }
416
+ return null;
417
+ }
418
+
419
+ //#endregion
420
+ //#region src/commands/model-allowlist.ts
421
+ function ensureModelAllowlistEntry(params) {
422
+ const rawModelRef = params.modelRef.trim();
423
+ if (!rawModelRef) return params.cfg;
424
+ const models = { ...params.cfg.agents?.defaults?.models };
425
+ const keySet = new Set([rawModelRef]);
426
+ const canonicalKey = resolveAllowlistModelKey(rawModelRef, params.defaultProvider ?? DEFAULT_PROVIDER);
427
+ if (canonicalKey) keySet.add(canonicalKey);
428
+ for (const key of keySet) models[key] = { ...models[key] };
429
+ return {
430
+ ...params.cfg,
431
+ agents: {
432
+ ...params.cfg.agents,
433
+ defaults: {
434
+ ...params.cfg.agents?.defaults,
435
+ models
436
+ }
437
+ }
438
+ };
439
+ }
440
+
441
+ //#endregion
442
+ //#region src/commands/auth-choice.default-model.ts
443
+ async function applyDefaultModelChoice(params) {
444
+ if (params.setDefaultModel) {
445
+ const next = params.applyDefaultConfig(params.config);
446
+ if (params.noteDefault) await params.prompter.note(`Default model set to ${params.noteDefault}`, "Model configured");
447
+ return { config: next };
448
+ }
449
+ const nextWithModel = ensureModelAllowlistEntry({
450
+ cfg: params.applyProviderConfig(params.config),
451
+ modelRef: params.defaultModel
452
+ });
453
+ await params.noteAgentModel(params.defaultModel);
454
+ return {
455
+ config: nextWithModel,
456
+ agentModelOverride: params.defaultModel
457
+ };
458
+ }
459
+
460
+ //#endregion
461
+ //#region src/commands/google-gemini-model-default.ts
462
+ const GOOGLE_GEMINI_DEFAULT_MODEL = "google/gemini-3-pro-preview";
463
+ function resolvePrimaryModel$1(model) {
464
+ if (typeof model === "string") return model;
465
+ if (model && typeof model === "object" && typeof model.primary === "string") return model.primary;
466
+ }
467
+ function applyGoogleGeminiModelDefault(cfg) {
468
+ if (resolvePrimaryModel$1(cfg.agents?.defaults?.model)?.trim() === GOOGLE_GEMINI_DEFAULT_MODEL) return {
469
+ next: cfg,
470
+ changed: false
471
+ };
472
+ return {
473
+ next: {
474
+ ...cfg,
475
+ agents: {
476
+ ...cfg.agents,
477
+ defaults: {
478
+ ...cfg.agents?.defaults,
479
+ model: cfg.agents?.defaults?.model && typeof cfg.agents.defaults.model === "object" ? {
480
+ ...cfg.agents.defaults.model,
481
+ primary: GOOGLE_GEMINI_DEFAULT_MODEL
482
+ } : { primary: GOOGLE_GEMINI_DEFAULT_MODEL }
483
+ }
484
+ }
485
+ },
486
+ changed: true
487
+ };
488
+ }
489
+
490
+ //#endregion
491
+ //#region src/commands/opencode-zen-model-default.ts
492
+ const OPENCODE_ZEN_DEFAULT_MODEL = "opencode/claude-opus-4-6";
493
+
494
+ //#endregion
495
+ //#region src/commands/auth-choice.apply.api-providers.ts
496
+ async function applyAuthChoiceApiProviders(params) {
497
+ let nextConfig = params.config;
498
+ let agentModelOverride;
499
+ const noteAgentModel = async (model) => {
500
+ if (!params.agentId) return;
501
+ await params.prompter.note(`Default model set to ${model} for agent "${params.agentId}".`, "Model configured");
502
+ };
503
+ let authChoice = params.authChoice;
504
+ if (authChoice === "apiKey" && params.opts?.tokenProvider && params.opts.tokenProvider !== "anthropic" && params.opts.tokenProvider !== "openai") {
505
+ if (params.opts.tokenProvider === "openrouter") authChoice = "openrouter-api-key";
506
+ else if (params.opts.tokenProvider === "vercel-ai-gateway") authChoice = "ai-gateway-api-key";
507
+ else if (params.opts.tokenProvider === "cloudflare-ai-gateway") authChoice = "cloudflare-ai-gateway-api-key";
508
+ else if (params.opts.tokenProvider === "moonshot") authChoice = "moonshot-api-key";
509
+ else if (params.opts.tokenProvider === "kimi-code" || params.opts.tokenProvider === "kimi-coding") authChoice = "kimi-code-api-key";
510
+ else if (params.opts.tokenProvider === "google") authChoice = "gemini-api-key";
511
+ else if (params.opts.tokenProvider === "zai") authChoice = "zai-api-key";
512
+ else if (params.opts.tokenProvider === "xiaomi") authChoice = "xiaomi-api-key";
513
+ else if (params.opts.tokenProvider === "synthetic") authChoice = "synthetic-api-key";
514
+ else if (params.opts.tokenProvider === "venice") authChoice = "venice-api-key";
515
+ else if (params.opts.tokenProvider === "opencode") authChoice = "opencode-zen";
516
+ else if (params.opts.tokenProvider === "qianfan") authChoice = "qianfan-api-key";
517
+ }
518
+ if (authChoice === "openrouter-api-key") {
519
+ const store = ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false });
520
+ const existingProfileId = resolveAuthProfileOrder({
521
+ cfg: nextConfig,
522
+ store,
523
+ provider: "openrouter"
524
+ }).find((profileId) => Boolean(store.profiles[profileId]));
525
+ const existingCred = existingProfileId ? store.profiles[existingProfileId] : void 0;
526
+ let profileId = "openrouter:default";
527
+ let mode = "api_key";
528
+ let hasCredential = false;
529
+ if (existingProfileId && existingCred?.type) {
530
+ profileId = existingProfileId;
531
+ mode = existingCred.type === "oauth" ? "oauth" : existingCred.type === "token" ? "token" : "api_key";
532
+ hasCredential = true;
533
+ }
534
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "openrouter") {
535
+ await setOpenrouterApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
536
+ hasCredential = true;
537
+ }
538
+ if (!hasCredential) {
539
+ const envKey = resolveEnvApiKey("openrouter");
540
+ if (envKey) {
541
+ if (await params.prompter.confirm({
542
+ message: `Use existing OPENROUTER_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
543
+ initialValue: true
544
+ })) {
545
+ await setOpenrouterApiKey(envKey.apiKey, params.agentDir);
546
+ hasCredential = true;
547
+ }
548
+ }
549
+ }
550
+ if (!hasCredential) {
551
+ const key = await params.prompter.text({
552
+ message: "Enter OpenRouter API key",
553
+ validate: validateApiKeyInput
554
+ });
555
+ await setOpenrouterApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
556
+ hasCredential = true;
557
+ }
558
+ if (hasCredential) nextConfig = applyAuthProfileConfig(nextConfig, {
559
+ profileId,
560
+ provider: "openrouter",
561
+ mode
562
+ });
563
+ {
564
+ const applied = await applyDefaultModelChoice({
565
+ config: nextConfig,
566
+ setDefaultModel: params.setDefaultModel,
567
+ defaultModel: OPENROUTER_DEFAULT_MODEL_REF,
568
+ applyDefaultConfig: applyOpenrouterConfig,
569
+ applyProviderConfig: applyOpenrouterProviderConfig,
570
+ noteDefault: OPENROUTER_DEFAULT_MODEL_REF,
571
+ noteAgentModel,
572
+ prompter: params.prompter
573
+ });
574
+ nextConfig = applied.config;
575
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
576
+ }
577
+ return {
578
+ config: nextConfig,
579
+ agentModelOverride
580
+ };
581
+ }
582
+ if (authChoice === "ai-gateway-api-key") {
583
+ let hasCredential = false;
584
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "vercel-ai-gateway") {
585
+ await setVercelAiGatewayApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
586
+ hasCredential = true;
587
+ }
588
+ const envKey = resolveEnvApiKey("vercel-ai-gateway");
589
+ if (envKey) {
590
+ if (await params.prompter.confirm({
591
+ message: `Use existing AI_GATEWAY_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
592
+ initialValue: true
593
+ })) {
594
+ await setVercelAiGatewayApiKey(envKey.apiKey, params.agentDir);
595
+ hasCredential = true;
596
+ }
597
+ }
598
+ if (!hasCredential) {
599
+ const key = await params.prompter.text({
600
+ message: "Enter Vercel AI Gateway API key",
601
+ validate: validateApiKeyInput
602
+ });
603
+ await setVercelAiGatewayApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
604
+ }
605
+ nextConfig = applyAuthProfileConfig(nextConfig, {
606
+ profileId: "vercel-ai-gateway:default",
607
+ provider: "vercel-ai-gateway",
608
+ mode: "api_key"
609
+ });
610
+ {
611
+ const applied = await applyDefaultModelChoice({
612
+ config: nextConfig,
613
+ setDefaultModel: params.setDefaultModel,
614
+ defaultModel: VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
615
+ applyDefaultConfig: applyVercelAiGatewayConfig,
616
+ applyProviderConfig: applyVercelAiGatewayProviderConfig,
617
+ noteDefault: VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF,
618
+ noteAgentModel,
619
+ prompter: params.prompter
620
+ });
621
+ nextConfig = applied.config;
622
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
623
+ }
624
+ return {
625
+ config: nextConfig,
626
+ agentModelOverride
627
+ };
628
+ }
629
+ if (authChoice === "cloudflare-ai-gateway-api-key") {
630
+ let hasCredential = false;
631
+ let accountId = params.opts?.cloudflareAiGatewayAccountId?.trim() ?? "";
632
+ let gatewayId = params.opts?.cloudflareAiGatewayGatewayId?.trim() ?? "";
633
+ const ensureAccountGateway = async () => {
634
+ if (!accountId) {
635
+ const value = await params.prompter.text({
636
+ message: "Enter Cloudflare Account ID",
637
+ validate: (val) => String(val).trim() ? void 0 : "Account ID is required"
638
+ });
639
+ accountId = String(value).trim();
640
+ }
641
+ if (!gatewayId) {
642
+ const value = await params.prompter.text({
643
+ message: "Enter Cloudflare AI Gateway ID",
644
+ validate: (val) => String(val).trim() ? void 0 : "Gateway ID is required"
645
+ });
646
+ gatewayId = String(value).trim();
647
+ }
648
+ };
649
+ const optsApiKey = normalizeApiKeyInput(params.opts?.cloudflareAiGatewayApiKey ?? "");
650
+ if (!hasCredential && accountId && gatewayId && optsApiKey) {
651
+ await setCloudflareAiGatewayConfig(accountId, gatewayId, optsApiKey, params.agentDir);
652
+ hasCredential = true;
653
+ }
654
+ const envKey = resolveEnvApiKey("cloudflare-ai-gateway");
655
+ if (!hasCredential && envKey) {
656
+ if (await params.prompter.confirm({
657
+ message: `Use existing CLOUDFLARE_AI_GATEWAY_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
658
+ initialValue: true
659
+ })) {
660
+ await ensureAccountGateway();
661
+ await setCloudflareAiGatewayConfig(accountId, gatewayId, normalizeApiKeyInput(envKey.apiKey), params.agentDir);
662
+ hasCredential = true;
663
+ }
664
+ }
665
+ if (!hasCredential && optsApiKey) {
666
+ await ensureAccountGateway();
667
+ await setCloudflareAiGatewayConfig(accountId, gatewayId, optsApiKey, params.agentDir);
668
+ hasCredential = true;
669
+ }
670
+ if (!hasCredential) {
671
+ await ensureAccountGateway();
672
+ const key = await params.prompter.text({
673
+ message: "Enter Cloudflare AI Gateway API key",
674
+ validate: validateApiKeyInput
675
+ });
676
+ await setCloudflareAiGatewayConfig(accountId, gatewayId, normalizeApiKeyInput(String(key)), params.agentDir);
677
+ hasCredential = true;
678
+ }
679
+ if (hasCredential) nextConfig = applyAuthProfileConfig(nextConfig, {
680
+ profileId: "cloudflare-ai-gateway:default",
681
+ provider: "cloudflare-ai-gateway",
682
+ mode: "api_key"
683
+ });
684
+ {
685
+ const applied = await applyDefaultModelChoice({
686
+ config: nextConfig,
687
+ setDefaultModel: params.setDefaultModel,
688
+ defaultModel: CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF,
689
+ applyDefaultConfig: (cfg) => applyCloudflareAiGatewayConfig(cfg, {
690
+ accountId: accountId || params.opts?.cloudflareAiGatewayAccountId,
691
+ gatewayId: gatewayId || params.opts?.cloudflareAiGatewayGatewayId
692
+ }),
693
+ applyProviderConfig: (cfg) => applyCloudflareAiGatewayProviderConfig(cfg, {
694
+ accountId: accountId || params.opts?.cloudflareAiGatewayAccountId,
695
+ gatewayId: gatewayId || params.opts?.cloudflareAiGatewayGatewayId
696
+ }),
697
+ noteDefault: CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF,
698
+ noteAgentModel,
699
+ prompter: params.prompter
700
+ });
701
+ nextConfig = applied.config;
702
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
703
+ }
704
+ return {
705
+ config: nextConfig,
706
+ agentModelOverride
707
+ };
708
+ }
709
+ if (authChoice === "moonshot-api-key") {
710
+ let hasCredential = false;
711
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "moonshot") {
712
+ await setMoonshotApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
713
+ hasCredential = true;
714
+ }
715
+ const envKey = resolveEnvApiKey("moonshot");
716
+ if (envKey) {
717
+ if (await params.prompter.confirm({
718
+ message: `Use existing MOONSHOT_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
719
+ initialValue: true
720
+ })) {
721
+ await setMoonshotApiKey(envKey.apiKey, params.agentDir);
722
+ hasCredential = true;
723
+ }
724
+ }
725
+ if (!hasCredential) {
726
+ const key = await params.prompter.text({
727
+ message: "Enter Moonshot API key",
728
+ validate: validateApiKeyInput
729
+ });
730
+ await setMoonshotApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
731
+ }
732
+ nextConfig = applyAuthProfileConfig(nextConfig, {
733
+ profileId: "moonshot:default",
734
+ provider: "moonshot",
735
+ mode: "api_key"
736
+ });
737
+ {
738
+ const applied = await applyDefaultModelChoice({
739
+ config: nextConfig,
740
+ setDefaultModel: params.setDefaultModel,
741
+ defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
742
+ applyDefaultConfig: applyMoonshotConfig,
743
+ applyProviderConfig: applyMoonshotProviderConfig,
744
+ noteAgentModel,
745
+ prompter: params.prompter
746
+ });
747
+ nextConfig = applied.config;
748
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
749
+ }
750
+ return {
751
+ config: nextConfig,
752
+ agentModelOverride
753
+ };
754
+ }
755
+ if (authChoice === "moonshot-api-key-cn") {
756
+ let hasCredential = false;
757
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "moonshot") {
758
+ await setMoonshotApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
759
+ hasCredential = true;
760
+ }
761
+ const envKey = resolveEnvApiKey("moonshot");
762
+ if (envKey) {
763
+ if (await params.prompter.confirm({
764
+ message: `Use existing MOONSHOT_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
765
+ initialValue: true
766
+ })) {
767
+ await setMoonshotApiKey(envKey.apiKey, params.agentDir);
768
+ hasCredential = true;
769
+ }
770
+ }
771
+ if (!hasCredential) {
772
+ const key = await params.prompter.text({
773
+ message: "Enter Moonshot API key (.cn)",
774
+ validate: validateApiKeyInput
775
+ });
776
+ await setMoonshotApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
777
+ }
778
+ nextConfig = applyAuthProfileConfig(nextConfig, {
779
+ profileId: "moonshot:default",
780
+ provider: "moonshot",
781
+ mode: "api_key"
782
+ });
783
+ {
784
+ const applied = await applyDefaultModelChoice({
785
+ config: nextConfig,
786
+ setDefaultModel: params.setDefaultModel,
787
+ defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
788
+ applyDefaultConfig: applyMoonshotConfigCn,
789
+ applyProviderConfig: applyMoonshotProviderConfigCn,
790
+ noteAgentModel,
791
+ prompter: params.prompter
792
+ });
793
+ nextConfig = applied.config;
794
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
795
+ }
796
+ return {
797
+ config: nextConfig,
798
+ agentModelOverride
799
+ };
800
+ }
801
+ if (authChoice === "kimi-code-api-key") {
802
+ let hasCredential = false;
803
+ const tokenProvider = params.opts?.tokenProvider?.trim().toLowerCase();
804
+ if (!hasCredential && params.opts?.token && (tokenProvider === "kimi-code" || tokenProvider === "kimi-coding")) {
805
+ await setKimiCodingApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
806
+ hasCredential = true;
807
+ }
808
+ if (!hasCredential) await params.prompter.note(["Kimi Coding uses a dedicated endpoint and API key.", "Get your API key at: https://www.kimi.com/code/en"].join("\n"), "Kimi Coding");
809
+ const envKey = resolveEnvApiKey("kimi-coding");
810
+ if (envKey) {
811
+ if (await params.prompter.confirm({
812
+ message: `Use existing KIMI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
813
+ initialValue: true
814
+ })) {
815
+ await setKimiCodingApiKey(envKey.apiKey, params.agentDir);
816
+ hasCredential = true;
817
+ }
818
+ }
819
+ if (!hasCredential) {
820
+ const key = await params.prompter.text({
821
+ message: "Enter Kimi Coding API key",
822
+ validate: validateApiKeyInput
823
+ });
824
+ await setKimiCodingApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
825
+ }
826
+ nextConfig = applyAuthProfileConfig(nextConfig, {
827
+ profileId: "kimi-coding:default",
828
+ provider: "kimi-coding",
829
+ mode: "api_key"
830
+ });
831
+ {
832
+ const applied = await applyDefaultModelChoice({
833
+ config: nextConfig,
834
+ setDefaultModel: params.setDefaultModel,
835
+ defaultModel: KIMI_CODING_MODEL_REF,
836
+ applyDefaultConfig: applyKimiCodeConfig,
837
+ applyProviderConfig: applyKimiCodeProviderConfig,
838
+ noteDefault: KIMI_CODING_MODEL_REF,
839
+ noteAgentModel,
840
+ prompter: params.prompter
841
+ });
842
+ nextConfig = applied.config;
843
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
844
+ }
845
+ return {
846
+ config: nextConfig,
847
+ agentModelOverride
848
+ };
849
+ }
850
+ if (authChoice === "gemini-api-key") {
851
+ let hasCredential = false;
852
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "google") {
853
+ await setGeminiApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
854
+ hasCredential = true;
855
+ }
856
+ const envKey = resolveEnvApiKey("google");
857
+ if (envKey) {
858
+ if (await params.prompter.confirm({
859
+ message: `Use existing GEMINI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
860
+ initialValue: true
861
+ })) {
862
+ await setGeminiApiKey(envKey.apiKey, params.agentDir);
863
+ hasCredential = true;
864
+ }
865
+ }
866
+ if (!hasCredential) {
867
+ const key = await params.prompter.text({
868
+ message: "Enter Gemini API key",
869
+ validate: validateApiKeyInput
870
+ });
871
+ await setGeminiApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
872
+ }
873
+ nextConfig = applyAuthProfileConfig(nextConfig, {
874
+ profileId: "google:default",
875
+ provider: "google",
876
+ mode: "api_key"
877
+ });
878
+ if (params.setDefaultModel) {
879
+ const applied = applyGoogleGeminiModelDefault(nextConfig);
880
+ nextConfig = applied.next;
881
+ if (applied.changed) await params.prompter.note(`Default model set to ${GOOGLE_GEMINI_DEFAULT_MODEL}`, "Model configured");
882
+ } else {
883
+ agentModelOverride = GOOGLE_GEMINI_DEFAULT_MODEL;
884
+ await noteAgentModel(GOOGLE_GEMINI_DEFAULT_MODEL);
885
+ }
886
+ return {
887
+ config: nextConfig,
888
+ agentModelOverride
889
+ };
890
+ }
891
+ if (authChoice === "zai-api-key") {
892
+ let hasCredential = false;
893
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "zai") {
894
+ await setZaiApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
895
+ hasCredential = true;
896
+ }
897
+ const envKey = resolveEnvApiKey("zai");
898
+ if (envKey) {
899
+ if (await params.prompter.confirm({
900
+ message: `Use existing ZAI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
901
+ initialValue: true
902
+ })) {
903
+ await setZaiApiKey(envKey.apiKey, params.agentDir);
904
+ hasCredential = true;
905
+ }
906
+ }
907
+ if (!hasCredential) {
908
+ const key = await params.prompter.text({
909
+ message: "Enter Z.AI API key",
910
+ validate: validateApiKeyInput
911
+ });
912
+ await setZaiApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
913
+ }
914
+ nextConfig = applyAuthProfileConfig(nextConfig, {
915
+ profileId: "zai:default",
916
+ provider: "zai",
917
+ mode: "api_key"
918
+ });
919
+ {
920
+ const applied = await applyDefaultModelChoice({
921
+ config: nextConfig,
922
+ setDefaultModel: params.setDefaultModel,
923
+ defaultModel: ZAI_DEFAULT_MODEL_REF,
924
+ applyDefaultConfig: applyZaiConfig,
925
+ applyProviderConfig: (config) => ({
926
+ ...config,
927
+ agents: {
928
+ ...config.agents,
929
+ defaults: {
930
+ ...config.agents?.defaults,
931
+ models: {
932
+ ...config.agents?.defaults?.models,
933
+ [ZAI_DEFAULT_MODEL_REF]: {
934
+ ...config.agents?.defaults?.models?.[ZAI_DEFAULT_MODEL_REF],
935
+ alias: config.agents?.defaults?.models?.[ZAI_DEFAULT_MODEL_REF]?.alias ?? "GLM"
936
+ }
937
+ }
938
+ }
939
+ }
940
+ }),
941
+ noteDefault: ZAI_DEFAULT_MODEL_REF,
942
+ noteAgentModel,
943
+ prompter: params.prompter
944
+ });
945
+ nextConfig = applied.config;
946
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
947
+ }
948
+ return {
949
+ config: nextConfig,
950
+ agentModelOverride
951
+ };
952
+ }
953
+ if (authChoice === "xiaomi-api-key") {
954
+ let hasCredential = false;
955
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "xiaomi") {
956
+ await setXiaomiApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
957
+ hasCredential = true;
958
+ }
959
+ const envKey = resolveEnvApiKey("xiaomi");
960
+ if (envKey) {
961
+ if (await params.prompter.confirm({
962
+ message: `Use existing XIAOMI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
963
+ initialValue: true
964
+ })) {
965
+ await setXiaomiApiKey(envKey.apiKey, params.agentDir);
966
+ hasCredential = true;
967
+ }
968
+ }
969
+ if (!hasCredential) {
970
+ const key = await params.prompter.text({
971
+ message: "Enter Xiaomi API key",
972
+ validate: validateApiKeyInput
973
+ });
974
+ await setXiaomiApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
975
+ }
976
+ nextConfig = applyAuthProfileConfig(nextConfig, {
977
+ profileId: "xiaomi:default",
978
+ provider: "xiaomi",
979
+ mode: "api_key"
980
+ });
981
+ {
982
+ const applied = await applyDefaultModelChoice({
983
+ config: nextConfig,
984
+ setDefaultModel: params.setDefaultModel,
985
+ defaultModel: XIAOMI_DEFAULT_MODEL_REF,
986
+ applyDefaultConfig: applyXiaomiConfig,
987
+ applyProviderConfig: applyXiaomiProviderConfig,
988
+ noteDefault: XIAOMI_DEFAULT_MODEL_REF,
989
+ noteAgentModel,
990
+ prompter: params.prompter
991
+ });
992
+ nextConfig = applied.config;
993
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
994
+ }
995
+ return {
996
+ config: nextConfig,
997
+ agentModelOverride
998
+ };
999
+ }
1000
+ if (authChoice === "synthetic-api-key") {
1001
+ if (params.opts?.token && params.opts?.tokenProvider === "synthetic") await setSyntheticApiKey(String(params.opts.token).trim(), params.agentDir);
1002
+ else {
1003
+ const key = await params.prompter.text({
1004
+ message: "Enter Synthetic API key",
1005
+ validate: (value) => value?.trim() ? void 0 : "Required"
1006
+ });
1007
+ await setSyntheticApiKey(String(key).trim(), params.agentDir);
1008
+ }
1009
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1010
+ profileId: "synthetic:default",
1011
+ provider: "synthetic",
1012
+ mode: "api_key"
1013
+ });
1014
+ {
1015
+ const applied = await applyDefaultModelChoice({
1016
+ config: nextConfig,
1017
+ setDefaultModel: params.setDefaultModel,
1018
+ defaultModel: SYNTHETIC_DEFAULT_MODEL_REF,
1019
+ applyDefaultConfig: applySyntheticConfig,
1020
+ applyProviderConfig: applySyntheticProviderConfig,
1021
+ noteDefault: SYNTHETIC_DEFAULT_MODEL_REF,
1022
+ noteAgentModel,
1023
+ prompter: params.prompter
1024
+ });
1025
+ nextConfig = applied.config;
1026
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1027
+ }
1028
+ return {
1029
+ config: nextConfig,
1030
+ agentModelOverride
1031
+ };
1032
+ }
1033
+ if (authChoice === "venice-api-key") {
1034
+ let hasCredential = false;
1035
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "venice") {
1036
+ await setVeniceApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
1037
+ hasCredential = true;
1038
+ }
1039
+ if (!hasCredential) await params.prompter.note([
1040
+ "Venice AI provides privacy-focused inference with uncensored models.",
1041
+ "Get your API key at: https://venice.ai/settings/api",
1042
+ "Supports 'private' (fully private) and 'anonymized' (proxy) modes."
1043
+ ].join("\n"), "Venice AI");
1044
+ const envKey = resolveEnvApiKey("venice");
1045
+ if (envKey) {
1046
+ if (await params.prompter.confirm({
1047
+ message: `Use existing VENICE_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
1048
+ initialValue: true
1049
+ })) {
1050
+ await setVeniceApiKey(envKey.apiKey, params.agentDir);
1051
+ hasCredential = true;
1052
+ }
1053
+ }
1054
+ if (!hasCredential) {
1055
+ const key = await params.prompter.text({
1056
+ message: "Enter Venice AI API key",
1057
+ validate: validateApiKeyInput
1058
+ });
1059
+ await setVeniceApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
1060
+ }
1061
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1062
+ profileId: "venice:default",
1063
+ provider: "venice",
1064
+ mode: "api_key"
1065
+ });
1066
+ {
1067
+ const applied = await applyDefaultModelChoice({
1068
+ config: nextConfig,
1069
+ setDefaultModel: params.setDefaultModel,
1070
+ defaultModel: VENICE_DEFAULT_MODEL_REF,
1071
+ applyDefaultConfig: applyVeniceConfig,
1072
+ applyProviderConfig: applyVeniceProviderConfig,
1073
+ noteDefault: VENICE_DEFAULT_MODEL_REF,
1074
+ noteAgentModel,
1075
+ prompter: params.prompter
1076
+ });
1077
+ nextConfig = applied.config;
1078
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1079
+ }
1080
+ return {
1081
+ config: nextConfig,
1082
+ agentModelOverride
1083
+ };
1084
+ }
1085
+ if (authChoice === "opencode-zen") {
1086
+ let hasCredential = false;
1087
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "opencode") {
1088
+ await setOpencodeZenApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
1089
+ hasCredential = true;
1090
+ }
1091
+ if (!hasCredential) await params.prompter.note([
1092
+ "OpenCode Zen provides access to Claude, GPT, Gemini, and more models.",
1093
+ "Get your API key at: https://opencode.ai/auth",
1094
+ "OpenCode Zen bills per request. Check your OpenCode dashboard for details."
1095
+ ].join("\n"), "OpenCode Zen");
1096
+ const envKey = resolveEnvApiKey("opencode");
1097
+ if (envKey) {
1098
+ if (await params.prompter.confirm({
1099
+ message: `Use existing OPENCODE_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
1100
+ initialValue: true
1101
+ })) {
1102
+ await setOpencodeZenApiKey(envKey.apiKey, params.agentDir);
1103
+ hasCredential = true;
1104
+ }
1105
+ }
1106
+ if (!hasCredential) {
1107
+ const key = await params.prompter.text({
1108
+ message: "Enter OpenCode Zen API key",
1109
+ validate: validateApiKeyInput
1110
+ });
1111
+ await setOpencodeZenApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
1112
+ }
1113
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1114
+ profileId: "opencode:default",
1115
+ provider: "opencode",
1116
+ mode: "api_key"
1117
+ });
1118
+ {
1119
+ const applied = await applyDefaultModelChoice({
1120
+ config: nextConfig,
1121
+ setDefaultModel: params.setDefaultModel,
1122
+ defaultModel: OPENCODE_ZEN_DEFAULT_MODEL,
1123
+ applyDefaultConfig: applyOpencodeZenConfig,
1124
+ applyProviderConfig: applyOpencodeZenProviderConfig,
1125
+ noteDefault: OPENCODE_ZEN_DEFAULT_MODEL,
1126
+ noteAgentModel,
1127
+ prompter: params.prompter
1128
+ });
1129
+ nextConfig = applied.config;
1130
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1131
+ }
1132
+ return {
1133
+ config: nextConfig,
1134
+ agentModelOverride
1135
+ };
1136
+ }
1137
+ if (authChoice === "qianfan-api-key") {
1138
+ let hasCredential = false;
1139
+ if (!hasCredential && params.opts?.token && params.opts?.tokenProvider === "qianfan") {
1140
+ setQianfanApiKey(normalizeApiKeyInput(params.opts.token), params.agentDir);
1141
+ hasCredential = true;
1142
+ }
1143
+ if (!hasCredential) await params.prompter.note(["Get your API key at: https://console.bce.baidu.com/qianfan/ais/console/apiKey", "API key format: bce-v3/ALTAK-..."].join("\n"), "QIANFAN");
1144
+ const envKey = resolveEnvApiKey("qianfan");
1145
+ if (envKey) {
1146
+ if (await params.prompter.confirm({
1147
+ message: `Use existing QIANFAN_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
1148
+ initialValue: true
1149
+ })) {
1150
+ setQianfanApiKey(envKey.apiKey, params.agentDir);
1151
+ hasCredential = true;
1152
+ }
1153
+ }
1154
+ if (!hasCredential) {
1155
+ const key = await params.prompter.text({
1156
+ message: "Enter QIANFAN API key",
1157
+ validate: validateApiKeyInput
1158
+ });
1159
+ setQianfanApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
1160
+ }
1161
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1162
+ profileId: "qianfan:default",
1163
+ provider: "qianfan",
1164
+ mode: "api_key"
1165
+ });
1166
+ {
1167
+ const applied = await applyDefaultModelChoice({
1168
+ config: nextConfig,
1169
+ setDefaultModel: params.setDefaultModel,
1170
+ defaultModel: QIANFAN_DEFAULT_MODEL_REF,
1171
+ applyDefaultConfig: applyQianfanConfig,
1172
+ applyProviderConfig: applyQianfanProviderConfig,
1173
+ noteDefault: QIANFAN_DEFAULT_MODEL_REF,
1174
+ noteAgentModel,
1175
+ prompter: params.prompter
1176
+ });
1177
+ nextConfig = applied.config;
1178
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1179
+ }
1180
+ return {
1181
+ config: nextConfig,
1182
+ agentModelOverride
1183
+ };
1184
+ }
1185
+ return null;
1186
+ }
1187
+
1188
+ //#endregion
1189
+ //#region src/commands/auth-choice.apply.plugin-provider.ts
1190
+ function resolveProviderMatch(providers, rawProvider) {
1191
+ const normalized = normalizeProviderId(rawProvider);
1192
+ return providers.find((provider) => normalizeProviderId(provider.id) === normalized) ?? providers.find((provider) => provider.aliases?.some((alias) => normalizeProviderId(alias) === normalized) ?? false) ?? null;
1193
+ }
1194
+ function pickAuthMethod(provider, rawMethod) {
1195
+ const raw = rawMethod?.trim();
1196
+ if (!raw) return null;
1197
+ const normalized = raw.toLowerCase();
1198
+ return provider.auth.find((method) => method.id.toLowerCase() === normalized) ?? provider.auth.find((method) => method.label.toLowerCase() === normalized) ?? null;
1199
+ }
1200
+ function isPlainRecord(value) {
1201
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
1202
+ }
1203
+ function mergeConfigPatch(base, patch) {
1204
+ if (!isPlainRecord(base) || !isPlainRecord(patch)) return patch;
1205
+ const next = { ...base };
1206
+ for (const [key, value] of Object.entries(patch)) {
1207
+ const existing = next[key];
1208
+ if (isPlainRecord(existing) && isPlainRecord(value)) next[key] = mergeConfigPatch(existing, value);
1209
+ else next[key] = value;
1210
+ }
1211
+ return next;
1212
+ }
1213
+ function applyDefaultModel(cfg, model) {
1214
+ const models = { ...cfg.agents?.defaults?.models };
1215
+ models[model] = models[model] ?? {};
1216
+ const existingModel = cfg.agents?.defaults?.model;
1217
+ return {
1218
+ ...cfg,
1219
+ agents: {
1220
+ ...cfg.agents,
1221
+ defaults: {
1222
+ ...cfg.agents?.defaults,
1223
+ models,
1224
+ model: {
1225
+ ...existingModel && typeof existingModel === "object" && "fallbacks" in existingModel ? { fallbacks: existingModel.fallbacks } : void 0,
1226
+ primary: model
1227
+ }
1228
+ }
1229
+ }
1230
+ };
1231
+ }
1232
+ async function applyAuthChoicePluginProvider(params, options) {
1233
+ if (params.authChoice !== options.authChoice) return null;
1234
+ const enableResult = enablePluginInConfig(params.config, options.pluginId);
1235
+ let nextConfig = enableResult.config;
1236
+ if (!enableResult.enabled) {
1237
+ await params.prompter.note(`${options.label} plugin is disabled (${enableResult.reason ?? "blocked"}).`, options.label);
1238
+ return { config: nextConfig };
1239
+ }
1240
+ const agentId = params.agentId ?? resolveDefaultAgentId(nextConfig);
1241
+ const defaultAgentId = resolveDefaultAgentId(nextConfig);
1242
+ const agentDir = params.agentDir ?? (agentId === defaultAgentId ? resolveSynurexAgentDir() : resolveAgentDir(nextConfig, agentId));
1243
+ const workspaceDir = resolveAgentWorkspaceDir(nextConfig, agentId) ?? resolveDefaultAgentWorkspaceDir();
1244
+ const provider = resolveProviderMatch(resolvePluginProviders({
1245
+ config: nextConfig,
1246
+ workspaceDir
1247
+ }), options.providerId);
1248
+ if (!provider) {
1249
+ await params.prompter.note(`${options.label} auth plugin is not available. Enable it and re-run the wizard.`, options.label);
1250
+ return { config: nextConfig };
1251
+ }
1252
+ const method = pickAuthMethod(provider, options.methodId) ?? provider.auth[0];
1253
+ if (!method) {
1254
+ await params.prompter.note(`${options.label} auth method missing.`, options.label);
1255
+ return { config: nextConfig };
1256
+ }
1257
+ const isRemote = isRemoteEnvironment();
1258
+ const result = await method.run({
1259
+ config: nextConfig,
1260
+ agentDir,
1261
+ workspaceDir,
1262
+ prompter: params.prompter,
1263
+ runtime: params.runtime,
1264
+ isRemote,
1265
+ openUrl: async (url) => {
1266
+ await openUrl(url);
1267
+ },
1268
+ oauth: { createVpsAwareHandlers: (opts) => createVpsAwareOAuthHandlers(opts) }
1269
+ });
1270
+ if (result.configPatch) nextConfig = mergeConfigPatch(nextConfig, result.configPatch);
1271
+ for (const profile of result.profiles) {
1272
+ upsertAuthProfile({
1273
+ profileId: profile.profileId,
1274
+ credential: profile.credential,
1275
+ agentDir
1276
+ });
1277
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1278
+ profileId: profile.profileId,
1279
+ provider: profile.credential.provider,
1280
+ mode: profile.credential.type === "token" ? "token" : profile.credential.type,
1281
+ ..."email" in profile.credential && profile.credential.email ? { email: profile.credential.email } : {}
1282
+ });
1283
+ }
1284
+ let agentModelOverride;
1285
+ if (result.defaultModel) {
1286
+ if (params.setDefaultModel) {
1287
+ nextConfig = applyDefaultModel(nextConfig, result.defaultModel);
1288
+ await params.prompter.note(`Default model set to ${result.defaultModel}`, "Model configured");
1289
+ } else if (params.agentId) {
1290
+ agentModelOverride = result.defaultModel;
1291
+ await params.prompter.note(`Default model set to ${result.defaultModel} for agent "${params.agentId}".`, "Model configured");
1292
+ }
1293
+ }
1294
+ if (result.notes && result.notes.length > 0) await params.prompter.note(result.notes.join("\n"), "Provider notes");
1295
+ return {
1296
+ config: nextConfig,
1297
+ agentModelOverride
1298
+ };
1299
+ }
1300
+
1301
+ //#endregion
1302
+ //#region src/commands/auth-choice.apply.copilot-proxy.ts
1303
+ async function applyAuthChoiceCopilotProxy(params) {
1304
+ return await applyAuthChoicePluginProvider(params, {
1305
+ authChoice: "copilot-proxy",
1306
+ pluginId: "copilot-proxy",
1307
+ providerId: "copilot-proxy",
1308
+ methodId: "local",
1309
+ label: "Copilot Proxy"
1310
+ });
1311
+ }
1312
+
1313
+ //#endregion
1314
+ //#region src/commands/auth-choice.apply.github-copilot.ts
1315
+ async function applyAuthChoiceGitHubCopilot(params) {
1316
+ if (params.authChoice !== "github-copilot") return null;
1317
+ let nextConfig = params.config;
1318
+ await params.prompter.note(["This will open a GitHub device login to authorize Copilot.", "Requires an active GitHub Copilot subscription."].join("\n"), "GitHub Copilot");
1319
+ if (!process.stdin.isTTY) {
1320
+ await params.prompter.note("GitHub Copilot login requires an interactive TTY.", "GitHub Copilot");
1321
+ return { config: nextConfig };
1322
+ }
1323
+ try {
1324
+ await githubCopilotLoginCommand({ yes: true }, params.runtime);
1325
+ } catch (err) {
1326
+ await params.prompter.note(`GitHub Copilot login failed: ${String(err)}`, "GitHub Copilot");
1327
+ return { config: nextConfig };
1328
+ }
1329
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1330
+ profileId: "github-copilot:github",
1331
+ provider: "github-copilot",
1332
+ mode: "token"
1333
+ });
1334
+ if (params.setDefaultModel) {
1335
+ const model = "github-copilot/gpt-4o";
1336
+ nextConfig = {
1337
+ ...nextConfig,
1338
+ agents: {
1339
+ ...nextConfig.agents,
1340
+ defaults: {
1341
+ ...nextConfig.agents?.defaults,
1342
+ model: {
1343
+ ...typeof nextConfig.agents?.defaults?.model === "object" ? nextConfig.agents.defaults.model : void 0,
1344
+ primary: model
1345
+ }
1346
+ }
1347
+ }
1348
+ };
1349
+ await params.prompter.note(`Default model set to ${model}`, "Model configured");
1350
+ }
1351
+ return { config: nextConfig };
1352
+ }
1353
+
1354
+ //#endregion
1355
+ //#region src/commands/auth-choice.apply.google-antigravity.ts
1356
+ async function applyAuthChoiceGoogleAntigravity(params) {
1357
+ return await applyAuthChoicePluginProvider(params, {
1358
+ authChoice: "google-antigravity",
1359
+ pluginId: "google-antigravity-auth",
1360
+ providerId: "google-antigravity",
1361
+ methodId: "oauth",
1362
+ label: "Google Antigravity"
1363
+ });
1364
+ }
1365
+
1366
+ //#endregion
1367
+ //#region src/commands/auth-choice.apply.google-gemini-cli.ts
1368
+ async function applyAuthChoiceGoogleGeminiCli(params) {
1369
+ return await applyAuthChoicePluginProvider(params, {
1370
+ authChoice: "google-gemini-cli",
1371
+ pluginId: "google-gemini-cli-auth",
1372
+ providerId: "google-gemini-cli",
1373
+ methodId: "oauth",
1374
+ label: "Google Gemini CLI"
1375
+ });
1376
+ }
1377
+
1378
+ //#endregion
1379
+ //#region src/commands/auth-choice.apply.minimax.ts
1380
+ async function applyAuthChoiceMiniMax(params) {
1381
+ let nextConfig = params.config;
1382
+ let agentModelOverride;
1383
+ const noteAgentModel = async (model) => {
1384
+ if (!params.agentId) return;
1385
+ await params.prompter.note(`Default model set to ${model} for agent "${params.agentId}".`, "Model configured");
1386
+ };
1387
+ if (params.authChoice === "minimax-portal") return await applyAuthChoicePluginProvider(params, {
1388
+ authChoice: "minimax-portal",
1389
+ pluginId: "minimax-portal-auth",
1390
+ providerId: "minimax-portal",
1391
+ methodId: await params.prompter.select({
1392
+ message: "Select MiniMax endpoint",
1393
+ options: [{
1394
+ value: "oauth",
1395
+ label: "Global",
1396
+ hint: "OAuth for international users"
1397
+ }, {
1398
+ value: "oauth-cn",
1399
+ label: "CN",
1400
+ hint: "OAuth for users in China"
1401
+ }]
1402
+ }),
1403
+ label: "MiniMax"
1404
+ });
1405
+ if (params.authChoice === "minimax-cloud" || params.authChoice === "minimax-api" || params.authChoice === "minimax-api-lightning") {
1406
+ const modelId = params.authChoice === "minimax-api-lightning" ? "MiniMax-M2.1-lightning" : "MiniMax-M2.1";
1407
+ let hasCredential = false;
1408
+ const envKey = resolveEnvApiKey("minimax");
1409
+ if (envKey) {
1410
+ if (await params.prompter.confirm({
1411
+ message: `Use existing MINIMAX_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
1412
+ initialValue: true
1413
+ })) {
1414
+ await setMinimaxApiKey(envKey.apiKey, params.agentDir);
1415
+ hasCredential = true;
1416
+ }
1417
+ }
1418
+ if (!hasCredential) {
1419
+ const key = await params.prompter.text({
1420
+ message: "Enter MiniMax API key",
1421
+ validate: validateApiKeyInput
1422
+ });
1423
+ await setMinimaxApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
1424
+ }
1425
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1426
+ profileId: "minimax:default",
1427
+ provider: "minimax",
1428
+ mode: "api_key"
1429
+ });
1430
+ {
1431
+ const modelRef = `minimax/${modelId}`;
1432
+ const applied = await applyDefaultModelChoice({
1433
+ config: nextConfig,
1434
+ setDefaultModel: params.setDefaultModel,
1435
+ defaultModel: modelRef,
1436
+ applyDefaultConfig: (config) => applyMinimaxApiConfig(config, modelId),
1437
+ applyProviderConfig: (config) => applyMinimaxApiProviderConfig(config, modelId),
1438
+ noteAgentModel,
1439
+ prompter: params.prompter
1440
+ });
1441
+ nextConfig = applied.config;
1442
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1443
+ }
1444
+ return {
1445
+ config: nextConfig,
1446
+ agentModelOverride
1447
+ };
1448
+ }
1449
+ if (params.authChoice === "minimax") {
1450
+ const applied = await applyDefaultModelChoice({
1451
+ config: nextConfig,
1452
+ setDefaultModel: params.setDefaultModel,
1453
+ defaultModel: "lmstudio/minimax-m2.1-gs32",
1454
+ applyDefaultConfig: applyMinimaxConfig,
1455
+ applyProviderConfig: applyMinimaxProviderConfig,
1456
+ noteAgentModel,
1457
+ prompter: params.prompter
1458
+ });
1459
+ nextConfig = applied.config;
1460
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1461
+ return {
1462
+ config: nextConfig,
1463
+ agentModelOverride
1464
+ };
1465
+ }
1466
+ return null;
1467
+ }
1468
+
1469
+ //#endregion
1470
+ //#region src/commands/chutes-oauth.ts
1471
+ function buildAuthorizeUrl(params) {
1472
+ return `${CHUTES_AUTHORIZE_ENDPOINT}?${new URLSearchParams({
1473
+ client_id: params.clientId,
1474
+ redirect_uri: params.redirectUri,
1475
+ response_type: "code",
1476
+ scope: params.scopes.join(" "),
1477
+ state: params.state,
1478
+ code_challenge: params.challenge,
1479
+ code_challenge_method: "S256"
1480
+ }).toString()}`;
1481
+ }
1482
+ async function waitForLocalCallback(params) {
1483
+ const redirectUrl = new URL(params.redirectUri);
1484
+ if (redirectUrl.protocol !== "http:") throw new Error(`Chutes OAuth redirect URI must be http:// (got ${params.redirectUri})`);
1485
+ const hostname = redirectUrl.hostname || "127.0.0.1";
1486
+ const port = redirectUrl.port ? Number.parseInt(redirectUrl.port, 10) : 80;
1487
+ const expectedPath = redirectUrl.pathname || "/";
1488
+ return await new Promise((resolve, reject) => {
1489
+ let timeout = null;
1490
+ const server = createServer((req, res) => {
1491
+ try {
1492
+ const requestUrl = new URL(req.url ?? "/", redirectUrl.origin);
1493
+ if (requestUrl.pathname !== expectedPath) {
1494
+ res.statusCode = 404;
1495
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
1496
+ res.end("Not found");
1497
+ return;
1498
+ }
1499
+ const code = requestUrl.searchParams.get("code")?.trim();
1500
+ const state = requestUrl.searchParams.get("state")?.trim();
1501
+ if (!code) {
1502
+ res.statusCode = 400;
1503
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
1504
+ res.end("Missing code");
1505
+ return;
1506
+ }
1507
+ if (!state || state !== params.expectedState) {
1508
+ res.statusCode = 400;
1509
+ res.setHeader("Content-Type", "text/plain; charset=utf-8");
1510
+ res.end("Invalid state");
1511
+ return;
1512
+ }
1513
+ res.statusCode = 200;
1514
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
1515
+ res.end([
1516
+ "<!doctype html>",
1517
+ "<html><head><meta charset='utf-8' /></head>",
1518
+ "<body><h2>Chutes OAuth complete</h2>",
1519
+ "<p>You can close this window and return to Synurex.</p></body></html>"
1520
+ ].join(""));
1521
+ if (timeout) clearTimeout(timeout);
1522
+ server.close();
1523
+ resolve({
1524
+ code,
1525
+ state
1526
+ });
1527
+ } catch (err) {
1528
+ if (timeout) clearTimeout(timeout);
1529
+ server.close();
1530
+ reject(err);
1531
+ }
1532
+ });
1533
+ server.once("error", (err) => {
1534
+ if (timeout) clearTimeout(timeout);
1535
+ server.close();
1536
+ reject(err);
1537
+ });
1538
+ server.listen(port, hostname, () => {
1539
+ params.onProgress?.(`Waiting for OAuth callback on ${redirectUrl.origin}${expectedPath}…`);
1540
+ });
1541
+ timeout = setTimeout(() => {
1542
+ try {
1543
+ server.close();
1544
+ } catch {}
1545
+ reject(/* @__PURE__ */ new Error("OAuth callback timeout"));
1546
+ }, params.timeoutMs);
1547
+ });
1548
+ }
1549
+ async function loginChutes(params) {
1550
+ const createPkce = params.createPkce ?? generateChutesPkce;
1551
+ const createState = params.createState ?? (() => randomBytes(16).toString("hex"));
1552
+ const { verifier, challenge } = createPkce();
1553
+ const state = createState();
1554
+ const timeoutMs = params.timeoutMs ?? 180 * 1e3;
1555
+ const url = buildAuthorizeUrl({
1556
+ clientId: params.app.clientId,
1557
+ redirectUri: params.app.redirectUri,
1558
+ scopes: params.app.scopes,
1559
+ state,
1560
+ challenge
1561
+ });
1562
+ let codeAndState;
1563
+ if (params.manual) {
1564
+ await params.onAuth({ url });
1565
+ params.onProgress?.("Waiting for redirect URL…");
1566
+ const input = await params.onPrompt({
1567
+ message: "Paste the redirect URL (or authorization code)",
1568
+ placeholder: `${params.app.redirectUri}?code=...&state=...`
1569
+ });
1570
+ const parsed = parseOAuthCallbackInput(String(input), state);
1571
+ if ("error" in parsed) throw new Error(parsed.error);
1572
+ if (parsed.state !== state) throw new Error("Invalid OAuth state");
1573
+ codeAndState = parsed;
1574
+ } else {
1575
+ const callback = waitForLocalCallback({
1576
+ redirectUri: params.app.redirectUri,
1577
+ expectedState: state,
1578
+ timeoutMs,
1579
+ onProgress: params.onProgress
1580
+ }).catch(async () => {
1581
+ params.onProgress?.("OAuth callback not detected; paste redirect URL…");
1582
+ const input = await params.onPrompt({
1583
+ message: "Paste the redirect URL (or authorization code)",
1584
+ placeholder: `${params.app.redirectUri}?code=...&state=...`
1585
+ });
1586
+ const parsed = parseOAuthCallbackInput(String(input), state);
1587
+ if ("error" in parsed) throw new Error(parsed.error);
1588
+ if (parsed.state !== state) throw new Error("Invalid OAuth state");
1589
+ return parsed;
1590
+ });
1591
+ await params.onAuth({ url });
1592
+ codeAndState = await callback;
1593
+ }
1594
+ params.onProgress?.("Exchanging code for tokens…");
1595
+ return await exchangeChutesCodeForTokens({
1596
+ app: params.app,
1597
+ code: codeAndState.code,
1598
+ codeVerifier: verifier,
1599
+ fetchFn: params.fetchFn
1600
+ });
1601
+ }
1602
+
1603
+ //#endregion
1604
+ //#region src/commands/auth-choice.apply.oauth.ts
1605
+ async function applyAuthChoiceOAuth(params) {
1606
+ if (params.authChoice === "chutes") {
1607
+ let nextConfig = params.config;
1608
+ const isRemote = isRemoteEnvironment();
1609
+ const redirectUri = process.env.CHUTES_OAUTH_REDIRECT_URI?.trim() || "http://127.0.0.1:1456/oauth-callback";
1610
+ const scopes = process.env.CHUTES_OAUTH_SCOPES?.trim() || "openid profile chutes:invoke";
1611
+ const clientId = process.env.CHUTES_CLIENT_ID?.trim() || String(await params.prompter.text({
1612
+ message: "Enter Chutes OAuth client id",
1613
+ placeholder: "cid_xxx",
1614
+ validate: (value) => value?.trim() ? void 0 : "Required"
1615
+ })).trim();
1616
+ const clientSecret = process.env.CHUTES_CLIENT_SECRET?.trim() || void 0;
1617
+ await params.prompter.note(isRemote ? [
1618
+ "You are running in a remote/VPS environment.",
1619
+ "A URL will be shown for you to open in your LOCAL browser.",
1620
+ "After signing in, paste the redirect URL back here.",
1621
+ "",
1622
+ `Redirect URI: ${redirectUri}`
1623
+ ].join("\n") : [
1624
+ "Browser will open for Chutes authentication.",
1625
+ "If the callback doesn't auto-complete, paste the redirect URL.",
1626
+ "",
1627
+ `Redirect URI: ${redirectUri}`
1628
+ ].join("\n"), "Chutes OAuth");
1629
+ const spin = params.prompter.progress("Starting OAuth flow…");
1630
+ try {
1631
+ const { onAuth, onPrompt } = createVpsAwareOAuthHandlers({
1632
+ isRemote,
1633
+ prompter: params.prompter,
1634
+ runtime: params.runtime,
1635
+ spin,
1636
+ openUrl,
1637
+ localBrowserMessage: "Complete sign-in in browser…"
1638
+ });
1639
+ const creds = await loginChutes({
1640
+ app: {
1641
+ clientId,
1642
+ clientSecret,
1643
+ redirectUri,
1644
+ scopes: scopes.split(/\s+/).filter(Boolean)
1645
+ },
1646
+ manual: isRemote,
1647
+ onAuth,
1648
+ onPrompt,
1649
+ onProgress: (msg) => spin.update(msg)
1650
+ });
1651
+ spin.stop("Chutes OAuth complete");
1652
+ const profileId = `chutes:${typeof creds.email === "string" && creds.email.trim() ? creds.email.trim() : "default"}`;
1653
+ await writeOAuthCredentials("chutes", creds, params.agentDir);
1654
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1655
+ profileId,
1656
+ provider: "chutes",
1657
+ mode: "oauth"
1658
+ });
1659
+ } catch (err) {
1660
+ spin.stop("Chutes OAuth failed");
1661
+ params.runtime.error(String(err));
1662
+ await params.prompter.note([
1663
+ "Trouble with OAuth?",
1664
+ "Verify CHUTES_CLIENT_ID (and CHUTES_CLIENT_SECRET if required).",
1665
+ `Verify the OAuth app redirect URI includes: ${redirectUri}`,
1666
+ "Chutes docs: https://chutes.ai/docs/sign-in-with-chutes/overview"
1667
+ ].join("\n"), "OAuth help");
1668
+ }
1669
+ return { config: nextConfig };
1670
+ }
1671
+ return null;
1672
+ }
1673
+
1674
+ //#endregion
1675
+ //#region src/infra/env-file.ts
1676
+ function escapeRegExp(value) {
1677
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1678
+ }
1679
+ function upsertSharedEnvVar(params) {
1680
+ const dir = resolveConfigDir(params.env ?? process.env);
1681
+ const filepath = path.join(dir, ".env");
1682
+ const key = params.key.trim();
1683
+ const value = params.value;
1684
+ let raw = "";
1685
+ if (fs.existsSync(filepath)) raw = fs.readFileSync(filepath, "utf8");
1686
+ const lines = raw.length ? raw.split(/\r?\n/) : [];
1687
+ const matcher = new RegExp(`^(\\s*(?:export\\s+)?)${escapeRegExp(key)}\\s*=`);
1688
+ let updated = false;
1689
+ let replaced = false;
1690
+ const nextLines = lines.map((line) => {
1691
+ const match = line.match(matcher);
1692
+ if (!match) return line;
1693
+ replaced = true;
1694
+ const next = `${match[1] ?? ""}${key}=${value}`;
1695
+ if (next !== line) updated = true;
1696
+ return next;
1697
+ });
1698
+ if (!replaced) {
1699
+ nextLines.push(`${key}=${value}`);
1700
+ updated = true;
1701
+ }
1702
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, {
1703
+ recursive: true,
1704
+ mode: 448
1705
+ });
1706
+ const output = `${nextLines.join("\n")}\n`;
1707
+ fs.writeFileSync(filepath, output, "utf8");
1708
+ fs.chmodSync(filepath, 384);
1709
+ return {
1710
+ path: filepath,
1711
+ updated,
1712
+ created: !raw
1713
+ };
1714
+ }
1715
+
1716
+ //#endregion
1717
+ //#region src/commands/openai-codex-model-default.ts
1718
+ const OPENAI_CODEX_DEFAULT_MODEL = "openai-codex/gpt-5.3-codex";
1719
+ function shouldSetOpenAICodexModel(model) {
1720
+ const trimmed = model?.trim();
1721
+ if (!trimmed) return true;
1722
+ const normalized = trimmed.toLowerCase();
1723
+ if (normalized.startsWith("openai-codex/")) return false;
1724
+ if (normalized.startsWith("openai/")) return true;
1725
+ return normalized === "gpt" || normalized === "gpt-mini";
1726
+ }
1727
+ function resolvePrimaryModel(model) {
1728
+ if (typeof model === "string") return model;
1729
+ if (model && typeof model === "object" && typeof model.primary === "string") return model.primary;
1730
+ }
1731
+ function applyOpenAICodexModelDefault(cfg) {
1732
+ if (!shouldSetOpenAICodexModel(resolvePrimaryModel(cfg.agents?.defaults?.model))) return {
1733
+ next: cfg,
1734
+ changed: false
1735
+ };
1736
+ return {
1737
+ next: {
1738
+ ...cfg,
1739
+ agents: {
1740
+ ...cfg.agents,
1741
+ defaults: {
1742
+ ...cfg.agents?.defaults,
1743
+ model: cfg.agents?.defaults?.model && typeof cfg.agents.defaults.model === "object" ? {
1744
+ ...cfg.agents.defaults.model,
1745
+ primary: OPENAI_CODEX_DEFAULT_MODEL
1746
+ } : { primary: OPENAI_CODEX_DEFAULT_MODEL }
1747
+ }
1748
+ }
1749
+ },
1750
+ changed: true
1751
+ };
1752
+ }
1753
+
1754
+ //#endregion
1755
+ //#region src/commands/openai-model-default.ts
1756
+ const OPENAI_DEFAULT_MODEL = "openai/gpt-5.1-codex";
1757
+ function applyOpenAIProviderConfig(cfg) {
1758
+ const next = ensureModelAllowlistEntry({
1759
+ cfg,
1760
+ modelRef: OPENAI_DEFAULT_MODEL
1761
+ });
1762
+ const models = { ...next.agents?.defaults?.models };
1763
+ models[OPENAI_DEFAULT_MODEL] = {
1764
+ ...models[OPENAI_DEFAULT_MODEL],
1765
+ alias: models[OPENAI_DEFAULT_MODEL]?.alias ?? "GPT"
1766
+ };
1767
+ return {
1768
+ ...next,
1769
+ agents: {
1770
+ ...next.agents,
1771
+ defaults: {
1772
+ ...next.agents?.defaults,
1773
+ models
1774
+ }
1775
+ }
1776
+ };
1777
+ }
1778
+ function applyOpenAIConfig(cfg) {
1779
+ const next = applyOpenAIProviderConfig(cfg);
1780
+ return {
1781
+ ...next,
1782
+ agents: {
1783
+ ...next.agents,
1784
+ defaults: {
1785
+ ...next.agents?.defaults,
1786
+ model: next.agents?.defaults?.model && typeof next.agents.defaults.model === "object" ? {
1787
+ ...next.agents.defaults.model,
1788
+ primary: OPENAI_DEFAULT_MODEL
1789
+ } : { primary: OPENAI_DEFAULT_MODEL }
1790
+ }
1791
+ }
1792
+ };
1793
+ }
1794
+
1795
+ //#endregion
1796
+ //#region src/commands/auth-choice.apply.openai.ts
1797
+ async function applyAuthChoiceOpenAI(params) {
1798
+ let authChoice = params.authChoice;
1799
+ if (authChoice === "apiKey" && params.opts?.tokenProvider === "openai") authChoice = "openai-api-key";
1800
+ if (authChoice === "openai-api-key") {
1801
+ let nextConfig = params.config;
1802
+ let agentModelOverride;
1803
+ const noteAgentModel = async (model) => {
1804
+ if (!params.agentId) return;
1805
+ await params.prompter.note(`Default model set to ${model} for agent "${params.agentId}".`, "Model configured");
1806
+ };
1807
+ const envKey = resolveEnvApiKey("openai");
1808
+ if (envKey) {
1809
+ if (await params.prompter.confirm({
1810
+ message: `Use existing OPENAI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
1811
+ initialValue: true
1812
+ })) {
1813
+ const result = upsertSharedEnvVar({
1814
+ key: "OPENAI_API_KEY",
1815
+ value: envKey.apiKey
1816
+ });
1817
+ if (!process.env.OPENAI_API_KEY) process.env.OPENAI_API_KEY = envKey.apiKey;
1818
+ await params.prompter.note(`Copied OPENAI_API_KEY to ${result.path} for launchd compatibility.`, "OpenAI API key");
1819
+ const applied = await applyDefaultModelChoice({
1820
+ config: nextConfig,
1821
+ setDefaultModel: params.setDefaultModel,
1822
+ defaultModel: OPENAI_DEFAULT_MODEL,
1823
+ applyDefaultConfig: applyOpenAIConfig,
1824
+ applyProviderConfig: applyOpenAIProviderConfig,
1825
+ noteDefault: OPENAI_DEFAULT_MODEL,
1826
+ noteAgentModel,
1827
+ prompter: params.prompter
1828
+ });
1829
+ nextConfig = applied.config;
1830
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1831
+ return {
1832
+ config: nextConfig,
1833
+ agentModelOverride
1834
+ };
1835
+ }
1836
+ }
1837
+ let key;
1838
+ if (params.opts?.token && params.opts?.tokenProvider === "openai") key = params.opts.token;
1839
+ else key = await params.prompter.text({
1840
+ message: "Enter OpenAI API key",
1841
+ validate: validateApiKeyInput
1842
+ });
1843
+ const trimmed = normalizeApiKeyInput(String(key));
1844
+ const result = upsertSharedEnvVar({
1845
+ key: "OPENAI_API_KEY",
1846
+ value: trimmed
1847
+ });
1848
+ process.env.OPENAI_API_KEY = trimmed;
1849
+ await params.prompter.note(`Saved OPENAI_API_KEY to ${result.path} for launchd compatibility.`, "OpenAI API key");
1850
+ const applied = await applyDefaultModelChoice({
1851
+ config: nextConfig,
1852
+ setDefaultModel: params.setDefaultModel,
1853
+ defaultModel: OPENAI_DEFAULT_MODEL,
1854
+ applyDefaultConfig: applyOpenAIConfig,
1855
+ applyProviderConfig: applyOpenAIProviderConfig,
1856
+ noteDefault: OPENAI_DEFAULT_MODEL,
1857
+ noteAgentModel,
1858
+ prompter: params.prompter
1859
+ });
1860
+ nextConfig = applied.config;
1861
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1862
+ return {
1863
+ config: nextConfig,
1864
+ agentModelOverride
1865
+ };
1866
+ }
1867
+ if (params.authChoice === "openai-codex") {
1868
+ let nextConfig = params.config;
1869
+ let agentModelOverride;
1870
+ const noteAgentModel = async (model) => {
1871
+ if (!params.agentId) return;
1872
+ await params.prompter.note(`Default model set to ${model} for agent "${params.agentId}".`, "Model configured");
1873
+ };
1874
+ const isRemote = isRemoteEnvironment();
1875
+ await params.prompter.note(isRemote ? [
1876
+ "You are running in a remote/VPS environment.",
1877
+ "A URL will be shown for you to open in your LOCAL browser.",
1878
+ "After signing in, paste the redirect URL back here."
1879
+ ].join("\n") : [
1880
+ "Browser will open for OpenAI authentication.",
1881
+ "If the callback doesn't auto-complete, paste the redirect URL.",
1882
+ "OpenAI OAuth uses localhost:1455 for the callback."
1883
+ ].join("\n"), "OpenAI Codex OAuth");
1884
+ const spin = params.prompter.progress("Starting OAuth flow…");
1885
+ try {
1886
+ const { onAuth, onPrompt } = createVpsAwareOAuthHandlers({
1887
+ isRemote,
1888
+ prompter: params.prompter,
1889
+ runtime: params.runtime,
1890
+ spin,
1891
+ openUrl,
1892
+ localBrowserMessage: "Complete sign-in in browser…"
1893
+ });
1894
+ const creds = await loginOpenAICodex({
1895
+ onAuth,
1896
+ onPrompt,
1897
+ onProgress: (msg) => spin.update(msg)
1898
+ });
1899
+ spin.stop("OpenAI OAuth complete");
1900
+ if (creds) {
1901
+ await writeOAuthCredentials("openai-codex", creds, params.agentDir);
1902
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1903
+ profileId: "openai-codex:default",
1904
+ provider: "openai-codex",
1905
+ mode: "oauth"
1906
+ });
1907
+ if (params.setDefaultModel) {
1908
+ const applied = applyOpenAICodexModelDefault(nextConfig);
1909
+ nextConfig = applied.next;
1910
+ if (applied.changed) await params.prompter.note(`Default model set to ${OPENAI_CODEX_DEFAULT_MODEL}`, "Model configured");
1911
+ } else {
1912
+ agentModelOverride = OPENAI_CODEX_DEFAULT_MODEL;
1913
+ await noteAgentModel(OPENAI_CODEX_DEFAULT_MODEL);
1914
+ }
1915
+ }
1916
+ } catch (err) {
1917
+ spin.stop("OpenAI OAuth failed");
1918
+ params.runtime.error(String(err));
1919
+ await params.prompter.note("Trouble with OAuth? See https://docs.synurex.com/start/faq", "OAuth help");
1920
+ }
1921
+ return {
1922
+ config: nextConfig,
1923
+ agentModelOverride
1924
+ };
1925
+ }
1926
+ return null;
1927
+ }
1928
+
1929
+ //#endregion
1930
+ //#region src/commands/auth-choice.apply.qwen-portal.ts
1931
+ async function applyAuthChoiceQwenPortal(params) {
1932
+ return await applyAuthChoicePluginProvider(params, {
1933
+ authChoice: "qwen-portal",
1934
+ pluginId: "qwen-portal-auth",
1935
+ providerId: "qwen-portal",
1936
+ methodId: "device",
1937
+ label: "Qwen"
1938
+ });
1939
+ }
1940
+
1941
+ //#endregion
1942
+ //#region src/commands/auth-choice.apply.xai.ts
1943
+ async function applyAuthChoiceXAI(params) {
1944
+ if (params.authChoice !== "xai-api-key") return null;
1945
+ let nextConfig = params.config;
1946
+ let agentModelOverride;
1947
+ const noteAgentModel = async (model) => {
1948
+ if (!params.agentId) return;
1949
+ await params.prompter.note(`Default model set to ${model} for agent "${params.agentId}".`, "Model configured");
1950
+ };
1951
+ let hasCredential = false;
1952
+ const optsKey = params.opts?.xaiApiKey?.trim();
1953
+ if (optsKey) {
1954
+ setXaiApiKey(normalizeApiKeyInput(optsKey), params.agentDir);
1955
+ hasCredential = true;
1956
+ }
1957
+ if (!hasCredential) {
1958
+ const envKey = resolveEnvApiKey("xai");
1959
+ if (envKey) {
1960
+ if (await params.prompter.confirm({
1961
+ message: `Use existing XAI_API_KEY (${envKey.source}, ${formatApiKeyPreview(envKey.apiKey)})?`,
1962
+ initialValue: true
1963
+ })) {
1964
+ setXaiApiKey(envKey.apiKey, params.agentDir);
1965
+ hasCredential = true;
1966
+ }
1967
+ }
1968
+ }
1969
+ if (!hasCredential) {
1970
+ const key = await params.prompter.text({
1971
+ message: "Enter xAI API key",
1972
+ validate: validateApiKeyInput
1973
+ });
1974
+ setXaiApiKey(normalizeApiKeyInput(String(key)), params.agentDir);
1975
+ }
1976
+ nextConfig = applyAuthProfileConfig(nextConfig, {
1977
+ profileId: "xai:default",
1978
+ provider: "xai",
1979
+ mode: "api_key"
1980
+ });
1981
+ {
1982
+ const applied = await applyDefaultModelChoice({
1983
+ config: nextConfig,
1984
+ setDefaultModel: params.setDefaultModel,
1985
+ defaultModel: XAI_DEFAULT_MODEL_REF,
1986
+ applyDefaultConfig: applyXaiConfig,
1987
+ applyProviderConfig: applyXaiProviderConfig,
1988
+ noteDefault: XAI_DEFAULT_MODEL_REF,
1989
+ noteAgentModel,
1990
+ prompter: params.prompter
1991
+ });
1992
+ nextConfig = applied.config;
1993
+ agentModelOverride = applied.agentModelOverride ?? agentModelOverride;
1994
+ }
1995
+ return {
1996
+ config: nextConfig,
1997
+ agentModelOverride
1998
+ };
1999
+ }
2000
+
2001
+ //#endregion
2002
+ //#region src/commands/auth-choice.apply.ts
2003
+ async function applyAuthChoice(params) {
2004
+ const handlers = [
2005
+ applyAuthChoiceAnthropic,
2006
+ applyAuthChoiceOpenAI,
2007
+ applyAuthChoiceOAuth,
2008
+ applyAuthChoiceApiProviders,
2009
+ applyAuthChoiceMiniMax,
2010
+ applyAuthChoiceGitHubCopilot,
2011
+ applyAuthChoiceGoogleAntigravity,
2012
+ applyAuthChoiceGoogleGeminiCli,
2013
+ applyAuthChoiceCopilotProxy,
2014
+ applyAuthChoiceQwenPortal,
2015
+ applyAuthChoiceXAI
2016
+ ];
2017
+ for (const handler of handlers) {
2018
+ const result = await handler(params);
2019
+ if (result) return result;
2020
+ }
2021
+ return { config: params.config };
2022
+ }
2023
+
2024
+ //#endregion
2025
+ //#region src/commands/auth-choice.model-check.ts
2026
+ async function warnIfModelConfigLooksOff(config, prompter, options) {
2027
+ const agentModelOverride = options?.agentId ? resolveAgentModelPrimary(config, options.agentId) : void 0;
2028
+ const configWithModel = agentModelOverride && agentModelOverride.length > 0 ? {
2029
+ ...config,
2030
+ agents: {
2031
+ ...config.agents,
2032
+ defaults: {
2033
+ ...config.agents?.defaults,
2034
+ model: {
2035
+ ...typeof config.agents?.defaults?.model === "object" ? config.agents.defaults.model : void 0,
2036
+ primary: agentModelOverride
2037
+ }
2038
+ }
2039
+ }
2040
+ } : config;
2041
+ const ref = resolveConfiguredModelRef({
2042
+ cfg: configWithModel,
2043
+ defaultProvider: DEFAULT_PROVIDER,
2044
+ defaultModel: DEFAULT_MODEL
2045
+ });
2046
+ const warnings = [];
2047
+ const catalog = await loadModelCatalog({
2048
+ config: configWithModel,
2049
+ useCache: false
2050
+ });
2051
+ if (catalog.length > 0) {
2052
+ if (!catalog.some((entry) => entry.provider === ref.provider && entry.id === ref.model)) warnings.push(`Model not found: ${ref.provider}/${ref.model}. Update agents.defaults.model or run /models list.`);
2053
+ }
2054
+ const store = ensureAuthProfileStore(options?.agentDir);
2055
+ const hasProfile = listProfilesForProvider(store, ref.provider).length > 0;
2056
+ const envKey = resolveEnvApiKey(ref.provider);
2057
+ const customKey = getCustomProviderApiKey(config, ref.provider);
2058
+ if (!hasProfile && !envKey && !customKey) warnings.push(`No auth configured for provider "${ref.provider}". The agent may fail until credentials are added.`);
2059
+ if (ref.provider === "openai") {
2060
+ if (listProfilesForProvider(store, "openai-codex").length > 0) warnings.push(`Detected OpenAI Codex OAuth. Consider setting agents.defaults.model to ${OPENAI_CODEX_DEFAULT_MODEL}.`);
2061
+ }
2062
+ if (warnings.length > 0) await prompter.note(warnings.join("\n"), "Model check");
2063
+ }
2064
+
2065
+ //#endregion
2066
+ //#region src/commands/auth-choice.preferred-provider.ts
2067
+ const PREFERRED_PROVIDER_BY_AUTH_CHOICE = {
2068
+ oauth: "anthropic",
2069
+ "setup-token": "anthropic",
2070
+ "claude-cli": "anthropic",
2071
+ token: "anthropic",
2072
+ apiKey: "anthropic",
2073
+ "openai-codex": "openai-codex",
2074
+ "codex-cli": "openai-codex",
2075
+ chutes: "chutes",
2076
+ "openai-api-key": "openai",
2077
+ "openrouter-api-key": "openrouter",
2078
+ "ai-gateway-api-key": "vercel-ai-gateway",
2079
+ "cloudflare-ai-gateway-api-key": "cloudflare-ai-gateway",
2080
+ "moonshot-api-key": "moonshot",
2081
+ "moonshot-api-key-cn": "moonshot",
2082
+ "kimi-code-api-key": "kimi-coding",
2083
+ "gemini-api-key": "google",
2084
+ "google-antigravity": "google-antigravity",
2085
+ "google-gemini-cli": "google-gemini-cli",
2086
+ "zai-api-key": "zai",
2087
+ "xiaomi-api-key": "xiaomi",
2088
+ "synthetic-api-key": "synthetic",
2089
+ "venice-api-key": "venice",
2090
+ "github-copilot": "github-copilot",
2091
+ "copilot-proxy": "copilot-proxy",
2092
+ "minimax-cloud": "minimax",
2093
+ "minimax-api": "minimax",
2094
+ "minimax-api-lightning": "minimax",
2095
+ minimax: "lmstudio",
2096
+ "opencode-zen": "opencode",
2097
+ "xai-api-key": "xai",
2098
+ "qwen-portal": "qwen-portal",
2099
+ "minimax-portal": "minimax-portal",
2100
+ "qianfan-api-key": "qianfan"
2101
+ };
2102
+ function resolvePreferredProviderForAuthChoice(choice) {
2103
+ return PREFERRED_PROVIDER_BY_AUTH_CHOICE[choice];
2104
+ }
2105
+
2106
+ //#endregion
2107
+ //#region src/commands/model-picker.ts
2108
+ const KEEP_VALUE = "__keep__";
2109
+ const MANUAL_VALUE = "__manual__";
2110
+ const PROVIDER_FILTER_THRESHOLD = 30;
2111
+ const HIDDEN_ROUTER_MODELS = new Set(["openrouter/auto"]);
2112
+ function hasAuthForProvider(provider, cfg, store) {
2113
+ if (listProfilesForProvider(store, provider).length > 0) return true;
2114
+ if (resolveEnvApiKey(provider)) return true;
2115
+ if (getCustomProviderApiKey(cfg, provider)) return true;
2116
+ return false;
2117
+ }
2118
+ function resolveConfiguredModelRaw(cfg) {
2119
+ const raw = cfg.agents?.defaults?.model;
2120
+ if (typeof raw === "string") return raw.trim();
2121
+ return raw?.primary?.trim() ?? "";
2122
+ }
2123
+ function resolveConfiguredModelKeys(cfg) {
2124
+ const models = cfg.agents?.defaults?.models ?? {};
2125
+ return Object.keys(models).map((key) => String(key ?? "").trim()).filter((key) => key.length > 0);
2126
+ }
2127
+ function normalizeModelKeys(values) {
2128
+ const seen = /* @__PURE__ */ new Set();
2129
+ const next = [];
2130
+ for (const raw of values) {
2131
+ const value = String(raw ?? "").trim();
2132
+ if (!value || seen.has(value)) continue;
2133
+ seen.add(value);
2134
+ next.push(value);
2135
+ }
2136
+ return next;
2137
+ }
2138
+ async function promptManualModel(params) {
2139
+ const modelInput = await params.prompter.text({
2140
+ message: params.allowBlank ? "Default model (blank to keep)" : "Default model",
2141
+ initialValue: params.initialValue,
2142
+ placeholder: "provider/model",
2143
+ validate: params.allowBlank ? void 0 : (value) => value?.trim() ? void 0 : "Required"
2144
+ });
2145
+ const model = String(modelInput ?? "").trim();
2146
+ if (!model) return {};
2147
+ return { model };
2148
+ }
2149
+ async function promptDefaultModel(params) {
2150
+ const cfg = params.config;
2151
+ const allowKeep = params.allowKeep ?? true;
2152
+ const includeManual = params.includeManual ?? true;
2153
+ const ignoreAllowlist = params.ignoreAllowlist ?? false;
2154
+ const preferredProviderRaw = params.preferredProvider?.trim();
2155
+ const preferredProvider = preferredProviderRaw ? normalizeProviderId(preferredProviderRaw) : void 0;
2156
+ const configuredRaw = resolveConfiguredModelRaw(cfg);
2157
+ const resolved = resolveConfiguredModelRef({
2158
+ cfg,
2159
+ defaultProvider: DEFAULT_PROVIDER,
2160
+ defaultModel: DEFAULT_MODEL
2161
+ });
2162
+ const resolvedKey = modelKey(resolved.provider, resolved.model);
2163
+ const configuredKey = configuredRaw ? resolvedKey : "";
2164
+ const catalog = await loadModelCatalog({
2165
+ config: cfg,
2166
+ useCache: false
2167
+ });
2168
+ if (catalog.length === 0) return promptManualModel({
2169
+ prompter: params.prompter,
2170
+ allowBlank: allowKeep,
2171
+ initialValue: configuredRaw || resolvedKey || void 0
2172
+ });
2173
+ const aliasIndex = buildModelAliasIndex({
2174
+ cfg,
2175
+ defaultProvider: DEFAULT_PROVIDER
2176
+ });
2177
+ let models = catalog;
2178
+ if (!ignoreAllowlist) {
2179
+ const { allowedCatalog } = buildAllowedModelSet({
2180
+ cfg,
2181
+ catalog,
2182
+ defaultProvider: DEFAULT_PROVIDER
2183
+ });
2184
+ models = allowedCatalog.length > 0 ? allowedCatalog : catalog;
2185
+ }
2186
+ if (models.length === 0) return promptManualModel({
2187
+ prompter: params.prompter,
2188
+ allowBlank: allowKeep,
2189
+ initialValue: configuredRaw || resolvedKey || void 0
2190
+ });
2191
+ const providers = Array.from(new Set(models.map((entry) => entry.provider))).toSorted((a, b) => a.localeCompare(b));
2192
+ const hasPreferredProvider = preferredProvider ? providers.includes(preferredProvider) : false;
2193
+ if (!hasPreferredProvider && providers.length > 1 && models.length > PROVIDER_FILTER_THRESHOLD) {
2194
+ const selection = await params.prompter.select({
2195
+ message: "Filter models by provider",
2196
+ options: [{
2197
+ value: "*",
2198
+ label: "All providers"
2199
+ }, ...providers.map((provider) => {
2200
+ const count = models.filter((entry) => entry.provider === provider).length;
2201
+ return {
2202
+ value: provider,
2203
+ label: provider,
2204
+ hint: `${count} model${count === 1 ? "" : "s"}`
2205
+ };
2206
+ })]
2207
+ });
2208
+ if (selection !== "*") models = models.filter((entry) => entry.provider === selection);
2209
+ }
2210
+ if (hasPreferredProvider && preferredProvider) models = models.filter((entry) => entry.provider === preferredProvider);
2211
+ const authStore = ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false });
2212
+ const authCache = /* @__PURE__ */ new Map();
2213
+ const hasAuth = (provider) => {
2214
+ const cached = authCache.get(provider);
2215
+ if (cached !== void 0) return cached;
2216
+ const value = hasAuthForProvider(provider, cfg, authStore);
2217
+ authCache.set(provider, value);
2218
+ return value;
2219
+ };
2220
+ const options = [];
2221
+ if (allowKeep) options.push({
2222
+ value: KEEP_VALUE,
2223
+ label: configuredRaw ? `Keep current (${configuredRaw})` : `Keep current (default: ${resolvedKey})`,
2224
+ hint: configuredRaw && configuredRaw !== resolvedKey ? `resolves to ${resolvedKey}` : void 0
2225
+ });
2226
+ if (includeManual) options.push({
2227
+ value: MANUAL_VALUE,
2228
+ label: "Enter model manually"
2229
+ });
2230
+ const seen = /* @__PURE__ */ new Set();
2231
+ const addModelOption = (entry) => {
2232
+ const key = modelKey(entry.provider, entry.id);
2233
+ if (seen.has(key)) return;
2234
+ if (HIDDEN_ROUTER_MODELS.has(key)) return;
2235
+ const hints = [];
2236
+ if (entry.name && entry.name !== entry.id) hints.push(entry.name);
2237
+ if (entry.contextWindow) hints.push(`ctx ${formatTokenK(entry.contextWindow)}`);
2238
+ if (entry.reasoning) hints.push("reasoning");
2239
+ const aliases = aliasIndex.byKey.get(key);
2240
+ if (aliases?.length) hints.push(`alias: ${aliases.join(", ")}`);
2241
+ if (!hasAuth(entry.provider)) hints.push("auth missing");
2242
+ options.push({
2243
+ value: key,
2244
+ label: key,
2245
+ hint: hints.length > 0 ? hints.join(" · ") : void 0
2246
+ });
2247
+ seen.add(key);
2248
+ };
2249
+ for (const entry of models) addModelOption(entry);
2250
+ if (configuredKey && !seen.has(configuredKey)) options.push({
2251
+ value: configuredKey,
2252
+ label: configuredKey,
2253
+ hint: "current (not in catalog)"
2254
+ });
2255
+ let initialValue = allowKeep ? KEEP_VALUE : configuredKey || void 0;
2256
+ if (allowKeep && hasPreferredProvider && preferredProvider && resolved.provider !== preferredProvider) {
2257
+ const firstModel = models[0];
2258
+ if (firstModel) initialValue = modelKey(firstModel.provider, firstModel.id);
2259
+ }
2260
+ const selection = await params.prompter.select({
2261
+ message: params.message ?? "Default model",
2262
+ options,
2263
+ initialValue
2264
+ });
2265
+ if (selection === KEEP_VALUE) return {};
2266
+ if (selection === MANUAL_VALUE) return promptManualModel({
2267
+ prompter: params.prompter,
2268
+ allowBlank: false,
2269
+ initialValue: configuredRaw || resolvedKey || void 0
2270
+ });
2271
+ return { model: String(selection) };
2272
+ }
2273
+ async function promptModelAllowlist(params) {
2274
+ const cfg = params.config;
2275
+ const existingKeys = resolveConfiguredModelKeys(cfg);
2276
+ const allowedKeys = normalizeModelKeys(params.allowedKeys ?? []);
2277
+ const allowedKeySet = allowedKeys.length > 0 ? new Set(allowedKeys) : null;
2278
+ const resolved = resolveConfiguredModelRef({
2279
+ cfg,
2280
+ defaultProvider: DEFAULT_PROVIDER,
2281
+ defaultModel: DEFAULT_MODEL
2282
+ });
2283
+ const resolvedKey = modelKey(resolved.provider, resolved.model);
2284
+ const initialSeeds = normalizeModelKeys([
2285
+ ...existingKeys,
2286
+ resolvedKey,
2287
+ ...params.initialSelections ?? []
2288
+ ]);
2289
+ const initialKeys = allowedKeySet ? initialSeeds.filter((key) => allowedKeySet.has(key)) : initialSeeds;
2290
+ const catalog = await loadModelCatalog({
2291
+ config: cfg,
2292
+ useCache: false
2293
+ });
2294
+ if (catalog.length === 0 && allowedKeys.length === 0) {
2295
+ const raw = await params.prompter.text({
2296
+ message: params.message ?? "Allowlist models (comma-separated provider/model; blank to keep current)",
2297
+ initialValue: existingKeys.join(", "),
2298
+ placeholder: `${OPENAI_CODEX_DEFAULT_MODEL}, anthropic/claude-opus-4-6`
2299
+ });
2300
+ const parsed = String(raw ?? "").split(",").map((value) => value.trim()).filter((value) => value.length > 0);
2301
+ if (parsed.length === 0) return {};
2302
+ return { models: normalizeModelKeys(parsed) };
2303
+ }
2304
+ const aliasIndex = buildModelAliasIndex({
2305
+ cfg,
2306
+ defaultProvider: DEFAULT_PROVIDER
2307
+ });
2308
+ const authStore = ensureAuthProfileStore(params.agentDir, { allowKeychainPrompt: false });
2309
+ const authCache = /* @__PURE__ */ new Map();
2310
+ const hasAuth = (provider) => {
2311
+ const cached = authCache.get(provider);
2312
+ if (cached !== void 0) return cached;
2313
+ const value = hasAuthForProvider(provider, cfg, authStore);
2314
+ authCache.set(provider, value);
2315
+ return value;
2316
+ };
2317
+ const options = [];
2318
+ const seen = /* @__PURE__ */ new Set();
2319
+ const addModelOption = (entry) => {
2320
+ const key = modelKey(entry.provider, entry.id);
2321
+ if (seen.has(key)) return;
2322
+ if (HIDDEN_ROUTER_MODELS.has(key)) return;
2323
+ const hints = [];
2324
+ if (entry.name && entry.name !== entry.id) hints.push(entry.name);
2325
+ if (entry.contextWindow) hints.push(`ctx ${formatTokenK(entry.contextWindow)}`);
2326
+ if (entry.reasoning) hints.push("reasoning");
2327
+ const aliases = aliasIndex.byKey.get(key);
2328
+ if (aliases?.length) hints.push(`alias: ${aliases.join(", ")}`);
2329
+ if (!hasAuth(entry.provider)) hints.push("auth missing");
2330
+ options.push({
2331
+ value: key,
2332
+ label: key,
2333
+ hint: hints.length > 0 ? hints.join(" · ") : void 0
2334
+ });
2335
+ seen.add(key);
2336
+ };
2337
+ const filteredCatalog = allowedKeySet ? catalog.filter((entry) => allowedKeySet.has(modelKey(entry.provider, entry.id))) : catalog;
2338
+ for (const entry of filteredCatalog) addModelOption(entry);
2339
+ const supplementalKeys = allowedKeySet ? allowedKeys : existingKeys;
2340
+ for (const key of supplementalKeys) {
2341
+ if (seen.has(key)) continue;
2342
+ options.push({
2343
+ value: key,
2344
+ label: key,
2345
+ hint: allowedKeySet ? "allowed (not in catalog)" : "configured (not in catalog)"
2346
+ });
2347
+ seen.add(key);
2348
+ }
2349
+ if (options.length === 0) return {};
2350
+ const selected = normalizeModelKeys((await params.prompter.multiselect({
2351
+ message: params.message ?? "Models in /model picker (multi-select)",
2352
+ options,
2353
+ initialValues: initialKeys.length > 0 ? initialKeys : void 0
2354
+ })).map((value) => String(value)));
2355
+ if (selected.length > 0) return { models: selected };
2356
+ if (existingKeys.length === 0) return { models: [] };
2357
+ if (!await params.prompter.confirm({
2358
+ message: "Clear the model allowlist? (shows all models)",
2359
+ initialValue: false
2360
+ })) return {};
2361
+ return { models: [] };
2362
+ }
2363
+ function applyPrimaryModel(cfg, model) {
2364
+ const defaults = cfg.agents?.defaults;
2365
+ const existingModel = defaults?.model;
2366
+ const existingModels = defaults?.models;
2367
+ const fallbacks = typeof existingModel === "object" && existingModel !== null && "fallbacks" in existingModel ? existingModel.fallbacks : void 0;
2368
+ return {
2369
+ ...cfg,
2370
+ agents: {
2371
+ ...cfg.agents,
2372
+ defaults: {
2373
+ ...defaults,
2374
+ model: {
2375
+ ...fallbacks ? { fallbacks } : void 0,
2376
+ primary: model
2377
+ },
2378
+ models: {
2379
+ ...existingModels,
2380
+ [model]: existingModels?.[model] ?? {}
2381
+ }
2382
+ }
2383
+ }
2384
+ };
2385
+ }
2386
+ function applyModelAllowlist(cfg, models) {
2387
+ const defaults = cfg.agents?.defaults;
2388
+ const normalized = normalizeModelKeys(models);
2389
+ if (normalized.length === 0) {
2390
+ if (!defaults?.models) return cfg;
2391
+ const { models: _ignored, ...restDefaults } = defaults;
2392
+ return {
2393
+ ...cfg,
2394
+ agents: {
2395
+ ...cfg.agents,
2396
+ defaults: restDefaults
2397
+ }
2398
+ };
2399
+ }
2400
+ const existingModels = defaults?.models ?? {};
2401
+ const nextModels = {};
2402
+ for (const key of normalized) nextModels[key] = existingModels[key] ?? {};
2403
+ return {
2404
+ ...cfg,
2405
+ agents: {
2406
+ ...cfg.agents,
2407
+ defaults: {
2408
+ ...defaults,
2409
+ models: nextModels
2410
+ }
2411
+ }
2412
+ };
2413
+ }
2414
+ function applyModelFallbacksFromSelection(cfg, selection) {
2415
+ const normalized = normalizeModelKeys(selection);
2416
+ if (normalized.length <= 1) return cfg;
2417
+ const resolved = resolveConfiguredModelRef({
2418
+ cfg,
2419
+ defaultProvider: DEFAULT_PROVIDER,
2420
+ defaultModel: DEFAULT_MODEL
2421
+ });
2422
+ const resolvedKey = modelKey(resolved.provider, resolved.model);
2423
+ if (!normalized.includes(resolvedKey)) return cfg;
2424
+ const defaults = cfg.agents?.defaults;
2425
+ const existingModel = defaults?.model;
2426
+ const existingPrimary = typeof existingModel === "string" ? existingModel : existingModel && typeof existingModel === "object" ? existingModel.primary : void 0;
2427
+ const fallbacks = normalized.filter((key) => key !== resolvedKey);
2428
+ return {
2429
+ ...cfg,
2430
+ agents: {
2431
+ ...cfg.agents,
2432
+ defaults: {
2433
+ ...defaults,
2434
+ model: {
2435
+ ...typeof existingModel === "object" ? existingModel : void 0,
2436
+ primary: existingPrimary ?? resolvedKey,
2437
+ fallbacks
2438
+ }
2439
+ }
2440
+ }
2441
+ };
2442
+ }
2443
+
2444
+ //#endregion
2445
+ //#region src/infra/bonjour-discovery.ts
2446
+ const DEFAULT_TIMEOUT_MS = 2e3;
2447
+ const GATEWAY_SERVICE_TYPE = "_Synurex-gw._tcp";
2448
+ function decodeDnsSdEscapes(value) {
2449
+ let decoded = false;
2450
+ const bytes = [];
2451
+ let pending = "";
2452
+ const flush = () => {
2453
+ if (!pending) return;
2454
+ bytes.push(...Buffer.from(pending, "utf8"));
2455
+ pending = "";
2456
+ };
2457
+ for (let i = 0; i < value.length; i += 1) {
2458
+ const ch = value[i] ?? "";
2459
+ if (ch === "\\" && i + 3 < value.length) {
2460
+ const escaped = value.slice(i + 1, i + 4);
2461
+ if (/^[0-9]{3}$/.test(escaped)) {
2462
+ const byte = Number.parseInt(escaped, 10);
2463
+ if (!Number.isFinite(byte) || byte < 0 || byte > 255) {
2464
+ pending += ch;
2465
+ continue;
2466
+ }
2467
+ flush();
2468
+ bytes.push(byte);
2469
+ decoded = true;
2470
+ i += 3;
2471
+ continue;
2472
+ }
2473
+ }
2474
+ pending += ch;
2475
+ }
2476
+ if (!decoded) return value;
2477
+ flush();
2478
+ return Buffer.from(bytes).toString("utf8");
2479
+ }
2480
+ function isTailnetIPv4(address) {
2481
+ const parts = address.split(".");
2482
+ if (parts.length !== 4) return false;
2483
+ const octets = parts.map((p) => Number.parseInt(p, 10));
2484
+ if (octets.some((n) => !Number.isFinite(n) || n < 0 || n > 255)) return false;
2485
+ const [a, b] = octets;
2486
+ return a === 100 && b >= 64 && b <= 127;
2487
+ }
2488
+ function parseDigShortLines(stdout) {
2489
+ return stdout.split("\n").map((l) => l.trim()).filter(Boolean);
2490
+ }
2491
+ function parseDigTxt(stdout) {
2492
+ const tokens = [];
2493
+ for (const raw of stdout.split("\n")) {
2494
+ const line = raw.trim();
2495
+ if (!line) continue;
2496
+ const matches = Array.from(line.matchAll(/"([^"]*)"/g), (m) => m[1] ?? "");
2497
+ for (const m of matches) {
2498
+ const unescaped = m.replaceAll("\\\\", "\\").replaceAll("\\\"", "\"").replaceAll("\\n", "\n");
2499
+ tokens.push(unescaped);
2500
+ }
2501
+ }
2502
+ return tokens;
2503
+ }
2504
+ function parseDigSrv(stdout) {
2505
+ const line = stdout.split("\n").map((l) => l.trim()).find(Boolean);
2506
+ if (!line) return null;
2507
+ const parts = line.split(/\s+/).filter(Boolean);
2508
+ if (parts.length < 4) return null;
2509
+ const port = Number.parseInt(parts[2] ?? "", 10);
2510
+ const hostRaw = parts[3] ?? "";
2511
+ if (!Number.isFinite(port) || port <= 0) return null;
2512
+ const host = hostRaw.replace(/\.$/, "");
2513
+ if (!host) return null;
2514
+ return {
2515
+ host,
2516
+ port
2517
+ };
2518
+ }
2519
+ function parseTailscaleStatusIPv4s(stdout) {
2520
+ const parsed = stdout ? JSON.parse(stdout) : {};
2521
+ const out = [];
2522
+ const addIps = (value) => {
2523
+ if (!value || typeof value !== "object") return;
2524
+ const ips = value.TailscaleIPs;
2525
+ if (!Array.isArray(ips)) return;
2526
+ for (const ip of ips) {
2527
+ if (typeof ip !== "string") continue;
2528
+ const trimmed = ip.trim();
2529
+ if (trimmed && isTailnetIPv4(trimmed)) out.push(trimmed);
2530
+ }
2531
+ };
2532
+ addIps(parsed.Self);
2533
+ const peerObj = parsed.Peer;
2534
+ if (peerObj && typeof peerObj === "object") for (const peer of Object.values(peerObj)) addIps(peer);
2535
+ return [...new Set(out)];
2536
+ }
2537
+ function parseIntOrNull(value) {
2538
+ if (!value) return;
2539
+ const parsed = Number.parseInt(value, 10);
2540
+ return Number.isFinite(parsed) ? parsed : void 0;
2541
+ }
2542
+ function parseTxtTokens(tokens) {
2543
+ const txt = {};
2544
+ for (const token of tokens) {
2545
+ const idx = token.indexOf("=");
2546
+ if (idx <= 0) continue;
2547
+ const key = token.slice(0, idx).trim();
2548
+ const value = decodeDnsSdEscapes(token.slice(idx + 1).trim());
2549
+ if (!key) continue;
2550
+ txt[key] = value;
2551
+ }
2552
+ return txt;
2553
+ }
2554
+ function parseDnsSdBrowse(stdout) {
2555
+ const instances = /* @__PURE__ */ new Set();
2556
+ for (const raw of stdout.split("\n")) {
2557
+ const line = raw.trim();
2558
+ if (!line || !line.includes(GATEWAY_SERVICE_TYPE)) continue;
2559
+ if (!line.includes("Add")) continue;
2560
+ const match = line.match(/_Synurex-gw\._tcp\.?\s+(.+)$/);
2561
+ if (match?.[1]) instances.add(decodeDnsSdEscapes(match[1].trim()));
2562
+ }
2563
+ return Array.from(instances.values());
2564
+ }
2565
+ function parseDnsSdResolve(stdout, instanceName) {
2566
+ const decodedInstanceName = decodeDnsSdEscapes(instanceName);
2567
+ const beacon = { instanceName: decodedInstanceName };
2568
+ let txt = {};
2569
+ for (const raw of stdout.split("\n")) {
2570
+ const line = raw.trim();
2571
+ if (!line) continue;
2572
+ if (line.includes("can be reached at")) {
2573
+ const match = line.match(/can be reached at\s+([^\s:]+):(\d+)/i);
2574
+ if (match?.[1]) beacon.host = match[1].replace(/\.$/, "");
2575
+ if (match?.[2]) beacon.port = parseIntOrNull(match[2]);
2576
+ continue;
2577
+ }
2578
+ if (line.startsWith("txt") || line.includes("txtvers=")) txt = parseTxtTokens(line.split(/\s+/).filter(Boolean));
2579
+ }
2580
+ beacon.txt = Object.keys(txt).length ? txt : void 0;
2581
+ if (txt.displayName) beacon.displayName = decodeDnsSdEscapes(txt.displayName);
2582
+ if (txt.lanHost) beacon.lanHost = txt.lanHost;
2583
+ if (txt.tailnetDns) beacon.tailnetDns = txt.tailnetDns;
2584
+ if (txt.cliPath) beacon.cliPath = txt.cliPath;
2585
+ beacon.gatewayPort = parseIntOrNull(txt.gatewayPort);
2586
+ beacon.sshPort = parseIntOrNull(txt.sshPort);
2587
+ if (txt.gatewayTls) {
2588
+ const raw = txt.gatewayTls.trim().toLowerCase();
2589
+ beacon.gatewayTls = raw === "1" || raw === "true" || raw === "yes";
2590
+ }
2591
+ if (txt.gatewayTlsSha256) beacon.gatewayTlsFingerprintSha256 = txt.gatewayTlsSha256;
2592
+ if (txt.role) beacon.role = txt.role;
2593
+ if (txt.transport) beacon.transport = txt.transport;
2594
+ if (!beacon.displayName) beacon.displayName = decodedInstanceName;
2595
+ return beacon;
2596
+ }
2597
+ async function discoverViaDnsSd(domain, timeoutMs, run) {
2598
+ const instances = parseDnsSdBrowse((await run([
2599
+ "dns-sd",
2600
+ "-B",
2601
+ GATEWAY_SERVICE_TYPE,
2602
+ domain
2603
+ ], { timeoutMs })).stdout);
2604
+ const results = [];
2605
+ for (const instance of instances) {
2606
+ const parsed = parseDnsSdResolve((await run([
2607
+ "dns-sd",
2608
+ "-L",
2609
+ instance,
2610
+ GATEWAY_SERVICE_TYPE,
2611
+ domain
2612
+ ], { timeoutMs })).stdout, instance);
2613
+ if (parsed) results.push({
2614
+ ...parsed,
2615
+ domain
2616
+ });
2617
+ }
2618
+ return results;
2619
+ }
2620
+ async function discoverWideAreaViaTailnetDns(domain, timeoutMs, run) {
2621
+ if (!domain || domain === "local.") return [];
2622
+ const startedAt = Date.now();
2623
+ const remainingMs = () => timeoutMs - (Date.now() - startedAt);
2624
+ const tailscaleCandidates = ["tailscale", "/Applications/Tailscale.app/Contents/MacOS/Tailscale"];
2625
+ let ips = [];
2626
+ for (const candidate of tailscaleCandidates) try {
2627
+ ips = parseTailscaleStatusIPv4s((await run([
2628
+ candidate,
2629
+ "status",
2630
+ "--json"
2631
+ ], { timeoutMs: Math.max(1, Math.min(700, remainingMs())) })).stdout);
2632
+ if (ips.length > 0) break;
2633
+ } catch {}
2634
+ if (ips.length === 0) return [];
2635
+ if (remainingMs() <= 0) return [];
2636
+ ips = ips.slice(0, 40);
2637
+ const probeName = `${GATEWAY_SERVICE_TYPE}.${domain.replace(/\.$/, "")}`;
2638
+ const concurrency = 6;
2639
+ let nextIndex = 0;
2640
+ let nameserver = null;
2641
+ let ptrs = [];
2642
+ const worker = async () => {
2643
+ while (nameserver === null) {
2644
+ const budget = remainingMs();
2645
+ if (budget <= 0) return;
2646
+ const i = nextIndex;
2647
+ nextIndex += 1;
2648
+ if (i >= ips.length) return;
2649
+ const ip = ips[i] ?? "";
2650
+ if (!ip) continue;
2651
+ try {
2652
+ const lines = parseDigShortLines((await run([
2653
+ "dig",
2654
+ "+short",
2655
+ "+time=1",
2656
+ "+tries=1",
2657
+ `@${ip}`,
2658
+ probeName,
2659
+ "PTR"
2660
+ ], { timeoutMs: Math.max(1, Math.min(250, budget)) })).stdout);
2661
+ if (lines.length === 0) continue;
2662
+ nameserver = ip;
2663
+ ptrs = lines;
2664
+ return;
2665
+ } catch {}
2666
+ }
2667
+ };
2668
+ await Promise.all(Array.from({ length: Math.min(concurrency, ips.length) }, () => worker()));
2669
+ if (!nameserver || ptrs.length === 0) return [];
2670
+ if (remainingMs() <= 0) return [];
2671
+ const nameserverArg = `@${String(nameserver)}`;
2672
+ const results = [];
2673
+ for (const ptr of ptrs) {
2674
+ const budget = remainingMs();
2675
+ if (budget <= 0) break;
2676
+ const ptrName = ptr.trim().replace(/\.$/, "");
2677
+ if (!ptrName) continue;
2678
+ const instanceName = ptrName.replace(/\.?_Synurex-gw\._tcp\..*$/, "");
2679
+ const srv = await run([
2680
+ "dig",
2681
+ "+short",
2682
+ "+time=1",
2683
+ "+tries=1",
2684
+ nameserverArg,
2685
+ ptrName,
2686
+ "SRV"
2687
+ ], { timeoutMs: Math.max(1, Math.min(350, budget)) }).catch(() => null);
2688
+ const srvParsed = srv ? parseDigSrv(srv.stdout) : null;
2689
+ if (!srvParsed) continue;
2690
+ const txtBudget = remainingMs();
2691
+ if (txtBudget <= 0) {
2692
+ results.push({
2693
+ instanceName: instanceName || ptrName,
2694
+ displayName: instanceName || ptrName,
2695
+ domain,
2696
+ host: srvParsed.host,
2697
+ port: srvParsed.port
2698
+ });
2699
+ continue;
2700
+ }
2701
+ const txt = await run([
2702
+ "dig",
2703
+ "+short",
2704
+ "+time=1",
2705
+ "+tries=1",
2706
+ nameserverArg,
2707
+ ptrName,
2708
+ "TXT"
2709
+ ], { timeoutMs: Math.max(1, Math.min(350, txtBudget)) }).catch(() => null);
2710
+ const txtTokens = txt ? parseDigTxt(txt.stdout) : [];
2711
+ const txtMap = txtTokens.length > 0 ? parseTxtTokens(txtTokens) : {};
2712
+ const beacon = {
2713
+ instanceName: instanceName || ptrName,
2714
+ displayName: txtMap.displayName || instanceName || ptrName,
2715
+ domain,
2716
+ host: srvParsed.host,
2717
+ port: srvParsed.port,
2718
+ txt: Object.keys(txtMap).length ? txtMap : void 0,
2719
+ gatewayPort: parseIntOrNull(txtMap.gatewayPort),
2720
+ sshPort: parseIntOrNull(txtMap.sshPort),
2721
+ tailnetDns: txtMap.tailnetDns || void 0,
2722
+ cliPath: txtMap.cliPath || void 0
2723
+ };
2724
+ if (txtMap.gatewayTls) {
2725
+ const raw = txtMap.gatewayTls.trim().toLowerCase();
2726
+ beacon.gatewayTls = raw === "1" || raw === "true" || raw === "yes";
2727
+ }
2728
+ if (txtMap.gatewayTlsSha256) beacon.gatewayTlsFingerprintSha256 = txtMap.gatewayTlsSha256;
2729
+ if (txtMap.role) beacon.role = txtMap.role;
2730
+ if (txtMap.transport) beacon.transport = txtMap.transport;
2731
+ results.push(beacon);
2732
+ }
2733
+ return results;
2734
+ }
2735
+ function parseAvahiBrowse(stdout) {
2736
+ const results = [];
2737
+ let current = null;
2738
+ for (const raw of stdout.split("\n")) {
2739
+ const line = raw.trimEnd();
2740
+ if (!line) continue;
2741
+ if (line.startsWith("=") && line.includes(GATEWAY_SERVICE_TYPE)) {
2742
+ if (current) results.push(current);
2743
+ const marker = ` ${GATEWAY_SERVICE_TYPE}`;
2744
+ const idx = line.indexOf(marker);
2745
+ const left = idx >= 0 ? line.slice(0, idx).trim() : line;
2746
+ const parts = left.split(/\s+/);
2747
+ const instanceName = parts.length > 3 ? parts.slice(3).join(" ") : left;
2748
+ current = {
2749
+ instanceName,
2750
+ displayName: instanceName
2751
+ };
2752
+ continue;
2753
+ }
2754
+ if (!current) continue;
2755
+ const trimmed = line.trim();
2756
+ if (trimmed.startsWith("hostname =")) {
2757
+ const match = trimmed.match(/hostname\s*=\s*\[([^\]]+)\]/);
2758
+ if (match?.[1]) current.host = match[1];
2759
+ continue;
2760
+ }
2761
+ if (trimmed.startsWith("port =")) {
2762
+ const match = trimmed.match(/port\s*=\s*\[(\d+)\]/);
2763
+ if (match?.[1]) current.port = parseIntOrNull(match[1]);
2764
+ continue;
2765
+ }
2766
+ if (trimmed.startsWith("txt =")) {
2767
+ const txt = parseTxtTokens(Array.from(trimmed.matchAll(/"([^"]*)"/g), (m) => m[1]));
2768
+ current.txt = Object.keys(txt).length ? txt : void 0;
2769
+ if (txt.displayName) current.displayName = txt.displayName;
2770
+ if (txt.lanHost) current.lanHost = txt.lanHost;
2771
+ if (txt.tailnetDns) current.tailnetDns = txt.tailnetDns;
2772
+ if (txt.cliPath) current.cliPath = txt.cliPath;
2773
+ current.gatewayPort = parseIntOrNull(txt.gatewayPort);
2774
+ current.sshPort = parseIntOrNull(txt.sshPort);
2775
+ if (txt.gatewayTls) {
2776
+ const raw = txt.gatewayTls.trim().toLowerCase();
2777
+ current.gatewayTls = raw === "1" || raw === "true" || raw === "yes";
2778
+ }
2779
+ if (txt.gatewayTlsSha256) current.gatewayTlsFingerprintSha256 = txt.gatewayTlsSha256;
2780
+ if (txt.role) current.role = txt.role;
2781
+ if (txt.transport) current.transport = txt.transport;
2782
+ }
2783
+ }
2784
+ if (current) results.push(current);
2785
+ return results;
2786
+ }
2787
+ async function discoverViaAvahi(domain, timeoutMs, run) {
2788
+ const args = [
2789
+ "avahi-browse",
2790
+ "-rt",
2791
+ GATEWAY_SERVICE_TYPE
2792
+ ];
2793
+ if (domain && domain !== "local.") args.push("-d", domain.replace(/\.$/, ""));
2794
+ return parseAvahiBrowse((await run(args, { timeoutMs })).stdout).map((beacon) => ({
2795
+ ...beacon,
2796
+ domain
2797
+ }));
2798
+ }
2799
+ async function discoverGatewayBeacons(opts = {}) {
2800
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
2801
+ const platform = opts.platform ?? process.platform;
2802
+ const run = opts.run ?? runCommandWithTimeout;
2803
+ const wideAreaDomain = resolveWideAreaDiscoveryDomain({ configDomain: opts.wideAreaDomain });
2804
+ const domainsRaw = Array.isArray(opts.domains) ? opts.domains : [];
2805
+ const defaultDomains = ["local.", ...wideAreaDomain ? [wideAreaDomain] : []];
2806
+ const domains = (domainsRaw.length > 0 ? domainsRaw : defaultDomains).map((d) => String(d).trim()).filter(Boolean).map((d) => d.endsWith(".") ? d : `${d}.`);
2807
+ try {
2808
+ if (platform === "darwin") {
2809
+ const discovered = (await Promise.allSettled(domains.map(async (domain) => await discoverViaDnsSd(domain, timeoutMs, run)))).flatMap((r) => r.status === "fulfilled" ? r.value : []);
2810
+ const wantsWideArea = wideAreaDomain ? domains.includes(wideAreaDomain) : false;
2811
+ const hasWideArea = wideAreaDomain ? discovered.some((b) => b.domain === wideAreaDomain) : false;
2812
+ if (wantsWideArea && !hasWideArea && wideAreaDomain) {
2813
+ const fallback = await discoverWideAreaViaTailnetDns(wideAreaDomain, timeoutMs, run).catch(() => []);
2814
+ return [...discovered, ...fallback];
2815
+ }
2816
+ return discovered;
2817
+ }
2818
+ if (platform === "linux") return (await Promise.allSettled(domains.map(async (domain) => await discoverViaAvahi(domain, timeoutMs, run)))).flatMap((r) => r.status === "fulfilled" ? r.value : []);
2819
+ } catch {
2820
+ return [];
2821
+ }
2822
+ return [];
2823
+ }
2824
+
2825
+ //#endregion
2826
+ //#region src/commands/onboard-remote.ts
2827
+ const DEFAULT_GATEWAY_URL = "ws://127.0.0.1:18789";
2828
+ function pickHost(beacon) {
2829
+ return beacon.tailnetDns || beacon.lanHost || beacon.host;
2830
+ }
2831
+ function buildLabel(beacon) {
2832
+ const host = pickHost(beacon);
2833
+ const port = beacon.gatewayPort ?? beacon.port ?? 18789;
2834
+ return `${beacon.displayName ?? beacon.instanceName} (${host ? `${host}:${port}` : "host unknown"})`;
2835
+ }
2836
+ function ensureWsUrl(value) {
2837
+ const trimmed = value.trim();
2838
+ if (!trimmed) return DEFAULT_GATEWAY_URL;
2839
+ return trimmed;
2840
+ }
2841
+ async function promptRemoteGatewayConfig(cfg, prompter) {
2842
+ let selectedBeacon = null;
2843
+ let suggestedUrl = cfg.gateway?.remote?.url ?? DEFAULT_GATEWAY_URL;
2844
+ const hasBonjourTool = await detectBinary("dns-sd") || await detectBinary("avahi-browse");
2845
+ const wantsDiscover = hasBonjourTool ? await prompter.confirm({
2846
+ message: "Discover gateway on LAN (Bonjour)?",
2847
+ initialValue: true
2848
+ }) : false;
2849
+ if (!hasBonjourTool) await prompter.note(["Bonjour discovery requires dns-sd (macOS) or avahi-browse (Linux).", "Docs: https://docs.synurex.com/gateway/discovery"].join("\n"), "Discovery");
2850
+ if (wantsDiscover) {
2851
+ const wideAreaDomain = resolveWideAreaDiscoveryDomain({ configDomain: cfg.discovery?.wideArea?.domain });
2852
+ const spin = prompter.progress("Searching for gateways…");
2853
+ const beacons = await discoverGatewayBeacons({
2854
+ timeoutMs: 2e3,
2855
+ wideAreaDomain
2856
+ });
2857
+ spin.stop(beacons.length > 0 ? `Found ${beacons.length} gateway(s)` : "No gateways found");
2858
+ if (beacons.length > 0) {
2859
+ const selection = await prompter.select({
2860
+ message: "Select gateway",
2861
+ options: [...beacons.map((beacon, index) => ({
2862
+ value: String(index),
2863
+ label: buildLabel(beacon)
2864
+ })), {
2865
+ value: "manual",
2866
+ label: "Enter URL manually"
2867
+ }]
2868
+ });
2869
+ if (selection !== "manual") {
2870
+ const idx = Number.parseInt(String(selection), 10);
2871
+ selectedBeacon = Number.isFinite(idx) ? beacons[idx] ?? null : null;
2872
+ }
2873
+ }
2874
+ }
2875
+ if (selectedBeacon) {
2876
+ const host = pickHost(selectedBeacon);
2877
+ const port = selectedBeacon.gatewayPort ?? 18789;
2878
+ if (host) if (await prompter.select({
2879
+ message: "Connection method",
2880
+ options: [{
2881
+ value: "direct",
2882
+ label: `Direct gateway WS (${host}:${port})`
2883
+ }, {
2884
+ value: "ssh",
2885
+ label: "SSH tunnel (loopback)"
2886
+ }]
2887
+ }) === "direct") suggestedUrl = `ws://${host}:${port}`;
2888
+ else {
2889
+ suggestedUrl = DEFAULT_GATEWAY_URL;
2890
+ await prompter.note([
2891
+ "Start a tunnel before using the CLI:",
2892
+ `ssh -N -L 18789:127.0.0.1:18789 <user>@${host}${selectedBeacon.sshPort ? ` -p ${selectedBeacon.sshPort}` : ""}`,
2893
+ "Docs: https://docs.synurex.com/gateway/remote"
2894
+ ].join("\n"), "SSH tunnel");
2895
+ }
2896
+ }
2897
+ const urlInput = await prompter.text({
2898
+ message: "Gateway WebSocket URL",
2899
+ initialValue: suggestedUrl,
2900
+ validate: (value) => String(value).trim().startsWith("ws://") || String(value).trim().startsWith("wss://") ? void 0 : "URL must start with ws:// or wss://"
2901
+ });
2902
+ const url = ensureWsUrl(String(urlInput));
2903
+ const authChoice = await prompter.select({
2904
+ message: "Gateway auth",
2905
+ options: [{
2906
+ value: "token",
2907
+ label: "Token (recommended)"
2908
+ }, {
2909
+ value: "off",
2910
+ label: "No auth"
2911
+ }]
2912
+ });
2913
+ let token = cfg.gateway?.remote?.token ?? "";
2914
+ if (authChoice === "token") token = String(await prompter.text({
2915
+ message: "Gateway token",
2916
+ initialValue: token,
2917
+ validate: (value) => value?.trim() ? void 0 : "Required"
2918
+ })).trim();
2919
+ else token = "";
2920
+ return {
2921
+ ...cfg,
2922
+ gateway: {
2923
+ ...cfg.gateway,
2924
+ mode: "remote",
2925
+ remote: {
2926
+ url,
2927
+ token: token || void 0
2928
+ }
2929
+ }
2930
+ };
2931
+ }
2932
+
2933
+ //#endregion
2934
+ //#region src/agents/skills-install.ts
2935
+ function isNodeReadableStream(value) {
2936
+ return Boolean(value && typeof value.pipe === "function");
2937
+ }
2938
+ function summarizeInstallOutput(text) {
2939
+ const raw = text.trim();
2940
+ if (!raw) return;
2941
+ const lines = raw.split("\n").map((line) => line.trim()).filter(Boolean);
2942
+ if (lines.length === 0) return;
2943
+ const preferred = lines.find((line) => /^error\b/i.test(line)) ?? lines.find((line) => /\b(err!|error:|failed)\b/i.test(line)) ?? lines.at(-1);
2944
+ if (!preferred) return;
2945
+ const normalized = preferred.replace(/\s+/g, " ").trim();
2946
+ const maxLen = 200;
2947
+ return normalized.length > maxLen ? `${normalized.slice(0, maxLen - 1)}…` : normalized;
2948
+ }
2949
+ function formatInstallFailureMessage(result) {
2950
+ const code = typeof result.code === "number" ? `exit ${result.code}` : "unknown exit";
2951
+ const summary = summarizeInstallOutput(result.stderr) ?? summarizeInstallOutput(result.stdout);
2952
+ if (!summary) return `Install failed (${code})`;
2953
+ return `Install failed (${code}): ${summary}`;
2954
+ }
2955
+ function withWarnings(result, warnings) {
2956
+ if (warnings.length === 0) return result;
2957
+ return {
2958
+ ...result,
2959
+ warnings: warnings.slice()
2960
+ };
2961
+ }
2962
+ function formatScanFindingDetail(rootDir, finding) {
2963
+ const relativePath = path.relative(rootDir, finding.file);
2964
+ const filePath = relativePath && relativePath !== "." && !relativePath.startsWith("..") ? relativePath : path.basename(finding.file);
2965
+ return `${finding.message} (${filePath}:${finding.line})`;
2966
+ }
2967
+ async function collectSkillInstallScanWarnings(entry) {
2968
+ const warnings = [];
2969
+ const skillName = entry.skill.name;
2970
+ const skillDir = path.resolve(entry.skill.baseDir);
2971
+ try {
2972
+ const summary = await scanDirectoryWithSummary(skillDir);
2973
+ if (summary.critical > 0) {
2974
+ const criticalDetails = summary.findings.filter((finding) => finding.severity === "critical").map((finding) => formatScanFindingDetail(skillDir, finding)).join("; ");
2975
+ warnings.push(`WARNING: Skill "${skillName}" contains dangerous code patterns: ${criticalDetails}`);
2976
+ } else if (summary.warn > 0) warnings.push(`Skill "${skillName}" has ${summary.warn} suspicious code pattern(s). Run "synurex security audit --deep" for details.`);
2977
+ } catch (err) {
2978
+ warnings.push(`Skill "${skillName}" code safety scan failed (${String(err)}). Installation continues; run "synurex security audit --deep" after install.`);
2979
+ }
2980
+ return warnings;
2981
+ }
2982
+ function resolveInstallId(spec, index) {
2983
+ return (spec.id ?? `${spec.kind}-${index}`).trim();
2984
+ }
2985
+ function findInstallSpec(entry, installId) {
2986
+ const specs = entry.metadata?.install ?? [];
2987
+ for (const [index, spec] of specs.entries()) if (resolveInstallId(spec, index) === installId) return spec;
2988
+ }
2989
+ function buildNodeInstallCommand(packageName, prefs) {
2990
+ switch (prefs.nodeManager) {
2991
+ case "pnpm": return [
2992
+ "pnpm",
2993
+ "add",
2994
+ "-g",
2995
+ packageName
2996
+ ];
2997
+ case "yarn": return [
2998
+ "yarn",
2999
+ "global",
3000
+ "add",
3001
+ packageName
3002
+ ];
3003
+ case "bun": return [
3004
+ "bun",
3005
+ "add",
3006
+ "-g",
3007
+ packageName
3008
+ ];
3009
+ default: return [
3010
+ "npm",
3011
+ "install",
3012
+ "-g",
3013
+ packageName
3014
+ ];
3015
+ }
3016
+ }
3017
+ function buildInstallCommand(spec, prefs) {
3018
+ switch (spec.kind) {
3019
+ case "brew":
3020
+ if (!spec.formula) return {
3021
+ argv: null,
3022
+ error: "missing brew formula"
3023
+ };
3024
+ return { argv: [
3025
+ "brew",
3026
+ "install",
3027
+ spec.formula
3028
+ ] };
3029
+ case "node":
3030
+ if (!spec.package) return {
3031
+ argv: null,
3032
+ error: "missing node package"
3033
+ };
3034
+ return { argv: buildNodeInstallCommand(spec.package, prefs) };
3035
+ case "go":
3036
+ if (!spec.module) return {
3037
+ argv: null,
3038
+ error: "missing go module"
3039
+ };
3040
+ return { argv: [
3041
+ "go",
3042
+ "install",
3043
+ spec.module
3044
+ ] };
3045
+ case "uv":
3046
+ if (!spec.package) return {
3047
+ argv: null,
3048
+ error: "missing uv package"
3049
+ };
3050
+ return { argv: [
3051
+ "uv",
3052
+ "tool",
3053
+ "install",
3054
+ spec.package
3055
+ ] };
3056
+ case "download": return {
3057
+ argv: null,
3058
+ error: "download install handled separately"
3059
+ };
3060
+ default: return {
3061
+ argv: null,
3062
+ error: "unsupported installer"
3063
+ };
3064
+ }
3065
+ }
3066
+ function resolveDownloadTargetDir(entry, spec) {
3067
+ if (spec.targetDir?.trim()) return resolveUserPath(spec.targetDir);
3068
+ const key = resolveSkillKey(entry.skill, entry);
3069
+ return path.join(CONFIG_DIR, "tools", key);
3070
+ }
3071
+ function resolveArchiveType(spec, filename) {
3072
+ const explicit = spec.archive?.trim().toLowerCase();
3073
+ if (explicit) return explicit;
3074
+ const lower = filename.toLowerCase();
3075
+ if (lower.endsWith(".tar.gz") || lower.endsWith(".tgz")) return "tar.gz";
3076
+ if (lower.endsWith(".tar.bz2") || lower.endsWith(".tbz2")) return "tar.bz2";
3077
+ if (lower.endsWith(".zip")) return "zip";
3078
+ }
3079
+ async function downloadFile(url, destPath, timeoutMs) {
3080
+ const { response, release } = await fetchWithSsrFGuard({
3081
+ url,
3082
+ timeoutMs: Math.max(1e3, timeoutMs)
3083
+ });
3084
+ try {
3085
+ if (!response.ok || !response.body) throw new Error(`Download failed (${response.status} ${response.statusText})`);
3086
+ await ensureDir(path.dirname(destPath));
3087
+ const file = fs.createWriteStream(destPath);
3088
+ const body = response.body;
3089
+ await pipeline(isNodeReadableStream(body) ? body : Readable.fromWeb(body), file);
3090
+ return { bytes: (await fs.promises.stat(destPath)).size };
3091
+ } finally {
3092
+ await release();
3093
+ }
3094
+ }
3095
+ async function extractArchive(params) {
3096
+ const { archivePath, archiveType, targetDir, stripComponents, timeoutMs } = params;
3097
+ if (archiveType === "zip") {
3098
+ if (!hasBinary("unzip")) return {
3099
+ stdout: "",
3100
+ stderr: "unzip not found on PATH",
3101
+ code: null
3102
+ };
3103
+ return await runCommandWithTimeout([
3104
+ "unzip",
3105
+ "-q",
3106
+ archivePath,
3107
+ "-d",
3108
+ targetDir
3109
+ ], { timeoutMs });
3110
+ }
3111
+ if (!hasBinary("tar")) return {
3112
+ stdout: "",
3113
+ stderr: "tar not found on PATH",
3114
+ code: null
3115
+ };
3116
+ const argv = [
3117
+ "tar",
3118
+ "xf",
3119
+ archivePath,
3120
+ "-C",
3121
+ targetDir
3122
+ ];
3123
+ if (typeof stripComponents === "number" && Number.isFinite(stripComponents)) argv.push("--strip-components", String(Math.max(0, Math.floor(stripComponents))));
3124
+ return await runCommandWithTimeout(argv, { timeoutMs });
3125
+ }
3126
+ async function installDownloadSpec(params) {
3127
+ const { entry, spec, timeoutMs } = params;
3128
+ const url = spec.url?.trim();
3129
+ if (!url) return {
3130
+ ok: false,
3131
+ message: "missing download url",
3132
+ stdout: "",
3133
+ stderr: "",
3134
+ code: null
3135
+ };
3136
+ let filename = "";
3137
+ try {
3138
+ const parsed = new URL(url);
3139
+ filename = path.basename(parsed.pathname);
3140
+ } catch {
3141
+ filename = path.basename(url);
3142
+ }
3143
+ if (!filename) filename = "download";
3144
+ const targetDir = resolveDownloadTargetDir(entry, spec);
3145
+ await ensureDir(targetDir);
3146
+ const archivePath = path.join(targetDir, filename);
3147
+ let downloaded = 0;
3148
+ try {
3149
+ downloaded = (await downloadFile(url, archivePath, timeoutMs)).bytes;
3150
+ } catch (err) {
3151
+ const message = err instanceof Error ? err.message : String(err);
3152
+ return {
3153
+ ok: false,
3154
+ message,
3155
+ stdout: "",
3156
+ stderr: message,
3157
+ code: null
3158
+ };
3159
+ }
3160
+ const archiveType = resolveArchiveType(spec, filename);
3161
+ if (!(spec.extract ?? Boolean(archiveType))) return {
3162
+ ok: true,
3163
+ message: `Downloaded to ${archivePath}`,
3164
+ stdout: `downloaded=${downloaded}`,
3165
+ stderr: "",
3166
+ code: 0
3167
+ };
3168
+ if (!archiveType) return {
3169
+ ok: false,
3170
+ message: "extract requested but archive type could not be detected",
3171
+ stdout: "",
3172
+ stderr: "",
3173
+ code: null
3174
+ };
3175
+ const extractResult = await extractArchive({
3176
+ archivePath,
3177
+ archiveType,
3178
+ targetDir,
3179
+ stripComponents: spec.stripComponents,
3180
+ timeoutMs
3181
+ });
3182
+ const success = extractResult.code === 0;
3183
+ return {
3184
+ ok: success,
3185
+ message: success ? `Downloaded and extracted to ${targetDir}` : formatInstallFailureMessage(extractResult),
3186
+ stdout: extractResult.stdout.trim(),
3187
+ stderr: extractResult.stderr.trim(),
3188
+ code: extractResult.code
3189
+ };
3190
+ }
3191
+ async function resolveBrewBinDir(timeoutMs, brewExe) {
3192
+ const exe = brewExe ?? (hasBinary("brew") ? "brew" : resolveBrewExecutable());
3193
+ if (!exe) return;
3194
+ const prefixResult = await runCommandWithTimeout([exe, "--prefix"], { timeoutMs: Math.min(timeoutMs, 3e4) });
3195
+ if (prefixResult.code === 0) {
3196
+ const prefix = prefixResult.stdout.trim();
3197
+ if (prefix) return path.join(prefix, "bin");
3198
+ }
3199
+ const envPrefix = process.env.HOMEBREW_PREFIX?.trim();
3200
+ if (envPrefix) return path.join(envPrefix, "bin");
3201
+ for (const candidate of ["/opt/homebrew/bin", "/usr/local/bin"]) try {
3202
+ if (fs.existsSync(candidate)) return candidate;
3203
+ } catch {}
3204
+ }
3205
+ async function installSkill(params) {
3206
+ const timeoutMs = Math.min(Math.max(params.timeoutMs ?? 3e5, 1e3), 9e5);
3207
+ const entry = loadWorkspaceSkillEntries(resolveUserPath(params.workspaceDir)).find((item) => item.skill.name === params.skillName);
3208
+ if (!entry) return {
3209
+ ok: false,
3210
+ message: `Skill not found: ${params.skillName}`,
3211
+ stdout: "",
3212
+ stderr: "",
3213
+ code: null
3214
+ };
3215
+ const spec = findInstallSpec(entry, params.installId);
3216
+ const warnings = await collectSkillInstallScanWarnings(entry);
3217
+ if (!spec) return withWarnings({
3218
+ ok: false,
3219
+ message: `Installer not found: ${params.installId}`,
3220
+ stdout: "",
3221
+ stderr: "",
3222
+ code: null
3223
+ }, warnings);
3224
+ if (spec.kind === "download") return withWarnings(await installDownloadSpec({
3225
+ entry,
3226
+ spec,
3227
+ timeoutMs
3228
+ }), warnings);
3229
+ const command = buildInstallCommand(spec, resolveSkillsInstallPreferences(params.config));
3230
+ if (command.error) return withWarnings({
3231
+ ok: false,
3232
+ message: command.error,
3233
+ stdout: "",
3234
+ stderr: "",
3235
+ code: null
3236
+ }, warnings);
3237
+ const brewExe = hasBinary("brew") ? "brew" : resolveBrewExecutable();
3238
+ if (spec.kind === "brew" && !brewExe) return withWarnings({
3239
+ ok: false,
3240
+ message: "brew not installed",
3241
+ stdout: "",
3242
+ stderr: "",
3243
+ code: null
3244
+ }, warnings);
3245
+ if (spec.kind === "uv" && !hasBinary("uv")) if (brewExe) {
3246
+ const brewResult = await runCommandWithTimeout([
3247
+ brewExe,
3248
+ "install",
3249
+ "uv"
3250
+ ], { timeoutMs });
3251
+ if (brewResult.code !== 0) return withWarnings({
3252
+ ok: false,
3253
+ message: "Failed to install uv (brew)",
3254
+ stdout: brewResult.stdout.trim(),
3255
+ stderr: brewResult.stderr.trim(),
3256
+ code: brewResult.code
3257
+ }, warnings);
3258
+ } else return withWarnings({
3259
+ ok: false,
3260
+ message: "uv not installed (install via brew)",
3261
+ stdout: "",
3262
+ stderr: "",
3263
+ code: null
3264
+ }, warnings);
3265
+ if (!command.argv || command.argv.length === 0) return withWarnings({
3266
+ ok: false,
3267
+ message: "invalid install command",
3268
+ stdout: "",
3269
+ stderr: "",
3270
+ code: null
3271
+ }, warnings);
3272
+ if (spec.kind === "brew" && brewExe && command.argv[0] === "brew") command.argv[0] = brewExe;
3273
+ if (spec.kind === "go" && !hasBinary("go")) if (brewExe) {
3274
+ const brewResult = await runCommandWithTimeout([
3275
+ brewExe,
3276
+ "install",
3277
+ "go"
3278
+ ], { timeoutMs });
3279
+ if (brewResult.code !== 0) return withWarnings({
3280
+ ok: false,
3281
+ message: "Failed to install go (brew)",
3282
+ stdout: brewResult.stdout.trim(),
3283
+ stderr: brewResult.stderr.trim(),
3284
+ code: brewResult.code
3285
+ }, warnings);
3286
+ } else return withWarnings({
3287
+ ok: false,
3288
+ message: "go not installed (install via brew)",
3289
+ stdout: "",
3290
+ stderr: "",
3291
+ code: null
3292
+ }, warnings);
3293
+ let env;
3294
+ if (spec.kind === "go" && brewExe) {
3295
+ const brewBin = await resolveBrewBinDir(timeoutMs, brewExe);
3296
+ if (brewBin) env = { GOBIN: brewBin };
3297
+ }
3298
+ const result = await (async () => {
3299
+ const argv = command.argv;
3300
+ if (!argv || argv.length === 0) return {
3301
+ code: null,
3302
+ stdout: "",
3303
+ stderr: "invalid install command"
3304
+ };
3305
+ try {
3306
+ return await runCommandWithTimeout(argv, {
3307
+ timeoutMs,
3308
+ env
3309
+ });
3310
+ } catch (err) {
3311
+ return {
3312
+ code: null,
3313
+ stdout: "",
3314
+ stderr: err instanceof Error ? err.message : String(err)
3315
+ };
3316
+ }
3317
+ })();
3318
+ const success = result.code === 0;
3319
+ return withWarnings({
3320
+ ok: success,
3321
+ message: success ? "Installed" : formatInstallFailureMessage(result),
3322
+ stdout: result.stdout.trim(),
3323
+ stderr: result.stderr.trim(),
3324
+ code: result.code
3325
+ }, warnings);
3326
+ }
3327
+
3328
+ //#endregion
3329
+ //#region src/commands/onboard-skills.ts
3330
+ function summarizeInstallFailure(message) {
3331
+ const cleaned = message.replace(/^Install failed(?:\s*\([^)]*\))?\s*:?\s*/i, "").trim();
3332
+ if (!cleaned) return;
3333
+ const maxLen = 140;
3334
+ return cleaned.length > maxLen ? `${cleaned.slice(0, maxLen - 1)}…` : cleaned;
3335
+ }
3336
+ function formatSkillHint(skill) {
3337
+ const desc = skill.description?.trim();
3338
+ const installLabel = skill.install[0]?.label?.trim();
3339
+ const combined = desc && installLabel ? `${desc} — ${installLabel}` : desc || installLabel;
3340
+ if (!combined) return "install";
3341
+ const maxLen = 90;
3342
+ return combined.length > maxLen ? `${combined.slice(0, maxLen - 1)}…` : combined;
3343
+ }
3344
+ function upsertSkillEntry(cfg, skillKey, patch) {
3345
+ const entries = { ...cfg.skills?.entries };
3346
+ entries[skillKey] = {
3347
+ ...entries[skillKey] ?? {},
3348
+ ...patch
3349
+ };
3350
+ return {
3351
+ ...cfg,
3352
+ skills: {
3353
+ ...cfg.skills,
3354
+ entries
3355
+ }
3356
+ };
3357
+ }
3358
+ async function setupSkills(cfg, workspaceDir, runtime, prompter) {
3359
+ const report = buildWorkspaceSkillStatus(workspaceDir, { config: cfg });
3360
+ const eligible = report.skills.filter((s) => s.eligible);
3361
+ const missing = report.skills.filter((s) => !s.eligible && !s.disabled && !s.blockedByAllowlist);
3362
+ const blocked = report.skills.filter((s) => s.blockedByAllowlist);
3363
+ const needsBrewPrompt = process.platform !== "win32" && report.skills.some((skill) => skill.install.some((option) => option.kind === "brew")) && !await detectBinary("brew");
3364
+ await prompter.note([
3365
+ `Eligible: ${eligible.length}`,
3366
+ `Missing requirements: ${missing.length}`,
3367
+ `Blocked by allowlist: ${blocked.length}`
3368
+ ].join("\n"), "Skills status");
3369
+ if (!await prompter.confirm({
3370
+ message: "Configure skills now? (recommended)",
3371
+ initialValue: true
3372
+ })) return cfg;
3373
+ if (needsBrewPrompt) {
3374
+ await prompter.note(["Many skill dependencies are shipped via Homebrew.", "Without brew, you'll need to build from source or download releases manually."].join("\n"), "Homebrew recommended");
3375
+ if (await prompter.confirm({
3376
+ message: "Show Homebrew install command?",
3377
+ initialValue: true
3378
+ })) await prompter.note(["Run:", "/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""].join("\n"), "Homebrew install");
3379
+ }
3380
+ const nodeManager = await prompter.select({
3381
+ message: "Preferred node manager for skill installs",
3382
+ options: resolveNodeManagerOptions()
3383
+ });
3384
+ let next = {
3385
+ ...cfg,
3386
+ skills: {
3387
+ ...cfg.skills,
3388
+ install: {
3389
+ ...cfg.skills?.install,
3390
+ nodeManager
3391
+ }
3392
+ }
3393
+ };
3394
+ const installable = missing.filter((skill) => skill.install.length > 0 && skill.missing.bins.length > 0);
3395
+ if (installable.length > 0) {
3396
+ const selected = (await prompter.multiselect({
3397
+ message: "Install missing skill dependencies",
3398
+ options: [{
3399
+ value: "__skip__",
3400
+ label: "Skip for now",
3401
+ hint: "Continue without installing dependencies"
3402
+ }, ...installable.map((skill) => ({
3403
+ value: skill.name,
3404
+ label: `${skill.emoji ?? "🧩"} ${skill.name}`,
3405
+ hint: formatSkillHint(skill)
3406
+ }))]
3407
+ })).filter((name) => name !== "__skip__");
3408
+ for (const name of selected) {
3409
+ const target = installable.find((s) => s.name === name);
3410
+ if (!target || target.install.length === 0) continue;
3411
+ const installId = target.install[0]?.id;
3412
+ if (!installId) continue;
3413
+ const spin = prompter.progress(`Installing ${name}…`);
3414
+ const result = await installSkill({
3415
+ workspaceDir,
3416
+ skillName: target.name,
3417
+ installId,
3418
+ config: next
3419
+ });
3420
+ const warnings = result.warnings ?? [];
3421
+ if (result.ok) {
3422
+ spin.stop(warnings.length > 0 ? `Installed ${name} (with warnings)` : `Installed ${name}`);
3423
+ for (const warning of warnings) runtime.log(warning);
3424
+ continue;
3425
+ }
3426
+ const code = result.code == null ? "" : ` (exit ${result.code})`;
3427
+ const detail = summarizeInstallFailure(result.message);
3428
+ spin.stop(`Install failed: ${name}${code}${detail ? ` — ${detail}` : ""}`);
3429
+ for (const warning of warnings) runtime.log(warning);
3430
+ if (result.stderr) runtime.log(result.stderr.trim());
3431
+ else if (result.stdout) runtime.log(result.stdout.trim());
3432
+ runtime.log(`Tip: run \`${formatCliCommand("synurex doctor")}\` to review skills + requirements.`);
3433
+ runtime.log("Docs: https://docs.synurex.com/skills");
3434
+ }
3435
+ }
3436
+ for (const skill of missing) {
3437
+ if (!skill.primaryEnv || skill.missing.env.length === 0) continue;
3438
+ if (!await prompter.confirm({
3439
+ message: `Set ${skill.primaryEnv} for ${skill.name}?`,
3440
+ initialValue: false
3441
+ })) continue;
3442
+ const apiKey = String(await prompter.text({
3443
+ message: `Enter ${skill.primaryEnv}`,
3444
+ validate: (value) => value?.trim() ? void 0 : "Required"
3445
+ }));
3446
+ next = upsertSkillEntry(next, skill.skillKey, { apiKey: apiKey.trim() });
3447
+ }
3448
+ return next;
3449
+ }
3450
+
3451
+ //#endregion
3452
+ export { applyModelAllowlist as a, promptDefaultModel as c, warnIfModelConfigLooksOff as d, applyAuthChoice as f, promptAuthChoiceGrouped as g, applyGoogleGeminiModelDefault as h, discoverGatewayBeacons as i, promptModelAllowlist as l, upsertSharedEnvVar as m, installSkill as n, applyModelFallbacksFromSelection as o, applyOpenAIConfig as p, promptRemoteGatewayConfig as r, applyPrimaryModel as s, setupSkills as t, resolvePreferredProviderForAuthChoice as u };