@vellumai/assistant 0.10.4 → 0.10.5-dev.202607022329.d89bf2f

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 (866) hide show
  1. package/ARCHITECTURE.md +94 -91
  2. package/Dockerfile +5 -16
  3. package/README.md +7 -10
  4. package/bun.lock +0 -4
  5. package/docs/architecture/security.md +20 -20
  6. package/docs/stt-provider-onboarding.md +4 -5
  7. package/docs/trusted-contact-access.md +7 -7
  8. package/eslint-rules/cli-no-daemon-internals.js +4 -0
  9. package/eslint.config.mjs +7 -1
  10. package/knip.json +0 -1
  11. package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +36 -0
  12. package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +233 -0
  13. package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +40 -0
  14. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -8
  15. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  16. package/node_modules/@vellumai/gateway-client/src/index.ts +33 -0
  17. package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +216 -0
  18. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +91 -0
  19. package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +39 -3
  20. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +0 -8
  21. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +1 -5
  22. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +3 -14
  23. package/openapi.yaml +1073 -225
  24. package/package.json +1 -4
  25. package/scripts/test.sh +35 -13
  26. package/src/__tests__/access-request-seed-content-blocks.test.ts +60 -4
  27. package/src/__tests__/acp-session.test.ts +4 -1
  28. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +0 -6
  29. package/src/__tests__/add-message-preassigned-id.test.ts +56 -0
  30. package/src/__tests__/agent-loop-set-system-prompt.test.ts +139 -0
  31. package/src/__tests__/app-conversation-ids-backfill.test.ts +3 -0
  32. package/src/__tests__/app-source-watcher.test.ts +11 -0
  33. package/src/__tests__/approval-interception-trust-gates.test.ts +148 -3
  34. package/src/__tests__/assistant-attachments.test.ts +62 -4
  35. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -1
  36. package/src/__tests__/attachments-store-heic-normalize.test.ts +230 -0
  37. package/src/__tests__/attachments-store.test.ts +3 -0
  38. package/src/__tests__/background-shell-bash.test.ts +34 -0
  39. package/src/__tests__/background-shell-host-bash.test.ts +12 -0
  40. package/src/__tests__/background-tool-registry.test.ts +97 -0
  41. package/src/__tests__/background-tool-routes.test.ts +72 -1
  42. package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
  43. package/src/__tests__/btw-routes.test.ts +57 -3
  44. package/src/__tests__/call-controller.test.ts +474 -84
  45. package/src/__tests__/call-domain.test.ts +48 -1
  46. package/src/__tests__/call-pointer-messages.test.ts +57 -19
  47. package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +2 -6
  48. package/src/__tests__/call-routes-http.test.ts +15 -14
  49. package/src/__tests__/call-setup-flow-invite.test.ts +568 -0
  50. package/src/__tests__/call-setup-flow-midcall-trust.test.ts +231 -0
  51. package/src/__tests__/call-setup-flow-name-capture.test.ts +754 -0
  52. package/src/__tests__/call-setup-flow-verification.test.ts +925 -0
  53. package/src/__tests__/call-setup-flow.test.ts +311 -0
  54. package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -1
  55. package/src/__tests__/channel-guardian.test.ts +4 -7
  56. package/src/__tests__/channel-readiness-service.test.ts +0 -6
  57. package/src/__tests__/channel-readiness-slack-remote.test.ts +0 -4
  58. package/src/__tests__/channel-retry-sweep.test.ts +76 -64
  59. package/src/__tests__/channel-setup-panel-ack.test.ts +184 -0
  60. package/src/__tests__/clear-all-lexical.test.ts +90 -0
  61. package/src/__tests__/compactor-media-strip.test.ts +177 -0
  62. package/src/__tests__/config-loader-backfill.test.ts +5 -5
  63. package/src/__tests__/config-schema.test.ts +17 -0
  64. package/src/__tests__/contact-store-interaction-info.test.ts +27 -70
  65. package/src/__tests__/contacts-relay-reads.test.ts +188 -23
  66. package/src/__tests__/contacts-tools.test.ts +42 -1
  67. package/src/__tests__/contacts-write.test.ts +181 -0
  68. package/src/__tests__/context-search-conversations-source.test.ts +220 -81
  69. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
  70. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
  71. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  72. package/src/__tests__/conversation-agent-loop.test.ts +39 -0
  73. package/src/__tests__/conversation-analysis-routes.test.ts +1 -1
  74. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -0
  75. package/src/__tests__/conversation-clear-safety.test.ts +0 -1
  76. package/src/__tests__/conversation-crud-enabled-plugins.test.ts +60 -0
  77. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -1
  78. package/src/__tests__/conversation-disk-view.test.ts +1 -0
  79. package/src/__tests__/conversation-enabledplugins-route.test.ts +184 -0
  80. package/src/__tests__/conversation-error.test.ts +0 -18
  81. package/src/__tests__/conversation-fork-crud.test.ts +67 -0
  82. package/src/__tests__/conversation-history-web-search.test.ts +7 -137
  83. package/src/__tests__/conversation-initial-prompt.test.ts +110 -0
  84. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +191 -0
  85. package/src/__tests__/conversation-process-callsite.test.ts +37 -0
  86. package/src/__tests__/conversation-queue.test.ts +149 -0
  87. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +392 -0
  88. package/src/__tests__/conversation-routes-guardian-reply.test.ts +84 -0
  89. package/src/__tests__/conversation-routes-hidden-queue.test.ts +407 -0
  90. package/src/__tests__/conversation-runtime-assembly.test.ts +36 -16
  91. package/src/__tests__/conversation-skill-tools.test.ts +73 -0
  92. package/src/__tests__/conversation-wipe.test.ts +20 -5
  93. package/src/__tests__/credential-prompt-route.test.ts +69 -0
  94. package/src/__tests__/credential-security-invariants.test.ts +1 -3
  95. package/src/__tests__/db-drop-messages-fts.test.ts +115 -0
  96. package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -62
  97. package/src/__tests__/edit-propagation.test.ts +56 -2
  98. package/src/__tests__/empty-state-greeting-cache.test.ts +9 -0
  99. package/src/__tests__/gateway-only-enforcement.test.ts +15 -110
  100. package/src/__tests__/guardian-expiry-notifier.test.ts +1 -0
  101. package/src/__tests__/guardian-question-mode.test.ts +57 -0
  102. package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
  103. package/src/__tests__/guardian-wait-controller.test.ts +619 -0
  104. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +33 -2
  105. package/src/__tests__/heic-fixture.ts +55 -0
  106. package/src/__tests__/helpers/seed-contact-channel.ts +0 -2
  107. package/src/__tests__/http-conversation-lineage.test.ts +6 -1
  108. package/src/__tests__/image-conversion.test.ts +170 -0
  109. package/src/__tests__/inbound-invite-redemption.test.ts +72 -341
  110. package/src/__tests__/introduction-card-resolver.test.ts +354 -0
  111. package/src/__tests__/invite-redeemed-ipc.test.ts +97 -0
  112. package/src/__tests__/invite-routes-http.test.ts +246 -420
  113. package/src/__tests__/job-handler-registration-guard.test.ts +104 -0
  114. package/src/__tests__/lexical-index-dual-write.test.ts +426 -0
  115. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +2 -2
  116. package/src/__tests__/list-messages-attachments.test.ts +159 -0
  117. package/src/__tests__/list-messages-background-tool-completion.test.ts +141 -0
  118. package/src/__tests__/list-messages-queued.test.ts +25 -0
  119. package/src/__tests__/managed-store.test.ts +129 -1
  120. package/src/__tests__/media-stream-audio-transcode.test.ts +113 -0
  121. package/src/__tests__/media-stream-output.test.ts +350 -19
  122. package/src/__tests__/media-stream-server-integration.test.ts +943 -169
  123. package/src/__tests__/media-stream-stt-session.test.ts +498 -1
  124. package/src/__tests__/memory-jobs-worker-lanes.test.ts +2 -2
  125. package/src/__tests__/model-intents.test.ts +1 -1
  126. package/src/__tests__/mtime-cache.test.ts +19 -0
  127. package/src/__tests__/non-member-access-request.test.ts +349 -3
  128. package/src/__tests__/notification-decision-fallback.test.ts +104 -8
  129. package/src/__tests__/notification-decision-strategy.test.ts +57 -8
  130. package/src/__tests__/onboarding-template-contract.test.ts +27 -43
  131. package/src/__tests__/openai-provider.test.ts +33 -0
  132. package/src/__tests__/openai-responses-provider.test.ts +40 -0
  133. package/src/__tests__/persistence-layering-guard.test.ts +29 -20
  134. package/src/__tests__/persona-resolver.test.ts +56 -2
  135. package/src/__tests__/personal-memory-auth-bypass.test.ts +62 -0
  136. package/src/__tests__/phone.test.ts +1 -15
  137. package/src/__tests__/plugin-bootstrap.test.ts +25 -196
  138. package/src/__tests__/plugin-disabled-state.test.ts +33 -0
  139. package/src/__tests__/plugin-effective-enabled-set.test.ts +227 -0
  140. package/src/__tests__/plugin-event-hub-facade.test.ts +323 -0
  141. package/src/__tests__/plugin-import-boundary-guard.test.ts +156 -42
  142. package/src/__tests__/plugin-injector-contribution.test.ts +4 -20
  143. package/src/__tests__/plugin-pipeline.test.ts +63 -1
  144. package/src/__tests__/plugin-route-contribution.test.ts +62 -115
  145. package/src/__tests__/plugin-tool-contribution.test.ts +0 -22
  146. package/src/__tests__/plugin-types.test.ts +0 -1
  147. package/src/__tests__/pointer-conversation-trust.test.ts +38 -6
  148. package/src/__tests__/pre-model-call-sanitize.test.ts +1 -1
  149. package/src/__tests__/prune-old-tool-invocations-job.test.ts +97 -0
  150. package/src/__tests__/public-ingress-urls.test.ts +0 -48
  151. package/src/__tests__/qdrant-collection-migration.test.ts +145 -2
  152. package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +0 -1
  153. package/src/__tests__/resolve-trust-class.test.ts +28 -10
  154. package/src/__tests__/scaffold-managed-skill-tool.test.ts +137 -0
  155. package/src/__tests__/schedule-retry.test.ts +38 -14
  156. package/src/__tests__/schedule-routes-workflow-validation.test.ts +3 -3
  157. package/src/__tests__/schedule-routes.test.ts +14 -6
  158. package/src/__tests__/schedule-store.test.ts +3 -1
  159. package/src/__tests__/scheduler-disk-pressure.test.ts +17 -6
  160. package/src/__tests__/scheduler-recurrence.test.ts +57 -107
  161. package/src/__tests__/scheduler-reuse-conversation.test.ts +51 -46
  162. package/src/__tests__/scheduler-wake.test.ts +13 -23
  163. package/src/__tests__/scheduler-worker-standdown.test.ts +220 -0
  164. package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
  165. package/src/__tests__/shell-observability.test.ts +1 -0
  166. package/src/__tests__/skill-boundary-guard.test.ts +3 -4
  167. package/src/__tests__/skill-load-plugin-scope.test.ts +238 -0
  168. package/src/__tests__/skill-projection-feature-flag.test.ts +2 -0
  169. package/src/__tests__/skill-script-runner-host.test.ts +53 -0
  170. package/src/__tests__/skill-script-runner-sandbox.test.ts +5 -2
  171. package/src/__tests__/skill-tool-factory.test.ts +73 -1
  172. package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -14
  173. package/src/__tests__/slack-inbound-verification.test.ts +36 -0
  174. package/src/__tests__/slack-notification-approval-card.test.ts +89 -2
  175. package/src/__tests__/slack-reaction-canonical-approval.test.ts +51 -1
  176. package/src/__tests__/stt-hints.test.ts +2 -256
  177. package/src/__tests__/subagent-allowlist-validation.test.ts +47 -0
  178. package/src/__tests__/subagent-call-site-routing.test.ts +72 -0
  179. package/src/__tests__/subagent-fork-notifications.test.ts +14 -2
  180. package/src/__tests__/subagent-persistence.test.ts +122 -0
  181. package/src/__tests__/subagent-spawn-and-await.test.ts +1 -0
  182. package/src/__tests__/subagent-terminal-message.test.ts +99 -0
  183. package/src/__tests__/subagent-tool-gate-mode.test.ts +78 -1
  184. package/src/__tests__/system-prompt.test.ts +17 -118
  185. package/src/__tests__/task-scheduler.test.ts +68 -89
  186. package/src/__tests__/telephony-credential-preflight.test.ts +312 -0
  187. package/src/__tests__/telephony-tts-guard.test.ts +538 -0
  188. package/src/__tests__/title-generate-hook.test.ts +16 -0
  189. package/src/__tests__/tool-approval-handler.test.ts +87 -1
  190. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +45 -20
  191. package/src/__tests__/tool-grant-request-escalation.test.ts +39 -0
  192. package/src/__tests__/trust-context-guards.test.ts +21 -10
  193. package/src/__tests__/trusted-contact-multichannel.test.ts +4 -0
  194. package/src/__tests__/twilio-provider.test.ts +17 -17
  195. package/src/__tests__/twilio-routes-twiml.test.ts +6 -543
  196. package/src/__tests__/twilio-routes.test.ts +257 -387
  197. package/src/__tests__/twilio-validation.test.ts +1 -1
  198. package/src/__tests__/unified-turn-context-client-os.test.ts +45 -0
  199. package/src/__tests__/usage-cache-backfill-migration.test.ts +5 -0
  200. package/src/__tests__/voice-approval-resolver-relay.test.ts +150 -0
  201. package/src/__tests__/voice-ingress-preflight.test.ts +61 -0
  202. package/src/__tests__/voice-quality.test.ts +2 -2
  203. package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -7
  204. package/src/__tests__/voice-session-bridge-processing-wait.test.ts +27 -0
  205. package/src/__tests__/voice-session-bridge.test.ts +1 -10
  206. package/src/__tests__/workspace-git-service.test.ts +1 -1
  207. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -0
  208. package/src/__tests__/workspace-migration-118-seed-now-md.test.ts +120 -0
  209. package/src/__tests__/workspace-migration-120-revise-onboarding-threads.test.ts +175 -0
  210. package/src/__tests__/workspace-migration-121-seed-default-user-guardrails.test.ts +118 -0
  211. package/src/__tests__/workspace-migration-122-relocate-default-user-boundary.test.ts +119 -0
  212. package/src/__tests__/workspace-migration-123-swap-quality-profile-to-fable.test.ts +191 -0
  213. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +235 -241
  214. package/src/acp/__tests__/prepare-agent-env.test.ts +0 -97
  215. package/src/acp/__tests__/session-manager-persistence.test.ts +2 -0
  216. package/src/acp/__tests__/session-manager-resume.test.ts +8 -0
  217. package/src/acp/__tests__/session-manager-usage.test.ts +6 -0
  218. package/src/acp/__tests__/session-manager.test.ts +6 -0
  219. package/src/acp/agent-process.test.ts +116 -0
  220. package/src/acp/agent-process.ts +71 -0
  221. package/src/acp/auto-install.ts +12 -8
  222. package/src/acp/failure-error.test.ts +109 -0
  223. package/src/acp/failure-error.ts +111 -0
  224. package/src/acp/prepare-agent-env.ts +0 -12
  225. package/src/acp/resolve-agent.test.ts +6 -45
  226. package/src/acp/resolve-agent.ts +2 -4
  227. package/src/acp/session-manager.test.ts +312 -0
  228. package/src/acp/session-manager.ts +102 -46
  229. package/src/agent/ax-tree-compaction.test.ts +4 -1
  230. package/src/agent/image-optimize.ts +17 -127
  231. package/src/agent/loop.ts +45 -192
  232. package/src/api/events/background-tool-completed.test.ts +51 -0
  233. package/src/api/events/background-tool-completed.ts +29 -0
  234. package/src/api/events/background-tool-started.test.ts +36 -0
  235. package/src/api/events/background-tool-started.ts +28 -0
  236. package/src/api/events/conversation-error.ts +0 -1
  237. package/src/api/events/open-panel.ts +33 -0
  238. package/src/api/events/subagent-status-changed.ts +4 -1
  239. package/src/api/index.ts +19 -0
  240. package/src/api/responses/conversation-message.ts +34 -0
  241. package/src/approvals/guardian-decision-primitive.ts +74 -24
  242. package/src/approvals/guardian-request-resolvers.ts +450 -122
  243. package/src/apps/app-store.ts +1 -0
  244. package/src/apps/shared-app-links-store.ts +1 -0
  245. package/src/avatar/identity-avatar.ts +3 -7
  246. package/src/background-wake/wake-intent-hooks.test.ts +1 -1
  247. package/src/calls/__tests__/fish-audio-client.test.ts +73 -0
  248. package/src/calls/__tests__/gateway-invite-reader.test.ts +170 -0
  249. package/src/calls/__tests__/relay-setup-router.test.ts +126 -102
  250. package/src/calls/call-controller.ts +134 -48
  251. package/src/calls/call-domain.ts +18 -42
  252. package/src/calls/call-pointer-messages.ts +51 -67
  253. package/src/calls/call-setup-flow-types.ts +76 -0
  254. package/src/calls/call-setup-flow.ts +1743 -0
  255. package/src/calls/call-speech-output.ts +87 -23
  256. package/src/calls/call-store.ts +4 -0
  257. package/src/calls/call-transport.ts +22 -36
  258. package/src/calls/fish-audio-client.ts +3 -0
  259. package/src/calls/gateway-invite-reader.ts +98 -0
  260. package/src/calls/guardian-wait-controller.ts +451 -0
  261. package/src/calls/media-stream-audio-transcode.ts +82 -2
  262. package/src/calls/media-stream-output.ts +142 -36
  263. package/src/calls/media-stream-server.ts +297 -178
  264. package/src/calls/media-stream-stt-session.ts +393 -50
  265. package/src/calls/media-turn-detector.ts +4 -6
  266. package/src/calls/relay-access-wait.ts +3 -4
  267. package/src/calls/relay-setup-router.ts +22 -43
  268. package/src/calls/relay-verification.ts +17 -24
  269. package/src/calls/resolve-call-tts-provider.ts +96 -29
  270. package/src/calls/stt-hints.ts +24 -87
  271. package/src/calls/telephony-credential-preflight.ts +159 -0
  272. package/src/calls/telephony-tts-capability.ts +183 -0
  273. package/src/calls/tts-call-strategy.ts +18 -20
  274. package/src/calls/twilio-provider.ts +3 -2
  275. package/src/calls/twilio-routes.ts +47 -351
  276. package/src/calls/types.ts +5 -3
  277. package/src/calls/voice-ingress-preflight.ts +9 -0
  278. package/src/calls/voice-quality.ts +13 -18
  279. package/src/calls/voice-session-bridge.ts +25 -35
  280. package/src/channels/__tests__/types.test.ts +28 -0
  281. package/src/channels/channel-verification-sessions.ts +7 -2
  282. package/src/channels/config.ts +0 -42
  283. package/src/channels/slack-thread-store.ts +12 -0
  284. package/src/channels/types.ts +23 -0
  285. package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -1
  286. package/src/cli/commands/__tests__/schedules.test.ts +83 -34
  287. package/src/cli/commands/__tests__/status.test.ts +42 -2
  288. package/src/cli/commands/contacts.ts +2 -2
  289. package/src/cli/commands/credentials.ts +17 -0
  290. package/src/cli/commands/monitoring.ts +191 -0
  291. package/src/cli/commands/schedules-worker.ts +175 -0
  292. package/src/cli/commands/schedules.ts +169 -43
  293. package/src/cli/commands/status.ts +12 -1
  294. package/src/cli/commands/tools.ts +5 -1
  295. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +1 -0
  296. package/src/cli/lib/__tests__/search-plugins.test.ts +29 -1
  297. package/src/cli/lib/__tests__/toggle-plugin.test.ts +7 -0
  298. package/src/cli/lib/search-plugins.ts +6 -0
  299. package/src/cli/lib/toggle-plugin.ts +21 -2
  300. package/src/cli/program.ts +3 -1
  301. package/src/config/__tests__/deployment-context-defaults.test.ts +23 -0
  302. package/src/config/acp-defaults.test.ts +0 -10
  303. package/src/config/acp-defaults.ts +0 -6
  304. package/src/config/bundled-skills/acp/SKILL.md +13 -45
  305. package/src/config/bundled-skills/acp/TOOLS.json +3 -3
  306. package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
  307. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +9 -9
  308. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +1 -1
  309. package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -1
  310. package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
  311. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -9
  312. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +10 -7
  313. package/src/config/bundled-skills/skill-management/TOOLS.json +10 -0
  314. package/src/config/call-site-defaults.ts +0 -2
  315. package/src/config/feature-flag-registry.json +16 -8
  316. package/src/config/loader.ts +11 -0
  317. package/src/config/schema.ts +9 -1
  318. package/src/config/schemas/__tests__/memory-v2.test.ts +2 -2
  319. package/src/config/schemas/__tests__/memory-v3.test.ts +64 -0
  320. package/src/config/schemas/call-site-catalog.ts +0 -12
  321. package/src/config/schemas/calls.ts +8 -0
  322. package/src/config/schemas/elevenlabs.ts +1 -1
  323. package/src/config/schemas/llm.ts +0 -2
  324. package/src/config/schemas/memory-v2.ts +1 -1
  325. package/src/config/schemas/memory-v3.ts +82 -0
  326. package/src/config/schemas/monitoring.ts +61 -0
  327. package/src/config/schemas/schedules.ts +35 -0
  328. package/src/config/seed-inference-profiles.ts +2 -2
  329. package/src/config/skills-plugin-filter.test.ts +96 -0
  330. package/src/config/skills.ts +26 -0
  331. package/src/contacts/__tests__/member-write-relay.test.ts +156 -4
  332. package/src/contacts/canonical-guardian-store.ts +5 -0
  333. package/src/contacts/contact-store.ts +81 -35
  334. package/src/contacts/contacts-write.ts +50 -25
  335. package/src/contacts/member-write-relay.ts +115 -31
  336. package/src/contacts/types.ts +0 -8
  337. package/src/context/compactor.ts +29 -15
  338. package/src/context/outbound-sanitize.ts +202 -0
  339. package/src/daemon/__tests__/abort-null-controller.test.ts +167 -0
  340. package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +122 -0
  341. package/src/daemon/__tests__/embedding-reconcile.test.ts +99 -16
  342. package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +107 -0
  343. package/src/daemon/abort-watchdog.ts +7 -0
  344. package/src/daemon/app-source-watcher.ts +9 -0
  345. package/src/daemon/assistant-attachments.ts +42 -0
  346. package/src/daemon/conversation-agent-loop-handlers.ts +256 -147
  347. package/src/daemon/conversation-agent-loop.ts +61 -68
  348. package/src/daemon/conversation-error.ts +1 -15
  349. package/src/daemon/conversation-history.ts +32 -236
  350. package/src/daemon/conversation-initial-prompt.ts +77 -0
  351. package/src/daemon/conversation-lifecycle.ts +25 -1
  352. package/src/daemon/conversation-messaging.ts +2 -2
  353. package/src/daemon/conversation-plugin-scope.ts +38 -0
  354. package/src/daemon/conversation-process.ts +50 -14
  355. package/src/daemon/conversation-runtime-assembly.ts +36 -6
  356. package/src/daemon/conversation-skill-tools.ts +19 -3
  357. package/src/daemon/conversation-store.ts +3 -3
  358. package/src/daemon/conversation-surfaces.ts +171 -0
  359. package/src/daemon/conversation-tool-setup.test.ts +95 -0
  360. package/src/daemon/conversation-tool-setup.ts +116 -1
  361. package/src/daemon/conversation-turn-finalize.ts +211 -0
  362. package/src/daemon/conversation.ts +92 -1
  363. package/src/daemon/disk-pressure-policy.ts +2 -1
  364. package/src/daemon/event-loop-watchdog.ts +22 -6
  365. package/src/daemon/external-plugins-bootstrap.ts +47 -134
  366. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
  367. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +26 -14
  368. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +27 -14
  369. package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -5
  370. package/src/daemon/handlers/config-a2a.ts +7 -14
  371. package/src/daemon/handlers/config-channels.ts +2 -10
  372. package/src/daemon/handlers/conversation-history.ts +3 -1
  373. package/src/daemon/handlers/conversations.ts +0 -52
  374. package/src/daemon/handlers/shared.ts +4 -24
  375. package/src/daemon/handlers/skills.ts +4 -1
  376. package/src/daemon/host-cu-proxy.ts +1 -1
  377. package/src/daemon/lifecycle.ts +59 -472
  378. package/src/daemon/message-protocol.ts +3 -3
  379. package/src/daemon/message-provenance.ts +12 -14
  380. package/src/daemon/message-types/background-tools.ts +28 -0
  381. package/src/daemon/message-types/contacts.ts +2 -10
  382. package/src/daemon/message-types/conversations.ts +10 -0
  383. package/src/daemon/message-types/integrations.ts +2 -0
  384. package/src/daemon/message-types/surfaces.ts +1 -0
  385. package/src/daemon/message-types/sync.ts +1 -0
  386. package/src/daemon/pointer-conversation-trust.ts +23 -9
  387. package/src/daemon/pointer-turn-runner.ts +174 -0
  388. package/src/daemon/providers-setup.ts +16 -0
  389. package/src/daemon/shutdown-handlers.ts +139 -47
  390. package/src/daemon/skill-memory-refresh.ts +2 -2
  391. package/src/daemon/sqlite-corruption-watchdog.test.ts +217 -0
  392. package/src/daemon/sqlite-corruption-watchdog.ts +155 -0
  393. package/src/daemon/tool-setup-types.ts +8 -0
  394. package/src/daemon/trust-context.ts +21 -6
  395. package/src/daemon/turn-latency-tracker.test.ts +93 -0
  396. package/src/daemon/turn-latency-tracker.ts +38 -0
  397. package/src/daemon/wake-conversation-ops.ts +10 -8
  398. package/src/documents/document-comments-store.test.ts +7 -1
  399. package/src/documents/document-comments-store.ts +8 -0
  400. package/src/documents/document-store.ts +15 -0
  401. package/src/export/__tests__/transcript-formatter.test.ts +11 -0
  402. package/src/export/transcript-formatter.ts +49 -67
  403. package/src/home/__tests__/feed-writer.test.ts +247 -1
  404. package/src/home/conversation-starter-checkpoints.ts +1 -0
  405. package/src/home/feed-writer.ts +61 -0
  406. package/src/home/job-handlers/conversation-starters.ts +1 -0
  407. package/src/hooks/hook-loader.ts +12 -0
  408. package/src/hooks/registry.ts +32 -4
  409. package/src/inbound/public-ingress-urls.ts +0 -17
  410. package/src/ipc/__tests__/contacts-info-ipc.test.ts +285 -0
  411. package/src/ipc/assistant-server.ts +28 -7
  412. package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +62 -0
  413. package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +272 -0
  414. package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +322 -0
  415. package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +60 -4
  416. package/src/ipc/routes/contacts-info-ipc-routes.ts +239 -0
  417. package/src/ipc/routes/contacts-mirror-ipc-routes.ts +202 -0
  418. package/src/ipc/routes/db-proxy.ts +5 -2
  419. package/src/ipc/routes/invite-ipc-routes.ts +53 -39
  420. package/src/jobs/worker.ts +9 -2
  421. package/src/live-voice/__tests__/live-voice-archive.test.ts +10 -1
  422. package/src/live-voice/live-voice-archive.ts +5 -0
  423. package/src/messaging/providers/__tests__/transport-dispatch.test.ts +22 -6
  424. package/src/messaging/providers/channel-transport.ts +6 -0
  425. package/src/messaging/providers/index.ts +3 -0
  426. package/src/messaging/providers/slack/api.test.ts +49 -1
  427. package/src/messaging/providers/slack/api.ts +110 -0
  428. package/src/messaging/providers/slack/send.test.ts +85 -0
  429. package/src/messaging/providers/slack/send.ts +100 -28
  430. package/src/messaging/providers/slack/transport.ts +7 -13
  431. package/src/messaging/providers/whatsapp/send.ts +29 -9
  432. package/src/monitoring/__tests__/control.test.ts +235 -0
  433. package/src/monitoring/__tests__/sample-ring-buffer.test.ts +96 -0
  434. package/src/monitoring/control.ts +105 -0
  435. package/src/monitoring/resource-sampler.ts +258 -0
  436. package/src/monitoring/sample-ring-buffer.ts +108 -0
  437. package/src/monitoring/worker.ts +94 -0
  438. package/src/notifications/README.md +1 -1
  439. package/src/notifications/access-request-copy.ts +94 -23
  440. package/src/notifications/adapters/slack.ts +89 -21
  441. package/src/notifications/approval-card-builder.ts +33 -18
  442. package/src/notifications/approval-card-data.ts +48 -15
  443. package/src/notifications/broadcaster.ts +25 -16
  444. package/src/notifications/decision-engine.ts +131 -32
  445. package/src/notifications/guardian-question-mode.ts +58 -10
  446. package/src/permissions/approval-policy.ts +8 -1
  447. package/src/permissions/checker.ts +2 -0
  448. package/src/permissions/gateway-threshold-reader.ts +7 -6
  449. package/src/permissions/ipc-risk-types.ts +1 -0
  450. package/src/permissions/secret-prompter.ts +11 -3
  451. package/src/permissions/types.ts +2 -2
  452. package/src/persistence/__tests__/conversation-queries-search.test.ts +397 -0
  453. package/src/persistence/__tests__/conversation-search-lexical.test.ts +103 -0
  454. package/src/persistence/__tests__/jobs-worker-memory-disabled.test.ts +95 -0
  455. package/src/persistence/__tests__/slow-query-log.test.ts +266 -0
  456. package/src/persistence/__tests__/slow-sync-log.test.ts +155 -0
  457. package/src/persistence/a2a-invite-store.ts +205 -0
  458. package/src/persistence/attachments-store.ts +94 -10
  459. package/src/persistence/checkpoints.ts +45 -0
  460. package/src/persistence/conversation-crud.ts +453 -260
  461. package/src/persistence/conversation-display-order-migration.ts +8 -2
  462. package/src/persistence/conversation-group-migration.test.ts +8 -0
  463. package/src/persistence/conversation-group-migration.ts +9 -0
  464. package/src/persistence/conversation-queries.ts +244 -125
  465. package/src/persistence/conversation-row-batch-delete.ts +9 -5
  466. package/src/persistence/conversation-search-lexical.ts +49 -0
  467. package/src/persistence/db-async-query.ts +42 -0
  468. package/src/persistence/db-connection.ts +13 -0
  469. package/src/persistence/delivery-channels.ts +0 -82
  470. package/src/persistence/delivery-crud.ts +27 -6
  471. package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +18 -5
  472. package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +334 -0
  473. package/src/persistence/embeddings/embedding-identity.ts +17 -5
  474. package/src/persistence/embeddings/embedding-runtime-manager.ts +31 -0
  475. package/src/persistence/embeddings/messages-lexical-index.ts +396 -0
  476. package/src/persistence/embeddings/qdrant-client.ts +81 -5
  477. package/src/persistence/group-crud.ts +13 -1
  478. package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +506 -0
  479. package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +164 -0
  480. package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +259 -0
  481. package/src/persistence/job-handlers/cleanup.ts +57 -9
  482. package/src/persistence/job-handlers/message-lexical-backfill.ts +187 -0
  483. package/src/persistence/job-handlers/message-lexical.ts +251 -0
  484. package/src/persistence/jobs-store.ts +102 -8
  485. package/src/persistence/jobs-worker.ts +68 -28
  486. package/src/persistence/llm-request-log-store.ts +35 -19
  487. package/src/persistence/llm-usage-store.ts +11 -0
  488. package/src/persistence/memory-lifecycle-hooks.test.ts +65 -0
  489. package/src/persistence/memory-lifecycle-hooks.ts +55 -1
  490. package/src/persistence/migrations/028-call-session-mode.ts +1 -1
  491. package/src/persistence/migrations/116-messages-fts.ts +8 -1
  492. package/src/persistence/migrations/311-create-subagents-table.ts +50 -0
  493. package/src/persistence/migrations/312-drop-inbox-conversation-state-table.ts +15 -0
  494. package/src/persistence/migrations/313-drop-messages-fts.ts +17 -0
  495. package/src/persistence/migrations/314-add-conversation-enabled-plugins.ts +25 -0
  496. package/src/persistence/migrations/315-create-a2a-invites.ts +58 -0
  497. package/src/persistence/migrations/316-drop-contact-channels-invite-id.ts +28 -0
  498. package/src/persistence/migrations/317-canonical-guardian-requester-signals.ts +24 -0
  499. package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +32 -0
  500. package/src/persistence/migrations/__tests__/315-create-a2a-invites.test.ts +161 -0
  501. package/src/persistence/migrations/__tests__/316-drop-contact-channels-invite-id.test.ts +156 -0
  502. package/src/persistence/migrations/__tests__/318-drop-contact-channel-telemetry.test.ts +134 -0
  503. package/src/persistence/migrations/__tests__/migration-prefix-guard.test.ts +99 -0
  504. package/src/persistence/raw-query.ts +50 -11
  505. package/src/persistence/schema/a2a.ts +14 -0
  506. package/src/persistence/schema/contacts.ts +0 -62
  507. package/src/persistence/schema/conversation-groups.ts +12 -0
  508. package/src/persistence/schema/conversations.ts +2 -0
  509. package/src/persistence/schema/documents.ts +65 -0
  510. package/src/persistence/schema/guardian.ts +4 -0
  511. package/src/persistence/schema/index.ts +4 -0
  512. package/src/persistence/schema/memory-injection.ts +62 -0
  513. package/src/persistence/schema/workflows.ts +55 -0
  514. package/src/persistence/slow-query-log.ts +437 -0
  515. package/src/persistence/slow-sync-log.ts +204 -0
  516. package/src/persistence/steps.ts +16 -0
  517. package/src/persistence/subagent-store.ts +125 -0
  518. package/src/persistence/worker-control.ts +45 -238
  519. package/src/plugin-api/event-hub-facade.ts +172 -0
  520. package/src/plugin-api/index.ts +9 -1
  521. package/src/plugin-api/types.ts +40 -9
  522. package/src/plugins/defaults/default-plugin-names.ts +60 -0
  523. package/src/plugins/defaults/index.ts +19 -29
  524. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +46 -67
  525. package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +36 -1
  526. package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +2 -4
  527. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +2 -2
  528. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +9 -0
  529. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +7 -4
  530. package/src/plugins/defaults/memory/config.ts +11 -0
  531. package/src/plugins/defaults/memory/context-search/agent-runner.ts +1 -1
  532. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +124 -113
  533. package/src/plugins/defaults/memory/embeddings.ts +77 -0
  534. package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +66 -0
  535. package/src/plugins/defaults/memory/frontmatter.ts +50 -0
  536. package/src/plugins/defaults/memory/graph/bootstrap.test.ts +36 -10
  537. package/src/plugins/defaults/memory/graph/bootstrap.ts +6 -5
  538. package/src/plugins/defaults/memory/graph/consolidation.ts +3 -5
  539. package/src/plugins/defaults/memory/graph/extraction.ts +3 -6
  540. package/src/plugins/defaults/memory/graph/graph-search.ts +12 -23
  541. package/src/plugins/defaults/memory/graph/narrative.ts +3 -5
  542. package/src/plugins/defaults/memory/graph/pattern-scan.ts +3 -5
  543. package/src/plugins/defaults/memory/graph/retriever.test.ts +1 -6
  544. package/src/plugins/defaults/memory/graph/retriever.ts +5 -10
  545. package/src/plugins/defaults/memory/graph/tools.ts +1 -1
  546. package/src/plugins/defaults/memory/hooks/init.ts +31 -5
  547. package/src/plugins/defaults/memory/indexer.ts +2 -3
  548. package/src/plugins/defaults/memory/injectors.ts +2 -2
  549. package/src/plugins/defaults/memory/job-handler-registration.ts +96 -0
  550. package/src/plugins/defaults/memory/job-handlers/backfill.ts +4 -26
  551. package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +6 -19
  552. package/src/plugins/defaults/memory/job-handlers/embedding.ts +9 -22
  553. package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +2 -3
  554. package/src/plugins/defaults/memory/job-handlers.ts +13 -12
  555. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +1 -1
  556. package/src/plugins/defaults/memory/llm-helpers.ts +76 -0
  557. package/src/plugins/defaults/memory/memory-retrospective-job.ts +8 -5
  558. package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +2 -2
  559. package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +2 -0
  560. package/src/plugins/defaults/memory/persistence-hooks.ts +46 -1
  561. package/src/plugins/defaults/memory/pkb/pkb-index.ts +1 -5
  562. package/src/plugins/defaults/memory/pkb/pkb-search.ts +2 -2
  563. package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +4 -6
  564. package/src/plugins/defaults/memory/routes/memory-item-routes.ts +1 -1
  565. package/src/plugins/defaults/memory/search/semantic.ts +2 -2
  566. package/src/plugins/defaults/memory/startup.ts +244 -0
  567. package/src/plugins/defaults/memory/task-memory-cleanup.ts +8 -0
  568. package/src/{daemon → plugins/defaults/memory/v2}/__tests__/memory-v2-startup.test.ts +6 -6
  569. package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +2 -13
  570. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +4 -5
  571. package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +1 -8
  572. package/src/plugins/defaults/memory/v2/activation.ts +2 -4
  573. package/src/plugins/defaults/memory/v2/cli-command-store.ts +2 -4
  574. package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +1 -1
  575. package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.test.ts +8 -8
  576. package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.ts +20 -22
  577. package/src/plugins/defaults/memory/v2/migration.ts +2 -5
  578. package/src/plugins/defaults/memory/v2/page-store.ts +1 -1
  579. package/src/plugins/defaults/memory/v2/qdrant.ts +2 -3
  580. package/src/plugins/defaults/memory/v2/router.ts +5 -5
  581. package/src/plugins/defaults/memory/v2/sim.ts +2 -4
  582. package/src/plugins/defaults/memory/v2/skill-store.ts +2 -4
  583. package/src/plugins/defaults/memory/v2/sweep-job.ts +6 -6
  584. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +11 -9
  585. package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +107 -2
  586. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +69 -0
  587. package/src/plugins/defaults/memory/v3/__tests__/gate.test.ts +181 -0
  588. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +7 -3
  589. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +345 -8
  590. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +1 -4
  591. package/src/plugins/defaults/memory/v3/__tests__/section-needle.test.ts +64 -0
  592. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +18 -13
  593. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +62 -1
  594. package/src/plugins/defaults/memory/v3/card.ts +1 -4
  595. package/src/plugins/defaults/memory/v3/dense.ts +60 -25
  596. package/src/plugins/defaults/memory/v3/edge.ts +1 -1
  597. package/src/plugins/defaults/memory/v3/gate-flag.ts +20 -0
  598. package/src/plugins/defaults/memory/v3/gate.ts +158 -0
  599. package/src/plugins/defaults/memory/v3/maintain-job.ts +2 -4
  600. package/src/plugins/defaults/memory/v3/orchestrate.ts +186 -25
  601. package/src/plugins/defaults/memory/v3/pool-select.test.ts +7 -9
  602. package/src/plugins/defaults/memory/v3/pool-select.ts +6 -6
  603. package/src/plugins/defaults/memory/v3/prune.ts +2 -2
  604. package/src/plugins/defaults/memory/v3/section-dense-store.ts +8 -11
  605. package/src/plugins/defaults/memory/v3/section-needle.ts +27 -7
  606. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +10 -0
  607. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +1 -4
  608. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +5 -0
  609. package/src/plugins/defaults/turn-context/injectors.ts +1 -0
  610. package/src/plugins/defaults/turn-context/unified-turn-context.ts +12 -0
  611. package/src/plugins/injector-registry.ts +13 -2
  612. package/src/plugins/mtime-cache.ts +36 -47
  613. package/src/plugins/pipeline.ts +15 -1
  614. package/src/plugins/types.ts +14 -23
  615. package/src/prompts/__tests__/system-prompt.test.ts +170 -32
  616. package/src/prompts/persona-resolver.ts +13 -9
  617. package/src/prompts/system-prompt.ts +30 -9
  618. package/src/prompts/templates/BOOTSTRAP.md +16 -119
  619. package/src/prompts/templates/SOUL.md +43 -13
  620. package/src/prompts/templates/system-sections.ts +32 -27
  621. package/src/prompts/templates/users/default.md +19 -0
  622. package/src/providers/__tests__/placeholder-sentinels.test.ts +56 -0
  623. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +96 -1
  624. package/src/providers/model-intents.ts +2 -2
  625. package/src/providers/openai/chat-completions-provider.ts +14 -1
  626. package/src/providers/openai/responses-provider.ts +18 -0
  627. package/src/providers/placeholder-sentinels.ts +18 -8
  628. package/src/providers/retry.ts +1 -0
  629. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +0 -64
  630. package/src/providers/speech-to-text/__tests__/resolve.test.ts +92 -79
  631. package/src/providers/speech-to-text/deepgram-realtime.test.ts +98 -0
  632. package/src/providers/speech-to-text/deepgram-realtime.ts +62 -3
  633. package/src/providers/speech-to-text/provider-catalog.ts +0 -89
  634. package/src/providers/speech-to-text/resolve.ts +55 -0
  635. package/src/providers/tool-progress-events.test.ts +50 -0
  636. package/src/providers/tool-progress-events.ts +99 -0
  637. package/src/providers/types.ts +1 -1
  638. package/src/providers/vellum-model-routing.test.ts +51 -0
  639. package/src/providers/vellum-model-routing.ts +84 -0
  640. package/src/runtime/AGENTS.md +5 -4
  641. package/src/runtime/__tests__/agent-wake.test.ts +158 -1
  642. package/src/runtime/__tests__/channel-verification-service.test.ts +2 -2
  643. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +37 -8
  644. package/src/runtime/access-request-helper.ts +154 -3
  645. package/src/runtime/actor-trust-resolver.ts +7 -21
  646. package/src/runtime/agent-wake.ts +41 -1
  647. package/src/runtime/assistant-event.ts +86 -12
  648. package/src/runtime/auth/__tests__/route-policy.test.ts +31 -0
  649. package/src/runtime/channel-approval-types.ts +52 -2
  650. package/src/runtime/channel-approvals.ts +23 -8
  651. package/src/runtime/channel-invite-transport.ts +2 -2
  652. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  653. package/src/runtime/channel-readiness-service.ts +3 -5
  654. package/src/runtime/channel-retry-sweep.ts +18 -24
  655. package/src/runtime/channel-verification-service.ts +9 -11
  656. package/src/runtime/finalize-event-delivery.ts +30 -16
  657. package/src/runtime/guardian-action-service.ts +10 -11
  658. package/src/runtime/guardian-reply-router.ts +122 -21
  659. package/src/runtime/http-server.ts +44 -101
  660. package/src/runtime/introduction-policy.test.ts +214 -0
  661. package/src/runtime/introduction-policy.ts +284 -0
  662. package/src/runtime/invite-service.ts +104 -361
  663. package/src/runtime/local-actor-identity.test.ts +38 -0
  664. package/src/runtime/local-actor-identity.ts +14 -0
  665. package/src/runtime/middleware/__tests__/rate-limiter.test.ts +22 -0
  666. package/src/runtime/middleware/rate-limiter.ts +30 -0
  667. package/src/runtime/middleware/twilio-validation.ts +5 -7
  668. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +28 -0
  669. package/src/runtime/migrations/origin-mode.ts +6 -6
  670. package/src/runtime/pre-first-message-gate.ts +1 -0
  671. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +6 -35
  672. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +24 -3
  673. package/src/runtime/routes/__tests__/contact-routes.test.ts +80 -15
  674. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +7 -1
  675. package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -3
  676. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +142 -1
  677. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +119 -30
  678. package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +70 -0
  679. package/src/runtime/routes/__tests__/monitoring-routes.test.ts +194 -0
  680. package/src/runtime/routes/__tests__/plugins-routes.test.ts +755 -29
  681. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +4 -0
  682. package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +70 -0
  683. package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +161 -0
  684. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +1 -1
  685. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
  686. package/src/runtime/routes/acp-routes.ts +15 -3
  687. package/src/runtime/routes/app-management-routes.ts +4 -7
  688. package/src/runtime/routes/approval-routes.ts +4 -0
  689. package/src/runtime/routes/attachment-routes.ts +54 -3
  690. package/src/runtime/routes/avatar-routes.ts +0 -4
  691. package/src/runtime/routes/background-tool-routes.ts +34 -5
  692. package/src/runtime/routes/btw-routes.ts +32 -4
  693. package/src/runtime/routes/channel-route-shared.ts +18 -14
  694. package/src/runtime/routes/channel-verification-routes.ts +0 -3
  695. package/src/runtime/routes/contact-routes.ts +298 -117
  696. package/src/runtime/routes/conversation-list-routes.ts +6 -0
  697. package/src/runtime/routes/conversation-management-routes.ts +74 -37
  698. package/src/runtime/routes/conversation-query-routes.ts +5 -2
  699. package/src/runtime/routes/conversation-routes.ts +222 -82
  700. package/src/runtime/routes/conversations-import-routes.ts +8 -1
  701. package/src/runtime/routes/credential-prompt-routes.ts +20 -5
  702. package/src/runtime/routes/debug-routes.ts +1 -0
  703. package/src/runtime/routes/documents-routes.ts +5 -2
  704. package/src/runtime/routes/empty-state-greeting-cache.ts +37 -10
  705. package/src/runtime/routes/global-search-routes.ts +2 -1
  706. package/src/runtime/routes/guardian-approval-interception.ts +51 -0
  707. package/src/runtime/routes/home-feed-routes.ts +60 -1
  708. package/src/runtime/routes/identity-routes.ts +4 -87
  709. package/src/runtime/routes/inbound-message-handler.ts +82 -41
  710. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +430 -57
  711. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +302 -572
  712. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +76 -270
  713. package/src/runtime/routes/inbound-stages/background-dispatch.ts +21 -116
  714. package/src/runtime/routes/inbound-stages/edit-intercept.ts +9 -1
  715. package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +158 -0
  716. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +22 -1
  717. package/src/runtime/routes/index.ts +6 -0
  718. package/src/runtime/routes/inference-provider-connection-routes.ts +22 -16
  719. package/src/runtime/routes/internal-twilio-routes.ts +0 -15
  720. package/src/runtime/routes/messages-lexical-routes.ts +75 -0
  721. package/src/runtime/routes/migration-routes.ts +69 -6
  722. package/src/runtime/routes/monitoring-routes.ts +237 -0
  723. package/src/runtime/routes/plugins-routes.ts +329 -8
  724. package/src/runtime/routes/schedule-routes.ts +49 -8
  725. package/src/runtime/routes/schedule-worker-routes.ts +210 -0
  726. package/src/runtime/routes/secret-routes.ts +1 -1
  727. package/src/runtime/routes/surface-conversation-resolver.ts +1 -0
  728. package/src/runtime/services/__tests__/analyze-conversation.test.ts +54 -9
  729. package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +30 -6
  730. package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +43 -8
  731. package/src/runtime/services/__tests__/conversation-serializer.test.ts +20 -0
  732. package/src/runtime/services/analyze-conversation.ts +14 -4
  733. package/src/runtime/services/conversation-serializer.ts +5 -0
  734. package/src/runtime/slack-no-response.ts +47 -0
  735. package/src/runtime/slack-reply-session.test.ts +633 -0
  736. package/src/runtime/slack-reply-session.ts +382 -0
  737. package/src/runtime/slack-task-progress.ts +95 -0
  738. package/src/runtime/sync/resource-sync-events.ts +25 -0
  739. package/src/runtime/tool-grant-request-helper.ts +17 -1
  740. package/src/runtime/trust-class.test.ts +141 -0
  741. package/src/runtime/trust-class.ts +121 -0
  742. package/src/runtime/trust-verdict-consumer.ts +7 -6
  743. package/src/schedule/__tests__/run-script.test.ts +21 -0
  744. package/src/schedule/__tests__/worker-control.test.ts +241 -0
  745. package/src/schedule/run-script.ts +13 -6
  746. package/src/schedule/schedule-usage-store.ts +1 -0
  747. package/src/schedule/scheduler.ts +178 -127
  748. package/src/schedule/worker-control.ts +118 -0
  749. package/src/schedule/worker.ts +131 -0
  750. package/src/skills/__tests__/categories-cache.test.ts +38 -0
  751. package/src/skills/categories-cache.ts +40 -5
  752. package/src/skills/managed-store.ts +41 -6
  753. package/src/skills/validate-input.ts +47 -0
  754. package/src/stt/types.ts +5 -9
  755. package/src/subagent/manager.ts +267 -39
  756. package/src/subagent/types.ts +6 -2
  757. package/src/subagent/validate-allowlists.ts +65 -0
  758. package/src/telemetry/watchdog-direct-emit.test.ts +109 -0
  759. package/src/telemetry/watchdog-direct-emit.ts +89 -0
  760. package/src/tools/acp/list-agents.test.ts +0 -6
  761. package/src/tools/background-tool-registry.ts +61 -0
  762. package/src/tools/document/document-comment-tool.test.ts +4 -0
  763. package/src/tools/host-terminal/host-shell.test.ts +397 -0
  764. package/src/tools/host-terminal/host-shell.ts +203 -14
  765. package/src/tools/skills/find-similar-skills.test.ts +152 -1
  766. package/src/tools/skills/find-similar-skills.ts +30 -4
  767. package/src/tools/skills/load.ts +36 -0
  768. package/src/tools/skills/scaffold-managed.ts +66 -34
  769. package/src/tools/skills/skill-script-runner.ts +17 -0
  770. package/src/tools/skills/skill-tool-factory.ts +5 -1
  771. package/src/tools/terminal/safe-env.ts +3 -0
  772. package/src/tools/terminal/shell.test.ts +177 -0
  773. package/src/tools/terminal/shell.ts +98 -4
  774. package/src/tools/tool-approval-handler.ts +106 -29
  775. package/{node_modules/@vellumai/skill-host-contracts/src → src/tools}/tool-types.ts +16 -17
  776. package/src/tools/types.ts +29 -17
  777. package/src/tools/ui-surface/definitions.ts +3 -1
  778. package/src/tts/__tests__/provider-adapters.test.ts +37 -0
  779. package/src/tts/__tests__/provider-catalog.test.ts +21 -0
  780. package/src/tts/provider-catalog.ts +40 -9
  781. package/src/tts/providers/fish-audio-provider.ts +19 -10
  782. package/src/tts/types.ts +3 -4
  783. package/src/util/__tests__/process-tree.test.ts +10 -2
  784. package/src/util/__tests__/text-spacing.test.ts +53 -0
  785. package/src/util/cgroup-memory.ts +142 -0
  786. package/src/util/image-conversion.ts +281 -0
  787. package/src/util/phone.ts +1 -8
  788. package/src/util/platform.ts +33 -0
  789. package/src/util/process-tree.ts +10 -2
  790. package/src/util/text-spacing.ts +53 -0
  791. package/src/util/worker-process.ts +271 -0
  792. package/src/workflows/journal-store.ts +16 -1
  793. package/src/workflows/library.test.ts +35 -20
  794. package/src/workflows/library.ts +105 -66
  795. package/src/workspace/git-service.ts +1 -0
  796. package/src/workspace/migrations/011-backfill-installation-id.ts +83 -31
  797. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +41 -22
  798. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +1 -1
  799. package/src/workspace/migrations/118-seed-now-md.ts +64 -0
  800. package/src/workspace/migrations/119-strip-persisted-memory-v3-tuning-defaults.ts +169 -0
  801. package/src/workspace/migrations/120-revise-onboarding-threads.ts +47 -0
  802. package/src/workspace/migrations/121-seed-default-user-guardrails.ts +82 -0
  803. package/src/workspace/migrations/122-relocate-default-user-boundary.ts +111 -0
  804. package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +85 -0
  805. package/src/workspace/migrations/__tests__/119-strip-persisted-memory-v3-tuning-defaults.test.ts +181 -0
  806. package/src/workspace/migrations/registry.ts +12 -0
  807. package/drizzle/0000_dizzy_maggott.sql +0 -301
  808. package/drizzle/meta/0000_snapshot.json +0 -1933
  809. package/drizzle/meta/_journal.json +0 -13
  810. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +0 -887
  811. package/node_modules/@vellumai/skill-host-contracts/bun.lock +0 -24
  812. package/node_modules/@vellumai/skill-host-contracts/package.json +0 -18
  813. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -97
  814. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +0 -1349
  815. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +0 -6
  816. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +0 -11
  817. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +0 -32
  818. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +0 -333
  819. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +0 -20
  820. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +0 -12
  821. package/src/__tests__/invite-redemption-service.test.ts +0 -1180
  822. package/src/__tests__/invite-service-ipc.test.ts +0 -350
  823. package/src/__tests__/job-handler-registry-guard.test.ts +0 -125
  824. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -203
  825. package/src/__tests__/relay-server.test.ts +0 -6153
  826. package/src/__tests__/telephony-stt-routing.test.ts +0 -329
  827. package/src/__tests__/voice-invite-redemption.test.ts +0 -702
  828. package/src/calls/relay-server.ts +0 -2463
  829. package/src/calls/telephony-stt-routing.ts +0 -145
  830. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -128
  831. package/src/daemon/__tests__/daemon-skill-host.test.ts +0 -273
  832. package/src/daemon/daemon-skill-host.ts +0 -262
  833. package/src/daemon/message-types/meet.ts +0 -143
  834. package/src/daemon/shutdown-registry.ts +0 -40
  835. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -253
  836. package/src/ipc/__tests__/skill-server.test.ts +0 -182
  837. package/src/ipc/skill-ipc-types.ts +0 -54
  838. package/src/ipc/skill-routes/__tests__/config.test.ts +0 -146
  839. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +0 -448
  840. package/src/ipc/skill-routes/__tests__/identity.test.ts +0 -62
  841. package/src/ipc/skill-routes/__tests__/log.test.ts +0 -133
  842. package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -203
  843. package/src/ipc/skill-routes/__tests__/platform.test.ts +0 -111
  844. package/src/ipc/skill-routes/__tests__/providers.test.ts +0 -265
  845. package/src/ipc/skill-routes/__tests__/registries.test.ts +0 -400
  846. package/src/ipc/skill-routes/config.ts +0 -47
  847. package/src/ipc/skill-routes/events.ts +0 -147
  848. package/src/ipc/skill-routes/identity.ts +0 -21
  849. package/src/ipc/skill-routes/index.ts +0 -37
  850. package/src/ipc/skill-routes/log.ts +0 -40
  851. package/src/ipc/skill-routes/memory.ts +0 -92
  852. package/src/ipc/skill-routes/platform.ts +0 -39
  853. package/src/ipc/skill-routes/providers.ts +0 -162
  854. package/src/ipc/skill-routes/registries.ts +0 -338
  855. package/src/ipc/skill-server.ts +0 -831
  856. package/src/ipc/skill-socket-path.ts +0 -20
  857. package/src/jobs/register-job-handlers.ts +0 -74
  858. package/src/persistence/invite-store.ts +0 -481
  859. package/src/plugins/job-handler-registry.ts +0 -94
  860. package/src/providers/cache-control.ts +0 -26
  861. package/src/runtime/__tests__/runtime-mode.test.ts +0 -62
  862. package/src/runtime/invite-redemption-service.ts +0 -828
  863. package/src/runtime/invite-redemption-templates.ts +0 -46
  864. package/src/runtime/runtime-mode.ts +0 -40
  865. package/src/runtime/slack-dm-text-delivery.ts +0 -177
  866. package/src/util/voice-code.ts +0 -31
