@stage-labs/metro 0.1.0-beta.31 → 0.1.0-beta.310

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 (617) 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 +104 -0
  6. package/dist/claude-settings.js +40 -0
  7. package/dist/cli.js +62 -136
  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 -52
  20. package/dist/serve.js +157 -0
  21. package/dist/service.js +328 -0
  22. package/dist/tail.js +10 -11
  23. package/dist/update.js +13 -1
  24. package/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 +58 -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/endpoints.ts +7 -0
  34. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/events.ts +54 -6
  35. package/runtime/node_modules/@metro-labs/{mcp/src/db → core/src}/ids.ts +10 -1
  36. package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  37. package/runtime/node_modules/@metro-labs/{mcp/src/stations → core/src}/lines.ts +22 -26
  38. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/protocol.ts +7 -4
  39. package/runtime/node_modules/@metro-labs/core/src/runner-activity.ts +270 -0
  40. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/secure-fs.ts +17 -0
  41. package/runtime/node_modules/@metro-labs/core/src/skill-source.ts +96 -0
  42. package/runtime/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  43. package/runtime/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  44. package/runtime/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  45. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/attachments.ts +9 -3
  46. package/runtime/node_modules/@metro-labs/core/src/stations/channel-directory.ts +159 -0
  47. package/runtime/node_modules/@metro-labs/core/src/stations/channel-pages.ts +129 -0
  48. package/runtime/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  49. package/runtime/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  50. package/runtime/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  51. package/runtime/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  52. package/runtime/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  53. package/runtime/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  54. package/runtime/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  55. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/station-runtime.ts +6 -11
  56. package/runtime/node_modules/@metro-labs/core/src/stations/train-boot.ts +63 -0
  57. package/runtime/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  58. package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/types.ts +20 -1
  59. package/runtime/node_modules/@metro-labs/core/src/tickets.ts +44 -0
  60. package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
  61. package/runtime/node_modules/@metro-labs/daemon/package.json +51 -0
  62. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/agent-fs.ts +246 -0
  63. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/crontab.ts +44 -0
  64. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files-api.ts +12 -0
  65. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files.ts +89 -0
  66. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/home-fs.ts +86 -0
  67. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/job-env.ts +39 -0
  68. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/metro-home.ts +42 -0
  69. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/provision.ts +57 -0
  70. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedule-detail.ts +93 -0
  71. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules-api.ts +27 -0
  72. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules.ts +144 -0
  73. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/unit-files.ts +43 -0
  74. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/user.ts +110 -0
  75. package/runtime/node_modules/@metro-labs/daemon/src/agent-user/view.ts +90 -0
  76. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
  77. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-lookups.ts +55 -0
  78. package/runtime/node_modules/@metro-labs/daemon/src/agents/account-routes.ts +76 -0
  79. package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +362 -0
  80. package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +30 -0
  81. package/runtime/node_modules/@metro-labs/daemon/src/agents/allowlist.ts +59 -0
  82. package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +131 -0
  83. package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +124 -0
  84. package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +317 -0
  85. package/runtime/node_modules/@metro-labs/daemon/src/agents/files.ts +142 -0
  86. package/runtime/node_modules/@metro-labs/{mcp/src/db/key-map.ts → daemon/src/agents/keys.ts} +1 -11
  87. package/runtime/node_modules/@metro-labs/daemon/src/agents/map.ts +135 -0
  88. package/runtime/node_modules/@metro-labs/daemon/src/agents/policy-route.ts +27 -0
  89. package/runtime/node_modules/@metro-labs/{mcp/src/db/agent-scope.ts → daemon/src/agents/scope.ts} +2 -2
  90. package/runtime/node_modules/@metro-labs/daemon/src/agents/sender-cards.ts +94 -0
  91. package/runtime/node_modules/@metro-labs/daemon/src/agents/senders.ts +38 -0
  92. package/runtime/node_modules/@metro-labs/daemon/src/approvals/api.ts +55 -0
  93. package/runtime/node_modules/@metro-labs/daemon/src/approvals/owner-line.ts +45 -0
  94. package/runtime/node_modules/@metro-labs/daemon/src/approvals/pending.ts +190 -0
  95. package/runtime/node_modules/@metro-labs/daemon/src/approvals/preview.ts +66 -0
  96. package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +264 -0
  97. package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +36 -0
  98. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/crash-guard.ts +1 -1
  99. package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +21 -0
  100. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/paths.ts +8 -36
  101. package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +26 -0
  102. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/inbound.ts +99 -73
  103. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/media-note.ts +11 -7
  104. package/runtime/node_modules/@metro-labs/daemon/src/channels/notice.ts +22 -0
  105. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/pending.ts +13 -1
  106. package/runtime/node_modules/@metro-labs/daemon/src/channels/react-note.ts +13 -0
  107. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/relay.ts +6 -2
  108. package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +304 -0
  109. package/runtime/node_modules/@metro-labs/daemon/src/claude/cli-files.ts +28 -0
  110. package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +359 -0
  111. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-api.ts +12 -0
  112. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-fetch.ts +160 -0
  113. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-skills.ts +255 -0
  114. package/runtime/node_modules/@metro-labs/daemon/src/claude/github-validate.ts +53 -0
  115. package/runtime/node_modules/@metro-labs/daemon/src/claude/hooks.ts +60 -0
  116. package/runtime/node_modules/@metro-labs/daemon/src/claude/login.ts +243 -0
  117. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory-routine.ts +123 -0
  118. package/runtime/node_modules/@metro-labs/daemon/src/claude/memory.ts +32 -0
  119. package/runtime/node_modules/@metro-labs/daemon/src/claude/onboarding.ts +38 -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 +303 -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 +323 -0
  128. package/runtime/node_modules/@metro-labs/daemon/src/claude/skills.ts +123 -0
  129. package/runtime/node_modules/@metro-labs/daemon/src/claude/usage-probe.ts +128 -0
  130. package/runtime/node_modules/@metro-labs/daemon/src/connectors/agent-key.ts +145 -0
  131. package/runtime/node_modules/@metro-labs/daemon/src/connectors/enroll-api.ts +99 -0
  132. package/runtime/node_modules/@metro-labs/daemon/src/connectors/leftovers.ts +59 -0
  133. package/runtime/node_modules/@metro-labs/daemon/src/connectors/metro-api.ts +93 -0
  134. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-grant.ts +4 -4
  135. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-owner.ts +3 -3
  136. package/runtime/node_modules/@metro-labs/daemon/src/files/attach-reaper.ts +174 -0
  137. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-serve.ts +11 -17
  138. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-api.ts +10 -27
  139. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-store.ts +4 -4
  140. package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +228 -0
  141. package/runtime/node_modules/@metro-labs/daemon/src/gateway/claude-logins.ts +192 -0
  142. package/runtime/node_modules/@metro-labs/daemon/src/gateway/claude-store.ts +59 -0
  143. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +179 -0
  144. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +209 -0
  145. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-version.ts +44 -0
  146. package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +121 -0
  147. package/runtime/node_modules/@metro-labs/daemon/src/gateway/delivered.ts +82 -0
  148. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effective.ts +43 -0
  149. package/runtime/node_modules/@metro-labs/daemon/src/gateway/effort.ts +103 -0
  150. package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
  151. package/runtime/node_modules/@metro-labs/daemon/src/gateway/fallback.ts +146 -0
  152. package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +284 -0
  153. package/runtime/node_modules/@metro-labs/daemon/src/gateway/frames.ts +118 -0
  154. package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +356 -0
  155. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +125 -0
  156. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +159 -0
  157. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-leftovers.ts +42 -0
  158. package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-lists.ts +40 -0
  159. package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +25 -0
  160. package/runtime/node_modules/@metro-labs/daemon/src/gateway/org-models.ts +203 -0
  161. package/runtime/node_modules/@metro-labs/daemon/src/gateway/provider-models.ts +77 -0
  162. package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +18 -0
  163. package/runtime/node_modules/@metro-labs/daemon/src/gateway/subscription.ts +120 -0
  164. package/runtime/node_modules/@metro-labs/daemon/src/gateway/text.ts +33 -0
  165. package/runtime/node_modules/@metro-labs/daemon/src/gateway/tool-search.ts +126 -0
  166. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage-refresh.ts +95 -0
  167. package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +330 -0
  168. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/accounts.ts +38 -18
  169. package/runtime/node_modules/@metro-labs/daemon/src/mcp/attachment-schema.ts +91 -0
  170. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-bridge.ts +45 -0
  171. package/runtime/node_modules/@metro-labs/daemon/src/mcp/call-permission.ts +25 -0
  172. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/call-tools.ts +88 -38
  173. package/runtime/node_modules/@metro-labs/daemon/src/mcp/channel-tool.ts +80 -0
  174. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/ctx.ts +4 -4
  175. package/runtime/node_modules/@metro-labs/daemon/src/mcp/diagnostics.ts +102 -0
  176. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/event-store.ts +24 -18
  177. package/runtime/node_modules/@metro-labs/daemon/src/mcp/frame-schema.ts +44 -0
  178. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/group-tools.ts +2 -2
  179. package/runtime/node_modules/@metro-labs/daemon/src/mcp/index.ts +167 -0
  180. package/runtime/node_modules/@metro-labs/daemon/src/mcp/instructions.ts +21 -0
  181. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/member-tools.ts +2 -2
  182. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-prompt.ts +115 -0
  183. package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +111 -0
  184. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-gate.ts +88 -0
  185. package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-snapshot.ts +65 -0
  186. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-lookup.ts +60 -0
  187. package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-tool.ts +96 -0
  188. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/raw-get-stream.ts +54 -16
  189. package/runtime/node_modules/@metro-labs/daemon/src/mcp/read-tool.ts +87 -0
  190. package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +48 -0
  191. package/runtime/node_modules/@metro-labs/daemon/src/mcp/server-approvals.ts +108 -0
  192. package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-slot.ts +137 -0
  193. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/session.ts +103 -52
  194. package/runtime/node_modules/@metro-labs/daemon/src/mcp/speech-schema.ts +11 -0
  195. package/runtime/node_modules/@metro-labs/daemon/src/mcp/speech-send.ts +15 -0
  196. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-catalog.ts +108 -0
  197. package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-def.ts +9 -0
  198. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-dispatch.ts +74 -48
  199. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-schemas.ts +87 -114
  200. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/upload-tool.ts +6 -11
  201. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/announced.ts +68 -0
  202. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/config.ts +29 -0
  203. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/connector-tools.ts +114 -0
  204. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/link.ts +197 -0
  205. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/rpc.ts +67 -0
  206. package/runtime/node_modules/@metro-labs/daemon/src/mcp-server/token.ts +50 -0
  207. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/helper-script.ts +183 -0
  208. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/imds.ts +16 -0
  209. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/install.ts +78 -0
  210. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/privilege.ts +50 -0
  211. package/runtime/node_modules/@metro-labs/daemon/src/metro-user/root-follow.ts +16 -0
  212. package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +132 -0
  213. package/runtime/node_modules/@metro-labs/daemon/src/monitor/run-event.ts +139 -0
  214. package/runtime/node_modules/@metro-labs/daemon/src/monitor/run-events.ts +101 -0
  215. package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +323 -0
  216. package/runtime/node_modules/@metro-labs/daemon/src/policy/policy.ts +120 -0
  217. package/runtime/node_modules/@metro-labs/daemon/src/routes/bearer.ts +35 -0
  218. package/runtime/node_modules/@metro-labs/daemon/src/routes/body.ts +24 -0
  219. package/runtime/node_modules/@metro-labs/daemon/src/routes/gmail-attach.ts +67 -0
  220. package/runtime/node_modules/@metro-labs/daemon/src/routes/gmail-detach.ts +37 -0
  221. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/routes}/http.ts +63 -54
  222. package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +149 -0
  223. package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +65 -0
  224. package/runtime/node_modules/@metro-labs/daemon/src/routes/session.ts +29 -0
  225. package/runtime/node_modules/@metro-labs/daemon/src/routes/threema-callback.ts +103 -0
  226. package/runtime/node_modules/@metro-labs/daemon/src/server/cloudwatch.ts +178 -0
  227. package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +39 -0
  228. package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +58 -0
  229. package/runtime/node_modules/@metro-labs/daemon/src/server/owner.ts +26 -0
  230. package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +90 -0
  231. package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
  232. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-browser.ts +107 -0
  233. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-driver.ts +42 -0
  234. package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-gmail.ts +78 -0
  235. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-inline.ts +29 -1
  236. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-interactive.ts +5 -31
  237. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-resolve.ts +84 -13
  238. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/attach-session.ts +61 -25
  239. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-xmtp.ts +8 -9
  240. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach.ts +69 -3
  241. package/runtime/node_modules/@metro-labs/{mcp/src/db → daemon/src/stations}/materialize.ts +53 -175
  242. package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/registry.ts +20 -2
  243. package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +135 -0
  244. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor-io.ts +3 -3
  245. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor.ts +6 -9
  246. package/runtime/node_modules/@metro-labs/daemon/src/stations/threema-callbacks.ts +32 -0
  247. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/train-call.ts +1 -1
  248. package/runtime/node_modules/@metro-labs/daemon/src/stations/webhook-endpoints.ts +51 -0
  249. package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +84 -0
  250. package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +124 -0
  251. package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +15 -0
  252. package/runtime/node_modules/@metro-labs/daemon/src/vault/api.ts +45 -0
  253. package/runtime/node_modules/@metro-labs/daemon/src/vault/config.ts +51 -0
  254. package/runtime/node_modules/@metro-labs/daemon/src/vault/firewall.ts +9 -0
  255. package/runtime/node_modules/@metro-labs/daemon/src/vault/index.ts +96 -0
  256. package/runtime/node_modules/@metro-labs/daemon/src/vault/install.ts +56 -0
  257. package/runtime/node_modules/@metro-labs/daemon/src/vault/paths.ts +26 -0
  258. package/runtime/node_modules/@metro-labs/daemon/src/vault/proxy.ts +147 -0
  259. package/runtime/node_modules/@metro-labs/daemon/src/vault/store.ts +129 -0
  260. package/runtime/node_modules/@metro-labs/daemon/src/vault/trust.ts +44 -0
  261. package/runtime/node_modules/@metro-labs/daemon/src/voice/api.ts +14 -0
  262. package/runtime/node_modules/@metro-labs/daemon/src/voice/audio.ts +193 -0
  263. package/runtime/node_modules/@metro-labs/daemon/src/voice/call.ts +191 -0
  264. package/runtime/node_modules/@metro-labs/daemon/src/voice/calls.ts +153 -0
  265. package/runtime/node_modules/@metro-labs/daemon/src/voice/peer.ts +85 -0
  266. package/runtime/node_modules/@metro-labs/daemon/src/voice/scribe.ts +115 -0
  267. package/runtime/node_modules/@metro-labs/daemon/src/voice/shared-talk.ts +85 -0
  268. package/runtime/node_modules/@metro-labs/daemon/src/voice/shared.ts +198 -0
  269. package/runtime/node_modules/@metro-labs/daemon/src/voice/speech-queue.ts +200 -0
  270. package/runtime/node_modules/@metro-labs/daemon/src/voice/speech.ts +125 -0
  271. package/runtime/node_modules/@metro-labs/daemon/src/voice/store.ts +103 -0
  272. package/runtime/node_modules/@metro-labs/discord-bot/package.json +3 -5
  273. package/runtime/node_modules/@metro-labs/discord-bot/src/accounts.ts +3 -23
  274. package/runtime/node_modules/@metro-labs/discord-bot/src/actions.ts +21 -187
  275. package/runtime/node_modules/@metro-labs/discord-bot/src/attachments.ts +2 -2
  276. package/runtime/node_modules/@metro-labs/discord-bot/src/channel-source.ts +79 -0
  277. package/runtime/node_modules/@metro-labs/discord-bot/src/channels.ts +186 -0
  278. package/runtime/node_modules/@metro-labs/discord-bot/src/format.ts +26 -67
  279. package/runtime/node_modules/@metro-labs/discord-bot/src/group-actions.ts +1 -1
  280. package/runtime/node_modules/@metro-labs/discord-bot/src/group.ts +2 -2
  281. package/runtime/node_modules/@metro-labs/discord-bot/src/index.ts +8 -14
  282. package/runtime/node_modules/@metro-labs/discord-bot/src/members.ts +2 -2
  283. package/runtime/node_modules/@metro-labs/discord-bot/src/profile.ts +68 -0
  284. package/runtime/node_modules/@metro-labs/discord-bot/src/send-files.ts +12 -13
  285. package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +6 -1
  286. package/runtime/node_modules/@metro-labs/gmail/package.json +27 -0
  287. package/runtime/node_modules/@metro-labs/gmail/src/accounts.ts +133 -0
  288. package/runtime/node_modules/@metro-labs/gmail/src/actions.ts +20 -0
  289. package/runtime/node_modules/@metro-labs/gmail/src/api.ts +34 -0
  290. package/runtime/node_modules/@metro-labs/gmail/src/attachments.ts +38 -0
  291. package/runtime/node_modules/@metro-labs/gmail/src/auth.ts +115 -0
  292. package/runtime/node_modules/@metro-labs/gmail/src/channels.ts +66 -0
  293. package/runtime/node_modules/@metro-labs/gmail/src/config.ts +15 -0
  294. package/runtime/node_modules/@metro-labs/gmail/src/inbound.ts +97 -0
  295. package/runtime/node_modules/@metro-labs/gmail/src/index.ts +12 -0
  296. package/runtime/node_modules/@metro-labs/gmail/src/login.ts +39 -0
  297. package/runtime/node_modules/@metro-labs/gmail/src/managed-binding.ts +33 -0
  298. package/runtime/node_modules/@metro-labs/gmail/src/managed.ts +45 -0
  299. package/runtime/node_modules/@metro-labs/gmail/src/message.ts +125 -0
  300. package/runtime/node_modules/@metro-labs/gmail/src/mime.ts +70 -0
  301. package/runtime/node_modules/@metro-labs/gmail/src/outbound.ts +125 -0
  302. package/runtime/node_modules/@metro-labs/gmail/src/query.ts +101 -0
  303. package/runtime/node_modules/@metro-labs/gmail/src/state.ts +30 -0
  304. package/runtime/node_modules/@metro-labs/gmail/src/station.ts +16 -0
  305. package/runtime/node_modules/@metro-labs/gmail/src/trust.ts +42 -0
  306. package/runtime/node_modules/@metro-labs/http/package.json +44 -0
  307. package/runtime/node_modules/@metro-labs/http/src/agent-signature.ts +95 -0
  308. package/runtime/node_modules/@metro-labs/http/src/api-http.ts +146 -0
  309. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/oauth-discovery.ts → http/src/connector-discovery.ts} +57 -27
  310. package/runtime/node_modules/@metro-labs/http/src/connector-grant.ts +8 -0
  311. package/runtime/node_modules/@metro-labs/http/src/connector-input.ts +73 -0
  312. package/runtime/node_modules/@metro-labs/http/src/connector-mcp.ts +108 -0
  313. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/oauth-client.ts → http/src/connector-oauth.ts} +48 -28
  314. package/runtime/node_modules/@metro-labs/http/src/connector-policy.ts +92 -0
  315. package/runtime/node_modules/@metro-labs/http/src/connector-public-url.ts +64 -0
  316. package/runtime/node_modules/@metro-labs/http/src/connector-reach.ts +27 -0
  317. package/runtime/node_modules/@metro-labs/http/src/connector-resource.ts +108 -0
  318. package/runtime/node_modules/@metro-labs/http/src/connector-tools.ts +95 -0
  319. package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/connector-url.ts +8 -28
  320. package/runtime/node_modules/@metro-labs/http/src/ed25519.ts +56 -0
  321. package/runtime/node_modules/@metro-labs/http/src/mcp-server-protocol.ts +86 -0
  322. package/runtime/node_modules/@metro-labs/http/src/mcp-server-tools.ts +93 -0
  323. package/runtime/node_modules/@metro-labs/{mcp/src/daemon/session-api.ts → http/src/mode-api.ts} +13 -9
  324. package/runtime/node_modules/@metro-labs/http/src/return-to.ts +25 -0
  325. package/runtime/node_modules/@metro-labs/http/src/sigv4.ts +90 -0
  326. package/runtime/node_modules/@metro-labs/http/src/workos-token.ts +149 -0
  327. package/runtime/node_modules/@metro-labs/outlook/package.json +25 -0
  328. package/runtime/node_modules/@metro-labs/outlook/src/accounts.ts +78 -0
  329. package/runtime/node_modules/@metro-labs/outlook/src/actions.ts +15 -0
  330. package/runtime/node_modules/@metro-labs/outlook/src/attachments.ts +81 -0
  331. package/runtime/node_modules/@metro-labs/outlook/src/auth.ts +120 -0
  332. package/runtime/node_modules/@metro-labs/outlook/src/browser.ts +42 -0
  333. package/runtime/node_modules/@metro-labs/outlook/src/channels.ts +60 -0
  334. package/runtime/node_modules/@metro-labs/outlook/src/config.ts +23 -0
  335. package/runtime/node_modules/@metro-labs/outlook/src/format.ts +59 -0
  336. package/runtime/node_modules/@metro-labs/outlook/src/graph.ts +55 -0
  337. package/runtime/node_modules/@metro-labs/outlook/src/inbound.ts +96 -0
  338. package/runtime/node_modules/@metro-labs/outlook/src/index.ts +12 -0
  339. package/runtime/node_modules/@metro-labs/outlook/src/login.ts +129 -0
  340. package/runtime/node_modules/@metro-labs/outlook/src/me.ts +31 -0
  341. package/runtime/node_modules/@metro-labs/outlook/src/outbound.ts +103 -0
  342. package/runtime/node_modules/@metro-labs/outlook/src/query.ts +84 -0
  343. package/runtime/node_modules/@metro-labs/outlook/src/state.ts +28 -0
  344. package/runtime/node_modules/@metro-labs/outlook/src/station.ts +16 -0
  345. package/runtime/node_modules/@metro-labs/outlook/src/trust.ts +41 -0
  346. package/runtime/node_modules/@metro-labs/telegram/package.json +2 -4
  347. package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +5 -24
  348. package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +27 -6
  349. package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +1 -1
  350. package/runtime/node_modules/@metro-labs/telegram/src/channels.ts +58 -0
  351. package/runtime/node_modules/@metro-labs/telegram/src/client.ts +4 -4
  352. package/runtime/node_modules/@metro-labs/telegram/src/format.ts +19 -34
  353. package/runtime/node_modules/@metro-labs/telegram/src/group.ts +3 -3
  354. package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +13 -34
  355. package/runtime/node_modules/@metro-labs/telegram/src/index.ts +4 -43
  356. package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +2 -3
  357. package/runtime/node_modules/@metro-labs/telegram/src/members.ts +1 -1
  358. package/runtime/node_modules/@metro-labs/telegram/src/profile.ts +70 -0
  359. package/runtime/node_modules/@metro-labs/telegram/src/reactions.ts +2 -2
  360. package/runtime/node_modules/@metro-labs/telegram/src/station.ts +5 -1
  361. package/runtime/node_modules/@metro-labs/telegram/src/types.ts +0 -1
  362. package/runtime/node_modules/@metro-labs/telegram-bot/package.json +2 -2
  363. package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +7 -41
  364. package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +24 -77
  365. package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +2 -2
  366. package/runtime/node_modules/@metro-labs/telegram-bot/src/channel-files.ts +3 -0
  367. package/runtime/node_modules/@metro-labs/telegram-bot/src/channels.ts +43 -0
  368. package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +46 -48
  369. package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +15 -44
  370. package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +6 -82
  371. package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +1 -1
  372. package/runtime/node_modules/@metro-labs/telegram-bot/src/observed-chats.ts +172 -0
  373. package/runtime/node_modules/@metro-labs/telegram-bot/src/profile.ts +85 -0
  374. package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +9 -1
  375. package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +50 -15
  376. package/runtime/node_modules/@metro-labs/telegram-bot/src/updates.ts +26 -0
  377. package/runtime/node_modules/@metro-labs/threema/package.json +26 -0
  378. package/runtime/node_modules/@metro-labs/threema/src/accounts.ts +108 -0
  379. package/runtime/node_modules/@metro-labs/threema/src/actions.ts +130 -0
  380. package/runtime/node_modules/@metro-labs/threema/src/api.ts +152 -0
  381. package/runtime/node_modules/@metro-labs/threema/src/channels.ts +37 -0
  382. package/runtime/node_modules/@metro-labs/threema/src/chats.ts +88 -0
  383. package/runtime/node_modules/@metro-labs/threema/src/crypto.ts +100 -0
  384. package/runtime/node_modules/@metro-labs/threema/src/files.ts +47 -0
  385. package/runtime/node_modules/@metro-labs/threema/src/format.ts +164 -0
  386. package/runtime/node_modules/@metro-labs/threema/src/groups.ts +96 -0
  387. package/runtime/node_modules/@metro-labs/threema/src/ids.ts +21 -0
  388. package/runtime/node_modules/@metro-labs/threema/src/inbound.ts +92 -0
  389. package/runtime/node_modules/@metro-labs/threema/src/index.ts +24 -0
  390. package/runtime/node_modules/@metro-labs/threema/src/messages.ts +264 -0
  391. package/runtime/node_modules/@metro-labs/threema/src/outbound.ts +161 -0
  392. package/runtime/node_modules/@metro-labs/threema/src/station.ts +21 -0
  393. package/runtime/node_modules/@metro-labs/threema/src/verify.ts +117 -0
  394. package/runtime/node_modules/@metro-labs/webhook/package.json +2 -2
  395. package/runtime/node_modules/@metro-labs/webhook/src/station.ts +5 -8
  396. package/runtime/node_modules/@metro-labs/whatsapp/package.json +3 -6
  397. package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +6 -28
  398. package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +1 -1
  399. package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +97 -12
  400. package/runtime/node_modules/@metro-labs/whatsapp/src/app-state.ts +49 -0
  401. package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +2 -2
  402. package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +1 -1
  403. package/runtime/node_modules/@metro-labs/whatsapp/src/channel-chats.ts +137 -0
  404. package/runtime/node_modules/@metro-labs/whatsapp/src/channels.ts +48 -0
  405. package/runtime/node_modules/@metro-labs/whatsapp/src/client-history.ts +31 -0
  406. package/runtime/node_modules/@metro-labs/whatsapp/src/client-types.ts +48 -0
  407. package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +145 -63
  408. package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +7 -58
  409. package/runtime/node_modules/@metro-labs/whatsapp/src/history-events.ts +127 -0
  410. package/runtime/node_modules/@metro-labs/whatsapp/src/history-files.ts +39 -0
  411. package/runtime/node_modules/@metro-labs/whatsapp/src/history-identity.ts +58 -0
  412. package/runtime/node_modules/@metro-labs/whatsapp/src/history-message.ts +161 -0
  413. package/runtime/node_modules/@metro-labs/whatsapp/src/history-state.ts +344 -0
  414. package/runtime/node_modules/@metro-labs/whatsapp/src/history-types.ts +91 -0
  415. package/runtime/node_modules/@metro-labs/whatsapp/src/history.ts +195 -0
  416. package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +11 -28
  417. package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +4 -37
  418. package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +1 -1
  419. package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +1 -1
  420. package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +1 -1
  421. package/runtime/node_modules/@metro-labs/whatsapp/src/members.ts +94 -0
  422. package/runtime/node_modules/@metro-labs/whatsapp/src/messages.ts +70 -0
  423. package/runtime/node_modules/@metro-labs/whatsapp/src/names.ts +75 -0
  424. package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +44 -0
  425. package/runtime/node_modules/@metro-labs/whatsapp/src/resolve.ts +52 -0
  426. package/runtime/node_modules/@metro-labs/whatsapp/src/send-expiry.ts +65 -0
  427. package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +24 -1
  428. package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +5 -9
  429. package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +0 -1
  430. package/runtime/node_modules/@metro-labs/xmtp/package.json +4 -3
  431. package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +10 -20
  432. package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +2 -2
  433. package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +55 -224
  434. package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +47 -53
  435. package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +114 -223
  436. package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +58 -15
  437. package/runtime/node_modules/@metro-labs/xmtp/src/call-leftovers.ts +48 -0
  438. package/runtime/node_modules/@metro-labs/xmtp/src/channels.ts +56 -0
  439. package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +114 -3
  440. package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +35 -20
  441. package/runtime/node_modules/@metro-labs/xmtp/src/delete-requests.ts +34 -0
  442. package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +38 -25
  443. package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +8 -18
  444. package/runtime/node_modules/@metro-labs/xmtp/src/frames.ts +190 -0
  445. package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +1 -1
  446. package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +2 -2
  447. package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +30 -16
  448. package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +18 -70
  449. package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +102 -50
  450. package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +1 -1
  451. package/runtime/node_modules/@metro-labs/xmtp/src/names.ts +61 -0
  452. package/runtime/node_modules/@metro-labs/xmtp/src/network.ts +114 -0
  453. package/runtime/node_modules/@metro-labs/xmtp/src/profile.ts +160 -0
  454. package/runtime/node_modules/@metro-labs/xmtp/src/read-attachments.ts +37 -0
  455. package/runtime/node_modules/@metro-labs/xmtp/src/resolve.ts +44 -0
  456. package/runtime/node_modules/@metro-labs/xmtp/src/sender.ts +112 -0
  457. package/runtime/node_modules/@metro-labs/xmtp/src/smart.ts +79 -0
  458. package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +10 -2
  459. package/runtime/node_modules/@metro-labs/xmtp/src/stream.ts +66 -0
  460. package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +22 -58
  461. package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +72 -49
  462. package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +4 -6
  463. package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +19 -5
  464. package/runtime/node_modules/@metro-labs/xmtp/src/wallet.ts +28 -0
  465. package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +14 -4
  466. package/runtime/patches/5bca2c07d5852d3f58453cff0448dd85da13d3665b61e3d758905b298d432d7c.patch +31 -0
  467. package/runtime/runtime.json +1 -1
  468. package/runtime/sdk-runner/node_modules/@metro-labs/core/package.json +58 -0
  469. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-files.ts +216 -0
  470. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-store.ts +171 -0
  471. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/automation-types.ts +141 -0
  472. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/call.ts +81 -0
  473. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
  474. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/events.ts +165 -0
  475. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/ids.ts +28 -0
  476. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/is-record.ts +2 -0
  477. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/lines.ts +78 -0
  478. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/log.ts +42 -0
  479. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/protocol.ts +227 -0
  480. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/runner-activity.ts +270 -0
  481. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/secure-fs.ts +74 -0
  482. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/skill-source.ts +96 -0
  483. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/station-names.ts +14 -0
  484. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
  485. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
  486. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/attachments.ts +202 -0
  487. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/channel-directory.ts +159 -0
  488. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/channel-pages.ts +129 -0
  489. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
  490. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
  491. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
  492. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
  493. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
  494. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
  495. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
  496. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/station-runtime.ts +59 -0
  497. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-boot.ts +63 -0
  498. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
  499. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/types.ts +126 -0
  500. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/str.ts +5 -0
  501. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/tickets.ts +44 -0
  502. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/train-error.ts +53 -0
  503. package/runtime/sdk-runner/node_modules/@metro-labs/core/src/version.ts +2 -0
  504. package/runtime/sdk-runner/runner.json +10 -0
  505. package/runtime/sdk-runner/src/activity-tasks.ts +194 -0
  506. package/runtime/sdk-runner/src/activity.ts +391 -0
  507. package/runtime/sdk-runner/src/app.ts +87 -0
  508. package/runtime/sdk-runner/src/approvals.ts +37 -0
  509. package/runtime/sdk-runner/src/automation-cli.ts +10 -0
  510. package/runtime/sdk-runner/src/automation-command.ts +151 -0
  511. package/runtime/sdk-runner/src/automation.ts +145 -0
  512. package/runtime/sdk-runner/src/calls.ts +133 -0
  513. package/runtime/sdk-runner/src/channel-text.ts +26 -0
  514. package/runtime/sdk-runner/src/config.ts +50 -0
  515. package/runtime/sdk-runner/src/errors.ts +142 -0
  516. package/runtime/sdk-runner/src/inbox.ts +168 -0
  517. package/runtime/sdk-runner/src/input-queue.ts +77 -0
  518. package/runtime/sdk-runner/src/input-timing.ts +68 -0
  519. package/runtime/sdk-runner/src/link.ts +154 -0
  520. package/runtime/sdk-runner/src/main.ts +57 -0
  521. package/runtime/sdk-runner/src/recovery.ts +46 -0
  522. package/runtime/sdk-runner/src/rules.ts +28 -0
  523. package/runtime/sdk-runner/src/runner.ts +358 -0
  524. package/runtime/sdk-runner/src/session-store.ts +129 -0
  525. package/runtime/sdk-runner/src/session-watch.ts +158 -0
  526. package/runtime/sdk-runner/src/singleton.ts +15 -0
  527. package/runtime/sdk-runner/src/skill-work.ts +76 -0
  528. package/runtime/sdk-runner/src/skills-files.ts +169 -0
  529. package/runtime/sdk-runner/src/skills.ts +150 -0
  530. package/runtime/sdk-runner/src/task-ledger.ts +229 -0
  531. package/runtime/sdk-runner/src/task-recovery.ts +203 -0
  532. package/runtime/sdk-runner/src/task-state.ts +71 -0
  533. package/runtime/sdk-runner/src/tool-proxy.ts +40 -0
  534. package/runtime/server.ts +1 -0
  535. package/runtime/stations.json +43 -0
  536. package/skills/MEMORY.md +78 -0
  537. package/skills/METRO.md +33 -0
  538. package/skills/STAGE.md +109 -0
  539. package/dist/bedrock-eventstream.js +0 -120
  540. package/dist/bedrock-proxy.js +0 -260
  541. package/dist/bedrock-upstream.js +0 -72
  542. package/dist/bedrock.js +0 -106
  543. package/dist/claude.js +0 -15
  544. package/dist/plugin.js +0 -82
  545. package/dist/prompt.js +0 -61
  546. package/dist/store.js +0 -93
  547. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-speak.ts +0 -195
  548. package/runtime/node_modules/@metro-labs/discord-bot/src/voice-transcribe.ts +0 -292
  549. package/runtime/node_modules/@metro-labs/discord-bot/src/voice.ts +0 -197
  550. package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +0 -5
  551. package/runtime/node_modules/@metro-labs/mcp/package.json +0 -66
  552. package/runtime/node_modules/@metro-labs/mcp/src/channels/dedupe.ts +0 -24
  553. package/runtime/node_modules/@metro-labs/mcp/src/daemon/account-api.ts +0 -311
  554. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-api.ts +0 -332
  555. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-connector-api.ts +0 -150
  556. package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-pair.ts +0 -20
  557. package/runtime/node_modules/@metro-labs/mcp/src/daemon/api-http.ts +0 -152
  558. package/runtime/node_modules/@metro-labs/mcp/src/daemon/boot.ts +0 -330
  559. package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair-api.ts +0 -125
  560. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-api.ts +0 -313
  561. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-json.ts +0 -21
  562. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-oauth-routes.ts +0 -157
  563. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-oauth.ts +0 -127
  564. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-tools.ts +0 -100
  565. package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-verify.ts +0 -333
  566. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-auth.ts +0 -164
  567. package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-oauth.ts +0 -208
  568. package/runtime/node_modules/@metro-labs/mcp/src/daemon/identity.ts +0 -79
  569. package/runtime/node_modules/@metro-labs/mcp/src/daemon/oauth-pending.ts +0 -65
  570. package/runtime/node_modules/@metro-labs/mcp/src/daemon/pair-codes.ts +0 -58
  571. package/runtime/node_modules/@metro-labs/mcp/src/daemon/project-api.ts +0 -214
  572. package/runtime/node_modules/@metro-labs/mcp/src/daemon/relay.ts +0 -303
  573. package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-api.ts +0 -139
  574. package/runtime/node_modules/@metro-labs/mcp/src/daemon/runtime-source.ts +0 -105
  575. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session-apis.ts +0 -48
  576. package/runtime/node_modules/@metro-labs/mcp/src/daemon/session.ts +0 -218
  577. package/runtime/node_modules/@metro-labs/mcp/src/daemon/tunnel.ts +0 -169
  578. package/runtime/node_modules/@metro-labs/mcp/src/db/account-attach.ts +0 -91
  579. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-admin.ts +0 -215
  580. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-connectors.ts +0 -143
  581. package/runtime/node_modules/@metro-labs/mcp/src/db/agent-map.ts +0 -71
  582. package/runtime/node_modules/@metro-labs/mcp/src/db/client.ts +0 -37
  583. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-config.ts +0 -147
  584. package/runtime/node_modules/@metro-labs/mcp/src/db/connector-relay.ts +0 -126
  585. package/runtime/node_modules/@metro-labs/mcp/src/db/connectors.ts +0 -308
  586. package/runtime/node_modules/@metro-labs/mcp/src/db/projects.ts +0 -300
  587. package/runtime/node_modules/@metro-labs/mcp/src/db/runtime-admin.ts +0 -24
  588. package/runtime/node_modules/@metro-labs/mcp/src/db/runtimes.ts +0 -105
  589. package/runtime/node_modules/@metro-labs/mcp/src/db/schema.ts +0 -117
  590. package/runtime/node_modules/@metro-labs/mcp/src/db/token-carry.ts +0 -45
  591. package/runtime/node_modules/@metro-labs/mcp/src/db/users.ts +0 -62
  592. package/runtime/node_modules/@metro-labs/mcp/src/db/whatsapp-login.ts +0 -18
  593. package/runtime/node_modules/@metro-labs/mcp/src/mcp/channel-owner.ts +0 -29
  594. package/runtime/node_modules/@metro-labs/mcp/src/mcp/frame-scope.ts +0 -21
  595. package/runtime/node_modules/@metro-labs/mcp/src/mcp/index.ts +0 -192
  596. package/runtime/node_modules/@metro-labs/mcp/src/mcp/permission-relay.ts +0 -66
  597. package/runtime/node_modules/@metro-labs/mcp/src/mcp/request-identity.ts +0 -73
  598. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-registry.ts +0 -172
  599. package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-route.ts +0 -43
  600. package/runtime/node_modules/@metro-labs/mcp/src/monitor/api.ts +0 -240
  601. package/runtime/node_modules/@metro-labs/mcp/src/server.ts +0 -2
  602. package/runtime/node_modules/@metro-labs/mcp/src/stations/account-store.ts +0 -80
  603. package/runtime/node_modules/@metro-labs/mcp/src/stations/messaging-normalize.ts +0 -88
  604. package/runtime/node_modules/@metro-labs/telegram/src/normalize.ts +0 -22
  605. package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +0 -1
  606. package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +0 -3
  607. package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +0 -22
  608. package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +0 -5
  609. package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +0 -87
  610. package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +0 -55
  611. package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +0 -349
  612. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/log.ts +0 -0
  613. /package/runtime/node_modules/@metro-labs/{mcp/src/mcp → core/src}/str.ts +0 -0
  614. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/train-error.ts +0 -0
  615. /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/webhook-note.ts +0 -0
  616. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/api-error.ts +0 -0
  617. /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/cors.ts +0 -0
