@vellumai/assistant 0.8.0 → 0.8.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/AGENTS.md +11 -0
- package/Dockerfile +5 -4
- package/README.md +2 -2
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4847 -1698
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +21 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +23 -3
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +118 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +2 -4
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +23 -4
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +162 -516
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +76 -14
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +32 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
- package/src/daemon/conversation-agent-loop.ts +127 -97
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +46 -5
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +76 -12
- package/src/daemon/conversation-tool-setup.ts +24 -14
- package/src/daemon/conversation.ts +48 -9
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +42 -43
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +9 -2
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +40 -53
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +148 -127
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +55 -6
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +76 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +44 -5
- package/src/memory/indexer.ts +17 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
- package/src/memory/jobs/embed-concept-page.ts +45 -9
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +52 -3
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +1 -4
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +11 -4
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +628 -10
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +440 -109
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +100 -87
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +15 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +19 -3
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +12 -4
- package/src/proactive-artifact/job.ts +4 -0
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +303 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +0 -18
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +334 -86
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-v2-routes.ts +13 -398
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/memory/register.test.ts +3 -3
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +13 -5
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +22 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -498
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -476
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import {
|
|
2
|
+
appendFileSync,
|
|
3
|
+
existsSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
writeFileSync,
|
|
6
|
+
} from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
import { getLogger } from "../../util/logger.js";
|
|
10
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
11
|
+
|
|
12
|
+
const log = getLogger(
|
|
13
|
+
"workspace-migration-074-drop-deprecated-secret-detection-keys",
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const MIGRATION_ID = "074-drop-deprecated-secret-detection-keys";
|
|
17
|
+
const NOTICE_MARKER = `<!-- release-note-id:${MIGRATION_ID} -->`;
|
|
18
|
+
|
|
19
|
+
function buildNotice(previousAction: string): string {
|
|
20
|
+
return `${NOTICE_MARKER}
|
|
21
|
+
## Heads-up: tool-output secret scanning was retired
|
|
22
|
+
|
|
23
|
+
Your previous \`secretDetection.action\` setting was \`"${previousAction}"\`,
|
|
24
|
+
which used to gate or redact tool output containing high-entropy strings or
|
|
25
|
+
matches against custom regex patterns. That post-execution scanning layer has
|
|
26
|
+
been removed because it was false-positive prone and prevented the assistant
|
|
27
|
+
from acting on values it had legitimately fetched.
|
|
28
|
+
|
|
29
|
+
Prefix-based ingress detection on user messages is still active
|
|
30
|
+
(\`secretDetection.enabled\` / \`secretDetection.blockIngress\`), and the
|
|
31
|
+
\`secretDetection.entropyThreshold\` and \`secretDetection.customPatterns\`
|
|
32
|
+
fields have been removed from your config. If you relied on the old behavior,
|
|
33
|
+
please reach out so we can find a better solution for your use case.
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const dropDeprecatedSecretDetectionKeysMigration: WorkspaceMigration = {
|
|
38
|
+
id: MIGRATION_ID,
|
|
39
|
+
description:
|
|
40
|
+
"Strip removed secretDetection.action / entropyThreshold / customPatterns keys; notify users who had a non-default action policy",
|
|
41
|
+
|
|
42
|
+
run(workspaceDir: string): void {
|
|
43
|
+
const configPath = join(workspaceDir, "config.json");
|
|
44
|
+
if (!existsSync(configPath)) return;
|
|
45
|
+
|
|
46
|
+
let config: Record<string, unknown>;
|
|
47
|
+
try {
|
|
48
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
49
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
50
|
+
config = raw as Record<string, unknown>;
|
|
51
|
+
} catch {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const secretDetection = readObject(config.secretDetection);
|
|
56
|
+
if (secretDetection === null) return;
|
|
57
|
+
|
|
58
|
+
const previousAction =
|
|
59
|
+
typeof secretDetection.action === "string"
|
|
60
|
+
? secretDetection.action
|
|
61
|
+
: null;
|
|
62
|
+
|
|
63
|
+
let mutated = false;
|
|
64
|
+
for (const key of ["action", "entropyThreshold", "customPatterns"]) {
|
|
65
|
+
if (key in secretDetection) {
|
|
66
|
+
delete secretDetection[key];
|
|
67
|
+
mutated = true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (mutated) {
|
|
72
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (previousAction === "block" || previousAction === "prompt") {
|
|
76
|
+
appendNotice(workspaceDir, previousAction);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
down(_workspaceDir: string): void {
|
|
81
|
+
// Forward-only: restoring the deleted keys would re-introduce schema
|
|
82
|
+
// warnings without changing runtime behavior — the post-execution scanner
|
|
83
|
+
// they used to drive no longer exists.
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function appendNotice(workspaceDir: string, previousAction: string): void {
|
|
88
|
+
const updatesPath = join(workspaceDir, "UPDATES.md");
|
|
89
|
+
const notice = buildNotice(previousAction);
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
if (existsSync(updatesPath)) {
|
|
93
|
+
const existing = readFileSync(updatesPath, "utf-8");
|
|
94
|
+
if (existing.includes(NOTICE_MARKER)) return;
|
|
95
|
+
const prefix = existing.endsWith("\n") ? "\n" : "\n\n";
|
|
96
|
+
appendFileSync(updatesPath, `${prefix}${notice}`, "utf-8");
|
|
97
|
+
} else {
|
|
98
|
+
writeFileSync(updatesPath, notice, "utf-8");
|
|
99
|
+
}
|
|
100
|
+
log.info(
|
|
101
|
+
{ path: updatesPath, previousAction },
|
|
102
|
+
"Appended secret-detection retirement notice",
|
|
103
|
+
);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
log.warn(
|
|
106
|
+
{ err, path: updatesPath, previousAction },
|
|
107
|
+
"Failed to append secret-detection retirement notice to UPDATES.md",
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
113
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return value as Record<string, unknown>;
|
|
117
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { Database } from "bun:sqlite";
|
|
5
|
+
|
|
6
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Enqueue a one-shot `memory_v2_reembed` job so existing concept pages pick
|
|
10
|
+
* up the new `memory.v2.bm25_b` default (0.4, lowered from 0.75 in PR
|
|
11
|
+
* #29345). `embed_concept_page` bakes `bm25_b` into the stored sparse
|
|
12
|
+
* vectors at write time, so without this nudge workspaces that never pinned
|
|
13
|
+
* the field would silently mix old and new length normalization until a
|
|
14
|
+
* manual reembed.
|
|
15
|
+
*/
|
|
16
|
+
export const memoryV2Bm25BDefaultReembedMigration: WorkspaceMigration = {
|
|
17
|
+
id: "075-memory-v2-bm25-b-default-reembed",
|
|
18
|
+
description:
|
|
19
|
+
"Enqueue memory_v2_reembed so existing concept pages pick up the new bm25_b=0.4 default",
|
|
20
|
+
|
|
21
|
+
run(workspaceDir: string): void {
|
|
22
|
+
const dbPath = join(workspaceDir, "data", "db", "assistant.db");
|
|
23
|
+
if (!existsSync(dbPath)) return; // Fresh install — pages will embed at the new default.
|
|
24
|
+
|
|
25
|
+
let db: Database;
|
|
26
|
+
try {
|
|
27
|
+
db = new Database(dbPath);
|
|
28
|
+
} catch {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const tableRow = db
|
|
34
|
+
.query(
|
|
35
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name='memory_jobs'`,
|
|
36
|
+
)
|
|
37
|
+
.get();
|
|
38
|
+
if (!tableRow) return;
|
|
39
|
+
|
|
40
|
+
const existing = db
|
|
41
|
+
.query(
|
|
42
|
+
`SELECT id FROM memory_jobs WHERE type='memory_v2_reembed' AND status IN ('pending','running') LIMIT 1`,
|
|
43
|
+
)
|
|
44
|
+
.get();
|
|
45
|
+
if (existing) return;
|
|
46
|
+
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
db.query(
|
|
49
|
+
`INSERT INTO memory_jobs
|
|
50
|
+
(id, type, payload, status, attempts, deferrals, run_after, last_error, created_at, updated_at)
|
|
51
|
+
VALUES (?, 'memory_v2_reembed', '{}', 'pending', 0, 0, ?, NULL, ?, ?)`,
|
|
52
|
+
).run(randomUUID(), now, now, now);
|
|
53
|
+
} finally {
|
|
54
|
+
db.close();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
down(_workspaceDir: string): void {
|
|
59
|
+
// Forward-only: the reembed is a one-shot data refresh.
|
|
60
|
+
},
|
|
61
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Strip the now-removed `services.inference.mode` field from existing
|
|
8
|
+
* `config.json` files. The field governed the global `managed` vs `your-own`
|
|
9
|
+
* routing toggle that was superseded by the `provider_connections` table. Auth
|
|
10
|
+
* routing is now per-profile via the `provider_connection` reference; there is
|
|
11
|
+
* no longer a schema-level field to store here.
|
|
12
|
+
*
|
|
13
|
+
* If `services.inference` becomes an empty object after stripping, it is left
|
|
14
|
+
* as `{}` — the schema still expects the key to be present (other code walks
|
|
15
|
+
* `config.services.inference`).
|
|
16
|
+
*
|
|
17
|
+
* Idempotent: re-running when `mode` is already absent is a no-op.
|
|
18
|
+
*/
|
|
19
|
+
export const dropServicesInferenceModeMigration: WorkspaceMigration = {
|
|
20
|
+
id: "076-drop-services-inference-mode",
|
|
21
|
+
description:
|
|
22
|
+
"Strip services.inference.mode from config.json (mode field removed from schema)",
|
|
23
|
+
run(workspaceDir: string): void {
|
|
24
|
+
const configPath = join(workspaceDir, "config.json");
|
|
25
|
+
if (!existsSync(configPath)) return;
|
|
26
|
+
|
|
27
|
+
let config: Record<string, unknown>;
|
|
28
|
+
try {
|
|
29
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
30
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
31
|
+
config = raw as Record<string, unknown>;
|
|
32
|
+
} catch {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const services = config.services;
|
|
37
|
+
if (
|
|
38
|
+
services === null ||
|
|
39
|
+
typeof services !== "object" ||
|
|
40
|
+
Array.isArray(services)
|
|
41
|
+
)
|
|
42
|
+
return;
|
|
43
|
+
|
|
44
|
+
const inference = (services as Record<string, unknown>).inference;
|
|
45
|
+
if (
|
|
46
|
+
inference === null ||
|
|
47
|
+
typeof inference !== "object" ||
|
|
48
|
+
Array.isArray(inference)
|
|
49
|
+
)
|
|
50
|
+
return;
|
|
51
|
+
|
|
52
|
+
const inferenceObj = inference as Record<string, unknown>;
|
|
53
|
+
if (!("mode" in inferenceObj)) return;
|
|
54
|
+
|
|
55
|
+
delete inferenceObj.mode;
|
|
56
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
57
|
+
},
|
|
58
|
+
down(_workspaceDir: string): void {
|
|
59
|
+
// Forward-only: re-adding mode would reintroduce a field the schema no
|
|
60
|
+
// longer recognizes.
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Seed `callSites.memoryRouter = { model: "claude-sonnet-4-6",
|
|
8
|
+
* contextWindow: { maxInputTokens: 1000000 } }` so the per-turn memory
|
|
9
|
+
* router runs on Sonnet 4.6 with the 1M context window by default.
|
|
10
|
+
*
|
|
11
|
+
* The router builds a numbered page index in the system prompt; a 1M
|
|
12
|
+
* context window keeps every concept page reachable even on large
|
|
13
|
+
* workspaces, and Sonnet 4.6 is the cheapest 1M-context Anthropic
|
|
14
|
+
* model that handles the routing task well. Without this seed the
|
|
15
|
+
* call site would inherit the workspace default model, which may
|
|
16
|
+
* cap context at 200k and silently truncate the index for large
|
|
17
|
+
* workspaces.
|
|
18
|
+
*
|
|
19
|
+
* Mirrors {@link seedMainAgentOpusCallsiteMigration} (050):
|
|
20
|
+
*
|
|
21
|
+
* 1. Existing workspace (config.json present): merge the seed into
|
|
22
|
+
* `llm.callSites` without overwriting a user-defined override.
|
|
23
|
+
* 2. Fresh install (config.json absent): write a minimal starter
|
|
24
|
+
* config carrying just the seed; `loadConfig()` applies schema
|
|
25
|
+
* defaults to the in-memory config after migrations run.
|
|
26
|
+
*
|
|
27
|
+
* Skipped when:
|
|
28
|
+
* - `VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH` is set (platform overlay wins),
|
|
29
|
+
* - the user already has `llm.callSites.memoryRouter` (any override stays),
|
|
30
|
+
* - the resolved provider is non-Anthropic (those workspaces pick their
|
|
31
|
+
* own equivalent — we don't know which OpenAI/Gemini/Ollama model the
|
|
32
|
+
* operator wants for the routing role).
|
|
33
|
+
*/
|
|
34
|
+
export const seedMemoryRouterCallsiteMigration: WorkspaceMigration = {
|
|
35
|
+
id: "077-seed-memory-router-callsite",
|
|
36
|
+
description:
|
|
37
|
+
"Seed callSites.memoryRouter to claude-sonnet-4-6 + 1M context for Anthropic",
|
|
38
|
+
run(workspaceDir: string): void {
|
|
39
|
+
if (process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH) return;
|
|
40
|
+
|
|
41
|
+
const configPath = join(workspaceDir, "config.json");
|
|
42
|
+
const configExisted = existsSync(configPath);
|
|
43
|
+
|
|
44
|
+
let config: Record<string, unknown> = {};
|
|
45
|
+
if (configExisted) {
|
|
46
|
+
try {
|
|
47
|
+
const raw = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
48
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
|
|
49
|
+
config = raw as Record<string, unknown>;
|
|
50
|
+
} catch {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const llm = readObject(config.llm) ?? {};
|
|
56
|
+
const defaultBlock = readObject(llm.default);
|
|
57
|
+
|
|
58
|
+
const explicitProvider = readString(defaultBlock?.provider);
|
|
59
|
+
if (explicitProvider !== undefined && explicitProvider !== "anthropic") {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const callSites = readObject(llm.callSites) ?? {};
|
|
64
|
+
if (readObject(callSites.memoryRouter) !== null) return;
|
|
65
|
+
|
|
66
|
+
callSites.memoryRouter = {
|
|
67
|
+
model: "claude-sonnet-4-6",
|
|
68
|
+
contextWindow: { maxInputTokens: 1_000_000 },
|
|
69
|
+
};
|
|
70
|
+
llm.callSites = callSites;
|
|
71
|
+
config.llm = llm;
|
|
72
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
73
|
+
},
|
|
74
|
+
down(_workspaceDir: string): void {
|
|
75
|
+
// Forward-only: removing the seed would downgrade the router to the
|
|
76
|
+
// workspace default model on every re-run, defeating the goal.
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
function readObject(value: unknown): Record<string, unknown> | null {
|
|
81
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return value as Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function readString(value: unknown): string | undefined {
|
|
88
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
89
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
appendFileSync,
|
|
3
|
+
existsSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
writeFileSync,
|
|
6
|
+
} from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
|
|
9
|
+
import { getLogger } from "../../util/logger.js";
|
|
10
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
11
|
+
|
|
12
|
+
const log = getLogger(
|
|
13
|
+
"workspace-migration-078-release-notes-tavily-web-search",
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const MIGRATION_ID = "078-release-notes-tavily-web-search";
|
|
17
|
+
const MARKER = `<!-- release-note-id:${MIGRATION_ID} -->`;
|
|
18
|
+
|
|
19
|
+
const RELEASE_NOTE = `${MARKER}
|
|
20
|
+
## Tavily web search
|
|
21
|
+
|
|
22
|
+
Tavily is now available as a web search provider. Add your Tavily API key in
|
|
23
|
+
Settings → Models & Services, or run \`assistant keys set tavily <key>\`, then
|
|
24
|
+
select Tavily for Web Search.
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
export const releaseNotesTavilyWebSearchMigration: WorkspaceMigration = {
|
|
28
|
+
id: MIGRATION_ID,
|
|
29
|
+
description: "Append release notes for Tavily web search to UPDATES.md",
|
|
30
|
+
|
|
31
|
+
run(workspaceDir: string): void {
|
|
32
|
+
const updatesPath = join(workspaceDir, "UPDATES.md");
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
if (existsSync(updatesPath)) {
|
|
36
|
+
const existing = readFileSync(updatesPath, "utf-8");
|
|
37
|
+
if (existing.includes(MARKER)) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const needsLeadingNewline = !existing.endsWith("\n\n");
|
|
41
|
+
const prefix = existing.endsWith("\n") ? "\n" : "\n\n";
|
|
42
|
+
appendFileSync(
|
|
43
|
+
updatesPath,
|
|
44
|
+
needsLeadingNewline ? `${prefix}${RELEASE_NOTE}` : RELEASE_NOTE,
|
|
45
|
+
"utf-8",
|
|
46
|
+
);
|
|
47
|
+
} else {
|
|
48
|
+
writeFileSync(updatesPath, RELEASE_NOTE, "utf-8");
|
|
49
|
+
}
|
|
50
|
+
log.info(
|
|
51
|
+
{ path: updatesPath },
|
|
52
|
+
"Appended Tavily web search release note",
|
|
53
|
+
);
|
|
54
|
+
} catch (err) {
|
|
55
|
+
log.warn(
|
|
56
|
+
{ err, path: updatesPath },
|
|
57
|
+
"Failed to append Tavily web search release note to UPDATES.md",
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
down(_workspaceDir: string): void {
|
|
63
|
+
// Forward-only: UPDATES.md is a user-facing bulletin the assistant
|
|
64
|
+
// processes and deletes on its own.
|
|
65
|
+
},
|
|
66
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace migration `076-home-feed-notification-only`.
|
|
3
|
+
*
|
|
4
|
+
* Rewrites `<workspace>/data/home-feed.json` from the legacy v1 schema
|
|
5
|
+
* (mixed `nudge | digest | action | thread` types with `source`,
|
|
6
|
+
* `author`, `minTimeAway` fields) into the collapsed v2 schema (single
|
|
7
|
+
* `notification` type, no source/author/minTimeAway).
|
|
8
|
+
*
|
|
9
|
+
* Behaviour:
|
|
10
|
+
* - Missing file → no-op.
|
|
11
|
+
* - Malformed JSON → log and no-op (daemon startup must never block;
|
|
12
|
+
* the writer's `readHomeFeed()` already treats unreadable files as
|
|
13
|
+
* empty so the next append cycle naturally rewrites a clean file).
|
|
14
|
+
* - Already v2 → no-op (idempotent).
|
|
15
|
+
* - v1 (or any non-v2 shape with an `items` array): drop entries
|
|
16
|
+
* whose `type !== "action"` (legacy nudge/digest/thread items have
|
|
17
|
+
* no v2 analogue and weren't surfaced as live notifications anyway,
|
|
18
|
+
* per PR 15 of the home-notif-feed-revamp plan); for kept entries
|
|
19
|
+
* drop `source` / `author` / `minTimeAway` and rewrite `type` to
|
|
20
|
+
* `"notification"`. Persist as `{ version: 2, items, updatedAt }`.
|
|
21
|
+
*
|
|
22
|
+
* Idempotent: running the migration a second time on a v2 file is a
|
|
23
|
+
* no-op. The runner's checkpoint also skips re-runs, but this in-file
|
|
24
|
+
* guard keeps the migration safe even if the checkpoint is wiped.
|
|
25
|
+
*
|
|
26
|
+
* `down()` is a no-op — the legacy v1 fields (`source`, `author`,
|
|
27
|
+
* `minTimeAway`, the four item types) were dropped during the
|
|
28
|
+
* forward migration and cannot be recovered. Rolling back to v1 from
|
|
29
|
+
* v2 would also leave the writer producing a shape the older code
|
|
30
|
+
* cannot parse, so a real rollback would require reverting the writer
|
|
31
|
+
* code in lockstep.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
35
|
+
import { join } from "node:path";
|
|
36
|
+
|
|
37
|
+
import { getLogger } from "../../util/logger.js";
|
|
38
|
+
import type { WorkspaceMigration } from "./types.js";
|
|
39
|
+
|
|
40
|
+
const log = getLogger("workspace-migration-076-home-feed-notification-only");
|
|
41
|
+
|
|
42
|
+
const HOME_FEED_RELATIVE_PATH = join("data", "home-feed.json");
|
|
43
|
+
|
|
44
|
+
/** v2 file format. Mirrors `HomeFeedFile` in `home/feed-types.ts`. */
|
|
45
|
+
interface V2HomeFeedFile {
|
|
46
|
+
version: 2;
|
|
47
|
+
items: V2FeedItem[];
|
|
48
|
+
updatedAt: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* v2 item shape. Inlined rather than imported from `home/feed-types.ts`
|
|
53
|
+
* so the migration stays self-contained — per AGENTS.md migrations
|
|
54
|
+
* should minimise cross-module coupling so they remain stable as code
|
|
55
|
+
* around them evolves.
|
|
56
|
+
*/
|
|
57
|
+
interface V2FeedItem {
|
|
58
|
+
id: string;
|
|
59
|
+
type: "notification";
|
|
60
|
+
priority: number;
|
|
61
|
+
title: string;
|
|
62
|
+
summary: string;
|
|
63
|
+
timestamp: string;
|
|
64
|
+
status: string;
|
|
65
|
+
expiresAt?: string;
|
|
66
|
+
actions?: unknown[];
|
|
67
|
+
urgency?: string;
|
|
68
|
+
conversationId?: string;
|
|
69
|
+
detailPanel?: unknown;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const homeFeedNotificationOnlyMigration: WorkspaceMigration = {
|
|
74
|
+
id: "home-feed-notification-only-v2",
|
|
75
|
+
description:
|
|
76
|
+
"Rewrite home-feed.json into v2 schema (single 'notification' type)",
|
|
77
|
+
|
|
78
|
+
run(workspaceDir: string): void {
|
|
79
|
+
const path = join(workspaceDir, HOME_FEED_RELATIVE_PATH);
|
|
80
|
+
if (!existsSync(path)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let raw: unknown;
|
|
85
|
+
try {
|
|
86
|
+
raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
87
|
+
} catch (err) {
|
|
88
|
+
// Daemon startup must never block on a parse failure here. The
|
|
89
|
+
// writer's read path also treats malformed files as empty, so
|
|
90
|
+
// skipping the migration just means the next append cycle will
|
|
91
|
+
// overwrite the file with a fresh v2 snapshot.
|
|
92
|
+
log.warn(
|
|
93
|
+
{ err, path },
|
|
94
|
+
"Failed to parse home-feed.json; skipping migration",
|
|
95
|
+
);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (!isPlainObject(raw)) {
|
|
100
|
+
log.warn({ path }, "home-feed.json is not an object; skipping migration");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (raw.version === 2) {
|
|
105
|
+
// Already migrated.
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const rawItems = Array.isArray(raw.items) ? raw.items : [];
|
|
110
|
+
const items: V2FeedItem[] = [];
|
|
111
|
+
for (const entry of rawItems) {
|
|
112
|
+
const migrated = migrateItem(entry);
|
|
113
|
+
if (migrated) items.push(migrated);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const next: V2HomeFeedFile = {
|
|
117
|
+
version: 2,
|
|
118
|
+
items,
|
|
119
|
+
updatedAt: new Date().toISOString(),
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
writeFileSync(path, JSON.stringify(next, null, 2), "utf-8");
|
|
124
|
+
log.info(
|
|
125
|
+
{ path, items: items.length },
|
|
126
|
+
"Rewrote home-feed.json to v2 schema",
|
|
127
|
+
);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
log.warn(
|
|
130
|
+
{ err, path },
|
|
131
|
+
"Failed to write migrated home-feed.json; leaving prior file in place",
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
down(_workspaceDir: string): void {
|
|
137
|
+
// Lossy migration — legacy fields (source/author/minTimeAway and
|
|
138
|
+
// nudge/digest/thread items) cannot be reconstructed. The writer
|
|
139
|
+
// code itself only emits v2 now, so rolling back would also leave
|
|
140
|
+
// the file in a shape the v1 reader could not parse without
|
|
141
|
+
// reverting feed-writer.ts in lockstep.
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Convert a single legacy item into a v2 item, or return `null` to
|
|
147
|
+
* drop it. Only `type === "action"` items survive — legacy
|
|
148
|
+
* nudge/digest/thread entries have no v2 analogue and were not
|
|
149
|
+
* surfaced as live notifications by PR 4's wiring (only assistant-
|
|
150
|
+
* authored `action` items reached the live feed via
|
|
151
|
+
* `home-feed-side-effect.ts`).
|
|
152
|
+
*/
|
|
153
|
+
function migrateItem(entry: unknown): V2FeedItem | null {
|
|
154
|
+
if (!isPlainObject(entry)) return null;
|
|
155
|
+
if (entry.type !== "action") return null;
|
|
156
|
+
|
|
157
|
+
// Required fields — fail-soft on missing critical strings rather
|
|
158
|
+
// than throwing, so a single bad legacy entry does not lose the
|
|
159
|
+
// rest of the items.
|
|
160
|
+
if (
|
|
161
|
+
typeof entry.id !== "string" ||
|
|
162
|
+
typeof entry.title !== "string" ||
|
|
163
|
+
typeof entry.summary !== "string" ||
|
|
164
|
+
typeof entry.timestamp !== "string" ||
|
|
165
|
+
typeof entry.createdAt !== "string"
|
|
166
|
+
) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
const priority =
|
|
170
|
+
typeof entry.priority === "number" && Number.isInteger(entry.priority)
|
|
171
|
+
? entry.priority
|
|
172
|
+
: 50;
|
|
173
|
+
const status = typeof entry.status === "string" ? entry.status : "new";
|
|
174
|
+
|
|
175
|
+
const out: V2FeedItem = {
|
|
176
|
+
id: entry.id,
|
|
177
|
+
type: "notification",
|
|
178
|
+
priority,
|
|
179
|
+
title: entry.title,
|
|
180
|
+
summary: entry.summary,
|
|
181
|
+
timestamp: entry.timestamp,
|
|
182
|
+
status,
|
|
183
|
+
createdAt: entry.createdAt,
|
|
184
|
+
};
|
|
185
|
+
if (typeof entry.expiresAt === "string") out.expiresAt = entry.expiresAt;
|
|
186
|
+
if (Array.isArray(entry.actions)) out.actions = entry.actions;
|
|
187
|
+
if (typeof entry.urgency === "string") out.urgency = entry.urgency;
|
|
188
|
+
if (typeof entry.conversationId === "string") {
|
|
189
|
+
out.conversationId = entry.conversationId;
|
|
190
|
+
}
|
|
191
|
+
if (isPlainObject(entry.detailPanel)) out.detailPanel = entry.detailPanel;
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
196
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
197
|
+
}
|