@@ -5,6 +5,7 @@ import { confirmPrompt } from "../lib/confirm-prompt.js";
5
5
  import { registerCommand } from "../lib/register-command.js";
6
6
  import { log } from "../logger.js";
7
7
  import { writeOutput } from "../output.js";
8
+ import { registerSchedulesWorkerCommand } from "./schedules-worker.js";
8
9
 
9
10
  interface ScheduleRecord {
10
11
  id: string;
@@ -77,12 +78,16 @@ and manual one-time execution. One documented exception: 'create' is limited
77
78
  to 'execute' mode — notify/script/wake schedules are created via the
78
79
  in-assistant schedule_create tool, but can be inspected and updated here.
79
80
 
81
+ The 'worker' subgroup manages the schedule worker process, which runs
82
+ scheduled jobs in a separate OS process when enabled.
83
+
80
84
  Examples:
81
85
  $ assistant schedules list
82
86
  $ assistant schedules get <schedule-id>
83
87
  $ assistant schedules update <schedule-id> --expression '0 9 * * *'
84
88
  $ assistant schedules runs <schedule-id> --limit 25 --json
85
- $ assistant schedules execute <schedule-id>`,
89
+ $ assistant schedules execute <schedule-id>
90
+ $ assistant schedules worker start`,
86
91
  );
