@vellumai/assistant 0.6.5 → 0.6.6

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 (443) hide show
  1. package/AGENTS.md +9 -1
  2. package/ARCHITECTURE.md +15 -17
  3. package/Dockerfile +6 -4
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +283 -0
  5. package/docs/architecture/integrations.md +32 -39
  6. package/docs/architecture/memory.md +25 -30
  7. package/docs/architecture/security.md +7 -6
  8. package/docs/browser-use-architecture-phase2.md +63 -20
  9. package/docs/plugins.md +761 -0
  10. package/examples/plugins/echo/README.md +132 -0
  11. package/examples/plugins/echo/package.json +17 -0
  12. package/examples/plugins/echo/register.ts +187 -0
  13. package/node_modules/@vellumai/egress-proxy/src/types.ts +19 -0
  14. package/openapi.yaml +212 -68
  15. package/package.json +1 -1
  16. package/src/__tests__/app-compiler.test.ts +57 -0
  17. package/src/__tests__/approval-cascade.test.ts +7 -2
  18. package/src/__tests__/auto-analysis-end-to-end.test.ts +1 -0
  19. package/src/__tests__/avatar-generator.test.ts +4 -2
  20. package/src/__tests__/bundled-asset.test.ts +6 -6
  21. package/src/__tests__/catalog-cache.test.ts +69 -0
  22. package/src/__tests__/checker.test.ts +459 -171
  23. package/src/__tests__/circuit-breaker-pipeline.test.ts +406 -0
  24. package/src/__tests__/compaction-events.test.ts +501 -0
  25. package/src/__tests__/compaction-pipeline.test.ts +210 -0
  26. package/src/__tests__/compaction-strip-metadata-clear.test.ts +181 -0
  27. package/src/__tests__/compaction-timeout-recovery.test.ts +262 -0
  28. package/src/__tests__/config-model-image-provider.test.ts +110 -0
  29. package/src/__tests__/config-schema.test.ts +22 -9
  30. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +0 -4
  31. package/src/__tests__/contacts-tools.test.ts +26 -0
  32. package/src/__tests__/context-overflow-policy.test.ts +7 -7
  33. package/src/__tests__/context-window-manager.test.ts +355 -4
  34. package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
  35. package/src/__tests__/conversation-agent-loop-overflow.test.ts +26 -30
  36. package/src/__tests__/conversation-agent-loop.test.ts +30 -141
  37. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -1
  38. package/src/__tests__/conversation-history-web-search.test.ts +1 -0
  39. package/src/__tests__/conversation-init.benchmark.test.ts +2 -16
  40. package/src/__tests__/conversation-pairing.test.ts +174 -10
  41. package/src/__tests__/conversation-pre-run-repair.test.ts +4 -1
  42. package/src/__tests__/conversation-process-callsite.test.ts +3 -0
  43. package/src/__tests__/conversation-provider-retry-repair.test.ts +16 -7
  44. package/src/__tests__/conversation-queue.test.ts +29 -14
  45. package/src/__tests__/conversation-routes-disk-view.test.ts +7 -6
  46. package/src/__tests__/conversation-runtime-assembly.test.ts +155 -110
  47. package/src/__tests__/conversation-runtime-workspace.test.ts +23 -38
  48. package/src/__tests__/conversation-seed-composer.test.ts +2 -2
  49. package/src/__tests__/conversation-slash-queue.test.ts +7 -2
  50. package/src/__tests__/conversation-slash-unknown.test.ts +25 -2
  51. package/src/__tests__/conversation-speed-override.test.ts +6 -1
  52. package/src/__tests__/conversation-title-service.test.ts +116 -0
  53. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +41 -2
  54. package/src/__tests__/conversation-usage.test.ts +1 -1
  55. package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
  56. package/src/__tests__/conversation-workspace-injection.test.ts +3 -0
  57. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +4 -1
  58. package/src/__tests__/credential-health-service.test.ts +78 -9
  59. package/src/__tests__/credential-security-invariants.test.ts +2 -2
  60. package/src/__tests__/db-schedule-syntax-migration.test.ts +1 -0
  61. package/src/__tests__/empty-response-pipeline.test.ts +305 -0
  62. package/src/__tests__/extension-id-sync-guard.test.ts +3 -3
  63. package/src/__tests__/first-greeting.test.ts +247 -5
  64. package/src/__tests__/headless-browser-mode.test.ts +57 -0
  65. package/src/__tests__/history-repair-pipeline.test.ts +399 -0
  66. package/src/__tests__/host-browser-e2e-cloud.test.ts +307 -0
  67. package/src/__tests__/host-browser-e2e-self-hosted.test.ts +3 -3
  68. package/src/__tests__/host-proxy-interface.test.ts +36 -2
  69. package/src/__tests__/image-credentials.test.ts +137 -0
  70. package/src/__tests__/image-service-dispatcher.test.ts +186 -0
  71. package/src/__tests__/injector-chain.test.ts +526 -0
  72. package/src/__tests__/intent-routing.test.ts +0 -26
  73. package/src/__tests__/llm-call-pipeline.test.ts +285 -0
  74. package/src/__tests__/llm-schema.test.ts +1 -1
  75. package/src/__tests__/media-generate-image.test.ts +119 -13
  76. package/src/__tests__/memory-retrieval-pipeline.test.ts +401 -0
  77. package/src/__tests__/memory-upsert-concurrency.test.ts +1 -0
  78. package/src/__tests__/migration-import-from-url.test.ts +5 -68
  79. package/src/__tests__/model-intents.test.ts +4 -2
  80. package/src/__tests__/notification-broadcaster.test.ts +3 -3
  81. package/src/__tests__/notification-decision-strategy.test.ts +0 -11
  82. package/src/__tests__/notification-schedule-notify-dedup.test.ts +108 -0
  83. package/src/__tests__/oauth-apps-routes.test.ts +1 -1
  84. package/src/__tests__/oauth-cli.test.ts +14 -12
  85. package/src/__tests__/oauth-connect-orchestrator.test.ts +4 -13
  86. package/src/__tests__/oauth-provider-serializer.test.ts +6 -4
  87. package/src/__tests__/oauth-provider-visibility.test.ts +3 -5
  88. package/src/__tests__/oauth-providers-routes.test.ts +3 -2
  89. package/src/__tests__/oauth-store.test.ts +41 -76
  90. package/src/__tests__/onboarding-template-contract.test.ts +16 -64
  91. package/src/__tests__/openai-image-service.test.ts +368 -0
  92. package/src/__tests__/overflow-reduce-pipeline.test.ts +676 -0
  93. package/src/__tests__/permission-checker-host-gate.test.ts +0 -24
  94. package/src/__tests__/persist-onboarding-artifacts.test.ts +266 -0
  95. package/src/__tests__/persistence-pipeline.test.ts +377 -0
  96. package/src/__tests__/pipeline-runner.test.ts +565 -0
  97. package/src/__tests__/platform.test.ts +5 -2
  98. package/src/__tests__/plugin-bootstrap.test.ts +483 -0
  99. package/src/__tests__/plugin-registry.test.ts +273 -0
  100. package/src/__tests__/plugin-route-contribution.test.ts +288 -0
  101. package/src/__tests__/plugin-skill-contribution.test.ts +367 -0
  102. package/src/__tests__/plugin-tool-contribution.test.ts +286 -0
  103. package/src/__tests__/plugin-types.test.ts +320 -0
  104. package/src/__tests__/pricing.test.ts +44 -12
  105. package/src/__tests__/proxy-approval-callback.test.ts +69 -8
  106. package/src/__tests__/reaction-persistence.test.ts +1 -0
  107. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
  108. package/src/__tests__/registry.test.ts +0 -2
  109. package/src/__tests__/schedule-routes.test.ts +131 -1
  110. package/src/__tests__/scheduler-recurrence.test.ts +14 -70
  111. package/src/__tests__/scheduler-reuse-conversation.test.ts +10 -50
  112. package/src/__tests__/secret-detection-handler.test.ts +0 -10
  113. package/src/__tests__/shell-identity.test.ts +0 -134
  114. package/src/__tests__/suggestion-routes.test.ts +103 -4
  115. package/src/__tests__/task-memory-cleanup.test.ts +1 -0
  116. package/src/__tests__/task-scheduler.test.ts +3 -15
  117. package/src/__tests__/test-preload.ts +11 -0
  118. package/src/__tests__/title-generate-pipeline.test.ts +224 -0
  119. package/src/__tests__/token-estimate-pipeline.test.ts +431 -0
  120. package/src/__tests__/tool-error-pipeline.test.ts +244 -0
  121. package/src/__tests__/tool-execute-pipeline.test.ts +431 -0
  122. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -6
  123. package/src/__tests__/tool-executor-shell-integration.test.ts +7 -10
  124. package/src/__tests__/tool-executor.test.ts +141 -0
  125. package/src/__tests__/tool-result-truncate-pipeline.test.ts +356 -0
  126. package/src/__tests__/tool-result-truncation.test.ts +0 -110
  127. package/src/__tests__/user-plugin-loader.test.ts +191 -0
  128. package/src/__tests__/workspace-migration-046-seed-conversation-starters-callsite.test.ts +185 -0
  129. package/src/__tests__/workspace-migration-049-release-notes-default-sonnet.test.ts +100 -0
  130. package/src/__tests__/workspace-migration-050-seed-main-agent-opus-callsite.test.ts +171 -0
  131. package/src/__tests__/workspace-migration-051-seed-conversation-summarization-callsite.test.ts +252 -0
  132. package/src/__tests__/workspace-migration-remove-hooks.test.ts +99 -0
  133. package/src/__tests__/workspace-policy.test.ts +21 -3
  134. package/src/agent/loop.ts +340 -102
  135. package/src/approvals/__tests__/guardian-feed-event.test.ts +304 -0
  136. package/src/approvals/guardian-request-resolvers.ts +80 -0
  137. package/src/backup/__tests__/backup-worker.test.ts +2 -13
  138. package/src/backup/backup-worker.ts +3 -15
  139. package/src/bundler/app-compiler.ts +84 -1
  140. package/src/calls/call-state.ts +2 -2
  141. package/src/channels/__tests__/types.test.ts +3 -3
  142. package/src/channels/types.ts +6 -4
  143. package/src/cli/__tests__/notifications.test.ts +87 -211
  144. package/src/cli/commands/__tests__/backup.test.ts +1 -1
  145. package/src/cli/commands/__tests__/image-generation.test.ts +255 -35
  146. package/src/cli/commands/__tests__/inference-send.test.ts +12 -0
  147. package/src/cli/commands/__tests__/tts-synthesize.test.ts +12 -0
  148. package/src/cli/commands/backup.ts +2 -2
  149. package/src/cli/commands/clients.ts +138 -0
  150. package/src/cli/commands/completions.ts +2 -9
  151. package/src/cli/commands/conversations.ts +55 -7
  152. package/src/cli/commands/image-generation.ts +33 -34
  153. package/src/cli/commands/notifications.ts +68 -103
  154. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +1 -1
  155. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +1 -1
  156. package/src/cli/commands/oauth/connect.ts +2 -2
  157. package/src/cli/commands/oauth/providers.ts +176 -8
  158. package/src/cli/commands/oauth/status.ts +46 -36
  159. package/src/cli/commands/skills.ts +3 -4
  160. package/src/cli/program.ts +25 -29
  161. package/src/config/__tests__/backup-schema.test.ts +7 -2
  162. package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
  163. package/src/config/bundled-skills/app-builder/references/WIDGETS.md +10 -10
  164. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +66 -87
  165. package/src/config/bundled-skills/contacts/tools/contact-search.ts +28 -51
  166. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +22 -40
  167. package/src/config/bundled-skills/image-studio/SKILL.md +2 -1
  168. package/src/config/bundled-skills/image-studio/TOOLS.json +2 -1
  169. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +23 -39
  170. package/src/config/bundled-skills/messaging/SKILL.md +3 -3
  171. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +207 -0
  172. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +12 -0
  173. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +58 -0
  174. package/src/config/bundled-skills/schedule/SKILL.md +8 -3
  175. package/src/config/bundled-skills/schedule/TOOLS.json +15 -7
  176. package/src/config/bundled-skills/schedule/references/SCRIPT_MODE_PATTERNS.md +59 -0
  177. package/src/config/bundled-tool-registry.ts +0 -15
  178. package/src/config/feature-flag-registry.json +17 -1
  179. package/src/config/schema.ts +19 -0
  180. package/src/config/schemas/backup.ts +1 -1
  181. package/src/config/schemas/conversations.ts +16 -0
  182. package/src/config/schemas/llm.ts +2 -3
  183. package/src/config/schemas/security.ts +6 -6
  184. package/src/config/schemas/tts.ts +11 -0
  185. package/src/config/skill-state.ts +6 -2
  186. package/src/config/skills.ts +94 -5
  187. package/src/context/__tests__/compact-prompt.test.ts +27 -9
  188. package/src/context/prompts/compact.md +26 -12
  189. package/src/context/tool-result-truncation.ts +3 -63
  190. package/src/context/window-manager.ts +190 -16
  191. package/src/credential-health/credential-health-service.ts +19 -6
  192. package/src/daemon/__tests__/conversation-feed-event.test.ts +317 -0
  193. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +4 -12
  194. package/src/daemon/__tests__/conversation-tool-setup.test.ts +14 -15
  195. package/src/daemon/config-watcher.ts +0 -2
  196. package/src/daemon/context-overflow-policy.ts +4 -13
  197. package/src/daemon/conversation-agent-loop-handlers.ts +83 -22
  198. package/src/daemon/conversation-agent-loop.ts +984 -683
  199. package/src/daemon/conversation-history.ts +10 -19
  200. package/src/daemon/conversation-lifecycle.ts +37 -19
  201. package/src/daemon/conversation-notifiers.ts +2 -110
  202. package/src/daemon/conversation-process.ts +14 -7
  203. package/src/daemon/conversation-runtime-assembly.ts +532 -411
  204. package/src/daemon/conversation-tool-setup.ts +41 -4
  205. package/src/daemon/conversation.ts +80 -35
  206. package/src/daemon/external-plugins-bootstrap.ts +478 -0
  207. package/src/daemon/first-greeting.ts +191 -14
  208. package/src/daemon/handlers/config-model.ts +11 -0
  209. package/src/daemon/handlers/skills.ts +5 -1
  210. package/src/daemon/lifecycle.ts +33 -68
  211. package/src/daemon/message-types/computer-use.ts +2 -34
  212. package/src/daemon/message-types/conversations.ts +49 -0
  213. package/src/daemon/message-types/messages.ts +12 -0
  214. package/src/daemon/server.ts +5 -3
  215. package/src/daemon/shutdown-handlers.ts +2 -12
  216. package/src/daemon/tool-side-effects.ts +14 -56
  217. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +160 -0
  218. package/src/heartbeat/heartbeat-service.ts +24 -1
  219. package/src/home/__tests__/feed-population-integration.test.ts +312 -0
  220. package/src/home/emit-feed-event.ts +7 -0
  221. package/src/home/feed-types.ts +41 -2
  222. package/src/home/rewrite-command-preview.ts +66 -0
  223. package/src/ipc/__tests__/socket-path.test.ts +11 -50
  224. package/src/ipc/cli-client.ts +1 -1
  225. package/src/ipc/cli-server.ts +3 -3
  226. package/src/ipc/gateway-client.ts +4 -1
  227. package/src/ipc/routes/browser-context.ts +2 -0
  228. package/src/ipc/routes/browser.ts +1 -0
  229. package/src/ipc/routes/get-contact.ts +16 -0
  230. package/src/ipc/routes/index.ts +14 -0
  231. package/src/ipc/routes/list-clients.ts +31 -0
  232. package/src/ipc/routes/merge-contacts.ts +17 -0
  233. package/src/ipc/routes/notification.ts +133 -0
  234. package/src/ipc/routes/rename-conversation.ts +59 -0
  235. package/src/ipc/routes/search-contacts.ts +19 -0
  236. package/src/ipc/routes/upsert-contact.ts +25 -0
  237. package/src/ipc/socket-path.ts +14 -38
  238. package/src/media/app-icon-generator.ts +23 -46
  239. package/src/media/avatar-router.ts +26 -41
  240. package/src/media/gemini-image-service.ts +8 -41
  241. package/src/media/image-credentials.ts +73 -0
  242. package/src/media/image-service.ts +85 -0
  243. package/src/media/openai-image-service.ts +131 -0
  244. package/src/media/types.ts +46 -0
  245. package/src/memory/conversation-crud.ts +48 -18
  246. package/src/memory/conversation-queries.ts +57 -4
  247. package/src/memory/conversation-title-service.ts +25 -0
  248. package/src/memory/db-init.ts +8 -0
  249. package/src/memory/embedding-gemini.test.ts +41 -2
  250. package/src/memory/embedding-gemini.ts +6 -1
  251. package/src/memory/graph/bootstrap.test.ts +282 -0
  252. package/src/memory/graph/bootstrap.ts +8 -5
  253. package/src/memory/graph/extraction.ts +10 -2
  254. package/src/memory/graph/graph-search.test.ts +1 -0
  255. package/src/memory/graph/inspect.ts +2 -2
  256. package/src/memory/graph/retriever.ts +10 -3
  257. package/src/memory/migrations/041-approval-prompt-ts-tracker.ts +26 -0
  258. package/src/memory/migrations/149-oauth-tables.ts +1 -0
  259. package/src/memory/migrations/223-schedule-script-column.ts +11 -0
  260. package/src/memory/migrations/224-oauth-providers-managed-service-is-paid.ts +24 -0
  261. package/src/memory/migrations/225-oauth-providers-available-scopes.ts +13 -0
  262. package/src/memory/migrations/index.ts +4 -0
  263. package/src/memory/pkb/pkb-index.test.ts +1 -0
  264. package/src/memory/pkb/pkb-reconcile.test.ts +1 -0
  265. package/src/memory/pkb/pkb-search.test.ts +65 -4
  266. package/src/memory/pkb/pkb-search.ts +40 -18
  267. package/src/memory/qdrant-client.test.ts +60 -0
  268. package/src/memory/qdrant-client.ts +25 -0
  269. package/src/memory/schema/infrastructure.ts +1 -0
  270. package/src/memory/schema/oauth.ts +4 -1
  271. package/src/messaging/providers/slack/render-transcript.test.ts +77 -29
  272. package/src/messaging/providers/slack/render-transcript.ts +58 -0
  273. package/src/notifications/conversation-pairing.ts +78 -19
  274. package/src/notifications/copy-composer.ts +0 -5
  275. package/src/notifications/emit-signal.ts +1 -1
  276. package/src/notifications/signal.ts +1 -2
  277. package/src/oauth/AGENTS.md +1 -1
  278. package/src/oauth/__tests__/identity-verifier.test.ts +2 -1
  279. package/src/oauth/connect-orchestrator.ts +8 -34
  280. package/src/oauth/connect-types.ts +6 -10
  281. package/src/oauth/manual-token-connection.ts +23 -0
  282. package/src/oauth/oauth-store.ts +30 -14
  283. package/src/oauth/provider-serializer.ts +6 -1
  284. package/src/oauth/seed-providers.ts +56 -108
  285. package/src/outbound-proxy/http-forwarder.ts +9 -0
  286. package/src/permissions/approval-policy.test.ts +293 -18
  287. package/src/permissions/approval-policy.ts +110 -58
  288. package/src/permissions/arg-parser.test.ts +161 -0
  289. package/src/permissions/arg-parser.ts +141 -0
  290. package/src/permissions/bash-risk-classifier.test.ts +414 -2
  291. package/src/permissions/bash-risk-classifier.ts +303 -60
  292. package/src/permissions/checker.ts +157 -29
  293. package/src/permissions/command-registry.test.ts +239 -0
  294. package/src/permissions/command-registry.ts +234 -54
  295. package/src/permissions/defaults.ts +5 -4
  296. package/src/permissions/gateway-threshold-reader.ts +196 -0
  297. package/src/permissions/prompter.ts +4 -0
  298. package/src/permissions/risk-types.ts +61 -4
  299. package/src/permissions/schedule-risk-classifier.test.ts +129 -0
  300. package/src/permissions/schedule-risk-classifier.ts +85 -0
  301. package/src/permissions/shell-identity.ts +2 -42
  302. package/src/permissions/types.ts +2 -0
  303. package/src/permissions/workspace-policy.ts +8 -3
  304. package/src/plugins/defaults/circuit-breaker.ts +146 -0
  305. package/src/plugins/defaults/compaction.ts +145 -0
  306. package/src/plugins/defaults/empty-response.ts +126 -0
  307. package/src/plugins/defaults/history-repair.ts +85 -0
  308. package/src/plugins/defaults/index.ts +116 -0
  309. package/src/plugins/defaults/injectors.ts +491 -0
  310. package/src/plugins/defaults/llm-call.ts +82 -0
  311. package/src/plugins/defaults/memory-retrieval.ts +226 -0
  312. package/src/plugins/defaults/overflow-reduce.ts +181 -0
  313. package/src/plugins/defaults/persistence.ts +129 -0
  314. package/src/plugins/defaults/title-generate.ts +95 -0
  315. package/src/plugins/defaults/token-estimate.ts +104 -0
  316. package/src/plugins/defaults/tool-error.ts +126 -0
  317. package/src/plugins/defaults/tool-execute.ts +89 -0
  318. package/src/plugins/defaults/tool-result-truncate.ts +88 -0
  319. package/src/plugins/pipeline.ts +316 -0
  320. package/src/plugins/plugin-skill-contributions.ts +292 -0
  321. package/src/plugins/registry.ts +241 -0
  322. package/src/plugins/types.ts +1134 -0
  323. package/src/plugins/user-loader.ts +177 -0
  324. package/src/prompts/templates/BOOTSTRAP.md +27 -77
  325. package/src/providers/model-catalog.ts +52 -29
  326. package/src/providers/model-intents.ts +1 -1
  327. package/src/providers/openrouter/client.ts +5 -1
  328. package/src/providers/speech-to-text/deepgram-realtime.test.ts +61 -0
  329. package/src/providers/speech-to-text/deepgram-realtime.ts +57 -0
  330. package/src/providers/speech-to-text/xai-realtime.test.ts +72 -4
  331. package/src/providers/speech-to-text/xai-realtime.ts +39 -14
  332. package/src/runtime/AGENTS.md +25 -16
  333. package/src/runtime/__tests__/browser-extension-pair-routes.test.ts +3 -3
  334. package/src/runtime/__tests__/client-registry.test.ts +293 -0
  335. package/src/runtime/client-registry.ts +261 -0
  336. package/src/runtime/http-server.ts +77 -8
  337. package/src/runtime/http-types.ts +0 -2
  338. package/src/runtime/migrations/vbundle-builder.ts +1 -22
  339. package/src/runtime/routes/approval-prompt-ts-tracker.ts +51 -31
  340. package/src/runtime/routes/approval-routes.ts +17 -0
  341. package/src/runtime/routes/browser-extension-pair-routes.ts +27 -8
  342. package/src/runtime/routes/conversation-routes.ts +223 -116
  343. package/src/runtime/routes/inbound-message-handler.ts +88 -13
  344. package/src/runtime/routes/memory-item-routes.test.ts +1 -0
  345. package/src/runtime/routes/migration-routes.ts +0 -3
  346. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +284 -0
  347. package/src/runtime/routes/playground/__tests__/guard.test.ts +80 -0
  348. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +294 -0
  349. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +271 -0
  350. package/src/runtime/routes/playground/__tests__/seed-conversation.test.ts +202 -0
  351. package/src/runtime/routes/playground/__tests__/seeded-conversations.test.ts +309 -0
  352. package/src/runtime/routes/playground/__tests__/state.test.ts +224 -0
  353. package/src/runtime/routes/playground/conversation-not-found.ts +29 -0
  354. package/src/runtime/routes/playground/deps.ts +56 -0
  355. package/src/runtime/routes/playground/force-compact.ts +73 -0
  356. package/src/runtime/routes/playground/guard.ts +37 -0
  357. package/src/runtime/routes/playground/index.ts +28 -0
  358. package/src/runtime/routes/playground/inject-failures.ts +159 -0
  359. package/src/runtime/routes/playground/reset-circuit.ts +115 -0
  360. package/src/runtime/routes/playground/seed-conversation.ts +139 -0
  361. package/src/runtime/routes/playground/seeded-conversations.ts +78 -0
  362. package/src/runtime/routes/playground/state.ts +78 -0
  363. package/src/runtime/routes/schedule-routes.ts +89 -8
  364. package/src/runtime/skill-route-registry.ts +75 -15
  365. package/src/schedule/run-script.ts +68 -0
  366. package/src/schedule/schedule-store.ts +7 -1
  367. package/src/schedule/scheduler.ts +48 -8
  368. package/src/skills/catalog-cache.ts +12 -5
  369. package/src/tools/browser/__tests__/browser-status.test.ts +189 -0
  370. package/src/tools/browser/browser-execution.ts +88 -19
  371. package/src/tools/browser/cdp-client/__tests__/extension-cdp-client.test.ts +230 -0
  372. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +146 -3
  373. package/src/tools/browser/cdp-client/extension-cdp-client.ts +54 -3
  374. package/src/tools/browser/cdp-client/factory.ts +15 -4
  375. package/src/tools/executor.ts +126 -74
  376. package/src/tools/network/script-proxy/session-manager.ts +37 -1
  377. package/src/tools/permission-checker.ts +98 -49
  378. package/src/tools/policy-context.ts +4 -0
  379. package/src/tools/registry.ts +140 -3
  380. package/src/tools/schedule/create.ts +23 -8
  381. package/src/tools/schedule/update.ts +3 -1
  382. package/src/tools/secret-detection-handler.ts +0 -51
  383. package/src/tools/system/avatar-generator.ts +6 -2
  384. package/src/tools/types.ts +28 -2
  385. package/src/util/platform.ts +7 -2
  386. package/src/util/pricing.ts +26 -3
  387. package/src/workspace/migrations/006-services-config.ts +2 -4
  388. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +2 -3
  389. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +3 -4
  390. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +108 -0
  391. package/src/workspace/migrations/047-remove-watch-callsites.ts +54 -0
  392. package/src/workspace/migrations/048-remove-workspace-hooks.ts +81 -0
  393. package/src/workspace/migrations/049-release-notes-default-sonnet.ts +80 -0
  394. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +86 -0
  395. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +128 -0
  396. package/src/workspace/migrations/registry.ts +12 -0
  397. package/tsconfig.json +1 -1
  398. package/hook-templates/debug-prompt-logger/hook.json +0 -7
  399. package/hook-templates/debug-prompt-logger/run.sh +0 -66
  400. package/src/__tests__/compaction-circuit-breaker.test.ts +0 -336
  401. package/src/__tests__/context-overflow-approval.test.ts +0 -156
  402. package/src/__tests__/hooks-blocking.test.ts +0 -178
  403. package/src/__tests__/hooks-cli.test.ts +0 -182
  404. package/src/__tests__/hooks-config.test.ts +0 -108
  405. package/src/__tests__/hooks-discovery.test.ts +0 -211
  406. package/src/__tests__/hooks-integration.test.ts +0 -196
  407. package/src/__tests__/hooks-manager.test.ts +0 -226
  408. package/src/__tests__/hooks-runner.test.ts +0 -175
  409. package/src/__tests__/hooks-settings.test.ts +0 -160
  410. package/src/__tests__/hooks-templates.test.ts +0 -169
  411. package/src/__tests__/hooks-ts-runner.test.ts +0 -170
  412. package/src/__tests__/hooks-watch.test.ts +0 -112
  413. package/src/__tests__/notification-schedule-dedup.test.ts +0 -213
  414. package/src/__tests__/oauth-scope-policy.test.ts +0 -180
  415. package/src/__tests__/send-notification-tool.test.ts +0 -83
  416. package/src/cli/commands/shotgun.ts +0 -266
  417. package/src/config/bundled-skills/conversations/SKILL.md +0 -20
  418. package/src/config/bundled-skills/conversations/TOOLS.json +0 -23
  419. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +0 -88
  420. package/src/config/bundled-skills/heartbeat/SKILL.md +0 -43
  421. package/src/config/bundled-skills/notifications/SKILL.md +0 -40
  422. package/src/config/bundled-skills/notifications/TOOLS.json +0 -80
  423. package/src/config/bundled-skills/notifications/tools/send-notification.ts +0 -152
  424. package/src/config/bundled-skills/notifications/tools/shared.ts +0 -13
  425. package/src/config/bundled-skills/screen-watch/SKILL.md +0 -27
  426. package/src/config/bundled-skills/screen-watch/TOOLS.json +0 -35
  427. package/src/config/bundled-skills/screen-watch/tools/start-screen-watch.ts +0 -12
  428. package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -84
  429. package/src/daemon/context-overflow-approval.ts +0 -52
  430. package/src/daemon/watch-handler.ts +0 -399
  431. package/src/hooks/cli.ts +0 -253
  432. package/src/hooks/config.ts +0 -100
  433. package/src/hooks/discovery.ts +0 -135
  434. package/src/hooks/manager.ts +0 -179
  435. package/src/hooks/runner.ts +0 -117
  436. package/src/hooks/templates.ts +0 -77
  437. package/src/hooks/types.ts +0 -75
  438. package/src/oauth/scope-policy.ts +0 -89
  439. package/src/runtime/gateway-internal-client.ts +0 -94
  440. package/src/runtime/routes/watch-routes.ts +0 -156
  441. package/src/signals/shotgun.ts +0 -203
  442. package/src/tools/watch/screen-watch.ts +0 -144
  443. package/src/tools/watch/watch-state.ts +0 -142
