@vellumai/assistant 0.7.2 → 0.8.0
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 +45 -29
- package/Dockerfile +1 -0
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docs/architecture/memory.md +5 -2
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/openapi.yaml +470 -25
- package/package.json +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/app-control-flow.test.ts +21 -11
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/assistant-event.test.ts +0 -10
- package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
- package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +4 -2
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
- package/src/__tests__/config-loader-backfill.test.ts +379 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
- package/src/__tests__/config-watcher.test.ts +140 -69
- 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 +6 -33
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +12 -7
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +457 -8
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
- package/src/__tests__/conversation-process-callsite.test.ts +38 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -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 +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/credentials-cli.test.ts +7 -0
- package/src/__tests__/cu-unified-flow.test.ts +176 -10
- package/src/__tests__/date-context.test.ts +164 -2
- 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__/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 +2 -20
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +260 -11
- package/src/__tests__/host-app-control-proxy.test.ts +195 -25
- package/src/__tests__/host-bash-proxy.test.ts +227 -34
- package/src/__tests__/host-bash-routes.test.ts +178 -13
- package/src/__tests__/host-cu-proxy.test.ts +210 -3
- package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
- package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
- package/src/__tests__/host-file-proxy.test.ts +268 -6
- package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
- package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
- package/src/__tests__/http-user-message-parity.test.ts +107 -1
- package/src/__tests__/injector-chain.test.ts +36 -16
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/oauth-cli.test.ts +121 -0
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- 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__/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 -27
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/relay-server.test.ts +60 -5
- package/src/__tests__/runtime-events-sse.test.ts +4 -8
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -1
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-tool.test.ts +44 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/twilio-validation.test.ts +2 -2
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- 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-069-seed-onboarding-threads.test.ts +120 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-request-resolvers.ts +3 -32
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +7 -1
- package/src/calls/voice-session-bridge.ts +1 -1
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/contacts.ts +64 -25
- package/src/cli/commands/credentials.ts +56 -0
- package/src/cli/commands/memory-v2.ts +11 -10
- package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
- package/src/cli/commands/oauth/connect.ts +124 -40
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
- package/src/cli/commands/platform/index.ts +16 -7
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/program.ts +4 -2
- package/src/config/assistant-feature-flags.ts +13 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
- 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/env.ts +0 -8
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +199 -27
- package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +2 -0
- package/src/config/schemas/memory-lifecycle.ts +13 -0
- package/src/config/schemas/memory-v2.ts +76 -12
- package/src/config/schemas/platform.ts +43 -3
- package/src/config/schemas/services.ts +28 -0
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -25
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/config-watcher.ts +85 -57
- package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
- package/src/daemon/conversation-agent-loop.ts +183 -43
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +22 -10
- package/src/daemon/conversation-process.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +26 -0
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +211 -29
- package/src/daemon/conversation-tool-setup.ts +66 -19
- package/src/daemon/conversation.ts +18 -23
- 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/handlers/shared.ts +26 -1
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +137 -41
- package/src/daemon/host-bash-proxy.ts +47 -22
- package/src/daemon/host-browser-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +50 -4
- package/src/daemon/host-file-proxy.ts +44 -8
- package/src/daemon/host-transfer-proxy.ts +97 -6
- package/src/daemon/lifecycle.ts +167 -101
- 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 +66 -15
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +4 -0
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/messages.ts +22 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/tool-setup-types.ts +2 -2
- package/src/documents/document-store.ts +119 -0
- package/src/filing/filing-service.ts +29 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
- package/src/heartbeat/heartbeat-run-store.ts +13 -0
- package/src/heartbeat/heartbeat-service.ts +205 -31
- package/src/home/feed-scheduler.ts +18 -0
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/assistant-server.ts +149 -38
- package/src/ipc/gateway-client.ts +37 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/protocol.ts +5 -7
- 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-worker-v2-schedule.test.ts +34 -51
- 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/admin.ts +5 -9
- package/src/memory/context-search/agent-runner.ts +19 -2
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +1 -16
- package/src/memory/context-search/sources/memory.ts +2 -3
- package/src/memory/context-search/sources/pkb.ts +2 -3
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +4 -12
- package/src/memory/db-init.ts +2 -0
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/conversation-graph-memory.ts +72 -61
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +11 -67
- package/src/memory/graph/graph-search.ts +4 -24
- package/src/memory/graph/retriever.test.ts +12 -1
- package/src/memory/graph/retriever.ts +10 -15
- package/src/memory/graph/tool-handlers.ts +3 -4
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/indexer.ts +53 -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 +116 -0
- package/src/memory/jobs/embed-concept-page.ts +223 -87
- package/src/memory/jobs-store.ts +48 -0
- package/src/memory/jobs-worker.ts +85 -43
- package/src/memory/memory-v2-activation-log-store.ts +32 -14
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/pkb/pkb-search.test.ts +7 -0
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/qdrant-client.ts +3 -13
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/search/semantic.ts +10 -72
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +346 -255
- package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
- package/src/memory/v2/__tests__/injection.test.ts +297 -190
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +113 -196
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/static-context.test.ts +77 -14
- package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
- package/src/memory/v2/activation.ts +149 -156
- package/src/memory/v2/consolidation-job.ts +69 -20
- package/src/memory/v2/injection.ts +75 -68
- package/src/memory/v2/page-store.ts +39 -0
- package/src/memory/v2/prompts/consolidation.ts +41 -1
- package/src/memory/v2/qdrant.ts +306 -46
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +77 -110
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +82 -59
- package/src/memory/v2/static-context.ts +26 -8
- package/src/memory/v2/sweep-job.ts +5 -6
- package/src/memory/v2/types.ts +17 -10
- package/src/notifications/copy-composer.ts +47 -0
- package/src/notifications/decision-engine.ts +46 -0
- 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 +2 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugins/defaults/injectors.ts +36 -4
- 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 +914 -0
- package/src/proactive-artifact/job.ts +366 -0
- package/src/proactive-artifact/message-copy.ts +58 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +21 -7
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -28
- 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/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 +36 -6
- package/src/runtime/assistant-event.ts +0 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/route-policy.ts +15 -1
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/pending-interactions.ts +27 -15
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/approval-routes.ts +7 -3
- package/src/runtime/routes/client-routes.ts +20 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +44 -1
- package/src/runtime/routes/conversation-routes.ts +35 -26
- package/src/runtime/routes/debug-bash-routes.ts +165 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +6 -2
- package/src/runtime/routes/documents-routes.ts +2 -75
- package/src/runtime/routes/events-routes.ts +41 -9
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/host-bash-routes.ts +23 -3
- package/src/runtime/routes/host-cu-routes.ts +33 -6
- package/src/runtime/routes/host-file-routes.ts +32 -6
- package/src/runtime/routes/host-transfer-routes.ts +79 -16
- package/src/runtime/routes/identity-routes.ts +7 -138
- package/src/runtime/routes/inbound-message-handler.ts +77 -12
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/memory-item-routes.test.ts +37 -17
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +136 -17
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/scheduler.ts +20 -1
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/skills/include-graph.ts +35 -13
- package/src/skills/remote-skill-policy.ts +4 -10
- 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/tools/background-tool-registry.ts +17 -3
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +43 -1
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +43 -1
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +56 -11
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +43 -1
- package/src/tools/host-terminal/host-shell.ts +13 -6
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +14 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/permission-checker.ts +15 -0
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +31 -6
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +43 -3
- package/src/tts/provider-catalog.ts +3 -5
- 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/heartbeat-service.ts +19 -0
- 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 +14 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/registry.ts +14 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -404
- package/src/signals/bash.ts +0 -198
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdtempSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
rmSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import {
|
|
11
|
+
afterAll,
|
|
12
|
+
afterEach,
|
|
13
|
+
beforeAll,
|
|
14
|
+
beforeEach,
|
|
15
|
+
describe,
|
|
16
|
+
expect,
|
|
17
|
+
test,
|
|
18
|
+
} from "bun:test";
|
|
19
|
+
|
|
20
|
+
import { removeSafeStorageReleaseNoteMigration } from "../workspace/migrations/071-remove-safe-storage-release-note.js";
|
|
21
|
+
|
|
22
|
+
const MIGRATION_ID = "071-remove-safe-storage-release-note";
|
|
23
|
+
const SAFE_STORAGE_MARKER =
|
|
24
|
+
"<!-- release-note-id:067-release-notes-safe-storage-limits -->";
|
|
25
|
+
const LATER_MARKER =
|
|
26
|
+
"<!-- release-note-id:068-release-notes-local-timezone -->";
|
|
27
|
+
|
|
28
|
+
const SAFE_STORAGE_RELEASE_NOTE = `${SAFE_STORAGE_MARKER}
|
|
29
|
+
## Safe storage limits
|
|
30
|
+
|
|
31
|
+
A new storage protection mode is available behind the safe-storage-limits
|
|
32
|
+
rollout flag. When enabled, the assistant watches workspace disk usage and
|
|
33
|
+
enters cleanup mode if the volume reaches the critical 95% threshold.
|
|
34
|
+
|
|
35
|
+
In cleanup mode, background processes pause and remote messages, including
|
|
36
|
+
trusted-contact messages, are blocked until the guardian frees enough space or
|
|
37
|
+
explicitly overrides the lock. The macOS app now shows a storage cleanup banner
|
|
38
|
+
that must be acknowledged before cleanup chat continues, then keeps a status
|
|
39
|
+
banner visible while cleanup mode is active.
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
let testRoot: string;
|
|
43
|
+
let workspaceDir: string;
|
|
44
|
+
|
|
45
|
+
beforeAll(() => {
|
|
46
|
+
testRoot = mkdtempSync(join(tmpdir(), "migration-071-remove-safe-storage-"));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
afterAll(() => {
|
|
50
|
+
rmSync(testRoot, { recursive: true, force: true });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
workspaceDir = mkdtempSync(join(testRoot, "ws-"));
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
afterEach(() => {
|
|
58
|
+
rmSync(workspaceDir, { recursive: true, force: true });
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
function updatesPath(): string {
|
|
62
|
+
return join(workspaceDir, "UPDATES.md");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
describe("workspace migration 071-remove-safe-storage-release-note", () => {
|
|
66
|
+
test("has the correct id and description", () => {
|
|
67
|
+
expect(removeSafeStorageReleaseNoteMigration.id).toBe(MIGRATION_ID);
|
|
68
|
+
expect(removeSafeStorageReleaseNoteMigration.description).toContain(
|
|
69
|
+
"safe storage release note",
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("missing UPDATES.md is a no-op", () => {
|
|
74
|
+
expect(existsSync(updatesPath())).toBe(false);
|
|
75
|
+
|
|
76
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
77
|
+
|
|
78
|
+
expect(existsSync(updatesPath())).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("removes UPDATES.md when it only contains the safe-storage bulletin", () => {
|
|
82
|
+
writeFileSync(updatesPath(), SAFE_STORAGE_RELEASE_NOTE, "utf-8");
|
|
83
|
+
|
|
84
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
85
|
+
|
|
86
|
+
expect(existsSync(updatesPath())).toBe(false);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("preserves prior unrelated release notes when removing the safe-storage block", () => {
|
|
90
|
+
const prior = `<!-- release-note-id:066-earlier-note -->
|
|
91
|
+
## Earlier note
|
|
92
|
+
|
|
93
|
+
This note should stay.
|
|
94
|
+
`;
|
|
95
|
+
writeFileSync(
|
|
96
|
+
updatesPath(),
|
|
97
|
+
`${prior}\n${SAFE_STORAGE_RELEASE_NOTE}`,
|
|
98
|
+
"utf-8",
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
102
|
+
|
|
103
|
+
const content = readFileSync(updatesPath(), "utf-8");
|
|
104
|
+
expect(content).toContain("## Earlier note");
|
|
105
|
+
expect(content).toContain("This note should stay.");
|
|
106
|
+
expect(content).not.toContain(SAFE_STORAGE_MARKER);
|
|
107
|
+
expect(content).not.toContain("Safe storage limits");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("preserves a later release-note block after safe storage", () => {
|
|
111
|
+
const later = `${LATER_MARKER}
|
|
112
|
+
## Local timezone grounding
|
|
113
|
+
|
|
114
|
+
This later note should stay.
|
|
115
|
+
`;
|
|
116
|
+
writeFileSync(
|
|
117
|
+
updatesPath(),
|
|
118
|
+
`${SAFE_STORAGE_RELEASE_NOTE}\n${later}`,
|
|
119
|
+
"utf-8",
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
123
|
+
|
|
124
|
+
const content = readFileSync(updatesPath(), "utf-8");
|
|
125
|
+
expect(content.startsWith(LATER_MARKER)).toBe(true);
|
|
126
|
+
expect(content).toContain("## Local timezone grounding");
|
|
127
|
+
expect(content).toContain("This later note should stay.");
|
|
128
|
+
expect(content).not.toContain(SAFE_STORAGE_MARKER);
|
|
129
|
+
expect(content).not.toContain("Safe storage limits");
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
test("fallback preserves a later release-note block after a partial safe-storage block", () => {
|
|
133
|
+
const partialSafeStorage = `${SAFE_STORAGE_MARKER}
|
|
134
|
+
## Safe storage limits
|
|
135
|
+
|
|
136
|
+
Partially written note.
|
|
137
|
+
`;
|
|
138
|
+
const later = `${LATER_MARKER}
|
|
139
|
+
## Local timezone grounding
|
|
140
|
+
|
|
141
|
+
This later note should stay.
|
|
142
|
+
`;
|
|
143
|
+
writeFileSync(updatesPath(), `${partialSafeStorage}\n${later}`, "utf-8");
|
|
144
|
+
|
|
145
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
146
|
+
|
|
147
|
+
const content = readFileSync(updatesPath(), "utf-8");
|
|
148
|
+
expect(content.startsWith(LATER_MARKER)).toBe(true);
|
|
149
|
+
expect(content).toContain("## Local timezone grounding");
|
|
150
|
+
expect(content).not.toContain(SAFE_STORAGE_MARKER);
|
|
151
|
+
expect(content).not.toContain("Partially written note.");
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test("content without the safe-storage marker is byte-identical", () => {
|
|
155
|
+
const original =
|
|
156
|
+
"## Existing note\r\n\r\nNo safe storage marker appears here.\r\n";
|
|
157
|
+
writeFileSync(updatesPath(), original, "utf-8");
|
|
158
|
+
|
|
159
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
160
|
+
|
|
161
|
+
expect(readFileSync(updatesPath(), "utf-8")).toBe(original);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test("preserves CRLF in unrelated content when removing the safe-storage block", () => {
|
|
165
|
+
const prior =
|
|
166
|
+
"<!-- release-note-id:066-earlier-note -->\r\n## Earlier note\r\n\r\nThis note should keep CRLF.\r\n";
|
|
167
|
+
writeFileSync(
|
|
168
|
+
updatesPath(),
|
|
169
|
+
`${prior}\r\n${SAFE_STORAGE_RELEASE_NOTE}`,
|
|
170
|
+
"utf-8",
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
174
|
+
|
|
175
|
+
expect(readFileSync(updatesPath(), "utf-8")).toBe(prior);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("running twice is idempotent", () => {
|
|
179
|
+
const prior = `<!-- release-note-id:066-earlier-note -->
|
|
180
|
+
## Earlier note
|
|
181
|
+
|
|
182
|
+
This note should stay.
|
|
183
|
+
`;
|
|
184
|
+
const later = `${LATER_MARKER}
|
|
185
|
+
## Local timezone grounding
|
|
186
|
+
|
|
187
|
+
This later note should stay.
|
|
188
|
+
`;
|
|
189
|
+
writeFileSync(
|
|
190
|
+
updatesPath(),
|
|
191
|
+
`${prior}\n${SAFE_STORAGE_RELEASE_NOTE}\n${later}`,
|
|
192
|
+
"utf-8",
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
196
|
+
const afterFirst = readFileSync(updatesPath(), "utf-8");
|
|
197
|
+
|
|
198
|
+
removeSafeStorageReleaseNoteMigration.run(workspaceDir);
|
|
199
|
+
const afterSecond = readFileSync(updatesPath(), "utf-8");
|
|
200
|
+
|
|
201
|
+
expect(afterSecond).toBe(afterFirst);
|
|
202
|
+
expect(afterSecond).toContain("## Earlier note");
|
|
203
|
+
expect(afterSecond).toContain("## Local timezone grounding");
|
|
204
|
+
expect(afterSecond).not.toContain(SAFE_STORAGE_MARKER);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {
|
|
2
|
+
existsSync,
|
|
3
|
+
mkdirSync,
|
|
4
|
+
readFileSync,
|
|
5
|
+
rmSync,
|
|
6
|
+
writeFileSync,
|
|
7
|
+
} from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
11
|
+
|
|
12
|
+
import { releaseNotesSafeStorageLimitsMigration } from "../workspace/migrations/067-release-notes-safe-storage-limits.js";
|
|
13
|
+
|
|
14
|
+
const MIGRATION_ID = "067-release-notes-safe-storage-limits";
|
|
15
|
+
|
|
16
|
+
let workspaceDir: string;
|
|
17
|
+
|
|
18
|
+
function freshWorkspace(): void {
|
|
19
|
+
workspaceDir = join(
|
|
20
|
+
tmpdir(),
|
|
21
|
+
`vellum-migration-067-test-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
22
|
+
);
|
|
23
|
+
mkdirSync(workspaceDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function updatesPath(): string {
|
|
27
|
+
return join(workspaceDir, "UPDATES.md");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
freshWorkspace();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
if (existsSync(workspaceDir)) {
|
|
36
|
+
rmSync(workspaceDir, { recursive: true, force: true });
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("workspace migration 067-release-notes-safe-storage-limits", () => {
|
|
41
|
+
test("has the correct id", () => {
|
|
42
|
+
expect(releaseNotesSafeStorageLimitsMigration.id).toBe(MIGRATION_ID);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("does not create UPDATES.md when file is absent", () => {
|
|
46
|
+
expect(existsSync(updatesPath())).toBe(false);
|
|
47
|
+
|
|
48
|
+
releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
|
|
49
|
+
|
|
50
|
+
expect(existsSync(updatesPath())).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("leaves existing UPDATES.md byte-identical", () => {
|
|
54
|
+
const existing = "## Prior\n\nExisting release note.\n";
|
|
55
|
+
writeFileSync(updatesPath(), existing, "utf-8");
|
|
56
|
+
|
|
57
|
+
releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
|
|
58
|
+
|
|
59
|
+
expect(readFileSync(updatesPath(), "utf-8")).toBe(existing);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("is idempotent when run twice in an empty workspace", () => {
|
|
63
|
+
releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
|
|
64
|
+
releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
|
|
65
|
+
|
|
66
|
+
expect(existsSync(updatesPath())).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("is idempotent when run twice with existing UPDATES.md", () => {
|
|
70
|
+
const existing = "## Prior\n\nExisting release note.\n";
|
|
71
|
+
writeFileSync(updatesPath(), existing, "utf-8");
|
|
72
|
+
|
|
73
|
+
releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
|
|
74
|
+
releaseNotesSafeStorageLimitsMigration.run(workspaceDir);
|
|
75
|
+
|
|
76
|
+
expect(readFileSync(updatesPath(), "utf-8")).toBe(existing);
|
|
77
|
+
});
|
|
78
|
+
});
|
package/src/agent/loop.ts
CHANGED
|
@@ -96,6 +96,11 @@ export type AgentEvent =
|
|
|
96
96
|
matchedTrustRuleId?: string;
|
|
97
97
|
isContainerized?: boolean;
|
|
98
98
|
riskScopeOptions?: Array<{ pattern: string; label: string }>;
|
|
99
|
+
riskAllowlistOptions?: Array<{
|
|
100
|
+
label: string;
|
|
101
|
+
description: string;
|
|
102
|
+
pattern: string;
|
|
103
|
+
}>;
|
|
99
104
|
riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
|
|
100
105
|
approvalMode?: string;
|
|
101
106
|
approvalReason?: string;
|
|
@@ -282,6 +287,11 @@ export type LoopToolExecutor = (
|
|
|
282
287
|
matchedTrustRuleId?: string;
|
|
283
288
|
isContainerized?: boolean;
|
|
284
289
|
riskScopeOptions?: Array<{ pattern: string; label: string }>;
|
|
290
|
+
riskAllowlistOptions?: Array<{
|
|
291
|
+
label: string;
|
|
292
|
+
description: string;
|
|
293
|
+
pattern: string;
|
|
294
|
+
}>;
|
|
285
295
|
riskDirectoryScopeOptions?: Array<{ scope: string; label: string }>;
|
|
286
296
|
approvalMode?: string;
|
|
287
297
|
approvalReason?: string;
|
|
@@ -1001,6 +1011,7 @@ export class AgentLoop {
|
|
|
1001
1011
|
matchedTrustRuleId: result.matchedTrustRuleId,
|
|
1002
1012
|
isContainerized: result.isContainerized,
|
|
1003
1013
|
riskScopeOptions: result.riskScopeOptions,
|
|
1014
|
+
riskAllowlistOptions: result.riskAllowlistOptions,
|
|
1004
1015
|
riskDirectoryScopeOptions: result.riskDirectoryScopeOptions,
|
|
1005
1016
|
approvalMode: result.approvalMode,
|
|
1006
1017
|
approvalReason: result.approvalReason,
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
import { answerCall } from "../calls/call-domain.js";
|
|
15
15
|
import { findContactChannel } from "../contacts/contact-store.js";
|
|
16
|
-
import { upsertContactChannel } from "../contacts/contacts-write.js";
|
|
17
16
|
import { findConversation } from "../daemon/conversation-store.js";
|
|
18
17
|
import { emitFeedEvent } from "../home/emit-feed-event.js";
|
|
19
18
|
import {
|
|
@@ -187,28 +186,15 @@ const pendingInteractionResolver: GuardianRequestResolver = {
|
|
|
187
186
|
return { ok: false, reason: "pending_interaction_not_found" };
|
|
188
187
|
}
|
|
189
188
|
|
|
190
|
-
// Resolve the interaction: remove from tracker and get the session.
|
|
191
|
-
const resolved = pendingInteractions.resolve(request.id);
|
|
192
|
-
if (!resolved) {
|
|
193
|
-
// Race condition: interaction was consumed between get() and resolve().
|
|
194
|
-
log.warn(
|
|
195
|
-
{
|
|
196
|
-
event: "resolver_tool_approval_resolve_race",
|
|
197
|
-
requestId: request.id,
|
|
198
|
-
},
|
|
199
|
-
"Tool approval resolver: pending interaction consumed between lookup and resolve",
|
|
200
|
-
);
|
|
201
|
-
return { ok: false, reason: "pending_interaction_race" };
|
|
202
|
-
}
|
|
203
|
-
|
|
204
189
|
// Map action to the permission system's UserDecision type and notify session.
|
|
190
|
+
// resolveConfirmation() owns pendingInteractions deregistration.
|
|
205
191
|
const userDecision: UserDecision =
|
|
206
192
|
decision.action === "reject" ? "deny" : "allow";
|
|
207
|
-
const conversation = findConversation(
|
|
193
|
+
const conversation = findConversation(interaction.conversationId);
|
|
208
194
|
if (!conversation) {
|
|
209
195
|
return {
|
|
210
196
|
ok: false,
|
|
211
|
-
reason: `conversation_not_found: ${
|
|
197
|
+
reason: `conversation_not_found: ${interaction.conversationId}`,
|
|
212
198
|
};
|
|
213
199
|
}
|
|
214
200
|
conversation.handleConfirmationResponse(
|
|
@@ -510,21 +496,6 @@ const accessRequestResolver: GuardianRequestResolver = {
|
|
|
510
496
|
// a verification session. The caller is already on the line and the
|
|
511
497
|
// relay server's in-call wait loop will detect the approved status.
|
|
512
498
|
if (channel === "phone") {
|
|
513
|
-
try {
|
|
514
|
-
upsertContactChannel({
|
|
515
|
-
sourceChannel: "phone",
|
|
516
|
-
externalUserId: requesterExternalUserId,
|
|
517
|
-
externalChatId: requesterChatId,
|
|
518
|
-
status: "active",
|
|
519
|
-
policy: "allow",
|
|
520
|
-
});
|
|
521
|
-
} catch (err) {
|
|
522
|
-
log.error(
|
|
523
|
-
{ err, requesterExternalUserId },
|
|
524
|
-
"Access request resolver: failed to activate voice caller as trusted contact",
|
|
525
|
-
);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
499
|
log.info(
|
|
529
500
|
{
|
|
530
501
|
event: "resolver_access_request_voice_approved",
|
|
@@ -32,10 +32,10 @@ import {
|
|
|
32
32
|
writeSync,
|
|
33
33
|
} from "node:fs";
|
|
34
34
|
import { dirname, join } from "node:path";
|
|
35
|
-
import { kill } from "node:process";
|
|
36
35
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
37
36
|
|
|
38
37
|
import { getLogger } from "../util/logger.js";
|
|
38
|
+
import { isProcessAlive } from "../util/process-liveness.js";
|
|
39
39
|
import { getLocalBackupsDir } from "./paths.js";
|
|
40
40
|
|
|
41
41
|
const log = getLogger("snapshot-lock");
|
|
@@ -88,29 +88,6 @@ export function getSnapshotLockPath(): string {
|
|
|
88
88
|
return join(dirname(getLocalBackupsDir()), ".snapshot.lock");
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
/**
|
|
92
|
-
* Check whether a PID refers to a live process. Uses `kill(pid, 0)`, which
|
|
93
|
-
* does not send any signal — it just probes for existence and permission.
|
|
94
|
-
*
|
|
95
|
-
* Returns `false` for obviously invalid PIDs (<= 0) and for any error that
|
|
96
|
-
* indicates the process is gone. Returns `true` for ESRCH-negative results
|
|
97
|
-
* (meaning a process exists) and for EPERM (process exists but is owned by
|
|
98
|
-
* another user — still a live process, still should not be taken over).
|
|
99
|
-
*/
|
|
100
|
-
function isProcessAlive(pid: number): boolean {
|
|
101
|
-
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
102
|
-
try {
|
|
103
|
-
kill(pid, 0);
|
|
104
|
-
return true;
|
|
105
|
-
} catch (err) {
|
|
106
|
-
const code = (err as NodeJS.ErrnoException).code;
|
|
107
|
-
// EPERM means the PID exists but we cannot signal it — treat as alive so
|
|
108
|
-
// we don't accidentally take over another user's lock.
|
|
109
|
-
if (code === "EPERM") return true;
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
91
|
/**
|
|
115
92
|
* Try to atomically create the lock file with mode `0o600` and the current
|
|
116
93
|
* PID as its contents. Returns `true` on success, `false` if the file
|
|
@@ -348,9 +325,7 @@ export async function acquireSnapshotLock(
|
|
|
348
325
|
}
|
|
349
326
|
|
|
350
327
|
if (isProcessAlive(holder.pid)) {
|
|
351
|
-
throw new Error(
|
|
352
|
-
`snapshot in progress (locked by pid ${holder.pid})`,
|
|
353
|
-
);
|
|
328
|
+
throw new Error(`snapshot in progress (locked by pid ${holder.pid})`);
|
|
354
329
|
}
|
|
355
330
|
|
|
356
331
|
// --- Step 3: stale takeover via rename-aside ---
|
|
@@ -15,10 +15,11 @@ import {
|
|
|
15
15
|
rmSync,
|
|
16
16
|
writeFileSync,
|
|
17
17
|
} from "node:fs";
|
|
18
|
-
import { arch,
|
|
18
|
+
import { arch, platform } from "node:os";
|
|
19
19
|
import { join } from "node:path";
|
|
20
20
|
|
|
21
21
|
import { getLogger } from "../util/logger.js";
|
|
22
|
+
import { getWorkspaceDir } from "../util/platform.js";
|
|
22
23
|
import { PromiseGuard } from "../util/promise-guard.js";
|
|
23
24
|
|
|
24
25
|
const log = getLogger("compiler-tools");
|
|
@@ -44,7 +45,7 @@ interface VersionManifest {
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
function getToolsDir(): string {
|
|
47
|
-
return join(
|
|
48
|
+
return join(getWorkspaceDir(), "compiler-tools");
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
const installGuard = new PromiseGuard<void>();
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
2
|
|
|
3
3
|
// Emergency/high-risk numbers that should never be called
|
|
4
|
-
const DENIED_NUMBERS = new Set([
|
|
5
|
-
"911",
|
|
6
|
-
"112",
|
|
7
|
-
"999",
|
|
8
|
-
"000",
|
|
9
|
-
"110",
|
|
10
|
-
"119",
|
|
11
|
-
]);
|
|
4
|
+
const DENIED_NUMBERS = new Set(["911", "112", "999", "000", "110", "119"]);
|
|
12
5
|
|
|
13
6
|
/**
|
|
14
7
|
* Check whether a phone number is a denied emergency number.
|
|
@@ -75,3 +68,7 @@ export function getGuardianWaitUpdateSteadyMaxIntervalMs(): number {
|
|
|
75
68
|
export function getSilenceTimeoutMs(): number {
|
|
76
69
|
return 30 * 1000; // 30 seconds
|
|
77
70
|
}
|
|
71
|
+
|
|
72
|
+
export function getEndCallListenWindowMs(): number {
|
|
73
|
+
return 15 * 1000;
|
|
74
|
+
}
|