87
92
 
88
93
  schedules
@@ -108,7 +113,9 @@ Examples:
108
113
  .action(
109
114
  async (opts: { all?: boolean; json?: boolean }, cmd: Command) => {
110
115
  const queryParams: Record<string, string> = {};
111
- if (opts.all) queryParams.include_all = "true";
116
+ if (opts.all) {
117
+ queryParams.include_all = "true";
118
+ }
112
119
 
113
120
  const result = await cliIpcCall<ListSchedulesResponse>(
114
121
  "listSchedules",
@@ -237,7 +244,9 @@ Examples:
237
244
  pathParams: { id: scheduleId },
238
245
  });
239
246
 
240
- if (!result.ok) return exitFromIpcResult(result, cmd);
247
+ if (!result.ok) {
248
+ return exitFromIpcResult(result, cmd);
249
+ }
241
250
 
242
251
  const schedule = result.result?.schedule;
243
252
  if (!schedule) {
@@ -320,14 +329,18 @@ Examples:
320
329
  ) => {
321
330
  const scheduleId = id.trim();
322
331
  const queryParams: Record<string, string> = {};
323
- if (opts.limit != null) queryParams.limit = opts.limit;
332
+ if (opts.limit != null) {
333
+ queryParams.limit = opts.limit;
334
+ }
324
335
 
325
336
  const result = await cliIpcCall<ListScheduleRunsResponse>(
326
337
  "listScheduleRuns",
327
338
  { pathParams: { id: scheduleId }, queryParams },
328
339
  );
329
340
 
330
- if (!result.ok) return exitFromIpcResult(result, cmd);
341
+ if (!result.ok) {
342
+ return exitFromIpcResult(result, cmd);
343
+ }
331
344
 
332
345
  const response = result.result ?? { runs: [] };
333
346
  if (opts.json) {
@@ -416,9 +429,21 @@ Examples:
416
429
  "-d, --description <text>",
417
430
  "Authored description explaining what the schedule is for",
418
431
  )
419
- .requiredOption(
432
+ .option(
420
433
  "-m, --message <text>",
421
- "Message body sent to the assistant on each fire",
434
+ "Message body sent to the assistant on each fire (required for execute mode)",
435
+ )
436
+ .option(
437
+ "--mode <mode>",
438
+ "Schedule mode: 'execute' (default), 'script', or 'workflow'",
439
+ )
440
+ .option(
441
+ "--script <command>",
442
+ "Shell command to run on each fire (required for --mode script)",
443
+ )
444
+ .option(
445
+ "--timeout-ms <ms>",
446
+ "Script execution timeout override in ms (--mode script)",
422
447
  )
423
448
  .option(
424
449
  "-t, --timezone <tz>",
@@ -436,7 +461,10 @@ Examples:
436
461
  Options:
437
462
  -e, --expression <expr> Cron (e.g. '*/30 * * * *') or RRULE expression.
438
463
  -d, --description <text> Authored description explaining what the schedule is for.
439
- -m, --message <text> Message body sent on each fire.
464
+ -m, --message <text> Message body sent on each fire (execute mode).
465
+ --mode <mode> execute (default), script, or workflow.
466
+ --script <command> Shell command for --mode script.
467
+ --timeout-ms <ms> Script timeout override in ms (--mode script).
440
468
  -t, --timezone <tz> IANA timezone applied to the expression.
441
469
  --profile <name> Inference profile (llm.profiles key) the schedule's
442
470
  runs use. When omitted, runs use the default —
@@ -448,11 +476,17 @@ Arguments:
448
476
  <name> Display name for the schedule.
449
477
 
450
478
  Behavior:
451
- Creates a recurring schedule in 'execute' mode. The IPC endpoint is
452
- currently locked to execute mode; notify/script/wake schedules remain
453
- reachable only through the in-assistant schedule_create LLM tool.
479
+ Defaults to 'execute' mode (requires --message). Pass --mode script with
480
+ --script to run a shell command on each fire with no LLM call; the script's
481
+ env includes $VELLUM_WORKSPACE_DIR and $__SCHEDULE_ID (this schedule's id).
482
+ notify/wake schedules remain reachable only through the schedule_create tool.
454
483
 
455
484
  Examples:
485
+ $ assistant schedules create "GitHub watcher" \\
486
+ --mode script \\
487
+ --script 'cd "$VELLUM_WORKSPACE_DIR/schedules/$__SCHEDULE_ID" && bun poll.ts' \\
488
+ --expression '*/15 * * * *' \\
489
+ --description 'Polls GitHub notifications' --json
456
490
  $ assistant schedules create "Heartbeat" \\
457
491
  --expression '*/30 * * * *' \\
458
492
  --description 'Checks service heartbeat every 30 minutes' \\
@@ -474,7 +508,10 @@ Examples:
474
508
  opts: {
475
509
  expression: string;
476
510
  description: string;
477
- message: string;
511
+ message?: string;
512
+ mode?: string;
513
+ script?: string;
514
+ timeoutMs?: string;
478
515
  timezone?: string;
479
516
  profile?: string;
480
517
  enabled: boolean;
@@ -506,26 +543,65 @@ Examples:
506
543
  return;
507
544
  }
508
545
 
546
+ const mode = opts.mode ?? "execute";
547
+ if (mode === "script" && !opts.script) {
548
+ const error = "--script is required for --mode script";
549
+ if (opts.json) {
550
+ writeOutput(cmd, { ok: false, error });
551
+ } else {
552
+ log.error(error);
553
+ }
554
+ process.exitCode = 1;
555
+ return;
556
+ }
557
+ if (mode === "execute" && !opts.message) {
558
+ const error = "--message is required for execute mode";
559
+ if (opts.json) {
560
+ writeOutput(cmd, { ok: false, error });
561
+ } else {
562
+ log.error(error);
563
+ }
564
+ process.exitCode = 1;
565
+ return;
566
+ }
567
+
509
568
  const body: Record<string, unknown> = {
510
569
  name: scheduleName,
511
570
  expression: opts.expression,
512
571
  description,
513
- message: opts.message,
514
572
  enabled: opts.enabled,
515
573
  };
516
- if (opts.timezone != null) body.timezone = opts.timezone;
517
- if (opts.profile != null) body.inferenceProfile = opts.profile;
574
+ // Omit mode for the default; the route treats absent as 'execute'.
575
+ if (mode !== "execute") {
576
+ body.mode = mode;
577
+ }
578
+ if (opts.message != null) {
579
+ body.message = opts.message;
580
+ }
581
+ if (opts.script != null) {
582
+ body.script = opts.script;
583
+ }
584
+ if (opts.timeoutMs != null) {
585
+ body.timeoutMs = Number(opts.timeoutMs);
586
+ }
587
+ if (opts.timezone != null) {
588
+ body.timezone = opts.timezone;
589
+ }
590
+ if (opts.profile != null) {
591
+ body.inferenceProfile = opts.profile;
592
+ }
518
593
 
519
- const result = await cliIpcCall<ListSchedulesResponse>(
594
+ const result = await cliIpcCall<GetScheduleResponse>(
520
595
  "createSchedule",
521
596
  { body },
522
597
  );
523
598
 
524
- if (!result.ok) return exitFromIpcResult(result, cmd);
599
+ if (!result.ok) {
600
+ return exitFromIpcResult(result, cmd);
601
+ }
525
602
 
526
- const response = result.result ?? { schedules: [] };
527
603
  if (opts.json) {
528
- writeOutput(cmd, response);
604
+ writeOutput(cmd, result.result ?? {});
529
605
  return;
530
606
  }
531
607
 
@@ -708,7 +784,9 @@ Examples:
708
784
  "getSchedule",
709
785
  { pathParams: { id: scheduleId } },
710
786
  );
711
- if (!existing.ok) return exitFromIpcResult(existing, cmd);
787
+ if (!existing.ok) {
788
+ return exitFromIpcResult(existing, cmd);
789
+ }
712
790
  if (!existing.result?.schedule.wakeConversationId) {
713
791
  fail(
714
792
  "--mode wake requires the schedule to already have a wake conversation target; this CLI cannot set one. Create wake schedules with the schedule tool instead.",
@@ -718,23 +796,41 @@ Examples:
718
796
  }
719
797
 
720
798
  const body: Record<string, unknown> = {};
721
- if (opts.name != null) body.name = opts.name;
722
- if (opts.description != null) body.description = opts.description;
723
- if (opts.expression != null) body.expression = opts.expression;
724
- if (opts.timezone != null) body.timezone = opts.timezone;
725
- if (opts.message != null) body.message = opts.message;
726
- if (opts.script != null) body.script = opts.script;
727
- if (opts.mode != null) body.mode = opts.mode;
799
+ if (opts.name != null) {
800
+ body.name = opts.name;
801
+ }
802
+ if (opts.description != null) {
803
+ body.description = opts.description;
804
+ }
805
+ if (opts.expression != null) {
806
+ body.expression = opts.expression;
807
+ }
808
+ if (opts.timezone != null) {
809
+ body.timezone = opts.timezone;
810
+ }
811
+ if (opts.message != null) {
812
+ body.message = opts.message;
813
+ }
814
+ if (opts.script != null) {
815
+ body.script = opts.script;
816
+ }
817
+ if (opts.mode != null) {
818
+ body.mode = opts.mode;
819
+ }
728
820
  if (opts.routingIntent != null) {
729
821
  body.routingIntent = opts.routingIntent;
730
822
  }
731
- if (opts.quiet != null) body.quiet = opts.quiet;
823
+ if (opts.quiet != null) {
824
+ body.quiet = opts.quiet;
825
+ }
732
826
  if (opts.reuseConversation != null) {
733
827
  body.reuseConversation = opts.reuseConversation;
734
828
  }
735
829
  if (opts.maxRetries != null) {
736
830
  const parsed = parseInteger("--max-retries", opts.maxRetries);
737
- if (parsed == null) return;
831
+ if (parsed == null) {
832
+ return;
833
+ }
738
834
  body.maxRetries = parsed;
739
835
  }
740
836
  if (opts.retryBackoffMs != null) {
@@ -742,17 +838,27 @@ Examples:
742
838
  "--retry-backoff-ms",
743
839
  opts.retryBackoffMs,
744
840
  );
745
- if (parsed == null) return;
841
+ if (parsed == null) {
842
+ return;
843
+ }
746
844
  body.retryBackoffMs = parsed;
747
845
  }
748
846
  if (opts.timeoutMs != null) {
749
847
  const parsed = parseInteger("--timeout-ms", opts.timeoutMs);
750
- if (parsed == null) return;
848
+ if (parsed == null) {
849
+ return;
850
+ }
751
851
  body.timeoutMs = parsed;
752
852
  }
753
- if (opts.clearTimeout) body.timeoutMs = null;
754
- if (opts.profile != null) body.inferenceProfile = opts.profile;
755
- if (opts.clearProfile) body.inferenceProfile = null;
853
+ if (opts.clearTimeout) {
854
+ body.timeoutMs = null;
855
+ }
856
+ if (opts.profile != null) {
857
+ body.inferenceProfile = opts.profile;
858
+ }
859
+ if (opts.clearProfile) {
860
+ body.inferenceProfile = null;
861
+ }
756
862
 
757
863
  if (Object.keys(body).length === 0) {
758
864
  fail(
@@ -766,7 +872,9 @@ Examples:
766
872
  { pathParams: { id: scheduleId }, body },
767
873
  );
768
874
 
769
- if (!result.ok) return exitFromIpcResult(result, cmd);
875
+ if (!result.ok) {
876
+ return exitFromIpcResult(result, cmd);
877
+ }
770
878
 
771
879
  const response = result.result ?? { schedules: [] };
772
880
  if (opts.json) {
@@ -858,7 +966,9 @@ Examples:
858
966
  { pathParams: { id: scheduleId } },
859
967
  );
860
968
 
861
- if (!result.ok) return exitFromIpcResult(result, cmd);
969
+ if (!result.ok) {
970
+ return exitFromIpcResult(result, cmd);
971
+ }
862
972
 
863
973
  const response = result.result ?? { schedules: [] };
864
974
  if (opts.json) {
@@ -934,7 +1044,9 @@ Examples:
934
1044
  { pathParams: { id: scheduleId } },
935
1045
  );
936
1046
 
937
- if (!result.ok) return exitFromIpcResult(result, cmd);
1047
+ if (!result.ok) {
1048
+ return exitFromIpcResult(result, cmd);
1049
+ }
938
1050
 
939
1051
  const response = result.result ?? { schedules: [] };
940
1052
  if (opts.json) {
@@ -981,7 +1093,9 @@ Examples:
981
1093
  { pathParams: { id: scheduleId } },
982
1094
  );
983
1095
 
984
- if (!result.ok) return exitFromIpcResult(result, cmd);
1096
+ if (!result.ok) {
1097
+ return exitFromIpcResult(result, cmd);
1098
+ }
985
1099
 
986
1100
  const response = result.result ?? { schedules: [] };
987
1101
  const schedule = response.schedules.find(
@@ -1003,6 +1117,8 @@ Examples:
1003
1117
 
1004
1118
  log.info(`Executed schedule: ${scheduleId}`);
1005
1119
  });
1120
+
1121
+ registerSchedulesWorkerCommand(schedules);
1006
1122
  },
1007
1123
  });
1008
1124
  }
@@ -1019,7 +1135,9 @@ async function toggleScheduleEnabled(
1019
1135
  body: { enabled },
1020
1136
  });
