@stage-labs/metro 0.1.0-beta.32 → 0.1.0-beta.321

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 (616) hide show
  1. package/dist/agent.js +123 -0
  2. package/dist/api.js +9 -129
  3. package/dist/automation.js +56 -0
  4. package/dist/child.js +33 -0
  5. package/dist/claude-env.js +113 -0
  6. package/dist/claude-settings.js +40 -0
  7. package/dist/cli.js +60 -139
  8. package/dist/control.js +19 -103
  9. package/dist/hold.js +210 -0
  10. package/dist/local.js +43 -0
  11. package/dist/lock.js +62 -0
  12. package/dist/memory.js +206 -0
  13. package/dist/node-name.js +71 -0
  14. package/dist/provider-flags.js +9 -0
  15. package/dist/root-release-io.js +160 -0
  16. package/dist/root-release.js +74 -0
  17. package/dist/route.js +65 -0
  18. package/dist/runtime-install.js +106 -0
  19. package/dist/runtime.js +29 -55
  20. package/dist/serve.js +117 -17
  21. package/dist/service.js +328 -0
  22. package/dist/tail.js +10 -11
  23. package/dist/update.js +13 -1
  24. package/hooks/guard.mjs +77 -0
  25. package/hooks/policy.mjs +74 -0
  26. package/hooks/session-start.mjs +31 -0
  27. package/package.json +6 -25
  28. package/runtime/node_modules/@metro-labs/core/package.json +61 -0
  29. package/runtime/node_modules/@metro-labs/core/src/automation-files.ts +216 -0
  30. package/runtime/node_modules/@metro-labs/core/src/automation-store.ts +171 -0
  31. package/runtime/node_modules/@metro-labs/core/src/automation-types.ts +141 -0
  32. package/runtime/node_modules/@metro-labs/core/src/call.ts +81 -0
  33. package/runtime/node_modules/@metro-labs/core/src/claude-token.ts +3 -0
  34. package/runtime/node_modules/@metro-labs/core/src/effort.ts +21 -0
  35. package/runtime/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  36. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/events.ts +54 -6
  37. package/runtime/node_modules/@metro-labs/{mcp/src/db → core/src}/ids.ts +8 -1
  38. package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  39. package/runtime/node_modules/@metro-labs/{mcp/src/stations → core/src}/lines.ts +22 -26
  40. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/protocol.ts +7 -4
  41. package/runtime/node_modules/@metro-labs/core/src/runner-activity.ts +270 -0
  42. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/secure-fs.ts +17 -0
  43. package/runtime/node_modules/@metro-labs/core/src/skill-source.ts +96 -0
  44. package/runtime/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  45. package/runtime/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  46. package/runtime/node_modules/@metro-labs/core/src/stations/account-status.ts +26 -0
  47. package/runtime/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  48. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/attachments.ts +9 -3
  49. package/runtime/node_modules/@metro-labs/core/src/stations/channel-directory.ts +159 -0
  50. package/runtime/node_modules/@metro-labs/core/src/stations/channel-pages.ts +129 -0
  51. package/runtime/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  52. package/runtime/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  53. package/runtime/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  54. package/runtime/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  55. package/runtime/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  56. package/runtime/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  57. package/runtime/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  58. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/station-runtime.ts +6 -11
  59. package/runtime/node_modules/@metro-labs/core/src/stations/train-boot.ts +63 -0
  60. package/runtime/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  61. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/types.ts +22 -1
  62. package/runtime/node_modules/@metro-labs/core/src/tickets.ts +44 -0
  63. package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
  64. package/runtime/node_modules/@metro-labs/daemon/package.json +51 -0
  65. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/agent-fs.ts +246 -0
  66. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/crontab.ts +38 -0
  67. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files-api.ts +12 -0
  68. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files.ts +89 -0
  69. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/home-fs.ts +86 -0
  70. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/metro-home.ts +42 -0
  71. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/provision.ts +57 -0
  72. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedule-detail.ts +93 -0
  73. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules-api.ts +27 -0
  74. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules.ts +144 -0
  75. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/unit-files.ts +29 -0
  76. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/user.ts +101 -0
  77. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/view.ts +90 -0
  78. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
  79. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-lookups.ts +55 -0
  80. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-routes.ts +78 -0
  81. package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +383 -0
  82. package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +30 -0
  83. package/runtime/node_modules/@metro-labs/daemon/src/agents/allowlist.ts +59 -0
  84. package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +134 -0
  85. package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +124 -0
  86. package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +334 -0
  87. package/runtime/node_modules/@metro-labs/{mcp/src/db/file-source.ts → daemon/src/agents/files.ts} +40 -50
  88. package/runtime/node_modules/@metro-labs/{mcp/src/db/key-map.ts → daemon/src/agents/keys.ts} +1 -11
  89. package/runtime/node_modules/@metro-labs/daemon/src/agents/map.ts +135 -0
  90. package/runtime/node_modules/@metro-labs/daemon/src/agents/policy-route.ts +27 -0
  91. package/runtime/node_modules/@metro-labs/{mcp/src/db/agent-scope.ts → daemon/src/agents/scope.ts} +2 -2
  92. package/runtime/node_modules/@metro-labs/daemon/src/agents/sender-cards.ts +94 -0
  93. package/runtime/node_modules/@metro-labs/daemon/src/agents/senders.ts +38 -0
  94. package/runtime/node_modules/@metro-labs/daemon/src/approvals/api.ts +55 -0
  95. package/runtime/node_modules/@metro-labs/daemon/src/approvals/owner-line.ts +45 -0
  96. package/runtime/node_modules/@metro-labs/daemon/src/approvals/pending.ts +190 -0
  97. package/runtime/node_modules/@metro-labs/daemon/src/approvals/preview.ts +66 -0
  98. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +259 -0
  99. package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +36 -0
  100. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/crash-guard.ts +1 -1
  101. package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +21 -0
  102. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/paths.ts +3 -41
  103. package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +26 -0
  104. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/inbound.ts +99 -73
  105. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/media-note.ts +11 -7
  106. package/runtime/node_modules/@metro-labs/daemon/src/channels/notice.ts +22 -0
  107. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/pending.ts +13 -1
  108. package/runtime/node_modules/@metro-labs/daemon/src/channels/react-note.ts +13 -0
  109. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/relay.ts +6 -2
  110. package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +269 -0
  111. package/runtime/node_modules/@metro-labs/daemon/src/claude/cli-files.ts +28 -0
  112. package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +359 -0
  113. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-api.ts +12 -0
  114. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-fetch.ts +160 -0
  115. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-skills.ts +255 -0
  116. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-validate.ts +53 -0
  117. package/runtime/node_modules/@metro-labs/daemon/src/claude/hooks.ts +60 -0
  118. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory-routine.ts +123 -0
  119. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory.ts +32 -0
  120. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-activity.ts +17 -0
  121. package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-process.ts +52 -0
  122. package/runtime/node_modules/@metro-labs/daemon/src/claude/session-files.ts +75 -0
  123. package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +294 -0
  124. package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +109 -0
  125. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-api.ts +114 -0
  126. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-state.ts +18 -0
  127. package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +325 -0
  128. package/runtime/node_modules/@metro-labs/daemon/src/claude/skills.ts +123 -0
  129. package/runtime/node_modules/@metro-labs/daemon/src/connectors/agent-key.ts +145 -0
  130. package/runtime/node_modules/@metro-labs/daemon/src/connectors/enroll-api.ts +99 -0
  131. package/runtime/node_modules/@metro-labs/daemon/src/connectors/leftovers.ts +59 -0
  132. package/runtime/node_modules/@metro-labs/daemon/src/connectors/metro-api.ts +93 -0
  133. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-grant.ts +4 -4
  134. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-owner.ts +3 -3
  135. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-reaper.ts +174 -0
  136. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-serve.ts +11 -19
  137. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-api.ts +10 -27
  138. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-store.ts +4 -4
  139. package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +253 -0
  140. package/runtime/node_modules/@metro-labs/daemon/src/gateway/cache-ttl.ts +43 -0
  141. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +186 -0
  142. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +209 -0
  143. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-version.ts +44 -0
  144. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +137 -0
  145. package/runtime/node_modules/@metro-labs/daemon/src/gateway/delivered.ts +102 -0
  146. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effective.ts +32 -0
  147. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effort.ts +130 -0
  148. package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
  149. package/runtime/node_modules/@metro-labs/daemon/src/gateway/failures.ts +40 -0
  150. package/runtime/node_modules/@metro-labs/daemon/src/gateway/fallback.ts +149 -0
  151. package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +305 -0
  152. package/runtime/node_modules/@metro-labs/daemon/src/gateway/frames.ts +118 -0
  153. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +372 -0
  154. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +121 -0
  155. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +150 -0
  156. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-leftovers.ts +63 -0
  157. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +25 -0
  158. package/runtime/node_modules/@metro-labs/daemon/src/gateway/org-models.ts +203 -0
  159. package/runtime/node_modules/@metro-labs/daemon/src/gateway/routeway.ts +88 -0
  160. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +18 -0
  161. package/runtime/node_modules/@metro-labs/daemon/src/gateway/subscription.ts +60 -0
  162. package/runtime/node_modules/@metro-labs/daemon/src/gateway/text.ts +33 -0
  163. package/runtime/node_modules/@metro-labs/daemon/src/gateway/tool-search.ts +126 -0
  164. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage-refresh.ts +51 -0
  165. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +265 -0
  166. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/accounts.ts +66 -19
  167. package/runtime/node_modules/@metro-labs/daemon/src/mcp/attachment-schema.ts +91 -0
  168. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-bridge.ts +45 -0
  169. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-permission.ts +25 -0
  170. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/call-tools.ts +88 -38
  171. package/runtime/node_modules/@metro-labs/daemon/src/mcp/channel-tool.ts +80 -0
  172. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/ctx.ts +4 -4
  173. package/runtime/node_modules/@metro-labs/daemon/src/mcp/diagnostics.ts +102 -0
  174. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/event-store.ts +24 -18
  175. package/runtime/node_modules/@metro-labs/daemon/src/mcp/frame-schema.ts +44 -0
  176. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/group-tools.ts +2 -2
  177. package/runtime/node_modules/@metro-labs/daemon/src/mcp/index.ts +167 -0
  178. package/runtime/node_modules/@metro-labs/daemon/src/mcp/instructions.ts +21 -0
  179. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/member-tools.ts +2 -2
  180. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-prompt.ts +115 -0
  181. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +111 -0
  182. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-gate.ts +88 -0
  183. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-snapshot.ts +65 -0
  184. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-lookup.ts +60 -0
  185. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-tool.ts +96 -0
  186. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/raw-get-stream.ts +55 -17
  187. package/runtime/node_modules/@metro-labs/daemon/src/mcp/read-tool.ts +87 -0
  188. package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +48 -0
  189. package/runtime/node_modules/@metro-labs/daemon/src/mcp/server-approvals.ts +118 -0
  190. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-slot.ts +137 -0
  191. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/session.ts +103 -52
  192. package/runtime/node_modules/@metro-labs/daemon/src/mcp/speech-schema.ts +11 -0
  193. package/runtime/node_modules/@metro-labs/daemon/src/mcp/speech-send.ts +15 -0
  194. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-catalog.ts +108 -0
  195. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-def.ts +9 -0
  196. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-dispatch.ts +74 -48
  197. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-schemas.ts +87 -114
  198. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/upload-tool.ts +6 -11
  199. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/announced.ts +68 -0
  200. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/config.ts +29 -0
  201. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/connector-tools.ts +114 -0
  202. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/link.ts +197 -0
  203. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/rpc.ts +67 -0
  204. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/token.ts +50 -0
  205. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/helper-script.ts +183 -0
  206. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/imds.ts +16 -0
  207. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/install.ts +78 -0
  208. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/privilege.ts +50 -0
  209. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/root-follow.ts +16 -0
  210. package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +132 -0
  211. package/runtime/node_modules/@metro-labs/daemon/src/monitor/run-event.ts +139 -0
  212. package/runtime/node_modules/@metro-labs/daemon/src/monitor/run-events.ts +101 -0
  213. package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +323 -0
  214. package/runtime/node_modules/@metro-labs/daemon/src/policy/policy.ts +120 -0
  215. package/runtime/node_modules/@metro-labs/daemon/src/routes/bearer.ts +35 -0
  216. package/runtime/node_modules/@metro-labs/daemon/src/routes/body.ts +24 -0
  217. package/runtime/node_modules/@metro-labs/daemon/src/routes/gmail-attach.ts +67 -0
  218. package/runtime/node_modules/@metro-labs/daemon/src/routes/gmail-detach.ts +37 -0
  219. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/routes}/http.ts +55 -56
  220. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +155 -0
  221. package/runtime/node_modules/@metro-labs/daemon/src/routes/pair-again.ts +23 -0
  222. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +63 -0
  223. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/session-api.ts → daemon/src/routes/session.ts} +9 -7
  224. package/runtime/node_modules/@metro-labs/daemon/src/routes/threema-callback.ts +103 -0
  225. package/runtime/node_modules/@metro-labs/daemon/src/server/cloudwatch.ts +178 -0
  226. package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +39 -0
  227. package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +58 -0
  228. package/runtime/node_modules/@metro-labs/daemon/src/server/owner.ts +26 -0
  229. package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +90 -0
  230. package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
  231. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-browser.ts +107 -0
  232. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-driver.ts +42 -0
  233. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-gmail.ts +78 -0
  234. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-inline.ts +29 -1
  235. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-interactive.ts +6 -32
  236. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-resolve.ts +84 -13
  237. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/attach-session.ts +70 -27
  238. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-xmtp.ts +8 -9
  239. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach.ts +69 -3
  240. package/runtime/node_modules/@metro-labs/{mcp/src/db → daemon/src/stations}/materialize.ts +50 -181
  241. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/registry.ts +26 -2
  242. package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +135 -0
  243. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor-io.ts +3 -3
  244. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor.ts +5 -5
  245. package/runtime/node_modules/@metro-labs/daemon/src/stations/threema-callbacks.ts +32 -0
  246. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/train-call.ts +1 -1
  247. package/runtime/node_modules/@metro-labs/daemon/src/stations/webhook-endpoints.ts +51 -0
  248. package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +84 -0
  249. package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +124 -0
  250. package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +15 -0
  251. package/runtime/node_modules/@metro-labs/daemon/src/voice/api.ts +14 -0
  252. package/runtime/node_modules/@metro-labs/daemon/src/voice/audio.ts +193 -0
  253. package/runtime/node_modules/@metro-labs/daemon/src/voice/call.ts +191 -0
  254. package/runtime/node_modules/@metro-labs/daemon/src/voice/calls.ts +153 -0
  255. package/runtime/node_modules/@metro-labs/daemon/src/voice/peer.ts +85 -0
  256. package/runtime/node_modules/@metro-labs/daemon/src/voice/scribe.ts +115 -0
  257. package/runtime/node_modules/@metro-labs/daemon/src/voice/shared-talk.ts +85 -0
  258. package/runtime/node_modules/@metro-labs/daemon/src/voice/shared.ts +198 -0
  259. package/runtime/node_modules/@metro-labs/daemon/src/voice/speech-queue.ts +200 -0
  260. package/runtime/node_modules/@metro-labs/daemon/src/voice/speech.ts +125 -0
  261. package/runtime/node_modules/@metro-labs/daemon/src/voice/store.ts +103 -0
  262. package/runtime/node_modules/@metro-labs/discord-bot/package.json +3 -5
  263. package/runtime/node_modules/@metro-labs/discord-bot/src/accounts.ts +3 -23
  264. package/runtime/node_modules/@metro-labs/discord-bot/src/actions.ts +21 -187
  265. package/runtime/node_modules/@metro-labs/discord-bot/src/attachments.ts +2 -2
  266. package/runtime/node_modules/@metro-labs/discord-bot/src/channel-source.ts +79 -0
  267. package/runtime/node_modules/@metro-labs/discord-bot/src/channels.ts +186 -0
  268. package/runtime/node_modules/@metro-labs/discord-bot/src/format.ts +26 -67
  269. package/runtime/node_modules/@metro-labs/discord-bot/src/group-actions.ts +1 -1
  270. package/runtime/node_modules/@metro-labs/discord-bot/src/group.ts +2 -2
  271. package/runtime/node_modules/@metro-labs/discord-bot/src/index.ts +8 -14
  272. package/runtime/node_modules/@metro-labs/discord-bot/src/members.ts +2 -2
  273. package/runtime/node_modules/@metro-labs/discord-bot/src/profile.ts +68 -0
  274. package/runtime/node_modules/@metro-labs/discord-bot/src/send-files.ts +12 -13
  275. package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +6 -1
  276. package/runtime/node_modules/@metro-labs/gmail/package.json +27 -0
  277. package/runtime/node_modules/@metro-labs/gmail/src/accounts.ts +133 -0
  278. package/runtime/node_modules/@metro-labs/gmail/src/actions.ts +20 -0
  279. package/runtime/node_modules/@metro-labs/gmail/src/api.ts +34 -0
  280. package/runtime/node_modules/@metro-labs/gmail/src/attachments.ts +38 -0
  281. package/runtime/node_modules/@metro-labs/gmail/src/auth.ts +115 -0
  282. package/runtime/node_modules/@metro-labs/gmail/src/channels.ts +66 -0
  283. package/runtime/node_modules/@metro-labs/gmail/src/config.ts +15 -0
  284. package/runtime/node_modules/@metro-labs/gmail/src/inbound.ts +97 -0
  285. package/runtime/node_modules/@metro-labs/gmail/src/index.ts +12 -0
  286. package/runtime/node_modules/@metro-labs/gmail/src/login.ts +39 -0
  287. package/runtime/node_modules/@metro-labs/gmail/src/managed-binding.ts +33 -0
  288. package/runtime/node_modules/@metro-labs/gmail/src/managed.ts +45 -0
  289. package/runtime/node_modules/@metro-labs/gmail/src/message.ts +125 -0
  290. package/runtime/node_modules/@metro-labs/gmail/src/mime.ts +70 -0
  291. package/runtime/node_modules/@metro-labs/gmail/src/outbound.ts +125 -0
  292. package/runtime/node_modules/@metro-labs/gmail/src/query.ts +101 -0
  293. package/runtime/node_modules/@metro-labs/gmail/src/state.ts +30 -0
  294. package/runtime/node_modules/@metro-labs/gmail/src/station.ts +16 -0
  295. package/runtime/node_modules/@metro-labs/gmail/src/trust.ts +42 -0
  296. package/runtime/node_modules/@metro-labs/http/package.json +44 -0
  297. package/runtime/node_modules/@metro-labs/http/src/agent-signature.ts +95 -0
  298. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +146 -0
  299. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/oauth-discovery.ts → http/src/connector-discovery.ts} +57 -27
  300. package/runtime/node_modules/@metro-labs/http/src/connector-grant.ts +8 -0
  301. package/runtime/node_modules/@metro-labs/http/src/connector-input.ts +73 -0
  302. package/runtime/node_modules/@metro-labs/http/src/connector-mcp.ts +108 -0
  303. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/oauth-client.ts → http/src/connector-oauth.ts} +60 -31
  304. package/runtime/node_modules/@metro-labs/http/src/connector-policy.ts +92 -0
  305. package/runtime/node_modules/@metro-labs/http/src/connector-public-url.ts +64 -0
  306. package/runtime/node_modules/@metro-labs/http/src/connector-reach.ts +27 -0
  307. package/runtime/node_modules/@metro-labs/http/src/connector-resource.ts +108 -0
  308. package/runtime/node_modules/@metro-labs/http/src/connector-tools.ts +101 -0
  309. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/connector-url.ts +8 -28
  310. package/runtime/node_modules/@metro-labs/http/src/ed25519.ts +56 -0
  311. package/runtime/node_modules/@metro-labs/http/src/mcp-server-protocol.ts +99 -0
  312. package/runtime/node_modules/@metro-labs/http/src/mcp-server-tools.ts +104 -0
  313. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/mode-api.ts +2 -2
  314. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/session-config.ts → http/src/return-to.ts} +4 -6
  315. package/runtime/node_modules/@metro-labs/http/src/sigv4.ts +90 -0
  316. package/runtime/node_modules/@metro-labs/http/src/workos-token.ts +149 -0
  317. package/runtime/node_modules/@metro-labs/outlook/package.json +25 -0
  318. package/runtime/node_modules/@metro-labs/outlook/src/accounts.ts +78 -0
  319. package/runtime/node_modules/@metro-labs/outlook/src/actions.ts +15 -0
  320. package/runtime/node_modules/@metro-labs/outlook/src/attachments.ts +81 -0
  321. package/runtime/node_modules/@metro-labs/outlook/src/auth.ts +120 -0
  322. package/runtime/node_modules/@metro-labs/outlook/src/browser.ts +42 -0
  323. package/runtime/node_modules/@metro-labs/outlook/src/channels.ts +60 -0
  324. package/runtime/node_modules/@metro-labs/outlook/src/config.ts +23 -0
  325. package/runtime/node_modules/@metro-labs/outlook/src/format.ts +59 -0
  326. package/runtime/node_modules/@metro-labs/outlook/src/graph.ts +55 -0
  327. package/runtime/node_modules/@metro-labs/outlook/src/inbound.ts +96 -0
  328. package/runtime/node_modules/@metro-labs/outlook/src/index.ts +12 -0
  329. package/runtime/node_modules/@metro-labs/outlook/src/login.ts +129 -0
  330. package/runtime/node_modules/@metro-labs/outlook/src/me.ts +31 -0
  331. package/runtime/node_modules/@metro-labs/outlook/src/outbound.ts +103 -0
  332. package/runtime/node_modules/@metro-labs/outlook/src/query.ts +84 -0
  333. package/runtime/node_modules/@metro-labs/outlook/src/state.ts +28 -0
  334. package/runtime/node_modules/@metro-labs/outlook/src/station.ts +16 -0
  335. package/runtime/node_modules/@metro-labs/outlook/src/trust.ts +41 -0
  336. package/runtime/node_modules/@metro-labs/telegram/package.json +2 -4
  337. package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +5 -24
  338. package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +27 -6
  339. package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +1 -1
  340. package/runtime/node_modules/@metro-labs/telegram/src/channels.ts +58 -0
  341. package/runtime/node_modules/@metro-labs/telegram/src/client.ts +4 -4
  342. package/runtime/node_modules/@metro-labs/telegram/src/format.ts +19 -34
  343. package/runtime/node_modules/@metro-labs/telegram/src/group.ts +3 -3
  344. package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +13 -34
  345. package/runtime/node_modules/@metro-labs/telegram/src/index.ts +4 -43
  346. package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +2 -3
  347. package/runtime/node_modules/@metro-labs/telegram/src/members.ts +1 -1
  348. package/runtime/node_modules/@metro-labs/telegram/src/profile.ts +70 -0
  349. package/runtime/node_modules/@metro-labs/telegram/src/reactions.ts +2 -2
  350. package/runtime/node_modules/@metro-labs/telegram/src/station.ts +5 -1
  351. package/runtime/node_modules/@metro-labs/telegram/src/types.ts +0 -1
  352. package/runtime/node_modules/@metro-labs/telegram-bot/package.json +2 -2
  353. package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +7 -41
  354. package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +24 -77
  355. package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +2 -2
  356. package/runtime/node_modules/@metro-labs/telegram-bot/src/channel-files.ts +3 -0
  357. package/runtime/node_modules/@metro-labs/telegram-bot/src/channels.ts +43 -0
  358. package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +46 -48
  359. package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +15 -44
  360. package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +6 -82
  361. package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +1 -1
  362. package/runtime/node_modules/@metro-labs/telegram-bot/src/observed-chats.ts +172 -0
  363. package/runtime/node_modules/@metro-labs/telegram-bot/src/profile.ts +85 -0
  364. package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +9 -1
  365. package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +50 -15
  366. package/runtime/node_modules/@metro-labs/telegram-bot/src/updates.ts +26 -0
  367. package/runtime/node_modules/@metro-labs/threema/package.json +26 -0
  368. package/runtime/node_modules/@metro-labs/threema/src/accounts.ts +108 -0
  369. package/runtime/node_modules/@metro-labs/threema/src/actions.ts +130 -0
  370. package/runtime/node_modules/@metro-labs/threema/src/api.ts +152 -0
  371. package/runtime/node_modules/@metro-labs/threema/src/channels.ts +37 -0
  372. package/runtime/node_modules/@metro-labs/threema/src/chats.ts +88 -0
  373. package/runtime/node_modules/@metro-labs/threema/src/crypto.ts +100 -0
  374. package/runtime/node_modules/@metro-labs/threema/src/files.ts +47 -0
  375. package/runtime/node_modules/@metro-labs/threema/src/format.ts +164 -0
  376. package/runtime/node_modules/@metro-labs/threema/src/groups.ts +96 -0
  377. package/runtime/node_modules/@metro-labs/threema/src/ids.ts +21 -0
  378. package/runtime/node_modules/@metro-labs/threema/src/inbound.ts +92 -0
  379. package/runtime/node_modules/@metro-labs/threema/src/index.ts +24 -0
  380. package/runtime/node_modules/@metro-labs/threema/src/messages.ts +264 -0
  381. package/runtime/node_modules/@metro-labs/threema/src/outbound.ts +161 -0
  382. package/runtime/node_modules/@metro-labs/threema/src/station.ts +21 -0
  383. package/runtime/node_modules/@metro-labs/threema/src/verify.ts +117 -0
  384. package/runtime/node_modules/@metro-labs/webhook/package.json +2 -2
  385. package/runtime/node_modules/@metro-labs/webhook/src/station.ts +5 -8
  386. package/runtime/node_modules/@metro-labs/whatsapp/package.json +3 -6
  387. package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +6 -28
  388. package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +1 -1
  389. package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +100 -14
  390. package/runtime/node_modules/@metro-labs/whatsapp/src/app-state.ts +49 -0
  391. package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +2 -2
  392. package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +1 -1
  393. package/runtime/node_modules/@metro-labs/whatsapp/src/channel-chats.ts +137 -0
  394. package/runtime/node_modules/@metro-labs/whatsapp/src/channels.ts +48 -0
  395. package/runtime/node_modules/@metro-labs/whatsapp/src/client-history.ts +31 -0
  396. package/runtime/node_modules/@metro-labs/whatsapp/src/client-types.ts +50 -0
  397. package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +161 -84
  398. package/runtime/node_modules/@metro-labs/whatsapp/src/connection.ts +139 -0
  399. package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +7 -58
  400. package/runtime/node_modules/@metro-labs/whatsapp/src/history-events.ts +127 -0
  401. package/runtime/node_modules/@metro-labs/whatsapp/src/history-files.ts +39 -0
  402. package/runtime/node_modules/@metro-labs/whatsapp/src/history-identity.ts +58 -0
  403. package/runtime/node_modules/@metro-labs/whatsapp/src/history-message.ts +161 -0
  404. package/runtime/node_modules/@metro-labs/whatsapp/src/history-state.ts +344 -0
  405. package/runtime/node_modules/@metro-labs/whatsapp/src/history-types.ts +91 -0
  406. package/runtime/node_modules/@metro-labs/whatsapp/src/history.ts +195 -0
  407. package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +11 -28
  408. package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +4 -37
  409. package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +1 -1
  410. package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +37 -4
  411. package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +1 -1
  412. package/runtime/node_modules/@metro-labs/whatsapp/src/members.ts +94 -0
  413. package/runtime/node_modules/@metro-labs/whatsapp/src/messages.ts +91 -0
  414. package/runtime/node_modules/@metro-labs/whatsapp/src/names.ts +106 -0
  415. package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +44 -0
  416. package/runtime/node_modules/@metro-labs/whatsapp/src/profile.ts +158 -0
  417. package/runtime/node_modules/@metro-labs/whatsapp/src/resolve.ts +52 -0
  418. package/runtime/node_modules/@metro-labs/whatsapp/src/send-expiry.ts +65 -0
  419. package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +26 -1
  420. package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +5 -9
  421. package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +0 -1
  422. package/runtime/node_modules/@metro-labs/xmtp/package.json +4 -3
  423. package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +10 -20
  424. package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +2 -2
  425. package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +55 -224
  426. package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +55 -54
  427. package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +114 -223
  428. package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +58 -15
  429. package/runtime/node_modules/@metro-labs/xmtp/src/call-leftovers.ts +48 -0
  430. package/runtime/node_modules/@metro-labs/xmtp/src/channels.ts +56 -0
  431. package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +114 -3
  432. package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +36 -20
  433. package/runtime/node_modules/@metro-labs/xmtp/src/delete-requests.ts +34 -0
  434. package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +38 -25
  435. package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +8 -18
  436. package/runtime/node_modules/@metro-labs/xmtp/src/frames.ts +190 -0
  437. package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +1 -1
  438. package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +2 -2
  439. package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +30 -16
  440. package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +18 -70
  441. package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +102 -50
  442. package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +1 -1
  443. package/runtime/node_modules/@metro-labs/xmtp/src/names.ts +61 -0
  444. package/runtime/node_modules/@metro-labs/xmtp/src/network.ts +114 -0
  445. package/runtime/node_modules/@metro-labs/xmtp/src/profile.ts +160 -0
  446. package/runtime/node_modules/@metro-labs/xmtp/src/read-attachments.ts +37 -0
  447. package/runtime/node_modules/@metro-labs/xmtp/src/resolve.ts +44 -0
  448. package/runtime/node_modules/@metro-labs/xmtp/src/sender.ts +112 -0
  449. package/runtime/node_modules/@metro-labs/xmtp/src/smart.ts +79 -0
  450. package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +10 -2
  451. package/runtime/node_modules/@metro-labs/xmtp/src/stream.ts +66 -0
  452. package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +32 -60
  453. package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +78 -49
  454. package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +4 -6
  455. package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +19 -5
  456. package/runtime/node_modules/@metro-labs/xmtp/src/wallet.ts +28 -0
  457. package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +14 -4
  458. package/runtime/patches/5bca2c07d5852d3f58453cff0448dd85da13d3665b61e3d758905b298d432d7c.patch +31 -0
  459. package/runtime/runtime.json +1 -1
  460. package/runtime/sdk-runner/node_modules/@metro-labs/core/package.json +61 -0
  461. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-files.ts +216 -0
  462. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-store.ts +171 -0
  463. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-types.ts +141 -0
  464. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/call.ts +81 -0
  465. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/claude-token.ts +3 -0
  466. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/effort.ts +21 -0
  467. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  468. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/events.ts +165 -0
  469. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/ids.ts +28 -0
  470. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  471. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/lines.ts +78 -0
  472. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/log.ts +42 -0
  473. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/protocol.ts +227 -0
  474. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/runner-activity.ts +270 -0
  475. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/secure-fs.ts +74 -0
  476. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/skill-source.ts +96 -0
  477. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  478. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  479. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-status.ts +26 -0
  480. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  481. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/attachments.ts +202 -0
  482. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/channel-directory.ts +159 -0
  483. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/channel-pages.ts +129 -0
  484. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  485. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  486. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  487. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  488. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  489. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  490. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  491. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/station-runtime.ts +59 -0
  492. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-boot.ts +63 -0
  493. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  494. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/types.ts +128 -0
  495. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/str.ts +5 -0
  496. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/tickets.ts +44 -0
  497. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/train-error.ts +53 -0
  498. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/version.ts +2 -0
  499. package/runtime/sdk-runner/runner.json +10 -0
  500. package/runtime/sdk-runner/src/activity-tasks.ts +194 -0
  501. package/runtime/sdk-runner/src/activity.ts +392 -0
  502. package/runtime/sdk-runner/src/app.ts +87 -0
  503. package/runtime/sdk-runner/src/approvals.ts +37 -0
  504. package/runtime/sdk-runner/src/automation-cli.ts +10 -0
  505. package/runtime/sdk-runner/src/automation-command.ts +151 -0
  506. package/runtime/sdk-runner/src/automation.ts +145 -0
  507. package/runtime/sdk-runner/src/calls.ts +133 -0
  508. package/runtime/sdk-runner/src/channel-text.ts +26 -0
  509. package/runtime/sdk-runner/src/config.ts +50 -0
  510. package/runtime/sdk-runner/src/errors.ts +142 -0
  511. package/runtime/sdk-runner/src/inbox.ts +168 -0
  512. package/runtime/sdk-runner/src/input-queue.ts +77 -0
  513. package/runtime/sdk-runner/src/input-timing.ts +68 -0
  514. package/runtime/sdk-runner/src/link.ts +154 -0
  515. package/runtime/sdk-runner/src/main.ts +57 -0
  516. package/runtime/sdk-runner/src/recovery.ts +46 -0
  517. package/runtime/sdk-runner/src/rules.ts +28 -0
  518. package/runtime/sdk-runner/src/runner.ts +358 -0
  519. package/runtime/sdk-runner/src/session-store.ts +129 -0
  520. package/runtime/sdk-runner/src/session-watch.ts +158 -0
  521. package/runtime/sdk-runner/src/singleton.ts +15 -0
  522. package/runtime/sdk-runner/src/skill-work.ts +76 -0
  523. package/runtime/sdk-runner/src/skills-files.ts +169 -0
  524. package/runtime/sdk-runner/src/skills.ts +150 -0
  525. package/runtime/sdk-runner/src/task-ledger.ts +244 -0
  526. package/runtime/sdk-runner/src/task-recovery.ts +203 -0
  527. package/runtime/sdk-runner/src/task-state.ts +77 -0
  528. package/runtime/sdk-runner/src/tool-proxy.ts +40 -0
  529. package/runtime/server.ts +1 -0
  530. package/runtime/stations.json +43 -0
  531. package/skills/MEMORY.md +78 -0
  532. package/skills/METRO.md +35 -0
  533. package/skills/STAGE.md +110 -0
  534. package/dist/bedrock-eventstream.js +0 -120
  535. package/dist/bedrock-proxy.js +0 -260
  536. package/dist/bedrock-upstream.js +0 -72
  537. package/dist/bedrock.js +0 -106
  538. package/dist/claude.js +0 -15
  539. package/dist/plugin.js +0 -82
  540. package/dist/prompt.js +0 -61
  541. package/dist/store.js +0 -93
  542. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-speak.ts +0 -195
  543. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-transcribe.ts +0 -292
  544. package/runtime/node_modules/@metro-labs/discord-bot/src/voice.ts +0 -197
  545. package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +0 -5
  546. package/runtime/node_modules/@metro-labs/mcp/package.json +0 -67
  547. package/runtime/node_modules/@metro-labs/mcp/src/channels/dedupe.ts +0 -24
  548. package/runtime/node_modules/@metro-labs/mcp/src/daemon/account-api.ts +0 -311
  549. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-api.ts +0 -333
  550. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-connector-api.ts +0 -150
  551. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-pair.ts +0 -20
  552. package/runtime/node_modules/@metro-labs/mcp/src/daemon/api-http.ts +0 -153
  553. package/runtime/node_modules/@metro-labs/mcp/src/daemon/boot.ts +0 -368
  554. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair-api.ts +0 -134
  555. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-api.ts +0 -313
  556. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-json.ts +0 -21
  557. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-oauth-routes.ts +0 -157
  558. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-oauth.ts +0 -127
  559. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-tools.ts +0 -100
  560. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-verify.ts +0 -333
  561. package/runtime/node_modules/@metro-labs/mcp/src/daemon/identity.ts +0 -86
  562. package/runtime/node_modules/@metro-labs/mcp/src/daemon/local-mode.ts +0 -158
  563. package/runtime/node_modules/@metro-labs/mcp/src/daemon/local-secret.ts +0 -21
  564. package/runtime/node_modules/@metro-labs/mcp/src/daemon/oauth-pending.ts +0 -65
  565. package/runtime/node_modules/@metro-labs/mcp/src/daemon/pair-codes.ts +0 -58
  566. package/runtime/node_modules/@metro-labs/mcp/src/daemon/project-api.ts +0 -214
  567. package/runtime/node_modules/@metro-labs/mcp/src/daemon/relay.ts +0 -303
  568. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-api.ts +0 -139
  569. package/runtime/node_modules/@metro-labs/mcp/src/daemon/runtime-source.ts +0 -105
  570. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session-apis.ts +0 -52
  571. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session.ts +0 -218
  572. package/runtime/node_modules/@metro-labs/mcp/src/daemon/siwe-auth.ts +0 -82
  573. package/runtime/node_modules/@metro-labs/mcp/src/daemon/siwe-nonces.ts +0 -43
  574. package/runtime/node_modules/@metro-labs/mcp/src/daemon/siwe-routes.ts +0 -89
  575. package/runtime/node_modules/@metro-labs/mcp/src/daemon/tunnel.ts +0 -169
  576. package/runtime/node_modules/@metro-labs/mcp/src/db/account-attach.ts +0 -91
  577. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-admin.ts +0 -214
  578. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-connectors.ts +0 -143
  579. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-map.ts +0 -71
  580. package/runtime/node_modules/@metro-labs/mcp/src/db/client.ts +0 -37
  581. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-config.ts +0 -147
  582. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-relay.ts +0 -126
  583. package/runtime/node_modules/@metro-labs/mcp/src/db/connectors.ts +0 -308
  584. package/runtime/node_modules/@metro-labs/mcp/src/db/file-admin.ts +0 -250
  585. package/runtime/node_modules/@metro-labs/mcp/src/db/projects.ts +0 -309
  586. package/runtime/node_modules/@metro-labs/mcp/src/db/runtime-admin.ts +0 -24
  587. package/runtime/node_modules/@metro-labs/mcp/src/db/runtimes.ts +0 -105
  588. package/runtime/node_modules/@metro-labs/mcp/src/db/schema.ts +0 -118
  589. package/runtime/node_modules/@metro-labs/mcp/src/db/token-carry.ts +0 -45
  590. package/runtime/node_modules/@metro-labs/mcp/src/db/users.ts +0 -72
  591. package/runtime/node_modules/@metro-labs/mcp/src/db/whatsapp-login.ts +0 -18
  592. package/runtime/node_modules/@metro-labs/mcp/src/mcp/channel-owner.ts +0 -29
  593. package/runtime/node_modules/@metro-labs/mcp/src/mcp/frame-scope.ts +0 -21
  594. package/runtime/node_modules/@metro-labs/mcp/src/mcp/index.ts +0 -192
  595. package/runtime/node_modules/@metro-labs/mcp/src/mcp/permission-relay.ts +0 -66
  596. package/runtime/node_modules/@metro-labs/mcp/src/mcp/request-identity.ts +0 -73
  597. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-registry.ts +0 -172
  598. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-route.ts +0 -43
  599. package/runtime/node_modules/@metro-labs/mcp/src/monitor/api.ts +0 -240
  600. package/runtime/node_modules/@metro-labs/mcp/src/server.ts +0 -2
  601. package/runtime/node_modules/@metro-labs/mcp/src/stations/account-store.ts +0 -80
  602. package/runtime/node_modules/@metro-labs/mcp/src/stations/messaging-normalize.ts +0 -88
  603. package/runtime/node_modules/@metro-labs/telegram/src/normalize.ts +0 -22
  604. package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +0 -1
  605. package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +0 -3
  606. package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +0 -22
  607. package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +0 -5
  608. package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +0 -87
  609. package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +0 -55
  610. package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +0 -349
  611. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/log.ts +0 -0
  612. /package/runtime/node_modules/@metro-labs/{mcp/src/mcp → core/src}/str.ts +0 -0
  613. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/train-error.ts +0 -0
  614. /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/webhook-note.ts +0 -0
  615. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/api-error.ts +0 -0
  616. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/cors.ts +0 -0
