@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
@@ -240,8 +240,14 @@ export interface MessageComplete {
240
240
  conversationId?: string;
241
241
  attachments?: UserMessageAttachment[];
242
242
  attachmentWarnings?: string[];
243
- /** Database ID of the persisted assistant message, if any. */
243
+ /** Database ID of the final persisted assistant row, if any. */
244
244
  messageId?: string;
245
+ /**
246
+ * Database ID used by clients for the rendered assistant bubble. Tool turns
247
+ * may persist multiple assistant rows; this matches the history row that
248
+ * survives query-time merging.
249
+ */
250
+ displayMessageId?: string;
245
251
  /**
246
252
  * Distinguishes a real main-turn completion from auxiliary events such as
247
253
  * call transcripts, call summaries, and watch notifier outputs. Clients
@@ -370,6 +376,8 @@ export interface ConversationInferenceProfileUpdated {
370
376
  type: "conversation_inference_profile_updated";
371
377
  conversationId: string;
372
378
  profile: string | null;
379
+ sessionId?: string | null;
380
+ expiresAt?: number | null;
373
381
  }
374
382
 
375
383
  export type TraceEventKind =
@@ -0,0 +1,60 @@
1
+ import { z } from "zod";
2
+
3
+ export const SYNC_TAGS = {
4
+ assistantAvatar: "assistant:self:avatar",
5
+ assistantIdentity: "assistant:self:identity",
6
+ assistantConfig: "assistant:self:config",
7
+ assistantSounds: "assistant:self:sounds",
8
+ conversationsList: "conversations:list",
9
+ } as const;
10
+
11
+ export type KnownSyncInvalidationTag =
12
+ (typeof SYNC_TAGS)[keyof typeof SYNC_TAGS];
13
+
14
+ export type ConversationSyncInvalidationTag =
15
+ | `conversation:${string}:messages`
16
+ | `conversation:${string}:metadata`;
17
+
18
+ export type SyncInvalidationTag =
19
+ | KnownSyncInvalidationTag
20
+ | ConversationSyncInvalidationTag
21
+ | (string & {});
22
+
23
+ export interface SyncChangedMessage {
24
+ type: "sync_changed";
25
+ tags: SyncInvalidationTag[];
26
+ }
27
+
28
+ export const SyncInvalidationTagSchema = z.string().min(1);
29
+
30
+ export const SyncChangedMessageSchema = z
31
+ .object({
32
+ type: z.literal("sync_changed"),
33
+ tags: z.array(SyncInvalidationTagSchema).min(1),
34
+ })
35
+ .strict();
36
+
37
+ export function conversationMessagesSyncTag(
38
+ conversationId: string,
39
+ ): ConversationSyncInvalidationTag {
40
+ return `conversation:${conversationId}:messages`;
41
+ }
42
+
43
+ export function conversationMetadataSyncTag(
44
+ conversationId: string,
45
+ ): ConversationSyncInvalidationTag {
46
+ return `conversation:${conversationId}:metadata`;
47
+ }
48
+
49
+ export function buildSyncChangedMessage(
50
+ tags: SyncInvalidationTag[],
51
+ ): SyncChangedMessage {
52
+ const dedupedTags = Array.from(new Set(tags));
53
+ const parsed = SyncChangedMessageSchema.parse({
54
+ type: "sync_changed",
55
+ tags: dedupedTags,
56
+ });
57
+ return parsed as SyncChangedMessage;
58
+ }
59
+
60
+ export type _SyncInvalidationServerMessages = SyncChangedMessage;
@@ -2,26 +2,33 @@ import { describe, expect, test } from "bun:test";
2
2
 
3
3
  import { buildPkbReminder } from "./pkb-reminder-builder.js";
4
4
 
5
- // Byte-for-byte fixture of the base PKB reminder.
6
- const BASE_REMINDER =
5
+ // Byte-for-byte fixture of the default (non-relaxed) PKB reminder. Asserted
6
+ // verbatim so that any future edit to the BODY text is caught by tests.
7
+ const BASE_REMINDER_DEFAULT =
7
8
  "<system_reminder>" +
8
- "\nCall `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
9
+ "\n**CRITICAL:** Call `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
9
10
  "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." +
10
- "\nRead any unread workspace files that look even partially relevant." +
11
11
  "\n</system_reminder>";
12
12
 
13
- describe("buildPkbReminder", () => {
13
+ // Byte-for-byte fixture of the relaxed PKB reminder used when the
14
+ // `memory-retrospective` feature flag is on.
15
+ const BASE_REMINDER_RELAXED =
16
+ "<system_reminder>" +
17
+ "\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments, things the user asks you to hold onto. You don't have to capture everything in the moment — a retrospective pass reviews this conversation in the background and saves what you didn't capture." +
18
+ "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." +
19
+ "\n</system_reminder>";
20
+
21
+ describe("buildPkbReminder — default body (relaxed=false)", () => {
14
22
  test("empty hints returns exact base reminder byte-for-byte", () => {
15
- expect(buildPkbReminder([])).toBe(BASE_REMINDER);
23
+ expect(buildPkbReminder([], false)).toBe(BASE_REMINDER_DEFAULT);
16
24
  });
17
25
 
18
26
  test("single hint renders one bullet with no duplicates or trailing blank line", () => {
19
- const out = buildPkbReminder(["projects/alpha.md"]);
27
+ const out = buildPkbReminder(["projects/alpha.md"], false);
20
28
  const expected =
21
29
  "<system_reminder>" +
22
- "\nCall `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
30
+ "\n**CRITICAL:** Call `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
23
31
  "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." +
24
- "\nRead any unread workspace files that look even partially relevant." +
25
32
  "\nBased on the current context, these files look especially relevant:" +
26
33
  "\n- projects/alpha.md" +
27
34
  "\n</system_reminder>";
@@ -37,12 +44,11 @@ describe("buildPkbReminder", () => {
37
44
 
38
45
  test("three hints render all three in order", () => {
39
46
  const hints = ["a.md", "sub/b.md", "c/d/e.md"];
40
- const out = buildPkbReminder(hints);
47
+ const out = buildPkbReminder(hints, false);
41
48
  const expected =
42
49
  "<system_reminder>" +
43
- "\nCall `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
50
+ "\n**CRITICAL:** Call `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
44
51
  "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." +
45
- "\nRead any unread workspace files that look even partially relevant." +
46
52
  "\nBased on the current context, these files look especially relevant:" +
47
53
  "\n- a.md" +
48
54
  "\n- sub/b.md" +
@@ -61,7 +67,7 @@ describe("buildPkbReminder", () => {
61
67
 
62
68
  test("hints with special chars (< and &) are emitted verbatim (no escaping)", () => {
63
69
  const hints = ["weird<name>.md", "foo&bar.md"];
64
- const out = buildPkbReminder(hints);
70
+ const out = buildPkbReminder(hints, false);
65
71
  expect(out).toContain("- weird<name>.md");
66
72
  expect(out).toContain("- foo&bar.md");
67
73
  // Ensure no HTML-style escaping happened.
@@ -69,3 +75,38 @@ describe("buildPkbReminder", () => {
69
75
  expect(out).not.toContain("&amp;");
70
76
  });
71
77
  });
78
+
79
+ describe("buildPkbReminder — relaxed body (relaxed=true)", () => {
80
+ test("empty hints returns the relaxed base reminder byte-for-byte", () => {
81
+ expect(buildPkbReminder([], true)).toBe(BASE_REMINDER_RELAXED);
82
+ });
83
+
84
+ test("relaxed BODY does NOT contain the default high-pressure phrasing", () => {
85
+ const out = buildPkbReminder([], true);
86
+ expect(out).not.toContain("**CRITICAL:**");
87
+ expect(out).not.toContain("most frequently used tool");
88
+ expect(out).not.toContain("Default to remembering");
89
+ });
90
+
91
+ test("relaxed BODY mentions the retrospective backstop framing", () => {
92
+ const out = buildPkbReminder([], true);
93
+ expect(out).toContain("Stay present");
94
+ expect(out).toContain("retrospective pass");
95
+ });
96
+
97
+ test("hints render below the relaxed body in the same shape as default", () => {
98
+ const out = buildPkbReminder(["projects/alpha.md"], true);
99
+ expect(out).toContain("- projects/alpha.md");
100
+ expect(out).toContain(
101
+ "Based on the current context, these files look especially relevant:",
102
+ );
103
+ // Should still close cleanly with no double newline before the tag.
104
+ expect(out.includes("\n\n</system_reminder>")).toBe(false);
105
+ });
106
+ });
107
+
108
+ describe("buildPkbReminder — relaxed vs default differ", () => {
109
+ test("the two BODY variants are NOT byte-identical", () => {
110
+ expect(buildPkbReminder([], false)).not.toBe(buildPkbReminder([], true));
111
+ });
112
+ });
@@ -1,7 +1,10 @@
1
- const BODY =
2
- "\nCall `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
3
- "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing." +
4
- "\nRead any unread workspace files that look even partially relevant.";
1
+ const BODY_DEFAULT =
2
+ "\n**CRITICAL:** Call `remember` this turn for anything concrete the user said — facts, preferences, plans, names, dates, decisions, corrections, felt moments. Default to remembering; skip only obvious noise. This should be your most frequently used tool." +
3
+ "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing.";
4
+
5
+ const BODY_RELAXED =
6
+ "\nStay present in this conversation. Use `remember` when something feels worth pausing to mark — corrections (highest priority), plans, decisions, felt moments, things the user asks you to hold onto. You don't have to capture everything in the moment — a retrospective pass reviews this conversation in the background and saves what you didn't capture." +
7
+ "\nIf you're unsure about something that may live in the workspace — past decisions, prior conversations, files — use `recall` before asking or guessing.";
5
8
 
6
9
  /**
7
10
  * Render the PKB system_reminder text, optionally with a bulleted list of
@@ -12,12 +15,23 @@ const BODY =
12
15
  * hint. Hints are emitted verbatim — they are trusted internal paths, not
13
16
  * user input, so no escaping is performed.
14
17
  *
18
+ * The `relaxed` flag selects between the default high-pressure body and the
19
+ * relaxed "judgment framing" body used when the `memory-retrospective`
20
+ * feature flag is on. With the flag on, the in-conversation remember pressure
21
+ * eases because the retrospective is the backstop. Callers must pass
22
+ * `relaxed` explicitly — no default — so the contract is visible at every
23
+ * call site.
24
+ *
15
25
  * Caller is responsible for capping the hints array at 3 entries.
16
26
  */
17
- export function buildPkbReminder(hints: ReadonlyArray<string>): string {
27
+ export function buildPkbReminder(
28
+ hints: ReadonlyArray<string>,
29
+ relaxed: boolean,
30
+ ): string {
31
+ const body = relaxed ? BODY_RELAXED : BODY_DEFAULT;
18
32
  if (hints.length === 0) {
19
- return `<system_reminder>${BODY}\n</system_reminder>`;
33
+ return `<system_reminder>${body}\n</system_reminder>`;
20
34
  }
21
35
  const bullets = hints.map((h) => `- ${h}`).join("\n");
22
- return `<system_reminder>${BODY}\nBased on the current context, these files look especially relevant:\n${bullets}\n</system_reminder>`;
36
+ return `<system_reminder>${body}\nBased on the current context, these files look especially relevant:\n${bullets}\n</system_reminder>`;
23
37
  }
@@ -15,7 +15,6 @@ import {
15
15
  type InterfaceId,
16
16
  parseChannelId,
17
17
  parseInterfaceId,
18
- supportsHostProxy,
19
18
  } from "../channels/types.js";
20
19
  import {
21
20
  getAttachmentsByIds,
@@ -47,10 +46,41 @@ import {
47
46
  import type { ConversationCreateOptions } from "./handlers/shared.js";
48
47
  import { HostAppControlProxy } from "./host-app-control-proxy.js";
49
48
  import { HostCuProxy } from "./host-cu-proxy.js";
50
- import { preactivateHostProxySkills } from "./host-proxy-preactivation.js";
49
+ import {
50
+ preactivateHostProxySkills,
51
+ shouldAttachHostProxyForCapability,
52
+ } from "./host-proxy-preactivation.js";
53
+ import type { ServerMessage } from "./message-protocol.js";
51
54
 
52
55
  const log = getLogger("process-message");
53
56
 
57
+ type ProcessMessageOptions = ConversationCreateOptions & {
58
+ /** Per-turn observer for live agent-loop events. Does not replace SSE broadcast. */
59
+ onEvent?: (msg: ServerMessage) => void;
60
+ };
61
+
62
+ function stripPerTurnObservers(
63
+ options?: ProcessMessageOptions,
64
+ ): ConversationCreateOptions | undefined {
65
+ if (!options) return undefined;
66
+ const { onEvent: _onEvent, ...conversationOptions } = options;
67
+ return conversationOptions;
68
+ }
69
+
70
+ function buildEventEmitter(
71
+ observer?: (msg: ServerMessage) => void,
72
+ ): (msg: ServerMessage) => void {
73
+ if (!observer) return broadcastMessage;
74
+ return (msg) => {
75
+ broadcastMessage(msg);
76
+ try {
77
+ observer(msg);
78
+ } catch (err) {
79
+ log.warn({ err, messageType: msg.type }, "Agent event observer failed");
80
+ }
81
+ };
82
+ }
83
+
54
84
  // ---------------------------------------------------------------------------
55
85
  // Turn-context resolution helpers
56
86
  // ---------------------------------------------------------------------------
@@ -154,7 +184,7 @@ async function prepareConversationForMessage(
154
184
  );
155
185
  }
156
186
  // CU is per-conversation (owns step count, AX tree history, loop detection).
157
- if (supportsHostProxy(resolvedInterface, "host_cu")) {
187
+ if (shouldAttachHostProxyForCapability("host_cu", resolvedInterface)) {
158
188
  if (!conversation.isProcessing() || !conversation.hostCuProxy) {
159
189
  conversation.setHostCuProxy(new HostCuProxy());
160
190
  }
@@ -162,10 +192,12 @@ async function prepareConversationForMessage(
162
192
  conversation.setHostCuProxy(undefined);
163
193
  }
164
194
  // App-control mirrors CU's per-conversation lifecycle. The proxy attaches
165
- // unconditionally when the client supports the capability — feature-flag
166
- // gating is enforced by the skill-projection layer via SKILL.md
167
- // frontmatter, so an attached proxy is harmless when the flag is off.
168
- if (supportsHostProxy(resolvedInterface, "host_app_control")) {
195
+ // unconditionally when the capability is reachable — feature-flag gating
196
+ // is enforced by the skill-projection layer via SKILL.md frontmatter, so
197
+ // an attached proxy is harmless when the flag is off.
198
+ if (
199
+ shouldAttachHostProxyForCapability("host_app_control", resolvedInterface)
200
+ ) {
169
201
  if (!conversation.isProcessing() || !conversation.hostAppControlProxy) {
170
202
  conversation.setHostAppControlProxy(
171
203
  new HostAppControlProxy(conversationId),
@@ -214,18 +246,20 @@ export async function processMessage(
214
246
  conversationId: string,
215
247
  content: string,
216
248
  attachmentIds?: string[],
217
- options?: ConversationCreateOptions,
249
+ options?: ProcessMessageOptions,
218
250
  sourceChannel?: string,
219
251
  sourceInterface?: string,
220
252
  ): Promise<{ messageId: string }> {
253
+ const conversationOptions = stripPerTurnObservers(options);
221
254
  const { conversation, attachments } = await prepareConversationForMessage(
222
255
  conversationId,
223
256
  content,
224
257
  attachmentIds,
225
- options,
258
+ conversationOptions,
226
259
  sourceChannel,
227
260
  sourceInterface,
228
261
  );
262
+ const emitEvent = buildEventEmitter(options?.onEvent);
229
263
 
230
264
  const serverInterfaceCtx = conversation.getTurnInterfaceContext();
231
265
  const slashContext = buildSlashContextForContent(content, {
@@ -375,7 +409,9 @@ export async function processMessage(
375
409
  "context_compacting",
376
410
  "assistant_turn",
377
411
  );
378
- const result = await conversation.forceCompact();
412
+ const result = await conversation.forceCompact({
413
+ targetInputTokensOverride: slashResult.targetInputTokensOverride,
414
+ });
379
415
  const responseText = formatCompactResult(result);
380
416
  const assistantMsg = createAssistantMessage(responseText);
381
417
  await addMessage(
@@ -409,16 +445,11 @@ export async function processMessage(
409
445
  conversation.setSlackRuntimeContextNotice(
410
446
  options?.slackRuntimeContextNotice,
411
447
  );
412
- await conversation.runAgentLoop(
413
- resolvedContent,
414
- messageId,
415
- broadcastMessage,
416
- {
417
- isInteractive: options?.isInteractive ?? false,
418
- isUserMessage: true,
419
- ...(options?.callSite ? { callSite: options.callSite } : {}),
420
- },
421
- );
448
+ await conversation.runAgentLoop(resolvedContent, messageId, emitEvent, {
449
+ isInteractive: options?.isInteractive ?? false,
450
+ isUserMessage: true,
451
+ ...(options?.callSite ? { callSite: options.callSite } : {}),
452
+ });
422
453
  } finally {
423
454
  conversation.setSlackRuntimeContextNotice(undefined);
424
455
  if (
@@ -444,18 +475,20 @@ export async function processMessageInBackground(
444
475
  conversationId: string,
445
476
  content: string,
446
477
  attachmentIds?: string[],
447
- options?: ConversationCreateOptions,
478
+ options?: ProcessMessageOptions,
448
479
  sourceChannel?: string,
449
480
  sourceInterface?: string,
450
481
  ): Promise<{ messageId: string }> {
482
+ const conversationOptions = stripPerTurnObservers(options);
451
483
  const { conversation, attachments } = await prepareConversationForMessage(
452
484
  conversationId,
453
485
  content,
454
486
  attachmentIds,
455
- options,
487
+ conversationOptions,
456
488
  sourceChannel,
457
489
  sourceInterface,
458
490
  );
491
+ const emitEvent = buildEventEmitter(options?.onEvent);
459
492
 
460
493
  const requestId = crypto.randomUUID();
461
494
  const persistMetadata = options?.slackInbound
@@ -474,7 +507,7 @@ export async function processMessageInBackground(
474
507
 
475
508
  conversation.setSlackRuntimeContextNotice(options?.slackRuntimeContextNotice);
476
509
  conversation
477
- .runAgentLoop(content, messageId, broadcastMessage, {
510
+ .runAgentLoop(content, messageId, emitEvent, {
478
511
  isInteractive: options?.isInteractive ?? false,
479
512
  isUserMessage: true,
480
513
  ...(options?.callSite ? { callSite: options.callSite } : {}),
@@ -14,13 +14,14 @@ import { syncIdentityNameToPlatform } from "../platform/sync-identity.js";
14
14
  import { initializeProviders } from "../providers/registry.js";
15
15
  import { broadcastMessage } from "../runtime/assistant-event-hub.js";
16
16
  import { getSigningKeyFingerprint } from "../runtime/auth/token-service.js";
17
+ import {
18
+ publishAvatarChanged,
19
+ publishIdentityChanged,
20
+ } from "../runtime/sync/resource-sync-events.js";
17
21
  import { updatePublishedAppDeployment } from "../services/published-app-updater.js";
18
22
  import { getSubagentManager } from "../subagent/index.js";
19
23
  import { getLogger } from "../util/logger.js";
20
- import {
21
- getAvatarImagePath,
22
- getWorkspacePromptPath,
23
- } from "../util/platform.js";
24
+ import { getWorkspacePromptPath } from "../util/platform.js";
24
25
  import {
25
26
  AppSourceWatcher,
26
27
  setEnsureAppSourceWatcher,
@@ -164,14 +165,7 @@ export class DaemonServer {
164
165
  ? readFileSync(identityPath, "utf-8")
165
166
  : "";
166
167
  const fields = parseIdentityFields(content);
167
- broadcastMessage({
168
- type: "identity_changed",
169
- name: fields.name,
170
- role: fields.role,
171
- personality: fields.personality,
172
- emoji: fields.emoji,
173
- home: fields.home,
174
- });
168
+ publishIdentityChanged(fields);
175
169
 
176
170
  // Best-effort sync of the assistant name to the platform record.
177
171
  if (fields.name) {
@@ -207,10 +201,7 @@ export class DaemonServer {
207
201
  }
208
202
 
209
203
  private broadcastAvatarUpdated(): void {
210
- broadcastMessage({
211
- type: "avatar_updated",
212
- avatarPath: getAvatarImagePath(),
213
- });
204
+ publishAvatarChanged();
214
205
  }
215
206
 
216
207
  /**
@@ -260,13 +251,27 @@ export class DaemonServer {
260
251
 
261
252
  this.evictor.start();
262
253
 
263
- await this.cliIpc.start();
254
+ try {
255
+ await this.cliIpc.start();
256
+ } catch (err) {
257
+ log.warn(
258
+ { err },
259
+ "CLI IPC server failed to start — continuing startup with degraded CLI connectivity",
260
+ );
261
+ }
264
262
 
265
263
  // Start the skill IPC server. First-party skill processes connect to this
266
264
  // socket to access host capabilities (host.log, host.config.*,
267
265
  // host.events.*, host.registries.*). Route registry is populated by
268
266
  // subsequent PRs in the skill-isolation plan.
269
- await this.skillIpc.start();
267
+ try {
268
+ await this.skillIpc.start();
269
+ } catch (err) {
270
+ log.warn(
271
+ { err },
272
+ "Skill IPC server failed to start — continuing startup with degraded skill host connectivity",
273
+ );
274
+ }
270
275
 
271
276
  this.configWatcher.start(
272
277
  () => this.evictConversationsForReload(),
@@ -23,7 +23,6 @@ export interface ShutdownDeps {
23
23
  filing: FilingService | null;
24
24
  runtimeHttp: RuntimeHttpServer | null;
25
25
  scheduler: { stop(): void };
26
- feedScheduler: { stop(): void } | null;
27
26
  getMemoryWorker: () => { stop(): void } | null;
28
27
  getQdrantManager: () => QdrantManager | null;
29
28
  mcpManager: McpServerManager | null;
@@ -119,7 +118,6 @@ export function installShutdownHandlers(deps: ShutdownDeps): void {
119
118
  await browserManager.closeAllPages();
120
119
  cleanupShellOutputTempFiles();
121
120
  deps.scheduler.stop();
122
- deps.feedScheduler?.stop();
123
121
  deps.getMemoryWorker()?.stop();
124
122
 
125
123
  if (deps.mcpManager) {
@@ -40,6 +40,15 @@ export interface ToolSetupContext extends SurfaceConversationContext {
40
40
 
41
41
  /** Turn-scoped flag: true when any tool call in the current turn received explicit user approval via interactive prompt. Cleared at turn end. */
42
42
  approvedViaPromptThisTurn?: boolean;
43
+ /**
44
+ * When true, side-effect tools must prompt for confirmation even if a
45
+ * trust/allow rule would auto-allow them. Set by callers without an
46
+ * interactive approval UI (e.g. non-guardian phone voice turns) to force
47
+ * a `confirmation_request` event that the caller's auto-deny / scoped-grant
48
+ * handler can intercept. Provides a second layer of defense against broad
49
+ * trust rules auto-executing side-effect tools in non-interactive contexts.
50
+ */
51
+ forcePromptSideEffects?: boolean;
43
52
  /**
44
53
  * Per-turn snapshot of the resolved inference-profile override, set by
45
54
  * `runAgentLoopImpl`. Propagated into `ToolContext.overrideProfile` so
@@ -12,6 +12,7 @@ import { isAbsolute, resolve, sep } from "node:path";
12
12
  import { generateAppIcon } from "../media/app-icon-generator.js";
13
13
  import { addAppConversationId } from "../memory/app-store.js";
14
14
  import { invalidateEdgeIndex } from "../memory/v2/edge-index.js";
15
+ import { invalidatePageIndex } from "../memory/v2/page-index.js";
15
16
  import { getConceptsDir } from "../memory/v2/page-store.js";
16
17
  import { broadcastMessage } from "../runtime/assistant-event-hub.js";
17
18
  import { findActiveSession } from "../runtime/channel-verification-service.js";
@@ -245,10 +246,10 @@ registerHook("bash", (_name, input, result) => {
245
246
  }
246
247
  });
247
248
 
248
- // Invalidate the in-memory v2 edge index when the LLM writes or edits a file
249
- // under `memory/concepts/`. The page-store invalidates on programmatic writes;
250
- // this hook covers consolidation, where the LLM edits page frontmatter through
251
- // the file tools rather than through `writePage`.
249
+ // Invalidate the in-memory v2 edge index and page index when the LLM writes
250
+ // or edits a file under `memory/concepts/`. The page-store invalidates on
251
+ // programmatic writes; this hook covers consolidation, where the LLM edits
252
+ // page frontmatter through the file tools rather than through `writePage`.
252
253
  function invalidateEdgeIndexIfConceptPage(
253
254
  input: Record<string, unknown>,
254
255
  ): void {
@@ -264,6 +265,7 @@ function invalidateEdgeIndexIfConceptPage(
264
265
  : conceptsRoot + sep;
265
266
  if (absPath.startsWith(rootWithSep)) {
266
267
  invalidateEdgeIndex(workspaceDir);
268
+ invalidatePageIndex(workspaceDir);
267
269
  }
268
270
  }
269
271
  registerHook("file_write", (_name, input) =>
@@ -14,6 +14,7 @@ import {
14
14
  provenanceFromTrustContext,
15
15
  } from "../memory/conversation-crud.js";
16
16
  import { syncMessageToDisk } from "../memory/conversation-disk-view.js";
17
+ import { backfillMessageIdOnLogs } from "../memory/llm-request-log-store.js";
17
18
  import type { WakeTarget } from "../runtime/agent-wake.js";
18
19
  import { broadcastMessage } from "../runtime/assistant-event-hub.js";
19
20
  import { getLogger } from "../util/logger.js";
@@ -197,6 +198,16 @@ export function conversationToWakeTarget(
197
198
  JSON.stringify(message.content),
198
199
  metadata,
199
200
  );
201
+ if (message.role === "assistant") {
202
+ try {
203
+ backfillMessageIdOnLogs(conversation.conversationId, persisted.id);
204
+ } catch (err) {
205
+ log.warn(
206
+ { err, conversationId: conversation.conversationId },
207
+ "wake adapter: backfill messageId on LLM logs failed (non-fatal)",
208
+ );
209
+ }
210
+ }
200
211
  try {
201
212
  const convRow = getConversation(conversation.conversationId);
202
213
  if (convRow) {
@@ -97,6 +97,61 @@ function parseContent(raw: string): ContentBlock[] {
97
97
  }
98
98
  }
99
99
 
100
+ type TranscriptMessage = ReturnType<typeof getMessages>[number];
101
+
102
+ /**
103
+ * Format a slice of messages as a transcript body (no top-of-conversation
104
+ * header). Used by background jobs that process incremental slices — the
105
+ * memory-retrospective job re-renders only the messages added since its
106
+ * last successful run rather than the whole conversation. The format
107
+ * matches `buildAnalysisTranscript` per message so downstream agents see a
108
+ * consistent shape regardless of whether the input is a full transcript or
109
+ * a slice.
110
+ */
111
+ export function formatMessageSliceForTranscript(
112
+ messages: TranscriptMessage[],
113
+ ): string {
114
+ const lines: string[] = [];
115
+ for (const msg of messages) {
116
+ appendMessageBlock(lines, msg);
117
+ }
118
+ return lines.join("\n");
119
+ }
120
+
121
+ function appendMessageBlock(lines: string[], msg: TranscriptMessage): void {
122
+ const role = formatRole(msg.role);
123
+ const time = formatTimestamp(msg.createdAt);
124
+ const content = parseContent(msg.content);
125
+ const text = extractAnalysisText(content);
126
+
127
+ lines.push(`## ${role} (${time})`);
128
+ lines.push(text);
129
+ lines.push("");
130
+
131
+ if (msg.metadata) {
132
+ try {
133
+ const parsed = messageMetadataSchema.safeParse(JSON.parse(msg.metadata));
134
+ if (parsed.success && parsed.data.subagentNotification) {
135
+ const notif = parsed.data.subagentNotification;
136
+ if (
137
+ (notif.status === "completed" ||
138
+ notif.status === "failed" ||
139
+ notif.status === "aborted") &&
140
+ notif.conversationId
141
+ ) {
142
+ const subMessages = getMessages(notif.conversationId);
143
+ lines.push(`### Subagent: ${notif.label} (${notif.status})`);
144
+ lines.push("");
145
+ lines.push(formatSubagentMessages(subMessages));
146
+ lines.push("");
147
+ }
148
+ }
149
+ } catch {
150
+ // Skip unparseable metadata
151
+ }
152
+ }
153
+ }
154
+
100
155
  export function buildAnalysisTranscript(conversationId: string): string {
101
156
  const conversation = getConversation(conversationId);
102
157
  if (!conversation) {
@@ -124,11 +179,15 @@ export function buildAnalysisTranscript(conversationId: string): string {
124
179
  // Check for subagent notifications in metadata
125
180
  if (msg.metadata) {
126
181
  try {
127
- const parsed = messageMetadataSchema.safeParse(JSON.parse(msg.metadata));
182
+ const parsed = messageMetadataSchema.safeParse(
183
+ JSON.parse(msg.metadata),
184
+ );
128
185
  if (parsed.success && parsed.data.subagentNotification) {
129
186
  const notif = parsed.data.subagentNotification;
130
187
  if (
131
- (notif.status === "completed" || notif.status === "failed" || notif.status === "aborted") &&
188
+ (notif.status === "completed" ||
189
+ notif.status === "failed" ||
190
+ notif.status === "aborted") &&
132
191
  notif.conversationId
133
192
  ) {
134
193
  const subMessages = getMessages(notif.conversationId);