@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,113 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { ApiError } from '@metro-labs/http/api-error';
5
+ import { errMsg, log } from '@metro-labs/core/log';
6
+ import { isRecord } from '@metro-labs/core/is-record';
7
+ import { sessionRunning, stopSession, type SessionDeps } from './session.js';
8
+ import { agentUser, asAgent, claudeBin } from '../agent-user/user.js';
9
+
10
+ const LATEST_URL = 'https://registry.npmjs.org/@anthropic-ai/claude-code/latest';
11
+ const VERSION_RE = /(\d+)\.(\d+)\.(\d+)/;
12
+ const CACHE_MS = 10 * 60_000;
13
+ const INSTALL_TIMEOUT_MS = 5 * 60_000;
14
+ const TAIL = 400;
15
+
16
+ export interface VersionDeps {
17
+ claude?: string;
18
+ fetchImpl?: typeof fetch;
19
+ session?: SessionDeps;
20
+ now?: () => number;
21
+ }
22
+
23
+ export interface ClaudeVersion {
24
+ installed: string | null;
25
+ latest: string | null;
26
+ newer: boolean;
27
+ }
28
+
29
+ let cached: { latest: string | null; at: number } | null = null;
30
+
31
+ function candidates(deps: VersionDeps): string[] {
32
+ if (deps.claude !== undefined) return [deps.claude];
33
+ return agentUser() === null ? ['claude', join(homedir(), '.local', 'bin', 'claude')] : [claudeBin()];
34
+ }
35
+
36
+ const parse = (text: string): string | null => {
37
+ const m = VERSION_RE.exec(text);
38
+ return m === null ? null : `${m[1] ?? ''}.${m[2] ?? ''}.${m[3] ?? ''}`;
39
+ };
40
+
41
+ function probe(bin: string): string | null {
42
+ const run = spawnSync(...asAgent(bin, ['--version']), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
43
+ return run.error === undefined && run.status === 0 && typeof run.stdout === 'string' ? parse(run.stdout) : null;
44
+ }
45
+
46
+ function located(deps: VersionDeps): { bin: string; installed: string } | null {
47
+ for (const bin of candidates(deps)) {
48
+ const installed = probe(bin);
49
+ if (installed !== null) return { bin, installed };
50
+ }
51
+ return null;
52
+ }
53
+
54
+ export function newerThan(a: string, b: string): boolean {
55
+ const left = a.split('.').map(Number);
56
+ const right = b.split('.').map(Number);
57
+ for (let i = 0; i < 3; i += 1) {
58
+ const d = (left[i] ?? 0) - (right[i] ?? 0);
59
+ if (d !== 0) return d > 0;
60
+ }
61
+ return false;
62
+ }
63
+
64
+ async function latestClaudeVersion(deps: VersionDeps = {}): Promise<string | null> {
65
+ const now = (deps.now ?? Date.now)();
66
+ if (cached !== null && now - cached.at < CACHE_MS) return cached.latest;
67
+ const fetchImpl = deps.fetchImpl ?? fetch;
68
+ let latest: string | null = null;
69
+ try {
70
+ const res = await fetchImpl(LATEST_URL, { headers: { accept: 'application/json' }, redirect: 'manual' });
71
+ const body: unknown = res.ok ? await res.json() : null;
72
+ latest = isRecord(body) && typeof body.version === 'string' ? parse(body.version) : null;
73
+ } catch (err) {
74
+ log.warn({ err: errMsg(err) }, 'claude-version: could not read the latest version from npm');
75
+ }
76
+ cached = { latest, at: now };
77
+ return latest;
78
+ }
79
+
80
+ export function forgetClaudeVersion(): void {
81
+ cached = null;
82
+ }
83
+
84
+ export async function claudeVersion(deps: VersionDeps = {}): Promise<ClaudeVersion> {
85
+ const installed = located(deps)?.installed ?? null;
86
+ const latest = await latestClaudeVersion(deps);
87
+ return { installed, latest, newer: installed !== null && latest !== null && newerThan(latest, installed) };
88
+ }
89
+
90
+ function install(bin: string): void {
91
+ const run = spawnSync(...asAgent(bin, ['install', 'latest']), { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: INSTALL_TIMEOUT_MS });
92
+ if (run.error !== undefined) throw new ApiError(`claude install latest failed: ${errMsg(run.error)}`, 502);
93
+ if (run.status === 0) return;
94
+ const said = `${run.stderr ?? ''}${run.stdout ?? ''}`.trim().slice(-TAIL);
95
+ throw new ApiError(`claude install latest failed: ${said}`, 502);
96
+ }
97
+
98
+ function restartIfChanged(changed: boolean, session: SessionDeps): boolean {
99
+ if (!changed || !sessionRunning(session.tmux ?? 'tmux')) return false;
100
+ stopSession(session);
101
+ return true;
102
+ }
103
+
104
+ export async function updateClaude(deps: VersionDeps = {}): Promise<ClaudeVersion & { restarted: boolean }> {
105
+ const found = located(deps);
106
+ if (found === null) throw new ApiError('Claude Code is not installed on this machine', 404);
107
+ install(found.bin);
108
+ forgetClaudeVersion();
109
+ const after = await claudeVersion(deps);
110
+ const restarted = restartIfChanged(after.installed !== null && after.installed !== found.installed, deps.session ?? {});
111
+ log.info({ from: found.installed, to: after.installed, restarted }, 'claude-version: Claude Code updated');
112
+ return { ...after, restarted };
113
+ }
@@ -1,83 +1,44 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
- import { errMsg, log } from './log.js';
2
+ import { log } from '@metro-labs/core/log';
3
+ import { healthOf } from './health.js';
4
+ import type { RemoteTool } from './tools.js';
5
+ import { normalizePolicy, type ToolPolicy } from '../policy/policy.js';
3
6
  import {
4
7
  apiFailure,
5
8
  apiSession,
6
- projectParam,
7
9
  bodyField,
8
10
  cors,
9
11
  readJsonBody,
10
12
  sendJson,
11
- type ApiSession,
12
- } from './api-http.js';
13
- import { parseId } from '../db/ids.js';
14
- import type { ConnectorCollectionRow } from '../db/connector-collections.js';
15
- import type { RelayServerEntry } from './connector-json.js';
13
+ stringOf,
14
+ } from '@metro-labs/http/api-http';
15
+ import { parseId } from '@metro-labs/core/ids';
16
16
  import {
17
17
  handleCallback,
18
18
  handleConnect,
19
19
  hostOf,
20
20
  startOAuth,
21
21
  type OAuthRouteDeps,
22
- } from './connector-oauth-routes.js';
23
- import { ConnectorUnauthorized } from './connector-verify.js';
22
+ } from './oauth-routes.js';
23
+ import { ConnectorUnauthorized } from './verify.js';
24
24
  import type {
25
25
  Connector,
26
26
  ConnectorCheck,
27
27
  ConnectorInput,
28
28
  DeletedConnector,
29
- } from '../db/connectors.js';
29
+ } from './store.js';
30
30
 
