vellum 0.2.0 → 0.2.2
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/README.md +15 -2
- package/bun.lock +5 -2
- package/package.json +4 -2
- package/scripts/capture-x-graphql.ts +562 -0
- package/scripts/ipc/check-swift-decoder-drift.ts +2 -1
- package/scripts/test.sh +5 -0
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +161 -34
- package/src/__tests__/account-registry.test.ts +2 -1
- package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
- package/src/__tests__/app-bundler.test.ts +12 -33
- package/src/__tests__/asset-materialize-tool.test.ts +16 -15
- package/src/__tests__/asset-search-tool.test.ts +23 -22
- package/src/__tests__/attachments-store.test.ts +56 -127
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +5 -4
- package/src/__tests__/browser-skill-endstate.test.ts +5 -8
- package/src/__tests__/call-bridge.test.ts +385 -0
- package/src/__tests__/call-constants.test.ts +40 -0
- package/src/__tests__/call-orchestrator.test.ts +454 -0
- package/src/__tests__/call-recovery.test.ts +518 -0
- package/src/__tests__/call-routes-http.test.ts +459 -0
- package/src/__tests__/call-state-machine.test.ts +143 -0
- package/src/__tests__/call-state.test.ts +133 -0
- package/src/__tests__/call-store.test.ts +691 -0
- package/src/__tests__/cli-discover.test.ts +1 -1
- package/src/__tests__/commit-message-enrichment-service.test.ts +550 -0
- package/src/__tests__/compaction.benchmark.test.ts +176 -0
- package/src/__tests__/computer-use-tools.test.ts +250 -0
- package/src/__tests__/config-schema.test.ts +348 -3
- package/src/__tests__/conflict-store.test.ts +2 -1
- package/src/__tests__/contacts-tools.test.ts +331 -0
- package/src/__tests__/conversation-store.test.ts +30 -32
- package/src/__tests__/credential-security-invariants.test.ts +4 -0
- package/src/__tests__/date-context.test.ts +373 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +129 -0
- package/src/__tests__/doordash-session.test.ts +9 -0
- package/src/__tests__/fixtures/media-reuse-fixtures.ts +3 -3
- package/src/__tests__/followup-tools.test.ts +303 -0
- package/src/__tests__/handlers-twitter-config.test.ts +718 -0
- package/src/__tests__/intent-routing.test.ts +64 -57
- package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
- package/src/__tests__/ipc-snapshot.test.ts +96 -28
- package/src/__tests__/llm-usage-store.test.ts +3 -8
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/media-reuse-story.e2e.test.ts +7 -7
- package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
- package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
- package/src/__tests__/playbook-tools.test.ts +342 -0
- package/src/__tests__/profile-compiler.test.ts +2 -1
- package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
- package/src/__tests__/recurrence-engine-rruleset.test.ts +78 -0
- package/src/__tests__/recurrence-engine.test.ts +69 -0
- package/src/__tests__/recurrence-types.test.ts +71 -0
- package/src/__tests__/registry.test.ts +17 -10
- package/src/__tests__/relay-server.test.ts +633 -0
- package/src/__tests__/reminder-store.test.ts +6 -3
- package/src/__tests__/reminder.test.ts +43 -77
- package/src/__tests__/run-orchestrator-assistant-events.test.ts +222 -0
- package/src/__tests__/run-orchestrator.test.ts +7 -7
- package/src/__tests__/runtime-attachment-metadata.test.ts +19 -20
- package/src/__tests__/runtime-runs-http.test.ts +5 -23
- package/src/__tests__/runtime-runs.test.ts +11 -11
- package/src/__tests__/schedule-store.test.ts +482 -0
- package/src/__tests__/schedule-tools.test.ts +700 -0
- package/src/__tests__/scheduler-recurrence.test.ts +329 -0
- package/src/__tests__/server-history-render.test.ts +14 -13
- package/src/__tests__/session-error.test.ts +28 -0
- package/src/__tests__/session-init.benchmark.test.ts +462 -0
- package/src/__tests__/session-queue.test.ts +89 -16
- package/src/__tests__/session-runtime-assembly.test.ts +161 -0
- package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
- package/src/__tests__/signup-e2e.test.ts +2 -1
- package/src/__tests__/skill-projection.benchmark.test.ts +328 -0
- package/src/__tests__/skill-script-runner.test.ts +159 -0
- package/src/__tests__/speaker-identification.test.ts +52 -0
- package/src/__tests__/subagent-manager-notify.test.ts +42 -10
- package/src/__tests__/subagent-tools.test.ts +141 -41
- package/src/__tests__/task-compiler.test.ts +2 -1
- package/src/__tests__/task-runner.test.ts +2 -1
- package/src/__tests__/task-scheduler.test.ts +2 -1
- package/src/__tests__/task-tools.test.ts +49 -56
- package/src/__tests__/tool-audit-listener.test.ts +1 -0
- package/src/__tests__/tool-domain-event-publisher.test.ts +2 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
- package/src/__tests__/tool-executor.test.ts +13 -17
- package/src/__tests__/turn-commit.test.ts +273 -2
- package/src/__tests__/twilio-provider.test.ts +143 -0
- package/src/__tests__/twilio-routes.test.ts +789 -0
- package/src/__tests__/twitter-auth-handler.test.ts +581 -0
- package/src/__tests__/view-image-tool.test.ts +217 -0
- package/src/__tests__/workspace-git-service.test.ts +403 -0
- package/src/__tests__/workspace-heartbeat-service.test.ts +141 -2
- package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
- package/src/bundler/app-bundler.ts +35 -14
- package/src/calls/call-bridge.ts +95 -0
- package/src/calls/call-constants.ts +48 -0
- package/src/calls/call-domain.ts +276 -0
- package/src/calls/call-orchestrator.ts +390 -0
- package/src/calls/call-recovery.ts +207 -0
- package/src/calls/call-state-machine.ts +68 -0
- package/src/calls/call-state.ts +64 -0
- package/src/calls/call-store.ts +416 -0
- package/src/calls/relay-server.ts +335 -0
- package/src/calls/speaker-identification.ts +213 -0
- package/src/calls/twilio-config.ts +34 -0
- package/src/calls/twilio-provider.ts +173 -0
- package/src/calls/twilio-routes.ts +250 -0
- package/src/calls/types.ts +37 -0
- package/src/calls/voice-provider.ts +14 -0
- package/src/cli/config-commands.ts +334 -0
- package/src/cli/core-commands.ts +776 -0
- package/src/cli/doordash.ts +256 -25
- package/src/cli/ipc-client.ts +82 -0
- package/src/cli/map.ts +246 -0
- package/src/cli/twitter.ts +575 -0
- package/src/cli.ts +7 -5
- package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
- package/src/commands/cc-command-registry.ts +209 -0
- package/src/config/bundled-skills/contacts/SKILL.md +39 -0
- package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +9 -0
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +9 -0
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +9 -0
- package/src/config/bundled-skills/document/SKILL.md +18 -0
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
- package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
- package/src/config/bundled-skills/doordash/SKILL.md +163 -0
- package/src/config/bundled-skills/followups/SKILL.md +32 -0
- package/src/config/bundled-skills/followups/TOOLS.json +100 -0
- package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
- package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
- package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +2 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -24
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -1
- package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
- package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +9 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +9 -0
- package/src/config/bundled-skills/reminder/SKILL.md +20 -0
- package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
- package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
- package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
- package/src/config/bundled-skills/schedule/SKILL.md +74 -0
- package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
- package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
- package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
- package/src/config/bundled-skills/subagent/SKILL.md +25 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
- package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
- package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
- package/src/config/bundled-skills/tasks/SKILL.md +28 -0
- package/src/config/bundled-skills/tasks/TOOLS.json +256 -0
- package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
- package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
- package/src/config/bundled-skills/twitter/SKILL.md +134 -0
- package/src/config/bundled-skills/watcher/SKILL.md +27 -0
- package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
- package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
- package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
- package/src/config/defaults.ts +44 -0
- package/src/config/loader.ts +4 -1
- package/src/config/schema.ts +218 -1
- package/src/config/system-prompt.ts +100 -6
- package/src/config/templates/IDENTITY.md +7 -0
- package/src/config/types.ts +5 -0
- package/src/contacts/contact-store.ts +4 -4
- package/src/daemon/assistant-attachments.ts +10 -0
- package/src/daemon/classifier.ts +3 -1
- package/src/daemon/computer-use-session.ts +3 -1
- package/src/daemon/date-context.ts +136 -0
- package/src/daemon/handlers/apps.ts +16 -1
- package/src/daemon/handlers/browser.ts +54 -0
- package/src/daemon/handlers/computer-use.ts +7 -1
- package/src/daemon/handlers/config.ts +192 -4
- package/src/daemon/handlers/diagnostics.ts +5 -1
- package/src/daemon/handlers/documents.ts +18 -29
- package/src/daemon/handlers/home-base.ts +5 -1
- package/src/daemon/handlers/index.ts +40 -271
- package/src/daemon/handlers/misc.ts +9 -1
- package/src/daemon/handlers/publish.ts +6 -1
- package/src/daemon/handlers/sessions.ts +65 -12
- package/src/daemon/handlers/shared.ts +36 -1
- package/src/daemon/handlers/signing.ts +37 -0
- package/src/daemon/handlers/skills.ts +20 -6
- package/src/daemon/handlers/subagents.ts +8 -3
- package/src/daemon/handlers/twitter-auth.ts +169 -0
- package/src/daemon/handlers/work-items.ts +495 -39
- package/src/daemon/ipc-contract-inventory.json +40 -4
- package/src/daemon/ipc-contract.ts +185 -37
- package/src/daemon/ipc-protocol.ts +7 -2
- package/src/daemon/lifecycle.ts +48 -5
- package/src/daemon/main.ts +10 -4
- package/src/daemon/ride-shotgun-handler.ts +74 -10
- package/src/daemon/server.ts +144 -29
- package/src/daemon/session-agent-loop.ts +887 -0
- package/src/daemon/session-attachments.ts +28 -5
- package/src/daemon/session-error.ts +24 -3
- package/src/daemon/session-lifecycle.ts +147 -0
- package/src/daemon/session-media-retry.ts +147 -0
- package/src/daemon/session-messaging.ts +145 -0
- package/src/daemon/session-notifiers.ts +164 -0
- package/src/daemon/session-process.ts +2 -2
- package/src/daemon/session-queue-manager.ts +1 -0
- package/src/daemon/session-runtime-assembly.ts +52 -0
- package/src/daemon/session-skill-tools.ts +124 -5
- package/src/daemon/session-slash.ts +3 -0
- package/src/daemon/session-surfaces.ts +77 -2
- package/src/daemon/session-tool-setup.ts +222 -2
- package/src/daemon/session-usage.ts +0 -2
- package/src/daemon/session.ts +114 -1365
- package/src/daemon/video-thumbnail.ts +60 -0
- package/src/doordash/client.ts +121 -27
- package/src/doordash/queries.ts +1 -2
- package/src/export/formatter.ts +3 -1
- package/src/followups/followup-store.ts +4 -2
- package/src/followups/types.ts +6 -0
- package/src/hooks/templates.ts +1 -1
- package/src/index.ts +32 -1151
- package/src/media/gemini-image-service.ts +1 -1
- package/src/memory/attachments-store.ts +28 -83
- package/src/memory/channel-delivery-store.ts +7 -21
- package/src/memory/clarification-resolver.ts +6 -5
- package/src/memory/contradiction-checker.ts +3 -2
- package/src/memory/conversation-key-store.ts +10 -29
- package/src/memory/conversation-store.ts +2 -1
- package/src/memory/db.ts +362 -2
- package/src/memory/entity-extractor.ts +6 -3
- package/src/memory/items-extractor.ts +5 -4
- package/src/memory/jobs-store.ts +3 -2
- package/src/memory/llm-usage-store.ts +1 -2
- package/src/memory/runs-store.ts +1 -2
- package/src/memory/schema.ts +65 -2
- package/src/messaging/style-analyzer.ts +3 -2
- package/src/messaging/thread-summarizer.ts +8 -12
- package/src/messaging/triage-engine.ts +4 -2
- package/src/providers/openrouter/client.ts +20 -0
- package/src/providers/registry.ts +8 -0
- package/src/runtime/http-server.ts +277 -25
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/routes/attachment-routes.ts +5 -6
- package/src/runtime/routes/call-routes.ts +140 -0
- package/src/runtime/routes/channel-routes.ts +12 -19
- package/src/runtime/routes/conversation-routes.ts +5 -9
- package/src/runtime/routes/run-routes.ts +4 -8
- package/src/runtime/run-orchestrator.ts +39 -6
- package/src/schedule/recurrence-engine.ts +138 -0
- package/src/schedule/recurrence-types.ts +67 -0
- package/src/schedule/schedule-store.ts +102 -57
- package/src/schedule/scheduler.ts +9 -6
- package/src/security/oauth2.ts +29 -4
- package/src/security/secret-allowlist.ts +46 -0
- package/src/skills/clawhub.ts +1 -1
- package/src/subagent/manager.ts +40 -8
- package/src/swarm/backend-claude-code.ts +64 -9
- package/src/swarm/worker-prompts.ts +2 -1
- package/src/tasks/SPEC.md +34 -28
- package/src/tasks/ephemeral-permissions.ts +16 -7
- package/src/tasks/task-compiler.ts +5 -4
- package/src/tasks/task-runner.ts +10 -5
- package/src/tasks/task-scheduler.ts +1 -1
- package/src/tasks/tool-sanitizer.ts +36 -0
- package/src/tools/assets/search.ts +4 -4
- package/src/tools/browser/api-map.ts +220 -0
- package/src/tools/browser/auto-navigate.ts +270 -0
- package/src/tools/browser/browser-execution.ts +2 -1
- package/src/tools/browser/browser-manager.ts +2 -2
- package/src/tools/browser/network-recorder.ts +5 -4
- package/src/tools/browser/x-auto-navigate.ts +207 -0
- package/src/tools/calls/call-end.ts +67 -0
- package/src/tools/calls/call-start.ts +73 -0
- package/src/tools/calls/call-status.ts +81 -0
- package/src/tools/claude-code/claude-code.ts +77 -11
- package/src/tools/contacts/contact-merge.ts +46 -78
- package/src/tools/contacts/contact-search.ts +35 -79
- package/src/tools/contacts/contact-upsert.ts +35 -108
- package/src/tools/credentials/vault.ts +21 -5
- package/src/tools/document/document-tool.ts +71 -144
- package/src/tools/executor.ts +129 -10
- package/src/tools/followups/followup_create.ts +46 -88
- package/src/tools/followups/followup_list.ts +34 -74
- package/src/tools/followups/followup_resolve.ts +31 -66
- package/src/tools/host-terminal/cli-discover.ts +2 -1
- package/src/tools/host-terminal/host-shell.ts +10 -0
- package/src/tools/memory/handlers.ts +5 -4
- package/src/tools/network/__tests__/web-search.test.ts +427 -0
- package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
- package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
- package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
- package/src/tools/network/web-fetch.ts +18 -6
- package/src/tools/playbooks/index.ts +4 -5
- package/src/tools/playbooks/playbook-create.ts +3 -47
- package/src/tools/playbooks/playbook-delete.ts +1 -25
- package/src/tools/playbooks/playbook-list.ts +1 -28
- package/src/tools/playbooks/playbook-update.ts +3 -51
- package/src/tools/registry.ts +2 -4
- package/src/tools/reminder/reminder.ts +5 -78
- package/src/tools/schedule/create.ts +69 -74
- package/src/tools/schedule/delete.ts +21 -47
- package/src/tools/schedule/list.ts +55 -74
- package/src/tools/schedule/update.ts +77 -84
- package/src/tools/subagent/abort.ts +29 -58
- package/src/tools/subagent/message.ts +30 -63
- package/src/tools/subagent/read.ts +53 -84
- package/src/tools/subagent/spawn.ts +43 -82
- package/src/tools/subagent/status.ts +42 -71
- package/src/tools/swarm/delegate.ts +2 -1
- package/src/tools/tasks/index.ts +8 -6
- package/src/tools/tasks/task-delete.ts +69 -56
- package/src/tools/tasks/task-list.ts +31 -52
- package/src/tools/tasks/task-run.ts +74 -102
- package/src/tools/tasks/task-save.ts +33 -65
- package/src/tools/tasks/work-item-enqueue.ts +192 -134
- package/src/tools/tasks/work-item-list.ts +33 -78
- package/src/tools/tasks/work-item-remove.ts +60 -0
- package/src/tools/tasks/work-item-update.ts +114 -0
- package/src/tools/terminal/backends/native.ts +3 -1
- package/src/tools/tool-manifest.ts +20 -74
- package/src/tools/types.ts +6 -0
- package/src/tools/ui-surface/definitions.ts +6 -1
- package/src/tools/watch/screen-watch.ts +3 -1
- package/src/tools/watcher/create.ts +52 -98
- package/src/tools/watcher/delete.ts +20 -46
- package/src/tools/watcher/digest.ts +36 -70
- package/src/tools/watcher/list.ts +49 -79
- package/src/tools/watcher/update.ts +45 -91
- package/src/twitter/client.ts +690 -0
- package/src/twitter/session.ts +91 -0
- package/src/usage/types.ts +0 -1
- package/src/util/truncate.ts +6 -0
- package/src/watcher/providers/slack.ts +2 -1
- package/src/watcher/watcher-store.ts +3 -2
- package/src/work-items/work-item-store.ts +236 -2
- package/src/workspace/commit-message-enrichment-service.ts +284 -0
- package/src/workspace/commit-message-provider.ts +95 -0
- package/src/workspace/git-service.ts +272 -52
- package/src/workspace/heartbeat-service.ts +70 -13
- package/src/workspace/provider-commit-message-generator.ts +242 -0
- package/src/workspace/turn-commit.ts +100 -51
- package/src/tools/contacts/index.ts +0 -4
- package/src/tools/document/index.ts +0 -5
- package/src/tools/followups/index.ts +0 -3
- package/src/tools/subagent/index.ts +0 -5
- /package/src/__tests__/{memory-context-benchmark.test.ts → memory-context-benchmark.benchmark.test.ts} +0 -0
|
@@ -3,114 +3,23 @@ import type { ClientMessage } from '../ipc-protocol.js';
|
|
|
3
3
|
import { handleRideShotgunStart, handleRideShotgunStop } from '../ride-shotgun-handler.js';
|
|
4
4
|
import { handleWatchObservation } from '../watch-handler.js';
|
|
5
5
|
import { handleOpenBundle } from './open-bundle-handler.js';
|
|
6
|
-
import { log,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
handleSandboxSet,
|
|
24
|
-
} from './sessions.js';
|
|
25
|
-
|
|
26
|
-
import {
|
|
27
|
-
handleSkillsList,
|
|
28
|
-
handleSkillDetail,
|
|
29
|
-
handleSkillsEnable,
|
|
30
|
-
handleSkillsDisable,
|
|
31
|
-
handleSkillsConfigure,
|
|
32
|
-
handleSkillsInstall,
|
|
33
|
-
handleSkillsUninstall,
|
|
34
|
-
handleSkillsUpdate,
|
|
35
|
-
handleSkillsCheckUpdates,
|
|
36
|
-
handleSkillsSearch,
|
|
37
|
-
handleSkillsInspect,
|
|
38
|
-
} from './skills.js';
|
|
39
|
-
|
|
40
|
-
import {
|
|
41
|
-
handleAppDataRequest,
|
|
42
|
-
handleAppOpenRequest,
|
|
43
|
-
handleAppUpdatePreview,
|
|
44
|
-
handleAppPreview,
|
|
45
|
-
handleAppsList,
|
|
46
|
-
handleSharedAppsList,
|
|
47
|
-
handleSharedAppDelete,
|
|
48
|
-
handleForkSharedApp,
|
|
49
|
-
handleShareAppCloud,
|
|
50
|
-
handleBundleApp,
|
|
51
|
-
handleGalleryList,
|
|
52
|
-
handleGalleryInstall,
|
|
53
|
-
} from './apps.js';
|
|
54
|
-
|
|
55
|
-
import {
|
|
56
|
-
handleModelGet,
|
|
57
|
-
handleModelSet,
|
|
58
|
-
handleAddTrustRule,
|
|
59
|
-
handleTrustRulesList,
|
|
60
|
-
handleRemoveTrustRule,
|
|
61
|
-
handleUpdateTrustRule,
|
|
62
|
-
handleAcceptStarterBundle,
|
|
63
|
-
handleSchedulesList,
|
|
64
|
-
handleScheduleToggle,
|
|
65
|
-
handleScheduleRemove,
|
|
66
|
-
handleRemindersList,
|
|
67
|
-
handleReminderCancel,
|
|
68
|
-
handleShareToSlack,
|
|
69
|
-
handleSlackWebhookConfig,
|
|
70
|
-
handleVercelApiConfig,
|
|
71
|
-
handleEnvVarsRequest,
|
|
72
|
-
} from './config.js';
|
|
73
|
-
|
|
74
|
-
import {
|
|
75
|
-
handleCuSessionCreate,
|
|
76
|
-
handleCuSessionAbort,
|
|
77
|
-
handleCuObservation,
|
|
78
|
-
} from './computer-use.js';
|
|
79
|
-
|
|
80
|
-
import {
|
|
81
|
-
handlePublishPage,
|
|
82
|
-
handleUnpublishPage,
|
|
83
|
-
} from './publish.js';
|
|
84
|
-
import { handleHomeBaseGet } from './home-base.js';
|
|
85
|
-
import { handleDiagnosticsExport } from './diagnostics.js';
|
|
86
|
-
|
|
87
|
-
import {
|
|
88
|
-
handleTaskSubmit,
|
|
89
|
-
handleSuggestionRequest,
|
|
90
|
-
handleLinkOpenRequest,
|
|
91
|
-
handleIpcBlobProbe,
|
|
92
|
-
} from './misc.js';
|
|
93
|
-
|
|
94
|
-
import {
|
|
95
|
-
handleDocumentSave,
|
|
96
|
-
handleDocumentLoad,
|
|
97
|
-
handleDocumentList,
|
|
98
|
-
} from './documents.js';
|
|
99
|
-
|
|
100
|
-
import {
|
|
101
|
-
handleWorkItemsList,
|
|
102
|
-
handleWorkItemGet,
|
|
103
|
-
handleWorkItemCreate,
|
|
104
|
-
handleWorkItemUpdate,
|
|
105
|
-
handleWorkItemComplete,
|
|
106
|
-
handleWorkItemRunTask,
|
|
107
|
-
} from './work-items.js';
|
|
108
|
-
|
|
109
|
-
import {
|
|
110
|
-
handleSubagentAbort,
|
|
111
|
-
handleSubagentStatus,
|
|
112
|
-
handleSubagentMessage,
|
|
113
|
-
} from './subagents.js';
|
|
6
|
+
import { log, defineHandlers, type HandlerContext, type DispatchMap } from './shared.js';
|
|
7
|
+
|
|
8
|
+
import { sessionHandlers } from './sessions.js';
|
|
9
|
+
import { skillHandlers } from './skills.js';
|
|
10
|
+
import { appHandlers } from './apps.js';
|
|
11
|
+
import { configHandlers } from './config.js';
|
|
12
|
+
import { computerUseHandlers } from './computer-use.js';
|
|
13
|
+
import { publishHandlers } from './publish.js';
|
|
14
|
+
import { homeBaseHandlers } from './home-base.js';
|
|
15
|
+
import { diagnosticsHandlers } from './diagnostics.js';
|
|
16
|
+
import { miscHandlers } from './misc.js';
|
|
17
|
+
import { documentHandlers } from './documents.js';
|
|
18
|
+
import { workItemHandlers } from './work-items.js';
|
|
19
|
+
import { subagentHandlers } from './subagents.js';
|
|
20
|
+
import { browserHandlers } from './browser.js';
|
|
21
|
+
import { signingHandlers } from './signing.js';
|
|
22
|
+
import { twitterAuthHandlers } from './twitter-auth.js';
|
|
114
23
|
|
|
115
24
|
// Re-export types and utilities for backwards compatibility
|
|
116
25
|
export type {
|
|
@@ -129,105 +38,13 @@ export {
|
|
|
129
38
|
|
|
130
39
|
// ─── Typed dispatch ──────────────────────────────────────────────────────────
|
|
131
40
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
type DispatchableType = Exclude<MessageType, 'auth'>;
|
|
135
|
-
type MessageOfType<T extends MessageType> = Extract<ClientMessage, { type: T }>;
|
|
136
|
-
type MessageHandler<T extends MessageType> = (
|
|
137
|
-
msg: MessageOfType<T>,
|
|
138
|
-
socket: net.Socket,
|
|
139
|
-
ctx: HandlerContext,
|
|
140
|
-
) => void | Promise<void>;
|
|
141
|
-
type DispatchMap = { [T in DispatchableType]: MessageHandler<T> };
|
|
142
|
-
|
|
143
|
-
const handlers: DispatchMap = {
|
|
144
|
-
user_message: handleUserMessage,
|
|
145
|
-
confirmation_response: handleConfirmationResponse,
|
|
146
|
-
secret_response: handleSecretResponse,
|
|
147
|
-
session_list: (_msg, socket, ctx) => handleSessionList(socket, ctx),
|
|
148
|
-
session_create: handleSessionCreate,
|
|
149
|
-
sessions_clear: (_msg, socket, ctx) => handleSessionsClear(socket, ctx),
|
|
150
|
-
session_switch: handleSessionSwitch,
|
|
151
|
-
cancel: handleCancel,
|
|
152
|
-
delete_queued_message: handleDeleteQueuedMessage,
|
|
153
|
-
model_get: (_msg, socket, ctx) => handleModelGet(socket, ctx),
|
|
154
|
-
model_set: handleModelSet,
|
|
155
|
-
history_request: handleHistoryRequest,
|
|
156
|
-
undo: handleUndo,
|
|
157
|
-
regenerate: handleRegenerate,
|
|
158
|
-
usage_request: handleUsageRequest,
|
|
159
|
-
sandbox_set: handleSandboxSet,
|
|
160
|
-
cu_session_create: handleCuSessionCreate,
|
|
161
|
-
cu_session_abort: handleCuSessionAbort,
|
|
162
|
-
cu_observation: handleCuObservation,
|
|
41
|
+
// Inline handlers for messages not owned by any feature group
|
|
42
|
+
const inlineHandlers = defineHandlers({
|
|
163
43
|
ride_shotgun_start: handleRideShotgunStart,
|
|
164
44
|
ride_shotgun_stop: handleRideShotgunStop,
|
|
165
45
|
watch_observation: handleWatchObservation,
|
|
166
|
-
task_submit: handleTaskSubmit,
|
|
167
|
-
app_data_request: handleAppDataRequest,
|
|
168
|
-
skills_list: (_msg, socket, ctx) => handleSkillsList(socket, ctx),
|
|
169
|
-
skill_detail: handleSkillDetail,
|
|
170
|
-
skills_enable: handleSkillsEnable,
|
|
171
|
-
skills_disable: handleSkillsDisable,
|
|
172
|
-
skills_configure: handleSkillsConfigure,
|
|
173
|
-
skills_install: handleSkillsInstall,
|
|
174
|
-
skills_uninstall: handleSkillsUninstall,
|
|
175
|
-
skills_update: handleSkillsUpdate,
|
|
176
|
-
skills_check_updates: handleSkillsCheckUpdates,
|
|
177
|
-
skills_search: handleSkillsSearch,
|
|
178
|
-
skills_inspect: handleSkillsInspect,
|
|
179
|
-
suggestion_request: handleSuggestionRequest,
|
|
180
|
-
add_trust_rule: handleAddTrustRule,
|
|
181
|
-
trust_rules_list: (_msg, socket, ctx) => handleTrustRulesList(socket, ctx),
|
|
182
|
-
remove_trust_rule: handleRemoveTrustRule,
|
|
183
|
-
update_trust_rule: handleUpdateTrustRule,
|
|
184
|
-
accept_starter_bundle: (_msg, socket, ctx) => handleAcceptStarterBundle(socket, ctx),
|
|
185
|
-
schedules_list: (_msg, socket, ctx) => handleSchedulesList(socket, ctx),
|
|
186
|
-
schedule_toggle: handleScheduleToggle,
|
|
187
|
-
schedule_remove: handleScheduleRemove,
|
|
188
|
-
reminders_list: (_msg, socket, ctx) => handleRemindersList(socket, ctx),
|
|
189
|
-
reminder_cancel: handleReminderCancel,
|
|
190
|
-
share_app_cloud: handleShareAppCloud,
|
|
191
|
-
bundle_app: handleBundleApp,
|
|
192
46
|
open_bundle: handleOpenBundle,
|
|
193
|
-
|
|
194
|
-
app_update_preview: handleAppUpdatePreview,
|
|
195
|
-
apps_list: (_msg, socket, ctx) => handleAppsList(socket, ctx),
|
|
196
|
-
app_preview_request: handleAppPreview,
|
|
197
|
-
home_base_get: handleHomeBaseGet,
|
|
198
|
-
shared_apps_list: (_msg, socket, ctx) => handleSharedAppsList(socket, ctx),
|
|
199
|
-
shared_app_delete: handleSharedAppDelete,
|
|
200
|
-
fork_shared_app: handleForkSharedApp,
|
|
201
|
-
sign_bundle_payload_response: (msg) => {
|
|
202
|
-
const pending = pendingSignBundlePayload.get(msg.requestId);
|
|
203
|
-
if (pending) {
|
|
204
|
-
clearTimeout(pending.timer);
|
|
205
|
-
pendingSignBundlePayload.delete(msg.requestId);
|
|
206
|
-
pending.resolve({ signature: msg.signature, keyId: msg.keyId, publicKey: msg.publicKey });
|
|
207
|
-
} else {
|
|
208
|
-
log.warn({ requestId: msg.requestId }, 'Received sign_bundle_payload_response with no pending request');
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
get_signing_identity_response: (msg) => {
|
|
212
|
-
const pending = pendingSigningIdentity.get(msg.requestId);
|
|
213
|
-
if (pending) {
|
|
214
|
-
clearTimeout(pending.timer);
|
|
215
|
-
pendingSigningIdentity.delete(msg.requestId);
|
|
216
|
-
pending.resolve({ keyId: msg.keyId, publicKey: msg.publicKey });
|
|
217
|
-
} else {
|
|
218
|
-
log.warn({ requestId: msg.requestId }, 'Received get_signing_identity_response with no pending request');
|
|
219
|
-
}
|
|
220
|
-
},
|
|
221
|
-
gallery_list: (_msg, socket, ctx) => handleGalleryList(socket, ctx),
|
|
222
|
-
gallery_install: handleGalleryInstall,
|
|
223
|
-
share_to_slack: handleShareToSlack,
|
|
224
|
-
slack_webhook_config: handleSlackWebhookConfig,
|
|
225
|
-
vercel_api_config: handleVercelApiConfig,
|
|
226
|
-
publish_page: handlePublishPage,
|
|
227
|
-
unpublish_page: handleUnpublishPage,
|
|
228
|
-
ping: (_msg, socket, ctx) => { ctx.send(socket, { type: 'pong' }); },
|
|
229
|
-
link_open_request: handleLinkOpenRequest,
|
|
230
|
-
ipc_blob_probe: handleIpcBlobProbe,
|
|
47
|
+
|
|
231
48
|
ui_surface_action: (msg, _socket, ctx) => {
|
|
232
49
|
const cuSession = ctx.cuSessions.get(msg.sessionId);
|
|
233
50
|
if (cuSession) {
|
|
@@ -251,15 +68,6 @@ const handlers: DispatchMap = {
|
|
|
251
68
|
}
|
|
252
69
|
log.warn({ sessionId: msg.sessionId, surfaceId: msg.surfaceId }, 'No session found for surface undo');
|
|
253
70
|
},
|
|
254
|
-
diagnostics_export_request: handleDiagnosticsExport,
|
|
255
|
-
env_vars_request: (_msg, socket, ctx) => handleEnvVarsRequest(socket, ctx),
|
|
256
|
-
document_save: handleDocumentSave,
|
|
257
|
-
document_load: handleDocumentLoad,
|
|
258
|
-
document_list: handleDocumentList,
|
|
259
|
-
|
|
260
|
-
browser_cdp_response: (msg) => {
|
|
261
|
-
browserManager.resolveCDPResponse(msg.sessionId, msg.success, msg.declined);
|
|
262
|
-
},
|
|
263
71
|
|
|
264
72
|
// Stub handlers: the integration registry was removed but the Swift client
|
|
265
73
|
// still sends these messages. Return safe no-op responses so the client
|
|
@@ -275,66 +83,27 @@ const handlers: DispatchMap = {
|
|
|
275
83
|
error: 'Please use chat to connect integrations.',
|
|
276
84
|
});
|
|
277
85
|
},
|
|
278
|
-
|
|
279
|
-
browser_user_click: async (msg) => {
|
|
280
|
-
try {
|
|
281
|
-
const page = await browserManager.getOrCreateSessionPage(msg.sessionId);
|
|
282
|
-
const viewport = await page.evaluate('(() => ({ vw: window.innerWidth, vh: window.innerHeight }))()') as { vw: number; vh: number };
|
|
283
|
-
const scale = Math.min(1280 / viewport.vw, 960 / viewport.vh);
|
|
284
|
-
const pageX = msg.x / scale;
|
|
285
|
-
const pageY = msg.y / scale;
|
|
286
|
-
const options: Record<string, unknown> = {};
|
|
287
|
-
if (msg.button === 'right') options.button = 'right';
|
|
288
|
-
if (msg.doubleClick) options.clickCount = 2;
|
|
289
|
-
await page.mouse.click(pageX, pageY, options);
|
|
290
|
-
} catch (err) {
|
|
291
|
-
log.warn({ err, sessionId: msg.sessionId }, 'Failed to forward user click');
|
|
292
|
-
}
|
|
293
|
-
},
|
|
294
|
-
|
|
295
|
-
browser_user_scroll: async (msg) => {
|
|
296
|
-
try {
|
|
297
|
-
const page = await browserManager.getOrCreateSessionPage(msg.sessionId);
|
|
298
|
-
await page.mouse.wheel(msg.deltaX, msg.deltaY);
|
|
299
|
-
} catch (err) {
|
|
300
|
-
log.warn({ err, sessionId: msg.sessionId }, 'Failed to forward user scroll');
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
|
|
304
|
-
browser_user_keypress: async (msg) => {
|
|
305
|
-
try {
|
|
306
|
-
const page = await browserManager.getOrCreateSessionPage(msg.sessionId);
|
|
307
|
-
const combo = msg.modifiers?.length ? [...msg.modifiers, msg.key].join('+') : msg.key;
|
|
308
|
-
await page.keyboard.press(combo);
|
|
309
|
-
} catch (err) {
|
|
310
|
-
log.warn({ err, sessionId: msg.sessionId }, 'Failed to forward user keypress');
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
|
|
314
|
-
browser_interactive_mode: (msg, socket, ctx) => {
|
|
315
|
-
log.info({ sessionId: msg.sessionId, enabled: msg.enabled }, 'Interactive mode toggled');
|
|
316
|
-
browserManager.setInteractiveMode(msg.sessionId, msg.enabled);
|
|
317
|
-
ctx.send(socket, {
|
|
318
|
-
type: 'browser_interactive_mode_changed',
|
|
319
|
-
sessionId: msg.sessionId,
|
|
320
|
-
surfaceId: msg.surfaceId,
|
|
321
|
-
enabled: msg.enabled,
|
|
322
|
-
});
|
|
323
|
-
},
|
|
324
|
-
|
|
325
86
|
integration_disconnect: () => { /* no-op — integration registry removed */ },
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const handlers = {
|
|
90
|
+
...sessionHandlers,
|
|
91
|
+
...skillHandlers,
|
|
92
|
+
...appHandlers,
|
|
93
|
+
...configHandlers,
|
|
94
|
+
...computerUseHandlers,
|
|
95
|
+
...publishHandlers,
|
|
96
|
+
...homeBaseHandlers,
|
|
97
|
+
...diagnosticsHandlers,
|
|
98
|
+
...miscHandlers,
|
|
99
|
+
...documentHandlers,
|
|
100
|
+
...workItemHandlers,
|
|
101
|
+
...subagentHandlers,
|
|
102
|
+
...browserHandlers,
|
|
103
|
+
...signingHandlers,
|
|
104
|
+
...twitterAuthHandlers,
|
|
105
|
+
...inlineHandlers,
|
|
106
|
+
} satisfies DispatchMap;
|
|
338
107
|
|
|
339
108
|
export function handleMessage(
|
|
340
109
|
msg: ClientMessage,
|
|
@@ -18,7 +18,7 @@ import type {
|
|
|
18
18
|
IpcBlobProbe,
|
|
19
19
|
CuSessionCreate,
|
|
20
20
|
} from '../ipc-protocol.js';
|
|
21
|
-
import { log, wireEscalationHandler, renderHistoryContent, type HandlerContext } from './shared.js';
|
|
21
|
+
import { log, wireEscalationHandler, renderHistoryContent, defineHandlers, type HandlerContext } from './shared.js';
|
|
22
22
|
import { handleCuSessionCreate } from './computer-use.js';
|
|
23
23
|
|
|
24
24
|
// ─── Task submit handler ────────────────────────────────────────────────────
|
|
@@ -321,3 +321,11 @@ export function handleIpcBlobProbe(
|
|
|
321
321
|
observedNonceSha256: observedHash,
|
|
322
322
|
});
|
|
323
323
|
}
|
|
324
|
+
|
|
325
|
+
export const miscHandlers = defineHandlers({
|
|
326
|
+
task_submit: handleTaskSubmit,
|
|
327
|
+
suggestion_request: handleSuggestionRequest,
|
|
328
|
+
link_open_request: handleLinkOpenRequest,
|
|
329
|
+
ipc_blob_probe: handleIpcBlobProbe,
|
|
330
|
+
ping: (_msg, socket, ctx) => { ctx.send(socket, { type: 'pong' }); },
|
|
331
|
+
});
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
PublishPageRequest,
|
|
11
11
|
UnpublishPageRequest,
|
|
12
12
|
} from '../ipc-protocol.js';
|
|
13
|
-
import { log, requestSecretStandalone, type HandlerContext } from './shared.js';
|
|
13
|
+
import { log, requestSecretStandalone, defineHandlers, type HandlerContext } from './shared.js';
|
|
14
14
|
|
|
15
15
|
export async function handlePublishPage(
|
|
16
16
|
msg: PublishPageRequest,
|
|
@@ -180,3 +180,8 @@ export async function handleUnpublishPage(
|
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
+
|
|
184
|
+
export const publishHandlers = defineHandlers({
|
|
185
|
+
publish_page: handlePublishPage,
|
|
186
|
+
unpublish_page: handleUnpublishPage,
|
|
187
|
+
});
|
|
@@ -3,7 +3,8 @@ import { v4 as uuid } from 'uuid';
|
|
|
3
3
|
import * as conversationStore from '../../memory/conversation-store.js';
|
|
4
4
|
import { checkIngressForSecrets } from '../../security/secret-ingress.js';
|
|
5
5
|
import { classifySessionError, buildSessionErrorMessage } from '../session-error.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getAttachmentsForMessage, setAttachmentThumbnail } from '../../memory/attachments-store.js';
|
|
7
|
+
import { generateVideoThumbnail } from '../video-thumbnail.js';
|
|
7
8
|
import type { UserMessageAttachment } from '../ipc-contract.js';
|
|
8
9
|
import { normalizeThreadType } from '../ipc-protocol.js';
|
|
9
10
|
import type {
|
|
@@ -30,10 +31,12 @@ import {
|
|
|
30
31
|
mergeToolResults,
|
|
31
32
|
pendingStandaloneSecrets,
|
|
32
33
|
type HandlerContext,
|
|
34
|
+
defineHandlers,
|
|
33
35
|
type HistoryToolCall,
|
|
34
36
|
type HistorySurface,
|
|
35
37
|
type ParsedHistoryMessage,
|
|
36
38
|
} from './shared.js';
|
|
39
|
+
import { truncate } from '../../util/truncate.js';
|
|
37
40
|
|
|
38
41
|
export async function handleUserMessage(
|
|
39
42
|
msg: UserMessage,
|
|
@@ -271,14 +274,27 @@ export async function handleSessionSwitch(
|
|
|
271
274
|
ctx.send(socket, { type: 'error', message: `Session ${msg.sessionId} not found` });
|
|
272
275
|
return;
|
|
273
276
|
}
|
|
277
|
+
|
|
278
|
+
// If the target session is headless-locked (actively executing a task run),
|
|
279
|
+
// skip rebinding the socket so tool confirmations stay suppressed.
|
|
280
|
+
const existingSession = ctx.sessions.get(msg.sessionId);
|
|
281
|
+
const isHeadlessLocked = existingSession && (existingSession as unknown as { headlessLock?: boolean }).headlessLock;
|
|
282
|
+
|
|
274
283
|
ctx.socketToSession.set(socket, msg.sessionId);
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
284
|
+
|
|
285
|
+
if (isHeadlessLocked) {
|
|
286
|
+
// Load the session without rebinding the client — the session stays headless
|
|
287
|
+
await ctx.getOrCreateSession(msg.sessionId, socket, false);
|
|
288
|
+
} else {
|
|
289
|
+
const session = await ctx.getOrCreateSession(msg.sessionId, socket, true);
|
|
290
|
+
// Only wire the escalation handler if one isn't already set — handleTaskSubmit
|
|
291
|
+
// sets a handler with the client's actual screen dimensions, and overwriting it
|
|
292
|
+
// here would replace those dimensions with the daemon's defaults.
|
|
293
|
+
if (!session.hasEscalationHandler()) {
|
|
294
|
+
wireEscalationHandler(session, socket, ctx);
|
|
295
|
+
}
|
|
281
296
|
}
|
|
297
|
+
|
|
282
298
|
ctx.send(socket, {
|
|
283
299
|
type: 'session_info',
|
|
284
300
|
sessionId: conversation.id,
|
|
@@ -326,7 +342,7 @@ export function handleHistoryRequest(
|
|
|
326
342
|
contentOrder = rendered.contentOrder;
|
|
327
343
|
surfaces = rendered.surfaces;
|
|
328
344
|
if (m.role === 'assistant' && toolCalls.length > 0) {
|
|
329
|
-
log.info({ messageId: m.id, toolCallCount: toolCalls.length, text: text
|
|
345
|
+
log.info({ messageId: m.id, toolCallCount: toolCalls.length, text: truncate(text, 100, '') }, 'History message with tool calls');
|
|
330
346
|
}
|
|
331
347
|
} catch (err) {
|
|
332
348
|
log.debug({ err, messageId: m.id }, 'Failed to parse message content as JSON, using raw text');
|
|
@@ -335,7 +351,15 @@ export function handleHistoryRequest(
|
|
|
335
351
|
contentOrder = text ? ['text:0'] : [];
|
|
336
352
|
surfaces = [];
|
|
337
353
|
}
|
|
338
|
-
|
|
354
|
+
let subagentNotification: ParsedHistoryMessage['subagentNotification'];
|
|
355
|
+
if (m.metadata) {
|
|
356
|
+
try {
|
|
357
|
+
subagentNotification = (JSON.parse(m.metadata) as { subagentNotification?: ParsedHistoryMessage['subagentNotification'] }).subagentNotification;
|
|
358
|
+
} catch (err) {
|
|
359
|
+
log.debug({ err, messageId: m.id }, 'Failed to parse message metadata as JSON, ignoring');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return { id: m.id, role: m.role, text, timestamp: m.createdAt, toolCalls, toolCallsBeforeText, textSegments, contentOrder, surfaces, ...(subagentNotification ? { subagentNotification } : {}) };
|
|
339
363
|
});
|
|
340
364
|
|
|
341
365
|
// Merge tool_result data from user messages into the preceding assistant
|
|
@@ -346,7 +370,7 @@ export function handleHistoryRequest(
|
|
|
346
370
|
const historyMessages = merged.map((m) => {
|
|
347
371
|
let attachments: UserMessageAttachment[] | undefined;
|
|
348
372
|
if (m.role === 'assistant' && m.id) {
|
|
349
|
-
const linked =
|
|
373
|
+
const linked = getAttachmentsForMessage(m.id);
|
|
350
374
|
if (linked.length > 0) {
|
|
351
375
|
// Skip embedding base64 data for large video attachments to keep the
|
|
352
376
|
// history_response payload small. Only videos have a lazy-fetch path on
|
|
@@ -354,12 +378,23 @@ export function handleHistoryRequest(
|
|
|
354
378
|
const MAX_INLINE_B64_SIZE = 512 * 1024;
|
|
355
379
|
attachments = linked.map((a) => {
|
|
356
380
|
const omit = a.mimeType.startsWith('video/') && a.dataBase64.length > MAX_INLINE_B64_SIZE;
|
|
381
|
+
|
|
382
|
+
// Lazily generate thumbnails for existing video attachments on first history load.
|
|
383
|
+
if (a.mimeType.startsWith('video/') && !a.thumbnailBase64) {
|
|
384
|
+
const attachmentId = a.id;
|
|
385
|
+
const base64 = a.dataBase64;
|
|
386
|
+
generateVideoThumbnail(base64).then((thumb) => {
|
|
387
|
+
if (thumb) setAttachmentThumbnail(attachmentId, thumb);
|
|
388
|
+
}).catch(() => {});
|
|
389
|
+
}
|
|
390
|
+
|
|
357
391
|
return {
|
|
358
392
|
id: a.id,
|
|
359
393
|
filename: a.originalFilename,
|
|
360
394
|
mimeType: a.mimeType,
|
|
361
395
|
data: omit ? '' : a.dataBase64,
|
|
362
396
|
...(omit ? { sizeBytes: a.sizeBytes } : {}),
|
|
397
|
+
...(a.thumbnailBase64 ? { thumbnailData: a.thumbnailBase64 } : {}),
|
|
363
398
|
};
|
|
364
399
|
});
|
|
365
400
|
}
|
|
@@ -374,6 +409,7 @@ export function handleHistoryRequest(
|
|
|
374
409
|
...(m.textSegments.length > 0 ? { textSegments: m.textSegments } : {}),
|
|
375
410
|
...(m.contentOrder.length > 0 ? { contentOrder: m.contentOrder } : {}),
|
|
376
411
|
...(m.surfaces.length > 0 ? { surfaces: m.surfaces } : {}),
|
|
412
|
+
...(m.subagentNotification ? { subagentNotification: m.subagentNotification } : {}),
|
|
377
413
|
};
|
|
378
414
|
});
|
|
379
415
|
ctx.send(socket, { type: 'history_response', sessionId: msg.sessionId, messages: historyMessages });
|
|
@@ -421,10 +457,10 @@ export async function handleRegenerate(
|
|
|
421
457
|
} catch (err) {
|
|
422
458
|
const message = err instanceof Error ? err.message : String(err);
|
|
423
459
|
log.error({ err, sessionId: msg.sessionId }, 'Error regenerating message');
|
|
424
|
-
session.traceEmitter.emit('request_error', message
|
|
460
|
+
session.traceEmitter.emit('request_error', truncate(message, 200, ''), {
|
|
425
461
|
requestId,
|
|
426
462
|
status: 'error',
|
|
427
|
-
attributes: { errorClass: err instanceof Error ? err.constructor.name : 'Error', message: message
|
|
463
|
+
attributes: { errorClass: err instanceof Error ? err.constructor.name : 'Error', message: truncate(message, 500, '') },
|
|
428
464
|
});
|
|
429
465
|
ctx.send(socket, { type: 'error', message: `Failed to regenerate: ${message}` });
|
|
430
466
|
const classified = classifySessionError(err, { phase: 'regenerate' });
|
|
@@ -484,3 +520,20 @@ export function handleDeleteQueuedMessage(
|
|
|
484
520
|
log.warn({ sessionId: msg.sessionId, requestId: msg.requestId }, 'Queued message not found for deletion');
|
|
485
521
|
}
|
|
486
522
|
}
|
|
523
|
+
|
|
524
|
+
export const sessionHandlers = defineHandlers({
|
|
525
|
+
user_message: handleUserMessage,
|
|
526
|
+
confirmation_response: handleConfirmationResponse,
|
|
527
|
+
secret_response: handleSecretResponse,
|
|
528
|
+
session_list: (_msg, socket, ctx) => handleSessionList(socket, ctx),
|
|
529
|
+
session_create: handleSessionCreate,
|
|
530
|
+
sessions_clear: (_msg, socket, ctx) => handleSessionsClear(socket, ctx),
|
|
531
|
+
session_switch: handleSessionSwitch,
|
|
532
|
+
cancel: handleCancel,
|
|
533
|
+
delete_queued_message: handleDeleteQueuedMessage,
|
|
534
|
+
history_request: handleHistoryRequest,
|
|
535
|
+
undo: handleUndo,
|
|
536
|
+
regenerate: handleRegenerate,
|
|
537
|
+
usage_request: handleUsageRequest,
|
|
538
|
+
sandbox_set: handleSandboxSet,
|
|
539
|
+
});
|
|
@@ -5,7 +5,7 @@ import { ComputerUseSession } from '../computer-use-session.js';
|
|
|
5
5
|
import { getLogger } from '../../util/logger.js';
|
|
6
6
|
import { execSync } from 'node:child_process';
|
|
7
7
|
import { estimateBase64Bytes } from '../assistant-attachments.js';
|
|
8
|
-
import type { CuSessionCreate, ServerMessage, SessionTransportMetadata } from '../ipc-protocol.js';
|
|
8
|
+
import type { ClientMessage, CuSessionCreate, ServerMessage, SessionTransportMetadata } from '../ipc-protocol.js';
|
|
9
9
|
import type { SecretPromptResult } from '../../permissions/secret-prompter.js';
|
|
10
10
|
import { getConfig } from '../../config/loader.js';
|
|
11
11
|
|
|
@@ -13,6 +13,9 @@ const log = getLogger('handlers');
|
|
|
13
13
|
|
|
14
14
|
export { log };
|
|
15
15
|
|
|
16
|
+
/** Debounce window for suppressing file-watcher config reloads after programmatic saves. */
|
|
17
|
+
export const CONFIG_RELOAD_DEBOUNCE_MS = 300;
|
|
18
|
+
|
|
16
19
|
const HISTORY_ATTACHMENT_TEXT_LIMIT = 500;
|
|
17
20
|
|
|
18
21
|
export const FALLBACK_SCREEN = { width: 1920, height: 1080 };
|
|
@@ -67,6 +70,13 @@ export interface RenderedHistoryContent {
|
|
|
67
70
|
surfaces: HistorySurface[];
|
|
68
71
|
}
|
|
69
72
|
|
|
73
|
+
export interface SubagentNotificationData {
|
|
74
|
+
subagentId: string;
|
|
75
|
+
label: string;
|
|
76
|
+
status: 'completed' | 'failed' | 'aborted';
|
|
77
|
+
error?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
export interface ParsedHistoryMessage {
|
|
71
81
|
id?: string;
|
|
72
82
|
role: string;
|
|
@@ -77,6 +87,7 @@ export interface ParsedHistoryMessage {
|
|
|
77
87
|
textSegments: string[];
|
|
78
88
|
contentOrder: string[];
|
|
79
89
|
surfaces: HistorySurface[];
|
|
90
|
+
subagentNotification?: SubagentNotificationData;
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
/**
|
|
@@ -120,6 +131,30 @@ export interface HandlerContext {
|
|
|
120
131
|
touchSession(sessionId: string): void;
|
|
121
132
|
}
|
|
122
133
|
|
|
134
|
+
// ─── Typed dispatch ──────────────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
type MessageType = ClientMessage['type'];
|
|
137
|
+
// 'auth' is handled at the transport layer (server.ts) and never reaches dispatch.
|
|
138
|
+
export type DispatchableType = Exclude<MessageType, 'auth'>;
|
|
139
|
+
type MessageOfType<T extends MessageType> = Extract<ClientMessage, { type: T }>;
|
|
140
|
+
type MessageHandler<T extends MessageType> = (
|
|
141
|
+
msg: MessageOfType<T>,
|
|
142
|
+
socket: net.Socket,
|
|
143
|
+
ctx: HandlerContext,
|
|
144
|
+
) => void | Promise<void>;
|
|
145
|
+
export type DispatchMap = { [T in DispatchableType]: MessageHandler<T> };
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Type-safe handler group definition. Preserves exact key types so the
|
|
149
|
+
* combined spread in index.ts can be checked for exhaustiveness via
|
|
150
|
+
* `satisfies DispatchMap` instead of an unsafe `as DispatchMap` cast.
|
|
151
|
+
*/
|
|
152
|
+
export function defineHandlers<K extends DispatchableType>(
|
|
153
|
+
handlers: Pick<DispatchMap, K>,
|
|
154
|
+
): Pick<DispatchMap, K> {
|
|
155
|
+
return handlers;
|
|
156
|
+
}
|
|
157
|
+
|
|
123
158
|
/**
|
|
124
159
|
* Query the main display dimensions via CoreGraphics.
|
|
125
160
|
* Cached after the first successful call; falls back to 1920x1080.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { log, pendingSignBundlePayload, pendingSigningIdentity, defineHandlers } from './shared.js';
|
|
2
|
+
|
|
3
|
+
export const signingHandlers = defineHandlers({
|
|
4
|
+
sign_bundle_payload_response: (msg) => {
|
|
5
|
+
const pending = pendingSignBundlePayload.get(msg.requestId);
|
|
6
|
+
if (pending) {
|
|
7
|
+
clearTimeout(pending.timer);
|
|
8
|
+
pendingSignBundlePayload.delete(msg.requestId);
|
|
9
|
+
if (msg.error) {
|
|
10
|
+
pending.reject(new Error(msg.error));
|
|
11
|
+
} else if (msg.signature && msg.keyId && msg.publicKey) {
|
|
12
|
+
pending.resolve({ signature: msg.signature, keyId: msg.keyId, publicKey: msg.publicKey });
|
|
13
|
+
} else {
|
|
14
|
+
pending.reject(new Error('Missing required fields in sign_bundle_payload_response'));
|
|
15
|
+
}
|
|
16
|
+
} else {
|
|
17
|
+
log.warn({ requestId: msg.requestId }, 'Received sign_bundle_payload_response with no pending request');
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
get_signing_identity_response: (msg) => {
|
|
22
|
+
const pending = pendingSigningIdentity.get(msg.requestId);
|
|
23
|
+
if (pending) {
|
|
24
|
+
clearTimeout(pending.timer);
|
|
25
|
+
pendingSigningIdentity.delete(msg.requestId);
|
|
26
|
+
if (msg.error) {
|
|
27
|
+
pending.reject(new Error(msg.error));
|
|
28
|
+
} else if (msg.keyId && msg.publicKey) {
|
|
29
|
+
pending.resolve({ keyId: msg.keyId, publicKey: msg.publicKey });
|
|
30
|
+
} else {
|
|
31
|
+
pending.reject(new Error('Missing required fields in get_signing_identity_response'));
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
log.warn({ requestId: msg.requestId }, 'Received get_signing_identity_response with no pending request');
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
});
|