@vellumai/assistant 0.7.1 → 0.7.3

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 (739) hide show
  1. package/ARCHITECTURE.md +48 -50
  2. package/Dockerfile +1 -0
  3. package/README.md +1 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
  5. package/bun.lock +26 -26
  6. package/docs/architecture/memory.md +5 -2
  7. package/docs/architecture/security.md +20 -0
  8. package/docs/plugins.md +7 -9
  9. package/knip.json +1 -0
  10. package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
  11. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
  12. package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
  13. package/node_modules/@vellumai/service-contracts/package.json +2 -0
  14. package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
  15. package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
  16. package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
  17. package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
  18. package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
  19. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  20. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  21. package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
  22. package/node_modules/@vellumai/twilio-client/package.json +18 -0
  23. package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
  24. package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
  25. package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
  26. package/openapi.yaml +1020 -40
  27. package/package.json +6 -3
  28. package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
  29. package/src/__tests__/app-bundler.test.ts +170 -1
  30. package/src/__tests__/app-control-flow.test.ts +384 -0
  31. package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
  32. package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
  33. package/src/__tests__/app-executors.test.ts +30 -43
  34. package/src/__tests__/approval-routes-http.test.ts +23 -6
  35. package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
  36. package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
  37. package/src/__tests__/assistant-event-hub.test.ts +157 -2
  38. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
  39. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  40. package/src/__tests__/background-shell-host-bash.test.ts +14 -15
  41. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  42. package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
  43. package/src/__tests__/btw-routes.test.ts +13 -4
  44. package/src/__tests__/call-controller.test.ts +49 -1
  45. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  46. package/src/__tests__/call-domain.test.ts +0 -2
  47. package/src/__tests__/call-routes-http.test.ts +0 -2
  48. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  49. package/src/__tests__/channel-readiness-service.test.ts +62 -2
  50. package/src/__tests__/checker.test.ts +3 -4
  51. package/src/__tests__/config-loader-backfill.test.ts +461 -147
  52. package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
  53. package/src/__tests__/config-schema-cmd.test.ts +0 -1
  54. package/src/__tests__/config-schema.test.ts +1 -0
  55. package/src/__tests__/config-set-platform-guard.test.ts +48 -4
  56. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
  57. package/src/__tests__/config-watcher.test.ts +142 -71
  58. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  59. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  60. package/src/__tests__/context-search-fanout.test.ts +0 -1
  61. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  62. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  63. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  64. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  65. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  66. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  67. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  68. package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
  70. package/src/__tests__/conversation-error.test.ts +150 -3
  71. package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
  72. package/src/__tests__/conversation-lifecycle.test.ts +36 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
  74. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  76. package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
  77. package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
  78. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
  79. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  80. package/src/__tests__/conversation-slash-commands.test.ts +0 -4
  81. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  82. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  83. package/src/__tests__/conversation-store.test.ts +0 -18
  84. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
  85. package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
  86. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  87. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  88. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  89. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  90. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
  91. package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
  92. package/src/__tests__/credentials-cli.test.ts +12 -12
  93. package/src/__tests__/cu-unified-flow.test.ts +351 -23
  94. package/src/__tests__/daemon-credential-client.test.ts +101 -19
  95. package/src/__tests__/date-context.test.ts +164 -2
  96. package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
  97. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  98. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  99. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  100. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  101. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  102. package/src/__tests__/disk-usage.test.ts +150 -0
  103. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  104. package/src/__tests__/events-client-registration.test.ts +52 -0
  105. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  106. package/src/__tests__/file-write-tool.test.ts +4 -10
  107. package/src/__tests__/filing-service.test.ts +3 -4
  108. package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
  109. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
  110. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
  111. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
  112. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  113. package/src/__tests__/heartbeat-service.test.ts +968 -2
  114. package/src/__tests__/helpers/call-route-handler.ts +7 -1
  115. package/src/__tests__/host-app-control-proxy.test.ts +772 -0
  116. package/src/__tests__/host-app-control-routes.test.ts +263 -0
  117. package/src/__tests__/host-bash-proxy.test.ts +439 -47
  118. package/src/__tests__/host-bash-routes.test.ts +459 -0
  119. package/src/__tests__/host-browser-proxy.test.ts +24 -22
  120. package/src/__tests__/host-browser-routes.test.ts +39 -13
  121. package/src/__tests__/host-cu-proxy.test.ts +248 -52
  122. package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
  123. package/src/__tests__/host-file-edit-tool.test.ts +47 -1
  124. package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
  125. package/src/__tests__/host-file-proxy.test.ts +301 -45
  126. package/src/__tests__/host-file-read-tool.test.ts +17 -0
  127. package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
  128. package/src/__tests__/host-file-write-tool.test.ts +42 -1
  129. package/src/__tests__/host-proxy-base.test.ts +312 -0
  130. package/src/__tests__/host-shell-tool.test.ts +22 -4
  131. package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
  132. package/src/__tests__/host-transfer-proxy.test.ts +121 -22
  133. package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
  134. package/src/__tests__/http-user-message-parity.test.ts +108 -1
  135. package/src/__tests__/identity-intro-cache.test.ts +29 -0
  136. package/src/__tests__/identity-routes.test.ts +103 -1
  137. package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
  138. package/src/__tests__/injector-chain.test.ts +18 -6
  139. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  140. package/src/__tests__/inline-command-runner.test.ts +0 -1
  141. package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
  142. package/src/__tests__/integration-status.test.ts +85 -5
  143. package/src/__tests__/intent-routing.test.ts +0 -1
  144. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
  145. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
  146. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  147. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
  148. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  149. package/src/__tests__/mcp-auth-routes.test.ts +197 -0
  150. package/src/__tests__/mcp-cli.test.ts +338 -2
  151. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
  153. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  154. package/src/__tests__/migration-import-commit-http.test.ts +108 -2
  155. package/src/__tests__/mock-gateway-ipc.ts +1 -0
  156. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  157. package/src/__tests__/oauth-cli.test.ts +0 -2
  158. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  159. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  160. package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
  161. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  162. package/src/__tests__/openai-provider.test.ts +45 -8
  163. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  164. package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
  165. package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
  166. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  167. package/src/__tests__/platform.test.ts +2 -1
  168. package/src/__tests__/playbook-execution.test.ts +0 -43
  169. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  170. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
  171. package/src/__tests__/process-message-background-slack.test.ts +2 -0
  172. package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
  173. package/src/__tests__/provider-tool-name.test.ts +23 -0
  174. package/src/__tests__/public-ingress-urls.test.ts +97 -0
  175. package/src/__tests__/relay-server.test.ts +15 -4
  176. package/src/__tests__/require-fresh-approval.test.ts +0 -1
  177. package/src/__tests__/retry-backoff.test.ts +87 -0
  178. package/src/__tests__/runtime-events-sse.test.ts +2 -2
  179. package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
  180. package/src/__tests__/schedule-retry.test.ts +715 -0
  181. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  182. package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
  183. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  184. package/src/__tests__/send-endpoint-busy.test.ts +3 -0
  185. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
  186. package/src/__tests__/skill-feature-flags.test.ts +43 -41
  187. package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
  188. package/src/__tests__/skill-load-inline-command.test.ts +0 -51
  189. package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
  190. package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
  191. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
  192. package/src/__tests__/slack-channel-config.test.ts +9 -14
  193. package/src/__tests__/suggestion-routes.test.ts +46 -0
  194. package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
  195. package/src/__tests__/system-prompt.test.ts +0 -1
  196. package/src/__tests__/telegram-config.test.ts +0 -1
  197. package/src/__tests__/test-preload.ts +8 -0
  198. package/src/__tests__/tool-approval-handler.test.ts +3 -4
  199. package/src/__tests__/tool-audit-listener.test.ts +48 -0
  200. package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
  201. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
  202. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  203. package/src/__tests__/tool-executor.test.ts +0 -1
  204. package/src/__tests__/twilio-config.test.ts +3 -16
  205. package/src/__tests__/twilio-routes.test.ts +3 -5
  206. package/src/__tests__/twilio-validation.test.ts +93 -0
  207. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
  208. package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
  209. package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
  210. package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
  211. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  212. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  213. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  214. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
  215. package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
  216. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  217. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
  218. package/src/approvals/guardian-decision-primitive.ts +13 -0
  219. package/src/approvals/guardian-request-resolvers.ts +16 -17
  220. package/src/backup/__tests__/paths.test.ts +0 -22
  221. package/src/backup/__tests__/restore.test.ts +51 -151
  222. package/src/backup/paths.ts +2 -18
  223. package/src/backup/restore.ts +107 -231
  224. package/src/backup/snapshot-lock.ts +2 -27
  225. package/src/bundler/app-bundler.ts +51 -3
  226. package/src/bundler/compiler-tools.ts +3 -2
  227. package/src/calls/call-conversation-messages.ts +46 -10
  228. package/src/calls/relay-server.ts +4 -44
  229. package/src/calls/twilio-config.ts +2 -17
  230. package/src/calls/twilio-rest.ts +33 -105
  231. package/src/calls/twilio-routes.ts +11 -12
  232. package/src/channels/types.ts +8 -7
  233. package/src/cli/commands/__tests__/backup.test.ts +6 -277
  234. package/src/cli/commands/__tests__/gateway.test.ts +288 -0
  235. package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
  236. package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
  237. package/src/cli/commands/backup.ts +6 -331
  238. package/src/cli/commands/bash.ts +35 -108
  239. package/src/cli/commands/clients.ts +36 -37
  240. package/src/cli/commands/contacts.ts +137 -25
  241. package/src/cli/commands/conversations.ts +2 -5
  242. package/src/cli/commands/credentials.ts +71 -7
  243. package/src/cli/commands/domain.ts +66 -15
  244. package/src/cli/commands/gateway.ts +183 -0
  245. package/src/cli/commands/keys.ts +9 -6
  246. package/src/cli/commands/mcp.ts +116 -156
  247. package/src/cli/commands/memory-v2.ts +303 -7
  248. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  249. package/src/cli/commands/oauth/connect.ts +127 -1
  250. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
  251. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
  252. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
  253. package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
  254. package/src/cli/commands/platform/disconnect.ts +5 -4
  255. package/src/cli/commands/platform/index.ts +16 -25
  256. package/src/cli/commands/status.ts +57 -0
  257. package/src/cli/lib/daemon-credential-client.ts +110 -28
  258. package/src/cli/program.ts +6 -2
  259. package/src/config/assistant-feature-flags.ts +79 -12
  260. package/src/config/bundled-skills/acp/SKILL.md +6 -0
  261. package/src/config/bundled-skills/acp/TOOLS.json +1 -22
  262. package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
  263. package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
  264. package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
  265. package/src/config/bundled-skills/app-control/SKILL.md +75 -0
  266. package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
  267. package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
  268. package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
  269. package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
  270. package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
  271. package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
  272. package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
  273. package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
  274. package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
  275. package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
  276. package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
  277. package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
  278. package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
  279. package/src/config/bundled-skills/document/TOOLS.json +0 -8
  280. package/src/config/bundled-skills/followups/TOOLS.json +0 -12
  281. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  282. package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
  283. package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
  284. package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
  285. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  286. package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
  287. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
  288. package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
  289. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  290. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  291. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  292. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  293. package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
  294. package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
  295. package/src/config/bundled-skills/settings/SKILL.md +4 -0
  296. package/src/config/bundled-skills/settings/TOOLS.json +0 -12
  297. package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
  298. package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
  299. package/src/config/bundled-skills/subagent/SKILL.md +6 -2
  300. package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
  301. package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
  302. package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
  303. package/src/config/bundled-tool-registry.ts +21 -0
  304. package/src/config/env-registry.ts +0 -2
  305. package/src/config/env.ts +19 -20
  306. package/src/config/feature-flag-registry.json +47 -135
  307. package/src/config/loader.ts +197 -104
  308. package/src/config/sanitize-for-transfer.ts +2 -0
  309. package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
  310. package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
  311. package/src/config/schemas/call-site-catalog.ts +14 -0
  312. package/src/config/schemas/calls.ts +0 -9
  313. package/src/config/schemas/channels.ts +0 -5
  314. package/src/config/schemas/heartbeat.ts +64 -1
  315. package/src/config/schemas/ingress.ts +10 -6
  316. package/src/config/schemas/llm.ts +7 -10
  317. package/src/config/schemas/memory-lifecycle.ts +90 -24
  318. package/src/config/schemas/memory-v2.ts +121 -13
  319. package/src/config/schemas/platform.ts +49 -3
  320. package/src/config/schemas/services.ts +29 -15
  321. package/src/config/schemas/skills.ts +0 -6
  322. package/src/config/seed-inference-profiles.ts +230 -33
  323. package/src/contacts/contact-store.ts +0 -55
  324. package/src/contacts/contacts-write.ts +0 -27
  325. package/src/context/window-manager.ts +1 -2
  326. package/src/credential-execution/feature-gates.ts +10 -10
  327. package/src/credential-execution/process-manager.ts +12 -41
  328. package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
  329. package/src/daemon/assistant-attachments.ts +4 -4
  330. package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
  331. package/src/daemon/config-watcher.ts +89 -60
  332. package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
  333. package/src/daemon/conversation-agent-loop.ts +202 -61
  334. package/src/daemon/conversation-error.ts +87 -15
  335. package/src/daemon/conversation-lifecycle.ts +9 -4
  336. package/src/daemon/conversation-process.ts +24 -11
  337. package/src/daemon/conversation-runtime-assembly.ts +28 -2
  338. package/src/daemon/conversation-store.ts +2 -2
  339. package/src/daemon/conversation-surfaces.ts +305 -4
  340. package/src/daemon/conversation-tool-setup.ts +66 -62
  341. package/src/daemon/conversation.ts +38 -24
  342. package/src/daemon/date-context.ts +71 -22
  343. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  344. package/src/daemon/disk-pressure-guard.ts +343 -0
  345. package/src/daemon/disk-pressure-policy.ts +163 -0
  346. package/src/daemon/doordash-steps.ts +1 -1
  347. package/src/daemon/handlers/shared.ts +4 -2
  348. package/src/daemon/handlers/skills.ts +3 -4
  349. package/src/daemon/host-app-control-proxy.ts +389 -0
  350. package/src/daemon/host-bash-proxy.ts +117 -82
  351. package/src/daemon/host-browser-proxy.ts +67 -82
  352. package/src/daemon/host-cu-proxy.ts +127 -86
  353. package/src/daemon/host-file-proxy.ts +129 -69
  354. package/src/daemon/host-proxy-base.ts +294 -0
  355. package/src/daemon/host-proxy-preactivation.ts +82 -0
  356. package/src/daemon/host-transfer-proxy.ts +338 -129
  357. package/src/daemon/lifecycle.ts +194 -145
  358. package/src/daemon/meet-host-supervisor.ts +4 -4
  359. package/src/daemon/meet-manifest-loader.ts +0 -1
  360. package/src/daemon/memory-v2-startup.ts +14 -4
  361. package/src/daemon/message-protocol.ts +6 -8
  362. package/src/daemon/message-types/contacts.ts +23 -1
  363. package/src/daemon/message-types/conversations.ts +15 -8
  364. package/src/daemon/message-types/disk-pressure.ts +9 -0
  365. package/src/daemon/message-types/host-app-control.ts +150 -0
  366. package/src/daemon/message-types/host-bash.ts +4 -0
  367. package/src/daemon/message-types/host-cu.ts +2 -0
  368. package/src/daemon/message-types/host-file.ts +4 -0
  369. package/src/daemon/message-types/host-transfer.ts +3 -0
  370. package/src/daemon/message-types/messages.ts +3 -0
  371. package/src/daemon/message-types/schedules.ts +8 -3
  372. package/src/daemon/message-types/skills.ts +2 -2
  373. package/src/daemon/process-message.ts +18 -1
  374. package/src/daemon/profiler-run-store.ts +5 -5
  375. package/src/daemon/shutdown-handlers.ts +0 -3
  376. package/src/daemon/tool-setup-types.ts +51 -0
  377. package/src/daemon/tool-side-effects.ts +1 -1
  378. package/src/documents/document-store.ts +85 -0
  379. package/src/events/tool-audit-listener.ts +2 -1
  380. package/src/filing/filing-service.ts +30 -5
  381. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
  382. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
  383. package/src/heartbeat/heartbeat-run-store.ts +249 -0
  384. package/src/heartbeat/heartbeat-service.ts +459 -54
  385. package/src/home/__tests__/post-connect-feed.test.ts +99 -0
  386. package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
  387. package/src/home/__tests__/suggested-prompts.test.ts +89 -0
  388. package/src/home/feed-scheduler.ts +18 -0
  389. package/src/home/post-connect-feed.ts +68 -0
  390. package/src/home/relationship-state-writer.ts +17 -92
  391. package/src/home/suggested-prompts.ts +46 -10
  392. package/src/inbound/platform-callback-registration.ts +8 -15
  393. package/src/inbound/public-ingress-urls.ts +32 -34
  394. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  395. package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
  396. package/src/ipc/assistant-server.ts +70 -3
  397. package/src/ipc/cli-client.ts +32 -1
  398. package/src/ipc/gateway-client.ts +37 -3
  399. package/src/live-voice/live-voice-archive.ts +4 -4
  400. package/src/live-voice/live-voice-metrics.ts +10 -10
  401. package/src/live-voice/protocol.ts +5 -7
  402. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
  403. package/src/mcp/mcp-auth-orchestrator.ts +213 -0
  404. package/src/mcp/mcp-auth-state.ts +133 -0
  405. package/src/mcp/mcp-oauth-provider.ts +19 -0
  406. package/src/media/image-service.ts +1 -7
  407. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  408. package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
  409. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  412. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  413. package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
  414. package/src/memory/admin.ts +5 -9
  415. package/src/memory/anisotropy.test.ts +247 -0
  416. package/src/memory/anisotropy.ts +443 -0
  417. package/src/memory/auto-analysis-constants.ts +17 -0
  418. package/src/memory/auto-analysis-guard.ts +5 -15
  419. package/src/memory/canonical-guardian-store.ts +7 -7
  420. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
  421. package/src/memory/context-search/agent-protocol.ts +6 -6
  422. package/src/memory/context-search/agent-runner.ts +51 -9
  423. package/src/memory/context-search/sources/conversations.ts +2 -11
  424. package/src/memory/context-search/sources/memory-v2.ts +22 -9
  425. package/src/memory/context-search/sources/memory.ts +0 -1
  426. package/src/memory/context-search/types.ts +0 -1
  427. package/src/memory/conversation-crud.ts +5 -13
  428. package/src/memory/conversation-key-store.ts +2 -15
  429. package/src/memory/db-init.ts +6 -0
  430. package/src/memory/embedding-backend.ts +9 -21
  431. package/src/memory/embedding-runtime-manager.ts +119 -5
  432. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
  433. package/src/memory/graph/conversation-graph-memory.ts +43 -78
  434. package/src/memory/graph/extraction.ts +1 -3
  435. package/src/memory/graph/graph-search.test.ts +10 -67
  436. package/src/memory/graph/graph-search.ts +9 -20
  437. package/src/memory/graph/retriever.test.ts +6 -0
  438. package/src/memory/graph/retriever.ts +34 -10
  439. package/src/memory/graph/tools.ts +1 -1
  440. package/src/memory/indexer.ts +54 -45
  441. package/src/memory/job-handlers/backfill.ts +2 -11
  442. package/src/memory/job-handlers/cleanup.ts +43 -0
  443. package/src/memory/job-handlers/embedding.ts +6 -8
  444. package/src/memory/job-handlers/summarization.ts +2 -7
  445. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
  446. package/src/memory/jobs/embed-concept-page.ts +28 -2
  447. package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
  448. package/src/memory/jobs-store.ts +114 -22
  449. package/src/memory/jobs-worker.ts +193 -106
  450. package/src/memory/memory-v2-activation-log-store.ts +33 -15
  451. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  452. package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
  453. package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
  454. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  455. package/src/memory/migrations/index.ts +6 -0
  456. package/src/memory/migrations/registry.ts +8 -0
  457. package/src/memory/pkb/pkb-search.test.ts +6 -0
  458. package/src/memory/pkb/pkb-search.ts +7 -0
  459. package/src/memory/qdrant-client.ts +49 -32
  460. package/src/memory/rerank-local.ts +374 -0
  461. package/src/memory/schema/infrastructure.ts +15 -0
  462. package/src/memory/search/semantic.ts +13 -67
  463. package/src/memory/sparse-tokenize.ts +49 -0
  464. package/src/memory/trace-event-store.ts +1 -17
  465. package/src/memory/v2/__tests__/activation.test.ts +387 -344
  466. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  467. package/src/memory/v2/__tests__/injection.test.ts +181 -169
  468. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  469. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  470. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  471. package/src/memory/v2/__tests__/sim.test.ts +154 -188
  472. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  473. package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  474. package/src/memory/v2/__tests__/static-context.test.ts +76 -2
  475. package/src/memory/v2/activation.ts +213 -239
  476. package/src/memory/v2/consolidation-job.ts +65 -17
  477. package/src/memory/v2/constants.ts +7 -0
  478. package/src/memory/v2/injection.ts +123 -103
  479. package/src/memory/v2/prompts/consolidation.ts +348 -92
  480. package/src/memory/v2/qdrant.ts +198 -1
  481. package/src/memory/v2/reranker.ts +177 -0
  482. package/src/memory/v2/sim.ts +113 -77
  483. package/src/memory/v2/skill-content.ts +4 -3
  484. package/src/memory/v2/skill-store.ts +91 -53
  485. package/src/memory/v2/sparse-bm25.ts +245 -0
  486. package/src/memory/v2/static-context.ts +28 -5
  487. package/src/memory/v2/types.ts +10 -10
  488. package/src/messaging/providers/gmail/types.ts +0 -49
  489. package/src/messaging/providers/slack/adapter.ts +1 -31
  490. package/src/messaging/providers/slack/types.ts +0 -32
  491. package/src/notifications/README.md +10 -10
  492. package/src/notifications/broadcaster.ts +1 -1
  493. package/src/notifications/copy-composer.ts +13 -0
  494. package/src/notifications/guardian-question-mode.ts +5 -5
  495. package/src/notifications/signal.ts +4 -0
  496. package/src/oauth/AGENTS.md +3 -1
  497. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  498. package/src/oauth/connect-orchestrator.ts +6 -0
  499. package/src/oauth/connection-resolver.test.ts +66 -1
  500. package/src/oauth/connection-resolver.ts +55 -1
  501. package/src/oauth/credential-token-resolver.ts +1 -3
  502. package/src/oauth/manual-token-connection.ts +0 -4
  503. package/src/oauth/oauth-connect-state.ts +77 -0
  504. package/src/oauth/seed-providers.ts +58 -1
  505. package/src/outbound-proxy/index.ts +1 -37
  506. package/src/outbound-proxy/logging.ts +1 -1
  507. package/src/outbound-proxy/policy.ts +6 -5
  508. package/src/outbound-proxy/router.ts +2 -1
  509. package/src/permissions/approval-policy.test.ts +6 -275
  510. package/src/permissions/approval-policy.ts +0 -51
  511. package/src/permissions/checker.test.ts +0 -1
  512. package/src/permissions/checker.ts +3 -17
  513. package/src/permissions/gateway-threshold-reader.ts +2 -0
  514. package/src/permissions/prompter.ts +34 -1
  515. package/src/permissions/secret-prompter.ts +6 -2
  516. package/src/plugins/defaults/injectors.ts +35 -2
  517. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  518. package/src/plugins/types.ts +7 -0
  519. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  520. package/src/proactive-artifact/decision.test.ts +226 -0
  521. package/src/proactive-artifact/decision.ts +165 -0
  522. package/src/proactive-artifact/index.ts +7 -0
  523. package/src/proactive-artifact/job.test.ts +867 -0
  524. package/src/proactive-artifact/job.ts +352 -0
  525. package/src/proactive-artifact/message-copy.ts +41 -0
  526. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  527. package/src/proactive-artifact/trigger-state.ts +119 -0
  528. package/src/prompts/bootstrap-cleanup.ts +27 -0
  529. package/src/prompts/normalize-onboarding.ts +80 -0
  530. package/src/prompts/persona-resolver.ts +101 -9
  531. package/src/prompts/system-prompt.ts +23 -24
  532. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  533. package/src/prompts/templates/SOUL.md +13 -1
  534. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  535. package/src/providers/model-intents.ts +7 -0
  536. package/src/providers/openrouter/client.ts +8 -0
  537. package/src/providers/retry.ts +50 -0
  538. package/src/providers/speech-to-text/provider-catalog.ts +7 -8
  539. package/src/providers/types.ts +1 -0
  540. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  541. package/src/runtime/agent-wake.ts +238 -100
  542. package/src/runtime/assistant-event-hub.ts +151 -99
  543. package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
  544. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  545. package/src/runtime/auth/middleware.ts +0 -96
  546. package/src/runtime/auth/route-policy.ts +32 -0
  547. package/src/runtime/auth/same-actor.ts +216 -0
  548. package/src/runtime/btw-sidechain.ts +2 -3
  549. package/src/runtime/channel-invite-transport.ts +2 -48
  550. package/src/runtime/channel-invite-transports/email.ts +1 -1
  551. package/src/runtime/channel-invite-transports/slack.ts +1 -1
  552. package/src/runtime/channel-invite-transports/telegram.ts +1 -1
  553. package/src/runtime/channel-invite-transports/voice.ts +1 -1
  554. package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
  555. package/src/runtime/channel-invite-types.ts +54 -0
  556. package/src/runtime/channel-readiness-service.ts +32 -13
  557. package/src/runtime/channel-retry-sweep.ts +65 -1
  558. package/src/runtime/guardian-reply-router.ts +10 -0
  559. package/src/runtime/http-server.ts +3 -329
  560. package/src/runtime/http-types.ts +0 -5
  561. package/src/runtime/local-actor-identity.ts +52 -11
  562. package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
  563. package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
  564. package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
  565. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
  566. package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
  567. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
  568. package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
  569. package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
  570. package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
  571. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
  572. package/src/runtime/migrations/migration-transport.ts +7 -7
  573. package/src/runtime/migrations/vbundle-builder.ts +327 -60
  574. package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
  575. package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
  576. package/src/runtime/migrations/vbundle-importer.ts +245 -68
  577. package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
  578. package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
  579. package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
  580. package/src/runtime/migrations/vbundle-validator.ts +114 -0
  581. package/src/runtime/pending-interactions.ts +43 -9
  582. package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
  583. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  584. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
  585. package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
  586. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
  587. package/src/runtime/routes/approval-interception-types.ts +13 -0
  588. package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
  589. package/src/runtime/routes/backup-routes.ts +15 -38
  590. package/src/runtime/routes/btw-routes.ts +14 -37
  591. package/src/runtime/routes/client-routes.ts +21 -2
  592. package/src/runtime/routes/contact-prompt-routes.ts +183 -0
  593. package/src/runtime/routes/contact-routes.ts +0 -25
  594. package/src/runtime/routes/conversation-query-routes.ts +36 -1
  595. package/src/runtime/routes/conversation-routes.ts +65 -39
  596. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  597. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  598. package/src/runtime/routes/document-pdf-renderer.ts +169 -0
  599. package/src/runtime/routes/documents-routes.ts +32 -75
  600. package/src/runtime/routes/errors.ts +19 -4
  601. package/src/runtime/routes/events-routes.ts +38 -0
  602. package/src/runtime/routes/gateway-log-routes.ts +79 -0
  603. package/src/runtime/routes/guardian-approval-interception.ts +2 -8
  604. package/src/runtime/routes/heartbeat-routes.ts +103 -38
  605. package/src/runtime/routes/host-app-control-routes.ts +134 -0
  606. package/src/runtime/routes/host-bash-routes.ts +56 -6
  607. package/src/runtime/routes/host-browser-routes.ts +108 -13
  608. package/src/runtime/routes/host-cu-routes.ts +66 -9
  609. package/src/runtime/routes/host-file-routes.ts +54 -5
  610. package/src/runtime/routes/host-transfer-routes.ts +122 -19
  611. package/src/runtime/routes/http-adapter.ts +1 -0
  612. package/src/runtime/routes/identity-intro-cache.ts +30 -0
  613. package/src/runtime/routes/identity-routes.ts +21 -180
  614. package/src/runtime/routes/inbound-message-handler.ts +78 -21
  615. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
  616. package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
  617. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  618. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
  619. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
  620. package/src/runtime/routes/index.ts +14 -0
  621. package/src/runtime/routes/mcp-auth-routes.ts +132 -0
  622. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  623. package/src/runtime/routes/memory-item-routes.ts +10 -12
  624. package/src/runtime/routes/memory-v2-routes.ts +474 -1
  625. package/src/runtime/routes/migration-routes.ts +96 -0
  626. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  627. package/src/runtime/routes/schedule-routes.ts +7 -0
  628. package/src/runtime/verification-outbound-actions.ts +4 -4
  629. package/src/runtime/verification-templates.ts +4 -7
  630. package/src/schedule/integration-status.ts +66 -2
  631. package/src/schedule/recurrence-engine.ts +4 -1
  632. package/src/schedule/retry-backoff.ts +18 -0
  633. package/src/schedule/retry-policy.ts +82 -0
  634. package/src/schedule/run-script.ts +37 -5
  635. package/src/schedule/schedule-recovery.ts +64 -0
  636. package/src/schedule/schedule-store.ts +106 -2
  637. package/src/schedule/scheduler-types.ts +25 -0
  638. package/src/schedule/scheduler.ts +83 -39
  639. package/src/security/encrypted-store.ts +2 -0
  640. package/src/security/oauth-callback-registry.ts +8 -0
  641. package/src/security/secure-keys.ts +55 -0
  642. package/src/sequence/analytics.ts +5 -5
  643. package/src/sequence/engine.ts +1 -1
  644. package/src/skills/catalog-files.ts +2 -8
  645. package/src/skills/include-graph.ts +5 -5
  646. package/src/skills/remote-skill-policy.ts +10 -16
  647. package/src/skills/skill-file-provider.ts +1 -1
  648. package/src/skills/skill-file-types.ts +13 -0
  649. package/src/skills/skillssh-audit-types.ts +28 -0
  650. package/src/skills/skillssh-registry.ts +8 -21
  651. package/src/subagent/index.ts +1 -7
  652. package/src/subagent/manager.ts +1 -15
  653. package/src/tasks/task-runner.ts +0 -1
  654. package/src/tasks/task-store.ts +0 -3
  655. package/src/telemetry/types.ts +2 -0
  656. package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
  657. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  658. package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
  659. package/src/tools/apps/executors.ts +56 -69
  660. package/src/tools/background-tool-registry.ts +17 -3
  661. package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
  662. package/src/tools/browser/browser-execution.ts +2 -2
  663. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
  664. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
  665. package/src/tools/browser/cdp-client/factory.ts +23 -24
  666. package/src/tools/browser/cdp-client/index.ts +1 -14
  667. package/src/tools/computer-use/definitions.ts +42 -20
  668. package/src/tools/executor.ts +2 -0
  669. package/src/tools/host-filesystem/edit.test.ts +151 -0
  670. package/src/tools/host-filesystem/edit.ts +68 -0
  671. package/src/tools/host-filesystem/read.test.ts +129 -0
  672. package/src/tools/host-filesystem/read.ts +68 -0
  673. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  674. package/src/tools/host-filesystem/transfer.ts +78 -3
  675. package/src/tools/host-filesystem/write.test.ts +134 -0
  676. package/src/tools/host-filesystem/write.ts +68 -0
  677. package/src/tools/host-terminal/host-shell.ts +66 -1
  678. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  679. package/src/tools/memory/register.test.ts +12 -9
  680. package/src/tools/memory/register.ts +1 -2
  681. package/src/tools/provider-tool-name.ts +28 -0
  682. package/src/tools/registry.ts +30 -9
  683. package/src/tools/schedule/create.ts +6 -0
  684. package/src/tools/schedule/list.ts +2 -0
  685. package/src/tools/schedule/update.ts +10 -0
  686. package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
  687. package/src/tools/shared/filesystem/path-policy.ts +25 -1
  688. package/src/tools/skills/load.ts +0 -32
  689. package/src/tools/terminal/shell.ts +9 -1
  690. package/src/tools/tool-approval-handler.ts +32 -11
  691. package/src/tools/types.ts +28 -2
  692. package/src/tts/provider-catalog.ts +3 -5
  693. package/src/usage/pricing.ts +1 -1
  694. package/src/util/disk-usage.ts +138 -0
  695. package/src/util/platform.ts +21 -11
  696. package/src/util/process-liveness.ts +26 -0
  697. package/src/workspace/hatched-date.ts +86 -0
  698. package/src/workspace/heartbeat-service.ts +19 -0
  699. package/src/workspace/migrations/003-seed-device-id.ts +1 -1
  700. package/src/workspace/migrations/006-services-config.ts +8 -5
  701. package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
  702. package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
  703. package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
  704. package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
  705. package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
  706. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
  707. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
  708. package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
  709. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
  710. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  711. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  712. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  713. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  714. package/src/workspace/migrations/AGENTS.md +1 -1
  715. package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
  716. package/src/workspace/migrations/registry.ts +8 -0
  717. package/src/workspace/migrations/utils.ts +21 -0
  718. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  719. package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
  720. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
  721. package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
  722. package/src/__tests__/twilio-rest.test.ts +0 -34
  723. package/src/backup/__tests__/backup-key.test.ts +0 -152
  724. package/src/backup/__tests__/backup-worker.test.ts +0 -782
  725. package/src/backup/__tests__/offsite-writer.test.ts +0 -641
  726. package/src/backup/__tests__/stream-crypt.test.ts +0 -228
  727. package/src/backup/backup-key.ts +0 -137
  728. package/src/backup/backup-worker.ts +0 -472
  729. package/src/backup/offsite-writer.ts +0 -222
  730. package/src/backup/stream-crypt.ts +0 -263
  731. package/src/daemon/message-types/pairing.ts +0 -58
  732. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  733. package/src/memory/v2/skill-qdrant.ts +0 -395
  734. package/src/outbound-proxy/config.ts +0 -20
  735. package/src/outbound-proxy/health.ts +0 -18
  736. package/src/outbound-proxy/types.ts +0 -150
  737. package/src/runtime/capability-tokens.ts +0 -190
  738. package/src/signals/bash.ts +0 -198
  739. package/src/signals/mcp-reload.ts +0 -18
