@stage-labs/metro 0.1.0-beta.30 → 0.1.0-beta.301

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 (672) hide show
  1. package/dist/agent.js +128 -0
  2. package/dist/api.js +9 -129
  3. package/dist/automation.js +56 -0
  4. package/dist/background.js +141 -0
  5. package/dist/claude-settings.js +40 -0
  6. package/dist/claude.js +199 -10
  7. package/dist/cli.js +73 -126
  8. package/dist/control.js +19 -103
  9. package/dist/hold.js +210 -0
  10. package/dist/local.js +43 -0
  11. package/dist/mcp-config.js +27 -0
  12. package/dist/memory.js +222 -0
  13. package/dist/native-recovery-scan.js +246 -0
  14. package/dist/native-recovery-state.js +154 -0
  15. package/dist/native-recovery.js +164 -0
  16. package/dist/node-name.js +71 -0
  17. package/dist/onboarding.js +44 -0
  18. package/dist/provider-flags.js +9 -0
  19. package/dist/root-release-io.js +161 -0
  20. package/dist/root-release.js +74 -0
  21. package/dist/route.js +66 -0
  22. package/dist/runtime-install.js +114 -0
  23. package/dist/runtime.js +29 -52
  24. package/dist/serve.js +157 -0
  25. package/dist/service.js +328 -0
  26. package/dist/tail.js +10 -11
  27. package/dist/update.js +13 -1
  28. package/dist/voice.js +56 -0
  29. package/package.json +3 -24
  30. package/runtime/marketplace/.claude-plugin/marketplace.json +12 -0
  31. package/runtime/marketplace/plugin/.claude-plugin/plugin.json +17 -0
  32. package/runtime/marketplace/plugin/.mcp.json +1 -0
  33. package/runtime/marketplace/plugin/MEMORY.md +78 -0
  34. package/runtime/marketplace/plugin/METRO.md +26 -0
  35. package/runtime/marketplace/plugin/STAGE.md +109 -0
  36. package/runtime/marketplace/plugin/bin/guard.mjs +75 -0
  37. package/runtime/marketplace/plugin/bin/metro-plugin.mjs +30 -0
  38. package/runtime/marketplace/plugin/bin/policy.mjs +105 -0
  39. package/runtime/marketplace/plugin/bin/session-start.mjs +31 -0
  40. package/runtime/marketplace/plugin/hooks/hooks.json +25 -0
  41. package/runtime/node_modules/@metro-labs/core/package.json +59 -0
  42. package/runtime/node_modules/@metro-labs/core/src/automation-files.ts +216 -0
  43. package/runtime/node_modules/@metro-labs/core/src/automation-store.ts +171 -0
  44. package/runtime/node_modules/@metro-labs/core/src/automation-types.ts +141 -0
  45. package/runtime/node_modules/@metro-labs/core/src/call.ts +81 -0
  46. package/runtime/node_modules/@metro-labs/core/src/connector-sync.ts +17 -0
  47. package/runtime/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  48. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/events.ts +54 -6
  49. package/runtime/node_modules/@metro-labs/{mcp/src/db → core/src}/ids.ts +10 -1
  50. package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  51. package/runtime/node_modules/@metro-labs/{mcp/src/stations → core/src}/lines.ts +22 -26
  52. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/protocol.ts +7 -4
  53. package/runtime/node_modules/@metro-labs/core/src/runner-activity.ts +270 -0
  54. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/secure-fs.ts +17 -0
  55. package/runtime/node_modules/@metro-labs/core/src/skill-source.ts +96 -0
  56. package/runtime/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  57. package/runtime/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  58. package/runtime/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  59. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/attachments.ts +9 -3
  60. package/runtime/node_modules/@metro-labs/core/src/stations/channel-directory.ts +159 -0
  61. package/runtime/node_modules/@metro-labs/core/src/stations/channel-pages.ts +129 -0
  62. package/runtime/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  63. package/runtime/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  64. package/runtime/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  65. package/runtime/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  66. package/runtime/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  67. package/runtime/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  68. package/runtime/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  69. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/station-runtime.ts +6 -11
  70. package/runtime/node_modules/@metro-labs/core/src/stations/train-boot.ts +63 -0
  71. package/runtime/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  72. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/types.ts +20 -1
  73. package/runtime/node_modules/@metro-labs/core/src/tickets.ts +44 -0
  74. package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
  75. package/runtime/node_modules/@metro-labs/daemon/package.json +51 -0
  76. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/agent-fs.ts +246 -0
  77. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/crontab.ts +44 -0
  78. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files-api.ts +12 -0
  79. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files.ts +89 -0
  80. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/home-fs.ts +113 -0
  81. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/job-env.ts +39 -0
  82. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/metro-home.ts +42 -0
  83. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/provision.ts +92 -0
  84. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedule-detail.ts +93 -0
  85. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules-api.ts +27 -0
  86. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules.ts +144 -0
  87. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/unit-files.ts +43 -0
  88. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/user.ts +91 -0
  89. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/view.ts +93 -0
  90. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
  91. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-lookups.ts +55 -0
  92. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-routes.ts +76 -0
  93. package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +362 -0
  94. package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +30 -0
  95. package/runtime/node_modules/@metro-labs/daemon/src/agents/allowlist.ts +59 -0
  96. package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +133 -0
  97. package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +132 -0
  98. package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +317 -0
  99. package/runtime/node_modules/@metro-labs/daemon/src/agents/files.ts +142 -0
  100. package/runtime/node_modules/@metro-labs/{mcp/src/db/key-map.ts → daemon/src/agents/keys.ts} +1 -11
  101. package/runtime/node_modules/@metro-labs/daemon/src/agents/map.ts +135 -0
  102. package/runtime/node_modules/@metro-labs/daemon/src/agents/policy-route.ts +27 -0
  103. package/runtime/node_modules/@metro-labs/{mcp/src/db/agent-scope.ts → daemon/src/agents/scope.ts} +2 -2
  104. package/runtime/node_modules/@metro-labs/daemon/src/agents/sender-cards.ts +94 -0
  105. package/runtime/node_modules/@metro-labs/daemon/src/agents/senders.ts +38 -0
  106. package/runtime/node_modules/@metro-labs/daemon/src/approvals/api.ts +55 -0
  107. package/runtime/node_modules/@metro-labs/daemon/src/approvals/owner-line.ts +45 -0
  108. package/runtime/node_modules/@metro-labs/daemon/src/approvals/pending.ts +189 -0
  109. package/runtime/node_modules/@metro-labs/daemon/src/approvals/preview.ts +66 -0
  110. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +250 -0
  111. package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +36 -0
  112. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/crash-guard.ts +1 -1
  113. package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +21 -0
  114. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/paths.ts +8 -36
  115. package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +26 -0
  116. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/inbound.ts +95 -72
  117. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/media-note.ts +11 -7
  118. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/pending.ts +13 -1
  119. package/runtime/node_modules/@metro-labs/daemon/src/channels/react-note.ts +13 -0
  120. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/relay.ts +6 -2
  121. package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +316 -0
  122. package/runtime/node_modules/@metro-labs/daemon/src/claude/channel-check.ts +56 -0
  123. package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +359 -0
  124. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-api.ts +12 -0
  125. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-fetch.ts +160 -0
  126. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-skills.ts +259 -0
  127. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-validate.ts +53 -0
  128. package/runtime/node_modules/@metro-labs/daemon/src/claude/login.ts +242 -0
  129. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory-routine.ts +123 -0
  130. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory.ts +32 -0
  131. package/runtime/node_modules/@metro-labs/daemon/src/claude/onboarding.ts +60 -0
  132. package/runtime/node_modules/@metro-labs/daemon/src/claude/pinned.ts +16 -0
  133. package/runtime/node_modules/@metro-labs/daemon/src/claude/plugin-install.ts +149 -0
  134. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-activity.ts +17 -0
  135. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-process.ts +52 -0
  136. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner.ts +45 -0
  137. package/runtime/node_modules/@metro-labs/daemon/src/claude/session-continuity.ts +57 -0
  138. package/runtime/node_modules/@metro-labs/daemon/src/claude/session-files.ts +75 -0
  139. package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +382 -0
  140. package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +109 -0
  141. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-api.ts +161 -0
  142. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-state.ts +18 -0
  143. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +346 -0
  144. package/runtime/node_modules/@metro-labs/daemon/src/claude/skills.ts +123 -0
  145. package/runtime/node_modules/@metro-labs/daemon/src/claude/usage-probe.ts +128 -0
  146. package/runtime/node_modules/@metro-labs/daemon/src/claude/version.ts +76 -0
  147. package/runtime/node_modules/@metro-labs/daemon/src/connectors/agent-key.ts +148 -0
  148. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-api.ts → daemon/src/connectors/api.ts} +91 -114
  149. package/runtime/node_modules/@metro-labs/daemon/src/connectors/config.ts +105 -0
  150. package/runtime/node_modules/@metro-labs/daemon/src/connectors/enroll-api.ts +101 -0
  151. package/runtime/node_modules/@metro-labs/daemon/src/connectors/gates.ts +114 -0
  152. package/runtime/node_modules/@metro-labs/daemon/src/connectors/health.ts +18 -0
  153. package/runtime/node_modules/@metro-labs/daemon/src/connectors/metro-api.ts +93 -0
  154. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-api.ts +60 -0
  155. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-control.ts +366 -0
  156. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-guard.ts +95 -0
  157. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-operations.ts +226 -0
  158. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-preview.ts +235 -0
  159. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-source.ts +42 -0
  160. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-state.ts +142 -0
  161. package/runtime/node_modules/@metro-labs/daemon/src/connectors/migration-url.ts +9 -0
  162. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-routes.ts +178 -0
  163. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-oauth.ts → daemon/src/connectors/oauth.ts} +70 -26
  164. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-relay.ts +61 -0
  165. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-runtime-discovery.ts +115 -0
  166. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-runtime.ts +327 -0
  167. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-sync-api.ts +25 -0
  168. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-sync-control.ts +191 -0
  169. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-sync-setting.ts +60 -0
  170. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-sync-watch.ts +53 -0
  171. package/runtime/node_modules/@metro-labs/daemon/src/connectors/org-sync.ts +208 -0
  172. package/runtime/node_modules/@metro-labs/daemon/src/connectors/plugin-sync.ts +170 -0
  173. package/runtime/node_modules/@metro-labs/daemon/src/connectors/publication.ts +61 -0
  174. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-id.ts +2 -0
  175. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-passive.ts +96 -0
  176. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-policy.ts +90 -0
  177. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-session.ts +11 -0
  178. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-target.ts +4 -0
  179. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay.ts +392 -0
  180. package/runtime/node_modules/@metro-labs/daemon/src/connectors/server-keys.ts +46 -0
  181. package/runtime/node_modules/@metro-labs/daemon/src/connectors/store.ts +393 -0
  182. package/runtime/node_modules/@metro-labs/daemon/src/connectors/tools.ts +1 -0
  183. package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-api.ts +116 -0
  184. package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-crypto.ts +44 -0
  185. package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-store.ts +46 -0
  186. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-grant.ts +4 -4
  187. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-owner.ts +3 -3
  188. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-reaper.ts +174 -0
  189. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-serve.ts +11 -17
  190. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-api.ts +10 -27
  191. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-store.ts +4 -4
  192. package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +233 -0
  193. package/runtime/node_modules/@metro-labs/daemon/src/gateway/claude-logins.ts +168 -0
  194. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-auth.ts +219 -0
  195. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +119 -0
  196. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +179 -0
  197. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +209 -0
  198. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-version.ts +44 -0
  199. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +143 -0
  200. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effort.ts +103 -0
  201. package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
  202. package/runtime/node_modules/@metro-labs/daemon/src/gateway/fallback.ts +147 -0
  203. package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +285 -0
  204. package/runtime/node_modules/@metro-labs/daemon/src/gateway/frames.ts +118 -0
  205. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +396 -0
  206. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-auth.ts +160 -0
  207. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-client.ts +46 -0
  208. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-setup.ts +150 -0
  209. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-stream.ts +139 -0
  210. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-translate.ts +236 -0
  211. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini.ts +208 -0
  212. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +259 -0
  213. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +362 -0
  214. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-lists.ts +57 -0
  215. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-signin.ts +157 -0
  216. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-store.ts +83 -0
  217. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter-login.ts +192 -0
  218. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter-signin.ts +64 -0
  219. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +104 -0
  220. package/runtime/node_modules/@metro-labs/daemon/src/gateway/pkce.ts +36 -0
  221. package/runtime/node_modules/@metro-labs/daemon/src/gateway/provider-models.ts +117 -0
  222. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +18 -0
  223. package/runtime/node_modules/@metro-labs/daemon/src/gateway/subscription.ts +120 -0
  224. package/runtime/node_modules/@metro-labs/daemon/src/gateway/text.ts +35 -0
  225. package/runtime/node_modules/@metro-labs/daemon/src/gateway/tool-search.ts +126 -0
  226. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage-refresh.ts +115 -0
  227. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +343 -0
  228. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/accounts.ts +38 -18
  229. package/runtime/node_modules/@metro-labs/daemon/src/mcp/attachment-schema.ts +91 -0
  230. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-bridge.ts +45 -0
  231. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-permission.ts +25 -0
  232. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/call-tools.ts +88 -38
  233. package/runtime/node_modules/@metro-labs/daemon/src/mcp/channel-tool.ts +80 -0
  234. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/ctx.ts +4 -4
  235. package/runtime/node_modules/@metro-labs/daemon/src/mcp/diagnostics.ts +102 -0
  236. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/event-store.ts +24 -18
  237. package/runtime/node_modules/@metro-labs/daemon/src/mcp/frame-schema.ts +44 -0
  238. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/group-tools.ts +2 -2
  239. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/index.ts +55 -78
  240. package/runtime/node_modules/@metro-labs/daemon/src/mcp/instructions.ts +30 -0
  241. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/member-tools.ts +2 -2
  242. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-prompt.ts +108 -0
  243. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +109 -0
  244. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-gate.ts +87 -0
  245. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-snapshot.ts +79 -0
  246. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-lookup.ts +60 -0
  247. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-tool.ts +96 -0
  248. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/raw-get-stream.ts +54 -16
  249. package/runtime/node_modules/@metro-labs/daemon/src/mcp/read-tool.ts +87 -0
  250. package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +48 -0
  251. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-slot.ts +141 -0
  252. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session.ts +270 -0
  253. package/runtime/node_modules/@metro-labs/daemon/src/mcp/speech-schema.ts +11 -0
  254. package/runtime/node_modules/@metro-labs/daemon/src/mcp/speech-send.ts +15 -0
  255. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-catalog.ts +96 -0
  256. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-def.ts +9 -0
  257. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-dispatch.ts +60 -40
  258. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-schemas.ts +87 -114
  259. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/upload-tool.ts +6 -11
  260. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/helper-script.ts +183 -0
  261. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/imds.ts +16 -0
  262. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/install.ts +78 -0
  263. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/privilege.ts +50 -0
  264. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/root-follow.ts +16 -0
  265. package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +132 -0
  266. package/runtime/node_modules/@metro-labs/daemon/src/monitor/run-event.ts +139 -0
  267. package/runtime/node_modules/@metro-labs/daemon/src/monitor/run-events.ts +101 -0
  268. package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +323 -0
  269. package/runtime/node_modules/@metro-labs/daemon/src/policy/policy.ts +119 -0
  270. package/runtime/node_modules/@metro-labs/daemon/src/routes/bearer.ts +38 -0
  271. package/runtime/node_modules/@metro-labs/daemon/src/routes/body.ts +24 -0
  272. package/runtime/node_modules/@metro-labs/daemon/src/routes/gmail-attach.ts +67 -0
  273. package/runtime/node_modules/@metro-labs/daemon/src/routes/gmail-detach.ts +37 -0
  274. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/routes}/http.ts +65 -53
  275. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +229 -0
  276. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +82 -0
  277. package/runtime/node_modules/@metro-labs/daemon/src/routes/session.ts +29 -0
  278. package/runtime/node_modules/@metro-labs/daemon/src/routes/threema-callback.ts +103 -0
  279. package/runtime/node_modules/@metro-labs/daemon/src/server/cloudwatch.ts +178 -0
  280. package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +39 -0
  281. package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +58 -0
  282. package/runtime/node_modules/@metro-labs/daemon/src/server/owner.ts +26 -0
  283. package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +90 -0
  284. package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
  285. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-browser.ts +107 -0
  286. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-driver.ts +42 -0
  287. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-gmail.ts +78 -0
  288. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-inline.ts +29 -1
  289. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-interactive.ts +5 -31
  290. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-resolve.ts +84 -13
  291. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/attach-session.ts +61 -25
  292. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-xmtp.ts +8 -9
  293. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach.ts +69 -3
  294. package/runtime/node_modules/@metro-labs/{mcp/src/db → daemon/src/stations}/materialize.ts +60 -175
  295. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/registry.ts +20 -2
  296. package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +135 -0
  297. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor-io.ts +3 -3
  298. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor.ts +6 -9
  299. package/runtime/node_modules/@metro-labs/daemon/src/stations/threema-callbacks.ts +32 -0
  300. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/train-call.ts +1 -1
  301. package/runtime/node_modules/@metro-labs/daemon/src/stations/webhook-endpoints.ts +51 -0
  302. package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +84 -0
  303. package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +124 -0
  304. package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +15 -0
  305. package/runtime/node_modules/@metro-labs/daemon/src/vault/api.ts +45 -0
  306. package/runtime/node_modules/@metro-labs/daemon/src/vault/config.ts +51 -0
  307. package/runtime/node_modules/@metro-labs/daemon/src/vault/firewall.ts +9 -0
  308. package/runtime/node_modules/@metro-labs/daemon/src/vault/index.ts +96 -0
  309. package/runtime/node_modules/@metro-labs/daemon/src/vault/install.ts +56 -0
  310. package/runtime/node_modules/@metro-labs/daemon/src/vault/paths.ts +26 -0
  311. package/runtime/node_modules/@metro-labs/daemon/src/vault/proxy.ts +147 -0
  312. package/runtime/node_modules/@metro-labs/daemon/src/vault/store.ts +129 -0
  313. package/runtime/node_modules/@metro-labs/daemon/src/vault/trust.ts +44 -0
  314. package/runtime/node_modules/@metro-labs/daemon/src/voice/api.ts +14 -0
  315. package/runtime/node_modules/@metro-labs/daemon/src/voice/approvals.ts +38 -0
  316. package/runtime/node_modules/@metro-labs/daemon/src/voice/audio.ts +193 -0
  317. package/runtime/node_modules/@metro-labs/daemon/src/voice/brain.ts +146 -0
  318. package/runtime/node_modules/@metro-labs/daemon/src/voice/call.ts +274 -0
  319. package/runtime/node_modules/@metro-labs/daemon/src/voice/calls.ts +156 -0
  320. package/runtime/node_modules/@metro-labs/daemon/src/voice/peer.ts +85 -0
  321. package/runtime/node_modules/@metro-labs/daemon/src/voice/scribe.ts +115 -0
  322. package/runtime/node_modules/@metro-labs/daemon/src/voice/shared-talk.ts +85 -0
  323. package/runtime/node_modules/@metro-labs/daemon/src/voice/shared.ts +200 -0
  324. package/runtime/node_modules/@metro-labs/daemon/src/voice/speakable.ts +54 -0
  325. package/runtime/node_modules/@metro-labs/daemon/src/voice/speech-queue.ts +200 -0
  326. package/runtime/node_modules/@metro-labs/daemon/src/voice/speech.ts +129 -0
  327. package/runtime/node_modules/@metro-labs/daemon/src/voice/store.ts +116 -0
  328. package/runtime/node_modules/@metro-labs/daemon/src/voice/talk.ts +264 -0
  329. package/runtime/node_modules/@metro-labs/discord-bot/package.json +3 -5
  330. package/runtime/node_modules/@metro-labs/discord-bot/src/accounts.ts +3 -23
  331. package/runtime/node_modules/@metro-labs/discord-bot/src/actions.ts +21 -187
  332. package/runtime/node_modules/@metro-labs/discord-bot/src/attachments.ts +2 -2
  333. package/runtime/node_modules/@metro-labs/discord-bot/src/channel-source.ts +79 -0
  334. package/runtime/node_modules/@metro-labs/discord-bot/src/channels.ts +186 -0
  335. package/runtime/node_modules/@metro-labs/discord-bot/src/format.ts +26 -67
  336. package/runtime/node_modules/@metro-labs/discord-bot/src/group-actions.ts +1 -1
  337. package/runtime/node_modules/@metro-labs/discord-bot/src/group.ts +2 -2
  338. package/runtime/node_modules/@metro-labs/discord-bot/src/index.ts +8 -14
  339. package/runtime/node_modules/@metro-labs/discord-bot/src/members.ts +2 -2
  340. package/runtime/node_modules/@metro-labs/discord-bot/src/profile.ts +68 -0
  341. package/runtime/node_modules/@metro-labs/discord-bot/src/send-files.ts +12 -13
  342. package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +6 -1
  343. package/runtime/node_modules/@metro-labs/gmail/package.json +27 -0
  344. package/runtime/node_modules/@metro-labs/gmail/src/accounts.ts +133 -0
  345. package/runtime/node_modules/@metro-labs/gmail/src/actions.ts +20 -0
  346. package/runtime/node_modules/@metro-labs/gmail/src/api.ts +34 -0
  347. package/runtime/node_modules/@metro-labs/gmail/src/attachments.ts +38 -0
  348. package/runtime/node_modules/@metro-labs/gmail/src/auth.ts +115 -0
  349. package/runtime/node_modules/@metro-labs/gmail/src/channels.ts +66 -0
  350. package/runtime/node_modules/@metro-labs/gmail/src/config.ts +15 -0
  351. package/runtime/node_modules/@metro-labs/gmail/src/inbound.ts +97 -0
  352. package/runtime/node_modules/@metro-labs/gmail/src/index.ts +12 -0
  353. package/runtime/node_modules/@metro-labs/gmail/src/login.ts +39 -0
  354. package/runtime/node_modules/@metro-labs/gmail/src/managed-binding.ts +33 -0
  355. package/runtime/node_modules/@metro-labs/gmail/src/managed.ts +45 -0
  356. package/runtime/node_modules/@metro-labs/gmail/src/message.ts +125 -0
  357. package/runtime/node_modules/@metro-labs/gmail/src/mime.ts +70 -0
  358. package/runtime/node_modules/@metro-labs/gmail/src/outbound.ts +125 -0
  359. package/runtime/node_modules/@metro-labs/gmail/src/query.ts +101 -0
  360. package/runtime/node_modules/@metro-labs/gmail/src/state.ts +30 -0
  361. package/runtime/node_modules/@metro-labs/gmail/src/station.ts +16 -0
  362. package/runtime/node_modules/@metro-labs/gmail/src/trust.ts +42 -0
  363. package/runtime/node_modules/@metro-labs/http/package.json +43 -0
  364. package/runtime/node_modules/@metro-labs/http/src/agent-signature.ts +110 -0
  365. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +147 -0
  366. package/runtime/node_modules/@metro-labs/http/src/connector-delivery-validation.ts +116 -0
  367. package/runtime/node_modules/@metro-labs/http/src/connector-delivery.ts +19 -0
  368. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/oauth-discovery.ts → http/src/connector-discovery.ts} +57 -27
  369. package/runtime/node_modules/@metro-labs/http/src/connector-grant.ts +59 -0
  370. package/runtime/node_modules/@metro-labs/http/src/connector-input.ts +73 -0
  371. package/runtime/node_modules/@metro-labs/http/src/connector-mcp.ts +108 -0
  372. package/runtime/node_modules/@metro-labs/http/src/connector-migration.ts +178 -0
  373. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/oauth-client.ts → http/src/connector-oauth.ts} +48 -28
  374. package/runtime/node_modules/@metro-labs/http/src/connector-policy.ts +92 -0
  375. package/runtime/node_modules/@metro-labs/http/src/connector-public-url.ts +64 -0
  376. package/runtime/node_modules/@metro-labs/http/src/connector-reach.ts +27 -0
  377. package/runtime/node_modules/@metro-labs/http/src/connector-resource.ts +108 -0
  378. package/runtime/node_modules/@metro-labs/http/src/connector-tools.ts +94 -0
  379. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/connector-url.ts +8 -28
  380. package/runtime/node_modules/@metro-labs/http/src/ed25519.ts +56 -0
  381. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/session-api.ts → http/src/mode-api.ts} +13 -9
  382. package/runtime/node_modules/@metro-labs/http/src/return-to.ts +25 -0
  383. package/runtime/node_modules/@metro-labs/http/src/sigv4.ts +90 -0
  384. package/runtime/node_modules/@metro-labs/http/src/transfer-crypto.ts +44 -0
  385. package/runtime/node_modules/@metro-labs/http/src/workos-token.ts +149 -0
  386. package/runtime/node_modules/@metro-labs/outlook/package.json +25 -0
  387. package/runtime/node_modules/@metro-labs/outlook/src/accounts.ts +78 -0
  388. package/runtime/node_modules/@metro-labs/outlook/src/actions.ts +15 -0
  389. package/runtime/node_modules/@metro-labs/outlook/src/attachments.ts +81 -0
  390. package/runtime/node_modules/@metro-labs/outlook/src/auth.ts +120 -0
  391. package/runtime/node_modules/@metro-labs/outlook/src/browser.ts +42 -0
  392. package/runtime/node_modules/@metro-labs/outlook/src/channels.ts +60 -0
  393. package/runtime/node_modules/@metro-labs/outlook/src/config.ts +23 -0
  394. package/runtime/node_modules/@metro-labs/outlook/src/format.ts +59 -0
  395. package/runtime/node_modules/@metro-labs/outlook/src/graph.ts +55 -0
  396. package/runtime/node_modules/@metro-labs/outlook/src/inbound.ts +96 -0
  397. package/runtime/node_modules/@metro-labs/outlook/src/index.ts +12 -0
  398. package/runtime/node_modules/@metro-labs/outlook/src/login.ts +129 -0
  399. package/runtime/node_modules/@metro-labs/outlook/src/me.ts +31 -0
  400. package/runtime/node_modules/@metro-labs/outlook/src/outbound.ts +103 -0
  401. package/runtime/node_modules/@metro-labs/outlook/src/query.ts +84 -0
  402. package/runtime/node_modules/@metro-labs/outlook/src/state.ts +28 -0
  403. package/runtime/node_modules/@metro-labs/outlook/src/station.ts +16 -0
  404. package/runtime/node_modules/@metro-labs/outlook/src/trust.ts +41 -0
  405. package/runtime/node_modules/@metro-labs/telegram/package.json +2 -4
  406. package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +5 -24
  407. package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +27 -6
  408. package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +1 -1
  409. package/runtime/node_modules/@metro-labs/telegram/src/channels.ts +58 -0
  410. package/runtime/node_modules/@metro-labs/telegram/src/client.ts +4 -4
  411. package/runtime/node_modules/@metro-labs/telegram/src/format.ts +19 -34
  412. package/runtime/node_modules/@metro-labs/telegram/src/group.ts +3 -3
  413. package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +13 -34
  414. package/runtime/node_modules/@metro-labs/telegram/src/index.ts +4 -43
  415. package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +2 -3
  416. package/runtime/node_modules/@metro-labs/telegram/src/members.ts +1 -1
  417. package/runtime/node_modules/@metro-labs/telegram/src/profile.ts +70 -0
  418. package/runtime/node_modules/@metro-labs/telegram/src/reactions.ts +2 -2
  419. package/runtime/node_modules/@metro-labs/telegram/src/station.ts +5 -1
  420. package/runtime/node_modules/@metro-labs/telegram/src/types.ts +0 -1
  421. package/runtime/node_modules/@metro-labs/telegram-bot/package.json +2 -2
  422. package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +7 -41
  423. package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +24 -77
  424. package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +2 -2
  425. package/runtime/node_modules/@metro-labs/telegram-bot/src/channel-files.ts +3 -0
  426. package/runtime/node_modules/@metro-labs/telegram-bot/src/channels.ts +43 -0
  427. package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +46 -48
  428. package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +15 -44
  429. package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +6 -82
  430. package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +1 -1
  431. package/runtime/node_modules/@metro-labs/telegram-bot/src/observed-chats.ts +172 -0
  432. package/runtime/node_modules/@metro-labs/telegram-bot/src/profile.ts +85 -0
  433. package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +9 -1
  434. package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +50 -15
  435. package/runtime/node_modules/@metro-labs/telegram-bot/src/updates.ts +26 -0
  436. package/runtime/node_modules/@metro-labs/threema/package.json +26 -0
  437. package/runtime/node_modules/@metro-labs/threema/src/accounts.ts +108 -0
  438. package/runtime/node_modules/@metro-labs/threema/src/actions.ts +130 -0
  439. package/runtime/node_modules/@metro-labs/threema/src/api.ts +152 -0
  440. package/runtime/node_modules/@metro-labs/threema/src/channels.ts +37 -0
  441. package/runtime/node_modules/@metro-labs/threema/src/chats.ts +88 -0
  442. package/runtime/node_modules/@metro-labs/threema/src/crypto.ts +100 -0
  443. package/runtime/node_modules/@metro-labs/threema/src/files.ts +47 -0
  444. package/runtime/node_modules/@metro-labs/threema/src/format.ts +164 -0
  445. package/runtime/node_modules/@metro-labs/threema/src/groups.ts +96 -0
  446. package/runtime/node_modules/@metro-labs/threema/src/ids.ts +21 -0
  447. package/runtime/node_modules/@metro-labs/threema/src/inbound.ts +92 -0
  448. package/runtime/node_modules/@metro-labs/threema/src/index.ts +24 -0
  449. package/runtime/node_modules/@metro-labs/threema/src/messages.ts +264 -0
  450. package/runtime/node_modules/@metro-labs/threema/src/outbound.ts +161 -0
  451. package/runtime/node_modules/@metro-labs/threema/src/station.ts +21 -0
  452. package/runtime/node_modules/@metro-labs/threema/src/verify.ts +117 -0
  453. package/runtime/node_modules/@metro-labs/webhook/package.json +2 -2
  454. package/runtime/node_modules/@metro-labs/webhook/src/station.ts +5 -8
  455. package/runtime/node_modules/@metro-labs/whatsapp/package.json +3 -6
  456. package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +6 -28
  457. package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +1 -1
  458. package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +97 -12
  459. package/runtime/node_modules/@metro-labs/whatsapp/src/app-state.ts +49 -0
  460. package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +2 -2
  461. package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +1 -1
  462. package/runtime/node_modules/@metro-labs/whatsapp/src/channel-chats.ts +137 -0
  463. package/runtime/node_modules/@metro-labs/whatsapp/src/channels.ts +48 -0
  464. package/runtime/node_modules/@metro-labs/whatsapp/src/client-history.ts +31 -0
  465. package/runtime/node_modules/@metro-labs/whatsapp/src/client-types.ts +48 -0
  466. package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +145 -63
  467. package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +7 -58
  468. package/runtime/node_modules/@metro-labs/whatsapp/src/history-events.ts +127 -0
  469. package/runtime/node_modules/@metro-labs/whatsapp/src/history-files.ts +39 -0
  470. package/runtime/node_modules/@metro-labs/whatsapp/src/history-identity.ts +58 -0
  471. package/runtime/node_modules/@metro-labs/whatsapp/src/history-message.ts +161 -0
  472. package/runtime/node_modules/@metro-labs/whatsapp/src/history-state.ts +344 -0
  473. package/runtime/node_modules/@metro-labs/whatsapp/src/history-types.ts +91 -0
  474. package/runtime/node_modules/@metro-labs/whatsapp/src/history.ts +195 -0
  475. package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +11 -28
  476. package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +4 -37
  477. package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +1 -1
  478. package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +1 -1
  479. package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +1 -1
  480. package/runtime/node_modules/@metro-labs/whatsapp/src/members.ts +94 -0
  481. package/runtime/node_modules/@metro-labs/whatsapp/src/messages.ts +70 -0
  482. package/runtime/node_modules/@metro-labs/whatsapp/src/names.ts +75 -0
  483. package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +44 -0
  484. package/runtime/node_modules/@metro-labs/whatsapp/src/resolve.ts +52 -0
  485. package/runtime/node_modules/@metro-labs/whatsapp/src/send-expiry.ts +65 -0
  486. package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +24 -1
  487. package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +5 -9
  488. package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +0 -1
  489. package/runtime/node_modules/@metro-labs/xmtp/package.json +4 -3
  490. package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +10 -20
  491. package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +2 -2
  492. package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +55 -224
  493. package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +47 -53
  494. package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +114 -223
  495. package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +58 -15
  496. package/runtime/node_modules/@metro-labs/xmtp/src/call-leftovers.ts +48 -0
  497. package/runtime/node_modules/@metro-labs/xmtp/src/channels.ts +56 -0
  498. package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +114 -3
  499. package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +35 -20
  500. package/runtime/node_modules/@metro-labs/xmtp/src/delete-requests.ts +34 -0
  501. package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +38 -25
  502. package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +8 -18
  503. package/runtime/node_modules/@metro-labs/xmtp/src/frames.ts +190 -0
  504. package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +1 -1
  505. package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +2 -2
  506. package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +30 -16
  507. package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +18 -70
  508. package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +102 -50
  509. package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +1 -1
  510. package/runtime/node_modules/@metro-labs/xmtp/src/names.ts +61 -0
  511. package/runtime/node_modules/@metro-labs/xmtp/src/network.ts +114 -0
  512. package/runtime/node_modules/@metro-labs/xmtp/src/profile.ts +160 -0
  513. package/runtime/node_modules/@metro-labs/xmtp/src/read-attachments.ts +37 -0
  514. package/runtime/node_modules/@metro-labs/xmtp/src/resolve.ts +44 -0
  515. package/runtime/node_modules/@metro-labs/xmtp/src/sender.ts +112 -0
  516. package/runtime/node_modules/@metro-labs/xmtp/src/smart.ts +79 -0
  517. package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +10 -2
  518. package/runtime/node_modules/@metro-labs/xmtp/src/stream.ts +66 -0
  519. package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +22 -58
  520. package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +72 -49
  521. package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +4 -6
  522. package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +19 -5
  523. package/runtime/node_modules/@metro-labs/xmtp/src/wallet.ts +28 -0
  524. package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +14 -4
  525. package/runtime/patches/5bca2c07d5852d3f58453cff0448dd85da13d3665b61e3d758905b298d432d7c.patch +31 -0
  526. package/runtime/runtime.json +1 -1
  527. package/runtime/sdk-runner/node_modules/@metro-labs/core/package.json +59 -0
  528. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-files.ts +216 -0
  529. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-store.ts +171 -0
  530. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-types.ts +141 -0
  531. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/call.ts +81 -0
  532. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/connector-sync.ts +17 -0
  533. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  534. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/events.ts +165 -0
  535. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/ids.ts +28 -0
  536. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  537. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/lines.ts +78 -0
  538. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/log.ts +42 -0
  539. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/protocol.ts +227 -0
  540. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/runner-activity.ts +270 -0
  541. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/secure-fs.ts +74 -0
  542. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/skill-source.ts +96 -0
  543. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  544. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  545. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  546. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/attachments.ts +202 -0
  547. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/channel-directory.ts +159 -0
  548. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/channel-pages.ts +129 -0
  549. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  550. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  551. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  552. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  553. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  554. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  555. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  556. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/station-runtime.ts +59 -0
  557. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-boot.ts +63 -0
  558. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  559. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/types.ts +126 -0
  560. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/str.ts +5 -0
  561. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/tickets.ts +44 -0
  562. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/train-error.ts +53 -0
  563. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/version.ts +2 -0
  564. package/runtime/sdk-runner/runner.json +10 -0
  565. package/runtime/sdk-runner/src/activity-tasks.ts +194 -0
  566. package/runtime/sdk-runner/src/activity.ts +391 -0
  567. package/runtime/sdk-runner/src/app.ts +87 -0
  568. package/runtime/sdk-runner/src/approvals.ts +37 -0
  569. package/runtime/sdk-runner/src/automation-cli.ts +10 -0
  570. package/runtime/sdk-runner/src/automation-command.ts +151 -0
  571. package/runtime/sdk-runner/src/automation.ts +145 -0
  572. package/runtime/sdk-runner/src/calls.ts +133 -0
  573. package/runtime/sdk-runner/src/channel-text.ts +26 -0
  574. package/runtime/sdk-runner/src/config.ts +50 -0
  575. package/runtime/sdk-runner/src/errors.ts +142 -0
  576. package/runtime/sdk-runner/src/inbox.ts +168 -0
  577. package/runtime/sdk-runner/src/input-queue.ts +77 -0
  578. package/runtime/sdk-runner/src/input-timing.ts +68 -0
  579. package/runtime/sdk-runner/src/link.ts +154 -0
  580. package/runtime/sdk-runner/src/main.ts +57 -0
  581. package/runtime/sdk-runner/src/recovery.ts +46 -0
  582. package/runtime/sdk-runner/src/rules.ts +28 -0
  583. package/runtime/sdk-runner/src/runner.ts +358 -0
  584. package/runtime/sdk-runner/src/session-store.ts +129 -0
  585. package/runtime/sdk-runner/src/session-watch.ts +158 -0
  586. package/runtime/sdk-runner/src/singleton.ts +15 -0
  587. package/runtime/sdk-runner/src/skill-work.ts +76 -0
  588. package/runtime/sdk-runner/src/skills-files.ts +169 -0
  589. package/runtime/sdk-runner/src/skills.ts +150 -0
  590. package/runtime/sdk-runner/src/task-ledger.ts +229 -0
  591. package/runtime/sdk-runner/src/task-recovery.ts +203 -0
  592. package/runtime/sdk-runner/src/task-state.ts +71 -0
  593. package/runtime/sdk-runner/src/tool-proxy.ts +40 -0
  594. package/runtime/server.ts +1 -0
  595. package/runtime/stations.json +43 -0
  596. package/dist/bedrock-eventstream.js +0 -120
  597. package/dist/bedrock-proxy.js +0 -260
  598. package/dist/bedrock-upstream.js +0 -72
  599. package/dist/bedrock.js +0 -104
  600. package/dist/plugin.js +0 -82
  601. package/dist/prompt.js +0 -61
  602. package/dist/store.js +0 -70
  603. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-speak.ts +0 -195
  604. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-transcribe.ts +0 -292
  605. package/runtime/node_modules/@metro-labs/discord-bot/src/voice.ts +0 -197
  606. package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +0 -5
  607. package/runtime/node_modules/@metro-labs/mcp/package.json +0 -66
  608. package/runtime/node_modules/@metro-labs/mcp/src/channels/dedupe.ts +0 -24
  609. package/runtime/node_modules/@metro-labs/mcp/src/daemon/account-api.ts +0 -311
  610. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-api.ts +0 -337
  611. package/runtime/node_modules/@metro-labs/mcp/src/daemon/api-http.ts +0 -129
  612. package/runtime/node_modules/@metro-labs/mcp/src/daemon/boot.ts +0 -321
  613. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair-api.ts +0 -123
  614. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair.ts +0 -20
  615. package/runtime/node_modules/@metro-labs/mcp/src/daemon/collection-api.ts +0 -202
  616. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-json.ts +0 -21
  617. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-oauth-routes.ts +0 -157
  618. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-tools.ts +0 -100
  619. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-verify.ts +0 -333
  620. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-auth.ts +0 -164
  621. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-oauth.ts +0 -208
  622. package/runtime/node_modules/@metro-labs/mcp/src/daemon/identity.ts +0 -79
  623. package/runtime/node_modules/@metro-labs/mcp/src/daemon/oauth-pending.ts +0 -65
  624. package/runtime/node_modules/@metro-labs/mcp/src/daemon/pair-codes.ts +0 -58
  625. package/runtime/node_modules/@metro-labs/mcp/src/daemon/project-api.ts +0 -214
  626. package/runtime/node_modules/@metro-labs/mcp/src/daemon/relay.ts +0 -302
  627. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-api.ts +0 -130
  628. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-pair.ts +0 -18
  629. package/runtime/node_modules/@metro-labs/mcp/src/daemon/runtime-source.ts +0 -105
  630. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session-apis.ts +0 -43
  631. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session.ts +0 -218
  632. package/runtime/node_modules/@metro-labs/mcp/src/daemon/tunnel.ts +0 -169
  633. package/runtime/node_modules/@metro-labs/mcp/src/db/account-attach.ts +0 -91
  634. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-admin.ts +0 -215
  635. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-map.ts +0 -71
  636. package/runtime/node_modules/@metro-labs/mcp/src/db/client.ts +0 -37
  637. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-collections.ts +0 -218
  638. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-config.ts +0 -147
  639. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-relay.ts +0 -126
  640. package/runtime/node_modules/@metro-labs/mcp/src/db/connectors.ts +0 -308
  641. package/runtime/node_modules/@metro-labs/mcp/src/db/projects.ts +0 -300
  642. package/runtime/node_modules/@metro-labs/mcp/src/db/runtime-admin.ts +0 -31
  643. package/runtime/node_modules/@metro-labs/mcp/src/db/runtimes.ts +0 -105
  644. package/runtime/node_modules/@metro-labs/mcp/src/db/schema.ts +0 -131
  645. package/runtime/node_modules/@metro-labs/mcp/src/db/token-carry.ts +0 -45
  646. package/runtime/node_modules/@metro-labs/mcp/src/db/users.ts +0 -57
  647. package/runtime/node_modules/@metro-labs/mcp/src/db/whatsapp-login.ts +0 -18
  648. package/runtime/node_modules/@metro-labs/mcp/src/mcp/channel-owner.ts +0 -29
  649. package/runtime/node_modules/@metro-labs/mcp/src/mcp/frame-scope.ts +0 -21
  650. package/runtime/node_modules/@metro-labs/mcp/src/mcp/permission-relay.ts +0 -66
  651. package/runtime/node_modules/@metro-labs/mcp/src/mcp/request-identity.ts +0 -73
  652. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-registry.ts +0 -172
  653. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-route.ts +0 -43
  654. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session.ts +0 -211
  655. package/runtime/node_modules/@metro-labs/mcp/src/monitor/api.ts +0 -240
  656. package/runtime/node_modules/@metro-labs/mcp/src/server.ts +0 -2
  657. package/runtime/node_modules/@metro-labs/mcp/src/stations/account-store.ts +0 -80
  658. package/runtime/node_modules/@metro-labs/mcp/src/stations/messaging-normalize.ts +0 -88
  659. package/runtime/node_modules/@metro-labs/telegram/src/normalize.ts +0 -22
  660. package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +0 -1
  661. package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +0 -3
  662. package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +0 -22
  663. package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +0 -5
  664. package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +0 -87
  665. package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +0 -55
  666. package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +0 -349
  667. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/log.ts +0 -0
  668. /package/runtime/node_modules/@metro-labs/{mcp/src/mcp → core/src}/str.ts +0 -0
  669. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/train-error.ts +0 -0
  670. /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/webhook-note.ts +0 -0
  671. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/api-error.ts +0 -0
  672. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/cors.ts +0 -0
