@stage-labs/metro 0.1.0-beta.20 → 0.1.0-beta.201

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 (442) hide show
  1. package/dist/api.js +9 -101
  2. package/dist/claude-settings.js +40 -0
  3. package/dist/claude.js +163 -0
  4. package/dist/cli.js +50 -109
  5. package/dist/control.js +47 -75
  6. package/dist/hold.js +211 -0
  7. package/dist/local.js +43 -0
  8. package/dist/mcp-config.js +25 -0
  9. package/dist/node-name.js +71 -0
  10. package/dist/onboarding.js +44 -0
  11. package/dist/provider-flags.js +9 -0
  12. package/dist/route.js +58 -0
  13. package/dist/runtime-install.js +97 -0
  14. package/dist/runtime.js +32 -52
  15. package/dist/serve.js +158 -0
  16. package/dist/service.js +243 -0
  17. package/dist/tail.js +119 -0
  18. package/dist/update.js +13 -1
  19. package/package.json +1 -22
  20. package/runtime/marketplace/.claude-plugin/marketplace.json +12 -0
  21. package/runtime/marketplace/plugin/.claude-plugin/plugin.json +17 -0
  22. package/runtime/marketplace/plugin/.mcp.json +1 -0
  23. package/runtime/marketplace/plugin/bin/guard.mjs +71 -0
  24. package/runtime/marketplace/plugin/bin/metro-plugin.mjs +30 -0
  25. package/runtime/marketplace/plugin/bin/policy.mjs +97 -0
  26. package/runtime/marketplace/plugin/bin/session-start.mjs +31 -0
  27. package/runtime/marketplace/plugin/hooks/hooks.json +25 -0
  28. package/runtime/marketplace/plugin/orchestrator.md +24 -0
  29. package/runtime/node_modules/@metro-labs/core/package.json +47 -0
  30. package/runtime/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  31. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/events.ts +8 -6
  32. package/runtime/node_modules/@metro-labs/core/src/identity.ts +7 -0
  33. package/runtime/node_modules/@metro-labs/{mcp/src/db → core/src}/ids.ts +5 -0
  34. package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  35. package/runtime/node_modules/@metro-labs/{mcp/src/stations → core/src}/lines.ts +12 -3
  36. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/protocol.ts +7 -4
  37. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/secure-fs.ts +17 -0
  38. package/runtime/node_modules/@metro-labs/core/src/station-names.ts +13 -0
  39. package/runtime/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  40. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/account-store.ts +4 -24
  41. package/runtime/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  42. package/runtime/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  43. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/station-runtime.ts +3 -6
  44. package/runtime/node_modules/@metro-labs/core/src/stations/train-boot.ts +42 -0
  45. package/runtime/node_modules/@metro-labs/core/src/stations/train-events.ts +89 -0
  46. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/types.ts +16 -0
  47. package/runtime/node_modules/@metro-labs/core/src/tickets.ts +37 -0
  48. package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
  49. package/runtime/node_modules/@metro-labs/daemon/package.json +48 -0
  50. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/agent-fs.ts +134 -0
  51. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files-api.ts +12 -0
  52. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files.ts +119 -0
  53. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/home-fs.ts +113 -0
  54. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/job-env.ts +51 -0
  55. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/provision.ts +99 -0
  56. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedule-detail.ts +100 -0
  57. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules-api.ts +27 -0
  58. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules.ts +252 -0
  59. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/unit-files.ts +61 -0
  60. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/user.ts +91 -0
  61. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/view.ts +87 -0
  62. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
  63. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-lookups.ts +55 -0
  64. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-routes.ts +76 -0
  65. package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +357 -0
  66. package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +30 -0
  67. package/runtime/node_modules/@metro-labs/daemon/src/agents/allowlist.ts +59 -0
  68. package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +131 -0
  69. package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +132 -0
  70. package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +305 -0
  71. package/runtime/node_modules/@metro-labs/daemon/src/agents/files.ts +168 -0
  72. package/runtime/node_modules/@metro-labs/{mcp/src/db/key-map.ts → daemon/src/agents/keys.ts} +1 -11
  73. package/runtime/node_modules/@metro-labs/{mcp/src/db/agent-map.ts → daemon/src/agents/map.ts} +58 -1
  74. package/runtime/node_modules/@metro-labs/daemon/src/agents/policy-route.ts +27 -0
  75. package/runtime/node_modules/@metro-labs/{mcp/src/db/agent-scope.ts → daemon/src/agents/scope.ts} +2 -2
  76. package/runtime/node_modules/@metro-labs/daemon/src/agents/sender-cards.ts +86 -0
  77. package/runtime/node_modules/@metro-labs/daemon/src/agents/senders.ts +38 -0
  78. package/runtime/node_modules/@metro-labs/daemon/src/approvals/api.ts +55 -0
  79. package/runtime/node_modules/@metro-labs/daemon/src/approvals/needs.ts +2 -0
  80. package/runtime/node_modules/@metro-labs/daemon/src/approvals/pending.ts +149 -0
  81. package/runtime/node_modules/@metro-labs/daemon/src/approvals/preview.ts +66 -0
  82. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +221 -0
  83. package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +39 -0
  84. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/crash-guard.ts +1 -1
  85. package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +21 -0
  86. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/paths.ts +6 -34
  87. package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +26 -0
  88. package/runtime/node_modules/@metro-labs/daemon/src/channels/dedupe.ts +12 -0
  89. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/inbound.ts +47 -44
  90. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/media-note.ts +9 -4
  91. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/pending.ts +4 -1
  92. package/runtime/node_modules/@metro-labs/daemon/src/channels/react-note.ts +13 -0
  93. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/relay.ts +2 -2
  94. package/runtime/node_modules/@metro-labs/daemon/src/channels/reply-id.ts +1 -0
  95. package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +355 -0
  96. package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +359 -0
  97. package/runtime/node_modules/@metro-labs/daemon/src/claude/login.ts +208 -0
  98. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory.ts +82 -0
  99. package/runtime/node_modules/@metro-labs/daemon/src/claude/onboarding.ts +60 -0
  100. package/runtime/node_modules/@metro-labs/daemon/src/claude/plugin-install.ts +149 -0
  101. package/runtime/node_modules/@metro-labs/daemon/src/claude/session-files.ts +75 -0
  102. package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +283 -0
  103. package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +109 -0
  104. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +271 -0
  105. package/runtime/node_modules/@metro-labs/daemon/src/claude/skills.ts +120 -0
  106. package/runtime/node_modules/@metro-labs/daemon/src/claude/version.ts +113 -0
  107. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-api.ts → daemon/src/connectors/api.ts} +77 -109
  108. package/runtime/node_modules/@metro-labs/{mcp/src/db/connector-config.ts → daemon/src/connectors/config.ts} +55 -26
  109. package/runtime/node_modules/@metro-labs/daemon/src/connectors/gates.ts +72 -0
  110. package/runtime/node_modules/@metro-labs/daemon/src/connectors/health.ts +18 -0
  111. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/oauth-client.ts +14 -17
  112. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/oauth-discovery.ts +28 -13
  113. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-oauth-routes.ts → daemon/src/connectors/oauth-routes.ts} +30 -29
  114. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-oauth.ts → daemon/src/connectors/oauth.ts} +61 -22
  115. package/runtime/node_modules/@metro-labs/daemon/src/connectors/plugin-sync.ts +131 -0
  116. package/runtime/node_modules/@metro-labs/daemon/src/connectors/reach.ts +27 -0
  117. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-policy.ts +90 -0
  118. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-target.ts +29 -0
  119. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay.ts +348 -0
  120. package/runtime/node_modules/@metro-labs/daemon/src/connectors/store.ts +358 -0
  121. package/runtime/node_modules/@metro-labs/daemon/src/connectors/tools.ts +81 -0
  122. package/runtime/node_modules/@metro-labs/daemon/src/connectors/url.ts +37 -0
  123. package/runtime/node_modules/@metro-labs/daemon/src/connectors/verify.ts +106 -0
  124. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-grant.ts +4 -4
  125. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-owner.ts +3 -3
  126. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-reaper.ts +174 -0
  127. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-serve.ts +11 -12
  128. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-api.ts +10 -27
  129. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-store.ts +2 -2
  130. package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +233 -0
  131. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-auth.ts +208 -0
  132. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +91 -0
  133. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +173 -0
  134. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +194 -0
  135. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +137 -0
  136. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effort.ts +77 -0
  137. package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
  138. package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +237 -0
  139. package/runtime/node_modules/@metro-labs/daemon/src/gateway/frames.ts +118 -0
  140. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +274 -0
  141. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-auth.ts +160 -0
  142. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-client.ts +46 -0
  143. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-setup.ts +150 -0
  144. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-stream.ts +139 -0
  145. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-translate.ts +223 -0
  146. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini.ts +208 -0
  147. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +199 -0
  148. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +299 -0
  149. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-signin.ts +193 -0
  150. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-store.ts +70 -0
  151. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +90 -0
  152. package/runtime/node_modules/@metro-labs/daemon/src/gateway/pkce.ts +36 -0
  153. package/runtime/node_modules/@metro-labs/daemon/src/gateway/provider-models.ts +66 -0
  154. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +18 -0
  155. package/runtime/node_modules/@metro-labs/daemon/src/gateway/subscription.ts +120 -0
  156. package/runtime/node_modules/@metro-labs/daemon/src/gateway/text.ts +15 -0
  157. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +244 -0
  158. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/accounts.ts +59 -18
  159. package/runtime/node_modules/@metro-labs/daemon/src/mcp/attachment-schema.ts +91 -0
  160. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/call-tools.ts +43 -20
  161. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/ctx.ts +4 -4
  162. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/event-store.ts +15 -16
  163. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/group-tools.ts +2 -2
  164. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/index.ts +24 -79
  165. package/runtime/node_modules/@metro-labs/daemon/src/mcp/instructions.ts +19 -0
  166. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/member-tools.ts +2 -2
  167. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-prompt.ts +87 -0
  168. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +79 -0
  169. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-gate.ts +83 -0
  170. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-snapshot.ts +79 -0
  171. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-lookup.ts +60 -0
  172. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-tool.ts +96 -0
  173. package/runtime/node_modules/@metro-labs/daemon/src/mcp/read-tool.ts +87 -0
  174. package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +46 -0
  175. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-slot.ts +48 -0
  176. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/session.ts +33 -42
  177. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-catalog.ts +88 -0
  178. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-def.ts +9 -0
  179. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-dispatch.ts +53 -40
  180. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-schemas.ts +55 -119
  181. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/upload-tool.ts +6 -11
  182. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/api.ts +43 -0
  183. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/helper-script.ts +126 -0
  184. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/move.ts +165 -0
  185. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/privilege.ts +48 -0
  186. package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +132 -0
  187. package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +316 -0
  188. package/runtime/node_modules/@metro-labs/daemon/src/policy/policy.ts +118 -0
  189. package/runtime/node_modules/@metro-labs/daemon/src/routes/bearer.ts +35 -0
  190. package/runtime/node_modules/@metro-labs/daemon/src/routes/body.ts +24 -0
  191. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/routes}/http.ts +59 -51
  192. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +208 -0
  193. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +71 -0
  194. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/session-api.ts → daemon/src/routes/session.ts} +9 -7
  195. package/runtime/node_modules/@metro-labs/daemon/src/routes/threema-callback.ts +103 -0
  196. package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +39 -0
  197. package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +58 -0
  198. package/runtime/node_modules/@metro-labs/daemon/src/server/owner.ts +26 -0
  199. package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +90 -0
  200. package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
  201. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-driver.ts +42 -0
  202. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-inline.ts +29 -1
  203. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-interactive.ts +9 -36
  204. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-outlook.ts +63 -0
  205. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-resolve.ts +38 -13
  206. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/attach-session.ts +30 -20
  207. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-xmtp.ts +2 -2
  208. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach.ts +75 -9
  209. package/runtime/node_modules/@metro-labs/daemon/src/stations/materialize.ts +265 -0
  210. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/registry.ts +22 -6
  211. package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +82 -0
  212. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor-io.ts +2 -2
  213. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor.ts +5 -8
  214. package/runtime/node_modules/@metro-labs/daemon/src/stations/threema-callbacks.ts +32 -0
  215. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/train-call.ts +1 -1
  216. package/runtime/node_modules/@metro-labs/daemon/src/stations/webhook-endpoints.ts +51 -0
  217. package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +84 -0
  218. package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +124 -0
  219. package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +15 -0
  220. package/runtime/node_modules/@metro-labs/daemon/src/vault/api.ts +45 -0
  221. package/runtime/node_modules/@metro-labs/daemon/src/vault/config.ts +51 -0
  222. package/runtime/node_modules/@metro-labs/daemon/src/vault/firewall.ts +48 -0
  223. package/runtime/node_modules/@metro-labs/daemon/src/vault/index.ts +96 -0
  224. package/runtime/node_modules/@metro-labs/daemon/src/vault/install.ts +56 -0
  225. package/runtime/node_modules/@metro-labs/daemon/src/vault/paths.ts +26 -0
  226. package/runtime/node_modules/@metro-labs/daemon/src/vault/proxy.ts +148 -0
  227. package/runtime/node_modules/@metro-labs/daemon/src/vault/store.ts +130 -0
  228. package/runtime/node_modules/@metro-labs/daemon/src/vault/trust.ts +61 -0
  229. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/package.json +3 -5
  230. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/accounts.ts +11 -13
  231. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/actions.ts +6 -154
  232. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/attachments.ts +3 -3
  233. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/format.ts +28 -64
  234. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/group-actions.ts +1 -1
  235. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/group.ts +2 -2
  236. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/index.ts +14 -19
  237. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/members.ts +2 -2
  238. package/runtime/node_modules/@metro-labs/discord-bot/src/profile.ts +68 -0
  239. package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/send-files.ts +1 -1
  240. package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +22 -0
  241. package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +1 -0
  242. package/runtime/node_modules/@metro-labs/http/package.json +29 -0
  243. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +138 -0
  244. package/runtime/node_modules/@metro-labs/http/src/mode-api.ts +32 -0
  245. package/runtime/node_modules/@metro-labs/http/src/return-to.ts +21 -0
  246. package/runtime/node_modules/@metro-labs/http/src/workos-token.ts +149 -0
  247. package/runtime/node_modules/@metro-labs/{telegram-user → outlook}/package.json +2 -5
  248. package/runtime/node_modules/@metro-labs/outlook/src/accounts.ts +107 -0
  249. package/runtime/node_modules/@metro-labs/outlook/src/actions.ts +20 -0
  250. package/runtime/node_modules/@metro-labs/outlook/src/attachments.ts +97 -0
  251. package/runtime/node_modules/@metro-labs/outlook/src/auth.ts +150 -0
  252. package/runtime/node_modules/@metro-labs/outlook/src/browser.ts +53 -0
  253. package/runtime/node_modules/@metro-labs/outlook/src/config.ts +36 -0
  254. package/runtime/node_modules/@metro-labs/outlook/src/format.ts +141 -0
  255. package/runtime/node_modules/@metro-labs/outlook/src/graph.ts +60 -0
  256. package/runtime/node_modules/@metro-labs/outlook/src/html.ts +72 -0
  257. package/runtime/node_modules/@metro-labs/outlook/src/inbound.ts +104 -0
  258. package/runtime/node_modules/@metro-labs/outlook/src/index.ts +12 -0
  259. package/runtime/node_modules/@metro-labs/outlook/src/login.ts +150 -0
  260. package/runtime/node_modules/@metro-labs/outlook/src/me.ts +41 -0
  261. package/runtime/node_modules/@metro-labs/outlook/src/outbound.ts +116 -0
  262. package/runtime/node_modules/@metro-labs/outlook/src/query.ts +119 -0
  263. package/runtime/node_modules/@metro-labs/outlook/src/state.ts +43 -0
  264. package/runtime/node_modules/@metro-labs/outlook/src/station.ts +15 -0
  265. package/runtime/node_modules/@metro-labs/outlook/src/trust.ts +70 -0
  266. package/runtime/node_modules/@metro-labs/telegram/package.json +3 -2
  267. package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +48 -88
  268. package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +214 -253
  269. package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +67 -108
  270. package/runtime/node_modules/@metro-labs/{telegram-user → telegram}/src/client.ts +6 -6
  271. package/runtime/node_modules/@metro-labs/telegram/src/format.ts +102 -146
  272. package/runtime/node_modules/@metro-labs/{telegram-user → telegram}/src/group.ts +4 -4
  273. package/runtime/node_modules/@metro-labs/{telegram-user → telegram}/src/history.ts +1 -1
  274. package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +57 -0
  275. package/runtime/node_modules/@metro-labs/telegram/src/index.ts +6 -102
  276. package/runtime/node_modules/@metro-labs/{telegram-user → telegram}/src/login.ts +20 -20
  277. package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +65 -151
  278. package/runtime/node_modules/@metro-labs/telegram/src/members.ts +61 -33
  279. package/runtime/node_modules/@metro-labs/{telegram-user → telegram}/src/normalize.ts +1 -1
  280. package/runtime/node_modules/@metro-labs/telegram/src/profile.ts +70 -0
  281. package/runtime/node_modules/@metro-labs/{telegram-user → telegram}/src/reactions.ts +2 -2
  282. package/runtime/node_modules/@metro-labs/telegram/src/station.ts +11 -1
  283. package/runtime/node_modules/@metro-labs/telegram/src/types.ts +5 -47
  284. package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +1 -3
  285. package/runtime/node_modules/@metro-labs/telegram-bot/package.json +25 -0
  286. package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +119 -0
  287. package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +246 -0
  288. package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +128 -0
  289. package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +173 -0
  290. package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +103 -0
  291. package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +95 -0
  292. package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +47 -0
  293. package/runtime/node_modules/@metro-labs/telegram-bot/src/profile.ts +65 -0
  294. package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +20 -0
  295. package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +56 -0
  296. package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +1 -0
  297. package/runtime/node_modules/@metro-labs/threema/package.json +26 -0
  298. package/runtime/node_modules/@metro-labs/threema/src/accounts.ts +106 -0
  299. package/runtime/node_modules/@metro-labs/threema/src/actions.ts +134 -0
  300. package/runtime/node_modules/@metro-labs/threema/src/api.ts +152 -0
  301. package/runtime/node_modules/@metro-labs/threema/src/crypto.ts +100 -0
  302. package/runtime/node_modules/@metro-labs/threema/src/files.ts +58 -0
  303. package/runtime/node_modules/@metro-labs/threema/src/format.ts +169 -0
  304. package/runtime/node_modules/@metro-labs/threema/src/groups.ts +96 -0
  305. package/runtime/node_modules/@metro-labs/threema/src/ids.ts +21 -0
  306. package/runtime/node_modules/@metro-labs/threema/src/inbound.ts +89 -0
  307. package/runtime/node_modules/@metro-labs/threema/src/index.ts +24 -0
  308. package/runtime/node_modules/@metro-labs/threema/src/messages.ts +264 -0
  309. package/runtime/node_modules/@metro-labs/threema/src/outbound.ts +160 -0
  310. package/runtime/node_modules/@metro-labs/threema/src/station.ts +13 -0
  311. package/runtime/node_modules/@metro-labs/threema/src/verify.ts +117 -0
  312. package/runtime/node_modules/@metro-labs/webhook/package.json +1 -1
  313. package/runtime/node_modules/@metro-labs/webhook/src/station.ts +5 -8
  314. package/runtime/node_modules/@metro-labs/whatsapp/package.json +1 -3
  315. package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +1 -2
  316. package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +1 -1
  317. package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +40 -5
  318. package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +2 -2
  319. package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +1 -1
  320. package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +74 -4
  321. package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +7 -56
  322. package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +10 -27
  323. package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +4 -37
  324. package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +1 -1
  325. package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +1 -1
  326. package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +1 -1
  327. package/runtime/node_modules/@metro-labs/whatsapp/src/names.ts +28 -0
  328. package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +1 -1
  329. package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +44 -0
  330. package/runtime/node_modules/@metro-labs/whatsapp/src/resolve.ts +52 -0
  331. package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +8 -1
  332. package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +5 -9
  333. package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +0 -1
  334. package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +1 -5
  335. package/runtime/node_modules/@metro-labs/xmtp/package.json +3 -2
  336. package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +9 -8
  337. package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +1 -1
  338. package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +3 -201
  339. package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +3 -42
  340. package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +12 -143
  341. package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +3 -3
  342. package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +3 -3
  343. package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +7 -24
  344. package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +7 -16
  345. package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +1 -1
  346. package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +2 -2
  347. package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +30 -16
  348. package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +11 -14
  349. package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +1 -19
  350. package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +1 -1
  351. package/runtime/node_modules/@metro-labs/xmtp/src/names.ts +61 -0
  352. package/runtime/node_modules/@metro-labs/xmtp/src/profile.ts +153 -0
  353. package/runtime/node_modules/@metro-labs/xmtp/src/sender.ts +112 -0
  354. package/runtime/node_modules/@metro-labs/xmtp/src/smart.ts +72 -0
  355. package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +5 -1
  356. package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +3 -50
  357. package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +30 -44
  358. package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +4 -6
  359. package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +19 -5
  360. package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +15 -3
  361. package/runtime/runtime.json +1 -1
  362. package/runtime/server.ts +1 -0
  363. package/runtime/stations.json +37 -0
  364. package/dist/prompt.js +0 -10
  365. package/dist/store.js +0 -70
  366. package/runtime/node_modules/@metro-labs/discord/src/station.ts +0 -19
  367. package/runtime/node_modules/@metro-labs/discord/src/voice-speak.ts +0 -195
  368. package/runtime/node_modules/@metro-labs/discord/src/voice-transcribe.ts +0 -292
  369. package/runtime/node_modules/@metro-labs/discord/src/voice.ts +0 -197
  370. package/runtime/node_modules/@metro-labs/discord/src/wire.ts +0 -5
  371. package/runtime/node_modules/@metro-labs/mcp/package.json +0 -66
  372. package/runtime/node_modules/@metro-labs/mcp/src/channels/dedupe.ts +0 -24
  373. package/runtime/node_modules/@metro-labs/mcp/src/daemon/account-api.ts +0 -311
  374. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-api.ts +0 -335
  375. package/runtime/node_modules/@metro-labs/mcp/src/daemon/api-http.ts +0 -129
  376. package/runtime/node_modules/@metro-labs/mcp/src/daemon/boot.ts +0 -322
  377. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair-api.ts +0 -111
  378. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair.ts +0 -20
  379. package/runtime/node_modules/@metro-labs/mcp/src/daemon/collection-api.ts +0 -202
  380. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-json.ts +0 -31
  381. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-tools.ts +0 -100
  382. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-url.ts +0 -57
  383. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-verify.ts +0 -333
  384. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-auth.ts +0 -164
  385. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-oauth.ts +0 -208
  386. package/runtime/node_modules/@metro-labs/mcp/src/daemon/identity.ts +0 -79
  387. package/runtime/node_modules/@metro-labs/mcp/src/daemon/oauth-pending.ts +0 -65
  388. package/runtime/node_modules/@metro-labs/mcp/src/daemon/pair-codes.ts +0 -58
  389. package/runtime/node_modules/@metro-labs/mcp/src/daemon/project-api.ts +0 -214
  390. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-api.ts +0 -125
  391. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-pair.ts +0 -18
  392. package/runtime/node_modules/@metro-labs/mcp/src/daemon/runtime-source.ts +0 -105
  393. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session-apis.ts +0 -41
  394. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session.ts +0 -218
  395. package/runtime/node_modules/@metro-labs/mcp/src/daemon/tunnel.ts +0 -169
  396. package/runtime/node_modules/@metro-labs/mcp/src/db/account-attach.ts +0 -91
  397. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-admin.ts +0 -215
  398. package/runtime/node_modules/@metro-labs/mcp/src/db/client.ts +0 -37
  399. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-collections.ts +0 -218
  400. package/runtime/node_modules/@metro-labs/mcp/src/db/connectors.ts +0 -329
  401. package/runtime/node_modules/@metro-labs/mcp/src/db/materialize.ts +0 -340
  402. package/runtime/node_modules/@metro-labs/mcp/src/db/projects.ts +0 -300
  403. package/runtime/node_modules/@metro-labs/mcp/src/db/runtime-admin.ts +0 -28
  404. package/runtime/node_modules/@metro-labs/mcp/src/db/runtimes.ts +0 -105
  405. package/runtime/node_modules/@metro-labs/mcp/src/db/schema.ts +0 -131
  406. package/runtime/node_modules/@metro-labs/mcp/src/db/token-carry.ts +0 -45
  407. package/runtime/node_modules/@metro-labs/mcp/src/db/users.ts +0 -57
  408. package/runtime/node_modules/@metro-labs/mcp/src/db/whatsapp-login.ts +0 -18
  409. package/runtime/node_modules/@metro-labs/mcp/src/mcp/channel-owner.ts +0 -29
  410. package/runtime/node_modules/@metro-labs/mcp/src/mcp/frame-scope.ts +0 -21
  411. package/runtime/node_modules/@metro-labs/mcp/src/mcp/permission-relay.ts +0 -66
  412. package/runtime/node_modules/@metro-labs/mcp/src/mcp/request-identity.ts +0 -73
  413. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-registry.ts +0 -172
  414. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-route.ts +0 -43
  415. package/runtime/node_modules/@metro-labs/mcp/src/monitor/api.ts +0 -240
  416. package/runtime/node_modules/@metro-labs/mcp/src/server.ts +0 -2
  417. package/runtime/node_modules/@metro-labs/telegram-user/src/accounts.ts +0 -81
  418. package/runtime/node_modules/@metro-labs/telegram-user/src/actions.ts +0 -254
  419. package/runtime/node_modules/@metro-labs/telegram-user/src/attachments.ts +0 -87
  420. package/runtime/node_modules/@metro-labs/telegram-user/src/format.ts +0 -141
  421. package/runtime/node_modules/@metro-labs/telegram-user/src/inbound.ts +0 -78
  422. package/runtime/node_modules/@metro-labs/telegram-user/src/index.ts +0 -46
  423. package/runtime/node_modules/@metro-labs/telegram-user/src/media-actions.ts +0 -80
  424. package/runtime/node_modules/@metro-labs/telegram-user/src/members.ts +0 -75
  425. package/runtime/node_modules/@metro-labs/telegram-user/src/station.ts +0 -24
  426. package/runtime/node_modules/@metro-labs/telegram-user/src/types.ts +0 -7
  427. package/runtime/node_modules/@metro-labs/telegram-user/src/wire.ts +0 -1
  428. package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +0 -87
  429. package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +0 -55
  430. package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +0 -349
  431. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/log.ts +0 -0
  432. /package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/attachments.ts +0 -0
  433. /package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/messaging-normalize.ts +0 -0
  434. /package/runtime/node_modules/@metro-labs/{mcp/src/mcp → core/src}/str.ts +0 -0
  435. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/train-error.ts +0 -0
  436. /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/webhook-note.ts +0 -0
  437. /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/raw-get-stream.ts +0 -0
  438. /package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/api-base.ts +0 -0
  439. /package/runtime/node_modules/@metro-labs/{discord → discord-bot}/src/verify.ts +0 -0
  440. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/api-error.ts +0 -0
  441. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/cors.ts +0 -0
  442. /package/runtime/node_modules/@metro-labs/{telegram → telegram-bot}/src/verify.ts +0 -0