31
31
  const PREFIX = '/api/connectors';
32
32
 
33
- const asText = (value: unknown): string =>
34
- typeof value === 'string' ? value : '';
35
-
36
33
  export interface ConnectorApiDeps extends OAuthRouteDeps {
37
- listConnectors: (email: string, project: string) => Promise<Connector[]>;
38
- connectorNamesByIds: (ids: string[]) => Promise<RelayServerEntry[]>;
39
- listCollections: (
40
- email: string,
41
- project: string,
42
- ) => Promise<ConnectorCollectionRow[]>;
43
- getCollection: (email: string, id: string) => Promise<ConnectorCollectionRow>;
44
- createCollection: (
45
- email: string,
46
- project: string,
47
- name: string,
48
- ) => Promise<ConnectorCollectionRow>;
49
- renameCollection: (
50
- email: string,
51
- id: string,
52
- name: string,
53
- ) => Promise<ConnectorCollectionRow>;
54
- deleteCollection: (
55
- email: string,
56
- id: string,
57
- ) => Promise<{ id: string; name: string }>;
58
- addToCollection: (
59
- email: string,
60
- id: string,
61
- connectorId: string,
62
- ) => Promise<ConnectorCollectionRow>;
63
- removeFromCollection: (
64
- email: string,
65
- id: string,
66
- connectorId: string,
67
- ) => Promise<ConnectorCollectionRow>;
68
- createConnector: (
69
- email: string,
70
- project: string,
71
- input: ConnectorInput,
72
- ) => Promise<Connector>;
73
- verifyConnector: (email: string, id: string) => Promise<ConnectorCheck>;
74
- disconnectConnector: (email: string, id: string) => Promise<Connector>;
75
- renameConnector: (
76
- email: string,
77
- id: string,
78
- name: string,
79
- ) => Promise<Connector>;
80
- deleteConnector: (email: string, id: string) => Promise<DeletedConnector>;
34
+ listConnectors: () => Promise<Connector[]>;
35
+ createConnector: (input: ConnectorInput) => Promise<Connector>;
36
+ verifyConnector: (id: string) => Promise<ConnectorCheck>;
37
+ connectorTools: (id: string) => Promise<RemoteTool[]>;
38
+ disconnectConnector: (id: string) => Promise<Connector>;
39
+ renameConnector: (id: string, name: string) => Promise<Connector>;
40
+ deleteConnector: (id: string) => Promise<DeletedConnector>;
41
+ setConnectorPolicy: (id: string, policy: ToolPolicy) => Promise<Connector>;
81
42
  }
