@vellumai/assistant 0.4.41 → 0.4.43

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 (843) hide show
  1. package/.env.example +1 -6
  2. package/.prettierignore +3 -0
  3. package/ARCHITECTURE.md +131 -393
  4. package/Dockerfile +0 -1
  5. package/README.md +73 -83
  6. package/bun.lock +8 -2
  7. package/docs/architecture/integrations.md +16 -21
  8. package/docs/architecture/memory.md +1 -1
  9. package/docs/architecture/scheduling.md +63 -63
  10. package/docs/architecture/security.md +3 -3
  11. package/docs/runbook-trusted-contacts.md +11 -12
  12. package/docs/trusted-contact-access.md +39 -39
  13. package/package.json +5 -8
  14. package/src/__tests__/access-request-decision.test.ts +4 -4
  15. package/src/__tests__/active-skill-tools.test.ts +49 -34
  16. package/src/__tests__/actor-token-service.test.ts +55 -85
  17. package/src/__tests__/amazon-cdp-integration.test.ts +14 -26
  18. package/src/__tests__/app-bundler.test.ts +14 -368
  19. package/src/__tests__/app-compiler.test.ts +0 -1
  20. package/src/__tests__/app-executors.test.ts +10 -1
  21. package/src/__tests__/approval-hardcoded-copy-guard.test.ts +1 -1
  22. package/src/__tests__/approval-primitive.test.ts +2 -4
  23. package/src/__tests__/approval-routes-http.test.ts +1 -1
  24. package/src/__tests__/asset-materialize-tool.test.ts +1 -4
  25. package/src/__tests__/asset-search-tool.test.ts +1 -4
  26. package/src/__tests__/assistant-attachments.test.ts +23 -0
  27. package/src/__tests__/assistant-feature-flags-integration.test.ts +4 -8
  28. package/src/__tests__/assistant-id-boundary-guard.test.ts +5 -5
  29. package/src/__tests__/attachments-store.test.ts +1 -4
  30. package/src/__tests__/avatar-e2e.test.ts +43 -23
  31. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  32. package/src/__tests__/bundled-skill-retrieval-guard.test.ts +2 -9
  33. package/src/__tests__/call-controller.test.ts +4 -8
  34. package/src/__tests__/call-conversation-messages.test.ts +1 -1
  35. package/src/__tests__/call-domain.test.ts +250 -8
  36. package/src/__tests__/call-pointer-message-composer.test.ts +14 -14
  37. package/src/__tests__/call-pointer-messages.test.ts +7 -11
  38. package/src/__tests__/call-recovery.test.ts +47 -0
  39. package/src/__tests__/call-routes-http.test.ts +13 -0
  40. package/src/__tests__/call-start-guardian-guard.test.ts +1 -1
  41. package/src/__tests__/callback-handoff-copy.test.ts +5 -5
  42. package/src/__tests__/canonical-guardian-store.test.ts +3 -3
  43. package/src/__tests__/channel-approval-routes.test.ts +101 -134
  44. package/src/__tests__/channel-approval.test.ts +0 -201
  45. package/src/__tests__/channel-approvals.test.ts +2 -2
  46. package/src/__tests__/channel-delivery-store.test.ts +16 -24
  47. package/src/__tests__/channel-guardian.test.ts +641 -740
  48. package/src/__tests__/channel-invite-transport.test.ts +1 -2
  49. package/src/__tests__/channel-policy.test.ts +9 -12
  50. package/src/__tests__/channel-readiness-service.test.ts +156 -45
  51. package/src/__tests__/channel-reply-delivery.test.ts +3 -3
  52. package/src/__tests__/channel-retry-sweep.test.ts +7 -7
  53. package/src/__tests__/checker.test.ts +10 -7
  54. package/src/__tests__/chrome-cdp.test.ts +57 -17
  55. package/src/__tests__/cli-help-reference-sync.test.ts +26 -0
  56. package/src/__tests__/compaction.benchmark.test.ts +25 -5
  57. package/src/__tests__/computer-use-session-lifecycle.test.ts +1 -1
  58. package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
  59. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +1 -1
  60. package/src/__tests__/config-loader-backfill.test.ts +310 -0
  61. package/src/__tests__/config-watcher.test.ts +1 -5
  62. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +3 -5
  63. package/src/__tests__/connection-policy.test.ts +3 -62
  64. package/src/__tests__/contacts-tools.test.ts +0 -2
  65. package/src/__tests__/context-memory-e2e.test.ts +11 -7
  66. package/src/__tests__/context-overflow-policy.test.ts +2 -2
  67. package/src/__tests__/context-window-manager.test.ts +220 -61
  68. package/src/__tests__/conversation-attention-store.test.ts +178 -2
  69. package/src/__tests__/conversation-attention-telegram.test.ts +8 -11
  70. package/src/__tests__/conversation-pairing.test.ts +14 -14
  71. package/src/__tests__/conversation-routes-guardian-reply.test.ts +1 -1
  72. package/src/__tests__/conversation-store.test.ts +2 -2
  73. package/src/__tests__/conversation-unread-route.test.ts +155 -0
  74. package/src/__tests__/credential-metadata-store.test.ts +0 -2
  75. package/src/__tests__/credential-security-invariants.test.ts +9 -16
  76. package/src/__tests__/credentials-cli.test.ts +49 -5
  77. package/src/__tests__/daemon-assistant-events.test.ts +4 -22
  78. package/src/__tests__/db-migration-rollback.test.ts +2 -2
  79. package/src/__tests__/deterministic-verification-control-plane.test.ts +19 -19
  80. package/src/__tests__/dictation-mode-detection.test.ts +1 -1
  81. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  82. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -6
  83. package/src/__tests__/email-cli.test.ts +12 -12
  84. package/src/__tests__/email-service-config-fallback.test.ts +1 -1
  85. package/src/__tests__/emit-signal-routing-intent.test.ts +3 -18
  86. package/src/__tests__/event-bus.test.ts +0 -1
  87. package/src/__tests__/followup-tools.test.ts +0 -2
  88. package/src/__tests__/gateway-client-managed-outbound.test.ts +6 -6
  89. package/src/__tests__/gateway-only-enforcement.test.ts +13 -77
  90. package/src/__tests__/gateway-only-guard.test.ts +5 -0
  91. package/src/__tests__/guardian-action-conversation-turn.test.ts +3 -3
  92. package/src/__tests__/guardian-action-followup-executor.test.ts +29 -94
  93. package/src/__tests__/guardian-action-followup-store.test.ts +2 -12
  94. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +48 -194
  95. package/src/__tests__/guardian-action-late-reply.test.ts +12 -12
  96. package/src/__tests__/guardian-action-store.test.ts +2 -2
  97. package/src/__tests__/guardian-action-sweep.test.ts +5 -5
  98. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +1 -3
  99. package/src/__tests__/guardian-dispatch.test.ts +5 -46
  100. package/src/__tests__/guardian-grant-minting.test.ts +5 -44
  101. package/src/__tests__/guardian-outbound-http.test.ts +95 -114
  102. package/src/__tests__/guardian-question-mode.test.ts +1 -4
  103. package/src/__tests__/guardian-routing-invariants.test.ts +5 -13
  104. package/src/__tests__/guardian-routing-state.test.ts +3 -3
  105. package/src/__tests__/guardian-verification-voice-binding.test.ts +64 -7
  106. package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +2 -2
  107. package/src/__tests__/handle-user-message-secret-resume.test.ts +3 -5
  108. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +16 -34
  109. package/src/__tests__/headless-browser-interactions.test.ts +1 -1
  110. package/src/__tests__/headless-browser-navigate.test.ts +1 -1
  111. package/src/__tests__/headless-browser-read-tools.test.ts +1 -1
  112. package/src/__tests__/headless-browser-snapshot.test.ts +1 -1
  113. package/src/__tests__/heartbeat-service.test.ts +1 -1
  114. package/src/__tests__/home-base-bootstrap.test.ts +0 -2
  115. package/src/__tests__/host-shell-tool.test.ts +3 -12
  116. package/src/__tests__/inbound-invite-redemption.test.ts +2 -2
  117. package/src/__tests__/ingress-url-consistency.test.ts +0 -64
  118. package/src/__tests__/integration-status.test.ts +8 -8
  119. package/src/__tests__/intent-routing.test.ts +9 -13
  120. package/src/__tests__/invite-redemption-service.test.ts +4 -4
  121. package/src/__tests__/invite-routes-http.test.ts +10 -10
  122. package/src/__tests__/llm-usage-store.test.ts +45 -9
  123. package/src/__tests__/local-gateway-health.test.ts +209 -0
  124. package/src/__tests__/managed-avatar-client.test.ts +23 -12
  125. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -2
  126. package/src/__tests__/managed-store.test.ts +29 -12
  127. package/src/__tests__/managed-twitter-guardrails.test.ts +353 -0
  128. package/src/__tests__/mcp-cli.test.ts +1 -1
  129. package/src/__tests__/mcp-health-check.test.ts +1 -1
  130. package/src/__tests__/media-generate-image.test.ts +1 -1
  131. package/src/__tests__/media-reuse-story.e2e.test.ts +1 -4
  132. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +9 -6
  133. package/src/__tests__/memory-regressions.test.ts +1 -166
  134. package/src/__tests__/messaging-send-tool.test.ts +8 -4
  135. package/src/__tests__/migration-export-http.test.ts +2 -2
  136. package/src/__tests__/migration-transport.test.ts +44 -0
  137. package/src/__tests__/non-member-access-request.test.ts +49 -36
  138. package/src/__tests__/notification-broadcaster.test.ts +15 -15
  139. package/src/__tests__/notification-decision-fallback.test.ts +2 -2
  140. package/src/__tests__/notification-decision-strategy.test.ts +4 -4
  141. package/src/__tests__/notification-deep-link.test.ts +3 -3
  142. package/src/__tests__/notification-guardian-path.test.ts +6 -44
  143. package/src/__tests__/notification-routing-intent.test.ts +11 -7
  144. package/src/__tests__/oauth-cli.test.ts +1 -1
  145. package/src/__tests__/onboarding-starter-tasks.test.ts +2 -6
  146. package/src/__tests__/onboarding-template-contract.test.ts +2 -2
  147. package/src/__tests__/platform.test.ts +168 -5
  148. package/src/__tests__/playbook-execution.test.ts +0 -2
  149. package/src/__tests__/playbook-tools.test.ts +0 -2
  150. package/src/__tests__/pricing.test.ts +125 -0
  151. package/src/__tests__/provider-error-scenarios.test.ts +9 -3
  152. package/src/__tests__/recording-handler.test.ts +46 -80
  153. package/src/__tests__/recording-state-machine.test.ts +112 -183
  154. package/src/__tests__/registry.test.ts +1 -1
  155. package/src/__tests__/relay-server.test.ts +69 -71
  156. package/src/__tests__/reminder-store.test.ts +3 -3
  157. package/src/__tests__/request-file-tool.test.ts +2 -2
  158. package/src/__tests__/ride-shotgun-handler.test.ts +2 -33
  159. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -3
  160. package/src/__tests__/runtime-events-sse-parity.test.ts +1 -1
  161. package/src/__tests__/scaffold-managed-skill-tool.test.ts +4 -4
  162. package/src/__tests__/schedule-store.test.ts +13 -4
  163. package/src/__tests__/schedule-tools.test.ts +0 -2
  164. package/src/__tests__/scheduler-recurrence.test.ts +3 -4
  165. package/src/__tests__/scoped-approval-grants.test.ts +3 -5
  166. package/src/__tests__/scoped-grant-security-matrix.test.ts +6 -8
  167. package/src/__tests__/secret-prompt-log-hygiene.test.ts +1 -1
  168. package/src/__tests__/secret-response-routing.test.ts +1 -1
  169. package/src/__tests__/send-endpoint-busy.test.ts +1 -1
  170. package/src/__tests__/sequence-store.test.ts +0 -2
  171. package/src/__tests__/server-history-render.test.ts +2 -199
  172. package/src/__tests__/session-abort-tool-results.test.ts +9 -3
  173. package/src/__tests__/session-agent-loop.test.ts +107 -3
  174. package/src/__tests__/session-confirmation-signals.test.ts +10 -4
  175. package/src/__tests__/session-conflict-gate.test.ts +9 -3
  176. package/src/__tests__/session-init.benchmark.test.ts +22 -13
  177. package/src/__tests__/session-load-history-repair.test.ts +6 -3
  178. package/src/__tests__/session-pre-run-repair.test.ts +9 -3
  179. package/src/__tests__/session-profile-injection.test.ts +9 -3
  180. package/src/__tests__/session-provider-retry-repair.test.ts +10 -4
  181. package/src/__tests__/session-queue.test.ts +10 -4
  182. package/src/__tests__/session-runtime-assembly.test.ts +28 -18
  183. package/src/__tests__/session-skill-tools.test.ts +2 -3
  184. package/src/__tests__/session-slash-known.test.ts +11 -4
  185. package/src/__tests__/session-slash-queue.test.ts +11 -4
  186. package/src/__tests__/session-slash-unknown.test.ts +12 -4
  187. package/src/__tests__/session-surfaces-deselection.test.ts +2 -2
  188. package/src/__tests__/session-surfaces-task-progress.test.ts +3 -3
  189. package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -1
  190. package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -1
  191. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -1
  192. package/src/__tests__/session-usage.test.ts +180 -0
  193. package/src/__tests__/session-workspace-cache-state.test.ts +8 -2
  194. package/src/__tests__/session-workspace-injection.test.ts +8 -2
  195. package/src/__tests__/session-workspace-tool-tracking.test.ts +8 -2
  196. package/src/__tests__/skill-feature-flags-integration.test.ts +5 -11
  197. package/src/__tests__/skill-feature-flags.test.ts +1 -0
  198. package/src/__tests__/skill-include-graph.test.ts +1 -0
  199. package/src/__tests__/skill-load-feature-flag.test.ts +3 -9
  200. package/src/__tests__/skill-load-tool.test.ts +90 -12
  201. package/src/__tests__/skill-projection-feature-flag.test.ts +14 -15
  202. package/src/__tests__/skills-uninstall.test.ts +131 -0
  203. package/src/__tests__/skills.test.ts +32 -16
  204. package/src/__tests__/slack-block-formatting.test.ts +1 -1
  205. package/src/__tests__/slack-channel-config.test.ts +71 -12
  206. package/src/__tests__/slack-inbound-verification.test.ts +7 -7
  207. package/src/__tests__/slack-share-routes.test.ts +1 -1
  208. package/src/__tests__/slack-skill.test.ts +2 -2
  209. package/src/__tests__/slash-commands-catalog.test.ts +1 -0
  210. package/src/__tests__/slash-commands-resolver.test.ts +1 -0
  211. package/src/__tests__/starter-task-flow.test.ts +1 -1
  212. package/src/__tests__/subagent-manager-notify.test.ts +1 -1
  213. package/src/__tests__/subagent-tools.test.ts +2 -2
  214. package/src/__tests__/system-prompt.test.ts +4 -8
  215. package/src/__tests__/task-compiler.test.ts +0 -2
  216. package/src/__tests__/task-management-tools.test.ts +0 -2
  217. package/src/__tests__/task-runner.test.ts +0 -2
  218. package/src/__tests__/task-scheduler.test.ts +2 -2
  219. package/src/__tests__/telegram-bot-username-resolution.test.ts +46 -44
  220. package/src/__tests__/terminal-tools.test.ts +1 -11
  221. package/src/__tests__/thread-seed-composer.test.ts +3 -1
  222. package/src/__tests__/tool-approval-handler.test.ts +5 -7
  223. package/src/__tests__/tool-executor.test.ts +2 -2
  224. package/src/__tests__/tool-grant-request-escalation.test.ts +3 -5
  225. package/src/__tests__/tool-notification-listener.test.ts +1 -1
  226. package/src/__tests__/tool-profiling-listener.test.ts +1 -1
  227. package/src/__tests__/tool-trace-listener.test.ts +1 -2
  228. package/src/__tests__/trace-emitter.test.ts +1 -1
  229. package/src/__tests__/trust-context-guards.test.ts +1 -1
  230. package/src/__tests__/trust-store.test.ts +44 -395
  231. package/src/__tests__/trusted-contact-approval-notifier.test.ts +6 -8
  232. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +5 -7
  233. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +6 -6
  234. package/src/__tests__/trusted-contact-multichannel.test.ts +54 -47
  235. package/src/__tests__/trusted-contact-verification.test.ts +12 -12
  236. package/src/__tests__/twilio-config.test.ts +11 -2
  237. package/src/__tests__/twilio-provider.test.ts +6 -4
  238. package/src/__tests__/twilio-routes.test.ts +408 -86
  239. package/src/__tests__/twitter-platform-proxy-client.test.ts +450 -0
  240. package/src/__tests__/update-bulletin-format.test.ts +1 -1
  241. package/src/__tests__/update-bulletin-state.test.ts +1 -1
  242. package/src/__tests__/update-bulletin.test.ts +4 -8
  243. package/src/__tests__/update-template-contract.test.ts +1 -1
  244. package/src/__tests__/usage-cache-backfill-migration.test.ts +406 -0
  245. package/src/__tests__/usage-routes.test.ts +23 -5
  246. package/src/__tests__/user-reference.test.ts +1 -1
  247. package/src/__tests__/{guardian-control-plane-policy.test.ts → verification-control-plane-policy.test.ts} +142 -170
  248. package/src/__tests__/{guardian-verification-intent-routing.test.ts → verification-session-intent-routing.test.ts} +16 -16
  249. package/src/__tests__/view-image-tool.test.ts +0 -2
  250. package/src/__tests__/voice-ingress-preflight.test.ts +36 -0
  251. package/src/__tests__/voice-invite-redemption.test.ts +18 -18
  252. package/src/__tests__/voice-scoped-grant-consumer.test.ts +7 -7
  253. package/src/__tests__/voice-session-bridge.test.ts +14 -16
  254. package/src/__tests__/workspace-policy.test.ts +1 -1
  255. package/src/approvals/AGENTS.md +4 -4
  256. package/src/approvals/approval-primitive.ts +2 -2
  257. package/src/approvals/guardian-decision-primitive.ts +1 -1
  258. package/src/approvals/guardian-request-resolvers.ts +3 -4
  259. package/src/bundler/app-bundler.ts +29 -217
  260. package/src/bundler/app-compiler.ts +131 -103
  261. package/src/bundler/compiler-tools.ts +248 -0
  262. package/src/calls/active-call-lease.ts +207 -0
  263. package/src/calls/call-constants.ts +0 -7
  264. package/src/calls/call-controller.ts +1 -1
  265. package/src/calls/call-conversation-messages.ts +6 -6
  266. package/src/calls/call-domain.ts +73 -38
  267. package/src/calls/call-pointer-message-composer.ts +6 -6
  268. package/src/calls/call-pointer-messages.ts +14 -13
  269. package/src/calls/call-recovery.ts +2 -0
  270. package/src/calls/call-store.ts +21 -28
  271. package/src/calls/guardian-action-sweep.ts +6 -8
  272. package/src/calls/guardian-dispatch.ts +2 -6
  273. package/src/calls/relay-access-wait.ts +4 -4
  274. package/src/calls/relay-server.ts +69 -80
  275. package/src/calls/relay-setup-router.ts +16 -21
  276. package/src/calls/relay-verification.ts +27 -28
  277. package/src/calls/twilio-config.ts +28 -3
  278. package/src/calls/twilio-provider.ts +5 -5
  279. package/src/calls/twilio-rest.ts +26 -27
  280. package/src/calls/twilio-routes.ts +67 -54
  281. package/src/calls/types.ts +8 -8
  282. package/src/calls/voice-ingress-preflight.ts +110 -0
  283. package/src/calls/voice-session-bridge.ts +7 -7
  284. package/src/channels/config.ts +1 -10
  285. package/src/{config/channel-permission-profiles.ts → channels/permission-profiles.ts} +1 -1
  286. package/src/channels/types.ts +2 -13
  287. package/src/cli/__tests__/notifications.test.ts +1 -1
  288. package/src/{amazon → cli/commands/amazon}/client.ts +99 -42
  289. package/src/cli/{amazon.ts → commands/amazon/index.ts} +12 -17
  290. package/src/{amazon → cli/commands/amazon}/request-extractor.ts +39 -3
  291. package/src/cli/commands/amazon/session.ts +116 -0
  292. package/src/cli/{audit.ts → commands/audit.ts} +2 -4
  293. package/src/cli/{autonomy.ts → commands/autonomy.ts} +1 -3
  294. package/src/cli/commands/browser-relay.ts +520 -0
  295. package/src/cli/commands/channel-verification-sessions.ts +442 -0
  296. package/src/cli/{completions.ts → commands/completions.ts} +1 -3
  297. package/src/cli/{config.ts → commands/config.ts} +3 -5
  298. package/src/cli/{contacts.ts → commands/contacts.ts} +263 -16
  299. package/src/cli/{credentials.ts → commands/credentials.ts} +9 -10
  300. package/src/cli/{default-action.ts → commands/default-action.ts} +3 -3
  301. package/src/cli/{dev.ts → commands/dev.ts} +4 -6
  302. package/src/cli/{doctor.ts → commands/doctor.ts} +36 -60
  303. package/src/cli/{email.ts → commands/email.ts} +2 -2
  304. package/src/cli/{keys.ts → commands/keys.ts} +6 -6
  305. package/src/cli/{map.ts → commands/map.ts} +85 -93
  306. package/src/cli/{mcp.ts → commands/mcp.ts} +5 -7
  307. package/src/cli/{memory.ts → commands/memory.ts} +6 -7
  308. package/src/cli/{notifications.ts → commands/notifications.ts} +8 -10
  309. package/src/cli/{oauth.ts → commands/oauth.ts} +2 -2
  310. package/src/cli/commands/platform.ts +176 -0
  311. package/src/cli/{sequence.ts → commands/sequence.ts} +3 -3
  312. package/src/cli/{sessions.ts → commands/sessions.ts} +32 -52
  313. package/src/cli/commands/skills.ts +498 -0
  314. package/src/cli/{trust.ts → commands/trust.ts} +2 -4
  315. package/src/{__tests__/twitter-cli-error-shaping.test.ts → cli/commands/twitter/__tests__/cli-error-shaping.test.ts} +43 -2
  316. package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +483 -0
  317. package/src/{__tests__/twitter-cli-routing.test.ts → cli/commands/twitter/__tests__/cli-routing.test.ts} +130 -4
  318. package/src/{__tests__/twitter-oauth-client.test.ts → cli/commands/twitter/__tests__/oauth-client.test.ts} +2 -2
  319. package/src/{twitter → cli/commands/twitter}/client.ts +17 -7
  320. package/src/cli/{twitter.ts → commands/twitter/index.ts} +322 -273
  321. package/src/cli/commands/twitter/router.ts +396 -0
  322. package/src/cli/commands/twitter/session.ts +121 -0
  323. package/src/cli/db.ts +1 -0
  324. package/src/cli/http-client.ts +87 -0
  325. package/src/cli/logger.ts +6 -0
  326. package/src/cli/main-screen.tsx +4 -3
  327. package/src/cli/output.ts +19 -0
  328. package/src/cli/program.ts +29 -27
  329. package/src/cli/reference.ts +27 -37
  330. package/src/cli.ts +452 -240
  331. package/src/config/assistant-feature-flags.ts +3 -15
  332. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +3 -6
  333. package/src/config/bundled-skills/agentmail/SKILL.md +4 -4
  334. package/src/config/bundled-skills/amazon/SKILL.md +15 -5
  335. package/src/config/bundled-skills/api-mapping/SKILL.md +4 -4
  336. package/src/config/bundled-skills/app-builder/SKILL.md +21 -6
  337. package/src/config/bundled-skills/browser/SKILL.md +4 -5
  338. package/src/config/bundled-skills/chatgpt-import/SKILL.md +4 -4
  339. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +1 -1
  340. package/src/config/bundled-skills/claude-code/SKILL.md +4 -4
  341. package/src/config/bundled-skills/cli-discover/SKILL.md +4 -4
  342. package/src/config/bundled-skills/computer-use/SKILL.md +4 -4
  343. package/src/config/bundled-skills/contacts/SKILL.md +87 -229
  344. package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +4 -4
  345. package/src/config/bundled-skills/document/SKILL.md +4 -3
  346. package/src/config/bundled-skills/document-writer/SKILL.md +4 -4
  347. package/src/config/bundled-skills/doordash/SKILL.md +4 -11
  348. package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +8 -16
  349. package/src/config/bundled-skills/doordash/doordash-cli.ts +120 -86
  350. package/src/config/bundled-skills/doordash/lib/session.ts +1 -2
  351. package/src/config/bundled-skills/doordash/lib/shared/platform.ts +26 -9
  352. package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +140 -0
  353. package/src/config/bundled-skills/email-setup/SKILL.md +4 -4
  354. package/src/config/bundled-skills/followups/SKILL.md +4 -3
  355. package/src/config/bundled-skills/frontend-design/SKILL.md +2 -0
  356. package/src/config/bundled-skills/google-calendar/SKILL.md +4 -4
  357. package/src/config/bundled-skills/google-oauth-setup/SKILL.md +4 -6
  358. package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +26 -41
  359. package/src/config/bundled-skills/image-studio/SKILL.md +4 -5
  360. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +1 -1
  361. package/src/config/bundled-skills/influencer/SKILL.md +19 -19
  362. package/src/{influencer → config/bundled-skills/influencer/scripts}/client.ts +73 -56
  363. package/src/config/bundled-skills/influencer/scripts/influencer.ts +267 -0
  364. package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -2
  365. package/src/config/bundled-skills/macos-automation/SKILL.md +4 -5
  366. package/src/config/bundled-skills/mcp-setup/SKILL.md +4 -4
  367. package/src/config/bundled-skills/media-processing/SKILL.md +3 -2
  368. package/src/config/bundled-skills/messaging/SKILL.md +6 -33
  369. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -5
  370. package/src/config/bundled-skills/notifications/SKILL.md +4 -4
  371. package/src/config/bundled-skills/notion/SKILL.md +4 -4
  372. package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +4 -5
  373. package/src/config/bundled-skills/oauth-setup/SKILL.md +4 -5
  374. package/src/config/bundled-skills/phone-calls/SKILL.md +24 -458
  375. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +83 -0
  376. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +57 -0
  377. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +67 -0
  378. package/src/config/bundled-skills/playbooks/SKILL.md +4 -3
  379. package/src/config/bundled-skills/public-ingress/SKILL.md +65 -14
  380. package/src/config/bundled-skills/reminder/SKILL.md +4 -3
  381. package/src/config/bundled-skills/restaurant-reservation/SKILL.md +4 -6
  382. package/src/config/bundled-skills/schedule/SKILL.md +4 -3
  383. package/src/config/bundled-skills/screen-recording/SKILL.md +4 -3
  384. package/src/config/bundled-skills/self-upgrade/SKILL.md +4 -4
  385. package/src/config/bundled-skills/skills-catalog/SKILL.md +4 -4
  386. package/src/config/bundled-skills/slack/SKILL.md +4 -8
  387. package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +1 -1
  388. package/src/config/bundled-skills/slack-app-setup/SKILL.md +66 -88
  389. package/src/config/bundled-skills/slack-digest-setup/SKILL.md +4 -5
  390. package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +4 -5
  391. package/src/config/bundled-skills/start-the-day/SKILL.md +4 -4
  392. package/src/config/bundled-skills/subagent/SKILL.md +4 -3
  393. package/src/config/bundled-skills/tasks/SKILL.md +4 -3
  394. package/src/config/bundled-skills/telegram-setup/SKILL.md +63 -112
  395. package/src/config/bundled-skills/time-based-actions/SKILL.md +4 -3
  396. package/src/config/bundled-skills/transcribe/SKILL.md +4 -3
  397. package/src/config/bundled-skills/twilio-setup/SKILL.md +23 -50
  398. package/src/config/bundled-skills/twitter/SKILL.md +56 -14
  399. package/src/config/bundled-skills/typescript-eval/SKILL.md +4 -4
  400. package/src/config/bundled-skills/vercel-token-setup/SKILL.md +4 -5
  401. package/src/config/bundled-skills/voice-setup/SKILL.md +19 -45
  402. package/src/config/bundled-skills/watcher/SKILL.md +4 -3
  403. package/src/config/env-registry.ts +1 -10
  404. package/src/config/feature-flag-registry.json +0 -16
  405. package/src/config/loader.ts +78 -38
  406. package/src/config/schema.ts +143 -106
  407. package/src/config/schemas/channels.ts +80 -0
  408. package/src/config/schemas/heartbeat.ts +51 -0
  409. package/src/config/schemas/inference.ts +136 -0
  410. package/src/config/schemas/ingress.ts +81 -0
  411. package/src/config/schemas/logging.ts +21 -0
  412. package/src/config/schemas/memory-lifecycle.ts +67 -0
  413. package/src/config/schemas/memory-processing.ts +215 -0
  414. package/src/config/schemas/memory-retrieval.ts +222 -0
  415. package/src/config/schemas/memory-storage.ts +83 -0
  416. package/src/config/schemas/memory.ts +58 -0
  417. package/src/config/schemas/platform.ts +64 -0
  418. package/src/config/schemas/security.ts +54 -0
  419. package/src/config/schemas/swarm.ts +50 -0
  420. package/src/config/schemas/timeouts.ts +47 -0
  421. package/src/config/{agent-schema.ts → schemas/workspace-git.ts} +0 -97
  422. package/src/config/skill-state.ts +3 -13
  423. package/src/config/skills.ts +233 -75
  424. package/src/config/types.ts +1 -20
  425. package/src/contacts/contact-store.ts +12 -49
  426. package/src/contacts/contacts-write.ts +1 -5
  427. package/src/contacts/index.ts +0 -2
  428. package/src/contacts/types.ts +0 -8
  429. package/src/context/window-manager.ts +73 -14
  430. package/src/daemon/assistant-attachments.ts +9 -0
  431. package/src/daemon/computer-use-session.ts +3 -3
  432. package/src/daemon/connection-policy.ts +6 -21
  433. package/src/daemon/context-overflow-policy.ts +1 -1
  434. package/src/daemon/daemon-control.ts +46 -54
  435. package/src/daemon/doordash-steps.ts +1 -1
  436. package/src/daemon/handlers/config-channels.ts +407 -71
  437. package/src/daemon/handlers/config-ingress.ts +17 -85
  438. package/src/daemon/handlers/config-model.ts +145 -123
  439. package/src/daemon/handlers/config-slack-channel.ts +43 -29
  440. package/src/daemon/handlers/config-telegram.ts +32 -27
  441. package/src/daemon/handlers/config-voice.ts +1 -4
  442. package/src/daemon/handlers/dictation.ts +11 -16
  443. package/src/daemon/handlers/identity.ts +5 -6
  444. package/src/daemon/handlers/pairing.ts +5 -13
  445. package/src/daemon/handlers/recording.ts +97 -199
  446. package/src/daemon/handlers/session-history.ts +110 -96
  447. package/src/daemon/handlers/session-user-message.ts +29 -57
  448. package/src/daemon/handlers/sessions.ts +240 -137
  449. package/src/daemon/handlers/shared.ts +62 -95
  450. package/src/daemon/handlers/skills.ts +492 -543
  451. package/src/daemon/lifecycle.ts +168 -55
  452. package/src/daemon/main.ts +1 -0
  453. package/src/daemon/{ipc-contract.ts → message-protocol.ts} +49 -49
  454. package/src/daemon/{ipc-contract → message-types}/computer-use.ts +0 -3
  455. package/src/daemon/{ipc-contract → message-types}/diagnostics.ts +0 -16
  456. package/src/daemon/{ipc-contract → message-types}/integrations.ts +29 -13
  457. package/src/daemon/{ipc-contract → message-types}/memory.ts +8 -0
  458. package/src/daemon/{ipc-contract → message-types}/notifications.ts +15 -1
  459. package/src/daemon/{ipc-contract → message-types}/sessions.ts +1 -0
  460. package/src/daemon/{ipc-contract → message-types}/shared.ts +0 -8
  461. package/src/daemon/{ipc-contract → message-types}/workspace.ts +2 -2
  462. package/src/daemon/providers-setup.ts +0 -5
  463. package/src/daemon/recording-executor.ts +0 -7
  464. package/src/daemon/ride-shotgun-handler.ts +9 -13
  465. package/src/daemon/server.ts +136 -510
  466. package/src/daemon/session-agent-loop-handlers.ts +22 -7
  467. package/src/daemon/session-agent-loop.ts +86 -24
  468. package/src/daemon/session-attachments.ts +1 -1
  469. package/src/daemon/session-error.ts +1 -1
  470. package/src/daemon/session-history.ts +20 -15
  471. package/src/daemon/session-lifecycle.ts +9 -7
  472. package/src/daemon/session-memory.ts +15 -1
  473. package/src/daemon/session-messaging.ts +10 -6
  474. package/src/daemon/session-notifiers.ts +10 -8
  475. package/src/daemon/session-process.ts +34 -25
  476. package/src/daemon/session-queue-manager.ts +1 -1
  477. package/src/daemon/session-runtime-assembly.ts +6 -25
  478. package/src/daemon/session-surfaces.ts +2 -2
  479. package/src/daemon/session-tool-setup.ts +1 -1
  480. package/src/daemon/session-usage.ts +119 -18
  481. package/src/daemon/session.ts +13 -9
  482. package/src/daemon/tool-side-effects.ts +6 -5
  483. package/src/daemon/trace-emitter.ts +1 -1
  484. package/src/daemon/{guardian-verification-intent.ts → verification-session-intent.ts} +16 -16
  485. package/src/daemon/watch-handler.ts +2 -5
  486. package/src/email/service.ts +8 -8
  487. package/src/events/domain-events.ts +0 -1
  488. package/src/events/tool-notification-listener.ts +1 -1
  489. package/src/followups/followup-store.ts +1 -2
  490. package/src/followups/types.ts +0 -6
  491. package/src/heartbeat/heartbeat-service.ts +1 -1
  492. package/src/inbound/platform-callback-registration.ts +1 -1
  493. package/src/inbound/public-ingress-urls.ts +0 -8
  494. package/src/index.ts +12 -0
  495. package/src/mcp/client.ts +1 -1
  496. package/src/mcp/manager.ts +1 -1
  497. package/src/memory/app-store.ts +1 -42
  498. package/src/memory/{guardian-verification.ts → channel-verification-sessions.ts} +110 -93
  499. package/src/memory/conversation-attention-store.ts +154 -0
  500. package/src/memory/conversation-bootstrap.ts +1 -1
  501. package/src/memory/conversation-crud.ts +53 -1
  502. package/src/memory/conversation-display-order-migration.ts +2 -3
  503. package/src/memory/conversation-queries.ts +1 -29
  504. package/src/memory/conversation-title-service.ts +26 -21
  505. package/src/memory/db-connection.ts +1 -8
  506. package/src/memory/db-init.ts +20 -0
  507. package/src/memory/delivery-crud.ts +4 -34
  508. package/src/memory/external-conversation-store.ts +1 -1
  509. package/src/memory/format-recall.ts +47 -0
  510. package/src/memory/guardian-action-store.ts +4 -5
  511. package/src/memory/guardian-rate-limits.ts +0 -3
  512. package/src/memory/invite-store.ts +1 -1
  513. package/src/memory/job-handlers/backfill.ts +9 -2
  514. package/src/memory/job-handlers/extraction.ts +2 -7
  515. package/src/memory/job-handlers/summarization.ts +1 -1
  516. package/src/memory/llm-usage-store.ts +11 -0
  517. package/src/memory/migrations/114-notifications.ts +12 -40
  518. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +357 -0
  519. package/src/memory/migrations/141-rename-verification-table.ts +55 -0
  520. package/src/memory/migrations/142-rename-verification-session-id-column.ts +32 -0
  521. package/src/memory/migrations/143-rename-guardian-verification-values.ts +48 -0
  522. package/src/memory/migrations/144-rename-voice-to-phone.ts +147 -0
  523. package/src/memory/migrations/index.ts +5 -0
  524. package/src/memory/migrations/registry.ts +30 -0
  525. package/src/memory/qdrant-circuit-breaker.ts +5 -0
  526. package/src/memory/retriever.test.ts +707 -0
  527. package/src/memory/retriever.ts +120 -116
  528. package/src/memory/schema/calls.ts +3 -7
  529. package/src/memory/schema/guardian.ts +2 -2
  530. package/src/memory/search/lexical.ts +4 -1
  531. package/src/memory/search/query-expansion.test.ts +70 -0
  532. package/src/memory/search/query-expansion.ts +118 -0
  533. package/src/memory/search/types.ts +18 -17
  534. package/src/messaging/providers/telegram-bot/adapter.ts +1 -1
  535. package/src/messaging/providers/whatsapp/adapter.ts +1 -4
  536. package/src/messaging/registry.ts +0 -1
  537. package/src/notifications/README.md +13 -22
  538. package/src/notifications/adapters/macos.ts +1 -1
  539. package/src/notifications/conversation-pairing.ts +2 -2
  540. package/src/notifications/copy-composer.ts +2 -2
  541. package/src/notifications/decision-engine.ts +1 -10
  542. package/src/notifications/destination-resolver.ts +2 -3
  543. package/src/notifications/emit-signal.ts +2 -8
  544. package/src/notifications/guardian-question-mode.ts +5 -8
  545. package/src/notifications/signal.ts +1 -2
  546. package/src/notifications/types.ts +1 -1
  547. package/src/oauth/token-persistence.ts +25 -1
  548. package/src/permissions/checker.ts +4 -29
  549. package/src/permissions/defaults.ts +6 -6
  550. package/src/permissions/prompter.ts +1 -1
  551. package/src/permissions/secret-prompter.ts +1 -1
  552. package/src/permissions/shell-identity.ts +1 -1
  553. package/src/permissions/trust-store.ts +13 -76
  554. package/src/permissions/workspace-policy.ts +1 -1
  555. package/src/{config → prompts}/computer-use-prompt.ts +1 -1
  556. package/src/{config → prompts}/system-prompt.ts +40 -21
  557. package/src/runtime/AGENTS.md +6 -8
  558. package/src/runtime/access-request-helper.ts +36 -55
  559. package/src/runtime/actor-trust-resolver.ts +1 -24
  560. package/src/runtime/approval-message-composer.ts +6 -2
  561. package/src/runtime/assistant-event.ts +1 -1
  562. package/src/runtime/auth/__tests__/ipc-auth-context.test.ts +1 -1
  563. package/src/runtime/auth/__tests__/subject.test.ts +32 -0
  564. package/src/runtime/auth/route-policy.ts +140 -24
  565. package/src/runtime/auth/subject.ts +9 -0
  566. package/src/runtime/auth/token-service.ts +11 -0
  567. package/src/runtime/auth/types.ts +1 -1
  568. package/src/runtime/channel-approval-types.ts +1 -1
  569. package/src/runtime/channel-approvals.ts +1 -1
  570. package/src/runtime/channel-invite-transport.ts +0 -2
  571. package/src/runtime/channel-invite-transports/slack.ts +5 -19
  572. package/src/runtime/channel-invite-transports/telegram.ts +17 -34
  573. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  574. package/src/runtime/channel-readiness-service.ts +24 -159
  575. package/src/runtime/channel-readiness-types.ts +5 -1
  576. package/src/runtime/channel-reply-delivery.ts +43 -3
  577. package/src/runtime/channel-retry-sweep.ts +14 -22
  578. package/src/runtime/{channel-guardian-service.ts → channel-verification-service.ts} +50 -53
  579. package/src/runtime/confirmation-request-guardian-bridge.ts +2 -3
  580. package/src/runtime/gateway-client.ts +12 -15
  581. package/src/runtime/guardian-action-followup-executor.ts +8 -73
  582. package/src/runtime/guardian-action-grant-minter.ts +45 -61
  583. package/src/runtime/guardian-action-message-composer.ts +4 -4
  584. package/src/runtime/guardian-reply-router.ts +3 -3
  585. package/src/runtime/http-server.ts +133 -24
  586. package/src/runtime/http-types.ts +34 -1
  587. package/src/runtime/invite-instruction-generator.ts +1 -3
  588. package/src/runtime/invite-redemption-service.ts +5 -5
  589. package/src/runtime/invite-service.ts +7 -7
  590. package/src/runtime/local-actor-identity.ts +28 -2
  591. package/src/runtime/local-gateway-health.ts +275 -0
  592. package/src/runtime/middleware/twilio-validation.ts +3 -3
  593. package/src/runtime/migrations/migration-transport.ts +18 -3
  594. package/src/runtime/migrations/rebind-secrets-screen.ts +2 -2
  595. package/src/runtime/nl-approval-parser.ts +2 -3
  596. package/src/runtime/routes/access-request-decision.ts +2 -2
  597. package/src/runtime/routes/app-management-routes.ts +921 -0
  598. package/src/runtime/routes/approval-routes.ts +76 -7
  599. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +38 -203
  600. package/src/runtime/routes/channel-delivery-routes.ts +5 -4
  601. package/src/runtime/routes/channel-route-shared.ts +1 -3
  602. package/src/runtime/routes/channel-routes.ts +1 -4
  603. package/src/runtime/routes/channel-verification-routes.ts +257 -0
  604. package/src/runtime/routes/computer-use-routes.ts +595 -0
  605. package/src/runtime/routes/contact-routes.ts +1 -317
  606. package/src/runtime/routes/conversation-attention-routes.ts +6 -5
  607. package/src/runtime/routes/conversation-routes.ts +11 -18
  608. package/src/runtime/routes/debug-routes.ts +1 -1
  609. package/src/runtime/routes/diagnostics-routes.ts +813 -0
  610. package/src/runtime/routes/documents-routes.ts +227 -0
  611. package/src/runtime/routes/guardian-approval-interception.ts +25 -48
  612. package/src/runtime/routes/guardian-bootstrap-routes.ts +3 -3
  613. package/src/runtime/routes/guardian-expiry-sweep.ts +2 -2
  614. package/src/runtime/routes/guardian-refresh-routes.ts +11 -6
  615. package/src/runtime/routes/inbound-conversation.ts +3 -10
  616. package/src/runtime/routes/inbound-message-handler.ts +7 -6
  617. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +22 -22
  618. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +44 -0
  619. package/src/runtime/routes/inbound-stages/background-dispatch.ts +140 -22
  620. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +4 -4
  621. package/src/runtime/routes/inbound-stages/edit-intercept.ts +5 -5
  622. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +3 -3
  623. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -4
  624. package/src/runtime/routes/inbound-stages/verification-intercept.ts +13 -14
  625. package/src/runtime/routes/integrations/slack/channel.ts +72 -0
  626. package/src/runtime/routes/{slack-share-routes.ts → integrations/slack/share.ts} +9 -9
  627. package/src/runtime/routes/integrations/telegram.ts +111 -0
  628. package/src/runtime/routes/integrations/twilio.ts +451 -0
  629. package/src/runtime/routes/invite-routes.ts +2 -2
  630. package/src/runtime/routes/pairing-routes.ts +1 -1
  631. package/src/runtime/routes/recording-routes.ts +332 -0
  632. package/src/{daemon/handlers/config-scheduling.ts → runtime/routes/schedule-routes.ts} +91 -106
  633. package/src/runtime/routes/session-management-routes.ts +167 -0
  634. package/src/runtime/routes/session-query-routes.ts +204 -0
  635. package/src/runtime/routes/settings-routes.ts +977 -0
  636. package/src/runtime/routes/skills-routes.ts +266 -0
  637. package/src/runtime/routes/subagents-routes.ts +246 -0
  638. package/src/runtime/routes/surface-action-routes.ts +100 -10
  639. package/src/runtime/routes/surface-content-routes.ts +1 -1
  640. package/src/runtime/routes/work-items-routes.ts +809 -0
  641. package/src/runtime/routes/workspace-routes.test.ts +778 -0
  642. package/src/runtime/routes/workspace-routes.ts +410 -0
  643. package/src/runtime/routes/workspace-utils.ts +88 -0
  644. package/src/runtime/telegram-streaming-delivery.test.ts +597 -0
  645. package/src/runtime/telegram-streaming-delivery.ts +380 -0
  646. package/src/runtime/tool-grant-request-helper.ts +1 -2
  647. package/src/runtime/trust-context-resolver.ts +0 -1
  648. package/src/runtime/{guardian-outbound-actions.ts → verification-outbound-actions.ts} +23 -188
  649. package/src/runtime/verification-rate-limiter.ts +2 -2
  650. package/src/runtime/{guardian-verification-templates.ts → verification-templates.ts} +2 -28
  651. package/src/schedule/integration-status.ts +2 -2
  652. package/src/schedule/schedule-store.ts +7 -9
  653. package/src/sequence/engine.ts +1 -1
  654. package/src/skills/active-skill-tools.ts +0 -8
  655. package/src/skills/clawhub.ts +1 -10
  656. package/src/skills/managed-store.ts +14 -4
  657. package/src/skills/slash-commands.ts +1 -1
  658. package/src/subagent/manager.ts +1 -1
  659. package/src/subagent/types.ts +1 -1
  660. package/src/tasks/SPEC.md +10 -10
  661. package/src/tasks/task-scheduler.ts +1 -1
  662. package/src/telegram/bot-username.ts +13 -0
  663. package/src/tools/assets/materialize.ts +1 -1
  664. package/src/tools/assets/search.ts +1 -1
  665. package/src/tools/browser/browser-execution.ts +2 -2
  666. package/src/tools/browser/browser-manager.ts +88 -11
  667. package/src/tools/browser/browser-screencast.ts +1 -1
  668. package/src/tools/browser/headless-browser.ts +0 -17
  669. package/src/tools/browser/jit-auth.ts +1 -1
  670. package/src/tools/browser/recording-store.ts +19 -1
  671. package/src/tools/browser/runtime-check.ts +4 -2
  672. package/src/tools/calls/call-start.ts +3 -3
  673. package/src/tools/credentials/metadata-store.ts +0 -13
  674. package/src/tools/credentials/vault.ts +7 -31
  675. package/src/tools/followups/followup_create.ts +0 -8
  676. package/src/tools/mcp/mcp-tool-factory.ts +1 -1
  677. package/src/tools/memory/definitions.ts +32 -10
  678. package/src/tools/memory/handlers.test.ts +573 -0
  679. package/src/tools/memory/handlers.ts +222 -65
  680. package/src/tools/memory/register.ts +53 -24
  681. package/src/tools/network/script-proxy/session-manager.ts +1 -12
  682. package/src/tools/schedule/update.ts +0 -8
  683. package/src/tools/skills/load.ts +3 -3
  684. package/src/tools/subagent/read.ts +1 -1
  685. package/src/tools/system/voice-config.ts +2 -14
  686. package/src/tools/terminal/safe-env.ts +5 -18
  687. package/src/tools/tool-approval-handler.ts +4 -4
  688. package/src/tools/tool-manifest.ts +4 -2
  689. package/src/tools/types.ts +1 -1
  690. package/src/tools/{guardian-control-plane-policy.ts → verification-control-plane-policy.ts} +37 -39
  691. package/src/twitter/platform-proxy-client.ts +405 -0
  692. package/src/usage/types.ts +21 -0
  693. package/src/util/canonicalize-identity.ts +2 -6
  694. package/src/util/cookie-session.ts +35 -51
  695. package/src/util/platform.ts +93 -86
  696. package/src/util/pricing.ts +180 -43
  697. package/src/work-items/work-item-runner.ts +1 -1
  698. package/scripts/ipc/check-contract-inventory.ts +0 -107
  699. package/scripts/ipc/check-swift-decoder-drift.ts +0 -184
  700. package/scripts/ipc/generate-swift.ts +0 -528
  701. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +0 -3043
  702. package/src/__tests__/app-migration.test.ts +0 -148
  703. package/src/__tests__/config-loader-migration.test.ts +0 -85
  704. package/src/__tests__/daemon-lifecycle.test.ts +0 -715
  705. package/src/__tests__/daemon-server-session-init.test.ts +0 -864
  706. package/src/__tests__/guardian-actions-endpoint.test.ts +0 -1452
  707. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +0 -228
  708. package/src/__tests__/handlers-cu-observation-blob.test.ts +0 -397
  709. package/src/__tests__/handlers-ipc-blob-probe.test.ts +0 -218
  710. package/src/__tests__/handlers-slack-config.test.ts +0 -140
  711. package/src/__tests__/handlers-telegram-config.test.ts +0 -1317
  712. package/src/__tests__/handlers-twitter-config.test.ts +0 -1145
  713. package/src/__tests__/ingress-reconcile.test.ts +0 -606
  714. package/src/__tests__/integrations-cli.test.ts +0 -232
  715. package/src/__tests__/ipc-blob-store.test.ts +0 -329
  716. package/src/__tests__/ipc-contract-inventory.test.ts +0 -69
  717. package/src/__tests__/ipc-contract.test.ts +0 -76
  718. package/src/__tests__/ipc-protocol.test.ts +0 -120
  719. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +0 -250
  720. package/src/__tests__/ipc-snapshot.test.ts +0 -2197
  721. package/src/__tests__/ipc-validate.test.ts +0 -471
  722. package/src/__tests__/migration-cli-flows.test.ts +0 -186
  723. package/src/__tests__/migration-ordering.test.ts +0 -267
  724. package/src/__tests__/oauth-connect-handler.test.ts +0 -361
  725. package/src/__tests__/platform-move-helper.test.ts +0 -108
  726. package/src/__tests__/platform-socket-path.test.ts +0 -52
  727. package/src/__tests__/platform-workspace-migration.test.ts +0 -1051
  728. package/src/__tests__/recording-intent-handler.test.ts +0 -1155
  729. package/src/__tests__/script-proxy-profile-template-fallback.test.ts +0 -127
  730. package/src/__tests__/sms-messaging-provider.test.ts +0 -156
  731. package/src/__tests__/tool-permission-simulate-handler.test.ts +0 -367
  732. package/src/__tests__/twitter-auth-handler.test.ts +0 -561
  733. package/src/__tests__/work-item-output.test.ts +0 -150
  734. package/src/amazon/session.ts +0 -58
  735. package/src/cli/channels.ts +0 -51
  736. package/src/cli/influencer.ts +0 -319
  737. package/src/cli/integrations.ts +0 -372
  738. package/src/cli/ipc-client.ts +0 -88
  739. package/src/config/bundled-skills/configure-settings/SKILL.md +0 -86
  740. package/src/config/bundled-skills/doordash/lib/shared/ipc.ts +0 -32
  741. package/src/config/bundled-skills/sms-setup/SKILL.md +0 -210
  742. package/src/config/core-schema.ts +0 -434
  743. package/src/config/memory-schema.ts +0 -617
  744. package/src/daemon/auth-manager.ts +0 -106
  745. package/src/daemon/handlers/apps.ts +0 -758
  746. package/src/daemon/handlers/avatar.ts +0 -73
  747. package/src/daemon/handlers/browser.ts +0 -3
  748. package/src/daemon/handlers/computer-use.ts +0 -231
  749. package/src/daemon/handlers/config-dispatch.ts +0 -29
  750. package/src/daemon/handlers/config-heartbeat.ts +0 -299
  751. package/src/daemon/handlers/config-inbox.ts +0 -457
  752. package/src/daemon/handlers/config-integrations.ts +0 -409
  753. package/src/daemon/handlers/config-platform.ts +0 -77
  754. package/src/daemon/handlers/config-slack.ts +0 -41
  755. package/src/daemon/handlers/config-tools.ts +0 -226
  756. package/src/daemon/handlers/config-trust.ts +0 -135
  757. package/src/daemon/handlers/config.ts +0 -64
  758. package/src/daemon/handlers/contacts.ts +0 -193
  759. package/src/daemon/handlers/diagnostics.ts +0 -382
  760. package/src/daemon/handlers/documents.ts +0 -188
  761. package/src/daemon/handlers/guardian-actions.ts +0 -82
  762. package/src/daemon/handlers/home-base.ts +0 -82
  763. package/src/daemon/handlers/index.ts +0 -222
  764. package/src/daemon/handlers/misc.ts +0 -1139
  765. package/src/daemon/handlers/navigate-settings.ts +0 -29
  766. package/src/daemon/handlers/oauth-connect.ts +0 -202
  767. package/src/daemon/handlers/open-bundle-handler.ts +0 -88
  768. package/src/daemon/handlers/publish.ts +0 -176
  769. package/src/daemon/handlers/signing.ts +0 -56
  770. package/src/daemon/handlers/subagents.ts +0 -286
  771. package/src/daemon/handlers/twitter-auth.ts +0 -220
  772. package/src/daemon/handlers/work-items.ts +0 -796
  773. package/src/daemon/handlers/workspace-files.ts +0 -84
  774. package/src/daemon/handlers.ts +0 -16
  775. package/src/daemon/ipc-blob-store.ts +0 -246
  776. package/src/daemon/ipc-contract-inventory.json +0 -348
  777. package/src/daemon/ipc-contract-inventory.ts +0 -202
  778. package/src/daemon/ipc-handler.ts +0 -120
  779. package/src/daemon/ipc-protocol.ts +0 -85
  780. package/src/daemon/ipc-validate.ts +0 -254
  781. package/src/memory/app-migration.ts +0 -114
  782. package/src/memory/channel-delivery-store.ts +0 -40
  783. package/src/memory/channel-guardian-store.ts +0 -83
  784. package/src/memory/conversation-store.ts +0 -102
  785. package/src/memory/schema-migration.ts +0 -38
  786. package/src/messaging/providers/sms/adapter.ts +0 -232
  787. package/src/messaging/providers/sms/client.ts +0 -93
  788. package/src/messaging/providers/sms/types.ts +0 -7
  789. package/src/migrations/config-merge.ts +0 -62
  790. package/src/migrations/data-layout.ts +0 -89
  791. package/src/migrations/data-merge.ts +0 -44
  792. package/src/migrations/hooks-merge.ts +0 -118
  793. package/src/migrations/index.ts +0 -6
  794. package/src/migrations/log.ts +0 -28
  795. package/src/migrations/skills-merge.ts +0 -44
  796. package/src/migrations/workspace-layout.ts +0 -94
  797. package/src/notifications/adapters/sms.ts +0 -94
  798. package/src/runtime/channel-approval-parser.ts +0 -123
  799. package/src/runtime/channel-invite-transports/sms.ts +0 -53
  800. package/src/runtime/routes/approval-strategies/guardian-legacy-fallback-strategy.ts +0 -82
  801. package/src/runtime/routes/integration-routes.ts +0 -381
  802. package/src/runtime/routes/twilio-routes.ts +0 -1251
  803. package/src/twitter/router.ts +0 -131
  804. package/src/twitter/session.ts +0 -54
  805. package/src/watcher/providers/slack.ts +0 -282
  806. /package/src/{amazon → cli/commands/amazon}/cart.ts +0 -0
  807. /package/src/{amazon → cli/commands/amazon}/checkout.ts +0 -0
  808. /package/src/{amazon → cli/commands/amazon}/product-details.ts +0 -0
  809. /package/src/{amazon → cli/commands/amazon}/search.ts +0 -0
  810. /package/src/{twitter → cli/commands/twitter}/oauth-client.ts +0 -0
  811. /package/src/config/{calls-schema.ts → schemas/calls.ts} +0 -0
  812. /package/src/config/{elevenlabs-schema.ts → schemas/elevenlabs.ts} +0 -0
  813. /package/src/config/{mcp-schema.ts → schemas/mcp.ts} +0 -0
  814. /package/src/config/{notifications-schema.ts → schemas/notifications.ts} +0 -0
  815. /package/src/config/{sandbox-schema.ts → schemas/sandbox.ts} +0 -0
  816. /package/src/config/{skills-schema.ts → schemas/skills.ts} +0 -0
  817. /package/src/daemon/{ipc-contract → message-types}/apps.ts +0 -0
  818. /package/src/daemon/{ipc-contract → message-types}/browser.ts +0 -0
  819. /package/src/daemon/{ipc-contract → message-types}/contacts.ts +0 -0
  820. /package/src/daemon/{ipc-contract → message-types}/documents.ts +0 -0
  821. /package/src/daemon/{ipc-contract → message-types}/guardian-actions.ts +0 -0
  822. /package/src/daemon/{ipc-contract → message-types}/inbox.ts +0 -0
  823. /package/src/daemon/{ipc-contract → message-types}/messages.ts +0 -0
  824. /package/src/daemon/{ipc-contract → message-types}/pairing.ts +0 -0
  825. /package/src/daemon/{ipc-contract → message-types}/schedules.ts +0 -0
  826. /package/src/daemon/{ipc-contract → message-types}/settings.ts +0 -0
  827. /package/src/daemon/{ipc-contract → message-types}/skills.ts +0 -0
  828. /package/src/daemon/{ipc-contract → message-types}/subagents.ts +0 -0
  829. /package/src/daemon/{ipc-contract → message-types}/surfaces.ts +0 -0
  830. /package/src/daemon/{ipc-contract → message-types}/trust.ts +0 -0
  831. /package/src/daemon/{ipc-contract → message-types}/work-items.ts +0 -0
  832. /package/src/{cli/email-guardrails.ts → email/guardrails.ts} +0 -0
  833. /package/src/{config → prompts}/__tests__/build-cli-reference-section.test.ts +0 -0
  834. /package/src/{config → prompts}/templates/BOOTSTRAP.md +0 -0
  835. /package/src/{config → prompts}/templates/IDENTITY.md +0 -0
  836. /package/src/{config → prompts}/templates/SOUL.md +0 -0
  837. /package/src/{config → prompts}/templates/UPDATES.md +0 -0
  838. /package/src/{config → prompts}/templates/USER.md +0 -0
  839. /package/src/{config → prompts}/update-bulletin-format.ts +0 -0
  840. /package/src/{config → prompts}/update-bulletin-state.ts +0 -0
  841. /package/src/{config → prompts}/update-bulletin-template-path.ts +0 -0
  842. /package/src/{config → prompts}/update-bulletin.ts +0 -0
  843. /package/src/{config → prompts}/user-reference.ts +0 -0