@@ -0,0 +1,126 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ import { isRecord } from '@metro-labs/core/is-record';
3
+ import { stringOf } from '@metro-labs/http/api-http';
4
+
5
+ type Body = Record<string, unknown>;
6
+
7
+ const TOOL_SEARCH_BETA = /^(advanced-tool-use|tool-search-tool|mid-conversation-tool-changes)-/;
8
+ const PLACEHOLDER = 'DeferredToolPlaceholder';
9
+ const NOTHING_FOUND = 'No matching deferred tools found';
10
+
11
+ const blocksOf = (message: unknown): unknown[] => (isRecord(message) && Array.isArray(message.content) ? message.content : []);
12
+
13
+ const isResult = (block: unknown): block is Body & { content: unknown[] } => isRecord(block) && block.type === 'tool_result' && Array.isArray(block.content);
14
+
15
+ const inlineDefinition = (block: unknown): Body | null =>
16
+ isRecord(block) && block.type === 'tool_addition' && isRecord(block.tool) && block.tool.type === 'tool_definition' && isRecord(block.tool.definition) ? block.tool.definition : null;
17
+
18
+ function loadedName(block: unknown): string | null {
19
+ if (!isRecord(block)) return null;
20
+ if (block.type === 'tool_reference') return stringOf(block.tool_name);
21
+ if (block.type !== 'tool_addition' || !isRecord(block.tool)) return null;
22
+ return stringOf(inlineDefinition(block)?.name ?? block.tool.name);
23
+ }
24
+
25
+ const removedName = (block: unknown): string | null => (isRecord(block) && block.type === 'tool_removal' && isRecord(block.tool) ? stringOf(block.tool.name) : null);
26
+
27
+ const changes = (block: unknown): boolean => loadedName(block) !== null || removedName(block) !== null;
28
+
29
+ const changing = (message: unknown): boolean => blocksOf(message).some((block) => changes(block) || (isResult(block) && block.content.some(changes)));
30
+
31
+ const functionLine = (tool: Body): string =>
32
+ `<function>${JSON.stringify({ description: stringOf(tool.description), name: tool.name, parameters: isRecord(tool.input_schema) ? tool.input_schema : {} })}</function>`;
33
+
34
+ function functionsText(blocks: unknown[], catalog: Map<string, Body>): string {
35
+ const lines = blocks.flatMap((block) => {
36
+ const tool = catalog.get(loadedName(block) ?? '');
37
+ return tool === undefined ? [] : [functionLine(tool)];
38
+ });
39
+ return lines.length === 0 ? NOTHING_FOUND : ['<functions>', ...lines, '</functions>'].join('\n');
40
+ }
41
+
42
+ const cacheOf = (blocks: unknown[]): Body => {
43
+ const marked = blocks.find((block) => isRecord(block) && block.cache_control !== undefined);
44
+ return isRecord(marked) ? { cache_control: marked.cache_control } : {};
45
+ };
46
+
47
+ function expanded(blocks: unknown[], catalog: Map<string, Body>): unknown[] {
48
+ const found = blocks.filter((block) => loadedName(block) !== null);
49
+ return blocks.flatMap((block) => {
50
+ if (block === found[0]) return [{ type: 'text', text: functionsText(found, catalog), ...cacheOf(found) }];
51
+ if (loadedName(block) !== null) return [];
52
+ const removed = removedName(block);
53
+ return removed === null ? [block] : [{ type: 'text', text: `Tool ${removed} is no longer available.`, ...cacheOf([block]) }];
54
+ });
55
+ }
56
+
57
+ const expandedBlock = (block: unknown, catalog: Map<string, Body>): unknown =>
58
+ isResult(block) && block.content.some(changes) ? { ...block, content: expanded(block.content, catalog) } : block;
59
+
60
+ function expandedMessage(message: unknown, catalog: Map<string, Body>): unknown {
61
+ if (!changing(message) || !isRecord(message)) return message;
62
+ return { ...message, content: expanded(blocksOf(message).map((block) => expandedBlock(block, catalog)), catalog) };
63
+ }
64
+
65
+ interface Found {
66
+ names: Set<string>;
67
+ inline: Map<string, Body>;
68
+ }
69
+
70
+ function foundIn(messages: unknown[]): Found {
71
+ const found: Found = { names: new Set(), inline: new Map() };
72
+ const blocks = messages.flatMap(blocksOf).flatMap((block) => (isResult(block) ? block.content : [block]));
73
+ for (const block of blocks) {
74
+ const name = loadedName(block);
75
+ const definition = inlineDefinition(block);
76
+ if (name !== null) found.names.add(name);
77
+ if (definition !== null) found.inline.set(stringOf(definition.name), definition);
78
+ const removed = removedName(block);
79
+ if (removed === null) continue;
80
+ found.names.delete(removed);
81
+ found.inline.delete(removed);
82
+ }
83
+ return found;
84
+ }
85
+
86
+ const deferred = (tool: unknown): boolean => isRecord(tool) && tool.defer_loading === true;
87
+
88
+ const loaded = (tool: unknown): unknown =>
89
+ isRecord(tool) && 'defer_loading' in tool ? Object.fromEntries(Object.entries(tool).filter(([key]) => key !== 'defer_loading')) : tool;
90
+
91
+ const deferring = (tools: unknown): boolean => Array.isArray(tools) && tools.some((tool) => isRecord(tool) && 'defer_loading' in tool);
92
+
93
+ const nameOf = (tool: unknown): string => (isRecord(tool) ? stringOf(tool.name) : '');
94
+
95
+ export function resolveToolSearch(body: Body): Body {
96
+ const messages: unknown[] = Array.isArray(body.messages) ? body.messages : [];
97
+ if (!deferring(body.tools) && !messages.some(changing)) return body;
98
+ const declared: unknown[] = Array.isArray(body.tools) ? body.tools : [];
99
+ const found = foundIn(messages);
100
+ const shown = declared.filter((tool) => nameOf(tool) !== PLACEHOLDER && (!deferred(tool) || found.names.has(nameOf(tool)))).map(loaded);
101
+ const known = new Set(shown.map(nameOf));
102
+ const inline = [...found.inline.values()].filter((tool) => !known.has(nameOf(tool))).map(loaded);
103
+ const tools = [...shown, ...inline];
104
+ const catalog = new Map([...declared, ...inline].filter(isRecord).map((tool) => [nameOf(tool), tool]));
105
+ return {
106
+ ...body,
107
+ ...(Array.isArray(body.tools) || inline.length > 0 ? { tools } : {}),
108
+ ...(Array.isArray(body.messages) ? { messages: messages.map((message) => expandedMessage(message, catalog)) } : {}),
109
+ };
110
+ }
111
+
112
+ function dropToolSearchBeta(req: IncomingMessage): void {
113
+ const raw = req.headers['anthropic-beta'];
114
+ if (typeof raw !== 'string') return;
115
+ const kept = raw
116
+ .split(',')
117
+ .map((beta) => beta.trim())
118
+ .filter((beta) => beta !== '' && !TOOL_SEARCH_BETA.test(beta));
119
+ if (kept.length > 0) req.headers['anthropic-beta'] = kept.join(',');
120
+ else delete req.headers['anthropic-beta'];
121
+ }
122
+
123
+ export function fitToolSearch(req: IncomingMessage, body: Body): Body {
124
+ dropToolSearchBeta(req);
125
+ return resolveToolSearch(body);
126
+ }
@@ -0,0 +1,51 @@
1
+ import { errMsg, log } from '@metro-labs/core/log';
2
+ import { openrouterKey } from './openrouter.js';
3
+ import { mayProbe, noteUsage, openrouterUsage, usageOf } from './usage.js';
4
+ import type { Connection, ModelSetup } from './model-config.js';
5
+
6
+ export const CREDITS_TTL_MS = 5 * 60_000;
7
+ const WAIT_MS = 4_000;
8
+
9
+ export interface UsageDeps {
10
+ fetchImpl?: typeof fetch;
11
+ openrouterBase?: string;
12
+ usageWaitMs?: number;
13
+ }
14
+
15
+ const fresh = (id: string, now: number): boolean => {
16
+ const seen = usageOf(id);
17
+ return seen !== undefined && now - Date.parse(seen.at) < CREDITS_TTL_MS;
18
+ };
19
+
20
+ async function refreshKey(conn: Connection, deps: UsageDeps, now: number): Promise<void> {
21
+ if (conn.provider !== 'openrouter' || conn.apiKey === '' || fresh(conn.id, now) || !mayProbe(conn.id, now, CREDITS_TTL_MS)) return;
22
+ try {
23
+ noteUsage(conn.id, openrouterUsage(await openrouterKey(conn.apiKey, deps.openrouterBase, deps.fetchImpl), new Date(now)));
24
+ } catch (err) {
25
+ log.warn({ err: errMsg(err) }, 'model-api: could not read the OpenRouter key spend');
26
+ }
27
+ }
28
+
29
+ async function within(ms: number, work: Promise<unknown>): Promise<void> {
30
+ let timer: ReturnType<typeof setTimeout> | undefined;
31
+ const waited = new Promise<void>((resolve) => {
32
+ timer = setTimeout(resolve, ms);
33
+ });
34
+ await Promise.race([work, waited]);
35
+ clearTimeout(timer);
36
+ }
37
+
38
+ export async function refreshUsage(setup: ModelSetup, deps: UsageDeps = {}, now = Date.now()): Promise<void> {
39
+ await within(deps.usageWaitMs ?? WAIT_MS, Promise.all(setup.connections.map((conn) => refreshKey(conn, deps, now))));
40
+ }
41
+
42
+ export function watchFallbackUsage(setup: () => ModelSetup, deps: UsageDeps = {}, every = CREDITS_TTL_MS): void {
43
+ const run = (): void => {
44
+ const current = setup();
45
+ if (current.fallbacks.length === 0 && (current.helpers ?? null) === null) return;
46
+ refreshUsage(current, deps).catch((err: unknown) => {
47
+ log.warn({ err: errMsg(err) }, 'model-api: could not refresh the usage of the fallback models');
48
+ });
49
+ };
50
+ setInterval(run, every).unref();
51
+ }
@@ -0,0 +1,265 @@
1
+ type Key = string;
2
+
3
+ export interface UsageWindow {
4
+ label: string;
5
+ used: number | null;
6
+ resetAt: string | null;
7
+ detail: string | null;
8
+ }
9
+
10
+ interface Tally {
11
+ requests: number;
12
+ input: number;
13
+ output: number;
14
+ cached: number;
15
+ since: string;
16
+ }
17
+
18
+ export interface ProviderUsage {
19
+ windows: UsageWindow[];
20
+ note: string | null;
21
+ at: string;
22
+ tally: Tally | null;
23
+ }
24
+
25
+ export type Reported = Omit<ProviderUsage, 'tally'>;
26
+
27
+ const latest = new Map<Key, Reported>();
28
+ const stamps = new Map<Key, Map<string, number>>();
29
+ const tallies = new Map<Key, Tally>();
30
+ const probed = new Map<Key, number>();
31
+
32
+ export const noteUsage = (key: Key, usage: Reported): void => {
33
+ latest.set(key, usage);
34
+ stamps.set(key, new Map(usage.windows.map((w) => [w.label, Date.parse(usage.at)])));
35
+ };
36
+
37
+ function mergeUsage(key: Key, usage: Reported): void {
38
+ const seen = latest.get(key);
39
+ const marks = stamps.get(key);
40
+ if (seen === undefined || marks === undefined) {
41
+ noteUsage(key, usage);
42
+ return;
43
+ }
44
+ const at = Date.parse(usage.at);
45
+ const newer = new Map(usage.windows.filter((w) => (marks.get(w.label) ?? Number.NEGATIVE_INFINITY) <= at).map((w) => [w.label, w]));
46
+ for (const label of newer.keys()) marks.set(label, at);
47
+ const kept = seen.windows.map((w) => newer.get(w.label) ?? w);
48
+ const added = [...newer.values()].filter((w) => !seen.windows.some((old) => old.label === w.label));
49
+ const later = Date.parse(seen.at) <= at;
50
+ latest.set(key, { windows: [...kept, ...added], note: later ? usage.note : seen.note, at: later ? usage.at : seen.at });
51
+ }
52
+
53
+ export function usageSeen(): Record<Key, ProviderUsage> {
54
+ const out: Record<Key, ProviderUsage> = {};
55
+ for (const key of new Set<Key>([...latest.keys(), ...tallies.keys()])) {
56
+ const reported = latest.get(key);
57
+ const tally = tallies.get(key) ?? null;
58
+ out[key] = reported === undefined ? { windows: [], note: null, at: tally?.since ?? new Date().toISOString(), tally } : { ...reported, tally };
59
+ }
60
+ return out;
61
+ }
62
+
63
+ export const usageOf = (key: Key): Reported | undefined => latest.get(key);
64
+
65
+ export const forgetUsage = (): void => {
66
+ latest.clear();
67
+ stamps.clear();
68
+ tallies.clear();
69
+ probed.clear();
70
+ };
71
+
72
+ export function mayProbe(key: Key, now: number, every: number): boolean {
73
+ if (now - (probed.get(key) ?? Number.NEGATIVE_INFINITY) < every) return false;
74
+ probed.set(key, now);
75
+ return true;
76
+ }
77
+
78
+ export interface Counted {
79
+ input: number;
80
+ output: number;
81
+ cached: number;
82
+ }
83
+
84
+ export function tallyTokens(key: Key, counted: Counted, now = new Date()): void {
85
+ const so = tallies.get(key) ?? { requests: 0, input: 0, output: 0, cached: 0, since: now.toISOString() };
86
+ tallies.set(key, {
87
+ requests: so.requests + 1,
88
+ input: so.input + counted.input,
89
+ output: so.output + counted.output,
90
+ cached: so.cached + counted.cached,
91
+ since: so.since,
92
+ });
93
+ }
94
+
95
+ const TOKEN_FIELD = /"(input_tokens|output_tokens|cache_read_input_tokens|cache_creation_input_tokens)"\s*:\s*(\d+)/g;
96
+
97
+ export class UsageScanner {
98
+ private carry = '';
99
+ private readonly max = { input: 0, output: 0, read: 0, creation: 0 };
100
+ private touched = false;
101
+
102
+ constructor(private readonly key: Key) {}
103
+
104
+ private scan(text: string): void {
105
+ for (const hit of text.matchAll(TOKEN_FIELD)) {
106
+ const value = Number(hit[2]);
107
+ if (!Number.isFinite(value)) continue;
108
+ this.touched = true;
109
+ if (hit[1] === 'input_tokens') this.max.input = Math.max(this.max.input, value);
110
+ else if (hit[1] === 'output_tokens') this.max.output = Math.max(this.max.output, value);
111
+ else if (hit[1] === 'cache_read_input_tokens') this.max.read = Math.max(this.max.read, value);
112
+ else this.max.creation = Math.max(this.max.creation, value);
113
+ }
114
+ }
115
+
116
+ feed(text: string): void {
117
+ const joined = this.carry + text;
118
+ const cut = joined.lastIndexOf('\n');
119
+ if (cut === -1) {
120
+ this.carry = joined;
121
+ return;
122
+ }
123
+ this.scan(joined.slice(0, cut));
124
+ this.carry = joined.slice(cut + 1);
125
+ }
126
+
127
+ done(now = new Date()): void {
128
+ if (this.carry !== '') this.scan(this.carry);
129
+ this.carry = '';
130
+ if (!this.touched) return;
131
+ tallyTokens(this.key, { input: this.max.input, output: this.max.output, cached: this.max.read + this.max.creation }, now);
132
+ this.touched = false;
133
+ }
134
+ }
135
+
136
+ const clamp = (value: number): number => Math.min(1, Math.max(0, value));
137
+
138
+ function fraction(raw: string | null): number | null {
139
+ if (raw === null) return null;
140
+ const value = Number(raw);
141
+ return Number.isFinite(value) ? clamp(value) : null;
142
+ }
143
+
144
+ const MS_THRESHOLD = 1e12;
145
+
146
+ function whenFrom(raw: string | null, now: Date, relative = false): string | null {
147
+ if (raw === null || raw.trim() === '') return null;
148
+ const numeric = Number(raw);
149
+ if (Number.isFinite(numeric)) {
150
+ const absolute = numeric > MS_THRESHOLD ? numeric : numeric * 1000;
151
+ const ms = relative ? now.getTime() + numeric * 1000 : absolute;
152
+ return new Date(ms).toISOString();
153
+ }
154
+ const parsed = Date.parse(raw);
155
+ return Number.isNaN(parsed) ? null : new Date(parsed).toISOString();
156
+ }
157
+
158
+ const ANTHROPIC_WINDOWS: [string, string][] = [
159
+ ['5h', '5-hour window'],
160
+ ['7d', 'Weekly, all models'],
161
+ ['7d_sonnet', 'Weekly, Sonnet'],
162
+ ];
163
+
164
+ function anthropicUnified(headers: Headers, now: Date): { windows: UsageWindow[]; note: string | null } {
165
+ const windows: UsageWindow[] = [];
166
+ let note: string | null = null;
167
+ for (const [key, label] of ANTHROPIC_WINDOWS) {
168
+ const used = fraction(headers.get(`anthropic-ratelimit-unified-${key}-utilization`));
169
+ if (used === null) continue;
170
+ const status = headers.get(`anthropic-ratelimit-unified-${key}-status`);
171
+ const blocked = status !== null && status !== 'allowed' ? status.replaceAll('_', ' ') : null;
172
+ if (blocked !== null && note === null) note = `${label}: ${blocked}`;
173
+ windows.push({ label, used, resetAt: whenFrom(headers.get(`anthropic-ratelimit-unified-${key}-reset`), now), detail: blocked });
174
+ }
175
+ return { windows, note };
176
+ }
177
+
178
+ export const PER_MINUTE = 'Tokens per minute';
179
+
180
+ function anthropicKeyed(headers: Headers, now: Date): UsageWindow[] {
181
+ const limit = Number(headers.get('anthropic-ratelimit-tokens-limit'));
182
+ const remaining = Number(headers.get('anthropic-ratelimit-tokens-remaining'));
183
+ if (!Number.isFinite(limit) || !Number.isFinite(remaining) || limit <= 0) return [];
184
+ return [
185
+ {
186
+ label: PER_MINUTE,
187
+ used: clamp(1 - remaining / limit),
188
+ resetAt: whenFrom(headers.get('anthropic-ratelimit-tokens-reset'), now),
189
+ detail: `${remaining.toLocaleString('en-US')} of ${limit.toLocaleString('en-US')} left`,
190
+ },
191
+ ];
192
+ }
193
+
194
+ export function anthropicUsage(headers: Headers, now = new Date()): Reported | null {
195
+ const unified = anthropicUnified(headers, now);
196
+ if (unified.windows.length > 0) return { ...unified, at: now.toISOString() };
197
+ const keyed = anthropicKeyed(headers, now);
198
+ return keyed.length === 0 ? null : { windows: keyed, note: null, at: now.toISOString() };
199
+ }
200
+
201
+ const MINUTES_PER_HOUR = 60;
202
+ const MINUTES_PER_DAY = 24 * MINUTES_PER_HOUR;
203
+ const MINUTES_PER_WEEK = 7 * MINUTES_PER_DAY;
204
+
205
+ export function windowLabel(minutes: number | null): string {
206
+ if (minutes === null || !Number.isFinite(minutes) || minutes <= 0) return 'Usage window';
207
+ if (minutes === MINUTES_PER_WEEK) return 'Weekly';
208
+ if (minutes % MINUTES_PER_DAY === 0) return `${String(minutes / MINUTES_PER_DAY)}-day window`;
209
+ if (minutes % MINUTES_PER_HOUR === 0) return `${String(minutes / MINUTES_PER_HOUR)}-hour window`;
210
+ return `${String(minutes)}-minute window`;
211
+ }
212
+
213
+ function codexWindow(headers: Headers, kind: 'primary' | 'secondary', now: Date): UsageWindow | null {
214
+ const raw = headers.get(`x-codex-${kind}-used-percent`);
215
+ if (raw === null) return null;
216
+ const percent = Number(raw);
217
+ if (!Number.isFinite(percent)) return null;
218
+ const used = clamp(percent / 100);
219
+ const minutes = Number(headers.get(`x-codex-${kind}-window-minutes`) ?? 'none');
220
+ const absolute = whenFrom(headers.get(`x-codex-${kind}-reset-at`), now);
221
+ const resetAt = absolute ?? whenFrom(headers.get(`x-codex-${kind}-reset-after-seconds`), now, true);
222
+ return { label: windowLabel(Number.isFinite(minutes) ? minutes : null), used, resetAt, detail: null };
223
+ }
224
+
225
+ function creditsLeft(hasCredits: boolean, raw: string | null): UsageWindow | null {
226
+ if (!hasCredits) return null;
227
+ const balance = Number(raw ?? 'none');
228
+ if (!Number.isFinite(balance)) return null;
229
+ return { label: 'Credits', used: null, resetAt: null, detail: `${balance.toLocaleString('en-US')} left` };
230
+ }
231
+
232
+ const codexCredits = (headers: Headers): UsageWindow | null =>
233
+ creditsLeft(headers.get('x-codex-credits-has-credits') === 'true', headers.get('x-codex-credits-balance'));
234
+
235
+ export function codexUsage(headers: Headers, now = new Date()): Reported | null {
236
+ const windows = [codexWindow(headers, 'primary', now), codexWindow(headers, 'secondary', now), codexCredits(headers)].filter(
237
+ (w): w is UsageWindow => w !== null,
238
+ );
239
+ if (windows.length === 0) return null;
240
+ const reached = headers.get('x-codex-rate-limit-reached-type');
241
+ return { windows, note: reached === null || reached === '' ? null : reached.replaceAll('_', ' '), at: now.toISOString() };
242
+ }
243
+
244
+ export function noteUsageHeaders(kind: 'anthropic' | 'codex', key: Key, headers: Headers, now = new Date()): void {
245
+ const usage = kind === 'anthropic' ? anthropicUsage(headers, now) : codexUsage(headers, now);
246
+ if (usage === null) return;
247
+ if (kind === 'anthropic') mergeUsage(key, usage);
248
+ else noteUsage(key, usage);
249
+ }
250
+
251
+ const dollars = (value: number): string => `$${value.toFixed(2)}`;
252
+
253
+ export interface KeySpend {
254
+ limit: number | null;
255
+ remaining: number | null;
256
+ spent: number;
257
+ }
258
+
259
+ function keyWindow(key: KeySpend): UsageWindow {
260
+ if (key.limit === null || key.limit <= 0) return { label: 'Credits', used: null, resetAt: null, detail: `${dollars(key.spent)} used, no limit on this key` };
261
+ const spent = key.remaining === null ? key.spent : Math.max(0, key.limit - key.remaining);
262
+ return { label: 'Credits', used: clamp(spent / key.limit), resetAt: null, detail: `${dollars(spent)} of ${dollars(key.limit)} used` };
263
+ }
264
+
265
+ export const openrouterUsage = (key: KeySpend, now = new Date()): Reported => ({ windows: [keyWindow(key)], note: null, at: now.toISOString() });
@@ -1,17 +1,13 @@
1
- import { forwardTrainCall } from '../daemon/train-call.js';
1
+ import { storedPolicy } from '../policy/policy.js';
2
+ import { forwardTrainCall } from '../stations/train-call.js';
2
3
  import {
3
4
  accountStationNames,
4
5
  stationByName,
5
6
  } from '../stations/registry.js';