82
43
 
83
44
  type Routable =
@@ -85,9 +46,11 @@ type Routable =
85
46
  | { kind: 'callback' }
86
47
  | { kind: 'connector'; id: string }
87
48
  | { kind: 'verify'; id: string }
49
+ | { kind: 'tools'; id: string }
88
50
  | { kind: 'connect'; id: string }
89
51
  | { kind: 'disconnect'; id: string }
90
- | { kind: 'rename'; id: string };
52
+ | { kind: 'rename'; id: string }
53
+ | { kind: 'policy'; id: string };
91
54
 
92
55
  type Target = Routable | { kind: 'unknown' } | null;
93
56
 
@@ -96,9 +59,11 @@ function subTarget(id: string, rest: string[]): Target {
96
59
  if (rest.length > 1) return { kind: 'unknown' };
97
60
  const head = rest[0];
98
61
  if (head === 'verify') return { kind: 'verify', id };
62
+ if (head === 'tools') return { kind: 'tools', id };
99
63
  if (head === 'connect') return { kind: 'connect', id };
100
64
  if (head === 'disconnect') return { kind: 'disconnect', id };
101
65
  if (head === 'rename') return { kind: 'rename', id };
66
+ if (head === 'policy') return { kind: 'policy', id };
102
67
  return { kind: 'unknown' };
103
68
  }
104
69
 
@@ -113,20 +78,18 @@ function target(path: string): Target {
113
78
  return id === null ? { kind: 'unknown' } : subTarget(id, segments.slice(1));
114
79
  }
115
80
 