package/dist/serve.js ADDED
@@ -0,0 +1,158 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { agentsDir } from './local.js';
5
+ import { currentVersion } from './version.js';
6
+ import { serveLockedBy, serveStateDir } from './control.js';
7
+ import { findBun, localPort, spawnPlan } from './runtime.js';
8
+ import { prepareRuntime } from './runtime-install.js';
9
+ import { ensureNodeName } from './node-name.js';
10
+ import { holdUntilStart } from './hold.js';
11
+ const SCRUBBED = new Set(['DATABASE_URL']);
12
+ const PORT_FLAG = /^--port=(.*)$/;
13
+ const OWNER_FLAG = /^--owner=(.*)$/;
14
+ const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
15
+ const USAGE = 'usage: metro serve [--port <n>] [--owner <organization id>]';
16
+ const TUNNEL_FLAG = /^--(no-)?tunnel(=.*)?$/;
17
+ const TAILSCALE_APP = '/Applications/Tailscale.app/Contents/MacOS/Tailscale';
18
+ function portOf(raw) {
19
+ const n = Number(raw);
20
+ if (raw === undefined || raw === '' || !Number.isInteger(n) || n < 1 || n > 65535)
21
+ throw new Error(`'${raw ?? ''}' is not a port — ${USAGE}`);
22
+ return n;
23
+ }
24
+ const ORGANIZATION = /^org_[A-Za-z0-9]{10,64}$/;
25
+ function ownerOf(raw) {
26
+ if (raw !== undefined && ORGANIZATION.test(raw))
27
+ return { owner: raw };
28
+ if (raw !== undefined && ADDRESS.test(raw))
29
+ return { owner: null, ignoredOwner: raw };
30
+ throw new Error(`'${raw ?? ''}' is not an organization id (org_…) — ${USAGE}`);
31
+ }
32
+ export function parseServeArgs(argv) {
33
+ let port = localPort();
34
+ let owner = { owner: null };
35
+ for (let i = 0; i < argv.length; i += 1) {
36
+ const arg = argv[i] ?? '';
37
+ if (TUNNEL_FLAG.test(arg))
38
+ throw new Error('--tunnel is gone: metro serve always publishes through Tailscale Funnel — ' + USAGE);
39
+ const inlineOwner = OWNER_FLAG.exec(arg);
40
+ if (inlineOwner) {
41
+ owner = ownerOf(inlineOwner[1]);
42
+ continue;
43
+ }
44
+ if (arg === '--owner') {
45
+ owner = ownerOf(argv[i + 1]);
46
+ i += 1;
47
+ continue;
48
+ }
49
+ const inline = PORT_FLAG.exec(arg);
50
+ if (inline) {
51
+ port = portOf(inline[1]);
52
+ continue;
53
+ }
54
+ if (arg === '--port' || arg === '-p') {
55
+ port = portOf(argv[i + 1]);
56
+ i += 1;
57
+ continue;
58
+ }
59
+ throw new Error(`unknown argument '${arg}' — ${USAGE}`);
60
+ }
61
+ return { port, ...owner };
62
+ }
63
+ export function requireOwner(args, dir = agentsDir()) {
64
+ if (args.ignoredOwner !== undefined) {
65
+ process.stderr.write(`--owner ${args.ignoredOwner} is a wallet address, which metro ignores: the organization id in ${join(dir, '.owner')} decides who signs in\n`);
66
+ return;
67
+ }
68
+ if (args.owner !== null || existsSync(join(dir, '.owner')))
69
+ return;
70
+ throw new Error('no owner is set for this machine, so nobody could sign in.\n' +
71
+ 'Pass the organization that owns it once; it is remembered in ' +
72
+ join(dir, '.owner') +
73
+ ':\n metro serve --owner <org_…>');
74
+ }
75
+ export function readOwner(dir = agentsDir()) {
76
+ try {
77
+ const raw = readFileSync(join(dir, '.owner'), 'utf8').trim();
78
+ return ORGANIZATION.test(raw) ? raw : null;
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ }
84
+ export function holdInfo(port, owner, tailscaleBin) {
85
+ return {
86
+ port,
87
+ host: process.env.METRO_HTTP_HOST ?? '127.0.0.1',
88
+ owner: owner ?? readOwner(),
89
+ version: currentVersion(),
90
+ funnel: tailscaleBin,
91
+ lockFile: join(process.env.METRO_STATE_DIR ?? serveStateDir(), '.tail-lock'),
92
+ };
93
+ }
94
+ function tailscaleStatus(bin) {
95
+ const run = spawnSync(bin, ['status', '--json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
96
+ if (run.error !== undefined || run.status !== 0)
97
+ return { ok: false, state: 'not running' };
98
+ try {
99
+ const parsed = JSON.parse(run.stdout);
100
+ if (parsed.BackendState !== 'Running')
101
+ return { ok: false, state: String(parsed.BackendState) };
102
+ if (parsed.Self?.Online === false)
103
+ return { ok: false, state: 'Running, but not connected to the tailnet: the machine may have been removed from it' };
104
+ return { ok: true };
105
+ }
106
+ catch {
107
+ return { ok: false, state: 'unreadable' };
108
+ }
109
+ }
110
+ export function findTailscale(candidates = ['tailscale', TAILSCALE_APP]) {
111
+ const bin = candidates.find((c) => spawnSync(c, ['version'], { stdio: 'ignore' }).status === 0);
112
+ if (bin === undefined)
113
+ throw new Error('metro serve needs Tailscale on this machine: the daemon is published through Tailscale Funnel.\n' +
114
+ 'macOS: brew install --cask tailscale (or the App Store app)\n' +
115
+ 'Linux: curl -fsSL https://tailscale.com/install.sh | sh\n' +
116
+ 'Then sign the machine in: tailscale up');
117
+ const status = tailscaleStatus(bin);
118
+ if (!status.ok)
119
+ throw new Error(`Tailscale is installed but this machine is not connected (${status.state}). Sign it in first: tailscale up\n` +
120
+ 'Funnel also has to be enabled once on your tailnet: https://tailscale.com/kb/1223/funnel');
121
+ return bin;
122
+ }
123
+ export function servePlan(opts) {
124
+ const env = Object.fromEntries(Object.entries(process.env).filter(([key]) => !SCRUBBED.has(key)));
125
+ return {
126
+ command: findBun(),
127
+ args: [opts.runtime.entry],
128
+ cwd: opts.runtime.dir,
129
+ env: {
130
+ ...env,
131
+ METRO_VERSION: currentVersion(),
132
+ METRO_CLI_BIN: process.argv[1] ?? '',
133
+ METRO_WEBHOOK_PORT: String(opts.port),
134
+ METRO_HTTP_HOST: process.env.METRO_HTTP_HOST ?? '127.0.0.1',
135
+ METRO_TRAINS_DIR: opts.runtime.trains,
136
+ ...(opts.runtime.manifest === null
137
+ ? {}
138
+ : { METRO_RUNTIME_STORE: opts.runtime.dir, METRO_RUNTIME_MANIFEST: opts.runtime.manifest }),
139
+ METRO_STATE_DIR: process.env.METRO_STATE_DIR ?? serveStateDir(),
140
+ METRO_TUNNEL: 'tailscale',
141
+ METRO_TAILSCALE_BIN: opts.tailscaleBin,
142
+ ...(opts.owner === null ? {} : { METRO_OWNER: opts.owner }),
143
+ },
144
+ };
145
+ }
146
+ export function serve(argv) {
147
+ const args = parseServeArgs(argv);
148
+ const { port, owner } = args;
149
+ const running = serveLockedBy();
150
+ if (running !== null)
151
+ throw new Error(`a metro serve daemon is already running on this machine (pid ${String(running)}). ` +
152
+ 'Stop it first: metro stop');
153
+ requireOwner(args);
154
+ const tailscaleBin = findTailscale();
155
+ const node = ensureNodeName(tailscaleBin);
156
+ process.stderr.write(`Starting a metro daemon of your own on http://127.0.0.1:${String(port)}, published as ${node} on your tailnet\n`);
157
+ return spawnPlan(() => servePlan({ runtime: prepareRuntime(), port, owner, tailscaleBin }), () => holdUntilStart(holdInfo(port, owner, tailscaleBin)));
158
+ }
@@ -0,0 +1,243 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { homedir, platform, userInfo } from 'node:os';
4
+ import { dirname, join, resolve } from 'node:path';
5
+ import { serveLockedBy } from './control.js';
6
+ import { findBun } from './runtime.js';
7
+ import { findTailscale, parseServeArgs, requireOwner } from './serve.js';
8
+ const USAGE = 'usage: metro service install [--port <n>] [--owner <organization id>] | uninstall | status';
9
+ const SERVICE = 'metro';
10
+ const LABEL = 'box.metro.serve';
11
+ const CARRIED = /^(METRO_.*|XDG_CACHE_HOME|PATH|HOME)$/;
12
+ const PLAIN_WORD = /^[A-Za-z0-9_/.:=+@,-]+$/;
13
+ const carriedEnv = (env) => Object.entries(env)
14
+ .filter((entry) => CARRIED.test(entry[0]) && typeof entry[1] === 'string' && entry[1] !== '')
15
+ .sort(([a], [b]) => a.localeCompare(b));
16
+ const cacheDir = (host) => {
17
+ const xdg = host.env.XDG_CACHE_HOME?.trim();
18
+ return xdg === undefined || xdg === '' ? join(host.home, '.cache') : xdg;
19
+ };
20
+ function unitWord(arg) {
21
+ const escaped = arg.replaceAll('%', '%%');
22
+ if (PLAIN_WORD.test(arg))
23
+ return escaped;
24
+ return `"${escaped.replaceAll('\\', '\\\\').replaceAll('"', '\\"')}"`;
25
+ }
26
+ export function systemdUnit(host, exec, target) {
27
+ const env = carriedEnv(host.env).map(([key, value]) => `Environment=${unitWord(`${key}=${value}`)}`);
28
+ return [
29
+ '[Unit]',
30
+ 'Description=Metro daemon (metro serve)',
31
+ 'After=network-online.target tailscaled.service',
32
+ 'Wants=network-online.target',
33
+ '',
34
+ '[Service]',
35
+ `ExecStart=${exec.map(unitWord).join(' ')}`,
36
+ 'Restart=always',
37
+ 'RestartSec=2',
38
+ 'OOMPolicy=continue',
39
+ `WorkingDirectory=${unitWord(host.home)}`,
40
+ ...env,
41
+ '',
42
+ '[Install]',
43
+ `WantedBy=${target}`,
44
+ '',
45
+ ].join('\n');
46
+ }
47
+ const xml = (text) => text
48
+ .replaceAll('&', '&amp;')
49
+ .replaceAll('<', '&lt;')
50
+ .replaceAll('>', '&gt;')
51
+ .replaceAll('"', '&quot;')
52
+ .replaceAll("'", '&apos;');
53
+ export function launchdPlist(host, exec, logFile) {
54
+ const env = carriedEnv(host.env).map(([key, value]) => ` <key>${xml(key)}</key><string>${xml(value)}</string>`);
55
+ return [
56
+ '<?xml version="1.0" encoding="UTF-8"?>',
57
+ '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
58
+ '<plist version="1.0">',
59
+ '<dict>',
60
+ ` <key>Label</key><string>${LABEL}</string>`,
61
+ ' <key>ProgramArguments</key>',
62
+ ' <array>',
63
+ ...exec.map((arg) => ` <string>${xml(arg)}</string>`),
64
+ ' </array>',
65
+ ' <key>EnvironmentVariables</key>',
66
+ ' <dict>',
67
+ ...env,
68
+ ' </dict>',
69
+ ` <key>WorkingDirectory</key><string>${xml(host.home)}</string>`,
70
+ ' <key>RunAtLoad</key><true/>',
71
+ ' <key>KeepAlive</key><true/>',
72
+ ` <key>StandardOutPath</key><string>${xml(logFile)}</string>`,
73
+ ` <key>StandardErrorPath</key><string>${xml(logFile)}</string>`,
74
+ '</dict>',
75
+ '</plist>',
76
+ '',
77
+ ].join('\n');
78
+ }
79
+ function systemdPlan(host, exec) {
80
+ const system = host.uid === 0;
81
+ const ctl = system ? ['systemctl'] : ['systemctl', '--user'];
82
+ const file = system
83
+ ? `/etc/systemd/system/${SERVICE}.service`
84
+ : join(host.home, '.config', 'systemd', 'user', `${SERVICE}.service`);
85
+ return {
86
+ kind: 'systemd',
87
+ file,
88
+ content: systemdUnit(host, exec, system ? 'multi-user.target' : 'default.target'),
89
+ dirs: [],
90
+ install: [{ args: [...ctl, 'daemon-reload'] }, { args: [...ctl, 'enable', '--now', SERVICE] }],
91
+ uninstall: [{ args: [...ctl, 'disable', '--now', SERVICE], mayFail: true }],
92
+ reload: [{ args: [...ctl, 'daemon-reload'], mayFail: true }],
93
+ status: { args: [...ctl, 'is-active', SERVICE], mayFail: true },
94
+ hints: [
95
+ `Logs: journalctl ${system ? '' : '--user '}-u ${SERVICE} -f`,
96
+ ...(system
97
+ ? []
98
+ : [`A user service stops with your login session; keep it up without one: loginctl enable-linger ${host.user}`]),
99
+ ],
100
+ };
101
+ }
102
+ function launchdPlan(host, exec) {
103
+ const file = join(host.home, 'Library', 'LaunchAgents', `${LABEL}.plist`);
104
+ const domain = `gui/${String(host.uid)}`;
105
+ const logFile = join(cacheDir(host), 'metro', 'serve', 'service.log');
106
+ return {
107
+ kind: 'launchd',
108
+ file,
109
+ content: launchdPlist(host, exec, logFile),
110
+ dirs: [dirname(logFile)],
111
+ install: [
112
+ { args: ['launchctl', 'bootout', `${domain}/${LABEL}`], mayFail: true },
113
+ { args: ['launchctl', 'bootstrap', domain, file] },
114
+ ],
115
+ uninstall: [{ args: ['launchctl', 'bootout', `${domain}/${LABEL}`], mayFail: true }],
116
+ reload: [],
117
+ status: { args: ['launchctl', 'print', `${domain}/${LABEL}`], mayFail: true },
118
+ hints: [`Logs: tail -f ${logFile}`],
119
+ };
120
+ }
121
+ export function servicePlan(host, serveArgs) {
122
+ const exec = [host.node, host.cli, 'serve', ...serveArgs];
123
+ if (host.platform === 'linux')
124
+ return systemdPlan(host, exec);
125
+ if (host.platform === 'darwin')
126
+ return launchdPlan(host, exec);
127
+ throw new Error(`metro service supports Linux (systemd) and macOS (launchd), not ${host.platform}`);
128
+ }
129
+ function install(serveArgs, deps) {
130
+ const args = parseServeArgs(serveArgs);
131
+ const plan = servicePlan(deps.host, serveArgs);
132
+ if (deps.exists(plan.file)) {
133
+ deps.out(`metro is already installed as a ${plan.kind} service (${plan.file}) and restarts on its own; metro service status says whether it is running. To change its arguments: metro service uninstall, then install again`);
134
+ return 0;
135
+ }
136
+ deps.preflight(args);
137
+ const pid = deps.running();
138
+ if (pid !== null)
139
+ throw new Error(`a metro serve is running on this machine (pid ${String(pid)}). Stop it first (metro stop), then install: the service takes over from there`);
140
+ for (const dir of plan.dirs)
141
+ deps.mkdir(dir);
142
+ deps.write(plan.file, plan.content);
143
+ for (const command of plan.install)
144
+ deps.run(command);
145
+ deps.out(`Installed ${plan.file}: metro serve now starts at boot and after a crash, and the Server page on metro.box can stop, start and restart it.`);
146
+ for (const hint of plan.hints)
147
+ deps.out(hint);
148
+ return 0;
149
+ }
150
+ function uninstall(deps) {
151
+ const plan = servicePlan(deps.host, []);
152
+ if (!deps.exists(plan.file)) {
153
+ deps.out('metro is not installed as a service on this machine');
154
+ return 1;
155
+ }
156
+ for (const command of plan.uninstall)
157
+ deps.run(command);
158
+ deps.remove(plan.file);
159
+ for (const command of plan.reload)
160
+ deps.run(command);
161
+ deps.out(`Removed ${plan.file}; a running daemon was stopped, and metro serve no longer starts on its own`);
162
+ return 0;
163
+ }
164
+ function status(deps) {
165
+ const plan = servicePlan(deps.host, []);
166
+ if (!deps.exists(plan.file)) {
167
+ deps.out(`not installed (metro service install writes ${plan.file})`);
168
+ return 1;
169
+ }
170
+ const active = deps.run(plan.status).status === 0;
171
+ deps.out(active
172
+ ? `running as a ${plan.kind} service (${plan.file})`
173
+ : `installed as a ${plan.kind} service (${plan.file}), not running`);
174
+ return active ? 0 : 1;
175
+ }
176
+ function realHost() {
177
+ const who = userInfo();
178
+ return {
179
+ platform: platform(),
180
+ uid: who.uid,
181
+ user: who.username,
182
+ home: homedir(),
183
+ node: process.execPath,
184
+ cli: resolve(process.argv[1] ?? ''),
185
+ env: process.env,
186
+ };
187
+ }
188
+ export function serviceStopHint(host = realHost(), exists = existsSync) {
189
+ if (host.platform !== 'linux' && host.platform !== 'darwin')
190
+ return null;
191
+ const plan = servicePlan(host, []);
192
+ if (!exists(plan.file))
193
+ return null;
194
+ const keep = plan.kind === 'systemd'
195
+ ? `systemctl ${host.uid === 0 ? '' : '--user '}stop ${SERVICE}`
196
+ : `launchctl bootout gui/${String(host.uid)}/${LABEL}`;
197
+ return `metro runs as a ${plan.kind} service here (${plan.file}), so it starts again on its own in a moment. To keep it stopped: ${keep}`;
198
+ }
199
+ function realDeps() {
200
+ return {
201
+ host: realHost(),
202
+ run: (command) => {
203
+ const [bin = '', ...args] = command.args;
204
+ const result = spawnSync(bin, args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
205
+ const code = result.status ?? 1;
206
+ if (code !== 0 && command.mayFail !== true) {
207
+ const said = [result.stderr, result.stdout, result.error?.message].find((t) => typeof t === 'string' && t.trim() !== '') ?? '';
208
+ throw new Error(`${command.args.join(' ')} failed (exit ${String(code)}): ${said.trim()}`);
209
+ }
210
+ return { status: code, output: `${result.stdout}${result.stderr}` };
211
+ },
212
+ running: serveLockedBy,
213
+ preflight: (args) => {
214
+ requireOwner(args);
215
+ findBun();
216
+ findTailscale();
217
+ },
218
+ mkdir: (dir) => {
219
+ mkdirSync(dir, { recursive: true });
220
+ },
221
+ write: (file, content) => {
222
+ mkdirSync(dirname(file), { recursive: true });
223
+ writeFileSync(file, content, { mode: 0o644 });
224
+ },
225
+ remove: (file) => {
226
+ rmSync(file, { force: true });
227
+ },
228
+ exists: existsSync,
229
+ out: (line) => {
230
+ process.stderr.write(`${line}\n`);
231
+ },
232
+ };
233
+ }
234
+ export function service(argv, deps = realDeps()) {
235
+ const [verb, ...rest] = argv;
236
+ if (verb === 'install')
237
+ return Promise.resolve(install(rest, deps));
238
+ if (verb === 'uninstall' && rest.length === 0)
239
+ return Promise.resolve(uninstall(deps));
240
+ if (verb === 'status' && rest.length === 0)
241
+ return Promise.resolve(status(deps));
242
+ throw new Error(USAGE);
243
+ }
package/dist/tail.js ADDED
@@ -0,0 +1,119 @@
1
+ import { localAgent } from './local.js';
2
+ import { assertAgentId, localUrl } from './runtime.js';
3
+ const BACKOFF_MS = [1_000, 2_000, 5_000];
4
+ const STALL_MS = 90_000;
5
+ export const backoffAt = (attempt) => BACKOFF_MS[Math.min(attempt, BACKOFF_MS.length - 1)] ?? 5_000;
6
+ export function sseDataLines(buffer, chunk) {
7
+ const lines = (buffer + chunk).split('\n');
8
+ const rest = lines.pop() ?? '';
9
+ const events = [];
10
+ for (const raw of lines) {
11
+ const line = raw.endsWith('\r') ? raw.slice(0, -1) : raw;
12
+ if (!line.startsWith('data:'))
13
+ continue;
14
+ const value = line.slice(5);
15
+ events.push(value.startsWith(' ') ? value.slice(1) : value);
16
+ }
17
+ return { rest, events };
18
+ }
19
+ function keySource(agentId) {
20
+ const fromEnv = process.env.METRO_AGENT_KEY?.trim();
21
+ if (fromEnv !== undefined && fromEnv !== '')
22
+ return { resolve: () => Promise.resolve(fromEnv), fixed: true };
23
+ return {
24
+ resolve: () => {
25
+ const agent = localAgent();
26
+ if (agent === null || (agentId !== undefined && agent.id !== agentId))
27
+ throw new Error(`no agent ${agentId === undefined ? '' : `${agentId} `}on this machine — start metro serve, or set METRO_AGENT_KEY`);
28
+ return Promise.resolve(agent.key);
29
+ },
30
+ fixed: false,
31
+ };
32
+ }
33
+ const armStall = (control) => setTimeout(() => {
34
+ control.abort();
35
+ }, STALL_MS);
36
+ async function connect(key, signal) {
37
+ try {
38
+ return await fetch(`${localUrl()}/api/tail`, {
39
+ headers: { authorization: `Bearer ${key}` },
40
+ signal,
41
+ });
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ async function pump(body, control, stall) {
48
+ const reader = body.getReader();
49
+ const decoder = new TextDecoder();
50
+ let buffer = '';
51
+ try {
52
+ for (;;) {
53
+ const { done, value } = await reader.read();
54
+ if (done)
55
+ return 'ended';
56
+ clearTimeout(stall.timer);
57
+ stall.timer = armStall(control);
58
+ const out = sseDataLines(buffer, decoder.decode(value, { stream: true }));
59
+ buffer = out.rest;
60
+ for (const event of out.events)
61
+ process.stdout.write(`${event}\n`);
62
+ }
63
+ }
64
+ catch {
65
+ return 'ended';
66
+ }
67
+ }
68
+ async function streamOnce(key) {
69
+ const control = new AbortController();
70
+ const stall = { timer: armStall(control) };
71
+ try {
72
+ const res = await connect(key, control.signal);
73
+ if (res === null)
74
+ return 'unreachable';
75
+ if (res.status === 401)
76
+ return 'unauthorized';
77
+ if (!res.ok || res.body === null)
78
+ return 'unreachable';
79
+ return await pump(res.body, control, stall);
80
+ }
81
+ finally {
82
+ clearTimeout(stall.timer);
83
+ }
84
+ }
85
+ function note(state, message) {
86
+ if (state.last === message)
87
+ return;
88
+ state.last = message;
89
+ process.stderr.write(`metro: ${message}\n`);
90
+ }
91
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
92
+ async function settle(end, source, key, state) {
93
+ if (end === 'unauthorized') {
94
+ if (source.fixed)
95
+ throw new Error('the key in METRO_AGENT_KEY was refused by the local daemon');
96
+ note(state, 'key refused — fetching the current one');
97
+ return source.resolve();
98
+ }
99
+ if (end === 'unreachable')
100
+ note(state, `no metro daemon on ${localUrl()} — run 'metro serve'`);
101
+ else
102
+ note(state, 'stream ended — reconnecting');
103
+ return key;
104
+ }
105
+ export async function tailEvents(argv) {
106
+ const agentId = argv[0] === undefined ? undefined : assertAgentId(argv[0]);
107
+ const source = keySource(agentId);
108
+ let key = await source.resolve();
109
+ const state = { last: '' };
110
+ let attempt = 0;
111
+ for (;;) {
112
+ const end = await streamOnce(key);
113
+ if (end === 'ended')
114
+ attempt = 0;
115
+ key = await settle(end, source, key, state);
116
+ await delay(backoffAt(attempt));
117
+ attempt += 1;
118
+ }
119
+ }
package/dist/update.js CHANGED
@@ -9,7 +9,19 @@ export function installArgs(manager, version) {
9
9
  ? ['add', '--global', spec]
10
10
  : ['install', '--global', spec];
11
11
  }
12
- export async function update() {
12
+ export const checkReport = (current, latest) => ({
13
+ current,
14
+ latest,
15
+ newer: latest !== '' && isNewer(latest, current),
16
+ });
17
+ export async function updateCheck() {
18
+ return checkReport(currentVersion(), await publishedVersion());
19
+ }
20
+ export async function update(argv = []) {
21
+ if (argv.includes('--check')) {
22
+ process.stdout.write(`${JSON.stringify(await updateCheck())}\n`);
23
+ return 0;
24
+ }
13
25
  const current = currentVersion();
14
26
  const newest = await publishedVersion();
15
27
  if (newest === '') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stage-labs/metro",
3
- "version": "0.1.0-beta.20",
3
+ "version": "0.1.0-beta.201",
4
4
  "description": "The metro command line. Sign in once per machine, then hand your MCP connector list to Claude Code without the credentials touching disk, argv or shell history.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -35,26 +35,5 @@
35
35
  "knip": "^6.15.0",
36
36
  "madge": "^8.0.0",
37
37
  "typescript": "^5"
38
- },
39
- "dependencies": {
40
- "@discordjs/voice": "^0.19.2",
41
- "@modelcontextprotocol/sdk": "^1.12.0",
42
- "@mtcute/bun": "0.30.1",
43
- "@xmtp/content-type-primitives": "^3.0.1",
44
- "@xmtp/content-type-reaction": "^2.0.2",
45
- "@xmtp/content-type-remote-attachment": "^2.0.4",
46
- "@xmtp/content-type-reply": "^2.0.3",
47
- "@xmtp/content-type-wallet-send-calls": "^2.0.0",
48
- "@xmtp/node-bindings": "1.9.1",
49
- "@xmtp/node-sdk": "^6.0.0",
50
- "baileys": "7.0.0-rc14",
51
- "discord.js": "^14.26.4",
52
- "drizzle-orm": "^0.44.0",
53
- "pino": "^9.5.0",
54
- "pino-pretty": "^13.1.3",
55
- "postgres": "^3.4.5",
56
- "prism-media": "^1.3.5",
57
- "viem": "^2.52.2",
58
- "zod": "^3.23.8"
59
38
  }
60
39
  }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "metro",
3
+ "description": "Metro — connector relay and chat bridge for agents",
4
+ "owner": { "name": "Bonustrack", "url": "https://metro.box" },
5
+ "plugins": [
6
+ {
7
+ "name": "metro",
8
+ "source": "./plugin",
9
+ "description": "Every connector on this box as its own MCP server through metro's local relay, the orchestrator guard, and the standing rules loaded at session start."
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "metro",
3
+ "version": "0.1.0-beta.201",
4
+ "description": "Metro for Claude Code, installed by the metro daemon on this machine: every connector the agent holds as its own MCP server relayed through the daemon, the orchestrator-only guard on the main thread, and the standing rules loaded at each session start. No vendor credential ever sits in a config file.",
5
+ "author": {
6
+ "name": "Bonustrack",
7
+ "url": "https://metro.box"
8
+ },
9
+ "repository": "https://github.com/bonustrack/metro",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "metro",
13
+ "mcp",
14
+ "connectors",
15
+ "relay"
16
+ ]
17
+ }
@@ -0,0 +1 @@
1
+ {}