@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
@@ -2,6 +2,7 @@ import type { Command } from "commander";
2
2
 
3
3
  import {
4
4
  cleanupShortSegments,
5
+ compactLongMemoryNodes,
5
6
  findReextractTarget,
6
7
  findReextractTargets,
7
8
  getMemorySystemStatus,
@@ -35,7 +36,7 @@ Key concepts:
35
36
  Examples:
36
37
  $ assistant memory status
37
38
  $ assistant memory query "What is the project deadline?"
38
- $ assistant memory backfill`
39
+ $ assistant memory backfill`,
39
40
  );
40
41
 
41
42
  memory
@@ -57,7 +58,7 @@ Fields shown:
57
58
  jobs Status of background jobs (backfill, cleanup, rebuild-index)
58
59
 
59
60
  Examples:
60
- $ assistant memory status`
61
+ $ assistant memory status`,
61
62
  )
62
63
  .action(async () => {
63
64
  initializeDb();
@@ -97,7 +98,7 @@ useful after bulk imports or if the incremental state has become inconsistent.
97
98
 
98
99
  Examples:
99
100
  $ assistant memory backfill
100
- $ assistant memory backfill --force`
101
+ $ assistant memory backfill --force`,
101
102
  )
102
103
  .action((opts: { force?: boolean }) => {
103
104
  initializeDb();
@@ -121,20 +122,20 @@ existing short segments that were stored before the filter was added.
121
122
 
122
123
  Examples:
123
124
  $ assistant memory cleanup-segments
124
- $ assistant memory cleanup-segments --dry-run`
125
+ $ assistant memory cleanup-segments --dry-run`,
125
126
  )
126
127
  .action(async (opts: { dryRun?: boolean }) => {
127
128
  initializeDb();
128
129
  const result = await cleanupShortSegments({ dryRun: opts.dryRun });
129
130
  if (opts.dryRun) {
130
131
  log.info(
131
- `Dry run: ${result.dryRunCount} short segment(s) would be removed.`
132
+ `Dry run: ${result.dryRunCount} short segment(s) would be removed.`,
132
133
  );
133
134
  } else {
134
135
  log.info(`Removed ${result.removed} short segment(s).`);
135
136
  if (result.failed > 0) {
136
137
  log.warn(
137
- `${result.failed} segment(s) skipped — Qdrant deletion failed. Re-run when Qdrant is available.`
138
+ `${result.failed} segment(s) skipped — Qdrant deletion failed. Re-run when Qdrant is available.`,
138
139
  );
139
140
  }
140
141
  }
@@ -143,7 +144,7 @@ Examples:
143
144
  memory
144
145
  .command("query <text>")
145
146
  .description(
146
- "Run a memory recall query and print the injected memory payload"
147
+ "Run a memory recall query and print the injected memory payload",
147
148
  )
148
149
  .option("-c, --conversation <id>", "Optional conversation ID")
149
150
  .addHelpText(
@@ -164,7 +165,7 @@ context-aware recall. If omitted, the most recent conversation is used.
164
165
  Examples:
165
166
  $ assistant memory query "What is the project deadline?"
166
167
  $ assistant memory query "preferred communication style" --conversation conv_abc123
167
- $ assistant memory query "API rate limits"`
168
+ $ assistant memory query "API rate limits"`,
168
169
  )
169
170
  .action(async (text: string, opts?: { conversation?: string }) => {
170
171
  initializeDb();
@@ -181,8 +182,8 @@ Examples:
181
182
  for (const r of result.results) {
182
183
  log.info(
183
184
  `[${r.type}] (confidence: ${r.confidence.toFixed(
184
- 2
185
- )}, score: ${r.score.toFixed(3)})`
185
+ 2,
186
+ )}, score: ${r.score.toFixed(3)})`,
186
187
  );
187
188
  log.info(r.content);
188
189
  log.info("");
@@ -208,7 +209,7 @@ status" to monitor job progress.
208
209
 
209
210
  Examples:
210
211
  $ assistant memory rebuild-index
211
- $ assistant memory status`
212
+ $ assistant memory status`,
212
213
  )
213
214
  .action(() => {
214
215
  initializeDb();
@@ -219,13 +220,13 @@ Examples:
219
220
  memory
220
221
  .command("re-extract")
221
222
  .description(
222
- "Re-extract memories from conversations using the latest extraction prompt"
223
+ "Re-extract memories from conversations using the latest extraction prompt",
223
224
  )
224
225
  .option(
225
226
  "-c, --conversation <id>",
226
227
  "Target a specific conversation by ID (repeatable)",
227
228
  (val: string, prev: string[]) => [...prev, val],
228
- [] as string[]
229
+ [] as string[],
229
230
  )
230
231
  .option("-t, --top <n>", "Auto-select top N conversations by message count")
231
232
  .option("--dry-run", "Show what would be re-extracted without doing it")
@@ -248,7 +249,7 @@ background worker).
248
249
  Examples:
249
250
  $ assistant memory re-extract --top 20
250
251
  $ assistant memory re-extract --conversation conv_abc123
251
- $ assistant memory re-extract --top 10 --dry-run`
252
+ $ assistant memory re-extract --top 10 --dry-run`,
252
253
  )
253
254
  .action(
254
255
  (opts: { conversation?: string[]; top?: string; dryRun?: boolean }) => {
@@ -288,7 +289,7 @@ Examples:
288
289
 
289
290
  if (targets.length === 0) {
290
291
  log.info(
291
- "No targets specified. Use --conversation <id> or --top <n>."
292
+ "No targets specified. Use --conversation <id> or --top <n>.",
292
293
  );
293
294
  return;
294
295
  }
@@ -307,8 +308,117 @@ Examples:
307
308
 
308
309
  const { jobIds } = requestReextract(targets);
309
310
  log.info(
310
- `\nQueued ${jobIds.length} re-extraction job(s). The assistant will process them in the background.`
311
+ `\nQueued ${jobIds.length} re-extraction job(s). The assistant will process them in the background.`,
311
312
  );
312
- }
313
+ },
314
+ );
315
+
316
+ memory
317
+ .command("compact")
318
+ .description(
319
+ "Rewrite memory nodes whose content exceeds the length cap (backfill)",
320
+ )
321
+ .option(
322
+ "--threshold <n>",
323
+ "Content length threshold — nodes longer than this are candidates (default: 400)",
324
+ (v: string) => Number.parseInt(v, 10),
325
+ 400,
326
+ )
327
+ .option(
328
+ "--limit <n>",
329
+ "Maximum number of candidates to process (default: no limit)",
330
+ (v: string) => Number.parseInt(v, 10),
331
+ )
332
+ .option("--apply", "Rewrite content (default is a candidate-only preview)")
333
+ .addHelpText(
334
+ "after",
335
+ `
336
+ One-off backfill for memory graphs that accumulated over-long content before
337
+ the extraction prompt was tightened to enforce the 1-3 sentence / ~300
338
+ character cap. Scans memory_graph_nodes (skipping fidelity=gone) for entries
339
+ whose content length exceeds --threshold, then either lists them (default)
340
+ or rewrites each via the memoryConsolidation LLM call site (--apply).
341
+
342
+ Only the content field is rewritten; significance, emotionalCharge, edges,
343
+ triggers, and image_refs are preserved. Each rewrite is logged in
344
+ memory_graph_node_edits with source="manual" so it is reversible.
345
+
346
+ Start with a bounded spot-check before processing the whole graph:
347
+
348
+ $ assistant memory compact --limit 3 --apply
349
+
350
+ Examples:
351
+ $ assistant memory compact # preview candidates
352
+ $ assistant memory compact --threshold 500 # tighter threshold
353
+ $ assistant memory compact --limit 5 --apply # rewrite first 5
354
+ $ assistant memory compact --apply # rewrite everything`,
355
+ )
356
+ .action(
357
+ async (opts: { threshold: number; limit?: number; apply?: boolean }) => {
358
+ initializeDb();
359
+ const apply = Boolean(opts.apply);
360
+
361
+ if (!Number.isFinite(opts.threshold) || opts.threshold <= 0) {
362
+ log.info("--threshold must be a positive integer");
363
+ return;
364
+ }
365
+ if (
366
+ opts.limit !== undefined &&
367
+ (!Number.isFinite(opts.limit) || opts.limit <= 0)
368
+ ) {
369
+ log.info("--limit must be a positive integer");
370
+ return;
371
+ }
372
+
373
+ log.info(
374
+ `Scanning memory_graph_nodes for content > ${opts.threshold} chars${
375
+ apply ? "" : " (preview — no changes will be written)"
376
+ }...`,
377
+ );
378
+
379
+ const result = await compactLongMemoryNodes({
380
+ threshold: opts.threshold,
381
+ limit: opts.limit,
382
+ apply,
383
+ onCandidates: (candidates) => {
384
+ log.info(`Found ${candidates.length} candidate node(s)`);
385
+ if (!apply) {
386
+ for (const c of candidates) {
387
+ log.info(` ${c.id} ${c.beforeLen} chars`);
388
+ }
389
+ }
390
+ },
391
+ onProgress: (evt) => {
392
+ const tag = `[${evt.action}]`;
393
+ log.info(
394
+ `${tag} ${evt.nodeId}: ${evt.beforeLen} → ${evt.afterLen} chars${
395
+ evt.reason ? ` (${evt.reason})` : ""
396
+ }`,
397
+ );
398
+ if (evt.newContent && evt.action === "compacted") {
399
+ log.info(` new: ${evt.newContent}`);
400
+ }
401
+ },
402
+ });
403
+
404
+ log.info("");
405
+ log.info(`Scanned above threshold: ${result.scanned}`);
406
+ log.info(`Processed: ${result.processed}`);
407
+ if (apply) {
408
+ log.info(`Compacted: ${result.compacted}`);
409
+ log.info(`Skipped: ${result.skipped}`);
410
+ log.info(`Failures: ${result.failures}`);
411
+ if (result.processed > 0) {
412
+ log.info(
413
+ `Chars: ${result.beforeChars} → ${result.afterChars} (saved ${
414
+ result.beforeChars - result.afterChars
415
+ })`,
416
+ );
417
+ }
418
+ } else if (result.processed > 0) {
419
+ log.info("");
420
+ log.info("Preview only. Re-run with --apply to rewrite.");
421
+ }
422
+ },
313
423
  );
314
424
  }
@@ -32,7 +32,6 @@ mock.module("../../../lib/daemon-credential-client.js", () => ({
32
32
  getSecureKeyViaDaemon: async () => undefined,
33
33
  deleteSecureKeyViaDaemon: async () => "not-found" as const,
34
34
  setSecureKeyViaDaemon: async () => false,
35
- getProviderKeyViaDaemon: async () => undefined,
36
35
  getSecureKeyResultViaDaemon: async () => ({
37
36
  value: undefined,
38
37
  unreachable: false,
@@ -21,7 +21,6 @@ mock.module("../../../lib/daemon-credential-client.js", () => ({
21
21
  mockGetSecureKeyViaDaemon(account),
22
22
  deleteSecureKeyViaDaemon: async () => "not-found" as const,
23
23
  setSecureKeyViaDaemon: async () => true,
24
- getProviderKeyViaDaemon: async () => undefined,
25
24
  getSecureKeyResultViaDaemon: async () => ({
26
25
  value: undefined,
27
26
  unreachable: false,
@@ -57,7 +57,6 @@ mock.module("../../../lib/daemon-credential-client.js", () => ({
57
57
  return mockDeleteSecureKeyViaDaemonResult;
58
58
  },
59
59
  setSecureKeyViaDaemon: async () => false,
60
- getProviderKeyViaDaemon: async () => undefined,
61
60
  getSecureKeyResultViaDaemon: async () => ({
62
61
  value: undefined,
63
62
  unreachable: false,
@@ -37,7 +37,6 @@ mock.module("../../../lib/daemon-credential-client.js", () => ({
37
37
  mockGetSecureKeyViaDaemon(account),
38
38
  deleteSecureKeyViaDaemon: async () => "not-found" as const,
39
39
  setSecureKeyViaDaemon: async () => false,
40
- getProviderKeyViaDaemon: async () => undefined,
41
40
  getSecureKeyResultViaDaemon: async () => ({
42
41
  value: undefined,
43
42
  unreachable: false,
@@ -0,0 +1,339 @@
1
+ /**
2
+ * CLI command group: `assistant stt`
3
+ *
4
+ * Speech-to-text operations using the configured STT provider.
5
+ * Stateless, request-response commands — no daemon dependency.
6
+ */
7
+
8
+ import { randomUUID } from "node:crypto";
9
+ import { access, mkdir, readdir, readFile, rm, unlink } from "node:fs/promises";
10
+ import { tmpdir } from "node:os";
11
+ import { extname, join } from "node:path";
12
+
13
+ import type { Command } from "commander";
14
+
15
+ import { listProviderIds } from "../../providers/speech-to-text/provider-catalog.js";
16
+ import { resolveBatchTranscriber } from "../../providers/speech-to-text/resolve.js";
17
+ import type { BatchTranscriber } from "../../stt/types.js";
18
+ import {
19
+ FFMPEG_TRANSCODE_TIMEOUT_MS,
20
+ FFPROBE_TIMEOUT_MS,
21
+ spawnWithTimeout,
22
+ } from "../../util/spawn.js";
23
+ import { log } from "../logger.js";
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Constants
27
+ // ---------------------------------------------------------------------------
28
+
29
+ const VIDEO_EXTENSIONS = new Set([
30
+ ".mp4",
31
+ ".mov",
32
+ ".avi",
33
+ ".mkv",
34
+ ".webm",
35
+ ".m4v",
36
+ ".mpeg",
37
+ ".mpg",
38
+ ]);
39
+ const AUDIO_EXTENSIONS = new Set([
40
+ ".mp3",
41
+ ".wav",
42
+ ".m4a",
43
+ ".aac",
44
+ ".ogg",
45
+ ".flac",
46
+ ".aiff",
47
+ ".wma",
48
+ ]);
49
+
50
+ /** Max file size for a single STT chunk request (25MB). */
51
+ const STT_CHUNK_MAX_BYTES = 25 * 1024 * 1024;
52
+
53
+ /** Duration per chunk when splitting for large files (10 minutes). */
54
+ const CHUNK_DURATION_SECS = 600;
55
+
56
+ /** Timeout for a single STT transcription request. */
57
+ const STT_REQUEST_TIMEOUT_MS = 300_000;
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // Helpers
61
+ // ---------------------------------------------------------------------------
62
+
63
+ async function getAudioDuration(audioPath: string): Promise<number> {
64
+ const result = await spawnWithTimeout(
65
+ [
66
+ "ffprobe",
67
+ "-v",
68
+ "error",
69
+ "-show_entries",
70
+ "format=duration",
71
+ "-of",
72
+ "csv=p=0",
73
+ audioPath,
74
+ ],
75
+ FFPROBE_TIMEOUT_MS,
76
+ );
77
+ if (result.exitCode !== 0) return 0;
78
+ return parseFloat(result.stdout.trim()) || 0;
79
+ }
80
+
81
+ async function splitAudio(
82
+ audioPath: string,
83
+ chunkDir: string,
84
+ chunkDurationSecs: number,
85
+ ): Promise<string[]> {
86
+ const chunkPattern = join(chunkDir, "chunk-%03d.wav");
87
+ const result = await spawnWithTimeout(
88
+ [
89
+ "ffmpeg",
90
+ "-y",
91
+ "-i",
92
+ audioPath,
93
+ "-f",
94
+ "segment",
95
+ "-segment_time",
96
+ String(chunkDurationSecs),
97
+ "-acodec",
98
+ "pcm_s16le",
99
+ "-ar",
100
+ "16000",
101
+ "-ac",
102
+ "1",
103
+ chunkPattern,
104
+ ],
105
+ FFMPEG_TRANSCODE_TIMEOUT_MS,
106
+ );
107
+ if (result.exitCode !== 0) {
108
+ throw new Error(`Failed to split audio: ${result.stderr.slice(0, 300)}`);
109
+ }
110
+ const files = await readdir(chunkDir);
111
+ return files
112
+ .filter((f) => f.startsWith("chunk-") && f.endsWith(".wav"))
113
+ .sort()
114
+ .map((f) => join(chunkDir, f));
115
+ }
116
+
117
+ /** Convert source to 16kHz mono WAV for consistent processing. */
118
+ async function toWav(inputPath: string, isVideo: boolean): Promise<string> {
119
+ const wavPath = join(tmpdir(), `vellum-transcribe-${randomUUID()}.wav`);
120
+ const args = ["ffmpeg", "-y", "-i", inputPath];
121
+ if (isVideo) args.push("-vn");
122
+ args.push("-acodec", "pcm_s16le", "-ar", "16000", "-ac", "1", wavPath);
123
+ const result = await spawnWithTimeout(args, FFMPEG_TRANSCODE_TIMEOUT_MS);
124
+ if (result.exitCode !== 0) {
125
+ throw new Error(`ffmpeg failed: ${result.stderr.slice(0, 500)}`);
126
+ }
127
+ return wavPath;
128
+ }
129
+
130
+ async function transcribeWithProvider(
131
+ audioPath: string,
132
+ transcriber: BatchTranscriber,
133
+ ): Promise<string> {
134
+ const duration = await getAudioDuration(audioPath);
135
+ const fileSize = Bun.file(audioPath).size;
136
+
137
+ // If small enough, send directly
138
+ if (fileSize <= STT_CHUNK_MAX_BYTES) {
139
+ const audioBuffer = await readFile(audioPath);
140
+ const result = await transcriber.transcribe({
141
+ audio: audioBuffer,
142
+ mimeType: "audio/wav",
143
+ signal: AbortSignal.timeout(STT_REQUEST_TIMEOUT_MS),
144
+ });
145
+ return result.text;
146
+ }
147
+
148
+ // Split into chunks for large files
149
+ const chunkDir = join(tmpdir(), `vellum-transcribe-chunks-${randomUUID()}`);
150
+ await mkdir(chunkDir, { recursive: true });
151
+
152
+ try {
153
+ process.stderr.write(
154
+ `Large file (${Math.round(duration / 60)}min) - splitting into chunks...\n`,
155
+ );
156
+ const chunks = await splitAudio(audioPath, chunkDir, CHUNK_DURATION_SECS);
157
+ const parts: string[] = [];
158
+
159
+ for (let i = 0; i < chunks.length; i++) {
160
+ process.stderr.write(
161
+ ` Transcribing chunk ${i + 1}/${chunks.length}...\n`,
162
+ );
163
+ const audioBuffer = await readFile(chunks[i]);
164
+ const result = await transcriber.transcribe({
165
+ audio: audioBuffer,
166
+ mimeType: "audio/wav",
167
+ signal: AbortSignal.timeout(STT_REQUEST_TIMEOUT_MS),
168
+ });
169
+ if (result.text) parts.push(result.text);
170
+ }
171
+
172
+ return parts.join(" ");
173
+ } finally {
174
+ await rm(chunkDir, { recursive: true, force: true }).catch(() => {});
175
+ }
176
+ }
177
+
178
+ // ---------------------------------------------------------------------------
179
+ // Command registration
180
+ // ---------------------------------------------------------------------------
181
+
182
+ export function registerSttCommand(program: Command): void {
183
+ const sttCmd = program
184
+ .command("stt")
185
+ .description("Speech-to-text operations");
186
+
187
+ const supportedProviders = listProviderIds().join(", ");
188
+
189
+ sttCmd.addHelpText(
190
+ "after",
191
+ `
192
+ Speech-to-text commands use your configured STT provider to transcribe
193
+ audio and video files. The provider is set via:
194
+
195
+ $ assistant config set services.stt.provider <provider>
196
+
197
+ Supported providers: ${supportedProviders}.
198
+
199
+ Examples:
200
+ $ assistant stt transcribe --file /path/to/meeting.wav
201
+ $ assistant stt transcribe --file /path/to/video.mp4 --json`,
202
+ );
203
+
204
+ // ── transcribe ──────────────────────────────────────────────────────
205
+
206
+ sttCmd
207
+ .command("transcribe")
208
+ .description("Transcribe an audio or video file to text")
209
+ .requiredOption("--file <path>", "Absolute path to the audio/video file")
210
+ .option("--json", "Output structured JSON instead of plain transcript text")
211
+ .addHelpText(
212
+ "after",
213
+ `
214
+ Transcribes an audio or video file using the configured speech-to-text
215
+ provider. Video files automatically have their audio extracted via ffmpeg.
216
+ Large files (>25MB as WAV) are automatically split into chunks and
217
+ transcribed sequentially.
218
+
219
+ Supported audio formats: .mp3, .wav, .m4a, .aac, .ogg, .flac, .aiff, .wma
220
+ Supported video formats: .mp4, .mov, .avi, .mkv, .webm, .m4v, .mpeg, .mpg
221
+
222
+ Requires ffmpeg and ffprobe to be installed and on PATH.
223
+
224
+ Examples:
225
+ $ assistant stt transcribe --file /path/to/recording.wav
226
+ $ assistant stt transcribe --file /path/to/meeting.mp4
227
+ $ assistant stt transcribe --file /path/to/podcast.mp3 --json`,
228
+ )
229
+ .action(async (opts: { file: string; json?: boolean }) => {
230
+ const filePath = opts.file;
231
+ const jsonOutput = opts.json ?? false;
232
+
233
+ // Validate file exists
234
+ try {
235
+ await access(filePath);
236
+ } catch {
237
+ const msg = `File not found: ${filePath}`;
238
+ if (jsonOutput) {
239
+ process.stdout.write(
240
+ JSON.stringify({ ok: false, error: msg }) + "\n",
241
+ );
242
+ } else {
243
+ log.error(msg);
244
+ }
245
+ process.exitCode = 1;
246
+ return;
247
+ }
248
+
249
+ // Validate file extension
250
+ const ext = extname(filePath).toLowerCase();
251
+ const isVideo = VIDEO_EXTENSIONS.has(ext);
252
+ const isAudio = AUDIO_EXTENSIONS.has(ext);
253
+ if (!isVideo && !isAudio) {
254
+ const msg = `Unsupported file type: ${ext}. Only audio and video files can be transcribed.`;
255
+ if (jsonOutput) {
256
+ process.stdout.write(
257
+ JSON.stringify({ ok: false, error: msg }) + "\n",
258
+ );
259
+ } else {
260
+ log.error(msg);
261
+ }
262
+ process.exitCode = 1;
263
+ return;
264
+ }
265
+
266
+ // Resolve STT provider
267
+ const transcriber = await resolveBatchTranscriber();
268
+ if (!transcriber) {
269
+ const msg =
270
+ "No speech-to-text provider is configured. Run 'assistant config set services.stt.provider <provider>' to set one up.";
271
+ if (jsonOutput) {
272
+ process.stdout.write(
273
+ JSON.stringify({ ok: false, error: msg }) + "\n",
274
+ );
275
+ } else {
276
+ log.error(msg);
277
+ }
278
+ process.exitCode = 1;
279
+ return;
280
+ }
281
+
282
+ let wavPath: string | null = null;
283
+ try {
284
+ // Convert to WAV
285
+ wavPath = await toWav(filePath, isVideo);
286
+
287
+ const startTime = Date.now();
288
+ const text = await transcribeWithProvider(wavPath, transcriber);
289
+ const durationSeconds = (Date.now() - startTime) / 1000;
290
+
291
+ if (!text.trim()) {
292
+ if (jsonOutput) {
293
+ process.stdout.write(
294
+ JSON.stringify({
295
+ ok: true,
296
+ transcript: "",
297
+ provider: transcriber.providerId,
298
+ durationSeconds,
299
+ }) + "\n",
300
+ );
301
+ } else {
302
+ process.stdout.write("No speech detected in the audio.\n");
303
+ }
304
+ return;
305
+ }
306
+
307
+ if (jsonOutput) {
308
+ process.stdout.write(
309
+ JSON.stringify({
310
+ ok: true,
311
+ transcript: text,
312
+ provider: transcriber.providerId,
313
+ durationSeconds,
314
+ }) + "\n",
315
+ );
316
+ } else {
317
+ process.stdout.write(text + "\n");
318
+ }
319
+ } catch (err) {
320
+ const msg = `Transcription failed: ${(err as Error).message}`;
321
+ if (jsonOutput) {
322
+ process.stdout.write(
323
+ JSON.stringify({ ok: false, error: msg }) + "\n",
324
+ );
325
+ } else {
326
+ log.error(msg);
327
+ }
328
+ process.exitCode = 1;
329
+ } finally {
330
+ if (wavPath) {
331
+ try {
332
+ await unlink(wavPath);
333
+ } catch {
334
+ /* ignore */
335
+ }
336
+ }
337
+ }
338
+ });
339
+ }