@stage-labs/metro 0.1.0-beta.26 → 0.1.0-beta.260
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.
- package/dist/agent.js +128 -0
- package/dist/api.js +9 -129
- package/dist/background.js +141 -0
- package/dist/claude-settings.js +40 -0
- package/dist/claude.js +201 -0
- package/dist/cli.js +67 -117
- package/dist/control.js +19 -103
- package/dist/hold.js +210 -0
- package/dist/local.js +43 -0
- package/dist/mcp-config.js +27 -0
- package/dist/memory.js +222 -0
- package/dist/node-name.js +71 -0
- package/dist/onboarding.js +44 -0
- package/dist/provider-flags.js +9 -0
- package/dist/root-release-io.js +161 -0
- package/dist/root-release.js +74 -0
- package/dist/route.js +66 -0
- package/dist/runtime-install.js +97 -0
- package/dist/runtime.js +29 -52
- package/dist/serve.js +157 -0
- package/dist/service.js +328 -0
- package/dist/tail.js +10 -11
- package/dist/update.js +13 -1
- package/dist/voice.js +56 -0
- package/package.json +3 -24
- package/runtime/marketplace/.claude-plugin/marketplace.json +12 -0
- package/runtime/marketplace/plugin/.claude-plugin/plugin.json +17 -0
- package/runtime/marketplace/plugin/.mcp.json +1 -0
- package/runtime/marketplace/plugin/MEMORY.md +78 -0
- package/runtime/marketplace/plugin/METRO.md +26 -0
- package/runtime/marketplace/plugin/STAGE.md +95 -0
- package/runtime/marketplace/plugin/bin/guard.mjs +75 -0
- package/runtime/marketplace/plugin/bin/metro-plugin.mjs +30 -0
- package/runtime/marketplace/plugin/bin/policy.mjs +97 -0
- package/runtime/marketplace/plugin/bin/session-start.mjs +31 -0
- package/runtime/marketplace/plugin/hooks/hooks.json +25 -0
- package/runtime/node_modules/@metro-labs/core/package.json +52 -0
- package/runtime/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/events.ts +11 -7
- package/runtime/node_modules/@metro-labs/{mcp/src/db → core/src}/ids.ts +10 -1
- package/runtime/node_modules/@metro-labs/core/src/is-record.ts +2 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/stations → core/src}/lines.ts +22 -26
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/protocol.ts +7 -4
- package/runtime/node_modules/@metro-labs/core/src/runner-activity.ts +103 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/secure-fs.ts +17 -0
- package/runtime/node_modules/@metro-labs/core/src/station-names.ts +14 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
- package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/attachments.ts +0 -1
- package/runtime/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
- package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/station-runtime.ts +6 -11
- package/runtime/node_modules/@metro-labs/core/src/stations/train-boot.ts +42 -0
- package/runtime/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
- package/runtime/node_modules/@metro-labs/{mcp → core}/src/stations/types.ts +19 -1
- package/runtime/node_modules/@metro-labs/core/src/tickets.ts +37 -0
- package/runtime/node_modules/@metro-labs/core/src/version.ts +2 -0
- package/runtime/node_modules/@metro-labs/daemon/package.json +51 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/agent-fs.ts +246 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/crontab.ts +44 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files-api.ts +12 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/files.ts +89 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/home-fs.ts +113 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/job-env.ts +39 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/metro-home.ts +42 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/provision.ts +81 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedule-detail.ts +93 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules-api.ts +27 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedules.ts +144 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/unit-files.ts +43 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/user.ts +91 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/view.ts +93 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/account-attach.ts +19 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/account-lookups.ts +55 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/account-routes.ts +76 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/accounts-api.ts +357 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/admin.ts +30 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/allowlist.ts +59 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/api.ts +131 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/bundle.ts +132 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/file-admin.ts +305 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/files.ts +142 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/db/key-map.ts → daemon/src/agents/keys.ts} +1 -11
- package/runtime/node_modules/@metro-labs/daemon/src/agents/map.ts +133 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/policy-route.ts +27 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/db/agent-scope.ts → daemon/src/agents/scope.ts} +2 -2
- package/runtime/node_modules/@metro-labs/daemon/src/agents/sender-cards.ts +94 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agents/senders.ts +38 -0
- package/runtime/node_modules/@metro-labs/daemon/src/approvals/api.ts +55 -0
- package/runtime/node_modules/@metro-labs/daemon/src/approvals/pending.ts +150 -0
- package/runtime/node_modules/@metro-labs/daemon/src/approvals/preview.ts +66 -0
- package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +238 -0
- package/runtime/node_modules/@metro-labs/daemon/src/boot/connect-hint.ts +36 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/crash-guard.ts +1 -1
- package/runtime/node_modules/@metro-labs/daemon/src/boot/local-owner.ts +21 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/boot}/paths.ts +8 -36
- package/runtime/node_modules/@metro-labs/daemon/src/channels/addressed.ts +26 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/inbound.ts +75 -45
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/media-note.ts +11 -7
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/pending.ts +4 -1
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/relay.ts +2 -2
- package/runtime/node_modules/@metro-labs/daemon/src/claude/api.ts +285 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/files.ts +359 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/login.ts +242 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/memory-routine.ts +123 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/memory.ts +32 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/onboarding.ts +60 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/plugin-install.ts +149 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-activity.ts +17 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/runner-process.ts +50 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/runner.ts +45 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/session-continuity.ts +48 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/session-files.ts +75 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +358 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +109 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-api.ts +161 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/setup-state.ts +18 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +343 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/skills.ts +120 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/usage-probe.ts +128 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/version.ts +113 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-api.ts → daemon/src/connectors/api.ts} +79 -114
- package/runtime/node_modules/@metro-labs/{mcp/src/db/connector-config.ts → daemon/src/connectors/config.ts} +67 -41
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/gates.ts +72 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/health.ts +18 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/oauth-client.ts +14 -17
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/oauth-discovery.ts +33 -20
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-oauth-routes.ts → daemon/src/connectors/oauth-routes.ts} +30 -32
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon/connector-oauth.ts → daemon/src/connectors/oauth.ts} +60 -21
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/plugin-sync.ts +131 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/reach.ts +27 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/relay-policy.ts +90 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/connectors}/relay.ts +80 -35
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/store.ts +385 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/tools.ts +81 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-api.ts +116 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-crypto.ts +44 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/transfer-store.ts +48 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/url.ts +37 -0
- package/runtime/node_modules/@metro-labs/daemon/src/connectors/verify.ts +106 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-grant.ts +4 -4
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-owner.ts +3 -3
- package/runtime/node_modules/@metro-labs/daemon/src/files/attach-reaper.ts +174 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/attach-serve.ts +11 -17
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-api.ts +10 -27
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/files}/upload-store.ts +4 -4
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +233 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/claude-logins.ts +168 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-auth.ts +219 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +119 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +179 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-translate.ts +209 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-version.ts +44 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +143 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/effort.ts +103 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/fallback.ts +147 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +285 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/frames.ts +118 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +396 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-auth.ts +160 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-client.ts +46 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-setup.ts +150 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-stream.ts +139 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-translate.ts +236 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini.ts +208 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +254 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +353 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-lists.ts +57 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-signin.ts +157 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-store.ts +80 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +104 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/pkce.ts +36 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/provider-models.ts +117 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/served.ts +18 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/subscription.ts +120 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/text.ts +35 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/tool-search.ts +126 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage-refresh.ts +115 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +343 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/accounts.ts +38 -18
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/attachment-schema.ts +91 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/call-tools.ts +86 -38
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/ctx.ts +4 -4
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/event-store.ts +15 -16
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/group-tools.ts +2 -2
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/index.ts +49 -77
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/instructions.ts +30 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/member-tools.ts +2 -2
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-prompt.ts +92 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/permission-relay.ts +88 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-gate.ts +82 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/policy-snapshot.ts +79 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-lookup.ts +60 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/profile-tool.ts +96 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/read-tool.ts +87 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/request-identity.ts +48 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-slot.ts +75 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/session.ts +61 -57
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-catalog.ts +93 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/tool-def.ts +9 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-dispatch.ts +53 -40
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/tool-schemas.ts +115 -114
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/upload-tool.ts +6 -11
- package/runtime/node_modules/@metro-labs/daemon/src/metro-user/helper-script.ts +183 -0
- package/runtime/node_modules/@metro-labs/daemon/src/metro-user/imds.ts +16 -0
- package/runtime/node_modules/@metro-labs/daemon/src/metro-user/install.ts +78 -0
- package/runtime/node_modules/@metro-labs/daemon/src/metro-user/privilege.ts +50 -0
- package/runtime/node_modules/@metro-labs/daemon/src/metro-user/root-follow.ts +16 -0
- package/runtime/node_modules/@metro-labs/daemon/src/monitor/api.ts +132 -0
- package/runtime/node_modules/@metro-labs/daemon/src/net/tunnel.ts +316 -0
- package/runtime/node_modules/@metro-labs/daemon/src/policy/policy.ts +118 -0
- package/runtime/node_modules/@metro-labs/daemon/src/routes/bearer.ts +38 -0
- package/runtime/node_modules/@metro-labs/daemon/src/routes/body.ts +24 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/routes}/http.ts +64 -53
- package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +210 -0
- package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +71 -0
- package/runtime/node_modules/@metro-labs/daemon/src/routes/session.ts +29 -0
- package/runtime/node_modules/@metro-labs/daemon/src/routes/threema-callback.ts +103 -0
- package/runtime/node_modules/@metro-labs/daemon/src/server/cloudwatch.ts +178 -0
- package/runtime/node_modules/@metro-labs/daemon/src/server/control.ts +39 -0
- package/runtime/node_modules/@metro-labs/daemon/src/server/machine.ts +58 -0
- package/runtime/node_modules/@metro-labs/daemon/src/server/owner.ts +26 -0
- package/runtime/node_modules/@metro-labs/daemon/src/server/update.ts +90 -0
- package/runtime/node_modules/@metro-labs/daemon/src/server.ts +2 -0
- package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-browser.ts +102 -0
- package/runtime/node_modules/@metro-labs/daemon/src/stations/attach-driver.ts +42 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-inline.ts +29 -1
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-interactive.ts +5 -31
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-resolve.ts +84 -13
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/attach-session.ts +32 -22
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach-xmtp.ts +8 -9
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/attach.ts +69 -3
- package/runtime/node_modules/@metro-labs/{mcp/src/db → daemon/src/stations}/materialize.ts +60 -175
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/stations/registry.ts +20 -2
- package/runtime/node_modules/@metro-labs/daemon/src/stations/runtime-deps.ts +82 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor-io.ts +3 -3
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/supervisor.ts +6 -9
- package/runtime/node_modules/@metro-labs/daemon/src/stations/threema-callbacks.ts +32 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon → daemon/src/stations}/train-call.ts +1 -1
- package/runtime/node_modules/@metro-labs/daemon/src/stations/webhook-endpoints.ts +51 -0
- package/runtime/node_modules/@metro-labs/daemon/src/terminal/api.ts +84 -0
- package/runtime/node_modules/@metro-labs/daemon/src/terminal/socket.ts +124 -0
- package/runtime/node_modules/@metro-labs/daemon/src/terminal/tickets.ts +15 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/api.ts +45 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/config.ts +51 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/firewall.ts +9 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/index.ts +96 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/install.ts +56 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/paths.ts +26 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/proxy.ts +147 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/store.ts +129 -0
- package/runtime/node_modules/@metro-labs/daemon/src/vault/trust.ts +44 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/api.ts +14 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/approvals.ts +38 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/audio.ts +153 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/brain.ts +135 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/call.ts +200 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/calls.ts +130 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/peer.ts +84 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/scribe.ts +103 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/speakable.ts +54 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/speech.ts +104 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/store.ts +116 -0
- package/runtime/node_modules/@metro-labs/daemon/src/voice/talk.ts +256 -0
- package/runtime/node_modules/@metro-labs/discord-bot/package.json +3 -5
- package/runtime/node_modules/@metro-labs/discord-bot/src/accounts.ts +3 -23
- package/runtime/node_modules/@metro-labs/discord-bot/src/actions.ts +19 -187
- package/runtime/node_modules/@metro-labs/discord-bot/src/attachments.ts +2 -2
- package/runtime/node_modules/@metro-labs/discord-bot/src/format.ts +26 -67
- package/runtime/node_modules/@metro-labs/discord-bot/src/group-actions.ts +1 -1
- package/runtime/node_modules/@metro-labs/discord-bot/src/group.ts +2 -2
- package/runtime/node_modules/@metro-labs/discord-bot/src/index.ts +8 -14
- package/runtime/node_modules/@metro-labs/discord-bot/src/members.ts +2 -2
- package/runtime/node_modules/@metro-labs/discord-bot/src/profile.ts +68 -0
- package/runtime/node_modules/@metro-labs/discord-bot/src/send-files.ts +12 -13
- package/runtime/node_modules/@metro-labs/discord-bot/src/station.ts +5 -1
- package/runtime/node_modules/@metro-labs/gmail/package.json +25 -0
- package/runtime/node_modules/@metro-labs/gmail/src/accounts.ts +81 -0
- package/runtime/node_modules/@metro-labs/gmail/src/actions.ts +14 -0
- package/runtime/node_modules/@metro-labs/gmail/src/api.ts +31 -0
- package/runtime/node_modules/@metro-labs/gmail/src/attachments.ts +35 -0
- package/runtime/node_modules/@metro-labs/gmail/src/auth.ts +105 -0
- package/runtime/node_modules/@metro-labs/gmail/src/config.ts +13 -0
- package/runtime/node_modules/@metro-labs/gmail/src/inbound.ts +96 -0
- package/runtime/node_modules/@metro-labs/gmail/src/index.ts +12 -0
- package/runtime/node_modules/@metro-labs/gmail/src/login.ts +37 -0
- package/runtime/node_modules/@metro-labs/gmail/src/message.ts +125 -0
- package/runtime/node_modules/@metro-labs/gmail/src/mime.ts +70 -0
- package/runtime/node_modules/@metro-labs/gmail/src/outbound.ts +124 -0
- package/runtime/node_modules/@metro-labs/gmail/src/query.ts +99 -0
- package/runtime/node_modules/@metro-labs/gmail/src/state.ts +24 -0
- package/runtime/node_modules/@metro-labs/gmail/src/station.ts +15 -0
- package/runtime/node_modules/@metro-labs/gmail/src/trust.ts +42 -0
- package/runtime/node_modules/@metro-labs/http/package.json +30 -0
- package/runtime/node_modules/@metro-labs/http/src/api-http.ts +141 -0
- package/runtime/node_modules/@metro-labs/{mcp/src/daemon/session-api.ts → http/src/mode-api.ts} +13 -9
- package/runtime/node_modules/@metro-labs/http/src/return-to.ts +25 -0
- package/runtime/node_modules/@metro-labs/http/src/sigv4.ts +90 -0
- package/runtime/node_modules/@metro-labs/http/src/workos-token.ts +149 -0
- package/runtime/node_modules/@metro-labs/outlook/package.json +25 -0
- package/runtime/node_modules/@metro-labs/outlook/src/accounts.ts +78 -0
- package/runtime/node_modules/@metro-labs/outlook/src/actions.ts +14 -0
- package/runtime/node_modules/@metro-labs/outlook/src/attachments.ts +81 -0
- package/runtime/node_modules/@metro-labs/outlook/src/auth.ts +120 -0
- package/runtime/node_modules/@metro-labs/outlook/src/browser.ts +42 -0
- package/runtime/node_modules/@metro-labs/outlook/src/config.ts +23 -0
- package/runtime/node_modules/@metro-labs/outlook/src/format.ts +59 -0
- package/runtime/node_modules/@metro-labs/outlook/src/graph.ts +55 -0
- package/runtime/node_modules/@metro-labs/outlook/src/inbound.ts +96 -0
- package/runtime/node_modules/@metro-labs/outlook/src/index.ts +12 -0
- package/runtime/node_modules/@metro-labs/outlook/src/login.ts +129 -0
- package/runtime/node_modules/@metro-labs/outlook/src/me.ts +31 -0
- package/runtime/node_modules/@metro-labs/outlook/src/outbound.ts +103 -0
- package/runtime/node_modules/@metro-labs/outlook/src/query.ts +84 -0
- package/runtime/node_modules/@metro-labs/outlook/src/state.ts +28 -0
- package/runtime/node_modules/@metro-labs/outlook/src/station.ts +15 -0
- package/runtime/node_modules/@metro-labs/outlook/src/trust.ts +41 -0
- package/runtime/node_modules/@metro-labs/telegram/package.json +2 -4
- package/runtime/node_modules/@metro-labs/telegram/src/accounts.ts +5 -24
- package/runtime/node_modules/@metro-labs/telegram/src/actions.ts +8 -6
- package/runtime/node_modules/@metro-labs/telegram/src/attachments.ts +1 -1
- package/runtime/node_modules/@metro-labs/telegram/src/client.ts +4 -4
- package/runtime/node_modules/@metro-labs/telegram/src/format.ts +19 -34
- package/runtime/node_modules/@metro-labs/telegram/src/group.ts +3 -3
- package/runtime/node_modules/@metro-labs/telegram/src/inbound.ts +13 -34
- package/runtime/node_modules/@metro-labs/telegram/src/index.ts +4 -43
- package/runtime/node_modules/@metro-labs/telegram/src/media-actions.ts +2 -3
- package/runtime/node_modules/@metro-labs/telegram/src/members.ts +1 -1
- package/runtime/node_modules/@metro-labs/telegram/src/profile.ts +70 -0
- package/runtime/node_modules/@metro-labs/telegram/src/reactions.ts +2 -2
- package/runtime/node_modules/@metro-labs/telegram/src/station.ts +4 -1
- package/runtime/node_modules/@metro-labs/telegram/src/types.ts +0 -1
- package/runtime/node_modules/@metro-labs/telegram-bot/package.json +2 -2
- package/runtime/node_modules/@metro-labs/telegram-bot/src/accounts.ts +7 -41
- package/runtime/node_modules/@metro-labs/telegram-bot/src/actions.ts +22 -77
- package/runtime/node_modules/@metro-labs/telegram-bot/src/attachments.ts +2 -2
- package/runtime/node_modules/@metro-labs/telegram-bot/src/format.ts +46 -48
- package/runtime/node_modules/@metro-labs/telegram-bot/src/index.ts +15 -15
- package/runtime/node_modules/@metro-labs/telegram-bot/src/media-actions.ts +6 -82
- package/runtime/node_modules/@metro-labs/telegram-bot/src/members.ts +1 -1
- package/runtime/node_modules/@metro-labs/telegram-bot/src/profile.ts +85 -0
- package/runtime/node_modules/@metro-labs/telegram-bot/src/station.ts +5 -1
- package/runtime/node_modules/@metro-labs/telegram-bot/src/types.ts +20 -12
- package/runtime/node_modules/@metro-labs/threema/package.json +26 -0
- package/runtime/node_modules/@metro-labs/threema/src/accounts.ts +96 -0
- package/runtime/node_modules/@metro-labs/threema/src/actions.ts +124 -0
- package/runtime/node_modules/@metro-labs/threema/src/api.ts +152 -0
- package/runtime/node_modules/@metro-labs/threema/src/crypto.ts +100 -0
- package/runtime/node_modules/@metro-labs/threema/src/files.ts +47 -0
- package/runtime/node_modules/@metro-labs/threema/src/format.ts +164 -0
- package/runtime/node_modules/@metro-labs/threema/src/groups.ts +96 -0
- package/runtime/node_modules/@metro-labs/threema/src/ids.ts +21 -0
- package/runtime/node_modules/@metro-labs/threema/src/inbound.ts +87 -0
- package/runtime/node_modules/@metro-labs/threema/src/index.ts +24 -0
- package/runtime/node_modules/@metro-labs/threema/src/messages.ts +264 -0
- package/runtime/node_modules/@metro-labs/threema/src/outbound.ts +160 -0
- package/runtime/node_modules/@metro-labs/threema/src/station.ts +13 -0
- package/runtime/node_modules/@metro-labs/threema/src/verify.ts +117 -0
- package/runtime/node_modules/@metro-labs/webhook/package.json +2 -2
- package/runtime/node_modules/@metro-labs/webhook/src/station.ts +5 -8
- package/runtime/node_modules/@metro-labs/whatsapp/package.json +3 -6
- package/runtime/node_modules/@metro-labs/whatsapp/src/accounts.ts +6 -28
- package/runtime/node_modules/@metro-labs/whatsapp/src/ack.ts +1 -1
- package/runtime/node_modules/@metro-labs/whatsapp/src/actions.ts +54 -11
- package/runtime/node_modules/@metro-labs/whatsapp/src/attachments.ts +2 -2
- package/runtime/node_modules/@metro-labs/whatsapp/src/auth-state.ts +1 -1
- package/runtime/node_modules/@metro-labs/whatsapp/src/client.ts +86 -4
- package/runtime/node_modules/@metro-labs/whatsapp/src/format.ts +7 -58
- package/runtime/node_modules/@metro-labs/whatsapp/src/inbound.ts +11 -28
- package/runtime/node_modules/@metro-labs/whatsapp/src/index.ts +4 -37
- package/runtime/node_modules/@metro-labs/whatsapp/src/keys.ts +1 -1
- package/runtime/node_modules/@metro-labs/whatsapp/src/login.ts +1 -1
- package/runtime/node_modules/@metro-labs/whatsapp/src/media.ts +1 -1
- package/runtime/node_modules/@metro-labs/whatsapp/src/names.ts +75 -0
- package/runtime/node_modules/@metro-labs/whatsapp/src/parse.ts +44 -0
- package/runtime/node_modules/@metro-labs/whatsapp/src/resolve.ts +52 -0
- package/runtime/node_modules/@metro-labs/whatsapp/src/station.ts +16 -1
- package/runtime/node_modules/@metro-labs/whatsapp/src/token-store.ts +5 -9
- package/runtime/node_modules/@metro-labs/whatsapp/src/types.ts +0 -1
- package/runtime/node_modules/@metro-labs/xmtp/package.json +4 -3
- package/runtime/node_modules/@metro-labs/xmtp/src/accounts.ts +10 -20
- package/runtime/node_modules/@metro-labs/xmtp/src/actions-close.ts +2 -2
- package/runtime/node_modules/@metro-labs/xmtp/src/actions-conv.ts +39 -223
- package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +47 -53
- package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +112 -223
- package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +3 -3
- package/runtime/node_modules/@metro-labs/xmtp/src/call-leftovers.ts +48 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +113 -3
- package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +35 -20
- package/runtime/node_modules/@metro-labs/xmtp/src/delete-requests.ts +34 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +37 -25
- package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +8 -18
- package/runtime/node_modules/@metro-labs/xmtp/src/frames.ts +178 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/group-members.ts +1 -1
- package/runtime/node_modules/@metro-labs/xmtp/src/group.ts +2 -2
- package/runtime/node_modules/@metro-labs/xmtp/src/identity.ts +30 -16
- package/runtime/node_modules/@metro-labs/xmtp/src/index.ts +18 -70
- package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +102 -50
- package/runtime/node_modules/@metro-labs/xmtp/src/member-args.ts +1 -1
- package/runtime/node_modules/@metro-labs/xmtp/src/names.ts +61 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/network.ts +110 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/profile.ts +160 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/resolve.ts +44 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/sender.ts +112 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/smart.ts +79 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +8 -2
- package/runtime/node_modules/@metro-labs/xmtp/src/stream.ts +66 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +22 -58
- package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +72 -49
- package/runtime/node_modules/@metro-labs/xmtp/src/transcribe.ts +4 -6
- package/runtime/node_modules/@metro-labs/xmtp/src/verify.ts +19 -5
- package/runtime/node_modules/@metro-labs/xmtp/src/wallet.ts +28 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/wire.ts +14 -4
- package/runtime/runtime.json +1 -1
- package/runtime/sdk-runner/node_modules/@metro-labs/core/package.json +52 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/endpoints.ts +7 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/events.ts +121 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/ids.ts +28 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/is-record.ts +2 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/lines.ts +78 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/log.ts +42 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/protocol.ts +227 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/runner-activity.ts +103 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/secure-fs.ts +74 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/station-names.ts +14 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-files.ts +41 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/account-store.ts +83 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/attachments.ts +195 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-text.ts +72 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail-trust.ts +29 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/mail.ts +212 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/messaging-normalize.ts +16 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/oauth.ts +126 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/profile.ts +58 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/sender-profile.ts +64 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/station-runtime.ts +59 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-boot.ts +42 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/train-events.ts +84 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/stations/types.ts +125 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/str.ts +5 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/tickets.ts +37 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/train-error.ts +53 -0
- package/runtime/sdk-runner/node_modules/@metro-labs/core/src/version.ts +2 -0
- package/runtime/sdk-runner/runner.json +10 -0
- package/runtime/sdk-runner/src/activity-tasks.ts +142 -0
- package/runtime/sdk-runner/src/activity.ts +293 -0
- package/runtime/sdk-runner/src/app.ts +77 -0
- package/runtime/sdk-runner/src/approvals.ts +28 -0
- package/runtime/sdk-runner/src/channel-text.ts +26 -0
- package/runtime/sdk-runner/src/config.ts +50 -0
- package/runtime/sdk-runner/src/inbox.ts +94 -0
- package/runtime/sdk-runner/src/link.ts +130 -0
- package/runtime/sdk-runner/src/main.ts +44 -0
- package/runtime/sdk-runner/src/rules.ts +11 -0
- package/runtime/sdk-runner/src/runner.ts +251 -0
- package/runtime/sdk-runner/src/session-store.ts +71 -0
- package/runtime/sdk-runner/src/session-watch.ts +111 -0
- package/runtime/sdk-runner/src/singleton.ts +15 -0
- package/runtime/sdk-runner/src/speech.ts +79 -0
- package/runtime/sdk-runner/src/tool-proxy.ts +40 -0
- package/runtime/server.ts +1 -0
- package/runtime/stations.json +40 -0
- package/dist/plugin.js +0 -82
- package/dist/prompt.js +0 -61
- package/dist/store.js +0 -70
- package/runtime/node_modules/@metro-labs/discord-bot/src/voice-speak.ts +0 -195
- package/runtime/node_modules/@metro-labs/discord-bot/src/voice-transcribe.ts +0 -292
- package/runtime/node_modules/@metro-labs/discord-bot/src/voice.ts +0 -197
- package/runtime/node_modules/@metro-labs/discord-bot/src/wire.ts +0 -5
- package/runtime/node_modules/@metro-labs/mcp/package.json +0 -66
- package/runtime/node_modules/@metro-labs/mcp/src/channels/dedupe.ts +0 -24
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/account-api.ts +0 -311
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/agent-api.ts +0 -341
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/api-http.ts +0 -129
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/boot.ts +0 -321
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair-api.ts +0 -118
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair.ts +0 -20
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/collection-api.ts +0 -202
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-json.ts +0 -21
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-tools.ts +0 -100
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-url.ts +0 -57
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/connector-verify.ts +0 -333
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-auth.ts +0 -164
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/google-oauth.ts +0 -208
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/identity.ts +0 -79
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/oauth-pending.ts +0 -65
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/pair-codes.ts +0 -58
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/project-api.ts +0 -214
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-api.ts +0 -125
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/run-pair.ts +0 -18
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/runtime-source.ts +0 -105
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/session-apis.ts +0 -43
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/session.ts +0 -218
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/tunnel.ts +0 -169
- package/runtime/node_modules/@metro-labs/mcp/src/db/account-attach.ts +0 -91
- package/runtime/node_modules/@metro-labs/mcp/src/db/agent-admin.ts +0 -215
- package/runtime/node_modules/@metro-labs/mcp/src/db/agent-map.ts +0 -71
- package/runtime/node_modules/@metro-labs/mcp/src/db/client.ts +0 -37
- package/runtime/node_modules/@metro-labs/mcp/src/db/connector-collections.ts +0 -218
- package/runtime/node_modules/@metro-labs/mcp/src/db/connector-relay.ts +0 -126
- package/runtime/node_modules/@metro-labs/mcp/src/db/connectors.ts +0 -308
- package/runtime/node_modules/@metro-labs/mcp/src/db/projects.ts +0 -300
- package/runtime/node_modules/@metro-labs/mcp/src/db/runtime-admin.ts +0 -31
- package/runtime/node_modules/@metro-labs/mcp/src/db/runtimes.ts +0 -105
- package/runtime/node_modules/@metro-labs/mcp/src/db/schema.ts +0 -131
- package/runtime/node_modules/@metro-labs/mcp/src/db/token-carry.ts +0 -45
- package/runtime/node_modules/@metro-labs/mcp/src/db/users.ts +0 -57
- package/runtime/node_modules/@metro-labs/mcp/src/db/whatsapp-login.ts +0 -18
- package/runtime/node_modules/@metro-labs/mcp/src/mcp/channel-owner.ts +0 -29
- package/runtime/node_modules/@metro-labs/mcp/src/mcp/frame-scope.ts +0 -21
- package/runtime/node_modules/@metro-labs/mcp/src/mcp/permission-relay.ts +0 -66
- package/runtime/node_modules/@metro-labs/mcp/src/mcp/request-identity.ts +0 -73
- package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-registry.ts +0 -172
- package/runtime/node_modules/@metro-labs/mcp/src/mcp/session-route.ts +0 -43
- package/runtime/node_modules/@metro-labs/mcp/src/monitor/api.ts +0 -240
- package/runtime/node_modules/@metro-labs/mcp/src/server.ts +0 -2
- package/runtime/node_modules/@metro-labs/mcp/src/stations/account-store.ts +0 -80
- package/runtime/node_modules/@metro-labs/mcp/src/stations/messaging-normalize.ts +0 -88
- package/runtime/node_modules/@metro-labs/telegram/src/normalize.ts +0 -22
- package/runtime/node_modules/@metro-labs/telegram/src/wire.ts +0 -1
- package/runtime/node_modules/@metro-labs/telegram-bot/src/wire.ts +0 -3
- package/runtime/node_modules/@metro-labs/whatsapp/src/normalize.ts +0 -22
- package/runtime/node_modules/@metro-labs/whatsapp/src/wire.ts +0 -5
- package/runtime/node_modules/@metro-labs/xmtp/src/actions-push.ts +0 -87
- package/runtime/node_modules/@metro-labs/xmtp/src/emit-core.ts +0 -55
- package/runtime/node_modules/@metro-labs/xmtp/src/push.ts +0 -349
- /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/log.ts +0 -0
- /package/runtime/node_modules/@metro-labs/{mcp/src/mcp → core/src}/str.ts +0 -0
- /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → core/src}/train-error.ts +0 -0
- /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/channels/webhook-note.ts +0 -0
- /package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/raw-get-stream.ts +0 -0
- /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/api-error.ts +0 -0
- /package/runtime/node_modules/@metro-labs/{mcp/src/daemon → http/src}/cors.ts +0 -0
package/dist/agent.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { headlessEnv, runClaude } from './claude.js';
|
|
6
|
+
import { localAgent } from './local.js';
|
|
7
|
+
import { currentModel, harnessRunner, permissionMode, systemPrompt } from './route.js';
|
|
8
|
+
import { installDependencies, ranges, readOrNull } from './runtime-install.js';
|
|
9
|
+
import { findBun, localPort, runtimeDir } from './runtime.js';
|
|
10
|
+
export const RUNNER_SOURCES = 'sdk-runner';
|
|
11
|
+
const STAMP = 'runner.json';
|
|
12
|
+
const ENTRY = join('src', 'main.ts');
|
|
13
|
+
const METRO_MODULES = join('node_modules', '@metro-labs');
|
|
14
|
+
const BUNFIG = '[install]\noptional = false\npeer = false\n';
|
|
15
|
+
const SDK = '@anthropic-ai/claude-agent-sdk';
|
|
16
|
+
const NOT_THE_RUNNER = 'the Harness runs this agent as a Claude Code session, so metro agent does not start: it would take the metro chat away from it. Choose Agent SDK as the Harness runner on metro.box first';
|
|
17
|
+
export function runnerStore(env = process.env) {
|
|
18
|
+
const explicit = env.METRO_RUNNER_STORE?.trim() ?? '';
|
|
19
|
+
return explicit === '' ? join(homedir(), '.metro', 'sdk-runner') : explicit;
|
|
20
|
+
}
|
|
21
|
+
export function readRunnerManifest(text) {
|
|
22
|
+
const raw = JSON.parse(text);
|
|
23
|
+
return {
|
|
24
|
+
version: typeof raw.version === 'string' ? raw.version : '',
|
|
25
|
+
dependencies: ranges(raw.dependencies),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function glibcMissing() {
|
|
29
|
+
const report = process.report.getReport();
|
|
30
|
+
return report.header?.glibcVersionRuntime === undefined;
|
|
31
|
+
}
|
|
32
|
+
export function claudePackage(platform = process.platform, arch = process.arch, musl = platform === 'linux' && glibcMissing()) {
|
|
33
|
+
return { name: `${SDK}-${platform}-${arch}${musl ? '-musl' : ''}`, binary: platform === 'win32' ? 'claude.exe' : 'claude' };
|
|
34
|
+
}
|
|
35
|
+
export function runnerDependencies(manifest, pkg) {
|
|
36
|
+
const sdk = manifest.dependencies[SDK];
|
|
37
|
+
return sdk === undefined ? manifest.dependencies : { ...manifest.dependencies, [pkg.name]: sdk };
|
|
38
|
+
}
|
|
39
|
+
function stageSources(sources, store, stamp) {
|
|
40
|
+
mkdirSync(store, { recursive: true });
|
|
41
|
+
if (readOrNull(join(store, STAMP)) !== stamp || !existsSync(join(store, ENTRY))) {
|
|
42
|
+
rmSync(join(store, 'src'), { recursive: true, force: true });
|
|
43
|
+
rmSync(join(store, METRO_MODULES), { recursive: true, force: true });
|
|
44
|
+
cpSync(join(sources, 'src'), join(store, 'src'), { recursive: true });
|
|
45
|
+
cpSync(join(sources, METRO_MODULES), join(store, METRO_MODULES), { recursive: true });
|
|
46
|
+
writeFileSync(join(store, STAMP), stamp);
|
|
47
|
+
}
|
|
48
|
+
if (readOrNull(join(store, 'bunfig.toml')) !== BUNFIG)
|
|
49
|
+
writeFileSync(join(store, 'bunfig.toml'), BUNFIG);
|
|
50
|
+
}
|
|
51
|
+
export function prepareRunner(opts = {}) {
|
|
52
|
+
const sources = opts.sources ?? join(runtimeDir(), RUNNER_SOURCES);
|
|
53
|
+
const stamp = readFileSync(join(sources, STAMP), 'utf8');
|
|
54
|
+
const store = opts.store ?? runnerStore();
|
|
55
|
+
stageSources(sources, store, stamp);
|
|
56
|
+
const log = opts.log ??
|
|
57
|
+
((line) => {
|
|
58
|
+
process.stderr.write(`metro agent: ${line}\n`);
|
|
59
|
+
});
|
|
60
|
+
const pkg = opts.claude ?? claudePackage();
|
|
61
|
+
const claude = join(store, 'node_modules', ...pkg.name.split('/'), pkg.binary);
|
|
62
|
+
const marker = join(store, 'node_modules', '.metro-installed');
|
|
63
|
+
if (!existsSync(claude))
|
|
64
|
+
rmSync(marker, { force: true });
|
|
65
|
+
installDependencies(store, runnerDependencies(readRunnerManifest(stamp), pkg), opts.bun ?? findBun(), log);
|
|
66
|
+
if (!existsSync(claude)) {
|
|
67
|
+
rmSync(marker, { force: true });
|
|
68
|
+
throw new Error(`The Claude Code binary bundled with the Agent SDK is missing at ${claude}. Try preparing the runner again.`);
|
|
69
|
+
}
|
|
70
|
+
return { entry: join(store, ENTRY), claude };
|
|
71
|
+
}
|
|
72
|
+
export function runnerEnv(key, port, model, mode, prompt, claude) {
|
|
73
|
+
return {
|
|
74
|
+
METRO_RUNNER_MCP_URL: `http://127.0.0.1:${String(port)}/mcp`,
|
|
75
|
+
METRO_RUNNER_CLAUDE: claude,
|
|
76
|
+
METRO_AGENT_KEY: key,
|
|
77
|
+
METRO_RUNNER_PERMISSION_MODE: mode,
|
|
78
|
+
...(model === null ? {} : { METRO_RUNNER_MODEL: model }),
|
|
79
|
+
...(prompt === null ? {} : { METRO_RUNNER_PROMPT: prompt }),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function sdkGatewayEnv(env) {
|
|
83
|
+
const own = (env.ANTHROPIC_CUSTOM_HEADERS ?? '').trim();
|
|
84
|
+
const header = 'x-metro-runner: sdk';
|
|
85
|
+
return { ...env, ANTHROPIC_CUSTOM_HEADERS: own === '' ? header : `${own}\n${header}` };
|
|
86
|
+
}
|
|
87
|
+
function checkBinary(bin) {
|
|
88
|
+
const run = spawnSync(bin, ['--version'], { stdio: 'ignore', timeout: 30_000 });
|
|
89
|
+
if (run.error !== undefined || run.status !== 0)
|
|
90
|
+
throw new Error(`Runner preflight failed: ${bin} cannot run (${run.error?.message ?? `exit ${String(run.status)}`}).`);
|
|
91
|
+
}
|
|
92
|
+
function checkPreparedRunner(opts) {
|
|
93
|
+
const prepared = prepareRunner(opts);
|
|
94
|
+
try {
|
|
95
|
+
checkBinary(prepared.claude);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
rmSync(join(opts.store ?? runnerStore(), 'node_modules', '.metro-installed'), { force: true });
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function prepareAgentRunner(runner, opts = {}) {
|
|
103
|
+
if (runner === 'cli')
|
|
104
|
+
checkBinary('claude');
|
|
105
|
+
else if (runner === 'sdk')
|
|
106
|
+
checkPreparedRunner(opts);
|
|
107
|
+
else
|
|
108
|
+
throw new Error('metro agent --prepare needs cli or sdk');
|
|
109
|
+
}
|
|
110
|
+
export async function agentSession(args = []) {
|
|
111
|
+
if (args[0] === '--prepare' && args.length <= 2) {
|
|
112
|
+
prepareAgentRunner(args[1] ?? 'sdk');
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
if (args.length > 0)
|
|
116
|
+
throw new Error('metro agent accepts only --prepare [cli|sdk]');
|
|
117
|
+
process.chdir(homedir());
|
|
118
|
+
if (harnessRunner() !== 'sdk')
|
|
119
|
+
throw new Error(NOT_THE_RUNNER);
|
|
120
|
+
const agent = localAgent();
|
|
121
|
+
if (agent === null)
|
|
122
|
+
throw new Error('metro agent needs the agent of this machine, and there is none yet');
|
|
123
|
+
const bun = findBun();
|
|
124
|
+
const runner = prepareRunner({ bun });
|
|
125
|
+
process.stderr.write('metro agent: this agent runs as one Agent SDK session: a light front talks, background workers do the work\n');
|
|
126
|
+
const env = { ...sdkGatewayEnv(await headlessEnv()), ...runnerEnv(agent.key, localPort(), currentModel(), permissionMode(), systemPrompt(), runner.claude) };
|
|
127
|
+
return runClaude([runner.entry], env, undefined, bun);
|
|
128
|
+
}
|
package/dist/api.js
CHANGED
|
@@ -1,131 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
const TIMEOUT_MS = 20_000;
|
|
5
|
-
const LOOPBACK = new Set(['localhost', '127.0.0.1', '::1', '[::1]']);
|
|
6
|
-
export function carriesSecretsSafely(base) {
|
|
7
|
-
let url;
|
|
8
|
-
try {
|
|
9
|
-
url = new URL(base);
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
if (url.protocol === 'https:')
|
|
15
|
-
return true;
|
|
16
|
-
return url.protocol === 'http:' && LOOPBACK.has(url.hostname);
|
|
17
|
-
}
|
|
18
|
-
function tokenOrThrow() {
|
|
19
|
-
if (!carriesSecretsSafely(metroUrl()))
|
|
20
|
-
throw new Error(`refusing to send your session to ${metroUrl()} in the clear — use https, or a loopback address`);
|
|
21
|
-
const token = readToken();
|
|
22
|
-
if (token === null)
|
|
23
|
-
throw new NotSignedIn('not signed in — run `metro login` first');
|
|
24
|
-
return token;
|
|
25
|
-
}
|
|
26
|
-
async function get(path) {
|
|
27
|
-
const auth = tokenOrThrow();
|
|
28
|
-
let res;
|
|
29
|
-
try {
|
|
30
|
-
res = await fetch(`${metroUrl()}${path}`, {
|
|
31
|
-
headers: { authorization: `Bearer ${auth}` },
|
|
32
|
-
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
throw new Error(`could not reach ${metroUrl()}`);
|
|
37
|
-
}
|
|
38
|
-
if (res.status === 401)
|
|
39
|
-
throw new NotSignedIn('that sign-in has expired — run `metro login` again');
|
|
40
|
-
if (!res.ok)
|
|
41
|
-
throw new Error(`metro answered ${String(res.status)}`);
|
|
42
|
-
return res.json();
|
|
43
|
-
}
|
|
44
|
-
function isRecord(value) {
|
|
45
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
46
|
-
}
|
|
47
|
-
async function post(path, body) {
|
|
48
|
-
if (!carriesSecretsSafely(metroUrl()))
|
|
49
|
-
throw new Error(`refusing to send your code to ${metroUrl()} in the clear — use https, or a loopback address`);
|
|
50
|
-
let res;
|
|
51
|
-
try {
|
|
52
|
-
res = await fetch(`${metroUrl()}${path}`, {
|
|
53
|
-
method: 'POST',
|
|
54
|
-
headers: { 'content-type': 'application/json' },
|
|
55
|
-
body: JSON.stringify(body),
|
|
56
|
-
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
throw new Error(`could not reach ${metroUrl()}`);
|
|
61
|
-
}
|
|
62
|
-
const parsed = await res.json().catch(() => null);
|
|
63
|
-
if (res.ok)
|
|
64
|
-
return parsed;
|
|
65
|
-
const detail = isRecord(parsed) ? parsed.error : undefined;
|
|
66
|
-
throw new Error(typeof detail === 'string' ? detail : `metro answered ${String(res.status)}`);
|
|
67
|
-
}
|
|
68
|
-
export class RuntimeRevoked extends Error {
|
|
69
|
-
}
|
|
70
|
-
export function keyOfRunConfig(body) {
|
|
71
|
-
const agent = isRecord(body) ? body.agent : undefined;
|
|
72
|
-
const key = isRecord(agent) ? agent.key : undefined;
|
|
73
|
-
if (typeof key !== 'string' || key === '')
|
|
74
|
-
throw new Error('this agent has no key — reset it on its page in the web UI');
|
|
75
|
-
return key;
|
|
76
|
-
}
|
|
77
|
-
export async function runConfigKey(token) {
|
|
78
|
-
if (!carriesSecretsSafely(metroUrl()))
|
|
79
|
-
throw new Error(`refusing to send this machine's authorization to ${metroUrl()} in the clear — use https, or a loopback address`);
|
|
80
|
-
let res;
|
|
81
|
-
try {
|
|
82
|
-
res = await fetch(`${metroUrl()}/api/run/config`, {
|
|
83
|
-
headers: { authorization: `Bearer ${token}` },
|
|
84
|
-
signal: AbortSignal.timeout(TIMEOUT_MS),
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
throw new Error(`could not reach ${metroUrl()}`);
|
|
89
|
-
}
|
|
90
|
-
if (res.status === 401 || res.status === 403 || res.status === 409)
|
|
91
|
-
throw new RuntimeRevoked('this machine no longer holds the agent — authorize it again from the agent page');
|
|
92
|
-
if (!res.ok)
|
|
93
|
-
throw new Error(`metro answered ${String(res.status)}`);
|
|
94
|
-
return keyOfRunConfig(await res.json());
|
|
95
|
-
}
|
|
96
|
-
export async function claimCode(code) {
|
|
97
|
-
const body = await post('/api/cli/claim', { code });
|
|
98
|
-
if (!isRecord(body) ||
|
|
99
|
-
typeof body.token !== 'string' ||
|
|
100
|
-
typeof body.email !== 'string' ||
|
|
101
|
-
typeof body.collection !== 'string')
|
|
102
|
-
throw new Error('metro returned an unexpected response');
|
|
103
|
-
return {
|
|
104
|
-
token: body.token,
|
|
105
|
-
email: body.email,
|
|
106
|
-
collection: body.collection,
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
export async function claimRuntime(code, label) {
|
|
110
|
-
const body = await post('/api/run/claim', { code, label });
|
|
111
|
-
if (!isRecord(body) ||
|
|
112
|
-
typeof body.token !== 'string' ||
|
|
113
|
-
typeof body.agent !== 'string' ||
|
|
114
|
-
typeof body.label !== 'string')
|
|
115
|
-
throw new Error('metro returned an unexpected response');
|
|
116
|
-
return { token: body.token, agent: body.agent, label: body.label };
|
|
117
|
-
}
|
|
118
|
-
export async function mcpServers() {
|
|
119
|
-
const body = await get('/api/cli/mcp');
|
|
120
|
-
if (!isRecord(body) || typeof body.json !== 'string')
|
|
121
|
-
throw new Error('metro returned an unexpected response');
|
|
122
|
-
return body.json;
|
|
123
|
-
}
|
|
1
|
+
import { localAgent, localDaemonUp } from './local.js';
|
|
2
|
+
import { localUrl } from './runtime.js';
|
|
3
|
+
const NO_DAEMON = `no metro daemon on ${localUrl()} — start one with: metro serve`;
|
|
124
4
|
export async function whoisAuthorized() {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
throw new Error('
|
|
130
|
-
return {
|
|
5
|
+
if (!(await localDaemonUp()))
|
|
6
|
+
throw new Error(NO_DAEMON);
|
|
7
|
+
const agent = localAgent();
|
|
8
|
+
if (agent === null)
|
|
9
|
+
throw new Error('no agent on this machine yet');
|
|
10
|
+
return { agent: agent.id, where: localUrl() };
|
|
131
11
|
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { basename, join } from 'node:path';
|
|
5
|
+
export const AGENT_VIEW_OFF = 'CLAUDE_CODE_DISABLE_AGENT_VIEW';
|
|
6
|
+
const STOP_MS = 30_000;
|
|
7
|
+
const SETTLE_MS = 5_000;
|
|
8
|
+
const POLL_MS = 250;
|
|
9
|
+
const given = (value) => value !== undefined && value.trim() !== '' ? value.trim() : undefined;
|
|
10
|
+
export const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
11
|
+
export const keepInSession = (env) => given(env[AGENT_VIEW_OFF]) === undefined ? { ...env, [AGENT_VIEW_OFF]: '1' } : env;
|
|
12
|
+
export const claudeDir = (env = process.env) => given(env.CLAUDE_CONFIG_DIR) ?? join(given(env.HOME) ?? homedir(), '.claude');
|
|
13
|
+
export const projectDir = (dir, cwd) => join(dir, 'projects', cwd.replace(/[^A-Za-z0-9]/g, '-'));
|
|
14
|
+
function startTime(pid) {
|
|
15
|
+
try {
|
|
16
|
+
const stat = readFileSync(`/proc/${String(pid)}/stat`, 'utf8');
|
|
17
|
+
return stat.slice(stat.lastIndexOf(')') + 2).split(' ')[19] ?? null;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function processAlive(pid, procStart) {
|
|
24
|
+
try {
|
|
25
|
+
process.kill(pid, 0);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (err.code !== 'EPERM')
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
const started = procStart === undefined ? null : startTime(pid);
|
|
32
|
+
return started === null || started === procStart;
|
|
33
|
+
}
|
|
34
|
+
function backgroundEntry(file, alive) {
|
|
35
|
+
try {
|
|
36
|
+
const raw = JSON.parse(readFileSync(file, 'utf8'));
|
|
37
|
+
if (!isRecord(raw) || typeof raw.pid !== 'number' || typeof raw.sessionId !== 'string')
|
|
38
|
+
return null;
|
|
39
|
+
if (raw.kind === 'interactive' || typeof raw.kind !== 'string')
|
|
40
|
+
return null;
|
|
41
|
+
return alive(raw.pid, typeof raw.procStart === 'string' ? raw.procStart : undefined) ? raw.sessionId : null;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function liveBackground(sessions, alive = processAlive) {
|
|
48
|
+
if (!existsSync(sessions))
|
|
49
|
+
return new Set();
|
|
50
|
+
const ids = readdirSync(sessions)
|
|
51
|
+
.filter((name) => name.endsWith('.json'))
|
|
52
|
+
.map((name) => backgroundEntry(join(sessions, name), alive));
|
|
53
|
+
return new Set(ids.filter((id) => id !== null));
|
|
54
|
+
}
|
|
55
|
+
function newestFirst(dir) {
|
|
56
|
+
if (!existsSync(dir))
|
|
57
|
+
return [];
|
|
58
|
+
return readdirSync(dir)
|
|
59
|
+
.filter((name) => name.endsWith('.jsonl'))
|
|
60
|
+
.map((name) => ({ path: join(dir, name), at: statSync(join(dir, name)).mtimeMs }))
|
|
61
|
+
.sort((a, b) => b.at - a.at)
|
|
62
|
+
.map((file) => file.path);
|
|
63
|
+
}
|
|
64
|
+
function continuedIn(text) {
|
|
65
|
+
const last = text.split('\n').findLast((line) => line.includes('"type":"continued-in"'));
|
|
66
|
+
if (last === undefined)
|
|
67
|
+
return null;
|
|
68
|
+
try {
|
|
69
|
+
const record = JSON.parse(last);
|
|
70
|
+
return isRecord(record) && typeof record.continuedInSessionId === 'string' ? record.continuedInSessionId : null;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const HAS_TURN = /"type":"(user|assistant)"/;
|
|
77
|
+
export function heldConversation(dir, live) {
|
|
78
|
+
if (live.size === 0)
|
|
79
|
+
return null;
|
|
80
|
+
for (const file of newestFirst(dir)) {
|
|
81
|
+
const text = readFileSync(file, 'utf8');
|
|
82
|
+
if (!HAS_TURN.test(text))
|
|
83
|
+
continue;
|
|
84
|
+
const moved = continuedIn(text);
|
|
85
|
+
if (moved !== null && live.has(moved))
|
|
86
|
+
return moved;
|
|
87
|
+
if (!live.has(basename(file, '.jsonl')))
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function stopBackground(id, env = process.env) {
|
|
93
|
+
const run = spawnSync('claude', ['stop', id], { env, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: STOP_MS });
|
|
94
|
+
if (run.error !== undefined)
|
|
95
|
+
return { ok: false, detail: run.error.message };
|
|
96
|
+
const said = `${run.stdout}${run.stderr}`.trim().split('\n').at(-1) ?? '';
|
|
97
|
+
return { ok: run.status === 0, detail: said === '' ? `exit ${String(run.status)}` : said };
|
|
98
|
+
}
|
|
99
|
+
export function resumeSessionId(args) {
|
|
100
|
+
const index = args.findLastIndex((arg) => arg === '--resume' || arg === '-r');
|
|
101
|
+
const id = index === -1 ? undefined : args[index + 1];
|
|
102
|
+
return id !== undefined && /^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/.test(id) ? id : undefined;
|
|
103
|
+
}
|
|
104
|
+
function pinnedHeld(dir, live, id) {
|
|
105
|
+
if (live.has(id))
|
|
106
|
+
return id;
|
|
107
|
+
const path = join(dir, `${id}.jsonl`);
|
|
108
|
+
if (!existsSync(path))
|
|
109
|
+
return null;
|
|
110
|
+
const moved = continuedIn(readFileSync(path, 'utf8'));
|
|
111
|
+
return moved !== null && live.has(moved) ? moved : null;
|
|
112
|
+
}
|
|
113
|
+
const sleep = (ms) => new Promise((resolve) => {
|
|
114
|
+
setTimeout(resolve, ms);
|
|
115
|
+
});
|
|
116
|
+
async function settled(sessions, held, alive, ms) {
|
|
117
|
+
if (!liveBackground(sessions, alive).has(held))
|
|
118
|
+
return true;
|
|
119
|
+
if (ms <= 0)
|
|
120
|
+
return false;
|
|
121
|
+
await sleep(POLL_MS);
|
|
122
|
+
return settled(sessions, held, alive, ms - POLL_MS);
|
|
123
|
+
}
|
|
124
|
+
function heldFor(deps, dir, live) {
|
|
125
|
+
const project = projectDir(dir, deps.cwd ?? process.cwd());
|
|
126
|
+
return deps.sessionId === undefined ? heldConversation(project, live) : pinnedHeld(project, live, deps.sessionId);
|
|
127
|
+
}
|
|
128
|
+
export async function takeBackConversation(deps = {}) {
|
|
129
|
+
const env = deps.env ?? process.env;
|
|
130
|
+
const alive = deps.alive ?? processAlive;
|
|
131
|
+
const dir = claudeDir(env);
|
|
132
|
+
const sessions = join(dir, 'sessions');
|
|
133
|
+
const held = heldFor(deps, dir, liveBackground(sessions, alive));
|
|
134
|
+
if (held === null)
|
|
135
|
+
return null;
|
|
136
|
+
const id = held.slice(0, 8);
|
|
137
|
+
const stopped = (deps.stop ?? stopBackground)(id, env);
|
|
138
|
+
if (!stopped.ok || !(await settled(sessions, held, alive, deps.settleMs ?? SETTLE_MS)))
|
|
139
|
+
return `the conversation is held by the Claude Code background session ${id} and it could not be stopped (${stopped.detail}), so Claude Code will refuse to continue it: run claude stop ${id}`;
|
|
140
|
+
return `the conversation had moved to the Claude Code background session ${id}, where no chat reaches it; stopped that session (its conversation is kept) and continuing it here`;
|
|
141
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { PROVIDER_FLAGS } from './provider-flags.js';
|
|
5
|
+
const CONFLICTING = [...PROVIDER_FLAGS, 'ANTHROPIC_BASE_URL', 'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN'];
|
|
6
|
+
export function settingsFiles(cwd = process.cwd(), env = process.env) {
|
|
7
|
+
const explicit = env.CLAUDE_CONFIG_DIR?.trim() ?? '';
|
|
8
|
+
const configDir = explicit === '' ? join(homedir(), '.claude') : explicit;
|
|
9
|
+
return [
|
|
10
|
+
...new Set([
|
|
11
|
+
join(configDir, 'settings.json'),
|
|
12
|
+
join(cwd, '.claude', 'settings.json'),
|
|
13
|
+
join(cwd, '.claude', 'settings.local.json'),
|
|
14
|
+
]),
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
function envBlock(file) {
|
|
18
|
+
if (!existsSync(file))
|
|
19
|
+
return {};
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(readFileSync(file, 'utf8'));
|
|
22
|
+
const block = parsed.env;
|
|
23
|
+
return typeof block === 'object' && block !== null ? block : {};
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function settingsConflicts(files) {
|
|
30
|
+
const out = [];
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const block = envBlock(file);
|
|
33
|
+
for (const key of CONFLICTING) {
|
|
34
|
+
const value = block[key];
|
|
35
|
+
if (typeof value === 'string' && value.trim() !== '')
|
|
36
|
+
out.push(`${file}: ${key}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
package/dist/claude.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
2
|
+
import { markOnboardingDone, seedChannels } from './onboarding.js';
|
|
3
|
+
import { writeMcpConfig } from './mcp-config.js';
|
|
4
|
+
import { currentRoute, harnessRunner, permissionMode, routeModelEnv, systemPrompt } from './route.js';
|
|
5
|
+
import { settingsConflicts, settingsFiles } from './claude-settings.js';
|
|
6
|
+
import { localAgent } from './local.js';
|
|
7
|
+
import { PROVIDER_FLAGS } from './provider-flags.js';
|
|
8
|
+
import { localPort, localUrl } from './runtime.js';
|
|
9
|
+
import { keepInSession, resumeSessionId, takeBackConversation } from './background.js';
|
|
10
|
+
const CHANNEL_FLAGS = ['--dangerously-load-development-channels', 'server:metro'];
|
|
11
|
+
const FRESH_PROMPT_FLAGS = ['--system-prompt-snapshot', 'off'];
|
|
12
|
+
export const PERMISSION_MODE_FLAG = { auto: 'auto', bypass: 'bypassPermissions' };
|
|
13
|
+
const KEY_HEADER = 'x-metro-key';
|
|
14
|
+
const PROBE_MS = 3_000;
|
|
15
|
+
const AUTH_STATUS_MS = 20_000;
|
|
16
|
+
const KILL_GRACE_MS = 30_000;
|
|
17
|
+
export const claudeArgs = (extra, mcpConfig, mode = 'auto', prompt = null) => [
|
|
18
|
+
...CHANNEL_FLAGS,
|
|
19
|
+
'--permission-mode',
|
|
20
|
+
PERMISSION_MODE_FLAG[mode],
|
|
21
|
+
...FRESH_PROMPT_FLAGS,
|
|
22
|
+
...(mcpConfig === undefined ? [] : ['--mcp-config', mcpConfig]),
|
|
23
|
+
...(prompt === null ? [] : ['--append-system-prompt', prompt]),
|
|
24
|
+
...extra,
|
|
25
|
+
];
|
|
26
|
+
const set = (env, name) => (env[name] ?? '').trim() !== '';
|
|
27
|
+
export function pinnedBy(env) {
|
|
28
|
+
if (set(env, 'ANTHROPIC_BASE_URL'))
|
|
29
|
+
return 'ANTHROPIC_BASE_URL';
|
|
30
|
+
return PROVIDER_FLAGS.find((flag) => set(env, flag)) ?? null;
|
|
31
|
+
}
|
|
32
|
+
export function gatewayEnv(base, agentKey, port) {
|
|
33
|
+
if (agentKey === null || pinnedBy(base) !== null)
|
|
34
|
+
return base;
|
|
35
|
+
const own = (base.ANTHROPIC_CUSTOM_HEADERS ?? '').trim();
|
|
36
|
+
const mine = `${KEY_HEADER}: ${agentKey}`;
|
|
37
|
+
return {
|
|
38
|
+
...base,
|
|
39
|
+
ANTHROPIC_BASE_URL: `http://127.0.0.1:${String(port)}/gateway`,
|
|
40
|
+
ANTHROPIC_CUSTOM_HEADERS: own === '' ? mine : `${own}\n${mine}`,
|
|
41
|
+
CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY: '1',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export const channelEnv = (env) => set(env, 'MCP_PROTOCOL_NEGOTIATION') ? env : { ...env, MCP_PROTOCOL_NEGOTIATION: 'legacy' };
|
|
45
|
+
export const toolSearchEnv = (env) => set(env, 'ENABLE_TOOL_SEARCH') ? env : { ...env, ENABLE_TOOL_SEARCH: 'true' };
|
|
46
|
+
const OWN_CREDENTIALS = ['ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN'];
|
|
47
|
+
export function credentialEnv(env, agentKey, signedIn) {
|
|
48
|
+
if (signedIn || OWN_CREDENTIALS.some((name) => set(env, name)))
|
|
49
|
+
return env;
|
|
50
|
+
return { ...env, ANTHROPIC_AUTH_TOKEN: agentKey };
|
|
51
|
+
}
|
|
52
|
+
function claudeSignedIn() {
|
|
53
|
+
const run = spawnSync('claude', ['auth', 'status', '--json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: AUTH_STATUS_MS });
|
|
54
|
+
if (run.error !== undefined || typeof run.stdout !== 'string')
|
|
55
|
+
return false;
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(run.stdout);
|
|
58
|
+
return parsed.authenticated === true || parsed.loggedIn === true || typeof parsed.email === 'string' || typeof parsed.organization === 'string';
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function servingDaemon(body) {
|
|
65
|
+
if (typeof body !== 'object' || body === null)
|
|
66
|
+
return false;
|
|
67
|
+
const mode = body;
|
|
68
|
+
return mode.mode === 'local' && mode.stopped !== true;
|
|
69
|
+
}
|
|
70
|
+
async function daemonServing(base = localUrl()) {
|
|
71
|
+
try {
|
|
72
|
+
const res = await fetch(`${base}/api/mode`, { signal: AbortSignal.timeout(PROBE_MS) });
|
|
73
|
+
return res.ok && servingDaemon(await res.json());
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function agentKey(agent) {
|
|
80
|
+
return agent === null ? { skip: 'no agent lives on this machine yet, so Claude Code talks to Anthropic directly' } : { key: agent.key };
|
|
81
|
+
}
|
|
82
|
+
async function verdict() {
|
|
83
|
+
const pinned = pinnedBy(process.env);
|
|
84
|
+
if (pinned !== null)
|
|
85
|
+
return { skip: `${pinned} is set, so Claude Code keeps talking to it` };
|
|
86
|
+
const conflicts = settingsConflicts(settingsFiles());
|
|
87
|
+
if (conflicts.length > 0)
|
|
88
|
+
return { skip: `a settings file pins the provider (${conflicts.join(', ')}), so Claude Code keeps it` };
|
|
89
|
+
const picked = agentKey(localAgent());
|
|
90
|
+
if ('skip' in picked)
|
|
91
|
+
return picked;
|
|
92
|
+
if (await daemonServing())
|
|
93
|
+
return picked;
|
|
94
|
+
return { skip: 'the daemon is not serving here (stopped, or not running), so Claude Code talks to Anthropic directly' };
|
|
95
|
+
}
|
|
96
|
+
function deadline(child, timeoutMs) {
|
|
97
|
+
if (timeoutMs === undefined)
|
|
98
|
+
return () => undefined;
|
|
99
|
+
let kill;
|
|
100
|
+
const term = setTimeout(() => {
|
|
101
|
+
child.kill('SIGTERM');
|
|
102
|
+
kill = setTimeout(() => {
|
|
103
|
+
child.kill('SIGKILL');
|
|
104
|
+
}, KILL_GRACE_MS);
|
|
105
|
+
}, timeoutMs);
|
|
106
|
+
return () => {
|
|
107
|
+
clearTimeout(term);
|
|
108
|
+
clearTimeout(kill);
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function runClaude(args, env, headless, command = 'claude') {
|
|
112
|
+
return new Promise((resolve, reject) => {
|
|
113
|
+
const leaveToChild = () => undefined;
|
|
114
|
+
process.on('SIGINT', leaveToChild);
|
|
115
|
+
process.on('SIGTERM', leaveToChild);
|
|
116
|
+
const child = spawn(command, args, { stdio: [headless === undefined ? 'inherit' : 'ignore', 'inherit', 'inherit'], env });
|
|
117
|
+
const stop = deadline(child, headless?.timeoutMs);
|
|
118
|
+
child.on('error', (err) => {
|
|
119
|
+
reject(new Error(err.code === 'ENOENT'
|
|
120
|
+
? `the \`${command}\` command is not on PATH${command === 'claude' ? ' — install Claude Code first' : ''}`
|
|
121
|
+
: err.message));
|
|
122
|
+
});
|
|
123
|
+
child.on('exit', (code) => {
|
|
124
|
+
stop();
|
|
125
|
+
resolve(code ?? 1);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async function servedKey(decision) {
|
|
130
|
+
if ('key' in decision)
|
|
131
|
+
return decision.key;
|
|
132
|
+
const picked = agentKey(localAgent());
|
|
133
|
+
if ('skip' in picked)
|
|
134
|
+
return null;
|
|
135
|
+
return (await daemonServing()) ? picked.key : null;
|
|
136
|
+
}
|
|
137
|
+
function mcpConfigFor(key, port) {
|
|
138
|
+
if (key === null)
|
|
139
|
+
return null;
|
|
140
|
+
const file = writeMcpConfig(key, port);
|
|
141
|
+
process.stderr.write(`metro claude: the metro MCP server is loaded for this session from the daemon at http://127.0.0.1:${String(port)}/mcp, nothing to add by hand\n`);
|
|
142
|
+
return file;
|
|
143
|
+
}
|
|
144
|
+
function gatewayLaunchEnv(key, port) {
|
|
145
|
+
process.stderr.write(`metro claude: inference goes through the daemon at http://127.0.0.1:${String(port)}/gateway (the Model page decides where)\n`);
|
|
146
|
+
const pointed = routeModelEnv(gatewayEnv(process.env, key, port), currentRoute());
|
|
147
|
+
const routed = toolSearchEnv(pointed);
|
|
148
|
+
if (routed !== pointed)
|
|
149
|
+
process.stderr.write('metro claude: MCP tool search is on, so connector tools load when Claude needs them instead of all at start\n');
|
|
150
|
+
const env = credentialEnv(routed, key, claudeSignedIn());
|
|
151
|
+
if (env !== routed)
|
|
152
|
+
process.stderr.write("metro claude: Claude Code has no login of its own here, so metro's key stands in as its credential; the Model page must route to Bedrock, OpenRouter or Codex\n");
|
|
153
|
+
if (seedChannels() === 'marked')
|
|
154
|
+
process.stderr.write('metro claude: marked Channels as available in Claude Code cached flags, since a box that sends no telemetry never fetches them\n');
|
|
155
|
+
if (markOnboardingDone() === 'marked')
|
|
156
|
+
process.stderr.write("metro claude: skipped Claude Code's first-run setup, since it already has a credential here\n");
|
|
157
|
+
return env;
|
|
158
|
+
}
|
|
159
|
+
function inferenceEnv(decision, port) {
|
|
160
|
+
if ('key' in decision)
|
|
161
|
+
return gatewayLaunchEnv(decision.key, port);
|
|
162
|
+
process.stderr.write(`metro claude: ${decision.skip}\n`);
|
|
163
|
+
return process.env;
|
|
164
|
+
}
|
|
165
|
+
export async function headlessEnv() {
|
|
166
|
+
return keepInSession(inferenceEnv(await verdict(), localPort()));
|
|
167
|
+
}
|
|
168
|
+
const continues = (args) => args.includes('-c') || args.includes('--continue');
|
|
169
|
+
async function reclaimConversation(extra) {
|
|
170
|
+
const sessionId = resumeSessionId(extra);
|
|
171
|
+
if (sessionId === undefined && !continues(extra))
|
|
172
|
+
return;
|
|
173
|
+
try {
|
|
174
|
+
const note = await takeBackConversation({ sessionId });
|
|
175
|
+
if (note !== null)
|
|
176
|
+
process.stderr.write(`metro claude: ${note}\n`);
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
180
|
+
process.stderr.write(`metro claude: could not check for a Claude Code background session holding the conversation (${message})\n`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const SDK_HOLDS_CHAT = 'the Harness runs this agent as an Agent SDK session (metro agent), which holds the metro chat; a metro claude session would take it away. Switch the Harness runner back to the Claude Code session first, or open the conversation with plain claude --resume <session id>';
|
|
184
|
+
export async function launchClaude(extra) {
|
|
185
|
+
if (harnessRunner() === 'sdk')
|
|
186
|
+
throw new Error(SDK_HOLDS_CHAT);
|
|
187
|
+
await reclaimConversation(extra);
|
|
188
|
+
const decision = await verdict();
|
|
189
|
+
const port = localPort();
|
|
190
|
+
const mcp = mcpConfigFor(await servedKey(decision), port);
|
|
191
|
+
const mode = permissionMode();
|
|
192
|
+
const prompt = systemPrompt();
|
|
193
|
+
if (prompt !== null)
|
|
194
|
+
process.stderr.write('metro claude: the system prompt from the Harness page is appended to this session\n');
|
|
195
|
+
try {
|
|
196
|
+
return await runClaude(claudeArgs(extra, mcp?.path, mode, prompt), keepInSession(channelEnv(inferenceEnv(decision, port))));
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
mcp?.cleanup();
|
|
200
|
+
}
|
|
201
|
+
}
|