@stage-labs/metro 0.1.0-beta.26 → 0.1.0-beta.261

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 (541) hide show
  1. package/dist/agent.js +128 -0
  2. package/dist/api.js +9 -129
  3. package/dist/background.js +141 -0
  4. package/dist/claude-settings.js +40 -0
  5. package/dist/claude.js +201 -0
  6. package/dist/cli.js +67 -117
  7. package/dist/control.js +19 -103
  8. package/dist/hold.js +210 -0
  9. package/dist/local.js +43 -0
  10. package/dist/mcp-config.js +27 -0
  11. package/dist/memory.js +222 -0
  12. package/dist/node-name.js +71 -0
  13. package/dist/onboarding.js +44 -0
  14. package/dist/provider-flags.js +9 -0
  15. package/dist/root-release-io.js +161 -0
  16. package/dist/root-release.js +74 -0
  17. package/dist/route.js +66 -0
  18. package/dist/runtime-install.js +97 -0
  19. package/dist/runtime.js +29 -52
  20. package/dist/serve.js +157 -0
  21. package/dist/service.js +328 -0
  22. package/dist/tail.js +10 -11
  23. package/dist/update.js +13 -1
  24. package/dist/voice.js +56 -0
  25. package/package.json +3 -24
  26. package/runtime/marketplace/.claude-plugin/marketplace.json +12 -0
  27. package/runtime/marketplace/plugin/.claude-plugin/plugin.json +17 -0
  28. package/runtime/marketplace/plugin/.mcp.json +1 -0
  29. package/runtime/marketplace/plugin/MEMORY.md +78 -0
  30. package/runtime/marketplace/plugin/METRO.md +26 -0
  31. package/runtime/marketplace/plugin/STAGE.md +95 -0
  32. package/runtime/marketplace/plugin/bin/guard.mjs +75 -0
  33. package/runtime/marketplace/plugin/bin/metro-plugin.mjs +30 -0
  34. package/runtime/marketplace/plugin/bin/policy.mjs +97 -0
  35. package/runtime/marketplace/plugin/bin/session-start.mjs +31 -0
  36. package/runtime/marketplace/plugin/hooks/hooks.json +25 -0
  37. package/runtime/node_modules/@metro-labs/core/package.json +52 -0
  38. package/runtime/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  39. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/events.ts +11 -7
  40. package/runtime/node_modules/@metro-labs/{mcp/src/db → core/src}/ids.ts +10 -1
  41. package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  42. package/runtime/node_modules/@metro-labs/{mcp/src/stations → core/src}/lines.ts +22 -26
  43. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/protocol.ts +7 -4
  44. package/runtime/node_modules/@metro-labs/core/src/runner-activity.ts +103 -0
  45. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/secure-fs.ts +17 -0
  46. package/runtime/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  47. package/runtime/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  48. package/runtime/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  49. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/attachments.ts +0 -1
  50. package/runtime/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  51. package/runtime/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  52. package/runtime/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  53. package/runtime/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  54. package/runtime/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  55. package/runtime/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  56. package/runtime/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  57. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/station-runtime.ts +6 -11
  58. package/runtime/node_modules/@metro-labs/core/src/stations/train-boot.ts +42 -0
  59. package/runtime/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  60. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/types.ts +19 -1
  61. package/runtime/node_modules/@metro-labs/core/src/tickets.ts +37 -0
  62. package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
  63. package/runtime/node_modules/@metro-labs/daemon/package.json +51 -0
  64. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/agent-fs.ts +246 -0
  65. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/crontab.ts +44 -0
  66. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files-api.ts +12 -0
  67. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files.ts +89 -0
  68. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/home-fs.ts +113 -0
  69. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/job-env.ts +39 -0
  70. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/metro-home.ts +42 -0
  71. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/provision.ts +81 -0
  72. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedule-detail.ts +93 -0
  73. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules-api.ts +27 -0
  74. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules.ts +144 -0
  75. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/unit-files.ts +43 -0
  76. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/user.ts +91 -0
  77. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/view.ts +93 -0
  78. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
  79. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-lookups.ts +55 -0
  80. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-routes.ts +76 -0
  81. package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +357 -0
  82. package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +30 -0
  83. package/runtime/node_modules/@metro-labs/daemon/src/agents/allowlist.ts +59 -0
  84. package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +131 -0
  85. package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +132 -0
  86. package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +305 -0
  87. package/runtime/node_modules/@metro-labs/daemon/src/agents/files.ts +142 -0
  88. package/runtime/node_modules/@metro-labs/{mcp/src/db/key-map.ts → daemon/src/agents/keys.ts} +1 -11
  89. package/runtime/node_modules/@metro-labs/daemon/src/agents/map.ts +133 -0
  90. package/runtime/node_modules/@metro-labs/daemon/src/agents/policy-route.ts +27 -0
  91. package/runtime/node_modules/@metro-labs/{mcp/src/db/agent-scope.ts → daemon/src/agents/scope.ts} +2 -2
  92. package/runtime/node_modules/@metro-labs/daemon/src/agents/sender-cards.ts +94 -0
  93. package/runtime/node_modules/@metro-labs/daemon/src/agents/senders.ts +38 -0
  94. package/runtime/node_modules/@metro-labs/daemon/src/approvals/api.ts +55 -0
  95. package/runtime/node_modules/@metro-labs/daemon/src/approvals/pending.ts +150 -0
  96. package/runtime/node_modules/@metro-labs/daemon/src/approvals/preview.ts +66 -0
  97. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +238 -0
  98. package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +36 -0
  99. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/crash-guard.ts +1 -1
  100. package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +21 -0
  101. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/paths.ts +8 -36
  102. package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +26 -0
  103. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/inbound.ts +75 -45
  104. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/media-note.ts +11 -7
  105. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/pending.ts +4 -1
  106. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/relay.ts +2 -2
  107. package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +285 -0
  108. package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +359 -0
  109. package/runtime/node_modules/@metro-labs/daemon/src/claude/login.ts +242 -0
  110. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory-routine.ts +123 -0
  111. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory.ts +32 -0
  112. package/runtime/node_modules/@metro-labs/daemon/src/claude/onboarding.ts +60 -0
  113. package/runtime/node_modules/@metro-labs/daemon/src/claude/plugin-install.ts +149 -0
  114. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-activity.ts +17 -0
  115. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-process.ts +50 -0
  116. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner.ts +45 -0
  117. package/runtime/node_modules/@metro-labs/daemon/src/claude/session-continuity.ts +48 -0
  118. package/runtime/node_modules/@metro-labs/daemon/src/claude/session-files.ts +75 -0
  119. package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +358 -0
  120. package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +109 -0
  121. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-api.ts +161 -0
  122. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-state.ts +18 -0
  123. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +343 -0
  124. package/runtime/node_modules/@metro-labs/daemon/src/claude/skills.ts +120 -0
  125. package/runtime/node_modules/@metro-labs/daemon/src/claude/usage-probe.ts +128 -0
  126. package/runtime/node_modules/@metro-labs/daemon/src/claude/version.ts +113 -0
  127. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-api.ts → daemon/src/connectors/api.ts} +79 -114
  128. package/runtime/node_modules/@metro-labs/{mcp/src/db/connector-config.ts → daemon/src/connectors/config.ts} +67 -41
  129. package/runtime/node_modules/@metro-labs/daemon/src/connectors/gates.ts +72 -0
  130. package/runtime/node_modules/@metro-labs/daemon/src/connectors/health.ts +18 -0
  131. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/oauth-client.ts +14 -17
  132. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/oauth-discovery.ts +33 -20
  133. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-oauth-routes.ts → daemon/src/connectors/oauth-routes.ts} +30 -32
  134. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-oauth.ts → daemon/src/connectors/oauth.ts} +60 -21
  135. package/runtime/node_modules/@metro-labs/daemon/src/connectors/plugin-sync.ts +131 -0
  136. package/runtime/node_modules/@metro-labs/daemon/src/connectors/reach.ts +27 -0
  137. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-policy.ts +90 -0
  138. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/relay.ts +80 -35
  139. package/runtime/node_modules/@metro-labs/daemon/src/connectors/store.ts +385 -0
  140. package/runtime/node_modules/@metro-labs/daemon/src/connectors/tools.ts +81 -0
  141. package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-api.ts +116 -0
  142. package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-crypto.ts +44 -0
  143. package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-store.ts +48 -0
  144. package/runtime/node_modules/@metro-labs/daemon/src/connectors/url.ts +37 -0
  145. package/runtime/node_modules/@metro-labs/daemon/src/connectors/verify.ts +106 -0
  146. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-grant.ts +4 -4
  147. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-owner.ts +3 -3
  148. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-reaper.ts +174 -0
  149. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-serve.ts +11 -17
  150. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-api.ts +10 -27
  151. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-store.ts +4 -4
  152. package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +233 -0
  153. package/runtime/node_modules/@metro-labs/daemon/src/gateway/claude-logins.ts +168 -0
  154. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-auth.ts +219 -0
  155. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +119 -0
  156. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +179 -0
  157. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +209 -0
  158. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-version.ts +44 -0
  159. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +143 -0
  160. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effort.ts +103 -0
  161. package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
  162. package/runtime/node_modules/@metro-labs/daemon/src/gateway/fallback.ts +147 -0
  163. package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +285 -0
  164. package/runtime/node_modules/@metro-labs/daemon/src/gateway/frames.ts +118 -0
  165. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +396 -0
  166. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-auth.ts +160 -0
  167. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-client.ts +46 -0
  168. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-setup.ts +150 -0
  169. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-stream.ts +139 -0
  170. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-translate.ts +236 -0
  171. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini.ts +208 -0
  172. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +256 -0
  173. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +353 -0
  174. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-lists.ts +57 -0
  175. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-signin.ts +157 -0
  176. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-store.ts +83 -0
  177. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter-login.ts +192 -0
  178. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter-signin.ts +64 -0
  179. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +104 -0
  180. package/runtime/node_modules/@metro-labs/daemon/src/gateway/pkce.ts +36 -0
  181. package/runtime/node_modules/@metro-labs/daemon/src/gateway/provider-models.ts +117 -0
  182. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +18 -0
  183. package/runtime/node_modules/@metro-labs/daemon/src/gateway/subscription.ts +120 -0
  184. package/runtime/node_modules/@metro-labs/daemon/src/gateway/text.ts +35 -0
  185. package/runtime/node_modules/@metro-labs/daemon/src/gateway/tool-search.ts +126 -0
  186. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage-refresh.ts +115 -0
  187. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +343 -0
  188. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/accounts.ts +38 -18
  189. package/runtime/node_modules/@metro-labs/daemon/src/mcp/attachment-schema.ts +91 -0
  190. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/call-tools.ts +86 -38
  191. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/ctx.ts +4 -4
  192. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/event-store.ts +15 -16
  193. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/group-tools.ts +2 -2
  194. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/index.ts +49 -77
  195. package/runtime/node_modules/@metro-labs/daemon/src/mcp/instructions.ts +30 -0
  196. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/member-tools.ts +2 -2
  197. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-prompt.ts +92 -0
  198. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +88 -0
  199. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-gate.ts +82 -0
  200. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-snapshot.ts +79 -0
  201. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-lookup.ts +60 -0
  202. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-tool.ts +96 -0
  203. package/runtime/node_modules/@metro-labs/daemon/src/mcp/read-tool.ts +87 -0
  204. package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +48 -0
  205. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-slot.ts +75 -0
  206. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/session.ts +61 -57
  207. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-catalog.ts +93 -0
  208. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-def.ts +9 -0
  209. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-dispatch.ts +53 -40
  210. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-schemas.ts +115 -114
  211. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/upload-tool.ts +6 -11
  212. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/helper-script.ts +183 -0
  213. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/imds.ts +16 -0
  214. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/install.ts +78 -0
  215. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/privilege.ts +50 -0
  216. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/root-follow.ts +16 -0
  217. package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +132 -0
  218. package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +316 -0
  219. package/runtime/node_modules/@metro-labs/daemon/src/policy/policy.ts +118 -0
  220. package/runtime/node_modules/@metro-labs/daemon/src/routes/bearer.ts +38 -0
  221. package/runtime/node_modules/@metro-labs/daemon/src/routes/body.ts +24 -0
  222. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/routes}/http.ts +64 -53
  223. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +210 -0
  224. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +71 -0
  225. package/runtime/node_modules/@metro-labs/daemon/src/routes/session.ts +29 -0
  226. package/runtime/node_modules/@metro-labs/daemon/src/routes/threema-callback.ts +103 -0
  227. package/runtime/node_modules/@metro-labs/daemon/src/server/cloudwatch.ts +178 -0
  228. package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +39 -0
  229. package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +58 -0
  230. package/runtime/node_modules/@metro-labs/daemon/src/server/owner.ts +26 -0
  231. package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +90 -0
  232. package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
  233. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-browser.ts +102 -0
  234. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-driver.ts +42 -0
  235. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-inline.ts +29 -1
  236. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-interactive.ts +5 -31
  237. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-resolve.ts +84 -13
  238. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/attach-session.ts +32 -22
  239. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-xmtp.ts +8 -9
  240. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach.ts +69 -3
  241. package/runtime/node_modules/@metro-labs/{mcp/src/db → daemon/src/stations}/materialize.ts +60 -175
  242. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/registry.ts +20 -2
  243. package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +82 -0
  244. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor-io.ts +3 -3
  245. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor.ts +6 -9
  246. package/runtime/node_modules/@metro-labs/daemon/src/stations/threema-callbacks.ts +32 -0
  247. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/train-call.ts +1 -1
  248. package/runtime/node_modules/@metro-labs/daemon/src/stations/webhook-endpoints.ts +51 -0
  249. package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +84 -0
  250. package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +124 -0
  251. package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +15 -0
  252. package/runtime/node_modules/@metro-labs/daemon/src/vault/api.ts +45 -0
  253. package/runtime/node_modules/@metro-labs/daemon/src/vault/config.ts +51 -0
  254. package/runtime/node_modules/@metro-labs/daemon/src/vault/firewall.ts +9 -0
  255. package/runtime/node_modules/@metro-labs/daemon/src/vault/index.ts +96 -0
  256. package/runtime/node_modules/@metro-labs/daemon/src/vault/install.ts +56 -0
  257. package/runtime/node_modules/@metro-labs/daemon/src/vault/paths.ts +26 -0
  258. package/runtime/node_modules/@metro-labs/daemon/src/vault/proxy.ts +147 -0
  259. package/runtime/node_modules/@metro-labs/daemon/src/vault/store.ts +129 -0
  260. package/runtime/node_modules/@metro-labs/daemon/src/vault/trust.ts +44 -0
  261. package/runtime/node_modules/@metro-labs/daemon/src/voice/api.ts +14 -0
  262. package/runtime/node_modules/@metro-labs/daemon/src/voice/approvals.ts +38 -0
  263. package/runtime/node_modules/@metro-labs/daemon/src/voice/audio.ts +153 -0
  264. package/runtime/node_modules/@metro-labs/daemon/src/voice/brain.ts +135 -0
  265. package/runtime/node_modules/@metro-labs/daemon/src/voice/call.ts +200 -0
  266. package/runtime/node_modules/@metro-labs/daemon/src/voice/calls.ts +130 -0
  267. package/runtime/node_modules/@metro-labs/daemon/src/voice/peer.ts +84 -0
  268. package/runtime/node_modules/@metro-labs/daemon/src/voice/scribe.ts +103 -0
  269. package/runtime/node_modules/@metro-labs/daemon/src/voice/speakable.ts +54 -0
  270. package/runtime/node_modules/@metro-labs/daemon/src/voice/speech.ts +104 -0
  271. package/runtime/node_modules/@metro-labs/daemon/src/voice/store.ts +116 -0
  272. package/runtime/node_modules/@metro-labs/daemon/src/voice/talk.ts +256 -0
  273. package/runtime/node_modules/@metro-labs/discord-bot/package.json +3 -5
  274. package/runtime/node_modules/@metro-labs/discord-bot/src/accounts.ts +3 -23
  275. package/runtime/node_modules/@metro-labs/discord-bot/src/actions.ts +19 -187
  276. package/runtime/node_modules/@metro-labs/discord-bot/src/attachments.ts +2 -2
  277. package/runtime/node_modules/@metro-labs/discord-bot/src/format.ts +26 -67
  278. package/runtime/node_modules/@metro-labs/discord-bot/src/group-actions.ts +1 -1
  279. package/runtime/node_modules/@metro-labs/discord-bot/src/group.ts +2 -2
  280. package/runtime/node_modules/@metro-labs/discord-bot/src/index.ts +8 -14
  281. package/runtime/node_modules/@metro-labs/discord-bot/src/members.ts +2 -2
  282. package/runtime/node_modules/@metro-labs/discord-bot/src/profile.ts +68 -0
  283. package/runtime/node_modules/@metro-labs/discord-bot/src/send-files.ts +12 -13
  284. package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +5 -1
  285. package/runtime/node_modules/@metro-labs/gmail/package.json +25 -0
  286. package/runtime/node_modules/@metro-labs/gmail/src/accounts.ts +81 -0
  287. package/runtime/node_modules/@metro-labs/gmail/src/actions.ts +14 -0
  288. package/runtime/node_modules/@metro-labs/gmail/src/api.ts +31 -0
  289. package/runtime/node_modules/@metro-labs/gmail/src/attachments.ts +35 -0
  290. package/runtime/node_modules/@metro-labs/gmail/src/auth.ts +105 -0
  291. package/runtime/node_modules/@metro-labs/gmail/src/config.ts +13 -0
  292. package/runtime/node_modules/@metro-labs/gmail/src/inbound.ts +96 -0
  293. package/runtime/node_modules/@metro-labs/gmail/src/index.ts +12 -0
  294. package/runtime/node_modules/@metro-labs/gmail/src/login.ts +37 -0
  295. package/runtime/node_modules/@metro-labs/gmail/src/message.ts +125 -0
  296. package/runtime/node_modules/@metro-labs/gmail/src/mime.ts +70 -0
  297. package/runtime/node_modules/@metro-labs/gmail/src/outbound.ts +124 -0
  298. package/runtime/node_modules/@metro-labs/gmail/src/query.ts +99 -0
  299. package/runtime/node_modules/@metro-labs/gmail/src/state.ts +24 -0
  300. package/runtime/node_modules/@metro-labs/gmail/src/station.ts +15 -0
  301. package/runtime/node_modules/@metro-labs/gmail/src/trust.ts +42 -0
  302. package/runtime/node_modules/@metro-labs/http/package.json +30 -0
  303. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +141 -0
  304. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/session-api.ts → http/src/mode-api.ts} +13 -9
  305. package/runtime/node_modules/@metro-labs/http/src/return-to.ts +25 -0
  306. package/runtime/node_modules/@metro-labs/http/src/sigv4.ts +90 -0
  307. package/runtime/node_modules/@metro-labs/http/src/workos-token.ts +149 -0
  308. package/runtime/node_modules/@metro-labs/outlook/package.json +25 -0
  309. package/runtime/node_modules/@metro-labs/outlook/src/accounts.ts +78 -0
  310. package/runtime/node_modules/@metro-labs/outlook/src/actions.ts +14 -0
  311. package/runtime/node_modules/@metro-labs/outlook/src/attachments.ts +81 -0
  312. package/runtime/node_modules/@metro-labs/outlook/src/auth.ts +120 -0
  313. package/runtime/node_modules/@metro-labs/outlook/src/browser.ts +42 -0
  314. package/runtime/node_modules/@metro-labs/outlook/src/config.ts +23 -0
  315. package/runtime/node_modules/@metro-labs/outlook/src/format.ts +59 -0
  316. package/runtime/node_modules/@metro-labs/outlook/src/graph.ts +55 -0
  317. package/runtime/node_modules/@metro-labs/outlook/src/inbound.ts +96 -0
  318. package/runtime/node_modules/@metro-labs/outlook/src/index.ts +12 -0
  319. package/runtime/node_modules/@metro-labs/outlook/src/login.ts +129 -0
  320. package/runtime/node_modules/@metro-labs/outlook/src/me.ts +31 -0
  321. package/runtime/node_modules/@metro-labs/outlook/src/outbound.ts +103 -0
  322. package/runtime/node_modules/@metro-labs/outlook/src/query.ts +84 -0
  323. package/runtime/node_modules/@metro-labs/outlook/src/state.ts +28 -0
  324. package/runtime/node_modules/@metro-labs/outlook/src/station.ts +15 -0
  325. package/runtime/node_modules/@metro-labs/outlook/src/trust.ts +41 -0
  326. package/runtime/node_modules/@metro-labs/telegram/package.json +2 -4
  327. package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +5 -24
  328. package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +8 -6
  329. package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +1 -1
  330. package/runtime/node_modules/@metro-labs/telegram/src/client.ts +4 -4
  331. package/runtime/node_modules/@metro-labs/telegram/src/format.ts +19 -34
  332. package/runtime/node_modules/@metro-labs/telegram/src/group.ts +3 -3
  333. package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +13 -34
  334. package/runtime/node_modules/@metro-labs/telegram/src/index.ts +4 -43
  335. package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +2 -3
  336. package/runtime/node_modules/@metro-labs/telegram/src/members.ts +1 -1
  337. package/runtime/node_modules/@metro-labs/telegram/src/profile.ts +70 -0
  338. package/runtime/node_modules/@metro-labs/telegram/src/reactions.ts +2 -2
  339. package/runtime/node_modules/@metro-labs/telegram/src/station.ts +4 -1
  340. package/runtime/node_modules/@metro-labs/telegram/src/types.ts +0 -1
  341. package/runtime/node_modules/@metro-labs/telegram-bot/package.json +2 -2
  342. package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +7 -41
  343. package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +22 -77
  344. package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +2 -2
  345. package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +46 -48
  346. package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +15 -15
  347. package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +6 -82
  348. package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +1 -1
  349. package/runtime/node_modules/@metro-labs/telegram-bot/src/profile.ts +85 -0
  350. package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +5 -1
  351. package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +20 -12
  352. package/runtime/node_modules/@metro-labs/threema/package.json +26 -0
  353. package/runtime/node_modules/@metro-labs/threema/src/accounts.ts +96 -0
  354. package/runtime/node_modules/@metro-labs/threema/src/actions.ts +124 -0
  355. package/runtime/node_modules/@metro-labs/threema/src/api.ts +152 -0
  356. package/runtime/node_modules/@metro-labs/threema/src/crypto.ts +100 -0
  357. package/runtime/node_modules/@metro-labs/threema/src/files.ts +47 -0
  358. package/runtime/node_modules/@metro-labs/threema/src/format.ts +164 -0
  359. package/runtime/node_modules/@metro-labs/threema/src/groups.ts +96 -0
  360. package/runtime/node_modules/@metro-labs/threema/src/ids.ts +21 -0
  361. package/runtime/node_modules/@metro-labs/threema/src/inbound.ts +87 -0
  362. package/runtime/node_modules/@metro-labs/threema/src/index.ts +24 -0
  363. package/runtime/node_modules/@metro-labs/threema/src/messages.ts +264 -0
  364. package/runtime/node_modules/@metro-labs/threema/src/outbound.ts +160 -0
  365. package/runtime/node_modules/@metro-labs/threema/src/station.ts +13 -0
  366. package/runtime/node_modules/@metro-labs/threema/src/verify.ts +117 -0
  367. package/runtime/node_modules/@metro-labs/webhook/package.json +2 -2
  368. package/runtime/node_modules/@metro-labs/webhook/src/station.ts +5 -8
  369. package/runtime/node_modules/@metro-labs/whatsapp/package.json +3 -6
  370. package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +6 -28
  371. package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +1 -1
  372. package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +54 -11
  373. package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +2 -2
  374. package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +1 -1
  375. package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +86 -4
  376. package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +7 -58
  377. package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +11 -28
  378. package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +4 -37
  379. package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +1 -1
  380. package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +1 -1
  381. package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +1 -1
  382. package/runtime/node_modules/@metro-labs/whatsapp/src/names.ts +75 -0
  383. package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +44 -0
  384. package/runtime/node_modules/@metro-labs/whatsapp/src/resolve.ts +52 -0
  385. package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +16 -1
  386. package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +5 -9
  387. package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +0 -1
  388. package/runtime/node_modules/@metro-labs/xmtp/package.json +4 -3
  389. package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +10 -20
  390. package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +2 -2
  391. package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +39 -223
  392. package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +47 -53
  393. package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +112 -223
  394. package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +3 -3
  395. package/runtime/node_modules/@metro-labs/xmtp/src/call-leftovers.ts +48 -0
  396. package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +113 -3
  397. package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +35 -20
  398. package/runtime/node_modules/@metro-labs/xmtp/src/delete-requests.ts +34 -0
  399. package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +37 -25
  400. package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +8 -18
  401. package/runtime/node_modules/@metro-labs/xmtp/src/frames.ts +178 -0
  402. package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +1 -1
  403. package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +2 -2
  404. package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +30 -16
  405. package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +18 -70
  406. package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +102 -50
  407. package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +1 -1
  408. package/runtime/node_modules/@metro-labs/xmtp/src/names.ts +61 -0
  409. package/runtime/node_modules/@metro-labs/xmtp/src/network.ts +110 -0
  410. package/runtime/node_modules/@metro-labs/xmtp/src/profile.ts +160 -0
  411. package/runtime/node_modules/@metro-labs/xmtp/src/resolve.ts +44 -0
  412. package/runtime/node_modules/@metro-labs/xmtp/src/sender.ts +112 -0
  413. package/runtime/node_modules/@metro-labs/xmtp/src/smart.ts +79 -0
  414. package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +8 -2
  415. package/runtime/node_modules/@metro-labs/xmtp/src/stream.ts +66 -0
  416. package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +22 -58
  417. package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +72 -49
  418. package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +4 -6
  419. package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +19 -5
  420. package/runtime/node_modules/@metro-labs/xmtp/src/wallet.ts +28 -0
  421. package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +14 -4
  422. package/runtime/runtime.json +1 -1
  423. package/runtime/sdk-runner/node_modules/@metro-labs/core/package.json +52 -0
  424. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  425. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/events.ts +121 -0
  426. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/ids.ts +28 -0
  427. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  428. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/lines.ts +78 -0
  429. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/log.ts +42 -0
  430. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/protocol.ts +227 -0
  431. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/runner-activity.ts +103 -0
  432. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/secure-fs.ts +74 -0
  433. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  434. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  435. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  436. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/attachments.ts +195 -0
  437. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  438. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  439. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  440. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  441. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  442. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  443. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  444. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/station-runtime.ts +59 -0
  445. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-boot.ts +42 -0
  446. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  447. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/types.ts +125 -0
  448. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/str.ts +5 -0
  449. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/tickets.ts +37 -0
  450. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/train-error.ts +53 -0
  451. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/version.ts +2 -0
  452. package/runtime/sdk-runner/runner.json +10 -0
  453. package/runtime/sdk-runner/src/activity-tasks.ts +142 -0
  454. package/runtime/sdk-runner/src/activity.ts +293 -0
  455. package/runtime/sdk-runner/src/app.ts +77 -0
  456. package/runtime/sdk-runner/src/approvals.ts +28 -0
  457. package/runtime/sdk-runner/src/channel-text.ts +26 -0
  458. package/runtime/sdk-runner/src/config.ts +50 -0
  459. package/runtime/sdk-runner/src/inbox.ts +94 -0
  460. package/runtime/sdk-runner/src/link.ts +130 -0
  461. package/runtime/sdk-runner/src/main.ts +44 -0
  462. package/runtime/sdk-runner/src/rules.ts +11 -0
  463. package/runtime/sdk-runner/src/runner.ts +251 -0
  464. package/runtime/sdk-runner/src/session-store.ts +71 -0
  465. package/runtime/sdk-runner/src/session-watch.ts +111 -0
  466. package/runtime/sdk-runner/src/singleton.ts +15 -0
  467. package/runtime/sdk-runner/src/speech.ts +79 -0
  468. package/runtime/sdk-runner/src/tool-proxy.ts +40 -0
  469. package/runtime/server.ts +1 -0
  470. package/runtime/stations.json +40 -0
  471. package/dist/plugin.js +0 -82
  472. package/dist/prompt.js +0 -61
  473. package/dist/store.js +0 -70
  474. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-speak.ts +0 -195
  475. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-transcribe.ts +0 -292
  476. package/runtime/node_modules/@metro-labs/discord-bot/src/voice.ts +0 -197
  477. package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +0 -5
  478. package/runtime/node_modules/@metro-labs/mcp/package.json +0 -66
  479. package/runtime/node_modules/@metro-labs/mcp/src/channels/dedupe.ts +0 -24
  480. package/runtime/node_modules/@metro-labs/mcp/src/daemon/account-api.ts +0 -311
  481. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-api.ts +0 -341
  482. package/runtime/node_modules/@metro-labs/mcp/src/daemon/api-http.ts +0 -129
  483. package/runtime/node_modules/@metro-labs/mcp/src/daemon/boot.ts +0 -321
  484. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair-api.ts +0 -118
  485. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair.ts +0 -20
  486. package/runtime/node_modules/@metro-labs/mcp/src/daemon/collection-api.ts +0 -202
  487. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-json.ts +0 -21
  488. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-tools.ts +0 -100
  489. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-url.ts +0 -57
  490. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-verify.ts +0 -333
  491. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-auth.ts +0 -164
  492. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-oauth.ts +0 -208
  493. package/runtime/node_modules/@metro-labs/mcp/src/daemon/identity.ts +0 -79
  494. package/runtime/node_modules/@metro-labs/mcp/src/daemon/oauth-pending.ts +0 -65
  495. package/runtime/node_modules/@metro-labs/mcp/src/daemon/pair-codes.ts +0 -58
  496. package/runtime/node_modules/@metro-labs/mcp/src/daemon/project-api.ts +0 -214
  497. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-api.ts +0 -125
  498. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-pair.ts +0 -18
  499. package/runtime/node_modules/@metro-labs/mcp/src/daemon/runtime-source.ts +0 -105
  500. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session-apis.ts +0 -43
  501. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session.ts +0 -218
  502. package/runtime/node_modules/@metro-labs/mcp/src/daemon/tunnel.ts +0 -169
  503. package/runtime/node_modules/@metro-labs/mcp/src/db/account-attach.ts +0 -91
  504. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-admin.ts +0 -215
  505. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-map.ts +0 -71
  506. package/runtime/node_modules/@metro-labs/mcp/src/db/client.ts +0 -37
  507. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-collections.ts +0 -218
  508. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-relay.ts +0 -126
  509. package/runtime/node_modules/@metro-labs/mcp/src/db/connectors.ts +0 -308
  510. package/runtime/node_modules/@metro-labs/mcp/src/db/projects.ts +0 -300
  511. package/runtime/node_modules/@metro-labs/mcp/src/db/runtime-admin.ts +0 -31
  512. package/runtime/node_modules/@metro-labs/mcp/src/db/runtimes.ts +0 -105
  513. package/runtime/node_modules/@metro-labs/mcp/src/db/schema.ts +0 -131
  514. package/runtime/node_modules/@metro-labs/mcp/src/db/token-carry.ts +0 -45
  515. package/runtime/node_modules/@metro-labs/mcp/src/db/users.ts +0 -57
  516. package/runtime/node_modules/@metro-labs/mcp/src/db/whatsapp-login.ts +0 -18
  517. package/runtime/node_modules/@metro-labs/mcp/src/mcp/channel-owner.ts +0 -29
  518. package/runtime/node_modules/@metro-labs/mcp/src/mcp/frame-scope.ts +0 -21
  519. package/runtime/node_modules/@metro-labs/mcp/src/mcp/permission-relay.ts +0 -66
  520. package/runtime/node_modules/@metro-labs/mcp/src/mcp/request-identity.ts +0 -73
  521. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-registry.ts +0 -172
  522. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-route.ts +0 -43
  523. package/runtime/node_modules/@metro-labs/mcp/src/monitor/api.ts +0 -240
  524. package/runtime/node_modules/@metro-labs/mcp/src/server.ts +0 -2
  525. package/runtime/node_modules/@metro-labs/mcp/src/stations/account-store.ts +0 -80
  526. package/runtime/node_modules/@metro-labs/mcp/src/stations/messaging-normalize.ts +0 -88
  527. package/runtime/node_modules/@metro-labs/telegram/src/normalize.ts +0 -22
  528. package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +0 -1
  529. package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +0 -3
  530. package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +0 -22
  531. package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +0 -5
  532. package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +0 -87
  533. package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +0 -55
  534. package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +0 -349
  535. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/log.ts +0 -0
  536. /package/runtime/node_modules/@metro-labs/{mcp/src/mcp → core/src}/str.ts +0 -0
  537. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/train-error.ts +0 -0
  538. /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/webhook-note.ts +0 -0
  539. /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/raw-get-stream.ts +0 -0
  540. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/api-error.ts +0 -0
  541. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/cors.ts +0 -0
