@desplega.ai/agent-swarm 1.173.0 → 2.1.0

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 (511) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-ccm9xrep.js → acp-adapter-kr4abrsk.js} +17 -16
  3. package/dist/{actions-sgeyv08k.js → actions-eh4g6w2r.js} +39 -34
  4. package/dist/{amp-adapter-gpxp3kc9.js → amp-adapter-7h7wdt8q.js} +8 -7
  5. package/dist/{app-km9qnv2f.js → app-7k8s9w5p.js} +18 -14
  6. package/dist/{assistant-5r8tcvvd.js → assistant-wswt2y7p.js} +40 -35
  7. package/dist/{boot-reembed-16rv9843.js → boot-reembed-9apm9qw6.js} +10 -9
  8. package/dist/{boot-reembed-swwzdgd7.js → boot-reembed-whzbdthj.js} +10 -9
  9. package/dist/{boot-scrub-sweep-zkr6vkqb.js → boot-scrub-sweep-ndzmvmgt.js} +11 -10
  10. package/dist/{boot-seeds-d8sp49t2.js → boot-seeds-e9sta0yt.js} +16 -13
  11. package/dist/{claude-adapter-yzzzh8jp.js → claude-adapter-4mqd3r6r.js} +19 -18
  12. package/dist/{claude-managed-adapter-xgxhqrt2.js → claude-managed-adapter-9wswb52m.js} +7 -5
  13. package/dist/{claude-managed-setup-bnmjarjc.js → claude-managed-setup-tpe1effx.js} +6 -4
  14. package/dist/{claude-sdk-session-4whxere4.js → claude-sdk-session-q49ghmh9.js} +12402 -11850
  15. package/dist/{cli-ne7smj1b.js → cli-01xvj1rq.js} +10 -10
  16. package/dist/{cli-nwrdx840.js → cli-035vekcw.js} +3 -3
  17. package/dist/{cli-9xf7fdtp.js → cli-0pd8hzhc.js} +29 -6
  18. package/dist/{cli-tmhsxhb8.js → cli-0veb92a3.js} +28 -6
  19. package/dist/{cli-c3rk1v0x.js → cli-10jesr25.js} +3 -3
  20. package/dist/{cli-6thk4jz3.js → cli-1y7yywmj.js} +6 -6
  21. package/dist/{cli-6r2f7edk.js → cli-20krdhz5.js} +47 -19
  22. package/dist/{cli-rfs4vddv.js → cli-29rja109.js} +39 -20
  23. package/dist/cli-2m1ktfzz.js +17795 -0
  24. package/dist/{cli-na2pxe4f.js → cli-2pwa0q4d.js} +15 -4
  25. package/dist/{cli-7a93cv8c.js → cli-4mengw46.js} +441 -43
  26. package/dist/{cli-94b48jhk.js → cli-5twdke5x.js} +16 -14
  27. package/dist/{cli-7a0sde2x.js → cli-6cagzc96.js} +9 -0
  28. package/dist/cli-6cvfxs8r.js +47 -0
  29. package/dist/{cli-w1apjecb.js → cli-711vwbxn.js} +2 -2
  30. package/dist/{cli-r4fqfpwf.js → cli-78vv7446.js} +50 -27
  31. package/dist/{cli-srqq3gc5.js → cli-7n6s5man.js} +5 -5
  32. package/dist/{cli-m89t9jdf.js → cli-7x0g4sn1.js} +15416 -16024
  33. package/dist/{cli-2bw3w47j.js → cli-8wwxw8a3.js} +1 -1
  34. package/dist/{cli-yatxqynm.js → cli-9ha6hs2d.js} +1 -290
  35. package/dist/{cli-ywm1azg9.js → cli-9jzdj90z.js} +8 -4
  36. package/dist/cli-9traj3dn.js +638 -0
  37. package/dist/{cli-smcrrmhy.js → cli-agzebbd5.js} +9 -9
  38. package/dist/{cli-c5km5znr.js → cli-c8r3kzzb.js} +1 -1
  39. package/dist/cli-cvv9k0hh.js +10143 -0
  40. package/dist/{cli-anzdk0z4.js → cli-d9286m9h.js} +2 -2
  41. package/dist/cli-e3g5mbkz.js +776 -0
  42. package/dist/cli-f527ce74.js +781 -0
  43. package/dist/{cli-gmdajfw5.js → cli-gxzkg1de.js} +5020 -1729
  44. package/dist/{cli-451ks6aw.js → cli-h1arqn31.js} +1 -1
  45. package/dist/cli-hjwmhcg1.js +10622 -0
  46. package/dist/{cli-jpc4r224.js → cli-hqr88ew6.js} +19 -3
  47. package/dist/{cli-h7k0xtry.js → cli-hvqbtna4.js} +4 -1256
  48. package/dist/{cli-cd0hv9nh.js → cli-j67mh2vg.js} +2 -2
  49. package/dist/cli-jta2eyzc.js +619 -0
  50. package/dist/{cli-wd0hz6ah.js → cli-kbrt8gqa.js} +9 -91
  51. package/dist/cli-kceah1eh.js +92 -0
  52. package/dist/{cli-d603qf86.js → cli-ksphgh48.js} +10 -8
  53. package/dist/{cli-3nxdmjrc.js → cli-mgz4nbgg.js} +4 -4
  54. package/dist/{cli-saqyage0.js → cli-mz5as5ha.js} +179 -27
  55. package/dist/cli-n2wq4j7m.js +6985 -0
  56. package/dist/{cli-ppy4nnnh.js → cli-n8ndw8j7.js} +2 -2
  57. package/dist/{cli-1w0vj3gw.js → cli-naqzr17j.js} +7 -7
  58. package/dist/{cli-0a7mm3zp.js → cli-nm1p8jfr.js} +25 -21
  59. package/dist/{cli-wrh08zjd.js → cli-p3zbc1rw.js} +5 -18
  60. package/dist/{cli-hsem16hb.js → cli-pe05f8yk.js} +29 -6
  61. package/dist/{cli-5wpw4rab.js → cli-qmzsbkvy.js} +5 -5
  62. package/dist/{cli-bv2etw2y.js → cli-qnm4e9e4.js} +99 -590
  63. package/dist/{cli-1x7da0de.js → cli-qqy4q48b.js} +8 -8
  64. package/dist/{cli-r44t9wqc.js → cli-r106725k.js} +2 -2
  65. package/dist/{cli-5er5gjbm.js → cli-r35rw5de.js} +15 -15
  66. package/dist/{cli-v3zhnxsb.js → cli-r610p9bs.js} +2 -2
  67. package/dist/{cli-7jykv7ef.js → cli-rc6pf5kv.js} +1 -1
  68. package/dist/{cli-x119kdba.js → cli-rdxm77k3.js} +1 -1
  69. package/dist/cli-rhs9pz33.js +294 -0
  70. package/dist/{cli-0p3enk35.js → cli-s69nfyeh.js} +9 -1
  71. package/dist/{cli-0kxf81jj.js → cli-sawv63e8.js} +2 -2
  72. package/dist/{cli-e3pmyt39.js → cli-sg19gbf0.js} +1 -1
  73. package/dist/{cli-d161g69q.js → cli-shk7r5cs.js} +57 -6
  74. package/dist/{cli-7pz3b7x5.js → cli-sksetb2q.js} +36 -1
  75. package/dist/{cli-014vns2y.js → cli-stfs0k5s.js} +208 -525
  76. package/dist/{cli-db3m6zdt.js → cli-t02z59f2.js} +1 -1
  77. package/dist/{cli-b07hr3bt.js → cli-txqb9s38.js} +2 -2
  78. package/dist/{cli-s8z6x4b4.js → cli-v7g551te.js} +225 -113
  79. package/dist/{cli-rfz2ve55.js → cli-vgqzp4em.js} +3341 -955
  80. package/dist/{cli-7avy4v8w.js → cli-w1q7h2r2.js} +5 -3
  81. package/dist/{cli-rcp5aqdw.js → cli-w7m81tb7.js} +1 -1
  82. package/dist/cli-wfnemr1t.js +86 -0
  83. package/dist/cli-wmgrkscj.js +23254 -0
  84. package/dist/{cli-qm1448f9.js → cli-wms6x9db.js} +8 -8
  85. package/dist/{cli-tadfgd0t.js → cli-x1r545x8.js} +33 -4
  86. package/dist/{cli-xc7p7s3g.js → cli-xczsgshn.js} +6 -6
  87. package/dist/{cli-fmhj1ehj.js → cli-y3167wt1.js} +882 -271
  88. package/dist/{cli-r0byd61h.js → cli-yjmqpxt3.js} +17 -16
  89. package/dist/{cli-81r1wjyv.js → cli-z780ec7c.js} +1 -1
  90. package/dist/{cli-phcqp1b9.js → cli-zm9t2vde.js} +2 -2
  91. package/dist/cli.js +34 -49
  92. package/dist/{codex-adapter-r3dn4fp5.js → codex-adapter-4z16v9n0.js} +15 -14
  93. package/dist/{codex-login-841kv5fk.js → codex-login-pkepy2j1.js} +3 -2
  94. package/dist/{codex-session-runner-fwt793h4.js → codex-session-runner-rvms9y2x.js} +15 -14
  95. package/dist/{commands-z8fq9qna.js → commands-2a9rtyat.js} +11 -10
  96. package/dist/{controller-hq5ggpcp.js → controller-3k3madbn.js} +5 -4
  97. package/dist/{controllers-connect-3mf2btyj.js → controllers-connect-v9yn8zb9.js} +42 -37
  98. package/dist/{cursor-adapter-q8pgv5qa.js → cursor-adapter-98gbhyzn.js} +7 -6
  99. package/dist/{db-qfpq4bt7.js → db-eywwsnjw.js} +30 -9
  100. package/dist/{db-yyhqqrbf.js → db-ncypk9np.js} +12 -11
  101. package/dist/{devin-adapter-xgtj680j.js → devin-adapter-zeq8b9gz.js} +3 -2
  102. package/dist/{dispatcher-x0x7qfcq.js → dispatcher-w94kc575.js} +38 -33
  103. package/dist/{docker-f503k9p0.js → docker-b1e4cqab.js} +3 -2
  104. package/dist/{dsh-adapter-34etvb5m.js → dsh-adapter-47ztej36.js} +7 -6
  105. package/dist/{e2b-66xra4az.js → e2b-bbt8ey45.js} +4 -3
  106. package/dist/{e2b-xwhyj8cw.js → e2b-dp804sen.js} +4 -3
  107. package/dist/{event-bus-vjtv82gm.js → event-bus-j2jdg3qb.js} +3 -2
  108. package/dist/{external-channel-h1fjecwe.js → external-channel-zrkg8ar9.js} +11 -10
  109. package/dist/{google-generative-ai-szdxbpqg.js → google-generative-ai-g8db7x0f.js} +4 -2
  110. package/dist/{google-vertex-qzw3p36d.js → google-vertex-r2692q0r.js} +4 -2
  111. package/dist/{grok-adapter-e7mr287e.js → grok-adapter-s9ncp9vy.js} +18 -17
  112. package/dist/{handlers-znb9n7d4.js → handlers-kqftvjgw.js} +41 -36
  113. package/dist/{heartbeat-bm4qkn8d.js → heartbeat-9q96p8v9.js} +43 -38
  114. package/dist/{hook-254r4mza.js → hook-56qe10dp.js} +11 -23
  115. package/dist/{hook-xaa3q80s.js → hook-yy6rw42k.js} +12 -11
  116. package/dist/{http-3dgrgp8y.js → http-r2dnb8f8.js} +2411 -275
  117. package/dist/{index-fx3jqq1e.js → index-3gtmkhc6.js} +38 -33
  118. package/dist/{index-bdsqa799.js → index-3k5hkz7r.js} +43 -38
  119. package/dist/index-52j1aja4.js +3465 -0
  120. package/dist/{index-g2byveez.js → index-5e101240.js} +38 -33
  121. package/dist/{index-2ybk7khy.js → index-5wyfjc2c.js} +845 -683
  122. package/dist/index-9gw58n4k.js +193 -0
  123. package/dist/index-9j87mcm8.js +56305 -0
  124. package/dist/index-bsmcresk.js +79424 -0
  125. package/dist/index-mh85qhec.js +475 -0
  126. package/dist/{index-jd7sejm2.js → index-vxvhxxbn.js} +10 -9
  127. package/dist/index-we27kd31.js +12810 -0
  128. package/dist/{keepalive-6ywhpja1.js → keepalive-psj6j54c.js} +12 -11
  129. package/dist/{lead-cw45n21s.js → lead-hajz4688.js} +61 -56
  130. package/dist/{maintenance-ss1a1ge9.js → maintenance-ps02sb5m.js} +10 -9
  131. package/dist/{node-fkajaq96.js → node-mwb5r697.js} +2 -1
  132. package/dist/{oauth-refresh-sweep-3c6f8vyy.js → oauth-refresh-sweep-0284h93b.js} +11 -10
  133. package/dist/{onboard-8hzdhc1k.js → onboard-rbf6bg01.js} +11 -3
  134. package/dist/{opencode-adapter-qbchbcfz.js → opencode-adapter-13dcatgq.js} +18 -13
  135. package/dist/{otel-impl-e6mnvc4v.js → otel-impl-zvqcbhp7.js} +242 -868
  136. package/dist/{pi-mono-adapter-3c9g9snh.js → pi-mono-adapter-xxy47q4v.js} +244 -106
  137. package/dist/{pricing-refresh-gedkjdw0.js → pricing-refresh-kefx9v3t.js} +12 -11
  138. package/dist/{rbac-roles-dt4vh1yy.js → rbac-roles-3m36rxm2.js} +11 -10
  139. package/dist/{rbac-roles-eszdg6pm.js → rbac-roles-z76xv0hq.js} +12 -11
  140. package/dist/{render-v2-907cy6sa.js → render-v2-wz73bs25.js} +18 -14
  141. package/dist/{resume-42stcaz0.js → resume-k4wzge8w.js} +25 -21
  142. package/dist/{runtime-qfry88v2.js → runtime-sa2vr16g.js} +2 -2
  143. package/dist/{setup-adbc1c10.js → setup-2fp2pypp.js} +2 -2
  144. package/dist/{virtual-modules-rtmt494q.js → virtual-modules-9gkxqrap.js} +6 -5
  145. package/dist/{work-objects-wpj8ck95.js → work-objects-6k0ywz3m.js} +41 -36
  146. package/dist/{worker-bzdra9rf.js → worker-5v3rxsdh.js} +61 -56
  147. package/dist/{x-qfmygqqv.js → x-4mtdeym1.js} +3 -2
  148. package/openapi.json +1279 -329
  149. package/package.json +15 -15
  150. package/src/agentmail/handlers.ts +21 -11
  151. package/src/apps/definition.ts +16 -0
  152. package/src/azure-devops/api.ts +52 -2
  153. package/src/azure-devops/boards-sync.ts +50 -20
  154. package/src/azure-devops/index.ts +1 -0
  155. package/src/azure-devops/outbound.ts +95 -0
  156. package/src/be/boot-seeds.ts +11 -0
  157. package/src/be/config-refs.ts +60 -0
  158. package/src/be/db/model-profiles.ts +315 -0
  159. package/src/be/db/page-versions.ts +15 -0
  160. package/src/be/db/runtime.ts +35 -8
  161. package/src/be/db/skill-name-resolution.ts +36 -0
  162. package/src/be/db/tasks/read.ts +237 -0
  163. package/src/be/db/tasks/write.ts +7 -0
  164. package/src/be/db.ts +87 -36
  165. package/src/be/migrations/215_swarm_config_export_to_env.sql +34 -0
  166. package/src/be/migrations/216_task_resolved_effort.sql +5 -0
  167. package/src/be/migrations/217_chat_sdk_state.sql +104 -0
  168. package/src/be/migrations/219_relabel_pi_context_compactions.sql +22 -0
  169. package/src/be/migrations/220_model_profiles.sql +137 -0
  170. package/src/be/model-catalog-store.ts +5 -1
  171. package/src/be/model-tier-resolution.ts +155 -10
  172. package/src/be/model-validation.ts +12 -2
  173. package/src/be/models-catalog.ts +26 -1
  174. package/src/be/modelsdev-cache.json +198 -63
  175. package/src/be/modelsdev-cache.ts +9 -1
  176. package/src/be/script-credential-broker.ts +39 -2
  177. package/src/be/scripts/run-saved.ts +1 -0
  178. package/src/be/scripts/typecheck.ts +22 -8
  179. package/src/be/secret-registry.ts +6 -2
  180. package/src/be/seed/runner.ts +13 -1
  181. package/src/be/seed/state-db.ts +5 -0
  182. package/src/be/seed/types.ts +6 -0
  183. package/src/be/seed-model-profiles.ts +41 -0
  184. package/src/be/seed-pricing.ts +19 -2
  185. package/src/be/seed-scripts/catalog/heartbeat-jev-gate.ts +368 -0
  186. package/src/be/seed-scripts/catalog/ops-catalog-audit.inline.ts +1 -1
  187. package/src/be/seed-scripts/catalog/ops-catalog-audit.ts +1 -1
  188. package/src/be/seed-scripts/index.ts +9 -0
  189. package/src/be/seed-skills/bundled-files.generated.json +0 -18
  190. package/src/be/seed-skills/index.ts +104 -3
  191. package/src/be/swarm-config-guard.ts +53 -0
  192. package/src/cli.tsx +0 -16
  193. package/src/commands/onboard/non-interactive.ts +4 -2
  194. package/src/commands/provider-credentials.ts +52 -6
  195. package/src/commands/runner.ts +193 -71
  196. package/src/e2b/env.ts +5 -0
  197. package/src/extensions/catalog.generated.json +17 -0
  198. package/src/extensions/contract-types.generated.ts +1 -1
  199. package/src/extensions/contract.ts +45 -0
  200. package/src/extensions/dispatcher.ts +7 -0
  201. package/src/extensions/loader.ts +10 -5
  202. package/src/extensions/post-bridge.ts +40 -0
  203. package/src/github/handlers.ts +11 -4
  204. package/src/heartbeat/heartbeat.ts +2 -1
  205. package/src/heartbeat/templates.ts +8 -5
  206. package/src/hooks/hook.ts +0 -26
  207. package/src/http/agents.ts +49 -2
  208. package/src/http/all-routes.ts +1 -1
  209. package/src/http/apps.ts +30 -3
  210. package/src/http/config.ts +62 -19
  211. package/src/http/core.ts +8 -0
  212. package/src/http/index.ts +25 -3
  213. package/src/http/integrations.ts +88 -1
  214. package/src/http/mcp.ts +15 -5
  215. package/src/http/model-profiles.ts +303 -0
  216. package/src/http/page-proxy.ts +2 -4
  217. package/src/http/pages-public.ts +13 -7
  218. package/src/http/pages.ts +3 -13
  219. package/src/http/poll.ts +42 -71
  220. package/src/http/requested-by.ts +54 -0
  221. package/src/http/script-runs.ts +1 -1
  222. package/src/http/scripts.ts +26 -2
  223. package/src/http/stats.ts +1 -30
  224. package/src/http/tasks.ts +79 -5
  225. package/src/http/utils.ts +14 -0
  226. package/src/http/webhooks.ts +160 -3
  227. package/src/http/x.ts +1 -0
  228. package/src/integrations/chat-sdk/adapters.ts +129 -0
  229. package/src/integrations/chat-sdk/attachments.ts +232 -0
  230. package/src/integrations/chat-sdk/background.ts +36 -0
  231. package/src/integrations/chat-sdk/commands.ts +194 -0
  232. package/src/integrations/chat-sdk/config.ts +198 -0
  233. package/src/integrations/chat-sdk/discord-api.ts +63 -0
  234. package/src/integrations/chat-sdk/discord-gateway.ts +185 -0
  235. package/src/integrations/chat-sdk/handlers.ts +28 -0
  236. package/src/integrations/chat-sdk/inbound.ts +426 -0
  237. package/src/integrations/chat-sdk/limits.ts +48 -0
  238. package/src/integrations/chat-sdk/logger.ts +81 -0
  239. package/src/integrations/chat-sdk/outbound.ts +123 -0
  240. package/src/integrations/chat-sdk/relay.ts +172 -0
  241. package/src/integrations/chat-sdk/router.ts +169 -0
  242. package/src/integrations/chat-sdk/runtime.ts +351 -0
  243. package/src/integrations/chat-sdk/schema.ts +245 -0
  244. package/src/integrations/chat-sdk/state.ts +243 -0
  245. package/src/integrations/chat-sdk/status.ts +244 -0
  246. package/src/integrations/chat-sdk/steering.ts +58 -0
  247. package/src/integrations/chat-sdk/teams-origin.ts +77 -0
  248. package/src/integrations/chat-sdk/telegram-api.ts +56 -0
  249. package/src/integrations/chat-sdk/templates.ts +16 -0
  250. package/src/integrations/chat-sdk/test-hooks.ts +37 -0
  251. package/src/integrations/chat-sdk/thread-buffer.ts +100 -0
  252. package/src/integrations/chat-sdk/typing.ts +65 -0
  253. package/src/{artifact-sdk → pages}/feedback-overlay.ts +65 -6
  254. package/src/pages/version.ts +4 -5
  255. package/src/prompts/base-prompt.ts +111 -45
  256. package/src/providers/acp-target-catalog.ts +6 -0
  257. package/src/providers/acp-targets.ts +56 -3
  258. package/src/providers/amp-adapter.ts +1 -1
  259. package/src/providers/claude-adapter.ts +1 -1
  260. package/src/providers/claude-flag-settings.ts +17 -5
  261. package/src/providers/claude-managed-adapter.ts +1 -1
  262. package/src/providers/claude-session-events.ts +6 -1
  263. package/src/providers/dsh-adapter.ts +1 -1
  264. package/src/providers/opencode-adapter.ts +243 -26
  265. package/src/providers/opencode-swarm-plugin.ts +31 -0
  266. package/src/providers/pi-mono-adapter.ts +398 -153
  267. package/src/providers/pi-mono-extension.ts +17 -3
  268. package/src/providers/pricing-sources.md +33 -2
  269. package/src/providers/reasoning-effort.ts +37 -0
  270. package/src/providers/types.ts +6 -2
  271. package/src/rbac/legacy-policy.ts +16 -2
  272. package/src/rbac/permissions.ts +26 -0
  273. package/src/scheduler/deferred-task-waits.ts +18 -5
  274. package/src/scheduler/scheduler.ts +11 -3
  275. package/src/scripts-runtime/executors/quickjs-prelude.ts +75 -6
  276. package/src/scripts-runtime/executors/quickjs-runner.ts +85 -8
  277. package/src/scripts-runtime/executors/quickjs-web-shims.ts +1041 -0
  278. package/src/scripts-runtime/extract-args-schema.ts +9 -8
  279. package/src/scripts-runtime/loader.ts +19 -7
  280. package/src/scripts-runtime/quickjs-compat.ts +464 -0
  281. package/src/scripts-runtime/sdk-allowlist.ts +12 -6
  282. package/src/scripts-runtime/swarm-sdk.ts +0 -11
  283. package/src/scripts-runtime/types/stdlib.d.ts +39 -15
  284. package/src/scripts-runtime/types/swarm-extension.d.ts +66 -1
  285. package/src/scripts-runtime/types/swarm-sdk.d.ts +39 -15
  286. package/src/server.ts +62 -19
  287. package/src/slack/blocks.ts +4 -2
  288. package/src/slack/event-dedup.ts +1 -1
  289. package/src/slack/reaction-shortcode.ts +14 -0
  290. package/src/slack/render-v2.ts +12 -7
  291. package/src/slack/responses.ts +5 -4
  292. package/src/slack/thread-buffer.ts +41 -22
  293. package/src/tasks/additive-buffer.ts +4 -2
  294. package/src/tasks/context-key.ts +60 -1
  295. package/src/tasks/model-pin.ts +67 -0
  296. package/src/tasks/worker-follow-up.ts +15 -33
  297. package/src/tests/acp-adapter.test.ts +42 -0
  298. package/src/tests/agentmail-filters.test.ts +47 -0
  299. package/src/tests/api-drain-worker-e2e.test.ts +1 -6
  300. package/src/tests/apps-spike2.test.ts +35 -0
  301. package/src/tests/azure-devops-outbound.test.ts +420 -0
  302. package/src/tests/base-prompt.test.ts +58 -54
  303. package/src/tests/chat-sdk-commands.test.ts +191 -0
  304. package/src/tests/chat-sdk-config.test.ts +334 -0
  305. package/src/tests/chat-sdk-discord-api.test.ts +68 -0
  306. package/src/tests/chat-sdk-discord-gateway.test.ts +252 -0
  307. package/src/tests/chat-sdk-discord-webhook.test.ts +126 -0
  308. package/src/tests/chat-sdk-fields-sync.test.ts +50 -0
  309. package/src/tests/chat-sdk-harness.ts +146 -0
  310. package/src/tests/chat-sdk-inbound.test.ts +363 -0
  311. package/src/tests/chat-sdk-relay.test.ts +470 -0
  312. package/src/tests/chat-sdk-reload.test.ts +128 -0
  313. package/src/tests/chat-sdk-shutdown.test.ts +220 -0
  314. package/src/tests/chat-sdk-slack.test.ts +268 -0
  315. package/src/tests/chat-sdk-state.test.ts +163 -0
  316. package/src/tests/chat-sdk-status-route.test.ts +382 -0
  317. package/src/tests/chat-sdk-teams.test.ts +277 -0
  318. package/src/tests/chat-sdk-tools.test.ts +520 -0
  319. package/src/tests/chat-sdk-typing.test.ts +120 -0
  320. package/src/tests/chat-sdk-webhook-telegram.test.ts +200 -0
  321. package/src/tests/claude-adapter-binary.test.ts +9 -4
  322. package/src/tests/claude-flag-settings.test.ts +11 -3
  323. package/src/tests/claude-managed-adapter.test.ts +1 -1
  324. package/src/tests/claude-sdk-lifecycle.test.ts +9 -3
  325. package/src/tests/claude-thinking-tokens.test.ts +57 -0
  326. package/src/tests/claude-worker-parity.test.ts +2 -7
  327. package/src/tests/config-env-export-chat-sdk.test.ts +11 -0
  328. package/src/tests/config-refs.test.ts +66 -0
  329. package/src/tests/context-key.test.ts +19 -0
  330. package/src/tests/cors-allowlist.test.ts +25 -0
  331. package/src/tests/create-page-tool.test.ts +18 -0
  332. package/src/tests/credential-check.test.ts +139 -0
  333. package/src/tests/credentials.test.ts +21 -0
  334. package/src/tests/db-runtime.test.ts +61 -0
  335. package/src/tests/db-task-read-contract.test.ts +22 -0
  336. package/src/tests/db-task-write-contract.test.ts +11 -0
  337. package/src/tests/deferred-task-wake.test.ts +78 -1
  338. package/src/tests/docs-index-footprint.test.js +3 -3
  339. package/src/tests/dsh-adapter.test.ts +1 -1
  340. package/src/tests/enabled-capabilities.test.ts +20 -0
  341. package/src/tests/entrypoint-api-readiness.test.ts +14 -8
  342. package/src/tests/entrypoint-config-env-export.test.ts +5 -2
  343. package/src/tests/entrypoint-export-to-env.test.ts +78 -0
  344. package/src/tests/env-flag.test.ts +1 -0
  345. package/src/tests/explicit-model-validation.test.ts +105 -1
  346. package/src/tests/extensions-catalog.test.ts +1 -0
  347. package/src/tests/extensions-example-comms-adherence-gate.test.ts +413 -0
  348. package/src/tests/extensions-example-route-chat-channel.test.ts +154 -0
  349. package/src/tests/extensions-loader.test.ts +15 -0
  350. package/src/tests/extensions-post-bridge.test.ts +51 -0
  351. package/src/tests/fetch-resolved-env.test.ts +128 -0
  352. package/src/tests/fixtures/chat-sdk/telegram-private-text.json +10 -0
  353. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/hooks.ts +27 -0
  354. package/src/tests/fixtures/extensions/route-chat-channel-to-agent/manifest.json +9 -0
  355. package/src/tests/fixtures/openai-compatible-registry-extension.child.ts +146 -0
  356. package/src/tests/fixtures/runner-legacy-resume-prompt.ts +122 -0
  357. package/src/tests/github-handlers.test.ts +35 -0
  358. package/src/tests/harness-provider-resolution.test.ts +12 -0
  359. package/src/tests/heartbeat-checklist.test.ts +3 -2
  360. package/src/tests/heartbeat-jev-gate-credentials.test.ts +168 -0
  361. package/src/tests/heartbeat-jev-gate.test.ts +385 -0
  362. package/src/tests/hook-runtime-close.test.ts +0 -2
  363. package/src/tests/http-api-integration.test.ts +0 -25
  364. package/src/tests/migration-046-budgets.test.ts +17 -16
  365. package/src/tests/migration-217-chat-sdk-state.test.ts +113 -0
  366. package/src/tests/model-profile-backcompat.test.ts +327 -0
  367. package/src/tests/model-profile-providers.test.ts +302 -0
  368. package/src/tests/model-profile-runtime-secrets.test.ts +223 -0
  369. package/src/tests/model-profiles-api.test.ts +614 -0
  370. package/src/tests/model-tier-resolution.test.ts +93 -0
  371. package/src/tests/models-catalog.test.ts +42 -1
  372. package/src/tests/openai-compatible-providers.test.ts +134 -0
  373. package/src/tests/openai-compatible-registry-extension.test.ts +42 -0
  374. package/src/tests/opencode-adapter.test.ts +216 -2
  375. package/src/tests/opencode-helmcode-sdk.test.ts +201 -0
  376. package/src/tests/opencode-shell-env.test.ts +145 -0
  377. package/src/tests/openrouter-base-url.test.ts +101 -151
  378. package/src/tests/page-proxy.test.ts +1 -1
  379. package/src/tests/pages-browser-sdk.test.ts +76 -0
  380. package/src/tests/pages-feedback-keys.test.ts +121 -0
  381. package/src/tests/pages-feedback.test.ts +4 -1
  382. package/src/tests/paused-tasks-requested-by.test.ts +102 -0
  383. package/src/tests/pi-context-compaction.test.ts +193 -0
  384. package/src/tests/pi-custom-provider-fake-server.test.ts +442 -0
  385. package/src/tests/pi-mono-adapter.test.ts +385 -5
  386. package/src/tests/pi-shell-env.test.ts +170 -0
  387. package/src/tests/profile-claim.test.ts +269 -0
  388. package/src/tests/prompt-template-remaining.test.ts +35 -0
  389. package/src/tests/quickjs-compat.test.ts +213 -0
  390. package/src/tests/rbac-engine.test.ts +32 -3
  391. package/src/tests/runner-exit-after-tasks.test.ts +0 -4
  392. package/src/tests/runner-legacy-resume-prompt.test.ts +64 -0
  393. package/src/tests/script-connections.test.ts +6 -0
  394. package/src/tests/script-executor-conformance.test.ts +252 -1
  395. package/src/tests/script-executor-quickjs.test.ts +96 -0
  396. package/src/tests/script-runs-http.test.ts +89 -0
  397. package/src/tests/scripts-http.test.ts +217 -1
  398. package/src/tests/scripts-only-gating.test.ts +2 -3
  399. package/src/tests/scripts-runtime.test.ts +58 -40
  400. package/src/tests/secret-scrubber.test.ts +96 -0
  401. package/src/tests/seed-model-profiles.test.ts +174 -0
  402. package/src/tests/seed-scripts.test.ts +2 -2
  403. package/src/tests/seed-skills-bundled-files.test.ts +45 -53
  404. package/src/tests/seed-skills-retire.test.ts +182 -0
  405. package/src/tests/send-task-requester-gate.test.ts +58 -0
  406. package/src/tests/session-cost-recompute-unit.test.ts +46 -0
  407. package/src/tests/skill-get-name-resolution.test.ts +137 -0
  408. package/src/tests/skill-invocations.test.ts +4 -2
  409. package/src/tests/slack-blocks.test.ts +36 -0
  410. package/src/tests/slack-inline-output.test.ts +14 -0
  411. package/src/tests/slack-reaction-config.test.ts +20 -0
  412. package/src/tests/slack-render-v2.test.ts +37 -0
  413. package/src/tests/slack-thread-buffer.test.ts +98 -1
  414. package/src/tests/sonnet-5-5-registry.test.ts +9 -1
  415. package/src/tests/swarm-config-export-to-env.test.ts +267 -0
  416. package/src/tests/swarm-config-reserved-keys.test.ts +16 -0
  417. package/src/tests/swarm-diff.test.ts +1 -1
  418. package/src/tests/task-model-effort-rerun.test.ts +164 -0
  419. package/src/tests/task-session-prompts.test.ts +132 -0
  420. package/src/tests/task-tool-manifest.test.ts +14 -0
  421. package/src/tests/task-tools-ctx.test.ts +2 -0
  422. package/src/tests/tool-annotations.test.ts +6 -6
  423. package/src/tests/ui-logs-parser.test.ts +43 -0
  424. package/src/tests/used-by-route.test.ts +6 -0
  425. package/src/tests/vercel-ai-gateway.test.ts +149 -0
  426. package/src/tests/workflow-llm.test.ts +61 -0
  427. package/src/tests/workflow-swarm-script.test.ts +38 -0
  428. package/src/tests/workflow-wait-filter.test.ts +5 -3
  429. package/src/tools/chat-access.ts +41 -0
  430. package/src/tools/chat-open-dm.ts +59 -0
  431. package/src/tools/chat-post.ts +74 -0
  432. package/src/tools/chat-read-thread.ts +100 -0
  433. package/src/tools/chat-reply.ts +75 -0
  434. package/src/tools/create-page.ts +3 -13
  435. package/src/tools/model-catalog/index.ts +2 -1
  436. package/src/tools/model-profiles/list-model-profiles.ts +54 -0
  437. package/src/tools/register-chat-channel.ts +139 -0
  438. package/src/tools/request-human-input.ts +11 -3
  439. package/src/tools/script-apis.ts +5 -1
  440. package/src/tools/script-upsert.ts +4 -1
  441. package/src/tools/send-task.ts +48 -1
  442. package/src/tools/skills/skill-get.ts +17 -9
  443. package/src/tools/swarm-config/get-config.ts +2 -1
  444. package/src/tools/swarm-config/list-config.ts +2 -1
  445. package/src/tools/swarm-config/set-config.ts +16 -3
  446. package/src/tools/system-one-decide.ts +104 -0
  447. package/src/tools/task-action.ts +22 -1
  448. package/src/tools/tool-config.ts +14 -6
  449. package/src/types.ts +48 -3
  450. package/src/utils/config-env-export.ts +74 -0
  451. package/src/utils/credentials.test.ts +92 -0
  452. package/src/utils/credentials.ts +52 -4
  453. package/src/utils/harness-provider.ts +15 -6
  454. package/src/utils/runtime-model-catalog.ts +11 -1
  455. package/src/utils/secret-scrubber.ts +86 -10
  456. package/src/utils/task-tool-manifest.ts +19 -2
  457. package/src/utils/vcs-repo-match.ts +29 -0
  458. package/src/workflows/executors/raw-llm.ts +8 -3
  459. package/src/workflows/executors/swarm-script.ts +1 -0
  460. package/src/workflows/executors/system-one-decision.ts +21 -11
  461. package/src/workflows/executors/workflow-llm.ts +22 -0
  462. package/src/workflows/index.ts +21 -12
  463. package/templates/extensions/README.md +1 -0
  464. package/templates/extensions/comms-adherence-gate/README.md +88 -0
  465. package/templates/extensions/comms-adherence-gate/hooks.ts +489 -0
  466. package/templates/extensions/comms-adherence-gate/manifest.json +8 -0
  467. package/templates/skills/agent-browser/SKILL.md +1 -1
  468. package/templates/skills/agent-browser/content.md +1 -1
  469. package/templates/skills/apps/SKILL.md +8 -1
  470. package/templates/skills/apps/content.md +8 -1
  471. package/templates/skills/chat-sdk/config.json +14 -0
  472. package/templates/skills/chat-sdk/content.md +84 -0
  473. package/templates/skills/composio-gmail/content.md +7 -0
  474. package/templates/skills/composio-google-docs/content.md +1 -1
  475. package/templates/skills/email-domain-health/config.json +14 -0
  476. package/templates/skills/email-domain-health/content.md +131 -0
  477. package/templates/skills/kv-storage/content.md +2 -2
  478. package/templates/skills/pages/content.md +8 -10
  479. package/templates/skills/swarm-extensions/content.md +2 -0
  480. package/templates/skills/swarm-scripts/SKILL.md +4 -2
  481. package/templates/skills/swarm-scripts/config.json +1 -1
  482. package/templates/skills/swarm-scripts/content.md +4 -2
  483. package/templates/skills/workflow-iterate/content.md +38 -0
  484. package/dist/artifact-eczsknc3.js +0 -3843
  485. package/dist/cli-42qhyvwx.js +0 -33
  486. package/dist/cli-bd957dgb.js +0 -153
  487. package/dist/cli-q51yprfq.js +0 -1104
  488. package/dist/cli-t1ze64h3.js +0 -811
  489. package/dist/cli-tcc4wd5d.js +0 -56471
  490. package/dist/index-9ch1n761.js +0 -1102
  491. package/src/artifact-sdk/index.ts +0 -2
  492. package/src/artifact-sdk/localtunnel.d.ts +0 -20
  493. package/src/artifact-sdk/port.ts +0 -12
  494. package/src/artifact-sdk/server.ts +0 -183
  495. package/src/artifact-sdk/tunnel.ts +0 -19
  496. package/src/commands/artifact.ts +0 -249
  497. package/src/http/ecosystem.ts +0 -77
  498. package/src/tests/artifact-commands.test.ts +0 -92
  499. package/src/tests/artifact-sdk.test.ts +0 -793
  500. package/src/tests/register-service-security.test.ts +0 -194
  501. package/src/tools/list-services.ts +0 -107
  502. package/src/tools/register-service.ts +0 -177
  503. package/src/tools/unregister-service.ts +0 -73
  504. package/src/tools/update-service-status.ts +0 -96
  505. package/templates/skills/artifacts/config.json +0 -14
  506. package/templates/skills/artifacts/content.md +0 -344
  507. package/templates/skills/artifacts/files/examples/approval-flow.ts +0 -34
  508. package/templates/skills/artifacts/files/examples/hono-dashboard.ts +0 -31
  509. package/templates/skills/artifacts/files/examples/multi-artifact.ts +0 -20
  510. package/templates/skills/artifacts/files/examples/static-report.sh +0 -17
  511. /package/src/{artifact-sdk → pages}/browser-sdk.ts +0 -0
