@stage-labs/metro 0.1.0-beta.23 → 0.1.0-beta.231
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/api.js +9 -101
- package/dist/background.js +123 -0
- package/dist/claude-settings.js +40 -0
- package/dist/claude.js +197 -0
- package/dist/cli.js +52 -110
- package/dist/control.js +19 -103
- package/dist/hold.js +210 -0
- package/dist/local.js +43 -0
- package/dist/mcp-config.js +25 -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/route.js +58 -0
- package/dist/runtime-install.js +96 -0
- package/dist/runtime.js +29 -52
- package/dist/serve.js +157 -0
- package/dist/service.js +304 -0
- package/dist/tail.js +119 -0
- package/dist/update.js +13 -1
- package/package.json +2 -23
- 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 +42 -0
- package/runtime/marketplace/plugin/bin/guard.mjs +71 -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 +51 -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 +5 -0
- 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/{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 +18 -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 +49 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/agent-fs.ts +134 -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/provision.ts +80 -0
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/schedule-detail.ts +99 -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 +87 -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 +223 -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 +6 -34
- 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 +380 -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 +208 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/memory-routine.ts +114 -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/session-files.ts +75 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +295 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/settings.ts +109 -0
- package/runtime/node_modules/@metro-labs/daemon/src/claude/setup.ts +346 -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 +127 -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 -113
- 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} +61 -22
- 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/daemon/src/connectors/relay.ts +347 -0
- 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 +12 -13
- 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/codex-auth.ts +214 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +91 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-stream.ts +173 -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 +155 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/effort.ts +93 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/eventstream.ts +123 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/forward.ts +237 -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 +307 -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 +235 -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 +203 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +285 -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 +161 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-store.ts +72 -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 +118 -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 +102 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +348 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/accounts.ts +28 -17
- 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 +49 -20
- 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 +34 -80
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/instructions.ts +19 -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 +87 -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 +46 -0
- package/runtime/node_modules/@metro-labs/daemon/src/mcp/session-slot.ts +71 -0
- package/runtime/node_modules/@metro-labs/{mcp → daemon}/src/mcp/session.ts +47 -44
- 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 +64 -113
- 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 +126 -0
- package/runtime/node_modules/@metro-labs/daemon/src/metro-user/install.ts +37 -0
- package/runtime/node_modules/@metro-labs/daemon/src/metro-user/privilege.ts +48 -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 +35 -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 +63 -51
- package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +209 -0
- package/runtime/node_modules/@metro-labs/daemon/src/routes/session-apis.ts +69 -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 +38 -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 -179
- 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/discord-bot/package.json +2 -4
- 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 +135 -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 +21 -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 +1 -3
- 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 +2 -2
- 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 +1 -1
- 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 +1 -1
- package/runtime/node_modules/@metro-labs/webhook/src/station.ts +5 -8
- package/runtime/node_modules/@metro-labs/whatsapp/package.json +2 -5
- 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 +3 -2
- 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 +15 -204
- package/runtime/node_modules/@metro-labs/xmtp/src/actions-meta.ts +40 -53
- package/runtime/node_modules/@metro-labs/xmtp/src/actions.ts +72 -220
- package/runtime/node_modules/@metro-labs/xmtp/src/attachments.ts +3 -3
- package/runtime/node_modules/@metro-labs/xmtp/src/codecs.ts +27 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/conv-helpers.ts +11 -7
- package/runtime/node_modules/@metro-labs/xmtp/src/emit-payloads.ts +7 -24
- package/runtime/node_modules/@metro-labs/xmtp/src/emit.ts +8 -18
- 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 +12 -20
- package/runtime/node_modules/@metro-labs/xmtp/src/labels.ts +57 -33
- 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/profile.ts +153 -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 +72 -0
- package/runtime/node_modules/@metro-labs/xmtp/src/station.ts +7 -2
- package/runtime/node_modules/@metro-labs/xmtp/src/tools-handlers.ts +22 -58
- package/runtime/node_modules/@metro-labs/xmtp/src/tools.ts +55 -48
- 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/wire.ts +14 -4
- package/runtime/runtime.json +1 -1
- package/runtime/server.ts +1 -0
- package/runtime/stations.json +38 -0
- 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 -320
- package/runtime/node_modules/@metro-labs/mcp/src/daemon/cli-pair-api.ts +0 -111
- 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 -31
- 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 -41
- 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/connectors.ts +0 -329
- 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
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { IdentifierKind } from '@xmtp/node-sdk';
|
|
2
|
+
import { namehash, type Hex } from 'viem';
|
|
3
|
+
import { normalize } from 'viem/ens';
|
|
4
|
+
import { respond } from '@metro-labs/core/stations/station-runtime';
|
|
5
|
+
import { TrainError } from '@metro-labs/core/train-error';
|
|
6
|
+
import { accountForCall } from './accounts.js';
|
|
7
|
+
import { BASENAME_L2_RESOLVER, BASENAME_REGISTRY, REGISTRY_ABI } from './profile.js';
|
|
8
|
+
import { readerFor, type Reader } from './sender.js';
|
|
9
|
+
|
|
10
|
+
const ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
|
|
11
|
+
const INBOX_RE = /^[0-9a-f]{64}$/;
|
|
12
|
+
const NAME_RE = /^[a-z0-9-]+(\.[a-z0-9-]+)*\.eth$/i;
|
|
13
|
+
const ZERO = '0x0000000000000000000000000000000000000000';
|
|
14
|
+
const ADDR_ABI = [
|
|
15
|
+
{ name: 'addr', type: 'function', stateMutability: 'view', inputs: [{ name: 'node', type: 'bytes32' }], outputs: [{ name: '', type: 'address' }] },
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
function refuse(query: string, why: string): never {
|
|
19
|
+
throw new TrainError('bad_request', `'${query}' ${why}`, { retryable: false });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function addressOfName(name: string, client: Reader): Promise<string> {
|
|
23
|
+
const node = namehash(normalize(name));
|
|
24
|
+
const found: Hex = await client.readContract({ address: BASENAME_REGISTRY, abi: REGISTRY_ABI, functionName: 'resolver', args: [node] });
|
|
25
|
+
const resolver = found === ZERO ? BASENAME_L2_RESOLVER : found;
|
|
26
|
+
const address = await client.readContract({ address: resolver, abi: ADDR_ABI, functionName: 'addr', args: [node] });
|
|
27
|
+
if (address === ZERO) refuse(name, 'points to no address');
|
|
28
|
+
return address;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function addressOf(query: string, client: Reader = readerFor()): Promise<string> {
|
|
32
|
+
if (INBOX_RE.test(query)) refuse(query, 'is already an inbox id, so add it directly instead of looking it up');
|
|
33
|
+
if (ADDRESS_RE.test(query)) return query.toLowerCase();
|
|
34
|
+
if (NAME_RE.test(query)) return (await addressOfName(query.toLowerCase(), client)).toLowerCase();
|
|
35
|
+
refuse(query, 'is not a wallet address (0x followed by 40 characters) or a name ending in .eth');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function resolveSenderAction(id: string, args: Record<string, unknown>): Promise<void> {
|
|
39
|
+
const query = typeof args.query === 'string' ? args.query.trim() : '';
|
|
40
|
+
const acct = accountForCall({ account: typeof args.account === 'string' ? args.account : undefined });
|
|
41
|
+
const address = await addressOf(query);
|
|
42
|
+
const inboxId = await acct.client.fetchInboxIdByIdentifier({ identifier: address, identifierKind: IdentifierKind.Ethereum });
|
|
43
|
+
respond(id, { result: { account: acct.cfg.id, query, address, exists: inboxId !== null, id: inboxId } });
|
|
44
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createPublicClient, http, namehash, type Hex } from 'viem';
|
|
2
|
+
import { base } from 'viem/chains';
|
|
3
|
+
import { normalize } from 'viem/ens';
|
|
4
|
+
import { makeProfileCache, type SenderProfile as Profile } from '@metro-labs/core/stations/sender-profile';
|
|
5
|
+
import { respond } from '@metro-labs/core/stations/station-runtime';
|
|
6
|
+
import { TrainError } from '@metro-labs/core/train-error';
|
|
7
|
+
import { accountForCall, accounts, type Account } from './accounts.js';
|
|
8
|
+
import { resolveAddresses } from './conv-helpers.js';
|
|
9
|
+
import { nameOf } from './names.js';
|
|
10
|
+
import { BASENAME_L2_RESOLVER, BASENAME_REGISTRY, NAME_ABI, REGISTRY_ABI, reverseNodeOf } from './profile.js';
|
|
11
|
+
|
|
12
|
+
export interface SenderProfile {
|
|
13
|
+
address: string;
|
|
14
|
+
name: string | null;
|
|
15
|
+
displayName: string | null;
|
|
16
|
+
about: string | null;
|
|
17
|
+
avatar: string | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const BASE_RPC = 'https://rpc.brovider.xyz/8453';
|
|
21
|
+
const ZERO = '0x0000000000000000000000000000000000000000';
|
|
22
|
+
const AVATAR_RE = /^(https?:\/\/|ipfs:\/\/|data:image\/)/i;
|
|
23
|
+
|
|
24
|
+
const TEXT_ABI = [
|
|
25
|
+
{ name: 'addr', type: 'function', stateMutability: 'view', inputs: [{ name: 'node', type: 'bytes32' }], outputs: [{ name: '', type: 'address' }] },
|
|
26
|
+
{
|
|
27
|
+
name: 'text',
|
|
28
|
+
type: 'function',
|
|
29
|
+
stateMutability: 'view',
|
|
30
|
+
inputs: [{ name: 'node', type: 'bytes32' }, { name: 'key', type: 'string' }],
|
|
31
|
+
outputs: [{ name: '', type: 'string' }],
|
|
32
|
+
},
|
|
33
|
+
] as const;
|
|
34
|
+
|
|
35
|
+
export const baseRpc = (): string => process.env.METRO_BASE_RPC ?? BASE_RPC;
|
|
36
|
+
|
|
37
|
+
const makeReader = (rpc: string) => createPublicClient({ chain: base, transport: http(rpc), batch: { multicall: true } });
|
|
38
|
+
|
|
39
|
+
export type Reader = ReturnType<typeof makeReader>;
|
|
40
|
+
|
|
41
|
+
let reader: Reader | null = null;
|
|
42
|
+
export const readerFor = (): Reader => (reader ??= makeReader(baseRpc()));
|
|
43
|
+
|
|
44
|
+
const trimmed = (v: string): string | null => (v.trim() === '' ? null : v.trim());
|
|
45
|
+
|
|
46
|
+
async function resolverOf(client: Reader, node: Hex): Promise<Hex> {
|
|
47
|
+
const found: Hex = await client.readContract({ address: BASENAME_REGISTRY, abi: REGISTRY_ABI, functionName: 'resolver', args: [node] });
|
|
48
|
+
return found === ZERO ? BASENAME_L2_RESOLVER : found;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function primaryName(client: Reader, address: string): Promise<string | null> {
|
|
52
|
+
const node = reverseNodeOf(address);
|
|
53
|
+
const found = await client.readContract({ address: await resolverOf(client, node), abi: NAME_ABI, functionName: 'name', args: [node] });
|
|
54
|
+
return found === '' ? null : found;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function recordsOf(client: Reader, name: string, address: string): Promise<SenderProfile | null> {
|
|
58
|
+
const node = namehash(normalize(name));
|
|
59
|
+
const resolver = { address: await resolverOf(client, node), abi: TEXT_ABI } as const;
|
|
60
|
+
const text = (key: string): Promise<string> => client.readContract({ ...resolver, functionName: 'text', args: [node, key] });
|
|
61
|
+
const [forward, displayName, about, avatar] = await Promise.all([
|
|
62
|
+
client.readContract({ ...resolver, functionName: 'addr', args: [node] }),
|
|
63
|
+
text('name'),
|
|
64
|
+
text('description'),
|
|
65
|
+
text('avatar'),
|
|
66
|
+
]);
|
|
67
|
+
if (forward.toLowerCase() !== address.toLowerCase()) return null;
|
|
68
|
+
return { address, name, displayName: trimmed(displayName), about: trimmed(about), avatar: AVATAR_RE.test(avatar.trim()) ? avatar.trim() : null };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function profileOf(address: string, client: Reader = readerFor(), fetchImpl: typeof fetch = fetch): Promise<SenderProfile> {
|
|
72
|
+
const bare: SenderProfile = { address, name: null, displayName: null, about: null, avatar: null };
|
|
73
|
+
const name = (await primaryName(client, address)) ?? (await nameOf(address, fetchImpl));
|
|
74
|
+
if (name === null) return bare;
|
|
75
|
+
return (await recordsOf(client, name, address)) ?? bare;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const key = (acct: Account, inboxId: string): string => `${acct.cfg.id}:${inboxId}`;
|
|
79
|
+
|
|
80
|
+
const senders = makeProfileCache<SenderProfile>(
|
|
81
|
+
async (k) => {
|
|
82
|
+
const [accountId, inboxId] = k.split(':', 2) as [string, string];
|
|
83
|
+
const acct = accounts.get(accountId);
|
|
84
|
+
if (acct === undefined) return null;
|
|
85
|
+
const address = (await resolveAddresses(acct, [inboxId]))[inboxId];
|
|
86
|
+
return address === undefined ? null : profileOf(address);
|
|
87
|
+
},
|
|
88
|
+
{ onError: (k, err) => process.stderr.write(`xmtp: could not resolve the sender ${k}: ${err instanceof Error ? err.message : String(err)}\n`) },
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
export const senderFields = (p: SenderProfile | null): Record<string, string> =>
|
|
92
|
+
p === null ? {} : { from_name: p.name ?? p.address, ...(p.displayName === null ? {} : { from_display_name: p.displayName }) };
|
|
93
|
+
|
|
94
|
+
export const senderFieldsNow = (acct: Account, inboxId: string): Record<string, string> => senderFields(senders.peek(key(acct, inboxId)));
|
|
95
|
+
|
|
96
|
+
export const senderProfile = (acct: Account, inboxId: string): Promise<SenderProfile | null> => senders.get(key(acct, inboxId));
|
|
97
|
+
|
|
98
|
+
export const profileView = (inboxId: string, p: SenderProfile | null): Profile => ({
|
|
99
|
+
id: inboxId,
|
|
100
|
+
...(p === null ? {} : { address: p.address }),
|
|
101
|
+
...(p?.name == null ? {} : { name: p.name }),
|
|
102
|
+
...(p?.displayName == null ? {} : { display_name: p.displayName }),
|
|
103
|
+
...(p?.about == null ? {} : { about: p.about }),
|
|
104
|
+
...(p?.avatar == null ? {} : { avatar: p.avatar }),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
export async function profileAction(id: string, args: Record<string, unknown>): Promise<void> {
|
|
108
|
+
const user = typeof args.user === 'string' ? args.user.trim() : '';
|
|
109
|
+
if (user === '') throw new TrainError('xmtp_user_required', 'profile needs the inbox id of the person', { retryable: false });
|
|
110
|
+
const acct = accountForCall({ account: typeof args.account === 'string' ? args.account : undefined });
|
|
111
|
+
respond(id, { result: profileView(user, await senderProfile(acct, user)) });
|
|
112
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createPublicClient, http, type Hex } from 'viem';
|
|
2
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
3
|
+
import { base } from 'viem/chains';
|
|
4
|
+
import {
|
|
5
|
+
createKernelAccount,
|
|
6
|
+
createKernelAccountClient,
|
|
7
|
+
createZeroDevPaymasterClient,
|
|
8
|
+
getUserOperationGasPrice,
|
|
9
|
+
type KernelAccountClient,
|
|
10
|
+
} from '@zerodev/sdk';
|
|
11
|
+
import { getEntryPoint, KERNEL_V3_1 } from '@zerodev/sdk/constants';
|
|
12
|
+
import { signerToEcdsaValidator } from '@zerodev/ecdsa-validator';
|
|
13
|
+
|
|
14
|
+
export const SMART_CHAIN_ID = 8453;
|
|
15
|
+
const STAGE_ZERODEV_PROJECT = 'c107f734-f7bb-48c1-a5d2-ceb3f70a42f6';
|
|
16
|
+
const ENTRY_POINT = getEntryPoint('0.7');
|
|
17
|
+
|
|
18
|
+
export const zerodevRpc = (): string =>
|
|
19
|
+
`https://rpc.zerodev.app/api/v3/${process.env.METRO_ZERODEV_PROJECT ?? STAGE_ZERODEV_PROJECT}/chain/${String(SMART_CHAIN_ID)}`;
|
|
20
|
+
|
|
21
|
+
export const makePublicClient = (rpc: string) => createPublicClient({ chain: base, transport: http(rpc) });
|
|
22
|
+
|
|
23
|
+
export type BaseClient = ReturnType<typeof makePublicClient>;
|
|
24
|
+
|
|
25
|
+
export interface SmartAccount {
|
|
26
|
+
address: Hex;
|
|
27
|
+
publicClient: BaseClient;
|
|
28
|
+
client: () => KernelAccountClient;
|
|
29
|
+
signMessage: (message: string) => Promise<Hex>;
|
|
30
|
+
deployed: () => Promise<boolean>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function smartAccountFor(privateKey: string, rpc = zerodevRpc()): Promise<SmartAccount> {
|
|
34
|
+
const owner = privateKeyToAccount(privateKey as Hex);
|
|
35
|
+
const publicClient = makePublicClient(rpc);
|
|
36
|
+
const validator = await signerToEcdsaValidator(publicClient, { signer: owner, entryPoint: ENTRY_POINT, kernelVersion: KERNEL_V3_1 });
|
|
37
|
+
const account = await createKernelAccount(publicClient, { plugins: { sudo: validator }, entryPoint: ENTRY_POINT, kernelVersion: KERNEL_V3_1, index: 0n });
|
|
38
|
+
const paymaster = createZeroDevPaymasterClient({ chain: base, transport: http(rpc) });
|
|
39
|
+
const client = (): KernelAccountClient =>
|
|
40
|
+
createKernelAccountClient({
|
|
41
|
+
account,
|
|
42
|
+
chain: base,
|
|
43
|
+
bundlerTransport: http(rpc),
|
|
44
|
+
client: publicClient,
|
|
45
|
+
paymaster: { getPaymasterData: (userOperation) => paymaster.sponsorUserOperation({ userOperation }) },
|
|
46
|
+
userOperation: { estimateFeesPerGas: ({ bundlerClient }) => getUserOperationGasPrice(bundlerClient) },
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
address: account.address,
|
|
50
|
+
publicClient,
|
|
51
|
+
client,
|
|
52
|
+
signMessage: (message) => account.signMessage({ message }),
|
|
53
|
+
deployed: async () => {
|
|
54
|
+
const code = await publicClient.getCode({ address: account.address });
|
|
55
|
+
return code !== undefined && code !== '0x';
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function sendSponsored(smart: SmartAccount, to: Hex, data: Hex): Promise<Hex> {
|
|
61
|
+
const client = smart.client();
|
|
62
|
+
const hash = await client.sendTransaction({ to, data, value: 0n } as Parameters<typeof client.sendTransaction>[0]);
|
|
63
|
+
const receipt = await smart.publicClient.waitForTransactionReceipt({ hash });
|
|
64
|
+
if (receipt.status !== 'success') throw new Error(`the Base transaction ${hash} reverted`);
|
|
65
|
+
return hash;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function ensureDeployed(smart: SmartAccount): Promise<boolean> {
|
|
69
|
+
if (await smart.deployed()) return false;
|
|
70
|
+
await sendSponsored(smart, smart.address, '0x');
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import type { GroupOp, Station, Verb } from '@metro-labs/
|
|
1
|
+
import type { GroupOp, Station, Verb } from '@metro-labs/core/stations/types';
|
|
2
|
+
import { PROFILE_FIELDS, type ProfileField } from '@metro-labs/core/stations/profile';
|
|
2
3
|
import { XMTP_TOOLS, xmtpSendAttachments } from './tools.js';
|
|
3
4
|
|
|
4
5
|
export const xmtpStation: Station = {
|
|
5
6
|
name: 'xmtp',
|
|
6
7
|
hasAccounts: true,
|
|
7
8
|
hasTrain: true,
|
|
8
|
-
messageVerbs: new Set<Verb>(['send', 'reply', 'react', 'unreact', 'read']),
|
|
9
|
+
messageVerbs: new Set<Verb>(['send', 'reply', 'react', 'unreact', 'delete', 'read']),
|
|
9
10
|
groupOps: new Set<GroupOp>(['create_group', 'add_members', 'remove_members']),
|
|
10
11
|
attachmentMode: 'native',
|
|
12
|
+
profileFields: new Set<ProfileField>(PROFILE_FIELDS),
|
|
13
|
+
readsProfiles: true,
|
|
14
|
+
resolvesSenders: true,
|
|
15
|
+
claimsName: true,
|
|
11
16
|
sendAttachments: xmtpSendAttachments,
|
|
12
17
|
tools: XMTP_TOOLS,
|
|
13
18
|
};
|
|
@@ -1,59 +1,26 @@
|
|
|
1
|
-
import type { CanonicalAttachment, ToolContext } from '@metro-labs/
|
|
2
|
-
import { TrainError } from '@metro-labs/
|
|
1
|
+
import type { CanonicalAttachment, ToolContext } from '@metro-labs/core/stations/types';
|
|
2
|
+
import { TrainError } from '@metro-labs/core/train-error';
|
|
3
|
+
import { metadataPatch, mergeAppData } from './labels.js';
|
|
3
4
|
import {
|
|
4
5
|
guessMime,
|
|
5
6
|
isImageMime,
|
|
6
7
|
isImageExt,
|
|
7
8
|
kindOf,
|
|
8
|
-
} from '@metro-labs/
|
|
9
|
+
} from '@metro-labs/core/stations/attachments';
|
|
9
10
|
|
|
10
11
|
export const str = (v: unknown): string => (typeof v === 'string' ? v : '');
|
|
11
12
|
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
line: string,
|
|
24
|
-
labels: string[],
|
|
25
|
-
ctx: ToolContext,
|
|
26
|
-
): Promise<unknown> {
|
|
27
|
-
if (!labels.length) return undefined;
|
|
28
|
-
return ctx.call('updateChannelMeta', { line, appData: { labels } });
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export async function createChannel(
|
|
32
|
-
a: Record<string, unknown>,
|
|
33
|
-
ctx: ToolContext,
|
|
34
|
-
) {
|
|
35
|
-
const addresses = strList(a.addresses);
|
|
36
|
-
const channelName = str(a.name);
|
|
37
|
-
const labels = strList(a.labels);
|
|
38
|
-
const account = str(a.account) || undefined;
|
|
39
|
-
if (!addresses.length)
|
|
40
|
-
return ctx.err('create_channel requires a non-empty `addresses` array');
|
|
41
|
-
if (!channelName) return ctx.err('create_channel requires `name`');
|
|
42
|
-
const groupArgs: Record<string, unknown> = { addresses, name: channelName };
|
|
43
|
-
if (account) groupArgs.account = account;
|
|
44
|
-
const { result } = (await ctx.call('newGroup', groupArgs)) as {
|
|
45
|
-
result: CreatedGroup | null;
|
|
46
|
-
};
|
|
47
|
-
const newLine = result?.line ?? '';
|
|
48
|
-
const labelResult = newLine.length
|
|
49
|
-
? await applyCreateLabels(newLine, labels, ctx)
|
|
50
|
-
: undefined;
|
|
51
|
-
return ctx.okJson({
|
|
52
|
-
line: newLine,
|
|
53
|
-
convId: result?.id,
|
|
54
|
-
account: result?.account,
|
|
55
|
-
labels: labelResult,
|
|
56
|
-
});
|
|
13
|
+
function channelAppData(a: Record<string, unknown>): Record<string, unknown> {
|
|
14
|
+
const appData = a.metadata === undefined ? {} : { ...metadataPatch(a.metadata) };
|
|
15
|
+
for (const key of ['labels', 'github', 'preview']) {
|
|
16
|
+
if (!Object.hasOwn(a, key)) continue;
|
|
17
|
+
if (Object.hasOwn(appData, key)) {
|
|
18
|
+
throw new TrainError('INVALID_ARGS', `Specify ${key} only once, inside metadata or at the top level`);
|
|
19
|
+
}
|
|
20
|
+
appData[key] = a[key];
|
|
21
|
+
}
|
|
22
|
+
mergeAppData(undefined, appData);
|
|
23
|
+
return appData;
|
|
57
24
|
}
|
|
58
25
|
|
|
59
26
|
export async function setChannelMetadata(
|
|
@@ -62,18 +29,15 @@ export async function setChannelMetadata(
|
|
|
62
29
|
) {
|
|
63
30
|
const line = str(a.line);
|
|
64
31
|
if (!line) return ctx.err('set_channel_metadata requires `line`');
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
if (Array.isArray(labels)) appData.labels = labels.map(String);
|
|
71
|
-
if (typeof github === 'string') appData.github = github;
|
|
72
|
-
if (typeof preview === 'string') appData.preview = preview;
|
|
32
|
+
if (Object.hasOwn(a, 'name') && typeof a.name !== 'string') {
|
|
33
|
+
return ctx.err('set_channel_metadata name must be a string');
|
|
34
|
+
}
|
|
35
|
+
const appData = channelAppData(a);
|
|
36
|
+
const metaName = a.name;
|
|
73
37
|
const hasName = typeof metaName === 'string' && metaName.length > 0;
|
|
74
38
|
if (!hasName && Object.keys(appData).length === 0)
|
|
75
39
|
return ctx.err(
|
|
76
|
-
'set_channel_metadata requires at least one of `
|
|
40
|
+
'set_channel_metadata requires at least one of `metadata`, `github`, `preview`, `name`, `labels`',
|
|
77
41
|
);
|
|
78
42
|
const callArgs: Record<string, unknown> = { line, appData };
|
|
79
43
|
if (hasName) callArgs.name = metaName;
|
|
@@ -112,7 +76,7 @@ export async function xmtpSendAttachments(
|
|
|
112
76
|
): Promise<string[]> {
|
|
113
77
|
const sent: string[] = [];
|
|
114
78
|
for (const a of atts) {
|
|
115
|
-
const src = a.path ??
|
|
79
|
+
const src = a.path ?? '';
|
|
116
80
|
if (!src) continue;
|
|
117
81
|
const mime = a.mime ?? guessMime(src);
|
|
118
82
|
if (isImageMime(mime) || isImageExt(src)) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { StationTool } from '@metro-labs/
|
|
1
|
+
import type { StationTool } from '@metro-labs/core/stations/types';
|
|
2
2
|
import {
|
|
3
3
|
str,
|
|
4
|
-
createChannel,
|
|
5
4
|
setChannelMetadata,
|
|
6
5
|
xmtpSendAttachments,
|
|
7
6
|
} from './tools-handlers.js';
|
|
@@ -15,43 +14,9 @@ const lineProp = {
|
|
|
15
14
|
} as const;
|
|
16
15
|
|
|
17
16
|
export const XMTP_TOOLS: StationTool[] = [
|
|
18
|
-
{
|
|
19
|
-
name: 'create_channel',
|
|
20
|
-
description:
|
|
21
|
-
'Create a new XMTP group conversation (channel). Args: addresses (required, array of ' +
|
|
22
|
-
'Ethereum 0x addresses to add as members), name (required, the group name), labels? ' +
|
|
23
|
-
'(optional string[] status labels applied after creation), account? ' +
|
|
24
|
-
'(defaults to your only XMTP account). Calls the daemon xmtp `newGroup`, then ' +
|
|
25
|
-
'`updateChannelMeta` if labels ' +
|
|
26
|
-
'are given. Returns the new metro:// line and convId. This is an xmtp-only operation. ' +
|
|
27
|
-
'NOTE: there is no add-members verb on the daemon, so members must be supplied at ' +
|
|
28
|
-
'creation time.',
|
|
29
|
-
inputSchema: {
|
|
30
|
-
type: 'object',
|
|
31
|
-
properties: {
|
|
32
|
-
addresses: {
|
|
33
|
-
type: 'array',
|
|
34
|
-
description: 'Ethereum 0x addresses to add as group members.',
|
|
35
|
-
items: { type: 'string' },
|
|
36
|
-
},
|
|
37
|
-
name: { type: 'string', description: 'The group/channel name.' },
|
|
38
|
-
labels: {
|
|
39
|
-
type: 'array',
|
|
40
|
-
description: 'Optional status labels to apply after creation.',
|
|
41
|
-
items: { type: 'string' },
|
|
42
|
-
},
|
|
43
|
-
account: {
|
|
44
|
-
type: 'string',
|
|
45
|
-
description:
|
|
46
|
-
'XMTP account to create under. Omit when you have only one.',
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
required: ['addresses', 'name'],
|
|
50
|
-
},
|
|
51
|
-
handle: (a, ctx) => createChannel(a, ctx),
|
|
52
|
-
},
|
|
53
17
|
{
|
|
54
18
|
name: 'ask',
|
|
19
|
+
group: 'write',
|
|
55
20
|
description:
|
|
56
21
|
'Ask a question as a poll in an XMTP conversation (mirrors Claude AskUserQuestion). ' +
|
|
57
22
|
'Single-question form: question (required), options? (string[]), header?, multiSelect?, ' +
|
|
@@ -116,11 +81,12 @@ export const XMTP_TOOLS: StationTool[] = [
|
|
|
116
81
|
},
|
|
117
82
|
{
|
|
118
83
|
name: 'dm',
|
|
84
|
+
group: 'write',
|
|
119
85
|
description:
|
|
120
86
|
'Open (or reuse) a 1:1 XMTP DM with an Ethereum address. Args: address (required, 0x...), ' +
|
|
121
87
|
'account? (defaults to your only XMTP account). Returns the new metro:// line and ' +
|
|
122
88
|
'convId. xmtp-only ' +
|
|
123
|
-
'(daemon `newDm`).
|
|
89
|
+
'(daemon `newDm`). For a group, use create_group.',
|
|
124
90
|
inputSchema: {
|
|
125
91
|
type: 'object',
|
|
126
92
|
properties: {
|
|
@@ -145,10 +111,13 @@ export const XMTP_TOOLS: StationTool[] = [
|
|
|
145
111
|
},
|
|
146
112
|
{
|
|
147
113
|
name: 'group_info',
|
|
114
|
+
group: 'read',
|
|
148
115
|
description:
|
|
149
116
|
"Read an XMTP channel's current metadata + membership. Args: line (required). Returns " +
|
|
150
117
|
'{line, id, account, version (dm|group), name, memberCount, labels, github, preview, ' +
|
|
151
|
-
'
|
|
118
|
+
'assigned, appData (stored JSON object), rawAppData (stored JSON string), ' +
|
|
119
|
+
'members:[{inboxId, address}]}. Syncs first and fails if metadata cannot be read. ' +
|
|
120
|
+
'xmtp-only (daemon `groupInfo`). Use before ' +
|
|
152
121
|
'set_channel_metadata/add_members to see current state.',
|
|
153
122
|
inputSchema: {
|
|
154
123
|
type: 'object',
|
|
@@ -163,35 +132,73 @@ export const XMTP_TOOLS: StationTool[] = [
|
|
|
163
132
|
},
|
|
164
133
|
{
|
|
165
134
|
name: 'close_channel',
|
|
135
|
+
group: 'write',
|
|
136
|
+
destructive: true,
|
|
166
137
|
description:
|
|
167
|
-
'
|
|
168
|
-
'(
|
|
138
|
+
'Remove members from an XMTP group, and optionally leave it. Args: line (required), ' +
|
|
139
|
+
'removeInboxIds? (inbox ids to remove; your own is ignored here), removeSelf? (true to ' +
|
|
140
|
+
'leave the group yourself). With neither, nothing changes. xmtp-only (daemon ' +
|
|
141
|
+
'`closeGroup`). Returns {removed, leftSelf}.',
|
|
169
142
|
inputSchema: {
|
|
170
143
|
type: 'object',
|
|
171
|
-
properties: {
|
|
144
|
+
properties: {
|
|
145
|
+
line: lineProp,
|
|
146
|
+
removeInboxIds: {
|
|
147
|
+
type: 'array',
|
|
148
|
+
description: 'Inbox ids of the members to remove.',
|
|
149
|
+
items: { type: 'string' },
|
|
150
|
+
},
|
|
151
|
+
removeSelf: {
|
|
152
|
+
type: 'boolean',
|
|
153
|
+
description: 'Leave the group after removing the others.',
|
|
154
|
+
},
|
|
155
|
+
},
|
|
172
156
|
required: ['line'],
|
|
173
157
|
},
|
|
174
158
|
async handle(a, ctx) {
|
|
175
159
|
const line = str(a.line);
|
|
176
160
|
if (!line) return ctx.err('close_channel requires `line`');
|
|
177
|
-
|
|
161
|
+
const args: Record<string, unknown> = { line };
|
|
162
|
+
if (Array.isArray(a.removeInboxIds)) args.removeInboxIds = a.removeInboxIds.map(String);
|
|
163
|
+
if (a.removeSelf === true) args.removeSelf = true;
|
|
164
|
+
return ctx.okJson(await ctx.call('closeGroup', args));
|
|
178
165
|
},
|
|
179
166
|
},
|
|
180
167
|
{
|
|
181
168
|
name: 'set_channel_metadata',
|
|
169
|
+
group: 'write',
|
|
182
170
|
description:
|
|
183
171
|
"Update an existing channel's metadata. Args: line (required, the metro:// line), and " +
|
|
184
|
-
'any of
|
|
185
|
-
'
|
|
186
|
-
'
|
|
187
|
-
'
|
|
172
|
+
'any of metadata? (JSON object), github? (url), preview? (url), name? (string). ' +
|
|
173
|
+
'metadata is a shallow appData patch: omitted keys are preserved, supplied nested ' +
|
|
174
|
+
'values replace that key, and null deletes custom keys. v is reserved. Put labels ' +
|
|
175
|
+
'and assigned inside metadata. assigned replaces the array with normalized lowercase ' +
|
|
176
|
+
'Ethereum addresses of current members. Read group_info and union existing IDs to ' +
|
|
177
|
+
'add assignees. labels remains a legacy top-level alias. Duplicate top-level/metadata ' +
|
|
178
|
+
'label/link aliases are refused. All fields use one updateChannelMeta call. xmtp-only. ' +
|
|
179
|
+
'Returns updated metadata. Reread group_info to verify persistence.',
|
|
188
180
|
inputSchema: {
|
|
189
181
|
type: 'object',
|
|
190
182
|
properties: {
|
|
191
183
|
line: lineProp,
|
|
184
|
+
metadata: {
|
|
185
|
+
type: 'object',
|
|
186
|
+
description: 'Shallow JSON appData patch. Omitted keys stay unchanged. v is reserved.',
|
|
187
|
+
properties: {
|
|
188
|
+
labels: { type: 'array', items: { type: 'string' } },
|
|
189
|
+
assigned: {
|
|
190
|
+
type: 'array',
|
|
191
|
+
description: 'Replacement assignee list. Current member Ethereum addresses only. [] clears.',
|
|
192
|
+
items: { type: 'string', pattern: '^0x[0-9a-fA-F]{40}$' },
|
|
193
|
+
},
|
|
194
|
+
github: { type: 'string' },
|
|
195
|
+
preview: { type: 'string' },
|
|
196
|
+
},
|
|
197
|
+
additionalProperties: true,
|
|
198
|
+
},
|
|
192
199
|
labels: {
|
|
193
200
|
type: 'array',
|
|
194
|
-
description: '
|
|
201
|
+
description: 'Legacy alias. Prefer metadata.labels.',
|
|
195
202
|
items: { type: 'string' },
|
|
196
203
|
},
|
|
197
204
|
github: {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { errMsg } from '@metro-labs/
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type EmitInbound = (accountId: string, e: Record<string, unknown>) => void;
|
|
1
|
+
import { errMsg } from '@metro-labs/core/log';
|
|
2
|
+
import { emitInbound, selfUri } from '@metro-labs/core/stations/train-events';
|
|
3
|
+
import { mintId } from '@metro-labs/core/stations/station-runtime';
|
|
5
4
|
|
|
6
5
|
const WHISPER_BIN = process.env.METRO_WHISPER_BIN ?? 'whisper-cli';
|
|
7
6
|
const WHISPER_MODEL =
|
|
@@ -14,7 +13,6 @@ export async function transcribeAndEmit(
|
|
|
14
13
|
line: string,
|
|
15
14
|
accountId: string,
|
|
16
15
|
sourceMsgId: string,
|
|
17
|
-
emitInbound: EmitInbound,
|
|
18
16
|
): Promise<void> {
|
|
19
17
|
const {
|
|
20
18
|
existsSync: ex,
|
|
@@ -69,7 +67,7 @@ export async function transcribeAndEmit(
|
|
|
69
67
|
ts: new Date().toISOString(),
|
|
70
68
|
station: 'xmtp',
|
|
71
69
|
line,
|
|
72
|
-
from:
|
|
70
|
+
from: selfUri(),
|
|
73
71
|
text: `🎙️ ${text}`,
|
|
74
72
|
payload: {
|
|
75
73
|
contentType: 'transcript',
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname } from 'node:path';
|
|
3
3
|
import { Client, type ClientOptions, type Signer } from '@xmtp/node-sdk';
|
|
4
|
-
import { expandHome, signerFor, XMTP_ENV } from './identity.js';
|
|
4
|
+
import { expandHome, identityFor, signerFor, XMTP_ENV } from './identity.js';
|
|
5
|
+
import { ensureDeployed } from './smart.js';
|
|
5
6
|
|
|
6
7
|
export class XmtpVerifyError extends Error {}
|
|
7
8
|
|
|
@@ -10,6 +11,7 @@ export interface XmtpVerified {
|
|
|
10
11
|
address: string;
|
|
11
12
|
installationId: string;
|
|
12
13
|
dbPath: string;
|
|
14
|
+
smart: boolean;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
interface RegisteredClient {
|
|
@@ -34,15 +36,25 @@ const reason = (err: unknown): string =>
|
|
|
34
36
|
export async function verifyXmtpKey(
|
|
35
37
|
privateKey: string,
|
|
36
38
|
dbPath: string,
|
|
39
|
+
smart = false,
|
|
37
40
|
create: CreateXmtpClient = openInbox,
|
|
38
41
|
): Promise<XmtpVerified> {
|
|
39
|
-
let
|
|
40
|
-
let address: string;
|
|
42
|
+
let identity: Awaited<ReturnType<typeof identityFor>>;
|
|
41
43
|
try {
|
|
42
|
-
|
|
44
|
+
signerFor(privateKey);
|
|
43
45
|
} catch {
|
|
44
46
|
throw new XmtpVerifyError('that is not a usable XMTP private key');
|
|
45
47
|
}
|
|
48
|
+
try {
|
|
49
|
+
identity = await identityFor(privateKey, smart);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
throw new XmtpVerifyError(`could not build the smart account on Base: ${reason(err)}`);
|
|
52
|
+
}
|
|
53
|
+
const { signer, address } = identity;
|
|
54
|
+
if (identity.smart !== null)
|
|
55
|
+
await ensureDeployed(identity.smart).catch((err: unknown) => {
|
|
56
|
+
throw new XmtpVerifyError(`could not deploy the smart account on Base (is the ZeroDev sponsorship still on?): ${reason(err)}`);
|
|
57
|
+
});
|
|
46
58
|
const resolved = expandHome(dbPath);
|
|
47
59
|
mkdirSync(dirname(resolved), { recursive: true });
|
|
48
60
|
const client = await create(signer, resolved).catch((err: unknown) => {
|
|
@@ -59,6 +71,7 @@ export async function verifyXmtpKey(
|
|
|
59
71
|
address,
|
|
60
72
|
installationId: client.installationId,
|
|
61
73
|
dbPath: resolved,
|
|
74
|
+
smart,
|
|
62
75
|
};
|
|
63
76
|
}
|
|
64
77
|
|
|
@@ -68,10 +81,11 @@ async function runCli(): Promise<void> {
|
|
|
68
81
|
const input = JSON.parse(readFileSync(0, 'utf8')) as {
|
|
69
82
|
privateKey?: unknown;
|
|
70
83
|
dbPath?: unknown;
|
|
84
|
+
smart?: unknown;
|
|
71
85
|
};
|
|
72
86
|
if (typeof input.privateKey !== 'string' || typeof input.dbPath !== 'string')
|
|
73
87
|
throw new XmtpVerifyError('xmtp verify needs a privateKey and a dbPath');
|
|
74
|
-
out = { ok: true, ...(await verifyXmtpKey(input.privateKey, input.dbPath)) };
|
|
88
|
+
out = { ok: true, ...(await verifyXmtpKey(input.privateKey, input.dbPath, input.smart === true)) };
|
|
75
89
|
} catch (err) {
|
|
76
90
|
out = { ok: false, error: reason(err) };
|
|
77
91
|
}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export { emit, respond, mintId } from '@metro-labs/mcp/stations/station-runtime';
|
|
2
|
-
|
|
3
|
-
export const SELF_URI = process.env.METRO_SELF_URI ?? '';
|
|
4
|
-
|
|
5
1
|
const UID_MAP_MAX = 5000;
|
|
6
2
|
const uidToXmtp = new Map<string, string>();
|
|
7
3
|
|
|
@@ -37,3 +33,17 @@ export function resolveMsgId(rawId: string): string {
|
|
|
37
33
|
'(not seen by this train; pass the raw xmtp message_id)',
|
|
38
34
|
);
|
|
39
35
|
}
|
|
36
|
+
|
|
37
|
+
const SENT_MAX = 5000;
|
|
38
|
+
const sentIds = new Set<string>();
|
|
39
|
+
|
|
40
|
+
export function rememberSent(xmtpId: string | undefined): void {
|
|
41
|
+
if (!xmtpId) return;
|
|
42
|
+
sentIds.add(xmtpId);
|
|
43
|
+
if (sentIds.size > SENT_MAX) {
|
|
44
|
+
const oldest = sentIds.values().next().value;
|
|
45
|
+
if (oldest !== undefined) sentIds.delete(oldest);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const sentByMe = (xmtpId: string): boolean => sentIds.has(xmtpId);
|
package/runtime/runtime.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './node_modules/@metro-labs/daemon/src/server.ts';
|