@mycadet/assistant 0.12.6-dev.202610091338.ee7f3e3 → 0.12.7
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/README.md +3 -3
- package/docs/runbook-trusted-contacts.md +3 -3
- package/docs/skills.md +3 -3
- package/docs/trusted-contact-access.md +2 -2
- package/eslint.config.mjs +15 -0
- package/knip.json +2 -8
- package/openapi.yaml +11 -7
- package/package.json +2 -2
- package/scripts/run-tests.ts +4 -1
- package/src/__tests__/app-builder-tool-scripts.test.ts +34 -60
- package/src/__tests__/app-bundler.test.ts +9 -18
- package/src/__tests__/app-routes-csp.test.ts +28 -69
- package/src/__tests__/approval-cascade.test.ts +0 -22
- package/src/__tests__/approval-routes-http.test.ts +0 -21
- package/src/__tests__/assistant-attachment-directive.test.ts +1 -2
- package/src/__tests__/assistant-attachments.test.ts +2 -4
- package/src/__tests__/assistant-event-hub-connection-history.test.ts +7 -3
- package/src/__tests__/browser-fill-credential.test.ts +15 -18
- package/src/__tests__/byok-default-profile-ensure.test.ts +41 -24
- package/src/__tests__/compaction-events.test.ts +0 -10
- package/src/__tests__/compactor-tail-resolution.test.ts +2 -7
- package/src/__tests__/config-get-vision-flag.test.ts +0 -4
- package/src/__tests__/config-loader-backfill.test.ts +45 -48
- package/src/__tests__/config-schema.test.ts +15 -9
- package/src/__tests__/config-set-route.test.ts +13 -10
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
- package/src/__tests__/config-watcher.test.ts +0 -4
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -8
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +0 -6
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -6
- package/src/__tests__/conversation-agent-loop.test.ts +0 -6
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +0 -8
- package/src/__tests__/conversation-attachments.test.ts +0 -4
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -10
- package/src/__tests__/conversation-fork-referential.test.ts +8 -3
- package/src/__tests__/conversation-lifecycle.test.ts +0 -8
- package/src/__tests__/conversation-load-history-repair.test.ts +0 -8
- package/src/__tests__/conversation-load-history-stripped.test.ts +0 -8
- package/src/__tests__/conversation-messaging-secret-redirect.test.ts +13 -16
- package/src/__tests__/conversation-process-callsite.test.ts +0 -8
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -8
- package/src/__tests__/conversation-queue.test.ts +0 -11
- package/src/__tests__/conversation-rendered-delegation-state.test.ts +0 -10
- package/src/__tests__/conversation-slash-queue.test.ts +0 -8
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -8
- package/src/__tests__/conversation-slash.test.ts +2 -2
- package/src/__tests__/conversation-speed-override.test.ts +0 -10
- package/src/__tests__/conversation-store-ephemeral.test.ts +0 -8
- package/src/__tests__/conversation-summarize-up-to.test.ts +0 -10
- package/src/__tests__/conversation-title-service.test.ts +4 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +0 -7
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -8
- package/src/__tests__/conversation-wait-for-idle.test.ts +0 -10
- package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -15
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -12
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -12
- package/src/__tests__/copy-composer-tc-templates.test.ts +1 -3
- package/src/__tests__/credential-prompt-route.test.ts +17 -20
- package/src/__tests__/credential-routes.test.ts +112 -82
- package/src/__tests__/daemon-credential-client.test.ts +1 -7
- package/src/__tests__/db-migration-rollback.test.ts +1 -3
- package/src/__tests__/default-profile-catalog-fallback.test.ts +32 -23
- package/src/__tests__/ensure-conversation-exists.test.ts +1 -4
- package/src/__tests__/file-read-tool.test.ts +1 -7
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -4
- package/src/__tests__/headless-browser-navigate.test.ts +1 -3
- package/src/__tests__/helpers/secure-keys.ts +6 -1
- package/src/__tests__/helpers/seed-app.ts +64 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +2 -2
- package/src/__tests__/llm-resolver-override-or-default.test.ts +14 -4
- package/src/__tests__/llm-resolver.test.ts +30 -10
- package/src/__tests__/llm-schema-fallback-profile.test.ts +46 -52
- package/src/__tests__/llm-schema.test.ts +8 -8
- package/src/__tests__/managed-profile-guard.test.ts +4 -4
- package/src/__tests__/manual-token-reconciliation.test.ts +22 -16
- package/src/__tests__/mcp-config-secret-boundary.test.ts +0 -7
- package/src/__tests__/media-generate-image.test.ts +29 -45
- package/src/__tests__/media-resolve-image-validation.test.ts +3 -1
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -7
- package/src/__tests__/migration-export-http.test.ts +1 -7
- package/src/__tests__/migration-export-streaming.test.ts +1 -7
- package/src/__tests__/migration-export-to-gcs.test.ts +7 -15
- package/src/__tests__/migration-import-commit-http.test.ts +0 -7
- package/src/__tests__/migration-import-from-gcs.test.ts +0 -11
- package/src/__tests__/migration-import-from-path.test.ts +0 -7
- package/src/__tests__/migration-import-from-url.test.ts +0 -11
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -7
- package/src/__tests__/notification-decision-strategy.test.ts +1 -3
- package/src/__tests__/notification-routing-intent.test.ts +1 -5
- package/src/__tests__/oauth-provider-visibility.test.ts +5 -6
- package/src/__tests__/oauth-store.test.ts +44 -47
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -6
- package/src/__tests__/platform-callback-registration.test.ts +74 -50
- package/src/__tests__/processing-flag-persist-failure.test.ts +0 -15
- package/src/__tests__/prompt-cache-cross-turn-stability.test.ts +0 -12
- package/src/__tests__/provider-commit-message-generator.test.ts +1 -1
- package/src/__tests__/provider-platform-proxy-integration.test.ts +45 -43
- package/src/__tests__/proxy-approval-callback.test.ts +0 -10
- package/src/__tests__/published-app-updater.test.ts +18 -41
- package/src/__tests__/resolve-app-id.test.ts +50 -36
- package/src/__tests__/run-conversation-turn-persistence.test.ts +3 -3
- package/src/__tests__/scheduler-result-notification.test.ts +9 -1
- package/src/__tests__/secure-keys.test.ts +1 -7
- package/src/__tests__/slack-share-routes.test.ts +2 -18
- package/src/__tests__/starter-task-flow.test.ts +23 -29
- package/src/__tests__/subagent-tool-gate-mode.test.ts +0 -8
- package/src/__tests__/tool-side-effects-documents.test.ts +0 -29
- package/src/__tests__/tool-side-effects-hook-failures.test.ts +0 -29
- package/src/__tests__/usage-attribution.test.ts +5 -5
- package/src/__tests__/workspace-greetings.test.ts +20 -27
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +23 -40
- package/src/__tests__/workspace-migration-avatar-rename.test.ts +48 -90
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +31 -58
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +36 -58
- package/src/__tests__/workspace-migration-extract-collect-usage-data.test.ts +49 -81
- package/src/acp/__tests__/acp-claude-oauth.test.ts +32 -65
- package/src/acp/session-snapshot.ts +1 -3
- package/src/approvals/guardian-decision-primitive.ts +2 -4
- package/src/apps/resolve-app.ts +0 -1
- package/src/apps/source-fingerprint.ts +1 -6
- package/src/bundler/app-bundler.ts +1 -2
- package/src/bundler/manifest.ts +0 -4
- package/src/calls/__tests__/call-controller.test.ts +25 -19
- package/src/cli/commands/__tests__/avatar.test.ts +2 -3
- package/src/cli/commands/__tests__/changelog.test.ts +1 -2
- package/src/cli/commands/__tests__/email-core.test.ts +10 -2
- package/src/cli/commands/__tests__/inference-providers.test.ts +21 -41
- package/src/cli/commands/__tests__/tts.test.ts +10 -16
- package/src/cli/commands/__tests__/ui-confirm.test.ts +2 -0
- package/src/cli/commands/apps.ts +4 -10
- package/src/cli/commands/bash.ts +2 -3
- package/src/cli/commands/clients.ts +3 -1
- package/src/cli/commands/cloud/__tests__/callback-routes-list.test.ts +1 -5
- package/src/cli/commands/cloud/__tests__/invoices.test.ts +1 -5
- package/src/cli/commands/cloud/index.help.ts +1 -2
- package/src/cli/commands/cloud/index.ts +1 -4
- package/src/cli/commands/config.help.ts +6 -6
- package/src/cli/commands/db/status.ts +4 -3
- package/src/cli/commands/inference-providers-default.ts +1 -1
- package/src/cli/commands/inference-providers.ts +0 -7
- package/src/cli/commands/inference.help.ts +2 -81
- package/src/cli/commands/notifications.ts +4 -1
- package/src/cli/lib/__tests__/plugin-artifact.test.ts +1 -4
- package/src/config/__tests__/assistant-initiated-threads-gate.test.ts +2 -3
- package/src/config/__tests__/default-profile-catalog.test.ts +47 -33
- package/src/config/__tests__/default-provider.test.ts +82 -67
- package/src/config/__tests__/jev-managed-profile.test.ts +2 -2
- package/src/config/__tests__/platform-rehydration.test.ts +2 -4
- package/src/config/__tests__/seed-default-provider.test.ts +87 -43
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +1 -1
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +5 -5
- package/src/config/call-site-defaults.ts +1 -1
- package/src/config/default-profile-catalog.ts +31 -35
- package/src/config/default-profile-names.ts +1 -1
- package/src/config/default-provider-resolution.ts +20 -25
- package/src/config/default-provider.ts +54 -19
- package/src/config/feature-flag-registry.json +5 -23
- package/src/config/inference-profile-validation.ts +2 -5
- package/src/config/input-modalities.test.ts +3 -3
- package/src/config/input-modalities.ts +6 -4
- package/src/config/llm-resolver.ts +10 -12
- package/src/config/memory-v3-gate.test.ts +3 -3
- package/src/config/profile-tool-support.ts +1 -1
- package/src/config/schemas/llm.ts +78 -56
- package/src/config/schemas/services.ts +3 -1
- package/src/config/schemas/tts.ts +0 -1
- package/src/config/seed-inference-profiles.ts +65 -121
- package/src/credential-execution/ces-runtime.ts +2 -8
- package/src/credential-execution/process-manager.test.ts +1 -7
- package/src/daemon/__tests__/install-assistant-command.test.ts +1 -7
- package/src/daemon/auto-profile-router.ts +1 -4
- package/src/daemon/conversation-agent-loop.ts +1 -4
- package/src/daemon/conversation-error.ts +1 -2
- package/src/daemon/conversation-runtime-assembly.ts +1 -1
- package/src/daemon/conversation-slash.ts +1 -4
- package/src/daemon/lifecycle.ts +2 -17
- package/src/daemon/main.ts +0 -1
- package/src/daemon/port-oversized-content.test.ts +3 -3
- package/src/daemon/trust-context-types.test.ts +2 -7
- package/src/daemon/wake-conversation-ops.ts +2 -4
- package/src/documents/document-comments-store.ts +0 -12
- package/src/documents/document-store.ts +0 -28
- package/src/followups/followup-store.ts +1 -2
- package/src/inbound/__tests__/tunnel-probe.test.ts +9 -4
- package/src/mcp/__tests__/plugin-mcp-oauth-cleanup.test.ts +24 -48
- package/src/mcp/__tests__/plugin-mcp-oauth-provider-isolation.test.ts +5 -17
- package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +35 -24
- package/src/mcp/__tests__/tool-caps.test.ts +12 -13
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +6 -2
- package/src/mcp/workspace-mcp-config.ts +6 -2
- package/src/media/__tests__/image-models.test.ts +8 -2
- package/src/messaging/providers/slack/api.test.ts +11 -28
- package/src/monitoring/__tests__/mount-watch.test.ts +26 -8
- package/src/monitoring/mount-watch.ts +2 -1
- package/src/notifications/README.md +5 -5
- package/src/notifications/__tests__/channel-allowlist.test.ts +3 -1
- package/src/notifications/__tests__/copy-composer.test.ts +2 -6
- package/src/notifications/broadcaster.ts +1 -2
- package/src/notifications/channel-allowlist.ts +5 -3
- package/src/permissions/checker.test.ts +0 -6
- package/src/persistence/client-connection-events-store.ts +1 -4
- package/src/persistence/embeddings/embedding-backend.test.ts +19 -24
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +3 -1
- package/src/persistence/slow-query-log.ts +1 -3
- package/src/platform/managed-speech.ts +1 -2
- package/src/plugin-api/app-globals.d.ts +1 -4
- package/src/plugin-api/model-profiles.test.ts +1 -1
- package/src/plugin-api/model-profiles.ts +1 -4
- package/src/plugin-api/vision-support.test.ts +6 -8
- package/src/plugin-api/vision-support.ts +3 -4
- package/src/plugins/__tests__/active-plugin-env.test.ts +5 -8
- package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +0 -5
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +1 -4
- package/src/plugins/defaults/task-progress/__tests__/task-progress-context.test.ts +15 -13
- package/src/plugins/defaults/task-progress/src/format-task-progress-context.ts +1 -2
- package/src/providers/__tests__/cadet-connection-routing.test.ts +7 -15
- package/src/providers/__tests__/retry-callsite.test.ts +1 -1
- package/src/providers/__tests__/xml-tool-call-salvage.test.ts +7 -5
- package/src/providers/cadet-model-routing.ts +1 -3
- package/src/providers/connection-resolution.ts +1 -1
- package/src/providers/inference/__tests__/adapter-factory-opencode.test.ts +2 -3
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +12 -4
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +15 -18
- package/src/providers/inference/adapter-factory.ts +1 -1
- package/src/providers/inference/connection-availability.ts +1 -1
- package/src/providers/inline-audio-support.test.ts +4 -4
- package/src/providers/inline-audio-support.ts +1 -3
- package/src/providers/jev/client.ts +4 -2
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +1 -3
- package/src/providers/openai/__tests__/chat-completions-provider-xml-salvage.test.ts +30 -26
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +3 -1
- package/src/providers/speech-to-text/__tests__/cadet-managed.test.ts +3 -3
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +93 -100
- package/src/providers/speech-to-text/resolve.ts +3 -3
- package/src/runtime/__tests__/pages-route-policy.test.ts +13 -29
- package/src/runtime/anchored-guardian.ts +1 -4
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +1 -3
- package/src/runtime/channel-readiness-service.ts +3 -6
- package/src/runtime/http-server.ts +1 -3
- package/src/runtime/migrations/__tests__/staged-import-path.test.ts +8 -2
- package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +1 -4
- package/src/runtime/migrations/migration-transport.ts +57 -88
- package/src/runtime/migrations/migration-wizard.ts +51 -46
- package/src/runtime/migrations/vbundle-metadata-merge.ts +24 -40
- package/src/runtime/migrations/vbundle-streaming-importer.ts +20 -17
- package/src/runtime/pending-interactions.ts +1 -4
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +21 -38
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +10 -10
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +44 -79
- package/src/runtime/routes/__tests__/image-generation-routes.test.ts +1 -4
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +24 -14
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +26 -23
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +3 -2
- package/src/runtime/routes/__tests__/migration-cadet-metadata-reconcile.test.ts +6 -17
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +11 -19
- package/src/runtime/routes/app-management-routes.ts +1 -5
- package/src/runtime/routes/channel-metadata.ts +2 -6
- package/src/runtime/routes/client-routes.ts +2 -1
- package/src/runtime/routes/conversation-query-routes.ts +81 -53
- package/src/runtime/routes/conversation-routes.ts +2 -7
- package/src/runtime/routes/default-provider-routes.ts +24 -25
- package/src/runtime/routes/domain-routes.ts +3 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +1 -4
- package/src/runtime/routes/inference-profiles-routes.ts +5 -11
- package/src/runtime/routes/inference-provider-connection-routes.ts +14 -15
- package/src/runtime/routes/inference-send-routes.ts +2 -5
- package/src/runtime/routes/integrations/slack/__tests__/token-routing.test.ts +17 -9
- package/src/runtime/routes/integrations/twilio.ts +6 -4
- package/src/runtime/routes/llm-call-sites-routes.ts +1 -4
- package/src/runtime/routes/oauth-proxy-passthrough.test.ts +1 -3
- package/src/runtime/routes/secret-routes.ts +2 -1
- package/src/runtime/routes/settings-routes.ts +6 -5
- package/src/runtime/routes/watch-routes.ts +1 -3
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +3 -1
- package/src/security/secure-keys.ts +2 -1
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +15 -3
- package/src/tools/acp/status.ts +1 -4
- package/src/tools/browser/__tests__/auth-detector.test.ts +1 -3
- package/src/tools/network/__tests__/firecrawl-compat.test.ts +3 -3
- package/src/tools/network/__tests__/web-search.test.ts +74 -113
- package/src/tools/workflows/manage-workflows.ts +1 -4
- package/src/util/host-process.test.ts +4 -1
- package/src/util/oauth-request-body.test.ts +4 -1
- package/src/watcher/__tests__/engine.test.ts +3 -1
- package/src/watcher/engine.ts +1 -1
- package/src/workflows/leaf-runner.ts +1 -5
- package/src/workspace/byok-default-profile-ensure.ts +16 -14
- package/src/workspace/custom-profile-ensure.ts +2 -2
- package/src/workspace/migrations/130-speech-mode-to-provider.ts +1 -2
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +8 -4
- package/src/workspace/migrations/utils.ts +2 -1
- package/docs/backup-troubleshooting.md +0 -52
- package/docs/browser-use-architecture-phase2.md +0 -289
- package/docs/flux-turn-detection-spike.md +0 -249
- package/docs/workspace-tools.md +0 -207
- package/src/__tests__/default-provider-ensure.test.ts +0 -353
- package/src/workspace/default-provider-ensure.ts +0 -163
package/README.md
CHANGED
|
@@ -70,9 +70,9 @@ bun run src/index.ts # interactive CLI session
|
|
|
70
70
|
|
|
71
71
|
| Command | Description |
|
|
72
72
|
| ---------------------------------------------------------- | ------------------------------------------------ |
|
|
73
|
-
| `cadet wake`
|
|
74
|
-
| `cadet sleep`
|
|
75
|
-
| `cadet ps`
|
|
73
|
+
| `cadet wake` | Start assistant + gateway from current checkout |
|
|
74
|
+
| `cadet sleep` | Stop assistant + gateway processes |
|
|
75
|
+
| `cadet ps` | List assistants and per-assistant process status |
|
|
76
76
|
| `assistant` | Launch interactive CLI session |
|
|
77
77
|
| `assistant conversations list\|search\|new\|export\|clear` | Manage conversations |
|
|
78
78
|
| `assistant config set\|get\|list` | Manage configuration |
|
|
@@ -4,10 +4,10 @@ Operational procedures for inspecting, managing, and debugging the trusted conta
|
|
|
4
4
|
|
|
5
5
|
Two databases hold this state — pick the right one before reaching for SQL:
|
|
6
6
|
|
|
7
|
-
| Data | Database | Location
|
|
8
|
-
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- |
|
|
7
|
+
| Data | Database | Location |
|
|
8
|
+
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
9
9
|
| Contact ACL (`contacts` role, `contact_channels` status/policy/reasons), guardian requests (`guardian_requests` + `guardian_request_deliveries`), verification sessions, rate limits, invites | Gateway DB (`gateway.sqlite`) | `$GATEWAY_SECURITY_DIR/gateway.sqlite` (Docker: the `/gateway-security` volume; local fallback: `~/.cadet/protected/`) |
|
|
10
|
-
| Notification pipeline, contact info/identity mirror | Assistant DB (`assistant.db`) | `$CADET_WORKSPACE_DIR/data/db/assistant.db` (local fallback: `~/.cadet/workspace/`)
|
|
10
|
+
| Notification pipeline, contact info/identity mirror | Assistant DB (`assistant.db`) | `$CADET_WORKSPACE_DIR/data/db/assistant.db` (local fallback: `~/.cadet/workspace/`) |
|
|
11
11
|
|
|
12
12
|
Prefer the CLI and HTTP surfaces below over raw SQL — they go through the gateway's validation (status vocabulary, revoke-of-blocked guard) and emit the change events clients rely on. Raw SQL is break-glass only.
|
|
13
13
|
|
package/docs/skills.md
CHANGED
|
@@ -116,10 +116,10 @@ Acceptance is idempotent and recorded in `trust.json`. The bundle does not inclu
|
|
|
116
116
|
|
|
117
117
|
Tools can execute in two contexts:
|
|
118
118
|
|
|
119
|
-
| Target | Description
|
|
120
|
-
| --------- |
|
|
119
|
+
| Target | Description |
|
|
120
|
+
| --------- | --------------------------------------------------------------------------------------- |
|
|
121
121
|
| `sandbox` | Isolated execution within `$CADET_WORKSPACE_DIR` (Docker container or OS-level sandbox) |
|
|
122
|
-
| `host` | Direct execution on the host machine
|
|
122
|
+
| `host` | Direct execution on the host machine |
|
|
123
123
|
|
|
124
124
|
Trust rules can include an `executionTarget` field to bind the rule to a specific context. A rule without `executionTarget` matches both sandbox and host invocations.
|
|
125
125
|
|
|
@@ -9,7 +9,7 @@ Design doc defining how unknown users gain access to a Cadet assistant via chann
|
|
|
9
9
|
| `guardian` | The verified owner/administrator of the assistant on a given channel. Has a record in the gateway DB `contacts` table with `role: 'guardian'` and an active `contact_channels` entry. Approves or denies access requests. |
|
|
10
10
|
| `trusted_contact` | An external user who has completed the verification flow and holds a gateway `contact_channels` record with `status: 'active'` and `policy: 'allow'`. |
|
|
11
11
|
| `gateway` | The ACL and verification engine. Owns the contact ACL, guardian requests + their delivery records, verification sessions, rate limits, secret minting, code interception, and the validate+consume decision. Commits every guardian decision (status CAS + ACL outcome) in one transaction. Stamps a trust verdict on every inbound message. |
|
|
12
|
-
| `assistant` | The Cadet assistant daemon. Orchestrates the approval workflow around the gateway-owned requests: guardian notification, message composition, channel delivery, and post-decision side effects (cards, notices, grant minting). It never mints or validates verification secrets.
|
|
12
|
+
| `assistant` | The Cadet assistant daemon. Orchestrates the approval workflow around the gateway-owned requests: guardian notification, message composition, channel delivery, and post-decision side effects (cards, notices, grant minting). It never mints or validates verification secrets. |
|
|
13
13
|
|
|
14
14
|
## Data Ownership
|
|
15
15
|
|
|
@@ -84,7 +84,7 @@ Identity binding ensures the verification code can only be consumed by the inten
|
|
|
84
84
|
| Store | Table | Record |
|
|
85
85
|
| ----------------------------------------------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
86
86
|
| gateway `guardian-request-store.ts` (via the daemon's `channels/gateway-guardian-requests.ts` client) | `guardian_requests` (gateway DB) | `status: 'pending'`, `kind: 'access_request'`, `toolName: 'ingress_access_request'`, `requesterExternalUserId`, `requesterChatId`, `guardianExternalUserId`/`guardianPrincipalId` (anchored resolution), `requestCode`, `expiresAt` (GUARDIAN_APPROVAL_TTL_MS from now). |
|
|
87
|
-
| `guardian-delivery-recorder.ts` (single write sink, relays to the gateway) | `guardian_request_deliveries` (gateway DB) | Per-surface approval-card delivery records (cadet, Telegram, Slack).
|
|
87
|
+
| `guardian-delivery-recorder.ts` (single write sink, relays to the gateway) | `guardian_request_deliveries` (gateway DB) | Per-surface approval-card delivery records (cadet, Telegram, Slack). |
|
|
88
88
|
| notification pipeline (assistant DB) | `notification_events` | Event with `sourceEventName: 'ingress.access_request'`, deduped via `dedupeKey`. |
|
|
89
89
|
| notification pipeline (assistant DB) | `notification_decisions` | Decision engine output: `shouldNotify`, `selectedChannels`, `confidence`, reasoning. |
|
|
90
90
|
| notification pipeline (assistant DB) | `notification_deliveries` | Per-channel delivery records, linked via `notificationDecisionId`. |
|
package/eslint.config.mjs
CHANGED
|
@@ -35,6 +35,21 @@ const eslintConfig = defineConfig([
|
|
|
35
35
|
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
|
|
36
36
|
],
|
|
37
37
|
"@typescript-eslint/no-explicit-any": "error",
|
|
38
|
+
// Flag `mock.module` at warning level: the lint script pins
|
|
39
|
+
// --max-warnings to the current count and each PR chips away at it
|
|
40
|
+
// (same countdown the cli uses for `as` casts). Prefer running the
|
|
41
|
+
// test on the real backend behind a seam — e.g. the memory-backed
|
|
42
|
+
// helpers in src/__tests__/helpers/secure-keys.ts — instead of
|
|
43
|
+
// masking module state.
|
|
44
|
+
"no-restricted-syntax": [
|
|
45
|
+
"warn",
|
|
46
|
+
{
|
|
47
|
+
selector:
|
|
48
|
+
"CallExpression[callee.object.name='mock'][callee.property.name='module']",
|
|
49
|
+
message:
|
|
50
|
+
"mock.module masks module state across tests; run on the real backend behind a seam instead. Remaining uses are being counted down — do not add new ones.",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
38
53
|
},
|
|
39
54
|
},
|
|
40
55
|
{
|
package/knip.json
CHANGED
|
@@ -11,14 +11,8 @@
|
|
|
11
11
|
"src/api/index.ts!",
|
|
12
12
|
"src/config/bundled-skills/**/tools/**/*.ts!"
|
|
13
13
|
],
|
|
14
|
-
"project": [
|
|
15
|
-
|
|
16
|
-
"src/**/*.tsx!",
|
|
17
|
-
"scripts/**/*.ts"
|
|
18
|
-
],
|
|
19
|
-
"ignore": [
|
|
20
|
-
"src/config/preloaded-apps/**"
|
|
21
|
-
],
|
|
14
|
+
"project": ["src/**/*.ts!", "src/**/*.tsx!", "scripts/**/*.ts"],
|
|
15
|
+
"ignore": ["src/config/preloaded-apps/**"],
|
|
22
16
|
"ignoreDependencies": [
|
|
23
17
|
"@microsoft/api-extractor",
|
|
24
18
|
"@mycadet/app-icons",
|
package/openapi.yaml
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
openapi: 3.1.0
|
|
4
4
|
info:
|
|
5
5
|
title: Cadet Assistant API
|
|
6
|
-
version: 0.12.
|
|
6
|
+
version: 0.12.7
|
|
7
7
|
description: Auto-generated OpenAPI specification for the Cadet Assistant runtime HTTP server.
|
|
8
8
|
servers:
|
|
9
9
|
- url: http://127.0.0.1:7821
|
|
@@ -5659,9 +5659,9 @@ paths:
|
|
|
5659
5659
|
operationId: config_llm_defaultprovider_get
|
|
5660
5660
|
summary: Get the default provider and its availability
|
|
5661
5661
|
description:
|
|
5662
|
-
Returns `llm.
|
|
5663
|
-
usable (connection exists, credential stored, Cadet authenticated). Availability is
|
|
5664
|
-
default is a valid persisted state that surfaces explainable errors at resolution time.
|
|
5662
|
+
Returns the default provider stored in `llm.default`, the connection name it resolves to, and whether that
|
|
5663
|
+
connection is currently usable (connection exists, credential stored, Cadet authenticated). Availability is
|
|
5664
|
+
informational — a broken default is a valid persisted state that surfaces explainable errors at resolution time.
|
|
5665
5665
|
tags:
|
|
5666
5666
|
- config
|
|
5667
5667
|
responses:
|
|
@@ -5675,9 +5675,9 @@ paths:
|
|
|
5675
5675
|
operationId: config_llm_defaultprovider_put
|
|
5676
5676
|
summary: Set the default provider
|
|
5677
5677
|
description:
|
|
5678
|
-
Replaces `llm.
|
|
5679
|
-
silently drop invalid values). Does not require the referenced
|
|
5680
|
-
by design and reported via the availability status.
|
|
5678
|
+
Replaces the default provider stored in the `llm.default` blob. Strict-validates the body (unlike the
|
|
5679
|
+
generic config write paths, which silently drop or clamp invalid values). Does not require the referenced
|
|
5680
|
+
connection to exist — a dangling name is allowed by design and reported via the availability status.
|
|
5681
5681
|
tags:
|
|
5682
5682
|
- config
|
|
5683
5683
|
requestBody:
|
|
@@ -39199,6 +39199,9 @@ components:
|
|
|
39199
39199
|
type: object
|
|
39200
39200
|
properties:
|
|
39201
39201
|
autoArchive:
|
|
39202
|
+
default:
|
|
39203
|
+
enabled: false
|
|
39204
|
+
afterDays: 7
|
|
39202
39205
|
type: object
|
|
39203
39206
|
properties:
|
|
39204
39207
|
enabled:
|
|
@@ -39358,6 +39361,7 @@ components:
|
|
|
39358
39361
|
type: boolean
|
|
39359
39362
|
provider_connection:
|
|
39360
39363
|
type: string
|
|
39364
|
+
minLength: 1
|
|
39361
39365
|
additionalProperties: false
|
|
39362
39366
|
defaultProvider:
|
|
39363
39367
|
type: object
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mycadet/assistant",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"probe:skill-retrieval": "bun run scripts/probe-skill-retrieval.ts",
|
|
21
21
|
"format": "prettier --write .",
|
|
22
22
|
"format:check": "prettier --check .",
|
|
23
|
-
"lint": "bun run lint:skills && bun run lint:openapi && eslint",
|
|
23
|
+
"lint": "bun run lint:skills && bun run lint:openapi && eslint --max-warnings 3033",
|
|
24
24
|
"lint:unused": "knip --include files,dependencies,unlisted",
|
|
25
25
|
"lint:circular": "bun run scripts/check-circular-deps.ts",
|
|
26
26
|
"lint:unused:production": "knip --production --include exports",
|
package/scripts/run-tests.ts
CHANGED
|
@@ -84,5 +84,8 @@ await runIsolatedTests({
|
|
|
84
84
|
bunTestArgs: EXCLUDE_EXPERIMENTAL
|
|
85
85
|
? ["--test-name-pattern", "^(?!.*\\[experimental\\])"]
|
|
86
86
|
: [],
|
|
87
|
-
fixture: {
|
|
87
|
+
fixture: {
|
|
88
|
+
script: "scripts/build-test-fixtures.ts",
|
|
89
|
+
envVar: "CADET_TEST_FIXTURES_DIR",
|
|
90
|
+
},
|
|
88
91
|
});
|
|
@@ -2,43 +2,9 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { describe, expect, mock, test } from "bun:test";
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import type { AppStore } from "../tools/apps/executors.js";
|
|
5
|
+
import { initializeDb } from "../persistence/db-init.js";
|
|
7
6
|
import type { ToolContext } from "../tools/types.js";
|
|
8
|
-
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
// Mock factory helpers
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
|
|
13
|
-
function makeApp(overrides: Partial<AppDefinition> = {}): AppDefinition {
|
|
14
|
-
return {
|
|
15
|
-
id: "app-1",
|
|
16
|
-
name: "Test App",
|
|
17
|
-
description: "A test app",
|
|
18
|
-
schemaJson: "{}",
|
|
19
|
-
htmlDefinition: "<h1>Hi</h1>",
|
|
20
|
-
createdAt: 1000,
|
|
21
|
-
updatedAt: 2000,
|
|
22
|
-
...overrides,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function makeMockStore(overrides: Partial<AppStore> = {}): AppStore {
|
|
27
|
-
const files = new Set<string>();
|
|
28
|
-
return {
|
|
29
|
-
getApp: () => makeApp(),
|
|
30
|
-
listApps: () => [makeApp()],
|
|
31
|
-
appFileExists: (_appId: string, path: string) => files.has(path),
|
|
32
|
-
createApp: (params) =>
|
|
33
|
-
makeApp({ name: params.name, description: params.description }),
|
|
34
|
-
updateApp: (id, updates) => makeApp({ id, ...updates }),
|
|
35
|
-
deleteApp: () => {},
|
|
36
|
-
writeAppFile: (_appId: string, path: string) => {
|
|
37
|
-
files.add(path);
|
|
38
|
-
},
|
|
39
|
-
...overrides,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
7
|
+
import { seedApp } from "./helpers/seed-app.js";
|
|
42
8
|
|
|
43
9
|
function makeContext(overrides: Partial<ToolContext> = {}): ToolContext {
|
|
44
10
|
return {
|
|
@@ -50,25 +16,15 @@ function makeContext(overrides: Partial<ToolContext> = {}): ToolContext {
|
|
|
50
16
|
}
|
|
51
17
|
|
|
52
18
|
// ---------------------------------------------------------------------------
|
|
53
|
-
//
|
|
19
|
+
// The skill scripts pass the REAL app-store module to the executors, so the
|
|
20
|
+
// store runs on the per-process test workspace. `app-1` is re-seeded before
|
|
21
|
+
// each test (the app-delete test really deletes it); per-conversation lookups
|
|
22
|
+
// go through real rows seeded with conversationIds.
|
|
54
23
|
// ---------------------------------------------------------------------------
|
|
55
24
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// `resolveAppId` consults when a tool's app_id is omitted. Tests set it directly.
|
|
60
|
-
let appsByConversation: AppDefinition[] = [];
|
|
61
|
-
|
|
62
|
-
mock.module("../apps/app-store.js", () => ({
|
|
63
|
-
...mockStore,
|
|
64
|
-
listAppsByConversation: (_conversationId: string) => appsByConversation,
|
|
65
|
-
getAppsDir: () => "/tmp/test-apps",
|
|
66
|
-
getAppDirPath: (appId: string) => `/tmp/test-apps/${appId}`,
|
|
67
|
-
resolveAppDir: (id: string) => ({
|
|
68
|
-
dirName: id,
|
|
69
|
-
appDir: `/tmp/test-apps/${id}`,
|
|
70
|
-
}),
|
|
71
|
-
}));
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
await initializeDb();
|
|
27
|
+
});
|
|
72
28
|
|
|
73
29
|
// Mock compileApp for multifile scaffold path
|
|
74
30
|
mock.module("../bundler/app-compiler.js", () => ({
|
|
@@ -84,6 +40,8 @@ mock.module("../bundler/app-compiler.js", () => ({
|
|
|
84
40
|
// Import skill scripts (after mocking)
|
|
85
41
|
// ---------------------------------------------------------------------------
|
|
86
42
|
|
|
43
|
+
import { beforeAll, beforeEach } from "bun:test";
|
|
44
|
+
|
|
87
45
|
import * as appCreateScript from "../config/bundled-skills/app-builder/tools/app-create.js";
|
|
88
46
|
import * as appDeleteScript from "../config/bundled-skills/app-builder/tools/app-delete.js";
|
|
89
47
|
import * as appOpenScript from "../config/bundled-skills/app-builder/tools/app-open.js";
|
|
@@ -95,6 +53,10 @@ import * as appUpdateScript from "../config/bundled-skills/app-builder/tools/app
|
|
|
95
53
|
// ---------------------------------------------------------------------------
|
|
96
54
|
|
|
97
55
|
describe("app-builder skill tool scripts", () => {
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
seedApp({ id: "app-1", name: "Test App", description: "A test app" });
|
|
58
|
+
});
|
|
59
|
+
|
|
98
60
|
// ---- app-create --------------------------------------------------------
|
|
99
61
|
|
|
100
62
|
describe("app-create", () => {
|
|
@@ -208,7 +170,11 @@ describe("app-builder skill tool scripts", () => {
|
|
|
208
170
|
});
|
|
209
171
|
|
|
210
172
|
test("resolves the active app when app_id is omitted", async () => {
|
|
211
|
-
|
|
173
|
+
seedApp({
|
|
174
|
+
id: "active-app",
|
|
175
|
+
name: "active-app",
|
|
176
|
+
conversationIds: ["conv-open-1"],
|
|
177
|
+
});
|
|
212
178
|
const calls: Array<{ name: string; input: Record<string, unknown> }> = [];
|
|
213
179
|
const proxy: ToolContext["proxyToolResolver"] = async (name, input) => {
|
|
214
180
|
calls.push({ name, input });
|
|
@@ -217,7 +183,10 @@ describe("app-builder skill tool scripts", () => {
|
|
|
217
183
|
|
|
218
184
|
const result = await appOpenScript.run(
|
|
219
185
|
{},
|
|
220
|
-
makeContext({
|
|
186
|
+
makeContext({
|
|
187
|
+
conversationId: "conv-open-1",
|
|
188
|
+
proxyToolResolver: proxy,
|
|
189
|
+
}),
|
|
221
190
|
);
|
|
222
191
|
|
|
223
192
|
expect(result.isError).toBe(false);
|
|
@@ -227,7 +196,6 @@ describe("app-builder skill tool scripts", () => {
|
|
|
227
196
|
});
|
|
228
197
|
|
|
229
198
|
test("forwards an explicit app_id unchanged", async () => {
|
|
230
|
-
appsByConversation = [makeApp({ id: "active-app" })];
|
|
231
199
|
const calls: Array<{ input: Record<string, unknown> }> = [];
|
|
232
200
|
const proxy: ToolContext["proxyToolResolver"] = async (_name, input) => {
|
|
233
201
|
calls.push({ input });
|
|
@@ -243,7 +211,6 @@ describe("app-builder skill tool scripts", () => {
|
|
|
243
211
|
});
|
|
244
212
|
|
|
245
213
|
test("errors when app_id is omitted and no active app exists", async () => {
|
|
246
|
-
appsByConversation = [];
|
|
247
214
|
const proxy: ToolContext["proxyToolResolver"] = async () => ({
|
|
248
215
|
content: "opened",
|
|
249
216
|
isError: false,
|
|
@@ -251,7 +218,10 @@ describe("app-builder skill tool scripts", () => {
|
|
|
251
218
|
|
|
252
219
|
const result = await appOpenScript.run(
|
|
253
220
|
{},
|
|
254
|
-
makeContext({
|
|
221
|
+
makeContext({
|
|
222
|
+
conversationId: "conv-open-none",
|
|
223
|
+
proxyToolResolver: proxy,
|
|
224
|
+
}),
|
|
255
225
|
);
|
|
256
226
|
|
|
257
227
|
expect(result.isError).toBe(true);
|
|
@@ -259,10 +229,14 @@ describe("app-builder skill tool scripts", () => {
|
|
|
259
229
|
});
|
|
260
230
|
|
|
261
231
|
test("errors when no client proxy resolver is available", async () => {
|
|
262
|
-
|
|
232
|
+
seedApp({
|
|
233
|
+
id: "active-app",
|
|
234
|
+
name: "active-app",
|
|
235
|
+
conversationIds: ["conv-open-noproxy"],
|
|
236
|
+
});
|
|
263
237
|
const result = await appOpenScript.run(
|
|
264
238
|
{ app_id: "app-1" },
|
|
265
|
-
makeContext(),
|
|
239
|
+
makeContext({ conversationId: "conv-open-noproxy" }),
|
|
266
240
|
);
|
|
267
241
|
|
|
268
242
|
expect(result.isError).toBe(true);
|
|
@@ -6,22 +6,14 @@ import {
|
|
|
6
6
|
writeFileSync,
|
|
7
7
|
} from "node:fs";
|
|
8
8
|
import { readFile } from "node:fs/promises";
|
|
9
|
-
import { tmpdir } from "node:os";
|
|
10
9
|
import { join } from "node:path";
|
|
11
|
-
import { afterEach, describe, expect, mock, test } from "bun:test";
|
|
10
|
+
import { afterEach, beforeAll, describe, expect, mock, test } from "bun:test";
|
|
12
11
|
|
|
13
12
|
import JSZip from "jszip";
|
|
14
13
|
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// Mock app-store so packageApp can find our test apps
|
|
19
|
-
const mockApps = new Map<string, Record<string, unknown>>();
|
|
20
|
-
mock.module("../apps/app-store.js", () => ({
|
|
21
|
-
getApp: (id: string) => mockApps.get(id) ?? null,
|
|
22
|
-
getAppsDir: () => testAppsDir,
|
|
23
|
-
getAppDirPath: (id: string) => join(testAppsDir, id),
|
|
24
|
-
}));
|
|
14
|
+
// Real apps dir inside the per-process test workspace; packageApp tests
|
|
15
|
+
// write the store's on-disk format (<id>.json + <id>/src) directly.
|
|
16
|
+
let testAppsDir: string;
|
|
25
17
|
|
|
26
18
|
// Mock content-id to avoid pulling in crypto internals
|
|
27
19
|
mock.module("../util/content-id.js", () => ({
|
|
@@ -79,6 +71,7 @@ mock.module("./bundle-signer.js", () => ({
|
|
|
79
71
|
signBundle: async () => ({}),
|
|
80
72
|
}));
|
|
81
73
|
|
|
74
|
+
import { getAppsDir } from "../apps/app-store.js";
|
|
82
75
|
import { packageApp } from "../bundler/app-bundler.js";
|
|
83
76
|
import type { AppManifest } from "../bundler/manifest.js";
|
|
84
77
|
|
|
@@ -87,9 +80,12 @@ import type { AppManifest } from "../bundler/manifest.js";
|
|
|
87
80
|
// ---------------------------------------------------------------------------
|
|
88
81
|
|
|
89
82
|
describe("packageApp", () => {
|
|
83
|
+
beforeAll(() => {
|
|
84
|
+
testAppsDir = getAppsDir();
|
|
85
|
+
});
|
|
86
|
+
|
|
90
87
|
afterEach(() => {
|
|
91
88
|
compileAppOverride = undefined;
|
|
92
|
-
mockApps.clear();
|
|
93
89
|
try {
|
|
94
90
|
rmSync(testAppsDir, { recursive: true, force: true });
|
|
95
91
|
} catch {
|
|
@@ -133,7 +129,6 @@ describe("packageApp", () => {
|
|
|
133
129
|
formatVersion: 2,
|
|
134
130
|
};
|
|
135
131
|
writeFileSync(join(testAppsDir, `${appId}.json`), JSON.stringify(appDef));
|
|
136
|
-
mockApps.set(appId, appDef);
|
|
137
132
|
|
|
138
133
|
return appDef;
|
|
139
134
|
}
|
|
@@ -156,7 +151,6 @@ describe("packageApp", () => {
|
|
|
156
151
|
updatedAt: Date.now(),
|
|
157
152
|
};
|
|
158
153
|
writeFileSync(join(testAppsDir, `${appId}.json`), JSON.stringify(appDef));
|
|
159
|
-
mockApps.set(appId, appDef);
|
|
160
154
|
|
|
161
155
|
return appDef;
|
|
162
156
|
}
|
|
@@ -238,7 +232,6 @@ describe("packageApp", () => {
|
|
|
238
232
|
formatVersion: 2,
|
|
239
233
|
};
|
|
240
234
|
writeFileSync(join(testAppsDir, `${appId}.json`), JSON.stringify(appDef));
|
|
241
|
-
mockApps.set(appId, appDef);
|
|
242
235
|
|
|
243
236
|
await expect(packageApp(appId)).rejects.toThrow(
|
|
244
237
|
/Compilation failed for app "Broken App"/,
|
|
@@ -264,7 +257,6 @@ describe("packageApp", () => {
|
|
|
264
257
|
formatVersion: 2,
|
|
265
258
|
};
|
|
266
259
|
writeFileSync(join(testAppsDir, `${appId}.json`), JSON.stringify(appDef));
|
|
267
|
-
mockApps.set(appId, appDef);
|
|
268
260
|
|
|
269
261
|
await expect(packageApp(appId)).rejects.toThrow(
|
|
270
262
|
/missing src\/index\.html and src\/main\.tsx/,
|
|
@@ -302,7 +294,6 @@ render(<App />, document.getElementById('app')!);
|
|
|
302
294
|
formatVersion: 2,
|
|
303
295
|
};
|
|
304
296
|
writeFileSync(join(testAppsDir, `${appId}.json`), JSON.stringify(appDef));
|
|
305
|
-
mockApps.set(appId, appDef);
|
|
306
297
|
|
|
307
298
|
await expect(packageApp(appId)).rejects.toThrow(
|
|
308
299
|
/still has the default src\/main\.tsx scaffold/,
|
|
@@ -1,71 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const UNSUPPORTED_HTML = `<p>This app uses the retired single-file format and can no longer be opened.</p>`;
|
|
29
|
-
|
|
30
|
-
mock.module("../apps/app-store.js", () => ({
|
|
31
|
-
resolveAppSource: (id: string) => {
|
|
32
|
-
const app = apps.get(id);
|
|
33
|
-
if (!app) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
return {
|
|
37
|
-
id,
|
|
38
|
-
name: app.name,
|
|
39
|
-
dirName: id,
|
|
40
|
-
sourceDir: `/fake/apps/${id}`,
|
|
41
|
-
origin: { kind: "workspace" as const },
|
|
42
|
-
};
|
|
43
|
-
},
|
|
44
|
-
readAppFileBytesFromDir: () => Buffer.from(""),
|
|
45
|
-
// Only the legacy app's directory has a root index.html and no src/.
|
|
46
|
-
isLegacySingleFileDir: (sourceDir: string) =>
|
|
47
|
-
sourceDir === "/fake/apps/legacy-1",
|
|
48
|
-
UNSUPPORTED_LEGACY_APP_HTML: UNSUPPORTED_HTML,
|
|
49
|
-
}));
|
|
50
|
-
|
|
51
|
-
// Mock shared-app-links-store (imported by app-routes but unused here)
|
|
52
|
-
mock.module("../apps/shared-app-links-store.js", () => ({
|
|
53
|
-
createSharedAppLink: () => ({ shareToken: "tok" }),
|
|
54
|
-
getSharedAppLink: () => null,
|
|
55
|
-
incrementDownloadCount: () => {},
|
|
56
|
-
deleteSharedAppLinkByToken: () => false,
|
|
57
|
-
}));
|
|
58
|
-
|
|
59
|
-
// Stub fs so the serve path finds a fake dist/index.html for the compiled app
|
|
60
|
-
mock.module("node:fs", () => ({
|
|
61
|
-
existsSync: (p: string) => p === "/fake/apps/app-1/dist/index.html",
|
|
62
|
-
readFileSync: (p: string, _enc?: string) => {
|
|
63
|
-
if (p === "/fake/apps/app-1/dist/index.html") {
|
|
64
|
-
return '<!DOCTYPE html><html><head></head><body><script src="main.js"></script></body></html>';
|
|
65
|
-
}
|
|
66
|
-
return "";
|
|
67
|
-
},
|
|
68
|
-
}));
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { beforeAll, describe, expect, test } from "bun:test";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
getAppDirPath,
|
|
7
|
+
UNSUPPORTED_LEGACY_APP_HTML,
|
|
8
|
+
} from "../apps/app-store.js";
|
|
9
|
+
import { seedApp } from "./helpers/seed-app.js";
|
|
10
|
+
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
// Real store rows written in the on-disk format. The compiled app carries
|
|
13
|
+
// a dist/index.html; the legacy app has only a root index.html and no src/.
|
|
14
|
+
seedApp({ id: "app-1", name: "Compiled App", schemaJson: "{}" });
|
|
15
|
+
const appDir = getAppDirPath("app-1");
|
|
16
|
+
mkdirSync(join(appDir, "dist"), { recursive: true });
|
|
17
|
+
writeFileSync(
|
|
18
|
+
join(appDir, "dist", "index.html"),
|
|
19
|
+
'<!DOCTYPE html><html><head></head><body><script src="main.js"></script></body></html>',
|
|
20
|
+
);
|
|
21
|
+
seedApp({
|
|
22
|
+
id: "legacy-1",
|
|
23
|
+
name: "Legacy App",
|
|
24
|
+
htmlDefinition: "<div>Hello</div>",
|
|
25
|
+
schemaJson: "{}",
|
|
26
|
+
});
|
|
27
|
+
});
|
|
69
28
|
|
|
70
29
|
import { ROUTES } from "../runtime/routes/app-routes.js";
|
|
71
30
|
import { BadRequestError, NotFoundError } from "../runtime/routes/errors.js";
|
|
@@ -155,7 +114,7 @@ describe("handleServePage", () => {
|
|
|
155
114
|
|
|
156
115
|
test("serves the unsupported-format message for legacy single-file apps", () => {
|
|
157
116
|
const html = pageHandler({ pathParams: { appId: "legacy-1" } }) as string;
|
|
158
|
-
expect(html).toContain(
|
|
117
|
+
expect(html).toContain(UNSUPPORTED_LEGACY_APP_HTML);
|
|
159
118
|
expect(html).not.toContain("<div>Hello</div>");
|
|
160
119
|
});
|
|
161
120
|
|
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
8
8
|
|
|
9
|
-
import { Minimatch } from "minimatch";
|
|
10
|
-
|
|
11
9
|
import { CompactionCircuit } from "../agent/compaction-circuit.js";
|
|
12
10
|
import type { AgentEvent } from "../agent/loop.js";
|
|
13
11
|
import type { ConfirmationStateChangedEvent } from "../api/events/confirmation-state-changed.js";
|
|
@@ -38,26 +36,6 @@ mock.module("../config/skill-state.js", () => ({
|
|
|
38
36
|
resolveSkillStates: () => [],
|
|
39
37
|
}));
|
|
40
38
|
|
|
41
|
-
// Trust store mock — uses real minimatch for patternMatchesCandidate so the
|
|
42
|
-
// mock doesn't break trust-store-pattern-matches.test.ts when both files run
|
|
43
|
-
// in the same Bun process (mock.module leaks across test files).
|
|
44
|
-
mock.module("../permissions/trust-store.js", () => ({
|
|
45
|
-
addRule: () => {},
|
|
46
|
-
findHighestPriorityRule: () => null,
|
|
47
|
-
clearCache: () => {},
|
|
48
|
-
patternMatchesCandidate: (pattern: string, candidate: string): boolean => {
|
|
49
|
-
try {
|
|
50
|
-
return new Minimatch(pattern).match(candidate);
|
|
51
|
-
} catch {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
},
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
mock.module("../security/secret-allowlist.js", () => ({
|
|
58
|
-
resetAllowlist: () => {},
|
|
59
|
-
}));
|
|
60
|
-
|
|
61
39
|
mock.module("../persistence/conversation-crud.js", () => ({
|
|
62
40
|
setConversationProcessingStartedAt: () => {},
|
|
63
41
|
isConversationProcessing: () => false,
|
|
@@ -23,27 +23,6 @@ const addRuleCalls: Array<{
|
|
|
23
23
|
priority?: number;
|
|
24
24
|
options?: { executionTarget?: string };
|
|
25
25
|
}> = [];
|
|
26
|
-
mock.module("../permissions/trust-store.js", () => ({
|
|
27
|
-
addRule: (
|
|
28
|
-
tool: string,
|
|
29
|
-
pattern: string,
|
|
30
|
-
scope: string,
|
|
31
|
-
decision: string,
|
|
32
|
-
priority?: number,
|
|
33
|
-
options?: { executionTarget?: string },
|
|
34
|
-
) => {
|
|
35
|
-
addRuleCalls.push({ tool, pattern, scope, decision, priority, options });
|
|
36
|
-
return {
|
|
37
|
-
id: "test-rule",
|
|
38
|
-
tool,
|
|
39
|
-
pattern,
|
|
40
|
-
scope,
|
|
41
|
-
decision,
|
|
42
|
-
priority: priority ?? 100,
|
|
43
|
-
};
|
|
44
|
-
},
|
|
45
|
-
getRules: () => [],
|
|
46
|
-
}));
|
|
47
26
|
|
|
48
27
|
// ---------------------------------------------------------------------------
|
|
49
28
|
// Module mocks for direct-import deps used by conversation-routes ROUTES
|
|
@@ -132,8 +132,7 @@ describe("parseDirectives", () => {
|
|
|
132
132
|
});
|
|
133
133
|
|
|
134
134
|
test("preserves non-self-closing tags as plain text", () => {
|
|
135
|
-
const text =
|
|
136
|
-
'<cadet-attachment path="file.txt">content</cadet-attachment>';
|
|
135
|
+
const text = '<cadet-attachment path="file.txt">content</cadet-attachment>';
|
|
137
136
|
const result = parseDirectives(text);
|
|
138
137
|
|
|
139
138
|
// The regex only matches self-closing tags, so non-self-closing is not matched
|
|
@@ -816,16 +816,14 @@ describe("drainDirectiveDisplayBuffer", () => {
|
|
|
816
816
|
});
|
|
817
817
|
|
|
818
818
|
test("does not insert space when stripped directive already has trailing whitespace", () => {
|
|
819
|
-
const input =
|
|
820
|
-
'sentence. <cadet-attachment path="out.png" />Next sentence.';
|
|
819
|
+
const input = 'sentence. <cadet-attachment path="out.png" />Next sentence.';
|
|
821
820
|
const result = drainDirectiveDisplayBuffer(input);
|
|
822
821
|
expect(result.emitText).toBe("sentence. Next sentence.");
|
|
823
822
|
expect(result.bufferedRemainder).toBe("");
|
|
824
823
|
});
|
|
825
824
|
|
|
826
825
|
test("does not insert space when stripped directive already has leading whitespace on next char", () => {
|
|
827
|
-
const input =
|
|
828
|
-
'sentence.<cadet-attachment path="out.png" /> Next sentence.';
|
|
826
|
+
const input = 'sentence.<cadet-attachment path="out.png" /> Next sentence.';
|
|
829
827
|
const result = drainDirectiveDisplayBuffer(input);
|
|
830
828
|
expect(result.emitText).toBe("sentence. Next sentence.");
|
|
831
829
|
expect(result.bufferedRemainder).toBe("");
|