@vellumai/assistant 0.6.4 → 0.6.5

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 (717) hide show
  1. package/.prettierignore +5 -0
  2. package/ARCHITECTURE.md +32 -36
  3. package/Dockerfile +12 -0
  4. package/README.md +3 -4
  5. package/bun.lock +8 -3
  6. package/docs/architecture/integrations.md +1 -20
  7. package/docs/architecture/security.md +16 -16
  8. package/docs/error-handling.md +111 -0
  9. package/docs/skills.md +10 -10
  10. package/docs/stt-provider-onboarding.md +2 -1
  11. package/knip.json +9 -2
  12. package/node_modules/@vellumai/ces-contracts/package.json +2 -1
  13. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
  14. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
  15. package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
  16. package/node_modules/@vellumai/credential-storage/package.json +2 -2
  17. package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
  18. package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
  19. package/node_modules/@vellumai/egress-proxy/package.json +2 -2
  20. package/openapi.yaml +123 -11
  21. package/package.json +6 -3
  22. package/scripts/generate-openapi.ts +50 -11
  23. package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
  24. package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
  25. package/src/__tests__/agent-loop.test.ts +112 -1
  26. package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
  27. package/src/__tests__/anthropic-provider.test.ts +171 -2
  28. package/src/__tests__/approval-cascade.test.ts +31 -10
  29. package/src/__tests__/approval-routes-http.test.ts +134 -10
  30. package/src/__tests__/assistant-attachments.test.ts +44 -0
  31. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
  32. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  33. package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
  34. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
  35. package/src/__tests__/browser-skill-endstate.test.ts +51 -182
  36. package/src/__tests__/btw-routes.test.ts +47 -1
  37. package/src/__tests__/call-controller.test.ts +1 -2
  38. package/src/__tests__/call-site-routing-provider.test.ts +214 -0
  39. package/src/__tests__/catalog-cache.test.ts +27 -4
  40. package/src/__tests__/channel-approval-routes.test.ts +4 -4
  41. package/src/__tests__/channel-reply-delivery.test.ts +300 -2
  42. package/src/__tests__/checker.test.ts +428 -501
  43. package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
  44. package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
  45. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  46. package/src/__tests__/config-analysis.test.ts +11 -28
  47. package/src/__tests__/config-loader-backfill.test.ts +174 -0
  48. package/src/__tests__/config-loader-corrupt.test.ts +183 -0
  49. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
  50. package/src/__tests__/config-schema-cmd.test.ts +11 -5
  51. package/src/__tests__/config-schema.test.ts +427 -114
  52. package/src/__tests__/config-watcher.test.ts +2 -2
  53. package/src/__tests__/contact-store-user-file.test.ts +72 -73
  54. package/src/__tests__/contacts-write.test.ts +4 -4
  55. package/src/__tests__/context-token-estimator.test.ts +191 -1
  56. package/src/__tests__/context-window-manager.test.ts +530 -2
  57. package/src/__tests__/conversation-abort-tool-results.test.ts +30 -16
  58. package/src/__tests__/conversation-agent-loop-overflow.test.ts +61 -17
  59. package/src/__tests__/conversation-agent-loop.test.ts +412 -82
  60. package/src/__tests__/conversation-attachments.test.ts +1 -1
  61. package/src/__tests__/conversation-confirmation-signals.test.ts +30 -9
  62. package/src/__tests__/conversation-error.test.ts +37 -6
  63. package/src/__tests__/conversation-history-web-search.test.ts +6 -0
  64. package/src/__tests__/conversation-init.benchmark.test.ts +36 -0
  65. package/src/__tests__/conversation-lifecycle.test.ts +336 -0
  66. package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
  67. package/src/__tests__/conversation-pre-run-repair.test.ts +30 -16
  68. package/src/__tests__/conversation-process-callsite.test.ts +306 -0
  69. package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -16
  70. package/src/__tests__/conversation-queue.test.ts +41 -26
  71. package/src/__tests__/conversation-routes-disk-view.test.ts +29 -1
  72. package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
  73. package/src/__tests__/conversation-runtime-assembly.test.ts +2735 -55
  74. package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
  75. package/src/__tests__/conversation-skill-tools.test.ts +12 -146
  76. package/src/__tests__/conversation-slash-queue.test.ts +34 -19
  77. package/src/__tests__/conversation-slash-unknown.test.ts +30 -16
  78. package/src/__tests__/conversation-speed-override.test.ts +30 -11
  79. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
  80. package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
  81. package/src/__tests__/conversation-title-service.test.ts +2 -2
  82. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
  83. package/src/__tests__/conversation-unread-route.test.ts +2 -2
  84. package/src/__tests__/conversation-usage.test.ts +3 -1
  85. package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
  86. package/src/__tests__/conversation-workspace-injection.test.ts +43 -15
  87. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +44 -16
  88. package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
  89. package/src/__tests__/credential-security-invariants.test.ts +3 -0
  90. package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
  91. package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
  92. package/src/__tests__/credential-vault-unit.test.ts +135 -19
  93. package/src/__tests__/credentials-cli.test.ts +1 -9
  94. package/src/__tests__/cross-provider-web-search.test.ts +84 -0
  95. package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
  96. package/src/__tests__/delete-propagation.test.ts +437 -0
  97. package/src/__tests__/dm-backfill.test.ts +417 -0
  98. package/src/__tests__/dm-persistence.test.ts +227 -0
  99. package/src/__tests__/edit-propagation.test.ts +280 -0
  100. package/src/__tests__/ephemeral-permissions.test.ts +93 -3
  101. package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
  102. package/src/__tests__/estimator-calibration.test.ts +213 -0
  103. package/src/__tests__/extension-id-sync-guard.test.ts +26 -7
  104. package/src/__tests__/file-write-tool.test.ts +151 -1
  105. package/src/__tests__/filing-service.test.ts +255 -0
  106. package/src/__tests__/gemini-provider.test.ts +0 -3
  107. package/src/__tests__/guardian-grant-minting.test.ts +8 -0
  108. package/src/__tests__/headless-browser-interactions.test.ts +1 -1
  109. package/src/__tests__/heartbeat-service.test.ts +96 -15
  110. package/src/__tests__/host-shell-tool.test.ts +124 -18
  111. package/src/__tests__/http-user-message-parity.test.ts +29 -1
  112. package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
  113. package/src/__tests__/intent-routing.test.ts +1 -40
  114. package/src/__tests__/llm-catalog-parity.test.ts +174 -0
  115. package/src/__tests__/llm-context-normalization.test.ts +121 -0
  116. package/src/__tests__/llm-resolver.test.ts +214 -0
  117. package/src/__tests__/llm-schema.test.ts +223 -0
  118. package/src/__tests__/managed-proxy-context.test.ts +6 -2
  119. package/src/__tests__/messaging-skill-split.test.ts +3 -34
  120. package/src/__tests__/migration-import-from-url.test.ts +684 -0
  121. package/src/__tests__/model-intents.test.ts +9 -83
  122. package/src/__tests__/notification-decision-fallback.test.ts +0 -10
  123. package/src/__tests__/notification-decision-identity.test.ts +0 -9
  124. package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
  125. package/src/__tests__/oauth-store.test.ts +10 -7
  126. package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
  127. package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
  128. package/src/__tests__/openai-provider.test.ts +7 -0
  129. package/src/__tests__/openai-responses-provider.test.ts +396 -0
  130. package/src/__tests__/openrouter-provider-only.test.ts +135 -0
  131. package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
  132. package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
  133. package/src/__tests__/permission-mode.test.ts +16 -0
  134. package/src/__tests__/permission-types.test.ts +0 -1
  135. package/src/__tests__/persona-resolver.test.ts +13 -13
  136. package/src/__tests__/pkb-autoinject.test.ts +37 -1
  137. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
  138. package/src/__tests__/pricing.test.ts +50 -3
  139. package/src/__tests__/profiler-routes.test.ts +1 -1
  140. package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
  141. package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
  142. package/src/__tests__/provider-error-scenarios.test.ts +135 -6
  143. package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
  144. package/src/__tests__/provider-registry-ollama.test.ts +1 -2
  145. package/src/__tests__/proxy-approval-callback.test.ts +0 -1
  146. package/src/__tests__/reaction-persistence.test.ts +560 -0
  147. package/src/__tests__/relay-server.test.ts +1 -1
  148. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  149. package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
  150. package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
  151. package/src/__tests__/risk-classifier-parity.test.ts +230 -0
  152. package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
  153. package/src/__tests__/secret-ingress-http.test.ts +28 -0
  154. package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
  156. package/src/__tests__/secret-scanner-executor.test.ts +1 -1
  157. package/src/__tests__/send-endpoint-busy.test.ts +29 -1
  158. package/src/__tests__/server-history-render.test.ts +31 -0
  159. package/src/__tests__/shell-parser-property.test.ts +13 -13
  160. package/src/__tests__/skill-cache-store.test.ts +182 -0
  161. package/src/__tests__/skills.test.ts +19 -33
  162. package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
  163. package/src/__tests__/slack-skill.test.ts +3 -8
  164. package/src/__tests__/starter-bundle.test.ts +35 -0
  165. package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
  166. package/src/__tests__/suggestion-routes.test.ts +160 -3
  167. package/src/__tests__/system-prompt.test.ts +22 -35
  168. package/src/__tests__/task-runner.test.ts +3 -1
  169. package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
  170. package/src/__tests__/terminal-tools.test.ts +8 -0
  171. package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
  172. package/src/__tests__/thread-backfill.test.ts +941 -0
  173. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
  174. package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
  175. package/src/__tests__/tool-executor.test.ts +60 -94
  176. package/src/__tests__/trust-store.test.ts +442 -109
  177. package/src/__tests__/update-bulletin-job.test.ts +389 -0
  178. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
  179. package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
  180. package/src/__tests__/voice-session-bridge.test.ts +39 -0
  181. package/src/__tests__/volume-security-guard.test.ts +3 -2
  182. package/src/__tests__/web-search-history.test.ts +337 -0
  183. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
  184. package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
  185. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
  186. package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
  187. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
  188. package/src/__tests__/workspace-policy.test.ts +1 -13
  189. package/src/acp/client-handler.ts +1 -2
  190. package/src/agent/loop.ts +209 -17
  191. package/src/avatar/resvg-lazy.test.ts +136 -0
  192. package/src/avatar/resvg-lazy.ts +82 -9
  193. package/src/avatar/traits-png-sync.ts +21 -1
  194. package/src/browser/__tests__/operations.test.ts +163 -0
  195. package/src/browser/identifiers.ts +51 -0
  196. package/src/browser/operations.ts +660 -0
  197. package/src/browser/types.ts +81 -0
  198. package/src/calls/guardian-question-copy.ts +2 -2
  199. package/src/calls/telephony-stt-routing.ts +1 -1
  200. package/src/calls/voice-session-bridge.ts +1 -0
  201. package/src/cli/AGENTS.md +1 -1
  202. package/src/cli/commands/__tests__/attachment.test.ts +438 -0
  203. package/src/cli/commands/__tests__/browser.test.ts +554 -0
  204. package/src/cli/commands/__tests__/cache.test.ts +623 -0
  205. package/src/cli/commands/__tests__/email-list.test.ts +6 -0
  206. package/src/cli/commands/__tests__/email-send.test.ts +93 -1
  207. package/src/cli/commands/__tests__/image-generation.test.ts +666 -0
  208. package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
  209. package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
  210. package/src/cli/commands/__tests__/task.test.ts +913 -0
  211. package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
  212. package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
  213. package/src/cli/commands/__tests__/ui.test.ts +1215 -0
  214. package/src/cli/commands/__tests__/watchers.test.ts +716 -0
  215. package/src/cli/commands/attachment.ts +182 -0
  216. package/src/cli/commands/browser.ts +350 -0
  217. package/src/cli/commands/cache.ts +341 -0
  218. package/src/cli/commands/completions.ts +0 -3
  219. package/src/cli/commands/config.ts +6 -6
  220. package/src/cli/commands/conversations-import.ts +347 -0
  221. package/src/cli/commands/conversations.ts +14 -1
  222. package/src/cli/commands/email.ts +234 -194
  223. package/src/cli/commands/image-generation.ts +300 -0
  224. package/src/cli/commands/inference.ts +200 -0
  225. package/src/cli/commands/memory.ts +127 -17
  226. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
  227. package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
  228. package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
  229. package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
  230. package/src/cli/commands/stt.ts +339 -0
  231. package/src/cli/commands/task.ts +795 -0
  232. package/src/cli/commands/trust.ts +50 -19
  233. package/src/cli/commands/tts.ts +273 -0
  234. package/src/cli/commands/ui.ts +670 -0
  235. package/src/cli/commands/watchers.ts +509 -0
  236. package/src/cli/lib/daemon-credential-client.ts +0 -19
  237. package/src/cli/program.ts +23 -4
  238. package/src/cli.ts +0 -37
  239. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
  240. package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
  241. package/src/config/bundled-skills/messaging/SKILL.md +2 -2
  242. package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
  243. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +8 -1
  244. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
  245. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
  246. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
  247. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
  248. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  249. package/src/config/bundled-tool-registry.ts +0 -175
  250. package/src/config/env.ts +7 -2
  251. package/src/config/feature-flag-registry.json +25 -9
  252. package/src/config/llm-resolver.ts +128 -0
  253. package/src/config/loader.ts +194 -10
  254. package/src/config/raw-config-utils.ts +30 -2
  255. package/src/config/sanitize-for-transfer.ts +35 -0
  256. package/src/config/schema.ts +30 -41
  257. package/src/config/schemas/analysis.ts +3 -22
  258. package/src/config/schemas/calls.ts +0 -4
  259. package/src/config/schemas/filing.ts +2 -7
  260. package/src/config/schemas/heartbeat.ts +0 -5
  261. package/src/config/schemas/inference.ts +3 -23
  262. package/src/config/schemas/llm.ts +318 -0
  263. package/src/config/schemas/memory-processing.ts +1 -9
  264. package/src/config/schemas/notifications.ts +4 -11
  265. package/src/config/schemas/platform.ts +3 -9
  266. package/src/config/schemas/security.ts +33 -0
  267. package/src/config/schemas/services.ts +9 -4
  268. package/src/config/schemas/stt.ts +1 -0
  269. package/src/config/schemas/tts.ts +53 -0
  270. package/src/config/schemas/updates.ts +1 -1
  271. package/src/config/schemas/workspace-git.ts +3 -40
  272. package/src/config/skills.ts +2 -2
  273. package/src/context/__tests__/compact-prompt.test.ts +45 -0
  274. package/src/context/__tests__/microcompact.test.ts +805 -0
  275. package/src/context/estimator-calibration.ts +136 -0
  276. package/src/context/microcompact.ts +443 -0
  277. package/src/context/prompts/compact.md +12 -0
  278. package/src/context/token-estimator.ts +61 -3
  279. package/src/context/window-manager.ts +229 -25
  280. package/src/credential-execution/approval-bridge.ts +0 -1
  281. package/src/credential-execution/executable-discovery.ts +19 -8
  282. package/src/credential-execution/process-manager.test.ts +109 -0
  283. package/src/credential-execution/process-manager.ts +65 -2
  284. package/src/daemon/approval-generators.ts +29 -4
  285. package/src/daemon/assistant-attachments.ts +24 -13
  286. package/src/daemon/classifier.ts +2 -2
  287. package/src/daemon/config-watcher.ts +0 -1
  288. package/src/daemon/context-overflow-reducer.ts +4 -1
  289. package/src/daemon/conversation-agent-loop-handlers.ts +79 -12
  290. package/src/daemon/conversation-agent-loop.ts +462 -80
  291. package/src/daemon/conversation-attachments.ts +2 -6
  292. package/src/daemon/conversation-error.ts +36 -1
  293. package/src/daemon/conversation-lifecycle.ts +30 -6
  294. package/src/daemon/conversation-messaging.ts +73 -4
  295. package/src/daemon/conversation-process.ts +10 -4
  296. package/src/daemon/conversation-queue-manager.ts +3 -0
  297. package/src/daemon/conversation-runtime-assembly.ts +760 -29
  298. package/src/daemon/conversation-slash.ts +2 -2
  299. package/src/daemon/conversation-surfaces.ts +389 -1
  300. package/src/daemon/conversation-tool-setup.ts +10 -5
  301. package/src/daemon/conversation-usage.ts +1 -1
  302. package/src/daemon/conversation.ts +118 -30
  303. package/src/daemon/external-skills-bootstrap.ts +41 -0
  304. package/src/daemon/guardian-action-generators.ts +34 -14
  305. package/src/daemon/handlers/config-model.test.ts +86 -0
  306. package/src/daemon/handlers/config-model.ts +54 -12
  307. package/src/daemon/handlers/conversations.ts +9 -2
  308. package/src/daemon/handlers/shared.ts +39 -11
  309. package/src/daemon/handlers/skills.ts +2 -2
  310. package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
  311. package/src/daemon/lifecycle.ts +76 -14
  312. package/src/daemon/message-types/conversations.ts +14 -0
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/trust.ts +0 -2
  315. package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
  316. package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
  317. package/src/daemon/pkb-context-tracker.test.ts +169 -0
  318. package/src/daemon/pkb-context-tracker.ts +125 -0
  319. package/src/daemon/pkb-reminder-builder.test.ts +70 -0
  320. package/src/daemon/pkb-reminder-builder.ts +31 -0
  321. package/src/daemon/providers-setup.ts +6 -0
  322. package/src/daemon/server.ts +117 -9
  323. package/src/daemon/tool-side-effects.ts +0 -9
  324. package/src/daemon/watch-handler.ts +4 -4
  325. package/src/daemon/web-search-history.ts +126 -0
  326. package/src/events/domain-events.ts +0 -1
  327. package/src/filing/filing-service.ts +9 -10
  328. package/src/heartbeat/heartbeat-service.ts +76 -28
  329. package/src/home/__tests__/feed-scheduler.test.ts +39 -11
  330. package/src/home/__tests__/rollup-producer.test.ts +44 -0
  331. package/src/home/assistant-feed-authoring.ts +4 -0
  332. package/src/home/emit-feed-event.ts +4 -0
  333. package/src/home/feed-scheduler.ts +20 -4
  334. package/src/home/feed-types.ts +56 -2
  335. package/src/home/relationship-state-writer.ts +2 -2
  336. package/src/home/rollup-producer.ts +34 -5
  337. package/src/home/suggested-prompts.ts +101 -0
  338. package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
  339. package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
  340. package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
  341. package/src/ipc/__tests__/socket-path.test.ts +73 -0
  342. package/src/ipc/__tests__/task-ipc.test.ts +577 -0
  343. package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
  344. package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
  345. package/src/ipc/cli-client.ts +2 -1
  346. package/src/ipc/cli-server.ts +26 -8
  347. package/src/ipc/gateway-client.ts +4 -4
  348. package/src/ipc/routes/attachment.ts +114 -0
  349. package/src/ipc/routes/browser-context.ts +61 -0
  350. package/src/ipc/routes/browser.ts +96 -0
  351. package/src/ipc/routes/cache.ts +96 -0
  352. package/src/ipc/routes/index.ts +17 -1
  353. package/src/ipc/routes/task-queue.ts +226 -0
  354. package/src/ipc/routes/task.ts +173 -0
  355. package/src/ipc/routes/ui-request.ts +50 -0
  356. package/src/ipc/routes/watcher.ts +203 -0
  357. package/src/ipc/socket-path.ts +100 -0
  358. package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
  359. package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
  360. package/src/memory/admin.ts +18 -0
  361. package/src/memory/conversation-analyze-job.ts +14 -13
  362. package/src/memory/conversation-attention-store.ts +13 -6
  363. package/src/memory/conversation-crud.ts +103 -3
  364. package/src/memory/conversation-group-migration.ts +38 -6
  365. package/src/memory/conversation-title-service.ts +7 -4
  366. package/src/memory/db-init.ts +2 -0
  367. package/src/memory/embedding-backend.ts +1 -1
  368. package/src/memory/graph/compaction.ts +299 -0
  369. package/src/memory/graph/consolidation.ts +4 -4
  370. package/src/memory/graph/conversation-graph-memory.ts +89 -29
  371. package/src/memory/graph/extraction.test.ts +272 -2
  372. package/src/memory/graph/extraction.ts +173 -51
  373. package/src/memory/graph/graph-search.test.ts +92 -0
  374. package/src/memory/graph/graph-search.ts +4 -1
  375. package/src/memory/graph/narrative.ts +2 -2
  376. package/src/memory/graph/pattern-scan.ts +2 -2
  377. package/src/memory/graph/retriever.test.ts +459 -0
  378. package/src/memory/graph/retriever.ts +230 -48
  379. package/src/memory/graph/store.ts +41 -0
  380. package/src/memory/graph/tool-handlers.ts +27 -0
  381. package/src/memory/graph/tools.ts +6 -1
  382. package/src/memory/indexer.ts +5 -5
  383. package/src/memory/job-handlers/conversation-starters.ts +23 -20
  384. package/src/memory/job-handlers/summarization.ts +2 -2
  385. package/src/memory/job-utils.ts +7 -1
  386. package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
  387. package/src/memory/jobs/embed-pkb-file.ts +54 -0
  388. package/src/memory/jobs-store.ts +44 -3
  389. package/src/memory/jobs-worker.ts +4 -0
  390. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
  391. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
  392. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
  393. package/src/memory/migrations/index.ts +1 -0
  394. package/src/memory/pkb/pkb-index.test.ts +368 -0
  395. package/src/memory/pkb/pkb-index.ts +255 -0
  396. package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
  397. package/src/memory/pkb/pkb-reconcile.ts +148 -0
  398. package/src/memory/pkb/pkb-search.test.ts +438 -0
  399. package/src/memory/pkb/pkb-search.ts +137 -0
  400. package/src/memory/pkb/types.ts +53 -0
  401. package/src/memory/qdrant-client.ts +122 -1
  402. package/src/memory/slack-thread-store.ts +37 -0
  403. package/src/messaging/providers/gmail/adapter.ts +6 -16
  404. package/src/messaging/providers/gmail/client.ts +22 -0
  405. package/src/messaging/providers/gmail/types.ts +7 -0
  406. package/src/messaging/providers/slack/adapter.ts +14 -2
  407. package/src/messaging/providers/slack/backfill.test.ts +257 -0
  408. package/src/messaging/providers/slack/backfill.ts +101 -0
  409. package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
  410. package/src/messaging/providers/slack/message-metadata.ts +123 -0
  411. package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
  412. package/src/messaging/providers/slack/render-transcript.ts +443 -0
  413. package/src/messaging/style-analyzer.ts +5 -2
  414. package/src/notifications/README.md +9 -5
  415. package/src/notifications/decision-engine.ts +3 -9
  416. package/src/notifications/preference-extractor.ts +2 -6
  417. package/src/oauth/oauth-store.ts +1 -0
  418. package/src/oauth/platform-connection.test.ts +47 -0
  419. package/src/oauth/platform-connection.ts +15 -5
  420. package/src/oauth/seed-providers.ts +4 -2
  421. package/src/permissions/approval-policy.test.ts +948 -0
  422. package/src/permissions/approval-policy.ts +257 -0
  423. package/src/permissions/bash-risk-classifier.test.ts +1208 -0
  424. package/src/permissions/bash-risk-classifier.ts +707 -0
  425. package/src/permissions/checker.ts +217 -708
  426. package/src/permissions/command-registry.test.ts +535 -0
  427. package/src/permissions/command-registry.ts +825 -0
  428. package/src/permissions/defaults.ts +26 -78
  429. package/src/permissions/file-risk-classifier.test.ts +535 -0
  430. package/src/permissions/file-risk-classifier.ts +274 -0
  431. package/src/permissions/risk-types.ts +205 -0
  432. package/src/permissions/secret-prompter.ts +53 -2
  433. package/src/permissions/skill-risk-classifier.test.ts +311 -0
  434. package/src/permissions/skill-risk-classifier.ts +214 -0
  435. package/src/permissions/trust-client.ts +52 -25
  436. package/src/permissions/trust-store-interface.ts +1 -6
  437. package/src/permissions/trust-store.ts +161 -62
  438. package/src/permissions/types.ts +23 -14
  439. package/src/permissions/web-risk-classifier.test.ts +170 -0
  440. package/src/permissions/web-risk-classifier.ts +89 -0
  441. package/src/permissions/workspace-policy.ts +1 -16
  442. package/src/platform/client.ts +19 -1
  443. package/src/prompts/persona-resolver.ts +3 -3
  444. package/src/prompts/system-prompt.ts +19 -20
  445. package/src/prompts/templates/SOUL.md +2 -2
  446. package/src/prompts/update-bulletin-job.ts +190 -0
  447. package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
  448. package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
  449. package/src/providers/__tests__/retry-callsite.test.ts +424 -0
  450. package/src/providers/anthropic/client.ts +183 -14
  451. package/src/providers/call-site-routing.ts +71 -0
  452. package/src/providers/gemini/client.ts +65 -2
  453. package/src/providers/managed-proxy/constants.ts +2 -1
  454. package/src/providers/model-catalog.ts +501 -33
  455. package/src/providers/model-intents.ts +4 -4
  456. package/src/providers/openai/chat-completions-provider.ts +57 -1
  457. package/src/providers/openai/responses-provider.ts +86 -9
  458. package/src/providers/openrouter/client.ts +76 -9
  459. package/src/providers/provider-env-vars.ts +56 -0
  460. package/src/providers/provider-send-message.ts +22 -5
  461. package/src/providers/ratelimit.ts +4 -0
  462. package/src/providers/registry.ts +19 -8
  463. package/src/providers/retry.ts +174 -39
  464. package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
  465. package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
  466. package/src/providers/speech-to-text/provider-catalog.ts +17 -0
  467. package/src/providers/speech-to-text/resolve.ts +7 -0
  468. package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
  469. package/src/providers/speech-to-text/xai-realtime.ts +796 -0
  470. package/src/providers/speech-to-text/xai.test.ts +155 -0
  471. package/src/providers/speech-to-text/xai.ts +97 -0
  472. package/src/providers/types.ts +93 -3
  473. package/src/runtime/AGENTS.md +2 -2
  474. package/src/runtime/__tests__/agent-wake.test.ts +43 -2
  475. package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
  476. package/src/runtime/agent-wake.ts +63 -22
  477. package/src/runtime/auth/route-policy.ts +4 -0
  478. package/src/runtime/btw-sidechain.ts +13 -3
  479. package/src/runtime/channel-reply-delivery.ts +106 -2
  480. package/src/runtime/decision-token.ts +116 -0
  481. package/src/runtime/gateway-client.ts +2 -2
  482. package/src/runtime/http-router.ts +32 -0
  483. package/src/runtime/http-server.ts +52 -1
  484. package/src/runtime/http-types.ts +23 -1
  485. package/src/runtime/interactive-ui.ts +362 -0
  486. package/src/runtime/invite-instruction-generator.ts +2 -2
  487. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
  488. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
  489. package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
  490. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
  491. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
  492. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
  493. package/src/runtime/migrations/gcs-signed-url.ts +162 -0
  494. package/src/runtime/migrations/vbundle-importer.ts +154 -9
  495. package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
  496. package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
  497. package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
  498. package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
  499. package/src/runtime/migrations/vbundle-validator.ts +15 -6
  500. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
  501. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
  502. package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
  503. package/src/runtime/routes/approval-prompt-ts-tracker.ts +58 -0
  504. package/src/runtime/routes/approval-routes.ts +12 -17
  505. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
  506. package/src/runtime/routes/avatar-routes.ts +20 -4
  507. package/src/runtime/routes/btw-routes.ts +1 -4
  508. package/src/runtime/routes/conversation-management-routes.ts +20 -2
  509. package/src/runtime/routes/conversation-routes.ts +133 -27
  510. package/src/runtime/routes/debug-routes.ts +1 -1
  511. package/src/runtime/routes/diagnostics-routes.ts +6 -4
  512. package/src/runtime/routes/events-routes.ts +16 -0
  513. package/src/runtime/routes/guardian-approval-interception.ts +33 -3
  514. package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
  515. package/src/runtime/routes/home-feed-routes.ts +120 -2
  516. package/src/runtime/routes/inbound-message-handler.ts +912 -2
  517. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
  518. package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
  519. package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
  520. package/src/runtime/routes/integrations/slack/channel.ts +25 -3
  521. package/src/runtime/routes/llm-context-normalization.ts +23 -1
  522. package/src/runtime/routes/migration-routes.ts +720 -124
  523. package/src/runtime/routes/settings-routes.ts +4 -2
  524. package/src/runtime/routes/trust-rules-routes.ts +30 -14
  525. package/src/runtime/routes/work-items-routes.test.ts +1 -1
  526. package/src/runtime/routes/work-items-routes.ts +3 -2
  527. package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
  528. package/src/runtime/services/analyze-conversation.ts +12 -16
  529. package/src/runtime/skill-route-registry.ts +28 -6
  530. package/src/schedule/scheduler.ts +8 -0
  531. package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
  532. package/src/security/__tests__/untrusted-content.test.ts +109 -0
  533. package/src/security/oauth2.ts +98 -35
  534. package/src/security/secure-keys.ts +7 -8
  535. package/src/security/token-manager.ts +27 -13
  536. package/src/security/untrusted-content.ts +102 -0
  537. package/src/skills/catalog-cache.ts +26 -7
  538. package/src/skills/catalog-install.ts +31 -3
  539. package/src/skills/skill-cache-store.ts +97 -0
  540. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
  541. package/src/stt/daemon-batch-transcriber.ts +33 -0
  542. package/src/stt/stt-stream-session.ts +8 -1
  543. package/src/stt/types.ts +5 -1
  544. package/src/subagent/manager.ts +41 -13
  545. package/src/tasks/ephemeral-permissions.ts +9 -4
  546. package/src/telemetry/usage-telemetry-reporter.ts +27 -5
  547. package/src/tools/browser/__tests__/browser-status.test.ts +45 -2
  548. package/src/tools/browser/browser-execution.ts +65 -38
  549. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
  550. package/src/tools/credentials/tool-policy.ts +39 -5
  551. package/src/tools/credentials/vault.ts +9 -4
  552. package/src/tools/executor.ts +4 -0
  553. package/src/tools/filesystem/write.ts +52 -0
  554. package/src/tools/host-terminal/host-shell.ts +45 -5
  555. package/src/tools/memory/register.test.ts +185 -0
  556. package/src/tools/memory/register.ts +3 -1
  557. package/src/tools/network/web-fetch.ts +20 -10
  558. package/src/tools/network/web-search.ts +19 -4
  559. package/src/tools/permission-checker.ts +36 -15
  560. package/src/tools/policy-context.ts +25 -8
  561. package/src/tools/registry.ts +55 -3
  562. package/src/tools/side-effects.ts +0 -11
  563. package/src/tools/skills/execute.ts +2 -2
  564. package/src/tools/skills/sandbox-runner.ts +5 -2
  565. package/src/tools/terminal/backends/native.ts +51 -2
  566. package/src/tools/terminal/safe-env.ts +3 -2
  567. package/src/tools/terminal/shell.ts +1 -0
  568. package/src/tools/tool-manifest.ts +6 -21
  569. package/src/tools/types.ts +12 -3
  570. package/src/tools/verification-control-plane-policy.ts +1 -1
  571. package/src/tts/__tests__/provider-adapters.test.ts +240 -13
  572. package/src/tts/provider-catalog.ts +18 -0
  573. package/src/tts/providers/index.ts +2 -0
  574. package/src/tts/providers/xai-provider.ts +224 -0
  575. package/src/tts/types.ts +46 -0
  576. package/src/types/tar-stream.d.ts +66 -0
  577. package/src/util/json.ts +17 -0
  578. package/src/util/platform.ts +2 -2
  579. package/src/util/pricing.ts +15 -5
  580. package/src/watcher/engine.ts +1 -1
  581. package/src/watcher/providers/google-calendar.ts +134 -8
  582. package/src/watcher/providers/outlook-calendar.ts +42 -2
  583. package/src/workspace/git-service.ts +23 -4
  584. package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
  585. package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
  586. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
  587. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
  588. package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
  589. package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
  590. package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
  591. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
  592. package/src/workspace/migrations/AGENTS.md +1 -1
  593. package/src/workspace/migrations/registry.ts +16 -0
  594. package/src/workspace/provider-commit-message-generator.ts +19 -38
  595. package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
  596. package/src/__tests__/gmail-archive-gate.test.ts +0 -246
  597. package/src/__tests__/gmail-preferences.test.ts +0 -117
  598. package/src/__tests__/outlook-attachments.test.ts +0 -301
  599. package/src/__tests__/outlook-automation-tools.test.ts +0 -425
  600. package/src/__tests__/outlook-categories.test.ts +0 -212
  601. package/src/__tests__/outlook-compose-tools.test.ts +0 -325
  602. package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
  603. package/src/__tests__/outlook-follow-up.test.ts +0 -196
  604. package/src/__tests__/outlook-trash.test.ts +0 -77
  605. package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
  606. package/src/__tests__/update-bulletin-format.test.ts +0 -181
  607. package/src/__tests__/update-bulletin-state.test.ts +0 -135
  608. package/src/__tests__/update-bulletin.test.ts +0 -478
  609. package/src/__tests__/update-template-contract.test.ts +0 -29
  610. package/src/cli/commands/doctor.ts +0 -341
  611. package/src/config/bundled-skills/browser/SKILL.md +0 -88
  612. package/src/config/bundled-skills/browser/TOOLS.json +0 -516
  613. package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
  614. package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
  615. package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
  616. package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
  617. package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
  618. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
  619. package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
  620. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
  621. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
  622. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
  623. package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
  624. package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
  625. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
  626. package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
  627. package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
  628. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
  629. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
  630. package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
  631. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
  632. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
  633. package/src/config/bundled-skills/gmail/SKILL.md +0 -221
  634. package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
  635. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
  636. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
  637. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
  638. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
  639. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
  640. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
  641. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
  642. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
  643. package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
  644. package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
  645. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
  646. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
  647. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
  648. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
  649. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
  650. package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
  651. package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
  652. package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
  653. package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
  654. package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
  655. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
  656. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
  657. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
  658. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
  659. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
  660. package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
  661. package/src/config/bundled-skills/google-calendar/types.ts +0 -97
  662. package/src/config/bundled-skills/outlook/SKILL.md +0 -196
  663. package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
  664. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
  665. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
  666. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
  667. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
  668. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
  669. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
  670. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
  671. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
  672. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
  673. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
  674. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
  675. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
  676. package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
  677. package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
  678. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
  679. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
  680. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
  681. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
  682. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
  683. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
  684. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
  685. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
  686. package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
  687. package/src/config/bundled-skills/slack/SKILL.md +0 -108
  688. package/src/config/bundled-skills/tasks/SKILL.md +0 -37
  689. package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
  690. package/src/config/bundled-skills/tasks/icon.svg +0 -34
  691. package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
  692. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
  693. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
  694. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
  695. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
  696. package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
  697. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
  698. package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
  699. package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
  700. package/src/config/bundled-skills/watcher/SKILL.md +0 -31
  701. package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
  702. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
  703. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
  704. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
  705. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
  706. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
  707. package/src/prompts/templates/UPDATES.md +0 -50
  708. package/src/prompts/update-bulletin-format.ts +0 -85
  709. package/src/prompts/update-bulletin-state.ts +0 -58
  710. package/src/prompts/update-bulletin-template-path.ts +0 -13
  711. package/src/prompts/update-bulletin.ts +0 -139
  712. package/src/shared/provider-env-vars.ts +0 -19
  713. package/src/tools/watcher/create.ts +0 -86
  714. package/src/tools/watcher/delete.ts +0 -36
  715. package/src/tools/watcher/digest.ts +0 -54
  716. package/src/tools/watcher/list.ts +0 -83
  717. package/src/tools/watcher/update.ts +0 -71
