@vellumai/assistant 0.8.0 → 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 (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /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
- }