@@ -0,0 +1,72 @@
1
+ import type { ToolGroup } from '@metro-labs/core/stations/types';
2
+ import { policyFor, setPolicies, type PolicyTarget, type ToolPolicy } from '../policy/policy.js';
3
+ import { serverKeysOf } from './plugin-sync.js';
4
+ import { NEEDS_APPROVAL, settlePrompts, takeGrant } from '../approvals/pending.js';
5
+
6
+ interface GateRow {
7
+ id: string;
8
+ name: string;
9
+ config: { policy?: ToolPolicy; toolGroups?: Record<string, ToolGroup> };
10
+ }
11
+
12
+ export interface ConnectorGate {
13
+ id: string;
14
+ name: string;
15
+ server: string;
16
+ policy: ToolPolicy;
17
+ tools: Record<string, ToolGroup>;
18
+ }
19
+
20
+ let gates: ConnectorGate[] = [];
21
+
22
+ const normalized = (name: string): string => name.replace(/[^a-zA-Z0-9_-]/g, '_');
23
+
24
+ export function registerConnectors(rows: readonly GateRow[]): void {
25
+ const keys = serverKeysOf([...rows]);
26
+ gates = rows.map((row) => ({
27
+ id: row.id,
28
+ name: row.name,
29
+ server: keys.get(row.id) ?? '',
30
+ policy: row.config.policy ?? {},
31
+ tools: row.config.toolGroups ?? {},
32
+ }));
33
+ const entries = rows.flatMap((row): [PolicyTarget, ToolPolicy][] =>
34
+ row.config.policy === undefined ? [] : [[{ kind: 'connector', id: row.id }, row.config.policy]],
35
+ );
36
+ setPolicies('connector', entries);
37
+ }
38
+
39
+ export const connectorGates = (): readonly ConnectorGate[] => gates;
40
+
41
+ export const toolGroupOf = (gate: ConnectorGate, tool: string): ToolGroup => (gate.tools[tool] === 'read' ? 'read' : 'write');
42
+
43
+ const promptFor = (connectorId: string, tool: string) => (asked: string): boolean => {
44
+ const found = connectorToolOf(asked);
45
+ return found?.gate.id === connectorId && found.tool === tool;
46
+ };
47
+
48
+ export function blockedReason(connectorId: string, tool: string, args: Record<string, unknown> = {}): string | null {
49
+ const gate = gates.find((g) => g.id === connectorId);
50
+ if (gate === undefined) return null;
51
+ settlePrompts(promptFor(connectorId, tool), args);
52
+ const access = policyFor({ kind: 'connector', id: connectorId }, { name: tool, group: toolGroupOf(gate, tool) });
53
+ if (access === 'deny') return `Blocked by the owner's policy for ${gate.name} (${tool}).`;
54
+ if (access === 'allow' || takeGrant(promptFor(connectorId, tool), args)) return null;
55
+ return NEEDS_APPROVAL(gate.name, tool);
56
+ }
57
+
58
+ function prefixesOf(gate: ConnectorGate): string[] {
59
+ return [`mcp__plugin_metro_${gate.server}__`, `mcp__${gate.server}__`, `mcp__${normalized(`metro.box ${gate.name}`)}__`];
60
+ }
61
+
62
+ export function connectorToolOf(toolName: string): { gate: ConnectorGate; tool: string } | undefined {
63
+ if (toolName.startsWith('mcp__metro__')) return undefined;
64
+ for (const gate of gates)
65
+ for (const prefix of prefixesOf(gate))
66
+ if (toolName.startsWith(prefix) && toolName.length > prefix.length) {
67
+ const called = toolName.slice(prefix.length);
68
+ const known = [...Object.keys(gate.tools), ...Object.keys(gate.policy.tools ?? {})];
69
+ return { gate, tool: known.find((name) => name === called) ?? known.find((name) => normalized(name) === called) ?? called };
70
+ }
71
+ return undefined;
72
+ }
@@ -0,0 +1,18 @@
1
+ export interface ConnectorHealth {
2
+ ok: boolean;
3
+ reason: string | null;
4
+ at: string;
5
+ }
6
+
7
+ const seen = new Map<string, ConnectorHealth>();
8
+
9
+ export function noteHealth(id: string, ok: boolean, reason: string | null = null): void {
10
+ seen.set(id, { ok, reason: ok ? null : reason, at: new Date().toISOString() });
11
+ }
12
+
13
+ export const healthOf = (id: string): ConnectorHealth | null => seen.get(id) ?? null;
14
+
15
+ export function forgetHealth(id?: string): void {
16
+ if (id === undefined) seen.clear();
17
+ else seen.delete(id);
18
+ }
@@ -1,9 +1,8 @@
1
1
  import { createHash, randomBytes } from 'node:crypto';