@@ -7,6 +7,34 @@ import { beforeEach, describe, expect, mock, test } from "bun:test";
7
7
  const BASE_CONFIG = {
8
8
  contextWindow: { maxInputTokens: 100000 },
9
9
  services: { inference: { model: "test-model", provider: "test-provider" } },
10
+ llm: {
11
+ default: {
12
+ provider: "anthropic",
13
+ model: "claude-opus-4-7",
14
+ maxTokens: 64000,
15
+ effort: "max" as const,
16
+ speed: "standard" as const,
17
+ temperature: null,
18
+ thinking: { enabled: true, streamThinking: true },
19
+ contextWindow: {
20
+ enabled: true,
21
+ maxInputTokens: 200000,
22
+ targetBudgetRatio: 0.3,
23
+ compactThreshold: 0.8,
24
+ summaryBudgetRatio: 0.05,
25
+ overflowRecovery: {
26
+ enabled: true,
27
+ safetyMarginRatio: 0.05,
28
+ maxAttempts: 3,
29
+ interactiveLatestTurnCompression: "summarize",
30
+ nonInteractiveLatestTurnCompression: "truncate",
31
+ },
32
+ },
33
+ },
34
+ profiles: {},
35
+ callSites: {},
36
+ pricingOverrides: [],
37
+ },
10
38
  };
