@stage-labs/metro 0.1.0-beta.8 → 0.1.0-beta.80

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 (282) hide show
  1. package/dist/api.js +14 -0
  2. package/dist/claude-settings.js +40 -0
  3. package/dist/claude.js +107 -0
  4. package/dist/cli.js +101 -0
  5. package/dist/control.js +74 -0
  6. package/dist/hold.js +211 -0
  7. package/dist/local.js +93 -0
  8. package/dist/node-name.js +71 -0
  9. package/dist/plugin.js +80 -0
  10. package/dist/provider-flags.js +9 -0
  11. package/dist/runtime-install.js +87 -0
  12. package/dist/runtime.js +74 -0
  13. package/dist/serve.js +146 -0
  14. package/dist/service.js +242 -0
  15. package/dist/tail.js +119 -0
  16. package/dist/update.js +45 -0
  17. package/dist/version.js +97 -0
  18. package/package.json +14 -25
  19. package/runtime/node_modules/@metro-labs/core/package.json +43 -0
  20. package/runtime/node_modules/@metro-labs/core/src/address.ts +6 -0
  21. package/runtime/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  22. package/runtime/node_modules/@metro-labs/core/src/events.ts +120 -0
  23. package/runtime/node_modules/@metro-labs/core/src/identity.ts +7 -0
  24. package/runtime/node_modules/@metro-labs/core/src/ids.ts +21 -0
  25. package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  26. package/runtime/node_modules/@metro-labs/core/src/lines.ts +82 -0
  27. package/runtime/node_modules/@metro-labs/core/src/log.ts +42 -0
  28. package/runtime/node_modules/@metro-labs/core/src/protocol.ts +226 -0
  29. package/runtime/node_modules/@metro-labs/core/src/secure-fs.ts +57 -0
  30. package/runtime/node_modules/@metro-labs/core/src/station-names.ts +12 -0
  31. package/runtime/node_modules/@metro-labs/core/src/stations/account-store.ts +60 -0
  32. package/runtime/node_modules/@metro-labs/core/src/stations/attachments.ts +196 -0
  33. package/runtime/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +88 -0
  34. package/runtime/node_modules/@metro-labs/core/src/stations/station-runtime.ts +64 -0
  35. package/runtime/node_modules/@metro-labs/core/src/stations/types.ts +107 -0
  36. package/runtime/node_modules/@metro-labs/core/src/str.ts +5 -0
  37. package/runtime/node_modules/@metro-labs/core/src/train-error.ts +53 -0
  38. package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
  39. package/runtime/node_modules/@metro-labs/daemon/package.json +47 -0
  40. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
  41. package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +311 -0
  42. package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +43 -0
  43. package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +302 -0
  44. package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +111 -0
  45. package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +329 -0
  46. package/runtime/node_modules/@metro-labs/daemon/src/agents/files.ts +155 -0
  47. package/runtime/node_modules/@metro-labs/daemon/src/agents/keys.ts +45 -0
  48. package/runtime/node_modules/@metro-labs/daemon/src/agents/map.ts +84 -0
  49. package/runtime/node_modules/@metro-labs/daemon/src/agents/scope.ts +64 -0
  50. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +176 -0
  51. package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +39 -0
  52. package/runtime/node_modules/@metro-labs/daemon/src/boot/crash-guard.ts +49 -0
  53. package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +14 -0
  54. package/runtime/node_modules/@metro-labs/daemon/src/boot/paths.ts +106 -0
  55. package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +25 -0
  56. package/runtime/node_modules/@metro-labs/daemon/src/channels/dedupe.ts +24 -0
  57. package/runtime/node_modules/@metro-labs/daemon/src/channels/inbound.ts +377 -0
  58. package/runtime/node_modules/@metro-labs/daemon/src/channels/media-note.ts +85 -0
  59. package/runtime/node_modules/@metro-labs/daemon/src/channels/pending.ts +75 -0
  60. package/runtime/node_modules/@metro-labs/daemon/src/channels/relay.ts +129 -0
  61. package/runtime/node_modules/@metro-labs/daemon/src/channels/webhook-note.ts +51 -0
  62. package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +148 -0
  63. package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +329 -0
  64. package/runtime/node_modules/@metro-labs/daemon/src/claude/login.ts +167 -0
  65. package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +117 -0
  66. package/runtime/node_modules/@metro-labs/daemon/src/connectors/api.ts +307 -0
  67. package/runtime/node_modules/@metro-labs/daemon/src/connectors/cli-api.ts +63 -0
  68. package/runtime/node_modules/@metro-labs/daemon/src/connectors/config.ts +144 -0
  69. package/runtime/node_modules/@metro-labs/daemon/src/connectors/json.ts +21 -0
  70. package/runtime/node_modules/@metro-labs/daemon/src/connectors/model.ts +69 -0
  71. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-client.ts +159 -0
  72. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-discovery.ts +117 -0
  73. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-pending.ts +65 -0
  74. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth-routes.ts +157 -0
  75. package/runtime/node_modules/@metro-labs/daemon/src/connectors/oauth.ts +127 -0
  76. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-target.ts +39 -0
  77. package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay.ts +295 -0
  78. package/runtime/node_modules/@metro-labs/daemon/src/connectors/store.ts +277 -0
  79. package/runtime/node_modules/@metro-labs/daemon/src/connectors/tools.ts +98 -0
  80. package/runtime/node_modules/@metro-labs/daemon/src/connectors/url.ts +70 -0
  81. package/runtime/node_modules/@metro-labs/daemon/src/connectors/verify.ts +330 -0
  82. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-grant.ts +99 -0
  83. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-owner.ts +32 -0
  84. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-serve.ts +121 -0
  85. package/runtime/node_modules/@metro-labs/daemon/src/files/upload-api.ts +294 -0
  86. package/runtime/node_modules/@metro-labs/daemon/src/files/upload-store.ts +181 -0
  87. package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +252 -0
  88. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-auth.ts +231 -0
  89. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +91 -0
  90. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +288 -0
  91. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +203 -0
  92. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +220 -0
  93. package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
  94. package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +182 -0
  95. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +197 -0
  96. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +195 -0
  97. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +198 -0
  98. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +40 -0
  99. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +17 -0
  100. package/runtime/node_modules/@metro-labs/daemon/src/mcp/accounts.ts +137 -0
  101. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-tools.ts +216 -0
  102. package/runtime/node_modules/@metro-labs/daemon/src/mcp/channel-owner.ts +29 -0
  103. package/runtime/node_modules/@metro-labs/daemon/src/mcp/ctx.ts +62 -0
  104. package/runtime/node_modules/@metro-labs/daemon/src/mcp/event-store.ts +91 -0
  105. package/runtime/node_modules/@metro-labs/daemon/src/mcp/frame-scope.ts +21 -0
  106. package/runtime/node_modules/@metro-labs/daemon/src/mcp/group-tools.ts +129 -0
  107. package/runtime/node_modules/@metro-labs/daemon/src/mcp/index.ts +191 -0
  108. package/runtime/node_modules/@metro-labs/daemon/src/mcp/member-tools.ts +72 -0
  109. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +66 -0
  110. package/runtime/node_modules/@metro-labs/daemon/src/mcp/raw-get-stream.ts +207 -0
  111. package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +47 -0
  112. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-registry.ts +172 -0
  113. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-route.ts +43 -0
  114. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session.ts +215 -0
  115. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-dispatch.ts +215 -0
  116. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-schemas.ts +400 -0
  117. package/runtime/node_modules/@metro-labs/daemon/src/mcp/upload-tool.ts +66 -0
  118. package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +237 -0
  119. package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +389 -0
  120. package/runtime/node_modules/@metro-labs/daemon/src/routes/http.ts +390 -0
  121. package/runtime/node_modules/@metro-labs/daemon/src/routes/identity.ts +54 -0
  122. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +187 -0
  123. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +60 -0
  124. package/runtime/node_modules/@metro-labs/daemon/src/routes/session.ts +29 -0
  125. package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +64 -0
  126. package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +61 -0
  127. package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +116 -0
  128. package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
  129. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-inline.ts +100 -0
  130. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-interactive.ts +161 -0
  131. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-resolve.ts +202 -0
  132. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-session.ts +280 -0
  133. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-xmtp.ts +111 -0
  134. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach.ts +184 -0
  135. package/runtime/node_modules/@metro-labs/daemon/src/stations/materialize.ts +248 -0
  136. package/runtime/node_modules/@metro-labs/daemon/src/stations/registry.ts +35 -0
  137. package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +82 -0
  138. package/runtime/node_modules/@metro-labs/daemon/src/stations/supervisor-io.ts +97 -0
  139. package/runtime/node_modules/@metro-labs/daemon/src/stations/supervisor.ts +320 -0
  140. package/runtime/node_modules/@metro-labs/daemon/src/stations/train-call.ts +22 -0
  141. package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +71 -0
  142. package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +123 -0
  143. package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +40 -0
  144. package/runtime/node_modules/@metro-labs/discord-bot/package.json +28 -0
  145. package/runtime/node_modules/@metro-labs/discord-bot/src/accounts.ts +118 -0
  146. package/runtime/node_modules/@metro-labs/discord-bot/src/actions.ts +388 -0
  147. package/runtime/node_modules/@metro-labs/discord-bot/src/api-base.ts +1 -0
  148. package/runtime/node_modules/@metro-labs/discord-bot/src/attachments.ts +29 -0
  149. package/runtime/node_modules/@metro-labs/discord-bot/src/format.ts +220 -0
  150. package/runtime/node_modules/@metro-labs/discord-bot/src/group-actions.ts +50 -0
  151. package/runtime/node_modules/@metro-labs/discord-bot/src/group.ts +115 -0
  152. package/runtime/node_modules/@metro-labs/discord-bot/src/index.ts +127 -0
  153. package/runtime/node_modules/@metro-labs/discord-bot/src/members.ts +215 -0
  154. package/runtime/node_modules/@metro-labs/discord-bot/src/send-files.ts +43 -0
  155. package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +19 -0
  156. package/runtime/node_modules/@metro-labs/discord-bot/src/verify.ts +82 -0
  157. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-speak.ts +195 -0
  158. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-transcribe.ts +292 -0
  159. package/runtime/node_modules/@metro-labs/discord-bot/src/voice.ts +197 -0
  160. package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +5 -0
  161. package/runtime/node_modules/@metro-labs/http/package.json +33 -0
  162. package/runtime/node_modules/@metro-labs/http/src/api-error.ts +8 -0
  163. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +95 -0
  164. package/runtime/node_modules/@metro-labs/http/src/cors.ts +29 -0
  165. package/runtime/node_modules/@metro-labs/http/src/identity-key.ts +33 -0
  166. package/runtime/node_modules/@metro-labs/http/src/identity-registry.ts +13 -0
  167. package/runtime/node_modules/@metro-labs/http/src/mode-api.ts +32 -0
  168. package/runtime/node_modules/@metro-labs/http/src/return-to.ts +21 -0
  169. package/runtime/node_modules/@metro-labs/http/src/signed-identity.ts +36 -0
  170. package/runtime/node_modules/@metro-labs/telegram/package.json +26 -0
  171. package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +80 -0
  172. package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +254 -0
  173. package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +87 -0
  174. package/runtime/node_modules/@metro-labs/telegram/src/client.ts +77 -0
  175. package/runtime/node_modules/@metro-labs/telegram/src/format.ts +156 -0
  176. package/runtime/node_modules/@metro-labs/telegram/src/group.ts +261 -0
  177. package/runtime/node_modules/@metro-labs/telegram/src/history.ts +52 -0
  178. package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +78 -0
  179. package/runtime/node_modules/@metro-labs/telegram/src/index.ts +46 -0
  180. package/runtime/node_modules/@metro-labs/telegram/src/login.ts +166 -0
  181. package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +80 -0
  182. package/runtime/node_modules/@metro-labs/telegram/src/members.ts +75 -0
  183. package/runtime/node_modules/@metro-labs/telegram/src/normalize.ts +22 -0
  184. package/runtime/node_modules/@metro-labs/telegram/src/reactions.ts +167 -0
  185. package/runtime/node_modules/@metro-labs/telegram/src/station.ts +24 -0
  186. package/runtime/node_modules/@metro-labs/telegram/src/types.ts +7 -0
  187. package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +1 -0
  188. package/runtime/node_modules/@metro-labs/telegram-bot/package.json +25 -0
  189. package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +120 -0
  190. package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +295 -0
  191. package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +128 -0
  192. package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +201 -0
  193. package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +109 -0
  194. package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +166 -0
  195. package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +47 -0
  196. package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +17 -0
  197. package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +58 -0
  198. package/runtime/node_modules/@metro-labs/telegram-bot/src/verify.ts +38 -0
  199. package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +3 -0
  200. package/runtime/node_modules/@metro-labs/webhook/package.json +23 -0
  201. package/runtime/node_modules/@metro-labs/webhook/src/station.ts +37 -0
  202. package/runtime/node_modules/@metro-labs/whatsapp/package.json +27 -0
  203. package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +66 -0
  204. package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +101 -0
  205. package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +178 -0
  206. package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +72 -0
  207. package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +129 -0
  208. package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +327 -0
  209. package/runtime/node_modules/@metro-labs/whatsapp/src/delivery.ts +49 -0
  210. package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +138 -0
  211. package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +57 -0
  212. package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +40 -0
  213. package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +59 -0
  214. package/runtime/node_modules/@metro-labs/whatsapp/src/logger.ts +60 -0
  215. package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +176 -0
  216. package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +84 -0
  217. package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +22 -0
  218. package/runtime/node_modules/@metro-labs/whatsapp/src/outbox.ts +38 -0
  219. package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +185 -0
  220. package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +17 -0
  221. package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +98 -0
  222. package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +6 -0
  223. package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +5 -0
  224. package/runtime/node_modules/@metro-labs/xmtp/package.json +33 -0
  225. package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +112 -0
  226. package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +110 -0
  227. package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +299 -0
  228. package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +157 -0
  229. package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +87 -0
  230. package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +375 -0
  231. package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +107 -0
  232. package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +171 -0
  233. package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +239 -0
  234. package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +55 -0
  235. package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +335 -0
  236. package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +80 -0
  237. package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +34 -0
  238. package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +56 -0
  239. package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +33 -0
  240. package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +125 -0
  241. package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +157 -0
  242. package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +40 -0
  243. package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +349 -0
  244. package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +13 -0
  245. package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +126 -0
  246. package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +212 -0
  247. package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +90 -0
  248. package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +84 -0
  249. package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +53 -0
  250. package/runtime/runtime.json +3 -0
  251. package/runtime/server.ts +1 -0
  252. package/runtime/stations.json +36 -0
  253. package/runtime/trains/.keep +0 -0
  254. package/LICENSE +0 -21
  255. package/README.md +0 -249
  256. package/dist/cache.js +0 -75
  257. package/dist/cli/actions.js +0 -139
  258. package/dist/cli/config.js +0 -185
  259. package/dist/cli/index.js +0 -177
  260. package/dist/cli/skill.js +0 -62
  261. package/dist/cli/util.js +0 -72
  262. package/dist/cli/webhook.js +0 -83
  263. package/dist/codex-rc.js +0 -245
  264. package/dist/dispatcher.js +0 -122
  265. package/dist/history.js +0 -99
  266. package/dist/ipc.js +0 -72
  267. package/dist/log.js +0 -15
  268. package/dist/paths.js +0 -68
  269. package/dist/registry.js +0 -48
  270. package/dist/stations/claude.js +0 -45
  271. package/dist/stations/codex.js +0 -68
  272. package/dist/stations/discord.js +0 -200
  273. package/dist/stations/index.js +0 -133
  274. package/dist/stations/telegram-md.js +0 -34
  275. package/dist/stations/telegram-upload.js +0 -113
  276. package/dist/stations/telegram.js +0 -213
  277. package/dist/stations/webhook.js +0 -100
  278. package/dist/tunnel.js +0 -49
  279. package/dist/webhooks.js +0 -40
  280. package/docs/agents.md +0 -216
  281. package/docs/uri-scheme.md +0 -125
  282. package/skills/metro/SKILL.md +0 -249