@@ -0,0 +1,813 @@
1
+ /**
2
+ * HTTP route handlers for diagnostics export and dictation processing.
3
+ *
4
+ * Migrated from IPC handlers:
5
+ * - handlers/diagnostics.ts (diagnostics_export_request)
6
+ * - handlers/dictation.ts (dictation_request)
7
+ */
8
+
9
+ import { randomBytes } from "node:crypto";
10
+ import { createWriteStream, mkdirSync, rmSync, writeFileSync } from "node:fs";
11
+ import { homedir, tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+
14
+ import archiver from "archiver";
15
+ import { and, desc, eq, gte, lte } from "drizzle-orm";
16
+
17
+ import {
18
+ type ProfileResolution,
19
+ resolveProfile,
20
+ } from "../../daemon/dictation-profile-store.js";
21
+ import {
22
+ applyDictionary,
23
+ expandSnippets,
24
+ } from "../../daemon/dictation-text-processing.js";
25
+ import { detectDictationModeHeuristic } from "../../daemon/handlers/dictation.js";
26
+ import type { DictationRequest } from "../../daemon/message-types/diagnostics.js";
27
+ import type { DictationContext } from "../../daemon/message-types/shared.js";
28
+ import { getDb } from "../../memory/db.js";
29
+ import {
30
+ llmRequestLogs,
31
+ llmUsageEvents,
32
+ messages,
33
+ toolInvocations,
34
+ } from "../../memory/schema.js";
35
+ import {
36
+ createTimeout,
37
+ extractToolUse,
38
+ getConfiguredProvider,
39
+ userMessage,
40
+ } from "../../providers/provider-send-message.js";
41
+ import { getLogger } from "../../util/logger.js";
42
+ import { httpError } from "../http-errors.js";
43
+ import type { RouteDefinition } from "../http-router.js";
44
+
45
+ const log = getLogger("diagnostics-routes");
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // Diagnostics export — redaction helpers (shared with IPC handler)
49
+ // ---------------------------------------------------------------------------
50
+
51
+ const MAX_CONTENT_LENGTH = 500;
52
+
53
+ const REDACT_PATTERNS = [
54
+ /\b(sk|key|api[_-]?key|token|secret|password|passwd|credential)[_\-]?[a-zA-Z0-9]{16,}\b/gi,
55
+ /Bearer\s+[A-Za-z0-9\-._~+\/]+=*/gi,
56
+ /[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g,
57
+ /\b(AKIA|ASIA)[A-Z0-9]{16}\b/g,
58
+ /\b[A-Fa-f0-9]{32,}\b/g,
59
+ ];
60
+
61
+ function redact(text: string): string {
62
+ let result = text;
63
+ for (const pattern of REDACT_PATTERNS) {
64
+ result = result.replace(pattern, "[REDACTED]");
65
+ }
66
+ return result;
67
+ }
68
+
69
+ function truncateAndRedact(text: string): string {
70
+ const truncated =
71
+ text.length > MAX_CONTENT_LENGTH
72
+ ? text.slice(0, MAX_CONTENT_LENGTH) + "...[truncated]"
73
+ : text;
74
+ return redact(truncated);
75
+ }
76
+
77
+ const SENSITIVE_KEYS = new Set([
78
+ "api_key",
79
+ "apikey",
80
+ "api-key",
81
+ "authorization",
82
+ "x-api-key",
83
+ "secret",
84
+ "password",
85
+ "token",
86
+ "credential",
87
+ "credentials",
88
+ ]);
89
+
90
+ function redactDeep(value: unknown): unknown {
91
+ if (typeof value === "string") return redact(value);
92
+ if (Array.isArray(value)) return value.map(redactDeep);
93
+ if (value != null && typeof value === "object") {
94
+ const out: Record<string, unknown> = {};
95
+ for (const [k, v] of Object.entries(value as Record<string, unknown>)) {
96
+ if (SENSITIVE_KEYS.has(k.toLowerCase())) {
97
+ out[k] = "[REDACTED]";
98
+ } else {
99
+ out[k] = redactDeep(v);
100
+ }
101
+ }
102
+ return out;
103
+ }
104
+ return value;
105
+ }
106
+
107
+ // ---------------------------------------------------------------------------
108
+ // Diagnostics export handler
109
+ // ---------------------------------------------------------------------------
110
+
111
+ async function handleDiagnosticsExport(body: {
112
+ conversationId?: string;
113
+ anchorMessageId?: string;
114
+ }): Promise<Response> {
115
+ if (!body.conversationId) {
116
+ return httpError("BAD_REQUEST", "conversationId is required", 400);
117
+ }
118
+
119
+ const { conversationId, anchorMessageId } = body;
120
+
121
+ try {
122
+ const db = getDb();
123
+
124
+ // 1. Find the anchor message
125
+ let anchorMessage;
126
+ if (anchorMessageId) {
127
+ anchorMessage = db
128
+ .select()
129
+ .from(messages)
130
+ .where(
131
+ and(
132
+ eq(messages.id, anchorMessageId),
133
+ eq(messages.conversationId, conversationId),
134
+ ),
135
+ )
136
+ .get();
137
+ } else {
138
+ anchorMessage = db
139
+ .select()
140
+ .from(messages)
141
+ .where(
142
+ and(
143
+ eq(messages.conversationId, conversationId),
144
+ eq(messages.role, "assistant"),
145
+ ),
146
+ )
147
+ .orderBy(desc(messages.createdAt))
148
+ .limit(1)
149
+ .get();
150
+ }
151
+
152
+ if (!anchorMessage) {
153
+ return httpError("NOT_FOUND", "Anchor message not found", 404);
154
+ }
155
+
156
+ // 2. Find the preceding user message
157
+ const precedingUserMessage = db
158
+ .select()
159
+ .from(messages)
160
+ .where(
161
+ and(
162
+ eq(messages.conversationId, conversationId),
163
+ eq(messages.role, "user"),
164
+ lte(messages.createdAt, anchorMessage.createdAt),
165
+ ),
166
+ )
167
+ .orderBy(desc(messages.createdAt))
168
+ .limit(1)
169
+ .get();
170
+
171
+ const rangeStart =
172
+ precedingUserMessage?.createdAt ?? anchorMessage.createdAt - 2000;
173
+ const rangeEnd = anchorMessage.createdAt;
174
+ const usageRangeEnd = anchorMessage.createdAt + 5000;
175
+
176
+ // 3. Query all messages in the range
177
+ const rangeMessages = db
178
+ .select()
179
+ .from(messages)
180
+ .where(
181
+ and(
182
+ eq(messages.conversationId, conversationId),
183
+ gte(messages.createdAt, rangeStart),
184
+ lte(messages.createdAt, rangeEnd),
185
+ ),
186
+ )
187
+ .orderBy(messages.createdAt)
188
+ .all();
189
+
190
+ // 4. Query tool invocations in the range
191
+ const rangeToolInvocations = db
192
+ .select()
193
+ .from(toolInvocations)
194
+ .where(
195
+ and(
196
+ eq(toolInvocations.conversationId, conversationId),
197
+ gte(toolInvocations.createdAt, rangeStart),
198
+ lte(toolInvocations.createdAt, rangeEnd),
199
+ ),
200
+ )
201
+ .orderBy(toolInvocations.createdAt)
202
+ .all();
203
+
204
+ // 5. Query LLM usage events
205
+ const rangeUsageEvents = db
206
+ .select()
207
+ .from(llmUsageEvents)
208
+ .where(
209
+ and(
210
+ eq(llmUsageEvents.conversationId, conversationId),
211
+ gte(llmUsageEvents.createdAt, rangeStart),
212
+ lte(llmUsageEvents.createdAt, usageRangeEnd),
213
+ ),
214
+ )
215
+ .orderBy(llmUsageEvents.createdAt)
216
+ .all();
217
+
218
+ // 5b. Query raw LLM request/response logs
219
+ const rangeRequestLogs = db
220
+ .select()
221
+ .from(llmRequestLogs)
222
+ .where(
223
+ and(
224
+ eq(llmRequestLogs.conversationId, conversationId),
225
+ gte(llmRequestLogs.createdAt, rangeStart),
226
+ lte(llmRequestLogs.createdAt, usageRangeEnd),
227
+ ),
228
+ )
229
+ .orderBy(llmRequestLogs.createdAt)
230
+ .all();
231
+
232
+ // 6. Write export files to a temp directory
233
+ const exportId = `diagnostics-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(4).toString("hex")}`;
234
+ const tempDir = join(tmpdir(), exportId);
235
+ mkdirSync(tempDir, { recursive: true });
236
+
237
+ try {
238
+ const manifest = {
239
+ version: "1.1",
240
+ exportedAt: new Date().toISOString(),
241
+ conversationId,
242
+ messageId: anchorMessage.id,
243
+ };
244
+ writeFileSync(
245
+ join(tempDir, "manifest.json"),
246
+ JSON.stringify(manifest, null, 2),
247
+ );
248
+
249
+ const messagesLines = rangeMessages.map((m) =>
250
+ JSON.stringify({
251
+ id: m.id,
252
+ conversationId: m.conversationId,
253
+ role: m.role,
254
+ content: truncateAndRedact(m.content),
255
+ createdAt: m.createdAt,
256
+ }),
257
+ );
258
+ writeFileSync(
259
+ join(tempDir, "messages.jsonl"),
260
+ messagesLines.join("\n") + (messagesLines.length > 0 ? "\n" : ""),
261
+ );
262
+
263
+ const toolLines = rangeToolInvocations.map((t) =>
264
+ JSON.stringify({
265
+ id: t.id,
266
+ conversationId: t.conversationId,
267
+ toolName: t.toolName,
268
+ input: truncateAndRedact(t.input),
269
+ result: truncateAndRedact(t.result),
270
+ decision: t.decision,
271
+ riskLevel: t.riskLevel,
272
+ durationMs: t.durationMs,
273
+ createdAt: t.createdAt,
274
+ }),
275
+ );
276
+ writeFileSync(
277
+ join(tempDir, "tool_invocations.jsonl"),
278
+ toolLines.join("\n") + (toolLines.length > 0 ? "\n" : ""),
279
+ );
280
+
281
+ const usageLines = rangeUsageEvents.map((u) =>
282
+ JSON.stringify({
283
+ id: u.id,
284
+ conversationId: u.conversationId,
285
+ actor: u.actor,
286
+ provider: u.provider,
287
+ model: u.model,
288
+ inputTokens: u.inputTokens,
289
+ outputTokens: u.outputTokens,
290
+ cacheCreationInputTokens: u.cacheCreationInputTokens,
291
+ cacheReadInputTokens: u.cacheReadInputTokens,
292
+ estimatedCostUsd: u.estimatedCostUsd,
293
+ pricingStatus: u.pricingStatus,
294
+ createdAt: u.createdAt,
295
+ }),
296
+ );
297
+ writeFileSync(
298
+ join(tempDir, "usage.jsonl"),
299
+ usageLines.join("\n") + (usageLines.length > 0 ? "\n" : ""),
300
+ );
301
+
302
+ const requestLogLines = rangeRequestLogs.map((r) => {
303
+ let request: unknown;
304
+ let response: unknown;
305
+ try {
306
+ request = JSON.parse(r.requestPayload);
307
+ } catch {
308
+ request = r.requestPayload;
309
+ }
310
+ try {
311
+ response = JSON.parse(r.responsePayload);
312
+ } catch {
313
+ response = r.responsePayload;
314
+ }
315
+ return JSON.stringify({
316
+ id: r.id,
317
+ conversationId: r.conversationId,
318
+ request: redactDeep(request),
319
+ response: redactDeep(response),
320
+ createdAt: r.createdAt,
321
+ });
322
+ });
323
+ writeFileSync(
324
+ join(tempDir, "llm_requests.jsonl"),
325
+ requestLogLines.join("\n") + (requestLogLines.length > 0 ? "\n" : ""),
326
+ );
327
+
328
+ // 7. Zip the temp directory
329
+ const downloadsDir = join(homedir(), "Downloads");
330
+ mkdirSync(downloadsDir, { recursive: true });
331
+ const zipFilename = `${exportId}.zip`;
332
+ const zipPath = join(downloadsDir, zipFilename);
333
+
334
+ await new Promise<void>((resolve, reject) => {
335
+ const output = createWriteStream(zipPath);
336
+ const archive = archiver("zip", { zlib: { level: 9 } });
337
+
338
+ output.on("close", () => resolve());
339
+ output.on("error", (err: Error) => reject(err));
340
+ archive.on("error", (err: Error) => reject(err));
341
+ archive.on("warning", (err: Error) => {
342
+ log.warn({ err }, "Archiver warning during diagnostics export");
343
+ });
344
+
345
+ archive.pipe(output);
346
+ archive.directory(tempDir, false);
347
+ archive.finalize();
348
+ });
349
+
350
+ log.info(
351
+ { conversationId, zipPath, messageCount: rangeMessages.length },
352
+ "Diagnostics export completed via HTTP",
353
+ );
354
+
355
+ return Response.json({ ok: true, filePath: zipPath });
356
+ } finally {
357
+ try {
358
+ rmSync(tempDir, { recursive: true, force: true });
359
+ } catch {
360
+ // Best-effort cleanup
361
+ }
362
+ }
363
+ } catch (err) {
364
+ const errorMessage = err instanceof Error ? err.message : String(err);
365
+ log.error({ err, conversationId }, "Failed to export diagnostics");
366
+ return httpError(
367
+ "INTERNAL_ERROR",
368
+ `Failed to export diagnostics: ${errorMessage}`,
369
+ 500,
370
+ );
371
+ }
372
+ }
373
+
374
+ // ---------------------------------------------------------------------------
375
+ // Dictation
376
+ // ---------------------------------------------------------------------------
377
+
378
+ type DictationMode = "dictation" | "command" | "action";
379
+
380
+ const DICTATION_CLASSIFICATION_TIMEOUT_MS = 5000;
381
+ const MAX_WINDOW_TITLE_LENGTH = 100;
382
+
383
+ function sanitizeWindowTitle(title: string | undefined): string {
384
+ if (!title) return "";
385
+ return title
386
+ .replace(/[<>]/g, "")
387
+ .slice(0, MAX_WINDOW_TITLE_LENGTH);
388
+ }
389
+
390
+ interface DictationBody {
391
+ transcription: string;
392
+ context: DictationContext;
393
+ profileId?: string;
394
+ }
395
+
396
+ function buildAppMetadataBlock(context: DictationContext): string {
397
+ const windowTitle = sanitizeWindowTitle(context.windowTitle);
398
+ return [
399
+ "<app_metadata>",
400
+ `App: ${context.appName} (${context.bundleIdentifier})`,
401
+ `Window: ${windowTitle}`,
402
+ "</app_metadata>",
403
+ ].join("\n");
404
+ }
405
+
406
+ function buildCombinedDictationPrompt(
407
+ body: DictationBody,
408
+ stylePrompt?: string,
409
+ ): string {
410
+ const sections = [
411
+ "You are a voice input assistant. You will receive a speech transcription and must:",
412
+ '1. Classify it as "dictation" (text to insert) or "action" (task for an assistant to execute)',
413
+ "2. If dictation, clean up the text. If action, return the raw transcription.",
414
+ "",
415
+ "## Classification",
416
+ 'DICTATION examples: "Hey how are you doing", "I think we should move forward with the proposal", "Dear team comma please review the attached document"',
417
+ 'ACTION examples: "Message Aaron on Slack saying hey what\'s up", "Send an email to the team about the meeting", "Open Spotify and play my playlist", "Search for flights to Denver", "Create a new document in Google Docs"',
418
+ "",
419
+ "Key signals for ACTION: the user is addressing an assistant and asking it to DO something (send, message, open, search, create, schedule, etc.)",
420
+ "Key signals for DICTATION: the user is composing text content that should be typed out as-is",
421
+ `Cursor in text field: ${body.context.cursorInTextField ? "yes" : "no"} -- if yes, lean toward dictation unless the intent to command is clear.`,
422
+ "",
423
+ "## Cleanup Rules (for dictation mode only)",
424
+ "- Fix grammar, punctuation, and capitalization",
425
+ "- Remove filler words (um, uh, like, you know)",
426
+ '- Rewrite vague or hedging language ("so yeah probably", "I guess maybe") into clear, confident statements',
427
+ "- Maintain the speaker's intent and meaning",
428
+ ];
429
+
430
+ if (stylePrompt) {
431
+ sections.push(
432
+ "",
433
+ "## User Style (HIGHEST PRIORITY)",
434
+ "The user has configured these style preferences. They OVERRIDE the default tone adaptation below.",
435
+ "Follow these instructions precisely -- they reflect the user's personal writing voice and preferences.",
436
+ "",
437
+ stylePrompt,
438
+ );
439
+ }
440
+
441
+ sections.push("", "## Tone Adaptation");
442
+
443
+ if (stylePrompt) {
444
+ sections.push(
445
+ "Use these as fallback guidance only when the User Style above does not cover a specific aspect:",
446
+ );
447
+ } else {
448
+ sections.push("Adapt your output tone based on the active application:");
449
+ }
450
+
451
+ sections.push(
452
+ "- Email apps (Gmail, Mail): Professional but warm. Use proper greetings and sign-offs if appropriate.",
453
+ "- Slack: Casual and conversational. Match typical chat style.",
454
+ "- Code editors (VS Code, Xcode): Technical and concise. Code comments style.",
455
+ "- Terminal: Command-like, terse.",
456
+ "- Messages/iMessage: Very casual, texting style. Short sentences.",
457
+ "- Notes/Docs: Neutral, clear writing.",
458
+ "- Default: Match the user's natural voice.",
459
+ "",
460
+ "## Context Clues",
461
+ "- Window title may contain recipient name (Slack DMs, email compose)",
462
+ "- If you can identify a recipient, adapt formality to the apparent relationship",
463
+ "- Maintain the user's natural voice -- don't over-formalize casual speech",
464
+ "- The user's writing patterns and preferences may be available from memory context -- follow those when present",
465
+ "",
466
+ buildAppMetadataBlock(body.context),
467
+ );
468
+
469
+ return sections.join("\n");
470
+ }
471
+
472
+ function buildCommandPrompt(
473
+ body: DictationBody,
474
+ stylePrompt?: string,
475
+ ): string {
476
+ const sections = [
477
+ "You are a text transformation assistant. The user has selected text and given a voice command to transform it.",
478
+ "",
479
+ "## Rules",
480
+ "- Apply the instruction to the selected text",
481
+ "- Return ONLY the transformed text, nothing else",
482
+ "- Do NOT add explanations or commentary",
483
+ ];
484
+
485
+ if (stylePrompt) {
486
+ sections.push(
487
+ "",
488
+ "## User Style (HIGHEST PRIORITY)",
489
+ "The user has configured these style preferences. They OVERRIDE the default tone adaptation below.",
490
+ "Follow these instructions precisely -- they reflect the user's personal writing voice and preferences.",
491
+ "",
492
+ stylePrompt,
493
+ );
494
+ }
495
+
496
+ sections.push("", "## Tone Adaptation");
497
+
498
+ if (stylePrompt) {
499
+ sections.push(
500
+ "Use these as fallback guidance only when the User Style above does not cover a specific aspect:",
501
+ );
502
+ } else {
503
+ sections.push("Match the tone to the active application context:");
504
+ }
505
+
506
+ sections.push(
507
+ "- Email apps (Gmail, Mail): Professional but warm.",
508
+ "- Slack: Casual and conversational.",
509
+ "- Code editors (VS Code, Xcode): Technical and concise.",
510
+ "- Terminal: Command-like, terse.",
511
+ "- Messages/iMessage: Very casual, texting style.",
512
+ "- Notes/Docs: Neutral, clear writing.",
513
+ "- Default: Match the user's natural voice.",
514
+ "",
515
+ "## Context Clues",
516
+ "- Window title may contain recipient name (Slack DMs, email compose)",
517
+ "- If you can identify a recipient, adapt formality to the apparent relationship",
518
+ "- Maintain the user's natural voice -- don't over-formalize casual speech",
519
+ "- The user's writing patterns and preferences may be available from memory context -- follow those when present",
520
+ "",
521
+ buildAppMetadataBlock(body.context),
522
+ "",
523
+ "Selected text:",
524
+ body.context.selectedText ?? "",
525
+ "",
526
+ `Instruction: ${body.transcription}`,
527
+ );
528
+
529
+ return sections.join("\n");
530
+ }
531
+
532
+ function computeMaxTokens(inputLength: number): number {
533
+ const estimatedInputTokens = Math.ceil(inputLength / 3);
534
+ return Math.max(256, estimatedInputTokens + 128);
535
+ }
536
+
537
+ async function handleDictation(body: DictationBody): Promise<Response> {
538
+ log.info(
539
+ { transcriptionLength: body.transcription.length },
540
+ "Dictation request received via HTTP",
541
+ );
542
+
543
+ const resolution = resolveProfile(
544
+ body.context.bundleIdentifier,
545
+ body.context.appName,
546
+ body.profileId,
547
+ );
548
+ const { profile, source: profileSource } = resolution;
549
+ log.info(
550
+ { profileId: profile.id, profileSource },
551
+ "Resolved dictation profile",
552
+ );
553
+
554
+ const profileMeta = {
555
+ resolvedProfileId: profile.id,
556
+ profileSource,
557
+ };
558
+
559
+ const stylePrompt = profile.stylePrompt || undefined;
560
+
561
+ // Command mode: selected text present
562
+ if (body.context.selectedText && body.context.selectedText.trim().length > 0) {
563
+ log.info({ mode: "command" }, "Command mode (selected text present)");
564
+ return handleCommandMode(body, profile, profileMeta, stylePrompt);
565
+ }
566
+
567
+ // Non-command: single LLM call that classifies AND cleans in one shot
568
+ const transcription = expandSnippets(body.transcription, profile.snippets);
569
+
570
+ try {
571
+ const provider = getConfiguredProvider();
572
+ if (!provider) {
573
+ log.warn(
574
+ "Dictation: no provider available, using heuristic + raw transcription",
575
+ );
576
+ // Build an IPC-compatible msg for the heuristic
577
+ const mode = detectDictationModeHeuristic({
578
+ type: "dictation_request",
579
+ transcription: body.transcription,
580
+ context: body.context,
581
+ } as DictationRequest);
582
+ const normalizedText = applyDictionary(transcription, profile.dictionary);
583
+ if (mode === "action") {
584
+ return Response.json({
585
+ text: body.transcription,
586
+ mode: "action",
587
+ actionPlan: `User wants to: ${body.transcription}`,
588
+ ...profileMeta,
589
+ });
590
+ }
591
+ return Response.json({
592
+ text: normalizedText,
593
+ mode,
594
+ ...profileMeta,
595
+ });
596
+ }
597
+
598
+ const systemPrompt = buildCombinedDictationPrompt(body, stylePrompt);
599
+ const maxTokens = computeMaxTokens(transcription.length);
600
+ const { signal, cleanup } = createTimeout(
601
+ DICTATION_CLASSIFICATION_TIMEOUT_MS,
602
+ );
603
+
604
+ try {
605
+ const response = await provider.sendMessage(
606
+ [userMessage(`Transcription: "${transcription}"`)],
607
+ [
608
+ {
609
+ name: "process_dictation",
610
+ description: "Classify the voice input and return cleaned text",
611
+ input_schema: {
612
+ type: "object" as const,
613
+ properties: {
614
+ mode: {
615
+ type: "string",
616
+ enum: ["dictation", "action"],
617
+ description:
618
+ "dictation = user wants text inserted/cleaned up for typing. action = user wants the assistant to perform a task.",
619
+ },
620
+ text: {
621
+ type: "string",
622
+ description:
623
+ "If dictation: the cleaned/formatted text ready for insertion. If action: the raw transcription unchanged.",
624
+ },
625
+ reasoning: {
626
+ type: "string",
627
+ description: "Brief reasoning for the classification",
628
+ },
629
+ },
630
+ required: ["mode", "text", "reasoning"],
631
+ },
632
+ },
633
+ ],
634
+ systemPrompt,
635
+ {
636
+ config: {
637
+ modelIntent: "latency-optimized",
638
+ max_tokens: maxTokens,
639
+ tool_choice: {
640
+ type: "tool" as const,
641
+ name: "process_dictation",
642
+ },
643
+ },
644
+ signal,
645
+ },
646
+ );
647
+ cleanup();
648
+
649
+ const toolBlock = extractToolUse(response);
650
+ if (toolBlock) {
651
+ const input = toolBlock.input as {
652
+ mode?: string;
653
+ text?: string;
654
+ reasoning?: string;
655
+ };
656
+ const mode: DictationMode =
657
+ input.mode === "action" ? "action" : "dictation";
658
+ log.info(
659
+ { mode, reasoning: input.reasoning },
660
+ "LLM dictation classify+clean",
661
+ );
662
+
663
+ if (mode === "action") {
664
+ return Response.json({
665
+ text: body.transcription,
666
+ mode: "action",
667
+ actionPlan: `User wants to: ${body.transcription}`,
668
+ ...profileMeta,
669
+ });
670
+ }
671
+ const cleanedText = input.text?.trim() || transcription;
672
+ const normalizedText = applyDictionary(
673
+ cleanedText,
674
+ profile.dictionary,
675
+ );
676
+ return Response.json({
677
+ text: normalizedText,
678
+ mode: "dictation",
679
+ ...profileMeta,
680
+ });
681
+ }
682
+
683
+ log.warn("No tool_use block in combined dictation call, using heuristic");
684
+ } finally {
685
+ cleanup();
686
+ }
687
+ } catch (err) {
688
+ const message = err instanceof Error ? err.message : String(err);
689
+ log.warn(
690
+ { err: message },
691
+ "Combined dictation LLM call failed, using heuristic",
692
+ );
693
+ }
694
+
695
+ // Heuristic fallback
696
+ const fallbackMode = detectDictationModeHeuristic({
697
+ type: "dictation_request",
698
+ transcription: body.transcription,
699
+ context: body.context,
700
+ } as DictationRequest);
701
+ log.info({ mode: fallbackMode }, "Using heuristic fallback");
702
+ if (fallbackMode === "action") {
703
+ return Response.json({
704
+ text: body.transcription,
705
+ mode: "action",
706
+ actionPlan: `User wants to: ${body.transcription}`,
707
+ ...profileMeta,
708
+ });
709
+ }
710
+ const normalizedText = applyDictionary(transcription, profile.dictionary);
711
+ return Response.json({
712
+ text: normalizedText,
713
+ mode: fallbackMode,
714
+ ...profileMeta,
715
+ });
716
+ }
717
+
718
+ async function handleCommandMode(
719
+ body: DictationBody,
720
+ profile: ReturnType<typeof resolveProfile>["profile"],
721
+ profileMeta: {
722
+ resolvedProfileId: string;
723
+ profileSource: ProfileResolution["source"];
724
+ },
725
+ stylePrompt: string | undefined,
726
+ ): Promise<Response> {
727
+ const systemPrompt = buildCommandPrompt(body, stylePrompt);
728
+ const inputLength =
729
+ (body.context.selectedText ?? "").length + body.transcription.length;
730
+ const maxTokens = Math.max(1024, computeMaxTokens(inputLength));
731
+
732
+ try {
733
+ const provider = getConfiguredProvider();
734
+ if (!provider) {
735
+ log.warn("Command mode: no provider available, returning selected text");
736
+ const normalizedText = applyDictionary(
737
+ body.context.selectedText ?? body.transcription,
738
+ profile.dictionary,
739
+ );
740
+ return Response.json({
741
+ text: normalizedText,
742
+ mode: "command",
743
+ ...profileMeta,
744
+ });
745
+ }
746
+
747
+ const response = await provider.sendMessage(
748
+ [userMessage(body.transcription)],
749
+ [],
750
+ systemPrompt,
751
+ { config: { modelIntent: "latency-optimized", max_tokens: maxTokens } },
752
+ );
753
+
754
+ const textBlock = response.content.find((b) => b.type === "text");
755
+ const cleanedText =
756
+ textBlock && "text" in textBlock
757
+ ? textBlock.text.trim()
758
+ : (body.context.selectedText ?? body.transcription);
759
+ const normalizedText = applyDictionary(cleanedText, profile.dictionary);
760
+ return Response.json({
761
+ text: normalizedText,
762
+ mode: "command",
763
+ ...profileMeta,
764
+ });
765
+ } catch (err) {
766
+ log.error({ err }, "Command mode LLM call failed, returning selected text");
767
+ const normalizedText = applyDictionary(
768
+ body.context.selectedText ?? body.transcription,
769
+ profile.dictionary,
770
+ );
771
+ return Response.json({
772
+ text: normalizedText,
773
+ mode: "command",
774
+ ...profileMeta,
775
+ });
776
+ }
777
+ }
778
+
779
+ // ---------------------------------------------------------------------------
780
+ // Route definitions
781
+ // ---------------------------------------------------------------------------
782
+
783
+ export function diagnosticsRouteDefinitions(): RouteDefinition[] {
784
+ return [
785
+ {
786
+ endpoint: "diagnostics/export",
787
+ method: "POST",
788
+ policyKey: "diagnostics/export",
789
+ handler: async ({ req }) => {
790
+ const body = (await req.json()) as {
791
+ conversationId?: string;
792
+ anchorMessageId?: string;
793
+ };
794
+ return handleDiagnosticsExport(body);
795
+ },
796
+ },
797
+ {
798
+ endpoint: "dictation",
799
+ method: "POST",
800
+ policyKey: "dictation",
801
+ handler: async ({ req }) => {
802
+ const body = (await req.json()) as DictationBody;
803
+ if (!body.transcription) {
804
+ return httpError("BAD_REQUEST", "transcription is required", 400);
805
+ }
806
+ if (!body.context) {
807
+ return httpError("BAD_REQUEST", "context is required", 400);
808
+ }
809
+ return handleDictation(body);
810
+ },
811
+ },
812
+ ];
813
+ }