116
- function connectorPayload(
117
- row: Connector,
118
- detail = false,
119
- ): Record<string, unknown> {
120
- const { catalog, ...summary } = row.verified;
81
+ function connectorPayload(row: Connector): Record<string, unknown> {
121
82
  return {
122
83
  id: row.id,
123
84
  name: row.name,
124
85
  url: row.url,
125
- transport: row.transport,
126
86
  auth: row.auth,
127
87
  header: row.header,
88
+ clientId: row.client?.clientId ?? null,
128
89
  signIn: row.signIn,
129
- verified: detail ? { ...summary, catalog } : summary,
90
+ verified: row.verified,
91
+ policy: row.policy,
92
+ health: healthOf(row.id),
130
93
  };
131
94
  }
132
95
 
@@ -134,14 +97,8 @@ async function handleList(
134
97
  req: IncomingMessage,
135
98
  res: ServerResponse,
136
99
  deps: ConnectorApiDeps,
137
- session: ApiSession,
138
100
  ): Promise<void> {
139
- const project = projectParam(req);
140
- if (project === null) {
141
- sendJson(req, res, 400, { error: 'a project is required' });
142
- return;
143
- }
144
- const rows = await deps.listConnectors(session.email, project);
101
+ const rows = await deps.listConnectors();
145
102
  sendJson(req, res, 200, {
146
103
  connectors: rows.map((row) => connectorPayload(row)),
147
104
  });
@@ -151,21 +108,17 @@ async function handleCreate(
151
108
  req: IncomingMessage,
152
109
  res: ServerResponse,
153
110
  deps: ConnectorApiDeps,
154
- session: ApiSession,
155
111
  ): Promise<void> {
156
112
  const body = await readJsonBody(req);
157
- const project = projectParam(req);
158
- if (project === null) {
159
- sendJson(req, res, 400, { error: 'a project is required' });
160
- return;
161
- }
162
- const offered = asText(bodyField(body, 'value')).trim() !== '';
113
+ const offered = stringOf(bodyField(body, 'value')).trim() !== '';
163
114
  try {
164
- const created = await deps.createConnector(session.email, project, {
115
+ const created = await deps.createConnector({
165
116
  name: bodyField(body, 'name'),
166
117
  url: bodyField(body, 'url'),
167
118
  header: bodyField(body, 'header'),
168
119
  value: bodyField(body, 'value'),
120
+ clientId: bodyField(body, 'clientId'),
121
+ clientSecret: bodyField(body, 'clientSecret'),
169
122
  });
170
123
  log.info(
171
124
  { id: created.id, name: created.name, host: hostOf(created.url) },
@@ -174,7 +127,7 @@ async function handleCreate(
174
127
  sendJson(req, res, 201, connectorPayload(created));
175
128
  } catch (err) {
176
129
  if (offered || !(err instanceof ConnectorUnauthorized)) throw err;
177
- await startOAuth(req, res, deps, session, project, body, (row) =>
130
+ await startOAuth(req, res, deps, body, (row) =>
178
131
  connectorPayload(row),
179
132
  );
180
133
  }
@@ -184,10 +137,9 @@ async function handleVerify(
184
137
  req: IncomingMessage,
185
138
  res: ServerResponse,
186
139
  deps: ConnectorApiDeps,
187
- session: ApiSession,
188
140
  id: string,
189
141
  ): Promise<void> {
190
- const check = await deps.verifyConnector(session.email, id);
142
+ const check = await deps.verifyConnector(id);
191
143
  log.info(
192
144
  { id: check.id, name: check.name, ok: check.ok },
193
145
  'connector-api: re-verified connector',
@@ -199,10 +151,9 @@ async function handleDisconnect(
199
151
  req: IncomingMessage,
200
152
  res: ServerResponse,
201
153
  deps: ConnectorApiDeps,
202
- session: ApiSession,
203
154
  id: string,
204
155
  ): Promise<void> {
205
- const row = await deps.disconnectConnector(session.email, id);
156
+ const row = await deps.disconnectConnector(id);
206
157
  log.info(
207
158
  { id: row.id, name: row.name },
208
159
  'connector-api: signed the connector out',
@@ -214,10 +165,9 @@ async function handleDelete(
214
165
  req: IncomingMessage,
215
166
  res: ServerResponse,
216
167
  deps: ConnectorApiDeps,
217
- session: ApiSession,
218
168
  id: string,
219
169
  ): Promise<void> {
220
- const gone = await deps.deleteConnector(session.email, id);
170
+ const gone = await deps.deleteConnector(id);
221
171
  log.info(
222
172
  { id: gone.id, name: gone.name },
223
173
  'connector-api: deleted connector',
@@ -229,22 +179,20 @@ async function handleConnector(
229
179
  req: IncomingMessage,
230
180
  res: ServerResponse,
231
181
  deps: ConnectorApiDeps,
232
- session: ApiSession,
233
182
  id: string,
234
183
  ): Promise<void> {
235
184
  if (req.method !== 'GET') {
236
- await handleDelete(req, res, deps, session, id);
185
+ await handleDelete(req, res, deps, id);
237
186
  return;
238
187
  }
239
- const row = await deps.getConnector(session.email, id);
240
- sendJson(req, res, 200, connectorPayload(row, true));
188
+ const row = await deps.getConnector(id);
189
+ sendJson(req, res, 200, connectorPayload(row));
241
190
  }
242
191
 
243
192
  async function handleRename(
244
193
  req: IncomingMessage,
245
194
  res: ServerResponse,
246
195
  deps: ConnectorApiDeps,
247
- session: ApiSession,
248
196
  id: string,
249
197
  ): Promise<void> {
250
198
  const name = bodyField(await readJsonBody(req), 'name');
@@ -252,32 +200,48 @@ async function handleRename(
252
200
  sendJson(req, res, 400, { error: 'name is required' });
253
201
  return;
254
202
  }
255
- const row = await deps.renameConnector(session.email, id, name);
203
+ const row = await deps.renameConnector(id, name);
256
204
  log.info({ id: row.id, name: row.name }, 'connector-api: renamed connector');
257
205
  sendJson(req, res, 200, connectorPayload(row));
258
206
  }
259
207
 
208
+ async function handlePolicy(
209
+ req: IncomingMessage,
210
+ res: ServerResponse,
211
+ deps: ConnectorApiDeps,
212
+ id: string,
213
+ ): Promise<void> {
214
+ const policy = normalizePolicy(bodyField(await readJsonBody(req), 'policy'));
215
+ const row = await deps.setConnectorPolicy(id, policy);
216
+ log.info({ id: row.id, name: row.name, policy: row.policy }, 'connector-api: tool policy set');
217
+ sendJson(req, res, 200, connectorPayload(row));
218
+ }
219
+
220
+ type ById = Exclude<Routable['kind'], 'collection' | 'callback'>;
221
+
222
+ const BY_ID: Record<ById, (req: IncomingMessage, res: ServerResponse, deps: ConnectorApiDeps, id: string) => Promise<void>> = {
223
+ verify: handleVerify,
224
+ tools: async (req, res, deps, id) => {
225
+ sendJson(req, res, 200, { tools: await deps.connectorTools(id) });
226
+ },
227
+ connect: handleConnect,
228
+ disconnect: handleDisconnect,
229
+ rename: handleRename,
230
+ policy: handlePolicy,
231
+ connector: handleConnector,
232
+ };
233
+
260
234
  async function route(
261
235
  req: IncomingMessage,
262
236
  res: ServerResponse,
263
237
  deps: ConnectorApiDeps,
264
- session: ApiSession,
265
238
  tgt: Routable,
266
239
  ): Promise<void> {
267
240
  try {
268
241
  if (tgt.kind === 'callback') return;
269
- if (tgt.kind === 'verify')
270
- await handleVerify(req, res, deps, session, tgt.id);
271
- else if (tgt.kind === 'connect')
272
- await handleConnect(req, res, deps, session, tgt.id);
273
- else if (tgt.kind === 'disconnect')
274
- await handleDisconnect(req, res, deps, session, tgt.id);
275
- else if (tgt.kind === 'rename')
276
- await handleRename(req, res, deps, session, tgt.id);
277
- else if (tgt.kind === 'connector')
278
- await handleConnector(req, res, deps, session, tgt.id);
279
- else if (req.method === 'GET') await handleList(req, res, deps, session);
280
- else await handleCreate(req, res, deps, session);
242
+ if (tgt.kind !== 'collection') await BY_ID[tgt.kind](req, res, deps, tgt.id);
243
+ else if (req.method === 'GET') await handleList(req, res, deps);
244
+ else await handleCreate(req, res, deps);
281
245
  } catch (err) {
282
246
  apiFailure(req, res, err, 'connector-api');
283
247
  }
@@ -288,12 +252,14 @@ const ALLOWED: Record<Routable['kind'], string[]> = {
288
252
  callback: ['GET'],
289
253
  connector: ['GET', 'DELETE'],
290
254
  verify: ['POST'],
255
+ tools: ['GET'],
291
256
  connect: ['POST'],
292
257
  disconnect: ['POST'],
293
258
  rename: ['POST'],
259
+ policy: ['PUT'],
294
260
  };
295
261
 
296
- function dispatch(
262
+ async function dispatch(
297
263
  req: IncomingMessage,
298
264
  res: ServerResponse,
299
265
  deps: ConnectorApiDeps,
@@ -301,14 +267,14 @@ function dispatch(
301
267
  ): Promise<void> {
302
268
  if (tgt.kind === 'callback') {
303
269
  handleCallback(req, res, deps);
304
- return Promise.resolve();
270
+ return;
305
271
  }
306
- const session = apiSession(req);
272
+ const session = await apiSession(req);
307
273
  if (!session) {
308
274
  sendJson(req, res, 401, { error: 'unauthorized' });
309
- return Promise.resolve();
275
+ return;
310
276
  }
311
- return route(req, res, deps, session, tgt);
277
+ await route(req, res, deps, tgt);
312
278
  }
313
279
 
314
280
  export function handleConnectorApiRequest(
@@ -331,9 +297,8 @@ export function handleConnectorApiRequest(
331
297
  return true;
332
298
  }
333
299
  dispatch(req, res, deps, tgt).catch((err: unknown) => {
334
- log.warn({ err: errMsg(err) }, 'connector-api: unhandled error');
335
- if (!res.headersSent)
336
- sendJson(req, res, 500, { error: 'connector api failed' });
300
+ if (res.headersSent) return;
301
+ apiFailure(req, res, err, 'connector-api');
337
302
  });
338
303
  return true;
339
304
  }
@@ -1,14 +1,20 @@
1
- import { ApiError } from '../daemon/api-error.js';
1
+ import { ApiError } from '@metro-labs/http/api-error';
2
+ import { stringOf } from '@metro-labs/http/api-http';
2
3
  import type {
3
4
  ConnectorAuth,
4
5
  VerifiedRecord,
5
6
  VerifiedServer,
6
- } from '../daemon/connector-verify.js';
7
- import { readStoredTools } from '../daemon/connector-tools.js';
7
+ } from './verify.js';
8
+ import type { OAuthClient } from './oauth-client.js';
9
+ import { isRecord } from '@metro-labs/core/is-record';
10
+ import type { ToolGroup } from '@metro-labs/core/stations/types';
11
+ import { parsePolicy, type ToolPolicy } from '../policy/policy.js';
8
12
 
9
13
  const CONNECTOR_NAME_MAX = 64;
10
14
  const HEADER_NAME_RE = /^[A-Za-z0-9!#$%&'*+.^_`|~-]{1,64}$/;
11
15
  const HEADER_VALUE_RE = /^[\x20-\x7e]{1,4096}$/;
16
+ const CLIENT_ID_RE = /^[\x21-\x7e]{1,256}$/;
17
+ const CLIENT_SECRET_RE = /^[\x21-\x7e]{1,1024}$/;
12
18
  const DEFAULT_HEADER = 'Authorization';
13
19
 
14
20
  export class ConnectorError extends ApiError {}
@@ -20,14 +26,9 @@ export interface ConnectorConfig {
20
26
  createdAt: string;
21
27
  verified: VerifiedRecord;
22
28
  oauth: boolean;
23
- }
24
-
25
- function isRecord(value: unknown): value is Record<string, unknown> {
26
- return typeof value === 'object' && value !== null && !Array.isArray(value);
27
- }
28
-
29
- function text(value: unknown): string {
30
- return typeof value === 'string' ? value : '';
29
+ client: OAuthClient | null;
30
+ policy?: ToolPolicy;
31
+ toolGroups?: Record<string, ToolGroup>;
31
32
  }
32
33
 
33
34
  function hasControlChar(value: string): boolean {
@@ -58,8 +59,8 @@ export function connectorAuth(
58
59
  rawHeader: unknown,
59
60
  rawValue: unknown,
60
61
  ): ConnectorAuth {
61
- const header = text(rawHeader).trim();
62
- const value = text(rawValue).trim();
62
+ const header = stringOf(rawHeader).trim();
63
+ const value = stringOf(rawValue).trim();
63
64
  if (header === '' && value === '') return { kind: 'none' };
64
65
  if (value === '')
65
66
  throw new ConnectorError(
@@ -74,22 +75,48 @@ export function connectorAuth(
74
75
  return { kind: 'header', name, value };
75
76
  }
76
77
 
78
+ export function connectorClient(
79
+ rawId: unknown,
80
+ rawSecret: unknown,
81
+ ): OAuthClient | null {
82
+ const clientId = stringOf(rawId).trim();
83
+ const clientSecret = stringOf(rawSecret).trim();
84
+ if (clientId === '' && clientSecret === '') return null;
85
+ if (clientId === '')
86
+ throw new ConnectorError('a client secret needs the client ID it belongs to', 400);
87
+ if (!CLIENT_ID_RE.test(clientId))
88
+ throw new ConnectorError('that is not a client ID Metro can send', 400);
89
+ if (clientSecret !== '' && !CLIENT_SECRET_RE.test(clientSecret))
90
+ throw new ConnectorError('that client secret is not sendable', 400);
91
+ return { clientId, ...(clientSecret === '' ? {} : { clientSecret }) };
92
+ }
93
+
94
+ function readClient(raw: unknown): OAuthClient | null {
95
+ if (!isRecord(raw)) return null;
96
+ const clientId = stringOf(raw.clientId);
97
+ if (clientId === '') return null;
98
+ const clientSecret = stringOf(raw.clientSecret);
99
+ return { clientId, ...(clientSecret === '' ? {} : { clientSecret }) };
100
+ }
101
+
77
102
  function readOAuth(raw: Record<string, unknown>): ConnectorAuth {
78
- const accessToken = text(raw.accessToken);
79
- const clientId = text(raw.clientId);
80
- const tokenEndpoint = text(raw.tokenEndpoint);
103
+ const accessToken = stringOf(raw.accessToken);
104
+ const clientId = stringOf(raw.clientId);
105
+ const tokenEndpoint = stringOf(raw.tokenEndpoint);
81
106
  if (accessToken === '' || clientId === '' || tokenEndpoint === '')
82
107
  return { kind: 'none' };
83
- const refreshToken = text(raw.refreshToken);
84
- const clientSecret = text(raw.clientSecret);
108
+ const refreshToken = stringOf(raw.refreshToken);
109
+ const clientSecret = stringOf(raw.clientSecret);
110
+ const scope = stringOf(raw.scope);
85
111
  return {
86
112
  kind: 'oauth',
87
113
  accessToken,
88
114
  clientId,
89
115
  tokenEndpoint,
90
- issuer: text(raw.issuer),
116
+ issuer: stringOf(raw.issuer),
91
117
  ...(refreshToken === '' ? {} : { refreshToken }),
92
118
  ...(clientSecret === '' ? {} : { clientSecret }),
119
+ ...(scope === '' ? {} : { scope }),
93
120
  ...(typeof raw.expiresAt === 'number' ? { expiresAt: raw.expiresAt } : {}),
94
121
  };
95
122
  }
@@ -98,34 +125,41 @@ function readAuth(raw: unknown): ConnectorAuth {
98
125
  if (!isRecord(raw)) return { kind: 'none' };
99
126
  if (raw.kind === 'oauth') return readOAuth(raw);
100
127
  if (raw.kind !== 'header') return { kind: 'none' };
101
- const name = text(raw.name);
102
- const value = text(raw.value);
128
+ const name = stringOf(raw.name);
129
+ const value = stringOf(raw.value);
103
130
  if (name === '' || value === '') return { kind: 'none' };
104
131
  return { kind: 'header', name, value };
105
132
  }
106
133
 
107
134
  function readVerified(raw: unknown): VerifiedRecord {
108
135
  const record = isRecord(raw) ? raw : {};
109
- const catalog = readStoredTools(record.catalog);
110
- return {
111
- at: text(record.at),
112
- server: text(record.server),
113
- version: text(record.version),
114
- protocol: text(record.protocol),
115
- icon: text(record.icon),
116
- tools: typeof record.tools === 'number' ? record.tools : 0,
117
- catalog,
118
- };
136
+ return { at: stringOf(record.at), server: stringOf(record.server) };
137
+ }
138
+
139
+ const TOOL_NAME_MAX = 128;
140
+ const TOOL_GROUPS_MAX = 1000;
141
+
142
+ function readToolGroups(raw: unknown): Record<string, ToolGroup> | undefined {
143
+ if (!isRecord(raw)) return undefined;
144
+ const kept = Object.entries(raw)
145
+ .filter((entry): entry is [string, ToolGroup] => entry[0].length <= TOOL_NAME_MAX && (entry[1] === 'read' || entry[1] === 'write'))
146
+ .slice(0, TOOL_GROUPS_MAX);
147
+ return kept.length > 0 ? Object.fromEntries(kept) : undefined;
119
148
  }
120
149
 
121
150
  export function readConfig(raw: unknown): ConnectorConfig {
122
151
  const record = isRecord(raw) ? raw : {};
123
152
  const auth = readAuth(record.auth);
153
+ const policy = parsePolicy(record.policy, 'connectors.json');
154
+ const toolGroups = readToolGroups(record.toolGroups);
124
155
  return {
125
156
  auth,
126
- createdAt: text(record.createdAt),
157
+ createdAt: stringOf(record.createdAt),
127
158
  verified: readVerified(record.verified),
128
159
  oauth: record.oauth === true || auth.kind === 'oauth',
160
+ client: readClient(record.client),
161
+ ...(policy === undefined || Object.keys(policy).length === 0 ? {} : { policy }),
162
+ ...(toolGroups === undefined ? {} : { toolGroups }),
129
163
  };
130
164
  }
131
165
 
@@ -135,13 +169,5 @@ export function signInState(config: ConnectorConfig): ConnectorSignIn {
135
169
  }
136
170
 
137
171
  export function stamp(server: VerifiedServer): VerifiedRecord {
138
- return {
139
- at: new Date().toISOString(),
140
- server: server.server,
141
- version: server.version,
142
- protocol: server.protocol,
143
- icon: server.icon,
144
- tools: server.tools,
145
- catalog: server.catalog,
146
- };
172
+ return { at: new Date().toISOString(), server: server.server };
147
173
  }