@@ -191,10 +191,7 @@ export function consolidateAssistantMessages(
191
191
 
192
192
  // Clean up Qdrant vectors (fire-and-forget)
193
193
  if (allSegmentIds.length > 0) {
194
- cleanupQdrantVectors(
195
- conversationId,
196
- allSegmentIds,
197
- ).catch((err) => {
194
+ cleanupQdrantVectors(conversationId, allSegmentIds).catch((err) => {
198
195
  log.warn(
199
196
  { err, conversationId },
200
197
  "Qdrant cleanup after consolidation failed (non-fatal)",
@@ -326,10 +323,7 @@ export function consolidateAssistantMessages(
326
323
 
327
324
  // Clean up Qdrant vectors (fire-and-forget)
328
325
  if (allSegmentIds.length > 0) {
329
- cleanupQdrantVectors(
330
- conversationId,
331
- allSegmentIds,
332
- ).catch((err) => {
326
+ cleanupQdrantVectors(conversationId, allSegmentIds).catch((err) => {
333
327
  log.warn(
334
328
  { err, conversationId },
335
329
  "Qdrant cleanup after consolidation failed (non-fatal)",
@@ -365,7 +359,6 @@ export interface HistoryConversationContext {
365
359
  userMessageId: string,
366
360
  onEvent: (msg: ServerMessage) => void,
367
361
  options?: {
368
- skipPreMessageRollback?: boolean;
369
362
  isUserMessage?: boolean;
370
363
  titleText?: string;
371
364
  },
@@ -534,15 +527,14 @@ export async function regenerate(
534
527
  }
535
528
 
536
529
  // Clean up Qdrant vectors (fire-and-forget).
537
- cleanupQdrantVectors(
538
- conversation.conversationId,
539
- allSegmentIds,
540
- ).catch((err) => {
541
- log.warn(
542
- { err, conversationId: conversation.conversationId },
543
- "Qdrant cleanup after regenerate failed (non-fatal)",
544
- );
545
- });
530
+ cleanupQdrantVectors(conversation.conversationId, allSegmentIds).catch(
531
+ (err) => {
532
+ log.warn(
533
+ { err, conversationId: conversation.conversationId },
534
+ "Qdrant cleanup after regenerate failed (non-fatal)",
535
+ );
536
+ },
537
+ );
546
538
 
547
539
  // Re-extract the user message content for the agent loop.
548
540
  // Use all content blocks (text, image, file) so attachments are
@@ -581,7 +573,6 @@ export async function regenerate(
581
573
  // observability contract is preserved on those paths too.
582
574
  void conversation
583
575
  .runAgentLoop(content, existingUserMessageId, onEvent, {
584
- skipPreMessageRollback: true,
585
576
  isUserMessage: true,
586
577
  })
587
578
  .catch((err) => {
@@ -8,7 +8,6 @@ import { createContextSummaryMessage } from "../context/window-manager.js";
8
8
  import type { EventBus } from "../events/bus.js";
9
9
  import type { AssistantDomainEvents } from "../events/domain-events.js";
10
10
  import type { ToolProfiler } from "../events/tool-profiling-listener.js";
11
- import { getHookManager } from "../hooks/manager.js";
12
11
  import { enqueueAutoAnalysisIfEnabled } from "../memory/auto-analysis-enqueue.js";
13
12
  import { isAutoAnalysisConversation } from "../memory/auto-analysis-guard.js";
14
13
  import {
@@ -27,10 +26,7 @@ import {
27
26
  import { unregisterConversationSender } from "../tools/browser/browser-screencast.js";
28
27
  import { type AbortReason, createAbortReason } from "../util/abort-reasons.js";
29
28
  import { getLogger } from "../util/logger.js";
30
- import {
31
- unregisterCallNotifiers,
32
- unregisterWatchNotifiers,
33
- } from "./conversation-notifiers.js";
29
+ import { unregisterCallNotifiers } from "./conversation-notifiers.js";
34
30
  import type { MessageQueue } from "./conversation-queue-manager.js";
35
31
  import { resetSkillToolProjection } from "./conversation-skill-tools.js";
36
32
  import { repairHistory } from "./history-repair.js";
@@ -208,21 +204,34 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
208
204
 
209
205
  content = reinjectImageSourcePaths(content, role, m.metadata);
210
206
 
211
- // Re-inject persisted memory block from metadata so it survives
207
+ // Re-inject persisted injection blocks from metadata so it survives
212
208
  // conversation reloads (eviction, restart, fork).
213
209
  if (role === "user" && m.metadata) {
214
210
  try {
215
211
  const meta = JSON.parse(m.metadata);
216
212
  const isTail = index === arr.length - 1;
217
213
 
218
- // turn_context and system_reminder rehydrate for historical rows
219
- // only; the tail gets fresh blocks via applyRuntimeInjections on
220
- // the next turn. All three rehydration steps are prepends — the
221
- // ordering below (system_reminder first, memory second,
222
- // turn_context last) builds the documented shape right-to-left,
223
- // since each prepend shifts previously-prepended blocks one slot
224
- // right:
225
- // [<turn_context>, <memory __injected>, <system_reminder>, ...original]
214
+ // All rehydration steps are prepends the ordering below
215
+ // (innermost block first, outermost last) builds the documented
216
+ // shape right-to-left, since each prepend shifts previously-
217
+ // prepended blocks one slot right:
218
+ // [<workspace>, <turn_context>, <NOW.md>, <memory __injected>,
219
+ // <system_reminder>, <knowledge_base>, ...original]
220
+ //
221
+ // Persisted non-tail rows rehydrate the full set so Anthropic's
222
+ // prefix cache keeps matching msg[0] across daemon restarts and
223
+ // conversation eviction. The tail row gets fresh blocks via
224
+ // applyRuntimeInjections on the next turn, so rehydration for the
225
+ // tail is limited to blocks that the next turn's injection pipeline
226
+ // cannot reconstruct (currently just `memoryInjectedBlock`, which
227
+ // is not always re-injected on the next turn).
228
+ if (!isTail && typeof meta.pkbContextBlock === "string") {
229
+ content = [
230
+ { type: "text" as const, text: meta.pkbContextBlock },
231
+ ...content,
232
+ ];
233
+ }
234
+
226
235
  if (!isTail && typeof meta.pkbSystemReminderBlock === "string") {
227
236
  content = [
228
237
  { type: "text" as const, text: meta.pkbSystemReminderBlock },
@@ -241,12 +250,26 @@ export async function loadFromDb(ctx: LoadFromDbContext): Promise<void> {
241
250
  ];
242
251
  }
243
252
 
253
+ if (!isTail && typeof meta.nowScratchpadBlock === "string") {
254
+ content = [
255
+ { type: "text" as const, text: meta.nowScratchpadBlock },
256
+ ...content,
257
+ ];
258
+ }
259
+
244
260
  if (!isTail && typeof meta.turnContextBlock === "string") {
245
261
  content = [
246
262
  { type: "text" as const, text: meta.turnContextBlock },
247
263
  ...content,
248
264
  ];
249
265
  }
266
+
267
+ if (!isTail && typeof meta.workspaceBlock === "string") {
268
+ content = [
269
+ { type: "text" as const, text: meta.workspaceBlock },
270
+ ...content,
271
+ ];
272
+ }
250
273
  } catch {
251
274
  /* ignore parse errors — metadata may be malformed */
252
275
  }
@@ -314,7 +337,6 @@ export function abortConversation(
314
337
  ctx.surfaceActionRequestIds.clear();
315
338
  ctx.surfaceState.clear();
316
339
  ctx.accumulatedSurfaceState.clear();
317
- unregisterWatchNotifiers(ctx.conversationId);
318
340
  for (const queued of ctx.queue) {
319
341
  queued.onEvent({
320
342
  type: "generation_cancelled",
@@ -328,10 +350,6 @@ export function abortConversation(
328
350
  // ── dispose ──────────────────────────────────────────────────────────
329
351
 
330
352
  export function disposeConversation(ctx: DisposeContext): void {
331
- void getHookManager().trigger("conversation-end", {
332
- conversationId: ctx.conversationId,
333
- });
334
-
335
353
  // Trigger graph extraction for end-of-conversation sweep.
336
354
  // Only extract from guardian conversations to preserve the memory trust
337
355
  // boundary — untrusted content must not influence future memory retrieval.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Watch and call notifier registration/unregistration, extracted from
2
+ * Call notifier registration/unregistration, extracted from
3
3
  * the Conversation constructor and dispose/abort methods.
4
4
  *
5
5
  * Notifier callbacks read from the provided context object at invocation
@@ -22,24 +22,9 @@ import {
22
22
  addMessage,
23
23
  provenanceFromTrustContext,
24
24
  } from "../memory/conversation-crud.js";
25
- import { setMessageIdOnLogs } from "../memory/llm-request-log-store.js";
26
25
  import type { Message } from "../providers/types.js";
27
- import type { WatchSession } from "../tools/watch/watch-state.js";
28
- import {
29
- pruneWatchSessions,
30
- registerWatchCommentaryNotifier,
31
- registerWatchCompletionNotifier,
32
- registerWatchStartNotifier,
33
- unregisterWatchCommentaryNotifier,
34
- unregisterWatchCompletionNotifier,
35
- unregisterWatchStartNotifier,
36
- } from "../tools/watch/watch-state.js";
37
26
  import type { TrustContext } from "./conversation-runtime-assembly.js";
38
27
  import type { ServerMessage } from "./message-protocol.js";
39
- import {
40
- lastCommentaryByConversation,
41
- lastSummaryByConversation,
42
- } from "./watch-handler.js";
43
28
 
44
29
  /**
45
30
  * Subset of Conversation state that notifier callbacks need to read at
@@ -52,7 +37,7 @@ export interface NotifierConversationContext {
52
37
  }
53
38
 
54
39
  /**
55
- * Register watch and call notifiers for a conversation. Call once during
40
+ * Register call notifiers for a conversation. Call once during
56
41
  * construction; the notifier callbacks close over `ctx` so they see
57
42
  * live sendToClient/messages values.
58
43
  */
@@ -60,88 +45,6 @@ export function registerConversationNotifiers(
60
45
  conversationId: string,
61
46
  ctx: NotifierConversationContext,
62
47
  ): void {
63
- registerWatchStartNotifier(conversationId, (session: WatchSession) => {
64
- ctx.sendToClient({
65
- type: "watch_started",
66
- conversationId: conversationId,
67
- watchId: session.watchId,
68
- durationSeconds: session.durationSeconds,
69
- intervalSeconds: session.intervalSeconds,
70
- });
71
- });
72
-
73
- registerWatchCommentaryNotifier(
74
- conversationId,
75
- async (_session: WatchSession) => {
76
- const result = lastCommentaryByConversation.get(conversationId);
77
- if (result) {
78
- lastCommentaryByConversation.delete(conversationId);
79
-
80
- const msg = await addMessage(
81
- conversationId,
82
- "assistant",
83
- JSON.stringify([{ type: "text", text: result.text }]),
84
- provenanceFromTrustContext(ctx.trustContext),
85
- );
86
- ctx.messages.push(createAssistantMessage(result.text));
87
-
88
- try {
89
- setMessageIdOnLogs(result.logIds, msg.id);
90
- } catch {
91
- // non-fatal — message is persisted even if log linkage fails
92
- }
93
-
94
- ctx.sendToClient({
95
- type: "assistant_text_delta",
96
- text: result.text,
97
- conversationId: conversationId,
98
- });
99
- ctx.sendToClient({
100
- type: "message_complete",
101
- conversationId: conversationId,
102
- messageId: msg.id,
103
- source: "aux",
104
- });
105
- }
106
- },
107
- );
108
-
109
- registerWatchCompletionNotifier(
110
- conversationId,
111
- async (_session: WatchSession) => {
112
- const result = lastSummaryByConversation.get(conversationId);
113
- if (result) {
114
- lastSummaryByConversation.delete(conversationId);
115
-
116
- const msg = await addMessage(
117
- conversationId,
118
- "assistant",
119
- JSON.stringify([{ type: "text", text: result.text }]),
120
- provenanceFromTrustContext(ctx.trustContext),
121
- );
122
- ctx.messages.push(createAssistantMessage(result.text));
123
-
124
- try {
125
- setMessageIdOnLogs(result.logIds, msg.id);
126
- } catch {
127
- // non-fatal — message is persisted even if log linkage fails
128
- }
129
-
130
- ctx.sendToClient({
131
- type: "assistant_text_delta",
132
- text: result.text,
133
- conversationId: conversationId,
134
- });
135
- ctx.sendToClient({
136
- type: "message_complete",
137
- conversationId: conversationId,
138
- messageId: msg.id,
139
- source: "aux",
140
- });
141
- }
142
- },
143
- );
144
-
145
48
  registerCallQuestionNotifier(
146
49
  conversationId,
147
50
  async (callSessionId: string, question: string) => {
@@ -213,17 +116,6 @@ export function registerConversationNotifiers(
213
116
  });
214
117
  }
215
118
 
216
- /**
217
- * Unregister watch notifiers and prune watch sessions. Called during
218
- * abort when the conversation is actively processing.
219
- */
220
- export function unregisterWatchNotifiers(conversationId: string): void {
221
- unregisterWatchStartNotifier(conversationId);
222
- unregisterWatchCommentaryNotifier(conversationId);
223
- unregisterWatchCompletionNotifier(conversationId);
224
- pruneWatchSessions(conversationId);
225
- }
226
-
227
119
  /**
228
120
  * Unregister call notifiers. Called during dispose regardless of
229
121
  * processing state (notifiers are registered in the constructor).
@@ -137,7 +137,6 @@ export interface ProcessConversationContext {
137
137
  userMessageId: string,
138
138
  onEvent: (msg: ServerMessage) => void,
139
139
  options?: {
140
- skipPreMessageRollback?: boolean;
141
140
  isInteractive?: boolean;
142
141
  isUserMessage?: boolean;
143
142
  titleText?: string;
@@ -157,7 +156,7 @@ export interface ProcessConversationContext {
157
156
  * separately with the correct registry-routed sender.
158
157
  */
159
158
  restoreProxyAvailability(options?: { skipBrowser?: boolean }): void;
160
- /** Restore only the host browser proxy (used by chrome-extension and macOS+extension drains). */
159
+ /** Restore only the host browser proxy (used by chrome-extension and macOS drains). */
161
160
  restoreBrowserProxyAvailability(): void;
162
161
  /**
163
162
  * Registry-routed sender override for the host browser proxy. When set,
@@ -477,6 +476,10 @@ async function drainSingleMessage(
477
476
  // When hostBrowserSenderOverride is set, skip the browser proxy here
478
477
  // — restoreBrowserProxyAvailability() below will handle it with the
479
478
  // correct registry-routed sender instead of the SSE hub emitter.
479
+ // When no override is set (macOS without extension), restoring the
480
+ // browser proxy via restoreProxyAvailability is correct — it will
481
+ // use the SSE sender so host_browser_request frames reach the
482
+ // desktop client directly.
480
483
  conversation.restoreProxyAvailability(
481
484
  conversation.hostBrowserSenderOverride
482
485
  ? { skipBrowser: true }
@@ -485,11 +488,11 @@ async function drainSingleMessage(
485
488
  conversation.addPreactivatedSkillId("computer-use");
486
489
  }
487
490
  // Tear down a stale hostBrowserProxy inherited from a prior turn on a
488
- // different interface (e.g. chrome-extension installed one, then a CLI
489
- // turn drains). Without this, restoreProxyAvailability() above would
490
- // re-enable the proxy and getCdpClient() would route browser tools
491
- // through host_browser_request and hang waiting for a client that this
492
- // turn's interface can't service.
491
+ // different interface (e.g. chrome-extension or macOS installed one,
492
+ // then a CLI turn drains). Without this, restoreProxyAvailability()
493
+ // above would re-enable the proxy and getCdpClient() would route
494
+ // browser tools through host_browser_request and hang waiting for a
495
+ // client that this turn's interface can't service.
493
496
  //
494
497
  // Skip teardown only when BOTH conditions hold:
495
498
  // 1. `hostBrowserSenderOverride` is set (live registry-routed sender)
@@ -498,6 +501,10 @@ async function drainSingleMessage(
498
501
  // Without the interface check, queued turns from CLI/iOS/Vellum would
499
502
  // inherit a stale override left by a prior extension-connected turn
500
503
  // and keep the proxy alive, causing cross-interface misrouting.
504
+ //
505
+ // macOS and chrome-extension both support host_browser natively, so
506
+ // this teardown only fires for interfaces that do not support
507
+ // host_browser at all (CLI, iOS, Vellum, channels).
501
508
  const currentTurnCanServiceBrowser =
502
509
  !!sourceInterface && canServiceRegistryBrowser(sourceInterface);
503
510
  if (