remoteclaw 0.1.0-next.da482d8 → 0.1.0-next.db8a792

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 (1020) hide show
  1. package/dist/accounts-BZ2kR_Ij.js +47 -0
  2. package/dist/accounts-Bi4rFQG5.js +272 -0
  3. package/dist/accounts-Bpk-loA6.js +47 -0
  4. package/dist/accounts-D1CBpsaa.js +32 -0
  5. package/dist/accounts-DAdUdbPk.js +36 -0
  6. package/dist/accounts-WYyfAiie.js +270 -0
  7. package/dist/accounts-zQKMwnvt.js +36 -0
  8. package/dist/ack-reactions-B1l-vKPr.js +621 -0
  9. package/dist/ack-reactions-BnG0DLMu.js +621 -0
  10. package/dist/acp-cli-Btx71t69.js +1319 -0
  11. package/dist/acp-cli-DVQMjl0p.js +1324 -0
  12. package/dist/active-listener-BfN4RKlA.js +37 -0
  13. package/dist/active-listener-Bq7ckjOV.js +37 -0
  14. package/dist/agent-D2IwuL6g.js +688 -0
  15. package/dist/agent-WaE2mXI1.js +687 -0
  16. package/dist/agent-helpers-BcaiJFiG.js +400 -0
  17. package/dist/agent-scope-DVvX_nkQ.js +116 -0
  18. package/dist/agents-BwnT7jca.js +760 -0
  19. package/dist/agents.config-Dorm30BQ.js +116 -0
  20. package/dist/audio-B1lTyRqS.js +43 -0
  21. package/dist/audio-e0dFnrn8.js +43 -0
  22. package/dist/audit-DZvqycbG.js +3150 -0
  23. package/dist/audit-Mit73dYD.js +3150 -0
  24. package/dist/auth-C-XX0Tdt.js +314 -0
  25. package/dist/auth-D8--b01l.js +315 -0
  26. package/dist/auth-DJ7XEBDO.js +448 -0
  27. package/dist/auth-otyjXf9l.js +448 -0
  28. package/dist/banner-DSE-i7gH.js +294 -0
  29. package/dist/binaries-BSjilwX-.js +13 -0
  30. package/dist/bindings-DFTxQj8x.js +69 -0
  31. package/dist/bonjour-discovery-BnxTMHRd.js +378 -0
  32. package/dist/bonjour-discovery-CVJYHT3g.js +378 -0
  33. package/dist/boot/handler.js +28 -44
  34. package/dist/browser-cli-BR2pZWTC.js +1694 -0
  35. package/dist/browser-cli-I0kfR7FV.js +1690 -0
  36. package/dist/build-info.json +3 -3
  37. package/dist/call-Ck7ysmEl.js +517 -0
  38. package/dist/call-MN6mCJEB.js +518 -0
  39. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  40. package/dist/catalog-Bt9EM4sK.js +185 -0
  41. package/dist/catalog-BtUvWKd9.js +185 -0
  42. package/dist/channel-account-context-BLQq9NKz.js +133 -0
  43. package/dist/channel-account-context-CaCzVa76.js +133 -0
  44. package/dist/channel-activity-BatlvP_U.js +292 -0
  45. package/dist/channel-activity-DHVMMb2x.js +94 -0
  46. package/dist/channel-activity-DtRx3b0W.js +94 -0
  47. package/dist/channel-options-C6kT3nXB.js +32 -0
  48. package/dist/channel-options-CbgR_vsp.js +33 -0
  49. package/dist/channel-selection-CzbrpDPd.js +51 -0
  50. package/dist/channel-selection-Xv5UFxOx.js +51 -0
  51. package/dist/channel-web-DfDokU69.js +2134 -0
  52. package/dist/channel-web-DtvksSuY.js +2132 -0
  53. package/dist/channels-cli-BmdCVX6O.js +1435 -0
  54. package/dist/channels-cli-CrAZpaiN.js +1439 -0
  55. package/dist/channels-status-issues-B77y-TLr.js +18 -0
  56. package/dist/channels-status-issues-COECL8nx.js +18 -0
  57. package/dist/chrome-Cr5wmMk8.js +1733 -0
  58. package/dist/chrome-YBrnJN-g.js +1732 -0
  59. package/dist/chunk-CrfQ_O--.js +341 -0
  60. package/dist/chunk-DFBUmlXU.js +341 -0
  61. package/dist/clack-prompter-CFNKgQXx.js +122 -0
  62. package/dist/clack-prompter-DDlR2e34.js +121 -0
  63. package/dist/cli/daemon-cli.js +1 -1
  64. package/dist/cli-BbOinSy6.js +130 -0
  65. package/dist/cli-DuvHXQ5h.js +134 -0
  66. package/dist/client-BZeatr3g.js +2316 -0
  67. package/dist/client-Bc9JFAwL.js +2316 -0
  68. package/dist/clipboard-Com-8GBg.js +31 -0
  69. package/dist/clipboard-J_9AABIu.js +31 -0
  70. package/dist/command-format-CMAQa4dB.js +32 -0
  71. package/dist/command-format-KkslAzwV.js +18 -0
  72. package/dist/command-logger/handler.js +1 -1
  73. package/dist/command-registry-BJnVtHo0.js +215 -0
  74. package/dist/commands-ijxtne0J.js +41 -0
  75. package/dist/commands-kZtQfqDl.js +41 -0
  76. package/dist/commands-registry-BrBtH2_B.js +891 -0
  77. package/dist/commands-registry-xZoSouba.js +892 -0
  78. package/dist/common-6D7nhDP-.js +156 -0
  79. package/dist/common-B4cjsvqP.js +156 -0
  80. package/dist/completion-cli-CpUq9QC3.js +452 -0
  81. package/dist/completion-cli-De4umD_N.js +452 -0
  82. package/dist/config-C_WcTz_O.js +4231 -0
  83. package/dist/config-DfcqHTH-.js +4229 -0
  84. package/dist/config-cli-C7rq2n_m.js +243 -0
  85. package/dist/config-cli-VToCKln2.js +247 -0
  86. package/dist/config-guard-BlAcGEao.js +75 -0
  87. package/dist/config-guard-C-h_KIeI.js +99 -0
  88. package/dist/config-validation-C0YXR2dY.js +18 -0
  89. package/dist/config-validation-DDYBTmxT.js +18 -0
  90. package/dist/configure-Bkre1zEB.js +891 -0
  91. package/dist/configure-ifuEamRQ.js +889 -0
  92. package/dist/control-auth-DK6cIBzl.js +397 -0
  93. package/dist/control-auth-DQ8bfDMk.js +397 -0
  94. package/dist/control-ui-assets-DLEWfed6.js +186 -0
  95. package/dist/control-ui-assets-DVhkAyhv.js +186 -0
  96. package/dist/conversation-label-HuHoShPF.js +36 -0
  97. package/dist/conversation-label-L0QTtKji.js +36 -0
  98. package/dist/cron-cli-DnxnTi83.js +498 -0
  99. package/dist/cron-cli-yqcBkqZT.js +494 -0
  100. package/dist/daemon-cli-CmQYq8uO.js +735 -0
  101. package/dist/daemon-cli-_OIRoswC.js +737 -0
  102. package/dist/daemon-cli.js +34 -69
  103. package/dist/daemon-install-BEgffqDj.js +56 -0
  104. package/dist/daemon-install-DAorzotp.js +60 -0
  105. package/dist/daemon-install-helpers-B82uvJjJ.js +504 -0
  106. package/dist/daemon-install-helpers-BhL2Gh4l.js +504 -0
  107. package/dist/deliver-CCvDBk5c.js +481 -0
  108. package/dist/deliver-CqKw0wFi.js +481 -0
  109. package/dist/delivery-queue-CK7VnUJf.js +244 -0
  110. package/dist/delivery-queue-DMeQchpT.js +244 -0
  111. package/dist/devices-cli-C6UAfRV_.js +323 -0
  112. package/dist/devices-cli-Le-isdZB.js +319 -0
  113. package/dist/diagnostics-BhFwk6F3.js +35 -0
  114. package/dist/diagnostics-BtaQtaVR.js +35 -0
  115. package/dist/directory-cli-BqMfX5og.js +220 -0
  116. package/dist/directory-cli-DD72TTD4.js +224 -0
  117. package/dist/dispatcher-BLC2WYZv.js +173 -0
  118. package/dist/dispatcher-Cm2FAG_D.js +174 -0
  119. package/dist/dm-policy-shared-DOzpxMHC.js +22 -0
  120. package/dist/dm-policy-shared-DZY0f1bR.js +22 -0
  121. package/dist/dns-cli-BgsNg-bn.js +203 -0
  122. package/dist/dns-cli-CdMU5yuG.js +199 -0
  123. package/dist/dock-ByrYnLiz.js +929 -0
  124. package/dist/dock-CpNmmysM.js +928 -0
  125. package/dist/doctor-completion-BPeaRbmd.js +92 -0
  126. package/dist/doctor-completion-CfOyGJd3.js +92 -0
  127. package/dist/doctor-config-flow-DMyTycn7.js +1935 -0
  128. package/dist/doctor-config-flow-DoMu-pTm.js +1934 -0
  129. package/dist/enable-D5KetMo7.js +59 -0
  130. package/dist/entry.js +61 -1
  131. package/dist/env-BJ36dSrx.js +60 -0
  132. package/dist/errors-BfONuT95.js +35 -0
  133. package/dist/errors-_DSePI1C.js +35 -0
  134. package/dist/exec-DkFE7lqU.js +164 -0
  135. package/dist/exec-mY96dhIg.js +164 -0
  136. package/dist/extensionAPI.js +112 -76
  137. package/dist/fetch-B3EQXbTa.js +67 -0
  138. package/dist/fetch-BPeSHPvr.js +281 -0
  139. package/dist/fetch-BQ7HvRwe.js +67 -0
  140. package/dist/fetch-CbGTzJ8L.js +281 -0
  141. package/dist/fetch-CfIaWynF.js +67 -0
  142. package/dist/file-lock-BHfqppLm.js +107 -0
  143. package/dist/file-lock-CCBpdPM_.js +107 -0
  144. package/dist/fs-safe-BcEpbVjc.js +88 -0
  145. package/dist/fs-safe-S3Zvbabd.js +98 -0
  146. package/dist/gateway-cli-BXipRcsU.js +24602 -0
  147. package/dist/gateway-cli-Bv2K3rXx.js +24606 -0
  148. package/dist/gateway-rpc-BHnd7P1q.js +28 -0
  149. package/dist/gateway-rpc-COEQDswS.js +28 -0
  150. package/dist/gmail-setup-utils-BpdKFe3P.js +423 -0
  151. package/dist/gmail-setup-utils-CqbWr0Kq.js +422 -0
  152. package/dist/health-1ero5j64.js +1414 -0
  153. package/dist/health-ioP2au7j.js +1417 -0
  154. package/dist/heartbeat-visibility-C88L-_f2.js +125 -0
  155. package/dist/heartbeat-visibility-Dk_Q02qX.js +125 -0
  156. package/dist/hook-runner-global-BztoD8lu.js +527 -0
  157. package/dist/hooks-cli-B8D9DzRR.js +1226 -0
  158. package/dist/hooks-cli-rZ3GOXag.js +1222 -0
  159. package/dist/image-ops-Cx1ym2Hi.js +354 -0
  160. package/dist/image-ops-DWytvdh_.js +354 -0
  161. package/dist/import-CTUBsy7D.js +604 -0
  162. package/dist/import-cBp4f62k.js +606 -0
  163. package/dist/inbound-context-COwswi8z.js +68 -0
  164. package/dist/inbound-context-ChcNR30g.js +68 -0
  165. package/dist/index.js +127 -102
  166. package/dist/inspect-BsS3_z-x.js +286 -0
  167. package/dist/inspect-drfsUSIW.js +286 -0
  168. package/dist/installs-BFmmM5Zd.js +325 -0
  169. package/dist/installs-DA7SG0Tx.js +325 -0
  170. package/dist/ipv4-BZGSwnH4.js +46 -0
  171. package/dist/ipv4-DsOgHE0B.js +46 -0
  172. package/dist/ir-R3Pk8Cv8.js +972 -0
  173. package/dist/lifecycle-core-BZMeOT7u.js +474 -0
  174. package/dist/lifecycle-core-C6-_Gts0.js +476 -0
  175. package/dist/loader-CJ2UHqV7.js +22414 -0
  176. package/dist/loader-dEFvmwXu.js +22411 -0
  177. package/dist/logger-9I2fg5mr.js +49 -0
  178. package/dist/login-D9uJTyEv.js +62 -0
  179. package/dist/login-DTh702_w.js +61 -0
  180. package/dist/login-qr-BKsmW6XI.js +325 -0
  181. package/dist/login-qr-SOXdIR58.js +329 -0
  182. package/dist/logs-cli-BshJBHZQ.js +236 -0
  183. package/dist/logs-cli-Ckh-BBTT.js +240 -0
  184. package/dist/markdown-tables-Cfz7zDXI.js +29 -0
  185. package/dist/markdown-tables-DeFSK6aY.js +29 -0
  186. package/dist/media-BD2cZGXT.js +971 -0
  187. package/dist/media-CjvpnJmQ.js +10388 -0
  188. package/dist/message-action-names-CZHrHMRE.js +2520 -0
  189. package/dist/message-action-names-CiZ-0Smk.js +2520 -0
  190. package/dist/message-channel-EMCYRaxk.js +91 -0
  191. package/dist/mime-1E7nn9IU.js +146 -0
  192. package/dist/mime-mSgQeDnC.js +146 -0
  193. package/dist/net-Cg8AQeke.js +225 -0
  194. package/dist/net-DMh1m8AZ.js +225 -0
  195. package/dist/node-cli-BJ5CCbqx.js +1462 -0
  196. package/dist/node-cli-wYYhAs8x.js +1458 -0
  197. package/dist/node-service-CkwVlcey.js +67 -0
  198. package/dist/node-service-DTVW9YJh.js +67 -0
  199. package/dist/nodes-cli-CMFYLD1o.js +1346 -0
  200. package/dist/nodes-cli-DC2zUx3f.js +1350 -0
  201. package/dist/nodes-screen-6pXv1lYa.js +250 -0
  202. package/dist/nodes-screen-CTIZKksn.js +250 -0
  203. package/dist/note-CMELkPJN.js +92 -0
  204. package/dist/npm-registry-spec-BiJI7Rkr.js +786 -0
  205. package/dist/npm-registry-spec-Dza35Ig4.js +786 -0
  206. package/dist/npm-resolution-CUQGDty4.js +86 -0
  207. package/dist/npm-resolution-CwbZK9AI.js +86 -0
  208. package/dist/onboard-8Qd9lU8x.js +649 -0
  209. package/dist/onboard-Q3cY65m8.js +647 -0
  210. package/dist/onboard-auth-BUzYDEqf.js +211 -0
  211. package/dist/onboard-auth-DcVXyd-Z.js +207 -0
  212. package/dist/onboard-channels-BFHuA-AU.js +2548 -0
  213. package/dist/onboard-channels-DVrPP_ie.js +2547 -0
  214. package/dist/onboard-helpers-B-bBSsyR.js +363 -0
  215. package/dist/onboard-helpers-YsCa-sAt.js +364 -0
  216. package/dist/onboard-remote-BWFcuEOD.js +127 -0
  217. package/dist/onboard-remote-C0THuDTK.js +127 -0
  218. package/dist/onboarding-B31lnOPp.js +586 -0
  219. package/dist/onboarding-DmN_qC8e.js +588 -0
  220. package/dist/onboarding.finalize-DGD0PA-D.js +402 -0
  221. package/dist/onboarding.finalize-DNIb3meE.js +404 -0
  222. package/dist/onboarding.gateway-config-BaeIuA62.js +195 -0
  223. package/dist/onboarding.gateway-config-DMV2Odzr.js +201 -0
  224. package/dist/outbound-BdxBHDax.js +220 -0
  225. package/dist/outbound-D-Y9rMgB.js +221 -0
  226. package/dist/outbound-attachment-CvZ04r5k.js +18 -0
  227. package/dist/outbound-attachment-DYa1asB5.js +18 -0
  228. package/dist/outbound-attachment-DgUpk7Uh.js +18 -0
  229. package/dist/pairing-cli-BxTv78V7.js +125 -0
  230. package/dist/pairing-cli-CxUCzNUc.js +129 -0
  231. package/dist/pairing-labels-DVO6NJr0.js +9 -0
  232. package/dist/pairing-labels-D_pD8Cag.js +9 -0
  233. package/dist/pairing-store-Bu9pVlkO.js +459 -0
  234. package/dist/pairing-store-CWaGbAGi.js +460 -0
  235. package/dist/path-env-RsuO6yO-.js +89 -0
  236. package/dist/path-env-_my-d_iR.js +89 -0
  237. package/dist/path-safety-CfiVyVz7.js +14 -0
  238. package/dist/path-safety-D-wLK4pV.js +14 -0
  239. package/dist/plugin-auto-enable-CW01H36W.js +301 -0
  240. package/dist/plugin-auto-enable-CeHhBLCU.js +302 -0
  241. package/dist/plugin-registry-CWL37HnB.js +33 -0
  242. package/dist/plugin-registry-ELliiumZ.js +33 -0
  243. package/dist/plugin-sdk/auth/provider-auth.d.ts +0 -6
  244. package/dist/plugin-sdk/auto-reply/reply/agent-runner-utils.d.ts +9 -29
  245. package/dist/plugin-sdk/auto-reply/reply/commands-status.d.ts +0 -2
  246. package/dist/plugin-sdk/auto-reply/reply/commands-subagents/shared.d.ts +1 -1
  247. package/dist/plugin-sdk/auto-reply/reply/queue/types.d.ts +0 -2
  248. package/dist/plugin-sdk/auto-reply/status.d.ts +0 -4
  249. package/dist/plugin-sdk/auto-reply/templating.d.ts +0 -4
  250. package/dist/plugin-sdk/config/sessions/types.d.ts +0 -2
  251. package/dist/plugin-sdk/config/types.tools.d.ts +1 -59
  252. package/dist/plugin-sdk/config/types.tts.d.ts +2 -1
  253. package/dist/plugin-sdk/config/zod-schema.agent-runtime.d.ts +0 -177
  254. package/dist/plugin-sdk/config/zod-schema.core.d.ts +2 -230
  255. package/dist/plugin-sdk/config/zod-schema.d.ts +3 -192
  256. package/dist/plugin-sdk/config/zod-schema.providers-core.d.ts +3 -15
  257. package/dist/plugin-sdk/config/zod-schema.providers.d.ts +2 -10
  258. package/dist/plugin-sdk/config/zod-schema.session.d.ts +1 -5
  259. package/dist/plugin-sdk/gateway/protocol/index.d.ts +5 -5
  260. package/dist/plugin-sdk/index.js +72 -142
  261. package/dist/plugin-sdk/middleware/cli-runtime-base.d.ts +6 -0
  262. package/dist/plugin-sdk/middleware/runtimes/claude.d.ts +6 -0
  263. package/dist/plugin-sdk/middleware/runtimes/codex.d.ts +2 -2
  264. package/dist/plugin-sdk/plugin-sdk/index.d.ts +2 -0
  265. package/dist/plugin-sdk/plugins/manifest-registry.d.ts +2 -0
  266. package/dist/plugin-sdk/plugins/manifest.d.ts +2 -0
  267. package/dist/plugin-sdk/plugins/registry.d.ts +18 -0
  268. package/dist/plugin-sdk/plugins/types.d.ts +4 -0
  269. package/dist/plugin-sdk/stt/preflight.d.ts +2 -4
  270. package/dist/plugin-sdk/stt/providers/index.d.ts +1 -1
  271. package/dist/plugin-sdk/stt/providers/shared.d.ts +20 -1
  272. package/dist/plugin-sdk/tts/providers/edge.d.ts +2 -0
  273. package/dist/plugin-sdk/tts/providers/elevenlabs.d.ts +2 -0
  274. package/dist/plugin-sdk/tts/providers/index.d.ts +4 -0
  275. package/dist/plugin-sdk/tts/providers/openai.d.ts +2 -0
  276. package/dist/plugin-sdk/tts/tts.d.ts +13 -5
  277. package/dist/plugin-sdk/tts/types.d.ts +21 -0
  278. package/dist/plugins-DExsdlTp.js +455 -0
  279. package/dist/plugins-DdMgSc_b.js +453 -0
  280. package/dist/plugins-cli-DqBWiT_G.js +806 -0
  281. package/dist/plugins-cli-KQEzhU6P.js +802 -0
  282. package/dist/ports-CL0pXAXO.js +96 -0
  283. package/dist/ports-CRI-HSZx.js +370 -0
  284. package/dist/ports-DiQFcKUB.js +316 -0
  285. package/dist/ports-HRurfPIr.js +96 -0
  286. package/dist/preflight-6QRqxWh7.js +667 -0
  287. package/dist/preflight-DDZjr5KD.js +667 -0
  288. package/dist/program-DmhbOJj3.js +249 -0
  289. package/dist/program-context-PPMzZ6Gu.js +474 -0
  290. package/dist/prompt-select-styled-CmSWunD8.js +1669 -0
  291. package/dist/prompt-select-styled-PfxT9zl9.js +1672 -0
  292. package/dist/provider-auth-CfdnLqh3.js +187 -0
  293. package/dist/provider-auth-gpHOMUBP.js +187 -0
  294. package/dist/provider-dispatcher-D4eY8LZW.js +659 -0
  295. package/dist/provider-dispatcher-D5Q7M15D.js +660 -0
  296. package/dist/push-apns-BNwVMXX9.js +713 -0
  297. package/dist/push-apns-BszVkcZK.js +711 -0
  298. package/dist/pw-ai-Bdb3zrBM.js +1911 -0
  299. package/dist/pw-ai-BvcvEdGs.js +1908 -0
  300. package/dist/qr-cli-BBgk2ci1.js +349 -0
  301. package/dist/qr-cli-BLzVrhia.js +353 -0
  302. package/dist/redact-snapshot-CyBDcb_a.js +1966 -0
  303. package/dist/redact-snapshot-D9oPMqA-.js +1966 -0
  304. package/dist/register.agent-CAhKX3Ft.js +1019 -0
  305. package/dist/register.agent-RKHXtLLm.js +291 -0
  306. package/dist/register.configure-CW6XRGxV.js +129 -0
  307. package/dist/register.configure-dvrKc0j7.js +134 -0
  308. package/dist/register.import-CRLOolHv.js +31 -0
  309. package/dist/register.import-dhDEj7Om.js +29 -0
  310. package/dist/register.maintenance-EAhr1tJ9.js +500 -0
  311. package/dist/register.maintenance-lWz4v90u.js +502 -0
  312. package/dist/register.message-DyWkwUIU.js +690 -0
  313. package/dist/register.message-bl2Khz6c.js +686 -0
  314. package/dist/register.onboard-BAozmeei.js +97 -0
  315. package/dist/register.onboard-Da9hWQR1.js +93 -0
  316. package/dist/register.setup-DVrQWLoF.js +117 -0
  317. package/dist/register.setup-DbiLuuqg.js +113 -0
  318. package/dist/register.status-health-sessions-CA8ApUkH.js +668 -0
  319. package/dist/register.status-health-sessions-lGszs-NJ.js +428 -0
  320. package/dist/register.subclis-C-lqMygb.js +267 -0
  321. package/dist/replies-BTC1z8j0.js +136 -0
  322. package/dist/replies-BhlnuFp0.js +136 -0
  323. package/dist/reply-DZMooMoq.js +12880 -0
  324. package/dist/reply-directives-C0-hYyAt.js +182 -0
  325. package/dist/reply-directives-C_CGXLBJ.js +182 -0
  326. package/dist/reply-payloads-BospFSPI.js +527 -0
  327. package/dist/reply-prefix-DDgh77yy.js +37 -0
  328. package/dist/reply-prefix-DwKZPZyG.js +37 -0
  329. package/dist/reply-yGEQ0UW4.js +12877 -0
  330. package/dist/resolve-route-B73QhBIl.js +249 -0
  331. package/dist/resolve-route-DckdRbW8.js +249 -0
  332. package/dist/response-prefix-template-x5RBQnEy.js +134 -0
  333. package/dist/retry-CDrH81GP.js +77 -0
  334. package/dist/run-main-D869n5qf.js +307 -0
  335. package/dist/secure-random-CxzxAnMS.js +44 -0
  336. package/dist/security-cli-CfqosyUf.js +487 -0
  337. package/dist/security-cli-DMZun6gO.js +482 -0
  338. package/dist/send-3wvngctD.js +547 -0
  339. package/dist/send-AY7Fs5ky.js +374 -0
  340. package/dist/send-BSWD4Kr_.js +2245 -0
  341. package/dist/send-BT4HhTLm.js +349 -0
  342. package/dist/send-BvuxToC8.js +2245 -0
  343. package/dist/send-CaUxFvu0.js +492 -0
  344. package/dist/send-CiBRE4OY.js +1178 -0
  345. package/dist/send-Cidd4lQn.js +11 -0
  346. package/dist/send-Cq_Db9wG.js +1779 -0
  347. package/dist/send-DBFcxDPm.js +1776 -0
  348. package/dist/send-DUha0nIz.js +492 -0
  349. package/dist/send-DgYBI05s.js +332 -0
  350. package/dist/send-Dnf5bISH.js +426 -0
  351. package/dist/send-NcQk6UH1.js +547 -0
  352. package/dist/send-Og0-IMee.js +29 -0
  353. package/dist/send-oCN80Pl2.js +349 -0
  354. package/dist/server-DoGGLeP3.js +202 -0
  355. package/dist/server-V7G9FG2A.js +206 -0
  356. package/dist/server-lifecycle-CSWpSlvn.js +2437 -0
  357. package/dist/server-lifecycle-Cal8hBP1.js +2437 -0
  358. package/dist/server-node-events-DSee6jSG.js +394 -0
  359. package/dist/server-node-events-DbQWkU3M.js +390 -0
  360. package/dist/service-Duw0xMJX.js +670 -0
  361. package/dist/service-SRcnA1Am.js +670 -0
  362. package/dist/session-BLcfWX5_.js +170 -0
  363. package/dist/session-CQwkaAs-.js +170 -0
  364. package/dist/session-cost-usage-C-UcrvL4.js +627 -0
  365. package/dist/session-cost-usage-Dg3dzS0E.js +627 -0
  366. package/dist/session-dirs-D6mFEF90.js +318 -0
  367. package/dist/session-dirs-DVsG6e7L.js +318 -0
  368. package/dist/session-utils-C6522g3D.js +622 -0
  369. package/dist/session-utils-Dq2BJyVy.js +622 -0
  370. package/dist/sessions-CNkj4Eq8.js +247 -0
  371. package/dist/sessions-DDIoP7Rl.js +2569 -0
  372. package/dist/shell-env-D8nXPDbP.js +163 -0
  373. package/dist/ssrf-7I3FUHpm.js +183 -0
  374. package/dist/ssrf-DZi4qw5c.js +183 -0
  375. package/dist/status-CrAe8ZYt.js +1983 -0
  376. package/dist/status-DetRJxvZ.js +1979 -0
  377. package/dist/status.update-DquSK3p7.js +449 -0
  378. package/dist/status.update-iABAY3iW.js +449 -0
  379. package/dist/store-Bnm6zwaq.js +2571 -0
  380. package/dist/store-CVkGKjWm.js +64 -0
  381. package/dist/store-D_gpBpAW.js +64 -0
  382. package/dist/store-mxh63FBa.js +53 -0
  383. package/dist/subagent-registry-DNAz7Heu.js +4856 -0
  384. package/dist/subagent-registry-Dhz6HC4Z.js +4854 -0
  385. package/dist/subsystem-DGSHVL8I.js +1081 -0
  386. package/dist/subsystem-m7RSGQoR.js +1196 -0
  387. package/dist/system-cli-ByVDF6p8.js +77 -0
  388. package/dist/system-cli-CERb89Bl.js +73 -0
  389. package/dist/systemd-CSUtfsJx.js +547 -0
  390. package/dist/systemd-hints-BCxkQemJ.js +278 -0
  391. package/dist/systemd-hints-ef7m-7ZH.js +278 -0
  392. package/dist/systemd-linger-CWLgT0Wr.js +75 -0
  393. package/dist/systemd-linger-DT0E7YET.js +75 -0
  394. package/dist/systemd-tS61V4ao.js +547 -0
  395. package/dist/tables-DED01JNI.js +55 -0
  396. package/dist/tables-K3rOiGaJ.js +55 -0
  397. package/dist/tables-NcsXz3r_.js +55 -0
  398. package/dist/tailnet-CEudzG0i.js +40 -0
  399. package/dist/tailnet-D66Y5zC7.js +40 -0
  400. package/dist/tailscale-DjSRjPA-.js +230 -0
  401. package/dist/tailscale-DngZHD9L.js +230 -0
  402. package/dist/targets-BOpYPsGM.js +2545 -0
  403. package/dist/targets-BVsxzQh1.js +220 -0
  404. package/dist/targets-C99szk_e.js +114 -0
  405. package/dist/targets-CA4zx5G4.js +650 -0
  406. package/dist/targets-CTNm3bJ8.js +2544 -0
  407. package/dist/targets-DpmQjetK.js +53 -0
  408. package/dist/targets-Q-YGeAqu.js +650 -0
  409. package/dist/targets-rdWlC6Y-.js +53 -0
  410. package/dist/tool-display-Br6mwaJc.js +785 -0
  411. package/dist/tool-display-CLBf5cRa.js +785 -0
  412. package/dist/tool-images-DB4f57XK.js +263 -0
  413. package/dist/tool-images-kloBqxqK.js +263 -0
  414. package/dist/trash-B32LfX0l.js +125 -0
  415. package/dist/trash-SlUJxKO7.js +125 -0
  416. package/dist/tui-CHOtFK6k.js +3282 -0
  417. package/dist/tui-D4yiSpop.js +3282 -0
  418. package/dist/tui-cli-CzrjmAMZ.js +66 -0
  419. package/dist/tui-cli-Dpbs2QW_.js +62 -0
  420. package/dist/update-B5nYVxpc.js +349 -0
  421. package/dist/update-Bs3HhSnE.js +349 -0
  422. package/dist/update-cli-D_yz9Kyz.js +1147 -0
  423. package/dist/update-cli-DdfwNAsA.js +1149 -0
  424. package/dist/usage-BVyabt5E.js +5421 -0
  425. package/dist/voice-credentials-CI4VgB6u.js +46 -0
  426. package/dist/voice-credentials-l_d_gZiG.js +46 -0
  427. package/dist/web-B5xSAAH2.js +74 -0
  428. package/dist/web-Cc4tDVO9.js +3067 -0
  429. package/dist/web-Cdp9_IUk.js +79 -0
  430. package/dist/webhooks-cli-BDPcBkZL.js +330 -0
  431. package/dist/webhooks-cli-sRfsNesg.js +334 -0
  432. package/dist/whatsapp-actions-BGZXdWiP.js +125 -0
  433. package/dist/whatsapp-actions-HdmZu8oU.js +130 -0
  434. package/dist/workspace-D5LAl41l.js +449 -0
  435. package/dist/workspace-DRYGbrDM.js +447 -0
  436. package/dist/zod-schema-C8gEV0uz.js +2739 -0
  437. package/dist/zod-schema-CCUbW_Si.js +2739 -0
  438. package/package.json +1 -1
  439. package/dist/accounts-Aqbb2_Fn.js +0 -270
  440. package/dist/accounts-Bo2bX8jP.js +0 -272
  441. package/dist/accounts-D3fAPVzU.js +0 -36
  442. package/dist/accounts-DUEDngp6.js +0 -32
  443. package/dist/accounts-DZmv4bXS.js +0 -47
  444. package/dist/accounts-DmB4SVPK.js +0 -47
  445. package/dist/accounts-DtkyfvwR.js +0 -36
  446. package/dist/ack-reactions-Bvfy17SM.js +0 -446
  447. package/dist/ack-reactions-DYU8uhcz.js +0 -446
  448. package/dist/acp-cli-DVXhDMc6.js +0 -1324
  449. package/dist/acp-cli-QBL4_qcW.js +0 -1319
  450. package/dist/active-listener-CwxZ24bZ.js +0 -37
  451. package/dist/active-listener-v2sItamh.js +0 -37
  452. package/dist/agent-BisC5WZ6.js +0 -704
  453. package/dist/agent-Bqdrc0AK.js +0 -703
  454. package/dist/agent-helpers-BSGqeJr-.js +0 -400
  455. package/dist/agent-scope-_ND_-bJy.js +0 -116
  456. package/dist/agents-khSbraAA.js +0 -760
  457. package/dist/agents.config-D8gLHPWo.js +0 -116
  458. package/dist/audio-BIvUsncf.js +0 -43
  459. package/dist/audio-CQ8TfmVN.js +0 -43
  460. package/dist/audit-C0x7Cm6K.js +0 -3150
  461. package/dist/audit-CAY-uzWP.js +0 -3150
  462. package/dist/auth-DGqCLaQq.js +0 -448
  463. package/dist/auth-DLTRySEi.js +0 -314
  464. package/dist/auth-Drf91ntw.js +0 -315
  465. package/dist/auth-ku2khJyQ.js +0 -448
  466. package/dist/banner-txHC40UW.js +0 -294
  467. package/dist/binaries-BTvHIrCr.js +0 -13
  468. package/dist/bindings-DsWJQVKh.js +0 -69
  469. package/dist/bonjour-discovery-BElR62fH.js +0 -378
  470. package/dist/bonjour-discovery-C8XyVsjb.js +0 -378
  471. package/dist/browser-cli-DxJew43l.js +0 -1694
  472. package/dist/browser-cli-p0nakrjO.js +0 -1690
  473. package/dist/call-BrTmlOx3.js +0 -518
  474. package/dist/call-ChdUdwb4.js +0 -517
  475. package/dist/catalog-DTlcfTT9.js +0 -185
  476. package/dist/catalog-PixZqhZK.js +0 -185
  477. package/dist/channel-account-context-BO245Tcn.js +0 -133
  478. package/dist/channel-account-context-BgK0hm-I.js +0 -133
  479. package/dist/channel-activity-B0qlUR5e.js +0 -292
  480. package/dist/channel-activity-C-L6rDrQ.js +0 -94
  481. package/dist/channel-activity-DdgLBZ7M.js +0 -94
  482. package/dist/channel-options-CjlvAHSH.js +0 -32
  483. package/dist/channel-options-DpjP7qQf.js +0 -33
  484. package/dist/channel-selection-DW21dXB1.js +0 -51
  485. package/dist/channel-selection-wK_6S2Ku.js +0 -51
  486. package/dist/channel-web-COTkzJBt.js +0 -2136
  487. package/dist/channel-web-DUz5bn9h.js +0 -2134
  488. package/dist/channels-cli-D8RS8g2Q.js +0 -1438
  489. package/dist/channels-cli-X_8rENR6.js +0 -1434
  490. package/dist/channels-status-issues-B6I2l7Sm.js +0 -18
  491. package/dist/channels-status-issues-DhDH2fWp.js +0 -18
  492. package/dist/chrome-Dqtq7zCc.js +0 -1733
  493. package/dist/chrome-XeSY99Z_.js +0 -1732
  494. package/dist/chunk-CWD_zrz_.js +0 -341
  495. package/dist/chunk-LUabyS9k.js +0 -341
  496. package/dist/clack-prompter-fAgbvPW4.js +0 -122
  497. package/dist/clack-prompter-kf9qTN5p.js +0 -121
  498. package/dist/cli-BjPLpuZR.js +0 -133
  499. package/dist/cli-fFyOTtkD.js +0 -129
  500. package/dist/client-B9u3JdT_.js +0 -2316
  501. package/dist/client-DEEOhx0w.js +0 -2316
  502. package/dist/clipboard-B2nstLx7.js +0 -31
  503. package/dist/clipboard-C8QI9fes.js +0 -31
  504. package/dist/command-format-D0vKipG9.js +0 -32
  505. package/dist/command-format-LFmgWzKJ.js +0 -18
  506. package/dist/command-registry-BsPaMI53.js +0 -215
  507. package/dist/commands-BAYwlS3d.js +0 -41
  508. package/dist/commands-D842kCjj.js +0 -41
  509. package/dist/commands-registry-Cg2GTT2J.js +0 -892
  510. package/dist/commands-registry-Yz-uV5oG.js +0 -891
  511. package/dist/common-B67cBSew.js +0 -156
  512. package/dist/common-DEoiTqOr.js +0 -156
  513. package/dist/completion-cli-BO5mIPLa.js +0 -452
  514. package/dist/completion-cli-z9a6MVgr.js +0 -452
  515. package/dist/config-CAa0rZSx.js +0 -4225
  516. package/dist/config-W0w-gi2j.js +0 -4223
  517. package/dist/config-cli-DdRue35G.js +0 -243
  518. package/dist/config-cli-uOwxu5AC.js +0 -247
  519. package/dist/config-guard-BI85dxHR.js +0 -99
  520. package/dist/config-guard-DQqnigKh.js +0 -75
  521. package/dist/config-validation-D-h4LHyA.js +0 -18
  522. package/dist/config-validation-Df_kroIQ.js +0 -18
  523. package/dist/configure-B7ChPbXv.js +0 -891
  524. package/dist/configure-QspkIXME.js +0 -889
  525. package/dist/control-auth-BrBr2xb8.js +0 -397
  526. package/dist/control-auth-CehjYKnL.js +0 -397
  527. package/dist/control-ui-assets-D8F383Mo.js +0 -186
  528. package/dist/control-ui-assets-DYKtRIm0.js +0 -186
  529. package/dist/conversation-label-Bn5j3lUT.js +0 -36
  530. package/dist/conversation-label-CDH4rKMG.js +0 -36
  531. package/dist/cron-cli-DVzDHzAX.js +0 -494
  532. package/dist/cron-cli-gkH2qKM4.js +0 -498
  533. package/dist/daemon-cli-BTdNO1vH.js +0 -737
  534. package/dist/daemon-cli-DNNqI2LD.js +0 -735
  535. package/dist/daemon-install-CaEHG92p.js +0 -56
  536. package/dist/daemon-install-DbpDSDfW.js +0 -60
  537. package/dist/daemon-install-helpers-DjE_WnlY.js +0 -504
  538. package/dist/daemon-install-helpers-DocTUxqQ.js +0 -504
  539. package/dist/deliver-CDcL8ok6.js +0 -481
  540. package/dist/deliver-CS8JsevV.js +0 -481
  541. package/dist/delivery-queue-CTaYZQ_8.js +0 -244
  542. package/dist/delivery-queue-DMZ7mH8P.js +0 -244
  543. package/dist/devices-cli-BBJ4His-.js +0 -319
  544. package/dist/devices-cli-DHSJSFW1.js +0 -323
  545. package/dist/diagnostics-BSvCaLNs.js +0 -35
  546. package/dist/diagnostics-mWFAsFeo.js +0 -35
  547. package/dist/directory-cli-C-oHD_XE.js +0 -224
  548. package/dist/directory-cli-Cw99VGvr.js +0 -220
  549. package/dist/dispatcher-C8d1NNLZ.js +0 -174
  550. package/dist/dispatcher-DY6Ga60j.js +0 -173
  551. package/dist/dm-policy-shared-CRQ-Wr5g.js +0 -22
  552. package/dist/dm-policy-shared-CXXf2ltd.js +0 -22
  553. package/dist/dns-cli-BOqx9qo1.js +0 -199
  554. package/dist/dns-cli-WfqSC3JU.js +0 -203
  555. package/dist/dock-Big-J2VN.js +0 -929
  556. package/dist/dock-Cj4PKiUh.js +0 -928
  557. package/dist/doctor-completion-hYqcZ7IE.js +0 -92
  558. package/dist/doctor-completion-nxQQ5bEw.js +0 -92
  559. package/dist/doctor-config-flow-BUuADMDa.js +0 -1935
  560. package/dist/doctor-config-flow-yOUpQC2B.js +0 -1934
  561. package/dist/enable-DC9V0nTO.js +0 -59
  562. package/dist/env-B3zr72vQ.js +0 -60
  563. package/dist/errors-CdmXrBic.js +0 -35
  564. package/dist/errors-Cr_NbOb4.js +0 -35
  565. package/dist/exec-D_s-zAtY.js +0 -164
  566. package/dist/exec-Zz6eJ6YU.js +0 -164
  567. package/dist/fetch-BIZkXB5i.js +0 -67
  568. package/dist/fetch-DRVdxxEj.js +0 -67
  569. package/dist/fetch-DTR2MlOk.js +0 -67
  570. package/dist/file-lock-6NXMPZTT.js +0 -107
  571. package/dist/file-lock-C_KRlR7M.js +0 -107
  572. package/dist/fs-safe-DZHpH7TI.js +0 -98
  573. package/dist/fs-safe-vm3JMUkq.js +0 -88
  574. package/dist/gateway-cli-DEW-Ukmc.js +0 -24351
  575. package/dist/gateway-cli-DQYcZCOV.js +0 -24347
  576. package/dist/gateway-rpc-BCFkQPa2.js +0 -28
  577. package/dist/gateway-rpc-DOgYbsOG.js +0 -28
  578. package/dist/gmail-setup-utils-DMeA1UM1.js +0 -423
  579. package/dist/gmail-setup-utils-FHWSAur3.js +0 -422
  580. package/dist/health-BrLNGkZV.js +0 -1414
  581. package/dist/health-C8p9mnfl.js +0 -1417
  582. package/dist/heartbeat-visibility-CJVdaMZF.js +0 -125
  583. package/dist/heartbeat-visibility-DwK1UL0t.js +0 -125
  584. package/dist/hook-runner-global-C0DFQmQw.js +0 -527
  585. package/dist/hooks-cli-DEKi-tbA.js +0 -1221
  586. package/dist/hooks-cli-FndXPMD3.js +0 -1225
  587. package/dist/image-ops-B9ofmzSq.js +0 -354
  588. package/dist/image-ops-CMuvRsMY.js +0 -354
  589. package/dist/import-BH13F5mT.js +0 -606
  590. package/dist/import-D8HVcDqO.js +0 -604
  591. package/dist/inbound-context-BLy-G2Eq.js +0 -68
  592. package/dist/inbound-context-CmmmT8IP.js +0 -68
  593. package/dist/inbound-path-policy-BdmTOUka.js +0 -90
  594. package/dist/inbound-path-policy-BurOAu44.js +0 -90
  595. package/dist/inspect-nW8LAukU.js +0 -286
  596. package/dist/inspect-xy2EHy8G.js +0 -286
  597. package/dist/installs-CpfHmKY1.js +0 -325
  598. package/dist/installs-DebiMrGj.js +0 -325
  599. package/dist/ipv4-ysiNGssl.js +0 -46
  600. package/dist/ipv4-zc_Hfvbp.js +0 -46
  601. package/dist/ir-CaxTklDC.js +0 -940
  602. package/dist/lifecycle-core-Z5SScMlU.js +0 -476
  603. package/dist/lifecycle-core-pPwYSt7m.js +0 -474
  604. package/dist/loader-BapIdJyx.js +0 -22404
  605. package/dist/loader-BdAToyDH.js +0 -22401
  606. package/dist/local-roots-CrJ_Jv_G.js +0 -314
  607. package/dist/local-roots-n_Y4iYwb.js +0 -313
  608. package/dist/logger-B8yHnzPl.js +0 -49
  609. package/dist/login-C99fsB0N.js +0 -61
  610. package/dist/login-cLvGPjeO.js +0 -62
  611. package/dist/login-qr-CGqRFwgl.js +0 -329
  612. package/dist/login-qr-dnY5DC2C.js +0 -325
  613. package/dist/logs-cli-Bda7xY4N.js +0 -236
  614. package/dist/logs-cli-HzR-vnpD.js +0 -240
  615. package/dist/markdown-tables-58Hq__7K.js +0 -29
  616. package/dist/markdown-tables-GFEX0OR6.js +0 -29
  617. package/dist/media-CFsyXs3H.js +0 -940
  618. package/dist/media-Du5SHtnp.js +0 -10452
  619. package/dist/message-action-names-BfuEvR6j.js +0 -2521
  620. package/dist/message-action-names-CVBkpOLt.js +0 -2521
  621. package/dist/message-channel-FMNRI5Ax.js +0 -91
  622. package/dist/mime-AuIDUZPG.js +0 -149
  623. package/dist/mime-Cqg1jjia.js +0 -149
  624. package/dist/net-BEFkF-nI.js +0 -225
  625. package/dist/net-CNsUGiSw.js +0 -225
  626. package/dist/node-cli-Bu-InsO9.js +0 -1462
  627. package/dist/node-cli-DE7Pm7Fr.js +0 -1458
  628. package/dist/node-service-CumFZc9L.js +0 -67
  629. package/dist/node-service-DY1gG06I.js +0 -67
  630. package/dist/nodes-cli-B5aAExN0.js +0 -1350
  631. package/dist/nodes-cli-eKRqlKuO.js +0 -1346
  632. package/dist/nodes-screen-B3Sij1uT.js +0 -250
  633. package/dist/nodes-screen-DEvpoFmH.js +0 -250
  634. package/dist/note-CPFJCWJJ.js +0 -92
  635. package/dist/npm-registry-spec-BgMtTHvq.js +0 -786
  636. package/dist/npm-registry-spec-Dz3z1Zpd.js +0 -786
  637. package/dist/npm-resolution-Buio63BQ.js +0 -86
  638. package/dist/npm-resolution-gH1zHW2a.js +0 -86
  639. package/dist/onboard-BSf6qJWk.js +0 -647
  640. package/dist/onboard-V-SsZRk-.js +0 -649
  641. package/dist/onboard-auth-C_wHkop1.js +0 -207
  642. package/dist/onboard-auth-CkCBLvTg.js +0 -211
  643. package/dist/onboard-channels-DQTGPC18.js +0 -2548
  644. package/dist/onboard-channels-DSDQfR0u.js +0 -2547
  645. package/dist/onboard-helpers-Q7M6vdzh.js +0 -363
  646. package/dist/onboard-helpers-SCO3k5Y8.js +0 -364
  647. package/dist/onboard-remote-Co2hv1AD.js +0 -127
  648. package/dist/onboard-remote-Dl3BFSg2.js +0 -127
  649. package/dist/onboarding-B0bJfZ20.js +0 -588
  650. package/dist/onboarding-CeBR9OBi.js +0 -586
  651. package/dist/onboarding.finalize-BPgfWPB9.js +0 -404
  652. package/dist/onboarding.finalize-BmfLvNPJ.js +0 -402
  653. package/dist/onboarding.gateway-config-BL0Q7Wpg.js +0 -201
  654. package/dist/onboarding.gateway-config-D2QsXMYO.js +0 -195
  655. package/dist/outbound-CcaPcetn.js +0 -220
  656. package/dist/outbound-CeiW8z3a.js +0 -221
  657. package/dist/outbound-attachment-BIvFb3Is.js +0 -18
  658. package/dist/outbound-attachment-Bfm5-JYe.js +0 -18
  659. package/dist/outbound-attachment-CZ7zoYxB.js +0 -18
  660. package/dist/pairing-cli-CgX79ujL.js +0 -125
  661. package/dist/pairing-cli-DvbbXFgC.js +0 -129
  662. package/dist/pairing-labels-3wDxaApH.js +0 -9
  663. package/dist/pairing-labels-DCbWnbWk.js +0 -9
  664. package/dist/pairing-store-CdY7iRS0.js +0 -459
  665. package/dist/pairing-store-DykkYpQ7.js +0 -460
  666. package/dist/path-env-Cqo5LZmw.js +0 -89
  667. package/dist/path-env-GTM4HXCN.js +0 -89
  668. package/dist/path-safety-CXKAVpMp.js +0 -14
  669. package/dist/path-safety-DGB91qBk.js +0 -14
  670. package/dist/plugin-auto-enable-C6FPGg_-.js +0 -301
  671. package/dist/plugin-auto-enable-L8eOc8iC.js +0 -302
  672. package/dist/plugin-registry-CHlaWZD7.js +0 -33
  673. package/dist/plugin-registry-DQdMze4z.js +0 -33
  674. package/dist/plugin-sdk/auth/session-override.d.ts +0 -17
  675. package/dist/plugin-sdk/auto-reply/reply/directive-handling.auth.d.ts +0 -18
  676. package/dist/plugin-sdk/link-understanding/apply.d.ts +0 -10
  677. package/dist/plugin-sdk/link-understanding/defaults.d.ts +0 -2
  678. package/dist/plugin-sdk/link-understanding/detect.d.ts +0 -3
  679. package/dist/plugin-sdk/link-understanding/format.d.ts +0 -4
  680. package/dist/plugin-sdk/link-understanding/runner.d.ts +0 -11
  681. package/dist/plugin-sdk/media/input-files.d.ts +0 -95
  682. package/dist/plugin-sdk/media-understanding/apply.d.ts +0 -19
  683. package/dist/plugin-sdk/media-understanding/attachments.d.ts +0 -49
  684. package/dist/plugin-sdk/media-understanding/concurrency.d.ts +0 -1
  685. package/dist/plugin-sdk/media-understanding/defaults.d.ts +0 -11
  686. package/dist/plugin-sdk/media-understanding/errors.d.ts +0 -6
  687. package/dist/plugin-sdk/media-understanding/format.d.ts +0 -7
  688. package/dist/plugin-sdk/media-understanding/fs.d.ts +0 -1
  689. package/dist/plugin-sdk/media-understanding/output-extract.d.ts +0 -2
  690. package/dist/plugin-sdk/media-understanding/providers/anthropic/index.d.ts +0 -2
  691. package/dist/plugin-sdk/media-understanding/providers/deepgram/audio.d.ts +0 -1
  692. package/dist/plugin-sdk/media-understanding/providers/deepgram/index.d.ts +0 -2
  693. package/dist/plugin-sdk/media-understanding/providers/google/audio.d.ts +0 -1
  694. package/dist/plugin-sdk/media-understanding/providers/google/index.d.ts +0 -2
  695. package/dist/plugin-sdk/media-understanding/providers/google/video.d.ts +0 -3
  696. package/dist/plugin-sdk/media-understanding/providers/groq/index.d.ts +0 -2
  697. package/dist/plugin-sdk/media-understanding/providers/index.d.ts +0 -4
  698. package/dist/plugin-sdk/media-understanding/providers/minimax/index.d.ts +0 -2
  699. package/dist/plugin-sdk/media-understanding/providers/mistral/index.d.ts +0 -2
  700. package/dist/plugin-sdk/media-understanding/providers/moonshot/index.d.ts +0 -2
  701. package/dist/plugin-sdk/media-understanding/providers/moonshot/video.d.ts +0 -3
  702. package/dist/plugin-sdk/media-understanding/providers/openai/audio.d.ts +0 -1
  703. package/dist/plugin-sdk/media-understanding/providers/openai/index.d.ts +0 -2
  704. package/dist/plugin-sdk/media-understanding/providers/shared.d.ts +0 -20
  705. package/dist/plugin-sdk/media-understanding/providers/zai/index.d.ts +0 -2
  706. package/dist/plugin-sdk/media-understanding/resolve.d.ts +0 -44
  707. package/dist/plugin-sdk/media-understanding/runner.d.ts +0 -34
  708. package/dist/plugin-sdk/media-understanding/runner.entries.d.ts +0 -33
  709. package/dist/plugin-sdk/media-understanding/scope.d.ts +0 -9
  710. package/dist/plugin-sdk/media-understanding/types.d.ts +0 -59
  711. package/dist/plugin-sdk/media-understanding/video.d.ts +0 -2
  712. package/dist/plugin-sdk/utils/mask-api-key.d.ts +0 -1
  713. package/dist/plugin-sdk/utils/run-with-concurrency.d.ts +0 -11
  714. package/dist/plugins-7B167wIj.js +0 -453
  715. package/dist/plugins-BRHOfy1Z.js +0 -455
  716. package/dist/plugins-cli--I43zIaS.js +0 -797
  717. package/dist/plugins-cli-DIxMbY9I.js +0 -801
  718. package/dist/ports-BS8kQkd9.js +0 -96
  719. package/dist/ports-CAqyeQYZ.js +0 -316
  720. package/dist/ports-CTUgXF2d.js +0 -96
  721. package/dist/ports-DqfnVnCw.js +0 -370
  722. package/dist/preflight-CaRJtknt.js +0 -64
  723. package/dist/preflight-DeDRKMx4.js +0 -68
  724. package/dist/program-context-9dv7ClZz.js +0 -474
  725. package/dist/program-wVSvyiD-.js +0 -248
  726. package/dist/prompt-select-styled-BE_4W66Z.js +0 -1672
  727. package/dist/prompt-select-styled-BTPf06Os.js +0 -1669
  728. package/dist/provider-dispatcher-VZWITjmt.js +0 -660
  729. package/dist/provider-dispatcher-zYYGo00g.js +0 -659
  730. package/dist/push-apns-Cj0Ryn18.js +0 -713
  731. package/dist/push-apns-fFfYCqda.js +0 -711
  732. package/dist/pw-ai-CnN2sITD.js +0 -1908
  733. package/dist/pw-ai-fnX3cecw.js +0 -1911
  734. package/dist/qr-cli-CriPg41m.js +0 -349
  735. package/dist/qr-cli-DSURqD0D.js +0 -353
  736. package/dist/redact-snapshot-BecRL_h6.js +0 -2016
  737. package/dist/redact-snapshot-pTdzSrex.js +0 -2016
  738. package/dist/register.agent-B5_1XatO.js +0 -290
  739. package/dist/register.agent-Dba3CYyo.js +0 -1018
  740. package/dist/register.configure-DmwHGsPG.js +0 -128
  741. package/dist/register.configure-DrPlgBqB.js +0 -133
  742. package/dist/register.import-CPQqqdje.js +0 -31
  743. package/dist/register.import-D1UaH1QV.js +0 -29
  744. package/dist/register.maintenance-D76tiF4W.js +0 -501
  745. package/dist/register.maintenance-hUriFBfi.js +0 -499
  746. package/dist/register.message--VzmF3u4.js +0 -685
  747. package/dist/register.message-itNWUdvP.js +0 -689
  748. package/dist/register.onboard-Co8D908b.js +0 -93
  749. package/dist/register.onboard-q8JzWtuv.js +0 -97
  750. package/dist/register.setup-Djc6jZTc.js +0 -113
  751. package/dist/register.setup-hhPii4O7.js +0 -117
  752. package/dist/register.status-health-sessions-C1FhACQB.js +0 -668
  753. package/dist/register.status-health-sessions-DcUegHcH.js +0 -428
  754. package/dist/register.subclis-DAfihpBz.js +0 -267
  755. package/dist/replies-IpiCq1Ht.js +0 -136
  756. package/dist/replies-LSx_XhsP.js +0 -136
  757. package/dist/reply-D0CLqcBY.js +0 -13718
  758. package/dist/reply-Djq8ghfI.js +0 -13715
  759. package/dist/reply-directives-Cz7622Qx.js +0 -182
  760. package/dist/reply-directives-ssnaPNiU.js +0 -182
  761. package/dist/reply-payloads-CQMtrphw.js +0 -527
  762. package/dist/reply-prefix-CWcAZKhE.js +0 -37
  763. package/dist/reply-prefix-Drq7Pf3A.js +0 -37
  764. package/dist/resolve-route-B8uIc2H3.js +0 -249
  765. package/dist/resolve-route-C8ooNlI4.js +0 -249
  766. package/dist/response-prefix-template-DPOggmPO.js +0 -134
  767. package/dist/retry-BdhJlZQI.js +0 -77
  768. package/dist/run-main-B-Cb62fC.js +0 -306
  769. package/dist/runner-DUnmgjJ8.js +0 -2394
  770. package/dist/runner-EobZIrDt.js +0 -2394
  771. package/dist/secure-random-B5qmFc3N.js +0 -44
  772. package/dist/security-cli-05blEYyC.js +0 -482
  773. package/dist/security-cli-DYbt8duB.js +0 -487
  774. package/dist/send-7O3-bRtl.js +0 -547
  775. package/dist/send-9Huf62k3.js +0 -2245
  776. package/dist/send-B9mIJdUo.js +0 -547
  777. package/dist/send-Bj0RXr-a.js +0 -492
  778. package/dist/send-BzkAsn7K.js +0 -29
  779. package/dist/send-CXFhFLP9.js +0 -11
  780. package/dist/send-Ce_BDa8P.js +0 -349
  781. package/dist/send-ChvasRSh.js +0 -1779
  782. package/dist/send-Cl5BhbnF.js +0 -426
  783. package/dist/send-CpebTvM6.js +0 -374
  784. package/dist/send-DWf7BCPe.js +0 -492
  785. package/dist/send-DX8QSuSI.js +0 -1174
  786. package/dist/send-DZRn6PT2.js +0 -332
  787. package/dist/send-Dd2_MykI.js +0 -2245
  788. package/dist/send-IJaUAa8H.js +0 -1776
  789. package/dist/send-vvZXksNU.js +0 -349
  790. package/dist/server-BrzR9JmX.js +0 -206
  791. package/dist/server-_h27-uP_.js +0 -202
  792. package/dist/server-lifecycle-CUdA6Far.js +0 -2437
  793. package/dist/server-lifecycle-DQZWL8iP.js +0 -2437
  794. package/dist/server-node-events-DgB1z2Cx.js +0 -392
  795. package/dist/server-node-events-DtvPfM1I.js +0 -396
  796. package/dist/service-9le8AnC-.js +0 -670
  797. package/dist/service-Drb0kx6I.js +0 -670
  798. package/dist/session-BIAOl5QR.js +0 -170
  799. package/dist/session-Wu00pCn_.js +0 -170
  800. package/dist/session-cost-usage-7plmOKbs.js +0 -627
  801. package/dist/session-cost-usage-CPFxBFUg.js +0 -627
  802. package/dist/session-dirs-CfIrIJxG.js +0 -318
  803. package/dist/session-dirs-DlPpWt5Q.js +0 -318
  804. package/dist/session-utils-Sd9w4vc1.js +0 -622
  805. package/dist/session-utils-iL47hYmZ.js +0 -622
  806. package/dist/sessions-6pKQ3gN3.js +0 -247
  807. package/dist/sessions-ZRmCDdj1.js +0 -2569
  808. package/dist/shell-env-DYZq9PqC.js +0 -163
  809. package/dist/ssrf-B-rF_tZB.js +0 -183
  810. package/dist/ssrf-DJW14Wkh.js +0 -183
  811. package/dist/status-CTRQCXRj.js +0 -1979
  812. package/dist/status-Y67xsH93.js +0 -1983
  813. package/dist/status.update-DlBReI5-.js +0 -449
  814. package/dist/status.update-v7fEQ7R9.js +0 -449
  815. package/dist/store-B5989JkX.js +0 -64
  816. package/dist/store-BgtgYJoX.js +0 -53
  817. package/dist/store-DCrrxHyS.js +0 -2571
  818. package/dist/store-Ql6vAcsg.js +0 -64
  819. package/dist/subagent-registry-BGknZEUI.js +0 -4856
  820. package/dist/subagent-registry-CWeRBjfn.js +0 -4854
  821. package/dist/subsystem-Ct6qOOqZ.js +0 -1079
  822. package/dist/subsystem-PQ64_nsu.js +0 -1136
  823. package/dist/system-cli-CmO-4Rju.js +0 -77
  824. package/dist/system-cli-VBsa18K6.js +0 -73
  825. package/dist/systemd-CqFpK30Y.js +0 -547
  826. package/dist/systemd-fK9AV5bP.js +0 -547
  827. package/dist/systemd-hints-D3rr0j14.js +0 -278
  828. package/dist/systemd-hints-DNOSRaqA.js +0 -278
  829. package/dist/systemd-linger-B907NVVy.js +0 -75
  830. package/dist/systemd-linger-wYksBbM7.js +0 -75
  831. package/dist/tables-Boxa9MJH.js +0 -55
  832. package/dist/tables-CO_kxD0e.js +0 -55
  833. package/dist/tables-WZp8Vt9n.js +0 -55
  834. package/dist/tailnet-CfZhpSnt.js +0 -40
  835. package/dist/tailnet-D0NV0tRJ.js +0 -40
  836. package/dist/tailscale-B__xvMjA.js +0 -230
  837. package/dist/tailscale-q_ZrxUCc.js +0 -230
  838. package/dist/targets-B4rMyQFJ.js +0 -53
  839. package/dist/targets-BHYLCv06.js +0 -2534
  840. package/dist/targets-BjWhDMJM.js +0 -650
  841. package/dist/targets-BnpMZZC_.js +0 -120
  842. package/dist/targets-CHwGDIgO.js +0 -650
  843. package/dist/targets-DIDKlfKI.js +0 -220
  844. package/dist/targets-bqjVeCnF.js +0 -2535
  845. package/dist/targets-mqj9GNg1.js +0 -53
  846. package/dist/tool-display-C0hpLmkw.js +0 -785
  847. package/dist/tool-display-CQTRHo3Z.js +0 -785
  848. package/dist/tool-images-BYY11Gw3.js +0 -263
  849. package/dist/tool-images-CnJ0R8Fo.js +0 -263
  850. package/dist/trash-C0mjnHuW.js +0 -125
  851. package/dist/trash-Cgwc9mLD.js +0 -125
  852. package/dist/tui-9cJnR1dN.js +0 -3282
  853. package/dist/tui-BR3egaFJ.js +0 -3282
  854. package/dist/tui-cli-BYpkhE6J.js +0 -66
  855. package/dist/tui-cli-DndeZyup.js +0 -62
  856. package/dist/update-BJVdkzk7.js +0 -349
  857. package/dist/update-DjI6KTA5.js +0 -349
  858. package/dist/update-cli-B7Rl2Qr2.js +0 -1146
  859. package/dist/update-cli-CFk_jqUm.js +0 -1148
  860. package/dist/usage-CFv4a1Nf.js +0 -5448
  861. package/dist/voice-credentials-D59RcLbl.js +0 -45
  862. package/dist/voice-credentials-fjA7GShF.js +0 -45
  863. package/dist/web-Bs1td8Qw.js +0 -79
  864. package/dist/web-CSiw--Px.js +0 -3070
  865. package/dist/web-jRTtDiNf.js +0 -74
  866. package/dist/webhooks-cli-0yQha2yj.js +0 -334
  867. package/dist/webhooks-cli-ula0bTX-.js +0 -330
  868. package/dist/whatsapp-actions-3NdzsNg1.js +0 -130
  869. package/dist/whatsapp-actions-y_1vjkYY.js +0 -125
  870. package/dist/workspace-BT3X-qCZ.js +0 -449
  871. package/dist/workspace-D5hHXubL.js +0 -447
  872. package/dist/zod-schema-CbqZAIYy.js +0 -2696
  873. package/dist/zod-schema-YGQJEcnj.js +0 -2696
  874. /package/dist/{account-lookup-BOCzCnir.js → account-lookup-CIY_RKhi.js} +0 -0
  875. /package/dist/{account-lookup-C0ndrpt-.js → account-lookup-DGscKBsr.js} +0 -0
  876. /package/dist/{agent-helpers-eEHy5uX2.js → agent-helpers-D83kfcF9.js} +0 -0
  877. /package/dist/{agents.config-BgDBcY4h.js → agents.config-BPe_hkMn.js} +0 -0
  878. /package/dist/{api-Cd_7aESj.js → api-D8QQo5bc.js} +0 -0
  879. /package/dist/{api-DJ_oWYus.js → api-GywrnwRm.js} +0 -0
  880. /package/dist/{argv-BY8EVMTP.js → argv-DW4MYBdJ.js} +0 -0
  881. /package/dist/{bindings-Dr0bGRst.js → bindings-BpL4pISF.js} +0 -0
  882. /package/dist/{brew-CmTYeZk1.js → brew-CBsS-Vq1.js} +0 -0
  883. /package/dist/{brew-V4lMBeE3.js → brew-Clw9vXhE.js} +0 -0
  884. /package/dist/{chat-envelope-CrM0X4sl.js → chat-envelope-CY1yvCc-.js} +0 -0
  885. /package/dist/{chat-envelope-BIujl9Cj.js → chat-envelope-DUMcMMB2.js} +0 -0
  886. /package/dist/{chat-type-CH3W-zKy.js → chat-type-BKe459rw.js} +0 -0
  887. /package/dist/{chat-type-DyovJwCt.js → chat-type-CE6cJOyt.js} +0 -0
  888. /package/dist/{cleanup-utils-CNwlTKyR.js → cleanup-utils-365rf8YN.js} +0 -0
  889. /package/dist/{cleanup-utils-gNzIs9yk.js → cleanup-utils-rqUXvR3Z.js} +0 -0
  890. /package/dist/{cli-name-3MdfbvIR.js → cli-name-7Gb97Vyl.js} +0 -0
  891. /package/dist/{cli-name-CRLBidNP.js → cli-name-Yv30OygA.js} +0 -0
  892. /package/dist/{cli-utils-5ZIfXAfM.js → cli-utils-5W6ugvN5.js} +0 -0
  893. /package/dist/{cli-utils-BUOtyfnU.js → cli-utils-CZJacPS2.js} +0 -0
  894. /package/dist/{client-D5m46AuY.js → client-DQ-Nh-rV.js} +0 -0
  895. /package/dist/{client-DFyI5I0n.js → client-Fi2k2G9Z.js} +0 -0
  896. /package/dist/{command-options-Cn2fc1Of.js → command-options-CXHYeogR.js} +0 -0
  897. /package/dist/{command-options-D2nN4AXX.js → command-options-Cx6evn0x.js} +0 -0
  898. /package/dist/{config-eval-CU2G7a83.js → config-eval-DU_v_3lY.js} +0 -0
  899. /package/dist/{config-eval-BCKpAS_K.js → config-eval-V26Gl6eZ.js} +0 -0
  900. /package/dist/{constants-CRGAZ2ow.js → constants-C7gkSGRE.js} +0 -0
  901. /package/dist/{constants-BAZuhSRm.js → constants-DAiBiWlI.js} +0 -0
  902. /package/dist/{constants-DoYLsBmv.js → constants-DOnQraOP.js} +0 -0
  903. /package/dist/{constants-BBVTjb1j.js → constants-DQxqJVLu.js} +0 -0
  904. /package/dist/{credentials-DMAWNZdV.js → credentials-BHWUBHMd.js} +0 -0
  905. /package/dist/{credentials-Dmc3H-jd.js → credentials-DG0tD6-e.js} +0 -0
  906. /package/dist/{daemon-runtime-CzFI2dPw.js → daemon-runtime-B7Tmba31.js} +0 -0
  907. /package/dist/{daemon-runtime-aQhinwSL.js → daemon-runtime-KyXiP2ib.js} +0 -0
  908. /package/dist/{dangerous-name-matching-BlTBBZns.js → dangerous-name-matching-B4MRPcn-.js} +0 -0
  909. /package/dist/{dangerous-tools-BRmbBvRf.js → dangerous-tools-CIPZZJoN.js} +0 -0
  910. /package/dist/{dangerous-tools-E1i3IoxZ.js → dangerous-tools-D-GNbdpV.js} +0 -0
  911. /package/dist/{fetch-timeout-DBRRPNBi.js → fetch-timeout-CPe2rPLq.js} +0 -0
  912. /package/dist/{fetch-timeout-l_6RdoMw.js → fetch-timeout-DkT3EnRA.js} +0 -0
  913. /package/dist/{file-identity-BnGA6wyc.js → file-identity-C8MIb5lb.js} +0 -0
  914. /package/dist/{format-duration-B-Uv5nOi.js → format-duration-Cd7SCued.js} +0 -0
  915. /package/dist/{format-duration-D1M3Zxu6.js → format-duration-Oj8pTbYL.js} +0 -0
  916. /package/dist/{format-relative-Cywx6ldk.js → format-relative-8dpVUfzZ.js} +0 -0
  917. /package/dist/{format-relative-DcQZUAYl.js → format-relative-BMNeqaxW.js} +0 -0
  918. /package/dist/{health-format-CL2Xq92A.js → health-format-CwLlmYSK.js} +0 -0
  919. /package/dist/{health-format-CVgQD-z9.js → health-format-CycFH5Sj.js} +0 -0
  920. /package/dist/{heartbeat-wake-DLxQm6-U.js → heartbeat-wake-D6Lt5YUk.js} +0 -0
  921. /package/dist/{heartbeat-wake-DjsTDzF3.js → heartbeat-wake-uZkAP-tP.js} +0 -0
  922. /package/dist/{help-format-DM6-OBt-.js → help-format-B0YIbosn.js} +0 -0
  923. /package/dist/{help-format-CJQ7APRn.js → help-format-GeOPYD_A.js} +0 -0
  924. /package/dist/{helpers-BER76F_2.js → helpers-6_MYSJEW.js} +0 -0
  925. /package/dist/{helpers-DSMIGYx2.js → helpers-703bXVlF.js} +0 -0
  926. /package/dist/{helpers-D-r6yhnI.js → helpers-p_u0Gnj_.js} +0 -0
  927. /package/dist/{input-provenance-BgfeDgck.js → input-provenance-C4nlFv5Y.js} +0 -0
  928. /package/dist/{input-provenance-xUsSMOsz.js → input-provenance-duDehu0D.js} +0 -0
  929. /package/dist/{ip-BAhS4rY2.js → ip-BFJnbRh9.js} +0 -0
  930. /package/dist/{ip-BUhsZdJu.js → ip-D0zgNmBV.js} +0 -0
  931. /package/dist/{is-main-BmHYGRhd.js → is-main-BE1Jih91.js} +0 -0
  932. /package/dist/{json-file-B5WEJJye.js → json-file-CsV03dh-.js} +0 -0
  933. /package/dist/{json-file-Dbg7nZg1.js → json-file-CtQKYRLl.js} +0 -0
  934. /package/dist/{json-files-BFGbyEzL.js → json-files-B2yMsppu.js} +0 -0
  935. /package/dist/{json-files-CfhnuGaC.js → json-files-BYH8U7Mx.js} +0 -0
  936. /package/dist/{lanes-4FoQemog.js → lanes-BWL_LwXG.js} +0 -0
  937. /package/dist/{lanes-BhdzrAIa.js → lanes-cHJ5arWg.js} +0 -0
  938. /package/dist/{links-CwTlzaPe.js → links-BFtUmGLH.js} +0 -0
  939. /package/dist/{links-D5vtq30Q.js → links-BNjLUJ9U.js} +0 -0
  940. /package/dist/{location-50gaJF5Z.js → location-BC45kOxc.js} +0 -0
  941. /package/dist/{location-Qo8Ii1zo.js → location-BUhzov-a.js} +0 -0
  942. /package/dist/{logger-IA_Dr_BT.js → logger-1QWMF9Hc.js} +0 -0
  943. /package/dist/{logger-nEdVxm5D.js → logger-BWMPnILd.js} +0 -0
  944. /package/dist/{logger-O6JX52kK.js → logger-Liu31nEU.js} +0 -0
  945. /package/dist/{logging-FctZEleJ.js → logging-CtbzyUjs.js} +0 -0
  946. /package/dist/{logging-BiuZwq5D.js → logging-DJFQvfGD.js} +0 -0
  947. /package/dist/{logging-Bs1VqVFL.js → logging-JiRrQn2_.js} +0 -0
  948. /package/dist/{logging-JZEg5nDp.js → logging-kuFzZMsG.js} +0 -0
  949. /package/dist/{message-channel-tuc9CdEw.js → message-channel-DOyKgFu8.js} +0 -0
  950. /package/dist/{mutable-allowlist-detectors-CtKavajp.js → mutable-allowlist-detectors-4m-Kc8Kn.js} +0 -0
  951. /package/dist/{mutable-allowlist-detectors-TCG6mnbz.js → mutable-allowlist-detectors-BECxOoKX.js} +0 -0
  952. /package/dist/{onboard-config-BxfgUqk6.js → onboard-config-C9so5ggC.js} +0 -0
  953. /package/dist/{onboard-config-DNzlo8Cg.js → onboard-config-oXID97rS.js} +0 -0
  954. /package/dist/{parse-log-line-CT0H1-oQ.js → parse-log-line-BtFI563v.js} +0 -0
  955. /package/dist/{parse-log-line-pij_xhtE.js → parse-log-line-COptqka7.js} +0 -0
  956. /package/dist/{parse-timeout-CvODy9RC.js → parse-timeout-BpphuwYl.js} +0 -0
  957. /package/dist/{path-guards-DOpzcMXz.js → path-guards-DJteVA0d.js} +0 -0
  958. /package/dist/{path-guards-DipYoPVw.js → path-guards-DVRUJZVN.js} +0 -0
  959. /package/dist/plugin-sdk/{media-understanding → stt}/providers/google/inline-data.d.ts +0 -0
  960. /package/dist/{plugins-allowlist-Bcqe9Gd8.js → plugins-allowlist-Clt6dsY6.js} +0 -0
  961. /package/dist/{polls-DQrR-qT3.js → polls-C5xr-8pM.js} +0 -0
  962. /package/dist/{polls-ybwcqkWt.js → polls-DXd67TD8.js} +0 -0
  963. /package/dist/{ports-lsof-CDyv5GJd.js → ports-lsof-xWMTWvMQ.js} +0 -0
  964. /package/dist/{process-scoped-map-BwUkYFQV.js → process-scoped-map-C7KeadUK.js} +0 -0
  965. /package/dist/{process-scoped-map-_zxf_kLz.js → process-scoped-map-CQ1C5MbT.js} +0 -0
  966. /package/dist/{program-context-CG-t6Yp-.js → program-context-LuBAPt4y.js} +0 -0
  967. /package/dist/{progress-DRLmcFiG.js → progress-C-hTn2yV.js} +0 -0
  968. /package/dist/{progress-BOdRbOHD.js → progress-ChmZpgvt.js} +0 -0
  969. /package/dist/{prompt-WEkXwIMT.js → prompt-BXeXEH0o.js} +0 -0
  970. /package/dist/{prompt-BRGfic91.js → prompt-C31r0R5I.js} +0 -0
  971. /package/dist/{prompt-style-B4Cq4PyQ.js → prompt-style-BcM-VSMx.js} +0 -0
  972. /package/dist/{proxy-BMJL0Qog.js → proxy-dRhp8Ykw.js} +0 -0
  973. /package/dist/{pw-ai-state-CwXeO5d0.js → pw-ai-state-CjfcKQoO.js} +0 -0
  974. /package/dist/{pw-ai-state-DaISdsXY.js → pw-ai-state-DfjyEttO.js} +0 -0
  975. /package/dist/{redact-gXuh8MFk.js → redact-D975G-N6.js} +0 -0
  976. /package/dist/{redact-CqWx9rpK.js → redact-Dx1Fue21.js} +0 -0
  977. /package/dist/{redact-identifier-BJOQDEj0.js → redact-identifier-Bqj_YiPd.js} +0 -0
  978. /package/dist/{redact-identifier-DR54qsoT.js → redact-identifier-HyK89Sod.js} +0 -0
  979. /package/dist/{remoteclaw-root-CgNyrbxc.js → remoteclaw-root-B1iQBmbi.js} +0 -0
  980. /package/dist/{remoteclaw-root-u8dAeHID.js → remoteclaw-root-BmYwCzQN.js} +0 -0
  981. /package/dist/{render-CDCvpfhh.js → render-BvFSFJZW.js} +0 -0
  982. /package/dist/{render-CJl4GK1B.js → render-flG67HhW.js} +0 -0
  983. /package/dist/{response-prefix-template-D3ZcJP4E.js → response-prefix-template-DDvbVpx6.js} +0 -0
  984. /package/dist/{retry-cXXk2j6_.js → retry-CByUYDAZ.js} +0 -0
  985. /package/dist/{retry-B19gMxS7.js → retry-oNE3cBeG.js} +0 -0
  986. /package/dist/{runtime-guard-BS55uiSW.js → runtime-guard-CqNug-FG.js} +0 -0
  987. /package/dist/{runtime-guard-CK80eucm.js → runtime-guard-DAHXelsb.js} +0 -0
  988. /package/dist/{runtime-status-BhW7hP_U.js → runtime-status-CM4rzyfO.js} +0 -0
  989. /package/dist/{runtime-status-hFVEC3wO.js → runtime-status-DJYthOLz.js} +0 -0
  990. /package/dist/{secret-equal-CJzes24Z.js → secret-equal-1-dwi8DL.js} +0 -0
  991. /package/dist/{secret-equal-CQAmGfGc.js → secret-equal-CXJEZiWb.js} +0 -0
  992. /package/dist/{secure-random-B3f7Ri2X.js → secure-random-Ba4Y5xG5.js} +0 -0
  993. /package/dist/{secure-random-BkZFG9cd.js → secure-random-C6AVByhV.js} +0 -0
  994. /package/dist/{stagger-B-_Wnofy.js → stagger-CjeisVRF.js} +0 -0
  995. /package/dist/{stagger-B2ORDHsP.js → stagger-vkvpUmOz.js} +0 -0
  996. /package/dist/{status-C6YNwimj.js → status-DNLnVQZ4.js} +0 -0
  997. /package/dist/{status-yrDGXYZM.js → status-DZhl73dM.js} +0 -0
  998. /package/dist/{strip-inbound-meta-0cvL6itU.js → strip-inbound-meta-C3Cwe_ZO.js} +0 -0
  999. /package/dist/{strip-inbound-meta-DjKcSFaW.js → strip-inbound-meta-DuDjnGjC.js} +0 -0
  1000. /package/dist/{table-ByMyHTh_.js → table-B9zSN_7D.js} +0 -0
  1001. /package/dist/{table-C-dba-5-.js → table-j8Ayarot.js} +0 -0
  1002. /package/dist/{target-errors-DJVRKFcU.js → target-errors-ChjvOMuV.js} +0 -0
  1003. /package/dist/{target-errors-GZXDqlUu.js → target-errors-Dn4aykSV.js} +0 -0
  1004. /package/dist/{targets-B_d_1z3N.js → targets-BtGRUQMa.js} +0 -0
  1005. /package/dist/{targets-DOJXjN1U.js → targets-CE4AYRI9.js} +0 -0
  1006. /package/dist/{targets-D01MJGnh.js → targets-DlufWCmy.js} +0 -0
  1007. /package/dist/{targets-WSwPflb6.js → targets-akvAerZF.js} +0 -0
  1008. /package/dist/{text-format-DarxU3JH.js → text-format-VSogn9Yq.js} +0 -0
  1009. /package/dist/{text-format-mr5bZq0f.js → text-format-xeHt9ywT.js} +0 -0
  1010. /package/dist/{thinking-BqJmU6Zp.js → thinking-B171Rc3-.js} +0 -0
  1011. /package/dist/{tokens-C8yGxAcR.js → tokens-B-jmvNR9.js} +0 -0
  1012. /package/dist/{tokens-DAFBx5qr.js → tokens-kTLGxaAF.js} +0 -0
  1013. /package/dist/{usage-BXi79Rq6.js → usage-CRJFqYf8.js} +0 -0
  1014. /package/dist/{usage-C1lHaofV.js → usage-Txvb0Iq2.js} +0 -0
  1015. /package/dist/{usage-format-CD5jsZY1.js → usage-format-70DvrseE.js} +0 -0
  1016. /package/dist/{usage-format-CRVpDVj1.js → usage-format-Bs8DkQtr.js} +0 -0
  1017. /package/dist/{widearea-dns-C-0P7TRi.js → widearea-dns-BOgHvO4O.js} +0 -0
  1018. /package/dist/{widearea-dns-DFZMcfLf.js → widearea-dns-CGhfClCr.js} +0 -0
  1019. /package/dist/{workspace-BJCKO8Ns.js → workspace-DhUqtMK_.js} +0 -0
  1020. /package/dist/{wsl-kFaeW76c.js → wsl-Cs-gowFJ.js} +0 -0
