@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
@@ -1,7 +1,7 @@
1
- import type { StationTool } from '@metro-labs/mcp/stations/types';
1
+ import type { StationTool } from '@metro-labs/core/stations/types';
2
+ import { PRIORITIES } from './labels.js';
2
3
  import {
3
4
  str,
4
- createChannel,
5
5
  setChannelMetadata,
6
6
  xmtpSendAttachments,
7
7
  } from './tools-handlers.js';
@@ -15,43 +15,9 @@ const lineProp = {
15
15
  } as const;
16
16
 
17
17
  export const XMTP_TOOLS: StationTool[] = [
18
- {
19
- name: 'create_channel',
20
- description:
21
- 'Create a new XMTP group conversation (channel). Args: addresses (required, array of ' +
22
- 'Ethereum 0x addresses to add as members), name (required, the group name), labels? ' +
23
- '(optional string[] status labels applied after creation), account? ' +
24
- '(defaults to your only XMTP account). Calls the daemon xmtp `newGroup`, then ' +
25
- '`updateChannelMeta` if labels ' +
26
- 'are given. Returns the new metro:// line and convId. This is an xmtp-only operation. ' +
27
- 'NOTE: there is no add-members verb on the daemon, so members must be supplied at ' +
28
- 'creation time.',
29
- inputSchema: {
30
- type: 'object',
31
- properties: {
32
- addresses: {
33
- type: 'array',
34
- description: 'Ethereum 0x addresses to add as group members.',
35
- items: { type: 'string' },
36
- },
37
- name: { type: 'string', description: 'The group/channel name.' },
38
- labels: {
39
- type: 'array',
40
- description: 'Optional status labels to apply after creation.',
41
- items: { type: 'string' },
42
- },
43
- account: {
44
- type: 'string',
45
- description:
46
- 'XMTP account to create under. Omit when you have only one.',
47
- },
48
- },
49
- required: ['addresses', 'name'],
50
- },
51
- handle: (a, ctx) => createChannel(a, ctx),
52
- },
53
18
  {
54
19
  name: 'ask',
20
+ group: 'write',
55
21
  description:
56
22
  'Ask a question as a poll in an XMTP conversation (mirrors Claude AskUserQuestion). ' +
57
23
  'Single-question form: question (required), options? (string[]), header?, multiSelect?, ' +
@@ -116,11 +82,12 @@ export const XMTP_TOOLS: StationTool[] = [
116
82
  },
117
83
  {
118
84
  name: 'dm',
85
+ group: 'write',
119
86
  description:
120
87
  'Open (or reuse) a 1:1 XMTP DM with an Ethereum address. Args: address (required, 0x...), ' +
121
88
  'account? (defaults to your only XMTP account). Returns the new metro:// line and ' +
122
89
  'convId. xmtp-only ' +
123
- '(daemon `newDm`). Use this instead of create_channel when there is a single recipient.',
90
+ '(daemon `newDm`). For a group, use create_group.',
124
91
  inputSchema: {
125
92
  type: 'object',
126
93
  properties: {
@@ -145,10 +112,13 @@ export const XMTP_TOOLS: StationTool[] = [
145
112
  },
146
113
  {
147
114
  name: 'group_info',
115
+ group: 'read',
148
116
  description:
149
117
  "Read an XMTP channel's current metadata + membership. Args: line (required). Returns " +
150
- '{line, id, account, version (dm|group), name, memberCount, labels, github, preview, ' +
151
- 'members:[{inboxId, address}]}. xmtp-only (daemon `groupInfo`). Use before ' +
118
+ '{line, id, account, version (dm|group), name, memberCount, labels, category, status, priority, github, preview, ' +
119
+ 'assigned, appData (stored JSON object), rawAppData (stored JSON string), ' +
120
+ 'members:[{inboxId, address}]}. Syncs first and fails if metadata cannot be read. ' +
121
+ 'xmtp-only (daemon `groupInfo`). Use before ' +
152
122
  'set_channel_metadata/add_members to see current state.',
153
123
  inputSchema: {
154
124
  type: 'object',
@@ -163,35 +133,88 @@ export const XMTP_TOOLS: StationTool[] = [
163
133
  },
164
134
  {
165
135
  name: 'close_channel',
136
+ group: 'write',
137
+ destructive: true,
166
138
  description:
167
- 'Archive/close an XMTP group (removes members). Args: line (required). xmtp-only ' +
168
- '(daemon `closeGroup`). Irreversible-ish: members are removed from the group.',
139
+ 'Remove members from an XMTP group, and optionally leave it. Args: line (required), ' +
140
+ 'removeInboxIds? (inbox ids to remove; your own is ignored here), removeSelf? (true to ' +
141
+ 'leave the group yourself). With neither, nothing changes. xmtp-only (daemon ' +
142
+ '`closeGroup`). Returns {removed, leftSelf}.',
169
143
  inputSchema: {
170
144
  type: 'object',
171
- properties: { line: lineProp },
145
+ properties: {
146
+ line: lineProp,
147
+ removeInboxIds: {
148
+ type: 'array',
149
+ description: 'Inbox ids of the members to remove.',
150
+ items: { type: 'string' },
151
+ },
152
+ removeSelf: {
153
+ type: 'boolean',
154
+ description: 'Leave the group after removing the others.',
155
+ },
156
+ },
172
157
  required: ['line'],
173
158
  },
174
159
  async handle(a, ctx) {
175
160
  const line = str(a.line);
176
161
  if (!line) return ctx.err('close_channel requires `line`');
177
- return ctx.okJson(await ctx.call('closeGroup', { line }));
162
+ const args: Record<string, unknown> = { line };
163
+ if (Array.isArray(a.removeInboxIds)) args.removeInboxIds = a.removeInboxIds.map(String);
164
+ if (a.removeSelf === true) args.removeSelf = true;
165
+ return ctx.okJson(await ctx.call('closeGroup', args));
178
166
  },
179
167
  },
180
168
  {
181
169
  name: 'set_channel_metadata',
170
+ group: 'write',
182
171
  description:
183
172
  "Update an existing channel's metadata. Args: line (required, the metro:// line), and " +
184
- 'any of labels? (string[]), github? (url), preview? (url), name? (string). All provided ' +
185
- 'fields are applied together in one atomic updateChannelMeta daemon call (a single ' +
186
- 'appData merge plus name update). xmtp-only ' +
187
- '(channel metadata lives on xmtp groups). Returns the updated channel info.',
173
+ 'any of metadata? (JSON object), github? (url), preview? (url), name? (string). ' +
174
+ 'metadata is a shallow appData patch: omitted keys are preserved, supplied nested ' +
175
+ 'values replace that key, and null deletes custom keys. v is reserved. Put labels, ' +
176
+ 'assigned, category, status and priority inside metadata. assigned replaces the array with normalized lowercase ' +
177
+ 'Ethereum addresses of current members. Read group_info and union existing IDs to ' +
178
+ 'add assignees. category and status are each one free-form string per channel, trimmed, ' +
179
+ 'whitespace collapsed and truncated to 24 characters. priority is trimmed and must be Urgent, High, Medium or Low. ' +
180
+ '"" or null clears category, status or priority. labels remains a legacy top-level alias. Duplicate top-level/metadata ' +
181
+ 'label/link aliases are refused. All fields use one updateChannelMeta call. xmtp-only. ' +
182
+ 'Returns updated metadata. Reread group_info to verify persistence.',
188
183
  inputSchema: {
189
184
  type: 'object',
190
185
  properties: {
191
186
  line: lineProp,
187
+ metadata: {
188
+ type: 'object',
189
+ description: 'Shallow JSON appData patch. Omitted keys stay unchanged. v is reserved.',
190
+ properties: {
191
+ labels: { type: 'array', items: { type: 'string' } },
192
+ assigned: {
193
+ type: 'array',
194
+ description: 'Replacement assignee list. Current member Ethereum addresses only. [] clears.',
195
+ items: { type: 'string', pattern: '^0x[0-9a-fA-F]{40}$' },
196
+ },
197
+ category: {
198
+ type: ['string', 'null'],
199
+ description: 'One free-form category, trimmed, whitespace collapsed, truncated to 24 characters. "" or null clears it.',
200
+ },
201
+ status: {
202
+ type: ['string', 'null'],
203
+ description: 'One free-form status, trimmed, whitespace collapsed, truncated to 24 characters. "" or null clears it.',
204
+ },
205
+ priority: {
206
+ type: ['string', 'null'],
207
+ enum: [...PRIORITIES, '', null],
208
+ description: 'One priority: Urgent, High, Medium or Low. Surrounding whitespace is trimmed; empty or null clears it.',
209
+ },
210
+ github: { type: 'string' },
211
+ preview: { type: 'string' },
212
+ },
213
+ additionalProperties: true,
214
+ },
192
215
  labels: {
193
216
  type: 'array',
194
- description: 'Status labels to set.',
217
+ description: 'Legacy alias. Prefer metadata.labels.',
195
218
  items: { type: 'string' },
196
219
  },
197
220
  github: {
@@ -1,7 +1,6 @@
1
- import { errMsg } from '@metro-labs/mcp/log';
2
- import { mintId, SELF_URI } from './wire.js';
3
-
4
- type EmitInbound = (accountId: string, e: Record<string, unknown>) => void;
1
+ import { errMsg } from '@metro-labs/core/log';
2
+ import { emitInbound, selfUri } from '@metro-labs/core/stations/train-events';
3
+ import { mintId } from '@metro-labs/core/stations/station-runtime';
5
4
 
6
5
  const WHISPER_BIN = process.env.METRO_WHISPER_BIN ?? 'whisper-cli';
7
6
  const WHISPER_MODEL =
@@ -14,7 +13,6 @@ export async function transcribeAndEmit(
14
13
  line: string,
15
14
  accountId: string,
16
15
  sourceMsgId: string,
17
- emitInbound: EmitInbound,
18
16
  ): Promise<void> {
19
17
  const {
20
18
  existsSync: ex,
@@ -69,7 +67,7 @@ export async function transcribeAndEmit(
69
67
  ts: new Date().toISOString(),
70
68
  station: 'xmtp',
71
69
  line,
72
- from: SELF_URI,
70
+ from: selfUri(),
73
71
  text: `🎙️ ${text}`,
74
72
  payload: {
75
73
  contentType: 'transcript',
@@ -1,7 +1,8 @@
1
1
  import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { dirname } from 'node:path';
3
3
  import { Client, type ClientOptions, type Signer } from '@xmtp/node-sdk';
4
- import { expandHome, signerFor, XMTP_ENV } from './identity.js';
4
+ import { expandHome, identityFor, signerFor, XMTP_ENV } from './identity.js';
5
+ import { ensureDeployed } from './smart.js';
5
6
 
6
7
  export class XmtpVerifyError extends Error {}
7
8
 
@@ -10,6 +11,7 @@ export interface XmtpVerified {
10
11
  address: string;
11
12
  installationId: string;
12
13
  dbPath: string;
14
+ smart: boolean;
13
15
  }
14
16
 
15
17
  interface RegisteredClient {
@@ -34,15 +36,25 @@ const reason = (err: unknown): string =>
34
36
  export async function verifyXmtpKey(
35
37
  privateKey: string,
36
38
  dbPath: string,
39
+ smart = false,
37
40
  create: CreateXmtpClient = openInbox,
38
41
  ): Promise<XmtpVerified> {
39
- let signer: Signer;
40
- let address: string;
42
+ let identity: Awaited<ReturnType<typeof identityFor>>;
41
43
  try {
42
- ({ signer, address } = signerFor(privateKey));
44
+ signerFor(privateKey);
43
45
  } catch {
44
46
  throw new XmtpVerifyError('that is not a usable XMTP private key');
45
47
  }
48
+ try {
49
+ identity = await identityFor(privateKey, smart);
50
+ } catch (err) {
51
+ throw new XmtpVerifyError(`could not build the smart account on Base: ${reason(err)}`);
52
+ }
53
+ const { signer, address } = identity;
54
+ if (identity.smart !== null)
55
+ await ensureDeployed(identity.smart).catch((err: unknown) => {
56
+ throw new XmtpVerifyError(`could not deploy the smart account on Base (is the ZeroDev sponsorship still on?): ${reason(err)}`);
57
+ });
46
58
  const resolved = expandHome(dbPath);
47
59
  mkdirSync(dirname(resolved), { recursive: true });
48
60
  const client = await create(signer, resolved).catch((err: unknown) => {
@@ -59,6 +71,7 @@ export async function verifyXmtpKey(
59
71
  address,
60
72
  installationId: client.installationId,
61
73
  dbPath: resolved,
74
+ smart,
62
75
  };
63
76
  }
64
77
 
@@ -68,10 +81,11 @@ async function runCli(): Promise<void> {
68
81
  const input = JSON.parse(readFileSync(0, 'utf8')) as {
69
82
  privateKey?: unknown;
70
83
  dbPath?: unknown;
84
+ smart?: unknown;
71
85
  };
72
86
  if (typeof input.privateKey !== 'string' || typeof input.dbPath !== 'string')
73
87
  throw new XmtpVerifyError('xmtp verify needs a privateKey and a dbPath');
74
- out = { ok: true, ...(await verifyXmtpKey(input.privateKey, input.dbPath)) };
88
+ out = { ok: true, ...(await verifyXmtpKey(input.privateKey, input.dbPath, input.smart === true)) };
75
89
  } catch (err) {
76
90
  out = { ok: false, error: reason(err) };
77
91
  }
@@ -0,0 +1,28 @@
1
+ import type { EncodedContent } from '@xmtp/content-type-primitives';
2
+ import {
3
+ SignatureReferenceCodec,
4
+ SignatureRequestCodec,
5
+ TransactionReferenceCodec,
6
+ WalletSendCallsCodec,
7
+ } from './codecs.js';
8
+ import { bad, isNode, parseJson } from './frames.js';
9
+
10
+ const WALLET_TYPES: Record<string, { codec: { encode(c: Record<string, unknown>): EncodedContent }; needs: string[] }> = {
11
+ walletSendCalls: { codec: new WalletSendCallsCodec(), needs: ['version', 'chainId', 'from', 'calls'] },
12
+ transactionReference: { codec: new TransactionReferenceCodec(), needs: ['networkId', 'reference'] },
13
+ signatureRequest: { codec: new SignatureRequestCodec(), needs: ['id', 'kind'] },
14
+ signatureReference: { codec: new SignatureReferenceCodec(), needs: ['requestId', 'signature', 'signer'] },
15
+ };
16
+
17
+ export function buildWalletContent(raw: unknown): { encoded: EncodedContent; summary: string } {
18
+ const args = parseJson(raw, 'wallet');
19
+ const type = isNode(args) && typeof args.type === 'string' ? args.type : '';
20
+ const spec = Object.hasOwn(WALLET_TYPES, type) ? WALLET_TYPES[type] : undefined;
21
+ if (!isNode(args) || !spec) throw bad(`wallet type must be one of ${Object.keys(WALLET_TYPES).join(', ')}`);
22
+ const content = parseJson(args.content, 'wallet content');
23
+ if (!isNode(content)) throw bad(`wallet content must be the ${type} JSON object`);
24
+ const missing = spec.needs.filter((key) => content[key] === undefined);
25
+ if (missing.length > 0) throw bad(`${type} content needs ${missing.join(', ')}`);
26
+ const encoded = spec.codec.encode(content);
27
+ return { encoded, summary: encoded.fallback ?? type };
28
+ }
@@ -1,7 +1,3 @@
1
- export { emit, respond, mintId } from '@metro-labs/mcp/stations/station-runtime';
2
-
3
- export const SELF_URI = process.env.METRO_SELF_URI ?? '';
4
-
5
1
  const UID_MAP_MAX = 5000;
6
2
  const uidToXmtp = new Map<string, string>();
7
3
 
@@ -37,3 +33,17 @@ export function resolveMsgId(rawId: string): string {
37
33
  '(not seen by this train; pass the raw xmtp message_id)',
38
34
  );
39
35
  }
36
+
37
+ const SENT_MAX = 5000;
38
+ const sentIds = new Set<string>();
39
+
40
+ export function rememberSent(xmtpId: string | undefined): void {
41
+ if (!xmtpId) return;
42
+ sentIds.add(xmtpId);
43
+ if (sentIds.size > SENT_MAX) {
44
+ const oldest = sentIds.values().next().value;
45
+ if (oldest !== undefined) sentIds.delete(oldest);
46
+ }
47
+ }
48
+
49
+ export const sentByMe = (xmtpId: string): boolean => sentIds.has(xmtpId);
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.1.0-beta.26"
2
+ "version": "0.1.0-beta.261"
3
3
  }
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@metro-labs/core",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "description": "What every metro process shares: the logger, the event bus and its types, ids, secure file writes, the train protocol, station types and attachment handling. No HTTP, no policy.",
6
+ "type": "module",
7
+ "exports": {
8
+ "./log": "./src/log.ts",
9
+ "./events": "./src/events.ts",
10
+ "./is-record": "./src/is-record.ts",
11
+ "./runner-activity": "./src/runner-activity.ts",
12
+ "./secure-fs": "./src/secure-fs.ts",
13
+ "./version": "./src/version.ts",
14
+ "./train-error": "./src/train-error.ts",
15
+ "./trains/protocol": "./src/protocol.ts",
16
+ "./ids": "./src/ids.ts",
17
+ "./tickets": "./src/tickets.ts",
18
+ "./station-names": "./src/station-names.ts",
19
+ "./str": "./src/str.ts",
20
+ "./lines": "./src/lines.ts",
21
+ "./endpoints": "./src/endpoints.ts",
22
+ "./stations/types": "./src/stations/types.ts",
23
+ "./stations/account-files": "./src/stations/account-files.ts",
24
+ "./stations/station-runtime": "./src/stations/station-runtime.ts",
25
+ "./stations/account-store": "./src/stations/account-store.ts",
26
+ "./stations/attachments": "./src/stations/attachments.ts",
27
+ "./stations/mail": "./src/stations/mail.ts",
28
+ "./stations/mail-text": "./src/stations/mail-text.ts",
29
+ "./stations/mail-trust": "./src/stations/mail-trust.ts",
30
+ "./stations/oauth": "./src/stations/oauth.ts",
31
+ "./stations/messaging-normalize": "./src/stations/messaging-normalize.ts",
32
+ "./stations/profile": "./src/stations/profile.ts",
33
+ "./stations/sender-profile": "./src/stations/sender-profile.ts",
34
+ "./stations/train-events": "./src/stations/train-events.ts",
35
+ "./stations/train-boot": "./src/stations/train-boot.ts"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc",
39
+ "test": "tsc --noEmit && METRO_STATE_DIR=\"$(mktemp -d /tmp/metro-test.XXXXXX)\" bun test test/"
40
+ },
41
+ "dependencies": {
42
+ "pino": "^9.5.0",
43
+ "pino-pretty": "^13.1.3"
44
+ },
45
+ "devDependencies": {
46
+ "@stage-labs/config": "0.1.0-beta.3",
47
+ "eslint": "^10.3.0",
48
+ "knip": "^6.15.0",
49
+ "madge": "^8.0.0",
50
+ "typescript": "^5"
51
+ }
52
+ }
@@ -0,0 +1,7 @@
1
+ export interface Endpoint {
2
+ id: string;
3
+ webhookId?: string;
4
+ label: string;
5
+ secret?: string;
6
+ createdAt: string;
7
+ }
@@ -0,0 +1,121 @@
1
+ import { Line } from './lines.js';
2
+ import { errMsg, log } from './log.js';
3
+
4
+ export const userSelf = (): Line =>
5
+ (process.env.METRO_FROM ?? 'metro://user') as Line;
6
+
7
+ export type StructuredEvent =
8
+ | { type: 'msg' }
9
+ | { type: 'react'; emoji?: string; targetId?: string }
10
+ | { type: 'edit'; targetId?: string }
11
+ | { type: 'delete'; targetId?: string }
12
+ | { type: 'reply'; replyTo?: string }
13
+ | { type: 'system'; source?: string; eventName?: string };
14
+
15
+ export interface MetroEvent {
16
+ id: string;
17
+ ts: string;
18
+ station: string;
19
+ line: Line;
20
+ lineName?: string;
21
+ from: Line;
22
+ fromName?: string;
23
+ fromDisplayName?: string;
24
+ to: Line;
25
+ text?: string;
26
+ messageId?: string;
27
+ replyTo?: string;
28
+ isPrivate?: boolean;
29
+ mentionsSelf?: boolean;
30
+ replyToSelf?: boolean;
31
+ senderVerified?: boolean;
32
+ payload?: unknown;
33
+ display?: string;
34
+ event?: StructuredEvent;
35
+ agent?: string;
36
+ seq?: number;
37
+ }
38
+
39
+ function isExternalWebhook(e: MetroEvent): boolean {
40
+ return e.station === 'webhook' && !Line.isLocal(e.from);
41
+ }
42
+
43
+ function webhookEventName(e: MetroEvent): string | undefined {
44
+ const headers = (e.payload as { headers?: Record<string, string> } | undefined)
45
+ ?.headers;
46
+ return headers?.['x-github-event'] ?? headers?.['x-intercom-topic'];
47
+ }
48
+
49
+ export function classifyEvent(e: MetroEvent): StructuredEvent {
50
+ if (isExternalWebhook(e)) {
51
+ return {
52
+ type: 'system',
53
+ source: 'webhook',
54
+ eventName: webhookEventName(e),
55
+ };
56
+ }
57
+ const emoji =
58
+ (e.payload as { emoji?: string } | undefined)?.emoji ??
59
+ e.text?.match(/^\[react (.+)\]$/)?.[1];
60
+ if (emoji) return { type: 'react', emoji, targetId: e.replyTo };
61
+ if (e.replyTo) return { type: 'reply', replyTo: e.replyTo };
62
+ return { type: 'msg' };
63
+ }
64
+
65
+ export function formatDisplay(e: MetroEvent): string {
66
+ const headerFor = (icon: string, parts: (string | undefined)[]): string =>
67
+ `**${icon} ${parts.filter(Boolean).join(' · ')}**`;
68
+ const body = e.text ?? '';
69
+ if (isExternalWebhook(e)) {
70
+ const ev = webhookEventName(e);
71
+ return `${headerFor('🪝', ['webhook', e.lineName, ev])}\n> ${body}`;
72
+ }
73
+ if (Line.isLocal(e.from)) {
74
+ return `${headerFor('📤', [e.station, '→', e.fromName ?? e.to])}\n> ${body}`;
75
+ }
76
+ return `${headerFor('📩', [e.station, e.fromName ?? e.from, e.lineName])}\n> ${body}`;
77
+ }
78
+
79
+ export { mintId } from './ids.js';
80
+
81
+ export type BusListener = (event: MetroEvent, busSeq: number) => void;
82
+
83
+ export interface BufferedEvent {
84
+ busSeq: number;
85
+ event: MetroEvent;
86
+ }
87
+
88
+ const BUS_BUFFER_MAX = 500;
89
+
90
+ const listeners = new Set<BusListener>();
91
+ const buffer: BufferedEvent[] = [];
92
+ let busSeq = 0;
93
+
94
+ export function publishEvent(event: MetroEvent): void {
95
+ busSeq += 1;
96
+ const seq = busSeq;
97
+ buffer.push({ busSeq: seq, event });
98
+ if (buffer.length > BUS_BUFFER_MAX) buffer.shift();
99
+ for (const fn of [...listeners]) {
100
+ try {
101
+ fn(event, seq);
102
+ } catch (err) {
103
+ log.error({ busSeq: seq, err: errMsg(err) }, 'bus: a listener threw');
104
+ }
105
+ }
106
+ }
107
+
108
+ export function currentBusSeq(): number {
109
+ return busSeq;
110
+ }
111
+
112
+ export function bufferedSince(afterBusSeq: number): BufferedEvent[] {
113
+ return buffer.filter((b) => b.busSeq > afterBusSeq);
114
+ }
115
+
116
+ export function subscribeEvents(fn: BusListener): () => void {
117
+ listeners.add(fn);
118
+ return () => {
119
+ listeners.delete(fn);
120
+ };
121
+ }
@@ -0,0 +1,28 @@
1
+ import { randomBytes, randomInt } from 'node:crypto';
2
+
3
+ const ID_BYTES = 8;
4
+ const REROLLS = 16;
5
+ const APPROVAL_LETTERS = 'abcdefghijkmnopqrstuvwxyz';
6
+ const APPROVAL_LENGTH = 5;
7
+
8
+ export const approvalId = (): string => Array.from({ length: APPROVAL_LENGTH }, () => APPROVAL_LETTERS[randomInt(APPROVAL_LETTERS.length)]).join('');
9
+
10
+ export const ID_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{10}$/;
11
+
12
+ export const mintId = (): string =>
13
+ `msg_${randomBytes(6).toString('base64url')}`;
14
+
15
+ export function newId(): string {
16
+ for (let attempt = 0; attempt < REROLLS; attempt += 1) {
17
+ const id = randomBytes(ID_BYTES).toString('base64url');
18
+ if (ID_RE.test(id)) return id;
19
+ }
20
+ throw new Error('could not generate an id');
21
+ }
22
+
23
+ export function parseId(raw: unknown): string | null {
24
+ if (typeof raw !== 'string') return null;
25
+ return ID_RE.test(raw) ? raw : null;
26
+ }
27
+
28
+ export const AGENT_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{1,31}$/;
@@ -0,0 +1,2 @@
1
+ export const isRecord = (v: unknown): v is Record<string, unknown> =>
2
+ typeof v === 'object' && v !== null && !Array.isArray(v);
@@ -0,0 +1,78 @@
1
+ export type Line = string & { readonly __line: unique symbol };
2
+ export const asLine = (s: string): Line => s as Line;
3
+
4
+ const PREFIX = 'metro://';
5
+ const build = (station: string, ...seg: (string | number)[]): Line =>
6
+ asLine(`${PREFIX}${station}/${seg.map(String).join('/')}`);
7
+
8
+ function parseAccountScoped(
9
+ line: Line | string,
10
+ station: string,
11
+ validate?: (resource: string) => boolean,
12
+ ): { accountId: string; resource: string } | null {
13
+ const p = Line.parse(line);
14
+ if (p?.station !== station || p.path.length !== 2) return null;
15
+ const [accountId, resource] = p.path;
16
+ if (accountId === undefined || resource === undefined) return null;
17
+ if (validate && !validate(resource)) return null;
18
+ return { accountId, resource };
19
+ }
20
+
21
+ const isSnowflake = (s: string): boolean => /^\d+$/.test(s);
22
+ const isThreemaResource = (s: string): boolean =>
23
+ /^(?:[A-Z0-9]{8}|\*[A-Z0-9]{7})(?:-[0-9a-f]{16})?$/i.test(s);
24
+ const isMailResource = (s: string): boolean => /^[A-Za-z0-9=_%.@+-]+$/.test(s);
25
+ const isSignedInt = (s: string): boolean => /^-?\d+$/.test(s);
26
+
27
+ const topicPart = (topicId: string | undefined): { topicId?: number } | null => {
28
+ if (topicId === undefined) return {};
29
+ return isSnowflake(topicId) ? { topicId: Number(topicId) } : null;
30
+ };
31
+
32
+ function parseTelegramLine(
33
+ line: Line | string,
34
+ ): { accountId: string; chatId: number; topicId?: number } | null {
35
+ const p = Line.parse(line);
36
+ if (p?.station !== 'telegram-bot') return null;
37
+ const [accountId, chatId, topicId, ...extra] = p.path;
38
+ if (accountId === undefined || chatId === undefined || extra.length > 0) return null;
39
+ if (!isSignedInt(chatId)) return null;
40
+ const topic = topicPart(topicId);
41
+ return topic === null ? null : { accountId, chatId: Number(chatId), ...topic };
42
+ }
43
+
44
+ export const Line = {
45
+ claude: (orgId: string, sessionId: string): Line =>
46
+ build('claude', orgId, sessionId),
47
+ webhook: (endpointId: string): Line => build('webhook', endpointId),
48
+ user: (station: string, id: string | number): Line =>
49
+ build(station, 'user', id),
50
+
51
+ parse(line: Line | string): { station: string; path: string[] } | null {
52
+ if (!line.startsWith(PREFIX)) return null;
53
+ const rest = line.slice(PREFIX.length);
54
+ const slash = rest.indexOf('/');
55
+ if (slash <= 0) return null;
56
+ const path = rest
57
+ .slice(slash + 1)
58
+ .split('/')
59
+ .filter(Boolean);
60
+ return path.length ? { station: rest.slice(0, slash), path } : null;
61
+ },
62
+ station: (line: Line | string): string | null =>
63
+ Line.parse(line)?.station ?? null,
64
+ isLocal: (line: Line | string): boolean => Line.station(line) === 'claude',
65
+
66
+ parseXmtp: (line: Line | string) => parseAccountScoped(line, 'xmtp'),
67
+
68
+ parseDiscord: (line: Line | string) =>
69
+ parseAccountScoped(line, 'discord-bot', isSnowflake),
70
+
71
+ parseTelegram: (line: Line | string) => parseTelegramLine(line),
72
+
73
+ parseThreema: (line: Line | string) =>
74
+ parseAccountScoped(line, 'threema', isThreemaResource),
75
+
76
+ parseMail: (line: Line | string, station: 'outlook' | 'gmail') =>
77
+ parseAccountScoped(line, station, isMailResource),
78
+ };