2
- import {
3
- ConnectorVerifyError,
4
- type OAuthTokens,
5
- } from './connector-verify.js';
2
+ import { whyUnreachable } from './reach.js';
3
+ import { refused, type OAuthTokens } from './verify.js';
6
4
  import type { OAuthServer } from './oauth-discovery.js';
5
+ import { isRecord } from '@metro-labs/core/is-record';
7
6
 
8
7
  const TOKEN_TIMEOUT_MS = 15_000;
9
8
  const CLIENT_NAME = 'Metro';
@@ -13,14 +12,6 @@ export interface OAuthClient {
13
12
  clientSecret?: string;
14
13
  }
15
14
 
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
15
  export function newVerifier(): string {
25
16
  return randomBytes(32).toString('base64url');
26
17
  }
@@ -35,7 +26,9 @@ export async function registerClient(
35
26
  ): Promise<OAuthClient> {
36
27
  if (server.registrationEndpoint === null)
37
28
  throw refused(
38
- 'That server requires OAuth but does not accept client registration, so Metro cannot sign in to it.',
29
+ 'That server signs in with OAuth but registers no clients on its own. ' +
30
+ `Register an app with it yourself, with ${redirectUri} as its redirect URL, ` +
31
+ "and add the connector again with that app's client ID.",
39
32
  );
40
33
  let res: Response;
41
34
  try {
@@ -52,8 +45,8 @@ export async function registerClient(
52
45
  token_endpoint_auth_method: 'none',
53
46
  }),
54
47
  });