@@ -0,0 +1,99 @@
1
+ import { mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
5
+
6
+ // ─── assistantEventHub mock ────────────────────────────────────────────
7
+ const publishSpy = mock<(event: unknown) => Promise<void>>(async () => {});
8
+
9
+ mock.module("../../runtime/assistant-event-hub.js", () => ({
10
+ assistantEventHub: {
11
+ publish: publishSpy,
12
+ subscribe: () => () => {},
13
+ },
14
+ }));
15
+
16
+ const { emitPostConnectNudge } = await import("../post-connect-feed.js");
17
+ const { readHomeFeed } = await import("../feed-writer.js");
18
+
19
+ // ─── tmpdir workspace lifecycle ────────────────────────────────────────
20
+
21
+ let workspaceDir: string;
22
+ let origWorkspaceDir: string | undefined;
23
+
24
+ beforeEach(() => {
25
+ workspaceDir = mkdtempSync(join(tmpdir(), "vellum-pcf-"));
26
+ origWorkspaceDir = process.env.VELLUM_WORKSPACE_DIR;
27
+ process.env.VELLUM_WORKSPACE_DIR = workspaceDir;
28
+ publishSpy.mockClear();
29
+ });
30
+
31
+ afterEach(() => {
32
+ if (origWorkspaceDir === undefined) {
33
+ delete process.env.VELLUM_WORKSPACE_DIR;
34
+ } else {
35
+ process.env.VELLUM_WORKSPACE_DIR = origWorkspaceDir;
36
+ }
37
+ try {
38
+ rmSync(workspaceDir, { recursive: true, force: true });
39
+ } catch {
40
+ // best-effort
41
+ }
42
+ });
43
+
44
+ // ─── Tests ─────────────────────────────────────────────────────────────
45
+
46
+ describe("emitPostConnectNudge", () => {
47
+ test("emits a nudge feed item for google", async () => {
48
+ await emitPostConnectNudge("google");
49
+
50
+ const feed = readHomeFeed();
51
+ expect(feed.items).toHaveLength(1);
52
+
53
+ const item = feed.items[0]!;
54
+ expect(item.id).toBe("connect-nudge:google");
55
+ expect(item.type).toBe("nudge");
56
+ expect(item.source).toBe("gmail");
57
+ expect(item.title).toContain("Gmail connected");
58
+ expect(item.actions).toHaveLength(2);
59
+ expect(item.actions![0]!.label).toBe("Triage my inbox");
60
+ expect(item.actions![1]!.label).toBe("Set up daily digest");
61
+ expect(item.expiresAt).toBeDefined();
62
+ expect(item.author).toBe("platform");
63
+ });
64
+
65
+ test("no-ops for non-email services", async () => {
66
+ await emitPostConnectNudge("slack");
67
+ await emitPostConnectNudge("notion");
68
+ await emitPostConnectNudge("linear");
69
+
70
+ const feed = readHomeFeed();
71
+ expect(feed.items).toHaveLength(0);
72
+ });
73
+
74
+ test("reconnecting appends a second nudge (same-author nudges don't deduplicate)", async () => {
75
+ await emitPostConnectNudge("google");
76
+ await emitPostConnectNudge("google");
77
+
78
+ const feed = readHomeFeed();
79
+ // Same-author (platform) same-source nudges both persist —
80
+ // the feed writer's author-resolution only handles cross-author
81
+ // replacement. In practice, reconnects are rare and the 7-day
82
+ // expiry prevents buildup.
83
+ expect(feed.items).toHaveLength(2);
84
+ expect(feed.items.every((i) => i.id === "connect-nudge:google")).toBe(true);
85
+ });
86
+
87
+ test("nudge expires after 7 days", async () => {
88
+ await emitPostConnectNudge("google");
89
+
90
+ const feed = readHomeFeed();
91
+ const item = feed.items[0]!;
92
+ const created = new Date(item.createdAt).getTime();
93
+ const expires = new Date(item.expiresAt!).getTime();
94
+ const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;
95
+
96
+ // Allow 1 second tolerance for test execution time
97
+ expect(Math.abs(expires - created - sevenDaysMs)).toBeLessThan(1000);
98
+ });
99
+ });
@@ -432,6 +432,12 @@ describe("relationship-state-writer", () => {
432
432
  // Also sanity: it must be a real, recent date (not the epoch
433
433
  // sentinel we emit when stat fails).
434
434
  expect(Date.parse(first.hatchedDate)).toBeGreaterThan(0);
435
+ const sidecarPath = join(workspaceDir, "data", "hatched.json");
436
+ expect(existsSync(sidecarPath)).toBe(true);
437
+ const sidecar = JSON.parse(readFileSync(sidecarPath, "utf-8")) as {
438
+ hatchedAt: string;
439
+ };
440
+ expect(sidecar.hatchedAt).toBe(first.hatchedDate);
435
441
  });
436
442
 
437
443
  test("honors an explicit Hatched bullet in IDENTITY.md over file birthtime", async () => {
@@ -488,9 +494,10 @@ describe("relationship-state-writer", () => {
488
494
  expect(state.hatchedDate).toBe("2025-01-15T00:00:00.000Z");
489
495
  });
490
496
 
491
- test("IDENTITY.md birthtime takes precedence over the sidecar", async () => {
492
- // Seed a stale sidecar and then an IDENTITY.md without an
493
- // explicit Hatched bullet — birthtime wins over the sidecar.
497
+ test("sidecar takes precedence over IDENTITY.md metadata", async () => {
498
+ // Seed an existing sidecar and then an IDENTITY.md without an
499
+ // explicit Hatched bullet — the persisted sidecar wins so the
500
+ // date remains stable across later identity edits.
494
501
  mkdirSync(join(workspaceDir, "data"), { recursive: true });
495
502
  writeFileSync(
496
503
  join(workspaceDir, "data", "hatched.json"),
@@ -500,12 +507,7 @@ describe("relationship-state-writer", () => {
500
507
  writeFile("IDENTITY.md", "- **Name:** Sage\n- **Role:** Assistant\n");
501
508
 
502
509
  const state = (await computeRelationshipState()) as RelationshipStateLike;
503
- // The sidecar value is 2020-06-01 but IDENTITY.md was just
504
- // written, so birthtime will be a much more recent date.
505
- expect(state.hatchedDate).not.toBe("2020-06-01T00:00:00.000Z");
506
- expect(Date.parse(state.hatchedDate)).toBeGreaterThan(
507
- Date.parse("2020-06-01T00:00:00.000Z"),
508
- );
510
+ expect(state.hatchedDate).toBe("2020-06-01T00:00:00.000Z");
509
511
  });
510
512
  });
511
513
 
@@ -0,0 +1,89 @@
1
+ import { describe, expect, mock, test } from "bun:test";
2
+
3
+ // ─── Mocks ─────────────────────────────────────────────────────────────
4
+
5
+ let mockConnectedProviders = new Set<string>();
6
+
7
+ mock.module("../../oauth/oauth-store.js", () => ({
8
+ isProviderConnected: async (provider: string) =>
9
+ mockConnectedProviders.has(provider),
10
+ listProviders: () => [
11
+ { provider: "google" },
12
+ { provider: "slack" },
13
+ { provider: "notion" },
14
+ { provider: "linear" },
15
+ { provider: "github" },
16
+ ],
17
+ }));
18
+
19
+ mock.module("../../util/logger.js", () => ({
20
+ getLogger: () =>
21
+ new Proxy({} as Record<string, unknown>, {
22
+ get: () => () => {},
23
+ }),
24
+ }));
25
+
26
+ const { getSuggestedPrompts } = await import("../suggested-prompts.js");
27
+
28
+ // ─── Tests ─────────────────────────────────────────────────────────────
29
+
30
+ describe("getSuggestedPrompts", () => {
31
+ test("shows 'Connect X' prompts when providers are disconnected", async () => {
32
+ mockConnectedProviders = new Set();
33
+
34
+ const prompts = await getSuggestedPrompts();
35
+ const ids = prompts.map((p) => p.id);
36
+
37
+ expect(ids).toContain("connect-google");
38
+ expect(ids).toContain("connect-slack");
39
+ expect(prompts.find((p) => p.id === "connect-google")!.label).toBe(
40
+ "Connect Gmail",
41
+ );
42
+ });
43
+
44
+ test("shows email management prompts when Google is connected", async () => {
45
+ mockConnectedProviders = new Set(["google"]);
46
+
47
+ const prompts = await getSuggestedPrompts();
48
+ const ids = prompts.map((p) => p.id);
49
+
50
+ // Should NOT show "Connect Gmail"
51
+ expect(ids).not.toContain("connect-google");
52
+
53
+ // Should show management prompts
54
+ expect(ids).toContain("manage-google-triage-my-inbox");
55
+ expect(ids).toContain("manage-google-summarize-today's-emails");
56
+
57
+ const triage = prompts.find(
58
+ (p) => p.id === "manage-google-triage-my-inbox",
59
+ );
60
+ expect(triage).toBeDefined();
61
+ expect(triage!.label).toBe("Triage my inbox");
62
+ expect(triage!.icon).toBe("mail");
63
+ expect(triage!.source).toBe("deterministic");
64
+ });
65
+
66
+ test("still shows Connect prompts for disconnected providers alongside management prompts", async () => {
67
+ mockConnectedProviders = new Set(["google"]);
68
+
69
+ const prompts = await getSuggestedPrompts();
70
+ const ids = prompts.map((p) => p.id);
71
+
72
+ // Gmail management prompts
73
+ expect(ids).toContain("manage-google-triage-my-inbox");
74
+ // Slack still disconnected
75
+ expect(ids).toContain("connect-slack");
76
+ });
77
+
78
+ test("providers without connectedPrompts show nothing when connected", async () => {
79
+ mockConnectedProviders = new Set(["slack"]);
80
+
81
+ const prompts = await getSuggestedPrompts();
82
+ const ids = prompts.map((p) => p.id);
83
+
84
+ // No connect prompt since connected
85
+ expect(ids).not.toContain("connect-slack");
86
+ // No management prompts since Slack doesn't define any
87
+ expect(ids.filter((id) => id.startsWith("manage-slack"))).toHaveLength(0);
88
+ });
89
+ });
@@ -28,6 +28,11 @@
28
28
  * scheduler needing to touch the event hub.
29
29
  */
30
30
 
31
+ import {
32
+ checkDiskPressureBackgroundGate,
33
+ diskPressureBackgroundSkipLogFields,
34
+ shouldLogDiskPressureBackgroundSkip,
35
+ } from "../daemon/disk-pressure-background-gate.js";
31
36
  import { getLogger } from "../util/logger.js";
32
37
  import type { FeedItem } from "./feed-types.js";
33
38
  import {
@@ -119,6 +124,19 @@ export function startFeedScheduler(
119
124
  rollupRan: false,
120
125
  };
121
126
  if (stopped || tickRunning) return summary;
127
+ const diskPressureGate = checkDiskPressureBackgroundGate("background-work");
128
+ if (diskPressureGate.action === "skip") {
129
+ if (shouldLogDiskPressureBackgroundSkip("home-feed-scheduler")) {
130
+ log.warn(
131
+ {
132
+ source: "feed-scheduler",
133
+ ...diskPressureBackgroundSkipLogFields(diskPressureGate),
134
+ },
135
+ "Home feed scheduler skipped during disk pressure cleanup mode",
136
+ );
137
+ }
138
+ return summary;
139
+ }
122
140
  tickRunning = true;
123
141
  const nowMs = now.getTime();
124
142
  try {
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Post-connection feed nudge.
3
+ *
4
+ * Emits a one-time nudge feed item when the user successfully connects
5
+ * an email-capable OAuth provider. The nudge highlights ongoing email
6
+ * management capabilities (inbox triage, daily digests) so the user
7
+ * discovers what they can do beyond the initial setup.
8
+ *
9
+ * Uses a deterministic id (`connect-nudge:<service>`) so reconnecting
10
+ * the same provider replaces the existing nudge in place rather than
11
+ * appending a duplicate.
12
+ */
13
+
14
+ import type { FeedItem } from "./feed-types.js";
15
+ import { appendFeedItem } from "./feed-writer.js";
16
+
17
+ /**
18
+ * Services that should trigger an email management nudge on connection.
19
+ * Only providers with real email integration are listed — see
20
+ * `relationship-state-writer.ts` for the same "only Gmail is real" note.
21
+ */
22
+ const EMAIL_SERVICES = new Set(["google"]);
23
+
24
+ /**
25
+ * Emit a feed nudge for a newly connected email provider.
26
+ *
27
+ * No-ops silently when the service is not email-capable. Never throws —
28
+ * the feed writer's warn-log contract absorbs persistence failures.
29
+ */
30
+ export async function emitPostConnectNudge(service: string): Promise<void> {
31
+ if (!EMAIL_SERVICES.has(service)) return;
32
+
33
+ const now = new Date();
34
+ const expiresAt = new Date(
35
+ now.getTime() + 7 * 24 * 60 * 60 * 1000,
36
+ ).toISOString();
37
+
38
+ const item: FeedItem = {
39
+ id: `connect-nudge:${service}`,
40
+ type: "nudge",
41
+ priority: 70,
42
+ title: "Gmail connected — want ongoing help?",
43
+ summary:
44
+ "I can triage your inbox, summarize new emails, or draft replies to important threads.",
45
+ source: "gmail",
46
+ timestamp: now.toISOString(),
47
+ status: "new",
48
+ expiresAt,
49
+ author: "platform",
50
+ createdAt: now.toISOString(),
51
+ actions: [
52
+ {
53
+ id: "inbox-triage",
54
+ label: "Triage my inbox",
55
+ prompt:
56
+ "Help me triage my inbox — summarize what's unread and flag anything that needs a reply",
57
+ },
58
+ {
59
+ id: "daily-digest",
60
+ label: "Set up daily digest",
61
+ prompt:
62
+ "Set up a daily email digest that summarizes my unread messages each morning",
63
+ },
64
+ ],
65
+ };
66
+
67
+ await appendFeedItem(item);
68
+ }
@@ -18,13 +18,7 @@
18
18
  * a missing or unreadable file degrades gracefully to an empty string.
19
19
  */
20
20
 
21
- import {
22
- existsSync,
23
- mkdirSync,
24
- readFileSync,
25
- statSync,
26
- writeFileSync,
27
- } from "node:fs";
21
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
28
22
  import { join } from "node:path";
29
23
 
30
24
  import { countConversations as countConversationsDb } from "../memory/conversation-queries.js";
@@ -39,6 +33,7 @@ import {
39
33
  getWorkspaceDir,
40
34
  getWorkspacePromptPath,
41
35
  } from "../util/platform.js";
36
+ import { resolveAndPersistHatchedAt } from "../workspace/hatched-date.js";
42
37
  import { computeProgressPercent, computeTier } from "./progress-formula.js";
43
38
  import {
44
39
  type Capability,
@@ -149,11 +144,12 @@ function readOnboardingSidecar(): OnboardingContext | null {
149
144
  * Reads USER.md / SOUL.md / IDENTITY.md, queries the oauth connection
150
145
  * store, and counts conversations via the DB-authoritative helper.
151
146
  *
152
- * Side effect: on the very first call when IDENTITY.md cannot provide
153
- * a hatched date, `resolveFallbackHatchedDate` persists a one-time
154
- * `data/hatched.json` sidecar so subsequent calls return a monotonic
155
- * timestamp. All other paths are read-only. Callers that want to
156
- * persist the full snapshot should use `writeRelationshipState()`.
147
+ * Side effect: on the very first call without an explicit Hatched
148
+ * bullet or existing hatched sidecar, the shared resolver persists a
149
+ * one-time `data/hatched.json` value seeded from IDENTITY.md metadata
150
+ * or a real current timestamp. All other paths are read-only. Callers
151
+ * that want to persist the full snapshot should use
152
+ * `writeRelationshipState()`.
157
153
  */
158
154
  export async function computeRelationshipState(): Promise<RelationshipState> {
159
155
  // Persona source-of-truth:
@@ -682,74 +678,17 @@ function countConversations(): number {
682
678
  }
683
679
  }
684
680
 
685
- /**
686
- * Filename for the hatched-date sidecar, used as a stable fallback
687
- * when IDENTITY.md is missing / unreadable / has no explicit hatched
688
- * bullet and file stat is unavailable. Lives under the workspace
689
- * data dir alongside `relationship-state.json`.
690
- */
691
- const HATCHED_SIDECAR_FILENAME = "hatched.json";
692
-
693
- function getHatchedSidecarPath(): string {
694
- return join(getDataDir(), HATCHED_SIDECAR_FILENAME);
695
- }
696
-
697
- /**
698
- * Resolve a stable hatched-date fallback timestamp.
699
- *
700
- * The Swift client, OpenAPI schema, and UI have no special handling
701
- * for a Unix-epoch sentinel — they'll render "1/1/1970" to the user.
702
- * Instead, we use `new Date().toISOString()` the first time a
703
- * fallback is needed and persist it to a small sidecar file
704
- * (`data/hatched.json`). Subsequent calls read the sidecar first, so
705
- * the returned timestamp is monotonic across writes and the
706
- * `hatchedDate` field never drifts once initialized.
707
- *
708
- * Never throws — a sidecar read/write failure still yields a valid
709
- * (though non-stable) `now` timestamp, which is still far better than
710
- * the epoch sentinel.
711
- */
712
- function resolveFallbackHatchedDate(): string {
713
- const path = getHatchedSidecarPath();
714
- try {
715
- if (existsSync(path)) {
716
- const parsed = JSON.parse(readFileSync(path, "utf-8")) as {
717
- hatchedAt?: string;
718
- };
719
- if (parsed.hatchedAt && !isNaN(Date.parse(parsed.hatchedAt))) {
720
- return parsed.hatchedAt;
721
- }
722
- }
723
- } catch {
724
- // Fall through to write a fresh sidecar.
725
- }
726
- const now = new Date().toISOString();
727
- try {
728
- mkdirSync(getDataDir(), { recursive: true });
729
- writeFileSync(path, JSON.stringify({ hatchedAt: now }, null, 2), "utf-8");
730
- } catch {
731
- // If even the sidecar write fails, return `now` anyway — the
732
- // caller will just get a fresh-looking date on every call. Not
733
- // ideal, but far better than the epoch sentinel.
734
- }
735
- return now;
736
- }
737
-
738
681
  /**
739
682
  * Pull `assistantName` and `hatchedDate` from IDENTITY.md.
740
683
  *
741
684
  * IDENTITY.md is a freeform markdown file, so for the name we scan
742
685
  * bullet lines for any recognizable `name` label (`Name`,
743
686
  * `Assistant Name`, `Preferred Name`, etc.). For the hatched date we
744
- * prefer any explicit `hatched:` / `birth:` bullet, then fall back to
745
- * the file's `stat.birthtime` (matching the pattern already
746
- * established by `identity-routes.ts`), and finally to `stat.mtime`
747
- * if birthtime is unavailable. We never fall back to `new Date()`
748
- * directly — `writeRelationshipState()` is called on every turn
749
- * boundary, so a raw `Date.now()` fallback would cause `hatchedDate`
750
- * to drift forward on every write. Instead, when nothing else is
751
- * readable we resolve via `resolveFallbackHatchedDate()` which
752
- * persists a stable timestamp to a sidecar file on first use.
687
+ * prefer any explicit `hatched:` / `birth:` bullet, then use the
688
+ * shared hatched-date resolver. That resolver reads an existing
689
+ * `data/hatched.json` sidecar first, otherwise seeds it from valid
690
+ * IDENTITY.md birthtime/mtime or a real current timestamp. This keeps
691
+ * `hatchedDate` stable without writing from read-only HTTP handlers.
753
692
  */
754
693
  function parseIdentity(identityPath: string): {
755
694
  assistantName: string;
@@ -792,24 +731,10 @@ function parseIdentity(identityPath: string): {
792
731
  return { assistantName, hatchedDate: explicitHatched };
793
732
  }
794
733
 
795
- // Stable fallback: use the IDENTITY.md file birth time so the
796
- // relationship start date is monotonic across turns. Matches the
797
- // approach used by `identity-routes.ts` for the Settings UI.
798
- try {
799
- const stats = statSync(identityPath);
800
- const candidate =
801
- stats.birthtime.getTime() > 0 ? stats.birthtime : stats.mtime;
802
- if (candidate.getTime() > 0) {
803
- return { assistantName, hatchedDate: candidate.toISOString() };
804
- }
805
- } catch {
806
- // File missing or unreadable — fall through to the sidecar.
807
- }
808
-
809
- // Last-ditch fallback: `resolveFallbackHatchedDate` returns a stable,
810
- // real timestamp (persisted to `data/hatched.json` on first call) so
811
- // the wire contract always carries a valid ISO date.
812
- return { assistantName, hatchedDate: resolveFallbackHatchedDate() };
734
+ return {
735
+ assistantName,
736
+ hatchedDate: resolveAndPersistHatchedAt(identityPath),
737
+ };
813
738
  }
814
739
 
815
740
  /**
@@ -21,14 +21,34 @@ const log = getLogger("suggested-prompts");
21
21
  * listed here produce deterministic "Connect X" prompts when disconnected.
22
22
  * The icon values are VIcon case names rendered by the macOS client.
23
23
  */
24
+ interface PromptEntry {
25
+ label: string;
26
+ prompt: string;
27
+ icon: string;
28
+ }
29
+
24
30
  const CONNECT_PROMPT_META: Record<
25
31
  string,
26
- { label: string; prompt: string; icon: string }
32
+ PromptEntry & { connectedPrompts?: PromptEntry[] }
27
33
  > = {
28
34
  google: {
29
35
  label: "Connect Gmail",
30
36
  prompt: "Help me connect my Gmail account",
31
37
  icon: "mail",
38
+ connectedPrompts: [
39
+ {
40
+ label: "Triage my inbox",
41
+ prompt:
42
+ "Help me triage my inbox — summarize what's unread and flag anything that needs a reply",
43
+ icon: "mail",
44
+ },
45
+ {
46
+ label: "Summarize today's emails",
47
+ prompt:
48
+ "Summarize the emails I received today and highlight anything important",
49
+ icon: "mail",
50
+ },
51
+ ],
32
52
  },
33
53
  slack: {
34
54
  label: "Connect Slack",
@@ -75,7 +95,9 @@ export async function getSuggestedPrompts(): Promise<SuggestedPrompt[]> {
75
95
 
76
96
  /**
77
97
  * Check which well-known OAuth providers are not connected and return
78
- * a "Connect X" prompt for each.
98
+ * a "Connect X" prompt for each. For connected providers that have
99
+ * `connectedPrompts`, return those instead so users discover ongoing
100
+ * management capabilities.
79
101
  */
80
102
  async function getDeterministicPrompts(): Promise<SuggestedPrompt[]> {
81
103
  const providers = listProviders();
@@ -86,15 +108,29 @@ async function getDeterministicPrompts(): Promise<SuggestedPrompt[]> {
86
108
  if (!meta) continue;
87
109
 
88
110
  const connected = await isProviderConnected(provider.provider);
89
- if (connected) continue;
90
111
 
91
- prompts.push({
92
- id: `connect-${provider.provider}`,
93
- label: meta.label,
94
- icon: meta.icon,
95
- prompt: meta.prompt,
96
- source: "deterministic",
97
- });
112
+ if (!connected) {
113
+ prompts.push({
114
+ id: `connect-${provider.provider}`,
115
+ label: meta.label,
116
+ icon: meta.icon,
117
+ prompt: meta.prompt,
118
+ source: "deterministic",
119
+ });
120
+ continue;
121
+ }
122
+
123
+ if (meta.connectedPrompts) {
124
+ for (const cp of meta.connectedPrompts) {
125
+ prompts.push({
126
+ id: `manage-${provider.provider}-${cp.label.toLowerCase().replace(/\s+/g, "-")}`,
127
+ label: cp.label,
128
+ icon: cp.icon,
129
+ prompt: cp.prompt,
130
+ source: "deterministic",
131
+ });
132
+ }
133
+ }
98
134
  }
99
135
 
100
136
  return prompts;
@@ -16,11 +16,7 @@
16
16
  * callback_url that external services should use.
17
17
  */
18
18
 
19
- import {
20
- getPlatformAssistantId,
21
- getPlatformBaseUrl,
22
- getPlatformInternalApiKey,
23
- } from "../config/env.js";
19
+ import { getPlatformAssistantId, getPlatformBaseUrl } from "../config/env.js";
24
20
  import { getIsPlatform } from "../config/env-registry.js";
25
21
  import { credentialKey } from "../security/credential-key.js";
26
22
  import { getSecureKeyAsync } from "../security/secure-keys.js";
@@ -32,7 +28,6 @@ export interface PlatformCallbackRegistrationContext {
32
28
  isPlatform: boolean;
33
29
  platformBaseUrl: string;
34
30
  assistantId: string;
35
- hasInternalApiKey: boolean;
36
31
  hasAssistantApiKey: boolean;
37
32
  authHeader: string | null;
38
33
  enabled: boolean;
@@ -54,20 +49,18 @@ export async function resolvePlatformCallbackRegistrationContext(): Promise<Plat
54
49
  );
55
50
  const assistantId =
56
51
  getPlatformAssistantId().trim() || storedAssistantIdRaw?.trim() || "";
57
- const internalApiKey = getPlatformInternalApiKey().trim();
58
- const assistantApiKey = storedAssistantApiKeyRaw?.trim() || "";
59
- const authHeader = internalApiKey
60
- ? `Bearer ${internalApiKey}`
61
- : assistantApiKey
62
- ? `Api-Key ${assistantApiKey}`
63
- : null;
52
+ const envAssistantCredential = process.env.ASSISTANT_API_KEY?.trim();
53
+ const assistantCredential =
54
+ storedAssistantApiKeyRaw?.trim() || envAssistantCredential || undefined;
55
+ const authHeader = assistantCredential
56
+ ? `Api-Key ${assistantCredential}`
57
+ : null;
64
58
 
65
59
  return {
66
60
  isPlatform: platform,
67
61
  platformBaseUrl,
68
62
  assistantId,
69
- hasInternalApiKey: internalApiKey.length > 0,
70
- hasAssistantApiKey: assistantApiKey.length > 0,
63
+ hasAssistantApiKey: !!assistantCredential,
71
64
  authHeader,
72
65
  // Enabled when we have enough context to register callback routes.
73
66
  // Does NOT require IS_PLATFORM — self-hosted assistants with stored