@vellumai/assistant 0.12.1-dev.202609141913.5e16607 → 0.12.1-staging.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.
Files changed (439) hide show
  1. package/AGENTS.md +0 -4
  2. package/ARCHITECTURE.md +12 -11
  3. package/docs/architecture/turn-actor.md +8 -15
  4. package/docs/guardian-request-flow.md +0 -16
  5. package/openapi.yaml +49 -291
  6. package/package.json +1 -1
  7. package/src/__tests__/always-loaded-tools-guard.test.ts +10 -18
  8. package/src/__tests__/app-compiler.test.ts +0 -6
  9. package/src/__tests__/app-control-tool-schemas.test.ts +2 -5
  10. package/src/__tests__/app-dir-path-guard.test.ts +3 -1
  11. package/src/__tests__/app-source-watcher.test.ts +218 -0
  12. package/src/{calls/__tests__ → __tests__}/call-controller.test.ts +82 -503
  13. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +2 -5
  14. package/src/__tests__/computer-use-tools.test.ts +5 -17
  15. package/src/__tests__/config-schema-cmd.test.ts +2 -2
  16. package/src/__tests__/config-schema.test.ts +29 -28
  17. package/src/__tests__/config-watcher-skill-reseed.test.ts +359 -0
  18. package/src/__tests__/config-watcher.test.ts +8 -23
  19. package/src/__tests__/connection-model-compat.test.ts +2 -2
  20. package/src/__tests__/conversation-key-store-disk-view.test.ts +1 -1
  21. package/src/__tests__/conversation-pairing.test.ts +0 -26
  22. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +10 -4
  23. package/src/__tests__/conversation-queue.test.ts +207 -48
  24. package/src/__tests__/conversation-retry-discard.test.ts +1 -54
  25. package/src/__tests__/conversation-skill-tools.test.ts +0 -27
  26. package/src/__tests__/conversation-surfaces-app-control.test.ts +3 -8
  27. package/src/__tests__/conversation-surfaces-task-progress.test.ts +0 -67
  28. package/src/__tests__/conversation-title-service.test.ts +10 -14
  29. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +5 -3
  30. package/src/__tests__/conversation-tool-setup-attribution.test.ts +0 -51
  31. package/src/__tests__/credential-record-retire.test.ts +1 -171
  32. package/src/__tests__/credential-routes.test.ts +3 -212
  33. package/src/__tests__/credential-security-invariants.test.ts +2 -4
  34. package/src/__tests__/cu-unified-flow.test.ts +2 -8
  35. package/src/__tests__/document-sync-tags.test.ts +0 -25
  36. package/src/__tests__/drain-kick-guard.test.ts +2 -0
  37. package/src/__tests__/drain-requeue-on-contention.test.ts +6 -0
  38. package/src/__tests__/evict-conversations-for-reload.test.ts +1 -1
  39. package/src/__tests__/host-bash-proxy.test.ts +45 -26
  40. package/src/__tests__/host-browser-proxy.test.ts +17 -6
  41. package/src/__tests__/host-file-proxy-targeted.test.ts +0 -23
  42. package/src/__tests__/host-file-proxy.test.ts +23 -11
  43. package/src/__tests__/host-transfer-proxy-targeted.test.ts +9 -30
  44. package/src/__tests__/llm-catalog-parity.test.ts +0 -25
  45. package/src/__tests__/mcp-auth-routes.test.ts +9 -6
  46. package/src/__tests__/mcp-config-secret-boundary.test.ts +136 -78
  47. package/src/__tests__/mcp-health-check.test.ts +11 -8
  48. package/src/__tests__/mcp-list-plugin-servers.test.ts +10 -8
  49. package/src/{calls/__tests__ → __tests__}/media-stream-audio-transcode.test.ts +1 -1
  50. package/src/{calls/__tests__ → __tests__}/media-stream-output.test.ts +8 -37
  51. package/src/{calls/__tests__ → __tests__}/media-stream-parser.test.ts +1 -1
  52. package/src/{calls/__tests__ → __tests__}/media-stream-server-integration.test.ts +57 -150
  53. package/src/{calls/__tests__ → __tests__}/media-stream-stt-session.test.ts +5 -5
  54. package/src/{calls/__tests__ → __tests__}/media-turn-detector.test.ts +1 -1
  55. package/src/__tests__/messages-after-tiebreaker.test.ts +0 -91
  56. package/src/__tests__/messages-read-boundary-guard.test.ts +1 -1
  57. package/src/__tests__/messaging-send-tool.test.ts +548 -355
  58. package/src/__tests__/model-intents.test.ts +0 -3
  59. package/src/__tests__/notification-vellum-adapter.test.ts +2 -85
  60. package/src/__tests__/outlook-messaging-provider.test.ts +6 -6
  61. package/src/__tests__/platform-callback-registration.test.ts +16 -8
  62. package/src/__tests__/platform-client-verify-credential.test.ts +0 -2
  63. package/src/__tests__/plugin-import-boundary-guard.test.ts +0 -13
  64. package/src/__tests__/script-proxy-certs.test.ts +0 -35
  65. package/src/__tests__/skill-feature-flags-integration.test.ts +1 -1
  66. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  67. package/src/__tests__/speaker-identification.test.ts +56 -0
  68. package/src/__tests__/subagent-tool-gate-mode.test.ts +3 -19
  69. package/src/__tests__/subagent-tools.test.ts +2 -3
  70. package/src/__tests__/telephony-tts-guard.test.ts +3 -38
  71. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +0 -4
  72. package/src/{calls/__tests__/voice-session-bridge-turn-flow.test.ts → __tests__/voice-session-bridge.test.ts} +12 -20
  73. package/src/__tests__/watch-retro-tool-availability.test.ts +17 -8
  74. package/src/__tests__/workspace-git-service.test.ts +0 -26
  75. package/src/acp/__tests__/agent-process.test.ts +4 -258
  76. package/src/acp/__tests__/auth-required.test.ts +0 -96
  77. package/src/acp/__tests__/client-handler.test.ts +2 -90
  78. package/src/acp/__tests__/session-manager-persistence.test.ts +1 -5
  79. package/src/acp/__tests__/session-manager-resume.test.ts +6 -270
  80. package/src/acp/__tests__/session-manager-usage.test.ts +2 -4
  81. package/src/acp/__tests__/session-manager.test.ts +4 -895
  82. package/src/acp/agent-process.test.ts +1 -4
  83. package/src/acp/agent-process.ts +9 -94
  84. package/src/acp/auth-required.ts +1 -50
  85. package/src/acp/auto-install.test.ts +7 -9
  86. package/src/acp/client-handler.ts +3 -16
  87. package/src/acp/resolve-agent.test.ts +6 -220
  88. package/src/acp/resolve-agent.ts +23 -88
  89. package/src/acp/session-manager.test.ts +3 -196
  90. package/src/acp/session-manager.ts +18 -441
  91. package/src/acp/types.ts +5 -50
  92. package/src/api/events/app-files-changed.ts +3 -4
  93. package/src/api/events/notification-intent.ts +0 -2
  94. package/src/api/index.ts +0 -6
  95. package/src/apps/app-store.ts +1 -1
  96. package/src/bundler/app-compiler.ts +0 -15
  97. package/src/calls/__tests__/voice-control-protocol.test.ts +25 -58
  98. package/src/calls/__tests__/voice-session-bridge.test.ts +1 -37
  99. package/src/calls/__tests__/voice-triage-escalate.test.ts +0 -105
  100. package/src/calls/call-constants.ts +4 -24
  101. package/src/calls/call-controller.ts +199 -499
  102. package/src/calls/call-transport.ts +0 -16
  103. package/src/calls/media-stream-output.ts +0 -32
  104. package/src/calls/media-stream-server.ts +30 -82
  105. package/src/calls/media-stream-stt-session.ts +0 -15
  106. package/src/calls/resolve-call-tts-provider.ts +2 -33
  107. package/src/calls/speaker-identification.ts +233 -0
  108. package/src/calls/tts-call-strategy.ts +5 -9
  109. package/src/calls/types.ts +0 -2
  110. package/src/calls/voice-control-protocol.ts +21 -53
  111. package/src/calls/voice-session-bridge.ts +46 -59
  112. package/src/calls/voice-triage-escalate.ts +56 -175
  113. package/src/cli/commands/apps.help.ts +13 -67
  114. package/src/cli/commands/apps.ts +0 -183
  115. package/src/cli/commands/bash.help.ts +13 -8
  116. package/src/cli/commands/bash.ts +25 -7
  117. package/src/cli/commands/channels/index.help.ts +2 -70
  118. package/src/cli/commands/channels/index.ts +3 -16
  119. package/src/cli/commands/credentials.help.ts +2 -6
  120. package/src/cli/commands/credentials.ts +2 -2
  121. package/src/cli/commands/mcp.help.ts +8 -8
  122. package/src/cli/commands/mcp.ts +1 -1
  123. package/src/cli/commands/roadmap.help.ts +1 -5
  124. package/src/cli/commands/roadmap.ts +1 -1
  125. package/src/cli/lib/bundled-marketplace.json +90 -103
  126. package/src/config/__tests__/default-profile-catalog.test.ts +0 -22
  127. package/src/config/__tests__/memory-retrospective-schema.test.ts +1 -15
  128. package/src/config/__tests__/platform-rehydration.test.ts +9 -99
  129. package/src/config/acp-defaults.test.ts +3 -13
  130. package/src/config/acp-defaults.ts +6 -23
  131. package/src/config/acp-schema.ts +2 -30
  132. package/src/config/bundled-skills/acp/SKILL.md +14 -22
  133. package/src/config/bundled-skills/acp/TOOLS.json +1 -5
  134. package/src/config/bundled-skills/app-builder/SKILL.md +9 -12
  135. package/src/config/bundled-skills/app-builder/references/CUSTOM_ROUTES.md +1 -1
  136. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  137. package/src/config/bundled-skills/messaging/TOOLS.json +3 -3
  138. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +139 -67
  139. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +1 -1
  140. package/src/config/bundled-skills/schedule/SKILL.md +4 -3
  141. package/src/config/bundled-skills/screen-annotation/SKILL.md +1 -8
  142. package/src/config/bundled-skills/screen-annotation/tools/screen-annotation.test.ts +1 -4
  143. package/src/config/bundled-skills/skill-management/TOOLS.json +2 -2
  144. package/src/config/default-profile-catalog.ts +1 -1
  145. package/src/config/env.ts +2 -2
  146. package/src/config/feature-flag-registry.json +12 -24
  147. package/src/config/loader.ts +0 -1
  148. package/src/config/memory-v3-gate.test.ts +0 -31
  149. package/src/config/memory-v3-gate.ts +16 -20
  150. package/src/config/platform-rehydration.ts +27 -11
  151. package/src/config/schema.ts +2 -2
  152. package/src/config/schemas/__tests__/live-voice.test.ts +158 -8
  153. package/src/config/schemas/calls.ts +28 -1
  154. package/src/config/schemas/live-voice.ts +173 -1
  155. package/src/config/schemas/mcp.ts +1 -1
  156. package/src/config/schemas/memory-retrospective.ts +0 -10
  157. package/src/config/schemas/services.ts +0 -8
  158. package/src/config/schemas/skills.ts +14 -0
  159. package/src/credential-execution/process-manager.test.ts +19 -18
  160. package/src/daemon/__tests__/conversation-tool-setup.test.ts +121 -66
  161. package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +1 -4
  162. package/src/daemon/app-source-watcher.ts +218 -0
  163. package/src/daemon/config-watcher.ts +194 -13
  164. package/src/daemon/conversation-process.ts +64 -35
  165. package/src/daemon/conversation-skill-tools.ts +31 -13
  166. package/src/daemon/conversation-store.ts +1 -1
  167. package/src/daemon/conversation-surfaces.ts +8 -10
  168. package/src/daemon/conversation-tool-setup.ts +43 -37
  169. package/src/daemon/conversation.ts +3 -0
  170. package/src/daemon/host-bash-proxy.ts +12 -8
  171. package/src/daemon/host-browser-proxy.ts +1 -15
  172. package/src/daemon/host-file-proxy.ts +10 -8
  173. package/src/daemon/host-transfer-proxy.ts +18 -14
  174. package/src/daemon/lifecycle.ts +5 -0
  175. package/src/daemon/mcp-reload-service.ts +5 -5
  176. package/src/daemon/message-types/sync.ts +0 -1
  177. package/src/daemon/orphan-reaper.ts +1 -1
  178. package/src/daemon/providers-setup.ts +1 -1
  179. package/src/daemon/shutdown-handlers.ts +9 -1
  180. package/src/daemon/skill-memory-refresh.ts +0 -64
  181. package/src/daemon/tool-side-effects.ts +18 -7
  182. package/src/home/__tests__/feed-writer.test.ts +0 -22
  183. package/src/home/feed-writer.ts +2 -11
  184. package/src/hooks/types.ts +0 -33
  185. package/src/inbound/platform-callback-registration.ts +5 -4
  186. package/src/live-voice/__tests__/live-voice-metrics.test.ts +3 -0
  187. package/src/live-voice/__tests__/live-voice-progress.test.ts +15 -15
  188. package/src/live-voice/__tests__/live-voice-vad.test.ts +2 -2
  189. package/src/{calls → live-voice}/__tests__/progress-narration.test.ts +4 -4
  190. package/src/{calls → live-voice}/__tests__/progress-phrases.test.ts +1 -1
  191. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +69 -13
  192. package/src/live-voice/live-voice-session.ts +693 -213
  193. package/src/{calls → live-voice}/progress-narration.ts +2 -2
  194. package/src/live-voice/protocol.ts +2 -0
  195. package/src/mcp/__tests__/effective-config.test.ts +2 -2
  196. package/src/mcp/effective-config.ts +3 -3
  197. package/src/mcp/mcp-header-store.ts +45 -29
  198. package/src/mcp/startup.ts +4 -8
  199. package/src/messaging/provider.ts +3 -10
  200. package/src/messaging/providers/callback-routing.ts +0 -18
  201. package/src/messaging/providers/channel-transport.ts +0 -56
  202. package/src/messaging/providers/discord/transport.ts +0 -17
  203. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +17 -6
  204. package/src/messaging/providers/slack/adapter.ts +44 -7
  205. package/src/messaging/providers/slack/transport.ts +0 -16
  206. package/src/messaging/providers/telegram-bot/adapter.ts +48 -1
  207. package/src/messaging/providers/telegram-bot/client.ts +26 -0
  208. package/src/messaging/providers/telegram-bot/transport.ts +0 -20
  209. package/src/messaging/providers/whatsapp/adapter.ts +48 -1
  210. package/src/messaging/providers/whatsapp/client.ts +29 -0
  211. package/src/messaging/providers/whatsapp/transport.ts +0 -18
  212. package/src/monitoring/__tests__/workspace-git-heartbeat.test.ts +0 -8
  213. package/src/notifications/__tests__/assistant-reply-producer.test.ts +0 -55
  214. package/src/notifications/__tests__/guardian-feed-projection.test.ts +2 -158
  215. package/src/notifications/__tests__/home-feed-side-effect.test.ts +3 -153
  216. package/src/notifications/__tests__/schedule-result-producer.test.ts +3 -99
  217. package/src/notifications/adapters/macos.ts +0 -3
  218. package/src/notifications/assistant-reply-producer.ts +3 -8
  219. package/src/notifications/conversation-pairing.ts +16 -36
  220. package/src/notifications/delivered-post-record.ts +1 -11
  221. package/src/notifications/guardian-feed-projection.ts +5 -125
  222. package/src/notifications/home-feed-side-effect.ts +7 -55
  223. package/src/notifications/schedule-result-producer.ts +22 -66
  224. package/src/oauth/__tests__/seed-providers-managed.test.ts +0 -54
  225. package/src/oauth/byo-connection.test.ts +0 -45
  226. package/src/oauth/byo-connection.ts +6 -36
  227. package/src/oauth/connection-resolver.test.ts +0 -73
  228. package/src/oauth/connection-resolver.ts +2 -95
  229. package/src/oauth/seed-providers.ts +0 -165
  230. package/src/outbound-proxy/certs.ts +5 -3
  231. package/src/permissions/checker.test.ts +6 -11
  232. package/src/persistence/compaction-log-store-clickhouse.ts +3 -3
  233. package/src/persistence/conversation-crud.ts +63 -71
  234. package/src/persistence/conversation-lineage.ts +4 -12
  235. package/src/persistence/conversation-title-service.ts +26 -9
  236. package/src/persistence/llm-request-log-sink-clickhouse.ts +3 -3
  237. package/src/persistence/llm-request-log-source-clickhouse.ts +3 -3
  238. package/src/persistence/message-reads.ts +0 -30
  239. package/src/persistence/migrations/157-invite-contact-id.ts +6 -18
  240. package/src/persistence/schema/memory-core.ts +0 -5
  241. package/src/platform/client.test.ts +2 -4
  242. package/src/platform/client.ts +10 -2
  243. package/src/plugin-api/constants.ts +0 -2
  244. package/src/plugin-api/index.ts +0 -1
  245. package/src/plugin-api/types.ts +0 -2
  246. package/src/plugins/defaults/index.ts +0 -2
  247. package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +0 -46
  248. package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +5 -9
  249. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +10 -20
  250. package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +0 -219
  251. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +0 -31
  252. package/src/plugins/defaults/memory/__tests__/memory-retrospective-trigger-check.test.ts +0 -63
  253. package/src/plugins/defaults/memory/__tests__/shutdown-hook.test.ts +0 -4
  254. package/src/plugins/defaults/memory/graph/capability-seed.ts +6 -4
  255. package/src/plugins/defaults/memory/hooks/init.ts +0 -10
  256. package/src/plugins/defaults/memory/hooks/shutdown.ts +0 -2
  257. package/src/plugins/defaults/memory/jobs-worker.ts +0 -13
  258. package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +60 -34
  259. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +5 -3
  260. package/src/plugins/defaults/memory/memory-retrospective-job.ts +3 -12
  261. package/src/plugins/defaults/memory/memory-retrospective-state.ts +71 -312
  262. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +1 -2
  263. package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +3 -5
  264. package/src/plugins/defaults/memory/startup.ts +1 -6
  265. package/src/plugins/defaults/memory/substrate/__tests__/skill-content.test.ts +9 -7
  266. package/src/plugins/defaults/memory/substrate/skill-content.ts +2 -2
  267. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +0 -89
  268. package/src/plugins/defaults/memory/worker.ts +0 -6
  269. package/src/plugins/mcp-servers.ts +75 -15
  270. package/src/providers/__tests__/connection-model-compat.test.ts +3 -3
  271. package/src/providers/gemini/client.ts +23 -9
  272. package/src/providers/inference/auth.ts +3 -2
  273. package/src/providers/inference/connection-availability.ts +8 -27
  274. package/src/providers/inference/resolve-auth.ts +4 -22
  275. package/src/providers/model-catalog.ts +0 -34
  276. package/src/providers/model-intents.ts +5 -10
  277. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +18 -146
  278. package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +1 -83
  279. package/src/providers/openai/chat-completions-provider.ts +78 -192
  280. package/src/providers/openai/codex-models.ts +4 -0
  281. package/src/runtime/AGENTS.md +0 -2
  282. package/src/runtime/auth/same-actor.ts +3 -38
  283. package/src/runtime/http-server.ts +151 -160
  284. package/src/runtime/routes/__tests__/acp-routes.test.ts +4 -159
  285. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -108
  286. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +2 -2
  287. package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +12 -16
  288. package/src/runtime/routes/acp-routes.test.ts +0 -15
  289. package/src/runtime/routes/acp-routes.ts +9 -72
  290. package/src/runtime/routes/app-management-routes.ts +0 -73
  291. package/src/runtime/routes/app-routes.ts +1 -1
  292. package/src/runtime/routes/conversation-list-routes.ts +3 -14
  293. package/src/runtime/routes/conversation-query-routes.ts +0 -40
  294. package/src/runtime/routes/credential-routes.ts +10 -19
  295. package/src/runtime/routes/debug-bash-routes.ts +173 -0
  296. package/src/runtime/routes/diagnostics-routes.ts +3 -55
  297. package/src/runtime/routes/index.ts +2 -4
  298. package/src/runtime/routes/log-export-routes.ts +0 -2
  299. package/src/runtime/routes/mcp-auth-routes.ts +47 -39
  300. package/src/runtime/routes/migration-routes.ts +20 -6
  301. package/src/runtime/routes/platform-routes.ts +15 -18
  302. package/src/runtime/services/__tests__/conversation-serializer.test.ts +0 -28
  303. package/src/runtime/services/conversation-serializer.ts +3 -16
  304. package/src/runtime/sync/resource-sync-events.ts +1 -2
  305. package/src/schedule/worker.ts +1 -1
  306. package/src/security/ces-rpc-record-backend.ts +0 -7
  307. package/src/subagent/consult-context.ts +25 -12
  308. package/src/tools/acp/list-agents.test.ts +1 -3
  309. package/src/tools/acp/spawn.test.ts +11 -146
  310. package/src/tools/acp/spawn.ts +3 -21
  311. package/src/tools/acp/status.ts +3 -40
  312. package/src/tools/app-control/skill-proxy-bridge.ts +1 -2
  313. package/src/tools/capability-offer.test.ts +2 -22
  314. package/src/tools/capability-offer.ts +1 -16
  315. package/src/tools/computer-use/definitions.ts +2 -4
  316. package/src/tools/computer-use/skill-proxy-bridge.ts +1 -2
  317. package/src/tools/credentials/metadata-store.ts +0 -100
  318. package/src/tools/host-filesystem/edit.test.ts +1 -2
  319. package/src/tools/host-filesystem/edit.ts +2 -2
  320. package/src/tools/host-filesystem/read.test.ts +1 -2
  321. package/src/tools/host-filesystem/read.ts +2 -2
  322. package/src/tools/host-filesystem/transfer.test.ts +1 -2
  323. package/src/tools/host-filesystem/transfer.ts +2 -2
  324. package/src/tools/host-filesystem/write.test.ts +1 -2
  325. package/src/tools/host-filesystem/write.ts +2 -2
  326. package/src/tools/host-terminal/host-shell.test.ts +0 -16
  327. package/src/tools/host-terminal/host-shell.ts +20 -4
  328. package/src/tools/policy-context.ts +7 -6
  329. package/src/tools/subagent/spawn.ts +8 -5
  330. package/src/tools/watch/watch-retro-report.ts +8 -0
  331. package/src/util/__tests__/language-subtag.test.ts +1 -23
  332. package/src/util/fs-watcher-error.ts +36 -0
  333. package/src/util/language-subtag.ts +0 -16
  334. package/src/util/platform.ts +0 -8
  335. package/src/workspace/git-service.ts +54 -5
  336. package/src/workspace/migrations/registry.ts +0 -6
  337. package/scripts/smoke-desktop-window-theme.ts +0 -186
  338. package/src/__tests__/git-porcelain.test.ts +0 -47
  339. package/src/__tests__/helpers/set-workspace-mcp.ts +0 -11
  340. package/src/__tests__/message-deleted-hook-dispatch.test.ts +0 -119
  341. package/src/__tests__/resolve-app.test.ts +0 -135
  342. package/src/__tests__/service-account-token.test.ts +0 -247
  343. package/src/__tests__/source-fingerprint.test.ts +0 -184
  344. package/src/__tests__/workspace-migration-154-repair-retired-codex-gpt-5-4-model-ids.test.ts +0 -336
  345. package/src/acp/__tests__/helpers/acp-model-option.ts +0 -51
  346. package/src/acp/model-config.test.ts +0 -166
  347. package/src/acp/model-config.ts +0 -138
  348. package/src/api/events/acp-session-model-update.test.ts +0 -88
  349. package/src/api/events/acp-session-model-update.ts +0 -46
  350. package/src/apps/resolve-app.ts +0 -81
  351. package/src/apps/source-fingerprint.ts +0 -266
  352. package/src/calls/__tests__/barge-in-guard.test.ts +0 -81
  353. package/src/calls/__tests__/voice-leg-coordinator.test.ts +0 -229
  354. package/src/calls/__tests__/voice-progress-cadence.test.ts +0 -274
  355. package/src/calls/barge-in-guard.ts +0 -118
  356. package/src/calls/voice-leg-coordinator.ts +0 -189
  357. package/src/calls/voice-progress-cadence.ts +0 -423
  358. package/src/cli/commands/__tests__/apps.test.ts +0 -245
  359. package/src/cli/commands/__tests__/bash.test.ts +0 -53
  360. package/src/cli/commands/__tests__/roadmap.help.test.ts +0 -19
  361. package/src/cli/commands/channels/__tests__/send.test.ts +0 -218
  362. package/src/cli/commands/channels/send.ts +0 -128
  363. package/src/config/__tests__/platform-identity.test.ts +0 -255
  364. package/src/config/acp-agent-write.ts +0 -43
  365. package/src/config/acp-schema.test.ts +0 -81
  366. package/src/config/platform-identity.ts +0 -201
  367. package/src/config/schemas/__tests__/voice.test.ts +0 -148
  368. package/src/config/schemas/voice.ts +0 -150
  369. package/src/daemon/__tests__/skill-memory-refresh-mtime.test.ts +0 -133
  370. package/src/daemon/app-change-notify.ts +0 -45
  371. package/src/desktop/__tests__/fake-desktop.ts +0 -119
  372. package/src/desktop/desktop-chrome-policy.test.ts +0 -71
  373. package/src/desktop/desktop-chrome-policy.ts +0 -42
  374. package/src/desktop/desktop-dependencies.test.ts +0 -102
  375. package/src/desktop/desktop-dependencies.ts +0 -306
  376. package/src/desktop/desktop-feature.test.ts +0 -18
  377. package/src/desktop/desktop-feature.ts +0 -19
  378. package/src/desktop/desktop-panel-config.test.ts +0 -135
  379. package/src/desktop/desktop-panel-config.ts +0 -149
  380. package/src/desktop/desktop-session-manager.test.ts +0 -627
  381. package/src/desktop/desktop-session-manager.ts +0 -814
  382. package/src/desktop/desktop-stream-bridge.test.ts +0 -395
  383. package/src/desktop/desktop-stream-bridge.ts +0 -214
  384. package/src/desktop/desktop-wallpaper.test.ts +0 -191
  385. package/src/desktop/desktop-wallpaper.ts +0 -113
  386. package/src/desktop/desktop-window-theme.ts +0 -170
  387. package/src/i18n/AGENTS.md +0 -22
  388. package/src/i18n/__tests__/i18n.test.ts +0 -108
  389. package/src/i18n/index.ts +0 -16
  390. package/src/i18n/locales.ts +0 -93
  391. package/src/i18n/messages.ts +0 -61
  392. package/src/i18n/title.ts +0 -25
  393. package/src/mcp/__tests__/workspace-mcp-config.test.ts +0 -135
  394. package/src/mcp/spec-schema.ts +0 -111
  395. package/src/mcp/workspace-mcp-config.ts +0 -188
  396. package/src/messaging/providers/__tests__/proactive-address.test.ts +0 -95
  397. package/src/persistence/conversation-title-placeholders.ts +0 -23
  398. package/src/persistence/message-cursor.ts +0 -78
  399. package/src/persistence/migrations/__tests__/157-invite-contact-id.test.ts +0 -149
  400. package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-backfill.test.ts +0 -118
  401. package/src/plugins/defaults/memory/__tests__/memory-retrospective-cursor-preserve.test.ts +0 -83
  402. package/src/plugins/defaults/memory/hooks/message-deleted.ts +0 -21
  403. package/src/plugins/defaults/memory/memory-retrospective-cursor-backfill.ts +0 -126
  404. package/src/plugins/defaults/memory/memory-retrospective-cursor-preserve.ts +0 -79
  405. package/src/plugins/defaults/memory/memory-retrospective-cursor.ts +0 -28
  406. package/src/plugins/defaults/memory/skill-md-mtime-poll.ts +0 -9
  407. package/src/providers/gemini-thought-signature.test.ts +0 -63
  408. package/src/providers/gemini-thought-signature.ts +0 -44
  409. package/src/providers/inference/service-account-token.ts +0 -248
  410. package/src/providers/openai/__tests__/chat-completions-provider-thought-signature.test.ts +0 -613
  411. package/src/providers/openai/__tests__/google-thought-signature.test.ts +0 -235
  412. package/src/providers/openai/google-thought-signature.ts +0 -320
  413. package/src/runtime/__tests__/channel-send.test.ts +0 -443
  414. package/src/runtime/__tests__/desktop-stream-upgrade.test.ts +0 -89
  415. package/src/runtime/__tests__/live-voice-upgrade.test.ts +0 -58
  416. package/src/runtime/__tests__/runtime-ws-test-utils.ts +0 -72
  417. package/src/runtime/__tests__/watch-stream-upgrade.test.ts +0 -59
  418. package/src/runtime/channel-send.ts +0 -316
  419. package/src/runtime/routes/__tests__/apps-refresh-route.test.ts +0 -205
  420. package/src/runtime/routes/__tests__/channel-send-routes.test.ts +0 -127
  421. package/src/runtime/routes/__tests__/dictation-cleanup-guard.test.ts +0 -107
  422. package/src/runtime/routes/channel-send-routes.ts +0 -85
  423. package/src/runtime/routes/desktop-setup-routes.test.ts +0 -74
  424. package/src/runtime/routes/desktop-setup-routes.ts +0 -35
  425. package/src/security/__tests__/ces-http-record-backend.test.ts +0 -137
  426. package/src/security/ces-http-record-backend.ts +0 -120
  427. package/src/skills/__tests__/workspace-skill-md-signature.test.ts +0 -60
  428. package/src/skills/workspace-skill-md-signature.ts +0 -50
  429. package/src/tools/acp/status.test.ts +0 -94
  430. package/src/tools/terminal/__tests__/sanitized-bash.test.ts +0 -57
  431. package/src/tools/terminal/sanitized-bash.ts +0 -105
  432. package/src/util/ca-bundle.ts +0 -13
  433. package/src/workspace/git-porcelain.ts +0 -66
  434. package/src/workspace/migrations/154-repair-retired-codex-gpt-5-4-model-ids.ts +0 -258
  435. package/src/workspace/migrations/155-move-front-model-config-to-voice.ts +0 -78
  436. package/src/workspace/migrations/156-extract-workspace-mcp-json.ts +0 -214
  437. package/src/workspace/migrations/__tests__/155-move-front-model-config-to-voice.test.ts +0 -102
  438. package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +0 -199
  439. /package/src/{calls → live-voice}/progress-phrases.ts +0 -0
