@vellumai/assistant 0.7.1 → 0.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +48 -50
- package/Dockerfile +1 -0
- package/README.md +1 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
- package/bun.lock +26 -26
- package/docs/architecture/memory.md +5 -2
- package/docs/architecture/security.md +20 -0
- package/docs/plugins.md +7 -9
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +1020 -40
- package/package.json +6 -3
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +384 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-routes-http.test.ts +23 -6
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +157 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
- package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +49 -1
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +62 -2
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +461 -147
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
- package/src/__tests__/config-watcher.test.ts +142 -71
- package/src/__tests__/context-search-agent-runner.test.ts +61 -3
- package/src/__tests__/context-search-conversations-source.test.ts +0 -24
- package/src/__tests__/context-search-fanout.test.ts +0 -1
- package/src/__tests__/context-search-memory-source.test.ts +3 -7
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop.test.ts +454 -5
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +36 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-process-callsite.test.ts +43 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
- package/src/__tests__/conversation-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-store.test.ts +0 -18
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credentials-cli.test.ts +12 -12
- package/src/__tests__/cu-unified-flow.test.ts +351 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/date-context.test.ts +164 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/disk-pressure-guard.test.ts +262 -0
- package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
- package/src/__tests__/disk-pressure-policy.test.ts +241 -0
- package/src/__tests__/disk-pressure-routes.test.ts +379 -0
- package/src/__tests__/disk-pressure-tools.test.ts +277 -0
- package/src/__tests__/disk-usage.test.ts +150 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/events-client-registration.test.ts +52 -0
- package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
- package/src/__tests__/file-write-tool.test.ts +4 -10
- package/src/__tests__/filing-service.test.ts +3 -4
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +968 -2
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +772 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +439 -47
- package/src/__tests__/host-bash-routes.test.ts +459 -0
- package/src/__tests__/host-browser-proxy.test.ts +24 -22
- package/src/__tests__/host-browser-routes.test.ts +39 -13
- package/src/__tests__/host-cu-proxy.test.ts +248 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
- package/src/__tests__/host-file-proxy.test.ts +301 -45
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +22 -4
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
- package/src/__tests__/http-user-message-parity.test.ts +108 -1
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/injector-chain.test.ts +18 -6
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/onboarding-persona-write.test.ts +308 -0
- package/src/__tests__/openai-provider.test.ts +45 -8
- package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/platform-callback-registration.test.ts +21 -4
- package/src/__tests__/platform.test.ts +2 -1
- package/src/__tests__/playbook-execution.test.ts +0 -43
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/relay-server.test.ts +15 -4
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-events-sse.test.ts +2 -2
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
- package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
- package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/approvals/guardian-decision-primitive.ts +13 -0
- package/src/approvals/guardian-request-resolvers.ts +16 -17
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +51 -151
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +107 -231
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/app-bundler.ts +51 -3
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +4 -44
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +33 -105
- package/src/calls/twilio-routes.ts +11 -12
- package/src/channels/types.ts +8 -7
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +137 -25
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +71 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +9 -6
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +303 -7
- package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
- package/src/cli/commands/oauth/connect.ts +127 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +16 -25
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +6 -2
- package/src/config/assistant-feature-flags.ts +79 -12
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +0 -2
- package/src/config/env.ts +19 -20
- package/src/config/feature-flag-registry.json +47 -135
- package/src/config/loader.ts +197 -104
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +64 -1
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +7 -10
- package/src/config/schemas/memory-lifecycle.ts +90 -24
- package/src/config/schemas/memory-v2.ts +121 -13
- package/src/config/schemas/platform.ts +49 -3
- package/src/config/schemas/services.ts +29 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -55
- package/src/contacts/contacts-write.ts +0 -27
- package/src/context/window-manager.ts +1 -2
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +12 -41
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +89 -60
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
- package/src/daemon/conversation-agent-loop.ts +202 -61
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +9 -4
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-runtime-assembly.ts +28 -2
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +305 -4
- package/src/daemon/conversation-tool-setup.ts +66 -62
- package/src/daemon/conversation.ts +38 -24
- package/src/daemon/date-context.ts +71 -22
- package/src/daemon/disk-pressure-background-gate.ts +73 -0
- package/src/daemon/disk-pressure-guard.ts +343 -0
- package/src/daemon/disk-pressure-policy.ts +163 -0
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -2
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +389 -0
- package/src/daemon/host-bash-proxy.ts +117 -82
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +127 -86
- package/src/daemon/host-file-proxy.ts +129 -69
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +338 -129
- package/src/daemon/lifecycle.ts +194 -145
- package/src/daemon/meet-host-supervisor.ts +4 -4
- package/src/daemon/meet-manifest-loader.ts +0 -1
- package/src/daemon/memory-v2-startup.ts +14 -4
- package/src/daemon/message-protocol.ts +6 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +15 -8
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +4 -0
- package/src/daemon/message-types/host-cu.ts +2 -0
- package/src/daemon/message-types/host-file.ts +4 -0
- package/src/daemon/message-types/host-transfer.ts +3 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/shutdown-handlers.ts +0 -3
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/documents/document-store.ts +85 -0
- package/src/events/tool-audit-listener.ts +2 -1
- package/src/filing/filing-service.ts +30 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
- package/src/heartbeat/heartbeat-run-store.ts +249 -0
- package/src/heartbeat/heartbeat-service.ts +459 -54
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/feed-scheduler.ts +18 -0
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +17 -92
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +70 -3
- package/src/ipc/cli-client.ts +32 -1
- package/src/ipc/gateway-client.ts +37 -3
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/live-voice/protocol.ts +5 -7
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/media/image-service.ts +1 -7
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/admin.ts +5 -9
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +51 -9
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +22 -9
- package/src/memory/context-search/sources/memory.ts +0 -1
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +5 -13
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +6 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
- package/src/memory/graph/conversation-graph-memory.ts +43 -78
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +10 -67
- package/src/memory/graph/graph-search.ts +9 -20
- package/src/memory/graph/retriever.test.ts +6 -0
- package/src/memory/graph/retriever.ts +34 -10
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/indexer.ts +54 -45
- package/src/memory/job-handlers/backfill.ts +2 -11
- package/src/memory/job-handlers/cleanup.ts +43 -0
- package/src/memory/job-handlers/embedding.ts +6 -8
- package/src/memory/job-handlers/summarization.ts +2 -7
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +114 -22
- package/src/memory/jobs-worker.ts +193 -106
- package/src/memory/memory-v2-activation-log-store.ts +33 -15
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +49 -32
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +13 -67
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +387 -344
- package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
- package/src/memory/v2/__tests__/injection.test.ts +181 -169
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +154 -188
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +76 -2
- package/src/memory/v2/activation.ts +213 -239
- package/src/memory/v2/consolidation-job.ts +65 -17
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +123 -103
- package/src/memory/v2/prompts/consolidation.ts +348 -92
- package/src/memory/v2/qdrant.ts +198 -1
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +113 -77
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +91 -53
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +28 -5
- package/src/memory/v2/types.ts +10 -10
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/slack/adapter.ts +1 -31
- package/src/messaging/providers/slack/types.ts +0 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/copy-composer.ts +13 -0
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/notifications/signal.ts +4 -0
- package/src/oauth/AGENTS.md +3 -1
- package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
- package/src/oauth/connect-orchestrator.ts +6 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/outbound-proxy/index.ts +1 -37
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +3 -17
- package/src/permissions/gateway-threshold-reader.ts +2 -0
- package/src/permissions/prompter.ts +34 -1
- package/src/permissions/secret-prompter.ts +6 -2
- package/src/plugins/defaults/injectors.ts +35 -2
- package/src/plugins/defaults/memory-retrieval.ts +5 -6
- package/src/plugins/types.ts +7 -0
- package/src/proactive-artifact/aux-message-injector.ts +74 -0
- package/src/proactive-artifact/decision.test.ts +226 -0
- package/src/proactive-artifact/decision.ts +165 -0
- package/src/proactive-artifact/index.ts +7 -0
- package/src/proactive-artifact/job.test.ts +867 -0
- package/src/proactive-artifact/job.ts +352 -0
- package/src/proactive-artifact/message-copy.ts +41 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +23 -24
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/__tests__/retry-callsite.test.ts +222 -1
- package/src/providers/model-intents.ts +7 -0
- package/src/providers/openrouter/client.ts +8 -0
- package/src/providers/retry.ts +50 -0
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/providers/types.ts +1 -0
- package/src/runtime/__tests__/agent-wake.test.ts +456 -3
- package/src/runtime/agent-wake.ts +238 -100
- package/src/runtime/assistant-event-hub.ts +151 -99
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +32 -0
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/guardian-reply-router.ts +10 -0
- package/src/runtime/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
- package/src/runtime/migrations/migration-transport.ts +7 -7
- package/src/runtime/migrations/vbundle-builder.ts +327 -60
- package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +245 -68
- package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
- package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +114 -0
- package/src/runtime/pending-interactions.ts +43 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/client-routes.ts +21 -2
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +65 -39
- package/src/runtime/routes/debug-bash-routes.ts +163 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +169 -0
- package/src/runtime/routes/documents-routes.ts +32 -75
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +38 -0
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +56 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +66 -9
- package/src/runtime/routes/host-file-routes.ts +54 -5
- package/src/runtime/routes/host-transfer-routes.ts +122 -19
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +21 -180
- package/src/runtime/routes/inbound-message-handler.ts +78 -21
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +14 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.test.ts +41 -15
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +474 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -2
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +83 -39
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/remote-skill-policy.ts +10 -16
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/subagent/index.ts +1 -7
- package/src/subagent/manager.ts +1 -15
- package/src/tasks/task-runner.ts +0 -1
- package/src/tasks/task-store.ts +0 -3
- package/src/telemetry/types.ts +2 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/background-tool-registry.ts +17 -3
- package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +23 -24
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +2 -0
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +68 -0
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +68 -0
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +78 -3
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +68 -0
- package/src/tools/host-terminal/host-shell.ts +66 -1
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +12 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +32 -11
- package/src/tools/types.ts +28 -2
- package/src/tts/provider-catalog.ts +3 -5
- package/src/usage/pricing.ts +1 -1
- package/src/util/disk-usage.ts +138 -0
- package/src/util/platform.ts +21 -11
- package/src/util/process-liveness.ts +26 -0
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/heartbeat-service.ts +19 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
- package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
- package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -782
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -472
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -395
- package/src/outbound-proxy/config.ts +0 -20
- package/src/outbound-proxy/health.ts +0 -18
- package/src/outbound-proxy/types.ts +0 -150
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/signals/bash.ts +0 -198
- package/src/signals/mcp-reload.ts +0 -18
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
5
|
+
|
|
6
|
+
// ─── assistantEventHub mock ────────────────────────────────────────────
|
|
7
|
+
const publishSpy = mock<(event: unknown) => Promise<void>>(async () => {});
|
|
8
|
+
|
|
9
|
+
mock.module("../../runtime/assistant-event-hub.js", () => ({
|
|
10
|
+
assistantEventHub: {
|
|
11
|
+
publish: publishSpy,
|
|
12
|
+
subscribe: () => () => {},
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
const { emitPostConnectNudge } = await import("../post-connect-feed.js");
|
|
17
|
+
const { readHomeFeed } = await import("../feed-writer.js");
|
|
18
|
+
|
|
19
|
+
// ─── tmpdir workspace lifecycle ────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
let workspaceDir: string;
|
|
22
|
+
let origWorkspaceDir: string | undefined;
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
workspaceDir = mkdtempSync(join(tmpdir(), "vellum-pcf-"));
|
|
26
|
+
origWorkspaceDir = process.env.VELLUM_WORKSPACE_DIR;
|
|
27
|
+
process.env.VELLUM_WORKSPACE_DIR = workspaceDir;
|
|
28
|
+
publishSpy.mockClear();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
if (origWorkspaceDir === undefined) {
|
|
33
|
+
delete process.env.VELLUM_WORKSPACE_DIR;
|
|
34
|
+
} else {
|
|
35
|
+
process.env.VELLUM_WORKSPACE_DIR = origWorkspaceDir;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
rmSync(workspaceDir, { recursive: true, force: true });
|
|
39
|
+
} catch {
|
|
40
|
+
// best-effort
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// ─── Tests ─────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
describe("emitPostConnectNudge", () => {
|
|
47
|
+
test("emits a nudge feed item for google", async () => {
|
|
48
|
+
await emitPostConnectNudge("google");
|
|
49
|
+
|
|
50
|
+
const feed = readHomeFeed();
|
|
51
|
+
expect(feed.items).toHaveLength(1);
|
|
52
|
+
|
|
53
|
+
const item = feed.items[0]!;
|
|
54
|
+
expect(item.id).toBe("connect-nudge:google");
|
|
55
|
+
expect(item.type).toBe("nudge");
|
|
56
|
+
expect(item.source).toBe("gmail");
|
|
57
|
+
expect(item.title).toContain("Gmail connected");
|
|
58
|
+
expect(item.actions).toHaveLength(2);
|
|
59
|
+
expect(item.actions![0]!.label).toBe("Triage my inbox");
|
|
60
|
+
expect(item.actions![1]!.label).toBe("Set up daily digest");
|
|
61
|
+
expect(item.expiresAt).toBeDefined();
|
|
62
|
+
expect(item.author).toBe("platform");
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("no-ops for non-email services", async () => {
|
|
66
|
+
await emitPostConnectNudge("slack");
|
|
67
|
+
await emitPostConnectNudge("notion");
|
|
68
|
+
await emitPostConnectNudge("linear");
|
|
69
|
+
|
|
70
|
+
const feed = readHomeFeed();
|
|
71
|
+
expect(feed.items).toHaveLength(0);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("reconnecting appends a second nudge (same-author nudges don't deduplicate)", async () => {
|
|
75
|
+
await emitPostConnectNudge("google");
|
|
76
|
+
await emitPostConnectNudge("google");
|
|
77
|
+
|
|
78
|
+
const feed = readHomeFeed();
|
|
79
|
+
// Same-author (platform) same-source nudges both persist —
|
|
80
|
+
// the feed writer's author-resolution only handles cross-author
|
|
81
|
+
// replacement. In practice, reconnects are rare and the 7-day
|
|
82
|
+
// expiry prevents buildup.
|
|
83
|
+
expect(feed.items).toHaveLength(2);
|
|
84
|
+
expect(feed.items.every((i) => i.id === "connect-nudge:google")).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("nudge expires after 7 days", async () => {
|
|
88
|
+
await emitPostConnectNudge("google");
|
|
89
|
+
|
|
90
|
+
const feed = readHomeFeed();
|
|
91
|
+
const item = feed.items[0]!;
|
|
92
|
+
const created = new Date(item.createdAt).getTime();
|
|
93
|
+
const expires = new Date(item.expiresAt!).getTime();
|
|
94
|
+
const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;
|
|
95
|
+
|
|
96
|
+
// Allow 1 second tolerance for test execution time
|
|
97
|
+
expect(Math.abs(expires - created - sevenDaysMs)).toBeLessThan(1000);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -432,6 +432,12 @@ describe("relationship-state-writer", () => {
|
|
|
432
432
|
// Also sanity: it must be a real, recent date (not the epoch
|
|
433
433
|
// sentinel we emit when stat fails).
|
|
434
434
|
expect(Date.parse(first.hatchedDate)).toBeGreaterThan(0);
|
|
435
|
+
const sidecarPath = join(workspaceDir, "data", "hatched.json");
|
|
436
|
+
expect(existsSync(sidecarPath)).toBe(true);
|
|
437
|
+
const sidecar = JSON.parse(readFileSync(sidecarPath, "utf-8")) as {
|
|
438
|
+
hatchedAt: string;
|
|
439
|
+
};
|
|
440
|
+
expect(sidecar.hatchedAt).toBe(first.hatchedDate);
|
|
435
441
|
});
|
|
436
442
|
|
|
437
443
|
test("honors an explicit Hatched bullet in IDENTITY.md over file birthtime", async () => {
|
|
@@ -488,9 +494,10 @@ describe("relationship-state-writer", () => {
|
|
|
488
494
|
expect(state.hatchedDate).toBe("2025-01-15T00:00:00.000Z");
|
|
489
495
|
});
|
|
490
496
|
|
|
491
|
-
test("
|
|
492
|
-
// Seed
|
|
493
|
-
// explicit Hatched bullet —
|
|
497
|
+
test("sidecar takes precedence over IDENTITY.md metadata", async () => {
|
|
498
|
+
// Seed an existing sidecar and then an IDENTITY.md without an
|
|
499
|
+
// explicit Hatched bullet — the persisted sidecar wins so the
|
|
500
|
+
// date remains stable across later identity edits.
|
|
494
501
|
mkdirSync(join(workspaceDir, "data"), { recursive: true });
|
|
495
502
|
writeFileSync(
|
|
496
503
|
join(workspaceDir, "data", "hatched.json"),
|
|
@@ -500,12 +507,7 @@ describe("relationship-state-writer", () => {
|
|
|
500
507
|
writeFile("IDENTITY.md", "- **Name:** Sage\n- **Role:** Assistant\n");
|
|
501
508
|
|
|
502
509
|
const state = (await computeRelationshipState()) as RelationshipStateLike;
|
|
503
|
-
|
|
504
|
-
// written, so birthtime will be a much more recent date.
|
|
505
|
-
expect(state.hatchedDate).not.toBe("2020-06-01T00:00:00.000Z");
|
|
506
|
-
expect(Date.parse(state.hatchedDate)).toBeGreaterThan(
|
|
507
|
-
Date.parse("2020-06-01T00:00:00.000Z"),
|
|
508
|
-
);
|
|
510
|
+
expect(state.hatchedDate).toBe("2020-06-01T00:00:00.000Z");
|
|
509
511
|
});
|
|
510
512
|
});
|
|
511
513
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
// ─── Mocks ─────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
let mockConnectedProviders = new Set<string>();
|
|
6
|
+
|
|
7
|
+
mock.module("../../oauth/oauth-store.js", () => ({
|
|
8
|
+
isProviderConnected: async (provider: string) =>
|
|
9
|
+
mockConnectedProviders.has(provider),
|
|
10
|
+
listProviders: () => [
|
|
11
|
+
{ provider: "google" },
|
|
12
|
+
{ provider: "slack" },
|
|
13
|
+
{ provider: "notion" },
|
|
14
|
+
{ provider: "linear" },
|
|
15
|
+
{ provider: "github" },
|
|
16
|
+
],
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
mock.module("../../util/logger.js", () => ({
|
|
20
|
+
getLogger: () =>
|
|
21
|
+
new Proxy({} as Record<string, unknown>, {
|
|
22
|
+
get: () => () => {},
|
|
23
|
+
}),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
const { getSuggestedPrompts } = await import("../suggested-prompts.js");
|
|
27
|
+
|
|
28
|
+
// ─── Tests ─────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
describe("getSuggestedPrompts", () => {
|
|
31
|
+
test("shows 'Connect X' prompts when providers are disconnected", async () => {
|
|
32
|
+
mockConnectedProviders = new Set();
|
|
33
|
+
|
|
34
|
+
const prompts = await getSuggestedPrompts();
|
|
35
|
+
const ids = prompts.map((p) => p.id);
|
|
36
|
+
|
|
37
|
+
expect(ids).toContain("connect-google");
|
|
38
|
+
expect(ids).toContain("connect-slack");
|
|
39
|
+
expect(prompts.find((p) => p.id === "connect-google")!.label).toBe(
|
|
40
|
+
"Connect Gmail",
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("shows email management prompts when Google is connected", async () => {
|
|
45
|
+
mockConnectedProviders = new Set(["google"]);
|
|
46
|
+
|
|
47
|
+
const prompts = await getSuggestedPrompts();
|
|
48
|
+
const ids = prompts.map((p) => p.id);
|
|
49
|
+
|
|
50
|
+
// Should NOT show "Connect Gmail"
|
|
51
|
+
expect(ids).not.toContain("connect-google");
|
|
52
|
+
|
|
53
|
+
// Should show management prompts
|
|
54
|
+
expect(ids).toContain("manage-google-triage-my-inbox");
|
|
55
|
+
expect(ids).toContain("manage-google-summarize-today's-emails");
|
|
56
|
+
|
|
57
|
+
const triage = prompts.find(
|
|
58
|
+
(p) => p.id === "manage-google-triage-my-inbox",
|
|
59
|
+
);
|
|
60
|
+
expect(triage).toBeDefined();
|
|
61
|
+
expect(triage!.label).toBe("Triage my inbox");
|
|
62
|
+
expect(triage!.icon).toBe("mail");
|
|
63
|
+
expect(triage!.source).toBe("deterministic");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("still shows Connect prompts for disconnected providers alongside management prompts", async () => {
|
|
67
|
+
mockConnectedProviders = new Set(["google"]);
|
|
68
|
+
|
|
69
|
+
const prompts = await getSuggestedPrompts();
|
|
70
|
+
const ids = prompts.map((p) => p.id);
|
|
71
|
+
|
|
72
|
+
// Gmail management prompts
|
|
73
|
+
expect(ids).toContain("manage-google-triage-my-inbox");
|
|
74
|
+
// Slack still disconnected
|
|
75
|
+
expect(ids).toContain("connect-slack");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("providers without connectedPrompts show nothing when connected", async () => {
|
|
79
|
+
mockConnectedProviders = new Set(["slack"]);
|
|
80
|
+
|
|
81
|
+
const prompts = await getSuggestedPrompts();
|
|
82
|
+
const ids = prompts.map((p) => p.id);
|
|
83
|
+
|
|
84
|
+
// No connect prompt since connected
|
|
85
|
+
expect(ids).not.toContain("connect-slack");
|
|
86
|
+
// No management prompts since Slack doesn't define any
|
|
87
|
+
expect(ids.filter((id) => id.startsWith("manage-slack"))).toHaveLength(0);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
* scheduler needing to touch the event hub.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
+
import {
|
|
32
|
+
checkDiskPressureBackgroundGate,
|
|
33
|
+
diskPressureBackgroundSkipLogFields,
|
|
34
|
+
shouldLogDiskPressureBackgroundSkip,
|
|
35
|
+
} from "../daemon/disk-pressure-background-gate.js";
|
|
31
36
|
import { getLogger } from "../util/logger.js";
|
|
32
37
|
import type { FeedItem } from "./feed-types.js";
|
|
33
38
|
import {
|
|
@@ -119,6 +124,19 @@ export function startFeedScheduler(
|
|
|
119
124
|
rollupRan: false,
|
|
120
125
|
};
|
|
121
126
|
if (stopped || tickRunning) return summary;
|
|
127
|
+
const diskPressureGate = checkDiskPressureBackgroundGate("background-work");
|
|
128
|
+
if (diskPressureGate.action === "skip") {
|
|
129
|
+
if (shouldLogDiskPressureBackgroundSkip("home-feed-scheduler")) {
|
|
130
|
+
log.warn(
|
|
131
|
+
{
|
|
132
|
+
source: "feed-scheduler",
|
|
133
|
+
...diskPressureBackgroundSkipLogFields(diskPressureGate),
|
|
134
|
+
},
|
|
135
|
+
"Home feed scheduler skipped during disk pressure cleanup mode",
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
return summary;
|
|
139
|
+
}
|
|
122
140
|
tickRunning = true;
|
|
123
141
|
const nowMs = now.getTime();
|
|
124
142
|
try {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-connection feed nudge.
|
|
3
|
+
*
|
|
4
|
+
* Emits a one-time nudge feed item when the user successfully connects
|
|
5
|
+
* an email-capable OAuth provider. The nudge highlights ongoing email
|
|
6
|
+
* management capabilities (inbox triage, daily digests) so the user
|
|
7
|
+
* discovers what they can do beyond the initial setup.
|
|
8
|
+
*
|
|
9
|
+
* Uses a deterministic id (`connect-nudge:<service>`) so reconnecting
|
|
10
|
+
* the same provider replaces the existing nudge in place rather than
|
|
11
|
+
* appending a duplicate.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { FeedItem } from "./feed-types.js";
|
|
15
|
+
import { appendFeedItem } from "./feed-writer.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Services that should trigger an email management nudge on connection.
|
|
19
|
+
* Only providers with real email integration are listed — see
|
|
20
|
+
* `relationship-state-writer.ts` for the same "only Gmail is real" note.
|
|
21
|
+
*/
|
|
22
|
+
const EMAIL_SERVICES = new Set(["google"]);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Emit a feed nudge for a newly connected email provider.
|
|
26
|
+
*
|
|
27
|
+
* No-ops silently when the service is not email-capable. Never throws —
|
|
28
|
+
* the feed writer's warn-log contract absorbs persistence failures.
|
|
29
|
+
*/
|
|
30
|
+
export async function emitPostConnectNudge(service: string): Promise<void> {
|
|
31
|
+
if (!EMAIL_SERVICES.has(service)) return;
|
|
32
|
+
|
|
33
|
+
const now = new Date();
|
|
34
|
+
const expiresAt = new Date(
|
|
35
|
+
now.getTime() + 7 * 24 * 60 * 60 * 1000,
|
|
36
|
+
).toISOString();
|
|
37
|
+
|
|
38
|
+
const item: FeedItem = {
|
|
39
|
+
id: `connect-nudge:${service}`,
|
|
40
|
+
type: "nudge",
|
|
41
|
+
priority: 70,
|
|
42
|
+
title: "Gmail connected — want ongoing help?",
|
|
43
|
+
summary:
|
|
44
|
+
"I can triage your inbox, summarize new emails, or draft replies to important threads.",
|
|
45
|
+
source: "gmail",
|
|
46
|
+
timestamp: now.toISOString(),
|
|
47
|
+
status: "new",
|
|
48
|
+
expiresAt,
|
|
49
|
+
author: "platform",
|
|
50
|
+
createdAt: now.toISOString(),
|
|
51
|
+
actions: [
|
|
52
|
+
{
|
|
53
|
+
id: "inbox-triage",
|
|
54
|
+
label: "Triage my inbox",
|
|
55
|
+
prompt:
|
|
56
|
+
"Help me triage my inbox — summarize what's unread and flag anything that needs a reply",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "daily-digest",
|
|
60
|
+
label: "Set up daily digest",
|
|
61
|
+
prompt:
|
|
62
|
+
"Set up a daily email digest that summarizes my unread messages each morning",
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
await appendFeedItem(item);
|
|
68
|
+
}
|
|
@@ -18,13 +18,7 @@
|
|
|
18
18
|
* a missing or unreadable file degrades gracefully to an empty string.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import {
|
|
22
|
-
existsSync,
|
|
23
|
-
mkdirSync,
|
|
24
|
-
readFileSync,
|
|
25
|
-
statSync,
|
|
26
|
-
writeFileSync,
|
|
27
|
-
} from "node:fs";
|
|
21
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
28
22
|
import { join } from "node:path";
|
|
29
23
|
|
|
30
24
|
import { countConversations as countConversationsDb } from "../memory/conversation-queries.js";
|
|
@@ -39,6 +33,7 @@ import {
|
|
|
39
33
|
getWorkspaceDir,
|
|
40
34
|
getWorkspacePromptPath,
|
|
41
35
|
} from "../util/platform.js";
|
|
36
|
+
import { resolveAndPersistHatchedAt } from "../workspace/hatched-date.js";
|
|
42
37
|
import { computeProgressPercent, computeTier } from "./progress-formula.js";
|
|
43
38
|
import {
|
|
44
39
|
type Capability,
|
|
@@ -149,11 +144,12 @@ function readOnboardingSidecar(): OnboardingContext | null {
|
|
|
149
144
|
* Reads USER.md / SOUL.md / IDENTITY.md, queries the oauth connection
|
|
150
145
|
* store, and counts conversations via the DB-authoritative helper.
|
|
151
146
|
*
|
|
152
|
-
* Side effect: on the very first call
|
|
153
|
-
*
|
|
154
|
-
* `data/hatched.json`
|
|
155
|
-
* timestamp. All other paths are read-only. Callers
|
|
156
|
-
* persist the full snapshot should use
|
|
147
|
+
* Side effect: on the very first call without an explicit Hatched
|
|
148
|
+
* bullet or existing hatched sidecar, the shared resolver persists a
|
|
149
|
+
* one-time `data/hatched.json` value seeded from IDENTITY.md metadata
|
|
150
|
+
* or a real current timestamp. All other paths are read-only. Callers
|
|
151
|
+
* that want to persist the full snapshot should use
|
|
152
|
+
* `writeRelationshipState()`.
|
|
157
153
|
*/
|
|
158
154
|
export async function computeRelationshipState(): Promise<RelationshipState> {
|
|
159
155
|
// Persona source-of-truth:
|
|
@@ -682,74 +678,17 @@ function countConversations(): number {
|
|
|
682
678
|
}
|
|
683
679
|
}
|
|
684
680
|
|
|
685
|
-
/**
|
|
686
|
-
* Filename for the hatched-date sidecar, used as a stable fallback
|
|
687
|
-
* when IDENTITY.md is missing / unreadable / has no explicit hatched
|
|
688
|
-
* bullet and file stat is unavailable. Lives under the workspace
|
|
689
|
-
* data dir alongside `relationship-state.json`.
|
|
690
|
-
*/
|
|
691
|
-
const HATCHED_SIDECAR_FILENAME = "hatched.json";
|
|
692
|
-
|
|
693
|
-
function getHatchedSidecarPath(): string {
|
|
694
|
-
return join(getDataDir(), HATCHED_SIDECAR_FILENAME);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
/**
|
|
698
|
-
* Resolve a stable hatched-date fallback timestamp.
|
|
699
|
-
*
|
|
700
|
-
* The Swift client, OpenAPI schema, and UI have no special handling
|
|
701
|
-
* for a Unix-epoch sentinel — they'll render "1/1/1970" to the user.
|
|
702
|
-
* Instead, we use `new Date().toISOString()` the first time a
|
|
703
|
-
* fallback is needed and persist it to a small sidecar file
|
|
704
|
-
* (`data/hatched.json`). Subsequent calls read the sidecar first, so
|
|
705
|
-
* the returned timestamp is monotonic across writes and the
|
|
706
|
-
* `hatchedDate` field never drifts once initialized.
|
|
707
|
-
*
|
|
708
|
-
* Never throws — a sidecar read/write failure still yields a valid
|
|
709
|
-
* (though non-stable) `now` timestamp, which is still far better than
|
|
710
|
-
* the epoch sentinel.
|
|
711
|
-
*/
|
|
712
|
-
function resolveFallbackHatchedDate(): string {
|
|
713
|
-
const path = getHatchedSidecarPath();
|
|
714
|
-
try {
|
|
715
|
-
if (existsSync(path)) {
|
|
716
|
-
const parsed = JSON.parse(readFileSync(path, "utf-8")) as {
|
|
717
|
-
hatchedAt?: string;
|
|
718
|
-
};
|
|
719
|
-
if (parsed.hatchedAt && !isNaN(Date.parse(parsed.hatchedAt))) {
|
|
720
|
-
return parsed.hatchedAt;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
} catch {
|
|
724
|
-
// Fall through to write a fresh sidecar.
|
|
725
|
-
}
|
|
726
|
-
const now = new Date().toISOString();
|
|
727
|
-
try {
|
|
728
|
-
mkdirSync(getDataDir(), { recursive: true });
|
|
729
|
-
writeFileSync(path, JSON.stringify({ hatchedAt: now }, null, 2), "utf-8");
|
|
730
|
-
} catch {
|
|
731
|
-
// If even the sidecar write fails, return `now` anyway — the
|
|
732
|
-
// caller will just get a fresh-looking date on every call. Not
|
|
733
|
-
// ideal, but far better than the epoch sentinel.
|
|
734
|
-
}
|
|
735
|
-
return now;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
681
|
/**
|
|
739
682
|
* Pull `assistantName` and `hatchedDate` from IDENTITY.md.
|
|
740
683
|
*
|
|
741
684
|
* IDENTITY.md is a freeform markdown file, so for the name we scan
|
|
742
685
|
* bullet lines for any recognizable `name` label (`Name`,
|
|
743
686
|
* `Assistant Name`, `Preferred Name`, etc.). For the hatched date we
|
|
744
|
-
* prefer any explicit `hatched:` / `birth:` bullet, then
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
* boundary, so a raw `Date.now()` fallback would cause `hatchedDate`
|
|
750
|
-
* to drift forward on every write. Instead, when nothing else is
|
|
751
|
-
* readable we resolve via `resolveFallbackHatchedDate()` which
|
|
752
|
-
* persists a stable timestamp to a sidecar file on first use.
|
|
687
|
+
* prefer any explicit `hatched:` / `birth:` bullet, then use the
|
|
688
|
+
* shared hatched-date resolver. That resolver reads an existing
|
|
689
|
+
* `data/hatched.json` sidecar first, otherwise seeds it from valid
|
|
690
|
+
* IDENTITY.md birthtime/mtime or a real current timestamp. This keeps
|
|
691
|
+
* `hatchedDate` stable without writing from read-only HTTP handlers.
|
|
753
692
|
*/
|
|
754
693
|
function parseIdentity(identityPath: string): {
|
|
755
694
|
assistantName: string;
|
|
@@ -792,24 +731,10 @@ function parseIdentity(identityPath: string): {
|
|
|
792
731
|
return { assistantName, hatchedDate: explicitHatched };
|
|
793
732
|
}
|
|
794
733
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
const stats = statSync(identityPath);
|
|
800
|
-
const candidate =
|
|
801
|
-
stats.birthtime.getTime() > 0 ? stats.birthtime : stats.mtime;
|
|
802
|
-
if (candidate.getTime() > 0) {
|
|
803
|
-
return { assistantName, hatchedDate: candidate.toISOString() };
|
|
804
|
-
}
|
|
805
|
-
} catch {
|
|
806
|
-
// File missing or unreadable — fall through to the sidecar.
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
// Last-ditch fallback: `resolveFallbackHatchedDate` returns a stable,
|
|
810
|
-
// real timestamp (persisted to `data/hatched.json` on first call) so
|
|
811
|
-
// the wire contract always carries a valid ISO date.
|
|
812
|
-
return { assistantName, hatchedDate: resolveFallbackHatchedDate() };
|
|
734
|
+
return {
|
|
735
|
+
assistantName,
|
|
736
|
+
hatchedDate: resolveAndPersistHatchedAt(identityPath),
|
|
737
|
+
};
|
|
813
738
|
}
|
|
814
739
|
|
|
815
740
|
/**
|
|
@@ -21,14 +21,34 @@ const log = getLogger("suggested-prompts");
|
|
|
21
21
|
* listed here produce deterministic "Connect X" prompts when disconnected.
|
|
22
22
|
* The icon values are VIcon case names rendered by the macOS client.
|
|
23
23
|
*/
|
|
24
|
+
interface PromptEntry {
|
|
25
|
+
label: string;
|
|
26
|
+
prompt: string;
|
|
27
|
+
icon: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
24
30
|
const CONNECT_PROMPT_META: Record<
|
|
25
31
|
string,
|
|
26
|
-
|
|
32
|
+
PromptEntry & { connectedPrompts?: PromptEntry[] }
|
|
27
33
|
> = {
|
|
28
34
|
google: {
|
|
29
35
|
label: "Connect Gmail",
|
|
30
36
|
prompt: "Help me connect my Gmail account",
|
|
31
37
|
icon: "mail",
|
|
38
|
+
connectedPrompts: [
|
|
39
|
+
{
|
|
40
|
+
label: "Triage my inbox",
|
|
41
|
+
prompt:
|
|
42
|
+
"Help me triage my inbox — summarize what's unread and flag anything that needs a reply",
|
|
43
|
+
icon: "mail",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: "Summarize today's emails",
|
|
47
|
+
prompt:
|
|
48
|
+
"Summarize the emails I received today and highlight anything important",
|
|
49
|
+
icon: "mail",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
32
52
|
},
|
|
33
53
|
slack: {
|
|
34
54
|
label: "Connect Slack",
|
|
@@ -75,7 +95,9 @@ export async function getSuggestedPrompts(): Promise<SuggestedPrompt[]> {
|
|
|
75
95
|
|
|
76
96
|
/**
|
|
77
97
|
* Check which well-known OAuth providers are not connected and return
|
|
78
|
-
* a "Connect X" prompt for each.
|
|
98
|
+
* a "Connect X" prompt for each. For connected providers that have
|
|
99
|
+
* `connectedPrompts`, return those instead so users discover ongoing
|
|
100
|
+
* management capabilities.
|
|
79
101
|
*/
|
|
80
102
|
async function getDeterministicPrompts(): Promise<SuggestedPrompt[]> {
|
|
81
103
|
const providers = listProviders();
|
|
@@ -86,15 +108,29 @@ async function getDeterministicPrompts(): Promise<SuggestedPrompt[]> {
|
|
|
86
108
|
if (!meta) continue;
|
|
87
109
|
|
|
88
110
|
const connected = await isProviderConnected(provider.provider);
|
|
89
|
-
if (connected) continue;
|
|
90
111
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
112
|
+
if (!connected) {
|
|
113
|
+
prompts.push({
|
|
114
|
+
id: `connect-${provider.provider}`,
|
|
115
|
+
label: meta.label,
|
|
116
|
+
icon: meta.icon,
|
|
117
|
+
prompt: meta.prompt,
|
|
118
|
+
source: "deterministic",
|
|
119
|
+
});
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (meta.connectedPrompts) {
|
|
124
|
+
for (const cp of meta.connectedPrompts) {
|
|
125
|
+
prompts.push({
|
|
126
|
+
id: `manage-${provider.provider}-${cp.label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
127
|
+
label: cp.label,
|
|
128
|
+
icon: cp.icon,
|
|
129
|
+
prompt: cp.prompt,
|
|
130
|
+
source: "deterministic",
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
98
134
|
}
|
|
99
135
|
|
|
100
136
|
return prompts;
|
|
@@ -16,11 +16,7 @@
|
|
|
16
16
|
* callback_url that external services should use.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import {
|
|
20
|
-
getPlatformAssistantId,
|
|
21
|
-
getPlatformBaseUrl,
|
|
22
|
-
getPlatformInternalApiKey,
|
|
23
|
-
} from "../config/env.js";
|
|
19
|
+
import { getPlatformAssistantId, getPlatformBaseUrl } from "../config/env.js";
|
|
24
20
|
import { getIsPlatform } from "../config/env-registry.js";
|
|
25
21
|
import { credentialKey } from "../security/credential-key.js";
|
|
26
22
|
import { getSecureKeyAsync } from "../security/secure-keys.js";
|
|
@@ -32,7 +28,6 @@ export interface PlatformCallbackRegistrationContext {
|
|
|
32
28
|
isPlatform: boolean;
|
|
33
29
|
platformBaseUrl: string;
|
|
34
30
|
assistantId: string;
|
|
35
|
-
hasInternalApiKey: boolean;
|
|
36
31
|
hasAssistantApiKey: boolean;
|
|
37
32
|
authHeader: string | null;
|
|
38
33
|
enabled: boolean;
|
|
@@ -54,20 +49,18 @@ export async function resolvePlatformCallbackRegistrationContext(): Promise<Plat
|
|
|
54
49
|
);
|
|
55
50
|
const assistantId =
|
|
56
51
|
getPlatformAssistantId().trim() || storedAssistantIdRaw?.trim() || "";
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
: null;
|
|
52
|
+
const envAssistantCredential = process.env.ASSISTANT_API_KEY?.trim();
|
|
53
|
+
const assistantCredential =
|
|
54
|
+
storedAssistantApiKeyRaw?.trim() || envAssistantCredential || undefined;
|
|
55
|
+
const authHeader = assistantCredential
|
|
56
|
+
? `Api-Key ${assistantCredential}`
|
|
57
|
+
: null;
|
|
64
58
|
|
|
65
59
|
return {
|
|
66
60
|
isPlatform: platform,
|
|
67
61
|
platformBaseUrl,
|
|
68
62
|
assistantId,
|
|
69
|
-
|
|
70
|
-
hasAssistantApiKey: assistantApiKey.length > 0,
|
|
63
|
+
hasAssistantApiKey: !!assistantCredential,
|
|
71
64
|
authHeader,
|
|
72
65
|
// Enabled when we have enough context to register callback routes.
|
|
73
66
|
// Does NOT require IS_PLATFORM — self-hosted assistants with stored
|