11
39
 
12
40
  let mockConfig: Record<string, unknown> = {
@@ -0,0 +1,125 @@
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ import type {
4
+ SecretRequest,
5
+ ServerMessage,
6
+ } from "../daemon/message-protocol.js";
7
+
8
+ // Use a tiny timeout so the setTimeout branch fires quickly in tests
9
+ const mockConfig = {
10
+ timeouts: { permissionTimeoutSec: 0.01 },
11
+ secretDetection: { allowOneTimeSend: false },
12
+ };
13
+ mock.module("../config/loader.js", () => ({
14
+ getConfig: () => mockConfig,
15
+ loadConfig: () => mockConfig,
16
+ invalidateConfigCache: () => {},
17
+ }));
18
+
19
+ mock.module("../util/logger.js", () => ({
20
+ getLogger: () => ({
21
+ info: () => {},
22
+ warn: () => {},
23
+ error: () => {},
24
+ debug: () => {},
25
+ trace: () => {},
26
+ fatal: () => {},
27
+ child: () => ({
28
+ info: () => {},
29
+ warn: () => {},
30
+ error: () => {},
31
+ debug: () => {},
32
+ }),
33
+ }),
34
+ }));
35
+
36
+ const { SecretPrompter } = await import("../permissions/secret-prompter.js");
37
+
38
+ describe("secret prompter channel fallback", () => {
39
+ let sentMessages: ServerMessage[];
40
+ let broadcastMessages: ServerMessage[];
41
+
42
+ beforeEach(() => {
43
+ sentMessages = [];
44
+ broadcastMessages = [];
45
+ });
46
+
47
+ test("fails fast with unsupported_channel error when channel lacks dynamic UI and no broadcast available", async () => {
48
+ const prompter = new SecretPrompter((msg) => sentMessages.push(msg));
49
+ prompter.setChannelContext({
50
+ channel: "slack",
51
+ supportsDynamicUi: false,
52
+ });
53
+
54
+ const result = await prompter.prompt("myservice", "apikey", "API Key");
55
+
56
+ expect(result.value).toBeNull();
57
+ expect(result.error).toBe("unsupported_channel");
58
+ // No message should have been sent since we failed fast
59
+ expect(sentMessages).toHaveLength(0);
60
+ });
61
+
62
+ test("broadcasts secret_request via SSE hub when channel lacks dynamic UI but broadcast is available", async () => {
63
+ const prompter = new SecretPrompter(
64
+ (msg) => sentMessages.push(msg),
65
+ (msg) => broadcastMessages.push(msg),
66
+ );
67
+ prompter.setChannelContext({
68
+ channel: "slack",
69
+ supportsDynamicUi: false,
70
+ });
71
+
72
+ const promise = prompter.prompt("myservice", "apikey", "API Key");
73
+
74
+ // Should have broadcast the message, not sent via per-channel sender
75
+ expect(sentMessages).toHaveLength(0);
76
+ expect(broadcastMessages).toHaveLength(1);
77
+ expect(broadcastMessages[0]!.type).toBe("secret_request");
78
+
79
+ // Resolve the prompt so it doesn't hang
80
+ const requestId = (broadcastMessages[0] as SecretRequest).requestId;
81
+ prompter.resolveSecret(requestId, "test-secret", "store");
82
+ const result = await promise;
83
+ expect(result.value).toBe("test-secret");
84
+ expect(result.error).toBeUndefined();
85
+ });
86
+
87
+ test("uses sendToClient when channel supports dynamic UI", async () => {
88
+ const prompter = new SecretPrompter(
89
+ (msg) => sentMessages.push(msg),
90
+ (msg) => broadcastMessages.push(msg),
91
+ );
92
+ prompter.setChannelContext({
93
+ channel: "macos",
94
+ supportsDynamicUi: true,
95
+ });
96
+
97
+ const promise = prompter.prompt("myservice", "apikey", "API Key");
98
+
99
+ // Should use per-channel sender, not broadcast
100
+ expect(sentMessages).toHaveLength(1);
101
+ expect(broadcastMessages).toHaveLength(0);
102
+ expect(sentMessages[0]!.type).toBe("secret_request");
103
+
104
+ const requestId = (sentMessages[0] as SecretRequest).requestId;
105
+ prompter.resolveSecret(requestId, "test-secret", "store");
106
+ await promise;
107
+ });
108
+
109
+ test("uses sendToClient when no channel context is set (desktop default)", async () => {
110
+ const prompter = new SecretPrompter(
111
+ (msg) => sentMessages.push(msg),
112
+ (msg) => broadcastMessages.push(msg),
113
+ );
114
+ // No setChannelContext call — desktop default
115
+
116
+ const promise = prompter.prompt("myservice", "apikey", "API Key");
117
+
118
+ expect(sentMessages).toHaveLength(1);
119
+ expect(broadcastMessages).toHaveLength(0);
120
+
121
+ const requestId = (sentMessages[0] as SecretRequest).requestId;
122
+ prompter.resolveSecret(requestId, "val", "store");
123
+ await promise;
124
+ });
125
+ });
@@ -11,7 +11,7 @@ let providerRefreshCalls = 0;
11
11
  const PLATFORM_BASE_URL = "https://platform.example.com";
12
12
  const ASSISTANT_API_KEY_PATH = credentialKey("vellum", "assistant_api_key");
13
13
  const PLATFORM_BASE_URL_PATH = credentialKey("vellum", "platform_base_url");
14
- const MANAGED_PROVIDERS = ["anthropic", "gemini"] as const;
14
+ const MANAGED_PROVIDERS = ["anthropic", "openai", "gemini"] as const;
15
15
 
16
16
  let platformBaseUrlOverride: string | undefined;
17
17
 
@@ -19,8 +19,6 @@ const mockConfig = {
19
19
  services: {
20
20
  inference: {
21
21
  mode: "your-own" as const,
22
- provider: "anthropic",
23
- model: "test-model",
24
22
  },
25
23
  "image-generation": {
26
24
  mode: "your-own" as const,
@@ -32,6 +30,7 @@ const mockConfig = {
32
30
  provider: "inference-provider-native",
33
31
  },
34
32
  },
33
+ llm: { default: { provider: "anthropic", model: "test-model" } },
35
34
  };
36
35
 
37
36
  mock.module("@google/genai", () => ({
@@ -50,7 +50,7 @@ mock.module("../util/logger.js", () => ({
50
50
  }));
51
51
 
52
52
  mock.module("../permissions/checker.js", () => ({
53
- classifyRisk: () => "low",
53
+ classifyRisk: () => ({ level: "low" }),
54
54
  check: () => ({ decision: "allow" }),
55
55
  generateAllowlistOptions: () => [],
56
56
  generateScopeOptions: () => [],
@@ -39,11 +39,39 @@ mock.module("../config/loader.js", () => ({
39
39
  rateLimit: { maxRequestsPerMinute: 0 },
40
40
  secretDetection: { enabled: false },
41
41
  contextWindow: { maxInputTokens: 200000 },
42
+ llm: {
43
+ default: {
44
+ provider: "anthropic",
45
+ model: "claude-opus-4-7",
46
+ maxTokens: 64000,
47
+ effort: "max" as const,
48
+ speed: "standard" as const,
49
+ temperature: null,
50
+ thinking: { enabled: true, streamThinking: true },
51
+ contextWindow: {
52
+ enabled: true,
53
+ maxInputTokens: 200000,
54
+ targetBudgetRatio: 0.3,
55
+ compactThreshold: 0.8,
56
+ summaryBudgetRatio: 0.05,
57
+ overflowRecovery: {
58
+ enabled: true,
59
+ safetyMarginRatio: 0.05,
60
+ maxAttempts: 3,
61
+ interactiveLatestTurnCompression: "summarize",
62
+ nonInteractiveLatestTurnCompression: "truncate",
63
+ },
64
+ },
65
+ },
66
+ profiles: {},
67
+ callSites: {},
68
+ pricingOverrides: [],
69
+ },
42
70
  services: {
43
71
  inference: {
44
72
  mode: "your-own",
45
73
  provider: "anthropic",
46
- model: "claude-opus-4-6",
74
+ model: "claude-opus-4-7",
47
75
  },
48
76
  "image-generation": {
49
77
  mode: "your-own",
@@ -332,6 +332,37 @@ describe("renderHistoryContent", () => {
332
332
  expect(output.textSegments).toEqual(["Now let me try something else."]);
333
333
  expect(output.contentOrder).toEqual(["tool:0", "text:0", "tool:1"]);
334
334
  });
335
+
336
+ test("drops Anthropic placeholder sentinel text blocks from history", () => {
337
+ // Sentinels are injected into outbound API requests for role alternation
338
+ // and must never render to the UI. Guards against any leak path that
339
+ // bypasses cleanAssistantContent (bug-prone stored rows, historical
340
+ // data predating migration 222, future regressions).
341
+ const output = renderHistoryContent([
342
+ { type: "text", text: "Real response before." },
343
+ { type: "text", text: "\x00__PLACEHOLDER__[empty assistant turn]" },
344
+ { type: "text", text: "__PLACEHOLDER__[empty assistant turn]" },
345
+ { type: "text", text: "\x00__PLACEHOLDER__[internal blocks omitted]" },
346
+ { type: "text", text: "__PLACEHOLDER__[internal blocks omitted]" },
347
+ { type: "text", text: "Real response after." },
348
+ ]);
349
+
350
+ expect(output.text).toBe("Real response before. Real response after.");
351
+ expect(output.textSegments).toEqual([
352
+ "Real response before. Real response after.",
353
+ ]);
354
+ expect(output.contentOrder).toEqual(["text:0"]);
355
+ });
356
+
357
+ test("yields empty output when content is only a placeholder sentinel", () => {
358
+ const output = renderHistoryContent([
359
+ { type: "text", text: "\x00__PLACEHOLDER__[empty assistant turn]" },
360
+ ]);
361
+
362
+ expect(output.text).toBe("");
363
+ expect(output.textSegments).toEqual([]);
364
+ expect(output.contentOrder).toEqual([]);
365
+ });
335
366
  });
336
367
 
337
368
  describe("getAttachmentsForMessage", () => {
@@ -68,7 +68,7 @@ describe("Shell parser property-based tests", () => {
68
68
  async (program, args) => {
69
69
  const command = [program, ...args].join(" ");
70
70
  const risk = await classifyRisk("bash", { command });
71
- expect(risk).toBe(RiskLevel.High);
71
+ expect(risk.level).toBe(RiskLevel.High);
72
72
  },
73
73
  ),
74
74
  { numRuns: 200, ...FC_OPTS },
@@ -83,7 +83,7 @@ describe("Shell parser property-based tests", () => {
83
83
  async (flag, target) => {
84
84
  const command = `rm ${flag} ${target}`;
85
85
  const risk = await classifyRisk("bash", { command });
86
- expect(risk).toBe(RiskLevel.High);
86
+ expect(risk.level).toBe(RiskLevel.High);
87
87
  },
88
88
  ),
89
89
  { numRuns: 100, ...FC_OPTS },
@@ -95,7 +95,7 @@ describe("Shell parser property-based tests", () => {
95
95
  fc.asyncProperty(fc.constantFrom("/", "~", "$HOME"), async (target) => {
96
96
  const command = `rm ${target}`;
97
97
  const risk = await classifyRisk("bash", { command });
98
- expect(risk).toBe(RiskLevel.High);
98
+ expect(risk.level).toBe(RiskLevel.High);
99
99
  }),
100
100
  { numRuns: 10, ...FC_OPTS },
101
101
  );
@@ -112,7 +112,7 @@ describe("Shell parser property-based tests", () => {
112
112
  async (program, args) => {
113
113
  const command = ["sudo", program, ...args].join(" ");
114
114
  const risk = await classifyRisk("bash", { command });
115
- expect(risk).toBe(RiskLevel.High);
115
+ expect(risk.level).toBe(RiskLevel.High);
116
116
  },
117
117
  ),
118
118
  { numRuns: 100, ...FC_OPTS },
@@ -133,7 +133,7 @@ describe("Shell parser property-based tests", () => {
133
133
  const args = kvPairs.map(([k, v]) => `${k}=${v}`);
134
134
  const command = ["dd", ...args].join(" ");
135
135
  const risk = await classifyRisk("bash", { command });
136
- expect(risk).toBe(RiskLevel.High);
136
+ expect(risk.level).toBe(RiskLevel.High);
137
137
  },
138
138
  ),
139
139
  { numRuns: 50, ...FC_OPTS },
@@ -180,7 +180,7 @@ describe("Shell parser property-based tests", () => {
180
180
  async (program, args) => {
181
181
  const command = [program, ...args].join(" ");
182
182
  const risk = await classifyRisk("bash", { command });
183
- expect(risk).toBe(RiskLevel.Low);
183
+ expect(risk.level).toBe(RiskLevel.Low);
184
184
  },
185
185
  ),
186
186
  { numRuns: 200, ...FC_OPTS },
@@ -208,7 +208,7 @@ describe("Shell parser property-based tests", () => {
208
208
  async (subcommand) => {
209
209
  const command = `git ${subcommand}`;
210
210
  const risk = await classifyRisk("bash", { command });
211
- expect(risk).toBe(RiskLevel.Low);
211
+ expect(risk.level).toBe(RiskLevel.Low);
212
212
  },
213
213
  ),
214
214
  { numRuns: 100, ...FC_OPTS },
@@ -227,7 +227,7 @@ describe("Shell parser property-based tests", () => {
227
227
  async (safe, dangerous) => {
228
228
  const command = `${safe} something | ${dangerous}`;
229
229
  const risk = await classifyRisk("bash", { command });
230
- expect(risk).toBe(RiskLevel.High);
230
+ expect(risk.level).toBe(RiskLevel.High);
231
231
  },
232
232
  ),
233
233
  { numRuns: 50, ...FC_OPTS },
@@ -242,7 +242,7 @@ describe("Shell parser property-based tests", () => {
242
242
  async (safe, dangerous) => {
243
243
  const command = `${safe} && ${dangerous}`;
244
244
  const risk = await classifyRisk("bash", { command });
245
- expect(risk).toBe(RiskLevel.High);
245
+ expect(risk.level).toBe(RiskLevel.High);
246
246
  },
247
247
  ),
248
248
  { numRuns: 50, ...FC_OPTS },
@@ -289,7 +289,7 @@ describe("Shell parser property-based tests", () => {
289
289
  async (commands) => {
290
290
  const command = commands.join(" | ");
291
291
  const risk = await classifyRisk("bash", { command });
292
- expect(risk).toBe(RiskLevel.Low);
292
+ expect(risk.level).toBe(RiskLevel.Low);
293
293
  },
294
294
  ),
295
295
  { numRuns: 100, ...FC_OPTS },
@@ -340,7 +340,7 @@ describe("Shell parser property-based tests", () => {
340
340
  async (input) => {
341
341
  const risk = await classifyRisk("bash", { command: input });
342
342
  expect([RiskLevel.Low, RiskLevel.Medium, RiskLevel.High]).toContain(
343
- risk,
343
+ risk.level,
344
344
  );
345
345
  },
346
346
  ),
@@ -417,7 +417,7 @@ describe("Shell parser property-based tests", () => {
417
417
 
418
418
  test("empty command classifies as low risk", async () => {
419
419
  const risk = await classifyRisk("bash", { command: "" });
420
- expect(risk).toBe(RiskLevel.Low);
420
+ expect(risk.level).toBe(RiskLevel.Low);
421
421
  });
422
422
 
423
423
  test("whitespace-only commands classify as low risk (trimmed to empty)", async () => {
@@ -429,7 +429,7 @@ describe("Shell parser property-based tests", () => {
429
429
  }),
430
430
  async (ws) => {
431
431
  const risk = await classifyRisk("bash", { command: ws });
432
- expect(risk).toBe(RiskLevel.Low);
432
+ expect(risk.level).toBe(RiskLevel.Low);
433
433
  },
434
434
  ),
435
435
  { numRuns: 50, ...FC_OPTS },
@@ -0,0 +1,182 @@
1
+ import { afterEach, describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ _internals,
5
+ clearCacheForTests,
6
+ deleteCacheEntry,
7
+ getCacheEntry,
8
+ setCacheEntry,
9
+ } from "../skills/skill-cache-store.js";
10
+
11
+ afterEach(() => {
12
+ clearCacheForTests();
13
+ });
14
+
15
+ describe("setCacheEntry", () => {
16
+ test("auto-generated key is a 16-char lowercase hex string", () => {
17
+ const { key } = setCacheEntry("hello");
18
+ expect(key).toHaveLength(16);
19
+ expect(key).toMatch(/^[0-9a-f]{16}$/);
20
+ });
21
+
22
+ test("each auto-generated key is unique", () => {
23
+ const keys = new Set<string>();
24
+ for (let i = 0; i < 20; i++) {
25
+ keys.add(setCacheEntry(i).key);
26
+ }
27
+ expect(keys.size).toBe(20);
28
+ });
29
+
30
+ test("explicit key stores and retrieves correctly", () => {
31
+ setCacheEntry({ foo: "bar" }, { key: "my-key" });
32
+ const result = getCacheEntry("my-key");
33
+ expect(result).toEqual({ data: { foo: "bar" } });
34
+ });
35
+
36
+ test("explicit key upsert overwrites existing value", () => {
37
+ setCacheEntry("v1", { key: "same" });
38
+ setCacheEntry("v2", { key: "same" });
39
+ const result = getCacheEntry("same");
40
+ expect(result).toEqual({ data: "v2" });
41
+ // Only one entry in the store for this key.
42
+ let count = 0;
43
+ for (const k of _internals.store.keys()) {
44
+ if (k === "same") count++;
45
+ }
46
+ expect(count).toBe(1);
47
+ });
48
+
49
+ test("upsert refreshes insertion order (LRU position)", () => {
50
+ setCacheEntry("a", { key: "first" });
51
+ setCacheEntry("b", { key: "second" });
52
+ // Upsert 'first' — it should move to the end.
53
+ setCacheEntry("a-updated", { key: "first" });
54
+
55
+ const keys = [..._internals.store.keys()];
56
+ expect(keys).toEqual(["second", "first"]);
57
+ });
58
+
59
+ test("upsert resets expiry timestamp", () => {
60
+ setCacheEntry("v1", { key: "k", ttlMs: 1000 });
61
+ const expiryBefore = _internals.store.get("k")!.expiresAt;
62
+
63
+ // Small delay to ensure Date.now() advances.
64
+ const start = Date.now();
65
+ while (Date.now() === start) {
66
+ /* busy-wait for at least 1ms */
67
+ }
68
+
69
+ setCacheEntry("v2", { key: "k", ttlMs: 5000 });
70
+ const expiryAfter = _internals.store.get("k")!.expiresAt;
71
+ expect(expiryAfter).toBeGreaterThan(expiryBefore);
72
+ });
73
+ });
74
+
75
+ describe("getCacheEntry", () => {
76
+ test("returns data for a valid key", () => {
77
+ const { key } = setCacheEntry(42);
78
+ expect(getCacheEntry(key)).toEqual({ data: 42 });
79
+ });
80
+
81
+ test("returns null for an unknown key", () => {
82
+ expect(getCacheEntry("nonexistent")).toBeNull();
83
+ });
84
+
85
+ test("refreshes LRU position on access", () => {
86
+ setCacheEntry("a", { key: "k1" });
87
+ setCacheEntry("b", { key: "k2" });
88
+ setCacheEntry("c", { key: "k3" });
89
+
90
+ // Access k1 — should move to the end.
91
+ getCacheEntry("k1");
92
+
93
+ const keys = [..._internals.store.keys()];
94
+ expect(keys).toEqual(["k2", "k3", "k1"]);
95
+ });
96
+ });
97
+
98
+ describe("TTL expiry (lazy eviction)", () => {
99
+ test("expired entry returns null and is removed from the store", () => {
100
+ setCacheEntry("ephemeral", { key: "ttl-test", ttlMs: 1 });
101
+
102
+ // Wait for the TTL to elapse.
103
+ const deadline = Date.now() + 2;
104
+ while (Date.now() < deadline) {
105
+ /* busy-wait */
106
+ }
107
+
108
+ expect(getCacheEntry("ttl-test")).toBeNull();
109
+ expect(_internals.store.has("ttl-test")).toBe(false);
110
+ });
111
+
112
+ test("non-expired entry is still accessible", () => {
113
+ setCacheEntry("durable", { key: "long-lived", ttlMs: 60_000 });
114
+ expect(getCacheEntry("long-lived")).toEqual({ data: "durable" });
115
+ });
116
+
117
+ test("default TTL is 30 minutes", () => {
118
+ expect(_internals.DEFAULT_TTL_MS).toBe(30 * 60_000);
119
+ });
120
+ });
121
+
122
+ describe("LRU eviction at capacity", () => {
123
+ test("evicts oldest entry when at max capacity", () => {
124
+ const maxEntries = _internals.DEFAULT_MAX_ENTRIES; // 64
125
+
126
+ // Fill the store to capacity.
127
+ for (let i = 0; i < maxEntries; i++) {
128
+ setCacheEntry(i, { key: `entry-${i}` });
129
+ }
130
+ expect(_internals.store.size).toBe(maxEntries);
131
+
132
+ // One more insert should evict the oldest (entry-0).
133
+ setCacheEntry("overflow", { key: "new-entry" });
134
+ expect(_internals.store.size).toBe(maxEntries);
135
+ expect(getCacheEntry("entry-0")).toBeNull();
136
+ expect(getCacheEntry("new-entry")).toEqual({ data: "overflow" });
137
+ });
138
+
139
+ test("default max entries is 64", () => {
140
+ expect(_internals.DEFAULT_MAX_ENTRIES).toBe(64);
141
+ });
142
+
143
+ test("upsert at capacity does not evict (key already exists)", () => {
144
+ const maxEntries = _internals.DEFAULT_MAX_ENTRIES;
145
+ for (let i = 0; i < maxEntries; i++) {
146
+ setCacheEntry(i, { key: `entry-${i}` });
147
+ }
148
+
149
+ // Upsert an existing key — should not evict anything.
150
+ setCacheEntry("updated", { key: "entry-0" });
151
+ expect(_internals.store.size).toBe(maxEntries);
152
+ expect(getCacheEntry("entry-0")).toEqual({ data: "updated" });
153
+ expect(getCacheEntry("entry-1")).toEqual({ data: 1 });
154
+ });
155
+ });
156
+
157
+ describe("deleteCacheEntry", () => {
158
+ test("returns true when deleting an existing key", () => {
159
+ setCacheEntry("x", { key: "del" });
160
+ expect(deleteCacheEntry("del")).toBe(true);
161
+ expect(getCacheEntry("del")).toBeNull();
162
+ });
163
+
164
+ test("returns false for an unknown key (idempotent)", () => {
165
+ expect(deleteCacheEntry("ghost")).toBe(false);
166
+ });
167
+
168
+ test("double delete is idempotent", () => {
169
+ setCacheEntry("x", { key: "once" });
170
+ expect(deleteCacheEntry("once")).toBe(true);
171
+ expect(deleteCacheEntry("once")).toBe(false);
172
+ });
173
+ });
174
+
175
+ describe("clearCacheForTests", () => {
176
+ test("empties the entire store", () => {
177
+ setCacheEntry("a", { key: "k1" });
178
+ setCacheEntry("b", { key: "k2" });
179
+ clearCacheForTests();
180
+ expect(_internals.store.size).toBe(0);
181
+ });
182
+ });
@@ -520,9 +520,16 @@ describe("includes frontmatter parsing", () => {
520
520
  });
521
521
  });
522
522
 
523
- describe("bundled browser skill", () => {
523
+ describe("managed browser skill", () => {
524
+ const BROWSER_SKILL_MD = readFileSync(
525
+ join(import.meta.dirname, "../../../skills/vellum-browser-use/SKILL.md"),
526
+ "utf-8",
527
+ );
528
+
524
529
  beforeEach(() => {
525
- mkdirSync(join(TEST_DIR, "skills"), { recursive: true });
530
+ const skillDir = join(TEST_DIR, "skills", "vellum-browser-use");
531
+ mkdirSync(skillDir, { recursive: true });
532
+ writeFileSync(join(skillDir, "SKILL.md"), BROWSER_SKILL_MD);
526
533
  });
527
534
 
528
535
  afterEach(() => {
@@ -531,51 +538,30 @@ describe("bundled browser skill", () => {
531
538
  rmSync(skillsDir, { recursive: true, force: true });
532
539
  });
533
540
 
534
- test("browser skill appears in full catalog (including bundled)", () => {
541
+ test("browser skill appears in full catalog", () => {
535
542
  const catalog = loadSkillCatalog();
536
- const browserSkill = catalog.find((s) => s.id === "browser");
543
+ const browserSkill = catalog.find((s) => s.id === "vellum-browser-use");
537
544
  expect(browserSkill).toBeDefined();
538
- expect(browserSkill!.name).toBe("browser");
545
+ expect(browserSkill!.name).toBe("vellum-browser-use");
539
546
  expect(browserSkill!.displayName).toBe("Browser");
540
- expect(browserSkill!.bundled).toBe(true);
541
547
  });
542
548
 
543
549
  test("browser skill has correct metadata", () => {
544
550
  const catalog = loadSkillCatalog();
545
- const browserSkill = catalog.find((s) => s.id === "browser");
551
+ const browserSkill = catalog.find((s) => s.id === "vellum-browser-use");
546
552
  expect(browserSkill).toBeDefined();
547
553
  expect(browserSkill!.description).toBe(
548
- "Navigate and interact with web pages using a headless browser",
554
+ "Browse the web using `assistant browser` CLI commands",
549
555
  );
550
556
  });
551
557
 
552
- test("browser skill has a valid tool manifest with all browser tools", () => {
558
+ test("browser skill has no tool manifest", () => {
553
559
  const catalog = loadSkillCatalog();
554
- const browserSkill = catalog.find((s) => s.id === "browser");
560
+ const browserSkill = catalog.find((s) => s.id === "vellum-browser-use");
555
561
  expect(browserSkill).toBeDefined();
556
- expect(browserSkill!.toolManifest).toBeDefined();
557
- expect(browserSkill!.toolManifest!.present).toBe(true);
558
- expect(browserSkill!.toolManifest!.valid).toBe(true);
559
- expect(browserSkill!.toolManifest!.toolCount).toBe(17);
560
- expect(browserSkill!.toolManifest!.toolNames).toEqual([
561
- "browser_navigate",
562
- "browser_snapshot",
563
- "browser_screenshot",
564
- "browser_close",
565
- "browser_attach",
566
- "browser_detach",
567
- "browser_click",
568
- "browser_type",
569
- "browser_press_key",
570
- "browser_scroll",
571
- "browser_select_option",
572
- "browser_hover",
573
- "browser_wait_for",
574
- "browser_extract",
575
- "browser_wait_for_download",
576
- "browser_fill_credential",
577
- "browser_status",
578
- ]);
562
+ // Browser tools are dispatched via skill_execute and do not use
563
+ // a skill-tool manifest.
564
+ expect(browserSkill!.toolManifest).toBeUndefined();
579
565
  });
580
566
  });
581
567
 
@@ -19,7 +19,9 @@ describe("slack-app-setup skill regression", () => {
19
19
 
20
20
  test("forbids plaintext forms and chat-pasted secrets", () => {
21
21
  expect(skillContent).toContain("Do NOT use `ui_show`");
22
- expect(skillContent).toContain("Do NOT ask the user to paste them in chat");
22
+ expect(skillContent).toContain(
23
+ "Do NOT ask the user to paste tokens in chat",
24
+ );
23
25
  });
24
26
 
25
27
  test("does not instruct the agent to reimplement Slack validation in shell", () => {