@openparachute/agent 0.1.2 → 0.2.0
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/.parachute/module.json +124 -8
- package/LICENSE +2 -16
- package/README.md +118 -166
- package/package.json +32 -43
- package/scripts/spawn-agent.ts +371 -0
- package/src/_parked/interactive-spawn.test.ts +324 -0
- package/src/_parked/interactive-spawn.ts +701 -0
- package/src/agent-defs.test.ts +1504 -0
- package/src/agent-defs.ts +1702 -0
- package/src/agent-mcp-config.test.ts +115 -0
- package/src/agent-mcp-config.ts +115 -0
- package/src/agents.test.ts +360 -0
- package/src/agents.ts +379 -0
- package/src/auth.test.ts +46 -0
- package/src/auth.ts +140 -0
- package/src/backends/attached-queue.test.ts +376 -0
- package/src/backends/attached-queue.ts +372 -0
- package/src/backends/programmatic.test.ts +1715 -0
- package/src/backends/programmatic.ts +927 -0
- package/src/backends/registry.test.ts +1494 -0
- package/src/backends/registry.ts +1202 -0
- package/src/backends/stream-json.test.ts +570 -0
- package/src/backends/stream-json.ts +392 -0
- package/src/backends/types.ts +223 -0
- package/src/bridge.ts +417 -0
- package/src/channel-backend-wiring.test.ts +237 -0
- package/src/credentials.test.ts +274 -0
- package/src/credentials.ts +380 -0
- package/src/cron.test.ts +342 -0
- package/src/cron.ts +380 -0
- package/src/daemon-agent-def-api.test.ts +166 -0
- package/src/daemon-agent-defs-api.test.ts +953 -0
- package/src/daemon-agent-env-api.test.ts +338 -0
- package/src/daemon-attached-queue-store.test.ts +65 -0
- package/src/daemon-config-api.test.ts +962 -0
- package/src/daemon-jobs-api.test.ts +271 -0
- package/src/daemon-vault-chat.test.ts +250 -0
- package/src/daemon.test.ts +746 -0
- package/src/daemon.ts +3314 -0
- package/src/def-vaults.test.ts +136 -0
- package/src/def-vaults.ts +165 -0
- package/src/delivery-state.test.ts +110 -0
- package/src/delivery-state.ts +154 -0
- package/src/effective-env.test.ts +114 -0
- package/src/effective-env.ts +184 -0
- package/src/env-compat.ts +39 -0
- package/src/grants.test.ts +638 -0
- package/src/grants.ts +675 -0
- package/src/hub-jwt.test.ts +161 -0
- package/src/hub-jwt.ts +182 -0
- package/src/jobs.test.ts +245 -0
- package/src/jobs.ts +266 -0
- package/src/mcp-http.test.ts +265 -0
- package/src/mcp-http.ts +771 -0
- package/src/mint-token.test.ts +152 -0
- package/src/mint-token.ts +139 -0
- package/src/module-manifest.test.ts +158 -0
- package/src/oauth-discovery.ts +134 -0
- package/src/programmatic-wiring.test.ts +838 -0
- package/src/registry.test.ts +227 -0
- package/src/registry.ts +228 -0
- package/src/resolve-port.test.ts +64 -0
- package/src/routing.test.ts +184 -0
- package/src/routing.ts +76 -0
- package/src/runner.test.ts +506 -0
- package/src/runner.ts +255 -0
- package/src/sandbox/config.test.ts +150 -0
- package/src/sandbox/config.ts +102 -0
- package/src/sandbox/egress.test.ts +113 -0
- package/src/sandbox/egress.ts +123 -0
- package/src/sandbox/index.ts +180 -0
- package/src/sandbox/live-seatbelt.test.ts +277 -0
- package/src/sandbox/mounts.test.ts +154 -0
- package/src/sandbox/mounts.ts +133 -0
- package/src/sandbox/sandbox.test.ts +168 -0
- package/src/sandbox/types.ts +382 -0
- package/src/services-manifest.test.ts +106 -0
- package/src/services-manifest.ts +95 -0
- package/src/spa-serve.test.ts +116 -0
- package/src/spa-serve.ts +116 -0
- package/src/spawn-agent-cli.test.ts +172 -0
- package/src/spawn-agent.test.ts +1218 -0
- package/src/spawn-agent.ts +569 -0
- package/src/spawn-deps.test.ts +54 -0
- package/src/spawn-deps.ts +166 -0
- package/src/telegram/api.ts +153 -0
- package/src/terminal-assets.test.ts +50 -0
- package/src/terminal-assets.ts +79 -0
- package/src/terminal-ui.ts +305 -0
- package/src/terminal.test.ts +530 -0
- package/src/terminal.ts +458 -0
- package/src/transport.ts +270 -0
- package/src/transports/http-ui.test.ts +455 -0
- package/src/transports/http-ui.ts +201 -0
- package/src/transports/telegram.test.ts +174 -0
- package/src/transports/telegram.ts +426 -0
- package/src/transports/vault.test.ts +2011 -0
- package/src/transports/vault.ts +1790 -0
- package/src/ui-kit.test.ts +178 -0
- package/src/ui-kit.ts +402 -0
- package/tsconfig.json +8 -14
- package/web/ui/tsconfig.json +2 -1
- package/.claude/scheduled_tasks.lock +0 -1
- package/.claude/settings.json +0 -5
- package/.claude/skills/add-atomic-chat-tool/SKILL.md +0 -243
- package/.claude/skills/add-atomic-chat-tool/atomic-chat-mcp-stdio.ts +0 -229
- package/.claude/skills/add-codex/SKILL.md +0 -161
- package/.claude/skills/add-dashboard/SKILL.md +0 -138
- package/.claude/skills/add-dashboard/resources/dashboard-pusher.ts +0 -495
- package/.claude/skills/add-emacs/SKILL.md +0 -296
- package/.claude/skills/add-gcal-tool/SKILL.md +0 -210
- package/.claude/skills/add-gchat/REMOVE.md +0 -6
- package/.claude/skills/add-gchat/SKILL.md +0 -92
- package/.claude/skills/add-gchat/VERIFY.md +0 -3
- package/.claude/skills/add-github/REMOVE.md +0 -6
- package/.claude/skills/add-github/SKILL.md +0 -148
- package/.claude/skills/add-github/VERIFY.md +0 -3
- package/.claude/skills/add-gmail-tool/SKILL.md +0 -229
- package/.claude/skills/add-imessage/REMOVE.md +0 -6
- package/.claude/skills/add-imessage/SKILL.md +0 -113
- package/.claude/skills/add-imessage/VERIFY.md +0 -3
- package/.claude/skills/add-karpathy-llm-wiki/SKILL.md +0 -110
- package/.claude/skills/add-karpathy-llm-wiki/llm-wiki.md +0 -75
- package/.claude/skills/add-linear/REMOVE.md +0 -6
- package/.claude/skills/add-linear/SKILL.md +0 -168
- package/.claude/skills/add-linear/VERIFY.md +0 -3
- package/.claude/skills/add-macos-statusbar/SKILL.md +0 -133
- package/.claude/skills/add-macos-statusbar/add/src/statusbar.swift +0 -147
- package/.claude/skills/add-matrix/REMOVE.md +0 -6
- package/.claude/skills/add-matrix/SKILL.md +0 -148
- package/.claude/skills/add-matrix/VERIFY.md +0 -3
- package/.claude/skills/add-ollama-provider/SKILL.md +0 -179
- package/.claude/skills/add-ollama-tool/SKILL.md +0 -193
- package/.claude/skills/add-opencode/SKILL.md +0 -229
- package/.claude/skills/add-parallel/SKILL.md +0 -290
- package/.claude/skills/add-resend/REMOVE.md +0 -6
- package/.claude/skills/add-resend/SKILL.md +0 -93
- package/.claude/skills/add-resend/VERIFY.md +0 -3
- package/.claude/skills/add-signal/REMOVE.md +0 -13
- package/.claude/skills/add-signal/SKILL.md +0 -318
- package/.claude/skills/add-signal/VERIFY.md +0 -5
- package/.claude/skills/add-slack/REMOVE.md +0 -6
- package/.claude/skills/add-slack/SKILL.md +0 -112
- package/.claude/skills/add-slack/VERIFY.md +0 -3
- package/.claude/skills/add-teams/REMOVE.md +0 -6
- package/.claude/skills/add-teams/SKILL.md +0 -207
- package/.claude/skills/add-teams/VERIFY.md +0 -3
- package/.claude/skills/add-vercel/SKILL.md +0 -147
- package/.claude/skills/add-vercel/container-skills/vercel-cli/SKILL.md +0 -103
- package/.claude/skills/add-webex/REMOVE.md +0 -6
- package/.claude/skills/add-webex/SKILL.md +0 -88
- package/.claude/skills/add-webex/VERIFY.md +0 -3
- package/.claude/skills/add-wechat/REMOVE.md +0 -49
- package/.claude/skills/add-wechat/SKILL.md +0 -170
- package/.claude/skills/add-wechat/scripts/wire-dm.ts +0 -172
- package/.claude/skills/add-whatsapp/SKILL.md +0 -264
- package/.claude/skills/add-whatsapp-cloud/REMOVE.md +0 -6
- package/.claude/skills/add-whatsapp-cloud/SKILL.md +0 -95
- package/.claude/skills/add-whatsapp-cloud/VERIFY.md +0 -3
- package/.claude/skills/claw/SKILL.md +0 -131
- package/.claude/skills/claw/scripts/claw +0 -374
- package/.claude/skills/convert-to-apple-container/SKILL.md +0 -212
- package/.claude/skills/customize/SKILL.md +0 -110
- package/.claude/skills/debug/SKILL.md +0 -349
- package/.claude/skills/get-qodo-rules/SKILL.md +0 -122
- package/.claude/skills/get-qodo-rules/references/output-format.md +0 -41
- package/.claude/skills/get-qodo-rules/references/pagination.md +0 -33
- package/.claude/skills/get-qodo-rules/references/repository-scope.md +0 -26
- package/.claude/skills/init-first-agent/SKILL.md +0 -120
- package/.claude/skills/init-onecli/SKILL.md +0 -270
- package/.claude/skills/manage-channels/SKILL.md +0 -87
- package/.claude/skills/manage-mounts/SKILL.md +0 -47
- package/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md +0 -100
- package/.claude/skills/migrate-from-openclaw/SKILL.md +0 -447
- package/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts +0 -734
- package/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts +0 -476
- package/.claude/skills/migrate-nanoclaw/SKILL.md +0 -484
- package/.claude/skills/migrate-nanoclaw/diagnostics.md +0 -51
- package/.claude/skills/qodo-pr-resolver/SKILL.md +0 -326
- package/.claude/skills/qodo-pr-resolver/resources/providers.md +0 -329
- package/.claude/skills/update-nanoclaw/SKILL.md +0 -243
- package/.claude/skills/update-nanoclaw/diagnostics.md +0 -48
- package/.claude/skills/update-skills/SKILL.md +0 -130
- package/.claude/skills/use-native-credential-proxy/SKILL.md +0 -167
- package/.claude/skills/x-integration/SKILL.md +0 -417
- package/.claude/skills/x-integration/agent.ts +0 -243
- package/.claude/skills/x-integration/host.ts +0 -155
- package/.claude/skills/x-integration/lib/browser.ts +0 -148
- package/.claude/skills/x-integration/lib/config.ts +0 -62
- package/.claude/skills/x-integration/scripts/like.ts +0 -56
- package/.claude/skills/x-integration/scripts/post.ts +0 -66
- package/.claude/skills/x-integration/scripts/quote.ts +0 -80
- package/.claude/skills/x-integration/scripts/reply.ts +0 -74
- package/.claude/skills/x-integration/scripts/retweet.ts +0 -62
- package/.claude/skills/x-integration/scripts/setup.ts +0 -87
- package/.github/CODEOWNERS +0 -10
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -18
- package/.github/workflows/bump-version.yml +0 -35
- package/.github/workflows/ci.yml +0 -39
- package/.github/workflows/label-pr.yml +0 -40
- package/.github/workflows/update-tokens.yml +0 -43
- package/.husky/pre-commit +0 -1
- package/.mcp.json +0 -3
- package/.nvmrc +0 -1
- package/.prettierrc +0 -4
- package/CHANGELOG.md +0 -263
- package/CLAUDE.md +0 -307
- package/CODE_OF_CONDUCT.md +0 -128
- package/CONTRIBUTING.md +0 -159
- package/CONTRIBUTORS.md +0 -26
- package/LICENSE-NANOCLAW-MIT +0 -21
- package/README_ja.md +0 -194
- package/README_zh.md +0 -194
- package/assets/nanoclaw-favicon.png +0 -0
- package/assets/nanoclaw-icon.png +0 -0
- package/assets/nanoclaw-logo-dark.png +0 -0
- package/assets/nanoclaw-logo.png +0 -0
- package/assets/nanoclaw-profile.jpeg +0 -0
- package/assets/nanoclaw-sales.png +0 -0
- package/assets/social-preview.jpg +0 -0
- package/config-examples/mount-allowlist.json +0 -25
- package/container/.dockerignore +0 -2
- package/container/CLAUDE.md +0 -21
- package/container/Dockerfile +0 -121
- package/container/agent-runner/bun.lock +0 -243
- package/container/agent-runner/package.json +0 -22
- package/container/agent-runner/scripts/sdk-signal-probe.ts +0 -169
- package/container/agent-runner/src/config.ts +0 -55
- package/container/agent-runner/src/db/connection.ts +0 -267
- package/container/agent-runner/src/db/index.ts +0 -20
- package/container/agent-runner/src/db/messages-in.ts +0 -138
- package/container/agent-runner/src/db/messages-out.ts +0 -143
- package/container/agent-runner/src/db/session-routing.ts +0 -30
- package/container/agent-runner/src/db/session-state.test.ts +0 -100
- package/container/agent-runner/src/db/session-state.ts +0 -79
- package/container/agent-runner/src/destinations.ts +0 -135
- package/container/agent-runner/src/formatter.test.ts +0 -167
- package/container/agent-runner/src/formatter.ts +0 -260
- package/container/agent-runner/src/index.ts +0 -110
- package/container/agent-runner/src/integration.test.ts +0 -121
- package/container/agent-runner/src/mcp-tools/agents.instructions.md +0 -26
- package/container/agent-runner/src/mcp-tools/agents.ts +0 -66
- package/container/agent-runner/src/mcp-tools/core.instructions.md +0 -27
- package/container/agent-runner/src/mcp-tools/core.ts +0 -262
- package/container/agent-runner/src/mcp-tools/index.ts +0 -22
- package/container/agent-runner/src/mcp-tools/interactive.instructions.md +0 -22
- package/container/agent-runner/src/mcp-tools/interactive.ts +0 -169
- package/container/agent-runner/src/mcp-tools/scheduling.instructions.md +0 -40
- package/container/agent-runner/src/mcp-tools/scheduling.ts +0 -299
- package/container/agent-runner/src/mcp-tools/self-mod.instructions.md +0 -25
- package/container/agent-runner/src/mcp-tools/self-mod.ts +0 -120
- package/container/agent-runner/src/mcp-tools/server.ts +0 -54
- package/container/agent-runner/src/mcp-tools/types.ts +0 -6
- package/container/agent-runner/src/poll-loop.test.ts +0 -248
- package/container/agent-runner/src/poll-loop.ts +0 -437
- package/container/agent-runner/src/providers/claude.ts +0 -379
- package/container/agent-runner/src/providers/factory.test.ts +0 -19
- package/container/agent-runner/src/providers/factory.ts +0 -13
- package/container/agent-runner/src/providers/index.ts +0 -6
- package/container/agent-runner/src/providers/mock.ts +0 -77
- package/container/agent-runner/src/providers/provider-registry.ts +0 -33
- package/container/agent-runner/src/providers/types.ts +0 -82
- package/container/agent-runner/src/scheduling/task-script.ts +0 -121
- package/container/agent-runner/src/timezone.test.ts +0 -93
- package/container/agent-runner/src/timezone.ts +0 -107
- package/container/agent-runner/tsconfig.json +0 -14
- package/container/build.sh +0 -48
- package/container/entrypoint.sh +0 -16
- package/container/skills/agent-browser/SKILL.md +0 -159
- package/container/skills/frontend-engineer/SKILL.md +0 -157
- package/container/skills/self-customize/SKILL.md +0 -87
- package/container/skills/slack-formatting/SKILL.md +0 -94
- package/container/skills/vercel-cli/SKILL.md +0 -111
- package/container/skills/welcome/SKILL.md +0 -85
- package/docs/APPLE-CONTAINER-NETWORKING.md +0 -90
- package/docs/BRANCH-FORK-MAINTENANCE.md +0 -81
- package/docs/README.md +0 -25
- package/docs/SDK_DEEP_DIVE.md +0 -643
- package/docs/SECURITY.md +0 -162
- package/docs/agent-runner-details.md +0 -749
- package/docs/api-details.md +0 -365
- package/docs/architecture-diagram.html +0 -422
- package/docs/architecture-diagram.md +0 -215
- package/docs/architecture.md +0 -751
- package/docs/audit/2026-04-30-channel-endpoint-audit.md +0 -36
- package/docs/build-and-runtime.md +0 -80
- package/docs/cross-mount-stress/README.md +0 -112
- package/docs/cross-mount-stress/container-writer-retry.mjs +0 -55
- package/docs/cross-mount-stress/container-writer-slow.mjs +0 -42
- package/docs/cross-mount-stress/container-writer.mjs +0 -47
- package/docs/cross-mount-stress/host-writer-retry.mjs +0 -55
- package/docs/cross-mount-stress/host-writer-slow.mjs +0 -43
- package/docs/cross-mount-stress/host-writer.mjs +0 -47
- package/docs/db-central.md +0 -316
- package/docs/db-session.md +0 -183
- package/docs/db.md +0 -119
- package/docs/design/2026-04-29-vault-management-ui.md +0 -231
- package/docs/design/2026-04-30-channel-wiring-rework.md +0 -234
- package/docs/design/2026-05-01-channel-wiring-approvals-deep-dive.md +0 -272
- package/docs/design/2026-05-02-channel-policy-and-approval-routing.md +0 -250
- package/docs/docker-sandboxes.md +0 -359
- package/docs/isolation-model.md +0 -88
- package/docs/ollama.md +0 -79
- package/docs/parachute-integration.md +0 -109
- package/docs/post-night-rebirth-reflections.md +0 -151
- package/eslint.config.js +0 -32
- package/pnpm-workspace.yaml +0 -8
- package/repo-tokens/README.md +0 -113
- package/repo-tokens/action.yml +0 -186
- package/repo-tokens/badge.svg +0 -23
- package/repo-tokens/examples/green.svg +0 -14
- package/repo-tokens/examples/red.svg +0 -14
- package/repo-tokens/examples/yellow-green.svg +0 -14
- package/repo-tokens/examples/yellow.svg +0 -14
- package/scripts/chat.ts +0 -101
- package/scripts/cleanup-sessions.sh +0 -150
- package/scripts/init-cli-agent.ts +0 -172
- package/scripts/init-first-agent.ts +0 -378
- package/scripts/parachute.ts +0 -158
- package/scripts/run-migrations.ts +0 -105
- package/scripts/sanity-live-poll.ts +0 -95
- package/scripts/seed-discord.ts +0 -80
- package/scripts/test-v2-agent.ts +0 -106
- package/scripts/test-v2-channel-e2e.ts +0 -265
- package/scripts/test-v2-host.ts +0 -184
- package/src/channels/adapter.ts +0 -214
- package/src/channels/api-translator.test.ts +0 -306
- package/src/channels/api-translator.ts +0 -214
- package/src/channels/ask-question.ts +0 -46
- package/src/channels/channel-registry.test.ts +0 -421
- package/src/channels/channel-registry.ts +0 -313
- package/src/channels/chat-sdk-bridge.test.ts +0 -84
- package/src/channels/chat-sdk-bridge.ts +0 -652
- package/src/channels/cli.ts +0 -276
- package/src/channels/discord.ts +0 -90
- package/src/channels/index.ts +0 -17
- package/src/channels/telegram-markdown-sanitize.test.ts +0 -78
- package/src/channels/telegram-markdown-sanitize.ts +0 -55
- package/src/channels/telegram-pairing.test.ts +0 -254
- package/src/channels/telegram-pairing.ts +0 -339
- package/src/channels/telegram.ts +0 -279
- package/src/channels/trust-hint.test.ts +0 -48
- package/src/channels/trust-hint.ts +0 -75
- package/src/claude-md-compose.migrate.test.ts +0 -64
- package/src/claude-md-compose.ts +0 -205
- package/src/command-gate.ts +0 -63
- package/src/config.test.ts +0 -93
- package/src/config.ts +0 -128
- package/src/container-config.ts +0 -167
- package/src/container-runner.test.ts +0 -32
- package/src/container-runner.ts +0 -576
- package/src/container-runtime.test.ts +0 -269
- package/src/container-runtime.ts +0 -167
- package/src/db/_bun-sqlite-shim.ts +0 -88
- package/src/db/agent-activity.test.ts +0 -155
- package/src/db/agent-activity.ts +0 -121
- package/src/db/agent-groups.ts +0 -77
- package/src/db/connection.migrate.test.ts +0 -176
- package/src/db/connection.ts +0 -259
- package/src/db/db-v2.test.ts +0 -440
- package/src/db/dropped-messages.ts +0 -44
- package/src/db/index.ts +0 -40
- package/src/db/messaging-groups.ts +0 -252
- package/src/db/migrations/001-initial.ts +0 -112
- package/src/db/migrations/002-chat-sdk-state.ts +0 -36
- package/src/db/migrations/008-dropped-messages.ts +0 -27
- package/src/db/migrations/009-drop-pending-credentials.ts +0 -13
- package/src/db/migrations/010-engage-modes.ts +0 -103
- package/src/db/migrations/011-pending-sender-approvals.ts +0 -40
- package/src/db/migrations/012-channel-registration.ts +0 -48
- package/src/db/migrations/013-approval-render-metadata.ts +0 -27
- package/src/db/migrations/014-secrets.ts +0 -44
- package/src/db/migrations/015-secrets-drop-host-pattern.ts +0 -18
- package/src/db/migrations/016-secret-assignments.ts +0 -30
- package/src/db/migrations/017-agent-activity.ts +0 -40
- package/src/db/migrations/018-oauth-app-configs.ts +0 -34
- package/src/db/migrations/019-oauth-app-connections.ts +0 -48
- package/src/db/migrations/020-agent-app-connections.ts +0 -28
- package/src/db/migrations/021-pending-oauth-states.ts +0 -35
- package/src/db/migrations/022-app-connections-provider.ts +0 -25
- package/src/db/migrations/023-agent-group-secret-mode.test.ts +0 -124
- package/src/db/migrations/023-agent-group-secret-mode.ts +0 -65
- package/src/db/migrations/024-collapse-approvals.test.ts +0 -249
- package/src/db/migrations/024-collapse-approvals.ts +0 -182
- package/src/db/migrations/025-secret-mode-check.test.ts +0 -155
- package/src/db/migrations/025-secret-mode-check.ts +0 -49
- package/src/db/migrations/026-user-dms-bot-id.test.ts +0 -116
- package/src/db/migrations/026-user-dms-bot-id.ts +0 -54
- package/src/db/migrations/027-provider-credentials.ts +0 -41
- package/src/db/migrations/_test-helpers.ts +0 -41
- package/src/db/migrations/index.ts +0 -127
- package/src/db/migrations/module-agent-to-agent-destinations.ts +0 -84
- package/src/db/migrations/module-approvals-pending-approvals.ts +0 -42
- package/src/db/migrations/module-approvals-title-options.ts +0 -40
- package/src/db/schema.ts +0 -258
- package/src/db/session-db.test.ts +0 -93
- package/src/db/session-db.ts +0 -325
- package/src/db/sessions.ts +0 -241
- package/src/delivery.test.ts +0 -148
- package/src/delivery.ts +0 -445
- package/src/env.ts +0 -74
- package/src/group-folder.test.ts +0 -35
- package/src/group-folder.ts +0 -44
- package/src/group-init.ts +0 -92
- package/src/host-core.test.ts +0 -456
- package/src/host-sweep.test.ts +0 -146
- package/src/host-sweep.ts +0 -287
- package/src/index.ts +0 -232
- package/src/install-slug.ts +0 -33
- package/src/log.test.ts +0 -81
- package/src/log.ts +0 -117
- package/src/mcp/http.ts +0 -72
- package/src/mcp/server.ts +0 -92
- package/src/mcp/stdio.ts +0 -51
- package/src/mcp/tools/activity.ts +0 -88
- package/src/mcp/tools/agent-groups.ts +0 -183
- package/src/mcp/tools/approvals.ts +0 -122
- package/src/mcp/tools/channels.test.ts +0 -126
- package/src/mcp/tools/channels.ts +0 -134
- package/src/mcp/tools/index.ts +0 -27
- package/src/mcp/tools/oauth.ts +0 -48
- package/src/mcp/tools/secrets.ts +0 -169
- package/src/mcp/tools/sessions.ts +0 -135
- package/src/mcp/types.ts +0 -51
- package/src/modules/agent-to-agent/agent-route.test.ts +0 -46
- package/src/modules/agent-to-agent/agent-route.ts +0 -223
- package/src/modules/agent-to-agent/create-agent.ts +0 -127
- package/src/modules/agent-to-agent/db/agent-destinations.ts +0 -135
- package/src/modules/agent-to-agent/index.ts +0 -22
- package/src/modules/agent-to-agent/write-destinations.ts +0 -59
- package/src/modules/approvals/agent.md +0 -45
- package/src/modules/approvals/index.ts +0 -21
- package/src/modules/approvals/picks.test.ts +0 -291
- package/src/modules/approvals/primitive.ts +0 -279
- package/src/modules/approvals/project.md +0 -27
- package/src/modules/approvals/response-handler.ts +0 -87
- package/src/modules/index.ts +0 -24
- package/src/modules/interactive/agent.md +0 -21
- package/src/modules/interactive/index.ts +0 -69
- package/src/modules/interactive/project.md +0 -12
- package/src/modules/mount-security/expand-path.test.ts +0 -82
- package/src/modules/mount-security/index.ts +0 -459
- package/src/modules/mount-security/migrate.test.ts +0 -91
- package/src/modules/permissions/access.ts +0 -28
- package/src/modules/permissions/channel-approval.test.ts +0 -389
- package/src/modules/permissions/channel-approval.ts +0 -188
- package/src/modules/permissions/db/agent-group-members.ts +0 -44
- package/src/modules/permissions/db/pending-channel-approvals.test.ts +0 -86
- package/src/modules/permissions/db/pending-channel-approvals.ts +0 -66
- package/src/modules/permissions/db/pending-sender-approvals.ts +0 -60
- package/src/modules/permissions/db/user-dms.ts +0 -58
- package/src/modules/permissions/db/user-roles.ts +0 -85
- package/src/modules/permissions/db/users.ts +0 -38
- package/src/modules/permissions/index.ts +0 -421
- package/src/modules/permissions/permissions.test.ts +0 -358
- package/src/modules/permissions/sender-approval.test.ts +0 -641
- package/src/modules/permissions/sender-approval.ts +0 -165
- package/src/modules/permissions/user-dm.ts +0 -200
- package/src/modules/provider-credentials/db.ts +0 -121
- package/src/modules/provider-credentials/index.ts +0 -12
- package/src/modules/provider-credentials/spawn.test.ts +0 -206
- package/src/modules/provider-credentials/spawn.ts +0 -114
- package/src/modules/scheduling/actions.ts +0 -113
- package/src/modules/scheduling/db.test.ts +0 -282
- package/src/modules/scheduling/db.ts +0 -148
- package/src/modules/scheduling/index.ts +0 -34
- package/src/modules/scheduling/recurrence.test.ts +0 -98
- package/src/modules/scheduling/recurrence.ts +0 -54
- package/src/modules/self-mod/agent.md +0 -30
- package/src/modules/self-mod/apply.ts +0 -85
- package/src/modules/self-mod/index.ts +0 -30
- package/src/modules/self-mod/project.md +0 -39
- package/src/modules/self-mod/request.ts +0 -91
- package/src/modules/typing/index.ts +0 -165
- package/src/oauth/agent-app-connections.ts +0 -103
- package/src/oauth/app-configs.test.ts +0 -64
- package/src/oauth/app-configs.ts +0 -114
- package/src/oauth/app-connections.test.ts +0 -109
- package/src/oauth/app-connections.ts +0 -178
- package/src/oauth/crypto.ts +0 -56
- package/src/oauth/flow.ts +0 -104
- package/src/oauth/providers/google.test.ts +0 -38
- package/src/oauth/providers/google.ts +0 -46
- package/src/oauth/providers/index.ts +0 -48
- package/src/oauth/state-store.test.ts +0 -54
- package/src/oauth/state-store.ts +0 -93
- package/src/parachute/README.md +0 -27
- package/src/parachute/create-agent.test.ts +0 -83
- package/src/parachute/create-agent.ts +0 -122
- package/src/parachute/group-status.test.ts +0 -165
- package/src/parachute/group-status.ts +0 -136
- package/src/parachute/types.ts +0 -41
- package/src/parachute/vault-mcp.test.ts +0 -251
- package/src/parachute/vault-mcp.ts +0 -232
- package/src/platform-id.test.ts +0 -104
- package/src/platform-id.ts +0 -109
- package/src/providers/index.ts +0 -6
- package/src/providers/provider-container-registry.ts +0 -58
- package/src/response-registry.ts +0 -45
- package/src/router.ts +0 -530
- package/src/secrets/crypto.test.ts +0 -45
- package/src/secrets/crypto.ts +0 -55
- package/src/secrets/index.ts +0 -461
- package/src/secrets/master-key.ts +0 -70
- package/src/secrets/secrets.test.ts +0 -651
- package/src/session-manager.attachments.test.ts +0 -171
- package/src/session-manager.dup-skip.test.ts +0 -173
- package/src/session-manager.migrate.test.ts +0 -59
- package/src/session-manager.ts +0 -451
- package/src/startup-bootstrap.test.ts +0 -226
- package/src/startup-bootstrap.ts +0 -207
- package/src/state-sqlite.ts +0 -182
- package/src/timezone.test.ts +0 -64
- package/src/timezone.ts +0 -37
- package/src/types.ts +0 -233
- package/src/web/auth.test.ts +0 -335
- package/src/web/auth.ts +0 -214
- package/src/web/discord-validate.test.ts +0 -77
- package/src/web/discord-validate.ts +0 -88
- package/src/web/hub-discovery.test.ts +0 -98
- package/src/web/hub-discovery.ts +0 -69
- package/src/web/routes/activity.ts +0 -106
- package/src/web/routes/agent-provider.test.ts +0 -282
- package/src/web/routes/agent-provider.ts +0 -309
- package/src/web/routes/approvals.ts +0 -185
- package/src/web/routes/apps.ts +0 -434
- package/src/web/routes/channels-mg-detail.test.ts +0 -324
- package/src/web/routes/channels-mga-detail.test.ts +0 -472
- package/src/web/routes/channels.ts +0 -311
- package/src/web/routes/oauth-providers.ts +0 -42
- package/src/web/routes/secrets.test.ts +0 -220
- package/src/web/routes/secrets.ts +0 -317
- package/src/web/routes/sessions.ts +0 -123
- package/src/web/routes/settings.test.ts +0 -106
- package/src/web/routes/settings.ts +0 -247
- package/src/web/routes/setup-status.ts +0 -205
- package/src/web/routes/vaults.test.ts +0 -389
- package/src/web/routes/vaults.ts +0 -225
- package/src/web/server-version.test.ts +0 -16
- package/src/web/server.ts +0 -1024
- package/src/web/services-manifest.test.ts +0 -148
- package/src/web/services-manifest.ts +0 -66
- package/src/web/static-serve.test.ts +0 -255
- package/src/web/static-serve.ts +0 -104
- package/src/web/telegram-validate.test.ts +0 -116
- package/src/web/telegram-validate.ts +0 -107
- package/src/web/vault-proxy.test.ts +0 -214
- package/src/web/vault-proxy.ts +0 -120
- package/src/web/wire-channel.ts +0 -181
- package/src/webhook-server.ts +0 -134
- package/vitest.config.ts +0 -18
- package/web/README.md +0 -63
- package/web/ui/index.html +0 -13
- package/web/ui/package.json +0 -35
- package/web/ui/pnpm-lock.yaml +0 -2164
- package/web/ui/scripts/verify-base.mjs +0 -31
- package/web/ui/src/App.tsx +0 -88
- package/web/ui/src/components/ActivityFeed.tsx +0 -444
- package/web/ui/src/components/AgentGroupPicker.tsx +0 -263
- package/web/ui/src/components/AgentProviderCards.tsx +0 -220
- package/web/ui/src/components/CredentialForm.tsx +0 -214
- package/web/ui/src/components/ScopeGrants.tsx +0 -74
- package/web/ui/src/components/StatusDot.tsx +0 -43
- package/web/ui/src/components/VaultPicker.tsx +0 -127
- package/web/ui/src/components/setup/AdapterInstallStep.tsx +0 -178
- package/web/ui/src/components/setup/AgentGroupStep.tsx +0 -43
- package/web/ui/src/components/setup/ChannelPickStep.tsx +0 -74
- package/web/ui/src/components/setup/DoneStep.tsx +0 -49
- package/web/ui/src/components/setup/PrereqStep.tsx +0 -129
- package/web/ui/src/components/setup/TestConnectionStep.tsx +0 -108
- package/web/ui/src/components/setup/TestMessageStep.tsx +0 -104
- package/web/ui/src/components/setup/WireChannelStep.tsx +0 -166
- package/web/ui/src/components/setup/types.ts +0 -105
- package/web/ui/src/lib/api.test.ts +0 -410
- package/web/ui/src/lib/api.ts +0 -1248
- package/web/ui/src/lib/auth.test.ts +0 -352
- package/web/ui/src/lib/auth.ts +0 -405
- package/web/ui/src/lib/channel-adapters.ts +0 -136
- package/web/ui/src/main.tsx +0 -19
- package/web/ui/src/routes/ApprovalsList.tsx +0 -294
- package/web/ui/src/routes/Apps.tsx +0 -613
- package/web/ui/src/routes/ChannelWireDetail.test.tsx +0 -233
- package/web/ui/src/routes/ChannelWireDetail.tsx +0 -403
- package/web/ui/src/routes/ChannelsList.tsx +0 -158
- package/web/ui/src/routes/GroupDetail.test.tsx +0 -206
- package/web/ui/src/routes/GroupDetail.tsx +0 -880
- package/web/ui/src/routes/GroupList.tsx +0 -187
- package/web/ui/src/routes/MessagingGroupDetail.test.tsx +0 -233
- package/web/ui/src/routes/MessagingGroupDetail.tsx +0 -306
- package/web/ui/src/routes/NewGroupWizard.tsx +0 -390
- package/web/ui/src/routes/OAuthCallback.tsx +0 -56
- package/web/ui/src/routes/SecretsList.tsx +0 -942
- package/web/ui/src/routes/SessionsList.tsx +0 -220
- package/web/ui/src/routes/SettingsAgentProvider.tsx +0 -109
- package/web/ui/src/routes/SettingsApprovals.tsx +0 -234
- package/web/ui/src/routes/SetupWizard.tsx +0 -219
- package/web/ui/src/routes/VaultDetail.test.tsx +0 -363
- package/web/ui/src/routes/VaultDetail.tsx +0 -960
- package/web/ui/src/routes/VaultsList.tsx +0 -295
- package/web/ui/src/routes/WireChannelPage.tsx +0 -413
- package/web/ui/src/styles.css +0 -608
- package/web/ui/src/test/setup.ts +0 -23
- package/web/ui/src/vite-env.d.ts +0 -10
- package/web/ui/vite.config.ts +0 -34
- package/web/ui/vitest.config.ts +0 -25
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* api.ts unit tests — focused on the auth-gate behavior of `request<T>`.
|
|
3
|
-
* The vault token-mgmt helpers (mint/revoke/detach) thread an
|
|
4
|
-
* `authExtraScopes` hint so that a 403 scope-mismatch from the back-end
|
|
5
|
-
* triggers re-auth with the narrow per-vault scope appended, not just the
|
|
6
|
-
* broad REQUESTED_SCOPES set (paraclaw#56).
|
|
7
|
-
*
|
|
8
|
-
* Strategy: mock `auth.ts` so we can assert the exact arguments to
|
|
9
|
-
* beginLogin / refreshAccessToken / clearTokens; mock `fetch` to shape the
|
|
10
|
-
* wire response (200 / 403 with scope-mismatch body / 403 with unrelated
|
|
11
|
-
* body). beginLogin in production never returns (it does
|
|
12
|
-
* window.location.replace), so we mock it to *reject* — that lets the
|
|
13
|
-
* `await beginLogin(...)` inside request<T> propagate, and we assert on
|
|
14
|
-
* what it was called with.
|
|
15
|
-
*/
|
|
16
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
17
|
-
|
|
18
|
-
import * as auth from './auth.ts';
|
|
19
|
-
|
|
20
|
-
vi.mock('./auth.ts', () => ({
|
|
21
|
-
beginLogin: vi.fn(),
|
|
22
|
-
clearTokens: vi.fn(),
|
|
23
|
-
getAccessToken: vi.fn(() => 'cached-token'),
|
|
24
|
-
refreshAccessToken: vi.fn(),
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
beforeEach(() => {
|
|
28
|
-
// Each test does `await import('./api.ts')` after stubbing fetch. Without
|
|
29
|
-
// resetModules, vitest hands back the already-evaluated module from the
|
|
30
|
-
// first test in the file, so later tests see the *first* test's stubbed
|
|
31
|
-
// fetch — leading to false greens or confusing failures when one body
|
|
32
|
-
// shape is tested while another should fire. Reset between tests so
|
|
33
|
-
// every dynamic import re-evaluates against the current global stub.
|
|
34
|
-
vi.resetModules();
|
|
35
|
-
vi.mocked(auth.getAccessToken).mockReturnValue('cached-token');
|
|
36
|
-
// Reject so the `await beginLogin(...)` in request<T> resolves the chain
|
|
37
|
-
// and the caller's promise settles — letting us await + assert.
|
|
38
|
-
vi.mocked(auth.beginLogin).mockRejectedValue(new Error('beginLogin called (test)'));
|
|
39
|
-
vi.mocked(auth.refreshAccessToken).mockResolvedValue(null);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
vi.clearAllMocks();
|
|
44
|
-
vi.unstubAllGlobals();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
function jsonResponse(status: number, body: unknown): Response {
|
|
48
|
-
return new Response(JSON.stringify(body), {
|
|
49
|
-
status,
|
|
50
|
-
headers: { 'content-type': 'application/json' },
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
describe('mintVaultToken — auth gate on 403', () => {
|
|
55
|
-
it('passes vault:<name>:admin to beginLogin when the vault returns scope-mismatch', async () => {
|
|
56
|
-
// Factory-per-call: a Response body is single-consume, so a single
|
|
57
|
-
// mockResolvedValue would let isScopeMismatch.clone().text() drain the
|
|
58
|
-
// body for the first test and leave a stale Response with an empty
|
|
59
|
-
// body for any subsequent code path.
|
|
60
|
-
const fetchMock = vi.fn(async () =>
|
|
61
|
-
jsonResponse(403, { error: "This endpoint requires the 'vault:work:admin' scope" }),
|
|
62
|
-
);
|
|
63
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
64
|
-
|
|
65
|
-
const api = await import('./api.ts');
|
|
66
|
-
await expect(api.mintVaultToken('work', { label: 'claw-x', scopes: ['vault:read'] })).rejects.toThrow(
|
|
67
|
-
/beginLogin called/,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
expect(auth.clearTokens).toHaveBeenCalled();
|
|
71
|
-
expect(auth.beginLogin).toHaveBeenCalledWith(['vault:work:admin']);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe('revokeVaultToken — auth gate on 403', () => {
|
|
76
|
-
it('passes vault:<name>:admin to beginLogin', async () => {
|
|
77
|
-
// Factory-per-call: a Response body is single-consume, so a single
|
|
78
|
-
// mockResolvedValue would let isScopeMismatch.clone().text() drain the
|
|
79
|
-
// body for the first test and leave a stale Response with an empty
|
|
80
|
-
// body for any subsequent code path.
|
|
81
|
-
const fetchMock = vi.fn(async () =>
|
|
82
|
-
jsonResponse(403, { error: "This endpoint requires the 'vault:work:admin' scope" }),
|
|
83
|
-
);
|
|
84
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
85
|
-
|
|
86
|
-
const api = await import('./api.ts');
|
|
87
|
-
await expect(api.revokeVaultToken('work', 't_abc')).rejects.toThrow(/beginLogin called/);
|
|
88
|
-
|
|
89
|
-
expect(auth.beginLogin).toHaveBeenCalledWith(['vault:work:admin']);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe('detachVault — auth gate on 403', () => {
|
|
94
|
-
it('threads authExtraScopes from caller through to beginLogin', async () => {
|
|
95
|
-
// Factory-per-call: a Response body is single-consume, so a single
|
|
96
|
-
// mockResolvedValue would let isScopeMismatch.clone().text() drain the
|
|
97
|
-
// body for the first test and leave a stale Response with an empty
|
|
98
|
-
// body for any subsequent code path.
|
|
99
|
-
const fetchMock = vi.fn(async () =>
|
|
100
|
-
jsonResponse(403, { error: "This endpoint requires the 'vault:work:admin' scope" }),
|
|
101
|
-
);
|
|
102
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
103
|
-
|
|
104
|
-
const api = await import('./api.ts');
|
|
105
|
-
await expect(
|
|
106
|
-
api.detachVault('research', {
|
|
107
|
-
mcpName: 'parachute-vault',
|
|
108
|
-
revokeToken: true,
|
|
109
|
-
authExtraScopes: ['vault:work:admin'],
|
|
110
|
-
}),
|
|
111
|
-
).rejects.toThrow(/beginLogin called/);
|
|
112
|
-
|
|
113
|
-
expect(auth.beginLogin).toHaveBeenCalledWith(['vault:work:admin']);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('omits scope hint when caller did not supply one', async () => {
|
|
117
|
-
const fetchMock = vi
|
|
118
|
-
.fn()
|
|
119
|
-
.mockResolvedValue(jsonResponse(403, { error: 'This endpoint requires the agent:admin scope' }));
|
|
120
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
121
|
-
|
|
122
|
-
const api = await import('./api.ts');
|
|
123
|
-
await expect(api.detachVault('research', { revokeToken: false })).rejects.toThrow(/beginLogin called/);
|
|
124
|
-
|
|
125
|
-
expect(auth.beginLogin).toHaveBeenCalledWith(undefined);
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
describe('attachVault — auth gate on 403', () => {
|
|
130
|
-
it('threads authExtraScopes from caller through to beginLogin (paraclaw#65)', async () => {
|
|
131
|
-
const fetchMock = vi.fn(async () =>
|
|
132
|
-
jsonResponse(403, {
|
|
133
|
-
error: "vault token mint failed: This endpoint requires the 'vault:techne:admin' scope",
|
|
134
|
-
}),
|
|
135
|
-
);
|
|
136
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
137
|
-
|
|
138
|
-
const api = await import('./api.ts');
|
|
139
|
-
await expect(
|
|
140
|
-
api.attachVault(
|
|
141
|
-
'techne',
|
|
142
|
-
{ scope: 'vault:read', vaultBaseUrl: 'https://example/vault/techne' },
|
|
143
|
-
{ authExtraScopes: ['vault:techne:admin'] },
|
|
144
|
-
),
|
|
145
|
-
).rejects.toThrow(/beginLogin called/);
|
|
146
|
-
|
|
147
|
-
expect(auth.beginLogin).toHaveBeenCalledWith(['vault:techne:admin']);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('omits scope hint when caller did not supply one', async () => {
|
|
151
|
-
const fetchMock = vi.fn().mockResolvedValue(
|
|
152
|
-
jsonResponse(403, {
|
|
153
|
-
error: "vault token mint failed: This endpoint requires the 'vault:techne:admin' scope",
|
|
154
|
-
}),
|
|
155
|
-
);
|
|
156
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
157
|
-
|
|
158
|
-
const api = await import('./api.ts');
|
|
159
|
-
await expect(
|
|
160
|
-
api.attachVault('techne', { scope: 'vault:read', vaultBaseUrl: 'https://example/vault/techne' }),
|
|
161
|
-
).rejects.toThrow(/beginLogin called/);
|
|
162
|
-
|
|
163
|
-
expect(auth.beginLogin).toHaveBeenCalledWith(undefined);
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
describe('createGroup — auth gate on 403', () => {
|
|
168
|
-
it('threads authExtraScopes when create-with-attach 403s on vault scope (paraclaw#65)', async () => {
|
|
169
|
-
const fetchMock = vi.fn(async () =>
|
|
170
|
-
jsonResponse(403, {
|
|
171
|
-
error: "vault token mint failed: This endpoint requires the 'vault:techne:admin' scope",
|
|
172
|
-
}),
|
|
173
|
-
);
|
|
174
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
175
|
-
|
|
176
|
-
const api = await import('./api.ts');
|
|
177
|
-
await expect(
|
|
178
|
-
api.createGroup(
|
|
179
|
-
{
|
|
180
|
-
name: 'Techne',
|
|
181
|
-
folder: 'techne',
|
|
182
|
-
vault: { scope: 'vault:read', vaultBaseUrl: 'https://example/vault/techne' },
|
|
183
|
-
},
|
|
184
|
-
{ authExtraScopes: ['vault:techne:admin'] },
|
|
185
|
-
),
|
|
186
|
-
).rejects.toThrow(/beginLogin called/);
|
|
187
|
-
|
|
188
|
-
expect(auth.beginLogin).toHaveBeenCalledWith(['vault:techne:admin']);
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
describe('non-scope 403 does NOT trigger re-auth', () => {
|
|
193
|
-
it('throws HttpError(403) when body is unrelated', async () => {
|
|
194
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(403, { error: 'forbidden' }));
|
|
195
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
196
|
-
|
|
197
|
-
const api = await import('./api.ts');
|
|
198
|
-
await expect(api.mintVaultToken('work', { label: 'x', scopes: ['vault:read'] })).rejects.toMatchObject({
|
|
199
|
-
name: 'HttpError',
|
|
200
|
-
status: 403,
|
|
201
|
-
});
|
|
202
|
-
expect(auth.beginLogin).not.toHaveBeenCalled();
|
|
203
|
-
expect(auth.clearTokens).not.toHaveBeenCalled();
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
describe('happy path — 200 returns parsed body and skips auth', () => {
|
|
208
|
-
it('mintVaultToken returns the parsed MintedVaultToken', async () => {
|
|
209
|
-
const minted = {
|
|
210
|
-
token: 'pvt_secret',
|
|
211
|
-
id: 't_new',
|
|
212
|
-
label: 'claw-x',
|
|
213
|
-
scopes: ['vault:read'],
|
|
214
|
-
};
|
|
215
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(200, minted));
|
|
216
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
217
|
-
|
|
218
|
-
const api = await import('./api.ts');
|
|
219
|
-
const result = await api.mintVaultToken('work', { label: 'claw-x', scopes: ['vault:read'] });
|
|
220
|
-
|
|
221
|
-
expect(result).toEqual(minted);
|
|
222
|
-
expect(auth.beginLogin).not.toHaveBeenCalled();
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
describe('updateMessagingGroupPolicy — body shape and method', () => {
|
|
227
|
-
// Server-side validateMgPatchInput keys on `unknownSenderPolicy` exactly;
|
|
228
|
-
// pin the wire shape here so a future rename doesn't silently regress.
|
|
229
|
-
it('PATCHes /channels/mg/:id with unknownSenderPolicy', async () => {
|
|
230
|
-
const result = {
|
|
231
|
-
messagingGroup: {
|
|
232
|
-
id: 'mg_1',
|
|
233
|
-
channelType: 'telegram',
|
|
234
|
-
platformId: 'telegram:42:1',
|
|
235
|
-
displayName: null,
|
|
236
|
-
isGroup: false,
|
|
237
|
-
unknownSenderPolicy: 'public',
|
|
238
|
-
deniedAt: null,
|
|
239
|
-
createdAt: '2026-04-20T10:00:00Z',
|
|
240
|
-
wiredAgents: [],
|
|
241
|
-
},
|
|
242
|
-
};
|
|
243
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(200, result));
|
|
244
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
245
|
-
|
|
246
|
-
const api = await import('./api.ts');
|
|
247
|
-
const view = await api.updateMessagingGroupPolicy('mg_1', 'public');
|
|
248
|
-
|
|
249
|
-
expect(view.unknownSenderPolicy).toBe('public');
|
|
250
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
251
|
-
const [url, init] = fetchMock.mock.calls[0]!;
|
|
252
|
-
expect(String(url)).toMatch(/\/api\/channels\/mg\/mg_1$/);
|
|
253
|
-
expect((init as RequestInit).method).toBe('PATCH');
|
|
254
|
-
expect(JSON.parse((init as RequestInit).body as string)).toEqual({ unknownSenderPolicy: 'public' });
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
it('surfaces server 400 as HttpError(400) without re-auth', async () => {
|
|
258
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(400, { error: 'invalid unknownSenderPolicy: open' }));
|
|
259
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
260
|
-
|
|
261
|
-
const api = await import('./api.ts');
|
|
262
|
-
// Cast through unknown so we can drive the bad-input branch even though
|
|
263
|
-
// `open` isn't a valid UnknownSenderPolicy at the type level — the
|
|
264
|
-
// server is what we're pinning here, not the static check.
|
|
265
|
-
type UnknownSenderPolicy = import('./api.ts').UnknownSenderPolicy;
|
|
266
|
-
await expect(
|
|
267
|
-
api.updateMessagingGroupPolicy('mg_1', 'open' as unknown as UnknownSenderPolicy),
|
|
268
|
-
).rejects.toMatchObject({ name: 'HttpError', status: 400 });
|
|
269
|
-
expect(auth.beginLogin).not.toHaveBeenCalled();
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
describe('getMessagingGroupDetail — happy path', () => {
|
|
274
|
-
it('parses { messagingGroup } envelope and returns the view', async () => {
|
|
275
|
-
const view = {
|
|
276
|
-
id: 'mg_x',
|
|
277
|
-
channelType: 'discord',
|
|
278
|
-
platformId: 'discord:@me:99',
|
|
279
|
-
displayName: 'Aaron DM',
|
|
280
|
-
isGroup: false,
|
|
281
|
-
unknownSenderPolicy: 'request_approval',
|
|
282
|
-
deniedAt: null,
|
|
283
|
-
createdAt: '2026-04-20T10:00:00Z',
|
|
284
|
-
wiredAgents: [
|
|
285
|
-
{
|
|
286
|
-
messagingGroupAgentId: 'mga_1',
|
|
287
|
-
agentGroupId: 'ag_1',
|
|
288
|
-
agentGroupFolder: 'main',
|
|
289
|
-
agentGroupName: 'Main',
|
|
290
|
-
engageMode: 'mention',
|
|
291
|
-
engagePattern: null,
|
|
292
|
-
senderScope: 'unrestricted',
|
|
293
|
-
ignoredMessagePolicy: 'drop',
|
|
294
|
-
priority: 0,
|
|
295
|
-
createdAt: '2026-04-20T10:00:00Z',
|
|
296
|
-
},
|
|
297
|
-
],
|
|
298
|
-
};
|
|
299
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(200, { messagingGroup: view }));
|
|
300
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
301
|
-
|
|
302
|
-
const api = await import('./api.ts');
|
|
303
|
-
const result = await api.getMessagingGroupDetail('mg_x');
|
|
304
|
-
expect(result).toEqual(view);
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
describe('wireChannelToGroup — body contract with server', () => {
|
|
309
|
-
// Server keys on `channelType` (matches DB column + WireDmInput). Helper
|
|
310
|
-
// accepts `channel` for ergonomics; this test pins the wire boundary so
|
|
311
|
-
// a future rename can't silently regress to "channelType must be …" 400s.
|
|
312
|
-
it('serializes input.channel as channelType in the request body', async () => {
|
|
313
|
-
const result = {
|
|
314
|
-
messagingGroupId: 'mg_1',
|
|
315
|
-
messagingGroupAgentId: 'mga_1',
|
|
316
|
-
platformId: 'telegram:42',
|
|
317
|
-
created: { messagingGroup: true, wiring: true },
|
|
318
|
-
};
|
|
319
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(200, result));
|
|
320
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
321
|
-
|
|
322
|
-
const api = await import('./api.ts');
|
|
323
|
-
await api.wireChannelToGroup('forge', {
|
|
324
|
-
channel: 'telegram',
|
|
325
|
-
botId: '7654321',
|
|
326
|
-
botUserId: '42',
|
|
327
|
-
operatorUserId: '42',
|
|
328
|
-
displayName: 'Forge DM',
|
|
329
|
-
});
|
|
330
|
-
|
|
331
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
332
|
-
const [, init] = fetchMock.mock.calls[0]!;
|
|
333
|
-
const body = JSON.parse((init as RequestInit).body as string);
|
|
334
|
-
expect(body).toEqual({
|
|
335
|
-
channelType: 'telegram',
|
|
336
|
-
botId: '7654321',
|
|
337
|
-
botUserId: '42',
|
|
338
|
-
operatorUserId: '42',
|
|
339
|
-
displayName: 'Forge DM',
|
|
340
|
-
});
|
|
341
|
-
expect(body.channel).toBeUndefined();
|
|
342
|
-
});
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
describe('channel-wire helpers — pinned to /channels/mga/:id', () => {
|
|
346
|
-
// PR3 disambiguates per-MG and per-MGA detail under prefixed paths. Pin
|
|
347
|
-
// the helper paths so a future refactor can't silently fall back to the
|
|
348
|
-
// single-segment `/channels/:id` shape that PR3 deleted.
|
|
349
|
-
function wireView(over: Partial<import('./api.ts').ChannelWireView> = {}): import('./api.ts').ChannelWireView {
|
|
350
|
-
return {
|
|
351
|
-
id: 'mga_1',
|
|
352
|
-
channelType: 'telegram',
|
|
353
|
-
messagingGroupId: 'mg_1',
|
|
354
|
-
platformId: 'telegram:42:1',
|
|
355
|
-
displayName: null,
|
|
356
|
-
agentGroupId: 'ag_1',
|
|
357
|
-
agentGroupFolder: 'main',
|
|
358
|
-
agentGroupName: 'Main',
|
|
359
|
-
engageMode: 'mention',
|
|
360
|
-
engagePattern: null,
|
|
361
|
-
senderScope: 'unrestricted',
|
|
362
|
-
ignoredMessagePolicy: 'drop',
|
|
363
|
-
priority: 0,
|
|
364
|
-
createdAt: '2026-04-20T10:00:00Z',
|
|
365
|
-
...over,
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
it('getChannelWireDetail GETs /channels/mga/:id and unwraps { wire }', async () => {
|
|
370
|
-
const view = wireView({ id: 'mga_x', engageMode: 'all' });
|
|
371
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(200, { wire: view }));
|
|
372
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
373
|
-
|
|
374
|
-
const api = await import('./api.ts');
|
|
375
|
-
const result = await api.getChannelWireDetail('mga_x');
|
|
376
|
-
|
|
377
|
-
expect(result).toEqual(view);
|
|
378
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
379
|
-
const [url, init] = fetchMock.mock.calls[0]!;
|
|
380
|
-
expect(String(url)).toMatch(/\/api\/channels\/mga\/mga_x$/);
|
|
381
|
-
expect((init as RequestInit).method ?? 'GET').toBe('GET');
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
it('updateChannelWire PATCHes /channels/mga/:id with the input body', async () => {
|
|
385
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(200, { wire: wireView({ engageMode: 'all' }) }));
|
|
386
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
387
|
-
|
|
388
|
-
const api = await import('./api.ts');
|
|
389
|
-
await api.updateChannelWire('mga_1', { engageMode: 'all', priority: 3 });
|
|
390
|
-
|
|
391
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
392
|
-
const [url, init] = fetchMock.mock.calls[0]!;
|
|
393
|
-
expect(String(url)).toMatch(/\/api\/channels\/mga\/mga_1$/);
|
|
394
|
-
expect((init as RequestInit).method).toBe('PATCH');
|
|
395
|
-
expect(JSON.parse((init as RequestInit).body as string)).toEqual({ engageMode: 'all', priority: 3 });
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
it('deleteChannelWire DELETEs /channels/mga/:id', async () => {
|
|
399
|
-
const fetchMock = vi.fn().mockResolvedValue(jsonResponse(200, { id: 'mga_1', deleted: true }));
|
|
400
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
401
|
-
|
|
402
|
-
const api = await import('./api.ts');
|
|
403
|
-
await api.deleteChannelWire('mga_1');
|
|
404
|
-
|
|
405
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
406
|
-
const [url, init] = fetchMock.mock.calls[0]!;
|
|
407
|
-
expect(String(url)).toMatch(/\/api\/channels\/mga\/mga_1$/);
|
|
408
|
-
expect((init as RequestInit).method).toBe('DELETE');
|
|
409
|
-
});
|
|
410
|
-
});
|