1021
1137
 
1022
- if (!result.ok) return exitFromIpcResult(result, cmd);
1138
+ if (!result.ok) {
1139
+ return exitFromIpcResult(result, cmd);
1140
+ }
1023
1141
 
1024
1142
  const response = result.result ?? { schedules: [] };
1025
1143
  if (opts.json) {
@@ -1031,7 +1149,9 @@ async function toggleScheduleEnabled(
1031
1149
  }
1032
1150
 
1033
1151
  function describeSchedule(schedule: ScheduleRecord): string {
1034
- if (schedule.isOneShot) return "one-shot";
1152
+ if (schedule.isOneShot) {
1153
+ return "one-shot";
1154
+ }
1035
1155
  const expression = schedule.cadenceDescription ?? schedule.expression ?? "—";
1036
1156
  return schedule.timezone
1037
1157
  ? `${expression} (${schedule.timezone})`
@@ -1039,7 +1159,9 @@ function describeSchedule(schedule: ScheduleRecord): string {
1039
1159
  }
1040
1160
 
1041
1161
  function formatTimestamp(value: number): string {
1042
- if (!Number.isFinite(value) || value <= 0) return "—";
1162
+ if (!Number.isFinite(value) || value <= 0) {
1163
+ return "—";
1164
+ }
1043
1165
  return new Date(value).toISOString();
1044
1166
  }
1045
1167
 
@@ -1048,8 +1170,12 @@ function formatNullableTimestamp(value: number | null): string {
1048
1170
  }
1049
1171
 
1050
1172
  function formatDuration(value: number | null): string {
1051
- if (value == null || !Number.isFinite(value) || value < 0) return "—";
1052
- if (value < 1000) return `${Math.round(value)}ms`;
1173
+ if (value == null || !Number.isFinite(value) || value < 0) {
1174
+ return "—";
1175
+ }
1176
+ if (value < 1000) {
1177
+ return `${Math.round(value)}ms`;
1178
+ }
1053
1179
 
1054
1180
  // Keep one decimal of precision only in the sub-minute range, where it's
1055
1181
  // meaningful; coarser units round to whole seconds. Working in tenths of a
@@ -5,6 +5,7 @@ import type { Command } from "commander";
5
5
  import { cliIpcCall } from "../../ipc/cli-client.js";
6
6
  import { getAssistantSocketPath } from "../../ipc/socket-path.js";
7
7
  import { getWorkspaceDirDisplay } from "../../util/platform.js";
8
+ import { APP_VERSION } from "../../version.js";
8
9
  import { registerCommand } from "../lib/register-command.js";
9
10
 
10
11
  interface HealthResponse {
@@ -34,6 +35,9 @@ export function registerStatusCommand(program: Command): void {
34
35
  const socketPath = getAssistantSocketPath();
35
36
  const socketExists = existsSync(socketPath);
36
37
  const workspace = getWorkspaceDirDisplay();
38
+ // Daemon unreachable, so its runtime version is unknown; show the
39
+ // installed CLI version so there's always one reliable number.
40
+ process.stdout.write(`CLI Version: ${APP_VERSION}\n`);
37
41
  process.stdout.write(
38
42
  (socketExists ? "Assistant: running" : "Assistant: down") + "\n",
39
43
  );
@@ -52,8 +56,15 @@ export function registerStatusCommand(program: Command): void {
52
56
  const h = result.result;
53
57
  const workspace = getWorkspaceDirDisplay();
54
58
 
59
+ // h.version is the running runtime; APP_VERSION is the installed CLI.
60
+ // They drift mid-upgrade (CLI bumped, daemon not yet restarted).
61
+ const runtimeVersion =
62
+ h.version === APP_VERSION
63
+ ? h.version
64
+ : `${h.version} (stale — restart to run ${APP_VERSION})`;
65
+
55
66
  const rows: [string, string][] = [
56
- ["Version", h.version],
67
+ ["Assistant Version", runtimeVersion],
57
68
  ["Workspace", workspace],
58
69
  ["", ""],
59
70
  ["Memory", `${fmtMb(h.memory.currentMb)} / ${fmtMb(h.memory.maxMb)}`],
@@ -105,8 +105,12 @@ Examples:
105
105
  `${"NAME".padEnd(nameW)} ${"SOURCE".padEnd(sourceW)} ${"RISK".padEnd(riskW)} DESCRIPTION`,
106
106
  );
107
107
  for (const t of tools) {
108
+ const description =
109
+ t.description.length > 50
110
+ ? `${t.description.slice(0, 50)}…`
111
+ : t.description;
108
112
  console.log(
109
- `${t.name.padEnd(nameW)} ${t.source.padEnd(sourceW)} ${t.riskLevel.padEnd(riskW)} ${t.description}`,
113
+ `${t.name.padEnd(nameW)} ${t.source.padEnd(sourceW)} ${t.riskLevel.padEnd(riskW)} ${description}`,
110
114
  );
111
115
  }
112
116
  console.log(`\n${tools.length} tool(s)`);
@@ -56,6 +56,7 @@ function catalog(ref: string, names: string[]): PluginCatalog {
56
56
  matches: names.map((name) => ({
57
57
  name,
58
58
  path: `github:acme/${name}@${"0".repeat(40)}`,
59
+ category: null,
59
60
  source: {
60
61
  kind: "github" as const,
61
62
  repo: `acme/${name}`,
@@ -30,6 +30,7 @@ interface ManifestPlugin {
30
30
  name: string;
31
31
  source: { source: "github"; repo: string; path?: string; ref: string };
32
32
  description?: string;
33
+ category?: string;
33
34
  }
34
35
 
35
36
  /** Serve `plugins` as the raw marketplace manifest at the manifest URL. */
@@ -51,7 +52,7 @@ function entry(
51
52
  name: string,
52
53
  repo: string,
53
54
  ref: string,
54
- extra?: { path?: string; description?: string },
55
+ extra?: { path?: string; description?: string; category?: string },
55
56
  ): ManifestPlugin {
56
57
  return {
57
58
  name,
@@ -62,6 +63,7 @@ function entry(
62
63
  ref,
63
64
  },
64
65
  ...(extra?.description ? { description: extra.description } : {}),
66
+ ...(extra?.category ? { category: extra.category } : {}),
65
67
  };
66
68
  }
67
69
 
@@ -151,6 +153,7 @@ describe("searchPlugins", () => {
151
153
  name: "nested",
152
154
  path: `github:acme/monorepo/packages/nested@${SHA_B}`,
153
155
  description: "A nested plugin.",
156
+ category: null,
154
157
  source: {
155
158
  kind: "github",
156
159
  repo: "acme/monorepo",
@@ -161,6 +164,30 @@ describe("searchPlugins", () => {
161
164
  ]);
162
165
  });
163
166
 
167
+ test("carries the marketplace entry category, defaulting to null", async () => {
168
+ // GIVEN one entry that declares a category and one that does not
169
+ // WHEN we search
170
+ const result = await searchPlugins(
171
+ { query: "" },
172
+ {
173
+ fetch: manifestFetch([
174
+ entry("calendar-sync", "acme/calendar-sync", SHA_A, {
175
+ category: "calendar",
176
+ }),
177
+ entry("plain-plugin", "acme/plain-plugin", SHA_B),
178
+ ]),
179
+ },
180
+ );
181
+
182
+ // THEN the declared category flows through and a missing one is null
183
+ expect(
184
+ result.matches.map((m) => ({ name: m.name, category: m.category })),
185
+ ).toEqual([
186
+ { name: "calendar-sync", category: "calendar" },
187
+ { name: "plain-plugin", category: null },
188
+ ]);
189
+ });
190
+
164
191
  test("rejects invalid regex patterns up front (no network call)", async () => {
165
192
  let fetchCalled = false;
166
193
  const fetch: FetchLike = (async () => {
@@ -335,6 +362,7 @@ describe("searchPlugins", () => {
335
362
  {
336
363
  name: "caveman",
337
364
  path: `github:JuliusBrussee/caveman@${SHA_A}`,
365
+ category: null,
338
366
  source: {
339
367
  kind: "github",
340
368
  repo: "JuliusBrussee/caveman",
@@ -132,6 +132,13 @@ describe("enablePlugin", () => {
132
132
  );
133
133
  });
134
134
 
135
+ it("throws PluginDirectoryNotFoundError for non-default plugin with no directory", () => {
136
+ // A missing user plugin must 404, not surface as an already-enabled no-op.
137
+ expect(() => enablePlugin("nonexistent-plugin")).toThrow(
138
+ PluginDirectoryNotFoundError,
139
+ );
140
+ });
141
+
135
142
  it("throws InvalidPluginNameError for path traversal attempts", () => {
136
143
  expect(() => enablePlugin("../state")).toThrow(InvalidPluginNameError);
137
144
  expect(() => enablePlugin("foo/bar")).toThrow(InvalidPluginNameError);
@@ -67,6 +67,11 @@ export interface PluginSearchMatch {
67
67
  readonly path: string;
68
68
  /** Short description, when known (external entries only today). */
69
69
  readonly description?: string;
70
+ /**
71
+ * Free-form grouping hint from the curated marketplace entry (e.g.
72
+ * `productivity`), or `null` when the entry declares none.
73
+ */
74
+ readonly category: string | null;
70
75
  /** Discriminated origin, so callers can render/install accordingly. */
71
76
  readonly source: PluginMatchSource;
72
77
  }
@@ -199,6 +204,7 @@ function marketplaceMatch(entry: MarketplaceEntry): PluginSearchMatch {
199
204
  name: entry.name,
200
205
  path: locator,
201
206
  description: entry.description,
207
+ category: entry.category ?? null,
202
208
  source: { kind: "github", repo, path, ref },
203
209
  };
204
210
  }
@@ -16,7 +16,14 @@
16
16
  * it was the sentinel).
17
17
  */
18
18
 
19
- import { existsSync, mkdirSync, readdirSync, rmSync, unlinkSync } from "node:fs";
19
+ import {
20
+ existsSync,
21
+ mkdirSync,
22
+ readdirSync,
23
+ rmSync,
24
+ unlinkSync,
25
+ writeFileSync,
26
+ } from "node:fs";
20
27
  import { join } from "node:path";
21
28
 
22
29
  import { getWorkspacePluginsDir } from "../../util/platform.js";
@@ -111,7 +118,11 @@ export function disablePlugin(name: string): TogglePluginResult {
111
118
  }
112
119
 
113
120
  // Write empty sentinel file — content is irrelevant, existence is the signal.
114
- Bun.write(sentinelPath, "");
121
+ // Synchronous (like `enablePlugin`'s `unlinkSync`) so the sentinel is durable
122
+ // before the caller returns, and a write failure throws synchronously into the
123
+ // caller's try/catch instead of an unawaited `Bun.write` promise that could
124
+ // resolve/reject after the response.
125
+ writeFileSync(sentinelPath, "");
115
126
  return { name: validated, action: "disable", sentinelPath };
116
127
  }
117
128
 
@@ -126,6 +137,14 @@ export function enablePlugin(name: string): TogglePluginResult {
126
137
  const pluginDir = join(pluginsDir, validated);
127
138
  const sentinelPath = join(pluginDir, DISABLED_FILE);
128
139
 
140
+ // A missing user plugin is a 404, not a no-op: without this, a typo/deleted
141
+ // name has no sentinel and would fall through to "already enabled" (409),
142
+ // indistinguishable from a genuinely-enabled plugin. Default plugins have no
143
+ // directory when enabled, so they skip this check (their no-op stays 409).
144
+ if (!validated.startsWith("default-") && !existsSync(pluginDir)) {
145
+ throw new PluginDirectoryNotFoundError(validated);
146
+ }
147
+
129
148
  if (!existsSync(sentinelPath)) {
130
149
  throw new PluginAlreadyInStateException(validated, "enable");
131
150
  }
@@ -33,6 +33,7 @@ import { registerInferenceCommand } from "./commands/inference.js";
33
33
  import { registerKeysCommand } from "./commands/keys.js";
34
34
  import { registerMcpCommand } from "./commands/mcp.js";
35
35
  import { registerMemoryCommand } from "./commands/memory/index.js";
36
+ import { registerMonitoringCommand } from "./commands/monitoring.js";
36
37
  import { registerNotificationsCommand } from "./commands/notifications.js";
37
38
  import { registerOAuthCommand } from "./commands/oauth/index.js";
38
39
  import { registerPendingCommand } from "./commands/pending.js";
@@ -79,7 +80,7 @@ export function buildCliProgramTree(): Command {
79
80
 
80
81
  program
81
82
  .name("assistant")
82
- .description("Local AI assistant")
83
+ .description("Utilities for navigating and managing your own workspace")
83
84
  .version(APP_VERSION)
84
85
  .allowExcessArguments(true);
85
86
 
@@ -133,6 +134,7 @@ Examples:
133
134
  registerPendingCommand(program);
134
135
  registerPlatformCommand(program);
135
136
  registerPluginsCommand(program);
137
+ registerMonitoringCommand(program);
136
138
  registerPsCommand(program);
137
139
  registerRoutesCommand(program);
138
140
  registerSchedulesCommand(program);
@@ -225,4 +225,27 @@ describe("deployment-context embedding-provider default (via loadConfig)", () =>
225
225
  expect(config.memory.embeddings.provider).toBe("auto");
226
226
  expect(config.memory.qdrant.vectorSize).toBe(384);
227
227
  });
228
+
229
+ test("first launch seeds memory.v3 with only `live` — tuning knobs resolve from the schema, not disk", () => {
230
+ if (existsSync(CONFIG_PATH)) rmSync(CONFIG_PATH, { force: true });
231
+ delete process.env.IS_PLATFORM;
232
+
233
+ const config = loadConfig();
234
+
235
+ // In-memory effective config still carries the full tuning (schema defaults).
236
+ expect(config.memory.v3.gate.denseThreshold).toBe(0.66);
237
+ expect(config.memory.v3.needleK).toBe(100);
238
+
239
+ // Persisted config.json carries ONLY `live` under memory.v3 — no tuning knob
240
+ // is frozen to disk, so a shipped schema-default change reaches this
241
+ // assistant on its next load (mirrors the embedding-provider strip above).
242
+ const raw = readConfig();
243
+ const v3Raw = ((raw.memory as Record<string, unknown>).v3 ?? {}) as Record<
244
+ string,
245
+ unknown
246
+ >;
247
+ expect(Object.keys(v3Raw)).toEqual(["live"]);
248
+ expect(v3Raw.gate).toBeUndefined();
249
+ expect(v3Raw.needleK).toBeUndefined();
250
+ });
228
251
  });