@@ -0,0 +1,178 @@
1
+ import type { KeyObject } from 'node:crypto';
2
+ import { parseId } from '@metro-labs/core/ids';
3
+ import { sealingKeyOf } from './agent-signature.js';
4
+ import { deliveryBytes, deliveryRecord } from './connector-delivery-validation.js';
5
+ import { connectorAuth, connectorClient, connectorName } from './connector-input.js';
6
+ import type { OAuthClient } from './connector-oauth.js';
7
+ import { portableGrant, type PortableGrant } from './connector-grant.js';
8
+ import { connectorPolicyOf, type ConnectorPolicy } from './connector-policy.js';
9
+ import { boundOAuthResource, parsePublicConnectorUrl } from './connector-public-url.js';
10
+ import { openTransfer, sealTransfer, type SealedTransfer } from './transfer-crypto.js';
11
+ import { isOrganizationId } from './workos-token.js';
12
+
13
+ export const CONNECTOR_MIGRATION_MAX_BYTES = 96 * 1024;
14
+ const PAYLOAD_MAX = 60 * 1024;
15
+
16
+ export interface MigrationContext {
17
+ owner: string;
18
+ agent: string;
19
+ keyId: string;
20
+ operationId: string;
21
+ sourceId: string;
22
+ destinationId: string;
23
+ }
24
+
25
+ export interface MigrationPayload {
26
+ name: string;
27
+ url: string;
28
+ auth: { kind: 'none' } | { kind: 'header'; name: string; value: string } | { kind: 'oauth'; grant?: PortableGrant };
29
+ client: OAuthClient | null;
30
+ oauthResource?: string;
31
+ policy: ConnectorPolicy;
32
+ sourceStamp: string;
33
+ }
34
+
35
+ export interface MigrationView {
36
+ operationId: string;
37
+ sourceId: string;
38
+ destinationId: string;
39
+ phase: 'preparing' | 'prepared' | 'active' | 'rolled_back';
40
+ readiness: 'pending' | 'ready' | 'signin' | 'changed' | 'unavailable' | 'refresh_uncertain';
41
+ grantImported?: boolean;
42
+ name: string | null;
43
+ auth: 'none' | 'header' | 'oauth' | null;
44
+ policy: ConnectorPolicy | null;
45
+ sourceStamp: string | null;
46
+ }
47
+
48
+ export interface MigrationResponse {
49
+ migration: MigrationView;
50
+ receiving?: { publicKey: string; context: MigrationContext };
51
+ }
52
+
53
+ export type MigrationRequest = { action: 'begin' | 'status' | 'activate' | 'rollback'; operationId: string; sourceId: string } | { action: 'prepare' | 'handover'; operationId: string; sourceId: string; sealed: unknown };
54
+
55
+ const invalid = (): Error => new Error('Invalid connector migration.');
56
+ const idOf = (value: unknown): string => {
57
+ const id = parseId(value);
58
+ if (id === null) throw invalid();
59
+ return id;
60
+ };
61
+
62
+ export function migrationRequestOf(raw: unknown): MigrationRequest {
63
+ const value = deliveryRecord(raw, ['action', 'operationId', 'sourceId', 'sealed']);
64
+ const operationId = idOf(value.operationId);
65
+ const sourceId = idOf(value.sourceId);
66
+ if ((value.action === 'prepare' || value.action === 'handover') && Object.hasOwn(value, 'sealed')) return { action: value.action, operationId, sourceId, sealed: value.sealed };
67
+ if (Object.hasOwn(value, 'sealed')) throw invalid();
68
+ if (value.action !== 'begin' && value.action !== 'status' && value.action !== 'activate' && value.action !== 'rollback') throw invalid();
69
+ return { action: value.action, operationId, sourceId };
70
+ }
71
+
72
+ function contextOf(raw: unknown): MigrationContext {
73
+ const value = deliveryRecord(raw, ['owner', 'agent', 'keyId', 'operationId', 'sourceId', 'destinationId']);
74
+ if (typeof value.owner !== 'string' || !isOrganizationId(value.owner) || typeof value.keyId !== 'string') throw invalid();
75
+ deliveryBytes(value.keyId, 32);
76
+ return { owner: value.owner, agent: idOf(value.agent), keyId: value.keyId, operationId: idOf(value.operationId), sourceId: idOf(value.sourceId), destinationId: idOf(value.destinationId) };
77
+ }
78
+
79
+ function contextBytes(context: MigrationContext): Buffer {
80
+ const value = contextOf(context);
81
+ return Buffer.from(JSON.stringify(['metro-connector-migration/v1', value.owner, value.agent, value.keyId, value.operationId, value.sourceId, value.destinationId]));
82
+ }
83
+
84
+ function headerOf(value: Record<string, unknown>): MigrationPayload['auth'] {
85
+ const auth = connectorAuth(value.name, value.value);
86
+ if (auth.kind !== 'header' || auth.name !== value.name || auth.value !== value.value || ['__proto__', 'constructor', 'prototype'].includes(auth.name)) throw invalid();
87
+ return auth;
88
+ }
89
+
90
+ function authOf(raw: unknown, target: string): MigrationPayload['auth'] {
91
+ const value = deliveryRecord(raw, ['kind', 'name', 'value', 'grant']);
92
+ if (value.kind !== 'oauth' && Object.hasOwn(value, 'grant')) throw invalid();
93
+ if (value.kind === 'header') return headerOf(value);
94
+ if ((value.kind !== 'none' && value.kind !== 'oauth') || Object.hasOwn(value, 'name') || Object.hasOwn(value, 'value')) throw invalid();
95
+ if (value.kind === 'none' || value.grant === undefined) return { kind: value.kind };
96
+ return { kind: 'oauth', grant: portableGrant(value.grant, target) };
97
+ }
98
+
99
+ function clientOf(raw: unknown): OAuthClient | null {
100
+ if (raw === null) return null;
101
+ const value = deliveryRecord(raw, ['clientId', 'clientSecret']);
102
+ const client = connectorClient(value.clientId, value.clientSecret);
103
+ if (client === null || client.clientId !== value.clientId || client.clientSecret !== value.clientSecret) throw invalid();
104
+ return client;
105
+ }
106
+
107
+ function migrationClient(auth: MigrationPayload['auth'], input: Record<string, unknown>): OAuthClient | null {
108
+ const client = clientOf(input.client);
109
+ if (auth.kind !== 'oauth' && (client !== null || Object.hasOwn(input, 'oauthResource'))) throw invalid();
110
+ return client;
111
+ }
112
+
113
+ export function migrationPayloadOf(raw: unknown): MigrationPayload {
114
+ const value = deliveryRecord(raw, ['name', 'url', 'auth', 'client', 'oauthResource', 'policy', 'sourceStamp']);
115
+ if (typeof value.name !== 'string' || connectorName(value.name) !== value.name || typeof value.url !== 'string' || typeof value.sourceStamp !== 'string') throw invalid();
116
+ parsePublicConnectorUrl(value.url);
117
+ deliveryBytes(value.sourceStamp, 32);
118
+ const auth = authOf(value.auth, value.url);
119
+ const client = migrationClient(auth, value);
120
+ const payload = { name: value.name, url: value.url, auth, client, ...(Object.hasOwn(value, 'oauthResource') ? { oauthResource: boundOAuthResource(value.url, value.oauthResource) } : {}), policy: connectorPolicyOf(value.policy), sourceStamp: value.sourceStamp };
121
+ if (Buffer.byteLength(JSON.stringify(payload)) > PAYLOAD_MAX) throw invalid();
122
+ return payload;
123
+ }
124
+
125
+ function phaseOf(value: unknown): MigrationView['phase'] {
126
+ if (value !== 'preparing' && value !== 'prepared' && value !== 'active' && value !== 'rolled_back') throw invalid();
127
+ return value;
128
+ }
129
+
130
+ function readinessOf(value: unknown): MigrationView['readiness'] {
131
+ if (value !== 'pending' && value !== 'ready' && value !== 'signin' && value !== 'changed' && value !== 'unavailable' && value !== 'refresh_uncertain') throw invalid();
132
+ return value;
133
+ }
134
+
135
+ function authKindOf(value: unknown): MigrationView['auth'] {
136
+ if (value !== null && value !== 'none' && value !== 'header' && value !== 'oauth') throw invalid();
137
+ return value;
138
+ }
139
+
140
+ function nullableName(value: unknown): string | null {
141
+ if (value === null) return null;
142
+ if (typeof value !== 'string' || connectorName(value) !== value) throw invalid();
143
+ return value;
144
+ }
145
+
146
+ function nullableStamp(value: unknown): string | null {
147
+ if (value === null) return null;
148
+ if (typeof value !== 'string') throw invalid();
149
+ deliveryBytes(value, 32);
150
+ return value;
151
+ }
152
+
153
+ function viewOf(raw: unknown): MigrationView {
154
+ const view = deliveryRecord(raw, ['operationId', 'sourceId', 'destinationId', 'phase', 'readiness', 'name', 'auth', 'policy', 'sourceStamp', 'grantImported']);
155
+ if (view.grantImported !== undefined && typeof view.grantImported !== 'boolean') throw invalid();
156
+ return { ...(view.grantImported === undefined ? {} : { grantImported: view.grantImported }), operationId: idOf(view.operationId), sourceId: idOf(view.sourceId), destinationId: idOf(view.destinationId), phase: phaseOf(view.phase), readiness: readinessOf(view.readiness), name: nullableName(view.name), auth: authKindOf(view.auth), policy: view.policy === null ? null : connectorPolicyOf(view.policy), sourceStamp: nullableStamp(view.sourceStamp) };
157
+ }
158
+
159
+ export function migrationResponseOf(raw: unknown): MigrationResponse {
160
+ const value = deliveryRecord(raw, ['migration', 'receiving']);
161
+ const migration = viewOf(value.migration);
162
+ if (!Object.hasOwn(value, 'receiving')) return { migration };
163
+ const receiving = deliveryRecord(value.receiving, ['publicKey', 'context']);
164
+ if (typeof receiving.publicKey !== 'string' || sealingKeyOf(receiving.publicKey) === null) throw invalid();
165
+ const context = contextOf(receiving.context);
166
+ if (context.operationId !== migration.operationId || context.sourceId !== migration.sourceId || context.destinationId !== migration.destinationId) throw invalid();
167
+ return { migration, receiving: { publicKey: receiving.publicKey, context } };
168
+ }
169
+
170
+ export function sealConnectorMigration(publicKey: string, context: MigrationContext, payload: MigrationPayload): SealedTransfer {
171
+ return sealTransfer(publicKey, contextBytes(context), Buffer.from(JSON.stringify(migrationPayloadOf(payload))));
172
+ }
173
+
174
+ export function openConnectorMigration(privateKey: KeyObject, context: MigrationContext, sealed: unknown): MigrationPayload {
175
+ if (Buffer.byteLength(JSON.stringify(sealed)) > CONNECTOR_MIGRATION_MAX_BYTES) throw invalid();
176
+ const plain = openTransfer(privateKey, contextBytes(context), sealed, PAYLOAD_MAX);
177
+ return migrationPayloadOf(JSON.parse(plain.toString('utf8')) as unknown);
178
+ }
@@ -1,26 +1,21 @@
1
1
  import { createHash, randomBytes } from 'node:crypto';
