@vellumai/assistant 0.4.43 → 0.4.45
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/.prettierignore +4 -0
- package/ARCHITECTURE.md +46 -44
- package/README.md +15 -16
- package/bun.lock +10 -35
- package/docs/architecture/integrations.md +102 -215
- package/docs/architecture/keychain-broker.md +1 -1
- package/docs/architecture/memory.md +2 -2
- package/docs/architecture/scheduling.md +1 -1
- package/docs/architecture/security.md +11 -11
- package/docs/error-handling.md +1 -1
- package/docs/trusted-contact-access.md +3 -3
- package/drizzle/meta/0000_snapshot.json +34 -100
- package/drizzle/meta/_journal.json +1 -1
- package/drizzle.config.ts +4 -4
- package/package.json +3 -2
- package/scripts/capture-x-graphql.ts +237 -141
- package/scripts/generate-bundled-tool-registry.ts +223 -0
- package/src/__tests__/access-request-decision.test.ts +0 -1
- package/src/__tests__/actor-token-service.test.ts +23 -24
- package/src/__tests__/agent-loop.test.ts +0 -131
- package/src/__tests__/always-loaded-tools-guard.test.ts +71 -0
- package/src/__tests__/amazon-cdp-integration.test.ts +11 -9
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +11 -3
- package/src/__tests__/asset-materialize-tool.test.ts +0 -1
- package/src/__tests__/asset-search-tool.test.ts +0 -1
- package/src/__tests__/assistant-attachment-directive.test.ts +1 -1
- package/src/__tests__/assistant-events-sse-hardening.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +70 -18
- package/src/__tests__/assistant-id-boundary-guard.test.ts +6 -6
- package/src/__tests__/attachments-store.test.ts +0 -1
- package/src/__tests__/avatar-e2e.test.ts +74 -115
- package/src/__tests__/avatar-router.test.ts +25 -62
- package/src/__tests__/browser-manager.test.ts +24 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +4 -3
- package/src/__tests__/browser-skill-endstate.test.ts +8 -11
- package/src/__tests__/btw-routes.test.ts +326 -0
- package/src/__tests__/bundled-asset.test.ts +1 -1
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +23 -9
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/call-conversation-messages.test.ts +0 -1
- package/src/__tests__/call-domain.test.ts +0 -1
- package/src/__tests__/call-pointer-messages.test.ts +0 -1
- package/src/__tests__/call-recovery.test.ts +0 -1
- package/src/__tests__/call-routes-http.test.ts +0 -1
- package/src/__tests__/call-store.test.ts +0 -1
- package/src/__tests__/canonical-guardian-store.test.ts +0 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +0 -1
- package/src/__tests__/channel-guardian.test.ts +5 -7
- package/src/__tests__/channel-retry-sweep.test.ts +0 -1
- package/src/__tests__/checker.test.ts +32 -36
- package/src/__tests__/compaction.benchmark.test.ts +16 -14
- package/src/__tests__/computer-use-session-lifecycle.test.ts +10 -11
- package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -5
- package/src/__tests__/computer-use-tools.test.ts +35 -31
- package/src/__tests__/config-schema.test.ts +11 -15
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/conflict-store.test.ts +0 -1
- package/src/__tests__/connection-policy.test.ts +4 -7
- package/src/__tests__/contacts-tools.test.ts +0 -1
- package/src/__tests__/context-memory-e2e.test.ts +2 -4
- package/src/__tests__/context-overflow-reducer.test.ts +2 -4
- package/src/__tests__/context-window-manager.test.ts +147 -60
- package/src/__tests__/contradiction-checker.test.ts +0 -1
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +31 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +381 -0
- package/src/__tests__/conversation-store.test.ts +0 -1
- package/src/__tests__/conversation-unread-route.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +8 -8
- package/src/__tests__/cross-provider-web-search.test.ts +353 -0
- package/src/__tests__/daemon-assistant-events.test.ts +6 -7
- package/src/__tests__/db-schedule-syntax-migration.test.ts +15 -3
- package/src/__tests__/delete-managed-skill-tool.test.ts +5 -9
- package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
- package/src/__tests__/diagnostics-export.test.ts +189 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
- package/src/__tests__/entity-extractor.test.ts +0 -1
- package/src/__tests__/entity-search.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +2 -4
- package/src/__tests__/error-handler-friendly-messages.test.ts +46 -0
- package/src/__tests__/file-read-tool.test.ts +86 -0
- package/src/__tests__/followup-tools.test.ts +0 -1
- package/src/__tests__/frontmatter.test.ts +77 -34
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/gateway-only-guard.test.ts +1 -1
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -1
- package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
- package/src/__tests__/guardian-action-followup-store.test.ts +0 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-action-late-reply.test.ts +0 -1
- package/src/__tests__/guardian-action-store.test.ts +0 -1
- package/src/__tests__/guardian-action-sweep.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-outbound-http.test.ts +0 -1
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +1 -1
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +3 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +28 -426
- package/src/__tests__/host-bash-proxy.test.ts +335 -0
- package/src/__tests__/host-file-proxy.test.ts +374 -0
- package/src/__tests__/host-shell-tool.test.ts +147 -1
- package/src/__tests__/http-user-message-parity.test.ts +361 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
- package/src/__tests__/integration-status.test.ts +3 -8
- package/src/__tests__/intent-routing.test.ts +7 -46
- package/src/__tests__/invite-redemption-service.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +0 -1
- package/src/__tests__/llm-usage-store.test.ts +0 -1
- package/src/__tests__/managed-avatar-client.test.ts +101 -55
- package/src/__tests__/managed-skill-lifecycle.test.ts +9 -18
- package/src/__tests__/managed-store.test.ts +94 -21
- package/src/__tests__/media-reuse-story.e2e.test.ts +0 -1
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +2 -4
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -1
- package/src/__tests__/memory-recall-quality.test.ts +0 -1
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -1
- package/src/__tests__/memory-regressions.test.ts +0 -1
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +0 -1
- package/src/__tests__/messaging-send-tool.test.ts +35 -0
- package/src/__tests__/messaging-skill-split.test.ts +138 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
- package/src/__tests__/migration-export-http.test.ts +2 -3
- package/src/__tests__/migration-import-commit-http.test.ts +1 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -2
- package/src/__tests__/migration-validate-http.test.ts +1 -2
- package/src/__tests__/native-web-search.test.ts +475 -0
- package/src/__tests__/navigate-settings-tab.test.ts +84 -0
- package/src/__tests__/non-member-access-request.test.ts +0 -1
- package/src/__tests__/notification-broadcaster.test.ts +15 -15
- package/src/__tests__/notification-decision-strategy.test.ts +6 -6
- package/src/__tests__/notification-deep-link.test.ts +7 -7
- package/src/__tests__/notification-guardian-path.test.ts +2 -3
- package/src/__tests__/notification-telegram-adapter.test.ts +1 -1
- package/src/__tests__/notification-thread-candidates.test.ts +4 -4
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +0 -10
- package/src/__tests__/playbook-execution.test.ts +0 -1
- package/src/__tests__/playbook-tools.test.ts +0 -1
- package/src/__tests__/profile-compiler.test.ts +0 -1
- package/src/__tests__/provider-fail-open-selection.test.ts +12 -2
- package/src/__tests__/provider-managed-proxy-integration.test.ts +25 -0
- package/src/__tests__/qdrant-collection-migration.test.ts +223 -0
- package/src/__tests__/recording-handler.test.ts +30 -94
- package/src/__tests__/registry.test.ts +28 -35
- package/src/__tests__/relay-server.test.ts +0 -1
- package/src/__tests__/ride-shotgun-handler.test.ts +4 -20
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +0 -1
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +30 -28
- package/src/__tests__/schedule-store.test.ts +441 -1
- package/src/__tests__/schedule-tools.test.ts +468 -7
- package/src/__tests__/scheduler-recurrence.test.ts +196 -23
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +6 -3
- package/src/__tests__/secret-response-routing.test.ts +4 -1
- package/src/__tests__/send-endpoint-busy.test.ts +14 -5
- package/src/__tests__/send-notification-tool.test.ts +0 -7
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/server-history-render.test.ts +1 -2
- package/src/__tests__/session-abort-tool-results.test.ts +0 -1
- package/src/__tests__/session-agent-loop.test.ts +46 -6
- package/src/__tests__/session-confirmation-signals.test.ts +7 -46
- package/src/__tests__/session-conflict-gate.test.ts +2 -6
- package/src/__tests__/session-error.test.ts +5 -14
- package/src/__tests__/session-init.benchmark.test.ts +3 -5
- package/src/__tests__/session-load-history-repair.test.ts +0 -1
- package/src/__tests__/session-media-retry.test.ts +12 -74
- package/src/__tests__/session-pre-run-repair.test.ts +0 -1
- package/src/__tests__/session-profile-injection.test.ts +2 -6
- package/src/__tests__/session-provider-retry-repair.test.ts +2 -6
- package/src/__tests__/session-queue.test.ts +94 -139
- package/src/__tests__/session-skill-tools.test.ts +115 -115
- package/src/__tests__/session-slash-known.test.ts +0 -1
- package/src/__tests__/session-slash-queue.test.ts +0 -1
- package/src/__tests__/session-slash-unknown.test.ts +0 -1
- package/src/__tests__/session-surfaces-task-progress.test.ts +34 -0
- package/src/__tests__/session-usage.test.ts +0 -1
- package/src/__tests__/session-workspace-cache-state.test.ts +2 -6
- package/src/__tests__/session-workspace-injection.test.ts +2 -6
- package/src/__tests__/session-workspace-tool-tracking.test.ts +2 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +180 -184
- package/src/__tests__/skill-feature-flags.test.ts +125 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -2
- package/src/__tests__/skill-load-tool.test.ts +194 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +27 -16
- package/src/__tests__/skill-projection.benchmark.test.ts +15 -14
- package/src/__tests__/skills.test.ts +14 -53
- package/src/__tests__/slack-channel-config.test.ts +0 -1
- package/src/__tests__/slack-inbound-verification.test.ts +0 -1
- package/src/__tests__/slack-skill.test.ts +1 -1
- package/src/__tests__/starter-task-flow.test.ts +9 -19
- package/src/__tests__/subagent-tools.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +7 -7
- package/src/__tests__/task-compiler.test.ts +0 -1
- package/src/__tests__/task-management-tools.test.ts +0 -1
- package/src/__tests__/task-memory-cleanup.test.ts +0 -1
- package/src/__tests__/task-runner.test.ts +0 -1
- package/src/__tests__/task-scheduler.test.ts +0 -1
- package/src/__tests__/terminal-tools.test.ts +0 -1
- package/src/__tests__/test-support/computer-use-skill-harness.ts +2 -4
- package/src/__tests__/thread-seed-composer.test.ts +5 -5
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +8 -86
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/tool-notification-listener.test.ts +1 -1
- package/src/__tests__/tool-preview-lifecycle.test.ts +416 -0
- package/src/__tests__/trust-store.test.ts +84 -8
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/trusted-contact-verification.test.ts +0 -1
- package/src/__tests__/twilio-provider.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +0 -1
- package/src/__tests__/{request-file-tool.test.ts → ui-file-upload-surface.test.ts} +11 -72
- package/src/__tests__/update-bulletin.test.ts +0 -1
- package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -1
- package/src/__tests__/usage-routes.test.ts +0 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -4
- package/src/__tests__/voice-invite-redemption.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/__tests__/voice-session-bridge.test.ts +9 -1
- package/src/__tests__/web-fetch.test.ts +57 -0
- package/src/__tests__/workspace-git-service.test.ts +5 -14
- package/src/__tests__/workspace-policy.test.ts +0 -1
- package/src/agent/loop.ts +22 -34
- package/src/bundler/bundle-signer.ts +4 -4
- package/src/calls/call-controller.ts +1 -1
- package/src/calls/relay-server.ts +1 -1
- package/src/calls/twilio-rest.ts +1 -1
- package/src/calls/voice-session-bridge.ts +3 -1
- package/src/cli/__tests__/notifications.test.ts +3 -4
- package/src/cli/commands/map.ts +2 -6
- package/src/cli/commands/mcp.ts +73 -15
- package/src/cli/commands/notifications.ts +4 -4
- package/src/cli/commands/sessions.ts +9 -1
- package/src/cli/commands/skills.ts +6 -10
- package/src/cli/http-client.ts +2 -3
- package/src/cli/main-screen.tsx +10 -10
- package/src/cli/program.ts +0 -4
- package/src/cli/reference.ts +0 -2
- package/src/cli.ts +15 -9
- package/src/config/__tests__/bundled-tool-registry-guard.test.ts +120 -0
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +11 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +6 -7
- package/src/config/bundled-skills/app-builder/TOOLS.json +0 -4
- package/src/config/bundled-skills/browser/SKILL.md +6 -1
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +5 -1
- package/src/config/bundled-skills/claude-code/SKILL.md +5 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +6 -69
- package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +10 -1
- package/src/config/bundled-skills/contacts/SKILL.md +10 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +35 -0
- package/src/config/bundled-skills/{messaging → contacts}/tools/google-contacts.ts +9 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -1
- package/src/config/bundled-skills/doordash/SKILL.md +8 -2
- package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +1 -82
- package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -28
- package/src/config/bundled-skills/doordash/lib/session.ts +21 -17
- package/src/config/bundled-skills/doordash/lib/shared/platform.ts +4 -1
- package/src/config/bundled-skills/followups/SKILL.md +4 -1
- package/src/config/bundled-skills/gmail/SKILL.md +180 -0
- package/src/config/bundled-skills/gmail/TOOLS.json +506 -0
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +149 -0
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +110 -0
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-draft.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-filters.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-follow-up.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-forward.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +50 -0
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-outreach-scan.ts +8 -90
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-send-draft.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-sender-digest.ts +2 -2
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-trash.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-unsubscribe.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-vacation.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/shared.ts +47 -0
- package/src/config/bundled-skills/google-calendar/SKILL.md +5 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +5 -1
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -1
- package/src/config/bundled-skills/media-processing/SKILL.md +7 -13
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -22
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +12 -1
- package/src/config/bundled-skills/messaging/SKILL.md +23 -139
- package/src/config/bundled-skills/messaging/TOOLS.json +33 -1215
- package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +42 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +165 -2
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +1 -13
- package/src/config/bundled-skills/messaging/tools/shared.ts +81 -34
- package/src/config/bundled-skills/notifications/SKILL.md +5 -1
- package/src/config/bundled-skills/orchestration/SKILL.md +30 -0
- package/src/config/bundled-skills/orchestration/TOOLS.json +35 -0
- package/src/config/bundled-skills/{reminder/tools/reminder-cancel.ts → orchestration/tools/swarm-delegate.ts} +3 -3
- package/src/config/bundled-skills/phone-calls/SKILL.md +9 -1
- package/src/config/bundled-skills/playbooks/SKILL.md +4 -1
- package/src/config/bundled-skills/schedule/SKILL.md +70 -9
- package/src/config/bundled-skills/schedule/TOOLS.json +38 -6
- package/src/config/bundled-skills/screen-watch/SKILL.md +28 -0
- package/src/config/bundled-skills/screen-watch/TOOLS.json +35 -0
- package/src/config/bundled-skills/{reminder/tools/reminder-create.ts → screen-watch/tools/start-screen-watch.ts} +3 -3
- package/src/config/bundled-skills/sequences/SKILL.md +47 -0
- package/src/config/bundled-skills/sequences/TOOLS.json +340 -0
- package/src/config/bundled-skills/sequences/tools/sequence-update.ts +128 -0
- package/src/config/bundled-skills/sequences/tools/shared.ts +9 -0
- package/src/config/bundled-skills/settings/SKILL.md +12 -0
- package/src/config/bundled-skills/settings/TOOLS.json +112 -0
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +43 -0
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +52 -0
- package/src/config/bundled-skills/{computer-use/tools/computer-use-right-click.ts → settings/tools/set-avatar.ts} +2 -6
- package/src/{tools/system/voice-config.ts → config/bundled-skills/settings/tools/voice-config-update.ts} +59 -96
- package/src/config/bundled-skills/skill-management/SKILL.md +18 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +90 -0
- package/src/config/bundled-skills/{computer-use/tools/computer-use-double-click.ts → skill-management/tools/delete-managed.ts} +2 -6
- package/src/config/bundled-skills/skill-management/tools/scaffold-managed.ts +12 -0
- package/src/config/bundled-skills/slack/SKILL.md +5 -1
- package/src/config/bundled-skills/subagent/SKILL.md +4 -1
- package/src/config/bundled-skills/tasks/SKILL.md +5 -2
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -1
- package/src/config/bundled-skills/watcher/SKILL.md +4 -1
- package/src/config/bundled-tool-registry.ts +118 -107
- package/src/config/env.ts +5 -2
- package/src/config/feature-flag-registry.json +33 -9
- package/src/config/loader.ts +10 -2
- package/src/config/schema.ts +19 -16
- package/src/config/schemas/inference.ts +12 -22
- package/src/config/schemas/memory-storage.ts +19 -1
- package/src/config/schemas/platform.ts +0 -16
- package/src/config/skill-state.ts +11 -8
- package/src/config/skills.ts +83 -32
- package/src/context/token-estimator.ts +11 -0
- package/src/context/window-manager.ts +180 -151
- package/src/daemon/computer-use-session.ts +11 -43
- package/src/daemon/daemon-control.ts +4 -1
- package/src/daemon/handlers/config-channels.ts +5 -9
- package/src/daemon/handlers/config-ingress.ts +0 -4
- package/src/daemon/handlers/config-model.ts +7 -13
- package/src/daemon/handlers/config-telegram.ts +4 -8
- package/src/daemon/handlers/config-voice.ts +2 -5
- package/src/daemon/handlers/dictation.ts +2 -12
- package/src/daemon/handlers/identity.ts +0 -105
- package/src/daemon/handlers/recording.ts +3 -23
- package/src/daemon/handlers/session-history.ts +42 -10
- package/src/daemon/handlers/sessions.ts +53 -72
- package/src/daemon/handlers/shared.ts +7 -28
- package/src/daemon/handlers/skills.ts +31 -27
- package/src/daemon/host-bash-proxy.ts +148 -0
- package/src/daemon/host-file-proxy.ts +135 -0
- package/src/daemon/lifecycle.ts +53 -41
- package/src/daemon/mcp-reload-service.ts +123 -0
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/apps.ts +0 -25
- package/src/daemon/message-types/browser.ts +1 -1
- package/src/daemon/message-types/computer-use.ts +1 -4
- package/src/daemon/message-types/guardian-actions.ts +1 -1
- package/src/daemon/message-types/host-bash.ts +18 -0
- package/src/daemon/message-types/host-file.ts +44 -0
- package/src/daemon/message-types/integrations.ts +1 -73
- package/src/daemon/message-types/messages.ts +15 -0
- package/src/daemon/message-types/schedules.ts +11 -27
- package/src/daemon/message-types/sessions.ts +8 -2
- package/src/daemon/message-types/settings.ts +1 -1
- package/src/daemon/message-types/shared.ts +1 -1
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/ride-shotgun-handler.ts +35 -43
- package/src/daemon/seed-files.ts +3 -27
- package/src/daemon/server.ts +45 -28
- package/src/daemon/session-agent-loop-handlers.ts +72 -9
- package/src/daemon/session-agent-loop.ts +97 -66
- package/src/daemon/session-attachments.ts +1 -1
- package/src/daemon/session-error.ts +17 -16
- package/src/daemon/session-lifecycle.ts +20 -1
- package/src/daemon/session-media-retry.ts +1 -15
- package/src/daemon/session-messaging.ts +14 -6
- package/src/daemon/session-process.ts +36 -7
- package/src/daemon/session-queue-manager.ts +62 -103
- package/src/daemon/session-runtime-assembly.ts +27 -7
- package/src/daemon/session-skill-tools.ts +12 -11
- package/src/daemon/session-slash.ts +7 -0
- package/src/daemon/session-surfaces.ts +192 -118
- package/src/daemon/session-tool-setup.ts +146 -6
- package/src/daemon/session.ts +75 -37
- package/src/errors.ts +0 -2
- package/src/export/formatter.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +1 -3
- package/src/media/avatar-router.ts +20 -28
- package/src/media/avatar-types.ts +7 -14
- package/src/media/managed-avatar-client.ts +70 -34
- package/src/memory/app-store.ts +0 -18
- package/src/memory/conversation-title-service.ts +1 -2
- package/src/memory/db-init.ts +16 -0
- package/src/memory/embedding-backend.ts +129 -27
- package/src/memory/embedding-gemini.test.ts +256 -0
- package/src/memory/embedding-gemini.ts +47 -13
- package/src/memory/embedding-local.ts +14 -2
- package/src/memory/embedding-ollama.ts +15 -2
- package/src/memory/embedding-openai.ts +15 -2
- package/src/memory/embedding-types.test.ts +116 -0
- package/src/memory/embedding-types.ts +61 -0
- package/src/memory/fingerprint.ts +1 -1
- package/src/memory/indexer.ts +25 -1
- package/src/memory/job-handlers/embedding.test.ts +258 -0
- package/src/memory/job-handlers/embedding.ts +81 -1
- package/src/memory/job-handlers/index-maintenance.ts +35 -1
- package/src/memory/job-handlers/media-processing.ts +11 -1
- package/src/memory/job-utils.ts +21 -6
- package/src/memory/jobs-store.ts +5 -1
- package/src/memory/jobs-worker.ts +8 -0
- package/src/memory/message-content.ts +66 -0
- package/src/memory/migrations/100-core-tables.ts +1 -31
- package/src/memory/migrations/104-core-indexes.ts +0 -11
- package/src/memory/migrations/145-drop-accounts-table.ts +19 -0
- package/src/memory/migrations/146-schedule-oneshot-routing.ts +94 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +129 -0
- package/src/memory/migrations/148-drop-reminders-table.ts +18 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +19 -0
- package/src/memory/qdrant-client.ts +158 -43
- package/src/memory/retriever.test.ts +0 -1
- package/src/memory/retriever.ts +12 -2
- package/src/memory/schema/infrastructure.ts +5 -37
- package/src/memory/search/formatting.ts +34 -9
- package/src/memory/search/semantic.ts +57 -2
- package/src/memory/search/types.ts +2 -1
- package/src/notifications/AGENTS.md +2 -2
- package/src/notifications/README.md +59 -58
- package/src/notifications/adapters/macos.ts +1 -1
- package/src/notifications/broadcaster.ts +5 -5
- package/src/notifications/copy-composer.ts +1 -1
- package/src/notifications/decision-engine.ts +2 -2
- package/src/notifications/destination-resolver.ts +2 -2
- package/src/notifications/emit-signal.ts +8 -8
- package/src/notifications/signal.ts +1 -1
- package/src/notifications/thread-seed-composer.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +1 -1
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +12 -1
- package/src/permissions/defaults.ts +13 -17
- package/src/permissions/trust-store.ts +37 -0
- package/src/permissions/workspace-policy.ts +0 -1
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +11 -0
- package/src/prompts/computer-use-prompt.ts +1 -1
- package/src/prompts/system-prompt.ts +33 -35
- package/src/prompts/templates/BOOTSTRAP.md +0 -3
- package/src/prompts/templates/SOUL.md +1 -2
- package/src/prompts/templates/UPDATES.md +16 -7
- package/src/providers/anthropic/client.ts +87 -33
- package/src/providers/gemini/client.ts +6 -0
- package/src/providers/managed-proxy/constants.ts +5 -0
- package/src/providers/openai/client.ts +15 -0
- package/src/providers/registry.ts +4 -6
- package/src/providers/types.ts +24 -2
- package/src/runtime/AGENTS.md +18 -0
- package/src/runtime/assistant-event-hub.ts +2 -3
- package/src/runtime/assistant-event.ts +4 -4
- package/src/runtime/auth/__tests__/context.test.ts +5 -5
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/guard-tests.test.ts +3 -2
- package/src/runtime/auth/__tests__/{ipc-auth-context.test.ts → local-auth-context.test.ts} +21 -21
- package/src/runtime/auth/__tests__/route-policy.test.ts +2 -2
- package/src/runtime/auth/__tests__/scopes.test.ts +9 -8
- package/src/runtime/auth/__tests__/subject.test.ts +8 -8
- package/src/runtime/auth/__tests__/token-service.test.ts +0 -1
- package/src/runtime/auth/route-policy.ts +8 -8
- package/src/runtime/auth/scopes.ts +2 -1
- package/src/runtime/auth/subject.ts +4 -4
- package/src/runtime/auth/token-service.ts +1 -24
- package/src/runtime/auth/types.ts +3 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-action-grant-minter.ts +1 -1
- package/src/runtime/guardian-action-service.ts +3 -3
- package/src/runtime/http-server.ts +15 -2
- package/src/runtime/http-types.ts +10 -0
- package/src/runtime/invite-service.ts +3 -3
- package/src/runtime/local-actor-identity.ts +17 -22
- package/src/runtime/middleware/error-handler.ts +14 -1
- package/src/runtime/pending-interactions.ts +21 -9
- package/src/runtime/routes/app-management-routes.ts +63 -67
- package/src/runtime/routes/approval-routes.ts +1 -3
- package/src/runtime/routes/brain-graph/brain-graph.html +1845 -0
- package/src/runtime/routes/brain-graph-routes.ts +4 -42
- package/src/runtime/routes/btw-routes.ts +155 -0
- package/src/runtime/routes/computer-use-routes.ts +77 -31
- package/src/runtime/routes/conversation-routes.ts +234 -47
- package/src/runtime/routes/diagnostics-routes.ts +154 -43
- package/src/runtime/routes/documents-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/host-bash-routes.ts +83 -0
- package/src/runtime/routes/host-file-routes.ts +79 -0
- package/src/runtime/routes/integrations/slack/share.ts +1 -1
- package/src/runtime/routes/log-export-routes.ts +120 -0
- package/src/runtime/routes/mcp-routes.ts +20 -0
- package/src/runtime/routes/migration-routes.ts +3 -3
- package/src/runtime/routes/pairing-routes.ts +1 -1
- package/src/runtime/routes/recording-routes.ts +6 -4
- package/src/runtime/routes/schedule-routes.ts +31 -5
- package/src/runtime/routes/session-management-routes.ts +2 -6
- package/src/runtime/routes/session-query-routes.ts +18 -15
- package/src/runtime/routes/settings-routes.ts +7 -351
- package/src/runtime/routes/skills-routes.ts +7 -6
- package/src/runtime/routes/subagents-routes.ts +4 -10
- package/src/runtime/routes/surface-action-routes.ts +3 -14
- package/src/runtime/routes/surface-content-routes.ts +22 -5
- package/src/runtime/routes/work-items-routes.ts +21 -25
- package/src/runtime/routes/workspace-routes.test.ts +3 -3
- package/src/runtime/routes/workspace-utils.ts +1 -1
- package/src/runtime/telegram-streaming-delivery.ts +3 -0
- package/src/runtime/verification-outbound-actions.ts +2 -2
- package/src/schedule/integration-status.ts +0 -6
- package/src/schedule/schedule-store.ts +234 -43
- package/src/schedule/scheduler.ts +73 -74
- package/src/security/oauth2.ts +1 -1
- package/src/sequence/store.ts +12 -2
- package/src/skills/frontmatter.ts +19 -77
- package/src/skills/managed-store.ts +11 -2
- package/src/subagent/manager.ts +5 -3
- package/src/tasks/ephemeral-permissions.ts +3 -5
- package/src/tools/AGENTS.md +37 -0
- package/src/tools/apps/executors.ts +0 -6
- package/src/tools/browser/browser-manager.ts +17 -11
- package/src/tools/browser/jit-auth.ts +4 -1
- package/src/tools/claude-code/claude-code.ts +1 -1
- package/src/tools/computer-use/definitions.ts +48 -60
- package/src/tools/document/document-tool.ts +6 -6
- package/src/tools/document/editor-template.ts +10 -8
- package/src/tools/filesystem/edit.ts +2 -1
- package/src/tools/filesystem/read.ts +20 -2
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +17 -1
- package/src/tools/host-filesystem/read.ts +16 -1
- package/src/tools/host-filesystem/write.ts +15 -1
- package/src/tools/host-terminal/host-shell.ts +24 -0
- package/src/tools/memory/definitions.ts +45 -81
- package/src/tools/memory/handlers.test.ts +0 -1
- package/src/tools/memory/handlers.ts +1 -1
- package/src/tools/memory/register.ts +26 -60
- package/src/tools/network/script-proxy/session-manager.ts +6 -8
- package/src/tools/network/web-fetch.ts +7 -1
- package/src/tools/network/web-search.ts +2 -1
- package/src/tools/registry.ts +23 -0
- package/src/tools/schedule/create.ts +113 -5
- package/src/tools/schedule/list.ts +57 -15
- package/src/tools/schedule/update.ts +73 -3
- package/src/tools/shared/filesystem/image-read.ts +192 -0
- package/src/tools/side-effects.ts +1 -7
- package/src/tools/skills/delete-managed.ts +27 -64
- package/src/tools/skills/execute.ts +54 -0
- package/src/tools/skills/load.ts +127 -5
- package/src/tools/skills/scaffold-managed.ts +93 -172
- package/src/tools/subagent/message.ts +0 -7
- package/src/tools/subagent/spawn.ts +1 -1
- package/src/tools/swarm/delegate.ts +0 -3
- package/src/tools/system/avatar-generator.ts +13 -19
- package/src/tools/system/request-permission.ts +2 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/tool-manifest.ts +41 -47
- package/src/tools/types.ts +6 -2
- package/src/tools/ui-surface/definitions.ts +0 -55
- package/src/util/errors.ts +12 -10
- package/src/workspace/git-service.ts +0 -2
- package/src/__tests__/account-registry.test.ts +0 -258
- package/src/__tests__/email-classifier.test.ts +0 -25
- package/src/__tests__/gmail-integration.test.ts +0 -97
- package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -172
- package/src/__tests__/home-base-bootstrap.test.ts +0 -84
- package/src/__tests__/managed-twitter-guardrails.test.ts +0 -353
- package/src/__tests__/prebuilt-home-base-seed.test.ts +0 -79
- package/src/__tests__/recording-intent-fallback.test.ts +0 -199
- package/src/__tests__/recording-intent.test.ts +0 -985
- package/src/__tests__/recording-state-machine.test.ts +0 -1574
- package/src/__tests__/reminder-store.test.ts +0 -350
- package/src/__tests__/reminder.test.ts +0 -337
- package/src/__tests__/scan-result-store.test.ts +0 -121
- package/src/__tests__/twitter-platform-proxy-client.test.ts +0 -450
- package/src/__tests__/view-image-tool.test.ts +0 -241
- package/src/cli/commands/amazon/cart.ts +0 -513
- package/src/cli/commands/amazon/checkout.ts +0 -394
- package/src/cli/commands/amazon/client.ts +0 -513
- package/src/cli/commands/amazon/index.ts +0 -920
- package/src/cli/commands/amazon/product-details.ts +0 -145
- package/src/cli/commands/amazon/request-extractor.ts +0 -187
- package/src/cli/commands/amazon/search.ts +0 -76
- package/src/cli/commands/amazon/session.ts +0 -116
- package/src/cli/commands/twitter/__tests__/cli-error-shaping.test.ts +0 -265
- package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +0 -483
- package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +0 -412
- package/src/cli/commands/twitter/__tests__/oauth-client.test.ts +0 -197
- package/src/cli/commands/twitter/client.ts +0 -989
- package/src/cli/commands/twitter/index.ts +0 -1160
- package/src/cli/commands/twitter/oauth-client.ts +0 -94
- package/src/cli/commands/twitter/router.ts +0 -396
- package/src/cli/commands/twitter/session.ts +0 -121
- package/src/config/bundled-skills/agentmail/SKILL.md +0 -132
- package/src/config/bundled-skills/agentmail/icon.svg +0 -21
- package/src/config/bundled-skills/amazon/SKILL.md +0 -137
- package/src/config/bundled-skills/amazon/icon.svg +0 -13
- package/src/config/bundled-skills/api-mapping/SKILL.md +0 -78
- package/src/config/bundled-skills/api-mapping/icon.svg +0 -18
- package/src/config/bundled-skills/cli-discover/SKILL.md +0 -68
- package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +0 -179
- package/src/config/bundled-skills/document-writer/SKILL.md +0 -195
- package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +0 -140
- package/src/config/bundled-skills/email-setup/SKILL.md +0 -68
- package/src/config/bundled-skills/frontend-design/SKILL.md +0 -44
- package/src/config/bundled-skills/frontend-design/icon.svg +0 -16
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +0 -452
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +0 -203
- package/src/config/bundled-skills/influencer/SKILL.md +0 -144
- package/src/config/bundled-skills/influencer/scripts/client.ts +0 -1269
- package/src/config/bundled-skills/influencer/scripts/influencer.ts +0 -267
- package/src/config/bundled-skills/macos-automation/SKILL.md +0 -65
- package/src/config/bundled-skills/macos-automation/icon.svg +0 -12
- package/src/config/bundled-skills/mcp-setup/SKILL.md +0 -75
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +0 -184
- package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +0 -80
- package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -29
- package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -56
- package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -34
- package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +0 -47
- package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -31
- package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +0 -67
- package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +0 -97
- package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +0 -135
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -24
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -201
- package/src/config/bundled-skills/messaging/tools/send-notification.ts +0 -1
- package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +0 -27
- package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +0 -48
- package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +0 -27
- package/src/config/bundled-skills/messaging/tools/sequence-update.ts +0 -56
- package/src/config/bundled-skills/notion/SKILL.md +0 -240
- package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +0 -126
- package/src/config/bundled-skills/oauth-setup/SKILL.md +0 -143
- package/src/config/bundled-skills/public-ingress/SKILL.md +0 -258
- package/src/config/bundled-skills/reminder/SKILL.md +0 -79
- package/src/config/bundled-skills/reminder/TOOLS.json +0 -89
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -12
- package/src/config/bundled-skills/restaurant-reservation/SKILL.md +0 -141
- package/src/config/bundled-skills/screen-recording/SKILL.md +0 -148
- package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -69
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -78
- package/src/config/bundled-skills/slack-app-setup/SKILL.md +0 -178
- package/src/config/bundled-skills/slack-digest-setup/SKILL.md +0 -163
- package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +0 -157
- package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
- package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
- package/src/config/bundled-skills/telegram-setup/SKILL.md +0 -105
- package/src/config/bundled-skills/time-based-actions/SKILL.md +0 -142
- package/src/config/bundled-skills/twilio-setup/SKILL.md +0 -232
- package/src/config/bundled-skills/twitter/SKILL.md +0 -319
- package/src/config/bundled-skills/twitter/icon.svg +0 -14
- package/src/config/bundled-skills/typescript-eval/SKILL.md +0 -60
- package/src/config/bundled-skills/vercel-token-setup/SKILL.md +0 -214
- package/src/config/bundled-skills/voice-setup/SKILL.md +0 -131
- package/src/config/bundled-skills/voice-setup/icon.svg +0 -20
- package/src/daemon/handlers/pairing.ts +0 -119
- package/src/daemon/handlers/session-user-message.ts +0 -961
- package/src/daemon/recording-executor.ts +0 -180
- package/src/daemon/recording-intent-fallback.ts +0 -162
- package/src/daemon/recording-intent.ts +0 -493
- package/src/home-base/app-link-store.ts +0 -78
- package/src/home-base/bootstrap.ts +0 -74
- package/src/home-base/prebuilt/brain-graph.html +0 -1483
- package/src/home-base/prebuilt/index.html +0 -702
- package/src/home-base/prebuilt/seed-metadata.json +0 -21
- package/src/home-base/prebuilt/seed.ts +0 -122
- package/src/home-base/prebuilt-home-base-updater.ts +0 -36
- package/src/memory/account-store.ts +0 -117
- package/src/messaging/activity-analyzer.ts +0 -76
- package/src/messaging/email-classifier.ts +0 -208
- package/src/messaging/index.ts +0 -2
- package/src/messaging/outreach-classifier.ts +0 -185
- package/src/messaging/thread-summarizer.ts +0 -346
- package/src/messaging/types.ts +0 -17
- package/src/tools/browser/x-auto-navigate.ts +0 -254
- package/src/tools/credentials/account-registry.ts +0 -144
- package/src/tools/filesystem/view-image.ts +0 -244
- package/src/tools/reminder/reminder-store.ts +0 -194
- package/src/tools/reminder/reminder.ts +0 -158
- package/src/tools/system/navigate-settings.ts +0 -74
- package/src/tools/system/open-system-settings.ts +0 -85
- package/src/tools/system/version.ts +0 -54
- package/src/twitter/platform-proxy-client.ts +0 -405
- package/src/util/cookie-session.ts +0 -98
- /package/src/config/bundled-skills/{messaging → gmail}/tools/scan-result-store.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-analytics.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-create.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-delete.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enroll.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enrollment-list.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-get.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-import.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-list.ts +0 -0
|
@@ -14,15 +14,33 @@ import {
|
|
|
14
14
|
parseChannelId,
|
|
15
15
|
parseInterfaceId,
|
|
16
16
|
} from "../../channels/types.js";
|
|
17
|
+
import { getConfig } from "../../config/loader.js";
|
|
17
18
|
import { renderHistoryContent } from "../../daemon/handlers/shared.js";
|
|
19
|
+
import { HostBashProxy } from "../../daemon/host-bash-proxy.js";
|
|
20
|
+
import { HostFileProxy } from "../../daemon/host-file-proxy.js";
|
|
18
21
|
import type { ServerMessage } from "../../daemon/message-protocol.js";
|
|
22
|
+
import {
|
|
23
|
+
buildModelInfoEvent,
|
|
24
|
+
isModelSlashCommand,
|
|
25
|
+
} from "../../daemon/session-process.js";
|
|
26
|
+
import {
|
|
27
|
+
isProviderShortcut,
|
|
28
|
+
resolveSlash,
|
|
29
|
+
type SlashContext,
|
|
30
|
+
} from "../../daemon/session-slash.js";
|
|
19
31
|
import * as attachmentsStore from "../../memory/attachments-store.js";
|
|
20
32
|
import {
|
|
21
33
|
createCanonicalGuardianRequest,
|
|
22
34
|
generateCanonicalRequestCode,
|
|
23
35
|
listPendingRequestsByConversationScope,
|
|
24
36
|
} from "../../memory/canonical-guardian-store.js";
|
|
25
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
addMessage,
|
|
39
|
+
getMessages,
|
|
40
|
+
provenanceFromTrustContext,
|
|
41
|
+
setConversationOriginChannelIfUnset,
|
|
42
|
+
setConversationOriginInterfaceIfUnset,
|
|
43
|
+
} from "../../memory/conversation-crud.js";
|
|
26
44
|
import {
|
|
27
45
|
getConversationByKey,
|
|
28
46
|
getOrCreateConversation,
|
|
@@ -30,6 +48,7 @@ import {
|
|
|
30
48
|
import { searchConversations } from "../../memory/conversation-queries.js";
|
|
31
49
|
import { getConfiguredProvider } from "../../providers/provider-send-message.js";
|
|
32
50
|
import type { Provider } from "../../providers/types.js";
|
|
51
|
+
import { checkIngressForSecrets } from "../../security/secret-ingress.js";
|
|
33
52
|
import { getLogger } from "../../util/logger.js";
|
|
34
53
|
import { buildAssistantEvent } from "../assistant-event.js";
|
|
35
54
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
@@ -331,6 +350,9 @@ export function handleListMessages(
|
|
|
331
350
|
attachments: msgAttachments,
|
|
332
351
|
...(m.toolCalls.length > 0 ? { toolCalls: m.toolCalls } : {}),
|
|
333
352
|
...(interfaces ? { interfaces } : {}),
|
|
353
|
+
...(m.surfaces.length > 0 ? { surfaces: m.surfaces } : {}),
|
|
354
|
+
...(m.textSegments.length > 0 ? { textSegments: m.textSegments } : {}),
|
|
355
|
+
...(m.contentOrder.length > 0 ? { contentOrder: m.contentOrder } : {}),
|
|
334
356
|
};
|
|
335
357
|
});
|
|
336
358
|
|
|
@@ -341,9 +363,10 @@ export function handleListMessages(
|
|
|
341
363
|
* Build an `onEvent` callback that publishes every outbound event to the
|
|
342
364
|
* assistant event hub, maintaining ordered delivery through a serial chain.
|
|
343
365
|
*
|
|
344
|
-
* Also registers pending interactions when confirmation_request
|
|
345
|
-
* secret_request
|
|
346
|
-
* can look up the session
|
|
366
|
+
* Also registers pending interactions when confirmation_request,
|
|
367
|
+
* secret_request, host_bash_request, or host_file_request events flow
|
|
368
|
+
* through, so standalone approval/result endpoints can look up the session
|
|
369
|
+
* by requestId.
|
|
347
370
|
*/
|
|
348
371
|
function makeHubPublisher(
|
|
349
372
|
deps: SendMessageDeps,
|
|
@@ -370,7 +393,7 @@ function makeHubPublisher(
|
|
|
370
393
|
},
|
|
371
394
|
});
|
|
372
395
|
|
|
373
|
-
// Create a canonical guardian request so
|
|
396
|
+
// Create a canonical guardian request so HTTP handlers can find it
|
|
374
397
|
// via applyCanonicalGuardianDecision.
|
|
375
398
|
try {
|
|
376
399
|
const trustContext = session.trustContext;
|
|
@@ -414,6 +437,18 @@ function makeHubPublisher(
|
|
|
414
437
|
conversationId,
|
|
415
438
|
kind: "secret",
|
|
416
439
|
});
|
|
440
|
+
} else if (msg.type === "host_bash_request") {
|
|
441
|
+
pendingInteractions.register(msg.requestId, {
|
|
442
|
+
session,
|
|
443
|
+
conversationId,
|
|
444
|
+
kind: "host_bash",
|
|
445
|
+
});
|
|
446
|
+
} else if (msg.type === "host_file_request") {
|
|
447
|
+
pendingInteractions.register(msg.requestId, {
|
|
448
|
+
session,
|
|
449
|
+
conversationId,
|
|
450
|
+
kind: "host_file",
|
|
451
|
+
});
|
|
417
452
|
}
|
|
418
453
|
|
|
419
454
|
// ServerMessage is a large union; sessionId exists on most but not all variants.
|
|
@@ -523,6 +558,29 @@ export async function handleSendMessage(
|
|
|
523
558
|
}
|
|
524
559
|
}
|
|
525
560
|
|
|
561
|
+
// Block inbound messages containing secrets before they reach the model.
|
|
562
|
+
// This mirrors the legacy handleUserMessage behavior: secrets are
|
|
563
|
+
// detected and the message is rejected with a safe notice. The client
|
|
564
|
+
// should prompt the user to use the secure credential flow instead.
|
|
565
|
+
if (trimmedContent.length > 0) {
|
|
566
|
+
const ingressCheck = checkIngressForSecrets(trimmedContent);
|
|
567
|
+
if (ingressCheck.blocked) {
|
|
568
|
+
log.warn(
|
|
569
|
+
{ detectedTypes: ingressCheck.detectedTypes },
|
|
570
|
+
"Blocked user message containing secrets (POST /v1/messages)",
|
|
571
|
+
);
|
|
572
|
+
return Response.json(
|
|
573
|
+
{
|
|
574
|
+
accepted: false,
|
|
575
|
+
error: "secret_blocked",
|
|
576
|
+
message: ingressCheck.userNotice,
|
|
577
|
+
detectedTypes: ingressCheck.detectedTypes,
|
|
578
|
+
},
|
|
579
|
+
{ status: 422 },
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
526
584
|
if (!deps.sendMessageDeps) {
|
|
527
585
|
return httpError(
|
|
528
586
|
"SERVICE_UNAVAILABLE",
|
|
@@ -554,11 +612,49 @@ export async function handleSendMessage(
|
|
|
554
612
|
}
|
|
555
613
|
|
|
556
614
|
const onEvent = makeHubPublisher(smDeps, mapping.conversationId, session);
|
|
557
|
-
//
|
|
558
|
-
//
|
|
559
|
-
//
|
|
560
|
-
|
|
561
|
-
|
|
615
|
+
// Desktop, CLI, and web interfaces have an SSE client that can display
|
|
616
|
+
// permission prompts. Channel interfaces (telegram, slack, etc.) route
|
|
617
|
+
// approvals through the guardian system and have no interactive prompter UI.
|
|
618
|
+
const isInteractiveInterface =
|
|
619
|
+
sourceInterface === "macos" ||
|
|
620
|
+
sourceInterface === "ios" ||
|
|
621
|
+
sourceInterface === "cli" ||
|
|
622
|
+
sourceInterface === "vellum";
|
|
623
|
+
// Only create the host bash proxy for desktop client interfaces that can
|
|
624
|
+
// execute commands on the user's machine. Non-desktop sessions (CLI,
|
|
625
|
+
// channels, headless) fall back to local execution.
|
|
626
|
+
// Set the proxy BEFORE updateClient so updateClient's call to
|
|
627
|
+
// hostBashProxy.updateSender targets the correct (new) proxy.
|
|
628
|
+
if (sourceInterface === "macos" || sourceInterface === "ios") {
|
|
629
|
+
// Reuse the existing proxy if the session is actively processing a
|
|
630
|
+
// host bash request to avoid orphaning in-flight requests.
|
|
631
|
+
if (!session.isProcessing() || !session.hostBashProxy) {
|
|
632
|
+
const proxy = new HostBashProxy(onEvent, (requestId) => {
|
|
633
|
+
pendingInteractions.resolve(requestId);
|
|
634
|
+
});
|
|
635
|
+
session.setHostBashProxy(proxy);
|
|
636
|
+
}
|
|
637
|
+
if (!session.isProcessing() || !session.hostFileProxy) {
|
|
638
|
+
const fileProxy = new HostFileProxy(onEvent, (requestId) => {
|
|
639
|
+
pendingInteractions.resolve(requestId);
|
|
640
|
+
});
|
|
641
|
+
session.setHostFileProxy(fileProxy);
|
|
642
|
+
}
|
|
643
|
+
} else if (!session.isProcessing()) {
|
|
644
|
+
session.setHostBashProxy(undefined);
|
|
645
|
+
session.setHostFileProxy(undefined);
|
|
646
|
+
}
|
|
647
|
+
// Wire sendToClient to the SSE hub so all subsystems can reach the HTTP client.
|
|
648
|
+
// Called after setHostBashProxy so updateSender targets the current proxy.
|
|
649
|
+
// When proxies are preserved during an active turn (non-desktop request while
|
|
650
|
+
// processing), skip updating proxy senders to avoid degrading them.
|
|
651
|
+
const preservingProxies =
|
|
652
|
+
session.isProcessing() &&
|
|
653
|
+
sourceInterface !== "macos" &&
|
|
654
|
+
sourceInterface !== "ios";
|
|
655
|
+
session.updateClient(onEvent, !isInteractiveInterface, {
|
|
656
|
+
skipProxySenderUpdate: preservingProxies,
|
|
657
|
+
});
|
|
562
658
|
|
|
563
659
|
const attachments = hasAttachments
|
|
564
660
|
? smDeps.resolveAttachments(attachmentIds)
|
|
@@ -573,7 +669,7 @@ export async function handleSendMessage(
|
|
|
573
669
|
|
|
574
670
|
// Try to consume the message as a canonical guardian approval/rejection reply.
|
|
575
671
|
// On failure, degrade to the existing queue/auto-deny path rather than
|
|
576
|
-
// surfacing a 500 — mirrors the
|
|
672
|
+
// surfacing a 500 — mirrors the handler's catch-and-fallback.
|
|
577
673
|
try {
|
|
578
674
|
const inlineReplyResult = await tryConsumeCanonicalGuardianReply({
|
|
579
675
|
conversationId: mapping.conversationId,
|
|
@@ -606,11 +702,36 @@ export async function handleSendMessage(
|
|
|
606
702
|
}
|
|
607
703
|
|
|
608
704
|
if (session.isProcessing()) {
|
|
609
|
-
//
|
|
610
|
-
|
|
705
|
+
// Queue the message so it's processed when the current turn completes
|
|
706
|
+
const requestId = crypto.randomUUID();
|
|
707
|
+
const enqueueResult = session.enqueueMessage(
|
|
708
|
+
content ?? "",
|
|
709
|
+
attachments,
|
|
710
|
+
onEvent,
|
|
711
|
+
requestId,
|
|
712
|
+
undefined, // activeSurfaceId
|
|
713
|
+
undefined, // currentPage
|
|
714
|
+
{
|
|
715
|
+
userMessageChannel: sourceChannel,
|
|
716
|
+
assistantMessageChannel: sourceChannel,
|
|
717
|
+
userMessageInterface: sourceInterface,
|
|
718
|
+
assistantMessageInterface: sourceInterface,
|
|
719
|
+
},
|
|
720
|
+
{ isInteractive: isInteractiveInterface },
|
|
721
|
+
);
|
|
722
|
+
if (enqueueResult.rejected) {
|
|
723
|
+
return Response.json(
|
|
724
|
+
{ accepted: false, error: "queue_full" },
|
|
725
|
+
{ status: 429 },
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// Auto-deny pending confirmations only after enqueue succeeds, so we
|
|
730
|
+
// don't cancel approval-gated workflows when the replacement message
|
|
731
|
+
// is itself rejected by the queue budget.
|
|
611
732
|
if (session.hasAnyPendingConfirmation()) {
|
|
612
733
|
// Emit authoritative denial state for each pending request.
|
|
613
|
-
//
|
|
734
|
+
// sendToClient (wired to the SSE hub) delivers these to the client.
|
|
614
735
|
for (const interaction of pendingInteractions.getByConversation(
|
|
615
736
|
mapping.conversationId,
|
|
616
737
|
)) {
|
|
@@ -630,30 +751,6 @@ export async function handleSendMessage(
|
|
|
630
751
|
pendingInteractions.removeBySession(session);
|
|
631
752
|
}
|
|
632
753
|
|
|
633
|
-
// Queue the message so it's processed when the current turn completes
|
|
634
|
-
const requestId = crypto.randomUUID();
|
|
635
|
-
const result = session.enqueueMessage(
|
|
636
|
-
content ?? "",
|
|
637
|
-
attachments,
|
|
638
|
-
onEvent,
|
|
639
|
-
requestId,
|
|
640
|
-
undefined, // activeSurfaceId
|
|
641
|
-
undefined, // currentPage
|
|
642
|
-
{
|
|
643
|
-
userMessageChannel: sourceChannel,
|
|
644
|
-
assistantMessageChannel: sourceChannel,
|
|
645
|
-
userMessageInterface: sourceInterface,
|
|
646
|
-
assistantMessageInterface: sourceInterface,
|
|
647
|
-
},
|
|
648
|
-
{ isInteractive: false },
|
|
649
|
-
);
|
|
650
|
-
if (result.rejected) {
|
|
651
|
-
return httpError(
|
|
652
|
-
"RATE_LIMITED",
|
|
653
|
-
"Message queue is full. Please retry later.",
|
|
654
|
-
429,
|
|
655
|
-
);
|
|
656
|
-
}
|
|
657
754
|
return Response.json({ accepted: true, queued: true }, { status: 202 });
|
|
658
755
|
}
|
|
659
756
|
|
|
@@ -666,18 +763,108 @@ export async function handleSendMessage(
|
|
|
666
763
|
userMessageInterface: sourceInterface,
|
|
667
764
|
assistantMessageInterface: sourceInterface,
|
|
668
765
|
});
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
);
|
|
766
|
+
|
|
767
|
+
await session.ensureActorScopedHistory();
|
|
768
|
+
|
|
769
|
+
// Resolve slash commands before persisting or running the agent loop.
|
|
770
|
+
const rawContent = content ?? "";
|
|
771
|
+
const config = getConfig();
|
|
772
|
+
const slashContext: SlashContext = {
|
|
773
|
+
messageCount: session.getMessages().length,
|
|
774
|
+
inputTokens: session.usageStats.inputTokens,
|
|
775
|
+
outputTokens: session.usageStats.outputTokens,
|
|
776
|
+
maxInputTokens: config.contextWindow.maxInputTokens,
|
|
777
|
+
model: config.model,
|
|
778
|
+
provider: config.provider,
|
|
779
|
+
estimatedCost: session.usageStats.estimatedCost,
|
|
780
|
+
};
|
|
781
|
+
const slashResult = resolveSlash(rawContent, slashContext);
|
|
782
|
+
|
|
783
|
+
if (slashResult.kind === "unknown") {
|
|
784
|
+
session.processing = true;
|
|
785
|
+
try {
|
|
786
|
+
const provenance = provenanceFromTrustContext(session.trustContext);
|
|
787
|
+
const channelMeta = {
|
|
788
|
+
...provenance,
|
|
789
|
+
userMessageChannel: sourceChannel,
|
|
790
|
+
assistantMessageChannel: sourceChannel,
|
|
791
|
+
userMessageInterface: sourceInterface,
|
|
792
|
+
assistantMessageInterface: sourceInterface,
|
|
793
|
+
};
|
|
794
|
+
const userMsg = createUserMessage(rawContent, attachments);
|
|
795
|
+
const persisted = await addMessage(
|
|
796
|
+
mapping.conversationId,
|
|
797
|
+
"user",
|
|
798
|
+
JSON.stringify(userMsg.content),
|
|
799
|
+
channelMeta,
|
|
800
|
+
);
|
|
801
|
+
session.getMessages().push(userMsg);
|
|
802
|
+
|
|
803
|
+
const assistantMsg = createAssistantMessage(slashResult.message);
|
|
804
|
+
await addMessage(
|
|
805
|
+
mapping.conversationId,
|
|
806
|
+
"assistant",
|
|
807
|
+
JSON.stringify(assistantMsg.content),
|
|
808
|
+
channelMeta,
|
|
809
|
+
);
|
|
810
|
+
session.getMessages().push(assistantMsg);
|
|
811
|
+
|
|
812
|
+
setConversationOriginChannelIfUnset(
|
|
813
|
+
mapping.conversationId,
|
|
814
|
+
sourceChannel,
|
|
815
|
+
);
|
|
816
|
+
setConversationOriginInterfaceIfUnset(
|
|
817
|
+
mapping.conversationId,
|
|
818
|
+
sourceInterface,
|
|
819
|
+
);
|
|
820
|
+
|
|
821
|
+
// Emit fresh model info before the text delta so the client has
|
|
822
|
+
// up-to-date configuredProviders when rendering /model, /models,
|
|
823
|
+
// and provider shortcut commands (/gpt4, /opus, etc.).
|
|
824
|
+
if (isModelSlashCommand(rawContent) || isProviderShortcut(rawContent)) {
|
|
825
|
+
onEvent(buildModelInfoEvent());
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
onEvent({ type: "assistant_text_delta", text: slashResult.message });
|
|
829
|
+
onEvent({
|
|
830
|
+
type: "message_complete",
|
|
831
|
+
sessionId: mapping.conversationId,
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
return Response.json(
|
|
835
|
+
{ accepted: true, messageId: persisted.id },
|
|
836
|
+
{ status: 202 },
|
|
837
|
+
);
|
|
838
|
+
} finally {
|
|
839
|
+
session.processing = false;
|
|
840
|
+
session.drainQueue().catch(() => {});
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
const resolvedContent = slashResult.content;
|
|
845
|
+
if (slashResult.kind === "rewritten") {
|
|
846
|
+
session.setPreactivatedSkillIds([slashResult.skillId]);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
let messageId: string;
|
|
850
|
+
try {
|
|
851
|
+
const requestId = crypto.randomUUID();
|
|
852
|
+
messageId = await session.persistUserMessage(
|
|
853
|
+
resolvedContent,
|
|
854
|
+
attachments,
|
|
855
|
+
requestId,
|
|
856
|
+
);
|
|
857
|
+
} catch (err) {
|
|
858
|
+
// Reset preactivated skill IDs so a stale activation doesn't leak
|
|
859
|
+
// into the next message if persistence fails.
|
|
860
|
+
session.setPreactivatedSkillIds(undefined);
|
|
861
|
+
throw err;
|
|
862
|
+
}
|
|
675
863
|
|
|
676
864
|
// Fire-and-forget the agent loop; events flow to the hub via onEvent.
|
|
677
|
-
// Mark non-interactive so conflict clarification doesn't block the turn.
|
|
678
865
|
session
|
|
679
|
-
.runAgentLoop(
|
|
680
|
-
isInteractive:
|
|
866
|
+
.runAgentLoop(resolvedContent, messageId, onEvent, {
|
|
867
|
+
isInteractive: isInteractiveInterface,
|
|
681
868
|
isUserMessage: true,
|
|
682
869
|
})
|
|
683
870
|
.catch((err) => {
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HTTP route handlers for diagnostics export and dictation processing.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - handlers/diagnostics.ts (diagnostics_export_request)
|
|
6
|
-
* - handlers/dictation.ts (dictation_request)
|
|
4
|
+
* Handles diagnostics export and dictation processing requests.
|
|
7
5
|
*/
|
|
8
6
|
|
|
9
7
|
import { randomBytes } from "node:crypto";
|
|
10
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
createWriteStream,
|
|
10
|
+
mkdirSync,
|
|
11
|
+
readdirSync,
|
|
12
|
+
readFileSync,
|
|
13
|
+
rmSync,
|
|
14
|
+
statSync,
|
|
15
|
+
writeFileSync,
|
|
16
|
+
} from "node:fs";
|
|
11
17
|
import { homedir, tmpdir } from "node:os";
|
|
12
|
-
import { join } from "node:path";
|
|
18
|
+
import { basename, join } from "node:path";
|
|
13
19
|
|
|
14
20
|
import archiver from "archiver";
|
|
15
21
|
import { and, desc, eq, gte, lte } from "drizzle-orm";
|
|
@@ -45,7 +51,7 @@ import type { RouteDefinition } from "../http-router.js";
|
|
|
45
51
|
const log = getLogger("diagnostics-routes");
|
|
46
52
|
|
|
47
53
|
// ---------------------------------------------------------------------------
|
|
48
|
-
// Diagnostics export — redaction helpers
|
|
54
|
+
// Diagnostics export — redaction helpers
|
|
49
55
|
// ---------------------------------------------------------------------------
|
|
50
56
|
|
|
51
57
|
const MAX_CONTENT_LENGTH = 500;
|
|
@@ -104,6 +110,58 @@ function redactDeep(value: unknown): unknown {
|
|
|
104
110
|
return value;
|
|
105
111
|
}
|
|
106
112
|
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Crash report discovery
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
const CRASH_REPORT_EXTENSIONS = new Set([".crash", ".ips", ".diag"]);
|
|
118
|
+
const CRASH_REPORT_TAR_GZ = ".tar.gz";
|
|
119
|
+
const CRASH_REPORT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
120
|
+
|
|
121
|
+
function findRecentCrashReports(): string[] {
|
|
122
|
+
const diagnosticReportsDir = join(
|
|
123
|
+
homedir(),
|
|
124
|
+
"Library",
|
|
125
|
+
"Logs",
|
|
126
|
+
"DiagnosticReports",
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const entries = readdirSync(diagnosticReportsDir);
|
|
131
|
+
const now = Date.now();
|
|
132
|
+
const results: string[] = [];
|
|
133
|
+
|
|
134
|
+
for (const entry of entries) {
|
|
135
|
+
// Case-insensitive prefix match for "vellum-assistant"
|
|
136
|
+
if (!entry.toLowerCase().startsWith("vellum-assistant")) continue;
|
|
137
|
+
|
|
138
|
+
// Check extension
|
|
139
|
+
const lowerEntry = entry.toLowerCase();
|
|
140
|
+
const hasValidExt =
|
|
141
|
+
CRASH_REPORT_EXTENSIONS.has(
|
|
142
|
+
lowerEntry.slice(lowerEntry.lastIndexOf(".")),
|
|
143
|
+
) || lowerEntry.endsWith(CRASH_REPORT_TAR_GZ);
|
|
144
|
+
|
|
145
|
+
if (!hasValidExt) continue;
|
|
146
|
+
|
|
147
|
+
const filePath = join(diagnosticReportsDir, entry);
|
|
148
|
+
try {
|
|
149
|
+
const stat = statSync(filePath);
|
|
150
|
+
if (!stat.isFile()) continue;
|
|
151
|
+
if (now - stat.mtimeMs > CRASH_REPORT_MAX_AGE_MS) continue;
|
|
152
|
+
results.push(filePath);
|
|
153
|
+
} catch {
|
|
154
|
+
// Skip files we can't stat
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return results;
|
|
159
|
+
} catch {
|
|
160
|
+
// Directory doesn't exist or can't be read — not an error
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
107
165
|
// ---------------------------------------------------------------------------
|
|
108
166
|
// Diagnostics export handler
|
|
109
167
|
// ---------------------------------------------------------------------------
|
|
@@ -121,7 +179,12 @@ async function handleDiagnosticsExport(body: {
|
|
|
121
179
|
try {
|
|
122
180
|
const db = getDb();
|
|
123
181
|
|
|
124
|
-
// 1. Find the anchor message
|
|
182
|
+
// 1. Find the anchor message.
|
|
183
|
+
// Try in order: specific ID → most recent assistant message → any message.
|
|
184
|
+
// The final fallback handles the race condition where the user clicks
|
|
185
|
+
// "export" before message_complete fires and the assistant message has
|
|
186
|
+
// been persisted — the user message and in-flight tool/usage data are
|
|
187
|
+
// still captured.
|
|
125
188
|
let anchorMessage;
|
|
126
189
|
if (anchorMessageId) {
|
|
127
190
|
anchorMessage = db
|
|
@@ -134,7 +197,8 @@ async function handleDiagnosticsExport(body: {
|
|
|
134
197
|
),
|
|
135
198
|
)
|
|
136
199
|
.get();
|
|
137
|
-
}
|
|
200
|
+
}
|
|
201
|
+
if (!anchorMessage) {
|
|
138
202
|
anchorMessage = db
|
|
139
203
|
.select()
|
|
140
204
|
.from(messages)
|
|
@@ -148,30 +212,60 @@ async function handleDiagnosticsExport(body: {
|
|
|
148
212
|
.limit(1)
|
|
149
213
|
.get();
|
|
150
214
|
}
|
|
151
|
-
|
|
152
215
|
if (!anchorMessage) {
|
|
153
|
-
|
|
216
|
+
anchorMessage = db
|
|
217
|
+
.select()
|
|
218
|
+
.from(messages)
|
|
219
|
+
.where(eq(messages.conversationId, conversationId))
|
|
220
|
+
.orderBy(desc(messages.createdAt))
|
|
221
|
+
.limit(1)
|
|
222
|
+
.get();
|
|
154
223
|
}
|
|
155
224
|
|
|
156
|
-
// 2.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
225
|
+
// 2. Compute the export time range.
|
|
226
|
+
// When an anchor message exists, scope to the preceding user message
|
|
227
|
+
// through the anchor. When no messages exist at all (empty conversation
|
|
228
|
+
// or race condition), use the current timestamp so the export still
|
|
229
|
+
// captures any in-flight usage/tool data.
|
|
230
|
+
const now = Date.now();
|
|
231
|
+
let rangeEnd: number;
|
|
232
|
+
let rangeStart: number;
|
|
233
|
+
let usageRangeEnd: number;
|
|
234
|
+
|
|
235
|
+
if (anchorMessage) {
|
|
236
|
+
const precedingUserMessage = db
|
|
237
|
+
.select()
|
|
238
|
+
.from(messages)
|
|
239
|
+
.where(
|
|
240
|
+
and(
|
|
241
|
+
eq(messages.conversationId, conversationId),
|
|
242
|
+
eq(messages.role, "user"),
|
|
243
|
+
lte(messages.createdAt, anchorMessage.createdAt),
|
|
244
|
+
),
|
|
245
|
+
)
|
|
246
|
+
.orderBy(desc(messages.createdAt))
|
|
247
|
+
.limit(1)
|
|
248
|
+
.get();
|
|
170
249
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
250
|
+
rangeStart =
|
|
251
|
+
precedingUserMessage?.createdAt ?? anchorMessage.createdAt - 2000;
|
|
252
|
+
|
|
253
|
+
// When the anchor is not an assistant message (e.g. the fallback "any
|
|
254
|
+
// message" path hit because the assistant reply hasn't been persisted
|
|
255
|
+
// yet), extend the range to the current time so in-flight tool
|
|
256
|
+
// invocations and usage recorded after the user message are captured.
|
|
257
|
+
const anchorIsAssistant = anchorMessage.role === "assistant";
|
|
258
|
+
rangeEnd = anchorIsAssistant ? anchorMessage.createdAt : now;
|
|
259
|
+
usageRangeEnd = anchorIsAssistant
|
|
260
|
+
? anchorMessage.createdAt + 5000
|
|
261
|
+
: now + 5000;
|
|
262
|
+
} else {
|
|
263
|
+
// No messages at all — use the current time so we capture any
|
|
264
|
+
// in-flight LLM usage or tool invocations.
|
|
265
|
+
rangeStart = now - 60_000;
|
|
266
|
+
rangeEnd = now;
|
|
267
|
+
usageRangeEnd = now + 5000;
|
|
268
|
+
}
|
|
175
269
|
|
|
176
270
|
// 3. Query all messages in the range
|
|
177
271
|
const rangeMessages = db
|
|
@@ -239,7 +333,7 @@ async function handleDiagnosticsExport(body: {
|
|
|
239
333
|
version: "1.1",
|
|
240
334
|
exportedAt: new Date().toISOString(),
|
|
241
335
|
conversationId,
|
|
242
|
-
messageId: anchorMessage
|
|
336
|
+
messageId: anchorMessage?.id ?? null,
|
|
243
337
|
};
|
|
244
338
|
writeFileSync(
|
|
245
339
|
join(tempDir, "manifest.json"),
|
|
@@ -344,6 +438,28 @@ async function handleDiagnosticsExport(body: {
|
|
|
344
438
|
|
|
345
439
|
archive.pipe(output);
|
|
346
440
|
archive.directory(tempDir, false);
|
|
441
|
+
|
|
442
|
+
// Add recent crash report files under crash-reports/.
|
|
443
|
+
// Text-based crash files (.crash, .ips, .diag) are redacted using the
|
|
444
|
+
// same patterns as conversation data. Binary archives (.tar.gz) are
|
|
445
|
+
// added as-is since they can't be meaningfully text-redacted.
|
|
446
|
+
const crashReportFiles = findRecentCrashReports();
|
|
447
|
+
for (const filePath of crashReportFiles) {
|
|
448
|
+
try {
|
|
449
|
+
const fileName = basename(filePath);
|
|
450
|
+
if (fileName.toLowerCase().endsWith(CRASH_REPORT_TAR_GZ)) {
|
|
451
|
+
archive.file(filePath, { name: "crash-reports/" + fileName });
|
|
452
|
+
} else {
|
|
453
|
+
const content = readFileSync(filePath, "utf-8");
|
|
454
|
+
archive.append(redact(content), {
|
|
455
|
+
name: "crash-reports/" + fileName,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
} catch {
|
|
459
|
+
// Skip files that can't be read
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
347
463
|
archive.finalize();
|
|
348
464
|
});
|
|
349
465
|
|
|
@@ -352,7 +468,7 @@ async function handleDiagnosticsExport(body: {
|
|
|
352
468
|
"Diagnostics export completed via HTTP",
|
|
353
469
|
);
|
|
354
470
|
|
|
355
|
-
return Response.json({
|
|
471
|
+
return Response.json({ success: true, filePath: zipPath });
|
|
356
472
|
} finally {
|
|
357
473
|
try {
|
|
358
474
|
rmSync(tempDir, { recursive: true, force: true });
|
|
@@ -382,9 +498,7 @@ const MAX_WINDOW_TITLE_LENGTH = 100;
|
|
|
382
498
|
|
|
383
499
|
function sanitizeWindowTitle(title: string | undefined): string {
|
|
384
500
|
if (!title) return "";
|
|
385
|
-
return title
|
|
386
|
-
.replace(/[<>]/g, "")
|
|
387
|
-
.slice(0, MAX_WINDOW_TITLE_LENGTH);
|
|
501
|
+
return title.replace(/[<>]/g, "").slice(0, MAX_WINDOW_TITLE_LENGTH);
|
|
388
502
|
}
|
|
389
503
|
|
|
390
504
|
interface DictationBody {
|
|
@@ -469,10 +583,7 @@ function buildCombinedDictationPrompt(
|
|
|
469
583
|
return sections.join("\n");
|
|
470
584
|
}
|
|
471
585
|
|
|
472
|
-
function buildCommandPrompt(
|
|
473
|
-
body: DictationBody,
|
|
474
|
-
stylePrompt?: string,
|
|
475
|
-
): string {
|
|
586
|
+
function buildCommandPrompt(body: DictationBody, stylePrompt?: string): string {
|
|
476
587
|
const sections = [
|
|
477
588
|
"You are a text transformation assistant. The user has selected text and given a voice command to transform it.",
|
|
478
589
|
"",
|
|
@@ -559,7 +670,10 @@ async function handleDictation(body: DictationBody): Promise<Response> {
|
|
|
559
670
|
const stylePrompt = profile.stylePrompt || undefined;
|
|
560
671
|
|
|
561
672
|
// Command mode: selected text present
|
|
562
|
-
if (
|
|
673
|
+
if (
|
|
674
|
+
body.context.selectedText &&
|
|
675
|
+
body.context.selectedText.trim().length > 0
|
|
676
|
+
) {
|
|
563
677
|
log.info({ mode: "command" }, "Command mode (selected text present)");
|
|
564
678
|
return handleCommandMode(body, profile, profileMeta, stylePrompt);
|
|
565
679
|
}
|
|
@@ -573,7 +687,7 @@ async function handleDictation(body: DictationBody): Promise<Response> {
|
|
|
573
687
|
log.warn(
|
|
574
688
|
"Dictation: no provider available, using heuristic + raw transcription",
|
|
575
689
|
);
|
|
576
|
-
// Build
|
|
690
|
+
// Build a compatible msg for the heuristic
|
|
577
691
|
const mode = detectDictationModeHeuristic({
|
|
578
692
|
type: "dictation_request",
|
|
579
693
|
transcription: body.transcription,
|
|
@@ -669,10 +783,7 @@ async function handleDictation(body: DictationBody): Promise<Response> {
|
|
|
669
783
|
});
|
|
670
784
|
}
|
|
671
785
|
const cleanedText = input.text?.trim() || transcription;
|
|
672
|
-
const normalizedText = applyDictionary(
|
|
673
|
-
cleanedText,
|
|
674
|
-
profile.dictionary,
|
|
675
|
-
);
|
|
786
|
+
const normalizedText = applyDictionary(cleanedText, profile.dictionary);
|
|
676
787
|
return Response.json({
|
|
677
788
|
text: normalizedText,
|
|
678
789
|
mode: "dictation",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Route handlers for document persistence operations.
|
|
3
3
|
*
|
|
4
4
|
* Exposes document CRUD over HTTP, sharing business logic with the
|
|
5
|
-
*
|
|
5
|
+
* handlers in `daemon/handlers/documents.ts`.
|
|
6
6
|
*/
|
|
7
7
|
import { rawAll, rawGet, rawRun } from "../../memory/db.js";
|
|
8
8
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -24,7 +24,7 @@ interface DocumentRow {
|
|
|
24
24
|
type DocumentListRow = Omit<DocumentRow, "content">;
|
|
25
25
|
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
|
-
// Shared business logic (used by both
|
|
27
|
+
// Shared business logic (used by both message handlers and HTTP routes)
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
|
|
30
30
|
export function saveDocument(params: {
|