@@ -0,0 +1,71 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { randomBytes } from 'node:crypto';
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { agentsDir } from './local.js';
6
+ const NODE_FILE = '.node';
7
+ const ALPHABET = 'abcdefghjkmnpqrstuvwxyz23456789';
8
+ const NAME_RE = /^metro-[a-z0-9]{6}$/;
9
+ const RENAME_WAIT_MS = 30_000;
10
+ const RENAME_POLL_MS = 500;
11
+ const renameWaitMs = () => Number(process.env.METRO_NODE_RENAME_WAIT_MS) || RENAME_WAIT_MS;
12
+ const pause = (ms) => {
13
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
14
+ };
15
+ const stderrLine = (line) => {
16
+ process.stderr.write(`${line}\n`);
17
+ };
18
+ export function newNodeName() {
19
+ const bytes = randomBytes(6);
20
+ return `metro-${[...bytes].map((b) => ALPHABET[b % ALPHABET.length] ?? 'x').join('')}`;
21
+ }
22
+ export function nodeName(dir = agentsDir()) {
23
+ const path = join(dir, NODE_FILE);
24
+ if (existsSync(path)) {
25
+ const held = readFileSync(path, 'utf8').trim();
26
+ if (NAME_RE.test(held))
27
+ return held;
28
+ }
29
+ const name = newNodeName();
30
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
31
+ writeFileSync(path, `${name}\n`, { mode: 0o600 });
32
+ return name;
33
+ }
34
+ export function currentNodeLabel(bin) {
35
+ const run = spawnSync(bin, ['status', '--json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
36
+ if (run.error !== undefined || run.status !== 0)
37
+ return null;
38
+ try {
39
+ const parsed = JSON.parse(run.stdout);
40
+ const dns = typeof parsed.Self?.DNSName === 'string' ? parsed.Self.DNSName : '';
41
+ const label = dns.split('.')[0] ?? '';
42
+ return label === '' ? null : label.toLowerCase();
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ function awaitRename(bin, wanted, warn) {
49
+ const wait = renameWaitMs();
50
+ const until = Date.now() + wait;
51
+ while (Date.now() < until) {
52
+ if (currentNodeLabel(bin) === wanted)
53
+ return;
54
+ pause(RENAME_POLL_MS);
55
+ }
56
+ warn(`tailscale still reports the old machine name after ${String(Math.round(wait / 1000))}s; the Funnel address may come up under it until the next restart`);
57
+ }
58
+ export function ensureNodeName(bin, dir = agentsDir(), warn = stderrLine) {
59
+ const wanted = nodeName(dir);
60
+ if (currentNodeLabel(bin) === wanted)
61
+ return wanted;
62
+ const run = spawnSync(bin, ['set', '--hostname', wanted], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] });
63
+ if (run.error !== undefined || run.status !== 0) {
64
+ const said = run.stderr.trim();
65
+ const reason = said === '' ? (run.error?.message ?? `exit ${String(run.status)}`) : said;
66
+ throw new Error(`could not name this machine ${wanted} on your tailnet (${reason}).\n` +
67
+ `Run it once yourself, then start again: sudo tailscale set --hostname ${wanted}`);
68
+ }
69
+ awaitRename(bin, wanted, warn);
70
+ return wanted;
71
+ }
package/dist/plugin.js ADDED
@@ -0,0 +1,80 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ const MARKETPLACE_REPO = 'bonustrack/metro';
6
+ const PLUGIN_SPEC = 'metro@metro';
7
+ export function installPathFrom(raw) {
8
+ let parsed;
9
+ try {
10
+ parsed = JSON.parse(raw);
11
+ }
12
+ catch {
13
+ return null;
14
+ }
15
+ if (typeof parsed !== 'object' || parsed === null)
16
+ return null;
17
+ const plugins = parsed.plugins;
18
+ if (typeof plugins !== 'object' || plugins === null)
19
+ return null;
20
+ const entries = plugins[PLUGIN_SPEC];
21
+ if (!Array.isArray(entries))
22
+ return null;
23
+ const first = entries[0];
24
+ return typeof first?.installPath === 'string' ? first.installPath : null;
25
+ }
26
+ export function pluginInstallPath() {
27
+ const registry = join(homedir(), '.claude', 'plugins', 'installed_plugins.json');
28
+ let raw;
29
+ try {
30
+ raw = readFileSync(registry, 'utf8');
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ const path = installPathFrom(raw);
36
+ if (path === null)
37
+ return null;
38
+ return existsSync(join(path, 'bin', 'metro-plugin.mjs')) ? path : null;
39
+ }
40
+ function runClaude(args) {
41
+ const res = spawnSync('claude', args, { encoding: 'utf8' });
42
+ if (res.error !== undefined)
43
+ throw new Error('the `claude` command is not on PATH — install Claude Code first');
44
+ const output = `${res.stdout ?? ''}${res.stderr ?? ''}`;
45
+ return { ok: res.status === 0, output };
46
+ }
47
+ const tolerable = (output) => /already|exists|latest version/i.test(output);
48
+ export function syncPluginServers() {
49
+ const path = pluginInstallPath();
50
+ if (path === null)
51
+ return false;
52
+ const script = join(path, 'bin', 'metro-plugin.mjs');
53
+ const refreshed = spawnSync(process.execPath, [script, 'refresh'], {
54
+ stdio: ['ignore', 'inherit', 'inherit'],
55
+ });
56
+ if (refreshed.status !== 0)
57
+ return false;
58
+ runClaude(['plugin', 'update', PLUGIN_SPEC]);
59
+ return true;
60
+ }
61
+ export async function installPlugin() {
62
+ const added = runClaude(['plugin', 'marketplace', 'add', MARKETPLACE_REPO]);
63
+ if (!added.ok && !tolerable(added.output)) {
64
+ process.stderr.write(added.output);
65
+ return 1;
66
+ }
67
+ const installed = runClaude(['plugin', 'install', PLUGIN_SPEC]);
68
+ if (!installed.ok && !tolerable(installed.output)) {
69
+ process.stderr.write(installed.output);
70
+ return 1;
71
+ }
72
+ process.stderr.write('Claude Code plugin installed.\n');
73
+ if (syncPluginServers()) {
74
+ process.stderr.write('Connector servers loaded — new Claude sessions have them; ' +
75
+ 'run /reload-plugins in any session already open.\n');
76
+ return 0;
77
+ }
78
+ process.stderr.write('Start the daemon on this machine (metro serve), then run /metro:refresh inside Claude Code.\n');
79
+ return Promise.resolve(0);
80
+ }
@@ -0,0 +1,9 @@
1
+ export const PROVIDER_FLAGS = [
2
+ 'CLAUDE_CODE_USE_BEDROCK',
3
+ 'CLAUDE_CODE_USE_MANTLE',
4
+ 'CLAUDE_CODE_USE_VERTEX',
5
+ 'CLAUDE_CODE_USE_FOUNDRY',
6
+ 'CLAUDE_CODE_USE_ANTHROPIC_AWS',
7
+ 'CLAUDE_CODE_USE_ANTHROPIC_GOOGLE_CLOUD',
8
+ 'CLAUDE_CODE_USE_GATEWAY',
9
+ ];
@@ -0,0 +1,87 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { localStations } from './local.js';
6
+ import { STORE_ENTRY, daemonEntry, findBun, runtimeDir } from './runtime.js';
7
+ export const MANIFEST_FILE = 'stations.json';
8
+ const METRO_SOURCES = join('node_modules', '@metro-labs');
9
+ const INSTALL_TIMEOUT_MS = 15 * 60_000;
10
+ export function runtimeStore() {
11
+ const env = process.env.METRO_RUNTIME_STORE?.trim() ?? '';
12
+ return env === '' ? join(homedir(), '.metro', 'runtime') : env;
13
+ }
14
+ const isRecord = (v) => typeof v === 'object' && v !== null;
15
+ const ranges = (raw) => isRecord(raw)
16
+ ? Object.fromEntries(Object.entries(raw).filter((e) => typeof e[1] === 'string'))
17
+ : {};
18
+ export function readManifest(path) {
19
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
20
+ if (!isRecord(raw))
21
+ throw new Error(`${path} is not a runtime manifest`);
22
+ const stations = isRecord(raw.stations) ? raw.stations : {};
23
+ return {
24
+ core: ranges(raw.core),
25
+ stations: Object.fromEntries(Object.entries(stations).map(([name, deps]) => [name, ranges(deps)])),
26
+ };
27
+ }
28
+ export function dependenciesFor(manifest, stations) {
29
+ const out = { ...manifest.core };
30
+ for (const station of new Set(stations))
31
+ Object.assign(out, manifest.stations[station] ?? {});
32
+ return Object.fromEntries(Object.entries(out).sort(([a], [b]) => a.localeCompare(b)));
33
+ }
34
+ const packageText = (deps) => `${JSON.stringify({ name: 'metro-runtime', private: true, dependencies: deps }, null, 2)}\n`;
35
+ function readOrNull(path) {
36
+ try {
37
+ return readFileSync(path, 'utf8');
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ }
43
+ function syncSources(sources, store) {
44
+ const shim = join(sources, STORE_ENTRY);
45
+ if (existsSync(shim))
46
+ copyFileSync(shim, join(store, STORE_ENTRY));
47
+ const stamp = readOrNull(join(sources, 'runtime.json'));
48
+ if (stamp !== null && readOrNull(join(store, 'runtime.json')) === stamp)
49
+ return false;
50
+ rmSync(join(store, METRO_SOURCES), { recursive: true, force: true });
51
+ cpSync(join(sources, METRO_SOURCES), join(store, METRO_SOURCES), { recursive: true });
52
+ if (stamp !== null)
53
+ writeFileSync(join(store, 'runtime.json'), stamp);
54
+ return true;
55
+ }
56
+ export function installDependencies(store, deps, bun, log) {
57
+ const wanted = packageText(deps);
58
+ const marker = join(store, 'node_modules', '.metro-installed');
59
+ if (existsSync(marker) && readOrNull(join(store, 'package.json')) === wanted)
60
+ return false;
61
+ writeFileSync(join(store, 'package.json'), wanted);
62
+ log(`Installing the channel SDKs this machine needs into ${store}`);
63
+ const run = spawnSync(bun, ['install', '--no-summary', '--no-progress'], {
64
+ cwd: store,
65
+ stdio: ['ignore', 'inherit', 'inherit'],
66
+ timeout: INSTALL_TIMEOUT_MS,
67
+ });
68
+ if (run.error !== undefined || run.status !== 0)
69
+ throw new Error(`bun install failed in ${store}: ${run.error?.message ?? `exit ${String(run.status)}`}`);
70
+ writeFileSync(marker, `${new Date().toISOString()}\n`);
71
+ return true;
72
+ }
73
+ export function prepareRuntime(opts = {}) {
74
+ const sources = opts.sources ?? runtimeDir();
75
+ const manifestPath = join(sources, MANIFEST_FILE);
76
+ if (!existsSync(manifestPath))
77
+ return { dir: sources, entry: daemonEntry(sources), trains: join(sources, 'trains'), manifest: null };
78
+ const store = opts.store ?? runtimeStore();
79
+ const log = opts.log ??
80
+ ((line) => {
81
+ process.stderr.write(`${line}\n`);
82
+ });
83
+ mkdirSync(join(store, 'trains'), { recursive: true });
84
+ syncSources(sources, store);
85
+ installDependencies(store, dependenciesFor(readManifest(manifestPath), localStations(opts.agents)), opts.bun ?? findBun(), log);
86
+ return { dir: store, entry: daemonEntry(store), trains: join(store, 'trains'), manifest: manifestPath };
87
+ }
@@ -0,0 +1,74 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const AGENT_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{10}$/;
6
+ export const STORE_ENTRY = 'server.ts';
7
+ export const PACKAGE_ENTRY = join('node_modules', '@metro-labs', 'daemon', 'src', 'server.ts');
8
+ export const daemonEntry = (dir) => existsSync(join(dir, STORE_ENTRY))
9
+ ? join(dir, STORE_ENTRY)
10
+ : join(dir, PACKAGE_ENTRY);
11
+ export class MissingRuntime extends Error {
12
+ }
13
+ export function runtimeDir() {
14
+ const explicit = process.env.METRO_RUNTIME_DIR?.trim();
15
+ const dir = explicit !== undefined && explicit !== ''
16
+ ? explicit
17
+ : join(dirname(dirname(fileURLToPath(import.meta.url))), 'runtime');
18
+ if (!existsSync(daemonEntry(dir)))
19
+ throw new MissingRuntime(`no metro daemon at ${dir}. Reinstall with: npm i -g @stage-labs/metro@beta`);
20
+ return dir;
21
+ }
22
+ class MissingBun extends Error {
23
+ }
24
+ export function assertAgentId(id) {
25
+ if (id === undefined || !AGENT_RE.test(id))
26
+ throw new Error(`'${id ?? ''}' is not an agent id — copy it from the agent's page in the web UI`);
27
+ return id;
28
+ }
29
+ export function findBun() {
30
+ const found = spawnSync('bun', ['--version'], { stdio: 'ignore' });
31
+ if (found.error !== undefined || found.status !== 0)
32
+ throw new MissingBun('metro serve needs Bun, which is not on PATH.\n' +
33
+ 'Install it with: curl -fsSL https://bun.sh/install | bash');
34
+ return 'bun';
35
+ }
36
+ export const localPort = () => Number(process.env.METRO_WEBHOOK_PORT) || 8420;
37
+ export const localUrl = () => `http://127.0.0.1:${String(localPort())}`;
38
+ export const RESTART_CODE = 75;
39
+ export const HOLD_CODE = 76;
40
+ function spawnOnce(plan) {
41
+ const child = spawn(plan.command, plan.args, {
42
+ cwd: plan.cwd,
43
+ env: plan.env,
44
+ stdio: ['ignore', 'inherit', 'inherit'],
45
+ });
46
+ const relay = (sig) => () => {
47
+ child.kill(sig);
48
+ };
49
+ const onInt = relay('SIGINT');
50
+ const onTerm = relay('SIGTERM');
51
+ process.on('SIGINT', onInt);
52
+ process.on('SIGTERM', onTerm);
53
+ return new Promise((resolve) => {
54
+ child.on('exit', (code) => {
55
+ process.off('SIGINT', onInt);
56
+ process.off('SIGTERM', onTerm);
57
+ resolve(code ?? 0);
58
+ });
59
+ });
60
+ }
61
+ export async function spawnPlan(plan, hold) {
62
+ for (;;) {
63
+ const code = await spawnOnce(plan());
64
+ if (code === RESTART_CODE) {
65
+ process.stderr.write('metro was updated; restarting the daemon on the new version\n');
66
+ continue;
67
+ }
68
+ if (code !== HOLD_CODE || hold === undefined)
69
+ return code;
70
+ if ((await hold()) === 'exit')
71
+ return 0;
72
+ process.stderr.write('starting the daemon again\n');
73
+ }
74
+ }
package/dist/serve.js ADDED
@@ -0,0 +1,146 @@
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(['METRO_RUN_TOKEN', 'METRO_AGENT', '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 <address>]';
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
+ function ownerOf(raw) {
25
+ if (raw === undefined || !ADDRESS.test(raw))
26
+ throw new Error(`'${raw ?? ''}' is not an Ethereum address — ${USAGE}`);
27
+ return raw.toLowerCase();
28
+ }
29
+ export function parseServeArgs(argv) {
30
+ let port = localPort();
31
+ let owner = null;
32
+ for (let i = 0; i < argv.length; i += 1) {
33
+ const arg = argv[i] ?? '';
34
+ if (TUNNEL_FLAG.test(arg))
35
+ throw new Error('--tunnel is gone: metro serve always publishes through Tailscale Funnel — ' + USAGE);
36
+ const inlineOwner = OWNER_FLAG.exec(arg);
37
+ if (inlineOwner) {
38
+ owner = ownerOf(inlineOwner[1]);
39
+ continue;
40
+ }
41
+ if (arg === '--owner') {
42
+ owner = ownerOf(argv[i + 1]);
43
+ i += 1;
44
+ continue;
45
+ }
46
+ const inline = PORT_FLAG.exec(arg);
47
+ if (inline) {
48
+ port = portOf(inline[1]);
49
+ continue;
50
+ }
51
+ if (arg === '--port' || arg === '-p') {
52
+ port = portOf(argv[i + 1]);
53
+ i += 1;
54
+ continue;
55
+ }
56
+ throw new Error(`unknown argument '${arg}' — ${USAGE}`);
57
+ }
58
+ return { port, owner };
59
+ }
60
+ export function requireOwner(owner, dir = agentsDir()) {
61
+ if (owner !== null || existsSync(join(dir, '.owner')))
62
+ return;
63
+ throw new Error('no owner is set for this machine, so no wallet could sign in.\n' +
64
+ 'Pass the wallet that owns it once; it is remembered in ' +
65
+ join(dir, '.owner') +
66
+ ':\n metro serve --owner <address>');
67
+ }
68
+ export function readOwner(dir = agentsDir()) {
69
+ try {
70
+ const raw = readFileSync(join(dir, '.owner'), 'utf8').trim().toLowerCase();
71
+ return ADDRESS.test(raw) ? raw : null;
72
+ }
73
+ catch {
74
+ return null;
75
+ }
76
+ }
77
+ export function holdInfo(port, owner, tailscaleBin) {
78
+ return {
79
+ port,
80
+ host: process.env.METRO_HTTP_HOST ?? '127.0.0.1',
81
+ owner: owner ?? readOwner(),
82
+ version: currentVersion(),
83
+ funnel: tailscaleBin,
84
+ lockFile: join(process.env.METRO_STATE_DIR ?? serveStateDir(), '.tail-lock'),
85
+ };
86
+ }
87
+ function tailscaleStatus(bin) {
88
+ const run = spawnSync(bin, ['status', '--json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
89
+ if (run.error !== undefined || run.status !== 0)
90
+ return { ok: false, state: 'not running' };
91
+ try {
92
+ const parsed = JSON.parse(run.stdout);
93
+ return parsed.BackendState === 'Running' ? { ok: true } : { ok: false, state: String(parsed.BackendState) };
94
+ }
95
+ catch {
96
+ return { ok: false, state: 'unreadable' };
97
+ }
98
+ }
99
+ export function findTailscale(candidates = ['tailscale', TAILSCALE_APP]) {
100
+ const bin = candidates.find((c) => spawnSync(c, ['version'], { stdio: 'ignore' }).status === 0);
101
+ if (bin === undefined)
102
+ throw new Error('metro serve needs Tailscale on this machine: the daemon is published through Tailscale Funnel.\n' +
103
+ 'macOS: brew install --cask tailscale (or the App Store app)\n' +
104
+ 'Linux: curl -fsSL https://tailscale.com/install.sh | sh\n' +
105
+ 'Then sign the machine in: tailscale up');
106
+ const status = tailscaleStatus(bin);
107
+ if (!status.ok)
108
+ throw new Error(`Tailscale is installed but this machine is not connected (${status.state}). Sign it in first: tailscale up\n` +
109
+ 'Funnel also has to be enabled once on your tailnet: https://tailscale.com/kb/1223/funnel');
110
+ return bin;
111
+ }
112
+ export function servePlan(opts) {
113
+ const env = Object.fromEntries(Object.entries(process.env).filter(([key]) => !SCRUBBED.has(key)));
114
+ return {
115
+ command: findBun(),
116
+ args: [opts.runtime.entry],
117
+ cwd: opts.runtime.dir,
118
+ env: {
119
+ ...env,
120
+ METRO_VERSION: currentVersion(),
121
+ METRO_CLI_BIN: process.argv[1] ?? '',
122
+ METRO_WEBHOOK_PORT: String(opts.port),
123
+ METRO_HTTP_HOST: process.env.METRO_HTTP_HOST ?? '127.0.0.1',
124
+ METRO_TRAINS_DIR: opts.runtime.trains,
125
+ ...(opts.runtime.manifest === null
126
+ ? {}
127
+ : { METRO_RUNTIME_STORE: opts.runtime.dir, METRO_RUNTIME_MANIFEST: opts.runtime.manifest }),
128
+ METRO_STATE_DIR: process.env.METRO_STATE_DIR ?? serveStateDir(),
129
+ METRO_TUNNEL: 'tailscale',
130
+ METRO_TAILSCALE_BIN: opts.tailscaleBin,
131
+ ...(opts.owner === null ? {} : { METRO_OWNER: opts.owner }),
132
+ },
133
+ };
134
+ }
135
+ export function serve(argv) {
136
+ const { port, owner } = parseServeArgs(argv);
137
+ const running = serveLockedBy();
138
+ if (running !== null)
139
+ throw new Error(`a metro serve daemon is already running on this machine (pid ${String(running)}). ` +
140
+ 'Stop it first: metro stop');
141
+ requireOwner(owner);
142
+ const tailscaleBin = findTailscale();
143
+ const node = ensureNodeName(tailscaleBin);
144
+ 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`);
145
+ return spawnPlan(() => servePlan({ runtime: prepareRuntime(), port, owner, tailscaleBin }), () => holdUntilStart(holdInfo(port, owner, tailscaleBin)));
146
+ }