@@ -0,0 +1,4231 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
+ import { a as resolveCanonicalConfigPath, c as resolveDefaultConfigCandidates, d as resolveIsNixMode, f as resolveLegacyStateDirs, h as resolveStateDir, i as isNixMode, l as resolveGatewayLockDir, m as resolveOAuthDir, n as DEFAULT_GATEWAY_PORT, o as resolveConfigPath, p as resolveNewStateDir, r as STATE_DIR, s as resolveConfigPathCandidate, t as CONFIG_PATH, u as resolveGatewayPort, v as resolveRequiredHomeDir } from "./paths-BTaH3rLn.js";
3
+ import { _ as resolveUserPath, l as isRecord, m as resolveConfigDir, w as isPlainObject$2 } from "./utils-C5daYcFn.js";
4
+ import { _ as normalizeChatChannelId, l as CHANNEL_IDS } from "./subsystem-m7RSGQoR.js";
5
+ import { _ as isBlockedObjectKey, s as normalizeAgentId, t as DEFAULT_AGENT_ID } from "./session-key-CgKWfjoZ.js";
6
+ import { c as resolveDefaultAgentId, s as resolveAgentWorkspaceDirOrNull } from "./agent-scope-DVvX_nkQ.js";
7
+ import { o as parseModelRef } from "./provider-utils-C9kBVF1f.js";
8
+ import { a as shouldEnableShellEnvFallback, i as shouldDeferShellEnvFallback, n as loadShellEnvFallback, r as resolveShellEnvFallbackTimeoutMs } from "./shell-env-D8nXPDbP.js";
9
+ import { t as VERSION } from "./version-CVMnqdzu.js";
10
+ import { t as applyConfigEnvVars } from "./env-vars-a7S70ba7.js";
11
+ import { _ as resolveTelegramPreviewStreamMode, f as isSafeExecutableValue, g as resolveSlackStreamingMode, h as resolveSlackNativeStreaming, m as resolveDiscordPreviewStreamMode, t as RemoteClawSchema } from "./zod-schema-CCUbW_Si.js";
12
+ import { d as TOOLS_BY_SENDER_KEY_TYPES, f as parseToolsBySenderTypedKey } from "./dock-ByrYnLiz.js";
13
+ import { fileURLToPath } from "node:url";
14
+ import fs from "node:fs";
15
+ import os from "node:os";
16
+ import path from "node:path";
17
+ import JSON5 from "json5";
18
+ import { isDeepStrictEqual } from "node:util";
19
+ import crypto from "node:crypto";
20
+ import dotenv from "dotenv";
21
+ import AjvPkg from "ajv";
22
+
23
+ //#region src/agents/owner-display.ts
24
+ function trimToUndefined(value) {
25
+ const trimmed = value?.trim();
26
+ return trimmed ? trimmed : void 0;
27
+ }
28
+ /**
29
+ * Resolve owner display settings for prompt rendering.
30
+ * Keep auth secrets decoupled from owner hash secrets.
31
+ */
32
+ function resolveOwnerDisplaySetting(config) {
33
+ const ownerDisplay = config?.commands?.ownerDisplay;
34
+ if (ownerDisplay !== "hash") return {
35
+ ownerDisplay,
36
+ ownerDisplaySecret: void 0
37
+ };
38
+ return {
39
+ ownerDisplay: "hash",
40
+ ownerDisplaySecret: trimToUndefined(config?.commands?.ownerDisplaySecret)
41
+ };
42
+ }
43
+ /**
44
+ * Ensure hash mode has a dedicated secret.
45
+ * Returns updated config and generated secret when autofill was needed.
46
+ */
47
+ function ensureOwnerDisplaySecret(config, generateSecret = () => crypto.randomBytes(32).toString("hex")) {
48
+ const settings = resolveOwnerDisplaySetting(config);
49
+ if (settings.ownerDisplay !== "hash" || settings.ownerDisplaySecret) return { config };
50
+ const generatedSecret = generateSecret();
51
+ return {
52
+ config: {
53
+ ...config,
54
+ commands: {
55
+ ...config.commands,
56
+ ownerDisplay: "hash",
57
+ ownerDisplaySecret: generatedSecret
58
+ }
59
+ },
60
+ generatedSecret
61
+ };
62
+ }
63
+
64
+ //#endregion
65
+ //#region src/infra/dotenv.ts
66
+ function loadDotEnv(opts) {
67
+ const quiet = opts?.quiet ?? true;
68
+ dotenv.config({ quiet });
69
+ const globalEnvPath = path.join(resolveConfigDir(process.env), ".env");
70
+ if (!fs.existsSync(globalEnvPath)) return;
71
+ dotenv.config({
72
+ quiet,
73
+ path: globalEnvPath,
74
+ override: false
75
+ });
76
+ }
77
+
78
+ //#endregion
79
+ //#region src/config/agent-dirs.ts
80
+ var DuplicateAgentDirError = class extends Error {
81
+ constructor(duplicates) {
82
+ super(formatDuplicateAgentDirError(duplicates));
83
+ this.name = "DuplicateAgentDirError";
84
+ this.duplicates = duplicates;
85
+ }
86
+ };
87
+ function canonicalizeAgentDir(agentDir) {
88
+ const resolved = path.resolve(agentDir);
89
+ if (process.platform === "darwin" || process.platform === "win32") return resolved.toLowerCase();
90
+ return resolved;
91
+ }
92
+ function collectReferencedAgentIds(cfg) {
93
+ const ids = /* @__PURE__ */ new Set();
94
+ const agents = Array.isArray(cfg.agents?.list) ? cfg.agents?.list : [];
95
+ const defaultAgentId = agents.find((agent) => agent?.default)?.id ?? agents[0]?.id ?? DEFAULT_AGENT_ID;
96
+ ids.add(normalizeAgentId(defaultAgentId));
97
+ for (const entry of agents) if (entry?.id) ids.add(normalizeAgentId(entry.id));
98
+ const bindings = cfg.bindings;
99
+ if (Array.isArray(bindings)) for (const binding of bindings) {
100
+ const id = binding?.agentId;
101
+ if (typeof id === "string" && id.trim()) ids.add(normalizeAgentId(id));
102
+ }
103
+ return [...ids];
104
+ }
105
+ function resolveEffectiveAgentDir(cfg, agentId, deps) {
106
+ const id = normalizeAgentId(agentId);
107
+ const trimmed = (Array.isArray(cfg.agents?.list) ? cfg.agents?.list.find((agent) => normalizeAgentId(agent.id) === id)?.agentDir : void 0)?.trim();
108
+ if (trimmed) return resolveUserPath(trimmed);
109
+ const env = deps?.env ?? process.env;
110
+ const root = resolveStateDir(env, deps?.homedir ?? (() => resolveRequiredHomeDir(env, os.homedir)));
111
+ return path.join(root, "agents", id, "agent");
112
+ }
113
+ function findDuplicateAgentDirs(cfg, deps) {
114
+ const byDir = /* @__PURE__ */ new Map();
115
+ for (const agentId of collectReferencedAgentIds(cfg)) {
116
+ const agentDir = resolveEffectiveAgentDir(cfg, agentId, deps);
117
+ const key = canonicalizeAgentDir(agentDir);
118
+ const entry = byDir.get(key);
119
+ if (entry) entry.agentIds.push(agentId);
120
+ else byDir.set(key, {
121
+ agentDir,
122
+ agentIds: [agentId]
123
+ });
124
+ }
125
+ return [...byDir.values()].filter((v) => v.agentIds.length > 1);
126
+ }
127
+ function formatDuplicateAgentDirError(dups) {
128
+ return [
129
+ "Duplicate agentDir detected (multi-agent config).",
130
+ "Each agent must have a unique agentDir; sharing it causes session state collisions.",
131
+ "",
132
+ "Conflicts:",
133
+ ...dups.map((d) => `- ${d.agentDir}: ${d.agentIds.map((id) => `"${id}"`).join(", ")}`),
134
+ "",
135
+ "Fix: remove the shared agents.list[].agentDir override (or give each agent its own directory)."
136
+ ].join("\n");
137
+ }
138
+
139
+ //#endregion
140
+ //#region src/config/backup-rotation.ts
141
+ const CONFIG_BACKUP_COUNT = 5;
142
+ async function rotateConfigBackups(configPath, ioFs) {
143
+ if (CONFIG_BACKUP_COUNT <= 1) return;
144
+ const backupBase = `${configPath}.bak`;
145
+ const maxIndex = CONFIG_BACKUP_COUNT - 1;
146
+ await ioFs.unlink(`${backupBase}.${maxIndex}`).catch(() => {});
147
+ for (let index = maxIndex - 1; index >= 1; index -= 1) await ioFs.rename(`${backupBase}.${index}`, `${backupBase}.${index + 1}`).catch(() => {});
148
+ await ioFs.rename(backupBase, `${backupBase}.1`).catch(() => {});
149
+ }
150
+
151
+ //#endregion
152
+ //#region src/config/agent-limits.ts
153
+ const DEFAULT_AGENT_MAX_CONCURRENT = 4;
154
+ const DEFAULT_SUBAGENT_MAX_CONCURRENT = 8;
155
+ const DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH = 1;
156
+ function resolveAgentMaxConcurrent(cfg) {
157
+ const raw = cfg?.agents?.defaults?.maxConcurrent;
158
+ if (typeof raw === "number" && Number.isFinite(raw)) return Math.max(1, Math.floor(raw));
159
+ return DEFAULT_AGENT_MAX_CONCURRENT;
160
+ }
161
+ function resolveSubagentMaxConcurrent(cfg) {
162
+ const raw = cfg?.agents?.defaults?.subagents?.maxConcurrent;
163
+ if (typeof raw === "number" && Number.isFinite(raw)) return Math.max(1, Math.floor(raw));
164
+ return DEFAULT_SUBAGENT_MAX_CONCURRENT;
165
+ }
166
+
167
+ //#endregion
168
+ //#region src/config/talk.ts
169
+ const DEFAULT_TALK_PROVIDER = "elevenlabs";
170
+ function isPlainObject$1(value) {
171
+ return typeof value === "object" && value !== null && !Array.isArray(value);
172
+ }
173
+ function normalizeString(value) {
174
+ if (typeof value !== "string") return;
175
+ const trimmed = value.trim();
176
+ return trimmed.length > 0 ? trimmed : void 0;
177
+ }
178
+ function normalizeVoiceAliases(value) {
179
+ if (!isPlainObject$1(value)) return;
180
+ const aliases = {};
181
+ for (const [alias, rawId] of Object.entries(value)) {
182
+ if (typeof rawId !== "string") continue;
183
+ aliases[alias] = rawId;
184
+ }
185
+ return Object.keys(aliases).length > 0 ? aliases : void 0;
186
+ }
187
+ function normalizeTalkProviderConfig(value) {
188
+ if (!isPlainObject$1(value)) return;
189
+ const provider = {};
190
+ for (const [key, raw] of Object.entries(value)) {
191
+ if (raw === void 0) continue;
192
+ if (key === "voiceAliases") {
193
+ const aliases = normalizeVoiceAliases(raw);
194
+ if (aliases) provider.voiceAliases = aliases;
195
+ continue;
196
+ }
197
+ if (key === "voiceId" || key === "modelId" || key === "outputFormat" || key === "apiKey") {
198
+ const normalized = normalizeString(raw);
199
+ if (normalized) provider[key] = normalized;
200
+ continue;
201
+ }
202
+ provider[key] = raw;
203
+ }
204
+ return Object.keys(provider).length > 0 ? provider : void 0;
205
+ }
206
+ function normalizeTalkProviders(value) {
207
+ if (!isPlainObject$1(value)) return;
208
+ const providers = {};
209
+ for (const [rawProviderId, providerConfig] of Object.entries(value)) {
210
+ const providerId = normalizeString(rawProviderId);
211
+ if (!providerId) continue;
212
+ const normalizedProvider = normalizeTalkProviderConfig(providerConfig);
213
+ if (!normalizedProvider) continue;
214
+ providers[providerId] = normalizedProvider;
215
+ }
216
+ return Object.keys(providers).length > 0 ? providers : void 0;
217
+ }
218
+ function normalizedLegacyTalkFields(source) {
219
+ const legacy = {};
220
+ const voiceId = normalizeString(source.voiceId);
221
+ if (voiceId) legacy.voiceId = voiceId;
222
+ const voiceAliases = normalizeVoiceAliases(source.voiceAliases);
223
+ if (voiceAliases) legacy.voiceAliases = voiceAliases;
224
+ const modelId = normalizeString(source.modelId);
225
+ if (modelId) legacy.modelId = modelId;
226
+ const outputFormat = normalizeString(source.outputFormat);
227
+ if (outputFormat) legacy.outputFormat = outputFormat;
228
+ const apiKey = normalizeString(source.apiKey);
229
+ if (apiKey) legacy.apiKey = apiKey;
230
+ return legacy;
231
+ }
232
+ function legacyProviderConfigFromTalk(source) {
233
+ return normalizeTalkProviderConfig({
234
+ voiceId: source.voiceId,
235
+ voiceAliases: source.voiceAliases,
236
+ modelId: source.modelId,
237
+ outputFormat: source.outputFormat,
238
+ apiKey: source.apiKey
239
+ });
240
+ }
241
+ function activeProviderFromTalk(talk) {
242
+ const provider = normalizeString(talk.provider);
243
+ if (provider) return provider;
244
+ const providerIds = talk.providers ? Object.keys(talk.providers) : [];
245
+ return providerIds.length === 1 ? providerIds[0] : void 0;
246
+ }
247
+ function legacyTalkFieldsFromProviderConfig(config) {
248
+ if (!config) return {};
249
+ const legacy = {};
250
+ if (typeof config.voiceId === "string") legacy.voiceId = config.voiceId;
251
+ if (config.voiceAliases && typeof config.voiceAliases === "object" && !Array.isArray(config.voiceAliases)) {
252
+ const aliases = normalizeVoiceAliases(config.voiceAliases);
253
+ if (aliases) legacy.voiceAliases = aliases;
254
+ }
255
+ if (typeof config.modelId === "string") legacy.modelId = config.modelId;
256
+ if (typeof config.outputFormat === "string") legacy.outputFormat = config.outputFormat;
257
+ if (typeof config.apiKey === "string") legacy.apiKey = config.apiKey;
258
+ return legacy;
259
+ }
260
+ function normalizeTalkSection(value) {
261
+ if (!isPlainObject$1(value)) return;
262
+ const source = value;
263
+ const hasNormalizedShape = typeof source.provider === "string" || isPlainObject$1(source.providers);
264
+ const normalized = {};
265
+ const legacy = normalizedLegacyTalkFields(source);
266
+ if (Object.keys(legacy).length > 0) Object.assign(normalized, legacy);
267
+ if (typeof source.interruptOnSpeech === "boolean") normalized.interruptOnSpeech = source.interruptOnSpeech;
268
+ if (hasNormalizedShape) {
269
+ const providers = normalizeTalkProviders(source.providers);
270
+ const provider = normalizeString(source.provider);
271
+ if (providers) normalized.providers = providers;
272
+ if (provider) normalized.provider = provider;
273
+ else if (providers) {
274
+ const ids = Object.keys(providers);
275
+ if (ids.length === 1) normalized.provider = ids[0];
276
+ }
277
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
278
+ }
279
+ const legacyProviderConfig = legacyProviderConfigFromTalk(source);
280
+ if (legacyProviderConfig) {
281
+ normalized.provider = DEFAULT_TALK_PROVIDER;
282
+ normalized.providers = { [DEFAULT_TALK_PROVIDER]: legacyProviderConfig };
283
+ }
284
+ return Object.keys(normalized).length > 0 ? normalized : void 0;
285
+ }
286
+ function normalizeTalkConfig(config) {
287
+ if (!config.talk) return config;
288
+ const normalizedTalk = normalizeTalkSection(config.talk);
289
+ if (!normalizedTalk) return config;
290
+ return {
291
+ ...config,
292
+ talk: normalizedTalk
293
+ };
294
+ }
295
+ function resolveActiveTalkProviderConfig(talk) {
296
+ const normalizedTalk = normalizeTalkSection(talk);
297
+ if (!normalizedTalk) return {};
298
+ const provider = activeProviderFromTalk(normalizedTalk);
299
+ if (!provider) return {};
300
+ return {
301
+ provider,
302
+ config: normalizedTalk.providers?.[provider]
303
+ };
304
+ }
305
+ function buildTalkConfigResponse(value) {
306
+ if (!isPlainObject$1(value)) return;
307
+ const normalized = normalizeTalkSection(value);
308
+ if (!normalized) return;
309
+ const payload = {};
310
+ if (typeof normalized.interruptOnSpeech === "boolean") payload.interruptOnSpeech = normalized.interruptOnSpeech;
311
+ if (normalized.providers && Object.keys(normalized.providers).length > 0) payload.providers = normalized.providers;
312
+ if (typeof normalized.provider === "string") payload.provider = normalized.provider;
313
+ const activeProvider = activeProviderFromTalk(normalized);
314
+ const providerCompatibilityLegacy = legacyTalkFieldsFromProviderConfig(activeProvider ? normalized.providers?.[activeProvider] : void 0);
315
+ const compatibilityLegacy = Object.keys(providerCompatibilityLegacy).length > 0 ? providerCompatibilityLegacy : normalizedLegacyTalkFields(normalized);
316
+ Object.assign(payload, compatibilityLegacy);
317
+ return Object.keys(payload).length > 0 ? payload : void 0;
318
+ }
319
+ function readTalkApiKeyFromProfile(deps = {}) {
320
+ const fsImpl = deps.fs ?? fs;
321
+ const osImpl = deps.os ?? os;
322
+ const pathImpl = deps.path ?? path;
323
+ const home = osImpl.homedir();
324
+ const candidates = [
325
+ ".profile",
326
+ ".zprofile",
327
+ ".zshrc",
328
+ ".bashrc"
329
+ ].map((name) => pathImpl.join(home, name));
330
+ for (const candidate of candidates) {
331
+ if (!fsImpl.existsSync(candidate)) continue;
332
+ try {
333
+ const value = fsImpl.readFileSync(candidate, "utf-8").match(/(?:^|\n)\s*(?:export\s+)?ELEVENLABS_API_KEY\s*=\s*["']?([^\n"']+)["']?/)?.[1]?.trim();
334
+ if (value) return value;
335
+ } catch {}
336
+ }
337
+ return null;
338
+ }
339
+ function resolveTalkApiKey(env = process.env, deps = {}) {
340
+ const envValue = (env.ELEVENLABS_API_KEY ?? "").trim();
341
+ if (envValue) return envValue;
342
+ return readTalkApiKeyFromProfile(deps);
343
+ }
344
+
345
+ //#endregion
346
+ //#region src/config/defaults.ts
347
+ let defaultWarnState = { warned: false };
348
+ const DEFAULT_MODEL_ALIASES = {
349
+ opus: "anthropic/claude-opus-4-6",
350
+ sonnet: "anthropic/claude-sonnet-4-6",
351
+ gpt: "openai/gpt-5.2",
352
+ "gpt-mini": "openai/gpt-5-mini",
353
+ gemini: "google/gemini-3-pro-preview",
354
+ "gemini-flash": "google/gemini-3-flash-preview"
355
+ };
356
+ function resolveAnthropicDefaultAuthMode(cfg) {
357
+ const profiles = cfg.auth?.profiles ?? {};
358
+ const anthropicProfiles = Object.entries(profiles).filter(([, profile]) => profile?.provider === "anthropic");
359
+ const order = cfg.auth?.order?.anthropic ?? [];
360
+ for (const profileId of order) {
361
+ const entry = profiles[profileId];
362
+ if (!entry || entry.provider !== "anthropic") continue;
363
+ if (entry.mode === "api_key") return "api_key";
364
+ if (entry.mode === "oauth" || entry.mode === "token") return "oauth";
365
+ }
366
+ const hasApiKey = anthropicProfiles.some(([, profile]) => profile?.mode === "api_key");
367
+ const hasOauth = anthropicProfiles.some(([, profile]) => profile?.mode === "oauth" || profile?.mode === "token");
368
+ if (hasApiKey && !hasOauth) return "api_key";
369
+ if (hasOauth && !hasApiKey) return "oauth";
370
+ if (process.env.ANTHROPIC_OAUTH_TOKEN?.trim()) return "oauth";
371
+ if (process.env.ANTHROPIC_API_KEY?.trim()) return "api_key";
372
+ return null;
373
+ }
374
+ function resolvePrimaryModelRef(raw) {
375
+ if (!raw || typeof raw !== "string") return null;
376
+ const trimmed = raw.trim();
377
+ if (!trimmed) return null;
378
+ return DEFAULT_MODEL_ALIASES[trimmed.toLowerCase()] ?? trimmed;
379
+ }
380
+ function applyMessageDefaults(cfg) {
381
+ const messages = cfg.messages;
382
+ if (messages?.ackReactionScope !== void 0) return cfg;
383
+ const nextMessages = messages ? { ...messages } : {};
384
+ nextMessages.ackReactionScope = "group-mentions";
385
+ return {
386
+ ...cfg,
387
+ messages: nextMessages
388
+ };
389
+ }
390
+ function applySessionDefaults(cfg, options = {}) {
391
+ const session = cfg.session;
392
+ if (!session || session.mainKey === void 0) return cfg;
393
+ const trimmed = session.mainKey.trim();
394
+ const warn = options.warn ?? console.warn;
395
+ const warnState = options.warnState ?? defaultWarnState;
396
+ const next = {
397
+ ...cfg,
398
+ session: {
399
+ ...session,
400
+ mainKey: "main"
401
+ }
402
+ };
403
+ if (trimmed && trimmed !== "main" && !warnState.warned) {
404
+ warnState.warned = true;
405
+ warn("session.mainKey is ignored; main session is always \"main\".");
406
+ }
407
+ return next;
408
+ }
409
+ function applyTalkApiKey(config) {
410
+ const normalized = normalizeTalkConfig(config);
411
+ const resolved = resolveTalkApiKey();
412
+ if (!resolved) return normalized;
413
+ const talk = normalized.talk;
414
+ const active = resolveActiveTalkProviderConfig(talk);
415
+ if (active.provider && active.provider !== DEFAULT_TALK_PROVIDER) return normalized;
416
+ const existingProviderApiKey = typeof active.config?.apiKey === "string" ? active.config.apiKey.trim() : "";
417
+ const existingLegacyApiKey = typeof talk?.apiKey === "string" ? talk.apiKey.trim() : "";
418
+ if (existingProviderApiKey || existingLegacyApiKey) return normalized;
419
+ const providerId = active.provider ?? DEFAULT_TALK_PROVIDER;
420
+ const providers = { ...talk?.providers };
421
+ providers[providerId] = {
422
+ ...providers[providerId],
423
+ apiKey: resolved
424
+ };
425
+ const nextTalk = {
426
+ ...talk,
427
+ provider: talk?.provider ?? providerId,
428
+ providers,
429
+ apiKey: resolved
430
+ };
431
+ return {
432
+ ...normalized,
433
+ talk: nextTalk
434
+ };
435
+ }
436
+ function applyTalkConfigNormalization(config) {
437
+ return normalizeTalkConfig(config);
438
+ }
439
+ function applyModelDefaults(cfg) {
440
+ const existingAgent = cfg.agents?.defaults;
441
+ if (!existingAgent) return cfg;
442
+ const existingModels = existingAgent.models ?? {};
443
+ if (Object.keys(existingModels).length === 0) return cfg;
444
+ const nextModels = { ...existingModels };
445
+ let mutated = false;
446
+ for (const [alias, target] of Object.entries(DEFAULT_MODEL_ALIASES)) {
447
+ const entry = nextModels[target];
448
+ if (!entry) continue;
449
+ if (entry.alias !== void 0) continue;
450
+ nextModels[target] = {
451
+ ...entry,
452
+ alias
453
+ };
454
+ mutated = true;
455
+ }
456
+ if (!mutated) return cfg;
457
+ return {
458
+ ...cfg,
459
+ agents: {
460
+ ...cfg.agents,
461
+ defaults: {
462
+ ...existingAgent,
463
+ models: nextModels
464
+ }
465
+ }
466
+ };
467
+ }
468
+ function applyAgentDefaults(cfg) {
469
+ const agents = cfg.agents;
470
+ const defaults = agents?.defaults;
471
+ const hasMax = typeof defaults?.maxConcurrent === "number" && Number.isFinite(defaults.maxConcurrent);
472
+ const hasSubMax = typeof defaults?.subagents?.maxConcurrent === "number" && Number.isFinite(defaults.subagents.maxConcurrent);
473
+ if (hasMax && hasSubMax) return cfg;
474
+ let mutated = false;
475
+ const nextDefaults = defaults ? { ...defaults } : {};
476
+ if (!hasMax) {
477
+ nextDefaults.maxConcurrent = DEFAULT_AGENT_MAX_CONCURRENT;
478
+ mutated = true;
479
+ }
480
+ const nextSubagents = defaults?.subagents ? { ...defaults.subagents } : {};
481
+ if (!hasSubMax) {
482
+ nextSubagents.maxConcurrent = DEFAULT_SUBAGENT_MAX_CONCURRENT;
483
+ mutated = true;
484
+ }
485
+ if (!mutated) return cfg;
486
+ return {
487
+ ...cfg,
488
+ agents: {
489
+ ...agents,
490
+ defaults: {
491
+ ...nextDefaults,
492
+ subagents: nextSubagents
493
+ }
494
+ }
495
+ };
496
+ }
497
+ function applyLoggingDefaults(cfg) {
498
+ const logging = cfg.logging;
499
+ if (!logging) return cfg;
500
+ if (logging.redactSensitive) return cfg;
501
+ return {
502
+ ...cfg,
503
+ logging: {
504
+ ...logging,
505
+ redactSensitive: "tools"
506
+ }
507
+ };
508
+ }
509
+ function applyContextPruningDefaults(cfg) {
510
+ const defaults = cfg.agents?.defaults;
511
+ if (!defaults) return cfg;
512
+ const authMode = resolveAnthropicDefaultAuthMode(cfg);
513
+ if (!authMode) return cfg;
514
+ let mutated = false;
515
+ const nextDefaults = { ...defaults };
516
+ const contextPruning = defaults.contextPruning ?? {};
517
+ const heartbeat = defaults.heartbeat ?? {};
518
+ if (defaults.contextPruning?.mode === void 0) {
519
+ nextDefaults.contextPruning = {
520
+ ...contextPruning,
521
+ mode: "cache-ttl",
522
+ ttl: defaults.contextPruning?.ttl ?? "1h"
523
+ };
524
+ mutated = true;
525
+ }
526
+ if (defaults.heartbeat?.every === void 0) {
527
+ nextDefaults.heartbeat = {
528
+ ...heartbeat,
529
+ every: authMode === "oauth" ? "1h" : "30m"
530
+ };
531
+ mutated = true;
532
+ }
533
+ if (authMode === "api_key") {
534
+ const nextModels = defaults.models ? { ...defaults.models } : {};
535
+ let modelsMutated = false;
536
+ const isAnthropicCacheRetentionTarget = (parsed) => Boolean(parsed && (parsed.provider === "anthropic" || parsed.provider === "amazon-bedrock" && parsed.model.toLowerCase().includes("anthropic.claude")));
537
+ for (const [key, entry] of Object.entries(nextModels)) {
538
+ if (!isAnthropicCacheRetentionTarget(parseModelRef(key, "anthropic"))) continue;
539
+ const current = entry ?? {};
540
+ const params = current.params ?? {};
541
+ if (typeof params.cacheRetention === "string") continue;
542
+ nextModels[key] = {
543
+ ...current,
544
+ params: {
545
+ ...params,
546
+ cacheRetention: "short"
547
+ }
548
+ };
549
+ modelsMutated = true;
550
+ }
551
+ const rawModel = defaults.model;
552
+ const rawPrimary = typeof rawModel === "string" ? rawModel : rawModel?.primary;
553
+ const primary = resolvePrimaryModelRef(typeof rawPrimary === "string" ? rawPrimary : void 0);
554
+ if (primary) {
555
+ const parsedPrimary = parseModelRef(primary, "anthropic");
556
+ if (isAnthropicCacheRetentionTarget(parsedPrimary)) {
557
+ const key = `${parsedPrimary.provider}/${parsedPrimary.model}`;
558
+ const current = nextModels[key] ?? {};
559
+ const params = current.params ?? {};
560
+ if (typeof params.cacheRetention !== "string") {
561
+ nextModels[key] = {
562
+ ...current,
563
+ params: {
564
+ ...params,
565
+ cacheRetention: "short"
566
+ }
567
+ };
568
+ modelsMutated = true;
569
+ }
570
+ }
571
+ }
572
+ if (modelsMutated) {
573
+ nextDefaults.models = nextModels;
574
+ mutated = true;
575
+ }
576
+ }
577
+ if (!mutated) return cfg;
578
+ return {
579
+ ...cfg,
580
+ agents: {
581
+ ...cfg.agents,
582
+ defaults: nextDefaults
583
+ }
584
+ };
585
+ }
586
+
587
+ //#endregion
588
+ //#region src/config/env-preserve.ts
589
+ /**
590
+ * Preserves `${VAR}` environment variable references during config write-back.
591
+ *
592
+ * When config is read, `${VAR}` references are resolved to their values.
593
+ * When writing back, callers pass the resolved config. This module detects
594
+ * values that match what a `${VAR}` reference would resolve to and restores
595
+ * the original reference, so env var references survive config round-trips.
596
+ *
597
+ * A value is restored only if:
598
+ * 1. The pre-substitution value contained a `${VAR}` pattern
599
+ * 2. Resolving that pattern with current env vars produces the incoming value
600
+ *
601
+ * If a caller intentionally set a new value (different from what the env var
602
+ * resolves to), the new value is kept as-is.
603
+ */
604
+ const ENV_VAR_PATTERN = /\$\{[A-Z_][A-Z0-9_]*\}/;
605
+ /**
606
+ * Check if a string contains any `${VAR}` env var references.
607
+ */
608
+ function hasEnvVarRef(value) {
609
+ return ENV_VAR_PATTERN.test(value);
610
+ }
611
+ /**
612
+ * Resolve `${VAR}` references in a single string using the given env.
613
+ * Returns null if any referenced var is missing (instead of throwing).
614
+ *
615
+ * Mirrors the substitution semantics of `substituteString` in env-substitution.ts:
616
+ * - `${VAR}` → env value (returns null if missing)
617
+ * - `$${VAR}` → literal `${VAR}` (escape sequence)
618
+ */
619
+ function tryResolveString(template, env) {
620
+ const ENV_VAR_NAME = /^[A-Z_][A-Z0-9_]*$/;
621
+ const chunks = [];
622
+ for (let i = 0; i < template.length; i++) {
623
+ if (template[i] === "$") {
624
+ if (template[i + 1] === "$" && template[i + 2] === "{") {
625
+ const start = i + 3;
626
+ const end = template.indexOf("}", start);
627
+ if (end !== -1) {
628
+ const name = template.slice(start, end);
629
+ if (ENV_VAR_NAME.test(name)) {
630
+ chunks.push(`\${${name}}`);
631
+ i = end;
632
+ continue;
633
+ }
634
+ }
635
+ }
636
+ if (template[i + 1] === "{") {
637
+ const start = i + 2;
638
+ const end = template.indexOf("}", start);
639
+ if (end !== -1) {
640
+ const name = template.slice(start, end);
641
+ if (ENV_VAR_NAME.test(name)) {
642
+ const val = env[name];
643
+ if (val === void 0 || val === "") return null;
644
+ chunks.push(val);
645
+ i = end;
646
+ continue;
647
+ }
648
+ }
649
+ }
650
+ }
651
+ chunks.push(template[i]);
652
+ }
653
+ return chunks.join("");
654
+ }
655
+ /**
656
+ * Deep-walk the incoming config and restore `${VAR}` references from the
657
+ * pre-substitution parsed config wherever the resolved value matches.
658
+ *
659
+ * @param incoming - The resolved config about to be written
660
+ * @param parsed - The pre-substitution parsed config (from the current file on disk)
661
+ * @param env - Environment variables for verification
662
+ * @returns A new config object with env var references restored where appropriate
663
+ */
664
+ function restoreEnvVarRefs(incoming, parsed, env = process.env) {
665
+ if (parsed === null || parsed === void 0) return incoming;
666
+ if (typeof incoming === "string" && typeof parsed === "string") {
667
+ if (hasEnvVarRef(parsed)) {
668
+ if (tryResolveString(parsed, env) === incoming) return parsed;
669
+ }
670
+ return incoming;
671
+ }
672
+ if (Array.isArray(incoming) && Array.isArray(parsed)) return incoming.map((item, i) => i < parsed.length ? restoreEnvVarRefs(item, parsed[i], env) : item);
673
+ if (isPlainObject$2(incoming) && isPlainObject$2(parsed)) {
674
+ const result = {};
675
+ for (const [key, value] of Object.entries(incoming)) if (key in parsed) result[key] = restoreEnvVarRefs(value, parsed[key], env);
676
+ else result[key] = value;
677
+ return result;
678
+ }
679
+ return incoming;
680
+ }
681
+
682
+ //#endregion
683
+ //#region src/config/env-substitution.ts
684
+ /**
685
+ * Environment variable substitution for config values.
686
+ *
687
+ * Supports `${VAR_NAME}` syntax in string values, substituted at config load time.
688
+ * - Only uppercase env vars are matched: `[A-Z_][A-Z0-9_]*`
689
+ * - Escape with `$${}` to output literal `${}`
690
+ * - Missing env vars throw `MissingEnvVarError` with context
691
+ *
692
+ * @example
693
+ * ```json5
694
+ * {
695
+ * models: {
696
+ * providers: {
697
+ * "vercel-gateway": {
698
+ * apiKey: "${VERCEL_GATEWAY_API_KEY}"
699
+ * }
700
+ * }
701
+ * }
702
+ * }
703
+ * ```
704
+ */
705
+ const ENV_VAR_NAME_PATTERN = /^[A-Z_][A-Z0-9_]*$/;
706
+ var MissingEnvVarError = class extends Error {
707
+ constructor(varName, configPath) {
708
+ super(`Missing env var "${varName}" referenced at config path: ${configPath}`);
709
+ this.varName = varName;
710
+ this.configPath = configPath;
711
+ this.name = "MissingEnvVarError";
712
+ }
713
+ };
714
+ function parseEnvTokenAt(value, index) {
715
+ if (value[index] !== "$") return null;
716
+ const next = value[index + 1];
717
+ const afterNext = value[index + 2];
718
+ if (next === "$" && afterNext === "{") {
719
+ const start = index + 3;
720
+ const end = value.indexOf("}", start);
721
+ if (end !== -1) {
722
+ const name = value.slice(start, end);
723
+ if (ENV_VAR_NAME_PATTERN.test(name)) return {
724
+ kind: "escaped",
725
+ name,
726
+ end
727
+ };
728
+ }
729
+ }
730
+ if (next === "{") {
731
+ const start = index + 2;
732
+ const end = value.indexOf("}", start);
733
+ if (end !== -1) {
734
+ const name = value.slice(start, end);
735
+ if (ENV_VAR_NAME_PATTERN.test(name)) return {
736
+ kind: "substitution",
737
+ name,
738
+ end
739
+ };
740
+ }
741
+ }
742
+ return null;
743
+ }
744
+ function substituteString(value, env, configPath) {
745
+ if (!value.includes("$")) return value;
746
+ const chunks = [];
747
+ for (let i = 0; i < value.length; i += 1) {
748
+ const char = value[i];
749
+ if (char !== "$") {
750
+ chunks.push(char);
751
+ continue;
752
+ }
753
+ const token = parseEnvTokenAt(value, i);
754
+ if (token?.kind === "escaped") {
755
+ chunks.push(`\${${token.name}}`);
756
+ i = token.end;
757
+ continue;
758
+ }
759
+ if (token?.kind === "substitution") {
760
+ const envValue = env[token.name];
761
+ if (envValue === void 0 || envValue === "") throw new MissingEnvVarError(token.name, configPath);
762
+ chunks.push(envValue);
763
+ i = token.end;
764
+ continue;
765
+ }
766
+ chunks.push(char);
767
+ }
768
+ return chunks.join("");
769
+ }
770
+ function containsEnvVarReference(value) {
771
+ if (!value.includes("$")) return false;
772
+ for (let i = 0; i < value.length; i += 1) {
773
+ if (value[i] !== "$") continue;
774
+ const token = parseEnvTokenAt(value, i);
775
+ if (token?.kind === "escaped") {
776
+ i = token.end;
777
+ continue;
778
+ }
779
+ if (token?.kind === "substitution") return true;
780
+ }
781
+ return false;
782
+ }
783
+ function substituteAny(value, env, path) {
784
+ if (typeof value === "string") return substituteString(value, env, path);
785
+ if (Array.isArray(value)) return value.map((item, index) => substituteAny(item, env, `${path}[${index}]`));
786
+ if (isPlainObject$2(value)) {
787
+ const result = {};
788
+ for (const [key, val] of Object.entries(value)) result[key] = substituteAny(val, env, path ? `${path}.${key}` : key);
789
+ return result;
790
+ }
791
+ return value;
792
+ }
793
+ /**
794
+ * Resolves `${VAR_NAME}` environment variable references in config values.
795
+ *
796
+ * @param obj - The parsed config object (after JSON5 parse and $include resolution)
797
+ * @param env - Environment variables to use for substitution (defaults to process.env)
798
+ * @returns The config object with env vars substituted
799
+ * @throws {MissingEnvVarError} If a referenced env var is not set or empty
800
+ */
801
+ function resolveConfigEnvVars(obj, env = process.env) {
802
+ return substituteAny(obj, env, "");
803
+ }
804
+
805
+ //#endregion
806
+ //#region src/security/scan-paths.ts
807
+ function isPathInside$1(basePath, candidatePath) {
808
+ const base = path.resolve(basePath);
809
+ const candidate = path.resolve(candidatePath);
810
+ const rel = path.relative(base, candidate);
811
+ return rel === "" || !rel.startsWith(`..${path.sep}`) && rel !== ".." && !path.isAbsolute(rel);
812
+ }
813
+ function safeRealpathSync$1(filePath) {
814
+ try {
815
+ return fs.realpathSync(filePath);
816
+ } catch {
817
+ return null;
818
+ }
819
+ }
820
+ function isPathInsideWithRealpath(basePath, candidatePath, opts) {
821
+ if (!isPathInside$1(basePath, candidatePath)) return false;
822
+ const baseReal = safeRealpathSync$1(basePath);
823
+ const candidateReal = safeRealpathSync$1(candidatePath);
824
+ if (!baseReal || !candidateReal) return opts?.requireRealpath !== true;
825
+ return isPathInside$1(baseReal, candidateReal);
826
+ }
827
+ function extensionUsesSkippedScannerPath(entry) {
828
+ return entry.split(/[\\/]+/).filter(Boolean).some((segment) => segment === "node_modules" || segment.startsWith(".") && segment !== "." && segment !== "..");
829
+ }
830
+
831
+ //#endregion
832
+ //#region src/config/includes.ts
833
+ /**
834
+ * Config includes: $include directive for modular configs
835
+ *
836
+ * @example
837
+ * ```json5
838
+ * {
839
+ * "$include": "./base.json5", // single file
840
+ * "$include": ["./a.json5", "./b.json5"] // merge multiple
841
+ * }
842
+ * ```
843
+ */
844
+ const INCLUDE_KEY = "$include";
845
+ const MAX_INCLUDE_DEPTH = 10;
846
+ var ConfigIncludeError = class extends Error {
847
+ constructor(message, includePath, cause) {
848
+ super(message);
849
+ this.includePath = includePath;
850
+ this.cause = cause;
851
+ this.name = "ConfigIncludeError";
852
+ }
853
+ };
854
+ var CircularIncludeError = class extends ConfigIncludeError {
855
+ constructor(chain) {
856
+ super(`Circular include detected: ${chain.join(" -> ")}`, chain[chain.length - 1]);
857
+ this.chain = chain;
858
+ this.name = "CircularIncludeError";
859
+ }
860
+ };
861
+ /** Deep merge: arrays concatenate, objects merge recursively, primitives: source wins */
862
+ function deepMerge(target, source) {
863
+ if (Array.isArray(target) && Array.isArray(source)) return [...target, ...source];
864
+ if (isPlainObject$2(target) && isPlainObject$2(source)) {
865
+ const result = { ...target };
866
+ for (const key of Object.keys(source)) {
867
+ if (isBlockedObjectKey(key)) continue;
868
+ result[key] = key in result ? deepMerge(result[key], source[key]) : source[key];
869
+ }
870
+ return result;
871
+ }
872
+ return source;
873
+ }
874
+ var IncludeProcessor = class IncludeProcessor {
875
+ constructor(basePath, resolver, rootDir) {
876
+ this.basePath = basePath;
877
+ this.resolver = resolver;
878
+ this.visited = /* @__PURE__ */ new Set();
879
+ this.depth = 0;
880
+ this.visited.add(path.normalize(basePath));
881
+ this.rootDir = path.normalize(rootDir ?? path.dirname(basePath));
882
+ this.rootRealDir = path.normalize(safeRealpath(this.rootDir));
883
+ }
884
+ process(obj) {
885
+ if (Array.isArray(obj)) return obj.map((item) => this.process(item));
886
+ if (!isPlainObject$2(obj)) return obj;
887
+ if (!(INCLUDE_KEY in obj)) return this.processObject(obj);
888
+ return this.processInclude(obj);
889
+ }
890
+ processObject(obj) {
891
+ const result = {};
892
+ for (const [key, value] of Object.entries(obj)) result[key] = this.process(value);
893
+ return result;
894
+ }
895
+ processInclude(obj) {
896
+ const includeValue = obj[INCLUDE_KEY];
897
+ const otherKeys = Object.keys(obj).filter((k) => k !== INCLUDE_KEY);
898
+ const included = this.resolveInclude(includeValue);
899
+ if (otherKeys.length === 0) return included;
900
+ if (!isPlainObject$2(included)) throw new ConfigIncludeError("Sibling keys require included content to be an object", typeof includeValue === "string" ? includeValue : INCLUDE_KEY);
901
+ const rest = {};
902
+ for (const key of otherKeys) rest[key] = this.process(obj[key]);
903
+ return deepMerge(included, rest);
904
+ }
905
+ resolveInclude(value) {
906
+ if (typeof value === "string") return this.loadFile(value);
907
+ if (Array.isArray(value)) return value.reduce((merged, item) => {
908
+ if (typeof item !== "string") throw new ConfigIncludeError(`Invalid $include array item: expected string, got ${typeof item}`, String(item));
909
+ return deepMerge(merged, this.loadFile(item));
910
+ }, {});
911
+ throw new ConfigIncludeError(`Invalid $include value: expected string or array of strings, got ${typeof value}`, String(value));
912
+ }
913
+ loadFile(includePath) {
914
+ const resolvedPath = this.resolvePath(includePath);
915
+ this.checkCircular(resolvedPath);
916
+ this.checkDepth(includePath);
917
+ const raw = this.readFile(includePath, resolvedPath);
918
+ const parsed = this.parseFile(includePath, resolvedPath, raw);
919
+ return this.processNested(resolvedPath, parsed);
920
+ }
921
+ resolvePath(includePath) {
922
+ const configDir = path.dirname(this.basePath);
923
+ const resolved = path.isAbsolute(includePath) ? includePath : path.resolve(configDir, includePath);
924
+ const normalized = path.normalize(resolved);
925
+ if (!isPathInside$1(this.rootDir, normalized)) throw new ConfigIncludeError(`Include path escapes config directory: ${includePath} (root: ${this.rootDir})`, includePath);
926
+ try {
927
+ const real = fs.realpathSync(normalized);
928
+ if (!isPathInside$1(this.rootRealDir, real)) throw new ConfigIncludeError(`Include path resolves outside config directory (symlink): ${includePath} (root: ${this.rootDir})`, includePath);
929
+ } catch (err) {
930
+ if (err instanceof ConfigIncludeError) throw err;
931
+ }
932
+ return normalized;
933
+ }
934
+ checkCircular(resolvedPath) {
935
+ if (this.visited.has(resolvedPath)) throw new CircularIncludeError([...this.visited, resolvedPath]);
936
+ }
937
+ checkDepth(includePath) {
938
+ if (this.depth >= MAX_INCLUDE_DEPTH) throw new ConfigIncludeError(`Maximum include depth (${MAX_INCLUDE_DEPTH}) exceeded at: ${includePath}`, includePath);
939
+ }
940
+ readFile(includePath, resolvedPath) {
941
+ try {
942
+ return this.resolver.readFile(resolvedPath);
943
+ } catch (err) {
944
+ throw new ConfigIncludeError(`Failed to read include file: ${includePath} (resolved: ${resolvedPath})`, includePath, err instanceof Error ? err : void 0);
945
+ }
946
+ }
947
+ parseFile(includePath, resolvedPath, raw) {
948
+ try {
949
+ return this.resolver.parseJson(raw);
950
+ } catch (err) {
951
+ throw new ConfigIncludeError(`Failed to parse include file: ${includePath} (resolved: ${resolvedPath})`, includePath, err instanceof Error ? err : void 0);
952
+ }
953
+ }
954
+ processNested(resolvedPath, parsed) {
955
+ const nested = new IncludeProcessor(resolvedPath, this.resolver, this.rootDir);
956
+ nested.visited = new Set([...this.visited, resolvedPath]);
957
+ nested.depth = this.depth + 1;
958
+ return nested.process(parsed);
959
+ }
960
+ };
961
+ function safeRealpath(target) {
962
+ try {
963
+ return fs.realpathSync(target);
964
+ } catch {
965
+ return target;
966
+ }
967
+ }
968
+ const defaultResolver = {
969
+ readFile: (p) => fs.readFileSync(p, "utf-8"),
970
+ parseJson: (raw) => JSON5.parse(raw)
971
+ };
972
+ /**
973
+ * Resolves all $include directives in a parsed config object.
974
+ */
975
+ function resolveConfigIncludes(obj, configPath, resolver = defaultResolver) {
976
+ return new IncludeProcessor(configPath, resolver).process(obj);
977
+ }
978
+
979
+ //#endregion
980
+ //#region src/config/legacy.shared.ts
981
+ const getRecord = (value) => isRecord(value) ? value : null;
982
+ const ensureRecord = (root, key) => {
983
+ const existing = root[key];
984
+ if (isRecord(existing)) return existing;
985
+ const next = {};
986
+ root[key] = next;
987
+ return next;
988
+ };
989
+ const mergeMissing = (target, source) => {
990
+ for (const [key, value] of Object.entries(source)) {
991
+ if (value === void 0 || isBlockedObjectKey(key)) continue;
992
+ const existing = target[key];
993
+ if (existing === void 0) {
994
+ target[key] = value;
995
+ continue;
996
+ }
997
+ if (isRecord(existing) && isRecord(value)) mergeMissing(existing, value);
998
+ }
999
+ };
1000
+ const mapLegacyAudioTranscription = (value) => {
1001
+ const transcriber = getRecord(value);
1002
+ const command = Array.isArray(transcriber?.command) ? transcriber?.command : null;
1003
+ if (!command || command.length === 0) return null;
1004
+ if (typeof command[0] !== "string") return null;
1005
+ if (!command.every((part) => typeof part === "string")) return null;
1006
+ const rawExecutable = command[0].trim();
1007
+ if (!rawExecutable) return null;
1008
+ if (!isSafeExecutableValue(rawExecutable)) return null;
1009
+ const args = command.slice(1);
1010
+ const timeoutSeconds = typeof transcriber?.timeoutSeconds === "number" ? transcriber?.timeoutSeconds : void 0;
1011
+ const result = {
1012
+ command: rawExecutable,
1013
+ type: "cli"
1014
+ };
1015
+ if (args.length > 0) result.args = args;
1016
+ if (timeoutSeconds !== void 0) result.timeoutSeconds = timeoutSeconds;
1017
+ return result;
1018
+ };
1019
+ const getAgentsList = (agents) => {
1020
+ const list = agents?.list;
1021
+ return Array.isArray(list) ? list : [];
1022
+ };
1023
+ const resolveDefaultAgentIdFromRaw = (raw) => {
1024
+ const list = getAgentsList(getRecord(raw.agents));
1025
+ const defaultEntry = list.find((entry) => isRecord(entry) && entry.default === true && typeof entry.id === "string" && entry.id.trim() !== "");
1026
+ if (defaultEntry) return defaultEntry.id.trim();
1027
+ const routing = getRecord(raw.routing);
1028
+ const routingDefault = typeof routing?.defaultAgentId === "string" ? routing.defaultAgentId.trim() : "";
1029
+ if (routingDefault) return routingDefault;
1030
+ const firstEntry = list.find((entry) => isRecord(entry) && typeof entry.id === "string" && entry.id.trim() !== "");
1031
+ if (firstEntry) return firstEntry.id.trim();
1032
+ return "main";
1033
+ };
1034
+ const ensureAgentEntry = (list, id) => {
1035
+ const normalized = id.trim();
1036
+ const existing = list.find((entry) => isRecord(entry) && typeof entry.id === "string" && entry.id.trim() === normalized);
1037
+ if (existing) return existing;
1038
+ const created = { id: normalized };
1039
+ list.push(created);
1040
+ return created;
1041
+ };
1042
+
1043
+ //#endregion
1044
+ //#region src/config/legacy.migrations.part-1.ts
1045
+ function migrateBindings(raw, changes, changeNote, mutator) {
1046
+ const bindings = Array.isArray(raw.bindings) ? raw.bindings : null;
1047
+ if (!bindings) return;
1048
+ let touched = false;
1049
+ for (const entry of bindings) {
1050
+ if (!isRecord(entry)) continue;
1051
+ const match = getRecord(entry.match);
1052
+ if (!match) continue;
1053
+ if (!mutator(match)) continue;
1054
+ entry.match = match;
1055
+ touched = true;
1056
+ }
1057
+ if (touched) {
1058
+ raw.bindings = bindings;
1059
+ changes.push(changeNote);
1060
+ }
1061
+ }
1062
+ function ensureDefaultGroupEntry(section) {
1063
+ const groups = isRecord(section.groups) ? section.groups : {};
1064
+ const defaultKey = "*";
1065
+ return {
1066
+ groups,
1067
+ entry: isRecord(groups[defaultKey]) ? groups[defaultKey] : {}
1068
+ };
1069
+ }
1070
+ const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
1071
+ {
1072
+ id: "bindings.match.provider->bindings.match.channel",
1073
+ describe: "Move bindings[].match.provider to bindings[].match.channel",
1074
+ apply: (raw, changes) => {
1075
+ migrateBindings(raw, changes, "Moved bindings[].match.provider → bindings[].match.channel.", (match) => {
1076
+ if (typeof match.channel === "string" && match.channel.trim()) return false;
1077
+ const provider = typeof match.provider === "string" ? match.provider.trim() : "";
1078
+ if (!provider) return false;
1079
+ match.channel = provider;
1080
+ delete match.provider;
1081
+ return true;
1082
+ });
1083
+ }
1084
+ },
1085
+ {
1086
+ id: "bindings.match.accountID->bindings.match.accountId",
1087
+ describe: "Move bindings[].match.accountID to bindings[].match.accountId",
1088
+ apply: (raw, changes) => {
1089
+ migrateBindings(raw, changes, "Moved bindings[].match.accountID → bindings[].match.accountId.", (match) => {
1090
+ if (match.accountId !== void 0) return false;
1091
+ const accountID = typeof match.accountID === "string" ? match.accountID.trim() : match.accountID;
1092
+ if (!accountID) return false;
1093
+ match.accountId = accountID;
1094
+ delete match.accountID;
1095
+ return true;
1096
+ });
1097
+ }
1098
+ },
1099
+ {
1100
+ id: "session.sendPolicy.rules.match.provider->match.channel",
1101
+ describe: "Move session.sendPolicy.rules[].match.provider to match.channel",
1102
+ apply: (raw, changes) => {
1103
+ const session = getRecord(raw.session);
1104
+ if (!session) return;
1105
+ const sendPolicy = getRecord(session.sendPolicy);
1106
+ if (!sendPolicy) return;
1107
+ const rules = Array.isArray(sendPolicy.rules) ? sendPolicy.rules : null;
1108
+ if (!rules) return;
1109
+ let touched = false;
1110
+ for (const rule of rules) {
1111
+ if (!isRecord(rule)) continue;
1112
+ const match = getRecord(rule.match);
1113
+ if (!match) continue;
1114
+ if (typeof match.channel === "string" && match.channel.trim()) continue;
1115
+ const provider = typeof match.provider === "string" ? match.provider.trim() : "";
1116
+ if (!provider) continue;
1117
+ match.channel = provider;
1118
+ delete match.provider;
1119
+ rule.match = match;
1120
+ touched = true;
1121
+ }
1122
+ if (touched) {
1123
+ sendPolicy.rules = rules;
1124
+ session.sendPolicy = sendPolicy;
1125
+ raw.session = session;
1126
+ changes.push("Moved session.sendPolicy.rules[].match.provider → match.channel.");
1127
+ }
1128
+ }
1129
+ },
1130
+ {
1131
+ id: "messages.queue.byProvider->byChannel",
1132
+ describe: "Move messages.queue.byProvider to messages.queue.byChannel",
1133
+ apply: (raw, changes) => {
1134
+ const messages = getRecord(raw.messages);
1135
+ if (!messages) return;
1136
+ const queue = getRecord(messages.queue);
1137
+ if (!queue) return;
1138
+ if (queue.byProvider === void 0) return;
1139
+ if (queue.byChannel === void 0) {
1140
+ queue.byChannel = queue.byProvider;
1141
+ changes.push("Moved messages.queue.byProvider → messages.queue.byChannel.");
1142
+ } else changes.push("Removed messages.queue.byProvider (messages.queue.byChannel already set).");
1143
+ delete queue.byProvider;
1144
+ messages.queue = queue;
1145
+ raw.messages = messages;
1146
+ }
1147
+ },
1148
+ {
1149
+ id: "providers->channels",
1150
+ describe: "Move provider config sections to channels.*",
1151
+ apply: (raw, changes) => {
1152
+ const legacyEntries = [
1153
+ "whatsapp",
1154
+ "telegram",
1155
+ "discord",
1156
+ "slack",
1157
+ "signal",
1158
+ "imessage",
1159
+ "msteams"
1160
+ ].filter((key) => isRecord(raw[key]));
1161
+ if (legacyEntries.length === 0) return;
1162
+ const channels = ensureRecord(raw, "channels");
1163
+ for (const key of legacyEntries) {
1164
+ const legacy = getRecord(raw[key]);
1165
+ if (!legacy) continue;
1166
+ const channelEntry = ensureRecord(channels, key);
1167
+ const hadEntries = Object.keys(channelEntry).length > 0;
1168
+ mergeMissing(channelEntry, legacy);
1169
+ channels[key] = channelEntry;
1170
+ delete raw[key];
1171
+ changes.push(hadEntries ? `Merged ${key} → channels.${key}.` : `Moved ${key} → channels.${key}.`);
1172
+ }
1173
+ raw.channels = channels;
1174
+ }
1175
+ },
1176
+ {
1177
+ id: "channels.streaming-keys->channels.streaming",
1178
+ describe: "Normalize legacy streaming keys to channels.<provider>.streaming (Telegram/Discord/Slack)",
1179
+ apply: (raw, changes) => {
1180
+ const channels = getRecord(raw.channels);
1181
+ if (!channels) return;
1182
+ const migrateProviderEntry = (params) => {
1183
+ const migrateCommonStreamingMode = (resolveMode) => {
1184
+ const hasLegacyStreamMode = params.entry.streamMode !== void 0;
1185
+ const legacyStreaming = params.entry.streaming;
1186
+ if (!hasLegacyStreamMode && typeof legacyStreaming !== "boolean") return false;
1187
+ const resolved = resolveMode(params.entry);
1188
+ params.entry.streaming = resolved;
1189
+ if (hasLegacyStreamMode) {
1190
+ delete params.entry.streamMode;
1191
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolved}).`);
1192
+ }
1193
+ if (typeof legacyStreaming === "boolean") changes.push(`Normalized ${params.pathPrefix}.streaming boolean → enum (${resolved}).`);
1194
+ return true;
1195
+ };
1196
+ const hasLegacyStreamMode = params.entry.streamMode !== void 0;
1197
+ const legacyStreaming = params.entry.streaming;
1198
+ const legacyNativeStreaming = params.entry.nativeStreaming;
1199
+ if (params.provider === "telegram") {
1200
+ migrateCommonStreamingMode(resolveTelegramPreviewStreamMode);
1201
+ return;
1202
+ }
1203
+ if (params.provider === "discord") {
1204
+ migrateCommonStreamingMode(resolveDiscordPreviewStreamMode);
1205
+ return;
1206
+ }
1207
+ if (!hasLegacyStreamMode && typeof legacyStreaming !== "boolean") return;
1208
+ const resolvedStreaming = resolveSlackStreamingMode(params.entry);
1209
+ const resolvedNativeStreaming = resolveSlackNativeStreaming(params.entry);
1210
+ params.entry.streaming = resolvedStreaming;
1211
+ params.entry.nativeStreaming = resolvedNativeStreaming;
1212
+ if (hasLegacyStreamMode) {
1213
+ delete params.entry.streamMode;
1214
+ changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolvedStreaming}).`);
1215
+ }
1216
+ if (typeof legacyStreaming === "boolean") changes.push(`Moved ${params.pathPrefix}.streaming (boolean) → ${params.pathPrefix}.nativeStreaming (${resolvedNativeStreaming}).`);
1217
+ else if (typeof legacyNativeStreaming !== "boolean" && hasLegacyStreamMode) changes.push(`Set ${params.pathPrefix}.nativeStreaming → ${resolvedNativeStreaming}.`);
1218
+ };
1219
+ const migrateProvider = (provider) => {
1220
+ const providerEntry = getRecord(channels[provider]);
1221
+ if (!providerEntry) return;
1222
+ migrateProviderEntry({
1223
+ provider,
1224
+ entry: providerEntry,
1225
+ pathPrefix: `channels.${provider}`
1226
+ });
1227
+ const accounts = getRecord(providerEntry.accounts);
1228
+ if (!accounts) return;
1229
+ for (const [accountId, accountValue] of Object.entries(accounts)) {
1230
+ const account = getRecord(accountValue);
1231
+ if (!account) continue;
1232
+ migrateProviderEntry({
1233
+ provider,
1234
+ entry: account,
1235
+ pathPrefix: `channels.${provider}.accounts.${accountId}`
1236
+ });
1237
+ }
1238
+ };
1239
+ migrateProvider("telegram");
1240
+ migrateProvider("discord");
1241
+ migrateProvider("slack");
1242
+ }
1243
+ },
1244
+ {
1245
+ id: "routing.allowFrom->channels.whatsapp.allowFrom",
1246
+ describe: "Move routing.allowFrom to channels.whatsapp.allowFrom",
1247
+ apply: (raw, changes) => {
1248
+ const routing = raw.routing;
1249
+ if (!routing || typeof routing !== "object") return;
1250
+ const allowFrom = routing.allowFrom;
1251
+ if (allowFrom === void 0) return;
1252
+ const channels = getRecord(raw.channels);
1253
+ const whatsapp = channels ? getRecord(channels.whatsapp) : null;
1254
+ if (!whatsapp) {
1255
+ delete routing.allowFrom;
1256
+ if (Object.keys(routing).length === 0) delete raw.routing;
1257
+ changes.push("Removed routing.allowFrom (channels.whatsapp not configured).");
1258
+ return;
1259
+ }
1260
+ if (whatsapp.allowFrom === void 0) {
1261
+ whatsapp.allowFrom = allowFrom;
1262
+ changes.push("Moved routing.allowFrom → channels.whatsapp.allowFrom.");
1263
+ } else changes.push("Removed routing.allowFrom (channels.whatsapp.allowFrom already set).");
1264
+ delete routing.allowFrom;
1265
+ if (Object.keys(routing).length === 0) delete raw.routing;
1266
+ channels.whatsapp = whatsapp;
1267
+ raw.channels = channels;
1268
+ }
1269
+ },
1270
+ {
1271
+ id: "routing.groupChat.requireMention->groups.*.requireMention",
1272
+ describe: "Move routing.groupChat.requireMention to channels.whatsapp/telegram/imessage groups",
1273
+ apply: (raw, changes) => {
1274
+ const routing = raw.routing;
1275
+ if (!routing || typeof routing !== "object") return;
1276
+ const groupChat = routing.groupChat && typeof routing.groupChat === "object" ? routing.groupChat : null;
1277
+ if (!groupChat) return;
1278
+ const requireMention = groupChat.requireMention;
1279
+ if (requireMention === void 0) return;
1280
+ const channels = ensureRecord(raw, "channels");
1281
+ const applyTo = (key, options) => {
1282
+ if (options?.requireExisting && !isRecord(channels[key])) return;
1283
+ const section = channels[key] && typeof channels[key] === "object" ? channels[key] : {};
1284
+ const { groups, entry } = ensureDefaultGroupEntry(section);
1285
+ const defaultKey = "*";
1286
+ if (entry.requireMention === void 0) {
1287
+ entry.requireMention = requireMention;
1288
+ groups[defaultKey] = entry;
1289
+ section.groups = groups;
1290
+ channels[key] = section;
1291
+ changes.push(`Moved routing.groupChat.requireMention → channels.${key}.groups."*".requireMention.`);
1292
+ } else changes.push(`Removed routing.groupChat.requireMention (channels.${key}.groups."*" already set).`);
1293
+ };
1294
+ applyTo("whatsapp", { requireExisting: true });
1295
+ applyTo("telegram");
1296
+ applyTo("imessage");
1297
+ delete groupChat.requireMention;
1298
+ if (Object.keys(groupChat).length === 0) delete routing.groupChat;
1299
+ if (Object.keys(routing).length === 0) delete raw.routing;
1300
+ raw.channels = channels;
1301
+ }
1302
+ },
1303
+ {
1304
+ id: "gateway.token->gateway.auth.token",
1305
+ describe: "Move gateway.token to gateway.auth.token",
1306
+ apply: (raw, changes) => {
1307
+ const gateway = raw.gateway;
1308
+ if (!gateway || typeof gateway !== "object") return;
1309
+ const token = gateway.token;
1310
+ if (token === void 0) return;
1311
+ const gatewayObj = gateway;
1312
+ const auth = gatewayObj.auth && typeof gatewayObj.auth === "object" ? gatewayObj.auth : {};
1313
+ if (auth.token === void 0) {
1314
+ auth.token = token;
1315
+ if (!auth.mode) auth.mode = "token";
1316
+ changes.push("Moved gateway.token → gateway.auth.token.");
1317
+ } else changes.push("Removed gateway.token (gateway.auth.token already set).");
1318
+ delete gatewayObj.token;
1319
+ if (Object.keys(auth).length > 0) gatewayObj.auth = auth;
1320
+ raw.gateway = gatewayObj;
1321
+ }
1322
+ },
1323
+ {
1324
+ id: "telegram.requireMention->channels.telegram.groups.*.requireMention",
1325
+ describe: "Move telegram.requireMention to channels.telegram.groups.*.requireMention",
1326
+ apply: (raw, changes) => {
1327
+ const channels = ensureRecord(raw, "channels");
1328
+ const telegram = channels.telegram;
1329
+ if (!telegram || typeof telegram !== "object") return;
1330
+ const requireMention = telegram.requireMention;
1331
+ if (requireMention === void 0) return;
1332
+ const { groups, entry } = ensureDefaultGroupEntry(telegram);
1333
+ const defaultKey = "*";
1334
+ if (entry.requireMention === void 0) {
1335
+ entry.requireMention = requireMention;
1336
+ groups[defaultKey] = entry;
1337
+ telegram.groups = groups;
1338
+ changes.push("Moved telegram.requireMention → channels.telegram.groups.\"*\".requireMention.");
1339
+ } else changes.push("Removed telegram.requireMention (channels.telegram.groups.\"*\" already set).");
1340
+ delete telegram.requireMention;
1341
+ channels.telegram = telegram;
1342
+ raw.channels = channels;
1343
+ }
1344
+ }
1345
+ ];
1346
+
1347
+ //#endregion
1348
+ //#region src/config/legacy.migrations.part-2.ts
1349
+ function applyLegacyAudioTranscriptionModel(params) {
1350
+ const mapped = mapLegacyAudioTranscription(params.source);
1351
+ if (!mapped) {
1352
+ params.changes.push(params.invalidMessage);
1353
+ return;
1354
+ }
1355
+ const mediaAudio = ensureRecord(ensureRecord(ensureRecord(params.raw, "tools"), "media"), "audio");
1356
+ if ((Array.isArray(mediaAudio.models) ? mediaAudio.models : []).length === 0) {
1357
+ mediaAudio.enabled = true;
1358
+ mediaAudio.models = [mapped];
1359
+ params.changes.push(params.movedMessage);
1360
+ return;
1361
+ }
1362
+ params.changes.push(params.alreadySetMessage);
1363
+ }
1364
+ const LEGACY_CONFIG_MIGRATIONS_PART_2 = [
1365
+ {
1366
+ id: "agent.model-config-v2",
1367
+ describe: "Migrate legacy agent.model/allowedModels/modelAliases/modelFallbacks/imageModelFallbacks to agent.models + model lists",
1368
+ apply: (raw, changes) => {
1369
+ const agentRoot = getRecord(raw.agent);
1370
+ const defaults = getRecord(getRecord(raw.agents)?.defaults);
1371
+ const agent = agentRoot ?? defaults;
1372
+ if (!agent) return;
1373
+ const label = agentRoot ? "agent" : "agents.defaults";
1374
+ const legacyModel = typeof agent.model === "string" ? String(agent.model) : void 0;
1375
+ const legacyImageModel = typeof agent.imageModel === "string" ? String(agent.imageModel) : void 0;
1376
+ const legacyAllowed = Array.isArray(agent.allowedModels) ? agent.allowedModels.map(String) : [];
1377
+ const legacyModelFallbacks = Array.isArray(agent.modelFallbacks) ? agent.modelFallbacks.map(String) : [];
1378
+ const legacyImageModelFallbacks = Array.isArray(agent.imageModelFallbacks) ? agent.imageModelFallbacks.map(String) : [];
1379
+ const legacyAliases = agent.modelAliases && typeof agent.modelAliases === "object" ? agent.modelAliases : {};
1380
+ if (!(legacyModel || legacyImageModel || legacyAllowed.length > 0 || legacyModelFallbacks.length > 0 || legacyImageModelFallbacks.length > 0 || Object.keys(legacyAliases).length > 0)) return;
1381
+ const models = agent.models && typeof agent.models === "object" ? agent.models : {};
1382
+ const ensureModel = (rawKey) => {
1383
+ if (typeof rawKey !== "string") return;
1384
+ const key = rawKey.trim();
1385
+ if (!key) return;
1386
+ if (!models[key]) models[key] = {};
1387
+ };
1388
+ ensureModel(legacyModel);
1389
+ ensureModel(legacyImageModel);
1390
+ for (const key of legacyAllowed) ensureModel(key);
1391
+ for (const key of legacyModelFallbacks) ensureModel(key);
1392
+ for (const key of legacyImageModelFallbacks) ensureModel(key);
1393
+ for (const target of Object.values(legacyAliases)) {
1394
+ if (typeof target !== "string") continue;
1395
+ ensureModel(target);
1396
+ }
1397
+ for (const [alias, targetRaw] of Object.entries(legacyAliases)) {
1398
+ if (typeof targetRaw !== "string") continue;
1399
+ const target = targetRaw.trim();
1400
+ if (!target) continue;
1401
+ const entry = models[target] && typeof models[target] === "object" ? models[target] : {};
1402
+ if (!("alias" in entry)) {
1403
+ entry.alias = alias;
1404
+ models[target] = entry;
1405
+ }
1406
+ }
1407
+ const currentModel = agent.model && typeof agent.model === "object" ? agent.model : null;
1408
+ if (currentModel) {
1409
+ if (!currentModel.primary && legacyModel) currentModel.primary = legacyModel;
1410
+ if (legacyModelFallbacks.length > 0 && (!Array.isArray(currentModel.fallbacks) || currentModel.fallbacks.length === 0)) currentModel.fallbacks = legacyModelFallbacks;
1411
+ agent.model = currentModel;
1412
+ } else if (legacyModel || legacyModelFallbacks.length > 0) agent.model = {
1413
+ primary: legacyModel,
1414
+ fallbacks: legacyModelFallbacks.length ? legacyModelFallbacks : []
1415
+ };
1416
+ const currentImageModel = agent.imageModel && typeof agent.imageModel === "object" ? agent.imageModel : null;
1417
+ if (currentImageModel) {
1418
+ if (!currentImageModel.primary && legacyImageModel) currentImageModel.primary = legacyImageModel;
1419
+ if (legacyImageModelFallbacks.length > 0 && (!Array.isArray(currentImageModel.fallbacks) || currentImageModel.fallbacks.length === 0)) currentImageModel.fallbacks = legacyImageModelFallbacks;
1420
+ agent.imageModel = currentImageModel;
1421
+ } else if (legacyImageModel || legacyImageModelFallbacks.length > 0) agent.imageModel = {
1422
+ primary: legacyImageModel,
1423
+ fallbacks: legacyImageModelFallbacks.length ? legacyImageModelFallbacks : []
1424
+ };
1425
+ agent.models = models;
1426
+ if (legacyModel !== void 0) changes.push(`Migrated ${label}.model string → ${label}.model.primary.`);
1427
+ if (legacyModelFallbacks.length > 0) changes.push(`Migrated ${label}.modelFallbacks → ${label}.model.fallbacks.`);
1428
+ if (legacyImageModel !== void 0) changes.push(`Migrated ${label}.imageModel string → ${label}.imageModel.primary.`);
1429
+ if (legacyImageModelFallbacks.length > 0) changes.push(`Migrated ${label}.imageModelFallbacks → ${label}.imageModel.fallbacks.`);
1430
+ if (legacyAllowed.length > 0) changes.push(`Migrated ${label}.allowedModels → ${label}.models.`);
1431
+ if (Object.keys(legacyAliases).length > 0) changes.push(`Migrated ${label}.modelAliases → ${label}.models.*.alias.`);
1432
+ delete agent.allowedModels;
1433
+ delete agent.modelAliases;
1434
+ delete agent.modelFallbacks;
1435
+ delete agent.imageModelFallbacks;
1436
+ }
1437
+ },
1438
+ {
1439
+ id: "routing.agents-v2",
1440
+ describe: "Move routing.agents/defaultAgentId to agents.list",
1441
+ apply: (raw, changes) => {
1442
+ const routing = getRecord(raw.routing);
1443
+ if (!routing) return;
1444
+ const routingAgents = getRecord(routing.agents);
1445
+ const agents = ensureRecord(raw, "agents");
1446
+ const list = getAgentsList(agents);
1447
+ if (routingAgents) {
1448
+ for (const [rawId, entryRaw] of Object.entries(routingAgents)) {
1449
+ const agentId = String(rawId ?? "").trim();
1450
+ const entry = getRecord(entryRaw);
1451
+ if (!agentId || !entry) continue;
1452
+ const target = ensureAgentEntry(list, agentId);
1453
+ const entryCopy = { ...entry };
1454
+ if ("mentionPatterns" in entryCopy) {
1455
+ const mentionPatterns = entryCopy.mentionPatterns;
1456
+ const groupChat = ensureRecord(target, "groupChat");
1457
+ if (groupChat.mentionPatterns === void 0) {
1458
+ groupChat.mentionPatterns = mentionPatterns;
1459
+ changes.push(`Moved routing.agents.${agentId}.mentionPatterns → agents.list (id "${agentId}").groupChat.mentionPatterns.`);
1460
+ } else changes.push(`Removed routing.agents.${agentId}.mentionPatterns (agents.list groupChat mentionPatterns already set).`);
1461
+ delete entryCopy.mentionPatterns;
1462
+ }
1463
+ const legacyGroupChat = getRecord(entryCopy.groupChat);
1464
+ if (legacyGroupChat) {
1465
+ mergeMissing(ensureRecord(target, "groupChat"), legacyGroupChat);
1466
+ delete entryCopy.groupChat;
1467
+ }
1468
+ const legacySandbox = getRecord(entryCopy.sandbox);
1469
+ if (legacySandbox) {
1470
+ const sandboxTools = getRecord(legacySandbox.tools);
1471
+ if (sandboxTools) {
1472
+ mergeMissing(ensureRecord(ensureRecord(ensureRecord(target, "tools"), "sandbox"), "tools"), sandboxTools);
1473
+ delete legacySandbox.tools;
1474
+ changes.push(`Moved routing.agents.${agentId}.sandbox.tools → agents.list (id "${agentId}").tools.sandbox.tools.`);
1475
+ }
1476
+ entryCopy.sandbox = legacySandbox;
1477
+ }
1478
+ mergeMissing(target, entryCopy);
1479
+ }
1480
+ delete routing.agents;
1481
+ changes.push("Moved routing.agents → agents.list.");
1482
+ }
1483
+ const defaultAgentId = typeof routing.defaultAgentId === "string" ? routing.defaultAgentId.trim() : "";
1484
+ if (defaultAgentId) {
1485
+ if (!list.some((entry) => isRecord(entry) && entry.default === true)) {
1486
+ const entry = ensureAgentEntry(list, defaultAgentId);
1487
+ entry.default = true;
1488
+ changes.push(`Moved routing.defaultAgentId → agents.list (id "${defaultAgentId}").default.`);
1489
+ } else changes.push("Removed routing.defaultAgentId (agents.list default already set).");
1490
+ delete routing.defaultAgentId;
1491
+ }
1492
+ if (list.length > 0) agents.list = list;
1493
+ if (Object.keys(routing).length === 0) delete raw.routing;
1494
+ }
1495
+ },
1496
+ {
1497
+ id: "routing.config-v2",
1498
+ describe: "Move routing bindings/groupChat/queue/agentToAgent/transcribeAudio",
1499
+ apply: (raw, changes) => {
1500
+ const routing = getRecord(raw.routing);
1501
+ if (!routing) return;
1502
+ if (routing.bindings !== void 0) {
1503
+ if (raw.bindings === void 0) {
1504
+ raw.bindings = routing.bindings;
1505
+ changes.push("Moved routing.bindings → bindings.");
1506
+ } else changes.push("Removed routing.bindings (bindings already set).");
1507
+ delete routing.bindings;
1508
+ }
1509
+ if (routing.agentToAgent !== void 0) {
1510
+ const tools = ensureRecord(raw, "tools");
1511
+ if (tools.agentToAgent === void 0) {
1512
+ tools.agentToAgent = routing.agentToAgent;
1513
+ changes.push("Moved routing.agentToAgent → tools.agentToAgent.");
1514
+ } else changes.push("Removed routing.agentToAgent (tools.agentToAgent already set).");
1515
+ delete routing.agentToAgent;
1516
+ }
1517
+ if (routing.queue !== void 0) {
1518
+ const messages = ensureRecord(raw, "messages");
1519
+ if (messages.queue === void 0) {
1520
+ messages.queue = routing.queue;
1521
+ changes.push("Moved routing.queue → messages.queue.");
1522
+ } else changes.push("Removed routing.queue (messages.queue already set).");
1523
+ delete routing.queue;
1524
+ }
1525
+ const groupChat = getRecord(routing.groupChat);
1526
+ if (groupChat) {
1527
+ const historyLimit = groupChat.historyLimit;
1528
+ if (historyLimit !== void 0) {
1529
+ const messagesGroup = ensureRecord(ensureRecord(raw, "messages"), "groupChat");
1530
+ if (messagesGroup.historyLimit === void 0) {
1531
+ messagesGroup.historyLimit = historyLimit;
1532
+ changes.push("Moved routing.groupChat.historyLimit → messages.groupChat.historyLimit.");
1533
+ } else changes.push("Removed routing.groupChat.historyLimit (messages.groupChat.historyLimit already set).");
1534
+ delete groupChat.historyLimit;
1535
+ }
1536
+ const mentionPatterns = groupChat.mentionPatterns;
1537
+ if (mentionPatterns !== void 0) {
1538
+ const messagesGroup = ensureRecord(ensureRecord(raw, "messages"), "groupChat");
1539
+ if (messagesGroup.mentionPatterns === void 0) {
1540
+ messagesGroup.mentionPatterns = mentionPatterns;
1541
+ changes.push("Moved routing.groupChat.mentionPatterns → messages.groupChat.mentionPatterns.");
1542
+ } else changes.push("Removed routing.groupChat.mentionPatterns (messages.groupChat.mentionPatterns already set).");
1543
+ delete groupChat.mentionPatterns;
1544
+ }
1545
+ if (Object.keys(groupChat).length === 0) delete routing.groupChat;
1546
+ else routing.groupChat = groupChat;
1547
+ }
1548
+ if (routing.transcribeAudio !== void 0) {
1549
+ applyLegacyAudioTranscriptionModel({
1550
+ raw,
1551
+ source: routing.transcribeAudio,
1552
+ changes,
1553
+ movedMessage: "Moved routing.transcribeAudio → tools.media.audio.models.",
1554
+ alreadySetMessage: "Removed routing.transcribeAudio (tools.media.audio.models already set).",
1555
+ invalidMessage: "Removed routing.transcribeAudio (invalid or empty command)."
1556
+ });
1557
+ delete routing.transcribeAudio;
1558
+ }
1559
+ if (Object.keys(routing).length === 0) delete raw.routing;
1560
+ }
1561
+ },
1562
+ {
1563
+ id: "audio.transcription-v2",
1564
+ describe: "Move audio.transcription to tools.media.audio.models",
1565
+ apply: (raw, changes) => {
1566
+ const audio = getRecord(raw.audio);
1567
+ if (audio?.transcription === void 0) return;
1568
+ applyLegacyAudioTranscriptionModel({
1569
+ raw,
1570
+ source: audio.transcription,
1571
+ changes,
1572
+ movedMessage: "Moved audio.transcription → tools.media.audio.models.",
1573
+ alreadySetMessage: "Removed audio.transcription (tools.media.audio.models already set).",
1574
+ invalidMessage: "Removed audio.transcription (invalid or empty command)."
1575
+ });
1576
+ delete audio.transcription;
1577
+ if (Object.keys(audio).length === 0) delete raw.audio;
1578
+ else raw.audio = audio;
1579
+ }
1580
+ }
1581
+ ];
1582
+
1583
+ //#endregion
1584
+ //#region src/config/legacy.migrations.part-3.ts
1585
+ const LEGACY_CONFIG_MIGRATIONS_PART_3 = [
1586
+ {
1587
+ id: "auth.anthropic-claude-cli-mode-oauth",
1588
+ describe: "Switch anthropic:claude-cli auth profile mode to oauth",
1589
+ apply: (raw, changes) => {
1590
+ const profiles = getRecord(getRecord(raw.auth)?.profiles);
1591
+ if (!profiles) return;
1592
+ const claudeCli = getRecord(profiles["anthropic:claude-cli"]);
1593
+ if (!claudeCli) return;
1594
+ if (claudeCli.mode !== "token") return;
1595
+ claudeCli.mode = "oauth";
1596
+ changes.push("Updated auth.profiles[\"anthropic:claude-cli\"].mode → \"oauth\".");
1597
+ }
1598
+ },
1599
+ {
1600
+ id: "tools.bash->tools.exec",
1601
+ describe: "Move tools.bash to tools.exec",
1602
+ apply: (raw, changes) => {
1603
+ const tools = ensureRecord(raw, "tools");
1604
+ const bash = getRecord(tools.bash);
1605
+ if (!bash) return;
1606
+ if (tools.exec === void 0) {
1607
+ tools.exec = bash;
1608
+ changes.push("Moved tools.bash → tools.exec.");
1609
+ } else changes.push("Removed tools.bash (tools.exec already set).");
1610
+ delete tools.bash;
1611
+ }
1612
+ },
1613
+ {
1614
+ id: "messages.tts.enabled->auto",
1615
+ describe: "Move messages.tts.enabled to messages.tts.auto",
1616
+ apply: (raw, changes) => {
1617
+ const tts = getRecord(getRecord(raw.messages)?.tts);
1618
+ if (!tts) return;
1619
+ if (tts.auto !== void 0) {
1620
+ if ("enabled" in tts) {
1621
+ delete tts.enabled;
1622
+ changes.push("Removed messages.tts.enabled (messages.tts.auto already set).");
1623
+ }
1624
+ return;
1625
+ }
1626
+ if (typeof tts.enabled !== "boolean") return;
1627
+ tts.auto = tts.enabled ? "always" : "off";
1628
+ delete tts.enabled;
1629
+ changes.push(`Moved messages.tts.enabled → messages.tts.auto (${String(tts.auto)}).`);
1630
+ }
1631
+ },
1632
+ {
1633
+ id: "agent.defaults-v2",
1634
+ describe: "Move agent config to agents.defaults and tools",
1635
+ apply: (raw, changes) => {
1636
+ const agent = getRecord(raw.agent);
1637
+ if (!agent) return;
1638
+ const agents = ensureRecord(raw, "agents");
1639
+ const defaults = getRecord(agents.defaults) ?? {};
1640
+ const tools = ensureRecord(raw, "tools");
1641
+ const agentTools = getRecord(agent.tools);
1642
+ if (agentTools) {
1643
+ if (tools.allow === void 0 && agentTools.allow !== void 0) {
1644
+ tools.allow = agentTools.allow;
1645
+ changes.push("Moved agent.tools.allow → tools.allow.");
1646
+ }
1647
+ if (tools.deny === void 0 && agentTools.deny !== void 0) {
1648
+ tools.deny = agentTools.deny;
1649
+ changes.push("Moved agent.tools.deny → tools.deny.");
1650
+ }
1651
+ }
1652
+ const elevated = getRecord(agent.elevated);
1653
+ if (elevated) if (tools.elevated === void 0) {
1654
+ tools.elevated = elevated;
1655
+ changes.push("Moved agent.elevated → tools.elevated.");
1656
+ } else changes.push("Removed agent.elevated (tools.elevated already set).");
1657
+ const bash = getRecord(agent.bash);
1658
+ if (bash) if (tools.exec === void 0) {
1659
+ tools.exec = bash;
1660
+ changes.push("Moved agent.bash → tools.exec.");
1661
+ } else changes.push("Removed agent.bash (tools.exec already set).");
1662
+ const sandbox = getRecord(agent.sandbox);
1663
+ if (sandbox) {
1664
+ const sandboxTools = getRecord(sandbox.tools);
1665
+ if (sandboxTools) {
1666
+ mergeMissing(ensureRecord(ensureRecord(tools, "sandbox"), "tools"), sandboxTools);
1667
+ delete sandbox.tools;
1668
+ changes.push("Moved agent.sandbox.tools → tools.sandbox.tools.");
1669
+ }
1670
+ }
1671
+ const subagents = getRecord(agent.subagents);
1672
+ if (subagents) {
1673
+ const subagentTools = getRecord(subagents.tools);
1674
+ if (subagentTools) {
1675
+ mergeMissing(ensureRecord(ensureRecord(tools, "subagents"), "tools"), subagentTools);
1676
+ delete subagents.tools;
1677
+ changes.push("Moved agent.subagents.tools → tools.subagents.tools.");
1678
+ }
1679
+ }
1680
+ const agentCopy = structuredClone(agent);
1681
+ delete agentCopy.tools;
1682
+ delete agentCopy.elevated;
1683
+ delete agentCopy.bash;
1684
+ if (isRecord(agentCopy.sandbox)) delete agentCopy.sandbox.tools;
1685
+ if (isRecord(agentCopy.subagents)) delete agentCopy.subagents.tools;
1686
+ mergeMissing(defaults, agentCopy);
1687
+ agents.defaults = defaults;
1688
+ raw.agents = agents;
1689
+ delete raw.agent;
1690
+ changes.push("Moved agent → agents.defaults.");
1691
+ }
1692
+ },
1693
+ {
1694
+ id: "identity->agents.list",
1695
+ describe: "Move identity to agents.list[].identity",
1696
+ apply: (raw, changes) => {
1697
+ const identity = getRecord(raw.identity);
1698
+ if (!identity) return;
1699
+ const agents = ensureRecord(raw, "agents");
1700
+ const list = getAgentsList(agents);
1701
+ const defaultId = resolveDefaultAgentIdFromRaw(raw);
1702
+ const entry = ensureAgentEntry(list, defaultId);
1703
+ if (entry.identity === void 0) {
1704
+ entry.identity = identity;
1705
+ changes.push(`Moved identity → agents.list (id "${defaultId}").identity.`);
1706
+ } else changes.push("Removed identity (agents.list identity already set).");
1707
+ agents.list = list;
1708
+ raw.agents = agents;
1709
+ delete raw.identity;
1710
+ }
1711
+ }
1712
+ ];
1713
+
1714
+ //#endregion
1715
+ //#region src/config/legacy.migrations.ts
1716
+ const LEGACY_CONFIG_MIGRATIONS = [
1717
+ ...LEGACY_CONFIG_MIGRATIONS_PART_1,
1718
+ ...LEGACY_CONFIG_MIGRATIONS_PART_2,
1719
+ ...LEGACY_CONFIG_MIGRATIONS_PART_3
1720
+ ];
1721
+
1722
+ //#endregion
1723
+ //#region src/config/legacy.rules.ts
1724
+ const LEGACY_CONFIG_RULES = [
1725
+ {
1726
+ path: ["whatsapp"],
1727
+ message: "whatsapp config moved to channels.whatsapp (auto-migrated on load)."
1728
+ },
1729
+ {
1730
+ path: ["telegram"],
1731
+ message: "telegram config moved to channels.telegram (auto-migrated on load)."
1732
+ },
1733
+ {
1734
+ path: ["discord"],
1735
+ message: "discord config moved to channels.discord (auto-migrated on load)."
1736
+ },
1737
+ {
1738
+ path: ["slack"],
1739
+ message: "slack config moved to channels.slack (auto-migrated on load)."
1740
+ },
1741
+ {
1742
+ path: ["signal"],
1743
+ message: "signal config moved to channels.signal (auto-migrated on load)."
1744
+ },
1745
+ {
1746
+ path: ["imessage"],
1747
+ message: "imessage config moved to channels.imessage (auto-migrated on load)."
1748
+ },
1749
+ {
1750
+ path: ["msteams"],
1751
+ message: "msteams config moved to channels.msteams (auto-migrated on load)."
1752
+ },
1753
+ {
1754
+ path: ["routing", "allowFrom"],
1755
+ message: "routing.allowFrom was removed; use channels.whatsapp.allowFrom instead (auto-migrated on load)."
1756
+ },
1757
+ {
1758
+ path: ["routing", "bindings"],
1759
+ message: "routing.bindings was moved; use top-level bindings instead (auto-migrated on load)."
1760
+ },
1761
+ {
1762
+ path: ["routing", "agents"],
1763
+ message: "routing.agents was moved; use agents.list instead (auto-migrated on load)."
1764
+ },
1765
+ {
1766
+ path: ["routing", "defaultAgentId"],
1767
+ message: "routing.defaultAgentId was moved; use agents.list[].default instead (auto-migrated on load)."
1768
+ },
1769
+ {
1770
+ path: ["routing", "agentToAgent"],
1771
+ message: "routing.agentToAgent was moved; use tools.agentToAgent instead (auto-migrated on load)."
1772
+ },
1773
+ {
1774
+ path: [
1775
+ "routing",
1776
+ "groupChat",
1777
+ "requireMention"
1778
+ ],
1779
+ message: "routing.groupChat.requireMention was removed; use channels.whatsapp/telegram/imessage groups defaults (e.g. channels.whatsapp.groups.\"*\".requireMention) instead (auto-migrated on load)."
1780
+ },
1781
+ {
1782
+ path: [
1783
+ "routing",
1784
+ "groupChat",
1785
+ "mentionPatterns"
1786
+ ],
1787
+ message: "routing.groupChat.mentionPatterns was moved; use agents.list[].groupChat.mentionPatterns or messages.groupChat.mentionPatterns instead (auto-migrated on load)."
1788
+ },
1789
+ {
1790
+ path: ["routing", "queue"],
1791
+ message: "routing.queue was moved; use messages.queue instead (auto-migrated on load)."
1792
+ },
1793
+ {
1794
+ path: ["routing", "transcribeAudio"],
1795
+ message: "routing.transcribeAudio was moved; use tools.media.audio.models instead (auto-migrated on load)."
1796
+ },
1797
+ {
1798
+ path: ["telegram", "requireMention"],
1799
+ message: "telegram.requireMention was removed; use channels.telegram.groups.\"*\".requireMention instead (auto-migrated on load)."
1800
+ },
1801
+ {
1802
+ path: ["identity"],
1803
+ message: "identity was moved; use agents.list[].identity instead (auto-migrated on load)."
1804
+ },
1805
+ {
1806
+ path: ["agent"],
1807
+ message: "agent.* was moved; use agents.defaults (and tools.* for tool/elevated/exec settings) instead (auto-migrated on load)."
1808
+ },
1809
+ {
1810
+ path: ["tools", "bash"],
1811
+ message: "tools.bash was removed; use tools.exec instead (auto-migrated on load)."
1812
+ },
1813
+ {
1814
+ path: ["agent", "model"],
1815
+ message: "agent.model string was replaced by agents.defaults.model.primary/fallbacks and agents.defaults.models (auto-migrated on load).",
1816
+ match: (value) => typeof value === "string"
1817
+ },
1818
+ {
1819
+ path: ["agent", "imageModel"],
1820
+ message: "agent.imageModel string was replaced by agents.defaults.imageModel.primary/fallbacks (auto-migrated on load).",
1821
+ match: (value) => typeof value === "string"
1822
+ },
1823
+ {
1824
+ path: ["agent", "allowedModels"],
1825
+ message: "agent.allowedModels was replaced by agents.defaults.models (auto-migrated on load)."
1826
+ },
1827
+ {
1828
+ path: ["agent", "modelAliases"],
1829
+ message: "agent.modelAliases was replaced by agents.defaults.models.*.alias (auto-migrated on load)."
1830
+ },
1831
+ {
1832
+ path: ["agent", "modelFallbacks"],
1833
+ message: "agent.modelFallbacks was replaced by agents.defaults.model.fallbacks (auto-migrated on load)."
1834
+ },
1835
+ {
1836
+ path: ["agent", "imageModelFallbacks"],
1837
+ message: "agent.imageModelFallbacks was replaced by agents.defaults.imageModel.fallbacks (auto-migrated on load)."
1838
+ },
1839
+ {
1840
+ path: [
1841
+ "messages",
1842
+ "tts",
1843
+ "enabled"
1844
+ ],
1845
+ message: "messages.tts.enabled was replaced by messages.tts.auto (auto-migrated on load)."
1846
+ },
1847
+ {
1848
+ path: ["gateway", "token"],
1849
+ message: "gateway.token is ignored; use gateway.auth.token instead (auto-migrated on load)."
1850
+ }
1851
+ ];
1852
+
1853
+ //#endregion
1854
+ //#region src/config/legacy.ts
1855
+ function findLegacyConfigIssues(raw) {
1856
+ if (!raw || typeof raw !== "object") return [];
1857
+ const root = raw;
1858
+ const issues = [];
1859
+ for (const rule of LEGACY_CONFIG_RULES) {
1860
+ let cursor = root;
1861
+ for (const key of rule.path) {
1862
+ if (!cursor || typeof cursor !== "object") {
1863
+ cursor = void 0;
1864
+ break;
1865
+ }
1866
+ cursor = cursor[key];
1867
+ }
1868
+ if (cursor !== void 0 && (!rule.match || rule.match(cursor, root))) issues.push({
1869
+ path: rule.path.join("."),
1870
+ message: rule.message
1871
+ });
1872
+ }
1873
+ return issues;
1874
+ }
1875
+ function applyLegacyMigrations(raw) {
1876
+ if (!raw || typeof raw !== "object") return {
1877
+ next: null,
1878
+ changes: []
1879
+ };
1880
+ const next = structuredClone(raw);
1881
+ const changes = [];
1882
+ for (const migration of LEGACY_CONFIG_MIGRATIONS) migration.apply(next, changes);
1883
+ if (changes.length === 0) return {
1884
+ next: null,
1885
+ changes: []
1886
+ };
1887
+ return {
1888
+ next,
1889
+ changes
1890
+ };
1891
+ }
1892
+
1893
+ //#endregion
1894
+ //#region src/config/merge-patch.ts
1895
+ function isObjectWithStringId(value) {
1896
+ if (!isPlainObject$2(value)) return false;
1897
+ return typeof value.id === "string" && value.id.length > 0;
1898
+ }
1899
+ /**
1900
+ * Merge arrays of object-like entries keyed by `id`.
1901
+ *
1902
+ * Contract:
1903
+ * - Base array must be fully id-keyed; otherwise return undefined (caller should replace).
1904
+ * - Patch entries with valid id merge by id (or append when the id is new).
1905
+ * - Patch entries without valid id append as-is, avoiding destructive full-array replacement.
1906
+ */
1907
+ function mergeObjectArraysById(base, patch, options) {
1908
+ if (!base.every(isObjectWithStringId)) return;
1909
+ const merged = [...base];
1910
+ const indexById = /* @__PURE__ */ new Map();
1911
+ for (const [index, entry] of merged.entries()) {
1912
+ if (!isObjectWithStringId(entry)) return;
1913
+ indexById.set(entry.id, index);
1914
+ }
1915
+ for (const patchEntry of patch) {
1916
+ if (!isObjectWithStringId(patchEntry)) {
1917
+ merged.push(structuredClone(patchEntry));
1918
+ continue;
1919
+ }
1920
+ const existingIndex = indexById.get(patchEntry.id);
1921
+ if (existingIndex === void 0) {
1922
+ merged.push(structuredClone(patchEntry));
1923
+ indexById.set(patchEntry.id, merged.length - 1);
1924
+ continue;
1925
+ }
1926
+ merged[existingIndex] = applyMergePatch(merged[existingIndex], patchEntry, options);
1927
+ }
1928
+ return merged;
1929
+ }
1930
+ function applyMergePatch(base, patch, options = {}) {
1931
+ if (!isPlainObject$2(patch)) return patch;
1932
+ const result = isPlainObject$2(base) ? { ...base } : {};
1933
+ for (const [key, value] of Object.entries(patch)) {
1934
+ if (isBlockedObjectKey(key)) continue;
1935
+ if (value === null) {
1936
+ delete result[key];
1937
+ continue;
1938
+ }
1939
+ if (options.mergeObjectArraysById && Array.isArray(result[key]) && Array.isArray(value)) {
1940
+ const mergedArray = mergeObjectArraysById(result[key], value, options);
1941
+ if (mergedArray) {
1942
+ result[key] = mergedArray;
1943
+ continue;
1944
+ }
1945
+ }
1946
+ if (isPlainObject$2(value)) {
1947
+ const baseValue = result[key];
1948
+ result[key] = applyMergePatch(isPlainObject$2(baseValue) ? baseValue : {}, value, options);
1949
+ continue;
1950
+ }
1951
+ result[key] = value;
1952
+ }
1953
+ return result;
1954
+ }
1955
+
1956
+ //#endregion
1957
+ //#region src/config/normalize-paths.ts
1958
+ const PATH_VALUE_RE = /^~(?=$|[\\/])/;
1959
+ const PATH_KEY_RE = /(dir|path|paths|file|root|workspace)$/i;
1960
+ const PATH_LIST_KEYS = new Set(["paths", "pathPrepend"]);
1961
+ function normalizeStringValue(key, value) {
1962
+ if (!PATH_VALUE_RE.test(value.trim())) return value;
1963
+ if (!key) return value;
1964
+ if (PATH_KEY_RE.test(key) || PATH_LIST_KEYS.has(key)) return resolveUserPath(value);
1965
+ return value;
1966
+ }
1967
+ function normalizeAny(key, value) {
1968
+ if (typeof value === "string") return normalizeStringValue(key, value);
1969
+ if (Array.isArray(value)) {
1970
+ const normalizeChildren = Boolean(key && PATH_LIST_KEYS.has(key));
1971
+ return value.map((entry) => {
1972
+ if (typeof entry === "string") return normalizeChildren ? normalizeStringValue(key, entry) : entry;
1973
+ if (Array.isArray(entry)) return normalizeAny(void 0, entry);
1974
+ if (isPlainObject$2(entry)) return normalizeAny(void 0, entry);
1975
+ return entry;
1976
+ });
1977
+ }
1978
+ if (!isPlainObject$2(value)) return value;
1979
+ for (const [childKey, childValue] of Object.entries(value)) {
1980
+ const next = normalizeAny(childKey, childValue);
1981
+ if (next !== childValue) value[childKey] = next;
1982
+ }
1983
+ return value;
1984
+ }
1985
+ /**
1986
+ * Normalize "~" paths in path-ish config fields.
1987
+ *
1988
+ * Goal: accept `~/...` consistently across config file + env overrides, while
1989
+ * keeping the surface area small and predictable.
1990
+ */
1991
+ function normalizeConfigPaths(cfg) {
1992
+ if (!cfg || typeof cfg !== "object") return cfg;
1993
+ normalizeAny(void 0, cfg);
1994
+ return cfg;
1995
+ }
1996
+
1997
+ //#endregion
1998
+ //#region src/config/config-paths.ts
1999
+ function parseConfigPath(raw) {
2000
+ const trimmed = raw.trim();
2001
+ if (!trimmed) return {
2002
+ ok: false,
2003
+ error: "Invalid path. Use dot notation (e.g. foo.bar)."
2004
+ };
2005
+ const parts = trimmed.split(".").map((part) => part.trim());
2006
+ if (parts.some((part) => !part)) return {
2007
+ ok: false,
2008
+ error: "Invalid path. Use dot notation (e.g. foo.bar)."
2009
+ };
2010
+ if (parts.some((part) => isBlockedObjectKey(part))) return {
2011
+ ok: false,
2012
+ error: "Invalid path segment."
2013
+ };
2014
+ return {
2015
+ ok: true,
2016
+ path: parts
2017
+ };
2018
+ }
2019
+ function setConfigValueAtPath(root, path, value) {
2020
+ let cursor = root;
2021
+ for (let idx = 0; idx < path.length - 1; idx += 1) {
2022
+ const key = path[idx];
2023
+ const next = cursor[key];
2024
+ if (!isPlainObject$2(next)) cursor[key] = {};
2025
+ cursor = cursor[key];
2026
+ }
2027
+ cursor[path[path.length - 1]] = value;
2028
+ }
2029
+ function unsetConfigValueAtPath(root, path) {
2030
+ const stack = [];
2031
+ let cursor = root;
2032
+ for (let idx = 0; idx < path.length - 1; idx += 1) {
2033
+ const key = path[idx];
2034
+ const next = cursor[key];
2035
+ if (!isPlainObject$2(next)) return false;
2036
+ stack.push({
2037
+ node: cursor,
2038
+ key
2039
+ });
2040
+ cursor = next;
2041
+ }
2042
+ const leafKey = path[path.length - 1];
2043
+ if (!(leafKey in cursor)) return false;
2044
+ delete cursor[leafKey];
2045
+ for (let idx = stack.length - 1; idx >= 0; idx -= 1) {
2046
+ const { node, key } = stack[idx];
2047
+ const child = node[key];
2048
+ if (isPlainObject$2(child) && Object.keys(child).length === 0) delete node[key];
2049
+ else break;
2050
+ }
2051
+ return true;
2052
+ }
2053
+ function getConfigValueAtPath(root, path) {
2054
+ let cursor = root;
2055
+ for (const key of path) {
2056
+ if (!isPlainObject$2(cursor)) return;
2057
+ cursor = cursor[key];
2058
+ }
2059
+ return cursor;
2060
+ }
2061
+
2062
+ //#endregion
2063
+ //#region src/config/runtime-overrides.ts
2064
+ let overrides = {};
2065
+ function sanitizeOverrideValue(value, seen = /* @__PURE__ */ new WeakSet()) {
2066
+ if (Array.isArray(value)) return value.map((entry) => sanitizeOverrideValue(entry, seen));
2067
+ if (!isPlainObject$2(value)) return value;
2068
+ if (seen.has(value)) return {};
2069
+ seen.add(value);
2070
+ const sanitized = {};
2071
+ for (const [key, entry] of Object.entries(value)) {
2072
+ if (entry === void 0 || isBlockedObjectKey(key)) continue;
2073
+ sanitized[key] = sanitizeOverrideValue(entry, seen);
2074
+ }
2075
+ seen.delete(value);
2076
+ return sanitized;
2077
+ }
2078
+ function mergeOverrides(base, override) {
2079
+ if (!isPlainObject$2(base) || !isPlainObject$2(override)) return override;
2080
+ const next = { ...base };
2081
+ for (const [key, value] of Object.entries(override)) {
2082
+ if (value === void 0 || isBlockedObjectKey(key)) continue;
2083
+ next[key] = mergeOverrides(base[key], value);
2084
+ }
2085
+ return next;
2086
+ }
2087
+ function getConfigOverrides() {
2088
+ return overrides;
2089
+ }
2090
+ function resetConfigOverrides() {
2091
+ overrides = {};
2092
+ }
2093
+ function setConfigOverride(pathRaw, value) {
2094
+ const parsed = parseConfigPath(pathRaw);
2095
+ if (!parsed.ok || !parsed.path) return {
2096
+ ok: false,
2097
+ error: parsed.error ?? "Invalid path."
2098
+ };
2099
+ setConfigValueAtPath(overrides, parsed.path, sanitizeOverrideValue(value));
2100
+ return { ok: true };
2101
+ }
2102
+ function unsetConfigOverride(pathRaw) {
2103
+ const parsed = parseConfigPath(pathRaw);
2104
+ if (!parsed.ok || !parsed.path) return {
2105
+ ok: false,
2106
+ removed: false,
2107
+ error: parsed.error ?? "Invalid path."
2108
+ };
2109
+ return {
2110
+ ok: true,
2111
+ removed: unsetConfigValueAtPath(overrides, parsed.path)
2112
+ };
2113
+ }
2114
+ function applyConfigOverrides(cfg) {
2115
+ if (!overrides || Object.keys(overrides).length === 0) return cfg;
2116
+ return mergeOverrides(cfg, overrides);
2117
+ }
2118
+
2119
+ //#endregion
2120
+ //#region src/plugins/config-state.ts
2121
+ const BUNDLED_ENABLED_BY_DEFAULT = new Set([
2122
+ "device-pair",
2123
+ "phone-control",
2124
+ "talk-voice"
2125
+ ]);
2126
+ const normalizeList = (value) => {
2127
+ if (!Array.isArray(value)) return [];
2128
+ return value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
2129
+ };
2130
+ const normalizePluginEntries = (entries) => {
2131
+ if (!entries || typeof entries !== "object" || Array.isArray(entries)) return {};
2132
+ const normalized = {};
2133
+ for (const [key, value] of Object.entries(entries)) {
2134
+ if (!key.trim()) continue;
2135
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2136
+ normalized[key] = {};
2137
+ continue;
2138
+ }
2139
+ const entry = value;
2140
+ normalized[key] = {
2141
+ enabled: typeof entry.enabled === "boolean" ? entry.enabled : void 0,
2142
+ config: "config" in entry ? entry.config : void 0
2143
+ };
2144
+ }
2145
+ return normalized;
2146
+ };
2147
+ const normalizePluginsConfig = (config) => {
2148
+ return {
2149
+ enabled: config?.enabled !== false,
2150
+ allow: normalizeList(config?.allow),
2151
+ deny: normalizeList(config?.deny),
2152
+ loadPaths: normalizeList(config?.load?.paths),
2153
+ slots: {},
2154
+ entries: normalizePluginEntries(config?.entries)
2155
+ };
2156
+ };
2157
+ const hasExplicitPluginConfig = (plugins) => {
2158
+ if (!plugins) return false;
2159
+ if (typeof plugins.enabled === "boolean") return true;
2160
+ if (Array.isArray(plugins.allow) && plugins.allow.length > 0) return true;
2161
+ if (Array.isArray(plugins.deny) && plugins.deny.length > 0) return true;
2162
+ if (plugins.load?.paths && Array.isArray(plugins.load.paths) && plugins.load.paths.length > 0) return true;
2163
+ if (plugins.slots && Object.keys(plugins.slots).length > 0) return true;
2164
+ if (plugins.entries && Object.keys(plugins.entries).length > 0) return true;
2165
+ return false;
2166
+ };
2167
+ function applyTestPluginDefaults(cfg, env = process.env) {
2168
+ if (!env.VITEST) return cfg;
2169
+ const plugins = cfg.plugins;
2170
+ if (hasExplicitPluginConfig(plugins)) return cfg;
2171
+ return {
2172
+ ...cfg,
2173
+ plugins: {
2174
+ ...plugins,
2175
+ enabled: false
2176
+ }
2177
+ };
2178
+ }
2179
+ function resolveEnableState(id, origin, config) {
2180
+ if (!config.enabled) return {
2181
+ enabled: false,
2182
+ reason: "plugins disabled"
2183
+ };
2184
+ if (config.deny.includes(id)) return {
2185
+ enabled: false,
2186
+ reason: "blocked by denylist"
2187
+ };
2188
+ if (config.allow.length > 0 && !config.allow.includes(id)) return {
2189
+ enabled: false,
2190
+ reason: "not in allowlist"
2191
+ };
2192
+ const entry = config.entries[id];
2193
+ if (entry?.enabled === true) return { enabled: true };
2194
+ if (entry?.enabled === false) return {
2195
+ enabled: false,
2196
+ reason: "disabled in config"
2197
+ };
2198
+ if (origin === "bundled" && BUNDLED_ENABLED_BY_DEFAULT.has(id)) return { enabled: true };
2199
+ if (origin === "bundled") return {
2200
+ enabled: false,
2201
+ reason: "bundled (disabled by default)"
2202
+ };
2203
+ return { enabled: true };
2204
+ }
2205
+ function isBundledChannelEnabledByChannelConfig(cfg, pluginId) {
2206
+ if (!cfg) return false;
2207
+ const channelId = normalizeChatChannelId(pluginId);
2208
+ if (!channelId) return false;
2209
+ const entry = cfg.channels?.[channelId];
2210
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return false;
2211
+ return entry.enabled === true;
2212
+ }
2213
+ function resolveEffectiveEnableState(params) {
2214
+ const base = resolveEnableState(params.id, params.origin, params.config);
2215
+ if (!base.enabled && base.reason === "bundled (disabled by default)" && isBundledChannelEnabledByChannelConfig(params.rootConfig, params.id)) return { enabled: true };
2216
+ return base;
2217
+ }
2218
+
2219
+ //#endregion
2220
+ //#region src/plugins/bundled-dir.ts
2221
+ function resolveBundledPluginsDir() {
2222
+ const override = process.env.REMOTECLAW_BUNDLED_PLUGINS_DIR?.trim();
2223
+ if (override) return override;
2224
+ try {
2225
+ const execDir = path.dirname(process.execPath);
2226
+ const sibling = path.join(execDir, "extensions");
2227
+ if (fs.existsSync(sibling)) return sibling;
2228
+ } catch {}
2229
+ try {
2230
+ let cursor = path.dirname(fileURLToPath(import.meta.url));
2231
+ for (let i = 0; i < 6; i += 1) {
2232
+ const candidate = path.join(cursor, "extensions");
2233
+ if (fs.existsSync(candidate)) return candidate;
2234
+ const parent = path.dirname(cursor);
2235
+ if (parent === cursor) break;
2236
+ cursor = parent;
2237
+ }
2238
+ } catch {}
2239
+ }
2240
+
2241
+ //#endregion
2242
+ //#region src/compat/legacy-names.ts
2243
+ const PROJECT_NAME = "remoteclaw";
2244
+ const LEGACY_PROJECT_NAMES = [];
2245
+ const MANIFEST_KEY = PROJECT_NAME;
2246
+ const LEGACY_MANIFEST_KEYS = LEGACY_PROJECT_NAMES;
2247
+ const LEGACY_PLUGIN_MANIFEST_FILENAMES = [];
2248
+
2249
+ //#endregion
2250
+ //#region src/plugins/manifest.ts
2251
+ const PLUGIN_MANIFEST_FILENAME = "remoteclaw.plugin.json";
2252
+ const PLUGIN_MANIFEST_FILENAMES = [PLUGIN_MANIFEST_FILENAME, ...LEGACY_PLUGIN_MANIFEST_FILENAMES];
2253
+ function normalizeStringList(value) {
2254
+ if (!Array.isArray(value)) return [];
2255
+ return value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
2256
+ }
2257
+ function resolvePluginManifestPath(rootDir) {
2258
+ for (const filename of PLUGIN_MANIFEST_FILENAMES) {
2259
+ const candidate = path.join(rootDir, filename);
2260
+ if (fs.existsSync(candidate)) return candidate;
2261
+ }
2262
+ return path.join(rootDir, PLUGIN_MANIFEST_FILENAME);
2263
+ }
2264
+ function loadPluginManifest(rootDir) {
2265
+ const manifestPath = resolvePluginManifestPath(rootDir);
2266
+ if (!fs.existsSync(manifestPath)) return {
2267
+ ok: false,
2268
+ error: `plugin manifest not found: ${manifestPath}`,
2269
+ manifestPath
2270
+ };
2271
+ let raw;
2272
+ try {
2273
+ raw = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
2274
+ } catch (err) {
2275
+ return {
2276
+ ok: false,
2277
+ error: `failed to parse plugin manifest: ${String(err)}`,
2278
+ manifestPath
2279
+ };
2280
+ }
2281
+ if (!isRecord(raw)) return {
2282
+ ok: false,
2283
+ error: "plugin manifest must be an object",
2284
+ manifestPath
2285
+ };
2286
+ const id = typeof raw.id === "string" ? raw.id.trim() : "";
2287
+ if (!id) return {
2288
+ ok: false,
2289
+ error: "plugin manifest requires id",
2290
+ manifestPath
2291
+ };
2292
+ const configSchema = isRecord(raw.configSchema) ? raw.configSchema : null;
2293
+ if (!configSchema) return {
2294
+ ok: false,
2295
+ error: "plugin manifest requires configSchema",
2296
+ manifestPath
2297
+ };
2298
+ const kind = typeof raw.kind === "string" ? raw.kind : void 0;
2299
+ const name = typeof raw.name === "string" ? raw.name.trim() : void 0;
2300
+ const description = typeof raw.description === "string" ? raw.description.trim() : void 0;
2301
+ const version = typeof raw.version === "string" ? raw.version.trim() : void 0;
2302
+ const channels = normalizeStringList(raw.channels);
2303
+ const providers = normalizeStringList(raw.providers);
2304
+ const skills = normalizeStringList(raw.skills);
2305
+ const stt = normalizeStringList(raw.stt);
2306
+ const tts = normalizeStringList(raw.tts);
2307
+ let uiHints;
2308
+ if (isRecord(raw.uiHints)) uiHints = raw.uiHints;
2309
+ return {
2310
+ ok: true,
2311
+ manifest: {
2312
+ id,
2313
+ configSchema,
2314
+ kind,
2315
+ channels,
2316
+ providers,
2317
+ skills,
2318
+ stt,
2319
+ tts,
2320
+ name,
2321
+ description,
2322
+ version,
2323
+ uiHints
2324
+ },
2325
+ manifestPath
2326
+ };
2327
+ }
2328
+ function getPackageManifestMetadata(manifest) {
2329
+ if (!manifest) return;
2330
+ const current = manifest[MANIFEST_KEY];
2331
+ if (current) return current;
2332
+ for (const key of LEGACY_MANIFEST_KEYS) {
2333
+ const legacy = manifest[key];
2334
+ if (legacy) return legacy;
2335
+ }
2336
+ }
2337
+
2338
+ //#endregion
2339
+ //#region src/plugins/path-safety.ts
2340
+ function isPathInside(baseDir, targetPath) {
2341
+ const rel = path.relative(baseDir, targetPath);
2342
+ if (!rel) return true;
2343
+ return !rel.startsWith("..") && !path.isAbsolute(rel);
2344
+ }
2345
+ function safeRealpathSync(targetPath, cache) {
2346
+ const cached = cache?.get(targetPath);
2347
+ if (cached) return cached;
2348
+ try {
2349
+ const resolved = fs.realpathSync(targetPath);
2350
+ cache?.set(targetPath, resolved);
2351
+ return resolved;
2352
+ } catch {
2353
+ return null;
2354
+ }
2355
+ }
2356
+ function safeStatSync(targetPath) {
2357
+ try {
2358
+ return fs.statSync(targetPath);
2359
+ } catch {
2360
+ return null;
2361
+ }
2362
+ }
2363
+ function formatPosixMode(mode) {
2364
+ return (mode & 511).toString(8).padStart(3, "0");
2365
+ }
2366
+
2367
+ //#endregion
2368
+ //#region src/plugins/discovery.ts
2369
+ const EXTENSION_EXTS = new Set([
2370
+ ".ts",
2371
+ ".js",
2372
+ ".mts",
2373
+ ".cts",
2374
+ ".mjs",
2375
+ ".cjs"
2376
+ ]);
2377
+ function currentUid(overrideUid) {
2378
+ if (overrideUid !== void 0) return overrideUid;
2379
+ if (process.platform === "win32") return null;
2380
+ if (typeof process.getuid !== "function") return null;
2381
+ return process.getuid();
2382
+ }
2383
+ function checkSourceEscapesRoot(params) {
2384
+ const sourceRealPath = safeRealpathSync(params.source);
2385
+ const rootRealPath = safeRealpathSync(params.rootDir);
2386
+ if (!sourceRealPath || !rootRealPath) return null;
2387
+ if (isPathInside(rootRealPath, sourceRealPath)) return null;
2388
+ return {
2389
+ reason: "source_escapes_root",
2390
+ sourcePath: params.source,
2391
+ rootPath: params.rootDir,
2392
+ targetPath: params.source,
2393
+ sourceRealPath,
2394
+ rootRealPath
2395
+ };
2396
+ }
2397
+ function checkPathStatAndPermissions(params) {
2398
+ if (process.platform === "win32") return null;
2399
+ const pathsToCheck = [params.rootDir, params.source];
2400
+ const seen = /* @__PURE__ */ new Set();
2401
+ for (const targetPath of pathsToCheck) {
2402
+ const normalized = path.resolve(targetPath);
2403
+ if (seen.has(normalized)) continue;
2404
+ seen.add(normalized);
2405
+ const stat = safeStatSync(targetPath);
2406
+ if (!stat) return {
2407
+ reason: "path_stat_failed",
2408
+ sourcePath: params.source,
2409
+ rootPath: params.rootDir,
2410
+ targetPath
2411
+ };
2412
+ const modeBits = stat.mode & 511;
2413
+ if ((modeBits & 2) !== 0) return {
2414
+ reason: "path_world_writable",
2415
+ sourcePath: params.source,
2416
+ rootPath: params.rootDir,
2417
+ targetPath,
2418
+ modeBits
2419
+ };
2420
+ if (params.origin !== "bundled" && params.uid !== null && typeof stat.uid === "number" && stat.uid !== params.uid && stat.uid !== 0) return {
2421
+ reason: "path_suspicious_ownership",
2422
+ sourcePath: params.source,
2423
+ rootPath: params.rootDir,
2424
+ targetPath,
2425
+ foundUid: stat.uid,
2426
+ expectedUid: params.uid
2427
+ };
2428
+ }
2429
+ return null;
2430
+ }
2431
+ function findCandidateBlockIssue(params) {
2432
+ const escaped = checkSourceEscapesRoot({
2433
+ source: params.source,
2434
+ rootDir: params.rootDir
2435
+ });
2436
+ if (escaped) return escaped;
2437
+ return checkPathStatAndPermissions({
2438
+ source: params.source,
2439
+ rootDir: params.rootDir,
2440
+ origin: params.origin,
2441
+ uid: currentUid(params.ownershipUid)
2442
+ });
2443
+ }
2444
+ function formatCandidateBlockMessage(issue) {
2445
+ if (issue.reason === "source_escapes_root") return `blocked plugin candidate: source escapes plugin root (${issue.sourcePath} -> ${issue.sourceRealPath}; root=${issue.rootRealPath})`;
2446
+ if (issue.reason === "path_stat_failed") return `blocked plugin candidate: cannot stat path (${issue.targetPath})`;
2447
+ if (issue.reason === "path_world_writable") return `blocked plugin candidate: world-writable path (${issue.targetPath}, mode=${formatPosixMode(issue.modeBits ?? 0)})`;
2448
+ return `blocked plugin candidate: suspicious ownership (${issue.targetPath}, uid=${issue.foundUid}, expected uid=${issue.expectedUid} or root)`;
2449
+ }
2450
+ function isUnsafePluginCandidate(params) {
2451
+ const issue = findCandidateBlockIssue({
2452
+ source: params.source,
2453
+ rootDir: params.rootDir,
2454
+ origin: params.origin,
2455
+ ownershipUid: params.ownershipUid
2456
+ });
2457
+ if (!issue) return false;
2458
+ params.diagnostics.push({
2459
+ level: "warn",
2460
+ source: issue.targetPath,
2461
+ message: formatCandidateBlockMessage(issue)
2462
+ });
2463
+ return true;
2464
+ }
2465
+ function isExtensionFile(filePath) {
2466
+ const ext = path.extname(filePath);
2467
+ if (!EXTENSION_EXTS.has(ext)) return false;
2468
+ return !filePath.endsWith(".d.ts");
2469
+ }
2470
+ function shouldIgnoreScannedDirectory(dirName) {
2471
+ const normalized = dirName.trim().toLowerCase();
2472
+ if (!normalized) return true;
2473
+ if (normalized.endsWith(".bak")) return true;
2474
+ if (normalized.includes(".backup-")) return true;
2475
+ if (normalized.includes(".disabled")) return true;
2476
+ return false;
2477
+ }
2478
+ function readPackageManifest(dir) {
2479
+ const manifestPath = path.join(dir, "package.json");
2480
+ if (!fs.existsSync(manifestPath)) return null;
2481
+ try {
2482
+ const raw = fs.readFileSync(manifestPath, "utf-8");
2483
+ return JSON.parse(raw);
2484
+ } catch {
2485
+ return null;
2486
+ }
2487
+ }
2488
+ function resolvePackageExtensions(manifest) {
2489
+ const raw = getPackageManifestMetadata(manifest)?.extensions;
2490
+ if (!Array.isArray(raw)) return [];
2491
+ return raw.map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
2492
+ }
2493
+ function deriveIdHint(params) {
2494
+ const base = path.basename(params.filePath, path.extname(params.filePath));
2495
+ const rawPackageName = params.packageName?.trim();
2496
+ if (!rawPackageName) return base;
2497
+ const unscoped = rawPackageName.includes("/") ? rawPackageName.split("/").pop() ?? rawPackageName : rawPackageName;
2498
+ if (!params.hasMultipleExtensions) return unscoped;
2499
+ return `${unscoped}/${base}`;
2500
+ }
2501
+ function addCandidate(params) {
2502
+ const resolved = path.resolve(params.source);
2503
+ if (params.seen.has(resolved)) return;
2504
+ const resolvedRoot = path.resolve(params.rootDir);
2505
+ if (isUnsafePluginCandidate({
2506
+ source: resolved,
2507
+ rootDir: resolvedRoot,
2508
+ origin: params.origin,
2509
+ diagnostics: params.diagnostics,
2510
+ ownershipUid: params.ownershipUid
2511
+ })) return;
2512
+ params.seen.add(resolved);
2513
+ const manifest = params.manifest ?? null;
2514
+ params.candidates.push({
2515
+ idHint: params.idHint,
2516
+ source: resolved,
2517
+ rootDir: resolvedRoot,
2518
+ origin: params.origin,
2519
+ workspaceDir: params.workspaceDir,
2520
+ packageName: manifest?.name?.trim() || void 0,
2521
+ packageVersion: manifest?.version?.trim() || void 0,
2522
+ packageDescription: manifest?.description?.trim() || void 0,
2523
+ packageDir: params.packageDir,
2524
+ packageManifest: getPackageManifestMetadata(manifest ?? void 0)
2525
+ });
2526
+ }
2527
+ function resolvePackageEntrySource(params) {
2528
+ const source = path.resolve(params.packageDir, params.entryPath);
2529
+ if (!isPathInsideWithRealpath(params.packageDir, source, { requireRealpath: true })) {
2530
+ params.diagnostics.push({
2531
+ level: "error",
2532
+ message: `extension entry escapes package directory: ${params.entryPath}`,
2533
+ source: params.sourceLabel
2534
+ });
2535
+ return null;
2536
+ }
2537
+ return source;
2538
+ }
2539
+ function discoverInDirectory(params) {
2540
+ if (!fs.existsSync(params.dir)) return;
2541
+ let entries = [];
2542
+ try {
2543
+ entries = fs.readdirSync(params.dir, { withFileTypes: true });
2544
+ } catch (err) {
2545
+ params.diagnostics.push({
2546
+ level: "warn",
2547
+ message: `failed to read extensions dir: ${params.dir} (${String(err)})`,
2548
+ source: params.dir
2549
+ });
2550
+ return;
2551
+ }
2552
+ for (const entry of entries) {
2553
+ const fullPath = path.join(params.dir, entry.name);
2554
+ if (entry.isFile()) {
2555
+ if (!isExtensionFile(fullPath)) continue;
2556
+ addCandidate({
2557
+ candidates: params.candidates,
2558
+ diagnostics: params.diagnostics,
2559
+ seen: params.seen,
2560
+ idHint: path.basename(entry.name, path.extname(entry.name)),
2561
+ source: fullPath,
2562
+ rootDir: path.dirname(fullPath),
2563
+ origin: params.origin,
2564
+ ownershipUid: params.ownershipUid,
2565
+ workspaceDir: params.workspaceDir
2566
+ });
2567
+ }
2568
+ if (!entry.isDirectory()) continue;
2569
+ if (shouldIgnoreScannedDirectory(entry.name)) continue;
2570
+ const manifest = readPackageManifest(fullPath);
2571
+ const extensions = manifest ? resolvePackageExtensions(manifest) : [];
2572
+ if (extensions.length > 0) {
2573
+ for (const extPath of extensions) {
2574
+ const resolved = resolvePackageEntrySource({
2575
+ packageDir: fullPath,
2576
+ entryPath: extPath,
2577
+ sourceLabel: fullPath,
2578
+ diagnostics: params.diagnostics
2579
+ });
2580
+ if (!resolved) continue;
2581
+ addCandidate({
2582
+ candidates: params.candidates,
2583
+ diagnostics: params.diagnostics,
2584
+ seen: params.seen,
2585
+ idHint: deriveIdHint({
2586
+ filePath: resolved,
2587
+ packageName: manifest?.name,
2588
+ hasMultipleExtensions: extensions.length > 1
2589
+ }),
2590
+ source: resolved,
2591
+ rootDir: fullPath,
2592
+ origin: params.origin,
2593
+ ownershipUid: params.ownershipUid,
2594
+ workspaceDir: params.workspaceDir,
2595
+ manifest,
2596
+ packageDir: fullPath
2597
+ });
2598
+ }
2599
+ continue;
2600
+ }
2601
+ const indexFile = [
2602
+ "index.ts",
2603
+ "index.js",
2604
+ "index.mjs",
2605
+ "index.cjs"
2606
+ ].map((candidate) => path.join(fullPath, candidate)).find((candidate) => fs.existsSync(candidate));
2607
+ if (indexFile && isExtensionFile(indexFile)) addCandidate({
2608
+ candidates: params.candidates,
2609
+ diagnostics: params.diagnostics,
2610
+ seen: params.seen,
2611
+ idHint: entry.name,
2612
+ source: indexFile,
2613
+ rootDir: fullPath,
2614
+ origin: params.origin,
2615
+ ownershipUid: params.ownershipUid,
2616
+ workspaceDir: params.workspaceDir,
2617
+ manifest,
2618
+ packageDir: fullPath
2619
+ });
2620
+ }
2621
+ }
2622
+ function discoverFromPath(params) {
2623
+ const resolved = resolveUserPath(params.rawPath);
2624
+ if (!fs.existsSync(resolved)) {
2625
+ params.diagnostics.push({
2626
+ level: "error",
2627
+ message: `plugin path not found: ${resolved}`,
2628
+ source: resolved
2629
+ });
2630
+ return;
2631
+ }
2632
+ const stat = fs.statSync(resolved);
2633
+ if (stat.isFile()) {
2634
+ if (!isExtensionFile(resolved)) {
2635
+ params.diagnostics.push({
2636
+ level: "error",
2637
+ message: `plugin path is not a supported file: ${resolved}`,
2638
+ source: resolved
2639
+ });
2640
+ return;
2641
+ }
2642
+ addCandidate({
2643
+ candidates: params.candidates,
2644
+ diagnostics: params.diagnostics,
2645
+ seen: params.seen,
2646
+ idHint: path.basename(resolved, path.extname(resolved)),
2647
+ source: resolved,
2648
+ rootDir: path.dirname(resolved),
2649
+ origin: params.origin,
2650
+ ownershipUid: params.ownershipUid,
2651
+ workspaceDir: params.workspaceDir
2652
+ });
2653
+ return;
2654
+ }
2655
+ if (stat.isDirectory()) {
2656
+ const manifest = readPackageManifest(resolved);
2657
+ const extensions = manifest ? resolvePackageExtensions(manifest) : [];
2658
+ if (extensions.length > 0) {
2659
+ for (const extPath of extensions) {
2660
+ const source = resolvePackageEntrySource({
2661
+ packageDir: resolved,
2662
+ entryPath: extPath,
2663
+ sourceLabel: resolved,
2664
+ diagnostics: params.diagnostics
2665
+ });
2666
+ if (!source) continue;
2667
+ addCandidate({
2668
+ candidates: params.candidates,
2669
+ diagnostics: params.diagnostics,
2670
+ seen: params.seen,
2671
+ idHint: deriveIdHint({
2672
+ filePath: source,
2673
+ packageName: manifest?.name,
2674
+ hasMultipleExtensions: extensions.length > 1
2675
+ }),
2676
+ source,
2677
+ rootDir: resolved,
2678
+ origin: params.origin,
2679
+ ownershipUid: params.ownershipUid,
2680
+ workspaceDir: params.workspaceDir,
2681
+ manifest,
2682
+ packageDir: resolved
2683
+ });
2684
+ }
2685
+ return;
2686
+ }
2687
+ const indexFile = [
2688
+ "index.ts",
2689
+ "index.js",
2690
+ "index.mjs",
2691
+ "index.cjs"
2692
+ ].map((candidate) => path.join(resolved, candidate)).find((candidate) => fs.existsSync(candidate));
2693
+ if (indexFile && isExtensionFile(indexFile)) {
2694
+ addCandidate({
2695
+ candidates: params.candidates,
2696
+ diagnostics: params.diagnostics,
2697
+ seen: params.seen,
2698
+ idHint: path.basename(resolved),
2699
+ source: indexFile,
2700
+ rootDir: resolved,
2701
+ origin: params.origin,
2702
+ ownershipUid: params.ownershipUid,
2703
+ workspaceDir: params.workspaceDir,
2704
+ manifest,
2705
+ packageDir: resolved
2706
+ });
2707
+ return;
2708
+ }
2709
+ discoverInDirectory({
2710
+ dir: resolved,
2711
+ origin: params.origin,
2712
+ ownershipUid: params.ownershipUid,
2713
+ workspaceDir: params.workspaceDir,
2714
+ candidates: params.candidates,
2715
+ diagnostics: params.diagnostics,
2716
+ seen: params.seen
2717
+ });
2718
+ return;
2719
+ }
2720
+ }
2721
+ function discoverRemoteClawPlugins(params) {
2722
+ const candidates = [];
2723
+ const diagnostics = [];
2724
+ const seen = /* @__PURE__ */ new Set();
2725
+ const workspaceDir = params.workspaceDir?.trim();
2726
+ const extra = params.extraPaths ?? [];
2727
+ for (const extraPath of extra) {
2728
+ if (typeof extraPath !== "string") continue;
2729
+ const trimmed = extraPath.trim();
2730
+ if (!trimmed) continue;
2731
+ discoverFromPath({
2732
+ rawPath: trimmed,
2733
+ origin: "config",
2734
+ ownershipUid: params.ownershipUid,
2735
+ workspaceDir: workspaceDir?.trim() || void 0,
2736
+ candidates,
2737
+ diagnostics,
2738
+ seen
2739
+ });
2740
+ }
2741
+ if (workspaceDir) {
2742
+ const workspaceRoot = resolveUserPath(workspaceDir);
2743
+ const workspaceExtDirs = [path.join(workspaceRoot, ".remoteclaw", "extensions")];
2744
+ for (const dir of workspaceExtDirs) discoverInDirectory({
2745
+ dir,
2746
+ origin: "workspace",
2747
+ ownershipUid: params.ownershipUid,
2748
+ workspaceDir: workspaceRoot,
2749
+ candidates,
2750
+ diagnostics,
2751
+ seen
2752
+ });
2753
+ }
2754
+ discoverInDirectory({
2755
+ dir: path.join(resolveConfigDir(), "extensions"),
2756
+ origin: "global",
2757
+ ownershipUid: params.ownershipUid,
2758
+ candidates,
2759
+ diagnostics,
2760
+ seen
2761
+ });
2762
+ const bundledDir = resolveBundledPluginsDir();
2763
+ if (bundledDir) discoverInDirectory({
2764
+ dir: bundledDir,
2765
+ origin: "bundled",
2766
+ ownershipUid: params.ownershipUid,
2767
+ candidates,
2768
+ diagnostics,
2769
+ seen
2770
+ });
2771
+ return {
2772
+ candidates,
2773
+ diagnostics
2774
+ };
2775
+ }
2776
+
2777
+ //#endregion
2778
+ //#region src/plugins/manifest-registry.ts
2779
+ const PLUGIN_ORIGIN_RANK = {
2780
+ config: 0,
2781
+ workspace: 1,
2782
+ global: 2,
2783
+ bundled: 3
2784
+ };
2785
+ const registryCache = /* @__PURE__ */ new Map();
2786
+ const DEFAULT_MANIFEST_CACHE_MS = 200;
2787
+ function clearPluginManifestRegistryCache() {
2788
+ registryCache.clear();
2789
+ }
2790
+ function resolveManifestCacheMs(env) {
2791
+ const raw = env.REMOTECLAW_PLUGIN_MANIFEST_CACHE_MS?.trim();
2792
+ if (raw === "" || raw === "0") return 0;
2793
+ if (!raw) return DEFAULT_MANIFEST_CACHE_MS;
2794
+ const parsed = Number.parseInt(raw, 10);
2795
+ if (!Number.isFinite(parsed)) return DEFAULT_MANIFEST_CACHE_MS;
2796
+ return Math.max(0, parsed);
2797
+ }
2798
+ function shouldUseManifestCache(env) {
2799
+ if (env.REMOTECLAW_DISABLE_PLUGIN_MANIFEST_CACHE?.trim()) return false;
2800
+ return resolveManifestCacheMs(env) > 0;
2801
+ }
2802
+ function buildCacheKey(params) {
2803
+ const workspaceKey = params.workspaceDir ? resolveUserPath(params.workspaceDir) : "";
2804
+ const loadPaths = params.plugins.loadPaths.map((p) => resolveUserPath(p)).map((p) => p.trim()).filter(Boolean).toSorted();
2805
+ return `${workspaceKey}::${JSON.stringify(loadPaths)}`;
2806
+ }
2807
+ function safeStatMtimeMs(filePath) {
2808
+ try {
2809
+ return fs.statSync(filePath).mtimeMs;
2810
+ } catch {
2811
+ return null;
2812
+ }
2813
+ }
2814
+ function normalizeManifestLabel(raw) {
2815
+ const trimmed = raw?.trim();
2816
+ return trimmed ? trimmed : void 0;
2817
+ }
2818
+ function buildRecord(params) {
2819
+ return {
2820
+ id: params.manifest.id,
2821
+ name: normalizeManifestLabel(params.manifest.name) ?? params.candidate.packageName,
2822
+ description: normalizeManifestLabel(params.manifest.description) ?? params.candidate.packageDescription,
2823
+ version: normalizeManifestLabel(params.manifest.version) ?? params.candidate.packageVersion,
2824
+ kind: params.manifest.kind,
2825
+ channels: params.manifest.channels ?? [],
2826
+ providers: params.manifest.providers ?? [],
2827
+ skills: params.manifest.skills ?? [],
2828
+ stt: params.manifest.stt ?? [],
2829
+ tts: params.manifest.tts ?? [],
2830
+ origin: params.candidate.origin,
2831
+ workspaceDir: params.candidate.workspaceDir,
2832
+ rootDir: params.candidate.rootDir,
2833
+ source: params.candidate.source,
2834
+ manifestPath: params.manifestPath,
2835
+ schemaCacheKey: params.schemaCacheKey,
2836
+ configSchema: params.configSchema,
2837
+ configUiHints: params.manifest.uiHints
2838
+ };
2839
+ }
2840
+ function loadPluginManifestRegistry(params) {
2841
+ const normalized = normalizePluginsConfig((params.config ?? {}).plugins);
2842
+ const cacheKey = buildCacheKey({
2843
+ workspaceDir: params.workspaceDir,
2844
+ plugins: normalized
2845
+ });
2846
+ const env = params.env ?? process.env;
2847
+ const cacheEnabled = params.cache !== false && shouldUseManifestCache(env);
2848
+ if (cacheEnabled) {
2849
+ const cached = registryCache.get(cacheKey);
2850
+ if (cached && cached.expiresAt > Date.now()) return cached.registry;
2851
+ }
2852
+ const discovery = params.candidates ? {
2853
+ candidates: params.candidates,
2854
+ diagnostics: params.diagnostics ?? []
2855
+ } : discoverRemoteClawPlugins({
2856
+ workspaceDir: params.workspaceDir,
2857
+ extraPaths: normalized.loadPaths
2858
+ });
2859
+ const diagnostics = [...discovery.diagnostics];
2860
+ const candidates = discovery.candidates;
2861
+ const records = [];
2862
+ const seenIds = /* @__PURE__ */ new Map();
2863
+ const realpathCache = /* @__PURE__ */ new Map();
2864
+ for (const candidate of candidates) {
2865
+ const manifestRes = loadPluginManifest(candidate.rootDir);
2866
+ if (!manifestRes.ok) {
2867
+ diagnostics.push({
2868
+ level: "error",
2869
+ message: manifestRes.error,
2870
+ source: manifestRes.manifestPath
2871
+ });
2872
+ continue;
2873
+ }
2874
+ const manifest = manifestRes.manifest;
2875
+ if (candidate.idHint && candidate.idHint !== manifest.id) diagnostics.push({
2876
+ level: "warn",
2877
+ pluginId: manifest.id,
2878
+ source: candidate.source,
2879
+ message: `plugin id mismatch (manifest uses "${manifest.id}", entry hints "${candidate.idHint}")`
2880
+ });
2881
+ const configSchema = manifest.configSchema;
2882
+ const manifestMtime = safeStatMtimeMs(manifestRes.manifestPath);
2883
+ const schemaCacheKey = manifestMtime ? `${manifestRes.manifestPath}:${manifestMtime}` : manifestRes.manifestPath;
2884
+ const existing = seenIds.get(manifest.id);
2885
+ if (existing) {
2886
+ const existingReal = safeRealpathSync(existing.candidate.rootDir, realpathCache);
2887
+ const candidateReal = safeRealpathSync(candidate.rootDir, realpathCache);
2888
+ if (Boolean(existingReal && candidateReal && existingReal === candidateReal)) {
2889
+ if (PLUGIN_ORIGIN_RANK[candidate.origin] < PLUGIN_ORIGIN_RANK[existing.candidate.origin]) {
2890
+ records[existing.recordIndex] = buildRecord({
2891
+ manifest,
2892
+ candidate,
2893
+ manifestPath: manifestRes.manifestPath,
2894
+ schemaCacheKey,
2895
+ configSchema
2896
+ });
2897
+ seenIds.set(manifest.id, {
2898
+ candidate,
2899
+ recordIndex: existing.recordIndex
2900
+ });
2901
+ }
2902
+ continue;
2903
+ }
2904
+ diagnostics.push({
2905
+ level: "warn",
2906
+ pluginId: manifest.id,
2907
+ source: candidate.source,
2908
+ message: `duplicate plugin id detected; later plugin may be overridden (${candidate.source})`
2909
+ });
2910
+ } else seenIds.set(manifest.id, {
2911
+ candidate,
2912
+ recordIndex: records.length
2913
+ });
2914
+ records.push(buildRecord({
2915
+ manifest,
2916
+ candidate,
2917
+ manifestPath: manifestRes.manifestPath,
2918
+ schemaCacheKey,
2919
+ configSchema
2920
+ }));
2921
+ }
2922
+ const registry = {
2923
+ plugins: records,
2924
+ diagnostics
2925
+ };
2926
+ if (cacheEnabled) {
2927
+ const ttl = resolveManifestCacheMs(env);
2928
+ if (ttl > 0) registryCache.set(cacheKey, {
2929
+ expiresAt: Date.now() + ttl,
2930
+ registry
2931
+ });
2932
+ }
2933
+ return registry;
2934
+ }
2935
+
2936
+ //#endregion
2937
+ //#region src/plugins/schema-validator.ts
2938
+ const ajv = new AjvPkg({
2939
+ allErrors: true,
2940
+ strict: false,
2941
+ removeAdditional: false
2942
+ });
2943
+ const schemaCache = /* @__PURE__ */ new Map();
2944
+ function formatAjvErrors(errors) {
2945
+ if (!errors || errors.length === 0) return ["invalid config"];
2946
+ return errors.map((error) => {
2947
+ return `${error.instancePath?.replace(/^\//, "").replace(/\//g, ".") || "<root>"}: ${error.message ?? "invalid"}`;
2948
+ });
2949
+ }
2950
+ function validateJsonSchemaValue(params) {
2951
+ let cached = schemaCache.get(params.cacheKey);
2952
+ if (!cached || cached.schema !== params.schema) {
2953
+ cached = {
2954
+ validate: ajv.compile(params.schema),
2955
+ schema: params.schema
2956
+ };
2957
+ schemaCache.set(params.cacheKey, cached);
2958
+ }
2959
+ if (cached.validate(params.value)) return { ok: true };
2960
+ return {
2961
+ ok: false,
2962
+ errors: formatAjvErrors(cached.validate.errors)
2963
+ };
2964
+ }
2965
+
2966
+ //#endregion
2967
+ //#region src/shared/avatar-policy.ts
2968
+ const AVATAR_MAX_BYTES = 2 * 1024 * 1024;
2969
+ const LOCAL_AVATAR_EXTENSIONS = new Set([
2970
+ ".png",
2971
+ ".jpg",
2972
+ ".jpeg",
2973
+ ".gif",
2974
+ ".webp",
2975
+ ".svg"
2976
+ ]);
2977
+ const AVATAR_MIME_BY_EXT = {
2978
+ ".png": "image/png",
2979
+ ".jpg": "image/jpeg",
2980
+ ".jpeg": "image/jpeg",
2981
+ ".webp": "image/webp",
2982
+ ".gif": "image/gif",
2983
+ ".svg": "image/svg+xml",
2984
+ ".bmp": "image/bmp",
2985
+ ".tif": "image/tiff",
2986
+ ".tiff": "image/tiff"
2987
+ };
2988
+ const AVATAR_DATA_RE = /^data:/i;
2989
+ const AVATAR_IMAGE_DATA_RE = /^data:image\//i;
2990
+ const AVATAR_HTTP_RE = /^https?:\/\//i;
2991
+ const AVATAR_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
2992
+ const WINDOWS_ABS_RE = /^[a-zA-Z]:[\\/]/;
2993
+ const AVATAR_PATH_EXT_RE = /\.(png|jpe?g|gif|webp|svg|ico)$/i;
2994
+ function resolveAvatarMime(filePath) {
2995
+ return AVATAR_MIME_BY_EXT[path.extname(filePath).toLowerCase()] ?? "application/octet-stream";
2996
+ }
2997
+ function isAvatarDataUrl(value) {
2998
+ return AVATAR_DATA_RE.test(value);
2999
+ }
3000
+ function isAvatarImageDataUrl(value) {
3001
+ return AVATAR_IMAGE_DATA_RE.test(value);
3002
+ }
3003
+ function isAvatarHttpUrl(value) {
3004
+ return AVATAR_HTTP_RE.test(value);
3005
+ }
3006
+ function hasAvatarUriScheme(value) {
3007
+ return AVATAR_SCHEME_RE.test(value);
3008
+ }
3009
+ function isWindowsAbsolutePath(value) {
3010
+ return WINDOWS_ABS_RE.test(value);
3011
+ }
3012
+ function isWorkspaceRelativeAvatarPath(value) {
3013
+ if (!value) return false;
3014
+ if (value.startsWith("~")) return false;
3015
+ if (hasAvatarUriScheme(value) && !isWindowsAbsolutePath(value)) return false;
3016
+ return true;
3017
+ }
3018
+ function isPathWithinRoot(rootDir, targetPath) {
3019
+ const relative = path.relative(rootDir, targetPath);
3020
+ if (relative === "") return true;
3021
+ return !relative.startsWith("..") && !path.isAbsolute(relative);
3022
+ }
3023
+ function looksLikeAvatarPath(value) {
3024
+ if (/[\\/]/.test(value)) return true;
3025
+ return AVATAR_PATH_EXT_RE.test(value);
3026
+ }
3027
+ function isSupportedLocalAvatarExtension(filePath) {
3028
+ const ext = path.extname(filePath).toLowerCase();
3029
+ return LOCAL_AVATAR_EXTENSIONS.has(ext);
3030
+ }
3031
+
3032
+ //#endregion
3033
+ //#region src/config/validation.ts
3034
+ const LEGACY_REMOVED_PLUGIN_IDS = new Set(["google-antigravity-auth"]);
3035
+ function isWorkspaceAvatarPath(value, workspaceDir) {
3036
+ const workspaceRoot = path.resolve(workspaceDir);
3037
+ return isPathWithinRoot(workspaceRoot, path.resolve(workspaceRoot, value));
3038
+ }
3039
+ function validateIdentityAvatar(config) {
3040
+ const agents = config.agents?.list;
3041
+ if (!Array.isArray(agents) || agents.length === 0) return [];
3042
+ const issues = [];
3043
+ for (const [index, entry] of agents.entries()) {
3044
+ if (!entry || typeof entry !== "object") continue;
3045
+ const avatarRaw = entry.identity?.avatar;
3046
+ if (typeof avatarRaw !== "string") continue;
3047
+ const avatar = avatarRaw.trim();
3048
+ if (!avatar) continue;
3049
+ if (isAvatarDataUrl(avatar) || isAvatarHttpUrl(avatar)) continue;
3050
+ if (avatar.startsWith("~")) {
3051
+ issues.push({
3052
+ path: `agents.list.${index}.identity.avatar`,
3053
+ message: "identity.avatar must be a workspace-relative path, http(s) URL, or data URI."
3054
+ });
3055
+ continue;
3056
+ }
3057
+ if (hasAvatarUriScheme(avatar) && !isWindowsAbsolutePath(avatar)) {
3058
+ issues.push({
3059
+ path: `agents.list.${index}.identity.avatar`,
3060
+ message: "identity.avatar must be a workspace-relative path, http(s) URL, or data URI."
3061
+ });
3062
+ continue;
3063
+ }
3064
+ const workspaceDir = resolveAgentWorkspaceDirOrNull(config, entry.id ?? resolveDefaultAgentId(config));
3065
+ if (workspaceDir != null && !isWorkspaceAvatarPath(avatar, workspaceDir)) issues.push({
3066
+ path: `agents.list.${index}.identity.avatar`,
3067
+ message: "identity.avatar must stay within the agent workspace."
3068
+ });
3069
+ }
3070
+ return issues;
3071
+ }
3072
+ /**
3073
+ * Validates config without applying runtime defaults.
3074
+ * Use this when you need the raw validated config (e.g., for writing back to file).
3075
+ */
3076
+ function validateConfigObjectRaw(raw) {
3077
+ const legacyIssues = findLegacyConfigIssues(raw);
3078
+ if (legacyIssues.length > 0) return {
3079
+ ok: false,
3080
+ issues: legacyIssues.map((iss) => ({
3081
+ path: iss.path,
3082
+ message: iss.message
3083
+ }))
3084
+ };
3085
+ const validated = RemoteClawSchema.safeParse(raw);
3086
+ if (!validated.success) return {
3087
+ ok: false,
3088
+ issues: validated.error.issues.map((iss) => ({
3089
+ path: iss.path.join("."),
3090
+ message: iss.message
3091
+ }))
3092
+ };
3093
+ const duplicates = findDuplicateAgentDirs(validated.data);
3094
+ if (duplicates.length > 0) return {
3095
+ ok: false,
3096
+ issues: [{
3097
+ path: "agents.list",
3098
+ message: formatDuplicateAgentDirError(duplicates)
3099
+ }]
3100
+ };
3101
+ const avatarIssues = validateIdentityAvatar(validated.data);
3102
+ if (avatarIssues.length > 0) return {
3103
+ ok: false,
3104
+ issues: avatarIssues
3105
+ };
3106
+ return {
3107
+ ok: true,
3108
+ config: validated.data
3109
+ };
3110
+ }
3111
+ function validateConfigObject(raw) {
3112
+ const result = validateConfigObjectRaw(raw);
3113
+ if (!result.ok) return result;
3114
+ return {
3115
+ ok: true,
3116
+ config: applyModelDefaults(applyAgentDefaults(applySessionDefaults(result.config)))
3117
+ };
3118
+ }
3119
+ function validateConfigObjectWithPlugins(raw) {
3120
+ return validateConfigObjectWithPluginsBase(raw, { applyDefaults: true });
3121
+ }
3122
+ function validateConfigObjectRawWithPlugins(raw) {
3123
+ return validateConfigObjectWithPluginsBase(raw, { applyDefaults: false });
3124
+ }
3125
+ function validateConfigObjectWithPluginsBase(raw, opts) {
3126
+ const base = opts.applyDefaults ? validateConfigObject(raw) : validateConfigObjectRaw(raw);
3127
+ if (!base.ok) return {
3128
+ ok: false,
3129
+ issues: base.issues,
3130
+ warnings: []
3131
+ };
3132
+ const config = base.config;
3133
+ const issues = [];
3134
+ const warnings = [];
3135
+ const hasExplicitPluginsConfig = isRecord(raw) && Object.prototype.hasOwnProperty.call(raw, "plugins");
3136
+ let registryInfo = null;
3137
+ const ensureRegistry = () => {
3138
+ if (registryInfo) return registryInfo;
3139
+ const registry = loadPluginManifestRegistry({
3140
+ config,
3141
+ workspaceDir: resolveAgentWorkspaceDirOrNull(config, resolveDefaultAgentId(config)) ?? void 0
3142
+ });
3143
+ const knownIds = new Set(registry.plugins.map((record) => record.id));
3144
+ const normalizedPlugins = normalizePluginsConfig(config.plugins);
3145
+ for (const diag of registry.diagnostics) {
3146
+ let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
3147
+ if (!diag.pluginId && diag.message.includes("plugin path not found")) path = "plugins.load.paths";
3148
+ const message = `${diag.pluginId ? `plugin ${diag.pluginId}` : "plugin"}: ${diag.message}`;
3149
+ if (diag.level === "error") issues.push({
3150
+ path,
3151
+ message
3152
+ });
3153
+ else warnings.push({
3154
+ path,
3155
+ message
3156
+ });
3157
+ }
3158
+ registryInfo = {
3159
+ registry,
3160
+ knownIds,
3161
+ normalizedPlugins
3162
+ };
3163
+ return registryInfo;
3164
+ };
3165
+ const allowedChannels = new Set([
3166
+ "defaults",
3167
+ "modelByChannel",
3168
+ ...CHANNEL_IDS
3169
+ ]);
3170
+ if (config.channels && isRecord(config.channels)) for (const key of Object.keys(config.channels)) {
3171
+ const trimmed = key.trim();
3172
+ if (!trimmed) continue;
3173
+ if (!allowedChannels.has(trimmed)) {
3174
+ const { registry } = ensureRegistry();
3175
+ for (const record of registry.plugins) for (const channelId of record.channels) allowedChannels.add(channelId);
3176
+ }
3177
+ if (!allowedChannels.has(trimmed)) issues.push({
3178
+ path: `channels.${trimmed}`,
3179
+ message: `unknown channel id: ${trimmed}`
3180
+ });
3181
+ }
3182
+ const heartbeatChannelIds = /* @__PURE__ */ new Set();
3183
+ for (const channelId of CHANNEL_IDS) heartbeatChannelIds.add(channelId.toLowerCase());
3184
+ const validateHeartbeatTarget = (target, path) => {
3185
+ if (typeof target !== "string") return;
3186
+ const trimmed = target.trim();
3187
+ if (!trimmed) {
3188
+ issues.push({
3189
+ path,
3190
+ message: "heartbeat target must not be empty"
3191
+ });
3192
+ return;
3193
+ }
3194
+ const normalized = trimmed.toLowerCase();
3195
+ if (normalized === "last" || normalized === "none") return;
3196
+ if (normalizeChatChannelId(trimmed)) return;
3197
+ if (!heartbeatChannelIds.has(normalized)) {
3198
+ const { registry } = ensureRegistry();
3199
+ for (const record of registry.plugins) for (const channelId of record.channels) {
3200
+ const pluginChannel = channelId.trim();
3201
+ if (pluginChannel) heartbeatChannelIds.add(pluginChannel.toLowerCase());
3202
+ }
3203
+ }
3204
+ if (heartbeatChannelIds.has(normalized)) return;
3205
+ issues.push({
3206
+ path,
3207
+ message: `unknown heartbeat target: ${target}`
3208
+ });
3209
+ };
3210
+ validateHeartbeatTarget(config.agents?.defaults?.heartbeat?.target, "agents.defaults.heartbeat.target");
3211
+ if (Array.isArray(config.agents?.list)) for (const [index, entry] of config.agents.list.entries()) validateHeartbeatTarget(entry?.heartbeat?.target, `agents.list.${index}.heartbeat.target`);
3212
+ if (!hasExplicitPluginsConfig) {
3213
+ if (issues.length > 0) return {
3214
+ ok: false,
3215
+ issues,
3216
+ warnings
3217
+ };
3218
+ return {
3219
+ ok: true,
3220
+ config,
3221
+ warnings
3222
+ };
3223
+ }
3224
+ const { registry, knownIds, normalizedPlugins } = ensureRegistry();
3225
+ const pushMissingPluginIssue = (path, pluginId) => {
3226
+ if (LEGACY_REMOVED_PLUGIN_IDS.has(pluginId)) {
3227
+ warnings.push({
3228
+ path,
3229
+ message: `plugin removed: ${pluginId} (stale config entry ignored; remove it from plugins config)`
3230
+ });
3231
+ return;
3232
+ }
3233
+ issues.push({
3234
+ path,
3235
+ message: `plugin not found: ${pluginId}`
3236
+ });
3237
+ };
3238
+ const pluginsConfig = config.plugins;
3239
+ const entries = pluginsConfig?.entries;
3240
+ if (entries && isRecord(entries)) {
3241
+ for (const pluginId of Object.keys(entries)) if (!knownIds.has(pluginId)) pushMissingPluginIssue(`plugins.entries.${pluginId}`, pluginId);
3242
+ }
3243
+ const allow = pluginsConfig?.allow ?? [];
3244
+ for (const pluginId of allow) {
3245
+ if (typeof pluginId !== "string" || !pluginId.trim()) continue;
3246
+ if (!knownIds.has(pluginId)) pushMissingPluginIssue("plugins.allow", pluginId);
3247
+ }
3248
+ const deny = pluginsConfig?.deny ?? [];
3249
+ for (const pluginId of deny) {
3250
+ if (typeof pluginId !== "string" || !pluginId.trim()) continue;
3251
+ if (!knownIds.has(pluginId)) pushMissingPluginIssue("plugins.deny", pluginId);
3252
+ }
3253
+ const seenPlugins = /* @__PURE__ */ new Set();
3254
+ for (const record of registry.plugins) {
3255
+ const pluginId = record.id;
3256
+ if (seenPlugins.has(pluginId)) continue;
3257
+ seenPlugins.add(pluginId);
3258
+ const entry = normalizedPlugins.entries[pluginId];
3259
+ const entryHasConfig = Boolean(entry?.config);
3260
+ const enableState = resolveEffectiveEnableState({
3261
+ id: pluginId,
3262
+ origin: record.origin,
3263
+ config: normalizedPlugins,
3264
+ rootConfig: config
3265
+ });
3266
+ let enabled = enableState.enabled;
3267
+ let reason = enableState.reason;
3268
+ if (enabled || entryHasConfig) if (record.configSchema) {
3269
+ const res = validateJsonSchemaValue({
3270
+ schema: record.configSchema,
3271
+ cacheKey: record.schemaCacheKey ?? record.manifestPath ?? pluginId,
3272
+ value: entry?.config ?? {}
3273
+ });
3274
+ if (!res.ok) for (const error of res.errors) issues.push({
3275
+ path: `plugins.entries.${pluginId}.config`,
3276
+ message: `invalid config: ${error}`
3277
+ });
3278
+ } else issues.push({
3279
+ path: `plugins.entries.${pluginId}`,
3280
+ message: `plugin schema missing for ${pluginId}`
3281
+ });
3282
+ if (!enabled && entryHasConfig) warnings.push({
3283
+ path: `plugins.entries.${pluginId}`,
3284
+ message: `plugin disabled (${reason ?? "disabled"}) but config is present`
3285
+ });
3286
+ }
3287
+ if (issues.length > 0) return {
3288
+ ok: false,
3289
+ issues,
3290
+ warnings
3291
+ };
3292
+ return {
3293
+ ok: true,
3294
+ config,
3295
+ warnings
3296
+ };
3297
+ }
3298
+
3299
+ //#endregion
3300
+ //#region src/config/version.ts
3301
+ const VERSION_RE = /^v?(\d+)\.(\d+)\.(\d+)(?:-(\d+))?/;
3302
+ function parseRemoteClawVersion(raw) {
3303
+ if (!raw) return null;
3304
+ const match = raw.trim().match(VERSION_RE);
3305
+ if (!match) return null;
3306
+ const [, major, minor, patch, revision] = match;
3307
+ return {
3308
+ major: Number.parseInt(major, 10),
3309
+ minor: Number.parseInt(minor, 10),
3310
+ patch: Number.parseInt(patch, 10),
3311
+ revision: revision ? Number.parseInt(revision, 10) : 0
3312
+ };
3313
+ }
3314
+ function compareRemoteClawVersions(a, b) {
3315
+ const parsedA = parseRemoteClawVersion(a);
3316
+ const parsedB = parseRemoteClawVersion(b);
3317
+ if (!parsedA || !parsedB) return null;
3318
+ if (parsedA.major !== parsedB.major) return parsedA.major < parsedB.major ? -1 : 1;
3319
+ if (parsedA.minor !== parsedB.minor) return parsedA.minor < parsedB.minor ? -1 : 1;
3320
+ if (parsedA.patch !== parsedB.patch) return parsedA.patch < parsedB.patch ? -1 : 1;
3321
+ if (parsedA.revision !== parsedB.revision) return parsedA.revision < parsedB.revision ? -1 : 1;
3322
+ return 0;
3323
+ }
3324
+
3325
+ //#endregion
3326
+ //#region src/config/io.ts
3327
+ const SHELL_ENV_EXPECTED_KEYS = [
3328
+ "OPENAI_API_KEY",
3329
+ "ANTHROPIC_API_KEY",
3330
+ "ANTHROPIC_OAUTH_TOKEN",
3331
+ "GEMINI_API_KEY",
3332
+ "ZAI_API_KEY",
3333
+ "OPENROUTER_API_KEY",
3334
+ "AI_GATEWAY_API_KEY",
3335
+ "MINIMAX_API_KEY",
3336
+ "SYNTHETIC_API_KEY",
3337
+ "KILOCODE_API_KEY",
3338
+ "ELEVENLABS_API_KEY",
3339
+ "TELEGRAM_BOT_TOKEN",
3340
+ "DISCORD_BOT_TOKEN",
3341
+ "SLACK_BOT_TOKEN",
3342
+ "SLACK_APP_TOKEN",
3343
+ "REMOTECLAW_GATEWAY_TOKEN",
3344
+ "REMOTECLAW_GATEWAY_PASSWORD"
3345
+ ];
3346
+ const OPEN_DM_POLICY_ALLOW_FROM_RE = /^(?<policyPath>[a-z0-9_.-]+)\s*=\s*"open"\s+requires\s+(?<allowPath>[a-z0-9_.-]+)(?:\s+\(or\s+[a-z0-9_.-]+\))?\s+to include "\*"$/i;
3347
+ const CONFIG_AUDIT_LOG_FILENAME = "config-audit.jsonl";
3348
+ const loggedInvalidConfigs = /* @__PURE__ */ new Set();
3349
+ function hashConfigRaw(raw) {
3350
+ return crypto.createHash("sha256").update(raw ?? "").digest("hex");
3351
+ }
3352
+ function formatConfigValidationFailure(pathLabel, issueMessage) {
3353
+ const match = issueMessage.match(OPEN_DM_POLICY_ALLOW_FROM_RE);
3354
+ const policyPath = match?.groups?.policyPath?.trim();
3355
+ const allowPath = match?.groups?.allowPath?.trim();
3356
+ if (!policyPath || !allowPath) return `Config validation failed: ${pathLabel}: ${issueMessage}`;
3357
+ return [
3358
+ `Config validation failed: ${pathLabel}`,
3359
+ "",
3360
+ `Configuration mismatch: ${policyPath} is "open", but ${allowPath} does not include "*".`,
3361
+ "",
3362
+ "Fix with:",
3363
+ ` remoteclaw config set ${allowPath} '["*"]'`,
3364
+ "",
3365
+ "Or switch policy:",
3366
+ ` remoteclaw config set ${policyPath} "pairing"`
3367
+ ].join("\n");
3368
+ }
3369
+ function isNumericPathSegment(raw) {
3370
+ return /^[0-9]+$/.test(raw);
3371
+ }
3372
+ function isWritePlainObject(value) {
3373
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3374
+ }
3375
+ function hasOwnObjectKey(value, key) {
3376
+ return Object.prototype.hasOwnProperty.call(value, key);
3377
+ }
3378
+ const WRITE_PRUNED_OBJECT = Symbol("write-pruned-object");
3379
+ function unsetPathForWriteAt(value, pathSegments, depth) {
3380
+ if (depth >= pathSegments.length) return {
3381
+ changed: false,
3382
+ value
3383
+ };
3384
+ const segment = pathSegments[depth];
3385
+ const isLeaf = depth === pathSegments.length - 1;
3386
+ if (Array.isArray(value)) {
3387
+ if (!isNumericPathSegment(segment)) return {
3388
+ changed: false,
3389
+ value
3390
+ };
3391
+ const index = Number.parseInt(segment, 10);
3392
+ if (!Number.isFinite(index) || index < 0 || index >= value.length) return {
3393
+ changed: false,
3394
+ value
3395
+ };
3396
+ if (isLeaf) {
3397
+ const next = value.slice();
3398
+ next.splice(index, 1);
3399
+ return {
3400
+ changed: true,
3401
+ value: next
3402
+ };
3403
+ }
3404
+ const child = unsetPathForWriteAt(value[index], pathSegments, depth + 1);
3405
+ if (!child.changed) return {
3406
+ changed: false,
3407
+ value
3408
+ };
3409
+ const next = value.slice();
3410
+ if (child.value === WRITE_PRUNED_OBJECT) next.splice(index, 1);
3411
+ else next[index] = child.value;
3412
+ return {
3413
+ changed: true,
3414
+ value: next
3415
+ };
3416
+ }
3417
+ if (isBlockedObjectKey(segment) || !isWritePlainObject(value) || !hasOwnObjectKey(value, segment)) return {
3418
+ changed: false,
3419
+ value
3420
+ };
3421
+ if (isLeaf) {
3422
+ const next = { ...value };
3423
+ delete next[segment];
3424
+ return {
3425
+ changed: true,
3426
+ value: Object.keys(next).length === 0 ? WRITE_PRUNED_OBJECT : next
3427
+ };
3428
+ }
3429
+ const child = unsetPathForWriteAt(value[segment], pathSegments, depth + 1);
3430
+ if (!child.changed) return {
3431
+ changed: false,
3432
+ value
3433
+ };
3434
+ const next = { ...value };
3435
+ if (child.value === WRITE_PRUNED_OBJECT) delete next[segment];
3436
+ else next[segment] = child.value;
3437
+ return {
3438
+ changed: true,
3439
+ value: Object.keys(next).length === 0 ? WRITE_PRUNED_OBJECT : next
3440
+ };
3441
+ }
3442
+ function unsetPathForWrite(root, pathSegments) {
3443
+ if (pathSegments.length === 0) return {
3444
+ changed: false,
3445
+ next: root
3446
+ };
3447
+ const result = unsetPathForWriteAt(root, pathSegments, 0);
3448
+ if (!result.changed) return {
3449
+ changed: false,
3450
+ next: root
3451
+ };
3452
+ if (result.value === WRITE_PRUNED_OBJECT) return {
3453
+ changed: true,
3454
+ next: {}
3455
+ };
3456
+ if (isWritePlainObject(result.value)) return {
3457
+ changed: true,
3458
+ next: coerceConfig(result.value)
3459
+ };
3460
+ return {
3461
+ changed: false,
3462
+ next: root
3463
+ };
3464
+ }
3465
+ function resolveConfigSnapshotHash(snapshot) {
3466
+ if (typeof snapshot.hash === "string") {
3467
+ const trimmed = snapshot.hash.trim();
3468
+ if (trimmed) return trimmed;
3469
+ }
3470
+ if (typeof snapshot.raw !== "string") return null;
3471
+ return hashConfigRaw(snapshot.raw);
3472
+ }
3473
+ function coerceConfig(value) {
3474
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
3475
+ return value;
3476
+ }
3477
+ function isPlainObject(value) {
3478
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3479
+ }
3480
+ function hasConfigMeta(value) {
3481
+ if (!isPlainObject(value)) return false;
3482
+ const meta = value.meta;
3483
+ return isPlainObject(meta);
3484
+ }
3485
+ function resolveGatewayMode(value) {
3486
+ if (!isPlainObject(value)) return null;
3487
+ const gateway = value.gateway;
3488
+ if (!isPlainObject(gateway) || typeof gateway.mode !== "string") return null;
3489
+ const trimmed = gateway.mode.trim();
3490
+ return trimmed.length > 0 ? trimmed : null;
3491
+ }
3492
+ function cloneUnknown(value) {
3493
+ return structuredClone(value);
3494
+ }
3495
+ function createMergePatch(base, target) {
3496
+ if (!isPlainObject(base) || !isPlainObject(target)) return cloneUnknown(target);
3497
+ const patch = {};
3498
+ const keys = new Set([...Object.keys(base), ...Object.keys(target)]);
3499
+ for (const key of keys) {
3500
+ const hasBase = key in base;
3501
+ if (!(key in target)) {
3502
+ patch[key] = null;
3503
+ continue;
3504
+ }
3505
+ const targetValue = target[key];
3506
+ if (!hasBase) {
3507
+ patch[key] = cloneUnknown(targetValue);
3508
+ continue;
3509
+ }
3510
+ const baseValue = base[key];
3511
+ if (isPlainObject(baseValue) && isPlainObject(targetValue)) {
3512
+ const childPatch = createMergePatch(baseValue, targetValue);
3513
+ if (isPlainObject(childPatch) && Object.keys(childPatch).length === 0) continue;
3514
+ patch[key] = childPatch;
3515
+ continue;
3516
+ }
3517
+ if (!isDeepStrictEqual(baseValue, targetValue)) patch[key] = cloneUnknown(targetValue);
3518
+ }
3519
+ return patch;
3520
+ }
3521
+ function collectEnvRefPaths(value, path, output) {
3522
+ if (typeof value === "string") {
3523
+ if (containsEnvVarReference(value)) output.set(path, value);
3524
+ return;
3525
+ }
3526
+ if (Array.isArray(value)) {
3527
+ value.forEach((item, index) => {
3528
+ collectEnvRefPaths(item, `${path}[${index}]`, output);
3529
+ });
3530
+ return;
3531
+ }
3532
+ if (isPlainObject(value)) for (const [key, child] of Object.entries(value)) collectEnvRefPaths(child, path ? `${path}.${key}` : key, output);
3533
+ }
3534
+ function collectChangedPaths(base, target, path, output) {
3535
+ if (Array.isArray(base) && Array.isArray(target)) {
3536
+ const max = Math.max(base.length, target.length);
3537
+ for (let index = 0; index < max; index += 1) {
3538
+ const childPath = path ? `${path}[${index}]` : `[${index}]`;
3539
+ if (index >= base.length || index >= target.length) {
3540
+ output.add(childPath);
3541
+ continue;
3542
+ }
3543
+ collectChangedPaths(base[index], target[index], childPath, output);
3544
+ }
3545
+ return;
3546
+ }
3547
+ if (isPlainObject(base) && isPlainObject(target)) {
3548
+ const keys = new Set([...Object.keys(base), ...Object.keys(target)]);
3549
+ for (const key of keys) {
3550
+ const childPath = path ? `${path}.${key}` : key;
3551
+ const hasBase = key in base;
3552
+ if (!(key in target) || !hasBase) {
3553
+ output.add(childPath);
3554
+ continue;
3555
+ }
3556
+ collectChangedPaths(base[key], target[key], childPath, output);
3557
+ }
3558
+ return;
3559
+ }
3560
+ if (!isDeepStrictEqual(base, target)) output.add(path);
3561
+ }
3562
+ function parentPath(value) {
3563
+ if (!value) return "";
3564
+ if (value.endsWith("]")) {
3565
+ const index = value.lastIndexOf("[");
3566
+ return index > 0 ? value.slice(0, index) : "";
3567
+ }
3568
+ const index = value.lastIndexOf(".");
3569
+ return index >= 0 ? value.slice(0, index) : "";
3570
+ }
3571
+ function isPathChanged(path, changedPaths) {
3572
+ if (changedPaths.has(path)) return true;
3573
+ let current = parentPath(path);
3574
+ while (current) {
3575
+ if (changedPaths.has(current)) return true;
3576
+ current = parentPath(current);
3577
+ }
3578
+ return changedPaths.has("");
3579
+ }
3580
+ function restoreEnvRefsFromMap(value, path, envRefMap, changedPaths) {
3581
+ if (typeof value === "string") {
3582
+ if (!isPathChanged(path, changedPaths)) {
3583
+ const original = envRefMap.get(path);
3584
+ if (original !== void 0) return original;
3585
+ }
3586
+ return value;
3587
+ }
3588
+ if (Array.isArray(value)) {
3589
+ let changed = false;
3590
+ const next = value.map((item, index) => {
3591
+ const updated = restoreEnvRefsFromMap(item, `${path}[${index}]`, envRefMap, changedPaths);
3592
+ if (updated !== item) changed = true;
3593
+ return updated;
3594
+ });
3595
+ return changed ? next : value;
3596
+ }
3597
+ if (isPlainObject(value)) {
3598
+ let changed = false;
3599
+ const next = {};
3600
+ for (const [key, child] of Object.entries(value)) {
3601
+ const updated = restoreEnvRefsFromMap(child, path ? `${path}.${key}` : key, envRefMap, changedPaths);
3602
+ if (updated !== child) changed = true;
3603
+ next[key] = updated;
3604
+ }
3605
+ return changed ? next : value;
3606
+ }
3607
+ return value;
3608
+ }
3609
+ function resolveConfigAuditLogPath(env, homedir) {
3610
+ return path.join(resolveStateDir(env, homedir), "logs", CONFIG_AUDIT_LOG_FILENAME);
3611
+ }
3612
+ function resolveConfigWriteSuspiciousReasons(params) {
3613
+ const reasons = [];
3614
+ if (!params.existsBefore) return reasons;
3615
+ if (typeof params.previousBytes === "number" && typeof params.nextBytes === "number" && params.previousBytes >= 512 && params.nextBytes < Math.floor(params.previousBytes * .5)) reasons.push(`size-drop:${params.previousBytes}->${params.nextBytes}`);
3616
+ if (!params.hasMetaBefore) reasons.push("missing-meta-before-write");
3617
+ if (params.gatewayModeBefore && !params.gatewayModeAfter) reasons.push("gateway-mode-removed");
3618
+ return reasons;
3619
+ }
3620
+ async function appendConfigWriteAuditRecord(deps, record) {
3621
+ try {
3622
+ const auditPath = resolveConfigAuditLogPath(deps.env, deps.homedir);
3623
+ await deps.fs.promises.mkdir(path.dirname(auditPath), {
3624
+ recursive: true,
3625
+ mode: 448
3626
+ });
3627
+ await deps.fs.promises.appendFile(auditPath, `${JSON.stringify(record)}\n`, {
3628
+ encoding: "utf-8",
3629
+ mode: 384
3630
+ });
3631
+ } catch {}
3632
+ }
3633
+ function warnOnConfigMiskeys(raw, logger) {
3634
+ if (!raw || typeof raw !== "object") return;
3635
+ const gateway = raw.gateway;
3636
+ if (!gateway || typeof gateway !== "object") return;
3637
+ if ("token" in gateway) logger.warn("Config uses \"gateway.token\". This key is ignored; use \"gateway.auth.token\" instead.");
3638
+ }
3639
+ function stampConfigVersion(cfg) {
3640
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3641
+ return {
3642
+ ...cfg,
3643
+ meta: {
3644
+ ...cfg.meta,
3645
+ lastTouchedVersion: VERSION,
3646
+ lastTouchedAt: now
3647
+ }
3648
+ };
3649
+ }
3650
+ function warnIfConfigFromFuture(cfg, logger) {
3651
+ const touched = cfg.meta?.lastTouchedVersion;
3652
+ if (!touched) return;
3653
+ const cmp = compareRemoteClawVersions(VERSION, touched);
3654
+ if (cmp === null) return;
3655
+ if (cmp < 0) logger.warn(`Config was last written by a newer RemoteClaw (${touched}); current version is ${VERSION}.`);
3656
+ }
3657
+ function resolveConfigPathForDeps(deps) {
3658
+ if (deps.configPath) return deps.configPath;
3659
+ return resolveConfigPath(deps.env, resolveStateDir(deps.env, deps.homedir));
3660
+ }
3661
+ function normalizeDeps(overrides = {}) {
3662
+ return {
3663
+ fs: overrides.fs ?? fs,
3664
+ json5: overrides.json5 ?? JSON5,
3665
+ env: overrides.env ?? process.env,
3666
+ homedir: overrides.homedir ?? (() => resolveRequiredHomeDir(overrides.env ?? process.env, os.homedir)),
3667
+ configPath: overrides.configPath ?? "",
3668
+ logger: overrides.logger ?? console
3669
+ };
3670
+ }
3671
+ function maybeLoadDotEnvForConfig(env) {
3672
+ if (env !== process.env) return;
3673
+ loadDotEnv({ quiet: true });
3674
+ }
3675
+ function parseConfigJson5(raw, json5 = JSON5) {
3676
+ try {
3677
+ return {
3678
+ ok: true,
3679
+ parsed: json5.parse(raw)
3680
+ };
3681
+ } catch (err) {
3682
+ return {
3683
+ ok: false,
3684
+ error: String(err)
3685
+ };
3686
+ }
3687
+ }
3688
+ function resolveConfigIncludesForRead(parsed, configPath, deps) {
3689
+ return resolveConfigIncludes(parsed, configPath, {
3690
+ readFile: (candidate) => deps.fs.readFileSync(candidate, "utf-8"),
3691
+ parseJson: (raw) => deps.json5.parse(raw)
3692
+ });
3693
+ }
3694
+ function resolveConfigForRead(resolvedIncludes, env) {
3695
+ if (resolvedIncludes && typeof resolvedIncludes === "object" && "env" in resolvedIncludes) applyConfigEnvVars(resolvedIncludes, env);
3696
+ return {
3697
+ resolvedConfigRaw: resolveConfigEnvVars(resolvedIncludes, env),
3698
+ envSnapshotForRestore: { ...env }
3699
+ };
3700
+ }
3701
+ function createConfigIO(overrides = {}) {
3702
+ const deps = normalizeDeps(overrides);
3703
+ const requestedConfigPath = resolveConfigPathForDeps(deps);
3704
+ const configPath = (deps.configPath ? [requestedConfigPath] : resolveDefaultConfigCandidates(deps.env, deps.homedir)).find((candidate) => deps.fs.existsSync(candidate)) ?? requestedConfigPath;
3705
+ function loadConfig() {
3706
+ try {
3707
+ maybeLoadDotEnvForConfig(deps.env);
3708
+ if (!deps.fs.existsSync(configPath)) {
3709
+ if (shouldEnableShellEnvFallback(deps.env) && !shouldDeferShellEnvFallback(deps.env)) loadShellEnvFallback({
3710
+ enabled: true,
3711
+ env: deps.env,
3712
+ expectedKeys: SHELL_ENV_EXPECTED_KEYS,
3713
+ logger: deps.logger,
3714
+ timeoutMs: resolveShellEnvFallbackTimeoutMs(deps.env)
3715
+ });
3716
+ return {};
3717
+ }
3718
+ const raw = deps.fs.readFileSync(configPath, "utf-8");
3719
+ const { resolvedConfigRaw: resolvedConfig } = resolveConfigForRead(resolveConfigIncludesForRead(deps.json5.parse(raw), configPath, deps), deps.env);
3720
+ warnOnConfigMiskeys(resolvedConfig, deps.logger);
3721
+ if (typeof resolvedConfig !== "object" || resolvedConfig === null) return {};
3722
+ const preValidationDuplicates = findDuplicateAgentDirs(resolvedConfig, {
3723
+ env: deps.env,
3724
+ homedir: deps.homedir
3725
+ });
3726
+ if (preValidationDuplicates.length > 0) throw new DuplicateAgentDirError(preValidationDuplicates);
3727
+ const validated = validateConfigObjectWithPlugins(resolvedConfig);
3728
+ if (!validated.ok) {
3729
+ const details = validated.issues.map((iss) => `- ${iss.path || "<root>"}: ${iss.message}`).join("\n");
3730
+ if (!loggedInvalidConfigs.has(configPath)) {
3731
+ loggedInvalidConfigs.add(configPath);
3732
+ deps.logger.error(`Invalid config at ${configPath}:\\n${details}`);
3733
+ }
3734
+ const error = /* @__PURE__ */ new Error("Invalid config");
3735
+ error.code = "INVALID_CONFIG";
3736
+ error.details = details;
3737
+ throw error;
3738
+ }
3739
+ if (validated.warnings.length > 0) {
3740
+ const details = validated.warnings.map((iss) => `- ${iss.path || "<root>"}: ${iss.message}`).join("\n");
3741
+ deps.logger.warn(`Config warnings:\\n${details}`);
3742
+ }
3743
+ warnIfConfigFromFuture(validated.config, deps.logger);
3744
+ const cfg = applyTalkConfigNormalization(applyModelDefaults(applyContextPruningDefaults(applyAgentDefaults(applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config)))))));
3745
+ normalizeConfigPaths(cfg);
3746
+ const duplicates = findDuplicateAgentDirs(cfg, {
3747
+ env: deps.env,
3748
+ homedir: deps.homedir
3749
+ });
3750
+ if (duplicates.length > 0) throw new DuplicateAgentDirError(duplicates);
3751
+ applyConfigEnvVars(cfg, deps.env);
3752
+ if ((shouldEnableShellEnvFallback(deps.env) || cfg.env?.shellEnv?.enabled === true) && !shouldDeferShellEnvFallback(deps.env)) loadShellEnvFallback({
3753
+ enabled: true,
3754
+ env: deps.env,
3755
+ expectedKeys: SHELL_ENV_EXPECTED_KEYS,
3756
+ logger: deps.logger,
3757
+ timeoutMs: cfg.env?.shellEnv?.timeoutMs ?? resolveShellEnvFallbackTimeoutMs(deps.env)
3758
+ });
3759
+ const pendingSecret = AUTO_OWNER_DISPLAY_SECRET_BY_PATH.get(configPath);
3760
+ const ownerDisplaySecretResolution = ensureOwnerDisplaySecret(cfg, () => pendingSecret ?? crypto.randomBytes(32).toString("hex"));
3761
+ const cfgWithOwnerDisplaySecret = ownerDisplaySecretResolution.config;
3762
+ if (ownerDisplaySecretResolution.generatedSecret) {
3763
+ AUTO_OWNER_DISPLAY_SECRET_BY_PATH.set(configPath, ownerDisplaySecretResolution.generatedSecret);
3764
+ if (!AUTO_OWNER_DISPLAY_SECRET_PERSIST_IN_FLIGHT.has(configPath)) {
3765
+ AUTO_OWNER_DISPLAY_SECRET_PERSIST_IN_FLIGHT.add(configPath);
3766
+ writeConfigFile(cfgWithOwnerDisplaySecret, { expectedConfigPath: configPath }).then(() => {
3767
+ AUTO_OWNER_DISPLAY_SECRET_BY_PATH.delete(configPath);
3768
+ AUTO_OWNER_DISPLAY_SECRET_PERSIST_WARNED.delete(configPath);
3769
+ }).catch((err) => {
3770
+ if (!AUTO_OWNER_DISPLAY_SECRET_PERSIST_WARNED.has(configPath)) {
3771
+ AUTO_OWNER_DISPLAY_SECRET_PERSIST_WARNED.add(configPath);
3772
+ deps.logger.warn(`Failed to persist auto-generated commands.ownerDisplaySecret at ${configPath}: ${String(err)}`);
3773
+ }
3774
+ }).finally(() => {
3775
+ AUTO_OWNER_DISPLAY_SECRET_PERSIST_IN_FLIGHT.delete(configPath);
3776
+ });
3777
+ }
3778
+ } else {
3779
+ AUTO_OWNER_DISPLAY_SECRET_BY_PATH.delete(configPath);
3780
+ AUTO_OWNER_DISPLAY_SECRET_PERSIST_WARNED.delete(configPath);
3781
+ }
3782
+ return applyConfigOverrides(cfgWithOwnerDisplaySecret);
3783
+ } catch (err) {
3784
+ if (err instanceof DuplicateAgentDirError) {
3785
+ deps.logger.error(err.message);
3786
+ throw err;
3787
+ }
3788
+ if (err?.code === "INVALID_CONFIG") return {};
3789
+ deps.logger.error(`Failed to read config at ${configPath}`, err);
3790
+ return {};
3791
+ }
3792
+ }
3793
+ async function readConfigFileSnapshotInternal() {
3794
+ maybeLoadDotEnvForConfig(deps.env);
3795
+ if (!deps.fs.existsSync(configPath)) {
3796
+ const hash = hashConfigRaw(null);
3797
+ return { snapshot: {
3798
+ path: configPath,
3799
+ exists: false,
3800
+ raw: null,
3801
+ parsed: {},
3802
+ resolved: {},
3803
+ valid: true,
3804
+ config: applyTalkApiKey(applyTalkConfigNormalization(applyModelDefaults(applyContextPruningDefaults(applyAgentDefaults(applySessionDefaults(applyMessageDefaults({}))))))),
3805
+ hash,
3806
+ issues: [],
3807
+ warnings: [],
3808
+ legacyIssues: []
3809
+ } };
3810
+ }
3811
+ try {
3812
+ const raw = deps.fs.readFileSync(configPath, "utf-8");
3813
+ const hash = hashConfigRaw(raw);
3814
+ const parsedRes = parseConfigJson5(raw, deps.json5);
3815
+ if (!parsedRes.ok) return { snapshot: {
3816
+ path: configPath,
3817
+ exists: true,
3818
+ raw,
3819
+ parsed: {},
3820
+ resolved: {},
3821
+ valid: false,
3822
+ config: {},
3823
+ hash,
3824
+ issues: [{
3825
+ path: "",
3826
+ message: `JSON5 parse failed: ${parsedRes.error}`
3827
+ }],
3828
+ warnings: [],
3829
+ legacyIssues: []
3830
+ } };
3831
+ let resolved;
3832
+ try {
3833
+ resolved = resolveConfigIncludesForRead(parsedRes.parsed, configPath, deps);
3834
+ } catch (err) {
3835
+ const message = err instanceof ConfigIncludeError ? err.message : `Include resolution failed: ${String(err)}`;
3836
+ return { snapshot: {
3837
+ path: configPath,
3838
+ exists: true,
3839
+ raw,
3840
+ parsed: parsedRes.parsed,
3841
+ resolved: coerceConfig(parsedRes.parsed),
3842
+ valid: false,
3843
+ config: coerceConfig(parsedRes.parsed),
3844
+ hash,
3845
+ issues: [{
3846
+ path: "",
3847
+ message
3848
+ }],
3849
+ warnings: [],
3850
+ legacyIssues: []
3851
+ } };
3852
+ }
3853
+ let readResolution;
3854
+ try {
3855
+ readResolution = resolveConfigForRead(resolved, deps.env);
3856
+ } catch (err) {
3857
+ const message = err instanceof MissingEnvVarError ? err.message : `Env var substitution failed: ${String(err)}`;
3858
+ return { snapshot: {
3859
+ path: configPath,
3860
+ exists: true,
3861
+ raw,
3862
+ parsed: parsedRes.parsed,
3863
+ resolved: coerceConfig(resolved),
3864
+ valid: false,
3865
+ config: coerceConfig(resolved),
3866
+ hash,
3867
+ issues: [{
3868
+ path: "",
3869
+ message
3870
+ }],
3871
+ warnings: [],
3872
+ legacyIssues: []
3873
+ } };
3874
+ }
3875
+ const resolvedConfigRaw = readResolution.resolvedConfigRaw;
3876
+ const legacyIssues = findLegacyConfigIssues(resolvedConfigRaw);
3877
+ const validated = validateConfigObjectWithPlugins(resolvedConfigRaw);
3878
+ if (!validated.ok) return { snapshot: {
3879
+ path: configPath,
3880
+ exists: true,
3881
+ raw,
3882
+ parsed: parsedRes.parsed,
3883
+ resolved: coerceConfig(resolvedConfigRaw),
3884
+ valid: false,
3885
+ config: coerceConfig(resolvedConfigRaw),
3886
+ hash,
3887
+ issues: validated.issues,
3888
+ warnings: validated.warnings,
3889
+ legacyIssues
3890
+ } };
3891
+ warnIfConfigFromFuture(validated.config, deps.logger);
3892
+ const snapshotConfig = normalizeConfigPaths(applyTalkApiKey(applyTalkConfigNormalization(applyModelDefaults(applyAgentDefaults(applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config))))))));
3893
+ return {
3894
+ snapshot: {
3895
+ path: configPath,
3896
+ exists: true,
3897
+ raw,
3898
+ parsed: parsedRes.parsed,
3899
+ resolved: coerceConfig(resolvedConfigRaw),
3900
+ valid: true,
3901
+ config: snapshotConfig,
3902
+ hash,
3903
+ issues: [],
3904
+ warnings: validated.warnings,
3905
+ legacyIssues
3906
+ },
3907
+ envSnapshotForRestore: readResolution.envSnapshotForRestore
3908
+ };
3909
+ } catch (err) {
3910
+ const nodeErr = err;
3911
+ let message;
3912
+ if (nodeErr?.code === "EACCES") {
3913
+ const uid = process.getuid?.();
3914
+ const uidHint = typeof uid === "number" ? String(uid) : "$(id -u)";
3915
+ message = [
3916
+ `read failed: ${String(err)}`,
3917
+ ``,
3918
+ `Config file is not readable by the current process. If running in a container`,
3919
+ `or 1-click deployment, fix ownership with:`,
3920
+ ` chown ${uidHint} "${configPath}"`,
3921
+ `Then restart the gateway.`
3922
+ ].join("\n");
3923
+ deps.logger.error(message);
3924
+ } else message = `read failed: ${String(err)}`;
3925
+ return { snapshot: {
3926
+ path: configPath,
3927
+ exists: true,
3928
+ raw: null,
3929
+ parsed: {},
3930
+ resolved: {},
3931
+ valid: false,
3932
+ config: {},
3933
+ hash: hashConfigRaw(null),
3934
+ issues: [{
3935
+ path: "",
3936
+ message
3937
+ }],
3938
+ warnings: [],
3939
+ legacyIssues: []
3940
+ } };
3941
+ }
3942
+ }
3943
+ async function readConfigFileSnapshot() {
3944
+ return (await readConfigFileSnapshotInternal()).snapshot;
3945
+ }
3946
+ async function readConfigFileSnapshotForWrite() {
3947
+ const result = await readConfigFileSnapshotInternal();
3948
+ return {
3949
+ snapshot: result.snapshot,
3950
+ writeOptions: {
3951
+ envSnapshotForRestore: result.envSnapshotForRestore,
3952
+ expectedConfigPath: configPath
3953
+ }
3954
+ };
3955
+ }
3956
+ async function writeConfigFile(cfg, options = {}) {
3957
+ clearConfigCache();
3958
+ let persistCandidate = cfg;
3959
+ const { snapshot } = await readConfigFileSnapshotInternal();
3960
+ let envRefMap = null;
3961
+ let changedPaths = null;
3962
+ if (snapshot.valid && snapshot.exists) {
3963
+ const patch = createMergePatch(snapshot.config, cfg);
3964
+ persistCandidate = applyMergePatch(snapshot.resolved, patch);
3965
+ try {
3966
+ const resolvedIncludes = resolveConfigIncludes(snapshot.parsed, configPath, {
3967
+ readFile: (candidate) => deps.fs.readFileSync(candidate, "utf-8"),
3968
+ parseJson: (raw) => deps.json5.parse(raw)
3969
+ });
3970
+ const collected = /* @__PURE__ */ new Map();
3971
+ collectEnvRefPaths(resolvedIncludes, "", collected);
3972
+ if (collected.size > 0) {
3973
+ envRefMap = collected;
3974
+ changedPaths = /* @__PURE__ */ new Set();
3975
+ collectChangedPaths(snapshot.config, cfg, "", changedPaths);
3976
+ }
3977
+ } catch {
3978
+ envRefMap = null;
3979
+ }
3980
+ }
3981
+ const validated = validateConfigObjectRawWithPlugins(persistCandidate);
3982
+ if (!validated.ok) {
3983
+ const issue = validated.issues[0];
3984
+ const pathLabel = issue?.path ? issue.path : "<root>";
3985
+ const issueMessage = issue?.message ?? "invalid";
3986
+ throw new Error(formatConfigValidationFailure(pathLabel, issueMessage));
3987
+ }
3988
+ if (validated.warnings.length > 0) {
3989
+ const details = validated.warnings.map((warning) => `- ${warning.path}: ${warning.message}`).join("\n");
3990
+ deps.logger.warn(`Config warnings:\n${details}`);
3991
+ }
3992
+ let cfgToWrite = validated.config;
3993
+ try {
3994
+ if (deps.fs.existsSync(configPath)) {
3995
+ const parsedRes = parseConfigJson5(await deps.fs.promises.readFile(configPath, "utf-8"), deps.json5);
3996
+ if (parsedRes.ok) {
3997
+ const envForRestore = options.envSnapshotForRestore ?? deps.env;
3998
+ cfgToWrite = restoreEnvVarRefs(cfgToWrite, parsedRes.parsed, envForRestore);
3999
+ }
4000
+ }
4001
+ } catch {}
4002
+ const dir = path.dirname(configPath);
4003
+ await deps.fs.promises.mkdir(dir, {
4004
+ recursive: true,
4005
+ mode: 448
4006
+ });
4007
+ let outputConfig = envRefMap && changedPaths ? restoreEnvRefsFromMap(cfgToWrite, "", envRefMap, changedPaths) : cfgToWrite;
4008
+ if (options.unsetPaths?.length) for (const unsetPath of options.unsetPaths) {
4009
+ if (!Array.isArray(unsetPath) || unsetPath.length === 0) continue;
4010
+ const unsetResult = unsetPathForWrite(outputConfig, unsetPath);
4011
+ if (unsetResult.changed) outputConfig = unsetResult.next;
4012
+ }
4013
+ const stampedOutputConfig = stampConfigVersion(outputConfig);
4014
+ const json = JSON.stringify(stampedOutputConfig, null, 2).trimEnd().concat("\n");
4015
+ const nextHash = hashConfigRaw(json);
4016
+ const previousHash = resolveConfigSnapshotHash(snapshot);
4017
+ const changedPathCount = changedPaths?.size;
4018
+ const previousBytes = typeof snapshot.raw === "string" ? Buffer.byteLength(snapshot.raw, "utf-8") : null;
4019
+ const nextBytes = Buffer.byteLength(json, "utf-8");
4020
+ const hasMetaBefore = hasConfigMeta(snapshot.parsed);
4021
+ const hasMetaAfter = hasConfigMeta(stampedOutputConfig);
4022
+ const gatewayModeBefore = resolveGatewayMode(snapshot.resolved);
4023
+ const gatewayModeAfter = resolveGatewayMode(stampedOutputConfig);
4024
+ const suspiciousReasons = resolveConfigWriteSuspiciousReasons({
4025
+ existsBefore: snapshot.exists,
4026
+ previousBytes,
4027
+ nextBytes,
4028
+ hasMetaBefore,
4029
+ gatewayModeBefore,
4030
+ gatewayModeAfter
4031
+ });
4032
+ const logConfigOverwrite = () => {
4033
+ if (!snapshot.exists) return;
4034
+ const isVitest = deps.env.VITEST === "true";
4035
+ const shouldLogInVitest = deps.env.REMOTECLAW_TEST_CONFIG_OVERWRITE_LOG === "1";
4036
+ if (isVitest && !shouldLogInVitest) return;
4037
+ const changeSummary = typeof changedPathCount === "number" ? `, changedPaths=${changedPathCount}` : "";
4038
+ deps.logger.warn(`Config overwrite: ${configPath} (sha256 ${previousHash ?? "unknown"} -> ${nextHash}, backup=${configPath}.bak${changeSummary})`);
4039
+ };
4040
+ const logConfigWriteAnomalies = () => {
4041
+ if (suspiciousReasons.length === 0) return;
4042
+ const isVitest = deps.env.VITEST === "true";
4043
+ const shouldLogInVitest = deps.env.REMOTECLAW_TEST_CONFIG_WRITE_ANOMALY_LOG === "1";
4044
+ if (isVitest && !shouldLogInVitest) return;
4045
+ deps.logger.warn(`Config write anomaly: ${configPath} (${suspiciousReasons.join(", ")})`);
4046
+ };
4047
+ const auditRecordBase = {
4048
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
4049
+ source: "config-io",
4050
+ event: "config.write",
4051
+ configPath,
4052
+ pid: process.pid,
4053
+ ppid: process.ppid,
4054
+ cwd: process.cwd(),
4055
+ argv: process.argv.slice(0, 8),
4056
+ execArgv: process.execArgv.slice(0, 8),
4057
+ watchMode: deps.env.REMOTECLAW_WATCH_MODE === "1",
4058
+ watchSession: typeof deps.env.REMOTECLAW_WATCH_SESSION === "string" && deps.env.REMOTECLAW_WATCH_SESSION.trim().length > 0 ? deps.env.REMOTECLAW_WATCH_SESSION.trim() : null,
4059
+ watchCommand: typeof deps.env.REMOTECLAW_WATCH_COMMAND === "string" && deps.env.REMOTECLAW_WATCH_COMMAND.trim().length > 0 ? deps.env.REMOTECLAW_WATCH_COMMAND.trim() : null,
4060
+ existsBefore: snapshot.exists,
4061
+ previousHash: previousHash ?? null,
4062
+ nextHash,
4063
+ previousBytes,
4064
+ nextBytes,
4065
+ changedPathCount: typeof changedPathCount === "number" ? changedPathCount : null,
4066
+ hasMetaBefore,
4067
+ hasMetaAfter,
4068
+ gatewayModeBefore,
4069
+ gatewayModeAfter,
4070
+ suspicious: suspiciousReasons
4071
+ };
4072
+ const appendWriteAudit = async (result, err) => {
4073
+ const errorCode = err && typeof err === "object" && "code" in err && typeof err.code === "string" ? err.code : void 0;
4074
+ const errorMessage = err && typeof err === "object" && "message" in err && typeof err.message === "string" ? err.message : void 0;
4075
+ await appendConfigWriteAuditRecord(deps, {
4076
+ ...auditRecordBase,
4077
+ result,
4078
+ nextHash: result === "failed" ? null : auditRecordBase.nextHash,
4079
+ nextBytes: result === "failed" ? null : auditRecordBase.nextBytes,
4080
+ errorCode,
4081
+ errorMessage
4082
+ });
4083
+ };
4084
+ const tmp = path.join(dir, `${path.basename(configPath)}.${process.pid}.${crypto.randomUUID()}.tmp`);
4085
+ try {
4086
+ await deps.fs.promises.writeFile(tmp, json, {
4087
+ encoding: "utf-8",
4088
+ mode: 384
4089
+ });
4090
+ if (deps.fs.existsSync(configPath)) {
4091
+ await rotateConfigBackups(configPath, deps.fs.promises);
4092
+ await deps.fs.promises.copyFile(configPath, `${configPath}.bak`).catch(() => {});
4093
+ }
4094
+ try {
4095
+ await deps.fs.promises.rename(tmp, configPath);
4096
+ } catch (err) {
4097
+ const code = err.code;
4098
+ if (code === "EPERM" || code === "EEXIST") {
4099
+ await deps.fs.promises.copyFile(tmp, configPath);
4100
+ await deps.fs.promises.chmod(configPath, 384).catch(() => {});
4101
+ await deps.fs.promises.unlink(tmp).catch(() => {});
4102
+ logConfigOverwrite();
4103
+ logConfigWriteAnomalies();
4104
+ await appendWriteAudit("copy-fallback");
4105
+ return;
4106
+ }
4107
+ await deps.fs.promises.unlink(tmp).catch(() => {});
4108
+ throw err;
4109
+ }
4110
+ logConfigOverwrite();
4111
+ logConfigWriteAnomalies();
4112
+ await appendWriteAudit("rename");
4113
+ } catch (err) {
4114
+ await appendWriteAudit("failed", err);
4115
+ throw err;
4116
+ }
4117
+ }
4118
+ return {
4119
+ configPath,
4120
+ loadConfig,
4121
+ readConfigFileSnapshot,
4122
+ readConfigFileSnapshotForWrite,
4123
+ writeConfigFile
4124
+ };
4125
+ }
4126
+ const DEFAULT_CONFIG_CACHE_MS = 200;
4127
+ const AUTO_OWNER_DISPLAY_SECRET_BY_PATH = /* @__PURE__ */ new Map();
4128
+ const AUTO_OWNER_DISPLAY_SECRET_PERSIST_IN_FLIGHT = /* @__PURE__ */ new Set();
4129
+ const AUTO_OWNER_DISPLAY_SECRET_PERSIST_WARNED = /* @__PURE__ */ new Set();
4130
+ let configCache = null;
4131
+ function resolveConfigCacheMs(env) {
4132
+ const raw = env.REMOTECLAW_CONFIG_CACHE_MS?.trim();
4133
+ if (raw === "" || raw === "0") return 0;
4134
+ if (!raw) return DEFAULT_CONFIG_CACHE_MS;
4135
+ const parsed = Number.parseInt(raw, 10);
4136
+ if (!Number.isFinite(parsed)) return DEFAULT_CONFIG_CACHE_MS;
4137
+ return Math.max(0, parsed);
4138
+ }
4139
+ function shouldUseConfigCache(env) {
4140
+ if (env.REMOTECLAW_DISABLE_CONFIG_CACHE?.trim()) return false;
4141
+ return resolveConfigCacheMs(env) > 0;
4142
+ }
4143
+ function clearConfigCache() {
4144
+ configCache = null;
4145
+ }
4146
+ function loadConfig() {
4147
+ const io = createConfigIO();
4148
+ const configPath = io.configPath;
4149
+ const now = Date.now();
4150
+ if (shouldUseConfigCache(process.env)) {
4151
+ const cached = configCache;
4152
+ if (cached && cached.configPath === configPath && cached.expiresAt > now) return cached.config;
4153
+ }
4154
+ const config = io.loadConfig();
4155
+ if (shouldUseConfigCache(process.env)) {
4156
+ const cacheMs = resolveConfigCacheMs(process.env);
4157
+ if (cacheMs > 0) configCache = {
4158
+ configPath,
4159
+ expiresAt: now + cacheMs,
4160
+ config
4161
+ };
4162
+ }
4163
+ return config;
4164
+ }
4165
+ async function readConfigFileSnapshot() {
4166
+ return await createConfigIO().readConfigFileSnapshot();
4167
+ }
4168
+ async function readConfigFileSnapshotForWrite() {
4169
+ return await createConfigIO().readConfigFileSnapshotForWrite();
4170
+ }
4171
+ async function writeConfigFile(cfg, options = {}) {
4172
+ const io = createConfigIO();
4173
+ const sameConfigPath = options.expectedConfigPath === void 0 || options.expectedConfigPath === io.configPath;
4174
+ await io.writeConfigFile(cfg, {
4175
+ envSnapshotForRestore: sameConfigPath ? options.envSnapshotForRestore : void 0,
4176
+ unsetPaths: options.unsetPaths
4177
+ });
4178
+ }
4179
+
4180
+ //#endregion
4181
+ //#region src/config/legacy-migrate.ts
4182
+ function migrateLegacyConfig(raw) {
4183
+ const { next, changes } = applyLegacyMigrations(raw);
4184
+ if (!next) return {
4185
+ config: null,
4186
+ changes: []
4187
+ };
4188
+ const validated = validateConfigObjectWithPlugins(next);
4189
+ if (!validated.ok) {
4190
+ changes.push("Migration applied, but config still invalid; fix remaining issues manually.");
4191
+ return {
4192
+ config: null,
4193
+ changes
4194
+ };
4195
+ }
4196
+ return {
4197
+ config: validated.config,
4198
+ changes
4199
+ };
4200
+ }
4201
+
4202
+ //#endregion
4203
+ //#region src/config/config.ts
4204
+ var config_exports = /* @__PURE__ */ __exportAll({
4205
+ CONFIG_PATH: () => CONFIG_PATH,
4206
+ DEFAULT_GATEWAY_PORT: () => DEFAULT_GATEWAY_PORT,
4207
+ STATE_DIR: () => STATE_DIR,
4208
+ TOOLS_BY_SENDER_KEY_TYPES: () => TOOLS_BY_SENDER_KEY_TYPES,
4209
+ applyConfigOverrides: () => applyConfigOverrides,
4210
+ getConfigOverrides: () => getConfigOverrides,
4211
+ isNixMode: () => isNixMode,
4212
+ loadConfig: () => loadConfig,
4213
+ parseToolsBySenderTypedKey: () => parseToolsBySenderTypedKey,
4214
+ resetConfigOverrides: () => resetConfigOverrides,
4215
+ resolveCanonicalConfigPath: () => resolveCanonicalConfigPath,
4216
+ resolveConfigPath: () => resolveConfigPath,
4217
+ resolveConfigPathCandidate: () => resolveConfigPathCandidate,
4218
+ resolveDefaultConfigCandidates: () => resolveDefaultConfigCandidates,
4219
+ resolveGatewayLockDir: () => resolveGatewayLockDir,
4220
+ resolveGatewayPort: () => resolveGatewayPort,
4221
+ resolveIsNixMode: () => resolveIsNixMode,
4222
+ resolveLegacyStateDirs: () => resolveLegacyStateDirs,
4223
+ resolveNewStateDir: () => resolveNewStateDir,
4224
+ resolveOAuthDir: () => resolveOAuthDir,
4225
+ resolveStateDir: () => resolveStateDir,
4226
+ setConfigOverride: () => setConfigOverride,
4227
+ unsetConfigOverride: () => unsetConfigOverride
4228
+ });
4229
+
4230
+ //#endregion
4231
+ export { applyTestPluginDefaults as A, unsetConfigValueAtPath as B, discoverRemoteClawPlugins as C, LEGACY_MANIFEST_KEYS as D, loadPluginManifest as E, setConfigOverride as F, extensionUsesSkippedScannerPath as G, applyLegacyMigrations as H, unsetConfigOverride as I, buildTalkConfigResponse as J, isPathInside$1 as K, getConfigValueAtPath as L, resolveEffectiveEnableState as M, getConfigOverrides as N, MANIFEST_KEY as O, resetConfigOverrides as P, loadDotEnv as Q, parseConfigPath as R, loadPluginManifestRegistry as S, safeStatSync as T, INCLUDE_KEY as U, applyMergePatch as V, MAX_INCLUDE_DEPTH as W, resolveAgentMaxConcurrent as X, DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH as Y, resolveSubagentMaxConcurrent as Z, isWorkspaceRelativeAvatarPath as _, parseConfigJson5 as a, validateJsonSchemaValue as b, resolveConfigSnapshotHash as c, AVATAR_MAX_BYTES as d, isAvatarDataUrl as f, isSupportedLocalAvatarExtension as g, isPathWithinRoot as h, loadConfig as i, normalizePluginsConfig as j, resolveBundledPluginsDir as k, writeConfigFile as l, isAvatarImageDataUrl as m, migrateLegacyConfig as n, readConfigFileSnapshot as o, isAvatarHttpUrl as p, isPathInsideWithRealpath as q, createConfigIO as r, readConfigFileSnapshotForWrite as s, config_exports as t, validateConfigObjectWithPlugins as u, looksLikeAvatarPath as v, isPathInside as w, clearPluginManifestRegistryCache as x, resolveAvatarMime as y, setConfigValueAtPath as z };