@vellumai/assistant 0.4.42 → 0.4.44
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/.env.example +1 -6
- package/.prettierignore +3 -0
- package/ARCHITECTURE.md +140 -403
- package/Dockerfile +0 -1
- package/README.md +81 -92
- package/bun.lock +8 -2
- package/docs/architecture/integrations.md +81 -104
- package/docs/architecture/memory.md +1 -1
- package/docs/architecture/scheduling.md +63 -63
- package/docs/architecture/security.md +3 -3
- package/docs/runbook-trusted-contacts.md +11 -12
- package/docs/trusted-contact-access.md +39 -39
- package/package.json +5 -8
- package/src/__tests__/access-request-decision.test.ts +4 -4
- package/src/__tests__/active-skill-tools.test.ts +49 -34
- package/src/__tests__/actor-token-service.test.ts +55 -85
- package/src/__tests__/amazon-cdp-integration.test.ts +14 -26
- package/src/__tests__/app-bundler.test.ts +14 -368
- package/src/__tests__/app-compiler.test.ts +0 -1
- package/src/__tests__/app-executors.test.ts +10 -1
- package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
- package/src/__tests__/approval-primitive.test.ts +2 -4
- package/src/__tests__/approval-routes-http.test.ts +1 -3
- package/src/__tests__/asset-materialize-tool.test.ts +1 -4
- package/src/__tests__/asset-search-tool.test.ts +1 -4
- package/src/__tests__/assistant-attachments.test.ts +23 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +4 -8
- package/src/__tests__/assistant-id-boundary-guard.test.ts +5 -5
- package/src/__tests__/attachments-store.test.ts +1 -4
- package/src/__tests__/avatar-e2e.test.ts +43 -23
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/bundled-asset.test.ts +1 -1
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -9
- package/src/__tests__/call-controller.test.ts +4 -8
- package/src/__tests__/call-conversation-messages.test.ts +1 -1
- package/src/__tests__/call-domain.test.ts +250 -8
- package/src/__tests__/call-pointer-message-composer.test.ts +14 -14
- package/src/__tests__/call-pointer-messages.test.ts +7 -11
- package/src/__tests__/call-recovery.test.ts +47 -0
- package/src/__tests__/call-routes-http.test.ts +13 -0
- package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
- package/src/__tests__/callback-handoff-copy.test.ts +5 -5
- package/src/__tests__/canonical-guardian-store.test.ts +3 -3
- package/src/__tests__/channel-approval-routes.test.ts +101 -134
- package/src/__tests__/channel-approval.test.ts +0 -201
- package/src/__tests__/channel-approvals.test.ts +2 -2
- package/src/__tests__/channel-delivery-store.test.ts +16 -24
- package/src/__tests__/channel-guardian.test.ts +641 -740
- package/src/__tests__/channel-invite-transport.test.ts +1 -2
- package/src/__tests__/channel-policy.test.ts +9 -12
- package/src/__tests__/channel-readiness-service.test.ts +156 -45
- package/src/__tests__/channel-reply-delivery.test.ts +3 -3
- package/src/__tests__/channel-retry-sweep.test.ts +7 -7
- package/src/__tests__/checker.test.ts +41 -35
- package/src/__tests__/chrome-cdp.test.ts +57 -17
- package/src/__tests__/cli-help-reference-sync.test.ts +26 -0
- package/src/__tests__/compaction.benchmark.test.ts +25 -5
- package/src/__tests__/computer-use-session-lifecycle.test.ts +1 -1
- package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +1 -1
- package/src/__tests__/config-loader-backfill.test.ts +310 -0
- package/src/__tests__/config-watcher.test.ts +1 -5
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +3 -5
- package/src/__tests__/connection-policy.test.ts +3 -62
- package/src/__tests__/contacts-tools.test.ts +0 -2
- package/src/__tests__/context-memory-e2e.test.ts +11 -7
- package/src/__tests__/context-overflow-policy.test.ts +2 -2
- package/src/__tests__/context-window-manager.test.ts +220 -61
- package/src/__tests__/conversation-attention-store.test.ts +178 -2
- package/src/__tests__/conversation-attention-telegram.test.ts +8 -11
- package/src/__tests__/conversation-pairing.test.ts +14 -14
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +7 -7
- package/src/__tests__/conversation-store.test.ts +2 -2
- package/src/__tests__/conversation-unread-route.test.ts +155 -0
- package/src/__tests__/credential-metadata-store.test.ts +0 -2
- package/src/__tests__/credential-security-invariants.test.ts +10 -16
- package/src/__tests__/credentials-cli.test.ts +49 -5
- package/src/__tests__/daemon-assistant-events.test.ts +4 -22
- package/src/__tests__/db-migration-rollback.test.ts +2 -2
- package/src/__tests__/deterministic-verification-control-plane.test.ts +19 -19
- package/src/__tests__/dictation-mode-detection.test.ts +1 -1
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -6
- package/src/__tests__/email-cli.test.ts +12 -12
- package/src/__tests__/email-service-config-fallback.test.ts +1 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -18
- package/src/__tests__/error-handler-friendly-messages.test.ts +46 -0
- package/src/__tests__/event-bus.test.ts +0 -1
- package/src/__tests__/followup-tools.test.ts +0 -2
- package/src/__tests__/gateway-client-managed-outbound.test.ts +6 -6
- package/src/__tests__/gateway-only-enforcement.test.ts +13 -77
- package/src/__tests__/gateway-only-guard.test.ts +5 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +3 -3
- package/src/__tests__/guardian-action-followup-executor.test.ts +29 -94
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -12
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +48 -194
- package/src/__tests__/guardian-action-late-reply.test.ts +12 -12
- package/src/__tests__/guardian-action-store.test.ts +2 -2
- package/src/__tests__/guardian-action-sweep.test.ts +5 -5
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -3
- package/src/__tests__/guardian-dispatch.test.ts +5 -46
- package/src/__tests__/guardian-grant-minting.test.ts +5 -44
- package/src/__tests__/guardian-outbound-http.test.ts +95 -114
- package/src/__tests__/guardian-question-mode.test.ts +1 -4
- package/src/__tests__/guardian-routing-invariants.test.ts +5 -13
- package/src/__tests__/guardian-routing-state.test.ts +3 -3
- package/src/__tests__/guardian-verification-voice-binding.test.ts +64 -7
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +2 -2
- package/src/__tests__/handle-user-message-secret-resume.test.ts +3 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +16 -34
- package/src/__tests__/headless-browser-interactions.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +1 -1
- package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
- package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
- package/src/__tests__/heartbeat-service.test.ts +1 -1
- package/src/__tests__/host-shell-tool.test.ts +3 -12
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -2
- package/src/__tests__/ingress-url-consistency.test.ts +0 -64
- package/src/__tests__/integration-status.test.ts +8 -8
- package/src/__tests__/intent-routing.test.ts +9 -13
- package/src/__tests__/invite-redemption-service.test.ts +4 -4
- package/src/__tests__/invite-routes-http.test.ts +10 -10
- package/src/__tests__/llm-usage-store.test.ts +45 -9
- package/src/__tests__/local-gateway-health.test.ts +209 -0
- package/src/__tests__/managed-avatar-client.test.ts +23 -12
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -2
- package/src/__tests__/managed-store.test.ts +29 -12
- package/src/__tests__/managed-twitter-guardrails.test.ts +357 -0
- package/src/__tests__/mcp-cli.test.ts +1 -1
- package/src/__tests__/mcp-health-check.test.ts +1 -1
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/media-reuse-story.e2e.test.ts +1 -4
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +9 -6
- package/src/__tests__/memory-regressions.test.ts +1 -166
- package/src/__tests__/messaging-send-tool.test.ts +8 -4
- package/src/__tests__/migration-export-http.test.ts +2 -2
- package/src/__tests__/migration-transport.test.ts +44 -0
- package/src/__tests__/non-member-access-request.test.ts +49 -36
- package/src/__tests__/notification-broadcaster.test.ts +15 -15
- package/src/__tests__/notification-decision-fallback.test.ts +2 -2
- package/src/__tests__/notification-decision-strategy.test.ts +4 -4
- package/src/__tests__/notification-deep-link.test.ts +3 -3
- package/src/__tests__/notification-guardian-path.test.ts +6 -44
- package/src/__tests__/notification-routing-intent.test.ts +11 -7
- package/src/__tests__/oauth-cli.test.ts +1 -1
- package/src/__tests__/onboarding-starter-tasks.test.ts +2 -6
- package/src/__tests__/onboarding-template-contract.test.ts +2 -12
- package/src/__tests__/platform.test.ts +168 -5
- package/src/__tests__/playbook-execution.test.ts +0 -2
- package/src/__tests__/playbook-tools.test.ts +0 -2
- package/src/__tests__/pricing.test.ts +125 -0
- package/src/__tests__/provider-error-scenarios.test.ts +9 -3
- package/src/__tests__/provider-fail-open-selection.test.ts +12 -2
- package/src/__tests__/recording-handler.test.ts +46 -80
- package/src/__tests__/recording-state-machine.test.ts +112 -183
- package/src/__tests__/registry.test.ts +1 -1
- package/src/__tests__/relay-server.test.ts +69 -71
- package/src/__tests__/reminder-store.test.ts +3 -3
- package/src/__tests__/request-file-tool.test.ts +2 -2
- package/src/__tests__/ride-shotgun-handler.test.ts +2 -33
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -3
- package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +4 -4
- package/src/__tests__/schedule-store.test.ts +13 -4
- package/src/__tests__/schedule-tools.test.ts +0 -2
- package/src/__tests__/scheduler-recurrence.test.ts +3 -4
- package/src/__tests__/scoped-approval-grants.test.ts +3 -5
- package/src/__tests__/scoped-grant-security-matrix.test.ts +6 -8
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +1 -1
- package/src/__tests__/secret-response-routing.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +1 -4
- package/src/__tests__/sequence-store.test.ts +0 -2
- package/src/__tests__/server-history-render.test.ts +2 -199
- package/src/__tests__/session-abort-tool-results.test.ts +9 -3
- package/src/__tests__/session-agent-loop.test.ts +107 -3
- package/src/__tests__/session-confirmation-signals.test.ts +17 -49
- package/src/__tests__/session-conflict-gate.test.ts +9 -3
- package/src/__tests__/session-init.benchmark.test.ts +22 -13
- package/src/__tests__/session-load-history-repair.test.ts +6 -3
- package/src/__tests__/session-pre-run-repair.test.ts +9 -3
- package/src/__tests__/session-profile-injection.test.ts +9 -3
- package/src/__tests__/session-provider-retry-repair.test.ts +10 -4
- package/src/__tests__/session-queue.test.ts +10 -4
- package/src/__tests__/session-runtime-assembly.test.ts +28 -18
- package/src/__tests__/session-skill-tools.test.ts +2 -3
- package/src/__tests__/session-slash-known.test.ts +11 -4
- package/src/__tests__/session-slash-queue.test.ts +11 -4
- package/src/__tests__/session-slash-unknown.test.ts +12 -4
- package/src/__tests__/session-surfaces-deselection.test.ts +2 -2
- package/src/__tests__/session-surfaces-task-progress.test.ts +3 -3
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -1
- package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -1
- package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -1
- package/src/__tests__/session-usage.test.ts +180 -0
- package/src/__tests__/session-workspace-cache-state.test.ts +8 -2
- package/src/__tests__/session-workspace-injection.test.ts +8 -2
- package/src/__tests__/session-workspace-tool-tracking.test.ts +8 -2
- package/src/__tests__/skill-feature-flags-integration.test.ts +5 -11
- package/src/__tests__/skill-feature-flags.test.ts +1 -0
- package/src/__tests__/skill-include-graph.test.ts +1 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +3 -9
- package/src/__tests__/skill-load-tool.test.ts +90 -12
- package/src/__tests__/skill-projection-feature-flag.test.ts +14 -15
- package/src/__tests__/skills-uninstall.test.ts +131 -0
- package/src/__tests__/skills.test.ts +32 -16
- package/src/__tests__/slack-block-formatting.test.ts +1 -1
- package/src/__tests__/slack-channel-config.test.ts +71 -12
- package/src/__tests__/slack-inbound-verification.test.ts +7 -7
- package/src/__tests__/slack-share-routes.test.ts +1 -1
- package/src/__tests__/slack-skill.test.ts +2 -2
- package/src/__tests__/slash-commands-catalog.test.ts +1 -0
- package/src/__tests__/slash-commands-resolver.test.ts +1 -0
- package/src/__tests__/starter-task-flow.test.ts +10 -20
- package/src/__tests__/subagent-manager-notify.test.ts +1 -1
- package/src/__tests__/subagent-tools.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +7 -12
- package/src/__tests__/task-compiler.test.ts +0 -2
- package/src/__tests__/task-management-tools.test.ts +0 -2
- package/src/__tests__/task-runner.test.ts +0 -2
- package/src/__tests__/task-scheduler.test.ts +2 -2
- package/src/__tests__/telegram-bot-username-resolution.test.ts +46 -44
- package/src/__tests__/terminal-tools.test.ts +1 -11
- package/src/__tests__/thread-seed-composer.test.ts +3 -1
- package/src/__tests__/tool-approval-handler.test.ts +5 -7
- package/src/__tests__/tool-executor.test.ts +2 -2
- package/src/__tests__/tool-grant-request-escalation.test.ts +3 -5
- package/src/__tests__/tool-notification-listener.test.ts +1 -1
- package/src/__tests__/tool-profiling-listener.test.ts +1 -1
- package/src/__tests__/tool-trace-listener.test.ts +1 -2
- package/src/__tests__/trace-emitter.test.ts +1 -1
- package/src/__tests__/trust-context-guards.test.ts +1 -1
- package/src/__tests__/trust-store.test.ts +48 -399
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +6 -8
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +5 -7
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +6 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +54 -47
- package/src/__tests__/trusted-contact-verification.test.ts +12 -12
- package/src/__tests__/twilio-config.test.ts +11 -2
- package/src/__tests__/twilio-provider.test.ts +6 -4
- package/src/__tests__/twilio-routes.test.ts +408 -86
- package/src/__tests__/twitter-platform-proxy-client.test.ts +475 -0
- package/src/__tests__/update-bulletin-format.test.ts +1 -1
- package/src/__tests__/update-bulletin-state.test.ts +1 -1
- package/src/__tests__/update-bulletin.test.ts +4 -8
- package/src/__tests__/update-template-contract.test.ts +1 -1
- package/src/__tests__/usage-cache-backfill-migration.test.ts +406 -0
- package/src/__tests__/usage-routes.test.ts +23 -5
- package/src/__tests__/user-reference.test.ts +1 -1
- package/src/__tests__/{guardian-control-plane-policy.test.ts → verification-control-plane-policy.test.ts} +142 -170
- package/src/__tests__/{guardian-verification-intent-routing.test.ts → verification-session-intent-routing.test.ts} +16 -16
- package/src/__tests__/view-image-tool.test.ts +0 -2
- package/src/__tests__/voice-ingress-preflight.test.ts +36 -0
- package/src/__tests__/voice-invite-redemption.test.ts +18 -18
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +7 -7
- package/src/__tests__/voice-session-bridge.test.ts +14 -16
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/approvals/AGENTS.md +4 -4
- package/src/approvals/approval-primitive.ts +2 -2
- package/src/approvals/guardian-decision-primitive.ts +1 -1
- package/src/approvals/guardian-request-resolvers.ts +3 -4
- package/src/bundler/app-bundler.ts +29 -217
- package/src/calls/active-call-lease.ts +207 -0
- package/src/calls/call-constants.ts +0 -7
- package/src/calls/call-controller.ts +1 -1
- package/src/calls/call-conversation-messages.ts +6 -6
- package/src/calls/call-domain.ts +73 -38
- package/src/calls/call-pointer-message-composer.ts +6 -6
- package/src/calls/call-pointer-messages.ts +14 -13
- package/src/calls/call-recovery.ts +2 -0
- package/src/calls/call-store.ts +21 -28
- package/src/calls/guardian-action-sweep.ts +6 -8
- package/src/calls/guardian-dispatch.ts +2 -6
- package/src/calls/relay-access-wait.ts +4 -4
- package/src/calls/relay-server.ts +69 -80
- package/src/calls/relay-setup-router.ts +16 -21
- package/src/calls/relay-verification.ts +27 -28
- package/src/calls/twilio-config.ts +28 -3
- package/src/calls/twilio-provider.ts +5 -5
- package/src/calls/twilio-rest.ts +26 -27
- package/src/calls/twilio-routes.ts +67 -54
- package/src/calls/types.ts +8 -8
- package/src/calls/voice-ingress-preflight.ts +110 -0
- package/src/calls/voice-session-bridge.ts +7 -7
- package/src/channels/config.ts +1 -10
- package/src/{config/channel-permission-profiles.ts → channels/permission-profiles.ts} +1 -1
- package/src/channels/types.ts +2 -13
- package/src/cli/__tests__/notifications.test.ts +1 -1
- package/src/{amazon → cli/commands/amazon}/client.ts +99 -42
- package/src/cli/{amazon.ts → commands/amazon/index.ts} +14 -54
- package/src/{amazon → cli/commands/amazon}/request-extractor.ts +39 -3
- package/src/cli/commands/amazon/session.ts +108 -0
- package/src/cli/{audit.ts → commands/audit.ts} +2 -4
- package/src/cli/{autonomy.ts → commands/autonomy.ts} +1 -3
- package/src/cli/commands/browser-relay.ts +520 -0
- package/src/cli/commands/channel-verification-sessions.ts +442 -0
- package/src/cli/{completions.ts → commands/completions.ts} +1 -3
- package/src/cli/{config.ts → commands/config.ts} +3 -5
- package/src/cli/{contacts.ts → commands/contacts.ts} +15 -17
- package/src/cli/{credentials.ts → commands/credentials.ts} +9 -10
- package/src/cli/{default-action.ts → commands/default-action.ts} +3 -3
- package/src/cli/{dev.ts → commands/dev.ts} +4 -6
- package/src/cli/{doctor.ts → commands/doctor.ts} +36 -60
- package/src/cli/{email.ts → commands/email.ts} +2 -2
- package/src/cli/{keys.ts → commands/keys.ts} +6 -6
- package/src/cli/{map.ts → commands/map.ts} +85 -93
- package/src/cli/{mcp.ts → commands/mcp.ts} +5 -7
- package/src/cli/{memory.ts → commands/memory.ts} +6 -7
- package/src/cli/{notifications.ts → commands/notifications.ts} +8 -10
- package/src/cli/{oauth.ts → commands/oauth.ts} +2 -2
- package/src/cli/commands/platform.ts +176 -0
- package/src/cli/{sequence.ts → commands/sequence.ts} +3 -3
- package/src/cli/{sessions.ts → commands/sessions.ts} +32 -52
- package/src/cli/commands/skills.ts +498 -0
- package/src/cli/{trust.ts → commands/trust.ts} +2 -4
- package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +345 -0
- package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +252 -0
- package/src/{__tests__/twitter-oauth-client.test.ts → cli/commands/twitter/__tests__/oauth-client.test.ts} +2 -48
- package/src/cli/commands/twitter/index.ts +420 -0
- package/src/{twitter → cli/commands/twitter}/oauth-client.ts +1 -35
- package/src/cli/commands/twitter/router.ts +351 -0
- package/src/cli/commands/twitter/types.ts +30 -0
- package/src/cli/db.ts +1 -0
- package/src/cli/http-client.ts +87 -0
- package/src/cli/logger.ts +6 -0
- package/src/cli/main-screen.tsx +4 -3
- package/src/cli/output.ts +19 -0
- package/src/cli/program.ts +29 -27
- package/src/cli/reference.ts +27 -37
- package/src/cli.ts +452 -240
- package/src/config/assistant-feature-flags.ts +3 -15
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +3 -6
- package/src/config/bundled-skills/agentmail/SKILL.md +4 -4
- package/src/config/bundled-skills/amazon/SKILL.md +15 -6
- package/src/config/bundled-skills/api-mapping/SKILL.md +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +4 -9
- package/src/config/bundled-skills/app-builder/TOOLS.json +0 -4
- package/src/config/bundled-skills/browser/SKILL.md +4 -5
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +4 -4
- package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
- package/src/config/bundled-skills/claude-code/SKILL.md +4 -4
- package/src/config/bundled-skills/cli-discover/SKILL.md +4 -4
- package/src/config/bundled-skills/computer-use/SKILL.md +4 -4
- package/src/config/bundled-skills/contacts/SKILL.md +23 -77
- package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +4 -4
- package/src/config/bundled-skills/document/SKILL.md +4 -3
- package/src/config/bundled-skills/document-writer/SKILL.md +4 -4
- package/src/config/bundled-skills/doordash/SKILL.md +4 -12
- package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +1 -90
- package/src/config/bundled-skills/doordash/doordash-cli.ts +132 -109
- package/src/config/bundled-skills/doordash/lib/session.ts +22 -19
- package/src/config/bundled-skills/doordash/lib/shared/platform.ts +26 -9
- package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +140 -0
- package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
- package/src/config/bundled-skills/followups/SKILL.md +4 -3
- package/src/config/bundled-skills/frontend-design/SKILL.md +2 -0
- package/src/config/bundled-skills/google-calendar/SKILL.md +4 -4
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +4 -6
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +26 -41
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -5
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -1
- package/src/config/bundled-skills/influencer/SKILL.md +19 -19
- package/src/{influencer → config/bundled-skills/influencer/scripts}/client.ts +73 -56
- package/src/config/bundled-skills/influencer/scripts/influencer.ts +267 -0
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -2
- package/src/config/bundled-skills/macos-automation/SKILL.md +4 -5
- package/src/config/bundled-skills/mcp-setup/SKILL.md +4 -4
- package/src/config/bundled-skills/media-processing/SKILL.md +3 -2
- package/src/config/bundled-skills/messaging/SKILL.md +6 -33
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -5
- package/src/config/bundled-skills/notifications/SKILL.md +4 -4
- package/src/config/bundled-skills/notion/SKILL.md +4 -4
- package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/oauth-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/phone-calls/SKILL.md +24 -458
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +83 -0
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +57 -0
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +67 -0
- package/src/config/bundled-skills/playbooks/SKILL.md +4 -3
- package/src/config/bundled-skills/public-ingress/SKILL.md +65 -14
- package/src/config/bundled-skills/reminder/SKILL.md +4 -3
- package/src/config/bundled-skills/restaurant-reservation/SKILL.md +4 -6
- package/src/config/bundled-skills/schedule/SKILL.md +4 -3
- package/src/config/bundled-skills/screen-recording/SKILL.md +4 -3
- package/src/config/bundled-skills/self-upgrade/SKILL.md +4 -4
- package/src/config/bundled-skills/skills-catalog/SKILL.md +4 -4
- package/src/config/bundled-skills/slack/SKILL.md +4 -8
- package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +1 -1
- package/src/config/bundled-skills/slack-app-setup/SKILL.md +66 -88
- package/src/config/bundled-skills/slack-digest-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/start-the-day/SKILL.md +4 -4
- package/src/config/bundled-skills/subagent/SKILL.md +4 -3
- package/src/config/bundled-skills/tasks/SKILL.md +4 -3
- package/src/config/bundled-skills/telegram-setup/SKILL.md +63 -112
- package/src/config/bundled-skills/time-based-actions/SKILL.md +4 -3
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -3
- package/src/config/bundled-skills/twilio-setup/SKILL.md +23 -50
- package/src/config/bundled-skills/twitter/SKILL.md +73 -144
- package/src/config/bundled-skills/typescript-eval/SKILL.md +4 -4
- package/src/config/bundled-skills/vercel-token-setup/SKILL.md +4 -5
- package/src/config/bundled-skills/voice-setup/SKILL.md +19 -45
- package/src/config/bundled-skills/watcher/SKILL.md +4 -3
- package/src/config/env-registry.ts +1 -10
- package/src/config/feature-flag-registry.json +8 -16
- package/src/config/loader.ts +78 -38
- package/src/config/schema.ts +143 -106
- package/src/config/schemas/channels.ts +80 -0
- package/src/config/schemas/heartbeat.ts +51 -0
- package/src/config/schemas/inference.ts +136 -0
- package/src/config/schemas/ingress.ts +81 -0
- package/src/config/schemas/logging.ts +21 -0
- package/src/config/schemas/memory-lifecycle.ts +67 -0
- package/src/config/schemas/memory-processing.ts +215 -0
- package/src/config/schemas/memory-retrieval.ts +222 -0
- package/src/config/schemas/memory-storage.ts +83 -0
- package/src/config/schemas/memory.ts +58 -0
- package/src/config/schemas/platform.ts +64 -0
- package/src/config/schemas/security.ts +54 -0
- package/src/config/schemas/swarm.ts +50 -0
- package/src/config/schemas/timeouts.ts +47 -0
- package/src/config/{agent-schema.ts → schemas/workspace-git.ts} +0 -97
- package/src/config/skill-state.ts +3 -13
- package/src/config/skills.ts +196 -75
- package/src/config/types.ts +1 -20
- package/src/contacts/contact-store.ts +12 -49
- package/src/contacts/contacts-write.ts +1 -5
- package/src/contacts/index.ts +0 -2
- package/src/contacts/types.ts +0 -8
- package/src/context/window-manager.ts +73 -14
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/computer-use-session.ts +3 -3
- package/src/daemon/connection-policy.ts +6 -21
- package/src/daemon/context-overflow-policy.ts +1 -1
- package/src/daemon/daemon-control.ts +46 -54
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/config-channels.ts +407 -71
- package/src/daemon/handlers/config-ingress.ts +17 -85
- package/src/daemon/handlers/config-model.ts +145 -123
- package/src/daemon/handlers/config-slack-channel.ts +43 -29
- package/src/daemon/handlers/config-telegram.ts +32 -27
- package/src/daemon/handlers/config-voice.ts +1 -4
- package/src/daemon/handlers/dictation.ts +11 -16
- package/src/daemon/handlers/identity.ts +5 -6
- package/src/daemon/handlers/pairing.ts +5 -13
- package/src/daemon/handlers/recording.ts +97 -199
- package/src/daemon/handlers/session-history.ts +151 -105
- package/src/daemon/handlers/session-user-message.ts +29 -57
- package/src/daemon/handlers/sessions.ts +240 -137
- package/src/daemon/handlers/shared.ts +62 -95
- package/src/daemon/handlers/skills.ts +492 -543
- package/src/daemon/lifecycle.ts +155 -55
- package/src/daemon/{ipc-contract.ts → message-protocol.ts} +49 -49
- package/src/daemon/{ipc-contract → message-types}/apps.ts +0 -25
- package/src/daemon/{ipc-contract → message-types}/computer-use.ts +0 -3
- package/src/daemon/{ipc-contract → message-types}/diagnostics.ts +0 -16
- package/src/daemon/{ipc-contract → message-types}/integrations.ts +30 -20
- package/src/daemon/{ipc-contract → message-types}/memory.ts +8 -0
- package/src/daemon/{ipc-contract → message-types}/notifications.ts +15 -1
- package/src/daemon/{ipc-contract → message-types}/sessions.ts +7 -1
- package/src/daemon/{ipc-contract → message-types}/shared.ts +0 -8
- package/src/daemon/{ipc-contract → message-types}/surfaces.ts +2 -0
- package/src/daemon/{ipc-contract → message-types}/workspace.ts +2 -2
- package/src/daemon/providers-setup.ts +0 -5
- package/src/daemon/recording-executor.ts +0 -7
- package/src/daemon/ride-shotgun-handler.ts +42 -14
- package/src/daemon/seed-files.ts +3 -27
- package/src/daemon/server.ts +134 -524
- package/src/daemon/session-agent-loop-handlers.ts +46 -9
- package/src/daemon/session-agent-loop.ts +86 -24
- package/src/daemon/session-attachments.ts +1 -1
- package/src/daemon/session-error.ts +1 -1
- package/src/daemon/session-history.ts +20 -15
- package/src/daemon/session-lifecycle.ts +9 -7
- package/src/daemon/session-memory.ts +15 -1
- package/src/daemon/session-messaging.ts +10 -6
- package/src/daemon/session-notifiers.ts +10 -8
- package/src/daemon/session-process.ts +34 -25
- package/src/daemon/session-queue-manager.ts +1 -1
- package/src/daemon/session-runtime-assembly.ts +6 -32
- package/src/daemon/session-surfaces.ts +187 -35
- package/src/daemon/session-tool-setup.ts +1 -1
- package/src/daemon/session-usage.ts +119 -18
- package/src/daemon/session.ts +11 -33
- package/src/daemon/tool-side-effects.ts +6 -5
- package/src/daemon/trace-emitter.ts +1 -1
- package/src/daemon/{guardian-verification-intent.ts → verification-session-intent.ts} +16 -16
- package/src/daemon/watch-handler.ts +2 -5
- package/src/email/service.ts +8 -8
- package/src/events/domain-events.ts +0 -1
- package/src/events/tool-notification-listener.ts +1 -1
- package/src/followups/followup-store.ts +1 -2
- package/src/followups/types.ts +0 -6
- package/src/heartbeat/heartbeat-service.ts +1 -1
- package/src/inbound/platform-callback-registration.ts +1 -1
- package/src/inbound/public-ingress-urls.ts +0 -8
- package/src/index.ts +12 -0
- package/src/mcp/client.ts +1 -1
- package/src/mcp/manager.ts +1 -1
- package/src/memory/app-store.ts +1 -60
- package/src/memory/{guardian-verification.ts → channel-verification-sessions.ts} +110 -93
- package/src/memory/conversation-attention-store.ts +154 -0
- package/src/memory/conversation-bootstrap.ts +1 -1
- package/src/memory/conversation-crud.ts +53 -1
- package/src/memory/conversation-display-order-migration.ts +2 -3
- package/src/memory/conversation-queries.ts +1 -29
- package/src/memory/conversation-title-service.ts +26 -21
- package/src/memory/db-connection.ts +1 -8
- package/src/memory/db-init.ts +20 -0
- package/src/memory/delivery-crud.ts +4 -34
- package/src/memory/external-conversation-store.ts +1 -1
- package/src/memory/format-recall.ts +47 -0
- package/src/memory/guardian-action-store.ts +4 -5
- package/src/memory/guardian-rate-limits.ts +0 -3
- package/src/memory/invite-store.ts +1 -1
- package/src/memory/job-handlers/backfill.ts +9 -2
- package/src/memory/job-handlers/extraction.ts +2 -7
- package/src/memory/job-handlers/summarization.ts +1 -1
- package/src/memory/llm-usage-store.ts +11 -0
- package/src/memory/migrations/114-notifications.ts +12 -40
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +357 -0
- package/src/memory/migrations/141-rename-verification-table.ts +55 -0
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +32 -0
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +48 -0
- package/src/memory/migrations/144-rename-voice-to-phone.ts +147 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/migrations/registry.ts +30 -0
- package/src/memory/qdrant-circuit-breaker.ts +5 -0
- package/src/memory/retriever.test.ts +707 -0
- package/src/memory/retriever.ts +120 -116
- package/src/memory/schema/calls.ts +3 -7
- package/src/memory/schema/guardian.ts +2 -2
- package/src/memory/schema/infrastructure.ts +0 -8
- package/src/memory/search/lexical.ts +4 -1
- package/src/memory/search/query-expansion.test.ts +70 -0
- package/src/memory/search/query-expansion.ts +118 -0
- package/src/memory/search/types.ts +18 -17
- package/src/messaging/providers/telegram-bot/adapter.ts +1 -1
- package/src/messaging/providers/whatsapp/adapter.ts +1 -4
- package/src/messaging/registry.ts +0 -1
- package/src/notifications/README.md +13 -22
- package/src/notifications/adapters/macos.ts +1 -1
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +2 -2
- package/src/notifications/decision-engine.ts +1 -10
- package/src/notifications/destination-resolver.ts +2 -3
- package/src/notifications/emit-signal.ts +2 -8
- package/src/notifications/guardian-question-mode.ts +5 -8
- package/src/notifications/signal.ts +1 -2
- package/src/notifications/types.ts +1 -1
- package/src/oauth/token-persistence.ts +25 -1
- package/src/permissions/checker.ts +4 -29
- package/src/permissions/defaults.ts +9 -9
- package/src/permissions/prompter.ts +1 -1
- package/src/permissions/secret-prompter.ts +1 -1
- package/src/permissions/shell-identity.ts +1 -1
- package/src/permissions/trust-store.ts +13 -76
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/{config → prompts}/computer-use-prompt.ts +1 -1
- package/src/{config → prompts}/system-prompt.ts +44 -26
- package/src/{config → prompts}/templates/BOOTSTRAP.md +0 -3
- package/src/providers/registry.ts +2 -4
- package/src/runtime/AGENTS.md +6 -8
- package/src/runtime/access-request-helper.ts +36 -55
- package/src/runtime/actor-trust-resolver.ts +1 -24
- package/src/runtime/approval-message-composer.ts +6 -2
- package/src/runtime/assistant-event.ts +1 -1
- package/src/runtime/auth/__tests__/guard-tests.test.ts +1 -0
- package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +1 -1
- package/src/runtime/auth/__tests__/scopes.test.ts +2 -1
- package/src/runtime/auth/__tests__/subject.test.ts +32 -0
- package/src/runtime/auth/route-policy.ts +137 -25
- package/src/runtime/auth/scopes.ts +1 -0
- package/src/runtime/auth/subject.ts +9 -0
- package/src/runtime/auth/token-service.ts +12 -1
- package/src/runtime/auth/types.ts +1 -1
- package/src/runtime/channel-approval-types.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/channel-invite-transport.ts +0 -2
- package/src/runtime/channel-invite-transports/slack.ts +5 -19
- package/src/runtime/channel-invite-transports/telegram.ts +17 -34
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-readiness-service.ts +24 -159
- package/src/runtime/channel-readiness-types.ts +5 -1
- package/src/runtime/channel-reply-delivery.ts +43 -3
- package/src/runtime/channel-retry-sweep.ts +14 -22
- package/src/runtime/{channel-guardian-service.ts → channel-verification-service.ts} +50 -53
- package/src/runtime/confirmation-request-guardian-bridge.ts +2 -3
- package/src/runtime/gateway-client.ts +12 -15
- package/src/runtime/guardian-action-followup-executor.ts +8 -73
- package/src/runtime/guardian-action-grant-minter.ts +45 -61
- package/src/runtime/guardian-action-message-composer.ts +4 -4
- package/src/runtime/guardian-reply-router.ts +3 -3
- package/src/runtime/http-server.ts +133 -24
- package/src/runtime/http-types.ts +44 -1
- package/src/runtime/invite-instruction-generator.ts +1 -3
- package/src/runtime/invite-redemption-service.ts +5 -5
- package/src/runtime/invite-service.ts +7 -7
- package/src/runtime/local-actor-identity.ts +28 -2
- package/src/runtime/local-gateway-health.ts +275 -0
- package/src/runtime/middleware/error-handler.ts +14 -1
- package/src/runtime/middleware/twilio-validation.ts +3 -3
- package/src/runtime/migrations/migration-transport.ts +18 -3
- package/src/runtime/migrations/rebind-secrets-screen.ts +2 -2
- package/src/runtime/nl-approval-parser.ts +2 -3
- package/src/runtime/routes/access-request-decision.ts +2 -2
- package/src/runtime/routes/app-management-routes.ts +918 -0
- package/src/runtime/routes/approval-routes.ts +76 -7
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +38 -203
- 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/channel-delivery-routes.ts +5 -4
- package/src/runtime/routes/channel-route-shared.ts +1 -3
- package/src/runtime/routes/channel-routes.ts +1 -4
- package/src/runtime/routes/channel-verification-routes.ts +257 -0
- package/src/runtime/routes/computer-use-routes.ts +595 -0
- package/src/runtime/routes/contact-routes.ts +1 -317
- package/src/runtime/routes/conversation-attention-routes.ts +6 -5
- package/src/runtime/routes/conversation-routes.ts +20 -24
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/diagnostics-routes.ts +890 -0
- package/src/runtime/routes/documents-routes.ts +227 -0
- package/src/runtime/routes/guardian-approval-interception.ts +25 -48
- package/src/runtime/routes/guardian-bootstrap-routes.ts +3 -3
- package/src/runtime/routes/guardian-expiry-sweep.ts +2 -2
- package/src/runtime/routes/guardian-refresh-routes.ts +11 -6
- package/src/runtime/routes/inbound-conversation.ts +3 -10
- package/src/runtime/routes/inbound-message-handler.ts +7 -6
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +22 -22
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +44 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +140 -22
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +4 -4
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +5 -5
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +3 -3
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
- package/src/runtime/routes/inbound-stages/verification-intercept.ts +13 -14
- package/src/runtime/routes/integrations/slack/channel.ts +72 -0
- package/src/runtime/routes/{slack-share-routes.ts → integrations/slack/share.ts} +9 -9
- package/src/runtime/routes/integrations/telegram.ts +111 -0
- package/src/runtime/routes/integrations/twilio.ts +451 -0
- package/src/runtime/routes/invite-routes.ts +2 -2
- package/src/runtime/routes/pairing-routes.ts +1 -1
- package/src/runtime/routes/recording-routes.ts +332 -0
- package/src/{daemon/handlers/config-scheduling.ts → runtime/routes/schedule-routes.ts} +91 -106
- package/src/runtime/routes/session-management-routes.ts +167 -0
- package/src/runtime/routes/session-query-routes.ts +204 -0
- package/src/runtime/routes/settings-routes.ts +887 -0
- package/src/runtime/routes/skills-routes.ts +266 -0
- package/src/runtime/routes/subagents-routes.ts +246 -0
- package/src/runtime/routes/surface-action-routes.ts +100 -10
- package/src/runtime/routes/surface-content-routes.ts +1 -1
- package/src/runtime/routes/work-items-routes.ts +809 -0
- package/src/runtime/routes/workspace-routes.test.ts +778 -0
- package/src/runtime/routes/workspace-routes.ts +410 -0
- package/src/runtime/routes/workspace-utils.ts +88 -0
- package/src/runtime/telegram-streaming-delivery.test.ts +597 -0
- package/src/runtime/telegram-streaming-delivery.ts +380 -0
- package/src/runtime/tool-grant-request-helper.ts +1 -2
- package/src/runtime/trust-context-resolver.ts +0 -1
- package/src/runtime/{guardian-outbound-actions.ts → verification-outbound-actions.ts} +23 -188
- package/src/runtime/verification-rate-limiter.ts +2 -2
- package/src/runtime/{guardian-verification-templates.ts → verification-templates.ts} +2 -28
- package/src/schedule/integration-status.ts +2 -2
- package/src/schedule/schedule-store.ts +7 -9
- package/src/sequence/engine.ts +1 -1
- package/src/skills/active-skill-tools.ts +0 -8
- package/src/skills/clawhub.ts +1 -10
- package/src/skills/managed-store.ts +14 -4
- package/src/skills/slash-commands.ts +1 -1
- package/src/subagent/manager.ts +1 -1
- package/src/subagent/types.ts +1 -1
- package/src/tasks/SPEC.md +10 -10
- package/src/tasks/task-scheduler.ts +1 -1
- package/src/telegram/bot-username.ts +13 -0
- package/src/tools/AGENTS.md +38 -0
- package/src/tools/apps/executors.ts +0 -6
- package/src/tools/assets/materialize.ts +1 -1
- package/src/tools/assets/search.ts +1 -1
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/browser-manager.ts +88 -11
- package/src/tools/browser/browser-screencast.ts +1 -1
- package/src/tools/browser/headless-browser.ts +0 -17
- package/src/tools/browser/jit-auth.ts +1 -1
- package/src/tools/browser/recording-store.ts +19 -1
- package/src/tools/browser/runtime-check.ts +4 -2
- package/src/tools/calls/call-start.ts +3 -3
- package/src/tools/credentials/metadata-store.ts +0 -13
- package/src/tools/credentials/vault.ts +7 -31
- package/src/tools/document/editor-template.ts +10 -8
- package/src/tools/followups/followup_create.ts +0 -8
- package/src/tools/mcp/mcp-tool-factory.ts +1 -1
- package/src/tools/memory/definitions.ts +32 -10
- package/src/tools/memory/handlers.test.ts +573 -0
- package/src/tools/memory/handlers.ts +222 -65
- package/src/tools/memory/register.ts +53 -24
- package/src/tools/network/script-proxy/session-manager.ts +1 -12
- package/src/tools/schedule/update.ts +0 -8
- package/src/tools/skills/load.ts +3 -3
- package/src/tools/subagent/read.ts +1 -1
- package/src/tools/system/voice-config.ts +2 -14
- package/src/tools/terminal/safe-env.ts +5 -18
- package/src/tools/tool-approval-handler.ts +4 -4
- package/src/tools/tool-manifest.ts +4 -2
- package/src/tools/types.ts +1 -1
- package/src/tools/{guardian-control-plane-policy.ts → verification-control-plane-policy.ts} +37 -39
- package/src/twitter/platform-proxy-client.ts +408 -0
- package/src/usage/types.ts +21 -0
- package/src/util/canonicalize-identity.ts +2 -6
- package/src/util/errors.ts +12 -0
- package/src/util/platform.ts +93 -86
- package/src/util/pricing.ts +180 -43
- package/src/work-items/work-item-runner.ts +1 -1
- package/scripts/ipc/check-contract-inventory.ts +0 -107
- package/scripts/ipc/check-swift-decoder-drift.ts +0 -184
- package/scripts/ipc/generate-swift.ts +0 -528
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -3043
- package/src/__tests__/app-migration.test.ts +0 -148
- package/src/__tests__/config-loader-migration.test.ts +0 -85
- package/src/__tests__/daemon-lifecycle.test.ts +0 -715
- package/src/__tests__/daemon-server-session-init.test.ts +0 -864
- package/src/__tests__/guardian-actions-endpoint.test.ts +0 -1452
- package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +0 -228
- package/src/__tests__/handlers-cu-observation-blob.test.ts +0 -397
- package/src/__tests__/handlers-ipc-blob-probe.test.ts +0 -218
- package/src/__tests__/handlers-slack-config.test.ts +0 -140
- package/src/__tests__/handlers-telegram-config.test.ts +0 -1317
- package/src/__tests__/handlers-twitter-config.test.ts +0 -1145
- package/src/__tests__/home-base-bootstrap.test.ts +0 -86
- package/src/__tests__/ingress-reconcile.test.ts +0 -606
- package/src/__tests__/integrations-cli.test.ts +0 -232
- package/src/__tests__/ipc-blob-store.test.ts +0 -329
- package/src/__tests__/ipc-contract-inventory.test.ts +0 -69
- package/src/__tests__/ipc-contract.test.ts +0 -76
- package/src/__tests__/ipc-protocol.test.ts +0 -120
- package/src/__tests__/ipc-roundtrip.benchmark.test.ts +0 -250
- package/src/__tests__/ipc-snapshot.test.ts +0 -2197
- package/src/__tests__/ipc-validate.test.ts +0 -471
- package/src/__tests__/migration-cli-flows.test.ts +0 -186
- package/src/__tests__/migration-ordering.test.ts +0 -267
- package/src/__tests__/oauth-connect-handler.test.ts +0 -361
- package/src/__tests__/platform-move-helper.test.ts +0 -108
- package/src/__tests__/platform-socket-path.test.ts +0 -52
- package/src/__tests__/platform-workspace-migration.test.ts +0 -1051
- package/src/__tests__/prebuilt-home-base-seed.test.ts +0 -79
- package/src/__tests__/recording-intent-handler.test.ts +0 -1155
- package/src/__tests__/script-proxy-profile-template-fallback.test.ts +0 -127
- package/src/__tests__/sms-messaging-provider.test.ts +0 -156
- package/src/__tests__/tool-permission-simulate-handler.test.ts +0 -367
- package/src/__tests__/twitter-auth-handler.test.ts +0 -561
- package/src/__tests__/twitter-cli-error-shaping.test.ts +0 -224
- package/src/__tests__/twitter-cli-routing.test.ts +0 -286
- package/src/__tests__/work-item-output.test.ts +0 -150
- package/src/amazon/session.ts +0 -58
- package/src/cli/channels.ts +0 -51
- package/src/cli/influencer.ts +0 -319
- package/src/cli/integrations.ts +0 -372
- package/src/cli/ipc-client.ts +0 -88
- package/src/cli/twitter.ts +0 -1111
- package/src/config/bundled-skills/configure-settings/SKILL.md +0 -86
- package/src/config/bundled-skills/doordash/lib/shared/ipc.ts +0 -32
- package/src/config/bundled-skills/sms-setup/SKILL.md +0 -210
- package/src/config/core-schema.ts +0 -434
- package/src/config/memory-schema.ts +0 -617
- package/src/daemon/auth-manager.ts +0 -106
- package/src/daemon/handlers/apps.ts +0 -783
- package/src/daemon/handlers/avatar.ts +0 -73
- package/src/daemon/handlers/browser.ts +0 -3
- package/src/daemon/handlers/computer-use.ts +0 -231
- package/src/daemon/handlers/config-dispatch.ts +0 -29
- package/src/daemon/handlers/config-heartbeat.ts +0 -299
- package/src/daemon/handlers/config-inbox.ts +0 -457
- package/src/daemon/handlers/config-integrations.ts +0 -409
- package/src/daemon/handlers/config-platform.ts +0 -77
- package/src/daemon/handlers/config-slack.ts +0 -41
- package/src/daemon/handlers/config-tools.ts +0 -226
- package/src/daemon/handlers/config-trust.ts +0 -135
- package/src/daemon/handlers/config.ts +0 -64
- package/src/daemon/handlers/contacts.ts +0 -193
- package/src/daemon/handlers/diagnostics.ts +0 -382
- package/src/daemon/handlers/documents.ts +0 -188
- package/src/daemon/handlers/guardian-actions.ts +0 -82
- package/src/daemon/handlers/home-base.ts +0 -82
- package/src/daemon/handlers/index.ts +0 -222
- package/src/daemon/handlers/misc.ts +0 -1139
- package/src/daemon/handlers/navigate-settings.ts +0 -29
- package/src/daemon/handlers/oauth-connect.ts +0 -202
- package/src/daemon/handlers/open-bundle-handler.ts +0 -88
- package/src/daemon/handlers/publish.ts +0 -176
- package/src/daemon/handlers/signing.ts +0 -56
- package/src/daemon/handlers/subagents.ts +0 -286
- package/src/daemon/handlers/twitter-auth.ts +0 -220
- package/src/daemon/handlers/work-items.ts +0 -796
- package/src/daemon/handlers/workspace-files.ts +0 -84
- package/src/daemon/handlers.ts +0 -16
- package/src/daemon/ipc-blob-store.ts +0 -246
- package/src/daemon/ipc-contract-inventory.json +0 -348
- package/src/daemon/ipc-contract-inventory.ts +0 -202
- package/src/daemon/ipc-handler.ts +0 -120
- package/src/daemon/ipc-protocol.ts +0 -85
- package/src/daemon/ipc-validate.ts +0 -254
- 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/app-migration.ts +0 -114
- package/src/memory/channel-delivery-store.ts +0 -40
- package/src/memory/channel-guardian-store.ts +0 -83
- package/src/memory/conversation-store.ts +0 -102
- package/src/memory/schema-migration.ts +0 -38
- package/src/messaging/providers/sms/adapter.ts +0 -232
- package/src/messaging/providers/sms/client.ts +0 -93
- package/src/messaging/providers/sms/types.ts +0 -7
- package/src/migrations/config-merge.ts +0 -62
- package/src/migrations/data-layout.ts +0 -89
- package/src/migrations/data-merge.ts +0 -44
- package/src/migrations/hooks-merge.ts +0 -118
- package/src/migrations/index.ts +0 -6
- package/src/migrations/log.ts +0 -28
- package/src/migrations/skills-merge.ts +0 -44
- package/src/migrations/workspace-layout.ts +0 -94
- package/src/notifications/adapters/sms.ts +0 -94
- package/src/runtime/channel-approval-parser.ts +0 -123
- package/src/runtime/channel-invite-transports/sms.ts +0 -53
- package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +0 -82
- package/src/runtime/routes/integration-routes.ts +0 -381
- package/src/runtime/routes/twilio-routes.ts +0 -1251
- package/src/twitter/client.ts +0 -979
- package/src/twitter/router.ts +0 -131
- package/src/twitter/session.ts +0 -54
- package/src/util/cookie-session.ts +0 -114
- package/src/watcher/providers/slack.ts +0 -282
- /package/src/{amazon → cli/commands/amazon}/cart.ts +0 -0
- /package/src/{amazon → cli/commands/amazon}/checkout.ts +0 -0
- /package/src/{amazon → cli/commands/amazon}/product-details.ts +0 -0
- /package/src/{amazon → cli/commands/amazon}/search.ts +0 -0
- /package/src/config/{calls-schema.ts → schemas/calls.ts} +0 -0
- /package/src/config/{elevenlabs-schema.ts → schemas/elevenlabs.ts} +0 -0
- /package/src/config/{mcp-schema.ts → schemas/mcp.ts} +0 -0
- /package/src/config/{notifications-schema.ts → schemas/notifications.ts} +0 -0
- /package/src/config/{sandbox-schema.ts → schemas/sandbox.ts} +0 -0
- /package/src/config/{skills-schema.ts → schemas/skills.ts} +0 -0
- /package/src/daemon/{ipc-contract → message-types}/browser.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/contacts.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/documents.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/guardian-actions.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/inbox.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/messages.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/pairing.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/schedules.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/settings.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/skills.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/subagents.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/trust.ts +0 -0
- /package/src/daemon/{ipc-contract → message-types}/work-items.ts +0 -0
- /package/src/{cli/email-guardrails.ts → email/guardrails.ts} +0 -0
- /package/src/{config → prompts}/__tests__/build-cli-reference-section.test.ts +0 -0
- /package/src/{config → prompts}/templates/IDENTITY.md +0 -0
- /package/src/{config → prompts}/templates/SOUL.md +0 -0
- /package/src/{config → prompts}/templates/UPDATES.md +0 -0
- /package/src/{config → prompts}/templates/USER.md +0 -0
- /package/src/{config → prompts}/update-bulletin-format.ts +0 -0
- /package/src/{config → prompts}/update-bulletin-state.ts +0 -0
- /package/src/{config → prompts}/update-bulletin-template-path.ts +0 -0
- /package/src/{config → prompts}/update-bulletin.ts +0 -0
- /package/src/{config → prompts}/user-reference.ts +0 -0
package/src/daemon/server.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as net from "node:net";
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
2
|
import { join } from "node:path";
|
|
4
|
-
import * as tls from "node:tls";
|
|
5
3
|
|
|
6
4
|
import {
|
|
7
5
|
createAssistantMessage,
|
|
@@ -14,61 +12,51 @@ import {
|
|
|
14
12
|
parseInterfaceId,
|
|
15
13
|
} from "../channels/types.js";
|
|
16
14
|
import { getConfig } from "../config/loader.js";
|
|
17
|
-
import { buildSystemPrompt } from "../config/system-prompt.js";
|
|
18
15
|
import { onContactChange } from "../contacts/contact-events.js";
|
|
19
16
|
import type { HeartbeatService } from "../heartbeat/heartbeat-service.js";
|
|
20
|
-
import { bootstrapHomeBaseAppLink } from "../home-base/bootstrap.js";
|
|
21
17
|
import * as attachmentsStore from "../memory/attachments-store.js";
|
|
22
18
|
import {
|
|
23
19
|
createCanonicalGuardianRequest,
|
|
24
20
|
generateCanonicalRequestCode,
|
|
25
21
|
} from "../memory/canonical-guardian-store.js";
|
|
26
|
-
import
|
|
27
|
-
|
|
22
|
+
import {
|
|
23
|
+
addMessage,
|
|
24
|
+
getConversationMemoryScopeId,
|
|
25
|
+
getConversationThreadType,
|
|
26
|
+
provenanceFromTrustContext,
|
|
27
|
+
setConversationOriginChannelIfUnset,
|
|
28
|
+
setConversationOriginInterfaceIfUnset,
|
|
29
|
+
} from "../memory/conversation-crud.js";
|
|
30
|
+
import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
28
31
|
import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
29
32
|
import {
|
|
30
33
|
getFailoverProvider,
|
|
31
34
|
initializeProviders,
|
|
32
35
|
} from "../providers/registry.js";
|
|
36
|
+
import { buildAssistantEvent } from "../runtime/assistant-event.js";
|
|
37
|
+
import { assistantEventHub } from "../runtime/assistant-event-hub.js";
|
|
33
38
|
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
39
|
+
import { getSigningKeyFingerprint } from "../runtime/auth/token-service.js";
|
|
34
40
|
import { bridgeConfirmationRequestToGuardian } from "../runtime/confirmation-request-guardian-bridge.js";
|
|
35
41
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
36
42
|
import { checkIngressForSecrets } from "../security/secret-ingress.js";
|
|
37
43
|
import { getSubagentManager } from "../subagent/index.js";
|
|
38
44
|
import { IngressBlockedError } from "../util/errors.js";
|
|
39
45
|
import { getLogger } from "../util/logger.js";
|
|
40
|
-
import { getLocalIPv4 } from "../util/network-info.js";
|
|
41
46
|
import {
|
|
42
47
|
getSandboxWorkingDir,
|
|
43
|
-
getSocketPath,
|
|
44
|
-
getTCPHost,
|
|
45
|
-
getTCPPort,
|
|
46
48
|
getWorkspacePromptPath,
|
|
47
|
-
isIOSPairingEnabled,
|
|
48
|
-
isTCPEnabled,
|
|
49
|
-
removeSocketFile,
|
|
50
49
|
} from "../util/platform.js";
|
|
51
50
|
import { registerDaemonCallbacks } from "../work-items/work-item-runner.js";
|
|
52
|
-
import { AuthManager } from "./auth-manager.js";
|
|
53
51
|
import { ComputerUseSession } from "./computer-use-session.js";
|
|
54
52
|
import { ConfigWatcher } from "./config-watcher.js";
|
|
55
|
-
import {
|
|
56
|
-
handleMessage,
|
|
57
|
-
type HandlerContext,
|
|
58
|
-
type SessionCreateOptions,
|
|
59
|
-
} from "./handlers.js";
|
|
60
53
|
import { parseIdentityFields } from "./handlers/identity.js";
|
|
61
|
-
import {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
normalizeThreadType,
|
|
68
|
-
serialize,
|
|
69
|
-
type ServerMessage,
|
|
70
|
-
} from "./ipc-protocol.js";
|
|
71
|
-
import { validateClientMessage } from "./ipc-validate.js";
|
|
54
|
+
import type {
|
|
55
|
+
HandlerContext,
|
|
56
|
+
SessionCreateOptions,
|
|
57
|
+
} from "./handlers/shared.js";
|
|
58
|
+
import type { SkillOperationContext } from "./handlers/skills.js";
|
|
59
|
+
import type { ServerMessage } from "./message-protocol.js";
|
|
72
60
|
import {
|
|
73
61
|
DEFAULT_MEMORY_POLICY,
|
|
74
62
|
Session,
|
|
@@ -77,7 +65,6 @@ import {
|
|
|
77
65
|
import { SessionEvictor } from "./session-evictor.js";
|
|
78
66
|
import { resolveChannelCapabilities } from "./session-runtime-assembly.js";
|
|
79
67
|
import { resolveSlash } from "./session-slash.js";
|
|
80
|
-
import { ensureTlsCert } from "./tls-certs.js";
|
|
81
68
|
|
|
82
69
|
const log = getLogger("server");
|
|
83
70
|
|
|
@@ -132,7 +119,7 @@ function resolveTurnInterface(sourceInterface?: string): InterfaceId {
|
|
|
132
119
|
function resolveCanonicalRequestSourceType(
|
|
133
120
|
sourceChannel: string | undefined,
|
|
134
121
|
): "desktop" | "channel" | "voice" {
|
|
135
|
-
if (sourceChannel === "
|
|
122
|
+
if (sourceChannel === "phone") {
|
|
136
123
|
return "voice";
|
|
137
124
|
}
|
|
138
125
|
if (sourceChannel === "vellum") {
|
|
@@ -168,7 +155,7 @@ function makePendingInteractionRegistrar(
|
|
|
168
155
|
},
|
|
169
156
|
});
|
|
170
157
|
|
|
171
|
-
// Create a canonical guardian request so
|
|
158
|
+
// Create a canonical guardian request so HTTP handlers can find it
|
|
172
159
|
// via applyCanonicalGuardianDecision.
|
|
173
160
|
try {
|
|
174
161
|
const trustContext = session.trustContext;
|
|
@@ -217,29 +204,19 @@ function makePendingInteractionRegistrar(
|
|
|
217
204
|
}
|
|
218
205
|
|
|
219
206
|
export class DaemonServer {
|
|
220
|
-
private server: net.Server | null = null;
|
|
221
|
-
private tcpServer: tls.Server | null = null;
|
|
222
207
|
private sessions = new Map<string, Session>();
|
|
223
|
-
private socketToSession = new Map<net.Socket, string>();
|
|
224
208
|
private cuSessions = new Map<string, ComputerUseSession>();
|
|
225
|
-
private socketToCuSession = new Map<net.Socket, Set<string>>();
|
|
226
|
-
private connectedSockets = new Set<net.Socket>();
|
|
227
|
-
private socketSandboxOverride = new Map<net.Socket, boolean>();
|
|
228
209
|
private cuObservationParseSequence = new Map<string, number>();
|
|
229
210
|
private sessionOptions = new Map<string, SessionCreateOptions>();
|
|
230
211
|
private sessionCreating = new Map<string, Promise<Session>>();
|
|
231
212
|
private sharedRequestTimestamps: number[] = [];
|
|
232
|
-
private socketPath: string;
|
|
233
213
|
private httpPort: number | undefined;
|
|
234
|
-
private blobSweepTimer: ReturnType<typeof setInterval> | null = null;
|
|
235
214
|
private unsubscribeContactChange: (() => void) | null = null;
|
|
236
|
-
private static readonly MAX_CONNECTIONS = 50;
|
|
237
215
|
private evictor: SessionEvictor;
|
|
216
|
+
private _hubChain: Promise<void> = Promise.resolve();
|
|
238
217
|
|
|
239
218
|
// Composed subsystems
|
|
240
|
-
private auth = new AuthManager();
|
|
241
219
|
private configWatcher = new ConfigWatcher();
|
|
242
|
-
private ipc = new IpcSender();
|
|
243
220
|
|
|
244
221
|
/**
|
|
245
222
|
* Logical assistant identifier used when publishing to the assistant-events hub.
|
|
@@ -254,11 +231,10 @@ export class DaemonServer {
|
|
|
254
231
|
}
|
|
255
232
|
|
|
256
233
|
private deriveMemoryPolicy(conversationId: string): SessionMemoryPolicy {
|
|
257
|
-
const threadType =
|
|
258
|
-
conversationStore.getConversationThreadType(conversationId);
|
|
234
|
+
const threadType = getConversationThreadType(conversationId);
|
|
259
235
|
if (threadType === "private") {
|
|
260
236
|
return {
|
|
261
|
-
scopeId:
|
|
237
|
+
scopeId: getConversationMemoryScopeId(conversationId),
|
|
262
238
|
includeDefaultFallback: true,
|
|
263
239
|
strictSideEffects: true,
|
|
264
240
|
};
|
|
@@ -279,7 +255,6 @@ export class DaemonServer {
|
|
|
279
255
|
}
|
|
280
256
|
|
|
281
257
|
constructor() {
|
|
282
|
-
this.socketPath = getSocketPath();
|
|
283
258
|
this.evictor = new SessionEvictor(this.sessions);
|
|
284
259
|
getSubagentManager().sharedRequestTimestamps = this.sharedRequestTimestamps;
|
|
285
260
|
this.evictor.onEvict = (sessionId: string) => {
|
|
@@ -342,20 +317,29 @@ export class DaemonServer {
|
|
|
342
317
|
};
|
|
343
318
|
}
|
|
344
319
|
|
|
345
|
-
// ──
|
|
320
|
+
// ── Broadcast / Event publishing ──────────────────────────────────
|
|
346
321
|
|
|
347
|
-
|
|
348
|
-
|
|
322
|
+
/**
|
|
323
|
+
* Publish `msg` as an `AssistantEvent` to the process-level hub.
|
|
324
|
+
* Publications are serialized via a promise chain so subscribers
|
|
325
|
+
* always observe events in send order.
|
|
326
|
+
*/
|
|
327
|
+
private publishAssistantEvent(msg: ServerMessage, sessionId?: string): void {
|
|
328
|
+
const id = this.assistantId ?? "default";
|
|
329
|
+
const event = buildAssistantEvent(id, msg, sessionId);
|
|
330
|
+
this._hubChain = this._hubChain
|
|
331
|
+
.then(() => assistantEventHub.publish(event))
|
|
332
|
+
.catch((err: unknown) => {
|
|
333
|
+
log.warn(
|
|
334
|
+
{ err },
|
|
335
|
+
"assistant-events hub subscriber threw during broadcast",
|
|
336
|
+
);
|
|
337
|
+
});
|
|
349
338
|
}
|
|
350
339
|
|
|
351
|
-
broadcast(msg: ServerMessage
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
msg,
|
|
355
|
-
this.socketToSession,
|
|
356
|
-
this.assistantId,
|
|
357
|
-
excludeSocket,
|
|
358
|
-
);
|
|
340
|
+
broadcast(msg: ServerMessage): void {
|
|
341
|
+
const sessionId = extractSessionId(msg);
|
|
342
|
+
this.publishAssistantEvent(msg, sessionId);
|
|
359
343
|
}
|
|
360
344
|
|
|
361
345
|
private broadcastIdentityChanged(): void {
|
|
@@ -381,21 +365,10 @@ export class DaemonServer {
|
|
|
381
365
|
// ── Server lifecycle ────────────────────────────────────────────────
|
|
382
366
|
|
|
383
367
|
async start(): Promise<void> {
|
|
384
|
-
removeSocketFile(this.socketPath);
|
|
385
|
-
|
|
386
368
|
const config = getConfig();
|
|
387
369
|
initializeProviders(config);
|
|
388
370
|
this.configWatcher.initFingerprint(config);
|
|
389
371
|
|
|
390
|
-
try {
|
|
391
|
-
bootstrapHomeBaseAppLink();
|
|
392
|
-
} catch (err) {
|
|
393
|
-
log.warn(
|
|
394
|
-
{ err },
|
|
395
|
-
"Failed to bootstrap Home Base app link at daemon startup",
|
|
396
|
-
);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
372
|
this.evictor.start();
|
|
400
373
|
|
|
401
374
|
registerDaemonCallbacks({
|
|
@@ -404,16 +377,6 @@ export class DaemonServer {
|
|
|
404
377
|
broadcast: (msg) => this.broadcast(msg),
|
|
405
378
|
});
|
|
406
379
|
|
|
407
|
-
ensureBlobDir();
|
|
408
|
-
this.blobSweepTimer = setInterval(
|
|
409
|
-
() => {
|
|
410
|
-
sweepStaleBlobs(30 * 60 * 1000).catch((err) => {
|
|
411
|
-
log.warn({ err }, "Blob sweep failed");
|
|
412
|
-
});
|
|
413
|
-
},
|
|
414
|
-
5 * 60 * 1000,
|
|
415
|
-
);
|
|
416
|
-
|
|
417
380
|
this.configWatcher.start(
|
|
418
381
|
() => this.evictSessionsForReload(),
|
|
419
382
|
() => this.broadcastIdentityChanged(),
|
|
@@ -424,140 +387,17 @@ export class DaemonServer {
|
|
|
424
387
|
this.broadcast({ type: "contacts_changed" });
|
|
425
388
|
});
|
|
426
389
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
let tlsCreds: { cert: string; key: string; fingerprint: string } | null =
|
|
430
|
-
null;
|
|
431
|
-
if (isTCPEnabled()) {
|
|
432
|
-
try {
|
|
433
|
-
tlsCreds = await ensureTlsCert();
|
|
434
|
-
} catch (err) {
|
|
435
|
-
log.error(
|
|
436
|
-
{ err },
|
|
437
|
-
"Failed to generate TLS certificate — TCP listener will not start",
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
return new Promise((resolve, reject) => {
|
|
443
|
-
this.server = net.createServer((socket) => {
|
|
444
|
-
this.handleConnection(socket);
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
const oldUmask = process.umask(0o177);
|
|
448
|
-
|
|
449
|
-
this.server.once("error", (err) => {
|
|
450
|
-
process.umask(oldUmask);
|
|
451
|
-
log.error(
|
|
452
|
-
{ err, socketPath: this.socketPath },
|
|
453
|
-
"Server failed to start (is another daemon already running?)",
|
|
454
|
-
);
|
|
455
|
-
reject(err);
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
this.server.listen(this.socketPath, () => {
|
|
459
|
-
process.umask(oldUmask);
|
|
460
|
-
this.server!.removeAllListeners("error");
|
|
461
|
-
this.server!.on("error", (err) => {
|
|
462
|
-
log.error(
|
|
463
|
-
{ err, socketPath: this.socketPath },
|
|
464
|
-
"Server socket error while running",
|
|
465
|
-
);
|
|
466
|
-
});
|
|
467
|
-
chmodSync(this.socketPath, 0o600);
|
|
468
|
-
// Validate the chmod actually took effect — some filesystems
|
|
469
|
-
// (e.g. FAT32 mounts, container overlays) silently ignore chmod.
|
|
470
|
-
const socketStat = statSync(this.socketPath);
|
|
471
|
-
if ((socketStat.mode & 0o077) !== 0) {
|
|
472
|
-
const actual = "0o" + (socketStat.mode & 0o777).toString(8);
|
|
473
|
-
log.error(
|
|
474
|
-
{ socketPath: this.socketPath, mode: actual },
|
|
475
|
-
"IPC socket is accessible by other users (expected 0600) — filesystem may not support Unix permissions",
|
|
476
|
-
);
|
|
477
|
-
}
|
|
478
|
-
log.info({ socketPath: this.socketPath }, "Daemon server listening");
|
|
479
|
-
|
|
480
|
-
if (tlsCreds) {
|
|
481
|
-
const tcpPort = getTCPPort();
|
|
482
|
-
const tcpHost = getTCPHost();
|
|
483
|
-
this.tcpServer = tls.createServer(
|
|
484
|
-
{ cert: tlsCreds.cert, key: tlsCreds.key },
|
|
485
|
-
(socket) => {
|
|
486
|
-
this.handleConnection(socket);
|
|
487
|
-
},
|
|
488
|
-
);
|
|
489
|
-
this.tcpServer.on("error", (err) => {
|
|
490
|
-
log.error({ err, tcpPort }, "TLS TCP server error");
|
|
491
|
-
});
|
|
492
|
-
const fingerprint = tlsCreds.fingerprint;
|
|
493
|
-
this.tcpServer.listen(tcpPort, tcpHost, () => {
|
|
494
|
-
const localIP = getLocalIPv4();
|
|
495
|
-
log.info(
|
|
496
|
-
{
|
|
497
|
-
tcpPort,
|
|
498
|
-
tcpHost,
|
|
499
|
-
fingerprint,
|
|
500
|
-
localIP,
|
|
501
|
-
iosPairing: isIOSPairingEnabled(),
|
|
502
|
-
},
|
|
503
|
-
"TLS TCP listener started",
|
|
504
|
-
);
|
|
505
|
-
if (isIOSPairingEnabled() && localIP) {
|
|
506
|
-
log.warn(
|
|
507
|
-
{ localIP, tcpPort },
|
|
508
|
-
"iOS pairing enabled — daemon is reachable on the local network at %s:%d",
|
|
509
|
-
localIP,
|
|
510
|
-
tcpPort,
|
|
511
|
-
);
|
|
512
|
-
}
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
resolve();
|
|
517
|
-
});
|
|
518
|
-
});
|
|
390
|
+
log.info("DaemonServer started (HTTP-only mode)");
|
|
519
391
|
}
|
|
520
392
|
|
|
521
393
|
async stop(): Promise<void> {
|
|
522
394
|
getSubagentManager().disposeAll();
|
|
523
395
|
this.evictor.stop();
|
|
524
|
-
if (this.blobSweepTimer) {
|
|
525
|
-
clearInterval(this.blobSweepTimer);
|
|
526
|
-
this.blobSweepTimer = null;
|
|
527
|
-
}
|
|
528
396
|
this.configWatcher.stop();
|
|
529
397
|
if (this.unsubscribeContactChange) {
|
|
530
398
|
this.unsubscribeContactChange();
|
|
531
399
|
this.unsubscribeContactChange = null;
|
|
532
400
|
}
|
|
533
|
-
this.auth.cleanupAll();
|
|
534
|
-
|
|
535
|
-
const serverClosed = new Promise<void>((resolve) => {
|
|
536
|
-
if (this.server) {
|
|
537
|
-
this.server.close(() => {
|
|
538
|
-
try {
|
|
539
|
-
removeSocketFile(this.socketPath);
|
|
540
|
-
} catch (err) {
|
|
541
|
-
log.warn(
|
|
542
|
-
{ err, socketPath: this.socketPath },
|
|
543
|
-
"Failed to remove socket file during shutdown",
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
resolve();
|
|
547
|
-
});
|
|
548
|
-
} else {
|
|
549
|
-
resolve();
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
const tcpServerClosed = new Promise<void>((resolve) => {
|
|
554
|
-
if (this.tcpServer) {
|
|
555
|
-
this.tcpServer.close(() => resolve());
|
|
556
|
-
this.tcpServer = null;
|
|
557
|
-
} else {
|
|
558
|
-
resolve();
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
401
|
|
|
562
402
|
for (const session of this.sessions.values()) {
|
|
563
403
|
session.dispose();
|
|
@@ -568,225 +408,10 @@ export class DaemonServer {
|
|
|
568
408
|
cuSession.abort();
|
|
569
409
|
}
|
|
570
410
|
this.cuSessions.clear();
|
|
571
|
-
this.socketToCuSession.clear();
|
|
572
411
|
|
|
573
|
-
for (const socket of this.connectedSockets) {
|
|
574
|
-
socket.destroy();
|
|
575
|
-
}
|
|
576
|
-
this.connectedSockets.clear();
|
|
577
|
-
this.socketToSession.clear();
|
|
578
|
-
this.socketSandboxOverride.clear();
|
|
579
|
-
this.cuObservationParseSequence.clear();
|
|
580
|
-
|
|
581
|
-
await Promise.all([serverClosed, tcpServerClosed]);
|
|
582
412
|
log.info("Daemon server stopped");
|
|
583
413
|
}
|
|
584
414
|
|
|
585
|
-
// ── Connection handling ─────────────────────────────────────────────
|
|
586
|
-
|
|
587
|
-
private handleConnection(socket: net.Socket): void {
|
|
588
|
-
if (this.connectedSockets.size >= DaemonServer.MAX_CONNECTIONS) {
|
|
589
|
-
log.warn(
|
|
590
|
-
{
|
|
591
|
-
current: this.connectedSockets.size,
|
|
592
|
-
max: DaemonServer.MAX_CONNECTIONS,
|
|
593
|
-
},
|
|
594
|
-
"Connection limit reached, rejecting client",
|
|
595
|
-
);
|
|
596
|
-
socket.once("error", (err) => {
|
|
597
|
-
log.error({ err }, "Socket error while rejecting connection");
|
|
598
|
-
});
|
|
599
|
-
socket.write(
|
|
600
|
-
serialize({
|
|
601
|
-
type: "error",
|
|
602
|
-
message: `Connection limit reached (max ${DaemonServer.MAX_CONNECTIONS})`,
|
|
603
|
-
}),
|
|
604
|
-
);
|
|
605
|
-
socket.destroy();
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
log.info("Client connected");
|
|
610
|
-
this.connectedSockets.add(socket);
|
|
611
|
-
const parser = createMessageParser({ maxLineSize: MAX_LINE_SIZE });
|
|
612
|
-
|
|
613
|
-
if (this.auth.shouldAutoAuth()) {
|
|
614
|
-
this.auth.markAuthenticated(socket);
|
|
615
|
-
log.warn(
|
|
616
|
-
"Auto-authenticated client (VELLUM_DAEMON_NOAUTH is set — token auth bypassed)",
|
|
617
|
-
);
|
|
618
|
-
this.send(socket, { type: "auth_result", success: true });
|
|
619
|
-
this.sendInitialSession(socket).catch((err) => {
|
|
620
|
-
log.error(
|
|
621
|
-
{ err },
|
|
622
|
-
"Failed to send initial session info after auto-auth",
|
|
623
|
-
);
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
this.auth.startTimeout(socket, () => {
|
|
628
|
-
this.send(socket, { type: "error", message: "Authentication timeout" });
|
|
629
|
-
socket.destroy();
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
socket.on("data", (data) => {
|
|
633
|
-
const chunkReceivedAtMs = Date.now();
|
|
634
|
-
const parseStartNs = process.hrtime.bigint();
|
|
635
|
-
let parsed;
|
|
636
|
-
try {
|
|
637
|
-
parsed = parser.feedRaw(data.toString());
|
|
638
|
-
} catch (err) {
|
|
639
|
-
log.error(
|
|
640
|
-
{ err },
|
|
641
|
-
"IPC parse error (malformed JSON or message exceeded size limit), dropping client",
|
|
642
|
-
);
|
|
643
|
-
socket.write(
|
|
644
|
-
serialize({
|
|
645
|
-
type: "error",
|
|
646
|
-
message: `IPC parse error: ${(err as Error).message}`,
|
|
647
|
-
}),
|
|
648
|
-
);
|
|
649
|
-
socket.destroy();
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
const parsedAtMs = Date.now();
|
|
653
|
-
const parseDurationMs =
|
|
654
|
-
Number(process.hrtime.bigint() - parseStartNs) / 1_000_000;
|
|
655
|
-
for (const entry of parsed) {
|
|
656
|
-
const msg = entry.msg;
|
|
657
|
-
if (
|
|
658
|
-
typeof msg === "object" &&
|
|
659
|
-
msg != null &&
|
|
660
|
-
(msg as { type?: unknown }).type === "cu_observation"
|
|
661
|
-
) {
|
|
662
|
-
const maybeSessionId = (msg as { sessionId?: unknown }).sessionId;
|
|
663
|
-
const sessionId =
|
|
664
|
-
typeof maybeSessionId === "string" ? maybeSessionId : "unknown";
|
|
665
|
-
const previousSequence =
|
|
666
|
-
this.cuObservationParseSequence.get(sessionId) ?? 0;
|
|
667
|
-
const sequence = previousSequence + 1;
|
|
668
|
-
this.cuObservationParseSequence.set(sessionId, sequence);
|
|
669
|
-
log.info(
|
|
670
|
-
{
|
|
671
|
-
sessionId,
|
|
672
|
-
sequence,
|
|
673
|
-
chunkReceivedAtMs,
|
|
674
|
-
parsedAtMs,
|
|
675
|
-
parseDurationMs,
|
|
676
|
-
messageBytes: entry.rawByteLength,
|
|
677
|
-
},
|
|
678
|
-
"IPC_METRIC cu_observation_parse",
|
|
679
|
-
);
|
|
680
|
-
}
|
|
681
|
-
const result = validateClientMessage(msg);
|
|
682
|
-
if (!result.valid) {
|
|
683
|
-
log.warn(
|
|
684
|
-
{ reason: result.reason },
|
|
685
|
-
"Invalid IPC message, dropping client",
|
|
686
|
-
);
|
|
687
|
-
socket.write(
|
|
688
|
-
serialize({
|
|
689
|
-
type: "error",
|
|
690
|
-
message: `Invalid message: ${result.reason}`,
|
|
691
|
-
}),
|
|
692
|
-
);
|
|
693
|
-
socket.destroy();
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
// Auth gate
|
|
698
|
-
if (!this.auth.isAuthenticated(socket)) {
|
|
699
|
-
this.auth.clearTimeout(socket);
|
|
700
|
-
|
|
701
|
-
if (result.message.type === "auth") {
|
|
702
|
-
const authMsg = result.message as { type: "auth"; token: string };
|
|
703
|
-
if (this.auth.authenticate(socket, authMsg.token)) {
|
|
704
|
-
this.send(socket, { type: "auth_result", success: true });
|
|
705
|
-
this.sendInitialSession(socket).catch((err) => {
|
|
706
|
-
log.error(
|
|
707
|
-
{ err },
|
|
708
|
-
"Failed to send initial session info after auth",
|
|
709
|
-
);
|
|
710
|
-
});
|
|
711
|
-
} else {
|
|
712
|
-
this.send(socket, {
|
|
713
|
-
type: "auth_result",
|
|
714
|
-
success: false,
|
|
715
|
-
message: "Invalid token",
|
|
716
|
-
});
|
|
717
|
-
socket.destroy();
|
|
718
|
-
}
|
|
719
|
-
continue;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
log.warn(
|
|
723
|
-
{ type: result.message.type },
|
|
724
|
-
"Unauthenticated client sent non-auth message, disconnecting",
|
|
725
|
-
);
|
|
726
|
-
this.send(socket, {
|
|
727
|
-
type: "error",
|
|
728
|
-
message: "Authentication required",
|
|
729
|
-
});
|
|
730
|
-
socket.destroy();
|
|
731
|
-
return;
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// Already-authenticated socket sending auth (e.g. auto-auth'd + local token)
|
|
735
|
-
if (result.message.type === "auth") {
|
|
736
|
-
this.send(socket, { type: "auth_result", success: true });
|
|
737
|
-
continue;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
this.dispatchMessage(result.message, socket);
|
|
741
|
-
}
|
|
742
|
-
});
|
|
743
|
-
|
|
744
|
-
socket.on("close", () => {
|
|
745
|
-
this.auth.cleanupSocket(socket);
|
|
746
|
-
this.connectedSockets.delete(socket);
|
|
747
|
-
this.socketSandboxOverride.delete(socket);
|
|
748
|
-
const sessionId = this.socketToSession.get(socket);
|
|
749
|
-
if (sessionId) {
|
|
750
|
-
const session = this.sessions.get(sessionId);
|
|
751
|
-
if (session) {
|
|
752
|
-
session.abort();
|
|
753
|
-
}
|
|
754
|
-
getSubagentManager().abortAllForParent(sessionId);
|
|
755
|
-
}
|
|
756
|
-
// Clean up recording state for recordings whose owning conversation is
|
|
757
|
-
// bound to the disconnecting socket. Runs outside the sessionId check
|
|
758
|
-
// because recordings may be keyed to a different conversation than the
|
|
759
|
-
// socket's current session.
|
|
760
|
-
cleanupRecordingsOnDisconnect(socket, (convId) => {
|
|
761
|
-
for (const [s, sid] of this.socketToSession.entries()) {
|
|
762
|
-
if (sid === convId) return s;
|
|
763
|
-
}
|
|
764
|
-
return undefined;
|
|
765
|
-
});
|
|
766
|
-
this.socketToSession.delete(socket);
|
|
767
|
-
const cuSessionIds = this.socketToCuSession.get(socket);
|
|
768
|
-
if (cuSessionIds) {
|
|
769
|
-
for (const cuSessionId of cuSessionIds) {
|
|
770
|
-
this.cuObservationParseSequence.delete(cuSessionId);
|
|
771
|
-
const cuSession = this.cuSessions.get(cuSessionId);
|
|
772
|
-
if (cuSession) {
|
|
773
|
-
cuSession.abort();
|
|
774
|
-
this.cuSessions.delete(cuSessionId);
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
this.socketToCuSession.delete(socket);
|
|
779
|
-
log.info("Client disconnected");
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
socket.on("error", (err) => {
|
|
783
|
-
log.error(
|
|
784
|
-
{ err, remoteAddress: socket.remoteAddress },
|
|
785
|
-
"Client socket error",
|
|
786
|
-
);
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
|
-
|
|
790
415
|
// ── Session management ──────────────────────────────────────────────
|
|
791
416
|
|
|
792
417
|
setHttpPort(port: number): void {
|
|
@@ -795,6 +420,7 @@ export class DaemonServer {
|
|
|
795
420
|
type: "daemon_status",
|
|
796
421
|
httpPort: port,
|
|
797
422
|
version: daemonVersion,
|
|
423
|
+
keyFingerprint: getSigningKeyFingerprint(),
|
|
798
424
|
});
|
|
799
425
|
}
|
|
800
426
|
|
|
@@ -841,49 +467,12 @@ export class DaemonServer {
|
|
|
841
467
|
return changed;
|
|
842
468
|
}
|
|
843
469
|
|
|
844
|
-
private async sendInitialSession(socket: net.Socket): Promise<void> {
|
|
845
|
-
const conversation = conversationStore.getLatestConversation();
|
|
846
|
-
if (!conversation) {
|
|
847
|
-
this.send(socket, {
|
|
848
|
-
type: "daemon_status",
|
|
849
|
-
httpPort: this.httpPort,
|
|
850
|
-
version: daemonVersion,
|
|
851
|
-
});
|
|
852
|
-
return;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
await this.getOrCreateSession(conversation.id, undefined, false);
|
|
856
|
-
|
|
857
|
-
this.send(socket, {
|
|
858
|
-
type: "session_info",
|
|
859
|
-
sessionId: conversation.id,
|
|
860
|
-
title: conversation.title ?? "New Conversation",
|
|
861
|
-
threadType: normalizeThreadType(conversation.threadType),
|
|
862
|
-
});
|
|
863
|
-
|
|
864
|
-
this.send(socket, {
|
|
865
|
-
type: "daemon_status",
|
|
866
|
-
httpPort: this.httpPort,
|
|
867
|
-
version: daemonVersion,
|
|
868
|
-
});
|
|
869
|
-
}
|
|
870
|
-
|
|
871
470
|
private async getOrCreateSession(
|
|
872
471
|
conversationId: string,
|
|
873
|
-
socket?: net.Socket,
|
|
874
|
-
rebindClient = true,
|
|
875
472
|
options?: SessionCreateOptions,
|
|
876
473
|
): Promise<Session> {
|
|
877
474
|
let session = this.sessions.get(conversationId);
|
|
878
|
-
const sendToClient =
|
|
879
|
-
? (msg: ServerMessage) => this.send(socket, msg)
|
|
880
|
-
: () => {};
|
|
881
|
-
const maybeBindClient = (target: Session): void => {
|
|
882
|
-
if (!rebindClient || !socket) return;
|
|
883
|
-
target.updateClient(sendToClient);
|
|
884
|
-
target.setSandboxOverride(this.socketSandboxOverride.get(socket));
|
|
885
|
-
getSubagentManager().updateParentSender(conversationId, sendToClient);
|
|
886
|
-
};
|
|
475
|
+
const sendToClient = () => {};
|
|
887
476
|
|
|
888
477
|
if (options && Object.values(options).some((v) => v !== undefined)) {
|
|
889
478
|
this.sessionOptions.set(conversationId, {
|
|
@@ -901,7 +490,6 @@ export class DaemonServer {
|
|
|
901
490
|
const pending = this.sessionCreating.get(conversationId);
|
|
902
491
|
if (pending) {
|
|
903
492
|
session = await pending;
|
|
904
|
-
maybeBindClient(session);
|
|
905
493
|
return session;
|
|
906
494
|
}
|
|
907
495
|
|
|
@@ -936,19 +524,14 @@ export class DaemonServer {
|
|
|
936
524
|
provider,
|
|
937
525
|
systemPrompt,
|
|
938
526
|
maxTokens,
|
|
939
|
-
|
|
527
|
+
sendToClient,
|
|
940
528
|
workingDir,
|
|
941
|
-
(msg) => this.broadcast(msg
|
|
529
|
+
(msg) => this.broadcast(msg),
|
|
942
530
|
memoryPolicy,
|
|
943
531
|
);
|
|
944
|
-
|
|
945
|
-
newSession.updateClient(sendToClient, true);
|
|
946
|
-
}
|
|
532
|
+
newSession.updateClient(sendToClient, true);
|
|
947
533
|
await newSession.loadFromDb();
|
|
948
534
|
this.applyTransportMetadata(newSession, storedOptions);
|
|
949
|
-
if (rebindClient && socket) {
|
|
950
|
-
newSession.setSandboxOverride(this.socketSandboxOverride.get(socket));
|
|
951
|
-
}
|
|
952
535
|
this.sessions.set(conversationId, newSession);
|
|
953
536
|
return newSession;
|
|
954
537
|
})();
|
|
@@ -961,23 +544,19 @@ export class DaemonServer {
|
|
|
961
544
|
}
|
|
962
545
|
this.evictor.touch(conversationId);
|
|
963
546
|
} else {
|
|
964
|
-
maybeBindClient(session);
|
|
965
547
|
this.applyTransportMetadata(session, options);
|
|
966
548
|
this.evictor.touch(conversationId);
|
|
967
549
|
}
|
|
968
550
|
return session;
|
|
969
551
|
}
|
|
970
552
|
|
|
971
|
-
// ──
|
|
553
|
+
// ── Handler context ────────────────────────────────────────────────
|
|
972
554
|
|
|
973
555
|
private handlerContext(): HandlerContext {
|
|
974
556
|
return {
|
|
975
557
|
sessions: this.sessions,
|
|
976
|
-
socketToSession: this.socketToSession,
|
|
977
558
|
cuSessions: this.cuSessions,
|
|
978
|
-
socketToCuSession: this.socketToCuSession,
|
|
979
559
|
cuObservationParseSequence: this.cuObservationParseSequence,
|
|
980
|
-
socketSandboxOverride: this.socketSandboxOverride,
|
|
981
560
|
sharedRequestTimestamps: this.sharedRequestTimestamps,
|
|
982
561
|
debounceTimers: this.configWatcher.timers,
|
|
983
562
|
suppressConfigReload: this.configWatcher.suppressConfigReload,
|
|
@@ -987,39 +566,28 @@ export class DaemonServer {
|
|
|
987
566
|
updateConfigFingerprint: () => {
|
|
988
567
|
this.configWatcher.updateFingerprint();
|
|
989
568
|
},
|
|
990
|
-
send: (
|
|
569
|
+
send: (msg) => this.broadcast(msg),
|
|
991
570
|
broadcast: (msg) => this.broadcast(msg),
|
|
992
571
|
clearAllSessions: () => this.clearAllSessions(),
|
|
993
|
-
getOrCreateSession: (id,
|
|
994
|
-
this.getOrCreateSession(id,
|
|
572
|
+
getOrCreateSession: (id, options?) =>
|
|
573
|
+
this.getOrCreateSession(id, options),
|
|
995
574
|
touchSession: (id) => this.evictor.touch(id),
|
|
996
575
|
heartbeatService: this._heartbeatService,
|
|
997
576
|
};
|
|
998
577
|
}
|
|
999
578
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
if (changed) this.evictSessionsForReload();
|
|
1013
|
-
this.configWatcher.lastConfigRefreshTime = now;
|
|
1014
|
-
} catch (err) {
|
|
1015
|
-
log.warn(
|
|
1016
|
-
{ err },
|
|
1017
|
-
"Failed to refresh config from secure sources before handling IPC message",
|
|
1018
|
-
);
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
handleMessage(msg, socket, this.handlerContext());
|
|
579
|
+
/** Public subset of handler context for skill management HTTP routes. */
|
|
580
|
+
getSkillContext(): SkillOperationContext {
|
|
581
|
+
return {
|
|
582
|
+
debounceTimers: this.configWatcher.timers,
|
|
583
|
+
setSuppressConfigReload: (value: boolean) => {
|
|
584
|
+
this.configWatcher.suppressConfigReload = value;
|
|
585
|
+
},
|
|
586
|
+
updateConfigFingerprint: () => {
|
|
587
|
+
this.configWatcher.updateFingerprint();
|
|
588
|
+
},
|
|
589
|
+
broadcast: (msg) => this.broadcast(msg),
|
|
590
|
+
};
|
|
1023
591
|
}
|
|
1024
592
|
|
|
1025
593
|
// ── HTTP message processing ─────────────────────────────────────────
|
|
@@ -1048,12 +616,7 @@ export class DaemonServer {
|
|
|
1048
616
|
);
|
|
1049
617
|
}
|
|
1050
618
|
|
|
1051
|
-
const session = await this.getOrCreateSession(
|
|
1052
|
-
conversationId,
|
|
1053
|
-
undefined,
|
|
1054
|
-
true,
|
|
1055
|
-
options,
|
|
1056
|
-
);
|
|
619
|
+
const session = await this.getOrCreateSession(conversationId, options);
|
|
1057
620
|
|
|
1058
621
|
if (session.isProcessing()) {
|
|
1059
622
|
throw new Error("Session is already processing a message");
|
|
@@ -1121,12 +684,21 @@ export class DaemonServer {
|
|
|
1121
684
|
|
|
1122
685
|
// Register pending interactions so channel approval interception can
|
|
1123
686
|
// find the session by requestId when confirmation/secret events fire.
|
|
1124
|
-
const
|
|
687
|
+
const registrar = makePendingInteractionRegistrar(session, conversationId);
|
|
688
|
+
const onEvent = options?.onEvent
|
|
689
|
+
? (msg: ServerMessage) => {
|
|
690
|
+
registrar(msg);
|
|
691
|
+
try {
|
|
692
|
+
options.onEvent!(msg);
|
|
693
|
+
} catch (err) {
|
|
694
|
+
log.error(
|
|
695
|
+
{ err, conversationId },
|
|
696
|
+
"onEvent callback failed; continuing agent loop",
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
: registrar;
|
|
1125
701
|
if (options?.isInteractive === true) {
|
|
1126
|
-
// Interactive HTTP paths (e.g. channel ingress) still run without an IPC
|
|
1127
|
-
// socket. Route prompter events through the registrar callback so
|
|
1128
|
-
// confirmation_request/secret_request events are tracked, and mark the
|
|
1129
|
-
// session interactive so prompt decisions are not auto-denied.
|
|
1130
702
|
session.updateClient(onEvent, false);
|
|
1131
703
|
}
|
|
1132
704
|
|
|
@@ -1136,8 +708,6 @@ export class DaemonServer {
|
|
|
1136
708
|
isUserMessage: true,
|
|
1137
709
|
})
|
|
1138
710
|
.finally(() => {
|
|
1139
|
-
// Only reset if no other caller (e.g. a real IPC client) has rebound
|
|
1140
|
-
// the session's sender while the agent loop was running.
|
|
1141
711
|
if (
|
|
1142
712
|
options?.isInteractive === true &&
|
|
1143
713
|
session.getCurrentSender() === onEvent
|
|
@@ -1192,7 +762,7 @@ export class DaemonServer {
|
|
|
1192
762
|
: {}),
|
|
1193
763
|
};
|
|
1194
764
|
const userMsg = createUserMessage(content, attachments);
|
|
1195
|
-
const persisted = await
|
|
765
|
+
const persisted = await addMessage(
|
|
1196
766
|
conversationId,
|
|
1197
767
|
"user",
|
|
1198
768
|
JSON.stringify(userMsg.content),
|
|
@@ -1202,7 +772,7 @@ export class DaemonServer {
|
|
|
1202
772
|
|
|
1203
773
|
if (serverTurnCtx) {
|
|
1204
774
|
try {
|
|
1205
|
-
|
|
775
|
+
setConversationOriginChannelIfUnset(
|
|
1206
776
|
conversationId,
|
|
1207
777
|
serverTurnCtx.userMessageChannel,
|
|
1208
778
|
);
|
|
@@ -1215,7 +785,7 @@ export class DaemonServer {
|
|
|
1215
785
|
}
|
|
1216
786
|
if (serverInterfaceCtx) {
|
|
1217
787
|
try {
|
|
1218
|
-
|
|
788
|
+
setConversationOriginInterfaceIfUnset(
|
|
1219
789
|
conversationId,
|
|
1220
790
|
serverInterfaceCtx.userMessageInterface,
|
|
1221
791
|
);
|
|
@@ -1228,7 +798,7 @@ export class DaemonServer {
|
|
|
1228
798
|
}
|
|
1229
799
|
|
|
1230
800
|
const assistantMsg = createAssistantMessage(slashResult.message);
|
|
1231
|
-
await
|
|
801
|
+
await addMessage(
|
|
1232
802
|
conversationId,
|
|
1233
803
|
"assistant",
|
|
1234
804
|
JSON.stringify(assistantMsg.content),
|
|
@@ -1259,12 +829,21 @@ export class DaemonServer {
|
|
|
1259
829
|
|
|
1260
830
|
// Register pending interactions so channel approval interception can
|
|
1261
831
|
// find the session by requestId when confirmation/secret events fire.
|
|
1262
|
-
const
|
|
832
|
+
const registrar = makePendingInteractionRegistrar(session, conversationId);
|
|
833
|
+
const onEvent = options?.onEvent
|
|
834
|
+
? (msg: ServerMessage) => {
|
|
835
|
+
registrar(msg);
|
|
836
|
+
try {
|
|
837
|
+
options.onEvent!(msg);
|
|
838
|
+
} catch (err) {
|
|
839
|
+
log.error(
|
|
840
|
+
{ err, conversationId },
|
|
841
|
+
"onEvent callback failed; continuing agent loop",
|
|
842
|
+
);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
: registrar;
|
|
1263
846
|
if (options?.isInteractive === true) {
|
|
1264
|
-
// Interactive HTTP paths (e.g. channel ingress) still run without an IPC
|
|
1265
|
-
// socket. Route prompter events through the registrar callback so
|
|
1266
|
-
// confirmation_request/secret_request events are tracked, and mark the
|
|
1267
|
-
// session interactive so prompt decisions are not auto-denied.
|
|
1268
847
|
session.updateClient(onEvent, false);
|
|
1269
848
|
}
|
|
1270
849
|
|
|
@@ -1274,8 +853,6 @@ export class DaemonServer {
|
|
|
1274
853
|
isUserMessage: true,
|
|
1275
854
|
});
|
|
1276
855
|
} finally {
|
|
1277
|
-
// Only reset if no other caller (e.g. a real IPC client) has rebound
|
|
1278
|
-
// the session's sender while the agent loop was running.
|
|
1279
856
|
if (
|
|
1280
857
|
options?.isInteractive === true &&
|
|
1281
858
|
session.getCurrentSender() === onEvent
|
|
@@ -1292,15 +869,48 @@ export class DaemonServer {
|
|
|
1292
869
|
* The handler manages busy-state checking and queueing itself.
|
|
1293
870
|
*/
|
|
1294
871
|
async getSessionForMessages(conversationId: string): Promise<Session> {
|
|
1295
|
-
return this.getOrCreateSession(conversationId
|
|
872
|
+
return this.getOrCreateSession(conversationId);
|
|
1296
873
|
}
|
|
1297
874
|
|
|
1298
875
|
/**
|
|
1299
876
|
* Look up an active session by ID without creating one.
|
|
1300
877
|
* Checks both normal sessions and computer-use sessions so the HTTP
|
|
1301
|
-
* surface-action path is consistent with
|
|
878
|
+
* surface-action path is consistent with dispatch.
|
|
1302
879
|
*/
|
|
1303
880
|
findSession(sessionId: string): Session | ComputerUseSession | undefined {
|
|
1304
881
|
return this.cuSessions.get(sessionId) ?? this.sessions.get(sessionId);
|
|
1305
882
|
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Look up an active session that owns a given surfaceId.
|
|
886
|
+
* Falls back across both normal and computer-use sessions.
|
|
887
|
+
*/
|
|
888
|
+
findSessionBySurfaceId(
|
|
889
|
+
surfaceId: string,
|
|
890
|
+
): Session | ComputerUseSession | undefined {
|
|
891
|
+
for (const s of this.cuSessions.values()) {
|
|
892
|
+
if (s.surfaceState.has(surfaceId)) return s;
|
|
893
|
+
}
|
|
894
|
+
for (const s of this.sessions.values()) {
|
|
895
|
+
if (s.surfaceState.has(surfaceId)) return s;
|
|
896
|
+
}
|
|
897
|
+
return undefined;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* Expose the handler context for use by session management HTTP routes.
|
|
902
|
+
* The context is built on-the-fly so it always reflects the current server state.
|
|
903
|
+
*/
|
|
904
|
+
getHandlerContext(): HandlerContext {
|
|
905
|
+
return this.handlerContext();
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
/** Extract sessionId from a ServerMessage if present. */
|
|
910
|
+
function extractSessionId(msg: ServerMessage): string | undefined {
|
|
911
|
+
const record = msg as unknown as Record<string, unknown>;
|
|
912
|
+
if ("sessionId" in msg && typeof record.sessionId === "string") {
|
|
913
|
+
return record.sessionId as string;
|
|
914
|
+
}
|
|
915
|
+
return undefined;
|
|
1306
916
|
}
|