55
- } catch {
56
- throw refused('Metro could not reach that server to register.');
48
+ } catch (err) {
49
+ throw refused(`Metro could not reach that server to register: ${whyUnreachable(err)}`);
57
50
  }
58
51
  const body: unknown = await res.json().catch(() => null);
59
52
  if (!res.ok || !isRecord(body) || typeof body.client_id !== 'string')
@@ -83,6 +76,8 @@ export function authorizeUrl(input: AuthorizeInput): string {
83
76
  url.searchParams.set('code_challenge', challengeOf(input.verifier));
84
77
  url.searchParams.set('code_challenge_method', 'S256');
85
78
  url.searchParams.set('resource', input.resource);
79
+ if (input.server.scopes.length > 0)
80
+ url.searchParams.set('scope', input.server.scopes.join(' '));
86
81
  return url.toString();
87
82
  }
88
83
 
@@ -125,8 +120,8 @@ async function postToken(
125
120
  },
126
121
  body: params.toString(),
127
122
  });
128
- } catch {
129
- throw refused('Metro could not reach that server to finish signing in.');
123
+ } catch (err) {
124
+ throw refused(`Metro could not reach that server to finish signing in: ${whyUnreachable(err)}`);
130
125
  }
131
126
  const body: unknown = await res.json().catch(() => null);