2
- import {
3
- ConnectorVerifyError,
4
- type OAuthTokens,
5
- } from './connector-verify.js';
6
- import type { OAuthServer } from './oauth-discovery.js';
2
+ import { isRecord } from '@metro-labs/core/is-record';
3
+ import type { FetchLike } from '@metro-labs/core/stations/oauth';
4
+ import { whyUnreachable } from './connector-reach.js';
5
+ import { ConnectorVerifyError, refused } from './connector-url.js';
6
+ import type { OAuthTokens } from './connector-mcp.js';
7
+ import type { OAuthServer } from './connector-discovery.js';
7
8
 
8
9
  const TOKEN_TIMEOUT_MS = 15_000;
9
10
  const CLIENT_NAME = 'Metro';
10
11
 
12
+ export class OAuthInvalidGrant extends ConnectorVerifyError {}
13
+
11
14
  export interface OAuthClient {
12
15
  clientId: string;
13
16
  clientSecret?: string;
14
17
  }
15
18
 
16
- function refused(message: string): ConnectorVerifyError {
17
- return new ConnectorVerifyError(message, 400);
18
- }
19
-
20
- function isRecord(value: unknown): value is Record<string, unknown> {
21
- return typeof value === 'object' && value !== null && !Array.isArray(value);
22
- }
23
-
24
19
  export function newVerifier(): string {
25
20
  return randomBytes(32).toString('base64url');
26
21
  }