@@ -27,8 +27,6 @@ const {
27
27
  setPlatformOrganizationId,
28
28
  setPlatformUserId,
29
29
  } = await import("../env.js");
30
- const { _resetPlatformIdentityEnsureForTests } =
31
- await import("../platform-identity.js");
32
30
  const { rehydratePlatformCredentials } =
33
31
  await import("../platform-rehydration.js");
34
32
 
@@ -41,44 +39,23 @@ describe("rehydratePlatformCredentials", () => {
41
39
  const originalPlatformUrlEnv = process.env.VELLUM_PLATFORM_URL;
42
40
  const originalOrgEnv = process.env.PLATFORM_ORGANIZATION_ID;
43
41
  const originalUserEnv = process.env.PLATFORM_USER_ID;
44
- const originalAssistantApiKeyEnv = process.env.ASSISTANT_API_KEY;
45
- const originalFetch = globalThis.fetch;
46
- const fetchCalls: Array<{ url: string; init?: RequestInit }> = [];
47
- let fetchImpl: (
48
- input: RequestInfo | URL,
49
- init?: RequestInit,
50
- ) => Promise<Response> = async () =>
51
- new Response("not found", { status: 404 });
52
42
 
53
43
  beforeEach(() => {
54
44
  mockSecureKeys = {};
55
45
  throwForKey = undefined;
56
- fetchCalls.length = 0;
57
- fetchImpl = async () => new Response("not found", { status: 404 });
58
- globalThis.fetch = (async (
59
- input: RequestInfo | URL,
60
- init?: RequestInit,
61
- ) => {
62
- const url = typeof input === "string" ? input : input.toString();
63
- fetchCalls.push({ url, init });
64
- return fetchImpl(input, init);
65
- }) as unknown as typeof fetch;
66
46
  // Env vars take precedence over the rehydrated overrides for some fields;
67
47
  // clear them so the credential-store values are what we observe.
68
48
  delete process.env.VELLUM_PLATFORM_URL;
69
49
  delete process.env.PLATFORM_ORGANIZATION_ID;
70
50
  delete process.env.PLATFORM_USER_ID;
71
- delete process.env.ASSISTANT_API_KEY;
72
51
  // Reset in-memory overrides between tests.
73
52
  setPlatformBaseUrl(undefined);
74
53
  setPlatformAssistantId(undefined);
75
54
  setPlatformOrganizationId(undefined);
76
55
  setPlatformUserId(undefined);
77
- _resetPlatformIdentityEnsureForTests();
78
56
  });
79
57
 
80
58
  afterEach(() => {
81
- globalThis.fetch = originalFetch;
82
59
  if (originalPlatformUrlEnv === undefined) {
83
60
  delete process.env.VELLUM_PLATFORM_URL;
84
61
  } else {
@@ -94,18 +71,13 @@ describe("rehydratePlatformCredentials", () => {
94
71
  } else {
95
72
  process.env.PLATFORM_USER_ID = originalUserEnv;
96
73
  }
97
- if (originalAssistantApiKeyEnv === undefined) {
98
- delete process.env.ASSISTANT_API_KEY;
99
- } else {
100
- process.env.ASSISTANT_API_KEY = originalAssistantApiKeyEnv;
101
- }
102
74
  setPlatformBaseUrl(undefined);
103
75
  setPlatformAssistantId(undefined);
104
76
  setPlatformOrganizationId(undefined);
105
77
  setPlatformUserId(undefined);
106
78
  });
107
79
 
108
- test("rehydrates the platform base URL from the credential store", async () => {
80
+ test("rehydrates base URL and all platform IDs from the credential store", async () => {
109
81
  mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
110
82
  mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
111
83
  ASSISTANT_ID;
@@ -116,18 +88,21 @@ describe("rehydratePlatformCredentials", () => {
116
88
  await rehydratePlatformCredentials();
117
89
 
118
90
  expect(getPlatformBaseUrl()).toBe(PROD_URL);
119
- expect(getPlatformAssistantId()).toBe("");
120
- expect(getPlatformOrganizationId()).toBe("");
121
- expect(getPlatformUserId()).toBe("");
91
+ expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
92
+ expect(getPlatformOrganizationId()).toBe(ORG_ID);
93
+ expect(getPlatformUserId()).toBe(USER_ID);
122
94
  });
123
95
 
124
96
  test("trims stored values before applying them", async () => {
125
97
  mockSecureKeys[credentialKey("vellum", "platform_base_url")] =
126
98
  ` ${PROD_URL} `;
99
+ mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
100
+ `\n${ASSISTANT_ID}\n`;
127
101
 
128
102
  await rehydratePlatformCredentials();
129
103
 
130
104
  expect(getPlatformBaseUrl()).toBe(PROD_URL);
105
+ expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
131
106
  });
132
107
 
133
108
  test("leaves overrides untouched when nothing is stored", async () => {
@@ -138,78 +113,13 @@ describe("rehydratePlatformCredentials", () => {
138
113
  expect(getPlatformUserId()).toBe("");
139
114
  });
140
115
 
141
- test("a credential-store read failure does not throw", async () => {
116
+ test("a per-field read failure does not block the remaining fields", async () => {
142
117
  throwForKey = credentialKey("vellum", "platform_base_url");
143
-
144
- await expect(rehydratePlatformCredentials()).resolves.toBeUndefined();
145
- expect(getPlatformAssistantId()).toBe("");
146
- });
147
-
148
- test("trades the assistant API key for ids via platform validate", async () => {
149
- mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
150
- mockSecureKeys[credentialKey("vellum", "assistant_api_key")] =
151
- "assistant-key";
152
- fetchImpl = async () =>
153
- new Response(
154
- JSON.stringify({
155
- assistant_id: ASSISTANT_ID,
156
- organization_id: ORG_ID,
157
- user_id: USER_ID,
158
- }),
159
- { status: 200 },
160
- );
161
-
162
- await rehydratePlatformCredentials();
163
-
164
- expect(fetchCalls).toHaveLength(1);
165
- expect(fetchCalls[0]?.url).toBe(
166
- `${PROD_URL}/v1/internal/assistants/validate/`,
167
- );
168
- const headers = new Headers(fetchCalls[0]?.init?.headers);
169
- expect(headers.get("Authorization")).toBe("Api-Key assistant-key");
170
- expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
171
- expect(getPlatformOrganizationId()).toBe(ORG_ID);
172
- expect(getPlatformUserId()).toBe(USER_ID);
173
- });
174
-
175
- test("validate ids are used when the vault also has a copy", async () => {
176
- mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
177
- mockSecureKeys[credentialKey("vellum", "assistant_api_key")] =
178
- "assistant-key";
179
- mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
180
- "asst-from-vault";
181
- fetchImpl = async () =>
182
- new Response(
183
- JSON.stringify({
184
- assistant_id: ASSISTANT_ID,
185
- organization_id: ORG_ID,
186
- user_id: USER_ID,
187
- }),
188
- { status: 200 },
189
- );
190
-
191
- await rehydratePlatformCredentials();
192
-
193
- expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
194
- });
195
-
196
- test("does not populate ids from the vault when validate is unreachable", async () => {
197
- mockSecureKeys[credentialKey("vellum", "platform_base_url")] = PROD_URL;
198
- mockSecureKeys[credentialKey("vellum", "assistant_api_key")] =
199
- "assistant-key";
200
118
  mockSecureKeys[credentialKey("vellum", "platform_assistant_id")] =
201
119
  ASSISTANT_ID;
202
- mockSecureKeys[credentialKey("vellum", "platform_organization_id")] =
203
- ORG_ID;
204
- mockSecureKeys[credentialKey("vellum", "platform_user_id")] = USER_ID;
205
- fetchImpl = async () => {
206
- throw new Error("network down");
207
- };
208
120
 
209
121
  await rehydratePlatformCredentials();
210
122
 
211
- expect(getPlatformAssistantId()).toBe("");
212
- expect(getPlatformOrganizationId()).toBe("");
213
- expect(getPlatformUserId()).toBe("");
123
+ expect(getPlatformAssistantId()).toBe(ASSISTANT_ID);
214
124
  });
215
125
  });
@@ -13,17 +13,15 @@ describe("DEFAULT_ACP_AGENT_PROFILES", () => {
13
13
  ]);
14
14
  });
15
15
 
16
- test("claude profile uses the @agentclientprotocol adapter binary on opus", () => {
16
+ test("claude profile uses the @agentclientprotocol adapter binary", () => {
17
17
  expect(DEFAULT_ACP_AGENT_PROFILES.claude).toEqual({
18
18
  command: "claude-agent-acp",
19
19
  args: [],
20
20
  description: "Claude Code (via @agentclientprotocol/claude-agent-acp)",
21
- model: "opus",
22
21
  });
23
22
  });
24
23
 
25
24
  test("codex profile uses the @agentclientprotocol adapter binary", () => {
26
- // No model: Codex aliases are its own, so the adapter's default stands.
27
25
  expect(DEFAULT_ACP_AGENT_PROFILES.codex).toEqual({
28
26
  command: "codex-acp",
29
27
  args: [],
@@ -46,19 +44,11 @@ describe("DEFAULT_ACP_AGENT_PROFILES", () => {
46
44
  describe("DEFAULT_AGENT_NPM_PACKAGES", () => {
47
45
  test("is keyed by command name with the canonical npm package", () => {
48
46
  expect(DEFAULT_AGENT_NPM_PACKAGES).toEqual({
49
- "claude-agent-acp": "@agentclientprotocol/claude-agent-acp@0.75.1",
50
- "codex-acp": "@agentclientprotocol/codex-acp@1.10.0",
47
+ "claude-agent-acp": "@agentclientprotocol/claude-agent-acp",
48
+ "codex-acp": "@agentclientprotocol/codex-acp",
51
49
  });
52
50
  });
53
51
 
54
- test("every package spec pins an exact version", () => {
55
- // A bare name would let a clean install resolve whatever npm calls
56
- // latest, which is what the repo's pinning rule exists to prevent.
57
- for (const spec of Object.values(DEFAULT_AGENT_NPM_PACKAGES)) {
58
- expect(spec).toMatch(/^@?[^@]+@\d+\.\d+\.\d+$/);
59
- }
60
- });
61
-
62
52
  test("every default profile's command has a matching npm package", () => {
63
53
  for (const profile of Object.values(DEFAULT_ACP_AGENT_PROFILES)) {
64
54
  expect(DEFAULT_AGENT_NPM_PACKAGES[profile.command]).toBeDefined();
@@ -1,11 +1,5 @@
1
1
  import type { AcpAgentConfig } from "./acp-schema.js";
2
2
 
3
- /**
4
- * A bundled profile always names its command; a user entry for the same id
5
- * may omit `command` and inherit this one.
6
- */
7
- export type AcpAgentProfile = AcpAgentConfig & { command: string };
8
-
9
3
  // Shared frozen empty args array — these defaults are read by every ACP spawn,
10
4
  // so a single accidental `args.push(...)` from one caller would corrupt every
11
5
  // subsequent read. Cast through `unknown` because `AcpAgentConfig.args` is
@@ -19,22 +13,17 @@ const FROZEN_EMPTY_ARGS = Object.freeze([] as string[]) as unknown as string[];
19
13
  * falls back to this map so common agents like `claude` and `codex` Just Work
20
14
  * without requiring per-user config.
21
15
  *
22
- * A profile's `model` is the model a session of that agent starts on when the
23
- * ask names none, and is the rung `acp.agents.<id>.model` fills: a user config
24
- * entry that names a model overrides it, one that omits it inherits it.
25
- *
26
- * Keyed by agent id. Deeply frozen: the outer object, each profile, and the
27
- * `args` arrays, so mutation throws in strict mode rather than silently
16
+ * Keyed by agent id. Deeply frozen — the outer object, each profile, and the
17
+ * `args` arrays — so mutation throws in strict mode rather than silently
28
18
  * corrupting the shared defaults.
29
19
  */
30
20
  export const DEFAULT_ACP_AGENT_PROFILES: Readonly<
31
- Record<string, AcpAgentProfile>
21
+ Record<string, AcpAgentConfig>
32
22
  > = Object.freeze({
33
23
  claude: Object.freeze({
34
24
  command: "claude-agent-acp",
35
25
  args: FROZEN_EMPTY_ARGS,
36
26
  description: "Claude Code (via @agentclientprotocol/claude-agent-acp)",
37
- model: "opus",
38
27
  }),
39
28
  codex: Object.freeze({
40
29
  command: "codex-acp",
@@ -44,21 +33,15 @@ export const DEFAULT_ACP_AGENT_PROFILES: Readonly<
44
33
  });
45
34
 
46
35
  /**
47
- * Single source of truth for adapter binary → npm package spec. Automatic
36
+ * Single source of truth for adapter binary → npm package name. Automatic
48
37
  * installation and the resolver's install hints use this map, so a new
49
38
  * adapter only needs one entry here.
50
39
  *
51
40
  * Keyed by command name (not agent id) so the mapping follows the binary
52
41
  * regardless of how a user's config aliases an agent.
53
- *
54
- * Values carry an exact version, so a clean install lands the adapter version
55
- * the daemon was tested against instead of whatever npm calls latest today.
56
- * An adapter already on PATH is left alone: installation runs only when
57
- * preflight found no binary at all, so this never moves a version the user
58
- * installed themselves.
59
42
  */
60
43
  export const DEFAULT_AGENT_NPM_PACKAGES: Readonly<Record<string, string>> =
61
44
  Object.freeze({
62
- "claude-agent-acp": "@agentclientprotocol/claude-agent-acp@0.75.1",
63
- "codex-acp": "@agentclientprotocol/codex-acp@1.10.0",
45
+ "claude-agent-acp": "@agentclientprotocol/claude-agent-acp",
46
+ "codex-acp": "@agentclientprotocol/codex-acp",
64
47
  });
@@ -1,15 +1,8 @@
1
1
  import { z } from "zod";
2
2
 
3
- import { DEFAULT_ACP_AGENT_PROFILES } from "./acp-defaults.js";
4
-
5
- export const AcpAgentConfigSchema = z
3
+ const AcpAgentConfigSchema = z
6
4
  .object({
7
- command: z
8
- .string()
9
- .optional()
10
- .describe(
11
- "Command to spawn the ACP agent process. Required unless the id has a bundled profile, whose command is inherited when this is unset",
12
- ),
5
+ command: z.string().describe("Command to spawn the ACP agent process"),
13
6
  args: z
14
7
  .array(z.string())
15
8
  .default([])
@@ -22,12 +15,6 @@ export const AcpAgentConfigSchema = z
22
15
  .record(z.string(), z.string())
23
16
  .optional()
24
17
  .describe("Environment variables set for the agent process"),
25
- model: z
26
- .string()
27
- .optional()
28
- .describe(
29
- "Model sessions of this agent start on when the ask names none (an adapter-reported alias such as 'opus' or 'sonnet' for Claude, not an Assistant catalog id). Overrides the bundled profile's value; unset inherits it.",
30
- ),
31
18
  })
32
19
  .describe("Configuration for an individual ACP agent");
33
20
 
@@ -43,21 +30,6 @@ export const AcpConfigSchema = z
43
30
  ),
44
31
  agents: z
45
32
  .record(z.string(), AcpAgentConfigSchema)
46
- .superRefine((agents, ctx) => {
47
- for (const [id, agent] of Object.entries(agents)) {
48
- if (
49
- agent.command !== undefined ||
50
- Object.hasOwn(DEFAULT_ACP_AGENT_PROFILES, id)
51
- ) {
52
- continue;
53
- }
54
- ctx.addIssue({
55
- code: "custom",
56
- path: [id, "command"],
57
- message: `acp.agents.${id} needs a command: only the bundled ids (${Object.keys(DEFAULT_ACP_AGENT_PROFILES).join(", ")}) inherit one`,
58
- });
59
- }
60
- })
61
33
  .default({})
62
34
  .describe("Map of agent names to their configurations"),
63
35
  })
@@ -23,18 +23,6 @@ Use `acp_spawn` to delegate a coding task to an external agent. The agent runs a
23
23
 
24
24
  Users can refer to agents by natural names: "claude code", "codex cli", and "openai codex" all resolve to the canonical `claude` and `codex` ids (unless the user's config defines an agent literally keyed by that name, which always wins).
25
25
 
26
- ## Choosing a model
27
-
28
- Claude runs on Opus unless the user names a model; every other agent starts on its own default.
29
-
30
- When the user does name one, pass it as `model` on `acp_spawn`. Model names are the agent's own vocabulary, not Assistant model ids: an alias such as `default`, `sonnet`, `opus`, `haiku`, `fable`, or `opusplan` for Claude, or a full model id. Pass what the user said and let the agent resolve it.
31
-
32
- The spawn result reports `requestedModel` and `effectiveModel`. Treat `effectiveModel` as authoritative for the top-level ACP session. Never infer that model from the task text or from a nested subagent. When `requestedModel` is non-null and differs from `effectiveModel`, state which model the session is actually running on and relay `modelWarning` when present.
33
-
34
- If the agent refuses the model, or advertises no model selector, the spawn result says so: relay it in one sentence and carry on, because the session is live on the agent's own model.
35
-
36
- A session runs on the model it started on, so a different model means a new `acp_spawn`. A standing default per agent lives in the config at `acp.agents.<id>.model`.
37
-
38
26
  ## When the user names Claude Code or Codex
39
27
 
40
28
  If they name Claude Code or Codex without asking you to run it here (for example they say that tool will do the work), offer once, in one short sentence, that you can connect and run it in this conversation. Then continue with whatever they were doing.
@@ -47,23 +35,21 @@ If they name Claude Code or Codex without asking you to run it here (for example
47
35
 
48
36
  ACP is always available - default profiles for `claude` and `codex` ship out-of-box, so no config edit is needed to start. First-time setup is just making the adapter binary available, then spawning:
49
37
 
50
- 1. Install the adapter binary if it's missing. This happens automatically: when `acp_spawn` finds the agent's binary missing from PATH, the assistant installs the pinned version via a sandboxed bun global install and proceeds in the same call (see "Automatic adapter availability" below).
38
+ 1. Install the adapter binary if it's missing. This happens automatically: when `acp_spawn` finds the agent's binary missing from PATH, the assistant installs it once via a sandboxed bun global install and proceeds in the same call (see "Automatic adapter availability" below).
51
39
 
52
40
  2. Call `acp_spawn`. Do NOT run `vellum sleep && vellum wake` - that kills the conversation.
53
41
 
54
42
  ## Automatic adapter availability
55
43
 
56
- When an agent's binary is missing from PATH, the assistant installs the adapter version it was built against via a sandboxed bun global install and then runs the real installed binary. The install runs in a fresh empty temporary directory (never the task's project directory), with known secrets stripped from the installer environment and the registry pinned to the public npm registry, so a malicious project directory cannot hijack package resolution or capture a token.
57
-
58
- An adapter already on PATH is left alone, whoever installed it: the install runs only when preflight found no binary at all.
44
+ When `acp_spawn` finds the agent's binary missing from PATH, the assistant installs it once via a sandboxed bun global install and then runs the real installed binary. The install runs in a fresh empty temporary directory (never the task's project directory), with known secrets stripped from the installer environment and the registry pinned to the public npm registry, so a malicious project directory cannot hijack package resolution or capture a token. After this one-time install, the adapter is a normal trusted binary on PATH and every later spawn (and resume) uses it directly.
59
45
 
60
46
  Only the allowlisted out-of-box packages are ever installed this way (`@agentclientprotocol/claude-agent-acp`, `@agentclientprotocol/codex-acp`); user-configured agents with custom commands are never installed automatically.
61
47
 
62
- Manual installation is fallback guidance for unusual setups: bun unavailable, restricted global installs, or an auto-install failure (the failure reason is surfaced in the tool result). Install the pinned version below rather than `@latest`, so the adapter matches what the assistant was built against.
48
+ Manual installation is fallback guidance for unusual setups: bun unavailable, restricted global installs, or an auto-install failure (the failure reason is surfaced in the tool result).
63
49
 
64
50
  ```bash
65
- bun add -g @agentclientprotocol/claude-agent-acp@0.75.1 # claude
66
- bun add -g @agentclientprotocol/codex-acp@1.10.0 # codex
51
+ bun add -g @agentclientprotocol/claude-agent-acp # claude
52
+ bun add -g @agentclientprotocol/codex-acp # codex
67
53
  ```
68
54
 
69
55
  ## Claude setup
@@ -98,14 +84,20 @@ Do NOT put API keys (or any secret) in the workspace config file - secrets never
98
84
 
99
85
  - Two agents are supported out-of-box: `claude` (via the `claude-agent-acp` adapter) and `codex` (via the `codex-acp` adapter).
100
86
  - NEVER use `claude`, `claude -p`, `claude --acp`, or the bare `codex` CLI as the ACP `command`. Claude and Codex only speak the protocol through their dedicated `*-acp` adapters.
101
- - Default profiles for both ship out-of-box. Users only need an `agents.<id>` entry in config if they want to override the defaults (e.g. point to a custom binary path or pass extra args/env). An entry that still runs the bundled adapter, whether it omits `command` or names the same binary by name or full path, inherits the `command`, `description` and `model` it leaves out, so a single-field change such as `acp.agents.claude.model` is all it takes. An entry that points the id at a different binary stands on its own, so it must spell out everything it needs, `command` included.
87
+ - Default profiles for both ship out-of-box. Users only need an `agents.<id>` entry in config if they want to override the defaults (e.g. point to a custom binary path or pass extra args/env). An `acp.agents.<id>` entry replaces the bundled default entirely (no field merge), so any override must spell out the full `command` and `args`, not just the field being changed.
102
88
  - NEVER change an existing ACP config to use a different command. If the config already has `claude-agent-acp` or `codex-acp`, leave it alone.
103
89
 
104
90
  ## Updating an adapter
105
91
 
106
- Adapter upgrades ship with Assistant releases: the pinned version is what a missing adapter is installed at. An adapter already on PATH is never replaced, so a user who upgrades one themselves keeps that version.
92
+ Adapters are installed automatically when missing. To update an installed adapter, ask the user first and use its owning package manager. For bun installations:
93
+
94
+ ```bash
95
+ bun add -g @agentclientprotocol/claude-agent-acp@latest
96
+ # or
97
+ bun add -g @agentclientprotocol/codex-acp@latest
98
+ ```
107
99
 
108
- Codex uses the adapter's bundled dependency by default, within the version range declared by the adapter. If `CODEX_PATH` selects a separate CLI, update that installation separately.
100
+ Codex uses the adapter's bundled dependency by default, within the version range declared by the adapter. If `CODEX_PATH` selects a separate CLI, update that installation separately. Verify the required model with a fresh `acp_spawn` call after updating.
109
101
 
110
102
  ## When to use acp_steer vs acp_spawn
111
103
 
@@ -3,7 +3,7 @@
3
3
  "tools": [
4
4
  {
5
5
  "name": "acp_spawn",
6
- "description": "Spawn an external coding agent (e.g. Claude Code, Codex) via ACP to work on a task. Default profiles ship for `claude` (`claude-agent-acp`) and `codex` (`codex-acp`); the assistant resolves the agent id to the right binary. The result reports `requestedModel` and the adapter-reported `effectiveModel`; treat `effectiveModel` as authoritative for the top-level ACP session. The agent runs as a subprocess and streams results back. Use this when you want to delegate a coding task to an external agent that has its own tools, file editing, and terminal access. If a default agent's binary is missing, the assistant installs it once via a sandboxed bun global install and proceeds in the same call; if that fails (e.g. bun unavailable), an actionable install hint is returned - do NOT alter `agents.<id>.command` to swap binaries.",
6
+ "description": "Spawn an external coding agent (e.g. Claude Code, Codex) via ACP to work on a task. Default profiles ship for `claude` (`claude-agent-acp`) and `codex` (`codex-acp`); the assistant resolves the agent id to the right binary. The agent runs as a subprocess and streams results back. Use this when you want to delegate a coding task to an external agent that has its own tools, file editing, and terminal access. If a default agent's binary is missing, the assistant installs it once via a sandboxed bun global install and proceeds in the same call; if that fails (e.g. bun unavailable), an actionable install hint is returned - do NOT alter `agents.<id>.command` to swap binaries.",
7
7
  "category": "orchestration",
8
8
  "risk": "high",
9
9
  "input_schema": {
@@ -20,10 +20,6 @@
20
20
  "cwd": {
21
21
  "type": "string",
22
22
  "description": "Working directory for the agent. This determines where the agent runs and where its session is stored. Set this to the project/repo root the user wants the agent to work in. Defaults to current conversation's working directory."
23
- },
24
- "model": {
25
- "type": "string",
26
- "description": "Model the agent should run on, passed ONLY when the user named one (e.g. 'opus' for Claude). Left off, a Claude session runs on Opus and every other agent on its own default. If the agent refuses the value, or advertises no model selector, the result says so and the session runs on its own model."
27
23
  }
28
24
  },
29
25
  "required": ["task"]
@@ -60,7 +60,7 @@ Apps live under `/workspace/data/apps/`:
60
60
  <slug>.json # App metadata
61
61
  <slug>/
62
62
  src/ # Source files (TSX) — what you write
63
- dist/ # Compiled output, generated by app_refresh or assistant apps refresh
63
+ dist/ # Compiled output — auto-generated by app_refresh
64
64
  records/ # Data records (one JSON file per record)
65
65
  <slug>.preview # Preview image (auto-generated)
66
66
  ```
@@ -156,9 +156,9 @@ Calculators, single-page tools, landing pages, and slide decks skip this — pas
156
156
 
157
157
  ### 3 — Create the app (scaffold, then expand)
158
158
 
159
- ⚠️ **`app_create` is ONE-SHOT per build.** Call it exactly once. After it returns an `app_id`, all further changes go through `file_write` / `file_edit` and a single compile (`assistant apps refresh` or `app_refresh`). To start over: `app_delete(app_id)` first, then a fresh `app_create`.
159
+ ⚠️ **`app_create` is ONE-SHOT per build.** Call it exactly once. After it returns an `app_id`, all further changes go through `file_write` / `file_edit` + `app_refresh`. To start over: `app_delete(app_id)` first, then a fresh `app_create`.
160
160
 
161
- Apps are multi-file Preact + TSX projects; esbuild bundles when you compile. Structure:
161
+ Apps are multi-file Preact + TSX projects; esbuild bundles automatically. Structure:
162
162
 
163
163
  ```
164
164
  src/
@@ -179,9 +179,9 @@ render(<App />, document.getElementById("app")!);
179
179
 
180
180
  1. **`app_create`** with a **4-file scaffold**: `src/index.html`, `src/main.tsx`, a **placeholder** `src/components/App.tsx` (`<div>Loading...</div>`), and an **empty** `src/styles.css`. The placeholders make the first compile clean — a 2-file scaffold leaves broken imports.
181
181
  2. **`file_write`** each real file, one per tool call, overwriting the placeholders and adding components.
182
- 3. Compile ONCE at the end. File edits do not compile on their own. Use `assistant apps inspect <name>` to see whether source drifted, then `assistant apps refresh <name>` (or `app_refresh`).
182
+ 3. **`app_refresh`** ONCE at the end to compile.
183
183
 
184
- **Actually write the files.** Source code in reasoning/thinking is invisible to the app sandbox and is not a file write. Put every real file body in an `app_create.source_files`, `file_write`, `file_edit`, or `app_update.source_files` tool call, then verify the files exist before compiling when there is any doubt.
184
+ **Actually write the files.** Source code in reasoning/thinking is invisible to the app sandbox and is not a file write. Put every real file body in an `app_create.source_files`, `file_write`, `file_edit`, or `app_update.source_files` tool call, then verify the files exist before `app_refresh` when there is any doubt.
185
185
 
186
186
  **Allowed packages** (esbuild-resolved, no CDN): `date-fns`, `chart.js`, `lodash-es`, `zod`, `clsx`. For icons, write inline `<svg>` markup directly — no icon package is bundled.
187
187
 
@@ -221,14 +221,11 @@ app_create({ app_create({
221
221
 
222
222
  ### 4 — Compile
223
223
 
224
- File edits do not compile on their own. After ALL file writes, compile once:
225
-
226
224
  ```
227
- assistant apps inspect <name>
228
- assistant apps refresh <name>
225
+ app_refresh(app_id)
229
226
  ```
230
227
 
231
- `assistant apps inspect` reports whether source changed since the last compile. `assistant apps refresh` compiles and refreshes open surfaces. `app_refresh(app_id)` also compiles. If compile fails, the response has error details; fix with `file_edit`, then compile again.
228
+ Call it ONCE, after ALL file writes — batching is required. If it fails, the response has error details; fix with `file_edit`, then `app_refresh` again.
232
229
 
233
230
  ### 5 — Show the preview card
234
231
 
@@ -247,7 +244,7 @@ Editing an existing app means reusing its `app_id` — never `app_create`. Resol
247
244
  - **`app_update`** — rename or change description/schema, and/or rewrite files via `source_files`, in one call. It recompiles for you, so no separate `app_refresh` is needed. Use this instead of editing `<slug>.json` by hand.
248
245
  - **Full rebrand** — still iteration, edit the existing files.
249
246
 
250
- Then compile ONCE (`assistant apps refresh <name>` or `app_refresh(app_id)`) unless you used `app_update`, which already recompiled. If the change is substantial, `app_open(app_id, open_mode: "preview")` for a fresh card; for small tweaks the existing card stays valid.
247
+ Then `app_refresh(app_id)` ONCE (unless you used `app_update`, which already recompiled). If the change is substantial, `app_open(app_id, open_mode: "preview")` for a fresh card; for small tweaks the existing card stays valid.
251
248
 
252
249
  > ⚠️ **`skill_load("app-builder")` is required before every `app_*` call** (including the first `app_create`). The skill can auto-unload between turns; without the reload, `app_refresh` / `app_open` error with "not currently active." It's idempotent — call it every time.
253
250
 
@@ -353,7 +350,7 @@ Slide decks are a different domain — skip app patterns (contextual headers, se
353
350
  ## SKILL COMPLETE WHEN
354
351
 
355
352
  - [ ] Request was scoped: personal build (sandbox) or complex/shippable (handed off to a project folder + coding agent)
356
- - [ ] **Sandbox path:** `app_create` returned an `app_id`; all files written via `file_write`; compile ran ONCE clean (`assistant apps refresh` or `app_refresh`); `app_open(open_mode: "preview")` rendered the card; user told what was built (3-6 bullets); iterations reflected live
353
+ - [ ] **Sandbox path:** `app_create` returned an `app_id`; all files written via `file_write`; `app_refresh` ran ONCE clean; `app_open(open_mode: "preview")` rendered the card; user told what was built (3-6 bullets); iterations reflected live
357
354
  - [ ] **Handoff path:** project folder established; coding agent spawned via `acp_spawn({ task, cwd })`; user told work continues in the folder
358
355
 
359
356
  ---
@@ -143,7 +143,7 @@ Older routes were written with a second `context` argument (`context.assistantEv
143
143
 
144
144
  ## Key rules
145
145
 
146
- - Always create the route handler files via `file_write` before compiling (`app_refresh` or `assistant apps refresh`)
146
+ - Always create the route handler files via `file_write` before calling `app_refresh`
147
147
  - Export an optional `description` string for CLI discoverability (`assistant routes list`)
148
148
  - Handlers have full Node.js API access — `fs`, `path`, `crypto`, etc.
149
149
  - Handlers get a 30-second timeout per request
@@ -14,7 +14,7 @@ metadata:
14
14
 
15
15
  You are a unified messaging assistant with access to multiple platforms (Gmail, Outlook, Telegram, and more). Use the messaging tools to help users read, search, organize, draft, and send messages across all connected platforms.
16
16
 
17
- **On a channel, `messaging_send` posts through the channel's own transport.** Slack, Telegram, Discord, and WhatsApp all go out that way: threaded where you name a `thread_id`, rendered the way a reply is, and recorded in the chat's conversation once the channel acknowledges the post. Reading and searching Slack are not part of this skill; load the **slack** skill, which uses the Slack Web API for those.
17
+ **Slack is not handled by this skill.** Slack messaging (send, read, search) is handled by the **slack** skill, which uses the Slack Web API directly via CLI. Do not use messaging tools with `platform: "slack"`.
18
18
 
19
19
  ## External Identity
20
20
 
@@ -34,7 +34,7 @@ When a platform is connected (auth test succeeds), always use the messaging API
34
34
 
35
35
  On Gmail and Outlook, `messaging_send` creates a real mailbox draft for review. It does not send. Recipients are optional on Outlook: if the user has not named a To address, still create the draft (use a non-email `conversation_id` such as `drafts`) and tell them only after the tool returns a draft ID. If draft creation fails or is interrupted, say so and offer the email copy in chat. Do not claim a draft exists until the tool succeeds.
36
36
 
37
- **On a channel, the send goes out as the assistant's own bot**, so `account` does not apply and is refused. It carries text only: attachments stay on Gmail and Outlook. The post is recorded in the chat's conversation, which is what lets `recall` find it later.
37
+ **Exception: Slack.** Slack messaging should use the Slack Web API directly via CLI, not messaging tools. See the **slack** skill for details.
38
38
 
39
39
  ## Connection Setup
40
40
 
@@ -64,7 +64,7 @@ When the user asks to "connect my email", "set up email", "manage my email", or
64
64
 
65
65
  ### Slack
66
66
 
67
- For Slack setup, load the **slack-app-setup** skill directly. `messaging_send` posts to a Slack chat through the channel's transport. Reading, searching, reactions, and file upload live in the **slack** skill, which uses the Slack Web API.
67
+ Slack is **not** handled by this skill. For Slack setup, load the **slack-app-setup** skill directly. For Slack messaging, use the **slack** skill which accesses the Slack Web API via CLI.
68
68
 
69
69
  ### Telegram
70
70
 
@@ -125,7 +125,7 @@
125
125
  },
126
126
  {
127
127
  "name": "messaging_send",
128
- "description": "Send a message, reply to a thread, or create a draft. On Gmail and Outlook, always creates a real mailbox draft for review (recipients optional on Outlook). On a channel (Slack, Telegram, Discord, WhatsApp) the message goes out as the channel's own bot, threaded when thread_id names a thread. Supports replies (via thread_id) and attachments (via attachment_paths, Gmail and Outlook).",
128
+ "description": "Send a message, reply to a thread, or create a draft. On Gmail and Outlook, always creates a real mailbox draft for review (recipients optional on Outlook). Supports replies (via thread_id), attachments (via attachment_paths, Gmail and Outlook), and all messaging platforms.",
129
129
  "category": "messaging",
130
130
  "risk": "high",
131
131
  "input_schema": {
@@ -133,11 +133,11 @@
133
133
  "properties": {
134
134
  "platform": {
135
135
  "type": "string",
136
- "description": "Platform (e.g. \"gmail\", \"slack\", \"telegram\", \"discord\"). Auto-detected if only one is connected."
136
+ "description": "Platform (e.g. \"gmail\"). Auto-detected if only one is connected. Slack is not supported — use the Slack Web API directly."
137
137
  },
138
138
  "account": {
139
139
  "type": "string",
140
- "description": "Email address of the account to use. Required when multiple accounts are connected for the same email platform. If omitted, uses the most recently connected account. Does not apply to a channel: a channel send goes out as the channel's own bot."
140
+ "description": "Email address of the account to use. Required when multiple accounts are connected for the same platform. If omitted, uses the most recently connected account."
141
141
  },
142
142
  "conversation_id": {
143
143
  "type": "string",