@vellumai/assistant 0.12.0 → 0.12.1-dev.202609142113.d1590bc
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/AGENTS.md +5 -1
- package/ARCHITECTURE.md +20 -21
- package/docs/architecture/turn-actor.md +15 -8
- package/docs/guardian-request-flow.md +16 -0
- package/openapi.yaml +327 -52
- package/package.json +2 -1
- package/scripts/smoke-desktop-window-theme.ts +186 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +18 -10
- package/src/__tests__/anthropic-provider.test.ts +0 -63
- package/src/__tests__/app-compiler.test.ts +6 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +5 -2
- package/src/__tests__/app-dir-path-guard.test.ts +1 -3
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +6 -7
- package/src/__tests__/assistant-event-hub.test.ts +44 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +5 -2
- package/src/__tests__/computer-use-tools.test.ts +19 -7
- package/src/__tests__/config-schema-cmd.test.ts +2 -2
- package/src/__tests__/config-schema.test.ts +28 -29
- package/src/__tests__/config-watcher.test.ts +23 -8
- package/src/__tests__/connection-model-compat.test.ts +2 -2
- package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +26 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -10
- package/src/__tests__/conversation-queue.test.ts +48 -207
- package/src/__tests__/conversation-retry-discard.test.ts +54 -1
- package/src/__tests__/conversation-skill-tools.test.ts +27 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +8 -3
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +67 -0
- package/src/__tests__/conversation-title-service.test.ts +14 -10
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +3 -5
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +51 -0
- package/src/__tests__/credential-record-retire.test.ts +171 -1
- package/src/__tests__/credential-routes.test.ts +212 -3
- package/src/__tests__/credential-security-invariants.test.ts +4 -2
- package/src/__tests__/cu-unified-flow.test.ts +8 -2
- package/src/__tests__/document-sync-tags.test.ts +25 -0
- package/src/__tests__/drain-kick-guard.test.ts +0 -2
- package/src/__tests__/drain-requeue-on-contention.test.ts +0 -6
- package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
- package/src/__tests__/git-porcelain.test.ts +47 -0
- package/src/__tests__/heartbeat-service.test.ts +56 -40
- package/src/__tests__/helpers/set-workspace-mcp.ts +11 -0
- package/src/__tests__/host-bash-proxy.test.ts +26 -45
- package/src/__tests__/host-browser-proxy.test.ts +6 -17
- package/src/__tests__/host-cu-proxy.test.ts +539 -0
- package/src/__tests__/host-file-proxy-targeted.test.ts +23 -0
- package/src/__tests__/host-file-proxy.test.ts +11 -23
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +30 -9
- package/src/__tests__/list-messages-camera-frame.test.ts +121 -0
- package/src/__tests__/llm-catalog-parity.test.ts +25 -0
- package/src/__tests__/mcp-auth-routes.test.ts +6 -9
- package/src/__tests__/mcp-config-secret-boundary.test.ts +78 -136
- package/src/__tests__/mcp-health-check.test.ts +8 -11
- package/src/__tests__/mcp-list-plugin-servers.test.ts +8 -10
- package/src/__tests__/message-deleted-hook-dispatch.test.ts +119 -0
- package/src/__tests__/messages-after-tiebreaker.test.ts +91 -0
- package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +355 -548
- package/src/__tests__/model-intents.test.ts +3 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +85 -2
- package/src/__tests__/oauth-commands-routes.test.ts +113 -0
- package/src/__tests__/oauth-provider-profiles.test.ts +18 -0
- package/src/__tests__/openai-provider.test.ts +1 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
- package/src/__tests__/platform-callback-registration.test.ts +8 -16
- package/src/__tests__/platform-client-verify-credential.test.ts +2 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +14 -0
- package/src/__tests__/qdrant-manager.test.ts +132 -0
- package/src/__tests__/resolve-app.test.ts +135 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +229 -6
- package/src/__tests__/script-proxy-certs.test.ts +35 -0
- package/src/__tests__/service-account-token.test.ts +247 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skills.test.ts +9 -4
- package/src/__tests__/source-fingerprint.test.ts +184 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +19 -3
- package/src/__tests__/subagent-tools.test.ts +3 -2
- package/src/__tests__/telephony-tts-guard.test.ts +38 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/unicode.test.ts +13 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +4 -0
- package/src/__tests__/watch-retro-tool-availability.test.ts +8 -17
- package/src/__tests__/workspace-git-service.test.ts +26 -0
- package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +336 -0
- package/src/acp/__tests__/agent-process.test.ts +258 -4
- package/src/acp/__tests__/auth-required.test.ts +96 -0
- package/src/acp/__tests__/client-handler.test.ts +90 -2
- package/src/acp/__tests__/helpers/acp-model-option.ts +51 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +5 -1
- package/src/acp/__tests__/session-manager-resume.test.ts +270 -6
- package/src/acp/__tests__/session-manager-usage.test.ts +4 -2
- package/src/acp/__tests__/session-manager.test.ts +895 -4
- package/src/acp/agent-process.test.ts +4 -1
- package/src/acp/agent-process.ts +96 -10
- package/src/acp/auth-required.ts +50 -1
- package/src/acp/auto-install.test.ts +9 -7
- package/src/acp/client-handler.ts +16 -3
- package/src/acp/model-config.test.ts +166 -0
- package/src/acp/model-config.ts +138 -0
- package/src/acp/resolve-agent.test.ts +220 -6
- package/src/acp/resolve-agent.ts +88 -23
- package/src/acp/session-manager.test.ts +196 -3
- package/src/acp/session-manager.ts +441 -18
- package/src/acp/types.ts +50 -5
- package/src/agent/loop.ts +1 -0
- package/src/api/events/acp-session-model-update.test.ts +88 -0
- package/src/api/events/acp-session-model-update.ts +46 -0
- package/src/api/events/app-files-changed.ts +4 -3
- package/src/api/events/notification-intent.ts +2 -0
- package/src/api/events/user-message-echo.ts +7 -1
- package/src/api/index.ts +6 -0
- package/src/api/responses/conversation-message.ts +5 -0
- package/src/apps/app-store.ts +1 -1
- package/src/apps/resolve-app.ts +81 -0
- package/src/apps/source-fingerprint.ts +266 -0
- package/src/avatar/identity-avatar.ts +7 -2
- package/src/bundler/app-compiler.ts +15 -0
- package/src/calls/__tests__/barge-in-guard.test.ts +81 -0
- package/src/{__tests__ → calls/__tests__}/call-controller.test.ts +503 -82
- package/src/{__tests__ → calls/__tests__}/media-stream-audio-transcode.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-output.test.ts +37 -8
- package/src/{__tests__ → calls/__tests__}/media-stream-parser.test.ts +1 -1
- package/src/{__tests__ → calls/__tests__}/media-stream-server-integration.test.ts +150 -57
- package/src/{__tests__ → calls/__tests__}/media-stream-stt-session.test.ts +5 -5
- package/src/{__tests__ → calls/__tests__}/media-turn-detector.test.ts +1 -1
- package/src/{live-voice → calls}/__tests__/progress-narration.test.ts +4 -4
- package/src/{live-voice → calls}/__tests__/progress-phrases.test.ts +1 -1
- package/src/calls/__tests__/voice-control-protocol.test.ts +58 -25
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +229 -0
- package/src/calls/__tests__/voice-progress-cadence.test.ts +274 -0
- package/src/{__tests__/voice-session-bridge.test.ts → calls/__tests__/voice-session-bridge-turn-flow.test.ts} +20 -12
- package/src/calls/__tests__/voice-session-bridge.test.ts +37 -1
- package/src/calls/__tests__/voice-triage-escalate.test.ts +105 -0
- package/src/calls/barge-in-guard.ts +118 -0
- package/src/calls/call-constants.ts +24 -4
- package/src/calls/call-controller.ts +499 -199
- package/src/calls/call-transport.ts +16 -0
- package/src/calls/media-stream-output.ts +32 -0
- package/src/calls/media-stream-server.ts +82 -30
- package/src/calls/media-stream-stt-session.ts +15 -0
- package/src/{live-voice → calls}/progress-narration.ts +2 -2
- package/src/calls/resolve-call-tts-provider.ts +33 -2
- package/src/calls/tts-call-strategy.ts +9 -5
- package/src/calls/types.ts +2 -0
- package/src/calls/voice-control-protocol.ts +53 -21
- package/src/calls/voice-leg-coordinator.ts +189 -0
- package/src/calls/voice-progress-cadence.ts +423 -0
- package/src/calls/voice-session-bridge.ts +59 -46
- package/src/calls/voice-triage-escalate.ts +175 -56
- package/src/cli/commands/__tests__/apps.test.ts +245 -0
- package/src/cli/commands/__tests__/bash.test.ts +53 -0
- package/src/cli/commands/__tests__/roadmap.help.test.ts +19 -0
- package/src/cli/commands/apps.help.ts +67 -13
- package/src/cli/commands/apps.ts +183 -0
- package/src/cli/commands/bash.help.ts +8 -13
- package/src/cli/commands/bash.ts +7 -25
- package/src/cli/commands/channels/__tests__/send.test.ts +218 -0
- package/src/cli/commands/channels/index.help.ts +70 -2
- package/src/cli/commands/channels/index.ts +16 -3
- package/src/cli/commands/channels/send.ts +128 -0
- package/src/cli/commands/credentials.help.ts +6 -2
- package/src/cli/commands/credentials.ts +2 -2
- package/src/cli/commands/mcp.help.ts +8 -8
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/roadmap.help.ts +5 -1
- package/src/cli/commands/roadmap.ts +1 -1
- package/src/cli/lib/bundled-marketplace.json +103 -90
- package/src/config/__tests__/default-profile-catalog.test.ts +22 -0
- package/src/config/__tests__/memory-retrospective-schema.test.ts +15 -1
- package/src/config/__tests__/platform-identity.test.ts +255 -0
- package/src/config/__tests__/platform-rehydration.test.ts +99 -9
- package/src/config/acp-agent-write.ts +43 -0
- package/src/config/acp-defaults.test.ts +13 -3
- package/src/config/acp-defaults.ts +23 -6
- package/src/config/acp-schema.test.ts +81 -0
- package/src/config/acp-schema.ts +30 -2
- package/src/config/bundled-skills/acp/SKILL.md +22 -14
- package/src/config/bundled-skills/acp/TOOLS.json +5 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +12 -9
- package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +20 -2
- package/src/config/bundled-skills/computer-use/TOOLS.json +99 -0
- package/src/config/bundled-skills/computer-use/tools/computer-use-sequence.ts +12 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +2 -1
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +2 -1
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -1
- package/src/config/bundled-skills/messaging/SKILL.md +3 -3
- package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +67 -139
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -1
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -1
- package/src/config/bundled-skills/schedule/SKILL.md +3 -4
- package/src/config/bundled-skills/screen-annotation/SKILL.md +8 -1
- package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +4 -1
- package/src/config/bundled-skills/skill-management/TOOLS.json +6 -2
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +5 -2
- package/src/config/default-profile-catalog.ts +1 -1
- package/src/config/env.ts +2 -2
- package/src/config/feature-flag-registry.json +24 -12
- package/src/config/loader.ts +1 -0
- package/src/config/memory-v3-gate.test.ts +31 -0
- package/src/config/memory-v3-gate.ts +20 -16
- package/src/config/platform-identity.ts +201 -0
- package/src/config/platform-rehydration.ts +11 -27
- package/src/config/schema.ts +2 -2
- package/src/config/schemas/__tests__/live-voice.test.ts +8 -158
- package/src/config/schemas/__tests__/voice.test.ts +148 -0
- package/src/config/schemas/calls.ts +1 -28
- package/src/config/schemas/live-voice.ts +1 -173
- package/src/config/schemas/mcp.ts +1 -1
- package/src/config/schemas/memory-retrospective.ts +10 -0
- package/src/config/schemas/services.ts +8 -0
- package/src/config/schemas/skills.ts +0 -14
- package/src/config/schemas/voice.ts +150 -0
- package/src/credential-execution/process-manager.test.ts +18 -19
- package/src/credential-health/credential-health-service.ts +11 -17
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -121
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +4 -1
- package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +133 -0
- package/src/daemon/app-change-notify.ts +45 -0
- package/src/daemon/config-watcher.ts +13 -194
- package/src/daemon/conversation-error.ts +3 -2
- package/src/daemon/conversation-media-retry.ts +2 -1
- package/src/daemon/conversation-process.ts +35 -64
- package/src/daemon/conversation-runtime-assembly.ts +2 -1
- package/src/daemon/conversation-skill-tools.ts +13 -31
- package/src/daemon/conversation-store.ts +1 -1
- package/src/daemon/conversation-surfaces.ts +15 -9
- package/src/daemon/conversation-tool-setup.ts +37 -43
- package/src/daemon/conversation.ts +0 -3
- package/src/daemon/dictation-profile-store.ts +2 -1
- package/src/daemon/handlers/shared.ts +2 -1
- package/src/daemon/handlers/skills.ts +6 -3
- package/src/daemon/host-bash-proxy.ts +8 -12
- package/src/daemon/host-browser-proxy.ts +15 -1
- package/src/daemon/host-cu-proxy.ts +186 -19
- package/src/daemon/host-file-proxy.ts +8 -10
- package/src/daemon/host-proxy-preactivation.ts +2 -1
- package/src/daemon/host-transfer-proxy.ts +14 -18
- package/src/daemon/lifecycle.ts +0 -5
- package/src/daemon/mcp-reload-service.ts +5 -5
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/orphan-reaper.ts +1 -1
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/reaction-history-render.ts +2 -1
- package/src/daemon/shutdown-handlers.ts +1 -9
- package/src/daemon/skill-memory-refresh.ts +64 -0
- package/src/daemon/tool-side-effects.ts +7 -18
- package/src/desktop/__tests__/fake-desktop.ts +119 -0
- package/src/desktop/desktop-chrome-policy.test.ts +71 -0
- package/src/desktop/desktop-chrome-policy.ts +42 -0
- package/src/desktop/desktop-dependencies.test.ts +102 -0
- package/src/desktop/desktop-dependencies.ts +306 -0
- package/src/desktop/desktop-feature.test.ts +18 -0
- package/src/desktop/desktop-feature.ts +19 -0
- package/src/desktop/desktop-panel-config.test.ts +135 -0
- package/src/desktop/desktop-panel-config.ts +149 -0
- package/src/desktop/desktop-session-manager.test.ts +627 -0
- package/src/desktop/desktop-session-manager.ts +814 -0
- package/src/desktop/desktop-stream-bridge.test.ts +395 -0
- package/src/desktop/desktop-stream-bridge.ts +214 -0
- package/src/desktop/desktop-wallpaper.test.ts +191 -0
- package/src/desktop/desktop-wallpaper.ts +113 -0
- package/src/desktop/desktop-window-theme.ts +170 -0
- package/src/heartbeat/heartbeat-service.ts +21 -3
- package/src/home/__tests__/feed-writer.test.ts +22 -0
- package/src/home/feed-writer.ts +11 -2
- package/src/hooks/types.ts +33 -0
- package/src/i18n/AGENTS.md +22 -0
- package/src/i18n/__tests__/i18n.test.ts +108 -0
- package/src/i18n/index.ts +16 -0
- package/src/i18n/locales.ts +93 -0
- package/src/i18n/messages.ts +61 -0
- package/src/i18n/title.ts +25 -0
- package/src/inbound/platform-callback-registration.ts +4 -5
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +0 -3
- package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +238 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +13 -69
- package/src/live-voice/live-voice-photo.ts +25 -6
- package/src/live-voice/live-voice-session.ts +213 -693
- package/src/live-voice/protocol.ts +0 -2
- package/src/mcp/__tests__/effective-config.test.ts +2 -2
- package/src/mcp/__tests__/workspace-mcp-config.test.ts +135 -0
- package/src/mcp/effective-config.ts +3 -3
- package/src/mcp/mcp-header-store.ts +29 -45
- package/src/mcp/spec-schema.ts +111 -0
- package/src/mcp/startup.ts +8 -4
- package/src/mcp/workspace-mcp-config.ts +188 -0
- package/src/messaging/provider.ts +10 -3
- package/src/messaging/providers/__tests__/proactive-address.test.ts +95 -0
- package/src/messaging/providers/callback-routing.ts +18 -0
- package/src/messaging/providers/channel-transport.ts +56 -0
- package/src/messaging/providers/discord/transport.ts +17 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +6 -17
- package/src/messaging/providers/slack/adapter.ts +7 -44
- package/src/messaging/providers/slack/transport.ts +16 -0
- package/src/messaging/providers/telegram-bot/adapter.ts +1 -48
- package/src/messaging/providers/telegram-bot/client.ts +0 -26
- package/src/messaging/providers/telegram-bot/transport.ts +20 -0
- package/src/messaging/providers/whatsapp/adapter.ts +1 -48
- package/src/messaging/providers/whatsapp/transport.ts +18 -0
- package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +8 -0
- package/src/notifications/__tests__/assistant-reply-producer.test.ts +55 -0
- package/src/notifications/__tests__/guardian-feed-projection.test.ts +158 -2
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +153 -3
- package/src/notifications/__tests__/schedule-result-producer.test.ts +99 -3
- package/src/notifications/adapters/macos.ts +3 -0
- package/src/notifications/assistant-reply-producer.ts +8 -3
- package/src/notifications/conversation-pairing.ts +36 -16
- package/src/notifications/delivered-post-record.ts +11 -1
- package/src/notifications/guardian-feed-projection.ts +125 -5
- package/src/notifications/home-feed-side-effect.ts +55 -7
- package/src/notifications/schedule-result-producer.ts +66 -22
- package/src/oauth/AGENTS.md +2 -0
- package/src/oauth/__tests__/seed-providers-managed.test.ts +54 -0
- package/src/oauth/byo-connection.test.ts +105 -0
- package/src/oauth/byo-connection.ts +36 -6
- package/src/oauth/connection-resolver.test.ts +73 -0
- package/src/oauth/connection-resolver.ts +95 -2
- package/src/oauth/scope-utils.ts +24 -0
- package/src/oauth/seed-providers.ts +204 -25
- package/src/outbound-proxy/certs.ts +3 -5
- package/src/permissions/checker.test.ts +11 -6
- package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
- package/src/persistence/conversation-crud.ts +71 -63
- package/src/persistence/conversation-lineage.ts +12 -4
- package/src/persistence/conversation-queries.ts +2 -2
- package/src/persistence/conversation-title-placeholders.ts +23 -0
- package/src/persistence/conversation-title-service.ts +9 -26
- package/src/persistence/embeddings/qdrant-manager.ts +163 -18
- package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
- package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
- package/src/persistence/message-cursor.ts +78 -0
- package/src/persistence/message-reads.ts +30 -0
- package/src/persistence/migrations/157-invite-contact-id.ts +18 -6
- package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +149 -0
- package/src/persistence/schema/memory-core.ts +5 -0
- package/src/platform/client.test.ts +4 -2
- package/src/platform/client.ts +2 -10
- package/src/plugin-api/constants.ts +2 -0
- package/src/plugin-api/index.ts +1 -0
- package/src/plugin-api/types.ts +2 -0
- package/src/plugins/defaults/index.ts +2 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +46 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +118 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +83 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +9 -5
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +20 -10
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +5 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +219 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +31 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +63 -0
- package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +4 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +3 -2
- package/src/plugins/defaults/memory/context-search/format.ts +3 -2
- package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +6 -3
- package/src/plugins/defaults/memory/context-search/sources/workspace.ts +3 -2
- package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -7
- package/src/plugins/defaults/memory/hooks/init.ts +10 -0
- package/src/plugins/defaults/memory/hooks/message-deleted.ts +21 -0
- package/src/plugins/defaults/memory/hooks/shutdown.ts +2 -0
- package/src/plugins/defaults/memory/host-utils.ts +10 -0
- package/src/plugins/defaults/memory/jobs-worker.ts +13 -0
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +34 -60
- package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +126 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +79 -0
- package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +28 -0
- package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +3 -5
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +12 -3
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +1 -1
- package/src/plugins/defaults/memory/memory-retrospective-state.ts +312 -71
- package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +2 -1
- package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +5 -3
- package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +9 -0
- package/src/plugins/defaults/memory/startup.ts +28 -2
- package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +7 -9
- package/src/plugins/defaults/memory/substrate/page-index.ts +6 -1
- package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
- package/src/plugins/defaults/memory/v1/graph/consolidation.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +4 -2
- package/src/plugins/defaults/memory/v1/graph/retriever.ts +4 -1
- package/src/plugins/defaults/memory/v2/reranker.ts +6 -1
- package/src/plugins/defaults/memory/v3/__tests__/card.test.ts +24 -0
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +125 -0
- package/src/plugins/defaults/memory/v3/__tests__/sections.test.ts +26 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +30 -0
- package/src/plugins/defaults/memory/v3/card.ts +3 -2
- package/src/plugins/defaults/memory/v3/pool-select.ts +5 -3
- package/src/plugins/defaults/memory/v3/sections.ts +9 -3
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +5 -2
- package/src/plugins/defaults/memory/worker.ts +6 -0
- package/src/plugins/mcp-servers.ts +15 -75
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
- package/src/providers/__tests__/retry-outbound-sanitize.test.ts +176 -0
- package/src/providers/anthropic/client.ts +0 -47
- package/src/providers/gemini/client.ts +9 -23
- package/src/providers/gemini-thought-signature.test.ts +63 -0
- package/src/providers/gemini-thought-signature.ts +44 -0
- package/src/providers/inference/auth.ts +2 -3
- package/src/providers/inference/connection-availability.ts +27 -8
- package/src/providers/inference/resolve-auth.ts +22 -4
- package/src/providers/inference/service-account-token.ts +248 -0
- package/src/providers/model-catalog.ts +34 -0
- package/src/providers/model-intents.ts +10 -5
- package/src/providers/openai/__tests__/chat-completions-output-token-limit.test.ts +141 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +146 -18
- package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +613 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +235 -0
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +83 -1
- package/src/providers/openai/chat-completions-provider.ts +212 -79
- package/src/providers/openai/codex-models.ts +0 -4
- package/src/providers/openai/google-thought-signature.ts +320 -0
- package/src/providers/openrouter/client.ts +20 -0
- package/src/providers/outbound-request-sanitize.ts +96 -0
- package/src/providers/retry.ts +24 -3
- package/src/providers/unparseable-tool-args.ts +5 -1
- package/src/runtime/AGENTS.md +3 -1
- package/src/runtime/__tests__/channel-send.test.ts +443 -0
- package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +89 -0
- package/src/runtime/__tests__/host-observe.test.ts +40 -1
- package/src/runtime/__tests__/live-voice-upgrade.test.ts +58 -0
- package/src/runtime/__tests__/runtime-ws-test-utils.ts +72 -0
- package/src/runtime/__tests__/watch-stream-upgrade.test.ts +59 -0
- package/src/runtime/agent-wake.ts +2 -1
- package/src/runtime/assistant-event-hub.ts +21 -3
- package/src/runtime/auth/same-actor.ts +38 -3
- package/src/runtime/channel-send.ts +316 -0
- package/src/runtime/host-observe.ts +11 -1
- package/src/runtime/http-server.ts +160 -151
- package/src/runtime/routes/__tests__/acp-routes.test.ts +159 -4
- package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +205 -0
- package/src/runtime/routes/__tests__/channel-send-routes.test.ts +127 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +108 -1
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
- package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +107 -0
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +16 -12
- package/src/runtime/routes/acp-routes.test.ts +15 -0
- package/src/runtime/routes/acp-routes.ts +72 -9
- package/src/runtime/routes/app-management-routes.ts +73 -0
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/channel-send-routes.ts +85 -0
- package/src/runtime/routes/conversation-list-routes.ts +14 -3
- package/src/runtime/routes/conversation-query-routes.ts +40 -0
- package/src/runtime/routes/conversation-routes.ts +16 -3
- package/src/runtime/routes/credential-routes.ts +19 -10
- package/src/runtime/routes/desktop-setup-routes.test.ts +74 -0
- package/src/runtime/routes/desktop-setup-routes.ts +35 -0
- package/src/runtime/routes/diagnostics-routes.ts +61 -4
- package/src/runtime/routes/events-routes.ts +4 -0
- package/src/runtime/routes/host-cu-routes.ts +6 -0
- package/src/runtime/routes/index.ts +4 -2
- package/src/runtime/routes/log-export-routes.ts +2 -0
- package/src/runtime/routes/mcp-auth-routes.ts +39 -47
- package/src/runtime/routes/migration-routes.ts +6 -20
- package/src/runtime/routes/oauth-commands-routes.ts +36 -0
- package/src/runtime/routes/platform-routes.ts +18 -15
- package/src/runtime/routes/workspace-routes.test.ts +55 -26
- package/src/runtime/routes/workspace-routes.ts +46 -63
- package/src/runtime/routes/workspace-tree-walk.test.ts +244 -0
- package/src/runtime/routes/workspace-tree-walk.ts +240 -0
- package/src/runtime/routes/workspace-utils.ts +17 -0
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +16 -3
- package/src/runtime/sync/resource-sync-events.ts +2 -1
- package/src/schedule/run-script.ts +2 -1
- package/src/schedule/schedule-store.ts +9 -2
- package/src/schedule/worker.ts +1 -1
- package/src/security/__tests__/ces-http-record-backend.test.ts +137 -0
- package/src/security/ces-http-record-backend.ts +120 -0
- package/src/security/ces-rpc-record-backend.ts +7 -0
- package/src/security/untrusted-content.ts +3 -1
- package/src/skills/__tests__/workspace-skill-md-signature.test.ts +60 -0
- package/src/skills/workspace-skill-md-signature.ts +50 -0
- package/src/subagent/consult-context.ts +12 -25
- package/src/tools/__tests__/side-effect-abort-guard.test.ts +1 -0
- package/src/tools/acp/list-agents.test.ts +3 -1
- package/src/tools/acp/spawn.test.ts +146 -11
- package/src/tools/acp/spawn.ts +21 -3
- package/src/tools/acp/status.test.ts +94 -0
- package/src/tools/acp/status.ts +40 -3
- package/src/tools/app-control/skill-proxy-bridge.ts +2 -1
- package/src/tools/browser/browser-execution.ts +1 -1
- package/src/tools/browser/cdp-client/accessibility-snapshot.ts +9 -3
- package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +2 -1
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +3 -2
- package/src/tools/browser/network-recorder.ts +2 -1
- package/src/tools/capability-offer.test.ts +22 -2
- package/src/tools/capability-offer.ts +16 -1
- package/src/tools/computer-use/definitions.ts +121 -2
- package/src/tools/computer-use/skill-proxy-bridge.ts +2 -1
- package/src/tools/credentials/metadata-store.ts +100 -0
- package/src/tools/filesystem/search.ts +2 -1
- package/src/tools/host-filesystem/edit.test.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +2 -2
- package/src/tools/host-filesystem/read.test.ts +2 -1
- package/src/tools/host-filesystem/read.ts +2 -2
- package/src/tools/host-filesystem/transfer.test.ts +2 -1
- package/src/tools/host-filesystem/transfer.ts +2 -2
- package/src/tools/host-filesystem/write.test.ts +2 -1
- package/src/tools/host-filesystem/write.ts +2 -2
- package/src/tools/host-terminal/host-shell.test.ts +16 -0
- package/src/tools/host-terminal/host-shell.ts +4 -20
- package/src/tools/network/web-search.ts +6 -1
- package/src/tools/policy-context.ts +6 -7
- package/src/tools/skills/scaffold-managed.ts +61 -3
- package/src/tools/subagent/spawn.ts +5 -8
- package/src/tools/terminal/__tests__/safe-env.test.ts +6 -6
- package/src/tools/terminal/__tests__/sanitized-bash.test.ts +57 -0
- package/src/tools/terminal/safe-env.ts +23 -3
- package/src/tools/terminal/sanitized-bash.ts +105 -0
- package/src/tools/watch/watch-retro-report.ts +0 -8
- package/src/types/host-capabilities.ts +5 -3
- package/src/util/__tests__/language-subtag.test.ts +23 -1
- package/src/util/ca-bundle.ts +13 -0
- package/src/util/language-subtag.ts +16 -0
- package/src/util/platform.ts +8 -0
- package/src/util/unicode.ts +15 -1
- package/src/watch/watch-timeline.ts +2 -2
- package/src/workflows/run-manager.ts +2 -1
- package/src/workspace/git-porcelain.ts +66 -0
- package/src/workspace/git-service.ts +6 -55
- package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +258 -0
- package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +78 -0
- package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +214 -0
- package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +102 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +199 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/app-source-watcher.test.ts +0 -218
- package/src/__tests__/config-watcher-skill-reseed.test.ts +0 -359
- package/src/__tests__/speaker-identification.test.ts +0 -56
- package/src/calls/speaker-identification.ts +0 -233
- package/src/daemon/app-source-watcher.ts +0 -218
- package/src/messaging/providers/whatsapp/client.ts +0 -29
- package/src/runtime/routes/debug-bash-routes.ts +0 -173
- package/src/util/fs-watcher-error.ts +0 -36
- /package/src/{live-voice → calls}/progress-phrases.ts +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spawn a shell command with the same sanitized environment the bash tool
|
|
3
|
+
* forwards to tool-call subprocesses.
|
|
4
|
+
*
|
|
5
|
+
* Used by `assistant bash` so a CLI invocation sees the same allowlisted
|
|
6
|
+
* env, workspace cwd, and platform shell as a bash tool call, without
|
|
7
|
+
* round-tripping through the assistant HTTP or IPC API.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { spawn } from "node:child_process";
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
buildShellInvocation,
|
|
14
|
+
terminateProcessTree,
|
|
15
|
+
} from "../../util/host-process.js";
|
|
16
|
+
import { getWorkspaceDir } from "../../util/platform.js";
|
|
17
|
+
import { buildSanitizedEnv } from "./safe-env.js";
|
|
18
|
+
|
|
19
|
+
export const DEFAULT_SANITIZED_BASH_TIMEOUT_MS = 30_000;
|
|
20
|
+
|
|
21
|
+
export interface SanitizedBashResult {
|
|
22
|
+
stdout: string;
|
|
23
|
+
stderr: string;
|
|
24
|
+
exitCode: number | null;
|
|
25
|
+
timedOut: boolean;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function runSanitizedBash(
|
|
30
|
+
command: string,
|
|
31
|
+
timeoutMs: number = DEFAULT_SANITIZED_BASH_TIMEOUT_MS,
|
|
32
|
+
): Promise<SanitizedBashResult> {
|
|
33
|
+
if (!command) {
|
|
34
|
+
return Promise.resolve({
|
|
35
|
+
stdout: "",
|
|
36
|
+
stderr: "",
|
|
37
|
+
exitCode: null,
|
|
38
|
+
timedOut: false,
|
|
39
|
+
error: "command is required",
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const effectiveTimeout =
|
|
44
|
+
typeof timeoutMs === "number" && timeoutMs > 0
|
|
45
|
+
? timeoutMs
|
|
46
|
+
: DEFAULT_SANITIZED_BASH_TIMEOUT_MS;
|
|
47
|
+
|
|
48
|
+
return new Promise<SanitizedBashResult>((resolve) => {
|
|
49
|
+
const stdoutChunks: Buffer[] = [];
|
|
50
|
+
const stderrChunks: Buffer[] = [];
|
|
51
|
+
let timedOut = false;
|
|
52
|
+
let settled = false;
|
|
53
|
+
|
|
54
|
+
const finish = (result: SanitizedBashResult) => {
|
|
55
|
+
if (settled) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
settled = true;
|
|
59
|
+
resolve(result);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const wrapped = buildShellInvocation(command);
|
|
63
|
+
const child = spawn(wrapped.command, wrapped.args, {
|
|
64
|
+
cwd: getWorkspaceDir(),
|
|
65
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
66
|
+
detached: true,
|
|
67
|
+
env: buildSanitizedEnv(),
|
|
68
|
+
windowsHide: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const timer = setTimeout(() => {
|
|
72
|
+
timedOut = true;
|
|
73
|
+
terminateProcessTree(child);
|
|
74
|
+
}, effectiveTimeout);
|
|
75
|
+
|
|
76
|
+
child.stdout.on("data", (data: Buffer) => {
|
|
77
|
+
stdoutChunks.push(data);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
child.stderr.on("data", (data: Buffer) => {
|
|
81
|
+
stderrChunks.push(data);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
child.on("close", (code) => {
|
|
85
|
+
clearTimeout(timer);
|
|
86
|
+
finish({
|
|
87
|
+
stdout: Buffer.concat(stdoutChunks).toString(),
|
|
88
|
+
stderr: Buffer.concat(stderrChunks).toString(),
|
|
89
|
+
exitCode: code,
|
|
90
|
+
timedOut,
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
child.on("error", (err) => {
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
finish({
|
|
97
|
+
stdout: "",
|
|
98
|
+
stderr: "",
|
|
99
|
+
exitCode: null,
|
|
100
|
+
timedOut: false,
|
|
101
|
+
error: err.message,
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
@@ -14,14 +14,6 @@ import type {
|
|
|
14
14
|
/**
|
|
15
15
|
* How a watch retrospective hands its report to the daemon.
|
|
16
16
|
*
|
|
17
|
-
* **The card cannot come from `ui_show`.** A retrospective runs as a
|
|
18
|
-
* `clientless` wake, which pins the turn non-interactive, and
|
|
19
|
-
* `conversation-tool-setup` gates the whole `ui_surface` tool family on a
|
|
20
|
-
* client being present (`return channelCapabilities?.supportsDynamicUi ??
|
|
21
|
-
* !hasNoClient`). So `ui_show` is not merely denied in this turn, it is absent
|
|
22
|
-
* from the tool set, and a retrospective told to call it can only report that
|
|
23
|
-
* it cannot. This tool is an ordinary one and passes that gate untouched.
|
|
24
|
-
*
|
|
25
17
|
* **It records; it does not render.** The executor validates the payload and
|
|
26
18
|
* returns, and nothing here writes to the conversation. What makes the card is
|
|
27
19
|
* `watch-retro.ts` reading this call back out of the turn's own history once
|
|
@@ -16,6 +16,7 @@ export const HOST_PROXY_CAPABILITIES = [
|
|
|
16
16
|
"host_file",
|
|
17
17
|
"host_cu",
|
|
18
18
|
"host_cu_window_capture",
|
|
19
|
+
"host_cu_sequence",
|
|
19
20
|
"host_cu_annotate",
|
|
20
21
|
"host_browser",
|
|
21
22
|
"host_app_control",
|
|
@@ -24,11 +25,12 @@ export const HOST_PROXY_CAPABILITIES = [
|
|
|
24
25
|
|
|
25
26
|
export type HostProxyCapability = (typeof HOST_PROXY_CAPABILITIES)[number];
|
|
26
27
|
|
|
27
|
-
/** Every host capability except the
|
|
28
|
+
/** Every host capability except the macOS-only ones. */
|
|
28
29
|
const DESKTOP_SHARED_CAPABILITIES = HOST_PROXY_CAPABILITIES.filter(
|
|
29
30
|
(capability) =>
|
|
30
31
|
capability !== "host_app_control" &&
|
|
31
32
|
capability !== "host_cu_window_capture" &&
|
|
33
|
+
capability !== "host_cu_sequence" &&
|
|
32
34
|
capability !== "host_cu_annotate",
|
|
33
35
|
);
|
|
34
36
|
|
|
@@ -47,8 +49,8 @@ export type HostProxyInterfaceId = "macos" | "windows" | "linux";
|
|
|
47
49
|
* (web, ios, android, and every messaging transport) provide none.
|
|
48
50
|
*
|
|
49
51
|
* Windows and Linux run the same host proxy as macOS minus app control. The
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
+
* negotiated CU capabilities ride the host_cu transport and are claimed per
|
|
53
|
+
* connection; only the macOS native helper answers them, so a
|
|
52
54
|
* request elsewhere would reach that helper as an unknown action.
|
|
53
55
|
*
|
|
54
56
|
* macOS additionally provisions its `host_browser` proxy via the assistant
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
baseLanguageSubtag,
|
|
5
|
+
fixedPhraseLanguage,
|
|
6
|
+
localizedOrDefault,
|
|
7
|
+
} from "../language-subtag.js";
|
|
4
8
|
|
|
5
9
|
describe("baseLanguageSubtag", () => {
|
|
6
10
|
test("lowercases a bare tag", () => {
|
|
@@ -52,3 +56,21 @@ describe("localizedOrDefault", () => {
|
|
|
52
56
|
expect(localizedOrDefault(table, "__proto__", "fallback")).toBe("fallback");
|
|
53
57
|
});
|
|
54
58
|
});
|
|
59
|
+
|
|
60
|
+
describe("fixedPhraseLanguage", () => {
|
|
61
|
+
const table = { en: "one", es: "uno" };
|
|
62
|
+
|
|
63
|
+
test("pins English when the speaker's language has no table entry", () => {
|
|
64
|
+
expect(fixedPhraseLanguage(table, "ko")).toBe("en");
|
|
65
|
+
expect(fixedPhraseLanguage(table, "ar-EG")).toBe("en");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("rides the speaker's language when the table covers it", () => {
|
|
69
|
+
expect(fixedPhraseLanguage(table, "es")).toBeUndefined();
|
|
70
|
+
expect(fixedPhraseLanguage(table, "es-419")).toBeUndefined();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("carries no hint when the language is unknown", () => {
|
|
74
|
+
expect(fixedPhraseLanguage(table, undefined)).toBeUndefined();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
|
|
3
|
+
export async function writeCombinedCABundle(
|
|
4
|
+
systemBundlePath: string,
|
|
5
|
+
extraCAPath: string,
|
|
6
|
+
outputPath: string,
|
|
7
|
+
): Promise<void> {
|
|
8
|
+
const [systemCAs, extraCAs] = await Promise.all([
|
|
9
|
+
readFile(systemBundlePath, "utf-8"),
|
|
10
|
+
readFile(extraCAPath, "utf-8"),
|
|
11
|
+
]);
|
|
12
|
+
await writeFile(outputPath, `${systemCAs}\n${extraCAs}`, { mode: 0o644 });
|
|
13
|
+
}
|
|
@@ -41,3 +41,19 @@ export function localizedOrDefault<T>(
|
|
|
41
41
|
? (table[baseLanguageSubtag(language)!] as T)
|
|
42
42
|
: fallback;
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The TTS language hint for a fixed phrase picked from a localized table:
|
|
47
|
+
* "en" when the speaker has a language the table does not cover (the
|
|
48
|
+
* picker fell back to English text, which must not be synthesized under
|
|
49
|
+
* an ar/ko/ta hint), undefined otherwise (the phrase rides the speaker's
|
|
50
|
+
* language, or carries no hint at all when the language is unknown).
|
|
51
|
+
*/
|
|
52
|
+
export function fixedPhraseLanguage(
|
|
53
|
+
table: Readonly<Record<string, unknown>>,
|
|
54
|
+
language: string | undefined,
|
|
55
|
+
): string | undefined {
|
|
56
|
+
return language !== undefined && !hasLocalizedEntry(table, language)
|
|
57
|
+
? "en"
|
|
58
|
+
: undefined;
|
|
59
|
+
}
|
package/src/util/platform.ts
CHANGED
|
@@ -470,6 +470,14 @@ export function getWorkspaceConfigPath(): string {
|
|
|
470
470
|
return join(getWorkspaceDir(), "config.json");
|
|
471
471
|
}
|
|
472
472
|
|
|
473
|
+
/** Filename for the user-owned Agent Plugins MCP document. */
|
|
474
|
+
export const WORKSPACE_MCP_FILENAME = "mcp.json";
|
|
475
|
+
|
|
476
|
+
/** Returns $VELLUM_WORKSPACE_DIR/mcp.json */
|
|
477
|
+
export function getWorkspaceMcpConfigPath(): string {
|
|
478
|
+
return join(getWorkspaceDir(), WORKSPACE_MCP_FILENAME);
|
|
479
|
+
}
|
|
480
|
+
|
|
473
481
|
/** Returns $VELLUM_WORKSPACE_DIR/skills */
|
|
474
482
|
export function getWorkspaceSkillsDir(): string {
|
|
475
483
|
return join(getWorkspaceDir(), "skills");
|
package/src/util/unicode.ts
CHANGED
|
@@ -126,6 +126,15 @@ export interface DeepSanitizeResult<T> {
|
|
|
126
126
|
fixedStringCount: number;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
export interface DeepSanitizeOptions {
|
|
130
|
+
/**
|
|
131
|
+
* Skip a plain-object property entirely: its value is neither scanned nor
|
|
132
|
+
* copied. For fields known to hold ASCII (base64 payloads), scanning is
|
|
133
|
+
* pure cost.
|
|
134
|
+
*/
|
|
135
|
+
skipKey?: (key: string, parent: Record<string, unknown>) => boolean;
|
|
136
|
+
}
|
|
137
|
+
|
|
129
138
|
/**
|
|
130
139
|
* Recursively walk arrays and plain objects, replacing orphaned surrogates in
|
|
131
140
|
* every string value. Non-plain objects (class instances, Date, Buffer, Map,
|
|
@@ -136,8 +145,10 @@ export interface DeepSanitizeResult<T> {
|
|
|
136
145
|
*/
|
|
137
146
|
export function stripOrphanedSurrogatesDeep<T>(
|
|
138
147
|
input: T,
|
|
148
|
+
options: DeepSanitizeOptions = {},
|
|
139
149
|
): DeepSanitizeResult<T> {
|
|
140
150
|
let fixedStringCount = 0;
|
|
151
|
+
const { skipKey } = options;
|
|
141
152
|
|
|
142
153
|
const walk = (value: unknown): { value: unknown; changed: boolean } => {
|
|
143
154
|
if (typeof value === "string") {
|
|
@@ -178,7 +189,10 @@ export function stripOrphanedSurrogatesDeep<T>(
|
|
|
178
189
|
let next: Record<string, unknown> | null = null;
|
|
179
190
|
for (let i = 0; i < keys.length; i++) {
|
|
180
191
|
const key = keys[i]!;
|
|
181
|
-
const result =
|
|
192
|
+
const result =
|
|
193
|
+
skipKey?.(key, source) === true
|
|
194
|
+
? { value: source[key], changed: false }
|
|
195
|
+
: walk(source[key]);
|
|
182
196
|
if (result.changed && next === null) {
|
|
183
197
|
next = {};
|
|
184
198
|
for (let j = 0; j < i; j++) {
|
|
@@ -366,8 +366,8 @@ export function appendNarration(
|
|
|
366
366
|
* timeline of a session where observation stalled is simply a sparser one.
|
|
367
367
|
*
|
|
368
368
|
* The screenshot is stored only when `attachScreenshot` asks for it, and
|
|
369
|
-
* carrying one is not asking.
|
|
370
|
-
*
|
|
369
|
+
* carrying one is not asking. Watch requests a screenshot on every observe, so
|
|
370
|
+
* an observation normally has pixels available and a policy
|
|
371
371
|
* of "store what arrives" is a policy of storing every frame. Which frames are
|
|
372
372
|
* worth an image is a cadence decision, and it belongs to the caller driving
|
|
373
373
|
* the session rather than to the row writer.
|
|
@@ -33,6 +33,7 @@ import type { TrustContext } from "../daemon/trust-context-types.js";
|
|
|
33
33
|
import { wakeAgentForOpportunity } from "../runtime/agent-wake.js";
|
|
34
34
|
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
35
35
|
import { getLogger } from "../util/logger.js";
|
|
36
|
+
import { safeStringSlice } from "../util/unicode.js";
|
|
36
37
|
import type { CapabilityManifest } from "./capabilities.js";
|
|
37
38
|
import {
|
|
38
39
|
normalizeCapabilityManifest,
|
|
@@ -611,7 +612,7 @@ function truncateForSummary(s: string, runId: string): string {
|
|
|
611
612
|
}
|
|
612
613
|
const omitted = s.length - MAX_SUMMARY_RESULT_CHARS;
|
|
613
614
|
return (
|
|
614
|
-
`${s
|
|
615
|
+
`${safeStringSlice(s, 0, MAX_SUMMARY_RESULT_CHARS)}… ` +
|
|
615
616
|
`[truncated ${omitted} chars — fetch the full result with manage_workflows ` +
|
|
616
617
|
`{ action: "get_result", run_id: "${runId}" }]`
|
|
617
618
|
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NUL-terminated `git status --porcelain -z` parsing.
|
|
3
|
+
*
|
|
4
|
+
* Status reporting and batched staging share this parser so rename/copy
|
|
5
|
+
* origin paths cannot drift between the two readers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface PorcelainEntry {
|
|
9
|
+
/** Two-character XY status from porcelain v1. */
|
|
10
|
+
status: string;
|
|
11
|
+
/** Path git reports for this record (the destination for rename/copy). */
|
|
12
|
+
path: string;
|
|
13
|
+
/** Pre-rename/copy path. Present when the record is a rename or copy. */
|
|
14
|
+
origin?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Parse NUL-terminated `git status --porcelain -z` output into status/path
|
|
19
|
+
* records. NUL termination is required so paths with special characters
|
|
20
|
+
* (non-ASCII, quotes, newlines) arrive verbatim instead of C-style quoted.
|
|
21
|
+
*
|
|
22
|
+
* A rename/copy record is followed by a bare origin-path entry, captured on
|
|
23
|
+
* {@link PorcelainEntry.origin}.
|
|
24
|
+
*/
|
|
25
|
+
export function parsePorcelainZ(stdout: string): PorcelainEntry[] {
|
|
26
|
+
const entries = stdout.split("\0");
|
|
27
|
+
const parsed: PorcelainEntry[] = [];
|
|
28
|
+
for (let i = 0; i < entries.length; i++) {
|
|
29
|
+
const entry = entries[i] ?? "";
|
|
30
|
+
if (entry.length < 4) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const status = entry.substring(0, 2);
|
|
34
|
+
const path = entry.substring(3);
|
|
35
|
+
if (status[0] === "R" || status[0] === "C") {
|
|
36
|
+
i++;
|
|
37
|
+
const origin = entries[i];
|
|
38
|
+
if (origin && origin.length > 0) {
|
|
39
|
+
parsed.push({ status, path, origin });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
parsed.push({ status, path });
|
|
44
|
+
}
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Every path git status knows about, including rename/copy origins.
|
|
50
|
+
* Origins still need to be staged so a deletion is not left behind when a
|
|
51
|
+
* rename is split across add batches.
|
|
52
|
+
*/
|
|
53
|
+
export function collectDirtyPathsFromPorcelain(stdout: string): string[] {
|
|
54
|
+
const paths: string[] = [];
|
|
55
|
+
const seen = new Set<string>();
|
|
56
|
+
for (const entry of parsePorcelainZ(stdout)) {
|
|
57
|
+
for (const path of [entry.path, entry.origin]) {
|
|
58
|
+
if (!path || seen.has(path)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
seen.add(path);
|
|
62
|
+
paths.push(path);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return paths;
|
|
66
|
+
}
|
|
@@ -17,6 +17,10 @@ import { getLogger } from "../util/logger.js";
|
|
|
17
17
|
import { Mutex } from "../util/mutex.js";
|
|
18
18
|
import { addToPathEnv, getExtraToolPathDirs } from "../util/platform.js";
|
|
19
19
|
import { PromiseGuard } from "../util/promise-guard.js";
|
|
20
|
+
import {
|
|
21
|
+
collectDirtyPathsFromPorcelain,
|
|
22
|
+
parsePorcelainZ,
|
|
23
|
+
} from "./git-porcelain.js";
|
|
20
24
|
|
|
21
25
|
const execFileAsync = promisify(execFile);
|
|
22
26
|
const log = getLogger("workspace-git");
|
|
@@ -51,7 +55,7 @@ function cleanGitEnv(workspaceDir: string): Record<string, string> {
|
|
|
51
55
|
* Patterns excluded from workspace git tracking.
|
|
52
56
|
* These are written to .gitignore on init and appended to existing .gitignore files.
|
|
53
57
|
*/
|
|
54
|
-
const WORKSPACE_GITIGNORE_RULES = [
|
|
58
|
+
export const WORKSPACE_GITIGNORE_RULES = [
|
|
55
59
|
// Runtime state directories
|
|
56
60
|
"data/db/",
|
|
57
61
|
"data/qdrant/",
|
|
@@ -226,59 +230,6 @@ done
|
|
|
226
230
|
exit 0
|
|
227
231
|
`;
|
|
228
232
|
|
|
229
|
-
/**
|
|
230
|
-
* Parse NUL-terminated `git status --porcelain -z` output into status/path
|
|
231
|
-
* pairs. NUL termination is required so paths with special characters
|
|
232
|
-
* (non-ASCII, quotes, newlines) arrive verbatim instead of C-style quoted.
|
|
233
|
-
* A rename/copy record is followed by a bare origin-path entry, which is
|
|
234
|
-
* skipped.
|
|
235
|
-
*/
|
|
236
|
-
function parsePorcelainZ(
|
|
237
|
-
stdout: string,
|
|
238
|
-
): Array<{ status: string; path: string }> {
|
|
239
|
-
const entries = stdout.split("\0");
|
|
240
|
-
const parsed: Array<{ status: string; path: string }> = [];
|
|
241
|
-
for (let i = 0; i < entries.length; i++) {
|
|
242
|
-
const entry = entries[i] ?? "";
|
|
243
|
-
if (entry.length < 4) {
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
const status = entry.substring(0, 2);
|
|
247
|
-
parsed.push({ status, path: entry.substring(3) });
|
|
248
|
-
if (status[0] === "R" || status[0] === "C") {
|
|
249
|
-
i++;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return parsed;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Every path git status knows about, including rename/copy origins.
|
|
257
|
-
* Origins are skipped by {@link parsePorcelainZ} (they have no status
|
|
258
|
-
* prefix) but still need to be staged so a deletion is not left behind
|
|
259
|
-
* when a rename is split across add batches.
|
|
260
|
-
*/
|
|
261
|
-
function collectDirtyPathsFromPorcelain(stdout: string): string[] {
|
|
262
|
-
const entries = stdout.split("\0");
|
|
263
|
-
const paths: string[] = [];
|
|
264
|
-
for (let i = 0; i < entries.length; i++) {
|
|
265
|
-
const entry = entries[i] ?? "";
|
|
266
|
-
if (entry.length < 4) {
|
|
267
|
-
continue;
|
|
268
|
-
}
|
|
269
|
-
const status = entry.substring(0, 2);
|
|
270
|
-
paths.push(entry.substring(3));
|
|
271
|
-
if (status[0] === "R" || status[0] === "C") {
|
|
272
|
-
i++;
|
|
273
|
-
const origin = entries[i];
|
|
274
|
-
if (origin && origin.length > 0) {
|
|
275
|
-
paths.push(origin);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
return paths;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
233
|
/** Properties added by Node's child_process errors. */
|
|
283
234
|
interface ExecError extends Error {
|
|
284
235
|
killed?: boolean;
|
|
@@ -433,7 +384,7 @@ export class WorkspaceGitService {
|
|
|
433
384
|
*
|
|
434
385
|
* This method is always called inside the mutex, so no git operation from
|
|
435
386
|
* our code can be concurrently holding the lock. However, an external git
|
|
436
|
-
* process (user running `git add`, IDE tooling, etc.) could legitimately
|
|
387
|
+
* git process (user running `git add`, IDE tooling, etc.) could legitimately
|
|
437
388
|
* hold the lock. We use `lsof` to check — if any process has the file
|
|
438
389
|
* open, we leave it alone. If no process holds it, it's stale (crashed
|
|
439
390
|
* process) and safe to remove.
|