@@ -0,0 +1,1041 @@
1
+ /**
2
+ * Pure-JS web globals that the QuickJS build lacks: `URL`, `URLSearchParams`,
3
+ * `TextEncoder`, `TextDecoder` (UTF-8 only), `atob` and `btoa`. The quickjs runner evaluates
4
+ * this before `SANDBOX_PRELUDE`, so the prelude's fetch can serialize a
5
+ * `URLSearchParams` body. Nothing here calls the host.
6
+ *
7
+ * `URL` follows the WHATWG URL parser for what scripts use: special and
8
+ * non-special schemes, relative resolution, dot segments, percent-encoding,
9
+ * IPv4/IPv6 hosts and punycode for non-ASCII labels. It skips the full UTS #46
10
+ * mapping (hosts are lowercased and NFC-normalized only) and Windows drive
11
+ * letters in `file:` URLs.
12
+ */
13
+ export const SANDBOX_WEB_SHIMS = String.raw`(() => {
14
+ "use strict";
15
+
16
+ // ── UTF-8 ──
17
+ const utf8Encode = (input) => {
18
+ const str = String(input);
19
+ const out = [];
20
+ for (let i = 0; i < str.length; i++) {
21
+ let c = str.charCodeAt(i);
22
+ if (c >= 0xd800 && c <= 0xdbff && i + 1 < str.length) {
23
+ const d = str.charCodeAt(i + 1);
24
+ if (d >= 0xdc00 && d <= 0xdfff) {
25
+ c = 0x10000 + ((c - 0xd800) << 10) + (d - 0xdc00);
26
+ i++;
27
+ } else c = 0xfffd;
28
+ } else if (c >= 0xd800 && c <= 0xdfff) c = 0xfffd;
29
+ if (c < 0x80) out.push(c);
30
+ else if (c < 0x800) out.push(0xc0 | (c >> 6), 0x80 | (c & 63));
31
+ else if (c < 0x10000) out.push(0xe0 | (c >> 12), 0x80 | ((c >> 6) & 63), 0x80 | (c & 63));
32
+ else out.push(0xf0 | (c >> 18), 0x80 | ((c >> 12) & 63), 0x80 | ((c >> 6) & 63), 0x80 | (c & 63));
33
+ }
34
+ return new Uint8Array(out);
35
+ };
36
+
37
+ const INVALID_UTF8 = "The encoded data was not valid for encoding utf-8";
38
+
39
+ // WHATWG UTF-8 decode: one U+FFFD per maximal invalid subpart. With stream,
40
+ // an incomplete trailing sequence is returned as pending instead.
41
+ const utf8Decode = (bytes, fatal, stream) => {
42
+ const parts = [];
43
+ let units = [];
44
+ const flush = () => {
45
+ if (units.length) parts.push(String.fromCharCode.apply(null, units));
46
+ units = [];
47
+ };
48
+ const push = (cp) => {
49
+ if (cp > 0xffff) {
50
+ cp -= 0x10000;
51
+ units.push(0xd800 + (cp >> 10), 0xdc00 + (cp & 0x3ff));
52
+ } else units.push(cp);
53
+ if (units.length >= 8192) flush();
54
+ };
55
+ const n = bytes.length;
56
+ let i = 0;
57
+ let pending = null;
58
+ while (i < n) {
59
+ const b = bytes[i];
60
+ if (b < 0x80) {
61
+ push(b);
62
+ i++;
63
+ continue;
64
+ }
65
+ let need = 0;
66
+ let cp = 0;
67
+ let lower = 0x80;
68
+ let upper = 0xbf;
69
+ if (b >= 0xc2 && b <= 0xdf) {
70
+ need = 1;
71
+ cp = b & 0x1f;
72
+ } else if (b >= 0xe0 && b <= 0xef) {
73
+ need = 2;
74
+ cp = b & 0xf;
75
+ if (b === 0xe0) lower = 0xa0;
76
+ if (b === 0xed) upper = 0x9f;
77
+ } else if (b >= 0xf0 && b <= 0xf4) {
78
+ need = 3;
79
+ cp = b & 7;
80
+ if (b === 0xf0) lower = 0x90;
81
+ if (b === 0xf4) upper = 0x8f;
82
+ } else {
83
+ if (fatal) throw new TypeError(INVALID_UTF8);
84
+ push(0xfffd);
85
+ i++;
86
+ continue;
87
+ }
88
+ let j = 1;
89
+ for (; j <= need; j++) {
90
+ if (i + j >= n) break;
91
+ const c = bytes[i + j];
92
+ if (c < lower || c > upper) break;
93
+ lower = 0x80;
94
+ upper = 0xbf;
95
+ cp = (cp << 6) | (c & 63);
96
+ }
97
+ if (j > need) {
98
+ push(cp);
99
+ i += need + 1;
100
+ continue;
101
+ }
102
+ if (i + j >= n && stream) {
103
+ pending = bytes.slice(i);
104
+ break;
105
+ }
106
+ if (fatal) throw new TypeError(INVALID_UTF8);
107
+ push(0xfffd);
108
+ i += j;
109
+ }
110
+ flush();
111
+ return { text: parts.join(""), pending };
112
+ };
113
+
114
+ const toBytes = (input) => {
115
+ if (input === undefined) return new Uint8Array(0);
116
+ if (input instanceof ArrayBuffer) return new Uint8Array(input);
117
+ if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
118
+ throw new TypeError("The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
119
+ };
120
+
121
+ class TextEncoder {
122
+ get encoding() {
123
+ return "utf-8";
124
+ }
125
+ encode(input = "") {
126
+ return utf8Encode(input);
127
+ }
128
+ encodeInto(source, destination) {
129
+ const str = String(source);
130
+ let read = 0;
131
+ let written = 0;
132
+ for (const char of str) {
133
+ const bytes = utf8Encode(char);
134
+ if (written + bytes.length > destination.length) break;
135
+ destination.set(bytes, written);
136
+ written += bytes.length;
137
+ read += char.length;
138
+ }
139
+ return { read, written };
140
+ }
141
+ }
142
+
143
+ const UTF8_LABELS = ["utf-8", "utf8", "unicode-1-1-utf-8"];
144
+ class TextDecoder {
145
+ constructor(label = "utf-8", options = {}) {
146
+ if (!UTF8_LABELS.includes(String(label).trim().toLowerCase())) {
147
+ throw new RangeError("quickjs executor: TextDecoder supports utf-8 only, not " + JSON.stringify(String(label)));
148
+ }
149
+ this._fatal = Boolean(options && options.fatal);
150
+ this._ignoreBOM = Boolean(options && options.ignoreBOM);
151
+ this._pending = null;
152
+ this._started = false;
153
+ }
154
+ get encoding() {
155
+ return "utf-8";
156
+ }
157
+ get fatal() {
158
+ return this._fatal;
159
+ }
160
+ get ignoreBOM() {
161
+ return this._ignoreBOM;
162
+ }
163
+ decode(input, options) {
164
+ const stream = Boolean(options && options.stream);
165
+ let bytes = toBytes(input);
166
+ if (this._pending) {
167
+ const joined = new Uint8Array(this._pending.length + bytes.length);
168
+ joined.set(this._pending);
169
+ joined.set(bytes, this._pending.length);
170
+ bytes = joined;
171
+ }
172
+ let decoded;
173
+ try {
174
+ decoded = utf8Decode(bytes, this._fatal, stream);
175
+ } catch (error) {
176
+ this._pending = null;
177
+ this._started = false;
178
+ throw error;
179
+ }
180
+ let text = decoded.text;
181
+ if (!this._started && text.length > 0) {
182
+ if (!this._ignoreBOM && text.charCodeAt(0) === 0xfeff) text = text.slice(1);
183
+ this._started = true;
184
+ }
185
+ this._pending = decoded.pending;
186
+ if (!stream) {
187
+ this._pending = null;
188
+ this._started = false;
189
+ }
190
+ return text;
191
+ }
192
+ }
193
+
194
+ // ── percent-encoding ──
195
+ const HEX = "0123456789ABCDEF";
196
+ const hexByte = (b) => "%" + HEX[b >> 4] + HEX[b & 15];
197
+ const inSet = (chars) => (c) => c < 0x20 || c > 0x7e || chars.includes(String.fromCharCode(c));
198
+ const C0_SET = inSet("");
199
+ const FRAGMENT_SET = inSet(' "<>' + "\x60");
200
+ const QUERY_SET = inSet(' "#<>');
201
+ const SPECIAL_QUERY_SET = inSet(' "#<>' + "'");
202
+ const PATH_SET = inSet(' "#<>?^{}' + "\x60");
203
+ const USERINFO_SET = inSet(' "#<>?^{}/:;=@[\\]|' + "\x60");
204
+ const percentEncode = (input, set) => {
205
+ let out = "";
206
+ for (const char of String(input)) {
207
+ const code = char.codePointAt(0);
208
+ if (code < 0x80 && !set(code)) out += char;
209
+ else if (code < 0x80) out += hexByte(code);
210
+ else for (const b of utf8Encode(char)) out += hexByte(b);
211
+ }
212
+ return out;
213
+ };
214
+ const isHex = (c) => /^[0-9A-Fa-f]$/.test(c);
215
+ const percentDecodeBytes = (input) => {
216
+ const out = [];
217
+ for (let i = 0; i < input.length; i++) {
218
+ const ch = input[i];
219
+ if (ch === "%" && i + 2 < input.length && isHex(input[i + 1]) && isHex(input[i + 2])) {
220
+ out.push(parseInt(input.slice(i + 1, i + 3), 16));
221
+ i += 2;
222
+ } else {
223
+ let end = i;
224
+ while (end < input.length && input[end] !== "%") end++;
225
+ if (end === i) end = i + 1;
226
+ for (const b of utf8Encode(input.slice(i, end))) out.push(b);
227
+ i = end - 1;
228
+ }
229
+ }
230
+ return new Uint8Array(out);
231
+ };
232
+ const percentDecode = (input) => utf8Decode(percentDecodeBytes(input), false, false).text;
233
+
234
+ // ── URLSearchParams ──
235
+ const formEncode = (input) => {
236
+ let out = "";
237
+ for (const b of utf8Encode(input)) {
238
+ if (b === 0x20) out += "+";
239
+ else if (
240
+ (b >= 0x30 && b <= 0x39) || (b >= 0x41 && b <= 0x5a) || (b >= 0x61 && b <= 0x7a) ||
241
+ b === 0x2a || b === 0x2d || b === 0x2e || b === 0x5f
242
+ ) out += String.fromCharCode(b);
243
+ else out += hexByte(b);
244
+ }
245
+ return out;
246
+ };
247
+ const parseQuery = (input) => {
248
+ const list = [];
249
+ for (const piece of input.split("&")) {
250
+ if (piece === "") continue;
251
+ const eq = piece.indexOf("=");
252
+ const name = eq === -1 ? piece : piece.slice(0, eq);
253
+ const value = eq === -1 ? "" : piece.slice(eq + 1);
254
+ list.push([percentDecode(name.replace(/\+/g, " ")), percentDecode(value.replace(/\+/g, " "))]);
255
+ }
256
+ return list;
257
+ };
258
+ const toUSVString = (value) => utf8Decode(utf8Encode(value), false, false).text;
259
+ const liveIterator = (params, pick) => {
260
+ let index = 0;
261
+ return {
262
+ next() {
263
+ if (index >= params._list.length) return { value: undefined, done: true };
264
+ return { value: pick(params._list[index++]), done: false };
265
+ },
266
+ [Symbol.iterator]() {
267
+ return this;
268
+ },
269
+ };
270
+ };
271
+
272
+ class URLSearchParams {
273
+ constructor(init) {
274
+ this._list = [];
275
+ this._url = null;
276
+ if (init == null) return;
277
+ if (typeof init === "object" || typeof init === "function") {
278
+ if (typeof init[Symbol.iterator] === "function") {
279
+ for (const pair of init) {
280
+ const entry = Array.from(pair);
281
+ if (entry.length !== 2) throw new TypeError("Each query pair must be an iterable [name, value] tuple");
282
+ this._list.push([toUSVString(entry[0]), toUSVString(entry[1])]);
283
+ }
284
+ } else {
285
+ for (const key of Object.keys(init)) this._list.push([toUSVString(key), toUSVString(init[key])]);
286
+ }
287
+ return;
288
+ }
289
+ const text = String(init);
290
+ this._list = parseQuery(text.startsWith("?") ? text.slice(1) : text);
291
+ }
292
+ _update() {
293
+ if (!this._url) return;
294
+ const serialized = this.toString();
295
+ this._url._record.query = serialized === "" ? null : serialized;
296
+ }
297
+ get size() {
298
+ return this._list.length;
299
+ }
300
+ append(name, value) {
301
+ this._list.push([toUSVString(name), toUSVString(value)]);
302
+ this._update();
303
+ }
304
+ delete(name, value) {
305
+ const key = toUSVString(name);
306
+ const match = value === undefined ? null : toUSVString(value);
307
+ this._list = this._list.filter(([k, v]) => !(k === key && (match === null || v === match)));
308
+ this._update();
309
+ }
310
+ get(name) {
311
+ const key = toUSVString(name);
312
+ const entry = this._list.find(([k]) => k === key);
313
+ return entry ? entry[1] : null;
314
+ }
315
+ getAll(name) {
316
+ const key = toUSVString(name);
317
+ return this._list.filter(([k]) => k === key).map(([, v]) => v);
318
+ }
319
+ has(name, value) {
320
+ const key = toUSVString(name);
321
+ const match = value === undefined ? null : toUSVString(value);
322
+ return this._list.some(([k, v]) => k === key && (match === null || v === match));
323
+ }
324
+ set(name, value) {
325
+ const key = toUSVString(name);
326
+ const index = this._list.findIndex(([k]) => k === key);
327
+ if (index === -1) this._list.push([key, toUSVString(value)]);
328
+ else {
329
+ this._list[index] = [key, toUSVString(value)];
330
+ this._list = this._list.filter(([k], i) => i <= index || k !== key);
331
+ }
332
+ this._update();
333
+ }
334
+ sort() {
335
+ this._list = this._list
336
+ .map((entry, index) => ({ entry, index }))
337
+ .sort((a, b) => (a.entry[0] < b.entry[0] ? -1 : a.entry[0] > b.entry[0] ? 1 : a.index - b.index))
338
+ .map(({ entry }) => entry);
339
+ this._update();
340
+ }
341
+ // Traversal is live, as in the spec: each step reads the current list, so
342
+ // entries appended or deleted during iteration are seen or skipped.
343
+ forEach(callback, thisArg) {
344
+ for (let i = 0; i < this._list.length; i++) {
345
+ const [k, v] = this._list[i];
346
+ callback.call(thisArg, v, k, this);
347
+ }
348
+ }
349
+ keys() {
350
+ return liveIterator(this, ([k]) => k);
351
+ }
352
+ values() {
353
+ return liveIterator(this, ([, v]) => v);
354
+ }
355
+ entries() {
356
+ return liveIterator(this, ([k, v]) => [k, v]);
357
+ }
358
+ [Symbol.iterator]() {
359
+ return this.entries();
360
+ }
361
+ toString() {
362
+ return this._list.map(([k, v]) => formEncode(k) + "=" + formEncode(v)).join("&");
363
+ }
364
+ }
365
+
366
+ // ── hosts ──
367
+ const punycode = (label) => {
368
+ const codes = Array.from(label).map((c) => c.codePointAt(0));
369
+ const base = 36, tMin = 1, tMax = 26, skew = 38, damp = 700;
370
+ let n = 128, delta = 0, bias = 72;
371
+ let out = codes.filter((c) => c < 128).map((c) => String.fromCharCode(c)).join("");
372
+ const basic = out.length;
373
+ let handled = basic;
374
+ if (basic > 0) out += "-";
375
+ const digit = (d) => String.fromCharCode(d + 22 + (d < 26 ? 75 : 0));
376
+ const adapt = (d, points, first) => {
377
+ d = first ? Math.floor(d / damp) : d >> 1;
378
+ d += Math.floor(d / points);
379
+ let k = 0;
380
+ while (d > ((base - tMin) * tMax) >> 1) {
381
+ d = Math.floor(d / (base - tMin));
382
+ k += base;
383
+ }
384
+ return k + Math.floor(((base - tMin + 1) * d) / (d + skew));
385
+ };
386
+ while (handled < codes.length) {
387
+ let m = Infinity;
388
+ for (const c of codes) if (c >= n && c < m) m = c;
389
+ delta += (m - n) * (handled + 1);
390
+ n = m;
391
+ for (const c of codes) {
392
+ if (c < n) delta++;
393
+ if (c !== n) continue;
394
+ let q = delta;
395
+ for (let k = base; ; k += base) {
396
+ const t = k <= bias ? tMin : k >= bias + tMax ? tMax : k - bias;
397
+ if (q < t) break;
398
+ out += digit(t + ((q - t) % (base - t)));
399
+ q = Math.floor((q - t) / (base - t));
400
+ }
401
+ out += digit(q);
402
+ bias = adapt(delta, handled + 1, handled === basic);
403
+ delta = 0;
404
+ handled++;
405
+ }
406
+ delta++;
407
+ n++;
408
+ }
409
+ return out;
410
+ };
411
+
412
+ const parseIPv4Number = (input) => {
413
+ let text = input;
414
+ let radix = 10;
415
+ if (/^0[xX]/.test(text)) {
416
+ text = text.slice(2);
417
+ radix = 16;
418
+ } else if (text.length > 1 && text[0] === "0") {
419
+ text = text.slice(1);
420
+ radix = 8;
421
+ }
422
+ if (text === "") return 0;
423
+ const valid = radix === 16 ? /^[0-9A-Fa-f]+$/ : radix === 8 ? /^[0-7]+$/ : /^[0-9]+$/;
424
+ return valid.test(text) ? parseInt(text, radix) : NaN;
425
+ };
426
+ const endsInNumber = (host) => {
427
+ const parts = host.split(".");
428
+ if (parts[parts.length - 1] === "") {
429
+ if (parts.length === 1) return false;
430
+ parts.pop();
431
+ }
432
+ const last = parts[parts.length - 1];
433
+ return /^[0-9]+$/.test(last) || /^0[xX][0-9A-Fa-f]*$/.test(last);
434
+ };
435
+ const parseIPv4 = (host) => {
436
+ const parts = host.split(".");
437
+ if (parts[parts.length - 1] === "" && parts.length > 1) parts.pop();
438
+ if (parts.length > 4 || parts.some((part) => part === "")) return null;
439
+ const numbers = parts.map(parseIPv4Number);
440
+ if (numbers.some((value) => Number.isNaN(value))) return null;
441
+ const last = numbers[numbers.length - 1];
442
+ if (numbers.slice(0, -1).some((value) => value > 255)) return null;
443
+ if (last >= 256 ** (5 - numbers.length)) return null;
444
+ let address = last;
445
+ numbers.slice(0, -1).forEach((value, index) => {
446
+ address += value * 256 ** (3 - index);
447
+ });
448
+ const octets = [];
449
+ for (let i = 0; i < 4; i++) {
450
+ octets.unshift(address % 256);
451
+ address = Math.floor(address / 256);
452
+ }
453
+ return octets.join(".");
454
+ };
455
+
456
+ const parseIPv6 = (input) => {
457
+ const address = [0, 0, 0, 0, 0, 0, 0, 0];
458
+ let piece = 0;
459
+ let compress = null;
460
+ let p = 0;
461
+ const at = (i) => (i < input.length ? input[i] : "");
462
+ const isDigit = (c) => c >= "0" && c <= "9" && c !== "";
463
+ if (at(p) === ":") {
464
+ if (at(p + 1) !== ":") return null;
465
+ p += 2;
466
+ piece++;
467
+ compress = piece;
468
+ }
469
+ while (p < input.length) {
470
+ if (piece === 8) return null;
471
+ if (at(p) === ":") {
472
+ if (compress !== null) return null;
473
+ p++;
474
+ piece++;
475
+ compress = piece;
476
+ continue;
477
+ }
478
+ let value = 0;
479
+ let length = 0;
480
+ while (length < 4 && isHex(at(p))) {
481
+ value = value * 16 + parseInt(at(p), 16);
482
+ p++;
483
+ length++;
484
+ }
485
+ if (at(p) === ".") {
486
+ if (length === 0) return null;
487
+ p -= length;
488
+ if (piece > 6) return null;
489
+ let seen = 0;
490
+ while (p < input.length) {
491
+ let part = null;
492
+ if (seen > 0) {
493
+ if (at(p) === "." && seen < 4) p++;
494
+ else return null;
495
+ }
496
+ if (!isDigit(at(p))) return null;
497
+ while (isDigit(at(p))) {
498
+ const digit = Number(at(p));
499
+ if (part === null) part = digit;
500
+ else if (part === 0) return null;
501
+ else part = part * 10 + digit;
502
+ if (part > 255) return null;
503
+ p++;
504
+ }
505
+ address[piece] = address[piece] * 256 + part;
506
+ seen++;
507
+ if (seen === 2 || seen === 4) piece++;
508
+ }
509
+ if (seen !== 4) return null;
510
+ break;
511
+ } else if (at(p) === ":") {
512
+ p++;
513
+ if (p >= input.length) return null;
514
+ } else if (p < input.length) return null;
515
+ address[piece] = value;
516
+ piece++;
517
+ }
518
+ if (compress !== null) {
519
+ let swaps = piece - compress;
520
+ piece = 7;
521
+ while (piece !== 0 && swaps > 0) {
522
+ const other = compress + swaps - 1;
523
+ const tmp = address[piece];
524
+ address[piece] = address[other];
525
+ address[other] = tmp;
526
+ piece--;
527
+ swaps--;
528
+ }
529
+ } else if (piece !== 8) return null;
530
+ return address;
531
+ };
532
+ const serializeIPv6 = (address) => {
533
+ let best = -1;
534
+ let bestLength = 1;
535
+ for (let i = 0; i < 8; ) {
536
+ if (address[i] !== 0) {
537
+ i++;
538
+ continue;
539
+ }
540
+ let j = i;
541
+ while (j < 8 && address[j] === 0) j++;
542
+ if (j - i > bestLength) {
543
+ best = i;
544
+ bestLength = j - i;
545
+ }
546
+ i = j;
547
+ }
548
+ let out = "";
549
+ for (let i = 0; i < 8; i++) {
550
+ if (best !== -1 && i >= best && i < best + bestLength) {
551
+ if (i === best) out += i === 0 ? "::" : ":";
552
+ continue;
553
+ }
554
+ out += address[i].toString(16);
555
+ if (i !== 7) out += ":";
556
+ }
557
+ return "[" + out + "]";
558
+ };
559
+
560
+ const FORBIDDEN_HOST = /[\u0000\t\n\r #/:<>?@[\\\]^|]/;
561
+ const FORBIDDEN_DOMAIN = /[\u0000-\u001f #%/:<>?@[\\\]^|\u007f]/;
562
+ const invalid = (input) => new TypeError("Invalid URL: " + JSON.stringify(String(input)));
563
+
564
+ const parseHost = (input, special, original) => {
565
+ if (input.startsWith("[")) {
566
+ if (!input.endsWith("]")) throw invalid(original);
567
+ const address = parseIPv6(input.slice(1, -1));
568
+ if (!address) throw invalid(original);
569
+ return serializeIPv6(address);
570
+ }
571
+ if (!special) {
572
+ if (FORBIDDEN_HOST.test(input)) throw invalid(original);
573
+ return percentEncode(input, C0_SET);
574
+ }
575
+ let domain = percentDecode(input);
576
+ if (typeof domain.normalize === "function") domain = domain.normalize("NFC");
577
+ domain = domain.toLowerCase().replace(/[。.。]/g, ".");
578
+ const ascii = domain
579
+ .split(".")
580
+ .map((label) => (/[^\u0000-\u007f]/.test(label) ? "xn--" + punycode(label) : label))
581
+ .join(".");
582
+ if (ascii === "" || FORBIDDEN_DOMAIN.test(ascii)) throw invalid(original);
583
+ if (endsInNumber(ascii)) {
584
+ const ipv4 = parseIPv4(ascii);
585
+ if (ipv4 === null) throw invalid(original);
586
+ return ipv4;
587
+ }
588
+ return ascii;
589
+ };
590
+
591
+ // ── URL ──
592
+ const SPECIAL_PORTS = { "ftp": "21", "file": "", "http": "80", "https": "443", "ws": "80", "wss": "443" };
593
+ const isSpecial = (scheme) => Object.prototype.hasOwnProperty.call(SPECIAL_PORTS, scheme);
594
+ const isSingleDot = (segment) => segment === "." || segment.toLowerCase() === "%2e";
595
+ const isDoubleDot = (segment) => /^(\.|%2e)(\.|%2e)$/i.test(segment);
596
+
597
+ // Appends raw path segments to a path list, resolving dot segments.
598
+ const appendSegments = (path, segments) => {
599
+ segments.forEach((segment, index) => {
600
+ const last = index === segments.length - 1;
601
+ if (isDoubleDot(segment)) {
602
+ if (path.length > 0) path.pop();
603
+ if (last) path.push("");
604
+ } else if (isSingleDot(segment)) {
605
+ if (last) path.push("");
606
+ } else path.push(percentEncode(segment, PATH_SET));
607
+ });
608
+ return path;
609
+ };
610
+
611
+ // Splits "rest" into path, query and fragment, in that order.
612
+ const splitTail = (rest) => {
613
+ let fragment = null;
614
+ let query = null;
615
+ const hash = rest.indexOf("#");
616
+ if (hash !== -1) {
617
+ fragment = rest.slice(hash + 1);
618
+ rest = rest.slice(0, hash);
619
+ }
620
+ const question = rest.indexOf("?");
621
+ if (question !== -1) {
622
+ query = rest.slice(question + 1);
623
+ rest = rest.slice(0, question);
624
+ }
625
+ return { path: rest, query, fragment };
626
+ };
627
+
628
+ const encodeQuery = (query, special) => (query === null ? null : percentEncode(query, special ? SPECIAL_QUERY_SET : QUERY_SET));
629
+ const encodeFragment = (fragment) => (fragment === null ? null : percentEncode(fragment, FRAGMENT_SET));
630
+
631
+ // Parses "//authority/path?query#fragment" (slashes already stripped) into record.
632
+ const parseAuthorityAndTail = (record, input, original) => {
633
+ const special = isSpecial(record.scheme);
634
+ const end = input.search(special ? /[/\\?#]/ : /[/?#]/);
635
+ const authority = end === -1 ? input : input.slice(0, end);
636
+ const tail = end === -1 ? "" : input.slice(end);
637
+ const at = authority.lastIndexOf("@");
638
+ let hostPort = authority;
639
+ record.username = "";
640
+ record.password = "";
641
+ if (at !== -1) {
642
+ const userinfo = authority.slice(0, at);
643
+ hostPort = authority.slice(at + 1);
644
+ const colon = userinfo.indexOf(":");
645
+ record.username = percentEncode(colon === -1 ? userinfo : userinfo.slice(0, colon), USERINFO_SET);
646
+ record.password = colon === -1 ? "" : percentEncode(userinfo.slice(colon + 1), USERINFO_SET);
647
+ }
648
+ let hostText = hostPort;
649
+ let port = "";
650
+ const close = hostPort.lastIndexOf("]");
651
+ const colon = hostPort.indexOf(":", close === -1 ? 0 : close);
652
+ if (colon !== -1) {
653
+ hostText = hostPort.slice(0, colon);
654
+ port = hostPort.slice(colon + 1);
655
+ }
656
+ if (record.scheme === "file") {
657
+ record.host = hostText === "" ? "" : parseHost(hostText, true, original);
658
+ if (record.host === "localhost") record.host = "";
659
+ } else if (hostText === "") {
660
+ if (special || at !== -1 || port !== "") throw invalid(original);
661
+ record.host = "";
662
+ } else record.host = parseHost(hostText, special, original);
663
+ if (port !== "") {
664
+ if (!/^[0-9]+$/.test(port)) throw invalid(original);
665
+ const value = Number(port);
666
+ if (value > 65535) throw invalid(original);
667
+ record.port = String(value) === SPECIAL_PORTS[record.scheme] ? "" : String(value);
668
+ } else record.port = "";
669
+ parseTail(record, tail);
670
+ };
671
+
672
+ // Parses an absolute path (or empty path) plus query and fragment.
673
+ const parseTail = (record, tail) => {
674
+ const special = isSpecial(record.scheme);
675
+ const parts = splitTail(tail);
676
+ let path = parts.path;
677
+ if (special) path = path.replace(/\\/g, "/");
678
+ if (path === "" && !special) record.path = [];
679
+ else {
680
+ const segments = (path.startsWith("/") ? path.slice(1) : path).split("/");
681
+ record.path = appendSegments([], segments);
682
+ }
683
+ record.query = encodeQuery(parts.query, special);
684
+ record.fragment = encodeFragment(parts.fragment);
685
+ };
686
+
687
+ const blankRecord = (scheme) => ({
688
+ scheme,
689
+ username: "",
690
+ password: "",
691
+ host: null,
692
+ port: "",
693
+ path: [],
694
+ opaque: false,
695
+ query: null,
696
+ fragment: null,
697
+ });
698
+
699
+ const parseRelative = (record, rest, base, original) => {
700
+ const special = isSpecial(record.scheme);
701
+ const slash = (c) => c === "/" || (special && c === "\\");
702
+ if (slash(rest[0] || "") && slash(rest[1] || "")) {
703
+ parseAuthorityAndTail(record, special ? rest.replace(/^[/\\]+/, "") : rest.slice(2), original);
704
+ return record;
705
+ }
706
+ record.username = base.username;
707
+ record.password = base.password;
708
+ record.host = base.host;
709
+ record.port = base.port;
710
+ if (slash(rest[0] || "")) {
711
+ parseTail(record, rest);
712
+ return record;
713
+ }
714
+ const parts = splitTail(rest);
715
+ record.fragment = encodeFragment(parts.fragment);
716
+ if (parts.path === "") {
717
+ record.path = base.path.slice();
718
+ record.query = parts.query === null ? base.query : encodeQuery(parts.query, special);
719
+ return record;
720
+ }
721
+ const relative = special ? parts.path.replace(/\\/g, "/") : parts.path;
722
+ record.path = appendSegments(base.path.slice(0, -1), relative.split("/"));
723
+ record.query = encodeQuery(parts.query, special);
724
+ return record;
725
+ };
726
+
727
+ const parseURL = (rawInput, base) => {
728
+ const input = String(rawInput)
729
+ .replace(/^[\u0000- ]+|[\u0000- ]+$/g, "")
730
+ .replace(/[\t\n\r]/g, "");
731
+ const schemeMatch = /^([A-Za-z][A-Za-z0-9+.\-]*):/.exec(input);
732
+ if (!schemeMatch) {
733
+ if (!base) throw invalid(rawInput);
734
+ if (base.opaque) {
735
+ if (!input.startsWith("#")) throw invalid(rawInput);
736
+ return { ...base, fragment: encodeFragment(input.slice(1)) };
737
+ }
738
+ return parseRelative(blankRecord(base.scheme), input, base, rawInput);
739
+ }
740
+ const record = blankRecord(schemeMatch[1].toLowerCase());
741
+ const rest = input.slice(schemeMatch[0].length);
742
+ if (isSpecial(record.scheme)) {
743
+ // Same special scheme as the base: "http:x", "http:/x" and "http:?q"
744
+ // resolve against the base; two slashes start a new authority.
745
+ if (base && base.scheme === record.scheme && (record.scheme !== "file" || !/^[/\\]/.test(rest))) {
746
+ return parseRelative(record, rest, base, rawInput);
747
+ }
748
+ if (record.scheme === "file") {
749
+ if (/^[/\\]{2}/.test(rest)) parseAuthorityAndTail(record, rest.slice(2), rawInput);
750
+ else {
751
+ record.host = "";
752
+ parseTail(record, rest);
753
+ }
754
+ return record;
755
+ }
756
+ parseAuthorityAndTail(record, rest.replace(/^[/\\]+/, ""), rawInput);
757
+ return record;
758
+ }
759
+ if (rest.startsWith("//")) {
760
+ parseAuthorityAndTail(record, rest.slice(2), rawInput);
761
+ return record;
762
+ }
763
+ if (rest.startsWith("/")) {
764
+ parseTail(record, rest);
765
+ return record;
766
+ }
767
+ const parts = splitTail(rest);
768
+ record.opaque = true;
769
+ record.path = percentEncode(parts.path, C0_SET);
770
+ record.query = encodeQuery(parts.query, false);
771
+ record.fragment = encodeFragment(parts.fragment);
772
+ return record;
773
+ };
774
+
775
+ const pathnameOf = (record) =>
776
+ record.opaque ? record.path : record.path.map((segment) => "/" + segment).join("");
777
+ const hostOf = (record) => (record.host === null ? "" : record.host + (record.port ? ":" + record.port : ""));
778
+ const hrefOf = (record) => {
779
+ let out = record.scheme + ":";
780
+ if (record.host !== null) {
781
+ out += "//";
782
+ if (record.username || record.password) {
783
+ out += record.username + (record.password ? ":" + record.password : "") + "@";
784
+ }
785
+ out += hostOf(record);
786
+ } else if (!record.opaque && record.path.length > 1 && record.path[0] === "") out += "/.";
787
+ out += pathnameOf(record);
788
+ if (record.query !== null) out += "?" + record.query;
789
+ if (record.fragment !== null) out += "#" + record.fragment;
790
+ return out;
791
+ };
792
+
793
+ // The host and hostname setters: the host state of the URL parser with a state
794
+ // override. Invalid input leaves the URL unchanged; it never throws. Where Bun
795
+ // departs from the spec, the host setter follows Bun (the native executor):
796
+ // it ignores input with a second ":" outside brackets, keeps the old port when
797
+ // the new one is the default, and clears the port when the new one is out of range.
798
+ const setHost = (record, value, withPort) => {
799
+ if (record.opaque) return;
800
+ const special = isSpecial(record.scheme);
801
+ const input = String(value).replace(/[\t\n\r]/g, "");
802
+ let end = 0;
803
+ let brackets = false;
804
+ let colons = 0;
805
+ let colon = -1;
806
+ for (let i = 0; i < input.length; i++) {
807
+ const c = input[i];
808
+ if (c === "[") brackets = true;
809
+ else if (c === "]") brackets = false;
810
+ else if (c === ":" && !brackets && record.scheme !== "file") colons++;
811
+ }
812
+ brackets = false;
813
+ for (; end < input.length; end++) {
814
+ const c = input[end];
815
+ if (c === "/" || c === "?" || c === "#" || (special && c === "\\")) break;
816
+ if (c === ":" && !brackets && record.scheme !== "file") {
817
+ colon = end;
818
+ break;
819
+ }
820
+ if (c === "[") brackets = true;
821
+ else if (c === "]") brackets = false;
822
+ }
823
+ const buffer = input.slice(0, end);
824
+ if (colon !== -1 && (!withPort || colons > 1)) return;
825
+ if (record.scheme === "file") {
826
+ if (buffer === "") {
827
+ record.host = "";
828
+ return;
829
+ }
830
+ } else if (buffer === "") {
831
+ if (special || colon !== -1) return;
832
+ if (record.username || record.password || record.port !== "") return;
833
+ }
834
+ let host;
835
+ try {
836
+ host = parseHost(buffer, special || record.scheme === "file", value);
837
+ } catch {
838
+ return;
839
+ }
840
+ record.host = record.scheme === "file" && host === "localhost" ? "" : host;
841
+ if (colon === -1) return;
842
+ const digits = /^[0-9]*/.exec(input.slice(colon + 1))[0];
843
+ if (digits === "") return;
844
+ const port = Number(digits);
845
+ if (port > 65535) record.port = "";
846
+ else if (String(port) !== SPECIAL_PORTS[record.scheme]) record.port = String(port);
847
+ };
848
+
849
+ class URL {
850
+ constructor(url, base) {
851
+ const baseRecord = base === undefined ? null : parseURL(base instanceof URL ? base.href : base, null);
852
+ this._record = parseURL(url, baseRecord);
853
+ this._params = null;
854
+ }
855
+ static canParse(url, base) {
856
+ try {
857
+ new URL(url, base);
858
+ return true;
859
+ } catch {
860
+ return false;
861
+ }
862
+ }
863
+ static parse(url, base) {
864
+ try {
865
+ return new URL(url, base);
866
+ } catch {
867
+ return null;
868
+ }
869
+ }
870
+ _syncParams() {
871
+ if (this._params) this._params._list = this._record.query ? parseQuery(this._record.query) : [];
872
+ }
873
+ get href() {
874
+ return hrefOf(this._record);
875
+ }
876
+ set href(value) {
877
+ this._record = parseURL(value, null);
878
+ this._syncParams();
879
+ }
880
+ get origin() {
881
+ const record = this._record;
882
+ if (record.scheme === "blob") {
883
+ const inner = URL.parse(pathnameOf(record));
884
+ return inner && (inner.protocol === "http:" || inner.protocol === "https:") ? inner.origin : "null";
885
+ }
886
+ if (!isSpecial(record.scheme) || record.scheme === "file") return "null";
887
+ return record.scheme + "://" + hostOf(record);
888
+ }
889
+ get protocol() {
890
+ return this._record.scheme + ":";
891
+ }
892
+ set protocol(value) {
893
+ // The scheme must end the input or be followed by ":"; anything else is invalid.
894
+ const match = /^([A-Za-z][A-Za-z0-9+.\-]*)(:|$)/.exec(String(value).replace(/[\t\n\r]/g, ""));
895
+ if (!match) return;
896
+ const scheme = match[1].toLowerCase();
897
+ if (isSpecial(scheme) !== isSpecial(this._record.scheme)) return;
898
+ if (scheme === "file" && (this._record.username || this._record.password || this._record.port)) return;
899
+ if (this._record.scheme === "file" && this._record.host === "") return;
900
+ this._record.scheme = scheme;
901
+ if (this._record.port === SPECIAL_PORTS[scheme]) this._record.port = "";
902
+ }
903
+ get username() {
904
+ return this._record.username;
905
+ }
906
+ set username(value) {
907
+ if (this._record.host === null || this._record.host === "" || this._record.scheme === "file") return;
908
+ this._record.username = percentEncode(value, USERINFO_SET);
909
+ }
910
+ get password() {
911
+ return this._record.password;
912
+ }
913
+ set password(value) {
914
+ if (this._record.host === null || this._record.host === "" || this._record.scheme === "file") return;
915
+ this._record.password = percentEncode(value, USERINFO_SET);
916
+ }
917
+ get host() {
918
+ return hostOf(this._record);
919
+ }
920
+ set host(value) {
921
+ setHost(this._record, value, true);
922
+ }
923
+ get hostname() {
924
+ return this._record.host === null ? "" : this._record.host;
925
+ }
926
+ set hostname(value) {
927
+ setHost(this._record, value, false);
928
+ }
929
+ get port() {
930
+ return this._record.port;
931
+ }
932
+ set port(value) {
933
+ if (this._record.host === null || this._record.host === "" || this._record.scheme === "file") return;
934
+ const text = String(value);
935
+ if (text === "") {
936
+ this._record.port = "";
937
+ return;
938
+ }
939
+ const digits = /^[0-9]+/.exec(text);
940
+ if (!digits || Number(digits[0]) > 65535) return;
941
+ const port = String(Number(digits[0]));
942
+ this._record.port = port === SPECIAL_PORTS[this._record.scheme] ? "" : port;
943
+ }
944
+ get pathname() {
945
+ return pathnameOf(this._record);
946
+ }
947
+ set pathname(value) {
948
+ if (this._record.opaque) return;
949
+ let path = String(value);
950
+ if (isSpecial(this._record.scheme)) path = path.replace(/\\/g, "/");
951
+ if (path === "" && !isSpecial(this._record.scheme)) {
952
+ this._record.path = [];
953
+ return;
954
+ }
955
+ this._record.path = appendSegments([], (path.startsWith("/") ? path.slice(1) : path).split("/"));
956
+ }
957
+ get search() {
958
+ return this._record.query ? "?" + this._record.query : "";
959
+ }
960
+ set search(value) {
961
+ const text = String(value);
962
+ const query = text.startsWith("?") ? text.slice(1) : text;
963
+ this._record.query = text === "" ? null : encodeQuery(query, isSpecial(this._record.scheme));
964
+ this._syncParams();
965
+ }
966
+ get searchParams() {
967
+ if (!this._params) {
968
+ this._params = new URLSearchParams(this._record.query || "");
969
+ this._params._url = this;
970
+ }
971
+ return this._params;
972
+ }
973
+ get hash() {
974
+ return this._record.fragment ? "#" + this._record.fragment : "";
975
+ }
976
+ set hash(value) {
977
+ const text = String(value);
978
+ this._record.fragment = text === "" ? null : encodeFragment(text.startsWith("#") ? text.slice(1) : text);
979
+ }
980
+ toString() {
981
+ return this.href;
982
+ }
983
+ toJSON() {
984
+ return this.href;
985
+ }
986
+ }
987
+
988
+ // ── base64 (forgiving-base64, latin1 strings) ──
989
+ const B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
990
+ const invalidCharacter = (message) => {
991
+ const error = new Error(message);
992
+ error.name = "InvalidCharacterError";
993
+ return error;
994
+ };
995
+ function btoa(data) {
996
+ if (arguments.length === 0) throw new TypeError("btoa requires 1 argument");
997
+ const text = String(data);
998
+ let out = "";
999
+ for (let i = 0; i < text.length; i += 3) {
1000
+ const a = text.charCodeAt(i);
1001
+ const b = i + 1 < text.length ? text.charCodeAt(i + 1) : 0;
1002
+ const c = i + 2 < text.length ? text.charCodeAt(i + 2) : 0;
1003
+ if (a > 255 || b > 255 || c > 255) throw invalidCharacter("The string contains characters outside of the Latin1 range");
1004
+ const n = (a << 16) | (b << 8) | c;
1005
+ out += B64[n >> 18] + B64[(n >> 12) & 63];
1006
+ out += i + 1 < text.length ? B64[(n >> 6) & 63] : "=";
1007
+ out += i + 2 < text.length ? B64[n & 63] : "=";
1008
+ }
1009
+ return out;
1010
+ }
1011
+ function atob(data) {
1012
+ if (arguments.length === 0) throw new TypeError("atob requires 1 argument");
1013
+ let text = String(data).replace(/[\t\n\f\r ]/g, "");
1014
+ if (text.length % 4 === 0) text = text.replace(/==?$/, "");
1015
+ if (text.length % 4 === 1 || /[^A-Za-z0-9+/]/.test(text)) {
1016
+ throw invalidCharacter("The string contains invalid characters");
1017
+ }
1018
+ let out = "";
1019
+ let bits = 0;
1020
+ let buffer = 0;
1021
+ for (let i = 0; i < text.length; i++) {
1022
+ buffer = ((buffer << 6) | B64.indexOf(text[i])) & 0xffffff;
1023
+ bits += 6;
1024
+ if (bits >= 8) {
1025
+ bits -= 8;
1026
+ out += String.fromCharCode((buffer >> bits) & 255);
1027
+ }
1028
+ }
1029
+ return out;
1030
+ }
1031
+
1032
+ const define = (name, value) =>
1033
+ Object.defineProperty(globalThis, name, { value, writable: true, configurable: true, enumerable: false });
1034
+ define("atob", atob);
1035
+ define("btoa", btoa);
1036
+ define("URL", URL);
1037
+ define("URLSearchParams", URLSearchParams);
1038
+ define("TextEncoder", TextEncoder);
1039
+ define("TextDecoder", TextDecoder);
1040
+ })();
1041
+ `;