@vellumai/assistant 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -0,0 +1,66 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
+
3
+ import { resolveConversationId } from "../conversation-id.js";
4
+
5
+ const FAILURE_HELP = "No conversation ID. Provide one explicitly.";
6
+
7
+ let savedConvId: string | undefined;
8
+ let savedSkillCtx: string | undefined;
9
+
10
+ beforeEach(() => {
11
+ savedConvId = process.env.__CONVERSATION_ID;
12
+ savedSkillCtx = process.env.__SKILL_CONTEXT_JSON;
13
+ delete process.env.__CONVERSATION_ID;
14
+ delete process.env.__SKILL_CONTEXT_JSON;
15
+ });
16
+
17
+ afterEach(() => {
18
+ if (savedConvId !== undefined) {
19
+ process.env.__CONVERSATION_ID = savedConvId;
20
+ } else {
21
+ delete process.env.__CONVERSATION_ID;
22
+ }
23
+ if (savedSkillCtx !== undefined) {
24
+ process.env.__SKILL_CONTEXT_JSON = savedSkillCtx;
25
+ } else {
26
+ delete process.env.__SKILL_CONTEXT_JSON;
27
+ }
28
+ });
29
+
30
+ describe("resolveConversationId", () => {
31
+ test("explicit provided → returns it", () => {
32
+ const result = resolveConversationId({
33
+ explicit: "conv-explicit-123",
34
+ failureHelp: FAILURE_HELP,
35
+ });
36
+ expect(result).toBe("conv-explicit-123");
37
+ });
38
+
39
+ test("explicit absent, __SKILL_CONTEXT_JSON has conversationId → returns it", () => {
40
+ process.env.__SKILL_CONTEXT_JSON = JSON.stringify({
41
+ conversationId: "conv-from-skill-ctx",
42
+ });
43
+ const result = resolveConversationId({ failureHelp: FAILURE_HELP });
44
+ expect(result).toBe("conv-from-skill-ctx");
45
+ });
46
+
47
+ test("both envs absent → throws with provided failureHelp", () => {
48
+ expect(() =>
49
+ resolveConversationId({ failureHelp: FAILURE_HELP }),
50
+ ).toThrow(FAILURE_HELP);
51
+ });
52
+
53
+ test("malformed __SKILL_CONTEXT_JSON → falls through to __CONVERSATION_ID", () => {
54
+ process.env.__SKILL_CONTEXT_JSON = "not-valid-json{{{";
55
+ process.env.__CONVERSATION_ID = "conv-from-env";
56
+ const result = resolveConversationId({ failureHelp: FAILURE_HELP });
57
+ expect(result).toBe("conv-from-env");
58
+ });
59
+
60
+ test("__SKILL_CONTEXT_JSON without conversationId field → falls through to __CONVERSATION_ID", () => {
61
+ process.env.__SKILL_CONTEXT_JSON = JSON.stringify({ other: "value" });
62
+ process.env.__CONVERSATION_ID = "conv-from-env-fallback";
63
+ const result = resolveConversationId({ failureHelp: FAILURE_HELP });
64
+ expect(result).toBe("conv-from-env-fallback");
65
+ });
66
+ });
@@ -0,0 +1,49 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import { parseDuration } from "../parse-duration.js";
4
+
5
+ describe("parseDuration", () => {
6
+ test('"30s" → 30', () => {
7
+ expect(parseDuration("30s")).toBe(30);
8
+ });
9
+
10
+ test('"5m" → 300', () => {
11
+ expect(parseDuration("5m")).toBe(300);
12
+ });
13
+
14
+ test('"1h" → 3600', () => {
15
+ expect(parseDuration("1h")).toBe(3600);
16
+ });
17
+
18
+ test('"1h30m" → 5400', () => {
19
+ expect(parseDuration("1h30m")).toBe(5400);
20
+ });
21
+
22
+ test('"90m" → 5400', () => {
23
+ expect(parseDuration("90m")).toBe(5400);
24
+ });
25
+
26
+ test('"60" (bare number) → 60', () => {
27
+ expect(parseDuration("60")).toBe(60);
28
+ });
29
+
30
+ test("invalid string → throws Error", () => {
31
+ expect(() => parseDuration("abc")).toThrow('Invalid duration: "abc"');
32
+ });
33
+
34
+ test("empty string → throws Error", () => {
35
+ expect(() => parseDuration("")).toThrow();
36
+ });
37
+
38
+ test('"1hxyz" (partial parse) → throws with "Invalid duration"', () => {
39
+ expect(() => parseDuration("1hxyz")).toThrow("Invalid duration");
40
+ });
41
+
42
+ test('"1h-30m" (partial parse with dash) → throws with "Invalid duration"', () => {
43
+ expect(() => parseDuration("1h-30m")).toThrow("Invalid duration");
44
+ });
45
+
46
+ test('"30mxyz" (partial parse) → throws with "Invalid duration"', () => {
47
+ expect(() => parseDuration("30mxyz")).toThrow("Invalid duration");
48
+ });
49
+ });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Resolve the conversation ID by precedence:
3
+ * 1. Explicit value provided in `opts.explicit`
4
+ * 2. `__SKILL_CONTEXT_JSON` env var (set by skill sandbox runner)
5
+ * 3. `__CONVERSATION_ID` env var (set by bash tool subprocess)
6
+ * 4. Throw with the provided `failureHelp` message
7
+ */
8
+ export function resolveConversationId(opts: {
9
+ explicit?: string;
10
+ failureHelp: string;
11
+ }): string {
12
+ if (opts.explicit) return opts.explicit;
13
+
14
+ const contextJson = process.env.__SKILL_CONTEXT_JSON;
15
+ if (contextJson) {
16
+ try {
17
+ const parsed = JSON.parse(contextJson) as Record<string, unknown>;
18
+ if (typeof parsed.conversationId === "string" && parsed.conversationId) {
19
+ return parsed.conversationId;
20
+ }
21
+ } catch {
22
+ // ignore malformed JSON
23
+ }
24
+ }
25
+
26
+ const envConvId = process.env.__CONVERSATION_ID;
27
+ if (envConvId && typeof envConvId === "string") return envConvId;
28
+
29
+ throw new Error(opts.failureHelp);
30
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Parse a human-friendly duration string into seconds.
3
+ *
4
+ * Accepted formats:
5
+ * "60" → 60 (bare number = seconds)
6
+ * "60s" → 60
7
+ * "5m" → 300
8
+ * "1h" → 3600
9
+ * "1h30m" → 5400
10
+ * "90s" → 90
11
+ *
12
+ * Note: `--ttl never` is handled at the call site (mapped to ttlSeconds: null);
13
+ * do NOT pass "never" to this function.
14
+ */
15
+ export function parseDuration(input: string): number {
16
+ if (/^\d+$/.test(input)) return parseInt(input, 10);
17
+ // Validate the whole string is composed entirely of <digits><unit> groups
18
+ if (!/^(\d+[hms])+$/.test(input)) {
19
+ throw new Error(`Invalid duration: "${input}"`);
20
+ }
21
+
22
+ let total = 0;
23
+ const re = /(\d+)(h|m|s)/g;
24
+ let match;
25
+ while ((match = re.exec(input)) !== null) {
26
+ const val = parseInt(match[1], 10);
27
+ switch (match[2]) {
28
+ case "h":
29
+ total += val * 3600;
30
+ break;
31
+ case "m":
32
+ total += val * 60;
33
+ break;
34
+ case "s":
35
+ total += val;
36
+ break;
37
+ }
38
+ }
39
+ if (total === 0) throw new Error(`Invalid duration: "${input}"`);
40
+ return total;
41
+ }
@@ -29,10 +29,14 @@ describe("DEFAULT_ACP_AGENT_PROFILES", () => {
29
29
  });
30
30
  });
