@vellumai/assistant 0.7.0 → 0.7.1
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/ARCHITECTURE.md +6 -7
- package/Dockerfile +1 -0
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
- package/bun.lock +3 -0
- package/docs/architecture/security.md +18 -16
- package/knip.json +1 -0
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
- package/node_modules/@vellumai/slack-text/bun.lock +24 -0
- package/node_modules/@vellumai/slack-text/package.json +18 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
- package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
- package/openapi.yaml +294 -107
- package/package.json +4 -2
- package/scripts/generate-openapi.ts +16 -111
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
- package/src/__tests__/anthropic-provider.test.ts +56 -13
- package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
- package/src/__tests__/app-conversation-ids.test.ts +151 -0
- package/src/__tests__/approval-cascade.test.ts +0 -15
- package/src/__tests__/approval-routes-http.test.ts +6 -17
- package/src/__tests__/assistant-event-hub.test.ts +126 -77
- package/src/__tests__/assistant-event.test.ts +0 -5
- package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
- package/src/__tests__/background-shell-host-bash.test.ts +34 -43
- package/src/__tests__/call-controller.test.ts +1 -1
- package/src/__tests__/call-site-routing-provider.test.ts +193 -0
- package/src/__tests__/channel-approval-routes.test.ts +10 -296
- package/src/__tests__/channel-approvals.test.ts +25 -17
- package/src/__tests__/channel-guardian.test.ts +100 -146
- package/src/__tests__/checker.test.ts +20 -34
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/config-schema.test.ts +6 -48
- package/src/__tests__/config-watcher.test.ts +12 -0
- package/src/__tests__/connection-policy.test.ts +1 -52
- package/src/__tests__/contacts-write.test.ts +2 -64
- package/src/__tests__/context-image-dimensions.test.ts +1 -1
- package/src/__tests__/context-search-memory-source.test.ts +120 -1
- package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
- package/src/__tests__/context-search-pkb-source.test.ts +49 -0
- package/src/__tests__/context-search-workspace-source.test.ts +9 -22
- package/src/__tests__/context-window-manager.test.ts +46 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
- package/src/__tests__/conversation-agent-loop.test.ts +980 -13
- package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
- package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
- package/src/__tests__/conversation-history-web-search.test.ts +4 -3
- package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
- package/src/__tests__/conversation-lifecycle.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +79 -2
- package/src/__tests__/conversation-queue.test.ts +3 -8
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
- package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
- package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
- package/src/__tests__/conversation-slash-commands.test.ts +24 -4
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-starter-routes.test.ts +79 -2
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
- package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
- package/src/__tests__/conversation-usage.test.ts +253 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
- package/src/__tests__/credential-health-service.test.ts +68 -0
- package/src/__tests__/credential-security-e2e.test.ts +4 -3
- package/src/__tests__/credential-security-invariants.test.ts +1 -5
- package/src/__tests__/credential-token-resolver.test.ts +180 -0
- package/src/__tests__/cu-unified-flow.test.ts +33 -16
- package/src/__tests__/daemon-assistant-events.test.ts +34 -21
- package/src/__tests__/daemon-credential-client.test.ts +4 -1
- package/src/__tests__/db-connection-isolation.test.ts +125 -0
- package/src/__tests__/db-migration-rollback.test.ts +101 -0
- package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
- package/src/__tests__/document-conversations.test.ts +332 -0
- package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
- package/src/__tests__/emit-event-signal.test.ts +4 -6
- package/src/__tests__/events-client-registration.test.ts +193 -49
- package/src/__tests__/filing-service.test.ts +58 -7
- package/src/__tests__/first-greeting.test.ts +156 -150
- package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
- package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -1
- package/src/__tests__/guardian-grant-minting.test.ts +7 -2
- package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
- package/src/__tests__/guardian-routing-state.test.ts +1 -1
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
- package/src/__tests__/headless-browser-mode.test.ts +4 -9
- package/src/__tests__/headless-browser-navigate.test.ts +21 -20
- package/src/__tests__/heartbeat-service.test.ts +289 -7
- package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
- package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
- package/src/__tests__/host-bash-proxy.test.ts +46 -122
- package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
- package/src/__tests__/host-browser-proxy.test.ts +111 -185
- package/src/__tests__/host-browser-routes.test.ts +45 -75
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
- package/src/__tests__/host-cu-proxy.test.ts +56 -111
- package/src/__tests__/host-file-proxy.test.ts +44 -98
- package/src/__tests__/host-file-read-tool.test.ts +42 -21
- package/src/__tests__/host-shell-tool.test.ts +33 -68
- package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
- package/src/__tests__/host-transfer-proxy.test.ts +43 -53
- package/src/__tests__/http-user-message-parity.test.ts +0 -6
- package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
- package/src/__tests__/injector-chain.test.ts +10 -5
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -66
- package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
- package/src/__tests__/install-skill-routing.test.ts +1 -13
- package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
- package/src/__tests__/llm-catalog-parity.test.ts +90 -0
- package/src/__tests__/llm-context-resolution.test.ts +180 -0
- package/src/__tests__/llm-resolver.test.ts +80 -12
- package/src/__tests__/llm-usage-store.test.ts +269 -4
- package/src/__tests__/log-export-routes.test.ts +89 -0
- package/src/__tests__/managed-profile-guard.test.ts +225 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
- package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
- package/src/__tests__/migration-export-http.test.ts +33 -26
- package/src/__tests__/migration-export-streaming.test.ts +18 -10
- package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
- package/src/__tests__/migration-import-commit-http.test.ts +66 -21
- package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
- package/src/__tests__/migration-import-from-url.test.ts +20 -6
- package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
- package/src/__tests__/migration-parity-persistence.test.ts +62 -25
- package/src/__tests__/migration-transport.test.ts +115 -23
- package/src/__tests__/migration-validate-http.test.ts +105 -80
- package/src/__tests__/migration-wizard.test.ts +133 -27
- package/src/__tests__/non-member-access-request.test.ts +1 -1
- package/src/__tests__/notification-guardian-path.test.ts +1 -1
- package/src/__tests__/oauth-store.test.ts +19 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
- package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
- package/src/__tests__/pricing.test.ts +68 -4
- package/src/__tests__/process-message-background-slack.test.ts +331 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
- package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
- package/src/__tests__/provider-usage-tracking.test.ts +208 -0
- package/src/__tests__/reaction-persistence.test.ts +9 -6
- package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
- package/src/__tests__/recording-handler.test.ts +64 -81
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
- package/src/__tests__/relay-server.test.ts +18 -13
- package/src/__tests__/require-fresh-approval.test.ts +13 -22
- package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +3 -12
- package/src/__tests__/search-skills-unified.test.ts +9 -15
- package/src/__tests__/secret-ingress-cli.test.ts +2 -5
- package/src/__tests__/secret-ingress-http.test.ts +0 -4
- package/src/__tests__/secret-onetime-send.test.ts +4 -2
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
- package/src/__tests__/secret-response-routing.test.ts +29 -15
- package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
- package/src/__tests__/secret-scanner.test.ts +2 -545
- package/src/__tests__/send-endpoint-busy.test.ts +9 -24
- package/src/__tests__/settings-routes.test.ts +1 -1
- package/src/__tests__/shell-credential-ref.test.ts +0 -8
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
- package/src/__tests__/skill-tool-factory.test.ts +97 -0
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
- package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
- package/src/__tests__/slack-inbound-verification.test.ts +1 -62
- package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
- package/src/__tests__/subagent-manager-notify.test.ts +70 -70
- package/src/__tests__/subagent-notify-parent.test.ts +80 -83
- package/src/__tests__/system-prompt.test.ts +115 -13
- package/src/__tests__/terminal-tools.test.ts +0 -89
- package/src/__tests__/thread-backfill.test.ts +945 -31
- package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
- package/src/__tests__/tool-executor.test.ts +12 -19
- package/src/__tests__/tool-metrics-listener.test.ts +0 -35
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
- package/src/__tests__/tool-trace-listener.test.ts +0 -17
- package/src/__tests__/transfer-progress-screen.test.ts +63 -26
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
- package/src/__tests__/trusted-contact-verification.test.ts +1 -1
- package/src/__tests__/tts-catalog-parity.test.ts +16 -5
- package/src/__tests__/usage-attribution.test.ts +247 -0
- package/src/__tests__/usage-cli.test.ts +143 -0
- package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
- package/src/__tests__/usage-routes.test.ts +150 -0
- package/src/__tests__/validation-results-screen.test.ts +39 -16
- package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
- package/src/__tests__/voice-session-bridge.test.ts +5 -5
- package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
- package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
- package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
- package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
- package/src/acp/index.ts +0 -15
- package/src/acp/session-manager.ts +37 -34
- package/src/agent/loop.ts +16 -1
- package/src/approvals/AGENTS.md +4 -0
- package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
- package/src/approvals/guardian-request-resolvers.ts +10 -2
- package/src/backup/__tests__/backup-worker.test.ts +36 -8
- package/src/backup/__tests__/paths.test.ts +2 -2
- package/src/backup/__tests__/restore.test.ts +45 -28
- package/src/backup/backup-worker.ts +36 -2
- package/src/backup/paths.ts +9 -6
- package/src/browser-session/events.ts +0 -9
- package/src/calls/call-store.ts +1 -34
- package/src/calls/guardian-question-copy.ts +0 -108
- package/src/calls/relay-server.ts +0 -24
- package/src/calls/twilio-rest.ts +0 -38
- package/src/calls/twilio-routes.ts +1 -1
- package/src/calls/voice-session-bridge.ts +7 -38
- package/src/channels/types.ts +1 -36
- package/src/cli/commands/__tests__/cache.test.ts +152 -5
- package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
- package/src/cli/commands/__tests__/trust.test.ts +21 -387
- package/src/cli/commands/backup.ts +4 -4
- package/src/cli/commands/cache-fs.ts +8 -0
- package/src/cli/commands/cache.ts +153 -82
- package/src/cli/commands/clients.ts +63 -5
- package/src/cli/commands/completions.ts +3 -3
- package/src/cli/commands/contacts.ts +231 -76
- package/src/cli/commands/keys.ts +4 -1
- package/src/cli/commands/memory-v2.ts +24 -52
- package/src/cli/commands/oauth/shared.ts +2 -29
- package/src/cli/commands/pending.ts +102 -0
- package/src/cli/commands/skills.ts +77 -35
- package/src/cli/commands/trust.ts +70 -430
- package/src/cli/commands/usage.ts +25 -16
- package/src/cli/lib/daemon-credential-client.ts +14 -0
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +0 -21
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
- package/src/config/env-registry.ts +12 -2
- package/src/config/env.ts +3 -14
- package/src/config/feature-flag-registry.json +30 -30
- package/src/config/llm-callsite-catalog.ts +12 -0
- package/src/config/llm-context-resolution.ts +80 -0
- package/src/config/llm-resolver.ts +58 -22
- package/src/config/loader.ts +3 -3
- package/src/config/schema.ts +2 -158
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +271 -0
- package/src/config/schemas/calls.ts +5 -5
- package/src/config/schemas/inference.ts +1 -1
- package/src/config/schemas/ingress.ts +1 -1
- package/src/config/schemas/llm.ts +31 -3
- package/src/config/schemas/memory-retrieval.ts +2 -2
- package/src/config/schemas/memory-v2.ts +9 -0
- package/src/config/schemas/security.ts +1 -42
- package/src/config/schemas/services.ts +6 -6
- package/src/config/schemas/skills.ts +5 -5
- package/src/config/schemas/tts.ts +1 -1
- package/src/config/seed-inference-profiles.ts +117 -0
- package/src/config/skills.ts +0 -90
- package/src/config/types.ts +3 -6
- package/src/contacts/contact-store.ts +0 -17
- package/src/contacts/contacts-write.ts +1 -105
- package/src/context/window-manager.ts +44 -5
- package/src/credential-execution/process-manager.ts +34 -10
- package/src/credential-health/credential-health-service.ts +21 -16
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
- package/src/daemon/connection-policy.ts +1 -26
- package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
- package/src/daemon/conversation-agent-loop.ts +277 -36
- package/src/daemon/conversation-history.ts +8 -8
- package/src/daemon/conversation-launch.ts +20 -135
- package/src/daemon/conversation-lifecycle.ts +1 -1
- package/src/daemon/conversation-messaging.ts +1 -0
- package/src/daemon/conversation-process.ts +83 -163
- package/src/daemon/conversation-runtime-assembly.ts +219 -76
- package/src/daemon/conversation-slash.ts +47 -5
- package/src/daemon/conversation-store.ts +7 -31
- package/src/daemon/conversation-surfaces.ts +22 -28
- package/src/daemon/conversation-tool-setup.ts +3 -33
- package/src/daemon/conversation-usage.ts +36 -0
- package/src/daemon/conversation.ts +117 -233
- package/src/daemon/daemon-control.ts +3 -71
- package/src/daemon/daemon-skill-host.ts +8 -11
- package/src/daemon/dictation-profile-store.ts +2 -26
- package/src/daemon/first-greeting.ts +44 -156
- package/src/daemon/handlers/config-channels.ts +12 -12
- package/src/daemon/handlers/config-ingress.ts +4 -165
- package/src/daemon/handlers/config-model.ts +1 -1
- package/src/daemon/handlers/config-voice.ts +0 -42
- package/src/daemon/handlers/conversations.ts +11 -190
- package/src/daemon/handlers/recording.ts +26 -158
- package/src/daemon/handlers/shared.ts +23 -71
- package/src/daemon/handlers/skills.ts +42 -93
- package/src/daemon/host-bash-proxy.ts +67 -45
- package/src/daemon/host-browser-proxy.ts +65 -27
- package/src/daemon/host-cu-proxy.ts +40 -39
- package/src/daemon/host-file-proxy.ts +58 -37
- package/src/daemon/host-transfer-proxy.ts +84 -46
- package/src/daemon/lifecycle.ts +49 -15
- package/src/daemon/message-types/conversations.ts +7 -0
- package/src/daemon/message-types/host-bash.ts +1 -0
- package/src/daemon/message-types/host-cu.ts +1 -0
- package/src/daemon/message-types/host-file.ts +1 -0
- package/src/daemon/message-types/host-transfer.ts +1 -0
- package/src/daemon/message-types/messages.ts +10 -9
- package/src/daemon/message-types/workspace.ts +1 -1
- package/src/daemon/process-message.ts +102 -239
- package/src/daemon/server.ts +13 -462
- package/src/daemon/shutdown-handlers.ts +2 -2
- package/src/daemon/tool-side-effects.ts +125 -107
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +4 -9
- package/src/events/domain-events.ts +0 -8
- package/src/events/tool-audit-listener.ts +3 -1
- package/src/events/tool-domain-event-publisher.ts +0 -10
- package/src/events/tool-metrics-listener.ts +0 -17
- package/src/events/tool-trace-listener.ts +0 -14
- package/src/filing/filing-service.ts +13 -1
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
- package/src/heartbeat/heartbeat-service.ts +23 -5
- package/src/home/__tests__/feed-writer.test.ts +0 -4
- package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
- package/src/home/feed-writer.ts +1 -2
- package/src/home/relationship-state-writer.ts +16 -3
- package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
- package/src/ipc/assistant-server.ts +3 -10
- package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
- package/src/ipc/routes/route-adapter.ts +1 -1
- package/src/ipc/routes/trust-rules.test.ts +0 -95
- package/src/ipc/skill-ipc-types.ts +41 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
- package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
- package/src/ipc/skill-routes/events.ts +12 -23
- package/src/ipc/skill-routes/identity.ts +4 -17
- package/src/ipc/skill-routes/index.ts +1 -1
- package/src/ipc/skill-server.ts +6 -39
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
- package/src/live-voice/protocol.ts +4 -13
- package/src/mcp/manager.ts +0 -5
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
- package/src/memory/app-git-service.ts +0 -32
- package/src/memory/app-store.ts +154 -0
- package/src/memory/attachments-store.ts +6 -0
- package/src/memory/context-search/sources/memory-v2.ts +578 -0
- package/src/memory/context-search/sources/memory.ts +5 -0
- package/src/memory/context-search/sources/pkb.ts +10 -1
- package/src/memory/context-search/sources/workspace.ts +3 -2
- package/src/memory/conversation-crud.ts +29 -4
- package/src/memory/conversation-disk-view.ts +1 -5
- package/src/memory/conversation-starter-checkpoints.ts +63 -0
- package/src/memory/db-connection.ts +62 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +3 -21
- package/src/memory/embedding-gemini.ts +0 -2
- package/src/memory/embedding-local.ts +6 -6
- package/src/memory/embedding-ollama.ts +6 -6
- package/src/memory/embedding-openai.ts +6 -6
- package/src/memory/embedding-types.ts +21 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
- package/src/memory/graph/conversation-graph-memory.ts +35 -13
- package/src/memory/graph/injection.test.ts +2 -2
- package/src/memory/graph/injection.ts +1 -1
- package/src/memory/guardian-action-store.ts +0 -83
- package/src/memory/guardian-approvals.ts +0 -48
- package/src/memory/indexer.ts +1 -15
- package/src/memory/job-handlers/conversation-starters.ts +36 -53
- package/src/memory/job-utils.ts +0 -6
- package/src/memory/jobs-store.ts +0 -1
- package/src/memory/jobs-worker.ts +2 -16
- package/src/memory/llm-request-log-store.ts +0 -41
- package/src/memory/llm-usage-store.ts +129 -43
- package/src/memory/memory-v2-activation-log-store.ts +115 -0
- package/src/memory/migrations/233-document-conversations.ts +54 -0
- package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
- package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
- package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
- package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
- package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
- package/src/memory/migrations/index.ts +14 -0
- package/src/memory/migrations/registry.ts +24 -0
- package/src/memory/raw-query.ts +2 -68
- package/src/memory/schema/conversations.ts +7 -0
- package/src/memory/schema/infrastructure.ts +25 -0
- package/src/memory/search/semantic.ts +5 -16
- package/src/memory/tool-usage-store.ts +2 -0
- package/src/memory/usage-buckets.ts +40 -1
- package/src/memory/usage-grouped-buckets.ts +127 -0
- package/src/memory/v2/__tests__/activation.test.ts +289 -90
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
- package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
- package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
- package/src/memory/v2/__tests__/injection.test.ts +384 -15
- package/src/memory/v2/__tests__/migration.test.ts +64 -36
- package/src/memory/v2/__tests__/page-store.test.ts +191 -8
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
- package/src/memory/v2/__tests__/static-context.test.ts +153 -0
- package/src/memory/v2/activation.ts +168 -97
- package/src/memory/v2/backfill-jobs.ts +15 -100
- package/src/memory/v2/consolidation-job.ts +14 -12
- package/src/memory/v2/edge-index.ts +191 -0
- package/src/memory/v2/injection.ts +182 -58
- package/src/memory/v2/migration.ts +57 -64
- package/src/memory/v2/now-text.ts +2 -3
- package/src/memory/v2/page-store.ts +168 -31
- package/src/memory/v2/prompts/consolidation.ts +118 -42
- package/src/memory/v2/prompts/sweep.ts +3 -3
- package/src/memory/v2/skill-store.ts +55 -7
- package/src/memory/v2/static-context.ts +62 -0
- package/src/memory/v2/types.ts +10 -20
- package/src/memory/validation.ts +0 -11
- package/src/messaging/draft-store.ts +0 -6
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/provider.ts +7 -0
- package/src/messaging/providers/gmail/client.ts +1 -121
- package/src/messaging/providers/outlook/client.ts +0 -73
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
- package/src/messaging/providers/slack/adapter.ts +122 -21
- package/src/messaging/providers/slack/backfill.test.ts +95 -6
- package/src/messaging/providers/slack/backfill.ts +89 -11
- package/src/messaging/providers/slack/client.ts +10 -124
- package/src/messaging/providers/slack/message-metadata.ts +12 -2
- package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
- package/src/messaging/providers/slack/render-transcript.ts +126 -25
- package/src/messaging/providers/slack/types.ts +1 -0
- package/src/oauth/connection-resolver.test.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -16
- package/src/oauth/credential-token-resolver.ts +97 -0
- package/src/oauth/manual-token-connection.ts +30 -34
- package/src/oauth/oauth-store.ts +6 -4
- package/src/outbound-proxy/certs.ts +0 -7
- package/src/outbound-proxy/config.ts +0 -74
- package/src/outbound-proxy/health.ts +0 -44
- package/src/outbound-proxy/index.ts +0 -22
- package/src/permissions/approval-provenance.test.ts +184 -0
- package/src/permissions/approval-provenance.ts +70 -0
- package/src/permissions/checker.ts +4 -1
- package/src/permissions/gateway-threshold-reader.ts +4 -1
- package/src/permissions/prompter.ts +9 -2
- package/src/permissions/secret-prompter.ts +21 -48
- package/src/permissions/types.ts +33 -0
- package/src/permissions/workspace-policy.ts +0 -5
- package/src/platform/sync-identity.ts +0 -8
- package/src/plugins/defaults/injectors.ts +69 -2
- package/src/plugins/defaults/overflow-reduce.ts +3 -2
- package/src/plugins/types.ts +8 -0
- package/src/prompts/system-prompt.ts +34 -70
- package/src/prompts/templates/BOOTSTRAP.md +52 -6
- package/src/prompts/update-bulletin-job.ts +2 -0
- package/src/providers/__tests__/retry-callsite.test.ts +138 -1
- package/src/providers/anthropic/client.ts +72 -33
- package/src/providers/call-site-routing.ts +42 -3
- package/src/providers/gemini/client.ts +18 -2
- package/src/providers/managed-proxy/context.ts +0 -5
- package/src/providers/model-catalog.ts +105 -19
- package/src/providers/openai/chat-completions-provider.ts +6 -0
- package/src/providers/openai/responses-provider.ts +7 -1
- package/src/providers/provider-send-message.ts +45 -2
- package/src/providers/ratelimit.ts +7 -2
- package/src/providers/registry.ts +14 -9
- package/src/providers/retry.ts +96 -8
- package/src/providers/types.ts +13 -0
- package/src/providers/usage-tracking.ts +96 -0
- package/src/runtime/AGENTS.md +10 -6
- package/src/runtime/__tests__/agent-wake.test.ts +89 -0
- package/src/runtime/agent-wake.ts +39 -2
- package/src/runtime/assistant-event-hub.ts +541 -45
- package/src/runtime/assistant-event.ts +1 -6
- package/src/runtime/auth/context.ts +0 -9
- package/src/runtime/auth/middleware.ts +1 -1
- package/src/runtime/auth/route-policy.ts +11 -9
- package/src/runtime/auth/token-service.ts +0 -11
- package/src/runtime/channel-approvals.ts +6 -2
- package/src/runtime/channel-verification-service.ts +3 -5
- package/src/runtime/http-errors.ts +0 -34
- package/src/runtime/http-router.ts +6 -3
- package/src/runtime/http-server.ts +22 -82
- package/src/runtime/http-types.ts +5 -0
- package/src/runtime/interactive-ui.ts +0 -1
- package/src/runtime/middleware/auth.ts +0 -20
- package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
- package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
- package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
- package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
- package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
- package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
- package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
- package/src/runtime/migrations/migration-transport.ts +46 -13
- package/src/runtime/migrations/migration-wizard.ts +2 -2
- package/src/runtime/migrations/origin-mode.ts +40 -0
- package/src/runtime/migrations/vbundle-builder.ts +133 -79
- package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
- package/src/runtime/migrations/vbundle-importer.ts +7 -7
- package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
- package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
- package/src/runtime/migrations/vbundle-validator.ts +214 -41
- package/src/runtime/pending-interactions.ts +13 -4
- package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
- package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
- package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
- package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
- package/src/runtime/routes/acp-routes.test.ts +0 -3
- package/src/runtime/routes/acp-routes.ts +3 -7
- package/src/runtime/routes/app-management-routes.ts +18 -9
- package/src/runtime/routes/approval-routes.ts +55 -14
- package/src/runtime/routes/avatar-routes.ts +3 -5
- package/src/runtime/routes/browser-routes.ts +1 -15
- package/src/runtime/routes/channel-guardian-routes.ts +1 -5
- package/src/runtime/routes/channel-readiness-routes.ts +3 -7
- package/src/runtime/routes/channel-route-shared.ts +2 -28
- package/src/runtime/routes/client-routes.ts +45 -12
- package/src/runtime/routes/consolidation-routes.ts +115 -0
- package/src/runtime/routes/conversation-list-routes.ts +12 -29
- package/src/runtime/routes/conversation-management-routes.ts +14 -51
- package/src/runtime/routes/conversation-query-routes.ts +120 -8
- package/src/runtime/routes/conversation-routes.ts +44 -528
- package/src/runtime/routes/conversation-starter-routes.ts +19 -40
- package/src/runtime/routes/documents-routes.ts +53 -18
- package/src/runtime/routes/events-routes.ts +59 -91
- package/src/runtime/routes/filing-routes.ts +18 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -9
- package/src/runtime/routes/host-bash-routes.ts +3 -2
- package/src/runtime/routes/host-browser-routes.ts +9 -33
- package/src/runtime/routes/host-cu-routes.ts +6 -1
- package/src/runtime/routes/host-file-routes.ts +3 -2
- package/src/runtime/routes/host-transfer-routes.ts +11 -15
- package/src/runtime/routes/identity-routes.ts +78 -6
- package/src/runtime/routes/inbound-message-handler.ts +580 -137
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
- package/src/runtime/routes/index.ts +4 -0
- package/src/runtime/routes/integrations/slack/channel.ts +0 -24
- package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
- package/src/runtime/routes/memory-v2-routes.ts +10 -15
- package/src/runtime/routes/migration-routes.ts +188 -31
- package/src/runtime/routes/playground/guard.ts +1 -1
- package/src/runtime/routes/playground/index.ts +0 -2
- package/src/runtime/routes/recording-routes.ts +4 -24
- package/src/runtime/routes/rename-conversation-routes.ts +2 -6
- package/src/runtime/routes/schedule-routes.ts +3 -6
- package/src/runtime/routes/secret-routes.ts +87 -18
- package/src/runtime/routes/settings-routes.ts +29 -28
- package/src/runtime/routes/skills-routes.ts +12 -31
- package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
- package/src/runtime/routes/task-routes.ts +6 -6
- package/src/runtime/routes/trust-rules-routes.ts +3 -94
- package/src/runtime/routes/types.ts +4 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
- package/src/runtime/routes/usage-routes.ts +87 -10
- package/src/runtime/routes/user-routes.ts +17 -31
- package/src/runtime/routes/work-items-routes.ts +1 -4
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
- package/src/runtime/services/analyze-conversation.ts +7 -17
- package/src/runtime/services/conversation-serializer.ts +2 -4
- package/src/runtime/verification-outbound-actions.ts +1 -1
- package/src/runtime/verification-rate-limiter.ts +1 -1
- package/src/schedule/schedule-store.ts +0 -16
- package/src/security/secret-scanner.ts +14 -547
- package/src/security/secure-keys.ts +31 -11
- package/src/security/token-manager.ts +7 -3
- package/src/signals/cancel.ts +16 -25
- package/src/signals/conversation-undo.ts +2 -27
- package/src/signals/emit-event.ts +1 -2
- package/src/signals/user-message.ts +108 -22
- package/src/skills/catalog-install.ts +1 -0
- package/src/skills/clawhub.ts +2 -2
- package/src/skills/inline-command-runner.ts +1 -7
- package/src/subagent/manager.ts +67 -84
- package/src/tasks/task-store.ts +1 -28
- package/src/telemetry/types.ts +6 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
- package/src/telemetry/usage-telemetry-reporter.ts +3 -5
- package/src/tools/acp/spawn.test.ts +1 -2
- package/src/tools/acp/steer.test.ts +1 -2
- package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
- package/src/tools/browser/browser-execution.ts +31 -147
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
- package/src/tools/browser/cdp-client/factory.ts +48 -76
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/executor.ts +44 -31
- package/src/tools/host-filesystem/edit.ts +3 -2
- package/src/tools/host-filesystem/read.ts +3 -2
- package/src/tools/host-filesystem/transfer.test.ts +45 -42
- package/src/tools/host-filesystem/transfer.ts +4 -3
- package/src/tools/host-filesystem/write.ts +3 -2
- package/src/tools/host-terminal/host-shell.ts +4 -3
- package/src/tools/network/script-proxy/index.ts +1 -10
- package/src/tools/permission-checker.ts +66 -1
- package/src/tools/skills/sandbox-runner.ts +1 -6
- package/src/tools/skills/skill-tool-factory.ts +32 -0
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/terminal/shell.ts +2 -78
- package/src/tools/types.ts +12 -39
- package/src/tts/__tests__/provider-catalog.test.ts +2 -2
- package/src/tts/provider-catalog.ts +1 -1
- package/src/usage/actors.ts +2 -1
- package/src/usage/attribution.ts +185 -0
- package/src/usage/pricing.ts +166 -0
- package/src/usage/types.ts +14 -0
- package/src/util/json.ts +13 -0
- package/src/util/logger.ts +3 -3
- package/src/util/pricing.ts +50 -3
- package/src/work-items/work-item-runner.ts +15 -42
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
- package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
- package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
- package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
- package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
- package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/provider-commit-message-generator.ts +3 -3
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
- package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
- package/src/__tests__/secret-detection-handler.test.ts +0 -67
- package/src/__tests__/secret-scanner-executor.test.ts +0 -450
- package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
- package/src/__tests__/terminal-sandbox.test.ts +0 -374
- package/src/__tests__/tool-notification-listener.test.ts +0 -65
- package/src/context/__tests__/microcompact.test.ts +0 -805
- package/src/context/microcompact.ts +0 -443
- package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
- package/src/events/tool-notification-listener.ts +0 -17
- package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
- package/src/memory/v2/__tests__/edges.test.ts +0 -435
- package/src/memory/v2/edges.ts +0 -217
- package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
- package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
- package/src/runtime/__tests__/client-registry.test.ts +0 -271
- package/src/runtime/chrome-extension-registry.ts +0 -368
- package/src/runtime/client-registry.ts +0 -254
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
- package/src/tools/secret-detection-handler.ts +0 -269
- package/src/tools/terminal/backends/native.ts +0 -327
- package/src/tools/terminal/backends/types.ts +0 -37
- package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
- package/src/tools/terminal/sandbox.ts +0 -40
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for macOS TCC-protected directory deny rules in the sandbox profile.
|
|
3
|
-
*
|
|
4
|
-
* Verifies that the SBPL sandbox profile blocks access to TCC-protected
|
|
5
|
-
* directories (Photos, Contacts, Calendar, etc.) to prevent macOS
|
|
6
|
-
* permission prompts during filesystem traversal.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
10
|
-
import { join } from "node:path";
|
|
11
|
-
import { afterAll, describe, expect, test } from "bun:test";
|
|
12
|
-
|
|
13
|
-
import { MACOS_TCC_PROTECTED_PATHS } from "../tools/terminal/backends/native.js";
|
|
14
|
-
|
|
15
|
-
// We can't call buildSandboxProfile directly (not exported), but we can
|
|
16
|
-
// exercise it through NativeBackend.wrap() on macOS and inspect the
|
|
17
|
-
// generated .sb profile file on disk.
|
|
18
|
-
|
|
19
|
-
const isMacOS = process.platform === "darwin";
|
|
20
|
-
|
|
21
|
-
describe("macOS TCC sandbox deny rules", () => {
|
|
22
|
-
// On macOS, generate a profile and inspect it. On other platforms,
|
|
23
|
-
// just verify the constant is well-formed.
|
|
24
|
-
|
|
25
|
-
test("MACOS_TCC_PROTECTED_PATHS is non-empty", () => {
|
|
26
|
-
expect(MACOS_TCC_PROTECTED_PATHS.length).toBeGreaterThan(0);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test("all paths are relative (no leading slash)", () => {
|
|
30
|
-
for (const p of MACOS_TCC_PROTECTED_PATHS) {
|
|
31
|
-
expect(p.startsWith("/")).toBe(false);
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("no duplicate paths", () => {
|
|
36
|
-
const unique = new Set(MACOS_TCC_PROTECTED_PATHS);
|
|
37
|
-
expect(unique.size).toBe(MACOS_TCC_PROTECTED_PATHS.length);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
if (isMacOS) {
|
|
41
|
-
const profilePaths: string[] = [];
|
|
42
|
-
|
|
43
|
-
// Generate a profile by calling NativeBackend.wrap()
|
|
44
|
-
test("generated SBPL profile contains deny rules for all TCC paths", async () => {
|
|
45
|
-
const { NativeBackend } =
|
|
46
|
-
await import("../tools/terminal/backends/native.js");
|
|
47
|
-
const backend = new NativeBackend();
|
|
48
|
-
const result = backend.wrap("true", "/tmp/tcc-test", {
|
|
49
|
-
networkMode: "off",
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// The profile path is the second arg after -f
|
|
53
|
-
const profilePath = result.args[1]!;
|
|
54
|
-
profilePaths.push(profilePath);
|
|
55
|
-
expect(existsSync(profilePath)).toBe(true);
|
|
56
|
-
|
|
57
|
-
const profile = readFileSync(profilePath, "utf-8");
|
|
58
|
-
const home = process.env.HOME ?? "";
|
|
59
|
-
expect(home.length).toBeGreaterThan(0);
|
|
60
|
-
|
|
61
|
-
for (const rel of MACOS_TCC_PROTECTED_PATHS) {
|
|
62
|
-
const abs = join(home, rel);
|
|
63
|
-
expect(profile).toContain(`(deny file-read* (subpath "${abs}")`);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("all TCC deny rules include (with no-log)", async () => {
|
|
68
|
-
const { NativeBackend } =
|
|
69
|
-
await import("../tools/terminal/backends/native.js");
|
|
70
|
-
const backend = new NativeBackend();
|
|
71
|
-
const result = backend.wrap("true", "/tmp/tcc-test-nolog", {
|
|
72
|
-
networkMode: "off",
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const profilePath = result.args[1]!;
|
|
76
|
-
profilePaths.push(profilePath);
|
|
77
|
-
const profile = readFileSync(profilePath, "utf-8");
|
|
78
|
-
const home = process.env.HOME ?? "";
|
|
79
|
-
|
|
80
|
-
for (const rel of MACOS_TCC_PROTECTED_PATHS) {
|
|
81
|
-
const abs = join(home, rel);
|
|
82
|
-
expect(profile).toContain(
|
|
83
|
-
`(deny file-read* (subpath "${abs}") (with no-log))`,
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
test("TCC deny rules appear after (allow file-read*)", async () => {
|
|
89
|
-
const { NativeBackend } =
|
|
90
|
-
await import("../tools/terminal/backends/native.js");
|
|
91
|
-
const backend = new NativeBackend();
|
|
92
|
-
const result = backend.wrap("true", "/tmp/tcc-test-order", {
|
|
93
|
-
networkMode: "off",
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const profilePath = result.args[1]!;
|
|
97
|
-
profilePaths.push(profilePath);
|
|
98
|
-
const profile = readFileSync(profilePath, "utf-8");
|
|
99
|
-
const home = process.env.HOME ?? "";
|
|
100
|
-
|
|
101
|
-
const allowIdx = profile.indexOf("(allow file-read*)");
|
|
102
|
-
expect(allowIdx).toBeGreaterThanOrEqual(0);
|
|
103
|
-
|
|
104
|
-
for (const rel of MACOS_TCC_PROTECTED_PATHS) {
|
|
105
|
-
const abs = join(home, rel);
|
|
106
|
-
const denyIdx = profile.indexOf(`(deny file-read* (subpath "${abs}")`);
|
|
107
|
-
expect(denyIdx).toBeGreaterThan(allowIdx);
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test("working directory under TCC path gets file-read re-allowed", async () => {
|
|
112
|
-
const { NativeBackend } =
|
|
113
|
-
await import("../tools/terminal/backends/native.js");
|
|
114
|
-
const backend = new NativeBackend();
|
|
115
|
-
const home = process.env.HOME ?? "";
|
|
116
|
-
const workDir = join(home, "Documents", "my-project");
|
|
117
|
-
const result = backend.wrap("true", workDir, {
|
|
118
|
-
networkMode: "off",
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
const profilePath = result.args[1]!;
|
|
122
|
-
profilePaths.push(profilePath);
|
|
123
|
-
const profile = readFileSync(profilePath, "utf-8");
|
|
124
|
-
|
|
125
|
-
// The deny rule for Documents should still be present
|
|
126
|
-
expect(profile).toContain(
|
|
127
|
-
`(deny file-read* (subpath "${join(home, "Documents")}") (with no-log))`,
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
// But the working directory should have a file-read allow AFTER the deny
|
|
131
|
-
const denyIdx = profile.indexOf(
|
|
132
|
-
`(deny file-read* (subpath "${join(home, "Documents")}")`,
|
|
133
|
-
);
|
|
134
|
-
const allowWorkDirIdx = profile.indexOf(
|
|
135
|
-
`(allow file-read* (subpath "${workDir}"))`,
|
|
136
|
-
);
|
|
137
|
-
expect(allowWorkDirIdx).toBeGreaterThan(denyIdx);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
test("CES deny-read rules override working-dir allow (credential isolation)", async () => {
|
|
141
|
-
const { NativeBackend } =
|
|
142
|
-
await import("../tools/terminal/backends/native.js");
|
|
143
|
-
const backend = new NativeBackend();
|
|
144
|
-
const home = process.env.HOME ?? "";
|
|
145
|
-
// Simulate a working directory that overlaps with a CES-protected path
|
|
146
|
-
const workDir = join(home, "Documents", "my-project");
|
|
147
|
-
const cesProtectedPath = join(workDir, ".credentials");
|
|
148
|
-
const result = backend.wrap("true", workDir, {
|
|
149
|
-
networkMode: "off",
|
|
150
|
-
denyReadPaths: [cesProtectedPath],
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
const profilePath = result.args[1]!;
|
|
154
|
-
profilePaths.push(profilePath);
|
|
155
|
-
const profile = readFileSync(profilePath, "utf-8");
|
|
156
|
-
|
|
157
|
-
// The working-dir allow should be present
|
|
158
|
-
const allowWorkDirIdx = profile.indexOf(
|
|
159
|
-
`(allow file-read* (subpath "${workDir}"))`,
|
|
160
|
-
);
|
|
161
|
-
expect(allowWorkDirIdx).toBeGreaterThanOrEqual(0);
|
|
162
|
-
|
|
163
|
-
// The CES deny rule should appear AFTER the working-dir allow
|
|
164
|
-
const cesDenyIdx = profile.indexOf(
|
|
165
|
-
`(deny file-read* (subpath "${cesProtectedPath}")`,
|
|
166
|
-
);
|
|
167
|
-
expect(cesDenyIdx).toBeGreaterThan(allowWorkDirIdx);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
test("paths with spaces are handled correctly", async () => {
|
|
171
|
-
const { NativeBackend } =
|
|
172
|
-
await import("../tools/terminal/backends/native.js");
|
|
173
|
-
const backend = new NativeBackend();
|
|
174
|
-
const result = backend.wrap("true", "/tmp/tcc-test-spaces", {
|
|
175
|
-
networkMode: "off",
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
const profilePath = result.args[1]!;
|
|
179
|
-
profilePaths.push(profilePath);
|
|
180
|
-
const profile = readFileSync(profilePath, "utf-8");
|
|
181
|
-
const home = process.env.HOME ?? "";
|
|
182
|
-
|
|
183
|
-
// Photos Library.photoslibrary has a space — verify it's in the profile
|
|
184
|
-
const photosPath = join(home, "Pictures/Photos Library.photoslibrary");
|
|
185
|
-
expect(profile).toContain(`(subpath "${photosPath}")`);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
afterAll(() => {
|
|
189
|
-
for (const p of profilePaths) {
|
|
190
|
-
try {
|
|
191
|
-
unlinkSync(p);
|
|
192
|
-
} catch {
|
|
193
|
-
// ignore cleanup errors
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
});
|
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
import * as realChildProcess from "node:child_process";
|
|
2
|
-
import * as realFs from "node:fs";
|
|
3
|
-
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
4
|
-
|
|
5
|
-
import type { SandboxConfig } from "../tools/terminal/sandbox.js";
|
|
6
|
-
|
|
7
|
-
let platform = "linux";
|
|
8
|
-
|
|
9
|
-
const execSyncMock = mock((_command: string): unknown => {
|
|
10
|
-
throw new Error("bwrap unavailable");
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
mock.module("../util/platform.js", () => ({
|
|
14
|
-
isMacOS: () => platform === "darwin",
|
|
15
|
-
isLinux: () => platform === "linux",
|
|
16
|
-
getSandboxWorkingDir: () => "/tmp/sandbox/fs",
|
|
17
|
-
}));
|
|
18
|
-
|
|
19
|
-
mock.module("../util/logger.js", () => ({
|
|
20
|
-
getLogger: () => ({
|
|
21
|
-
error: () => {},
|
|
22
|
-
warn: () => {},
|
|
23
|
-
info: () => {},
|
|
24
|
-
debug: () => {},
|
|
25
|
-
}),
|
|
26
|
-
}));
|
|
27
|
-
|
|
28
|
-
mock.module("node:child_process", () => ({
|
|
29
|
-
...realChildProcess,
|
|
30
|
-
execSync: execSyncMock,
|
|
31
|
-
}));
|
|
32
|
-
|
|
33
|
-
const writeFileSyncMock = mock((..._args: unknown[]) => {});
|
|
34
|
-
const existsSyncMock = mock((_path: string) => true);
|
|
35
|
-
const mkdirSyncMock = mock((..._args: unknown[]) => {});
|
|
36
|
-
|
|
37
|
-
mock.module("node:fs", () => ({
|
|
38
|
-
...realFs,
|
|
39
|
-
writeFileSync: writeFileSyncMock,
|
|
40
|
-
existsSync: existsSyncMock,
|
|
41
|
-
mkdirSync: mkdirSyncMock,
|
|
42
|
-
}));
|
|
43
|
-
|
|
44
|
-
const { wrapCommand } = await import("../tools/terminal/sandbox.js");
|
|
45
|
-
const { ToolError } = await import("../util/errors.js");
|
|
46
|
-
|
|
47
|
-
function disabledConfig(): SandboxConfig {
|
|
48
|
-
return { enabled: false };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function nativeConfig(): SandboxConfig {
|
|
52
|
-
return { enabled: true };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
describe("terminal sandbox — disabled behavior", () => {
|
|
56
|
-
beforeEach(() => {
|
|
57
|
-
platform = "linux";
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("returns unsandboxed bash -c wrapper when disabled", () => {
|
|
61
|
-
const result = wrapCommand("pwd", "/tmp", disabledConfig());
|
|
62
|
-
expect(result).toEqual({
|
|
63
|
-
command: "bash",
|
|
64
|
-
args: ["-c", "--", "pwd"],
|
|
65
|
-
sandboxed: false,
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test("sandboxed flag is false when disabled regardless of platform", () => {
|
|
70
|
-
for (const p of ["linux", "darwin", "win32"]) {
|
|
71
|
-
platform = p;
|
|
72
|
-
const result = wrapCommand("echo hi", "/tmp", disabledConfig());
|
|
73
|
-
expect(result.sandboxed).toBe(false);
|
|
74
|
-
expect(result.command).toBe("bash");
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test("preserves the original command string in args when disabled", () => {
|
|
79
|
-
const cmd = "cat /etc/passwd | wc -l";
|
|
80
|
-
const result = wrapCommand(cmd, "/home/user", disabledConfig());
|
|
81
|
-
expect(result.args).toEqual(["-c", "--", cmd]);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
describe("terminal sandbox — enabled fail-closed behavior", () => {
|
|
86
|
-
beforeEach(() => {
|
|
87
|
-
platform = "linux";
|
|
88
|
-
execSyncMock.mockImplementation((_command: string) => {
|
|
89
|
-
throw new Error("bwrap unavailable");
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test("throws ToolError when bwrap is unavailable on linux", () => {
|
|
94
|
-
expect(() => wrapCommand("echo hello", "/tmp", nativeConfig())).toThrow(
|
|
95
|
-
ToolError,
|
|
96
|
-
);
|
|
97
|
-
expect(() => wrapCommand("echo hello", "/tmp", nativeConfig())).toThrow(
|
|
98
|
-
"Sandbox is enabled but bwrap is not available or cannot create namespaces.",
|
|
99
|
-
);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test("returns bwrap wrapper when bwrap is available on linux", () => {
|
|
103
|
-
// GIVEN bwrap is available on a linux platform
|
|
104
|
-
execSyncMock.mockImplementation(() => undefined);
|
|
105
|
-
|
|
106
|
-
// WHEN wrapping a command with the native sandbox config
|
|
107
|
-
const result = wrapCommand(
|
|
108
|
-
"echo hello",
|
|
109
|
-
"/home/user/project",
|
|
110
|
-
nativeConfig(),
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
// THEN the result uses bwrap with network isolation
|
|
114
|
-
expect(result.command).toBe("bwrap");
|
|
115
|
-
expect(result.sandboxed).toBe(true);
|
|
116
|
-
expect(result.args).toContain("--ro-bind");
|
|
117
|
-
expect(result.args).toContain("--unshare-net");
|
|
118
|
-
expect(result.args).toContain("--unshare-pid");
|
|
119
|
-
|
|
120
|
-
// AND the user command runs via bash inside the sandbox
|
|
121
|
-
const bashIdx = result.args.indexOf("bash");
|
|
122
|
-
expect(bashIdx).toBeGreaterThan(0);
|
|
123
|
-
expect(result.args.slice(bashIdx)).toEqual([
|
|
124
|
-
"bash",
|
|
125
|
-
"-c",
|
|
126
|
-
"--",
|
|
127
|
-
"echo hello",
|
|
128
|
-
]);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test("bind-mounts working directory read-write in bwrap args", () => {
|
|
132
|
-
execSyncMock.mockImplementation(() => undefined);
|
|
133
|
-
const workDir = "/home/user/my-project";
|
|
134
|
-
const result = wrapCommand("ls", workDir, nativeConfig());
|
|
135
|
-
// The args should contain --bind workDir workDir for read-write access
|
|
136
|
-
const bindIdx = result.args.indexOf("--bind");
|
|
137
|
-
expect(bindIdx).toBeGreaterThan(-1);
|
|
138
|
-
expect(result.args[bindIdx + 1]).toBe(workDir);
|
|
139
|
-
expect(result.args[bindIdx + 2]).toBe(workDir);
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
describe("terminal sandbox — unsupported platform fail-closed behavior", () => {
|
|
144
|
-
test("throws ToolError on unsupported platforms when enabled", () => {
|
|
145
|
-
platform = "win32";
|
|
146
|
-
expect(() => wrapCommand("pwd", "/tmp", nativeConfig())).toThrow(ToolError);
|
|
147
|
-
expect(() => wrapCommand("pwd", "/tmp", nativeConfig())).toThrow(
|
|
148
|
-
"Sandbox is enabled but not supported on this platform (",
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
test("error message includes refusing to execute unsandboxed", () => {
|
|
153
|
-
platform = "win32";
|
|
154
|
-
try {
|
|
155
|
-
wrapCommand("pwd", "/tmp", nativeConfig());
|
|
156
|
-
throw new Error("should have thrown");
|
|
157
|
-
} catch (err) {
|
|
158
|
-
expect(err).toBeInstanceOf(ToolError);
|
|
159
|
-
expect((err as Error).message).toContain(
|
|
160
|
-
"Refusing to execute unsandboxed",
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe("terminal sandbox — macOS sandbox-exec behavior", () => {
|
|
167
|
-
beforeEach(() => {
|
|
168
|
-
platform = "darwin";
|
|
169
|
-
writeFileSyncMock.mockClear();
|
|
170
|
-
existsSyncMock.mockImplementation(() => true);
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
test("returns sandbox-exec wrapper on macOS when enabled", () => {
|
|
174
|
-
// GIVEN the platform is macOS
|
|
175
|
-
// (set in beforeEach)
|
|
176
|
-
|
|
177
|
-
// WHEN wrapping a command with the native sandbox config
|
|
178
|
-
const result = wrapCommand("echo hello", "/tmp/project", nativeConfig());
|
|
179
|
-
|
|
180
|
-
// THEN the result uses sandbox-exec
|
|
181
|
-
expect(result.command).toBe("sandbox-exec");
|
|
182
|
-
expect(result.sandboxed).toBe(true);
|
|
183
|
-
expect(result.args[0]).toBe("-f");
|
|
184
|
-
|
|
185
|
-
// AND the profile path is the second arg
|
|
186
|
-
expect(result.args[1]).toContain("sandbox-profile-");
|
|
187
|
-
|
|
188
|
-
// AND bash -c -- command follows the profile
|
|
189
|
-
expect(result.args.slice(2)).toEqual(["bash", "-c", "--", "echo hello"]);
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
test("escapes SBPL metacharacters in working dirs instead of throwing", () => {
|
|
193
|
-
// The sandbox now escapes metacharacters rather than rejecting them
|
|
194
|
-
const result1 = wrapCommand("pwd", '/tmp/bad"dir', nativeConfig());
|
|
195
|
-
expect(result1.sandboxed).toBe(true);
|
|
196
|
-
const result2 = wrapCommand("pwd", "/tmp/bad(dir", nativeConfig());
|
|
197
|
-
expect(result2.sandboxed).toBe(true);
|
|
198
|
-
const result3 = wrapCommand("pwd", "/tmp/bad;dir", nativeConfig());
|
|
199
|
-
expect(result3.sandboxed).toBe(true);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
test("SBPL profile escapes metacharacters in working dir path", () => {
|
|
203
|
-
// Verify the sandbox profile is written with escaped chars
|
|
204
|
-
wrapCommand("pwd", '/tmp/bad"dir', nativeConfig());
|
|
205
|
-
const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
|
|
206
|
-
expect(profileContent).toContain('bad\\"dir');
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
test("SBPL profile allows writes to /dev/null", () => {
|
|
210
|
-
wrapCommand("git status", "/tmp/project", nativeConfig());
|
|
211
|
-
const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
|
|
212
|
-
expect(profileContent).toContain('(literal "/dev/null")');
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
describe("terminal sandbox — backend selection", () => {
|
|
217
|
-
beforeEach(() => {
|
|
218
|
-
platform = "darwin";
|
|
219
|
-
writeFileSyncMock.mockClear();
|
|
220
|
-
existsSyncMock.mockImplementation(() => true);
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
test('uses native backend when backend is "native"', () => {
|
|
224
|
-
const result = wrapCommand("echo hello", "/tmp/project", nativeConfig());
|
|
225
|
-
expect(result.command).toBe("sandbox-exec");
|
|
226
|
-
expect(result.sandboxed).toBe(true);
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
test("disabled config returns unsandboxed wrapper", () => {
|
|
230
|
-
const config: SandboxConfig = { enabled: false };
|
|
231
|
-
const result = wrapCommand("echo hello", "/tmp/project", config);
|
|
232
|
-
expect(result.command).toBe("bash");
|
|
233
|
-
expect(result.sandboxed).toBe(false);
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
describe("terminal sandbox — proxied network mode on Linux", () => {
|
|
238
|
-
beforeEach(() => {
|
|
239
|
-
platform = "linux";
|
|
240
|
-
execSyncMock.mockImplementation(() => undefined);
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
test("omits --unshare-net when networkMode is proxied", () => {
|
|
244
|
-
/**
|
|
245
|
-
* Tests that bwrap args omit --unshare-net in proxied mode so the process
|
|
246
|
-
* can reach the local credential proxy on 127.0.0.1.
|
|
247
|
-
*/
|
|
248
|
-
|
|
249
|
-
// GIVEN bwrap is available on linux
|
|
250
|
-
// (set in beforeEach)
|
|
251
|
-
|
|
252
|
-
// WHEN wrapping a command with proxied network mode
|
|
253
|
-
const result = wrapCommand(
|
|
254
|
-
"curl https://example.com",
|
|
255
|
-
"/home/user/project",
|
|
256
|
-
nativeConfig(),
|
|
257
|
-
{ networkMode: "proxied" },
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
// THEN the result uses bwrap
|
|
261
|
-
expect(result.command).toBe("bwrap");
|
|
262
|
-
expect(result.sandboxed).toBe(true);
|
|
263
|
-
|
|
264
|
-
// AND --unshare-net is NOT present (network is allowed)
|
|
265
|
-
expect(result.args).not.toContain("--unshare-net");
|
|
266
|
-
|
|
267
|
-
// AND --unshare-pid is still present (PID isolation remains)
|
|
268
|
-
expect(result.args).toContain("--unshare-pid");
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
test("includes --unshare-net when networkMode is off", () => {
|
|
272
|
-
/**
|
|
273
|
-
* Tests that bwrap args include --unshare-net when network is off (default).
|
|
274
|
-
*/
|
|
275
|
-
|
|
276
|
-
// GIVEN bwrap is available on linux
|
|
277
|
-
// (set in beforeEach)
|
|
278
|
-
|
|
279
|
-
// WHEN wrapping a command with network mode off
|
|
280
|
-
const result = wrapCommand(
|
|
281
|
-
"echo hello",
|
|
282
|
-
"/home/user/project",
|
|
283
|
-
nativeConfig(),
|
|
284
|
-
{ networkMode: "off" },
|
|
285
|
-
);
|
|
286
|
-
|
|
287
|
-
// THEN --unshare-net is present (network is blocked)
|
|
288
|
-
expect(result.args).toContain("--unshare-net");
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
test("includes --unshare-net when no options are provided", () => {
|
|
292
|
-
/**
|
|
293
|
-
* Tests that the default behavior (no options) blocks network access.
|
|
294
|
-
*/
|
|
295
|
-
|
|
296
|
-
// GIVEN bwrap is available on linux
|
|
297
|
-
// (set in beforeEach)
|
|
298
|
-
|
|
299
|
-
// WHEN wrapping a command without any options
|
|
300
|
-
const result = wrapCommand(
|
|
301
|
-
"echo hello",
|
|
302
|
-
"/home/user/project",
|
|
303
|
-
nativeConfig(),
|
|
304
|
-
);
|
|
305
|
-
|
|
306
|
-
// THEN --unshare-net is present (network is blocked by default)
|
|
307
|
-
expect(result.args).toContain("--unshare-net");
|
|
308
|
-
});
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
describe("terminal sandbox — proxied network mode on macOS", () => {
|
|
312
|
-
beforeEach(() => {
|
|
313
|
-
platform = "darwin";
|
|
314
|
-
writeFileSyncMock.mockClear();
|
|
315
|
-
existsSyncMock.mockImplementation(() => true);
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
test("writes SBPL profile with allow network when networkMode is proxied", () => {
|
|
319
|
-
/**
|
|
320
|
-
* Tests that the macOS sandbox profile allows network access in proxied mode
|
|
321
|
-
* so the process can reach the local credential proxy.
|
|
322
|
-
*/
|
|
323
|
-
|
|
324
|
-
// GIVEN the platform is macOS
|
|
325
|
-
// (set in beforeEach)
|
|
326
|
-
|
|
327
|
-
// WHEN wrapping a command with proxied network mode
|
|
328
|
-
wrapCommand("curl https://example.com", "/tmp/project", nativeConfig(), {
|
|
329
|
-
networkMode: "proxied",
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
// THEN the written profile contains (allow network*) instead of (deny network*)
|
|
333
|
-
const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
|
|
334
|
-
expect(profileContent).toContain("(allow network*)");
|
|
335
|
-
expect(profileContent).not.toContain("(deny network*)");
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
test("writes SBPL profile with deny network when networkMode is off", () => {
|
|
339
|
-
/**
|
|
340
|
-
* Tests that the macOS sandbox profile blocks network access when network
|
|
341
|
-
* mode is off (the default behavior).
|
|
342
|
-
*/
|
|
343
|
-
|
|
344
|
-
// GIVEN the platform is macOS
|
|
345
|
-
// (set in beforeEach)
|
|
346
|
-
|
|
347
|
-
// WHEN wrapping a command with network mode off
|
|
348
|
-
wrapCommand("echo hello", "/tmp/project", nativeConfig(), {
|
|
349
|
-
networkMode: "off",
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
// THEN the written profile contains (deny network*)
|
|
353
|
-
const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
|
|
354
|
-
expect(profileContent).toContain("(deny network*)");
|
|
355
|
-
expect(profileContent).not.toContain("(allow network*)");
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
test("writes SBPL profile with deny network when no options are provided", () => {
|
|
359
|
-
/**
|
|
360
|
-
* Tests that the default behavior (no options) blocks network access on macOS.
|
|
361
|
-
*/
|
|
362
|
-
|
|
363
|
-
// GIVEN the platform is macOS
|
|
364
|
-
// (set in beforeEach)
|
|
365
|
-
|
|
366
|
-
// WHEN wrapping a command without any options
|
|
367
|
-
wrapCommand("echo hello", "/tmp/project", nativeConfig());
|
|
368
|
-
|
|
369
|
-
// THEN the written profile contains (deny network*)
|
|
370
|
-
const profileContent = writeFileSyncMock.mock.calls[0]?.[1] as string;
|
|
371
|
-
expect(profileContent).toContain("(deny network*)");
|
|
372
|
-
expect(profileContent).not.toContain("(allow network*)");
|
|
373
|
-
});
|
|
374
|
-
});
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
|
|
3
|
-
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
4
|
-
import { EventBus } from "../events/bus.js";
|
|
5
|
-
import type { AssistantDomainEvents } from "../events/domain-events.js";
|
|
6
|
-
import { registerToolNotificationListener } from "../events/tool-notification-listener.js";
|
|
7
|
-
|
|
8
|
-
describe("registerToolNotificationListener", () => {
|
|
9
|
-
test("forwards tool.secret.detected events to secret_detected messages", async () => {
|
|
10
|
-
const bus = new EventBus<AssistantDomainEvents>();
|
|
11
|
-
const messages: ServerMessage[] = [];
|
|
12
|
-
registerToolNotificationListener(bus, (msg) => messages.push(msg));
|
|
13
|
-
|
|
14
|
-
await bus.emit("tool.secret.detected", {
|
|
15
|
-
conversationId: "conversation-1",
|
|
16
|
-
toolName: "file_read",
|
|
17
|
-
action: "warn",
|
|
18
|
-
matches: [
|
|
19
|
-
{
|
|
20
|
-
type: "AWS Access Key",
|
|
21
|
-
redactedValue: '<redacted type="AWS Access Key" />',
|
|
22
|
-
},
|
|
23
|
-
],
|
|
24
|
-
detectedAtMs: 123,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
expect(messages).toEqual([
|
|
28
|
-
{
|
|
29
|
-
type: "secret_detected",
|
|
30
|
-
toolName: "file_read",
|
|
31
|
-
action: "warn",
|
|
32
|
-
matches: [
|
|
33
|
-
{
|
|
34
|
-
type: "AWS Access Key",
|
|
35
|
-
redactedValue: '<redacted type="AWS Access Key" />',
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
]);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("stops forwarding after subscription is disposed", async () => {
|
|
43
|
-
const bus = new EventBus<AssistantDomainEvents>();
|
|
44
|
-
const messages: ServerMessage[] = [];
|
|
45
|
-
const subscription = registerToolNotificationListener(bus, (msg) =>
|
|
46
|
-
messages.push(msg),
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
subscription.dispose();
|
|
50
|
-
await bus.emit("tool.secret.detected", {
|
|
51
|
-
conversationId: "conversation-1",
|
|
52
|
-
toolName: "file_read",
|
|
53
|
-
action: "warn",
|
|
54
|
-
matches: [
|
|
55
|
-
{
|
|
56
|
-
type: "AWS Access Key",
|
|
57
|
-
redactedValue: '<redacted type="AWS Access Key" />',
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
detectedAtMs: 123,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
expect(messages).toHaveLength(0);
|
|
64
|
-
});
|
|
65
|
-
});
|