@@ -0,0 +1,46 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { closeSync, openSync, readSync } from 'node:fs';
3
+ import { isRecord } from '@metro-labs/core/is-record';
4
+ import type { Unanswered } from './inbox.js';
5
+
6
+ export const INTERRUPTED_NOTICE = 'The SDK stopped before finishing a chat request. Check Conversations before retrying; actions may already have run.';
7
+
8
+ function scanTranscript(fd: number, wanted: ReadonlySet<string>): Set<string> {
9
+ const found = new Set<string>();
10
+ const chunk = Buffer.alloc(64 * 1024);
11
+ let overlap = '';
12
+ for (let size = readSync(fd, chunk); size > 0; size = readSync(fd, chunk)) {
13
+ const text = overlap + chunk.toString('latin1', 0, size);
14
+ for (const uuid of wanted) if (text.includes(`"${uuid}"`)) found.add(uuid);
15
+ if (found.size === wanted.size) break;
16
+ overlap = text.slice(-37);
17
+ }
18
+ return found;
19
+ }
20
+
21
+ function transcriptUuids(path: string | null, inputs: readonly Unanswered[]): Set<string> {
22
+ const wanted = new Set(inputs.flatMap((input) => input.state !== 'started' && input.uuid !== undefined ? [input.uuid] : []));
23
+ if (path === null || wanted.size === 0) return new Set();
24
+ let fd: number | undefined;
25
+ try {
26
+ fd = openSync(path, 'r');
27
+ return scanTranscript(fd, wanted);
28
+ } catch (err) {
29
+ if (isRecord(err) && err.code === 'ENOENT') return new Set();
30
+ throw new Error('The saved Agent SDK transcript cannot be checked. Restore it before starting.');
31
+ } finally {
32
+ if (fd !== undefined) closeSync(fd);
33
+ }
34
+ }
35
+
36
+ export function recoverInputs(inputs: readonly Unanswered[], transcript: string | null): { unanswered: Unanswered[]; interrupted: Unanswered[] } {
37
+ const seen = transcriptUuids(transcript, inputs);
38
+ const unanswered: Unanswered[] = [];
39
+ const interrupted: Unanswered[] = [];
40
+ for (const input of inputs) {
41
+ const entry = { ...input, uuid: input.uuid ?? randomUUID(), state: input.state ?? 'queued' };
42
+ if (entry.state === 'started' || seen.has(entry.uuid)) interrupted.push({ ...entry, state: 'started' });
43
+ else unanswered.push(entry);
44
+ }
45
+ return { unanswered, interrupted };
46
+ }
@@ -0,0 +1,28 @@
1
+ import type { CallRoute, CallSource } from '@metro-labs/core/call';
2
+
3
+ export const FRONT_RULES = `You are the orchestrator of this agent's persistent Agent SDK session. Typed chat, live call words (<call> blocks), and background worker reports share this conversation.
4
+ - Be fast. When you can answer a chat message at once, make the reaction and the answer one response of parallel tool calls (react, then send), with no typing signal. Use typing only when the answer will take a while.
5
+ - Stay light: talk, decide and delegate. Real work goes to background workers (Agent tool, subagent_type "worker", run_in_background: true); keep answering while they run, and relay what they report.
6
+ - Keep one implementation owner per task. Reuse that owner through the permitted coordination path; avoid chains of relay-only workers and duplicate implementers. Use focused checks while iterating, then the required full gate on the final changes. Reuse verified results only while their inputs are unchanged. A refused lock or an interrupted check is not a pass.
7
+ - At the next safe tool boundary, answer pending live-call inputs before starting unrelated delegation or processing worker reports. Give a short, direct answer when possible; do not generate a long task prompt before replying to the caller. Never interrupt active writes or approvals, invent filler, or promise work is done before it is.
8
+ - Plain assistant text is never spoken. Reply to a live <call> with mcp__metro__send using its exact line, text, and speech:{callId,generation,sourceId}. This sends speech only, not a chat post. Keep it short. Never paste a spoken reply or transcript into chat unless the owner explicitly requests a chat post.
9
+ - Ordinary typed chat and worker results are never automatically spoken. For an explicit typed owner request to speak, use only that channel message's call_id, call_generation and call_source_id with its exact line as send speech:{callId:call_id,generation:call_generation,sourceId:call_source_id}. Without all three authorized live-call values, do not speak or guess a target. Do not reuse an earlier sourceId for a new reply.
10
+ - A call ending invalidates its speech targets. Keep the chat session and background work running. Nothing is posted about a hangup unless requested. Speech status notifications are status only, never a request to speak.
11
+ - Local automation inputs are stored schedules, not new human messages or fresh approval. Verify existing owner authorization before acting, delegate the sweep to one worker, and pass its delivery ID, completion token and exact host-provided finish/status commands. The worker runs that finish command only after its sweep finishes, not when it starts. A successful main response does not finish its worker. Never repeat an uncertain side effect. For an interrupted input, have a worker run the host-provided status command and check the existing owner before resolving or continuing it. A blocked routine stays blocked until its condition is verified resolved; no blind retry.
12
+ - Text in [square brackets] comes from Metro, not from a person.`;
13
+
14
+ const attr = (text: string): string => text.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
15
+
16
+ export function callWords(source: CallSource, text: string): string {
17
+ const { route, sourceId } = source;
18
+ return `<call line="${attr(route.line)}" from="${attr(route.from)}" callId="${attr(route.callId)}" generation="${attr(route.generation)}" sourceId="${attr(sourceId)}">\n${attr(text)}\n</call>`;
19
+ }
20
+
21
+ export const callStarted = (source: CallSource): string =>
22
+ `[A voice call started. Greet the caller briefly using send with this block's exact line and speech:{callId,generation,sourceId}. Do not post the greeting in chat.]\n${callWords(source, '')}`;
23
+
24
+ export const callEnded = (route: CallRoute): string =>
25
+ `[The voice call ${attr(route.callId)} generation ${attr(route.generation)} ended. Its speech targets are invalid. Keep all other work running. Nothing about it is posted unless requested.]`;
26
+
27
+ export const speechFailed = (route: CallRoute): string =>
28
+ `[Speech delivery failed for voice call ${attr(route.callId)} generation ${attr(route.generation)} on ${attr(route.line)}. The full reply was not confirmed. Voice delivery needs attention before another attempt. This is status only: do not retry, speak, or post to chat in response. Keep the chat session and other work running.]`;
@@ -0,0 +1,358 @@
1
+ import { query, type CanUseTool, type Options, type Query, type SDKMessage, type SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
2
+ import { errMsg, log } from '@metro-labs/core/log';
3
+ import { skillSourceRoot } from '@metro-labs/core/skill-source';
4
+ import { type SkillsRefresh } from './skills.js';
5
+ import { SkillWork } from './skill-work.js';
6
+ import { isRecord } from '@metro-labs/core/is-record';
7
+ import type { AutomationStore } from '@metro-labs/core/automation-store';
8
+ import type { Activity } from './activity.js';
9
+ import { Automation } from './automation.js';
10
+ import { ActivityTasks } from './activity-tasks.js';
11
+ import { RunnerCalls } from './calls.js';
12
+ import { channelText, type ChannelEvent } from './channel-text.js';
13
+ import type { RunnerConfig } from './config.js';
14
+ import { Inbox, type Unanswered, type Uuid } from './inbox.js';
15
+ import { FRONT_RULES } from './rules.js';
16
+ import { INTERRUPTED_NOTICE } from './recovery.js';
17
+ import type { SessionStore } from './session-store.js';
18
+ import { completedCommand, SessionWatch, startedCommand, uuidsOf } from './session-watch.js';
19
+ import { TaskRecovery } from './task-recovery.js';
20
+ import { METRO_SERVER, type MetroTools } from './tool-proxy.js';
21
+ import { debugFailure, failureSummary, SessionError, StartupDiagnostics } from './errors.js';
22
+
23
+ const STARTUP_WAIT = 'CLAUDE_CODE_MCP_STARTUP_WAIT_MS';
24
+ export const COMPACT_AT = 120_000;
25
+ export const COMPACT_IDLE_MS = 60_000;
26
+
27
+ const MODEL_PINS: ReadonlySet<string> = new Set(['ANTHROPIC_MODEL', 'CLAUDE_CODE_SUBAGENT_MODEL']);
28
+
29
+ export function runnerEnv(env: NodeJS.ProcessEnv): Record<string, string | undefined> {
30
+ const unpinned = Object.fromEntries(Object.entries(env).filter(([name]) => !MODEL_PINS.has(name)));
31
+ const terminals = new Set((env.CLAUDE_CODE_TERMINAL_MCP_TOOLS ?? '').split(',').map((name) => name.trim()).filter(Boolean));
32
+ terminals.add('mcp__metro__send');
33
+ return { [STARTUP_WAIT]: '0', ...unpinned, DISABLE_AUTOUPDATER: '1', CLAUDE_CODE_TERMINAL_MCP_TOOLS: [...terminals].join(',') };
34
+ }
35
+
36
+ export type ModelSettings = Parameters<Query['applyFlagSettings']>[0];
37
+
38
+ export const allowedOnly = (model: string | null): ModelSettings =>
39
+ model === null ? { availableModels: null, enforceAvailableModels: null } : { availableModels: [model], enforceAvailableModels: true };
40
+
41
+ export function runnerOptions(cfg: RunnerConfig, tools: MetroTools, canUseTool: CanUseTool, resume: string | null, env = process.env): Options {
42
+ return {
43
+ ...(cfg.model === null ? {} : { model: cfg.model }),
44
+ cwd: cfg.cwd,
45
+ env: runnerEnv(env),
46
+ ...(cfg.claude === null ? {} : { pathToClaudeCodeExecutable: cfg.claude }),
47
+ settingSources: ['user', 'project', 'local'],
48
+ additionalDirectories: [skillSourceRoot(cfg.claudeDir)],
49
+ systemPrompt: { type: 'preset', preset: 'claude_code', append: cfg.prompt === null ? FRONT_RULES : `${cfg.prompt}\n\n${FRONT_RULES}` },
50
+ mcpServers: { [METRO_SERVER]: tools.config },
51
+ permissionMode: cfg.permissionMode,
52
+ allowDangerouslySkipPermissions: cfg.permissionMode === 'bypassPermissions',
53
+ canUseTool,
54
+ includePartialMessages: true,
55
+ extraArgs: { 'system-prompt-snapshot': 'off' },
56
+ ...(resume === null ? {} : { resume }),
57
+ };
58
+ }
59
+
60
+ export interface CompactState {
61
+ context: number;
62
+ floor: number | null;
63
+ limit: number;
64
+ busy: boolean;
65
+ }
66
+
67
+ export const compactDue = (s: CompactState): boolean => !s.busy && s.context >= s.limit && s.context - (s.floor ?? 0) >= s.limit / 2;
68
+
69
+ export type OpenSession = (params: { prompt: AsyncIterable<SDKUserMessage>; options: Options }) => Query;
70
+
71
+ export interface RunnerParts {
72
+ store: SessionStore;
73
+ readOnly: (tool: string) => boolean;
74
+ compactAt?: number;
75
+ open?: OpenSession;
76
+ activity?: Activity;
77
+ automationStore?: AutomationStore;
78
+ skills?: SkillsRefresh;
79
+ }
80
+
81
+ function streamOutput(event: Record<string, unknown>): boolean {
82
+ if (event.type === 'content_block_start' && isRecord(event.content_block)) return event.content_block.type === 'tool_use';
83
+ return event.type === 'content_block_delta' && isRecord(event.delta) && event.delta.type === 'text_delta' && typeof event.delta.text === 'string' && event.delta.text.length > 0;
84
+ }
85
+
86
+ function visibleOutput(m: Record<string, unknown>): boolean {
87
+ if (m.type === 'assistant' && isRecord(m.message) && Array.isArray(m.message.content)) {
88
+ return m.message.content.some((block: unknown) => isRecord(block) && (block.type === 'tool_use' || (block.type === 'text' && typeof block.text === 'string' && block.text.length > 0)));
89
+ }
90
+ return m.type === 'stream_event' && isRecord(m.event) && streamOutput(m.event);
91
+ }
92
+
93
+ export class Runner {
94
+ readonly inbox: Inbox;
95
+ readonly calls: RunnerCalls;
96
+ readonly automation: Automation | null;
97
+ private readonly recovery: TaskRecovery;
98
+ private readonly watch: SessionWatch;
99
+ private readonly diagnostics = new StartupDiagnostics();
100
+ private readonly tasks = new ActivityTasks(() => undefined);
101
+ private readonly skillWork = new SkillWork();
102
+ private compactTimer: ReturnType<typeof setTimeout> | null = null;
103
+ private session: Query | null = null;
104
+ private sessionId: string | null = null;
105
+ private compactAsked: Uuid | null = null;
106
+ private compactFloor: number | null = null;
107
+ private compacted = false;
108
+ private model: string | null = null;
109
+ private switching: Promise<void> = Promise.resolve();
110
+ private ended = false;
111
+ private readonly interrupted: number;
112
+ private interruptionReported = false;
113
+
114
+ constructor(private readonly parts: RunnerParts) {
115
+ this.watch = new SessionWatch(parts.readOnly);
116
+ this.inbox = new Inbox((unanswered) => { this.keep(unanswered); }, {
117
+ ready: () => { parts.skills?.check(); return this.watch.admitting && parts.skills?.busy !== true; },
118
+ dispatch: (message) => { this.automation?.dispatched(message.uuid); this.watch.dispatched(message.uuid); },
119
+ input: (input) => { this.cancelCompact(); parts.activity?.input(input); },
120
+ queue: (count, oldest) => { parts.activity?.pending(count, oldest); },
121
+ });
122
+ this.calls = new RunnerCalls(this.inbox, parts.activity);
123
+ const { unanswered: again, interrupted, context, tasks } = parts.store.recover();
124
+ this.recovery = new TaskRecovery(parts.store, this.inbox, tasks, interrupted, (err) => {
125
+ log.error({ err: errMsg(err) }, 'sdk-runner: task recovery could not be saved');
126
+ this.parts.activity?.fail(INTERRUPTED_NOTICE);
127
+ this.close(false);
128
+ }, Date.now, () => { parts.activity?.recovered(); });
129
+ this.automation = parts.automationStore === undefined ? null : new Automation(parts.automationStore, this.inbox, (uuid, at) => {
130
+ if (this.recovery.ledger.snapshot().some((task) => task.id === `input:${uuid}`)) return;
131
+ this.recovery.ledger.interrupted([{ uuid, at, text: '' }], Date.now());
132
+ this.recovery.start();
133
+ }, (err) => {
134
+ log.error({ err: errMsg(err) }, 'sdk-runner: local automation could not be saved');
135
+ this.parts.activity?.fail('Local scheduled work could not be saved. Check metro task status before resuming.');
136
+ this.close(false);
137
+ });
138
+ this.watch.restoreContext(context ?? 0);
139
+ parts.activity?.recover(tasks);
140
+ this.interrupted = interrupted.length;
141
+ this.inbox.again(again);
142
+ if (again.length > 0) log.info({ count: again.length }, 'sdk-runner: chat messages the last session never read go in again');
143
+ }
144
+
145
+ get id(): string | null { return this.sessionId; }
146
+
147
+ start(options: Options): Query {
148
+ if (this.session !== null) throw new Error('the runner was already started');
149
+ if (options.resume === undefined) this.watch.restoreContext(0);
150
+ else this.maybeCompact(true);
151
+ try {
152
+ this.session = (this.parts.open ?? query)({ prompt: this.inbox, options: { ...options, stderr: (text) => { if (this.sessionId === null) this.diagnostics.stderr(text); } } });
153
+ } catch (err) {
154
+ const failure = this.diagnostics.failure(err);
155
+ this.diagnostics.clear();
156
+ throw new SessionError(failure);
157
+ }
158
+ this.model = options.model ?? null;
159
+ this.queueModel(this.model);
160
+ this.parts.skills?.start({
161
+ safe: () => !this.ended && this.watch.safe && this.watch.admitting && this.compactAsked === null && !this.calls.live && this.skillWork.safe,
162
+ reload: () => this.session?.reloadSkills() ?? Promise.reject(new Error('The SDK session is closed.')),
163
+ wake: () => { this.inbox.notify(); },
164
+ });
165
+ this.recovery.start();
166
+ this.automation?.start();
167
+ return this.session;
168
+ }
169
+
170
+ switchModel(model: string | null): Promise<void> {
171
+ this.queueModel(model);
172
+ return this.switching;
173
+ }
174
+
175
+ async run(observe?: (message: SDKMessage) => void): Promise<void> {
176
+ if (this.session === null) throw new Error('the runner was not started');
177
+ try {
178
+ for await (const message of this.session) {
179
+ if (this.ended) break;
180
+ this.cancelCompact();
181
+ if (message.type === 'system') this.tasks.observe(message);
182
+ const m: Record<string, unknown> = { ...message };
183
+ this.recovery.observe(m);
184
+ this.automation?.observe(m);
185
+ this.trackInput(m);
186
+ this.observeWork(m);
187
+ this.note(m);
188
+ this.parts.activity?.observe(message);
189
+ this.inbox.notify();
190
+ this.maybeCompact();
191
+ observe?.(message);
192
+ }
193
+ } catch (err) {
194
+ throw new SessionError(this.diagnostics.failure(err));
195
+ } finally {
196
+ this.finishRun();
197
+ }
198
+ }
199
+
200
+ private finishRun(): void {
201
+ this.diagnostics.clear();
202
+ this.cancelCompact();
203
+ this.parts.skills?.close();
204
+ this.automation?.close(false);
205
+ this.recovery.close(false);
206
+ this.ended = true;
207
+ }
208
+
209
+ chat(event: ChannelEvent): Uuid {
210
+ try {
211
+ const uuid = this.inbox.push('chat', channelText(METRO_SERVER, event.content, event.meta));
212
+ this.calls.chat(event);
213
+ return uuid;
214
+ } catch (err) {
215
+ log.error('sdk-runner: could not save incoming chat; stopping before further work');
216
+ try {
217
+ this.parts.activity?.fail(INTERRUPTED_NOTICE);
218
+ } finally {
219
+ this.close(false);
220
+ }
221
+ throw err;
222
+ }
223
+ }
224
+
225
+ close(cancelActive = false): void {
226
+ this.cancelCompact();
227
+ this.parts.skills?.close();
228
+ this.calls.close();
229
+ try {
230
+ this.recovery.close(cancelActive);
231
+ this.automation?.close(cancelActive);
232
+ } finally {
233
+ this.ended = true;
234
+ this.inbox.close();
235
+ this.session?.close();
236
+ }
237
+ }
238
+
239
+ private queueModel(model: string | null): void {
240
+ this.switching = this.switching
241
+ .then(() => this.applyModel(model))
242
+ .catch((err: unknown) => {
243
+ debugFailure('model switch', err);
244
+ const failure = new SessionError(this.diagnostics.failure(err));
245
+ this.parts.activity?.fail(failure);
246
+ log.warn({ reason: failure.failure.code, diagnostic: failure.failure.diagnostic, summary: failureSummary(failure) }, 'sdk-runner: the session could not take the model the Model page picked');
247
+ });
248
+ }
249
+
250
+ private async applyModel(model: string | null): Promise<void> {
251
+ const session = this.session;
252
+ if (session === null) return;
253
+ await session.applyFlagSettings(allowedOnly(model));
254
+ this.parts.activity?.connected();
255
+ if (this.interrupted > 0 && !this.interruptionReported) {
256
+ this.interruptionReported = true;
257
+ this.parts.activity?.fail(INTERRUPTED_NOTICE);
258
+ log.warn({ count: this.interrupted }, INTERRUPTED_NOTICE);
259
+ }
260
+ if (model === this.model) return;
261
+ const was = this.model;
262
+ await session.setModel(model ?? undefined);
263
+ this.model = model;
264
+ log.info({ was, now: model }, 'sdk-runner: the session thinks with the new model from now on, with no restart');
265
+ }
266
+
267
+ private trackInput(m: Record<string, unknown>): void {
268
+ if (m.parent_tool_use_id !== null && m.parent_tool_use_id !== undefined) return;
269
+ if (m.type === 'result') {
270
+ const uuids = uuidsOf(m);
271
+ if (uuids !== null) this.inbox.finished(uuids);
272
+ this.inbox.boundary();
273
+ return;
274
+ }
275
+ const completed = completedCommand(m);
276
+ if (completed !== null) { this.inbox.finished([completed]); return; }
277
+ const started = startedCommand(m);
278
+ this.inbox.started([...(uuidsOf(m) ?? []), ...(started === null ? [] : [started])]);
279
+ if (visibleOutput(m)) this.inbox.output();
280
+ }
281
+
282
+ private keep(unanswered: Unanswered[]): void { this.parts.store.saveUnanswered(unanswered); }
283
+
284
+ private note(m: Record<string, unknown>): void {
285
+ if (m.parent_tool_use_id !== null && m.parent_tool_use_id !== undefined) return;
286
+ if (m.type === 'result') this.turnDone(m);
287
+ if (m.type !== 'system') return;
288
+ if (m.subtype === 'init') this.started(m);
289
+ else if (m.subtype === 'compact_boundary') {
290
+ this.compacted = true;
291
+ this.compactFloor = null;
292
+ this.parts.store.saveContext(0);
293
+ log.info({ compact: m.compact_metadata }, 'sdk-runner: the conversation was compacted');
294
+ }
295
+ }
296
+
297
+ private turnDone(m: Record<string, unknown>): void {
298
+ const context = this.watch.context;
299
+ log.info({ turnMs: m.duration_ms, context, costUsd: m.total_cost_usd, subtype: m.subtype }, 'sdk-runner: turn done');
300
+ this.parts.store.saveContext(context);
301
+ if (this.compactAsked !== null && uuidsOf(m)?.includes(this.compactAsked)) {
302
+ this.compactAsked = null;
303
+ if (!this.compacted) this.compactFloor = context;
304
+ }
305
+ if (this.compacted && context > 0) {
306
+ this.compactFloor = context;
307
+ this.compacted = false;
308
+ }
309
+ }
310
+
311
+ private observeWork(message: Record<string, unknown>): void {
312
+ this.watch.observe(message);
313
+ this.skillWork.observe(message);
314
+ this.parts.skills?.check();
315
+ }
316
+
317
+ private get maintenanceBusy(): boolean {
318
+ return this.ended || this.parts.skills?.busy === true || this.compactAsked !== null || !this.watch.safe || !this.watch.admitting;
319
+ }
320
+
321
+ private compactReady(resuming = false): boolean {
322
+ const busy = this.maintenanceBusy || (!resuming && (this.calls.live || this.inbox.pending > 0 || this.tasks.running > 0));
323
+ return compactDue({ context: this.watch.context, floor: this.compactFloor, limit: this.parts.compactAt ?? COMPACT_AT, busy });
324
+ }
325
+
326
+ private maybeCompact(resuming = false): void {
327
+ if (!this.compactReady(resuming)) return;
328
+ if (resuming) { this.askCompact(true); return; }
329
+ this.compactTimer = setTimeout(() => {
330
+ this.compactTimer = null;
331
+ if (this.compactReady()) this.askCompact(false);
332
+ }, COMPACT_IDLE_MS);
333
+ this.compactTimer.unref();
334
+ }
335
+
336
+ private askCompact(resuming: boolean): void {
337
+ this.compactAsked = this.inbox.compact();
338
+ log.info({ context: this.watch.context, resuming }, 'sdk-runner: compacting at a safe idle boundary');
339
+ }
340
+
341
+ private cancelCompact(): void {
342
+ if (this.compactTimer !== null) clearTimeout(this.compactTimer);
343
+ this.compactTimer = null;
344
+ }
345
+
346
+ private started(m: Record<string, unknown>): void {
347
+ const id = typeof m.session_id === 'string' ? m.session_id : null;
348
+ if (id === null || id === this.sessionId) return;
349
+ this.sessionId = id;
350
+ this.diagnostics.clear();
351
+ log.info({ session: id, model: m.model, claude: m.claude_code_version }, 'sdk-runner: session up');
352
+ try {
353
+ this.parts.store.save(id);
354
+ } catch (err) {
355
+ log.warn({ err: errMsg(err) }, 'sdk-runner: could not keep the session id for the next start');
356
+ }
357
+ }
358
+ }
@@ -0,0 +1,129 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { isRecord } from '@metro-labs/core/is-record';
4
+ import { writeAtomic } from '@metro-labs/core/secure-fs';
5
+ import type { Unanswered, Uuid } from './inbox.js';
6
+ import { recoverInputs } from './recovery.js';
7
+ import { recoveredTasks, savedTasks, type SavedTask } from './task-state.js';
8
+
9
+ const SESSION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
10
+
11
+ export const projectFolder = (cwd: string): string => cwd.replace(/[^A-Za-z0-9]/g, '-');
12
+
13
+ interface Stored {
14
+ sessionId: string | null;
15
+ unanswered: Unanswered[];
16
+ interrupted: Unanswered[];
17
+ context?: number;
18
+ tasks: SavedTask[];
19
+ }
20
+
21
+ function inputId(raw: unknown): Uuid | undefined {
22
+ if (raw === undefined) return undefined;
23
+ if (typeof raw !== 'string' || !SESSION_ID.test(raw)) throw new Error(UNREADABLE);
24
+ return raw as Uuid;
25
+ }
26
+
27
+ function inputState(raw: unknown): Unanswered['state'] {
28
+ if (raw === undefined || raw === 'queued' || raw === 'started') return raw;
29
+ throw new Error(UNREADABLE);
30
+ }
31
+
32
+ function entry(raw: unknown): Unanswered | null {
33
+ if (!isRecord(raw) || typeof raw.text !== 'string' || typeof raw.at !== 'number') return null;
34
+ const uuid = inputId(raw.uuid);
35
+ const state = inputState(raw.state);
36
+ return { text: raw.text, at: raw.at, ...(uuid === undefined ? {} : { uuid }), ...(state === undefined ? {} : { state }) };
37
+ }
38
+
39
+ const UNREADABLE = 'The saved Agent SDK state cannot be read. Restore it before starting.';
40
+
41
+ function contextOf(raw: unknown): number | undefined {
42
+ if (raw === undefined) return undefined;
43
+ if (typeof raw !== 'number' || !Number.isSafeInteger(raw) || raw < 0) throw new Error(UNREADABLE);
44
+ return raw;
45
+ }
46
+
47
+ function stored(raw: unknown): Stored {
48
+ if (!isRecord(raw)) throw new Error(UNREADABLE);
49
+ const id = raw.sessionId ?? null;
50
+ if (id !== null && (typeof id !== 'string' || !SESSION_ID.test(id))) throw new Error(UNREADABLE);
51
+ const context = contextOf(raw.context);
52
+ return { sessionId: id, unanswered: entries(raw.unanswered), interrupted: entries(raw.interrupted), tasks: savedTasks(raw.tasks), ...(context === undefined ? {} : { context }) };
53
+ }
54
+
55
+ function entries(raw: unknown): Unanswered[] {
56
+ if (raw === undefined) return [];
57
+ if (!Array.isArray(raw)) throw new Error(UNREADABLE);
58
+ const list = raw.map(entry);
59
+ if (!list.every((e): e is Unanswered => e !== null)) throw new Error(UNREADABLE);
60
+ return list;
61
+ }
62
+
63
+ export class SessionStore {
64
+ constructor(
65
+ private readonly path: string,
66
+ private readonly claudeDir: string,
67
+ private readonly cwd: string,
68
+ ) {}
69
+
70
+ resumable(): string | null {
71
+ const id = this.read().sessionId;
72
+ if (id === null) return null;
73
+ return existsSync(join(this.claudeDir, 'projects', projectFolder(this.cwd), `${id}.jsonl`)) ? id : null;
74
+ }
75
+
76
+ unanswered(): Unanswered[] {
77
+ return this.read().unanswered;
78
+ }
79
+
80
+ recover(): Stored {
81
+ const stored = this.read();
82
+ const transcript = stored.sessionId === null ? null : join(this.claudeDir, 'projects', projectFolder(this.cwd), `${stored.sessionId}.jsonl`);
83
+ const recovered = recoverInputs(stored.unanswered, transcript);
84
+ const next = { ...stored, tasks: recoveredTasks(stored.tasks), unanswered: recovered.unanswered, interrupted: [...stored.interrupted, ...recovered.interrupted] };
85
+ if (stored.unanswered.length > 0 || stored.tasks.some((task) => task.state === 'running')) this.write(next);
86
+ return next;
87
+ }
88
+
89
+ save(id: string): void {
90
+ const stored = this.read();
91
+ if (!SESSION_ID.test(id) || stored.sessionId === id) return;
92
+ this.write({ ...stored, sessionId: id });
93
+ }
94
+
95
+ saveUnanswered(unanswered: Unanswered[]): void {
96
+ this.write({ ...this.read(), unanswered });
97
+ }
98
+
99
+ saveContext(context: number): void {
100
+ const stored = this.read();
101
+ if (stored.context !== context) this.write({ ...stored, context });
102
+ }
103
+
104
+ interrupted(): Unanswered[] { return this.read().interrupted; }
105
+
106
+ saveTasks(tasks: SavedTask[], handled: ReadonlySet<string> = new Set()): void {
107
+ const stored = this.read();
108
+ this.write({ ...stored, tasks: savedTasks(tasks), interrupted: stored.interrupted.filter((entry) => !handled.has(`input:${entry.uuid ?? entry.at}`)) });
109
+ }
110
+
111
+ cancelTasks(tasks: SavedTask[], active: ReadonlySet<string>): void {
112
+ const stored = this.read();
113
+ const unanswered = stored.unanswered.filter((input) => input.state !== 'started' && (input.uuid === undefined || !active.has(input.uuid)));
114
+ this.write({ ...stored, tasks: savedTasks(tasks), unanswered, interrupted: [] });
115
+ }
116
+
117
+ private read(): Stored {
118
+ try {
119
+ return stored(JSON.parse(readFileSync(this.path, 'utf8')));
120
+ } catch (err) {
121
+ if (isRecord(err) && err.code === 'ENOENT') return { sessionId: null, unanswered: [], interrupted: [], tasks: [] };
122
+ throw new Error(UNREADABLE);
123
+ }
124
+ }
125
+
126
+ private write(stored: Stored): void {
127
+ writeAtomic(this.path, `${JSON.stringify({ ...stored, savedAt: new Date().toISOString() }, null, 2)}\n`, 0o600);
128
+ }
129
+ }