31
31
 
32
- test("is frozen at runtime so mutation throws in strict mode", () => {
32
+ test("is deeply frozen so mutation throws in strict mode", () => {
33
33
  expect(Object.isFrozen(DEFAULT_ACP_AGENT_PROFILES)).toBe(true);
34
34
  for (const profile of Object.values(DEFAULT_ACP_AGENT_PROFILES)) {
35
35
  expect(Object.isFrozen(profile)).toBe(true);
36
+ // `args` arrays must also be frozen — `Object.freeze` is shallow, so
37
+ // an unfrozen `args` would let one caller silently corrupt every other
38
+ // read of the shared default via `.push(...)` / `.splice(...)`.
39
+ expect(Object.isFrozen(profile.args)).toBe(true);
36
40
  }
37
41
  });
38
42
  });
@@ -1,5 +1,11 @@
1
1
  import type { AcpAgentConfig } from "./acp-schema.js";
2
2
 
3
+ // Shared frozen empty args array — these defaults are read by every ACP spawn,
4
+ // so a single accidental `args.push(...)` from one caller would corrupt every
5
+ // subsequent read. Cast through `unknown` because `AcpAgentConfig.args` is
6
+ // `string[]` (Zod-inferred) but the value is genuinely immutable at runtime.
7
+ const FROZEN_EMPTY_ARGS = Object.freeze([] as string[]) as unknown as string[];
8
+
3
9
  /**
4
10
  * Default ACP agent profiles that ship with the assistant.
5
11
  *
@@ -7,20 +13,21 @@ import type { AcpAgentConfig } from "./acp-schema.js";
7
13
  * agent id, the resolver falls back to this map so common agents like `claude`
8
14
  * and `codex` Just Work without requiring per-user config.
9
15
  *
10
- * Keyed by agent id. Frozen so accidental runtime mutation throws in strict
11
- * mode and the readonly type matches actual runtime behavior.
16
+ * Keyed by agent id. Deeply frozen the outer object, each profile, and the
17
+ * `args` arrays so mutation throws in strict mode rather than silently
18
+ * corrupting the shared defaults.
12
19
  */