132
127
  if (!res.ok || !isRecord(body))
@@ -153,10 +148,12 @@ export function refreshTokens(
153
148
  client: OAuthClient,
154
149
  refreshToken: string,
155
150
  resource: string,
151
+ scope?: string,
156
152
  ): Promise<OAuthTokens> {
157
153
  return postToken(server, client, {
158
154
  grant_type: 'refresh_token',
159
155
  refresh_token: refreshToken,
160
156
  resource,
157
+ ...(scope === undefined ? {} : { scope }),
161
158
  });
162
159
  }
@@ -1,4 +1,6 @@
1
- import { ConnectorVerifyError, parseConnectorUrl } from './connector-verify.js';
1
+ import { parseConnectorUrl, refused } from './verify.js';
2
+ import { stringOf } from '@metro-labs/http/api-http';
3
+ import { isRecord } from '@metro-labs/core/is-record';
2
4
 
3
5
  const DISCOVERY_TIMEOUT_MS = 10_000;
4
6
 
@@ -8,19 +10,14 @@ export interface OAuthServer {
8
10
  tokenEndpoint: string;
9
11
  registrationEndpoint: string | null;
10
12
  supportsS256: boolean;
13
+ scopes: string[];
11
14
  }
12
15
 
13
- function refused(message: string): ConnectorVerifyError {
14
- return new ConnectorVerifyError(message, 400);
16
+ interface ResourceMetadata {
17
+ issuer: URL;
18
+ scopes: string[];
15
19
  }
16
20
 
17
- function isRecord(value: unknown): value is Record<string, unknown> {
18
- return typeof value === 'object' && value !== null && !Array.isArray(value);
19
- }
20
-
21
- const str = (value: unknown): string =>
22
- typeof value === 'string' ? value : '';
23
-
24
21
  async function getJson(url: URL): Promise<Record<string, unknown> | null> {
25
22
  let res: Response;
26
23
  try {
@@ -68,32 +65,48 @@ export async function advertisesOAuth(resource: URL): Promise<boolean> {
68
65
  return false;
69
66
  }
70
67
 
71
- async function authServerFor(resource: URL): Promise<URL> {
68
+ function scopesOf(body: Record<string, unknown> | null): string[] {
69
+ const raw: unknown = body?.scopes_supported;
70
+ if (!Array.isArray(raw)) return [];
71
+ const out: string[] = [];
72
+ for (const entry of raw) {
73
+ const scope = stringOf(entry).trim();
74
+ if (scope !== '' && !/\s/.test(scope) && !out.includes(scope)) out.push(scope);
75
+ }
76
+ return out;
77
+ }
78
+
79
+ async function resourceMetadata(resource: URL): Promise<ResourceMetadata> {
72
80
  for (const candidate of resourceMetadataUrls(resource)) {
73
81
  const body = await getJson(candidate);
74
82
  const servers: unknown = body?.authorization_servers;
75
83
  const first: unknown = Array.isArray(servers) ? servers[0] : undefined;
76
84
  if (typeof first === 'string' && first !== '')
77
- return parseConnectorUrl(first);
85
+ return { issuer: parseConnectorUrl(first), scopes: scopesOf(body) };
78
86
  }
79
- return parseConnectorUrl(resource.origin);
87
+ return { issuer: parseConnectorUrl(resource.origin), scopes: [] };
80
88
  }
81
89
 
82
- function toServer(body: Record<string, unknown>, issuer: URL): OAuthServer {
83
- const authorizationEndpoint = str(body.authorization_endpoint);
84
- const tokenEndpoint = str(body.token_endpoint);
90
+ function toServer(
91
+ body: Record<string, unknown>,
92
+ issuer: URL,
93
+ scopes: string[],
94
+ ): OAuthServer {
95
+ const authorizationEndpoint = stringOf(body.authorization_endpoint);
96
+ const tokenEndpoint = stringOf(body.token_endpoint);
85
97
  if (authorizationEndpoint === '' || tokenEndpoint === '')
86
98
  throw refused(
87
99
  `${issuer.hostname} advertises OAuth but not where to sign in.`,
88
100
  );
89
101
  const methods = body.code_challenge_methods_supported;
90
- const registration = str(body.registration_endpoint);
102
+ const registration = stringOf(body.registration_endpoint);
91
103
  return {
92
- issuer: str(body.issuer) === '' ? issuer.origin : str(body.issuer),
104
+ issuer: stringOf(body.issuer) === '' ? issuer.origin : stringOf(body.issuer),
93
105
  authorizationEndpoint,
94
106
  tokenEndpoint,
95
107
  registrationEndpoint: registration === '' ? null : registration,
96
108
  supportsS256: Array.isArray(methods) ? methods.includes('S256') : false,
109
+ scopes,
97
110
  };
98
111
  }
99
112
 
@@ -109,10 +122,10 @@ export function authServerMetadataUrls(issuer: URL): URL[] {
109
122
  }
110
123
 
111
124
  export async function discoverOAuth(resource: URL): Promise<OAuthServer> {
112
- const issuer = await authServerFor(resource);
125
+ const { issuer, scopes } = await resourceMetadata(resource);
113
126
  for (const candidate of authServerMetadataUrls(issuer)) {
114
127
  const body = await getJson(candidate);
115
- if (body !== null) return toServer(body, issuer);
128
+ if (body !== null) return toServer(body, issuer, scopes);
116
129
  }
117
130
  throw refused(
118
131
  `${resource.hostname} needs authorization, but publishes no OAuth metadata Metro can use.`,
@@ -1,18 +1,17 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
- import { errMsg, log } from './log.js';
3
- import { bodyField, readJsonBody, sendJson, type ApiSession } from './api-http.js';
2
+ import { errMsg, log } from '@metro-labs/core/log';
3
+ import { bodyField, readJsonBody, sendJson, stringOf } from '@metro-labs/http/api-http';
4
4
  import {
5
5
  beginOAuth,
6
6
  completeOAuth,
7
+ prepareOAuth,
7
8
  takePending,
8
9
  type PendingAuth,
9
- } from './connector-oauth.js';
10
- import { parseConnectorUrl } from './connector-verify.js';
11
- import type { OAuthAuth } from './connector-verify.js';
12
- import type { Connector } from '../db/connectors.js';
13
-
14
- const asText = (value: unknown): string =>
15
- typeof value === 'string' ? value : '';
10
+ } from './oauth.js';
11
+ import { connectorClient } from './config.js';
12
+ import { parseConnectorUrl } from './verify.js';
13
+ import type { OAuthAuth } from './verify.js';
14
+ import type { Connector, PendingConnectorInput } from './store.js';
16
15
 
17
16
  export function hostOf(url: string): string {
18
17
  try {
@@ -23,38 +22,37 @@ export function hostOf(url: string): string {
23
22
  }
24
23
 
25
24
  export interface OAuthRouteDeps {
26
- createPendingConnector: (
27
- email: string,
28
- project: string,
29
- input: { name: unknown; url: unknown },
30
- ) => Promise<Connector>;
31
- reconnectConnector: (
32
- email: string,
33
- id: string,
34
- auth: OAuthAuth,
35
- ) => Promise<Connector>;
36
- getConnector: (email: string, id: string) => Promise<Connector>;
25
+ createPendingConnector: (input: PendingConnectorInput) => Promise<Connector>;
26
+ reconnectConnector: (id: string, auth: OAuthAuth) => Promise<Connector>;
27
+ getConnector: (id: string) => Promise<Connector>;
37
28
  }
38
29
 
39
30
  export async function startOAuth(
40
31
  req: IncomingMessage,
41
32
  res: ServerResponse,
42
33
  deps: OAuthRouteDeps,
43
- session: ApiSession,
44
- project: string,
45
34
  body: unknown,
46
35
  payload: (row: Connector) => Record<string, unknown>,
47
36
  ): Promise<void> {
48
37
  const url = parseConnectorUrl(bodyField(body, 'url'));
49
- const row = await deps.createPendingConnector(session.email, project, {
38
+ const returnTo = stringOf(bodyField(body, 'returnTo'));
39
+ const clientId = bodyField(body, 'clientId');
40
+ const clientSecret = bodyField(body, 'clientSecret');
41
+ const prepared = await prepareOAuth({
42
+ url,
43
+ client: connectorClient(clientId, clientSecret),
44
+ returnTo,
45
+ });
46
+ const row = await deps.createPendingConnector({
50
47
  name: bodyField(body, 'name'),
51
48
  url: bodyField(body, 'url'),
49
+ clientId,
50
+ clientSecret,
52
51
  });
53
- const authorize = await beginOAuth({
54
- email: session.email,
52
+ const authorize = beginOAuth(prepared, {
55
53
  name: row.name,
56
54
  url,
57
- returnTo: asText(bodyField(body, 'returnTo')),
55
+ returnTo,
58
56
  connectorId: row.id,
59
57
  });
60
58
  log.info(
@@ -68,17 +66,17 @@ export async function handleConnect(
68
66
  req: IncomingMessage,
69
67
  res: ServerResponse,
70
68
  deps: OAuthRouteDeps,
71
- session: ApiSession,
72
69
  id: string,
73
70
  ): Promise<void> {
74
- const row = await deps.getConnector(session.email, id);
71
+ const row = await deps.getConnector(id);
75
72
  const url = parseConnectorUrl(row.url);
76
73
  const body = await readJsonBody(req);
77
- const authorize = await beginOAuth({
78
- email: session.email,
74
+ const returnTo = stringOf(bodyField(body, 'returnTo'));
75
+ const prepared = await prepareOAuth({ url, client: row.client, returnTo });
76
+ const authorize = beginOAuth(prepared, {
79
77
  name: row.name,
80
78
  url,
81
- returnTo: asText(bodyField(body, 'returnTo')),
79
+ returnTo,
82
80
  connectorId: row.id,
83
81
  });
84
82
  log.info(
@@ -110,7 +108,7 @@ async function saveOAuth(
110
108
  entry: PendingAuth,
111
109
  auth: OAuthAuth,
112
110
  ): Promise<Connector> {
113
- return deps.reconnectConnector(entry.email, entry.connectorId, auth);
111
+ return deps.reconnectConnector(entry.connectorId, auth);
114
112
  }
115
113
 
116
114
  async function settleCallback(
@@ -1,53 +1,82 @@
1
- import { publicBaseOrDefault } from './attach-serve.js';
1
+ import { publicBaseOrDefault } from '../files/attach-serve.js';
2
2
  import {
3
- ConnectorVerifyError,
3
+ refused,
4
4
  type OAuthAuth,
5
5
  type OAuthTokens,
6
- } from './connector-verify.js';
7
- import { validateReturnTo } from './google-oauth.js';
6
+ } from './verify.js';
7
+ import { validateReturnTo } from '@metro-labs/http/return-to';
8
8
  import {
9
9
  authorizeUrl,
10
10
  exchangeCode,
11
11
  newVerifier,
12
12
  refreshTokens,
13
13
  registerClient,
14
+ type OAuthClient,
14
15
  } from './oauth-client.js';
15
- import { discoverOAuth } from './oauth-discovery.js';
16
- import { startPending, takePending, type PendingAuth } from './oauth-pending.js';
16
+ import { discoverOAuth, type OAuthServer } from './oauth-discovery.js';
17
+ import { ticketStore } from '@metro-labs/core/tickets';
17
18
 
18
- export { takePending, type PendingAuth };
19
+ export interface PendingAuth {
20
+ name: string;
21
+ url: string;
22
+ resource: string;
23
+ returnTo: string;
24
+ verifier: string;
25
+ server: OAuthServer;
26
+ client: OAuthClient;
27
+ connectorId: string;
28
+ }
29
+
30
+ const pending = ticketStore<PendingAuth>(10 * 60_000, 100);
31
+
32
+ export const startPending = (entry: PendingAuth, now = Date.now()): string => pending.mint(entry, now).ticket;
33
+
34
+ export const takePending = (state: string, now = Date.now()): PendingAuth | undefined => pending.take(state, now);
35
+
36
+ export const pendingCount = (): number => pending.size();
19
37
 
20
38
  const REFRESH_SKEW_MS = 300_000;
21
39
 
22
- export const CALLBACK_PATH = '/api/connectors/callback';
40
+ const CALLBACK_PATH = '/api/connectors/callback';
23
41
 
24
- export const callbackUri = (): string =>
42
+ const callbackUri = (): string =>
25
43
  `${publicBaseOrDefault()}${CALLBACK_PATH}`;
26
44
 
27
- function refused(message: string): ConnectorVerifyError {
28
- return new ConnectorVerifyError(message, 400);
29
- }
30
-
31
45
  const resourceOf = (url: URL): string => url.toString();
32
46
 
33
- export interface BeginInput {
34
- connectorId: string;
35
- email: string;
36
- name: string;
47
+ export interface PrepareInput {
37
48
  url: URL;
49
+ client: OAuthClient | null;
38
50
  returnTo: string;
39
51
  }
40
52
 
41
- export async function beginOAuth(input: BeginInput): Promise<string> {
53
+ export interface PreparedOAuth {
54
+ server: OAuthServer;
55
+ client: OAuthClient;
56
+ redirectUri: string;
57
+ }
58
+
59
+ export async function prepareOAuth(input: PrepareInput): Promise<PreparedOAuth> {
42
60
  if (!validateReturnTo(input.returnTo))
43
61
  throw refused('that return address is not one Metro will send you back to');
44
62
  const server = await discoverOAuth(input.url);
45
63
  const redirectUri = callbackUri();
46
- const client = await registerClient(server, redirectUri);
64
+ const client = input.client ?? (await registerClient(server, redirectUri));
65
+ return { server, client, redirectUri };
66
+ }
67
+
68
+ export interface BeginInput {
69
+ connectorId: string;
70
+ name: string;
71
+ url: URL;
72
+ returnTo: string;
73
+ }
74
+
75
+ export function beginOAuth(prepared: PreparedOAuth, input: BeginInput): string {
76
+ const { server, client, redirectUri } = prepared;
47
77
  const verifier = newVerifier();
48
78
  const resource = resourceOf(input.url);
49
79
  const state = startPending({
50
- email: input.email,
51
80
  name: input.name,
52
81
  url: input.url.toString(),
53
82
  resource,
@@ -76,6 +105,9 @@ function authOf(pendingAuth: PendingAuth, tokens: OAuthTokens): OAuthAuth {
76
105
  ...(pendingAuth.client.clientSecret === undefined
77
106
  ? {}
78
107
  : { clientSecret: pendingAuth.client.clientSecret }),
108
+ ...(pendingAuth.server.scopes.length === 0
109
+ ? {}
110
+ : { scope: pendingAuth.server.scopes.join(' ') }),
79
111
  ...tokens,
80
112
  };
81
113
  }
@@ -109,6 +141,7 @@ export async function refreshOAuth(
109
141
  tokenEndpoint: auth.tokenEndpoint,
110
142
  registrationEndpoint: null,
111
143
  supportsS256: true,
144
+ scopes: [],
112
145
  };
113
146
  const client = {
114
147
  clientId: auth.clientId,
@@ -116,7 +149,13 @@ export async function refreshOAuth(
116
149
  ? {}
117
150
  : { clientSecret: auth.clientSecret }),
118
151
  };
119
- const tokens = await refreshTokens(server, client, auth.refreshToken, resource);
152
+ const tokens = await refreshTokens(
153
+ server,
154
+ client,
155
+ auth.refreshToken,
156
+ resource,
157
+ auth.scope,
158
+ );
120
159
  return {
121
160
  ...auth,
122
161
  ...tokens,
@@ -0,0 +1,131 @@
1
+ import { existsSync, readdirEntries, readFileSync } from '../agent-user/agent-fs.js';
2
+ import { writeHomeInPlace } from '../agent-user/home-fs.js';
3
+ import { agentMarketplaceDir, agentUser } from '../agent-user/user.js';
4
+ import { join } from 'node:path';
5
+ import { errMsg, log } from '@metro-labs/core/log';
6
+ import { claudeDir } from '../claude/files.js';
7
+ import { loopbackBase } from '../files/attach-serve.js';
8
+
9
+ const MARKER = join('bin', 'metro-plugin.mjs');
10
+ const FILE = '.mcp.json';
11
+ const HELPER = 'node "${CLAUDE_PLUGIN_ROOT}/bin/metro-plugin.mjs" headers';
12
+ const SLUG_MAX = 40;
13
+
14
+ export interface PluginRow {
15
+ id: string;
16
+ name: string;
17
+ }
18
+
19
+ export interface PluginServer {
20
+ type: 'http';
21
+ url: string;
22
+ headersHelper: string;
23
+ }
24
+
25
+ export function serverKey(name: string): string {
26
+ const slug = name
27
+ .toLowerCase()
28
+ .replace(/[^a-z0-9]+/g, '-')
29
+ .replace(/^-+|-+$/g, '')
30
+ .slice(0, SLUG_MAX)
31
+ .replace(/-+$/, '');
32
+ return slug === '' ? 'connector' : slug;
33
+ }
34
+
35
+ export function serverKeysOf(rows: PluginRow[]): Map<string, string> {
36
+ const taken = new Map<string, number>();
37
+ const keys = new Map<string, string>();
38
+ for (const row of rows) {
39
+ const wanted = serverKey(row.name);
40
+ const seen = taken.get(wanted) ?? 0;
41
+ taken.set(wanted, seen + 1);
42
+ keys.set(row.id, seen === 0 ? wanted : `${wanted}-${row.id.toLowerCase().replace(/[^a-z0-9]/g, '').slice(0, 4)}`);
43
+ }
44
+ return keys;
45
+ }
46
+
47
+ export function pluginServers(rows: PluginRow[], base: string): Record<string, PluginServer> {
48
+ const out: Record<string, PluginServer> = {};
49
+ for (const [id, key] of serverKeysOf(rows)) out[key] = { type: 'http', url: `${base}/relay/${id}`, headersHelper: HELPER };
50
+ return out;
51
+ }
52
+
53
+ const SEARCH_DEPTH = 5;
54
+
55
+ function pluginRootsUnder(dir: string, depth: number, out: string[]): void {
56
+ if (depth < 0 || out.length >= 8) return;
57
+ let entries;
58
+ try {
59
+ entries = readdirEntries(dir);
60
+ } catch {
61
+ return;
62
+ }
63
+ if (entries.some((e) => e.name === 'bin' && e.isDirectory()) && existsSync(join(dir, MARKER))) {
64
+ out.push(dir);
65
+ return;
66
+ }
67
+ for (const entry of entries)
68
+ if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules')
69
+ pluginRootsUnder(join(dir, entry.name), depth - 1, out);
70
+ }
71
+
72
+ function stagedPluginDir(env: NodeJS.ProcessEnv = process.env): string | null {
73
+ const store = env.METRO_RUNTIME_STORE?.trim() ?? '';
74
+ if (store === '') return null;
75
+ const user = agentUser();
76
+ return join(user === null ? join(store, 'marketplace') : agentMarketplaceDir(user), 'plugin');
77
+ }
78
+
79
+ export function installedPluginFiles(dir = claudeDir(), staged = stagedPluginDir()): string[] {
80
+ const roots: string[] = [];
81
+ const root = join(dir, 'plugins');
82
+ if (existsSync(root)) pluginRootsUnder(root, SEARCH_DEPTH, roots);
83
+ if (staged !== null && existsSync(join(staged, MARKER)) && !roots.includes(staged)) roots.push(staged);
84
+ return roots.map((found) => join(found, FILE));
85
+ }
86
+
87
+ const readOrNull = (path: string): string | null => {
88
+ try {
89
+ return readFileSync(path, 'utf8');
90
+ } catch {
91
+ return null;
92
+ }
93
+ };
94
+
95
+ function writeIfChanged(path: string, text: string): boolean {
96
+ if (readOrNull(path) === text) return false;
97
+ writeHomeInPlace(path, text, 0o644);
98
+ return true;
99
+ }
100
+
101
+ export interface PluginSyncOptions {
102
+ dir?: string;
103
+ base?: string;
104
+ staged?: string | null;
105
+ }
106
+
107
+ function filesFor(opts: PluginSyncOptions): string[] {
108
+ const staged = opts.staged === undefined ? stagedPluginDir() : opts.staged;
109
+ return installedPluginFiles(opts.dir ?? claudeDir(), staged);
110
+ }
111
+
112
+ export function syncPluginServers(rows: PluginRow[], opts: PluginSyncOptions = {}): number {
113
+ const files = filesFor(opts);
114
+ if (files.length === 0) return 0;
115
+ const servers = pluginServers(rows, opts.base ?? loopbackBase());
116
+ const text = `${JSON.stringify(servers, null, 2)}\n`;
117
+ let written = 0;
118
+ for (const file of files) {
119
+ try {
120
+ if (writeIfChanged(file, text)) written += 1;
121
+ } catch (err) {
122
+ log.warn({ file, err: errMsg(err) }, 'plugin: could not write the connector servers');
123
+ }
124
+ }
125
+ if (written > 0)
126
+ log.info(
127
+ { files: written, servers: Object.keys(servers).length },
128
+ 'plugin: connector servers written; run /reload-plugins --force to pick them up in a running session',
129
+ );
130
+ return written;
131
+ }
@@ -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
+ }