@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,49 +1,18 @@
1
1
  /**
2
2
  * CLI command group: `assistant sequence`
3
3
  *
4
- * Manage email sequenceslist, inspect, pause, resume, and view stats.
4
+ * Thin IPC wrapperall logic lives in sequence-routes.ts.
5
5
  */
6
6
 
7
- import { Command } from "commander";
8
-
9
- import { getDb } from "../../memory/db-connection.js";
10
- import {
11
- getGuardrailConfig,
12
- setGuardrailConfig,
13
- } from "../../sequence/guardrails.js";
14
- import {
15
- countActiveEnrollments,
16
- exitEnrollment,
17
- getSequence,
18
- listEnrollments,
19
- listSequences,
20
- updateSequence,
21
- } from "../../sequence/store.js";
7
+ import type { Command } from "commander";
8
+
9
+ import { cliIpcCall, exitFromIpcResult } from "../../ipc/cli-client.js";
10
+ import { registerCommand } from "../lib/register-command.js";
22
11
 
23
12
  // ---------------------------------------------------------------------------
24
13
  // Helpers
25
14
  // ---------------------------------------------------------------------------
26
15
 
27
- function output(data: unknown, json: boolean): void {
28
- process.stdout.write(
29
- json ? JSON.stringify(data) + "\n" : JSON.stringify(data, null, 2) + "\n",
30
- );
31
- }
32
-
33
- function exitError(message: string): void {
34
- output({ ok: false, error: message }, true);
35
- process.exitCode = 1;
36
- }
37
-
38
- function getJson(cmd: Command): boolean {
39
- let c: Command | null = cmd;
40
- while (c) {
41
- if ((c.opts() as { json?: boolean }).json) return true;
42
- c = c.parent;
43
- }
44
- return false;
45
- }
46
-
47
16
  function formatDuration(ms: number): string {
48
17
  const seconds = Math.floor(ms / 1000);
49
18
  if (seconds < 60) return `${seconds}s`;
@@ -55,19 +24,45 @@ function formatDuration(ms: number): string {
55
24
  return `${days}d ${hours % 24}h`;
56
25
  }
57
26
 
27
+ // ---------------------------------------------------------------------------
28
+ // Types
29
+ // ---------------------------------------------------------------------------
30
+
31
+ interface SequenceSummary {
32
+ id: string;
33
+ name: string;
34
+ status: string;
35
+ steps: { index: number; subjectTemplate: string; delaySeconds: number; requireApproval?: boolean }[];
36
+ activeEnrollments: number;
37
+ description?: string;
38
+ channel?: string;
39
+ exitOnReply?: boolean;
40
+ }
41
+
42
+ interface GuardrailConfig {
43
+ dailySendCap: number;
44
+ perSequenceHourlyRate: number;
45
+ minimumStepDelaySec: number;
46
+ maxActiveEnrollments: number;
47
+ duplicateEnrollmentCheck: boolean;
48
+ cooldownPeriodMs: number;
49
+ }
50
+
58
51
  // ---------------------------------------------------------------------------
59
52
  // Command registration
60
53
  // ---------------------------------------------------------------------------
61
54
 
62
55
  export function registerSequenceCommand(program: Command): void {
63
- const seqCmd = program
64
- .command("sequence")
65
- .description("Manage email sequences")
66
- .option("--json", "Machine-readable JSON output");
67
-
68
- seqCmd.addHelpText(
69
- "after",
70
- `
56
+ registerCommand(program, {
57
+ name: "sequence",
58
+ transport: "ipc",
59
+ description: "Manage email sequences",
60
+ build: (seqCmd) => {
61
+ seqCmd.option("--json", "Machine-readable JSON output");
62
+
63
+ seqCmd.addHelpText(
64
+ "after",
65
+ `
71
66
  Email sequences are automated multi-step email campaigns. Each sequence
72
67
  contains ordered steps with configurable delays, subject/body templates,
73
68
  and optional approval gates. Contacts are enrolled into a sequence and
@@ -85,16 +80,16 @@ Examples:
85
80
  $ assistant sequence get seq_abc123
86
81
  $ assistant sequence pause seq_abc123
87
82
  $ assistant sequence stats`,
88
- );
89
-
90
- // ── list ──────────────────────────────────────────────────────────
91
- seqCmd
92
- .command("list")
93
- .description("List all sequences")
94
- .option("--status <status>", "Filter by status (active, paused, archived)")
95
- .addHelpText(
96
- "after",
97
- `
83
+ );
84
+
85
+ // ── list ──────────────────────────────────────────────────────
86
+ seqCmd
87
+ .command("list")
88
+ .description("List all sequences")
89
+ .option("--status <status>", "Filter by status (active, paused, archived)")
90
+ .addHelpText(
91
+ "after",
92
+ `
98
93
  Lists all sequences with summary info: name, ID, status, step count,
99
94
  and active enrollment count.
100
95
 
@@ -105,42 +100,46 @@ Examples:
105
100
  $ assistant sequence list
106
101
  $ assistant sequence list --status active
107
102
  $ assistant sequence list --status paused --json`,
108
- )
109
- .action((opts: { status?: string }, cmd: Command) => {
110
- getDb();
111
- const json = getJson(cmd);
112
- const filter = opts.status
113
- ? { status: opts.status as "active" | "paused" | "archived" }
114
- : undefined;
115
- const seqs = listSequences(filter);
116
-
117
- if (json) {
118
- output({ ok: true, sequences: seqs }, true);
119
- return;
120
- }
121
-
122
- if (seqs.length === 0) {
123
- process.stdout.write("No sequences found.\n");
124
- return;
125
- }
126
-
127
- process.stdout.write(`${seqs.length} sequence(s):\n\n`);
128
- for (const seq of seqs) {
129
- const active = countActiveEnrollments(seq.id);
130
- process.stdout.write(
131
- ` ${seq.name} (${seq.id}) — ${seq.status}, ${seq.steps.length} steps, ${active} active\n`,
132
- );
133
- }
134
- process.stdout.write("\n");
135
- });
136
-
137
- // ── get ────────────────────────────────────────────────────────────
138
- seqCmd
139
- .command("get <id>")
140
- .description("Get sequence details with enrollment stats")
141
- .addHelpText(
142
- "after",
143
- `
103
+ )
104
+ .action(async (opts: { status?: string }) => {
105
+ const json = resolveJson(seqCmd);
106
+ const params: Record<string, unknown> = {};
107
+ if (opts.status) params.status = opts.status;
108
+
109
+ const r = await cliIpcCall<{ sequences: SequenceSummary[] }>(
110
+ "sequence_list",
111
+ params,
112
+ );
113
+ if (!r.ok) return exitFromIpcResult(r);
114
+
115
+ const seqs = r.result!.sequences;
116
+
117
+ if (json) {
118
+ console.log(JSON.stringify({ ok: true, sequences: seqs }));
119
+ return;
120
+ }
121
+
122
+ if (seqs.length === 0) {
123
+ process.stdout.write("No sequences found.\n");
124
+ return;
125
+ }
126
+
127
+ process.stdout.write(`${seqs.length} sequence(s):\n\n`);
128
+ for (const seq of seqs) {
129
+ process.stdout.write(
130
+ ` ${seq.name} (${seq.id}) — ${seq.status}, ${seq.steps.length} steps, ${seq.activeEnrollments} active\n`,
131
+ );
132
+ }
133
+ process.stdout.write("\n");
134
+ });
135
+
136
+ // ── get ────────────────────────────────────────────────────────
137
+ seqCmd
138
+ .command("get <id>")
139
+ .description("Get sequence details with enrollment stats")
140
+ .addHelpText(
141
+ "after",
142
+ `
144
143
  Arguments:
145
144
  id The sequence ID (e.g. seq_abc123). Run 'assistant sequence list' to find IDs.
146
145
 
@@ -151,69 +150,54 @@ breakdown by status (active, paused, completed, replied, cancelled, failed).
151
150
  Examples:
152
151
  $ assistant sequence get seq_abc123
153
152
  $ assistant sequence get seq_abc123 --json`,
154
- )
155
- .action((id: string, _opts: Record<string, unknown>, cmd: Command) => {
156
- getDb();
157
- const json = getJson(cmd);
158
- const seq = getSequence(id);
159
- if (!seq) return exitError(`Sequence not found: ${id}`);
160
-
161
- const enrollments = listEnrollments({ sequenceId: id });
162
- const statusCounts = enrollments.reduce(
163
- (acc, e) => {
164
- acc[e.status] = (acc[e.status] || 0) + 1;
165
- return acc;
166
- },
167
- {} as Record<string, number>,
168
- );
153
+ )
154
+ .action(async (id: string) => {
155
+ const json = resolveJson(seqCmd);
156
+ const r = await cliIpcCall<{
157
+ sequence: SequenceSummary;
158
+ enrollments: { total: number; byStatus: Record<string, number> };
159
+ }>("sequence_get", { id });
160
+ if (!r.ok) return exitFromIpcResult(r);
161
+
162
+ const { sequence: seq, enrollments } = r.result!;
163
+
164
+ if (json) {
165
+ console.log(JSON.stringify({ ok: true, sequence: seq, enrollments }));
166
+ return;
167
+ }
168
+
169
+ process.stdout.write(` Name: ${seq.name}\n`);
170
+ process.stdout.write(` ID: ${seq.id}\n`);
171
+ process.stdout.write(` Status: ${seq.status}\n`);
172
+ if (seq.channel) process.stdout.write(` Channel: ${seq.channel}\n`);
173
+ if (seq.description)
174
+ process.stdout.write(` Description: ${seq.description}\n`);
175
+ process.stdout.write(` Exit on reply: ${seq.exitOnReply}\n`);
176
+ process.stdout.write(` Active: ${seq.activeEnrollments} enrollment(s)\n\n`);
177
+
178
+ process.stdout.write(` Steps (${seq.steps.length}):\n`);
179
+ for (const step of seq.steps) {
180
+ const delay = formatDuration(step.delaySeconds * 1000);
181
+ const approval = step.requireApproval ? " [approval required]" : "";
182
+ process.stdout.write(
183
+ ` ${step.index + 1}. "${step.subjectTemplate}" — delay: ${delay}${approval}\n`,
184
+ );
185
+ }
169
186
 
170
- if (json) {
171
- output(
172
- {
173
- ok: true,
174
- sequence: seq,
175
- enrollments: { total: enrollments.length, byStatus: statusCounts },
176
- },
177
- true,
178
- );
179
- return;
180
- }
181
-
182
- const active = countActiveEnrollments(id);
183
- process.stdout.write(` Name: ${seq.name}\n`);
184
- process.stdout.write(` ID: ${seq.id}\n`);
185
- process.stdout.write(` Status: ${seq.status}\n`);
186
- process.stdout.write(` Channel: ${seq.channel}\n`);
187
- if (seq.description)
188
- process.stdout.write(` Description: ${seq.description}\n`);
189
- process.stdout.write(` Exit on reply: ${seq.exitOnReply}\n`);
190
- process.stdout.write(` Active: ${active} enrollment(s)\n\n`);
191
-
192
- process.stdout.write(` Steps (${seq.steps.length}):\n`);
193
- for (const step of seq.steps) {
194
- const delay = formatDuration(step.delaySeconds * 1000);
195
- const approval = step.requireApproval ? " [approval required]" : "";
196
- process.stdout.write(
197
- ` ${step.index + 1}. "${
198
- step.subjectTemplate
199
- }" — delay: ${delay}${approval}\n`,
200
- );
201
- }
202
-
203
- process.stdout.write(`\n Enrollments: ${enrollments.length} total\n`);
204
- for (const [status, count] of Object.entries(statusCounts)) {
205
- process.stdout.write(` ${status}: ${count}\n`);
206
- }
207
- process.stdout.write("\n");
208
- });
209
-
210
- // ── pause ──────────────────────────────────────────────────────────
211
- seqCmd
212
- .command("pause <id>")
213
- .description("Pause a sequence")
214
- .addHelpText(
215
- "after",
216
- `
187
+ process.stdout.write(`\n Enrollments: ${enrollments.total} total\n`);
188
+ for (const [status, count] of Object.entries(enrollments.byStatus)) {
189
+ process.stdout.write(` ${status}: ${count}\n`);
190
+ }
191
+ process.stdout.write("\n");
192
+ });
193
+
194
+ // ── pause ──────────────────────────────────────────────────────
195
+ seqCmd
196
+ .command("pause <id>")
197
+ .description("Pause a sequence")
198
+ .addHelpText(
199
+ "after",
200
+ `
217
201
  Arguments:
218
202
  id The sequence ID to pause (e.g. seq_abc123). Run 'assistant sequence list' to find IDs.
219
203
 
@@ -224,27 +208,26 @@ until the sequence is resumed. No-op if the sequence is already paused.
224
208
  Examples:
225
209
  $ assistant sequence pause seq_abc123
226
210
  $ assistant sequence pause seq_abc123 --json`,
227
- )
228
- .action((id: string, _opts: Record<string, unknown>, cmd: Command) => {
229
- getDb();
230
- const json = getJson(cmd);
231
- const seq = getSequence(id);
232
- if (!seq) return exitError(`Sequence not found: ${id}`);
233
- if (seq.status === "paused") {
234
- output({ ok: true, message: "Sequence is already paused." }, json);
235
- return;
236
- }
237
- updateSequence(id, { status: "paused" });
238
- output({ ok: true, message: `Sequence "${seq.name}" paused.` }, json);
239
- });
240
-
241
- // ── resume ─────────────────────────────────────────────────────────
242
- seqCmd
243
- .command("resume <id>")
244
- .description("Resume a paused sequence")
245
- .addHelpText(
246
- "after",
247
- `
211
+ )
212
+ .action(async (id: string) => {
213
+ const json = resolveJson(seqCmd);
214
+ const r = await cliIpcCall<{ message: string }>("sequence_pause", { id });
215
+ if (!r.ok) return exitFromIpcResult(r);
216
+
217
+ if (json) {
218
+ console.log(JSON.stringify({ ok: true, message: r.result!.message }));
219
+ } else {
220
+ process.stdout.write(r.result!.message + "\n");
221
+ }
222
+ });
223
+
224
+ // ── resume ─────────────────────────────────────────────────────
225
+ seqCmd
226
+ .command("resume <id>")
227
+ .description("Resume a paused sequence")
228
+ .addHelpText(
229
+ "after",
230
+ `
248
231
  Arguments:
249
232
  id The sequence ID to resume (e.g. seq_abc123). Run 'assistant sequence list' to find IDs.
250
233
 
@@ -254,27 +237,26 @@ active enrollments. No-op if the sequence is already active.
254
237
  Examples:
255
238
  $ assistant sequence resume seq_abc123
256
239
  $ assistant sequence resume seq_abc123 --json`,
257
- )
258
- .action((id: string, _opts: Record<string, unknown>, cmd: Command) => {
259
- getDb();
260
- const json = getJson(cmd);
261
- const seq = getSequence(id);
262
- if (!seq) return exitError(`Sequence not found: ${id}`);
263
- if (seq.status === "active") {
264
- output({ ok: true, message: "Sequence is already active." }, json);
265
- return;
266
- }
267
- updateSequence(id, { status: "active" });
268
- output({ ok: true, message: `Sequence "${seq.name}" resumed.` }, json);
269
- });
270
-
271
- // ── cancel-enrollment ──────────────────────────────────────────────
272
- seqCmd
273
- .command("cancel-enrollment <enrollmentId>")
274
- .description("Cancel a specific enrollment")
275
- .addHelpText(
276
- "after",
277
- `
240
+ )
241
+ .action(async (id: string) => {
242
+ const json = resolveJson(seqCmd);
243
+ const r = await cliIpcCall<{ message: string }>("sequence_resume", { id });
244
+ if (!r.ok) return exitFromIpcResult(r);
245
+
246
+ if (json) {
247
+ console.log(JSON.stringify({ ok: true, message: r.result!.message }));
248
+ } else {
249
+ process.stdout.write(r.result!.message + "\n");
250
+ }
251
+ });
252
+
253
+ // ── cancel-enrollment ──────────────────────────────────────────
254
+ seqCmd
255
+ .command("cancel-enrollment <enrollmentId>")
256
+ .description("Cancel a specific enrollment")
257
+ .addHelpText(
258
+ "after",
259
+ `
278
260
  Arguments:
279
261
  enrollmentId The enrollment ID to cancel (e.g. enr_xyz789). Run 'assistant sequence get <id>'
280
262
  to see enrollment IDs for a sequence.
@@ -287,72 +269,70 @@ other enrollments.
287
269
  Examples:
288
270
  $ assistant sequence cancel-enrollment enr_xyz789
289
271
  $ assistant sequence cancel-enrollment enr_xyz789 --json`,
290
- )
291
- .action(
292
- (enrollmentId: string, _opts: Record<string, unknown>, cmd: Command) => {
293
- getDb();
294
- const json = getJson(cmd);
295
- exitEnrollment(enrollmentId, "cancelled");
296
- output(
297
- { ok: true, message: `Enrollment ${enrollmentId} cancelled.` },
298
- json,
299
- );
300
- },
301
- );
302
-
303
- // ── stats ──────────────────────────────────────────────────────────
304
- seqCmd
305
- .command("stats")
306
- .description("Overall sequence stats")
307
- .addHelpText(
308
- "after",
309
- `
272
+ )
273
+ .action(async (enrollmentId: string) => {
274
+ const json = resolveJson(seqCmd);
275
+ const r = await cliIpcCall<{ message: string }>(
276
+ "sequence_cancel_enrollment",
277
+ { enrollmentId },
278
+ );
279
+ if (!r.ok) return exitFromIpcResult(r);
280
+
281
+ if (json) {
282
+ console.log(JSON.stringify({ ok: true, message: r.result!.message }));
283
+ } else {
284
+ process.stdout.write(r.result!.message + "\n");
285
+ }
286
+ });
287
+
288
+ // ── stats ──────────────────────────────────────────────────────
289
+ seqCmd
290
+ .command("stats")
291
+ .description("Overall sequence stats")
292
+ .addHelpText(
293
+ "after",
294
+ `
310
295
  Returns aggregate statistics across all sequences: total and active
311
296
  sequence counts, total and active enrollment counts.
312
297
 
313
298
  Examples:
314
299
  $ assistant sequence stats
315
300
  $ assistant sequence stats --json`,
316
- )
317
- .action((_opts: Record<string, unknown>, cmd: Command) => {
318
- getDb();
319
- const json = getJson(cmd);
320
- const seqs = listSequences();
321
- const activeSeqs = seqs.filter((s) => s.status === "active").length;
322
- const allEnrollments = listEnrollments();
323
- const activeEnrollments = allEnrollments.filter(
324
- (e) => e.status === "active",
325
- ).length;
326
-
327
- const stats = {
328
- totalSequences: seqs.length,
329
- activeSequences: activeSeqs,
330
- totalEnrollments: allEnrollments.length,
331
- activeEnrollments,
332
- };
333
-
334
- if (json) {
335
- output({ ok: true, ...stats }, true);
336
- return;
337
- }
338
-
339
- process.stdout.write(`Sequence Stats:\n`);
340
- process.stdout.write(
341
- ` Sequences: ${stats.totalSequences} total, ${stats.activeSequences} active\n`,
342
- );
343
- process.stdout.write(
344
- ` Enrollments: ${stats.totalEnrollments} total, ${stats.activeEnrollments} active\n\n`,
345
- );
346
- });
347
-
348
- // ── guardrails ─────────────────────────────────────────────────────
349
- const guardrailsCmd = seqCmd
350
- .command("guardrails")
351
- .description("View or update guardrail settings");
301
+ )
302
+ .action(async () => {
303
+ const json = resolveJson(seqCmd);
304
+ const r = await cliIpcCall<{
305
+ totalSequences: number;
306
+ activeSequences: number;
307
+ totalEnrollments: number;
308
+ activeEnrollments: number;
309
+ }>("sequence_stats");
310
+ if (!r.ok) return exitFromIpcResult(r);
311
+
312
+ const stats = r.result!;
313
+
314
+ if (json) {
315
+ console.log(JSON.stringify({ ok: true, ...stats }));
316
+ return;
317
+ }
352
318
 
353
- guardrailsCmd.addHelpText(
354
- "after",
355
- `
319
+ process.stdout.write(`Sequence Stats:\n`);
320
+ process.stdout.write(
321
+ ` Sequences: ${stats.totalSequences} total, ${stats.activeSequences} active\n`,
322
+ );
323
+ process.stdout.write(
324
+ ` Enrollments: ${stats.totalEnrollments} total, ${stats.activeEnrollments} active\n\n`,
325
+ );
326
+ });
327
+
328
+ // ── guardrails ─────────────────────────────────────────────────
329
+ const guardrailsCmd = seqCmd
330
+ .command("guardrails")
331
+ .description("View or update guardrail settings");
332
+
333
+ guardrailsCmd.addHelpText(
334
+ "after",
335
+ `
356
336
  Guardrails are sequence-specific safety limits that prevent excessive
357
337
  sending and protect deliverability. They enforce daily send caps, per-sequence
358
338
  hourly rate limits, minimum delays between steps, maximum concurrent active
@@ -362,14 +342,14 @@ Examples:
362
342
  $ assistant sequence guardrails show
363
343
  $ assistant sequence guardrails set dailySendCap 200
364
344
  $ assistant sequence guardrails set cooldown_days 7`,
365
- );
366
-
367
- guardrailsCmd
368
- .command("show")
369
- .description("Show current guardrail configuration")
370
- .addHelpText(
371
- "after",
372
- `
345
+ );
346
+
347
+ guardrailsCmd
348
+ .command("show")
349
+ .description("Show current guardrail configuration")
350
+ .addHelpText(
351
+ "after",
352
+ `
373
353
  Displays the current guardrail configuration with all safety limits:
374
354
 
375
355
  Daily send cap Max emails sent per day across all sequences
@@ -382,39 +362,46 @@ Displays the current guardrail configuration with all safety limits:
382
362
  Examples:
383
363
  $ assistant sequence guardrails show
384
364
  $ assistant sequence guardrails show --json`,
385
- )
386
- .action((_opts: Record<string, unknown>, cmd: Command) => {
387
- const json = getJson(cmd);
388
- const cfg = getGuardrailConfig();
389
- if (json) {
390
- output({ ok: true, config: cfg }, true);
391
- return;
392
- }
393
- process.stdout.write("Guardrail Configuration:\n");
394
- process.stdout.write(` Daily send cap: ${cfg.dailySendCap}\n`);
395
- process.stdout.write(
396
- ` Hourly rate (per-seq): ${cfg.perSequenceHourlyRate}\n`,
397
- );
398
- process.stdout.write(
399
- ` Min step delay: ${cfg.minimumStepDelaySec}s\n`,
400
- );
401
- process.stdout.write(
402
- ` Max active enrollments: ${cfg.maxActiveEnrollments}\n`,
403
- );
404
- process.stdout.write(
405
- ` Duplicate check: ${cfg.duplicateEnrollmentCheck}\n`,
406
- );
407
- process.stdout.write(
408
- ` Cooldown period: ${formatDuration(cfg.cooldownPeriodMs)}\n\n`,
409
- );
410
- });
411
-
412
- guardrailsCmd
413
- .command("set <key> <value>")
414
- .description("Update a guardrail setting")
415
- .addHelpText(
416
- "after",
417
- `
365
+ )
366
+ .action(async () => {
367
+ const json = resolveJson(seqCmd);
368
+ const r = await cliIpcCall<{ config: GuardrailConfig }>(
369
+ "sequence_guardrails_show",
370
+ );
371
+ if (!r.ok) return exitFromIpcResult(r);
372
+
373
+ const cfg = r.result!.config;
374
+
375
+ if (json) {
376
+ console.log(JSON.stringify({ ok: true, config: cfg }));
377
+ return;
378
+ }
379
+
380
+ process.stdout.write("Guardrail Configuration:\n");
381
+ process.stdout.write(` Daily send cap: ${cfg.dailySendCap}\n`);
382
+ process.stdout.write(
383
+ ` Hourly rate (per-seq): ${cfg.perSequenceHourlyRate}\n`,
384
+ );
385
+ process.stdout.write(
386
+ ` Min step delay: ${cfg.minimumStepDelaySec}s\n`,
387
+ );
388
+ process.stdout.write(
389
+ ` Max active enrollments: ${cfg.maxActiveEnrollments}\n`,
390
+ );
391
+ process.stdout.write(
392
+ ` Duplicate check: ${cfg.duplicateEnrollmentCheck}\n`,
393
+ );
394
+ process.stdout.write(
395
+ ` Cooldown period: ${formatDuration(cfg.cooldownPeriodMs)}\n\n`,
396
+ );
397
+ });
398
+
399
+ guardrailsCmd
400
+ .command("set <key> <value>")
401
+ .description("Update a guardrail setting")
402
+ .addHelpText(
403
+ "after",
404
+ `
418
405
  Arguments:
419
406
  key The guardrail setting name (see valid keys below)
420
407
  value The new value (numeric for limits/caps, true/false for booleans)
@@ -433,71 +420,40 @@ Examples:
433
420
  $ assistant sequence guardrails set hourly_rate 50
434
421
  $ assistant sequence guardrails set duplicate_check true
435
422
  $ assistant sequence guardrails set cooldown_days 7`,
436
- )
437
- .action(
438
- (
439
- key: string,
440
- value: string,
441
- _opts: Record<string, unknown>,
442
- cmd: Command,
443
- ) => {
444
- const json = getJson(cmd);
445
- const numVal = Number(value);
446
- const boolVal =
447
- value === "true" ? true : value === "false" ? false : undefined;
448
-
449
- const patch: Partial<ReturnType<typeof getGuardrailConfig>> = {};
450
- switch (key) {
451
- case "dailySendCap":
452
- case "daily_send_cap":
453
- if (!Number.isFinite(numVal))
454
- return exitError(`Invalid numeric value for ${key}: ${value}`);
455
- patch.dailySendCap = numVal;
456
- break;
457
- case "perSequenceHourlyRate":
458
- case "hourly_rate":
459
- if (!Number.isFinite(numVal))
460
- return exitError(`Invalid numeric value for ${key}: ${value}`);
461
- patch.perSequenceHourlyRate = numVal;
462
- break;
463
- case "minimumStepDelaySec":
464
- case "min_delay":
465
- if (!Number.isFinite(numVal))
466
- return exitError(`Invalid numeric value for ${key}: ${value}`);
467
- patch.minimumStepDelaySec = numVal;
468
- break;
469
- case "maxActiveEnrollments":
470
- case "max_enrollments":
471
- if (!Number.isFinite(numVal))
472
- return exitError(`Invalid numeric value for ${key}: ${value}`);
473
- patch.maxActiveEnrollments = numVal;
474
- break;
475
- case "duplicateEnrollmentCheck":
476
- case "duplicate_check":
477
- if (boolVal === undefined)
478
- return exitError("Value must be true or false");
479
- patch.duplicateEnrollmentCheck = boolVal;
480
- break;
481
- case "cooldownPeriodMs":
482
- if (!Number.isFinite(numVal))
483
- return exitError(`Invalid numeric value for ${key}: ${value}`);
484
- patch.cooldownPeriodMs = numVal;
485
- break;
486
- case "cooldown_days": {
487
- if (!Number.isFinite(numVal))
488
- return exitError(`Invalid numeric value for ${key}: ${value}`);
489
- patch.cooldownPeriodMs = numVal * 24 * 60 * 60 * 1000;
490
- break;
423
+ )
424
+ .action(async (key: string, value: string) => {
425
+ const json = resolveJson(seqCmd);
426
+ const r = await cliIpcCall<{ message: string; config: GuardrailConfig }>(
427
+ "sequence_guardrails_set",
428
+ { key, value },
429
+ );
430
+ if (!r.ok) return exitFromIpcResult(r);
431
+
432
+ if (json) {
433
+ console.log(
434
+ JSON.stringify({
435
+ ok: true,
436
+ message: r.result!.message,
437
+ config: r.result!.config,
438
+ }),
439
+ );
440
+ } else {
441
+ process.stdout.write(r.result!.message + "\n");
491
442
  }
492
- default:
493
- return exitError(`Unknown guardrail key: ${key}`);
494
- }
495
-
496
- const updated = setGuardrailConfig(patch);
497
- output(
498
- { ok: true, message: `Updated ${key} = ${value}`, config: updated },
499
- json,
500
- );
501
- },
502
- );
443
+ });
444
+ },
445
+ });
446
+ }
447
+
448
+ // ---------------------------------------------------------------------------
449
+ // Helpers
450
+ // ---------------------------------------------------------------------------
451
+
452
+ function resolveJson(cmd: Command): boolean {
453
+ let c: Command | null = cmd;
454
+ while (c) {
455
+ if ((c.opts() as { json?: boolean }).json) return true;
456
+ c = c.parent;
457
+ }
458
+ return false;
503
459
  }