@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
@@ -0,0 +1,670 @@
1
+ /**
2
+ * `assistant ui` CLI namespace.
3
+ *
4
+ * Subcommands:
5
+ * - `assistant ui request` — Present an arbitrary interactive surface to
6
+ * the user and block until they respond. Input is a JSON payload
7
+ * describing the surface (via `--payload` or stdin).
8
+ * - `assistant ui confirm` — Convenience wrapper that presents a yes/no
9
+ * confirmation prompt and exits 0 on confirm, 1 on deny/cancel/timeout.
10
+ *
11
+ * Both commands delegate to the daemon's `ui_request` IPC method, which
12
+ * manages the surface lifecycle on the active conversation.
13
+ */
14
+
15
+ import { readFileSync } from "node:fs";
16
+
17
+ import type { Command } from "commander";
18
+
19
+ import { cliIpcCall } from "../../ipc/cli-client.js";
20
+ import {
21
+ type InteractiveUiAction,
22
+ type InteractiveUiResult,
23
+ RESERVED_ACTION_IDS,
24
+ } from "../../runtime/interactive-ui.js";
25
+ import { log } from "../logger.js";
26
+
27
+ // ── Constants ─────────────────────────────────────────────────────────
28
+
29
+ /**
30
+ * Default request timeout in milliseconds (5 minutes). This is the time
31
+ * the daemon will wait for the user to respond before the surface
32
+ * auto-cancels with `status: "timed_out"`.
33
+ */
34
+ const DEFAULT_REQUEST_TIMEOUT_MS = 5 * 60 * 1000; // 5m
35
+
36
+ /**
37
+ * Extra buffer added to the IPC call timeout beyond the request timeout
38
+ * so the IPC socket stays open long enough for the daemon to resolve the
39
+ * surface and send the response.
40
+ */
41
+ const IPC_TIMEOUT_BUFFER_MS = 10_000; // 10s
42
+
43
+ // ── Conversation ID resolution ────────────────────────────────────────
44
+
45
+ /**
46
+ * Resolve the conversation ID by precedence:
47
+ * 1. Explicit `--conversation-id` flag
48
+ * 2. `__SKILL_CONTEXT_JSON` env var (set by skill sandbox runner)
49
+ * 3. `__CONVERSATION_ID` env var (set by bash tool subprocess)
50
+ * 4. Fail with an actionable error
51
+ */
52
+ function resolveConversationId(explicit?: string): string {
53
+ if (explicit) return explicit;
54
+
55
+ const contextJson = process.env.__SKILL_CONTEXT_JSON;
56
+ if (contextJson) {
57
+ try {
58
+ const parsed = JSON.parse(contextJson);
59
+ if (parsed.conversationId && typeof parsed.conversationId === "string") {
60
+ return parsed.conversationId;
61
+ }
62
+ } catch {
63
+ // Fall through
64
+ }
65
+ }
66
+
67
+ const envConvId = process.env.__CONVERSATION_ID;
68
+ if (envConvId && typeof envConvId === "string") {
69
+ return envConvId;
70
+ }
71
+
72
+ throw new Error(
73
+ "No conversation ID available.\n" +
74
+ "Provide --conversation-id explicitly (run 'assistant conversations list' to find it),\n" +
75
+ "or run this command from a skill or bash tool context.",
76
+ );
77
+ }
78
+
79
+ // ── Payload parsing ───────────────────────────────────────────────────
80
+
81
+ /**
82
+ * Read a JSON payload from either the `--payload` flag or stdin.
83
+ * Returns the parsed object. Throws on invalid input.
84
+ */
85
+ function readPayload(payloadFlag?: string): Record<string, unknown> {
86
+ if (payloadFlag) {
87
+ try {
88
+ const parsed = JSON.parse(payloadFlag);
89
+ if (
90
+ typeof parsed !== "object" ||
91
+ parsed === null ||
92
+ Array.isArray(parsed)
93
+ ) {
94
+ throw new Error(
95
+ "--payload must be a JSON object (not array or primitive).",
96
+ );
97
+ }
98
+ return parsed as Record<string, unknown>;
99
+ } catch (err) {
100
+ if (err instanceof SyntaxError) {
101
+ throw new Error(
102
+ `Invalid JSON in --payload: ${err.message}\n` +
103
+ ' Example: --payload \'{"message":"Are you sure?"}\'',
104
+ );
105
+ }
106
+ throw err;
107
+ }
108
+ }
109
+
110
+ // Read from stdin
111
+ if (process.stdin.isTTY) {
112
+ throw new Error(
113
+ "No payload provided. Use --payload <json> or pipe JSON into stdin.\n" +
114
+ ' Example: echo \'{"message":"Are you sure?"}\' | assistant ui request',
115
+ );
116
+ }
117
+
118
+ let raw: string;
119
+ try {
120
+ raw = readFileSync("/dev/stdin", "utf-8");
121
+ } catch (err) {
122
+ throw new Error(
123
+ `Failed to read stdin: ${err instanceof Error ? err.message : String(err)}`,
124
+ );
125
+ }
126
+
127
+ if (!raw.trim()) {
128
+ throw new Error(
129
+ "Empty input on stdin. Provide a valid JSON object.\n" +
130
+ ' Example: echo \'{"message":"Are you sure?"}\' | assistant ui request',
131
+ );
132
+ }
133
+
134
+ try {
135
+ const parsed = JSON.parse(raw);
136
+ if (
137
+ typeof parsed !== "object" ||
138
+ parsed === null ||
139
+ Array.isArray(parsed)
140
+ ) {
141
+ throw new Error(
142
+ "Stdin payload must be a JSON object (not array or primitive).",
143
+ );
144
+ }
145
+ return parsed as Record<string, unknown>;
146
+ } catch (err) {
147
+ if (err instanceof SyntaxError) {
148
+ throw new Error(
149
+ `Invalid JSON on stdin: ${err.message}\n` +
150
+ ' Example: echo \'{"message":"Are you sure?"}\' | assistant ui request',
151
+ );
152
+ }
153
+ throw err;
154
+ }
155
+ }
156
+
157
+ // ── Action parsing ────────────────────────────────────────────────────
158
+
159
+ /** Valid variant values for action buttons. */
160
+ const VALID_VARIANTS = new Set(["primary", "danger", "secondary"]);
161
+
162
+ /**
163
+ * Parse and validate the `--actions` JSON flag.
164
+ *
165
+ * Expected shape: an array of objects, each with:
166
+ * - `id` (string, required, non-empty)
167
+ * - `label` (string, required, non-empty)
168
+ * - `variant` (optional: "primary" | "danger" | "secondary")
169
+ *
170
+ * Returns the validated array, or throws with an actionable CLI error.
171
+ */
172
+ function parseActions(raw: string): InteractiveUiAction[] {
173
+ let parsed: unknown;
174
+ try {
175
+ parsed = JSON.parse(raw);
176
+ } catch (err) {
177
+ throw new Error(
178
+ `Invalid JSON in --actions: ${err instanceof SyntaxError ? err.message : String(err)}\n` +
179
+ " --actions must be a JSON array of action objects.\n" +
180
+ ' Example: --actions \'[{"id":"approve","label":"Approve"},{"id":"reject","label":"Reject","variant":"danger"}]\'',
181
+ );
182
+ }
183
+
184
+ if (!Array.isArray(parsed)) {
185
+ throw new Error(
186
+ "--actions must be a JSON array of action objects.\n" +
187
+ ' Example: --actions \'[{"id":"approve","label":"Approve"}]\'',
188
+ );
189
+ }
190
+
191
+ if (parsed.length === 0) {
192
+ throw new Error(
193
+ "--actions must contain at least one action.\n" +
194
+ ' Example: --actions \'[{"id":"approve","label":"Approve"}]\'',
195
+ );
196
+ }
197
+
198
+ const actions: InteractiveUiAction[] = [];
199
+ for (let i = 0; i < parsed.length; i++) {
200
+ const item = parsed[i];
201
+ if (typeof item !== "object" || item === null || Array.isArray(item)) {
202
+ throw new Error(
203
+ `--actions[${i}]: each action must be a JSON object with "id" and "label" fields.\n` +
204
+ ' Example: {"id":"approve","label":"Approve"}',
205
+ );
206
+ }
207
+
208
+ const obj = item as Record<string, unknown>;
209
+
210
+ if (typeof obj.id !== "string" || obj.id.length === 0) {
211
+ throw new Error(
212
+ `--actions[${i}]: "id" is required and must be a non-empty string.\n` +
213
+ ' Example: {"id":"approve","label":"Approve"}',
214
+ );
215
+ }
216
+
217
+ if (RESERVED_ACTION_IDS.has(obj.id)) {
218
+ const reserved = [...RESERVED_ACTION_IDS].sort().join(", ");
219
+ throw new Error(
220
+ `--actions[${i}]: id "${obj.id}" is reserved for internal use. Reserved IDs: ${reserved}`,
221
+ );
222
+ }
223
+
224
+ if (typeof obj.label !== "string" || obj.label.length === 0) {
225
+ throw new Error(
226
+ `--actions[${i}]: "label" is required and must be a non-empty string.\n` +
227
+ ' Example: {"id":"approve","label":"Approve"}',
228
+ );
229
+ }
230
+
231
+ const action: InteractiveUiAction = { id: obj.id, label: obj.label };
232
+
233
+ if (obj.variant !== undefined) {
234
+ if (typeof obj.variant !== "string" || !VALID_VARIANTS.has(obj.variant)) {
235
+ throw new Error(
236
+ `--actions[${i}]: "variant" must be one of "primary", "danger", or "secondary" (got ${JSON.stringify(obj.variant)}).\n` +
237
+ ' Example: {"id":"delete","label":"Delete","variant":"danger"}',
238
+ );
239
+ }
240
+ action.variant = obj.variant as InteractiveUiAction["variant"];
241
+ }
242
+
243
+ actions.push(action);
244
+ }
245
+
246
+ return actions;
247
+ }
248
+
249
+ // ── Strict integer parsing ────────────────────────────────────────────
250
+
251
+ /**
252
+ * Parse a string as a strict positive integer. Rejects inputs like
253
+ * `"1e3"`, `"30s"`, `"12.5"` that `parseInt` would silently truncate.
254
+ * Returns the parsed integer or `NaN` on any non-pure-integer input.
255
+ */
256
+ function parseStrictPositiveInt(value: string): number {
257
+ if (!/^\d+$/.test(value)) return NaN;
258
+ return Number(value);
259
+ }
260
+
261
+ // ── Registration ──────────────────────────────────────────────────────
262
+
263
+ export function registerUiCommand(program: Command): void {
264
+ const ui = program
265
+ .command("ui")
266
+ .description("Present interactive UI surfaces to the user");
267
+
268
+ ui.addHelpText(
269
+ "after",
270
+ `
271
+ Script-facing commands that present interactive surfaces (confirmations,
272
+ forms) to the user via the running assistant and block until the user
273
+ responds or the request times out.
274
+
275
+ The conversation ID is resolved automatically when running inside a skill
276
+ or bash tool context (__SKILL_CONTEXT_JSON or __CONVERSATION_ID).
277
+ Override with --conversation-id if needed.
278
+
279
+ Examples:
280
+ $ echo '{"message":"Delete all logs?"}' | assistant ui request --json
281
+ $ assistant ui confirm --title "Deploy to production?" --message "This will push to prod."
282
+ $ assistant ui confirm --message "Are you sure?" --json`,
283
+ );
284
+
285
+ // ── ui request ───────────────────────────────────────────────────
286
+
287
+ ui.command("request")
288
+ .description(
289
+ "Present an interactive surface and block until the user responds",
290
+ )
291
+ .option("--payload <json>", "JSON object describing the surface data")
292
+ .option(
293
+ "--surface-type <type>",
294
+ 'Surface type: "confirmation" or "form"',
295
+ "confirmation",
296
+ )
297
+ .option("--title <title>", "Title displayed on the surface")
298
+ .option(
299
+ "--actions <json>",
300
+ "JSON array of action objects defining custom buttons/options",
301
+ )
302
+ .option(
303
+ "--conversation-id <id>",
304
+ "Conversation ID — run 'assistant conversations list' to find it (auto-resolved from skill or bash tool context if omitted)",
305
+ )
306
+ .option(
307
+ "--timeout <ms>",
308
+ "Request timeout in milliseconds",
309
+ String(DEFAULT_REQUEST_TIMEOUT_MS),
310
+ )
311
+ .option("--json", "Output result as machine-readable JSON")
312
+ .addHelpText(
313
+ "after",
314
+ `
315
+ Sends a UI interaction request to the running assistant and blocks until
316
+ the user responds or the timeout elapses. The payload describes the
317
+ surface content and can be provided via --payload or piped through stdin.
318
+
319
+ The response includes the user's action (submitted, cancelled, timed_out)
320
+ and any submitted data.
321
+
322
+ Custom actions can be defined via --actions to control the buttons shown
323
+ on the surface. Each action requires an "id" and "label", with an optional
324
+ "variant" hint ("primary", "danger", or "secondary").
325
+
326
+ Arguments:
327
+ (none — payload via --payload flag or stdin)
328
+
329
+ Options:
330
+ --payload <json> JSON object with surface data
331
+ --surface-type <type> "confirmation" (default) or "form"
332
+ --title <title> Surface title
333
+ --actions <json> JSON array of custom action objects
334
+ --conversation-id <id> Explicit conversation ID
335
+ --timeout <ms> Request timeout in milliseconds (default: 300000)
336
+ --json Output as JSON
337
+
338
+ Examples:
339
+ $ echo '{"message":"Proceed?"}' | assistant ui request
340
+ $ assistant ui request --payload '{"message":"Proceed?"}' --json
341
+ $ assistant ui request --payload '{"fields":[]}' --surface-type form --json
342
+ $ assistant ui request --payload '{"message":"Choose an option"}' \\
343
+ --actions '[{"id":"approve","label":"Approve","variant":"primary"},{"id":"reject","label":"Reject","variant":"danger"}]'`,
344
+ )
345
+ .action(
346
+ async (opts: {
347
+ payload?: string;
348
+ surfaceType?: string;
349
+ title?: string;
350
+ actions?: string;
351
+ conversationId?: string;
352
+ timeout?: string;
353
+ json?: boolean;
354
+ }) => {
355
+ // Parse payload
356
+ let data: Record<string, unknown>;
357
+ try {
358
+ data = readPayload(opts.payload);
359
+ } catch (err) {
360
+ const msg = err instanceof Error ? err.message : String(err);
361
+ if (opts.json) {
362
+ process.stdout.write(
363
+ JSON.stringify({ ok: false, error: msg }) + "\n",
364
+ );
365
+ } else {
366
+ log.error(msg);
367
+ }
368
+ process.exitCode = 1;
369
+ return;
370
+ }
371
+
372
+ // Resolve conversation ID
373
+ let conversationId: string;
374
+ try {
375
+ conversationId = resolveConversationId(opts.conversationId);
376
+ } catch (err) {
377
+ const msg = err instanceof Error ? err.message : String(err);
378
+ if (opts.json) {
379
+ process.stdout.write(
380
+ JSON.stringify({ ok: false, error: msg }) + "\n",
381
+ );
382
+ } else {
383
+ log.error(msg);
384
+ }
385
+ process.exitCode = 1;
386
+ return;
387
+ }
388
+
389
+ // Parse actions (if provided)
390
+ let actions: InteractiveUiAction[] | undefined;
391
+ if (opts.actions !== undefined) {
392
+ try {
393
+ actions = parseActions(opts.actions);
394
+ } catch (err) {
395
+ const msg = err instanceof Error ? err.message : String(err);
396
+ if (opts.json) {
397
+ process.stdout.write(
398
+ JSON.stringify({ ok: false, error: msg }) + "\n",
399
+ );
400
+ } else {
401
+ log.error(msg);
402
+ }
403
+ process.exitCode = 1;
404
+ return;
405
+ }
406
+ }
407
+
408
+ // Parse timeout
409
+ const rawTimeout = opts.timeout ?? String(DEFAULT_REQUEST_TIMEOUT_MS);
410
+ const requestTimeoutMs = parseStrictPositiveInt(rawTimeout);
411
+ if (isNaN(requestTimeoutMs) || requestTimeoutMs <= 0) {
412
+ const msg = `Invalid --timeout value "${opts.timeout}". Must be a positive integer (milliseconds).`;
413
+ if (opts.json) {
414
+ process.stdout.write(
415
+ JSON.stringify({ ok: false, error: msg }) + "\n",
416
+ );
417
+ } else {
418
+ log.error(msg);
419
+ }
420
+ process.exitCode = 1;
421
+ return;
422
+ }
423
+
424
+ // Build IPC params
425
+ const ipcParams: Record<string, unknown> = {
426
+ conversationId,
427
+ surfaceType: opts.surfaceType ?? "confirmation",
428
+ data,
429
+ timeoutMs: requestTimeoutMs,
430
+ };
431
+ if (opts.title) {
432
+ ipcParams.title = opts.title;
433
+ }
434
+ if (actions) {
435
+ ipcParams.actions = actions;
436
+ }
437
+
438
+ // Call IPC with timeout budget = request timeout + buffer
439
+ const ipcTimeoutMs = requestTimeoutMs + IPC_TIMEOUT_BUFFER_MS;
440
+ const result = await cliIpcCall<InteractiveUiResult>(
441
+ "ui_request",
442
+ ipcParams,
443
+ {
444
+ timeoutMs: ipcTimeoutMs,
445
+ },
446
+ );
447
+
448
+ if (!result.ok) {
449
+ if (opts.json) {
450
+ process.stdout.write(
451
+ JSON.stringify({ ok: false, error: result.error }) + "\n",
452
+ );
453
+ } else {
454
+ log.error(`Error: ${result.error}`);
455
+ }
456
+ process.exitCode = 1;
457
+ return;
458
+ }
459
+
460
+ if (opts.json) {
461
+ process.stdout.write(
462
+ JSON.stringify({ ok: true, ...result.result }) + "\n",
463
+ );
464
+ } else {
465
+ const r = result.result!;
466
+ if (r.status === "submitted") {
467
+ log.info(
468
+ `User responded: ${r.actionId ?? "submitted"}${r.summary ? ` — ${r.summary}` : ""}`,
469
+ );
470
+ } else if (r.status === "timed_out") {
471
+ log.info("Request timed out without a response.");
472
+ } else {
473
+ log.info("Request was cancelled.");
474
+ }
475
+ }
476
+ },
477
+ );
478
+
479
+ // ── ui confirm ──────────────────────────────────────────────────
480
+
481
+ ui.command("confirm")
482
+ .description(
483
+ "Present a yes/no confirmation prompt; exits 0 on confirm, 1 on deny/cancel/timeout",
484
+ )
485
+ .option("--title <title>", "Title displayed on the confirmation prompt")
486
+ .option(
487
+ "--message <message>",
488
+ "Message body shown in the confirmation prompt",
489
+ )
490
+ .option(
491
+ "--confirm-label <label>",
492
+ 'Label for the confirm button (default: "Confirm")',
493
+ "Confirm",
494
+ )
495
+ .option(
496
+ "--deny-label <label>",
497
+ 'Label for the deny button (default: "Deny")',
498
+ "Deny",
499
+ )
500
+ .option(
501
+ "--conversation-id <id>",
502
+ "Conversation ID — run 'assistant conversations list' to find it (auto-resolved from skill or bash tool context if omitted)",
503
+ )
504
+ .option(
505
+ "--timeout <ms>",
506
+ "Request timeout in milliseconds",
507
+ String(DEFAULT_REQUEST_TIMEOUT_MS),
508
+ )
509
+ .option("--json", "Output result as machine-readable JSON")
510
+ .addHelpText(
511
+ "after",
512
+ `
513
+ Ergonomic wrapper around "ui request" for binary yes/no gating. Presents
514
+ a confirmation surface to the user and blocks until they respond.
515
+
516
+ Exit codes:
517
+ 0 — User confirmed
518
+ 1 — User denied, cancelled, or the request timed out
519
+
520
+ The --json flag outputs the full interaction result for scripts that need
521
+ to inspect the response details.
522
+
523
+ Options:
524
+ --title <title> Prompt title
525
+ --message <message> Prompt body text
526
+ --confirm-label <label> Confirm button label (default: "Confirm")
527
+ --deny-label <label> Deny button label (default: "Deny")
528
+ --conversation-id <id> Explicit conversation ID
529
+ --timeout <ms> Request timeout in ms (default: 300000)
530
+ --json Output as JSON
531
+
532
+ Examples:
533
+ $ assistant ui confirm --message "Delete all data?"
534
+ $ assistant ui confirm --title "Deploy" --message "Push to prod?" --json
535
+ $ assistant ui confirm --message "Proceed?" --confirm-label "Yes" --deny-label "No"`,
536
+ )
537
+ .action(
538
+ async (opts: {
539
+ title?: string;
540
+ message?: string;
541
+ confirmLabel?: string;
542
+ denyLabel?: string;
543
+ conversationId?: string;
544
+ timeout?: string;
545
+ json?: boolean;
546
+ }) => {
547
+ // Resolve conversation ID
548
+ let conversationId: string;
549
+ try {
550
+ conversationId = resolveConversationId(opts.conversationId);
551
+ } catch (err) {
552
+ const msg = err instanceof Error ? err.message : String(err);
553
+ if (opts.json) {
554
+ process.stdout.write(
555
+ JSON.stringify({ ok: false, error: msg }) + "\n",
556
+ );
557
+ } else {
558
+ log.error(msg);
559
+ }
560
+ process.exitCode = 1;
561
+ return;
562
+ }
563
+
564
+ // Parse timeout
565
+ const rawTimeout = opts.timeout ?? String(DEFAULT_REQUEST_TIMEOUT_MS);
566
+ const requestTimeoutMs = parseStrictPositiveInt(rawTimeout);
567
+ if (isNaN(requestTimeoutMs) || requestTimeoutMs <= 0) {
568
+ const msg = `Invalid --timeout value "${opts.timeout}". Must be a positive integer (milliseconds).`;
569
+ if (opts.json) {
570
+ process.stdout.write(
571
+ JSON.stringify({ ok: false, error: msg }) + "\n",
572
+ );
573
+ } else {
574
+ log.error(msg);
575
+ }
576
+ process.exitCode = 1;
577
+ return;
578
+ }
579
+
580
+ // Build confirmation surface data
581
+ const confirmLabel = opts.confirmLabel ?? "Confirm";
582
+ const denyLabel = opts.denyLabel ?? "Deny";
583
+ const data: Record<string, unknown> = {};
584
+ if (opts.message) data.message = opts.message;
585
+ // Pass custom labels via data payload so the renderer reads them
586
+ // from ConfirmationSurfaceData.confirmLabel / .cancelLabel.
587
+ data.confirmLabel = confirmLabel;
588
+ data.cancelLabel = denyLabel;
589
+
590
+ // Build IPC params
591
+ const ipcParams: Record<string, unknown> = {
592
+ conversationId,
593
+ surfaceType: "confirmation",
594
+ data,
595
+ actions: [
596
+ {
597
+ id: "confirm",
598
+ label: confirmLabel,
599
+ variant: "primary",
600
+ },
601
+ {
602
+ id: "deny",
603
+ label: denyLabel,
604
+ variant: "secondary",
605
+ },
606
+ ],
607
+ timeoutMs: requestTimeoutMs,
608
+ };
609
+ if (opts.title) {
610
+ ipcParams.title = opts.title;
611
+ }
612
+
613
+ // Call IPC with timeout budget
614
+ const ipcTimeoutMs = requestTimeoutMs + IPC_TIMEOUT_BUFFER_MS;
615
+ const result = await cliIpcCall<InteractiveUiResult>(
616
+ "ui_request",
617
+ ipcParams,
618
+ {
619
+ timeoutMs: ipcTimeoutMs,
620
+ },
621
+ );
622
+
623
+ if (!result.ok) {
624
+ if (opts.json) {
625
+ process.stdout.write(
626
+ JSON.stringify({ ok: false, error: result.error }) + "\n",
627
+ );
628
+ } else {
629
+ log.error(`Error: ${result.error}`);
630
+ }
631
+ process.exitCode = 1;
632
+ return;
633
+ }
634
+
635
+ const r = result.result!;
636
+ const confirmed = r.status === "submitted" && r.actionId === "confirm";
637
+
638
+ if (opts.json) {
639
+ const jsonOut: Record<string, unknown> = {
640
+ ok: true,
641
+ confirmed,
642
+ status: r.status,
643
+ actionId: r.actionId,
644
+ surfaceId: r.surfaceId,
645
+ };
646
+ if (r.decisionToken !== undefined) {
647
+ jsonOut.decisionToken = r.decisionToken;
648
+ }
649
+ if (r.summary !== undefined) {
650
+ jsonOut.summary = r.summary;
651
+ }
652
+ process.stdout.write(JSON.stringify(jsonOut) + "\n");
653
+ } else {
654
+ if (confirmed) {
655
+ log.info("Confirmed.");
656
+ } else if (r.status === "timed_out") {
657
+ log.info("Confirmation timed out.");
658
+ } else if (r.status === "cancelled") {
659
+ log.info("Confirmation cancelled.");
660
+ } else {
661
+ log.info("Denied.");
662
+ }
663
+ }
664
+
665
+ if (!confirmed) {
666
+ process.exitCode = 1;
667
+ }
668
+ },
669
+ );
670
+ }