6
- import { listEndpoints } from '../daemon/tunnel.js';
7
- import { hookUrl } from '../stations/attach.js';
8
- import { agentIdForAccount } from '../db/agent-map.js';
9
- import {
10
- listAllStations,
11
- stationRunsHere,
12
- type StationRecord,
13
- } from '../db/materialize.js';
14
- import { type StationName } from '../db/schema.js';
7
+ import { listEndpoints } from '../stations/webhook-endpoints.js';
8
+ import { hookUrl, threemaCallbackUrl } from '../stations/attach.js';
9
+ import { accountStatusOf } from '@metro-labs/core/stations/account-status';
10
+ import { accountEnabled, agentIdForAccount, allowlistForAccount, approversForAccount, knownAccounts, type KnownAccount } from '../agents/map.js';
15
11
 
16
12
  const accountId = (acc: unknown): string | undefined => {
17
13
  const id = (acc as { id?: unknown }).id;
@@ -29,7 +25,14 @@ function withAgentId(station: string, acc: unknown): unknown {
29
25
  const id = typeof rec.id === 'string' ? rec.id : undefined;
30
26
  if (id === undefined) return acc;
31
27
  const agentId = agentIdForAccount(station, id);
32
- return agentId === undefined ? acc : { ...rec, agentId };
28
+ if (agentId === undefined) return acc;
29
+ const allowlist = allowlistForAccount(station, id);
30
+ const stored = storedPolicy({ kind: 'channel', station, account: id });
31
+ const policy = stored === undefined ? {} : { policy: stored };
32
+ const approvers = approversForAccount(station, id);
33
+ const extra = approvers.length === 0 ? policy : { ...policy, approvers };
34
+ const tagged = allowlist === undefined ? { ...rec, agentId, ...extra } : { ...rec, agentId, allowlist, ...extra };
35
+ return accountEnabled(station, id) ? tagged : { ...tagged, enabled: false };
33
36
  }
34
37
 
35
38
  export function attachAgentIds(
@@ -75,6 +78,42 @@ function inCoreAccounts(station: string): unknown[] {
75
78
  );
76
79
  }
77
80
 
81
+ function withCallbackUrl(acc: unknown): unknown {
82
+ const rec = asRecord(acc);
83
+ if (rec === undefined) return acc;
84
+ const { callbackId, callbackToken, ...rest } = rec;
85
+ if (typeof callbackId !== 'string' || typeof callbackToken !== 'string') return rest;
86
+ return { ...rest, callback: threemaCallbackUrl(callbackId, callbackToken) };
87
+ }
88
+
89
+ function withStatus(reports: boolean, acc: unknown): unknown {
90
+ const rec = asRecord(acc);
91
+ if (rec === undefined || !('status' in rec)) return acc;
92
+ const { status, ...rest } = rec;
93
+ const live = reports ? accountStatusOf(status) : null;
94
+ return live === null ? rest : { ...rest, status: live };
95
+ }
96
+
97
+ function decorate(station: string, rows: unknown[]): unknown[] {
98
+ const reports = stationByName(station)?.reportsStatus === true;
99
+ const live = rows.map((row) => withStatus(reports, row));
100
+ return station === 'threema' ? live.map(withCallbackUrl) : live;
101
+ }
102
+
103
+ const STATUS_WAIT_MS = 5_000;
104
+
105
+ function answerIn<T>(call: Promise<T>, ms: number): Promise<T> {
106
+ let timer: ReturnType<typeof setTimeout> | undefined;
107
+ const late = new Promise<never>((_resolve, reject) => {
108
+ timer = setTimeout(() => {
109
+ reject(new Error(`no answer within ${String(ms)} ms`));
110
+ }, ms);
111
+ });
112
+ return Promise.race([call, late]).finally(() => {
113
+ clearTimeout(timer);
114
+ });
115
+ }
116
+
78
117
  export interface ScopedAccounts {
79
118
  accounts: Record<string, unknown[]>;
80
119
  unavailable: string[];
@@ -85,12 +124,11 @@ async function liveAccounts(
85
124
  ): Promise<{ rows: unknown[]; reachable: boolean }> {
86
125
  if (!hasTrain(station))
87
126
  return { rows: inCoreAccounts(station), reachable: true };
88
- if (!stationRunsHere(station as StationName))
89
- return { rows: [], reachable: true };
90
127
  try {
91
- const resp = await forwardTrainCall(station, 'accounts', {});
128
+ const call = forwardTrainCall(station, 'accounts', {});
129
+ const resp = await (stationByName(station)?.reportsStatus === true ? answerIn(call, STATUS_WAIT_MS) : call);
92
130
  const list = (resp.result as { accounts?: unknown[] } | undefined)?.accounts;
93
- return { rows: Array.isArray(list) ? list : [], reachable: true };
131
+ return { rows: decorate(station, Array.isArray(list) ? list : []), reachable: true };
94
132
  } catch {
95
133
  return { rows: [], reachable: false };
96
134
  }
@@ -99,7 +137,7 @@ async function liveAccounts(
99
137
  function mergeKnown(
100
138
  station: string,
101
139
  live: unknown[],
102
- known: StationRecord[],
140
+ known: KnownAccount[],
103
141
  ): unknown[] {
104
142
  const seen = new Set(
105
143
  live.flatMap((row) => {
@@ -116,22 +154,31 @@ function mergeKnown(
116
154
  async function loadStations(): Promise<ScopedAccounts> {
117
155
  const unavailable: string[] = [];
118
156
  const accounts: Record<string, unknown[]> = {};
119
- const known = await listAllStations();
157
+ const known = knownAccounts();
120
158
  await Promise.all(
121
159
  accountStationNames().map(async (station) => {
122
160
  const { rows, reachable } = await liveAccounts(station);
123
161
  if (!reachable) unavailable.push(station);
124
- accounts[station] = mergeKnown(station, rows, known);
162
+ accounts[station] = hasTrain(station) ? mergeKnown(station, rows, known) : rows;
125
163
  }),
126
164
  );
127
165
  return { accounts, unavailable };
128
166
  }
129
167
 
168
+ const URL_SECRETS = new Set(['endpoint', 'callback']);
169
+
170
+ function withoutUrlSecrets(acc: unknown): unknown {
171
+ const rec = asRecord(acc);
172
+ if (rec === undefined) return acc;
173
+ return Object.fromEntries(Object.entries(rec).filter(([key]) => !URL_SECRETS.has(key)));
174
+ }
175
+
130
176
  export async function gatherAccounts(
131
177
  allowedAgents?: Set<string>,
132
178
  ): Promise<Record<string, unknown[]>> {
133
179
  const { accounts } = await loadStations();
134
- return allowedAgents ? scopeAccountsByAgent(accounts, allowedAgents) : accounts;
180
+ const scoped = allowedAgents ? scopeAccountsByAgent(accounts, allowedAgents) : accounts;
181
+ return Object.fromEntries(Object.entries(scoped).map(([station, rows]) => [station, rows.map(withoutUrlSecrets)]));
135
182
  }
136
183
 
137
184
  export async function gatherAccountsForAgents(
@@ -0,0 +1,91 @@
1
+ import type { ToolDef } from './tool-def.js';
2
+
3
+ export const attachmentItem = {
4
+ type: 'object',
5
+ description:
6
+ 'A file to attach. Provide EXACTLY ONE source; naming two is an error and so is naming ' +
7
+ 'none. Which one to use: `upload` for any real file on your own machine, including a ' +
8
+ 'confidential one (call `create_upload` first, push the bytes over HTTP, then name the ' +
9
+ 'id here); `data` ONLY for a tiny file, a few KB at most, because the base64 has to be ' +
10
+ 'written out verbatim in this tool call and long base64 gets corrupted in the writing; ' +
11
+ '`url` when the file is ALREADY published somewhere the daemon can fetch it; `path` ONLY ' +
12
+ 'for a file that is already sitting on the daemon host, which is almost never your ' +
13
+ 'machine.',
14
+ properties: {
15
+ upload: {
16
+ type: 'string',
17
+ description:
18
+ 'The `upload_id` of a file already pushed to metro over HTTP (`create_upload` mints ' +
19
+ 'the slot and the one-line command; the bytes never pass through this conversation). ' +
20
+ 'THIS IS THE ROUTE FOR ANYTHING REAL: it takes files up to 64 MiB, works for a file on ' +
21
+ 'your own machine, and publishes nothing. The upload belongs to your agent, expires ' +
22
+ '30 minutes after it is created, and no other agent can name it.',
23
+ },
24
+ data: {
25
+ type: 'string',
26
+ description:
27
+ 'Base64-encoded file bytes, inline in this call. ONLY FOR TINY FILES. The hard cap is ' +
28
+ '8 MiB decoded, but the real ceiling is far lower and is not enforced by the daemon: ' +
29
+ 'this base64 has to be emitted verbatim as part of the tool call, and past roughly ' +
30
+ '10 KB (~13 KB of base64) it comes out corrupted, so the file arrives silently ' +
31
+ 'damaged or fails to decode. Use `upload` instead for anything bigger. A ' +
32
+ '`data:<mime>;base64,` prefix is accepted and supplies the mime when `mime` is ' +
33
+ 'omitted. Stations impose their own, lower limits (xmtp refuses non-image files over ' +
34
+ '~190 KiB).',
35
+ },
36
+ url: {
37
+ type: 'string',
38
+ description:
39
+ 'http(s) URL fetched BY THE DAEMON, so it must already be publicly reachable from the ' +
40
+ 'daemon host. Right when the file is already published; never for anything ' +
41
+ 'confidential, because it has to be public for this to work at all. Use `upload` for ' +
42
+ 'a confidential file.',
43
+ },
44
+ path: {
45
+ type: 'string',
46
+ description:
47
+ 'Absolute path resolved ON THE DAEMON HOST, which is a different machine from yours. ' +
48
+ 'A path on your own disk does NOT resolve here and is refused, however local it ' +
49
+ 'looks. Use `upload` for a file on your machine.',
50
+ },
51
+ mime: {
52
+ type: 'string',
53
+ description: 'MIME type (guessed from the name/extension if omitted).',
54
+ },
55
+ name: {
56
+ type: 'string',
57
+ description:
58
+ 'Filename to present (defaults to the basename, or to the name given at upload time).',
59
+ },
60
+ },
61
+ } as const;
62
+
63
+ export const CREATE_UPLOAD_TOOL: ToolDef = {
64
+ name: 'create_upload',
65
+ group: 'write',
66
+ description:
67
+ 'Reserve a slot to push a file to metro over HTTP so you can attach it with `send`. Use ' +
68
+ 'this for any file that actually matters: it is the only attachment route that carries a ' +
69
+ 'file from YOUR machine without publishing it and without the bytes passing through this ' +
70
+ 'conversation. Args: name? (the filename to present), mime?. Returns `upload_id`, a ' +
71
+ 'single-use `upload_url` and a ready-to-run `curl` line. ONE STEP NEEDS A SHELL: run that ' +
72
+ 'command (or any HTTP client) to push the bytes; there is no way to move a local file to ' +
73
+ 'the daemon over MCP alone, because anything in an MCP call has to be written out by the ' +
74
+ 'model first. If you have no shell, hand the single command to a subagent that does and ' +
75
+ 'keep the `upload_id` -- the slot belongs to this metro agent, not to whoever runs the ' +
76
+ 'command. Then: send({line, attachments:[{upload:"<upload_id>"}]}). Up to 64 MiB, expires ' +
77
+ '30 minutes after it is created, and no other agent can reference it.',
78
+ inputSchema: {
79
+ type: 'object',
80
+ properties: {
81
+ name: {
82
+ type: 'string',
83
+ description: 'Filename to present to the recipient (e.g. `report.pdf`).',
84
+ },
85
+ mime: {
86
+ type: 'string',
87
+ description: 'MIME type (guessed from the name/extension if omitted).',
88
+ },
89
+ },
90
+ },
91
+ };