@@ -32,14 +27,17 @@ export function challengeOf(verifier: string): string {
32
27
  export async function registerClient(
33
28
  server: OAuthServer,
34
29
  redirectUri: string,
30
+ fetchImpl: FetchLike = fetch,
35
31
  ): Promise<OAuthClient> {
36
32
  if (server.registrationEndpoint === null)
37
33
  throw refused(
38
- 'That server requires OAuth but does not accept client registration, so Metro cannot sign in to it.',
34
+ 'That server signs in with OAuth but registers no clients on its own. ' +
35
+ `Register an app with it yourself, with ${redirectUri} as its redirect URL, ` +
36
+ "and add the connector again with that app's client ID.",
39
37
  );
40
38
  let res: Response;
41
39
  try {
42
- res = await fetch(server.registrationEndpoint, {
40
+ res = await fetchImpl(server.registrationEndpoint, {
43
41
  method: 'POST',
44
42
  redirect: 'manual',
45
43
  signal: AbortSignal.timeout(TOKEN_TIMEOUT_MS),
@@ -52,8 +50,8 @@ export async function registerClient(
52
50
  token_endpoint_auth_method: 'none',
53
51
  }),
54
52
  });
55
- } catch {
56
- throw refused('Metro could not reach that server to register.');
53
+ } catch (err) {
54
+ throw refused(`Metro could not reach that server to register: ${whyUnreachable(err)}`);
57
55
  }
58
56
  const body: unknown = await res.json().catch(() => null);
59
57
  if (!res.ok || !isRecord(body) || typeof body.client_id !== 'string')
@@ -83,21 +81,37 @@ export function authorizeUrl(input: AuthorizeInput): string {
83
81
  url.searchParams.set('code_challenge', challengeOf(input.verifier));
84
82
  url.searchParams.set('code_challenge_method', 'S256');
85
83
  url.searchParams.set('resource', input.resource);
84
+ if (input.server.scopes.length > 0)
85
+ url.searchParams.set('scope', input.server.scopes.join(' '));
86
86
  return url.toString();
87
87
  }
88
88
 
89
+ function validateOptionalTokens(body: Record<string, unknown>): void {
90
+ const refresh = body.refresh_token;
91
+ if (Object.hasOwn(body, 'refresh_token') && (typeof refresh !== 'string' || !/^[\x21-\x7e]{1,16384}$/.test(refresh))) throw refused('That server returned an invalid refresh token.');
92
+ if (Object.hasOwn(body, 'token_type') && (typeof body.token_type !== 'string' || body.token_type.toLowerCase() !== 'bearer')) throw refused('That server returned an unsupported token type.');
93
+ }
94
+
95
+ function expiryFrom(body: Record<string, unknown>): number | undefined {
96
+ if (!Object.hasOwn(body, 'expires_in')) return undefined;
97
+ const expires = body.expires_in;
98
+ if (typeof expires !== 'number' || !Number.isFinite(expires) || expires <= 0) throw refused('That server returned an invalid token expiry.');
99
+ const at = Date.now() + expires * 1000;
100
+ if (!Number.isSafeInteger(at)) throw refused('That server returned an invalid token expiry.');
101
+ return at;
102
+ }
103
+
89
104
  function tokensFrom(body: Record<string, unknown>): OAuthTokens {
90
105
  const access = body.access_token;
91
- if (typeof access !== 'string' || access === '')
92
- throw refused('That server did not return an access token.');
106
+ if (typeof access !== 'string' || !/^[\x21-\x7e]{1,16377}$/.test(access))
107
+ throw refused('That server did not return a sendable access token.');
108
+ validateOptionalTokens(body);
109
+ const expiresAt = expiryFrom(body);
93
110
  const refresh = body.refresh_token;
94
- const expires = body.expires_in;
95
111
  return {
96
112
  accessToken: access,
97
113
  ...(typeof refresh === 'string' ? { refreshToken: refresh } : {}),
98
- ...(typeof expires === 'number'
99
- ? { expiresAt: Date.now() + expires * 1000 }
100
- : {}),
114
+ ...(expiresAt === undefined ? {} : { expiresAt }),
101
115
  };
102
116
  }
103
117
 
@@ -105,6 +119,7 @@ async function postToken(
105
119
  server: OAuthServer,
106
120
  client: OAuthClient,
107
121
  form: Record<string, string>,
122
+ fetchImpl: FetchLike,
108
123
  ): Promise<OAuthTokens> {
109
124
  const params = new URLSearchParams({
110
125
  ...form,
@@ -115,7 +130,7 @@ async function postToken(
115
130
  });
116
131
  let res: Response;
117
132
  try {
118
- res = await fetch(server.tokenEndpoint, {
133
+ res = await fetchImpl(server.tokenEndpoint, {
119
134
  method: 'POST',
120
135
  redirect: 'manual',
121
136
  signal: AbortSignal.timeout(TOKEN_TIMEOUT_MS),
@@ -125,10 +140,11 @@ async function postToken(
125
140
  },
126
141
  body: params.toString(),
127
142
  });
128
- } catch {
129
- throw refused('Metro could not reach that server to finish signing in.');
143
+ } catch (err) {
144
+ throw refused(`Metro could not reach that server to finish signing in: ${whyUnreachable(err)}`);
130
145
  }
131
146
  const body: unknown = await res.json().catch(() => null);
147
+ if (form.grant_type === 'refresh_token' && res.status === 400 && isRecord(body) && body.error === 'invalid_grant') throw new OAuthInvalidGrant('That server requires a new sign-in.', 400);
132
148
  if (!res.ok || !isRecord(body))
133
149
  throw refused('That server refused to complete the sign-in.');
134
150
  return tokensFrom(body);
@@ -138,6 +154,7 @@ export function exchangeCode(
138
154
  server: OAuthServer,
139
155
  client: OAuthClient,
140
156
  input: { code: string; redirectUri: string; verifier: string; resource: string },
157
+ fetchImpl: FetchLike = fetch,
141
158
  ): Promise<OAuthTokens> {
142
159
  return postToken(server, client, {
143
160
  grant_type: 'authorization_code',
@@ -145,7 +162,7 @@ export function exchangeCode(
145
162
  redirect_uri: input.redirectUri,
146
163
  code_verifier: input.verifier,
147
164
  resource: input.resource,
148
- });
165
+ }, fetchImpl);
149
166
  }
150
167
 
151
168
  export function refreshTokens(
@@ -153,10 +170,13 @@ export function refreshTokens(
153
170
  client: OAuthClient,
154
171
  refreshToken: string,
155
172
  resource: string,
173
+ scope?: string,
174
+ fetchImpl: FetchLike = fetch,
156
175
  ): Promise<OAuthTokens> {
157
176
  return postToken(server, client, {
158
177
  grant_type: 'refresh_token',
159
178
  refresh_token: refreshToken,
160
179
  resource,
161
- });
180
+ ...(scope === undefined ? {} : { scope }),
181
+ }, fetchImpl);
162
182
  }
@@ -0,0 +1,92 @@
1
+ import { isRecord } from '@metro-labs/core/is-record';
2
+
3
+ export type ConnectorDecision = 'allow' | 'ask' | 'deny';
4
+
5
+ type ToolGroup = 'read' | 'write';
6
+
7
+ export interface ConnectorPolicy {
8
+ read?: ConnectorDecision;
9
+ write?: ConnectorDecision;
10
+ tools?: Record<string, ConnectorDecision>;
11
+ }
12
+
13
+ export interface ConnectorPolicyLayers {
14
+ organization: ConnectorPolicy;
15
+ agent: ConnectorPolicy;
16
+ }
17
+
18
+ const RANK: Record<ConnectorDecision, number> = { allow: 0, ask: 1, deny: 2 };
19
+ const TOOL_RE = /^[A-Za-z0-9_.:/-]{1,256}$/;
20
+
21
+ export const validConnectorToolName = (name: string): boolean => TOOL_RE.test(name) && !['__proto__', 'constructor', 'prototype'].includes(name);
22
+
23
+ const decision = (value: unknown): value is ConnectorDecision => value === 'allow' || value === 'ask' || value === 'deny';
24
+
25
+ export function connectorPolicyOf(value: unknown): ConnectorPolicy {
26
+ if (!isRecord(value) || Object.keys(value).some((key) => !['read', 'write', 'tools'].includes(key))) throw new Error('Invalid connector policy.');
27
+ const out: ConnectorPolicy = {};
28
+ for (const group of ['read', 'write'] as const) {
29
+ if (!Object.hasOwn(value, group)) continue;
30
+ const field = value[group];
31
+ if (!decision(field)) throw new Error('Invalid connector policy.');
32
+ out[group] = field;
33
+ }
34
+ if (Object.hasOwn(value, 'tools')) out.tools = toolPolicyOf(value.tools);
35
+ return out;
36
+ }
37
+
38
+ function toolPolicyOf(value: unknown): Record<string, ConnectorDecision> {
39
+ if (!isRecord(value) || Object.keys(value).length > 2000) throw new Error('Invalid connector policy.');
40
+ const out: Record<string, ConnectorDecision> = {};
41
+ for (const [name, rule] of Object.entries(value)) {
42
+ if (!validConnectorToolName(name) || !decision(rule)) throw new Error('Invalid connector policy.');
43
+ out[name] = rule;
44
+ }
45
+ return out;
46
+ }
47
+
48
+ export function connectorPolicyLayersOf(value: unknown): ConnectorPolicyLayers {
49
+ if (!isRecord(value) || Object.keys(value).some((key) => !['organization', 'agent'].includes(key))) throw new Error('Invalid connector policy layers.');
50
+ return { organization: connectorPolicyOf(value.organization), agent: connectorPolicyOf(value.agent) };
51
+ }
52
+
53
+ const strictest = (...values: (ConnectorDecision | undefined)[]): ConnectorDecision => values.reduce<ConnectorDecision>((held, next) => next !== undefined && RANK[next] > RANK[held] ? next : held, 'allow');
54
+ const toolRule = (policy: ConnectorPolicy, name: string): ConnectorDecision | undefined => policy.tools !== undefined && Object.hasOwn(policy.tools, name) ? policy.tools[name] : undefined;
55
+ const toolGroup = (groups: Record<string, ToolGroup>, name: string): ToolGroup => Object.hasOwn(groups, name) && groups[name] === 'read' ? 'read' : 'write';
56
+ const access = (policy: ConnectorPolicy, name: string, group: ToolGroup): ConnectorDecision => toolRule(policy, name) ?? policy[group] ?? 'allow';
57
+
58
+ export function combineConnectorPolicies(global: ConnectorPolicy, assignment: ConnectorPolicy, groups?: Record<string, ToolGroup>): ConnectorPolicy {
59
+ const policies = [connectorPolicyOf(global), connectorPolicyOf(assignment)];
60
+ const neutral = (policy: ConnectorPolicy): boolean => (policy.read ?? 'allow') === 'allow' && (policy.write ?? 'allow') === 'allow' && Object.keys(policy.tools ?? {}).length === 0;
61
+ if (neutral(assignment)) return connectorPolicyOf(global);
62
+ if (neutral(global)) return connectorPolicyOf(assignment);
63
+ const out: ConnectorPolicy = {
64
+ read: strictest(...policies.map((policy) => policy.read)),
65
+ write: strictest(...policies.map((policy) => policy.write)),
66
+ };
67
+ const names = new Set(policies.flatMap((policy) => Object.keys(policy.tools ?? {})));
68
+ if (groups === undefined && names.size > 2000) return { read: 'deny', write: 'deny' };
69
+ if (names.size > 0) {
70
+ out.tools = {};
71
+ for (const name of names) {
72
+ out.tools[name] = groups === undefined
73
+ ? strictest(...policies.flatMap((policy) => [policy.read, policy.write, toolRule(policy, name)]))
74
+ : strictest(...policies.map((policy) => access(policy, name, toolGroup(groups, name))));
75
+ }
76
+ }
77
+ return out;
78
+ }
79
+
80
+ export function effectiveConnectorPolicy(row: { policy: ConnectorPolicy; policyLayers?: ConnectorPolicyLayers }, groups: Record<string, ToolGroup>): ConnectorPolicy {
81
+ const layers = row.policyLayers;
82
+ return layers === undefined ? connectorPolicyOf(row.policy) : combineConnectorPolicies(layers.organization, layers.agent, groups);
83
+ }
84
+
85
+ export function connectorPoliciesBlocked(layers: ConnectorPolicyLayers): boolean {
86
+ const policies = [layers.organization, layers.agent];
87
+ const names = new Set(policies.flatMap((policy) => Object.keys(policy.tools ?? {})));
88
+ return (['read', 'write'] as const).every((group) =>
89
+ strictest(...policies.map((policy) => policy[group])) === 'deny' &&
90
+ [...names].every((name) => strictest(...policies.map((policy) => access(policy, name, group))) === 'deny'),
91
+ );
92
+ }
@@ -0,0 +1,64 @@
1
+ import { BlockList, isIP } from 'node:net';
2
+ import { parseConnectorUrl, refused } from './connector-url.js';
3
+
4
+ const blocked = new BlockList();
5
+ for (const [address, prefix] of [
6
+ ['0.0.0.0', 8], ['10.0.0.0', 8], ['100.64.0.0', 10], ['127.0.0.0', 8], ['169.254.0.0', 16], ['172.16.0.0', 12],
7
+ ['192.0.0.0', 24], ['192.0.2.0', 24], ['192.88.99.0', 24], ['192.168.0.0', 16], ['198.18.0.0', 15],
8
+ ['198.51.100.0', 24], ['203.0.113.0', 24], ['224.0.0.0', 4], ['240.0.0.0', 4],
9
+ ] as const) blocked.addSubnet(address, prefix, 'ipv4');
10
+ for (const [address, prefix] of [
11
+ ['2001::', 32], ['2001:10::', 28], ['2001:20::', 28], ['2001:db8::', 32], ['2002::', 16],
12
+ ] as const) blocked.addSubnet(address, prefix, 'ipv6');
13
+ const globalV6 = new BlockList();
14
+ globalV6.addSubnet('2000::', 3, 'ipv6');
15
+
16
+ export function publicConnectorAddress(address: string, family: number): boolean {
17
+ if (family === 4) return isIP(address) === 4 && !blocked.check(address, 'ipv4');
18
+ return isIP(address) === 6 && globalV6.check(address, 'ipv6') && !blocked.check(address, 'ipv6');
19
+ }
20
+
21
+ function publicHost(host: string): boolean {
22
+ const family = isIP(host);
23
+ if (family !== 0) return publicConnectorAddress(host, family);
24
+ if (/(^|\.)(localhost|local|internal|lan|home|invalid|test|onion)$/.test(host)) return false;
25
+ return host.includes('.') && host.split('.').every((label) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label));
26
+ }
27
+
28
+ function invalidText(raw: string): boolean {
29
+ return raw.length > 2048 || /[\s\\#]/.test(raw) || /%(?![0-9a-f]{2})/i.test(raw);
30
+ }
31
+
32
+ export function parsePublicConnectorUrl(raw: unknown): URL {
33
+ const invalid = (): never => { throw refused('An organization endpoint must be a public HTTPS URL without user information or a fragment.'); };
34
+ if (typeof raw !== 'string' || invalidText(raw)) return invalid();
35
+ const authority = /^https:\/\/([^/ ?#]+)/i.exec(raw)?.[1];
36
+ if (authority === undefined || authority.includes('@')) return invalid();
37
+ let url: URL;
38
+ try { url = parseConnectorUrl(raw); } catch { return invalid(); }
39
+ if (url.toString().length > 2048 || !publicHost(url.hostname.replace(/^\[|\]$/g, ''))) return invalid();
40
+ return url;
41
+ }
42
+
43
+ export function publicOAuthResource(raw: unknown): string {
44
+ try {
45
+ const url = parsePublicConnectorUrl(raw);
46
+ if (typeof raw === 'string' && !raw.includes('?') && url.search === '') return raw;
47
+ } catch {
48
+ throw refused('The public OAuth resource must be a public HTTPS identifier without a query, user information or a fragment. Do not enter credentials.');
49
+ }
50
+ throw refused('The public OAuth resource must be a public HTTPS identifier without a query, user information or a fragment. Do not enter credentials.');
51
+ }
52
+
53
+ export function optionalOAuthResource(raw: unknown): string | undefined {
54
+ return raw === undefined || raw === '' ? undefined : publicOAuthResource(raw);
55
+ }
56
+
57
+ export function boundOAuthResource(target: string, raw: unknown): string {
58
+ const resource = publicOAuthResource(raw);
59
+ const transport = parsePublicConnectorUrl(target);
60
+ const url = new URL(resource);
61
+ const path = url.pathname.replace(/\/$/, '');
62
+ if (url.origin !== transport.origin || !(path === '' || transport.pathname === path || transport.pathname.startsWith(`${path}/`))) throw refused('The public OAuth resource does not identify this endpoint. Check the provider’s documented resource.');
63
+ return resource;
64
+ }
@@ -0,0 +1,27 @@
1
+ import { errMsg } from '@metro-labs/core/log';
2
+
3
+ const HINTS: Record<string, string> = {
4
+ ENOTFOUND: 'the name does not resolve',
5
+ EAI_AGAIN: 'the name did not resolve in time',
6
+ ECONNREFUSED: 'nothing is listening there',
7
+ ECONNRESET: 'the server dropped the connection',
8
+ ETIMEDOUT: 'the server did not answer in time',
9
+ ConnectionRefused: 'nothing is listening there',
10
+ CERT_HAS_EXPIRED: 'its certificate has expired',
11
+ DEPTH_ZERO_SELF_SIGNED_CERT: 'its certificate is self-signed',
12
+ UNABLE_TO_VERIFY_LEAF_SIGNATURE: 'its certificate could not be verified',
13
+ ERR_TLS_CERT_ALTNAME_INVALID: 'its certificate is for another name',
14
+ SELF_SIGNED_CERT_IN_CHAIN: 'its certificate chain is not trusted',
15
+ };
16
+
17
+ const codeOf = (err: unknown): string =>
18
+ err !== null && typeof err === 'object' && 'code' in err && typeof err.code === 'string' ? err.code : '';
19
+
20
+ export function whyUnreachable(err: unknown): string {
21
+ const inner = err instanceof Error && err.cause instanceof Error ? err.cause : err;
22
+ const message = errMsg(inner).trim();
23
+ const code = codeOf(inner) || codeOf(err);
24
+ const said = message !== '' && message !== 'fetch failed' ? message : code || 'no answer';
25
+ const hint = HINTS[code];
26
+ return hint === undefined ? said : `${said} (${hint})`;
27
+ }
@@ -0,0 +1,108 @@
1
+ import { isRecord } from '@metro-labs/core/is-record';
2
+ import type { FetchLike } from '@metro-labs/core/stations/oauth';
3
+ import { authServerMetadataUrls, resourceMetadataUrls, type OAuthServer } from './connector-discovery.js';
4
+ import { boundOAuthResource, optionalOAuthResource, parsePublicConnectorUrl, publicOAuthResource } from './connector-public-url.js';
5
+ import { refused, ConnectorVerifyError } from './connector-url.js';
6
+
7
+ const METADATA_MAX = 1024 * 1024;
8
+ const metadataError = (): Error => refused('The provider returned invalid or unavailable public OAuth metadata. Check its public OAuth resource and try again.');
9
+ export class OAuthResourceRequired extends ConnectorVerifyError {
10
+ constructor() { super('Enter the provider’s public OAuth resource before continuing. It is shown in the sign-in page; never enter a private endpoint or credentials.', 400); }
11
+ }
12
+
13
+ async function metadataBody(res: Response): Promise<Record<string, unknown>> {
14
+ if (res.body === null) throw metadataError();
15
+ const reader = res.body.getReader();
16
+ const chunks: Uint8Array[] = [];
17
+ let size = 0;
18
+ try {
19
+ for (;;) {
20
+ const { done, value } = await reader.read();
21
+ if (done) break;
22
+ size += value.length;
23
+ if (size > METADATA_MAX) throw metadataError();
24
+ chunks.push(value);
25
+ }
26
+ const body: unknown = JSON.parse(Buffer.concat(chunks).toString('utf8'));
27
+ if (!isRecord(body)) throw metadataError();
28
+ return body;
29
+ } finally {
30
+ await reader.cancel().catch(() => undefined);
31
+ }
32
+ }
33
+
34
+ async function metadata(url: URL, send: FetchLike): Promise<Record<string, unknown> | null> {
35
+ try {
36
+ const res = await send(url.toString(), { redirect: 'manual', signal: AbortSignal.timeout(10_000), headers: { accept: 'application/json' } });
37
+ if (res.status === 404) {
38
+ await res.body?.cancel();
39
+ return null;
40
+ }
41
+ if (!res.ok) {
42
+ await res.body?.cancel();
43
+ throw metadataError();
44
+ }
45
+ return await metadataBody(res);
46
+ } catch {
47
+ throw metadataError();
48
+ }
49
+ }
50
+
51
+ function selectedResource(transport: URL, offered: string | undefined, body: Record<string, unknown> | null): string {
52
+ const advertised = body !== null && Object.hasOwn(body, 'resource') ? publicOAuthResource(body.resource) : undefined;
53
+ if (advertised !== undefined && offered !== undefined && advertised !== offered) throw metadataError();
54
+ const resource = advertised ?? offered;
55
+ if (resource === undefined) throw new OAuthResourceRequired();
56
+ return boundOAuthResource(transport.toString(), resource);
57
+ }
58
+
59
+ function issuerOf(body: Record<string, unknown> | null, transport: URL): string {
60
+ if (body === null || !Object.hasOwn(body, 'authorization_servers')) return transport.origin;
61
+ const servers = body.authorization_servers;
62
+ if (!Array.isArray(servers) || servers.length === 0 || servers.length > 20) throw metadataError();
63
+ const values = servers.map((value: unknown) => publicOAuthResource(value));
64
+ return values[0] ?? '';
65
+ }
66
+
67
+ function scopesOf(body: Record<string, unknown> | null): string[] {
68
+ if (body === null || !Object.hasOwn(body, 'scopes_supported')) return [];
69
+ const scopes = body.scopes_supported;
70
+ if (!Array.isArray(scopes) || scopes.length > 100 || scopes.some((scope: unknown) => typeof scope !== 'string' || !/^[\x21\x23-\x5b\x5d-\x7e]{1,128}$/.test(scope))) throw metadataError();
71
+ return [...new Set(scopes as string[])];
72
+ }
73
+
74
+ function serverOf(body: Record<string, unknown>, issuer: string, scopes: string[]): OAuthServer {
75
+ if (typeof body.issuer !== 'string' || publicOAuthResource(body.issuer) !== issuer) throw metadataError();
76
+ const endpoint = (raw: unknown): string => parsePublicConnectorUrl(raw).toString();
77
+ return {
78
+ issuer,
79
+ authorizationEndpoint: endpoint(body.authorization_endpoint),
80
+ tokenEndpoint: endpoint(body.token_endpoint),
81
+ registrationEndpoint: body.registration_endpoint === undefined ? null : endpoint(body.registration_endpoint),
82
+ supportsS256: Array.isArray(body.code_challenge_methods_supported) && body.code_challenge_methods_supported.includes('S256'),
83
+ scopes,
84
+ };
85
+ }
86
+
87
+ async function protectedMetadata(base: URL, send: FetchLike): Promise<Record<string, unknown> | null> {
88
+ for (const candidate of resourceMetadataUrls(base)) {
89
+ const body = await metadata(candidate, send);
90
+ if (body !== null) return body;
91
+ }
92
+ return null;
93
+ }
94
+
95
+ export async function discoverPublicOAuth(target: string, offered: unknown, send: FetchLike = fetch): Promise<{ server: OAuthServer; resource: string }> {
96
+ const transport = parsePublicConnectorUrl(target);
97
+ const explicit = optionalOAuthResource(offered);
98
+ if (explicit !== undefined) boundOAuthResource(target, explicit);
99
+ const body = await protectedMetadata(new URL(explicit ?? transport.origin), send);
100
+ const resource = selectedResource(transport, explicit, body);
101
+ const issuer = issuerOf(body, transport);
102
+ const scopes = scopesOf(body);
103
+ for (const candidate of authServerMetadataUrls(new URL(issuer))) {
104
+ const authorization = await metadata(candidate, send);
105
+ if (authorization !== null) return { server: serverOf(authorization, issuer, scopes), resource };
106
+ }
107
+ throw metadataError();
108
+ }