13
20
  export const DEFAULT_ACP_AGENT_PROFILES: Readonly<
14
21
  Record<string, AcpAgentConfig>
15
22
  > = Object.freeze({
16
23
  claude: Object.freeze({
17
24
  command: "claude-agent-acp",
18
- args: [],
25
+ args: FROZEN_EMPTY_ARGS,
19
26
  description: "Claude Code (via @agentclientprotocol/claude-agent-acp)",
20
27
  }),
21
28
  codex: Object.freeze({
22
29
  command: "codex-acp",
23
- args: [],
30
+ args: FROZEN_EMPTY_ARGS,
24
31
  description: "OpenAI Codex CLI (via @zed-industries/codex-acp)",
25
32
  }),
26
33
  });
@@ -11,7 +11,7 @@
11
11
  "properties": {
12
12
  "agent": {
13
13
  "type": "string",
14
- "description": "Which agent to spawn (e.g. 'claude', 'codex', 'gemini'). Defaults to 'claude'."
14
+ "description": "Which agent to spawn (e.g. 'claude', 'codex'). Defaults to 'claude'."
15
15
  },
16
16
  "task": {
17
17
  "type": "string",
@@ -67,7 +67,7 @@
67
67
  "name": "acp_steer",
68
68
  "description": "**Interrupts** the in-flight prompt of a running ACP session and replaces it with `instruction`. Use to redirect the agent (e.g., 'stop, do X instead'). For follow-up work that should happen *after* the current task, do NOT use this — wait for `acp_session_completed` and `acp_spawn` again.",
69
69
  "category": "orchestration",
70
- "risk": "medium",
70
+ "risk": "high",
71
71
  "input_schema": {
72
72
  "type": "object",
73
73
  "properties": {
@@ -21,6 +21,10 @@
21
21
  "reasoning": {
22
22
  "type": "string",
23
23
  "description": "Explanation of why you are starting this app"
24
+ },
25
+ "target_client_id": {
26
+ "type": "string",
27
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
24
28
  }
25
29
  },
26
30
  "required": ["app", "reasoning"]
@@ -43,6 +47,10 @@
43
47
  "settle_ms": {
44
48
  "type": "integer",
45
49
  "description": "Milliseconds to wait before capturing so the target app and the WindowServer can flush pending input + composite a fresh frame. Default ~200ms (sized for emulator-class apps at 60fps). Pass 0 for static UIs; raise for slow-feedback apps."
50
+ },
51
+ "target_client_id": {
52
+ "type": "string",
53
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
46
54
  }
47
55
  },
48
56
  "required": ["app"]
@@ -78,6 +86,10 @@
78
86
  "reasoning": {
79
87
  "type": "string",
80
88
  "description": "Explanation of why you are pressing this key"
89
+ },
90
+ "target_client_id": {
91
+ "type": "string",
92
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
81
93
  }
82
94
  },
83
95
  "required": ["app", "key", "reasoning"]
@@ -109,6 +121,10 @@
109
121
  "reasoning": {
110
122
  "type": "string",
111
123
  "description": "Explanation of why you are pressing this combo"
124
+ },
125
+ "target_client_id": {
126
+ "type": "string",
127
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
112
128
  }
113
129
  },
114
130
  "required": ["app", "keys", "reasoning"]
@@ -158,6 +174,10 @@
158
174
  "reasoning": {
159
175
  "type": "string",
160
176
  "description": "Explanation of what this sequence does and why"
177
+ },
178
+ "target_client_id": {
179
+ "type": "string",
180
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
161
181
  }
