@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
|
@@ -10,7 +10,6 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
10
10
|
|
|
11
11
|
mock.module("../config/env.js", () => ({ isHttpAuthDisabled: () => true }));
|
|
12
12
|
|
|
13
|
-
import { createGuardianBinding } from "../contacts/contacts-write.js";
|
|
14
13
|
import type { Conversation } from "../daemon/conversation.js";
|
|
15
14
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
16
15
|
import {
|
|
@@ -21,6 +20,7 @@ import {
|
|
|
21
20
|
getConversationByKey,
|
|
22
21
|
getOrCreateConversation,
|
|
23
22
|
} from "../memory/conversation-key-store.js";
|
|
23
|
+
import { createGuardianBinding } from "./helpers/create-guardian-binding.js";
|
|
24
24
|
|
|
25
25
|
mock.module("../util/logger.js", () => ({
|
|
26
26
|
getLogger: () =>
|
|
@@ -92,6 +92,10 @@ let _conversationFactory: (() => Conversation) | undefined;
|
|
|
92
92
|
let _approvalGenerator: unknown;
|
|
93
93
|
|
|
94
94
|
mock.module("../daemon/conversation-store.js", () => ({
|
|
95
|
+
findConversation: () => {
|
|
96
|
+
if (!_conversationFactory) return undefined;
|
|
97
|
+
return _conversationFactory();
|
|
98
|
+
},
|
|
95
99
|
getOrCreateConversation: async (..._args: unknown[]) => {
|
|
96
100
|
if (!_conversationFactory)
|
|
97
101
|
throw new Error("_conversationFactory not set in test");
|
|
@@ -154,11 +158,7 @@ function makeCompletingConversation(): Conversation {
|
|
|
154
158
|
ensureActorScopedHistory: async () => {},
|
|
155
159
|
usageStats: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
|
|
156
160
|
updateClient: () => {},
|
|
157
|
-
setHostBashProxy: () => {},
|
|
158
161
|
setHostBrowserProxy: () => {},
|
|
159
|
-
setHostFileProxy: () => {},
|
|
160
|
-
setHostTransferProxy: () => {},
|
|
161
|
-
getHostTransferProxy: () => undefined,
|
|
162
162
|
setHostCuProxy: () => {},
|
|
163
163
|
addPreactivatedSkillId: () => {},
|
|
164
164
|
hasAnyPendingConfirmation: () => false,
|
|
@@ -214,11 +214,7 @@ function makeHangingConversation(): Conversation {
|
|
|
214
214
|
ensureActorScopedHistory: async () => {},
|
|
215
215
|
usageStats: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
|
|
216
216
|
updateClient: () => {},
|
|
217
|
-
setHostBashProxy: () => {},
|
|
218
217
|
setHostBrowserProxy: () => {},
|
|
219
|
-
setHostFileProxy: () => {},
|
|
220
|
-
setHostTransferProxy: () => {},
|
|
221
|
-
getHostTransferProxy: () => undefined,
|
|
222
218
|
setHostCuProxy: () => {},
|
|
223
219
|
addPreactivatedSkillId: () => {},
|
|
224
220
|
hasAnyPendingConfirmation: () => false,
|
|
@@ -302,11 +298,7 @@ function makePendingApprovalConversation(
|
|
|
302
298
|
ensureActorScopedHistory: async () => {},
|
|
303
299
|
usageStats: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
|
|
304
300
|
updateClient: () => {},
|
|
305
|
-
setHostBashProxy: () => {},
|
|
306
301
|
setHostBrowserProxy: () => {},
|
|
307
|
-
setHostFileProxy: () => {},
|
|
308
|
-
setHostTransferProxy: () => {},
|
|
309
|
-
getHostTransferProxy: () => undefined,
|
|
310
302
|
setHostCuProxy: () => {},
|
|
311
303
|
addPreactivatedSkillId: () => {},
|
|
312
304
|
hasAnyPendingConfirmation: () => pending.size > 0,
|
|
@@ -425,12 +417,12 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
425
417
|
// Subscribe on the module-level singleton that the route handler publishes to
|
|
426
418
|
const { assistantEventHub: routeEventHub } =
|
|
427
419
|
await import("../runtime/assistant-event-hub.js");
|
|
428
|
-
routeEventHub.subscribe(
|
|
429
|
-
|
|
430
|
-
(event: AssistantEvent) => {
|
|
420
|
+
routeEventHub.subscribe({
|
|
421
|
+
type: "process",
|
|
422
|
+
callback: (event: AssistantEvent) => {
|
|
431
423
|
publishedEvents.push(event);
|
|
432
424
|
},
|
|
433
|
-
);
|
|
425
|
+
});
|
|
434
426
|
|
|
435
427
|
const res = await fetch(messagesUrl(), {
|
|
436
428
|
method: "POST",
|
|
@@ -468,7 +460,6 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
468
460
|
} = makePendingApprovalConversation(requestId, false);
|
|
469
461
|
|
|
470
462
|
pendingInteractions.register(requestId, {
|
|
471
|
-
conversation,
|
|
472
463
|
conversationId,
|
|
473
464
|
kind: "confirmation",
|
|
474
465
|
});
|
|
@@ -528,7 +519,6 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
528
519
|
} = makePendingApprovalConversation(requestId, false);
|
|
529
520
|
|
|
530
521
|
pendingInteractions.register(requestId, {
|
|
531
|
-
conversation,
|
|
532
522
|
conversationId,
|
|
533
523
|
kind: "confirmation",
|
|
534
524
|
});
|
|
@@ -596,7 +586,6 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
596
586
|
} = makePendingApprovalConversation(requestId, true);
|
|
597
587
|
|
|
598
588
|
pendingInteractions.register(requestId, {
|
|
599
|
-
conversation,
|
|
600
589
|
conversationId,
|
|
601
590
|
kind: "confirmation",
|
|
602
591
|
});
|
|
@@ -656,7 +645,6 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
656
645
|
} = makePendingApprovalConversation(requestId, true, { queueDepth: 2 });
|
|
657
646
|
|
|
658
647
|
pendingInteractions.register(requestId, {
|
|
659
|
-
conversation,
|
|
660
648
|
conversationId,
|
|
661
649
|
kind: "confirmation",
|
|
662
650
|
});
|
|
@@ -716,7 +704,6 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
716
704
|
} = makePendingApprovalConversation(requestId, false);
|
|
717
705
|
|
|
718
706
|
pendingInteractions.register(requestId, {
|
|
719
|
-
conversation,
|
|
720
707
|
conversationId,
|
|
721
708
|
kind: "confirmation",
|
|
722
709
|
});
|
|
@@ -774,7 +761,6 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
774
761
|
);
|
|
775
762
|
|
|
776
763
|
pendingInteractions.register(requestId, {
|
|
777
|
-
conversation,
|
|
778
764
|
conversationId,
|
|
779
765
|
kind: "confirmation",
|
|
780
766
|
});
|
|
@@ -969,7 +955,6 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
969
955
|
makePendingApprovalConversation(requestId, false);
|
|
970
956
|
|
|
971
957
|
pendingInteractions.register(requestId, {
|
|
972
|
-
conversation,
|
|
973
958
|
conversationId,
|
|
974
959
|
kind: "confirmation",
|
|
975
960
|
});
|
|
@@ -17,12 +17,12 @@ mock.module("../util/logger.js", () => ({
|
|
|
17
17
|
}),
|
|
18
18
|
}));
|
|
19
19
|
|
|
20
|
-
import { createGuardianBinding } from "../contacts/contacts-write.js";
|
|
21
20
|
import { getSqlite } from "../memory/db-connection.js";
|
|
22
21
|
import { initializeDb } from "../memory/db-init.js";
|
|
23
22
|
import { BadRequestError, NotFoundError } from "../runtime/routes/errors.js";
|
|
24
23
|
import { ROUTES } from "../runtime/routes/settings-routes.js";
|
|
25
24
|
import type { RouteHandlerArgs } from "../runtime/routes/types.js";
|
|
25
|
+
import { createGuardianBinding } from "./helpers/create-guardian-binding.js";
|
|
26
26
|
|
|
27
27
|
initializeDb();
|
|
28
28
|
|
|
@@ -32,14 +32,6 @@ mock.module("../security/secret-scanner.js", () => ({
|
|
|
32
32
|
redactSecrets: (s: string) => s,
|
|
33
33
|
}));
|
|
34
34
|
|
|
35
|
-
// Mock sandbox
|
|
36
|
-
mock.module("../tools/terminal/sandbox.js", () => ({
|
|
37
|
-
wrapCommand: (cmd: string, _cwd: string) => ({
|
|
38
|
-
command: "/bin/sh",
|
|
39
|
-
args: ["-c", cmd],
|
|
40
|
-
}),
|
|
41
|
-
}));
|
|
42
|
-
|
|
43
35
|
// Mock safe-env
|
|
44
36
|
mock.module("../tools/terminal/safe-env.js", () => ({
|
|
45
37
|
buildSanitizedEnv: () => ({ PATH: "/usr/bin" }),
|
|
@@ -37,8 +37,6 @@ const mockConfig = {
|
|
|
37
37
|
rateLimit: { maxRequestsPerMinute: 0 },
|
|
38
38
|
secretDetection: {
|
|
39
39
|
enabled: true,
|
|
40
|
-
action: "warn" as const,
|
|
41
|
-
entropyThreshold: 4.0,
|
|
42
40
|
},
|
|
43
41
|
auditLog: { retentionDays: 0 },
|
|
44
42
|
};
|
|
@@ -65,26 +63,6 @@ mock.module("../security/secret-scanner.js", () => ({
|
|
|
65
63
|
redactSecrets: (s: string) => s,
|
|
66
64
|
}));
|
|
67
65
|
|
|
68
|
-
// Track wrapCommand calls to verify networkMode is forwarded
|
|
69
|
-
let wrapCommandCalls: {
|
|
70
|
-
cmd: string;
|
|
71
|
-
workingDir: string;
|
|
72
|
-
config: unknown;
|
|
73
|
-
options: unknown;
|
|
74
|
-
}[] = [];
|
|
75
|
-
|
|
76
|
-
mock.module("../tools/terminal/sandbox.js", () => ({
|
|
77
|
-
wrapCommand: (
|
|
78
|
-
cmd: string,
|
|
79
|
-
workingDir: string,
|
|
80
|
-
config: unknown,
|
|
81
|
-
options?: unknown,
|
|
82
|
-
) => {
|
|
83
|
-
wrapCommandCalls.push({ cmd, workingDir, config, options });
|
|
84
|
-
return { command: "/bin/sh", args: ["-c", cmd], sandboxed: false };
|
|
85
|
-
},
|
|
86
|
-
}));
|
|
87
|
-
|
|
88
66
|
// --- Proxy session mocks ---
|
|
89
67
|
let mockActiveSession: { id: string; conversationId: string } | undefined;
|
|
90
68
|
let getOrStartSessionCalls: {
|
|
@@ -181,7 +159,6 @@ function makeContext(overrides?: Partial<ToolContext>): ToolContext {
|
|
|
181
159
|
|
|
182
160
|
afterEach(() => {
|
|
183
161
|
spawnCalls.length = 0;
|
|
184
|
-
wrapCommandCalls = [];
|
|
185
162
|
getOrStartSessionCalls = [];
|
|
186
163
|
getSessionEnvCalls = [];
|
|
187
164
|
mockActiveSession = undefined;
|
|
@@ -303,37 +280,4 @@ describe("shell tool proxy mode", () => {
|
|
|
303
280
|
expect(props.network_mode).toBeDefined();
|
|
304
281
|
expect(props.credential_ids).toBeDefined();
|
|
305
282
|
});
|
|
306
|
-
|
|
307
|
-
test('wrapCommand receives { networkMode: "proxied" } when network_mode=proxied', async () => {
|
|
308
|
-
const result = await shellTool.execute(
|
|
309
|
-
{ command: "echo proxied-wrap", network_mode: "proxied" },
|
|
310
|
-
makeContext(),
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
expect(result.isError).toBe(false);
|
|
314
|
-
expect(wrapCommandCalls).toHaveLength(1);
|
|
315
|
-
expect(wrapCommandCalls[0].options).toEqual({ networkMode: "proxied" });
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
test('wrapCommand receives { networkMode: "off" } when network_mode is absent', async () => {
|
|
319
|
-
const result = await shellTool.execute(
|
|
320
|
-
{ command: "echo default-wrap" },
|
|
321
|
-
makeContext(),
|
|
322
|
-
);
|
|
323
|
-
|
|
324
|
-
expect(result.isError).toBe(false);
|
|
325
|
-
expect(wrapCommandCalls).toHaveLength(1);
|
|
326
|
-
expect(wrapCommandCalls[0].options).toEqual({ networkMode: "off" });
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
test('wrapCommand receives { networkMode: "off" } when network_mode=off', async () => {
|
|
330
|
-
const result = await shellTool.execute(
|
|
331
|
-
{ command: "echo off-wrap", network_mode: "off" },
|
|
332
|
-
makeContext(),
|
|
333
|
-
);
|
|
334
|
-
|
|
335
|
-
expect(result.isError).toBe(false);
|
|
336
|
-
expect(wrapCommandCalls).toHaveLength(1);
|
|
337
|
-
expect(wrapCommandCalls[0].options).toEqual({ networkMode: "off" });
|
|
338
|
-
});
|
|
339
283
|
});
|
|
@@ -20,8 +20,6 @@ const mockConfig = {
|
|
|
20
20
|
rateLimit: { maxRequestsPerMinute: 0 },
|
|
21
21
|
secretDetection: {
|
|
22
22
|
enabled: true,
|
|
23
|
-
action: "warn" as const,
|
|
24
|
-
entropyThreshold: 4.0,
|
|
25
23
|
},
|
|
26
24
|
auditLog: { retentionDays: 0 },
|
|
27
25
|
};
|
|
@@ -44,15 +42,6 @@ mock.module("../util/logger.js", () => ({
|
|
|
44
42
|
}),
|
|
45
43
|
}));
|
|
46
44
|
|
|
47
|
-
// Pass through without actual sandboxing so tests can run bun directly
|
|
48
|
-
mock.module("../tools/terminal/sandbox.js", () => ({
|
|
49
|
-
wrapCommand: (command: string, _workingDir: string, _config: unknown) => ({
|
|
50
|
-
command: "bash",
|
|
51
|
-
args: ["-c", "--", command],
|
|
52
|
-
sandboxed: false,
|
|
53
|
-
}),
|
|
54
|
-
}));
|
|
55
|
-
|
|
56
45
|
import { runSkillToolScript } from "../tools/skills/skill-script-runner.js";
|
|
57
46
|
import type { ToolContext } from "../tools/types.js";
|
|
58
47
|
|
|
@@ -269,6 +269,103 @@ describe("createSkillToolsFromManifest", () => {
|
|
|
269
269
|
});
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
+
// ---------------------------------------------------------------------------
|
|
273
|
+
// createSkillTool — unknown parameter validation
|
|
274
|
+
// ---------------------------------------------------------------------------
|
|
275
|
+
|
|
276
|
+
describe("createSkillTool — unknown parameter validation", () => {
|
|
277
|
+
test("rejects input with unknown parameters", async () => {
|
|
278
|
+
const hash = computeSkillVersionHash(tempDir);
|
|
279
|
+
const tool = createSkillTool(
|
|
280
|
+
makeEntry({ executor: "echo.ts" }),
|
|
281
|
+
"my-skill",
|
|
282
|
+
tempDir,
|
|
283
|
+
hash,
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const result = await tool.execute(
|
|
287
|
+
{ query: "hello", unsubscribe: true },
|
|
288
|
+
makeContext(),
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
expect(result.isError).toBe(true);
|
|
292
|
+
expect(result.content).toContain('Unknown parameter "unsubscribe"');
|
|
293
|
+
expect(result.content).toContain("Supported parameters");
|
|
294
|
+
expect(result.content).toContain('"query"');
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test("rejects multiple unknown parameters", async () => {
|
|
298
|
+
const hash = computeSkillVersionHash(tempDir);
|
|
299
|
+
const tool = createSkillTool(
|
|
300
|
+
makeEntry({ executor: "echo.ts" }),
|
|
301
|
+
"my-skill",
|
|
302
|
+
tempDir,
|
|
303
|
+
hash,
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
const result = await tool.execute(
|
|
307
|
+
{ query: "hello", foo: 1, bar: 2 },
|
|
308
|
+
makeContext(),
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
expect(result.isError).toBe(true);
|
|
312
|
+
expect(result.content).toContain("Unknown parameters");
|
|
313
|
+
expect(result.content).toContain('"foo"');
|
|
314
|
+
expect(result.content).toContain('"bar"');
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test("allows input with only known parameters", async () => {
|
|
318
|
+
const hash = computeSkillVersionHash(tempDir);
|
|
319
|
+
const tool = createSkillTool(
|
|
320
|
+
makeEntry({ executor: "echo.ts" }),
|
|
321
|
+
"my-skill",
|
|
322
|
+
tempDir,
|
|
323
|
+
hash,
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
const result = await tool.execute({ query: "hello" }, makeContext());
|
|
327
|
+
|
|
328
|
+
expect(result.isError).toBe(false);
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
test("allows empty input when schema has no required fields", async () => {
|
|
332
|
+
const hash = computeSkillVersionHash(tempDir);
|
|
333
|
+
const tool = createSkillTool(
|
|
334
|
+
makeEntry({
|
|
335
|
+
executor: "echo.ts",
|
|
336
|
+
input_schema: {
|
|
337
|
+
type: "object",
|
|
338
|
+
properties: { query: { type: "string" } },
|
|
339
|
+
},
|
|
340
|
+
}),
|
|
341
|
+
"my-skill",
|
|
342
|
+
tempDir,
|
|
343
|
+
hash,
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
const result = await tool.execute({}, makeContext());
|
|
347
|
+
|
|
348
|
+
expect(result.isError).toBe(false);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test("skips validation when schema has no properties", async () => {
|
|
352
|
+
const hash = computeSkillVersionHash(tempDir);
|
|
353
|
+
const tool = createSkillTool(
|
|
354
|
+
makeEntry({
|
|
355
|
+
executor: "echo.ts",
|
|
356
|
+
input_schema: { type: "object" },
|
|
357
|
+
}),
|
|
358
|
+
"my-skill",
|
|
359
|
+
tempDir,
|
|
360
|
+
hash,
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
const result = await tool.execute({ anything: "goes" }, makeContext());
|
|
364
|
+
|
|
365
|
+
expect(result.isError).toBe(false);
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
|
|
272
369
|
// ---------------------------------------------------------------------------
|
|
273
370
|
// createSkillTool — expectedSkillVersionHash plumbing
|
|
274
371
|
// ---------------------------------------------------------------------------
|
|
@@ -278,23 +278,11 @@ mock.module("../daemon/handlers/shared.js", () => ({
|
|
|
278
278
|
// Imports (after mocks)
|
|
279
279
|
// ---------------------------------------------------------------------------
|
|
280
280
|
|
|
281
|
-
import type { SkillOperationContext } from "../daemon/handlers/skills.js";
|
|
282
281
|
import {
|
|
283
282
|
_resetFileProvidersForTest,
|
|
284
283
|
getSkillFileContent,
|
|
285
284
|
} from "../daemon/handlers/skills.js";
|
|
286
285
|
|
|
287
|
-
// ---------------------------------------------------------------------------
|
|
288
|
-
// Helpers
|
|
289
|
-
// ---------------------------------------------------------------------------
|
|
290
|
-
|
|
291
|
-
const dummyCtx = {
|
|
292
|
-
debounceTimers: { schedule: () => {} },
|
|
293
|
-
setSuppressConfigReload: () => {},
|
|
294
|
-
updateConfigFingerprint: () => {},
|
|
295
|
-
broadcast: () => {},
|
|
296
|
-
} as unknown as SkillOperationContext;
|
|
297
|
-
|
|
298
286
|
type FetchFn = typeof globalThis.fetch;
|
|
299
287
|
|
|
300
288
|
let originalFetch: FetchFn;
|
|
@@ -375,7 +363,7 @@ describe("getSkillFileContent — installed skill", () => {
|
|
|
375
363
|
mockResolvedSkills = [installedSkill("my-skill", skillDir)];
|
|
376
364
|
installFetchForbidden();
|
|
377
365
|
|
|
378
|
-
const result = await getSkillFileContent("my-skill", "SKILL.md"
|
|
366
|
+
const result = await getSkillFileContent("my-skill", "SKILL.md");
|
|
379
367
|
expect("error" in result).toBe(false);
|
|
380
368
|
if ("error" in result) return;
|
|
381
369
|
expect(result.path).toBe("SKILL.md");
|
|
@@ -395,7 +383,7 @@ describe("getSkillFileContent — installed skill", () => {
|
|
|
395
383
|
mockResolvedSkills = [installedSkill("my-skill", skillDir)];
|
|
396
384
|
installFetchForbidden();
|
|
397
385
|
|
|
398
|
-
const result = await getSkillFileContent("my-skill", "img.png"
|
|
386
|
+
const result = await getSkillFileContent("my-skill", "img.png");
|
|
399
387
|
expect("error" in result).toBe(false);
|
|
400
388
|
if ("error" in result) return;
|
|
401
389
|
expect(result.isBinary).toBe(true);
|
|
@@ -410,7 +398,7 @@ describe("getSkillFileContent — installed skill", () => {
|
|
|
410
398
|
installFetchForbidden();
|
|
411
399
|
|
|
412
400
|
for (const bad of ["../secrets", "..", "/etc/passwd", "./../escape"]) {
|
|
413
|
-
const result = await getSkillFileContent("my-skill", bad
|
|
401
|
+
const result = await getSkillFileContent("my-skill", bad);
|
|
414
402
|
expect("error" in result).toBe(true);
|
|
415
403
|
if (!("error" in result)) continue;
|
|
416
404
|
expect(result.status).toBe(400);
|
|
@@ -427,7 +415,6 @@ describe("getSkillFileContent — installed skill", () => {
|
|
|
427
415
|
const result = await getSkillFileContent(
|
|
428
416
|
"my-skill",
|
|
429
417
|
"SKILL.md\0.png",
|
|
430
|
-
dummyCtx,
|
|
431
418
|
);
|
|
432
419
|
expect("error" in result).toBe(true);
|
|
433
420
|
if (!("error" in result)) return;
|
|
@@ -440,7 +427,7 @@ describe("getSkillFileContent — installed skill", () => {
|
|
|
440
427
|
mockResolvedSkills = [installedSkill("my-skill", skillDir)];
|
|
441
428
|
installFetchForbidden();
|
|
442
429
|
|
|
443
|
-
const result = await getSkillFileContent("my-skill", "ghost.txt"
|
|
430
|
+
const result = await getSkillFileContent("my-skill", "ghost.txt");
|
|
444
431
|
expect("error" in result).toBe(true);
|
|
445
432
|
if (!("error" in result)) return;
|
|
446
433
|
expect(result.status).toBe(404);
|
|
@@ -474,7 +461,6 @@ describe("getSkillFileContent — uninstalled skill (provider chain)", () => {
|
|
|
474
461
|
const result = await getSkillFileContent(
|
|
475
462
|
"remote-skill",
|
|
476
463
|
"SKILL.md",
|
|
477
|
-
dummyCtx,
|
|
478
464
|
);
|
|
479
465
|
expect("error" in result).toBe(false);
|
|
480
466
|
if ("error" in result) return;
|
|
@@ -495,7 +481,6 @@ describe("getSkillFileContent — uninstalled skill (provider chain)", () => {
|
|
|
495
481
|
const result = await getSkillFileContent(
|
|
496
482
|
"ghost-skill",
|
|
497
483
|
"SKILL.md",
|
|
498
|
-
dummyCtx,
|
|
499
484
|
);
|
|
500
485
|
expect("error" in result).toBe(true);
|
|
501
486
|
if (!("error" in result)) return;
|
|
@@ -528,7 +513,6 @@ describe("getSkillFileContent — uninstalled skill (provider chain)", () => {
|
|
|
528
513
|
const result = await getSkillFileContent(
|
|
529
514
|
"owner/repo/my-skill",
|
|
530
515
|
"SKILL.md",
|
|
531
|
-
dummyCtx,
|
|
532
516
|
);
|
|
533
517
|
expect("error" in result).toBe(false);
|
|
534
518
|
if ("error" in result) return;
|
|
@@ -559,7 +543,7 @@ describe("getSkillFileContent — uninstalled skill (provider chain)", () => {
|
|
|
559
543
|
toSlimSkill: async () => null,
|
|
560
544
|
};
|
|
561
545
|
|
|
562
|
-
const result = await getSkillFileContent("cool-tool", "SKILL.md"
|
|
546
|
+
const result = await getSkillFileContent("cool-tool", "SKILL.md");
|
|
563
547
|
expect("error" in result).toBe(false);
|
|
564
548
|
if ("error" in result) return;
|
|
565
549
|
expect(result.content).toBe("# clawhub content yo\n");
|
|
@@ -581,7 +565,6 @@ describe("getSkillFileContent — uninstalled skill (provider chain)", () => {
|
|
|
581
565
|
const result = await getSkillFileContent(
|
|
582
566
|
"known-skill",
|
|
583
567
|
"nonexistent.txt",
|
|
584
|
-
dummyCtx,
|
|
585
568
|
);
|
|
586
569
|
expect("error" in result).toBe(true);
|
|
587
570
|
if (!("error" in result)) return;
|
|
@@ -624,7 +607,6 @@ describe("getSkillFileContent — uninstalled skill (provider chain)", () => {
|
|
|
624
607
|
const result = await getSkillFileContent(
|
|
625
608
|
"simple-slug",
|
|
626
609
|
"SKILL.md",
|
|
627
|
-
dummyCtx,
|
|
628
610
|
);
|
|
629
611
|
// Should be "File not found" (vellum handled but returned null)
|
|
630
612
|
expect("error" in result).toBe(true);
|
|
@@ -647,7 +629,6 @@ describe("getSkillFileContent — skill not found", () => {
|
|
|
647
629
|
const result = await getSkillFileContent(
|
|
648
630
|
"ghost-skill",
|
|
649
631
|
"SKILL.md",
|
|
650
|
-
dummyCtx,
|
|
651
632
|
);
|
|
652
633
|
expect("error" in result).toBe(true);
|
|
653
634
|
if (!("error" in result)) return;
|
|
@@ -688,7 +669,6 @@ describe("getSkillFileContent — installed skill with missing directory", () =>
|
|
|
688
669
|
const result = await getSkillFileContent(
|
|
689
670
|
"ghost-installed",
|
|
690
671
|
"SKILL.md",
|
|
691
|
-
dummyCtx,
|
|
692
672
|
);
|
|
693
673
|
|
|
694
674
|
expect("error" in result).toBe(true);
|
|
@@ -713,7 +693,7 @@ describe("getSkillFileContent — hidden / SKIP_DIRS rejection", () => {
|
|
|
713
693
|
mockResolvedSkills = [installedSkill("leaky-skill", skillDir)];
|
|
714
694
|
installFetchForbidden();
|
|
715
695
|
|
|
716
|
-
const result = await getSkillFileContent("leaky-skill", ".env"
|
|
696
|
+
const result = await getSkillFileContent("leaky-skill", ".env");
|
|
717
697
|
expect("error" in result).toBe(true);
|
|
718
698
|
if (!("error" in result)) return;
|
|
719
699
|
expect(result.status).toBe(400);
|
|
@@ -737,7 +717,7 @@ describe("getSkillFileContent — hidden / SKIP_DIRS rejection", () => {
|
|
|
737
717
|
toSlimSkill: async () => null,
|
|
738
718
|
};
|
|
739
719
|
|
|
740
|
-
const result = await getSkillFileContent("catalog-leaky", ".env"
|
|
720
|
+
const result = await getSkillFileContent("catalog-leaky", ".env");
|
|
741
721
|
expect("error" in result).toBe(true);
|
|
742
722
|
if (!("error" in result)) return;
|
|
743
723
|
expect(result.status).toBe(400);
|
|
@@ -753,7 +733,7 @@ describe("getSkillFileContent — hidden / SKIP_DIRS rejection", () => {
|
|
|
753
733
|
installFetchForbidden();
|
|
754
734
|
|
|
755
735
|
for (const bad of [".git/config", "docs/.hidden/file.md"]) {
|
|
756
|
-
const result = await getSkillFileContent("my-skill", bad
|
|
736
|
+
const result = await getSkillFileContent("my-skill", bad);
|
|
757
737
|
expect("error" in result).toBe(true);
|
|
758
738
|
if (!("error" in result)) continue;
|
|
759
739
|
expect(result.status).toBe(400);
|
|
@@ -772,7 +752,7 @@ describe("getSkillFileContent — hidden / SKIP_DIRS rejection", () => {
|
|
|
772
752
|
"__pycache__/cached.pyc",
|
|
773
753
|
"nested/node_modules/mod/index.js",
|
|
774
754
|
]) {
|
|
775
|
-
const result = await getSkillFileContent("my-skill", bad
|
|
755
|
+
const result = await getSkillFileContent("my-skill", bad);
|
|
776
756
|
expect("error" in result).toBe(true);
|
|
777
757
|
if (!("error" in result)) continue;
|
|
778
758
|
expect(result.status).toBe(400);
|
|
@@ -789,7 +769,6 @@ describe("getSkillFileContent — hidden / SKIP_DIRS rejection", () => {
|
|
|
789
769
|
const result = await getSkillFileContent(
|
|
790
770
|
"healthy-skill",
|
|
791
771
|
"SKILL.md",
|
|
792
|
-
dummyCtx,
|
|
793
772
|
);
|
|
794
773
|
expect("error" in result).toBe(false);
|
|
795
774
|
if ("error" in result) return;
|
|
@@ -238,12 +238,6 @@ import {
|
|
|
238
238
|
// Helpers
|
|
239
239
|
// ---------------------------------------------------------------------------
|
|
240
240
|
|
|
241
|
-
const dummyCtx = {
|
|
242
|
-
debounceTimers: { schedule: () => {} },
|
|
243
|
-
setSuppressConfigReload: () => {},
|
|
244
|
-
updateConfigFingerprint: () => {},
|
|
245
|
-
broadcast: () => {},
|
|
246
|
-
} as unknown as Parameters<typeof getSkillFiles>[1];
|
|
247
241
|
|
|
248
242
|
function makeSummary(overrides: Partial<SkillSummary>): SkillSummary {
|
|
249
243
|
return {
|
|
@@ -318,7 +312,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
318
312
|
}),
|
|
319
313
|
};
|
|
320
314
|
|
|
321
|
-
const result = await getSkillFiles("acme-seo"
|
|
315
|
+
const result = await getSkillFiles("acme-seo");
|
|
322
316
|
|
|
323
317
|
expect("error" in result).toBe(false);
|
|
324
318
|
if ("error" in result) return;
|
|
@@ -348,7 +342,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
348
342
|
test("returns 404 when skill is neither installed nor handled by any provider", async () => {
|
|
349
343
|
mockResolvedStates = [];
|
|
350
344
|
|
|
351
|
-
const result = await getSkillFiles("ghost-skill"
|
|
345
|
+
const result = await getSkillFiles("ghost-skill");
|
|
352
346
|
|
|
353
347
|
expect("error" in result).toBe(true);
|
|
354
348
|
if (!("error" in result)) return;
|
|
@@ -364,7 +358,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
364
358
|
toSlimSkill: async () => null,
|
|
365
359
|
};
|
|
366
360
|
|
|
367
|
-
const result = await getSkillFiles("broken-skill"
|
|
361
|
+
const result = await getSkillFiles("broken-skill");
|
|
368
362
|
|
|
369
363
|
expect("error" in result).toBe(true);
|
|
370
364
|
if (!("error" in result)) return;
|
|
@@ -404,7 +398,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
404
398
|
},
|
|
405
399
|
];
|
|
406
400
|
|
|
407
|
-
const result = await getSkillFiles("installed-skill"
|
|
401
|
+
const result = await getSkillFiles("installed-skill");
|
|
408
402
|
|
|
409
403
|
expect("error" in result).toBe(false);
|
|
410
404
|
if ("error" in result) return;
|
|
@@ -467,7 +461,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
467
461
|
}),
|
|
468
462
|
};
|
|
469
463
|
|
|
470
|
-
const result = await getSkillFiles("ghost-installed"
|
|
464
|
+
const result = await getSkillFiles("ghost-installed");
|
|
471
465
|
|
|
472
466
|
expect("error" in result).toBe(true);
|
|
473
467
|
if (!("error" in result)) return;
|
|
@@ -491,7 +485,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
491
485
|
}),
|
|
492
486
|
};
|
|
493
487
|
|
|
494
|
-
const result = await getSkillFiles("plain-skill"
|
|
488
|
+
const result = await getSkillFiles("plain-skill");
|
|
495
489
|
|
|
496
490
|
expect("error" in result).toBe(false);
|
|
497
491
|
if ("error" in result) return;
|
|
@@ -516,7 +510,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
516
510
|
}),
|
|
517
511
|
};
|
|
518
512
|
|
|
519
|
-
const result = await getSkillFiles("fancy-skill"
|
|
513
|
+
const result = await getSkillFiles("fancy-skill");
|
|
520
514
|
|
|
521
515
|
expect("error" in result).toBe(false);
|
|
522
516
|
if ("error" in result) return;
|
|
@@ -559,7 +553,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
559
553
|
}),
|
|
560
554
|
};
|
|
561
555
|
|
|
562
|
-
const result = await getSkillFiles("owner/repo/my-skill"
|
|
556
|
+
const result = await getSkillFiles("owner/repo/my-skill");
|
|
563
557
|
|
|
564
558
|
expect("error" in result).toBe(false);
|
|
565
559
|
if ("error" in result) return;
|
|
@@ -621,7 +615,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
621
615
|
}),
|
|
622
616
|
};
|
|
623
617
|
|
|
624
|
-
const result = await getSkillFiles("cool-tool"
|
|
618
|
+
const result = await getSkillFiles("cool-tool");
|
|
625
619
|
|
|
626
620
|
expect("error" in result).toBe(false);
|
|
627
621
|
if ("error" in result) return;
|
|
@@ -635,7 +629,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
635
629
|
mockSkillsshProvider = makeNoopProvider("skillssh");
|
|
636
630
|
mockClawhubProvider = makeNoopProvider("clawhub");
|
|
637
631
|
|
|
638
|
-
const result = await getSkillFiles("unknown-origin-skill"
|
|
632
|
+
const result = await getSkillFiles("unknown-origin-skill");
|
|
639
633
|
|
|
640
634
|
expect("error" in result).toBe(true);
|
|
641
635
|
if (!("error" in result)) return;
|
|
@@ -715,7 +709,7 @@ describe("getSkillFiles — provider chain fallback", () => {
|
|
|
715
709
|
}),
|
|
716
710
|
};
|
|
717
711
|
|
|
718
|
-
const result = await getSkillFiles("contested-skill"
|
|
712
|
+
const result = await getSkillFiles("contested-skill");
|
|
719
713
|
|
|
720
714
|
expect("error" in result).toBe(false);
|
|
721
715
|
if ("error" in result) return;
|