@vellumai/assistant 0.7.3 → 0.8.1

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 (778) hide show
  1. package/AGENTS.md +11 -0
  2. package/ARCHITECTURE.md +29 -28
  3. package/Dockerfile +6 -4
  4. package/README.md +2 -2
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  6. package/bun.lock +3 -0
  7. package/docker-entrypoint.sh +16 -0
  8. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  9. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  10. package/eslint.config.mjs +12 -0
  11. package/knip.json +3 -1
  12. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  13. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  14. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  15. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  16. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  17. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  19. package/openapi.yaml +4126 -959
  20. package/package.json +5 -1
  21. package/scripts/generate-openapi.ts +52 -4
  22. package/scripts/sync-llm-catalog.ts +165 -0
  23. package/scripts/sync-web-search-catalog.ts +107 -0
  24. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  25. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  26. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  27. package/src/__tests__/anthropic-provider.test.ts +92 -2
  28. package/src/__tests__/app-control-flow.test.ts +7 -0
  29. package/src/__tests__/approval-cascade.test.ts +8 -16
  30. package/src/__tests__/approval-routes-http.test.ts +6 -0
  31. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  32. package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
  33. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  34. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  35. package/src/__tests__/btw-routes.test.ts +1 -0
  36. package/src/__tests__/call-constants.test.ts +10 -1
  37. package/src/__tests__/call-controller.test.ts +127 -0
  38. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  39. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  40. package/src/__tests__/channel-policy.test.ts +12 -0
  41. package/src/__tests__/checker.test.ts +89 -0
  42. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
  43. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  44. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  45. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  46. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
  48. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  49. package/src/__tests__/config-schema.test.ts +14 -3
  50. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  51. package/src/__tests__/config-set-route.test.ts +198 -0
  52. package/src/__tests__/config-watcher.test.ts +6 -0
  53. package/src/__tests__/contacts-tools.test.ts +51 -199
  54. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  55. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  56. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  57. package/src/__tests__/context-search-fanout.test.ts +20 -157
  58. package/src/__tests__/context-search-memory-source.test.ts +3 -26
  59. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  60. package/src/__tests__/context-search-types.test.ts +7 -2
  61. package/src/__tests__/context-window-manager.test.ts +389 -1
  62. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
  63. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  64. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
  65. package/src/__tests__/conversation-agent-loop.test.ts +3 -3
  66. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  67. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  68. package/src/__tests__/conversation-error.test.ts +38 -0
  69. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  70. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  71. package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
  72. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  74. package/src/__tests__/conversation-process-callsite.test.ts +22 -7
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
  76. package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
  77. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  78. package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
  79. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  80. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  81. package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
  82. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
  83. package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
  84. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
  85. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  86. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  87. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  88. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  89. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  90. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  91. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  92. package/src/__tests__/filing-service.test.ts +25 -22
  93. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  94. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  95. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  96. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
  97. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  98. package/src/__tests__/heartbeat-service.test.ts +50 -233
  99. package/src/__tests__/history-repair.test.ts +89 -0
  100. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  101. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  102. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  103. package/src/__tests__/host-browser-routes.test.ts +325 -33
  104. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  105. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  106. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  107. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  108. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  109. package/src/__tests__/injector-chain.test.ts +24 -16
  110. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  111. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  112. package/src/__tests__/install-skill-routing.test.ts +2 -2
  113. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
  114. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  115. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  116. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  117. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  118. package/src/__tests__/llm-resolver.test.ts +46 -0
  119. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  120. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  121. package/src/__tests__/mcp-cli.test.ts +182 -220
  122. package/src/__tests__/mcp-health-check.test.ts +56 -27
  123. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  124. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  125. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  126. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  127. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  128. package/src/__tests__/oauth-cli.test.ts +38 -1888
  129. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  130. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  131. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  132. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  133. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  134. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  135. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  136. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  137. package/src/__tests__/plugin-types.test.ts +13 -11
  138. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  139. package/src/__tests__/profile-entry-status.test.ts +43 -0
  140. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  141. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  142. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  143. package/src/__tests__/relay-server.test.ts +164 -2
  144. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  145. package/src/__tests__/schedule-retry.test.ts +56 -4
  146. package/src/__tests__/schedule-routes.test.ts +104 -0
  147. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  148. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  149. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  150. package/src/__tests__/scheduler-wake.test.ts +0 -63
  151. package/src/__tests__/secret-allowlist.test.ts +1 -0
  152. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  153. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  154. package/src/__tests__/secret-response-routing.test.ts +7 -5
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  156. package/src/__tests__/server-history-render.test.ts +82 -0
  157. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  158. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  159. package/src/__tests__/skill-include-graph.test.ts +31 -0
  160. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  161. package/src/__tests__/skill-load-tool.test.ts +42 -16
  162. package/src/__tests__/skills.test.ts +39 -0
  163. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  164. package/src/__tests__/suggestion-routes.test.ts +3 -3
  165. package/src/__tests__/sync-message-contract.test.ts +63 -0
  166. package/src/__tests__/task-scheduler.test.ts +88 -23
  167. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  168. package/src/__tests__/tool-executor.test.ts +155 -0
  169. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  170. package/src/__tests__/usage-cli.test.ts +11 -73
  171. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  172. package/src/__tests__/vercel-config.test.ts +168 -0
  173. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  174. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  175. package/src/__tests__/web-search.test.ts +303 -2
  176. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  177. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  178. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
  179. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  180. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  181. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  182. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  183. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  184. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  185. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  186. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  187. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
  188. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  189. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  190. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  191. package/src/acp/resolve-agent.test.ts +25 -0
  192. package/src/acp/resolve-agent.ts +13 -2
  193. package/src/acp/session-manager.ts +14 -0
  194. package/src/agent/loop.ts +11 -0
  195. package/src/approvals/guardian-decision-primitive.ts +0 -13
  196. package/src/approvals/guardian-request-resolvers.ts +19 -102
  197. package/src/calls/call-constants.ts +5 -8
  198. package/src/calls/call-controller.ts +130 -67
  199. package/src/calls/relay-server.ts +42 -1
  200. package/src/calls/relay-setup-router.ts +36 -0
  201. package/src/calls/types.ts +1 -0
  202. package/src/calls/voice-session-bridge.ts +24 -5
  203. package/src/channels/config.ts +14 -1
  204. package/src/channels/types.ts +1 -0
  205. package/src/cli/AGENTS.md +164 -4
  206. package/src/cli/__tests__/notifications.test.ts +54 -0
  207. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  208. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  209. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  210. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  211. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  212. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  213. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  214. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  215. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  216. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  217. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  218. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  219. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  220. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  221. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  222. package/src/cli/commands/__tests__/status.test.ts +249 -0
  223. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  224. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  225. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  226. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  227. package/src/cli/commands/attachment.ts +8 -3
  228. package/src/cli/commands/audit.ts +95 -64
  229. package/src/cli/commands/auth.ts +61 -58
  230. package/src/cli/commands/avatar.ts +276 -390
  231. package/src/cli/commands/backup.ts +409 -505
  232. package/src/cli/commands/bash.ts +9 -5
  233. package/src/cli/commands/browser.ts +28 -9
  234. package/src/cli/commands/cache.ts +9 -4
  235. package/src/cli/commands/changelog.ts +414 -0
  236. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  237. package/src/cli/commands/clients.ts +8 -3
  238. package/src/cli/commands/completions.ts +9 -9
  239. package/src/cli/commands/config.ts +102 -72
  240. package/src/cli/commands/contacts.ts +575 -696
  241. package/src/cli/commands/conversations-defer.ts +17 -69
  242. package/src/cli/commands/conversations-import.ts +90 -253
  243. package/src/cli/commands/conversations.ts +346 -436
  244. package/src/cli/commands/credential-execution.ts +9 -6
  245. package/src/cli/commands/credentials.ts +456 -736
  246. package/src/cli/commands/domain.ts +128 -206
  247. package/src/cli/commands/email.ts +606 -794
  248. package/src/cli/commands/gateway.ts +8 -1
  249. package/src/cli/commands/image-generation.ts +157 -205
  250. package/src/cli/commands/inference-providers.ts +352 -0
  251. package/src/cli/commands/inference-session.ts +415 -0
  252. package/src/cli/commands/inference.ts +87 -65
  253. package/src/cli/commands/keys.ts +8 -3
  254. package/src/cli/commands/mcp.ts +103 -287
  255. package/src/cli/commands/memory-v2.ts +163 -517
  256. package/src/cli/commands/notifications.ts +33 -7
  257. package/src/cli/commands/oauth/apps.ts +292 -261
  258. package/src/cli/commands/oauth/connect.ts +182 -345
  259. package/src/cli/commands/oauth/disconnect.ts +16 -215
  260. package/src/cli/commands/oauth/index.ts +49 -45
  261. package/src/cli/commands/oauth/mode.ts +43 -199
  262. package/src/cli/commands/oauth/ping.ts +17 -125
  263. package/src/cli/commands/oauth/providers.ts +732 -921
  264. package/src/cli/commands/oauth/request.ts +60 -350
  265. package/src/cli/commands/oauth/shared.ts +11 -121
  266. package/src/cli/commands/oauth/status.ts +31 -121
  267. package/src/cli/commands/oauth/token.ts +13 -55
  268. package/src/cli/commands/pending.ts +19 -10
  269. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  270. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  271. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  272. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  273. package/src/cli/commands/platform/connect.ts +16 -80
  274. package/src/cli/commands/platform/disconnect.ts +14 -112
  275. package/src/cli/commands/platform/index.ts +177 -246
  276. package/src/cli/commands/routes.ts +153 -336
  277. package/src/cli/commands/sequence.ts +316 -360
  278. package/src/cli/commands/skills.ts +449 -671
  279. package/src/cli/commands/status.ts +58 -37
  280. package/src/cli/commands/stt.ts +94 -262
  281. package/src/cli/commands/task.ts +14 -40
  282. package/src/cli/commands/trust.ts +8 -3
  283. package/src/cli/commands/tts.ts +162 -167
  284. package/src/cli/commands/ui.ts +35 -42
  285. package/src/cli/commands/usage.ts +188 -126
  286. package/src/cli/commands/watchers.ts +8 -3
  287. package/src/cli/commands/webhooks.ts +99 -193
  288. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  289. package/src/cli/lib/daemon-credential-client.ts +4 -5
  290. package/src/cli/lib/nested-value.ts +44 -0
  291. package/src/cli/lib/open-browser.ts +36 -0
  292. package/src/cli/lib/register-command.ts +19 -0
  293. package/src/cli/lib/time-ago.ts +34 -0
  294. package/src/cli/program.ts +2 -4
  295. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  296. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  297. package/src/cli/utils/conversation-id.ts +30 -0
  298. package/src/cli/utils/parse-duration.ts +41 -0
  299. package/src/config/acp-defaults.test.ts +5 -1
  300. package/src/config/acp-defaults.ts +11 -4
  301. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  302. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  303. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  304. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  305. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  306. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  307. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  308. package/src/config/bundled-tool-registry.ts +0 -2
  309. package/src/config/feature-flag-registry.json +17 -17
  310. package/src/config/llm-resolver.ts +16 -1
  311. package/src/config/loader.ts +148 -33
  312. package/src/config/raw-config-utils.ts +2 -30
  313. package/src/config/schema.ts +4 -0
  314. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  315. package/src/config/schemas/call-site-catalog.ts +29 -7
  316. package/src/config/schemas/llm-request-logs.ts +57 -0
  317. package/src/config/schemas/llm.ts +52 -2
  318. package/src/config/schemas/memory-retrospective.ts +48 -0
  319. package/src/config/schemas/memory-v2.ts +33 -2
  320. package/src/config/schemas/memory.ts +4 -0
  321. package/src/config/schemas/services.ts +15 -12
  322. package/src/config/seed-inference-profiles.ts +195 -134
  323. package/src/contacts/contact-store.ts +0 -61
  324. package/src/context/window-manager.ts +191 -5
  325. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
  326. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  327. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  328. package/src/daemon/approval-generators.ts +23 -29
  329. package/src/daemon/config-watcher.ts +2 -0
  330. package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
  331. package/src/daemon/conversation-agent-loop.ts +140 -107
  332. package/src/daemon/conversation-error.ts +21 -0
  333. package/src/daemon/conversation-lifecycle.ts +68 -13
  334. package/src/daemon/conversation-process.ts +36 -19
  335. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  336. package/src/daemon/conversation-slash.ts +175 -23
  337. package/src/daemon/conversation-store.ts +17 -10
  338. package/src/daemon/conversation-surfaces.ts +92 -26
  339. package/src/daemon/conversation-tool-setup.ts +33 -19
  340. package/src/daemon/conversation.ts +49 -10
  341. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  342. package/src/daemon/guardian-action-generators.ts +7 -22
  343. package/src/daemon/handlers/config-model.ts +8 -126
  344. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  345. package/src/daemon/handlers/config-vercel.ts +3 -1
  346. package/src/daemon/handlers/shared.ts +26 -0
  347. package/src/daemon/handlers/skills.ts +84 -5
  348. package/src/daemon/history-repair.ts +33 -6
  349. package/src/daemon/host-app-control-proxy.ts +44 -19
  350. package/src/daemon/host-bash-proxy.ts +85 -158
  351. package/src/daemon/host-browser-proxy.ts +97 -36
  352. package/src/daemon/host-cu-proxy.ts +1 -1
  353. package/src/daemon/host-file-proxy.ts +1 -1
  354. package/src/daemon/host-proxy-base.ts +13 -1
  355. package/src/daemon/host-proxy-preactivation.ts +25 -1
  356. package/src/daemon/host-transfer-proxy.ts +2 -2
  357. package/src/daemon/identity-helpers.ts +19 -0
  358. package/src/daemon/lifecycle.ts +128 -114
  359. package/src/daemon/meet-host-supervisor.ts +15 -15
  360. package/src/daemon/memory-v2-startup.ts +62 -14
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/bookmarks.ts +18 -0
  363. package/src/daemon/message-types/conversations.ts +12 -9
  364. package/src/daemon/message-types/messages.ts +28 -2
  365. package/src/daemon/message-types/sync.ts +60 -0
  366. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  367. package/src/daemon/pkb-reminder-builder.ts +21 -7
  368. package/src/daemon/process-message.ts +56 -23
  369. package/src/daemon/server.ts +23 -18
  370. package/src/daemon/shutdown-handlers.ts +0 -2
  371. package/src/daemon/tool-setup-types.ts +9 -0
  372. package/src/daemon/tool-side-effects.ts +6 -4
  373. package/src/daemon/wake-target-adapter.ts +11 -0
  374. package/src/documents/document-store.ts +35 -1
  375. package/src/export/transcript-formatter.ts +61 -2
  376. package/src/filing/filing-service.ts +42 -56
  377. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  378. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  379. package/src/heartbeat/heartbeat-service.ts +149 -128
  380. package/src/home/__tests__/feed-types.test.ts +63 -131
  381. package/src/home/__tests__/feed-writer.test.ts +77 -278
  382. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  383. package/src/home/feed-types.ts +19 -73
  384. package/src/home/feed-writer.ts +25 -156
  385. package/src/home/post-connect-feed.ts +1 -3
  386. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  387. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  388. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  389. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  390. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  391. package/src/ipc/assistant-server.ts +148 -42
  392. package/src/ipc/cli-client.ts +370 -50
  393. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  394. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  395. package/src/ipc/skill-routes/events.ts +30 -3
  396. package/src/ipc/skill-server.ts +99 -42
  397. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  398. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  399. package/src/live-voice/live-voice-session-manager.ts +11 -4
  400. package/src/live-voice/live-voice-session.ts +14 -6
  401. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  402. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  403. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  404. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  405. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
  406. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  407. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  408. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  409. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  412. package/src/memory/bookmark-crud.ts +179 -0
  413. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  414. package/src/memory/context-search/agent-protocol.ts +5 -1
  415. package/src/memory/context-search/agent-runner.ts +60 -85
  416. package/src/memory/context-search/limits.ts +1 -4
  417. package/src/memory/context-search/search.ts +23 -113
  418. package/src/memory/context-search/sources/conversations.ts +18 -6
  419. package/src/memory/context-search/sources/memory-v2.ts +40 -31
  420. package/src/memory/context-search/sources/memory.ts +9 -2
  421. package/src/memory/context-search/sources/workspace.ts +13 -10
  422. package/src/memory/context-search/types.ts +1 -1
  423. package/src/memory/conversation-bootstrap.ts +11 -0
  424. package/src/memory/conversation-crud.ts +312 -10
  425. package/src/memory/conversation-queries.ts +9 -5
  426. package/src/memory/conversation-title-service.ts +1 -0
  427. package/src/memory/conversation-types.ts +16 -0
  428. package/src/memory/db-init.ts +14 -0
  429. package/src/memory/embedding-backend.ts +2 -1
  430. package/src/memory/embedding-runtime-manager.ts +1 -2
  431. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
  432. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  433. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  434. package/src/memory/graph/conversation-graph-memory.ts +108 -14
  435. package/src/memory/graph/extraction.ts +4 -0
  436. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  437. package/src/memory/graph/graph-search.test.ts +6 -5
  438. package/src/memory/graph/graph-search.ts +3 -4
  439. package/src/memory/graph/retriever.test.ts +12 -7
  440. package/src/memory/graph/retriever.ts +4 -5
  441. package/src/memory/graph/tool-handlers.ts +20 -11
  442. package/src/memory/graph/tools.ts +48 -9
  443. package/src/memory/indexer.ts +18 -2
  444. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
  445. package/src/memory/jobs/embed-concept-page.ts +261 -89
  446. package/src/memory/jobs-store.ts +51 -1
  447. package/src/memory/jobs-worker.ts +60 -7
  448. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  449. package/src/memory/llm-request-log-source-local.ts +26 -0
  450. package/src/memory/llm-request-log-source.ts +97 -0
  451. package/src/memory/llm-request-log-store.ts +1 -1
  452. package/src/memory/memory-retrospective-constants.ts +13 -0
  453. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  454. package/src/memory/memory-retrospective-job.ts +351 -0
  455. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  456. package/src/memory/memory-retrospective-state.ts +162 -0
  457. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  458. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  459. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  460. package/src/memory/message-content.ts +38 -1
  461. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  462. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  463. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  464. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  465. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  466. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  467. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  468. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  469. package/src/memory/migrations/243-provider-connections.ts +68 -0
  470. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  471. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  472. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  473. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  474. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  475. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  476. package/src/memory/migrations/index.ts +7 -0
  477. package/src/memory/pkb/pkb-search.test.ts +6 -5
  478. package/src/memory/pkb/pkb-search.ts +4 -5
  479. package/src/memory/published-pages-store.ts +16 -0
  480. package/src/memory/qdrant-client.ts +3 -0
  481. package/src/memory/schema/bookmarks.ts +38 -0
  482. package/src/memory/schema/conversations.ts +2 -0
  483. package/src/memory/schema/index.ts +2 -0
  484. package/src/memory/schema/inference.ts +29 -0
  485. package/src/memory/schema/memory-core.ts +9 -0
  486. package/src/memory/search/semantic.ts +5 -9
  487. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  488. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  489. package/src/memory/v2/__tests__/activation.test.ts +46 -9
  490. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  491. package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
  492. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  493. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  494. package/src/memory/v2/__tests__/injection.test.ts +768 -33
  495. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  496. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  497. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  498. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  499. package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
  500. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  501. package/src/memory/v2/__tests__/router.test.ts +516 -0
  502. package/src/memory/v2/__tests__/sim.test.ts +163 -8
  503. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  504. package/src/memory/v2/__tests__/static-context.test.ts +8 -35
  505. package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
  506. package/src/memory/v2/activation-store.ts +34 -5
  507. package/src/memory/v2/activation.ts +40 -27
  508. package/src/memory/v2/backfill-jobs.ts +17 -84
  509. package/src/memory/v2/consolidation-job.ts +92 -86
  510. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  511. package/src/memory/v2/injection.ts +466 -115
  512. package/src/memory/v2/migration.ts +117 -20
  513. package/src/memory/v2/page-index.ts +191 -0
  514. package/src/memory/v2/page-store.ts +42 -0
  515. package/src/memory/v2/prompts/consolidation.ts +14 -7
  516. package/src/memory/v2/prompts/router.ts +192 -0
  517. package/src/memory/v2/qdrant.ts +307 -133
  518. package/src/memory/v2/reranker.ts +14 -7
  519. package/src/memory/v2/router.ts +322 -0
  520. package/src/memory/v2/sim.ts +88 -34
  521. package/src/memory/v2/skill-store.ts +118 -29
  522. package/src/memory/v2/static-context.ts +20 -17
  523. package/src/memory/v2/sweep-job.ts +127 -102
  524. package/src/memory/v2/types.ts +16 -5
  525. package/src/memory/validation.ts +13 -0
  526. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  527. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  528. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  529. package/src/notifications/adapters/platform.ts +171 -0
  530. package/src/notifications/conversation-pairing.ts +2 -2
  531. package/src/notifications/copy-composer.ts +61 -12
  532. package/src/notifications/decision-engine.ts +46 -0
  533. package/src/notifications/destination-resolver.ts +21 -0
  534. package/src/notifications/emit-signal.ts +28 -1
  535. package/src/notifications/home-feed-side-effect.ts +111 -0
  536. package/src/notifications/signal.ts +5 -0
  537. package/src/permissions/checker.ts +12 -0
  538. package/src/permissions/gateway-threshold-reader.ts +116 -8
  539. package/src/permissions/ipc-risk-types.ts +2 -0
  540. package/src/permissions/prompter.ts +86 -96
  541. package/src/permissions/secret-prompter.ts +31 -31
  542. package/src/plugin-api/index.ts +13 -0
  543. package/src/plugin-api/package.json +12 -0
  544. package/src/plugin-api/types.ts +62 -0
  545. package/src/plugins/defaults/injectors.ts +20 -5
  546. package/src/plugins/external-plugin-loader.ts +294 -0
  547. package/src/plugins/types.ts +46 -30
  548. package/src/plugins/user-loader.ts +64 -41
  549. package/src/proactive-artifact/job.test.ts +63 -8
  550. package/src/proactive-artifact/job.ts +20 -2
  551. package/src/proactive-artifact/message-copy.ts +18 -1
  552. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  553. package/src/proactive-artifact/trigger-state.ts +4 -0
  554. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  555. package/src/prompts/system-prompt.ts +22 -1
  556. package/src/prompts/templates/SOUL.md +13 -28
  557. package/src/prompts/update-bulletin-job.ts +61 -73
  558. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  559. package/src/providers/__tests__/inference.test.ts +288 -0
  560. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  561. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  562. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  563. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  564. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  565. package/src/providers/anthropic/client.ts +95 -26
  566. package/src/providers/call-site-routing.ts +94 -16
  567. package/src/providers/connection-resolution.ts +163 -0
  568. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  569. package/src/providers/inference/adapter-factory.ts +173 -0
  570. package/src/providers/inference/auth.ts +112 -0
  571. package/src/providers/inference/backfill.ts +196 -0
  572. package/src/providers/inference/connections.ts +356 -0
  573. package/src/providers/inference/resolve-auth.ts +65 -0
  574. package/src/providers/model-catalog.ts +104 -6
  575. package/src/providers/openai/responses-provider.ts +4 -2
  576. package/src/providers/provider-env-vars.ts +17 -7
  577. package/src/providers/provider-secret-catalog.ts +49 -30
  578. package/src/providers/provider-send-message.ts +41 -20
  579. package/src/providers/registry.ts +143 -159
  580. package/src/providers/retry.ts +18 -10
  581. package/src/providers/search-provider-catalog.ts +121 -0
  582. package/src/runtime/AGENTS.md +18 -5
  583. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  584. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  585. package/src/runtime/actor-trust-resolver.ts +32 -10
  586. package/src/runtime/agent-wake.ts +35 -6
  587. package/src/runtime/assistant-event-hub.ts +3 -85
  588. package/src/runtime/auth/route-policy.ts +304 -8
  589. package/src/runtime/auth/same-actor.ts +2 -0
  590. package/src/runtime/background-job-runner.ts +339 -0
  591. package/src/runtime/btw-sidechain.ts +1 -0
  592. package/src/runtime/channel-approvals.ts +3 -2
  593. package/src/runtime/guardian-reply-router.ts +0 -10
  594. package/src/runtime/http-router.ts +36 -1
  595. package/src/runtime/http-server.ts +31 -5
  596. package/src/runtime/http-types.ts +2 -0
  597. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  598. package/src/runtime/middleware/request-logger.ts +62 -1
  599. package/src/runtime/pending-interactions.ts +19 -15
  600. package/src/runtime/pre-first-message-gate.ts +83 -0
  601. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  602. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  603. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  604. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  605. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  606. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  607. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  608. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  609. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  610. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  611. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  612. package/src/runtime/routes/acp-routes.ts +10 -8
  613. package/src/runtime/routes/app-management-routes.ts +228 -3
  614. package/src/runtime/routes/approval-routes.ts +7 -21
  615. package/src/runtime/routes/audit-routes.ts +43 -0
  616. package/src/runtime/routes/auth-routes.ts +72 -0
  617. package/src/runtime/routes/avatar-routes.ts +273 -20
  618. package/src/runtime/routes/backup-routes.ts +406 -2
  619. package/src/runtime/routes/bookmark-routes.ts +154 -0
  620. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  621. package/src/runtime/routes/consolidation-routes.ts +8 -9
  622. package/src/runtime/routes/contact-routes.ts +0 -160
  623. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  624. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  625. package/src/runtime/routes/conversation-query-routes.ts +373 -82
  626. package/src/runtime/routes/conversation-routes.ts +31 -10
  627. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  628. package/src/runtime/routes/credential-routes.ts +540 -0
  629. package/src/runtime/routes/debug-bash-routes.ts +2 -0
  630. package/src/runtime/routes/debug-routes.ts +2 -2
  631. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  632. package/src/runtime/routes/domain-routes.ts +167 -0
  633. package/src/runtime/routes/email-routes.ts +603 -0
  634. package/src/runtime/routes/errors.ts +2 -2
  635. package/src/runtime/routes/events-routes.ts +192 -0
  636. package/src/runtime/routes/filing-routes.ts +2 -3
  637. package/src/runtime/routes/home-feed-routes.ts +6 -78
  638. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  639. package/src/runtime/routes/host-browser-routes.ts +103 -22
  640. package/src/runtime/routes/http-adapter.ts +2 -0
  641. package/src/runtime/routes/identity-routes.ts +5 -0
  642. package/src/runtime/routes/image-generation-routes.ts +99 -0
  643. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  644. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  645. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  646. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
  647. package/src/runtime/routes/index.ts +36 -0
  648. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  649. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  650. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  651. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  652. package/src/runtime/routes/inference-send-routes.ts +115 -0
  653. package/src/runtime/routes/integrations/twilio.ts +1 -0
  654. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  655. package/src/runtime/routes/memory-item-routes.test.ts +3 -9
  656. package/src/runtime/routes/memory-item-routes.ts +5 -6
  657. package/src/runtime/routes/memory-v2-routes.ts +105 -404
  658. package/src/runtime/routes/notification-routes.ts +2 -0
  659. package/src/runtime/routes/oauth-apps.ts +112 -7
  660. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  661. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  662. package/src/runtime/routes/oauth-providers.ts +298 -8
  663. package/src/runtime/routes/platform-routes.ts +336 -0
  664. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  665. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  666. package/src/runtime/routes/playground/state.ts +2 -1
  667. package/src/runtime/routes/publish-routes.ts +221 -0
  668. package/src/runtime/routes/schedule-routes.ts +82 -0
  669. package/src/runtime/routes/sequence-routes.ts +291 -0
  670. package/src/runtime/routes/settings-routes.ts +2 -10
  671. package/src/runtime/routes/skills-routes.ts +31 -1
  672. package/src/runtime/routes/stt-routes.ts +240 -3
  673. package/src/runtime/routes/surface-action-routes.ts +43 -7
  674. package/src/runtime/routes/tts-routes.ts +67 -0
  675. package/src/runtime/routes/types.ts +32 -0
  676. package/src/runtime/routes/user-routes-cli.ts +243 -0
  677. package/src/runtime/routes/webhook-routes.ts +165 -0
  678. package/src/runtime/sync/resource-sync-events.ts +25 -0
  679. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  680. package/src/runtime/sync/sync-publisher.ts +21 -0
  681. package/src/schedule/scheduler.ts +200 -123
  682. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  683. package/src/security/secret-patterns.ts +3 -0
  684. package/src/sequence/engine.ts +38 -40
  685. package/src/skills/include-graph.ts +35 -13
  686. package/src/subagent/manager.ts +20 -15
  687. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  688. package/src/tools/browser/browser-execution.ts +15 -4
  689. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  690. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  691. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  692. package/src/tools/browser/cdp-client/factory.ts +66 -5
  693. package/src/tools/browser/runtime-check.ts +77 -0
  694. package/src/tools/document/document-tool.ts +20 -0
  695. package/src/tools/executor.ts +18 -2
  696. package/src/tools/memory/register.test.ts +10 -8
  697. package/src/tools/memory/register.ts +9 -1
  698. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  699. package/src/tools/network/web-search.ts +280 -37
  700. package/src/tools/permission-checker.ts +28 -5
  701. package/src/tools/skills/load.ts +24 -20
  702. package/src/tools/subagent/spawn.ts +3 -3
  703. package/src/tools/terminal/shell.ts +44 -0
  704. package/src/tools/tool-name-aliases.ts +19 -0
  705. package/src/tools/types.ts +19 -1
  706. package/src/usage/attribution.ts +3 -2
  707. package/src/util/pricing.ts +86 -160
  708. package/src/watcher/__tests__/engine.test.ts +301 -0
  709. package/src/watcher/constants.ts +7 -0
  710. package/src/watcher/engine.ts +90 -90
  711. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  712. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  713. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  714. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
  715. package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
  716. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  717. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  718. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  719. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  720. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  721. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  722. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  723. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  724. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  725. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  726. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  727. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  728. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  729. package/src/workspace/migrations/registry.ts +28 -0
  730. package/src/workspace/migrations/runner.ts +13 -2
  731. package/src/workspace/migrations/types.ts +13 -3
  732. package/src/workspace/provider-commit-message-generator.ts +3 -2
  733. package/src/__tests__/context-search-pkb-source.test.ts +0 -492
  734. package/src/__tests__/credentials-cli.test.ts +0 -1225
  735. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  736. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  737. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  738. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  739. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  740. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  741. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  742. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  743. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  744. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  745. package/src/cli/commands/autonomy.ts +0 -365
  746. package/src/cli/commands/memory.ts +0 -424
  747. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
  748. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  749. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  750. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  751. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  752. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  753. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  754. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  755. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  756. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  757. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  758. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  759. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  760. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  761. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  762. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  763. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  764. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  765. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  766. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  767. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  768. package/src/home/assistant-feed-authoring.ts +0 -135
  769. package/src/home/emit-feed-event.ts +0 -169
  770. package/src/home/feed-scheduler.ts +0 -281
  771. package/src/home/platform-gmail-digest.ts +0 -163
  772. package/src/home/rewrite-command-preview.ts +0 -66
  773. package/src/home/rewrite-feed-title.ts +0 -58
  774. package/src/home/rollup-producer.ts +0 -426
  775. package/src/memory/admin.ts +0 -326
  776. package/src/memory/context-search/sources/pkb.ts +0 -477
  777. package/src/memory/graph/compaction.ts +0 -299
  778. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -1,169 +0,0 @@