162
182
  },
163
183
  "required": ["app", "steps", "reasoning"]
@@ -184,6 +204,10 @@
184
204
  "reasoning": {
185
205
  "type": "string",
186
206
  "description": "Explanation of what you are typing and why"
207
+ },
208
+ "target_client_id": {
209
+ "type": "string",
210
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
187
211
  }
188
212
  },
189
213
  "required": ["app", "text", "reasoning"]
@@ -223,6 +247,10 @@
223
247
  "reasoning": {
224
248
  "type": "string",
225
249
  "description": "Explanation of what you see and why you are clicking here"
250
+ },
251
+ "target_client_id": {
252
+ "type": "string",
253
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
226
254
  }
227
255
  },
228
256
  "required": ["app", "x", "y", "reasoning"]
@@ -266,6 +294,10 @@
266
294
  "reasoning": {
267
295
  "type": "string",
268
296
  "description": "Explanation of what you are dragging and why"
297
+ },
298
+ "target_client_id": {
299
+ "type": "string",
300
+ "description": "ID of the specific client to target. Required when multiple clients support host_app_control; omit when only one is connected. Obtain IDs from `assistant clients list --capability host_app_control`."
269
301
  }
270
302
  },
271
303
  "required": ["app", "from_x", "from_y", "to_x", "to_y", "reasoning"]
@@ -15,27 +15,7 @@ Manage the user's contacts, relationship graph, access control (trusted contacts
15
15
 
16
16
  ## Contact Management
17
17
 
18
- ### Create or update a contact
19
-
20
- Create a new contact or update an existing one in the relationship graph. Use this to track people the user interacts with across channels.
21
-
22
- ```bash
23
- assistant contacts upsert --display-name "<name>" --notes "<notes>" --channels '<json_array>' --json
24
- ```
25
-
26
- To update an existing contact, include the `--id` flag.
27
-
28
- Required flags:
29
-
30
- - `--display-name` -- the contact's name
31
-
32
- Optional flags:
33
-
34
- - `--id` -- contact ID to update (omit to create new, or auto-match by channel address)
35
- - `--notes` -- free-text notes about this contact (e.g. relationship, communication preferences, response expectations)
36
- - `--role` -- contact role: `contact` or `guardian` (default: `contact`)
37
- - `--contact-type` -- contact type: `human` or `assistant` (default: `human`)
38
- - `--channels` -- JSON array of channel objects, each with `type`, `address`, and optional `isPrimary`, `externalUserId`, `externalChatId`, `status`, `policy`
18
+ > **Contact writes are guardian-only.** You can list, search, and merge contacts, but creating contacts and granting access happen through the guardian-facing flows: the **Contacts tab in the assistant web UI** for new contacts and channel verification, and `assistant contacts invites create` for invite-based onboarding. The LLM does **not** have a direct create/update tool — when a user asks for one, walk them to the guardian flow instead.
39
19
 
40
20
  ### Search contacts
41
21
 
@@ -116,25 +96,12 @@ The response contains `{ ok: true, contacts: [...] }` where each contact has:
116
96
 
117
97
  ### Allow a user (add trusted contact)
118
98
 
119
- Use this when the user wants to grant someone access to message the assistant. **Always confirm with the user before executing this action.**
120
-
121
- Ask the user: _"I'll add [name/identifier] on [channel] as an allowed contact. Should I proceed?"_
122
-
123
- ```bash
124
- assistant contacts upsert --display-name "<display_name>" --channels '[{"type":"<channel>","address":"<user_id>","externalUserId":"<user_id>","status":"active","policy":"allow"}]' --json
125
- ```
126
-
127
- Required flags:
99
+ You can't add a trusted contact directly — contact writes are guardian-only. When the user wants to grant someone access, walk them through one of these guardian paths:
128
100
 
129
- - `--display-name` -- human-readable name for the contact
130
- - `--channels` -- at least one channel entry with:
131
- - `type` -- the channel type (e.g., `telegram`)
132
- - `address` -- the channel-specific identifier
133
- - `externalUserId` -- the user's ID on that channel (or `externalChatId` for chat-based channels)
134
- - `status` -- set to `"active"` for immediate access
135
- - `policy` -- set to `"allow"` to grant messaging access
101
+ 1. **Web UI** open the Contacts tab in the assistant dashboard, click "Add contact", and verify the channel via the outbound verification flow (SMS code, Telegram message, etc.).
102
+ 2. **Invite link** — for channels that support it (Telegram, email, etc.), create an invite with `assistant contacts invites create --source-channel <channel> --contact-id <existing_contact_id>` (the contact must already exist).
136
103
 