1
- /**
2
- * Background-job → home feed event helper.
3
- *
4
- * The "force-write, not taught-write" entry point for the activity
5
- * log. Every background job that wants to surface something on the
6
- * Home page calls `emitFeedEvent({ source, title, summary, ... })`
7
- * at the end of its completion path — no LLM involved, no prompt
8
- * instruction, just a deterministic side effect. This keeps the
9
- * "what got surfaced" question grep-able to a single symbol.
10
- *
11
- * Opinionated defaults for action items:
12
- *
13
- * - `type` is hard-coded to `"action"` — this helper is specifically
14
- * for the activity log. Nudges / digests / threads continue to
15
- * go through `writeAssistantFeedItem` or platform baseline
16
- * generators.
17
- * - `author` is hard-coded to `"assistant"` so hybrid authoring
18
- * resolution treats these as assistant-produced (platform
19
- * defaults can never overwrite them).
20
- * - `source` is REQUIRED — actions always have an origin (gmail,
21
- * slack, calendar, assistant). The per-source volume cap in
22
- * `feed-writer.ts` depends on this.
23
- * - No default `expiresAt`. Action items persist until the user
24
- * dismisses them. Callers that want auto-expiry pass `expiresAt`
25
- * explicitly.
26
- * - Optional `dedupKey` — when set, the helper derives a
27
- * deterministic id so a second emit for the same logical event
28
- * (e.g. the same background job running twice on the same
29
- * signal) updates the existing entry in place instead of
30
- * appending a duplicate. When absent, a fresh `randomUUID` is
31
- * used and every call produces a new entry.
32
- *
33
- * Persistence goes through `appendFeedItem`, inheriting its
34
- * warn-log-on-failure contract — callers never need a try/catch.
35
- * Schema validation runs at build time so a malformed call throws
36
- * loudly at the source rather than silently corrupting the file.
37
- */
38
-
39
- import { randomUUID } from "node:crypto";
40
-
41
- import {
42
- type FeedAction,
43
- type FeedItem,
44
- type FeedItemDetailPanel,
45
- feedItemSchema,
46
- type FeedItemSource,
47
- type FeedItemUrgency,
48
- } from "./feed-types.js";
49
- import { appendFeedItem } from "./feed-writer.js";
50
-
51
- /**
52
- * Default priority for background-job action items. Sits below the
53
- * assistant nudge default (60) so an explicit nudge from
54
- * `writeAssistantFeedItem` surfaces above routine activity log
55
- * entries, but above the platform baseline (40) so background job
56
- * traces outrank same-source platform defaults.
57
- */
58
- const DEFAULT_EMIT_PRIORITY = 50;
59
-
60
- /**
61
- * Parameters accepted by {@link emitFeedEvent}.
62
- *
63
- * All action items emitted by background jobs have an origin, so
64
- * `source` is required. Everything else is optional — callers supply
65
- * only the fields that describe the specific event.
66
- */
67
- export interface EmitFeedEventParams {
68
- /** Origin of the underlying event (gmail, slack, calendar, assistant). */
69
- source: FeedItemSource;
70
- /** Short headline rendered in the feed row. */
71
- title: string;
72
- /** Body copy rendered below the title. */
73
- summary: string;
74
- /**
75
- * Stable key used to derive a deterministic id so a second emit
76
- * for the same logical event updates the existing feed entry in
77
- * place. Should include enough structure to identify the event
78
- * uniquely (e.g. `"gmail-unread:msg-<messageId>"`,
79
- * `"task-runner:<taskId>"`). When omitted, every call produces a
80
- * fresh id and appends a new entry.
81
- */
82
- dedupKey?: string;
83
- /**
84
- * Priority in [0, 100]. Defaults to {@link DEFAULT_EMIT_PRIORITY}
85
- * (50) — above the platform baseline of 40, below the assistant
86
- * nudge default of 60.
87
- */
88
- priority?: number;
89
- /** Action buttons surfaced on the feed row. */
90
- actions?: FeedAction[];
91
- /** Minimum seconds the user must be away before the item is shown. */
92
- minTimeAway?: number;
93
- /**
94
- * Absolute ISO-8601 expiry timestamp. Omit to let the item persist
95
- * until the user dismisses it (default for activity-log actions).
96
- */
97
- expiresAt?: string;
98
- /** Visual urgency treatment — controls badge color independently of sort priority. */
99
- urgency?: FeedItemUrgency;
100
- /** Optional conversation this feed item is associated with. */
101
- conversationId?: string;
102
- /** Server-driven detail panel descriptor; when present, the client opens this panel kind. */
103
- detailPanel?: FeedItemDetailPanel;
104
- }
105
-
106
- /**
107
- * Build a deterministic feed item id from a source + dedup key.
108
- *
109
- * The id is intentionally human-readable: `emit:<source>:<dedupKey>`.
110
- * This makes debugging easier than a hash (you can eyeball the file
111
- * and immediately see which background job produced which entry)
112
- * and `FeedItem.id` is a free-form string so there is no length or
113
- * charset constraint to worry about.
114
- */
115
- function deterministicId(source: FeedItemSource, dedupKey: string): string {
116
- return `emit:${source}:${dedupKey}`;
117
- }
118
-
119
- /**
120
- * Emit a background-job activity-log entry onto the home feed.
121
- *
122
- * Builds a fully-formed assistant-authored `action` {@link FeedItem},
123
- * validates it against the canonical schema, and persists it via
124
- * {@link appendFeedItem}. Returns the constructed item so the caller
125
- * can log / reference it downstream.
126
- *
127
- * Throws a `ZodError` if the constructed item fails validation
128
- * (e.g. a `priority` outside `[0, 100]`) — a programming error in
129
- * the caller that must not be silently swallowed. Persistence-layer
130
- * failures are absorbed by `appendFeedItem` per its warn-log
131
- * contract.
132
- */
133
- export async function emitFeedEvent(
134
- params: EmitFeedEventParams,
135
- ): Promise<FeedItem> {
136
- const now = new Date().toISOString();
137
-
138
- const id =
139
- params.dedupKey !== undefined
140
- ? deterministicId(params.source, params.dedupKey)
141
- : randomUUID();
142
-
143
- const item: FeedItem = {
144
- id,
145
- type: "action",
146
- source: params.source,
147
- title: params.title,
148
- summary: params.summary,
149
- priority: params.priority ?? DEFAULT_EMIT_PRIORITY,
150
- status: "new",
151
- author: "assistant",
152
- timestamp: now,
153
- createdAt: now,
154
- actions: params.actions,
155
- urgency: params.urgency,
156
- conversationId: params.conversationId,
157
- detailPanel: params.detailPanel,
158
- minTimeAway: params.minTimeAway,
159
- expiresAt: params.expiresAt,
160
- };
161
-
162
- // Programming-error guardrail: invalid input throws at the source
163
- // instead of corrupting the on-disk snapshot via the writer.
164
- feedItemSchema.parse(item);
165
-
166
- await appendFeedItem(item);
167
-
168
- return item;
169
- }
@@ -1,281 +0,0 @@
1
- /**
2
- * Home activity feed scheduler.
3
- *
4
- * Periodic tick loop that drives the feed producers — the assistant
5
- * roll-up loop and the platform-baseline Gmail digest generator. This
6
- * is the layer that turns the Phase-5 scaffolding into a live feed: the
7
- * producers exist as standalone functions, the writer knows how to
8
- * persist their output, and the HTTP route + SSE pipeline surface it
9
- * to the macOS client; this scheduler is what actually calls them.
10
- *
11
- * Design notes:
12
- *
13
- * - Mirrors `schedule/scheduler.ts`: `setInterval` + coalescing flag
14
- * so two ticks never run in parallel, `timer.unref()` so the timer
15
- * never blocks daemon exit, stop() clears the interval on shutdown.
16
- *
17
- * - Each producer tracks its own "last ran at" timestamp and decides
18
- * whether to run on each tick. This keeps the tick cadence short
19
- * (so cheap producers refresh often) while expensive producers
20
- * (LLM roll-up) self-throttle independently.
21
- *
22
- * - Fire-and-forget: every producer failure is logged and swallowed.
23
- * A broken producer must never break the tick loop or the daemon.
24
- *
25
- * - `writeAssistantFeedItem` / `generateGmailDigest` both invoke the
26
- * feed writer directly, which publishes `home_feed_updated` on every
27
- * successful write, so the macOS store auto-refreshes without this
28
- * scheduler needing to touch the event hub.
29
- */
30
-
31
- import {
32
- checkDiskPressureBackgroundGate,
33
- diskPressureBackgroundSkipLogFields,
34
- shouldLogDiskPressureBackgroundSkip,
35
- } from "../daemon/disk-pressure-background-gate.js";
36
- import { getLogger } from "../util/logger.js";
37
- import type { FeedItem } from "./feed-types.js";
38
- import {
39
- generateGmailDigest,
40
- type GmailCountSource,
41
- } from "./platform-gmail-digest.js";
42
- import { type RollupResult, runRollupProducer } from "./rollup-producer.js";
43
-
44
- const log = getLogger("home-feed-scheduler");
45
-
46
- /** Tick cadence — fast enough for a Gmail digest to feel fresh. */
47
- const TICK_INTERVAL_MS = 5 * 60 * 1000;
48
-
49
- /** Per-producer minimum gap between runs. */
50
- const GMAIL_DIGEST_INTERVAL_MS = 5 * 60 * 1000;
51
- /**
52
- * Roll-up cadence is deliberately long — 120 minutes — because the
53
- * scheduler is the *safety net*, not the primary trigger. Opening the
54
- * Home page fires a debounced on-visit refresh in the HTTP route (see
55
- * `runtime/routes/home-feed-routes.ts`), which is the path most users
56
- * actually hit. The scheduler exists so the feed still stays fresh
57
- * for long idle stretches where nobody opens the Home page.
58
- */
59
- const ROLLUP_INTERVAL_MS = 2 * 60 * 60 * 1000;
60
-
61
- export interface FeedSchedulerHandle {
62
- /** Stops the interval. Safe to call multiple times. */
63
- stop(): void;
64
- /**
65
- * Run a single tick synchronously for tests. Returns a summary of
66
- * which producers ran during this tick.
67
- */
68
- runOnce(now?: Date): Promise<FeedTickSummary>;
69
- }
70
-
71
- export interface FeedTickSummary {
72
- gmailDigestRan: boolean;
73
- rollupRan: boolean;
74
- }
75
-
76
- export interface FeedSchedulerOptions {
77
- /**
78
- * Optional count source for the Gmail digest. Defaults to
79
- * {@link defaultGmailCountSource}, which reads the active OAuth
80
- * connection and issues one `messages.list?q=is:unread&maxResults=1`
81
- * call to read the `resultSizeEstimate` field (no body fetches).
82
- */
83
- gmailCountSource?: GmailCountSource;
84
- /**
85
- * When true (the default), the scheduler fires one tick synchronously
86
- * after startup so the feed is populated on the first app open after
87
- * daemon boot. Set to false in tests so the only ticks that run are
88
- * the ones the test drives via `runOnce()`.
89
- */
90
- runOnStart?: boolean;
91
- /**
92
- * Dependency seams for tests. Production callers pass `undefined` so
93
- * the scheduler uses the real producer implementations. Tests pass
94
- * spies to avoid `mock.module`, which leaks across files in Bun's
95
- * test runner.
96
- */
97
- gmailDigestRunner?: (
98
- now: Date,
99
- countSource: GmailCountSource,
100
- ) => Promise<FeedItem | null>;
101
- rollupRunner?: (now: Date) => Promise<RollupResult>;
102
- }
103
-
104
- /**
105
- * Start the home feed scheduler. Returns a handle whose `stop()` is
106
- * wired into the daemon shutdown sequence via `ShutdownDeps`.
107
- */
108
- export function startFeedScheduler(
109
- options: FeedSchedulerOptions = {},
110
- ): FeedSchedulerHandle {
111
- let stopped = false;
112
- let tickRunning = false;
113
- let lastGmailDigestAt = 0;
114
- let lastRollupAt = 0;
115
-
116
- const gmailCountSource = options.gmailCountSource ?? defaultGmailCountSource;
117
- const gmailDigestRunner = options.gmailDigestRunner ?? generateGmailDigest;
118
- const rollupRunner =
119
- options.rollupRunner ?? ((now: Date) => runRollupProducer(now));
120
-
121
- const tick = async (now: Date = new Date()): Promise<FeedTickSummary> => {
122
- const summary: FeedTickSummary = {
123
- gmailDigestRan: false,
124
- rollupRan: false,
125
- };
126
- if (stopped || tickRunning) return summary;
127
- const diskPressureGate = checkDiskPressureBackgroundGate("background-work");
128
- if (diskPressureGate.action === "skip") {
129
- if (shouldLogDiskPressureBackgroundSkip("home-feed-scheduler")) {
130
- log.warn(
131
- {
132
- source: "feed-scheduler",
133
- ...diskPressureBackgroundSkipLogFields(diskPressureGate),
134
- },
135
- "Home feed scheduler skipped during disk pressure cleanup mode",
136
- );
137
- }
138
- return summary;
139
- }
140
- tickRunning = true;
141
- const nowMs = now.getTime();
142
- try {
143
- if (nowMs - lastGmailDigestAt >= GMAIL_DIGEST_INTERVAL_MS) {
144
- lastGmailDigestAt = nowMs;
145
- summary.gmailDigestRan = true;
146
- const startedAt = Date.now();
147
- try {
148
- const item = await gmailDigestRunner(now, gmailCountSource);
149
- log.info(
150
- { wroteItem: item !== null, durationMs: Date.now() - startedAt },
151
- "Gmail digest producer ran",
152
- );
153
- } catch (err) {
154
- log.warn(
155
- { err, durationMs: Date.now() - startedAt },
156
- "Gmail digest producer threw",
157
- );
158
- }
159
- }
160
-
161
- if (nowMs - lastRollupAt >= ROLLUP_INTERVAL_MS) {
162
- summary.rollupRan = true;
163
- const startedAt = Date.now();
164
- try {
165
- const result = await rollupRunner(now);
166
- log.info(
167
- {
168
- wroteCount: result.wroteCount,
169
- skippedReason: result.skippedReason,
170
- durationMs: Date.now() - startedAt,
171
- },
172
- "Rollup producer ran",
173
- );
174
- // Only advance the cooldown gate when the producer actually
175
- // had a chance to run the LLM. Three skip reasons short-
176
- // circuit before any provider call and should NOT burn the
177
- // window:
178
- // - `no_provider`: the provider registry wasn't ready yet
179
- // (happens on the startup tick because the feed scheduler
180
- // boots before the provider init pass in
181
- // `daemon/lifecycle.ts`).
182
- // - `no_actions`: there was nothing to roll up. A subsequent
183
- // tick should retry as soon as new actions land, not wait
184
- // the full window.
185
- // - `in_flight`: another caller (usually the on-visit
186
- // refresh trigger in `home-feed-routes.ts`) is already
187
- // running the rollup. That caller's result effectively
188
- // counts as this scheduler tick's real run; bumping the
189
- // gate here would force the NEXT tick to also wait out
190
- // the full window even though nothing broken happened.
191
- // Every other outcome — success, empty items, malformed
192
- // output, provider error — is a real LLM attempt and does
193
- // advance the gate so a broken producer doesn't hammer us.
194
- if (
195
- result.skippedReason !== "no_provider" &&
196
- result.skippedReason !== "no_actions" &&
197
- result.skippedReason !== "in_flight"
198
- ) {
199
- lastRollupAt = nowMs;
200
- }
201
- } catch (err) {
202
- lastRollupAt = nowMs;
203
- log.warn(
204
- { err, durationMs: Date.now() - startedAt },
205
- "Rollup producer threw",
206
- );
207
- }
208
- }
209
- } finally {
210
- tickRunning = false;
211
- }
212
- return summary;
213
- };
214
-
215
- const timer = setInterval(() => {
216
- void tick();
217
- }, TICK_INTERVAL_MS);
218
- timer.unref();
219
- if (options.runOnStart !== false) {
220
- // Fire once on startup so the feed is populated on the first app
221
- // open after daemon boot. Runs in the background — startup does
222
- // not await it.
223
- void tick();
224
- }
225
-
226
- log.info(
227
- {
228
- tickIntervalMs: TICK_INTERVAL_MS,
229
- gmailDigestIntervalMs: GMAIL_DIGEST_INTERVAL_MS,
230
- rollupIntervalMs: ROLLUP_INTERVAL_MS,
231
- },
232
- "Home feed scheduler started",
233
- );
234
-
235
- return {
236
- stop(): void {
237
- if (stopped) return;
238
- stopped = true;
239
- clearInterval(timer);
240
- log.info("Home feed scheduler stopped");
241
- },
242
- runOnce: tick,
243
- };
244
- }
245
-
246
- /**
247
- * Default Gmail count source — resolves the active `google` OAuth
248
- * connection via {@link resolveOAuthConnection}, issues one cheap
249
- * `messages.list` call with `q=is:unread&maxResults=1`, and returns
250
- * the `resultSizeEstimate` field. Returns 0 when no Gmail connection
251
- * exists or the call fails so the digest generator no-ops without
252
- * throwing.
253
- *
254
- * Deliberately does NOT pre-check `isProviderConnected("google")` —
255
- * that helper only reports local oauth-store rows, which are absent
256
- * in managed-OAuth mode even when `resolveOAuthConnection("google")`
257
- * would still resolve via the platform path. Letting the resolver
258
- * make the decision is the only way to cover both modes.
259
- */
260
- async function defaultGmailCountSource(): Promise<number> {
261
- // Lazy import — the oauth resolver + gmail client drag in a fair
262
- // bit of transitive state, and we only want to pay that cost when a
263
- // tick actually runs (not at module load time).
264
- const [{ resolveOAuthConnection }, { listMessages }] = await Promise.all([
265
- import("../oauth/connection-resolver.js"),
266
- import("../messaging/providers/gmail/client.js"),
267
- ]);
268
-
269
- try {
270
- const connection = await resolveOAuthConnection("google");
271
- const response = await listMessages(connection, "is:unread", 1);
272
- const estimate = response.resultSizeEstimate;
273
- return typeof estimate === "number" && estimate >= 0 ? estimate : 0;
274
- } catch (err) {
275
- // Either no Gmail connection exists (managed or direct) or the
276
- // API call itself failed. Both paths degrade to zero so the
277
- // digest generator no-ops without writing a stale item.
278
- log.warn({ err }, "Gmail count source failed; treating as zero");
279
- return 0;
280
- }
281
- }
@@ -1,163 +0,0 @@
1
- /**
2
- * Platform-baseline Gmail digest generator.
3
- *
4
- * Produces a mechanical "N new emails" digest FeedItem for the home
5
- * activity feed. This is the first platform-authored feed source —
6
- * it writes a digest item via the feed writer. Scheduling/invocation
7
- * wiring lands in a follow-up PR when the end-to-end feed flow is
8
- * turned on.
9
- *
10
- * Design notes:
11
- *
12
- * - No LLM calls. Title and summary are purely mechanical so this
13
- * path stays cheap and deterministic. Assistant-authored nudges
14
- * can override a platform digest for the same `(type, source)`
15
- * pair via the feed writer's hybrid-authoring resolver (see
16
- * `feed-writer.ts`).
17
- * - No direct Gmail API fetches. The count is read from whatever
18
- * integration cache already exists. A dependency-injected count
19
- * source keeps the function testable and leaves room for the real
20
- * integration wiring to land in a follow-up PR.
21
- * - One-per-source replacement is handled by the writer — a fresh
22
- * digest automatically replaces any prior Gmail digest in place
23
- * on each call.
24
- * - `minTimeAway: 3600` (1 hour) avoids showing the digest to users
25
- * who've only briefly stepped away. Priority `40` is mid-tier so
26
- * assistant-authored items naturally win on the sort.
27
- */
28
-
29
- import { randomUUID } from "node:crypto";
30
-
31
- import { getLogger } from "../util/logger.js";
32
- import type { FeedItem } from "./feed-types.js";
33
- import { appendFeedItem, readHomeFeed } from "./feed-writer.js";
34
-
35
- const log = getLogger("platform-gmail-digest");
36
-
37
- /**
38
- * Count source for pending Gmail emails. Kept as an injectable
39
- * dependency so tests can supply a deterministic number and so the
40
- * real wiring (an integration cache / event bus) can be swapped in
41
- * without touching this module.
42
- *
43
- * The default source returns 0 — there is no persistent, platform-
44
- * wide Gmail inbox count tracked in the daemon today, so the default
45
- * path is a no-op until a real count source is wired in.
46
- */
47
- export type GmailCountSource = () => Promise<number>;
48
-
49
- async function defaultGmailCountSource(): Promise<number> {
50
- // No platform-wide Gmail inbox count exists in the daemon yet.
51
- // Callers pass an explicit `countSource` from whatever integration
52
- // state is appropriate for their context (tests, watcher store,
53
- // future integration event bus, etc.).
54
- return 0;
55
- }
56
-
57
- /**
58
- * Build and append a platform-baseline Gmail digest feed item.
59
- *
60
- * Returns `null` when the count is 0 (no-op; we do not write an
61
- * empty digest). Otherwise returns the constructed `FeedItem` after
62
- * successfully enqueueing it via `appendFeedItem`.
63
- *
64
- * Never throws — all failures degrade to a warn-log so the caller
65
- * (a scheduler tick) can fire-and-forget without a try/catch.
66
- */
67
- export async function generateGmailDigest(
68
- now: Date,
69
- countSource: GmailCountSource = defaultGmailCountSource,
70
- ): Promise<FeedItem | null> {
71
- let count: number;
72
- try {
73
- count = await countSource();
74
- } catch (err) {
75
- log.warn({ err }, "Gmail count source threw; skipping digest");
76
- return null;
77
- }
78
-
79
- if (!Number.isFinite(count) || count <= 0) {
80
- return null;
81
- }
82
-
83
- const flooredCount = Math.floor(count);
84
- const timestamp = now.toISOString();
85
- const summary = buildDigestSummary(now);
86
-
87
- const item: FeedItem = {
88
- id: randomUUID(),
89
- type: "digest",
90
- source: "gmail",
91
- author: "platform",
92
- title: `${flooredCount} new email${flooredCount === 1 ? "" : "s"}`,
93
- summary,
94
- priority: 40,
95
- minTimeAway: 3600,
96
- timestamp,
97
- createdAt: timestamp,
98
- status: "new",
99
- };
100
-
101
- try {
102
- await appendFeedItem(item);
103
- } catch (err) {
104
- log.warn({ err }, "Failed to append Gmail digest to feed");
105
- return null;
106
- }
107
-
108
- return item;
109
- }
110
-
111
- /**
112
- * Builds the digest summary line. Reads the prior Gmail digest's
113
- * timestamp from the feed and formats it as `"Since <short time>"`
114
- * so users can anchor "new emails" to a specific moment. Falls back
115
- * to a generic string on first-ever digest or on any read failure
116
- * (the writer is authoritative; we never throw out of the generator).
117
- */
118
- function buildDigestSummary(now: Date): string {
119
- const priorTimestamp = readPriorGmailDigestTimestamp();
120
- if (priorTimestamp == null) {
121
- return "Since your last check-in";
122
- }
123
-
124
- const priorDate = new Date(priorTimestamp);
125
- if (Number.isNaN(priorDate.getTime())) {
126
- return "Since your last check-in";
127
- }
128
-
129
- return `Since ${formatShortTime(priorDate, now)}`;
130
- }
131
-
132
- function readPriorGmailDigestTimestamp(): string | null {
133
- try {
134
- const feed = readHomeFeed();
135
- const prior = feed.items.find(
136
- (item) => item.type === "digest" && item.source === "gmail",
137
- );
138
- return prior?.timestamp ?? null;
139
- } catch (err) {
140
- log.warn({ err }, "Failed to read prior Gmail digest timestamp");
141
- return null;
142
- }
143
- }
144
-
145
- /**
146
- * Same-day prior → "10:32 AM". Cross-day prior → "Mon 10:32 AM".
147
- * Plain `toLocaleTimeString` would conflate yesterday and today.
148
- */
149
- function formatShortTime(prior: Date, now: Date): string {
150
- const time = prior.toLocaleTimeString("en-US", {
151
- hour: "numeric",
152
- minute: "2-digit",
153
- });
154
- const sameDay =
155
- prior.getFullYear() === now.getFullYear() &&
156
- prior.getMonth() === now.getMonth() &&
157
- prior.getDate() === now.getDate();
158
- if (sameDay) {
159
- return time;
160
- }
161
- const weekday = prior.toLocaleDateString("en-US", { weekday: "short" });
162
- return `${weekday} ${time}`;
163
- }
@@ -1,66 +0,0 @@
1
- import { getConfiguredProvider } from "../providers/provider-send-message.js";
2
- import { getLogger } from "../util/logger.js";
3
-
4
- const log = getLogger("command-preview-rewriter");
5
- const REWRITE_TIMEOUT_MS = 3000;
6
- const REWRITE_MAX_TOKENS = 100;
7
-
8
- const SYSTEM_PROMPT = `You rewrite technical computer commands into simple, human-readable descriptions.
9
- Output ONLY the rewritten description — no quotes, no explanation, no preamble.
10
- Keep it under 15 words. Use plain language a non-technical person would understand.
11
- Examples:
12
- - "ls -la ~/Desktop" → "View files on the desktop"
13
- - "cat ~/.bashrc" → "Read shell configuration file"
14
- - "rm -rf /tmp/cache" → "Delete temporary cache files"
15
- - "grep -r 'password' ." → "Search files for the word 'password'"
16
- - "curl https://api.example.com/users" → "Fetch user data from an API"`;
17
-
18
- export async function rewriteCommandPreview(
19
- toolName: string,
20
- commandPreview: string,
21
- ): Promise<string | null> {
22
- try {
23
- const provider = await getConfiguredProvider("feedEventCopy");
24
- if (!provider) return null;
25
-
26
- const response = await provider.sendMessage(
27
- [
28
- {
29
- role: "user",
30
- content: [
31
- {
32
- type: "text",
33
- text: `Tool: ${toolName}\nCommand: ${commandPreview}`,
34
- },
35
- ],
36
- },
37
- ],
38
- [],
39
- SYSTEM_PROMPT,
40
- {
41
- config: {
42
- max_tokens: REWRITE_MAX_TOKENS,
43
- callSite: "feedEventCopy",
44
- },
45
- signal: AbortSignal.timeout(REWRITE_TIMEOUT_MS),
46
- },
47
- );
48
-
49
- const block = response.content.find((entry) => entry.type === "text");
50
- const text =
51
- block && "text" in block ? (block as { text: string }).text.trim() : "";
52
- if (!text) return null;
53
- return (
54
- text
55
- .replace(/^["'`]+/, "")
56
- .replace(/["'`]+$/, "")
57
- .trim() || null
58
- );
59
- } catch (err) {
60
- log.warn(
61
- { err, toolName, commandPreview },
62
- "Command preview rewrite failed",
63
- );
64
- return null;
65
- }
66
- }