137
- If the user provides a name but not an external ID, explain that you need the channel-specific user ID or chat ID to create the contact entry. For Telegram, this is a numeric user ID.
104
+ If the user insists on adding someone, tell them: _"I can't add trusted contacts directly that's a guardian-only action. You can add them from the Contacts tab in the assistant dashboard, or I can create an invite link for an existing contact."_
138
105
 
139
106
  ### Revoke a user (remove access)
140
107
 
@@ -169,7 +136,7 @@ Replace `<channel_id>` with the channel's `id` from the contact's `channels` arr
169
136
 
170
137
  Invite links let the guardian share a link or code that automatically grants access when used. Telegram invites use a deep link; voice invites use a phone number + numeric code; email, WhatsApp, and Slack invites use a 6-digit code that the invitee sends to the assistant on the respective channel.
171
138
 
172
- **Every invite must be bound to a contact.** Before creating an invite, look up the contact with `assistant contacts list` or create one with `assistant contacts upsert`, then pass the contact's `id` via the required `--contact-id` flag.
139
+ **Every invite must be bound to a contact.** Before creating an invite, look up the contact with `assistant contacts list` and pass the contact's `id` via the required `--contact-id` flag. **You cannot create new contacts** — if the target contact doesn't exist yet, tell the user to add them from the **Contacts tab in the assistant web UI** first, then come back to create the invite.
173
140
 
174
141
  ### Create a Telegram invite link
175
142
 
@@ -216,7 +183,7 @@ echo "$INVITE_URL"
216
183
  Required flags:
217
184
 
218
185
  - `--source-channel` -- must be `telegram`
219
- - `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
186
+ - `--contact-id` -- the ID of the contact this invite is for. Look up the contact first with `assistant contacts list`. New contacts must be added via the Contacts tab in the assistant web UI; you cannot create them here.
220
187
 
221
188
  Optional flags:
222
189
 
@@ -256,7 +223,7 @@ assistant contacts invites create --source-channel phone --contact-id "<contact_
256
223
  Required flags:
257
224
 
258
225
  - `--source-channel` -- must be `phone`
259
- - `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
226
+ - `--contact-id` -- the ID of the contact this invite is for. Look up the contact first with `assistant contacts list`. New contacts must be added via the Contacts tab in the assistant web UI; you cannot create them here.
260
227
  - `--expected-external-user-id` -- the invitee's phone number in E.164 format (e.g., `+15551234567`)
261
228
  - `--friend-name` -- the invitee's display name (e.g., "Mom", "Dr. Smith"). Used during the voice verification call to personalize the experience.
262
229
  - `--guardian-name` -- the guardian's display name (e.g., "Alex"). Used during the voice verification call so the invitee knows who invited them.
@@ -302,7 +269,7 @@ assistant contacts invites create --source-channel email --contact-id "<contact_
302
269
  Required flags:
303
270
 
304
271
  - `--source-channel` -- must be `email`
305
- - `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
272
+ - `--contact-id` -- the ID of the contact this invite is for. Look up the contact first with `assistant contacts list`. New contacts must be added via the Contacts tab in the assistant web UI; you cannot create them here.
306
273
 
307
274
  The response contains `{ ok: true, invite: { id, token, inviteCode, guardianInstruction, channelHandle, ... } }`.
308
275
 
@@ -333,7 +300,7 @@ assistant contacts invites create --source-channel whatsapp --contact-id "<conta
333
300
  Required flags:
334
301
 
335
302
  - `--source-channel` -- must be `whatsapp`
336
- - `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
303
+ - `--contact-id` -- the ID of the contact this invite is for. Look up the contact first with `assistant contacts list`. New contacts must be added via the Contacts tab in the assistant web UI; you cannot create them here.
337
304
 
338
305
  The response contains `{ ok: true, invite: { id, token, inviteCode, guardianInstruction, channelHandle?, ... } }`.
339
306
 
@@ -366,7 +333,7 @@ assistant contacts invites create --source-channel slack --contact-id "<contact_
366
333
  Required flags:
367
334
 
368
335
  - `--source-channel` -- must be `slack`
369
- - `--contact-id` -- the ID of the contact this invite is for. Look up or create the contact first with `assistant contacts list` or `assistant contacts upsert`.
336
+ - `--contact-id` -- the ID of the contact this invite is for. Look up the contact first with `assistant contacts list`. New contacts must be added via the Contacts tab in the assistant web UI; you cannot create them here.
370
337
 
371
338
  The response follows the same shape as email and WhatsApp invites (`inviteCode`, `guardianInstruction`, `channelHandle`).
372
339
 
@@ -497,7 +464,7 @@ Each channel has:
497
464
 
498
465
  **"Who can message me?"** -- List all contacts with `assistant contacts list --json`, present active channels as a formatted list.
499
466
 
500
- **"Add my friend to Telegram"** -- Ask for their Telegram user ID (numeric) and display name, confirm, then create a contact with `assistant contacts upsert` including a channel entry with `policy: "allow"` and `status: "active"`.
467
+ **"Add my friend to Telegram"** -- You can't add trusted contacts directly (guardian-only action). Tell the user to add the contact from the Contacts tab in the assistant dashboard, where they can enter the Telegram user ID and verify the channel. Once the contact exists, you can create an invite with `assistant contacts invites create --source-channel telegram --contact-id <contact_id>`.
501
468
 
502
469
  **"Remove [name]'s access"** -- List contacts with `assistant contacts list --json` to find them, identify the channel to revoke, confirm the revocation, then run `assistant contacts channels update-status <channel_id> --status revoked --json`.
503
470
 
@@ -1,63 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
3
  "tools": [
4
- {
5
- "name": "contact_upsert",
6
- "description": "Create or update a contact in the relationship graph. Use this to track people the user interacts with across channels (email, Slack, etc.).",
7
- "category": "contacts",
8
- "risk": "low",
9
- "input_schema": {
10
- "type": "object",
11
- "properties": {
12
- "id": {
13
- "type": "string",
14
- "description": "Contact ID to update. Omit to create a new contact (or auto-match by channel address)."
15
- },
16
- "display_name": {
17
- "type": "string",
18
- "description": "Display name for the contact"
19
- },
20
- "notes": {
21
- "type": "string",
22
- "description": "Free-text notes about this contact (e.g. relationship, communication preferences, response expectations)"
23
- },
24
- "channels": {
25
- "type": "array",
26
- "description": "Communication channels for this contact",
27
- "items": {
28
- "type": "object",
29
- "properties": {
30
- "type": {
31
- "type": "string",
32
- "enum": [
33
- "email",
34
- "slack",
35
- "whatsapp",
36
- "phone",
37
- "telegram",
38
- "discord",
39
- "other"
40
- ],
41
- "description": "Channel type"
42
- },
43
- "address": {
44
- "type": "string",
45
- "description": "Channel address (email address, Slack handle, phone number, etc.)"
46
- },
47
- "is_primary": {
48
- "type": "boolean",
49
- "description": "Whether this is the primary channel for this type"
50
- }
51
- },
52
- "required": ["type", "address"]
53
- }
54
- }
55
- },
56
- "required": ["display_name"]
57
- },
58
- "executor": "tools/contact-upsert.ts",
59
- "execution_target": "host"
60
- },
61
4
  {
62
5
  "name": "contact_search",
63
6
  "description": "Search for contacts by name, channel address, or other criteria. Returns matching contacts with their channel information.",
@@ -1,13 +1,9 @@
1
- import { emitFeedEvent } from "../../../../home/emit-feed-event.js";
2
1
  import type {
3
2
  ToolContext,
4
3
  ToolExecutionResult,
5
4
  } from "../../../../tools/types.js";
6
- import { getLogger } from "../../../../util/logger.js";
7
5
  import { err, getProviderConnection, ok, resolveProvider } from "./shared.js";
8
6
 
9
- const log = getLogger("messaging-archive-by-sender");
10
-
11
7
  export async function run(
12
8
  input: Record<string, unknown>,
13
9
  context: ToolContext,
@@ -50,14 +46,6 @@ export async function run(
50
46
  }
51
47
 
52
48
  const summary = `Archived ${result.archived} message(s) matching query: ${query}`;
53
- void emitFeedEvent({
54
- source: "gmail",
55
- title: "Messages Archived",
56
- summary,
57
- dedupKey: `email-archive:${Date.now()}`,
58
- }).catch((err) => {
59
- log.warn({ err }, "Failed to emit email archive feed event");
60
- });
61
49
  if (result.truncated) {
62
50
  return ok(
63
51
  `${summary}\n\nNote: this operation was capped at 5000 messages. Additional messages matching the query may remain in the inbox. Run the command again to archive more.`,