@vellumai/assistant 0.9.0 → 0.10.0-staging.2

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 (572) hide show
  1. package/ARCHITECTURE.md +18 -34
  2. package/bun.lock +7 -8
  3. package/docs/activation-funnel-telemetry.md +28 -22
  4. package/docs/architecture/security.md +29 -28
  5. package/docs/stt-provider-onboarding.md +3 -5
  6. package/docs/workflows-testing.md +13 -44
  7. package/docs/workflows.md +3 -5
  8. package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
  9. package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
  10. package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
  11. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
  12. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  13. package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
  14. package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
  15. package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
  16. package/openapi.yaml +976 -63
  17. package/package.json +2 -1
  18. package/scripts/sync-llm-catalog.ts +6 -15
  19. package/scripts/sync-web-search-catalog.ts +3 -11
  20. package/src/__tests__/access-request-card-view.test.ts +98 -0
  21. package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
  22. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
  23. package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
  24. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
  25. package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
  26. package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
  27. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
  28. package/src/__tests__/app-compiler.test.ts +15 -1
  29. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  30. package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
  31. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  32. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  33. package/src/__tests__/avatar-identity-sync.test.ts +2 -27
  34. package/src/__tests__/btw-routes.test.ts +6 -8
  35. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  36. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  37. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  38. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  39. package/src/__tests__/checker.test.ts +0 -3
  40. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  41. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  42. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  43. package/src/__tests__/config-loader-backfill.test.ts +268 -27
  44. package/src/__tests__/config-schema.test.ts +35 -0
  45. package/src/__tests__/config-watcher.test.ts +0 -18
  46. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  47. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  48. package/src/__tests__/contacts-tools.test.ts +29 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  51. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  52. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  53. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  54. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  55. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  56. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  57. package/src/__tests__/conversation-title-service.test.ts +62 -0
  58. package/src/__tests__/credential-broker.test.ts +449 -1
  59. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  60. package/src/__tests__/credential-execution-tools.test.ts +0 -1
  61. package/src/__tests__/credential-prompt-route.test.ts +4 -4
  62. package/src/__tests__/credential-routes.test.ts +360 -0
  63. package/src/__tests__/credential-security-invariants.test.ts +4 -13
  64. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  65. package/src/__tests__/disk-usage.test.ts +65 -0
  66. package/src/__tests__/dynamic-page-surface.test.ts +152 -1
  67. package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
  68. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  69. package/src/__tests__/gateway-only-guard.test.ts +3 -7
  70. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  71. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  72. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  73. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  74. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  75. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  76. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  77. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  78. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  79. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  80. package/src/__tests__/identity-routes.test.ts +0 -189
  81. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  82. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  83. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  84. package/src/__tests__/invite-redemption-service.test.ts +4 -7
  85. package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
  86. package/src/__tests__/llm-catalog-parity.test.ts +30 -23
  87. package/src/__tests__/llm-resolver.test.ts +70 -24
  88. package/src/__tests__/llm-schema.test.ts +1 -0
  89. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  90. package/src/__tests__/mcp-health-check.test.ts +6 -7
  91. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  92. package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
  93. package/src/__tests__/onboarding-persona-write.test.ts +1 -1
  94. package/src/__tests__/path-policy.test.ts +34 -0
  95. package/src/__tests__/persona-resolver.test.ts +49 -14
  96. package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
  97. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  98. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  99. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  100. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  101. package/src/__tests__/reaction-persistence.test.ts +150 -29
  102. package/src/__tests__/registry.test.ts +2 -7
  103. package/src/__tests__/relay-server.test.ts +285 -0
  104. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  105. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
  106. package/src/__tests__/schedule-routes.test.ts +0 -30
  107. package/src/__tests__/schedule-tools.test.ts +2 -18
  108. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  109. package/src/__tests__/skill-execute-input.test.ts +51 -1
  110. package/src/__tests__/skill-runtime-path.test.ts +2 -3
  111. package/src/__tests__/skills.test.ts +51 -0
  112. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  113. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  114. package/src/__tests__/subagent-tools.test.ts +266 -0
  115. package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
  116. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  117. package/src/__tests__/title-generate-hook.test.ts +100 -3
  118. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
  119. package/src/__tests__/token-manager.test.ts +519 -0
  120. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  121. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  122. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  123. package/src/__tests__/tool-executor.test.ts +0 -79
  124. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  125. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  126. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  127. package/src/__tests__/trusted-contact-verification.test.ts +8 -10
  128. package/src/__tests__/twilio-routes.test.ts +81 -1
  129. package/src/__tests__/voice-invite-redemption.test.ts +2 -3
  130. package/src/__tests__/weak-open-model.test.ts +30 -0
  131. package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
  132. package/src/__tests__/workspace-greetings.test.ts +152 -0
  133. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  134. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  136. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  137. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  138. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  139. package/src/agent/loop.ts +49 -29
  140. package/src/api/README.md +6 -6
  141. package/src/api/events/tool-result.ts +6 -0
  142. package/src/api/events/workflow-completed.ts +53 -0
  143. package/src/api/events/workflow-leaf-finished.ts +38 -0
  144. package/src/api/events/workflow-leaf-started.ts +35 -0
  145. package/src/api/events/workflow-progress.ts +32 -0
  146. package/src/api/events/workflow-started.ts +31 -0
  147. package/src/api/index.ts +40 -0
  148. package/src/api/responses/conversation-message.ts +28 -4
  149. package/src/api/responses/home.ts +26 -4
  150. package/src/api/responses/workflow-journal.ts +53 -0
  151. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  152. package/src/approvals/guardian-decision-primitive.ts +26 -3
  153. package/src/approvals/guardian-request-resolvers.ts +183 -80
  154. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  155. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  156. package/src/calls/call-pointer-messages.ts +10 -4
  157. package/src/calls/channel-admission-reader.ts +104 -0
  158. package/src/calls/guardian-dispatch.ts +17 -45
  159. package/src/calls/media-stream-server.ts +84 -2
  160. package/src/calls/relay-access-wait.ts +1 -1
  161. package/src/calls/relay-server.ts +66 -0
  162. package/src/calls/relay-setup-router.ts +82 -1
  163. package/src/calls/twilio-routes.ts +17 -8
  164. package/src/calls/voice-session-bridge.ts +2 -2
  165. package/src/cli/commands/clients.ts +3 -0
  166. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  167. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  168. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  169. package/src/cli/commands/memory/index.ts +30 -0
  170. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  171. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  172. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  173. package/src/cli/commands/oauth/status.test.ts +36 -0
  174. package/src/cli/commands/oauth/status.ts +23 -3
  175. package/src/cli/commands/plugins.ts +197 -4
  176. package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
  177. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  178. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
  179. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  180. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
  181. package/src/cli/lib/diff-plugin.ts +346 -0
  182. package/src/cli/lib/inspect-plugin.ts +12 -1
  183. package/src/cli/lib/install-from-github.ts +105 -17
  184. package/src/cli/lib/merge-plugin-tree.ts +328 -0
  185. package/src/cli/lib/plugin-fingerprint.ts +14 -0
  186. package/src/cli/lib/plugin-surfaces.ts +104 -0
  187. package/src/cli/lib/upgrade-plugin.ts +298 -10
  188. package/src/cli/program.ts +2 -6
  189. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  190. package/src/config/assistant-feature-flags.ts +22 -7
  191. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  192. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  193. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  194. package/src/config/bundled-skills/subagent/SKILL.md +4 -0
  195. package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
  196. package/src/config/bundled-skills/workflows/SKILL.md +14 -8
  197. package/src/config/bundled-tool-registry.ts +2 -7
  198. package/src/config/call-site-defaults.ts +15 -2
  199. package/src/config/feature-flag-registry.json +46 -31
  200. package/src/config/inference-profile-validation.ts +26 -0
  201. package/src/config/llm-resolver.ts +3 -0
  202. package/src/config/loader.ts +4 -0
  203. package/src/config/memory-v3-gate.ts +11 -0
  204. package/src/config/profile-order.ts +28 -0
  205. package/src/config/schema.ts +8 -6
  206. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  207. package/src/config/schemas/call-site-catalog.ts +7 -0
  208. package/src/config/schemas/channels.ts +11 -0
  209. package/src/config/schemas/elevenlabs.ts +0 -1
  210. package/src/config/schemas/llm.ts +31 -0
  211. package/src/config/schemas/memory-lifecycle.ts +3 -7
  212. package/src/config/schemas/memory-v3.ts +6 -0
  213. package/src/config/schemas/platform.ts +0 -8
  214. package/src/config/schemas/services.ts +18 -0
  215. package/src/config/seed-inference-profiles.ts +109 -44
  216. package/src/config/skills.ts +21 -0
  217. package/src/config/sync-gated-profiles.ts +220 -0
  218. package/src/contacts/contact-store.ts +89 -106
  219. package/src/contacts/contacts-write.ts +5 -22
  220. package/src/contacts/types.ts +0 -1
  221. package/src/context/compactor.ts +88 -54
  222. package/src/context/strip-injections.ts +58 -10
  223. package/src/context/token-estimator.ts +1 -1
  224. package/src/credential-execution/process-manager.ts +55 -14
  225. package/src/credential-execution/prompted-credential.ts +2 -3
  226. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  227. package/src/daemon/config-watcher.ts +0 -4
  228. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  229. package/src/daemon/conversation-agent-loop.ts +114 -22
  230. package/src/daemon/conversation-history.ts +1 -1
  231. package/src/daemon/conversation-lifecycle.ts +3 -5
  232. package/src/daemon/conversation-process.ts +13 -5
  233. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  234. package/src/daemon/conversation-slash.ts +2 -23
  235. package/src/daemon/conversation-surfaces.ts +26 -0
  236. package/src/daemon/conversation-tool-setup.ts +27 -14
  237. package/src/daemon/conversation.ts +66 -14
  238. package/src/daemon/disk-pressure-policy.ts +5 -3
  239. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  240. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  241. package/src/daemon/handlers/config-a2a.ts +0 -2
  242. package/src/daemon/handlers/config-channels.ts +15 -16
  243. package/src/daemon/handlers/config-slack-channel.ts +22 -3
  244. package/src/daemon/handlers/conversations.ts +107 -0
  245. package/src/daemon/host-browser-proxy.ts +41 -0
  246. package/src/daemon/lifecycle.ts +55 -27
  247. package/src/daemon/message-provenance.ts +2 -0
  248. package/src/daemon/message-types/contacts.ts +0 -1
  249. package/src/daemon/message-types/conversations.ts +3 -3
  250. package/src/daemon/message-types/sync.ts +0 -1
  251. package/src/daemon/message-types/web-activity.ts +7 -1
  252. package/src/daemon/message-types/workflows.ts +83 -1
  253. package/src/daemon/orphan-reaper.test.ts +0 -19
  254. package/src/daemon/orphan-reaper.ts +2 -24
  255. package/src/daemon/server.ts +0 -10
  256. package/src/daemon/tool-setup-types.ts +4 -0
  257. package/src/daemon/trust-context.ts +1 -1
  258. package/src/events/tool-audit-listener.ts +2 -2
  259. package/src/home/feed-source-enrichment.test.ts +151 -0
  260. package/src/home/feed-source-enrichment.ts +176 -0
  261. package/src/home/relationship-state.ts +2 -4
  262. package/src/instrument.ts +18 -6
  263. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  264. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  265. package/src/ipc/assistant-server.ts +37 -4
  266. package/src/ipc/gateway-flag-listener.ts +18 -2
  267. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  268. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  269. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  270. package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
  271. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  272. package/src/memory/auth-fallback-events-store.ts +2 -2
  273. package/src/memory/auto-analysis-enqueue.ts +3 -5
  274. package/src/memory/bookmark-crud.ts +1 -2
  275. package/src/memory/canonical-guardian-store.ts +39 -1
  276. package/src/memory/conversation-crud.ts +9 -4
  277. package/src/memory/conversation-key-store.ts +17 -2
  278. package/src/memory/conversation-title-service.ts +64 -7
  279. package/src/memory/db-init.ts +17 -17
  280. package/src/memory/embedding-backend.ts +38 -1
  281. package/src/memory/embedding-billing-breaker.ts +96 -0
  282. package/src/memory/jobs-store.ts +25 -13
  283. package/src/memory/jobs-worker.ts +54 -1
  284. package/src/memory/lifecycle-events-store.ts +2 -2
  285. package/src/memory/memory-retrospective-constants.ts +4 -4
  286. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  287. package/src/memory/memory-retrospective-job.ts +28 -227
  288. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  289. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  290. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  291. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
  292. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  293. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  294. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  295. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  296. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  297. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  298. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  299. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  300. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  301. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
  302. package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
  303. package/src/memory/migrations/index.ts +6 -0
  304. package/src/memory/migrations/run-migrations.ts +41 -0
  305. package/src/memory/migrations/validate-migration-state.ts +1 -1
  306. package/src/memory/onboarding-events-store.ts +3 -3
  307. package/src/memory/schema/contacts.ts +0 -5
  308. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  309. package/src/memory/skill-loaded-events-store.ts +2 -2
  310. package/src/memory/tool-executed-events-store.test.ts +7 -7
  311. package/src/memory/turn-trace-store.test.ts +736 -0
  312. package/src/memory/turn-trace-store.ts +364 -0
  313. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  314. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  315. package/src/memory/v2/consolidation-job.ts +2 -2
  316. package/src/memory/v2/skill-content.ts +25 -7
  317. package/src/memory/v2/skill-store.ts +7 -1
  318. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  319. package/src/memory/v3-eval/eval-packets.ts +546 -0
  320. package/src/messaging/providers/slack/adapter.ts +1 -1
  321. package/src/messaging/providers/slack/api.ts +31 -0
  322. package/src/messaging/providers/slack/send.test.ts +114 -2
  323. package/src/messaging/providers/slack/send.ts +30 -7
  324. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  325. package/src/messaging/providers/slack/withdraw.ts +161 -0
  326. package/src/notifications/AGENTS.md +2 -0
  327. package/src/notifications/access-request-copy.ts +72 -59
  328. package/src/notifications/adapters/shared.ts +29 -0
  329. package/src/notifications/adapters/slack.ts +58 -103
  330. package/src/notifications/adapters/telegram.ts +2 -20
  331. package/src/notifications/approval-card-data.ts +333 -0
  332. package/src/notifications/broadcaster.ts +16 -3
  333. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  334. package/src/notifications/copy-composer.ts +3 -3
  335. package/src/notifications/decision-engine.ts +4 -2
  336. package/src/notifications/destination-resolver.ts +4 -6
  337. package/src/notifications/guardian-question-mode.ts +10 -0
  338. package/src/notifications/home-feed-side-effect.ts +7 -16
  339. package/src/notifications/notification-utils.ts +19 -20
  340. package/src/notifications/signal.ts +79 -43
  341. package/src/notifications/types.ts +98 -121
  342. package/src/oauth/AGENTS.md +5 -24
  343. package/src/permissions/checker.test.ts +51 -0
  344. package/src/permissions/checker.ts +185 -26
  345. package/src/permissions/ipc-risk-types.ts +24 -0
  346. package/src/permissions/question-prompter.test.ts +27 -0
  347. package/src/permissions/question-prompter.ts +4 -0
  348. package/src/platform/client.test.ts +119 -0
  349. package/src/platform/client.ts +66 -0
  350. package/src/platform/consent-cache.test.ts +267 -0
  351. package/src/platform/consent-cache.ts +174 -0
  352. package/src/plugin-api/constants.ts +1 -1
  353. package/src/plugin-api/index.ts +33 -1
  354. package/src/plugin-api/model-profiles.ts +33 -0
  355. package/src/plugin-api/types.ts +50 -2
  356. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  357. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  358. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  359. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  360. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  361. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  362. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  363. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  364. package/src/plugins/defaults/advisor/config.ts +21 -0
  365. package/src/plugins/defaults/advisor/consult.ts +93 -0
  366. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  367. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  368. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  369. package/src/plugins/defaults/advisor/package.json +14 -0
  370. package/src/plugins/defaults/advisor/steering.ts +67 -0
  371. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  372. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  373. package/src/plugins/defaults/index.ts +60 -0
  374. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  375. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  376. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  377. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  378. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  379. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  380. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
  381. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  382. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  383. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  384. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  385. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
  386. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  387. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  388. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  389. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
  390. package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
  391. package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
  392. package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
  393. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
  394. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  395. package/src/prompts/persona-resolver.ts +14 -4
  396. package/src/prompts/templates/system-sections.ts +7 -2
  397. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  398. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  399. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  400. package/src/providers/atlascloud/client.ts +85 -0
  401. package/src/providers/fetch-provider-catalog.ts +85 -0
  402. package/src/providers/inference/adapter-factory.ts +3 -0
  403. package/src/providers/model-catalog.ts +58 -0
  404. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  405. package/src/providers/openai/chat-completions-provider.ts +7 -0
  406. package/src/providers/openai/responses-provider.ts +10 -0
  407. package/src/providers/provider-send-message.ts +11 -3
  408. package/src/providers/retry.ts +53 -12
  409. package/src/providers/search-provider-catalog.ts +10 -0
  410. package/src/providers/weak-open-model.ts +22 -0
  411. package/src/runtime/AGENTS.md +0 -1
  412. package/src/runtime/__tests__/agent-wake.test.ts +181 -0
  413. package/src/runtime/__tests__/client-health.test.ts +44 -0
  414. package/src/runtime/access-request-helper.ts +21 -53
  415. package/src/runtime/actor-trust-resolver.ts +59 -63
  416. package/src/runtime/agent-wake.ts +52 -0
  417. package/src/runtime/assistant-event-hub.ts +18 -4
  418. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  419. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  420. package/src/runtime/btw-sidechain.ts +3 -6
  421. package/src/runtime/capabilities.test.ts +120 -0
  422. package/src/runtime/capabilities.ts +197 -0
  423. package/src/runtime/channel-approval-types.ts +22 -45
  424. package/src/runtime/channel-invite-transports/telegram.ts +4 -4
  425. package/src/runtime/channel-retry-sweep.ts +1 -0
  426. package/src/runtime/channel-verification-service.ts +3 -3
  427. package/src/runtime/client-health.ts +26 -0
  428. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  429. package/src/runtime/effective-capabilities.test.ts +128 -0
  430. package/src/runtime/effective-capabilities.ts +84 -0
  431. package/src/runtime/guardian-reply-router.ts +106 -21
  432. package/src/runtime/invite-redemption-service.ts +9 -25
  433. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
  434. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  435. package/src/runtime/pending-interactions.ts +15 -0
  436. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  437. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  438. package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
  439. package/src/runtime/routes/app-routes.ts +1 -1
  440. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
  441. package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
  442. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  443. package/src/runtime/routes/btw-routes.ts +1 -27
  444. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  445. package/src/runtime/routes/client-routes.ts +10 -0
  446. package/src/runtime/routes/contact-routes.ts +31 -8
  447. package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
  448. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  449. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  450. package/src/runtime/routes/conversation-routes.ts +39 -14
  451. package/src/runtime/routes/credential-routes.ts +40 -16
  452. package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
  453. package/src/runtime/routes/events-routes.ts +1 -3
  454. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  455. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  456. package/src/runtime/routes/home-feed-routes.ts +8 -3
  457. package/src/runtime/routes/identity-routes.ts +1 -296
  458. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  459. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
  460. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  461. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  462. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  463. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  464. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  465. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  466. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  467. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  468. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  469. package/src/runtime/routes/index.ts +2 -0
  470. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  471. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  472. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  473. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  474. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  475. package/src/runtime/routes/notification-routes.ts +122 -133
  476. package/src/runtime/routes/platform-routes.ts +2 -2
  477. package/src/runtime/routes/plugins-routes.ts +202 -3
  478. package/src/runtime/routes/schedule-routes.ts +0 -22
  479. package/src/runtime/routes/secret-routes.ts +10 -0
  480. package/src/runtime/routes/surface-action-routes.ts +2 -1
  481. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  482. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  483. package/src/runtime/routes/workflow-routes.test.ts +229 -44
  484. package/src/runtime/routes/workflow-routes.ts +131 -29
  485. package/src/runtime/routes/workspace-greetings.ts +55 -0
  486. package/src/runtime/sync/resource-sync-events.ts +1 -11
  487. package/src/runtime/tool-grant-request-helper.ts +18 -16
  488. package/src/runtime/trust-context-resolver.ts +8 -5
  489. package/src/schedule/inference-profile.ts +2 -14
  490. package/src/schedule/schedule-store.ts +1 -1
  491. package/src/schedule/scheduler-types.ts +5 -1
  492. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  493. package/src/security/secret-patterns.ts +3 -0
  494. package/src/subagent/manager.ts +17 -4
  495. package/src/subagent/types.ts +6 -0
  496. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  497. package/src/telemetry/trace-collection-policy.ts +30 -0
  498. package/src/telemetry/types.ts +89 -0
  499. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  500. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  501. package/src/tools/AGENTS.md +3 -3
  502. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  503. package/src/tools/browser/browser-execution.ts +30 -19
  504. package/src/tools/document/document-tool.ts +2 -3
  505. package/src/tools/executor.ts +5 -3
  506. package/src/tools/host-terminal/host-shell.ts +5 -4
  507. package/src/tools/memory/register.ts +2 -2
  508. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  509. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  510. package/src/tools/network/web-fetch.ts +372 -1
  511. package/src/tools/network/web-search-error.ts +1 -1
  512. package/src/tools/network/web-search.ts +213 -10
  513. package/src/tools/permission-checker.ts +4 -3
  514. package/src/tools/registry.ts +20 -0
  515. package/src/tools/schedule/create.ts +7 -12
  516. package/src/tools/schedule/update.ts +4 -11
  517. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  518. package/src/tools/side-effects.ts +2 -17
  519. package/src/tools/skills/execute.ts +33 -0
  520. package/src/tools/subagent/spawn.ts +61 -12
  521. package/src/tools/terminal/shell.ts +10 -4
  522. package/src/tools/tool-approval-handler.ts +18 -13
  523. package/src/tools/tool-manifest.ts +0 -2
  524. package/src/tools/types.ts +9 -0
  525. package/src/tools/ui-surface/definitions.ts +64 -3
  526. package/src/tools/verification-control-plane-policy.ts +3 -1
  527. package/src/tools/workflows/run-workflow.test.ts +8 -18
  528. package/src/tools/workflows/run-workflow.ts +1 -0
  529. package/src/util/disk-usage.ts +78 -23
  530. package/src/util/platform.ts +10 -3
  531. package/src/watcher/telemetry.ts +2 -2
  532. package/src/workflows/capabilities.ts +2 -3
  533. package/src/workflows/engine.test.ts +175 -1
  534. package/src/workflows/engine.ts +82 -0
  535. package/src/workflows/journal-store.test.ts +70 -0
  536. package/src/workflows/journal-store.ts +18 -3
  537. package/src/workflows/run-manager.test.ts +171 -28
  538. package/src/workflows/run-manager.ts +66 -24
  539. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  540. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  541. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  542. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  543. package/src/workspace/migrations/registry.ts +8 -0
  544. package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
  545. package/src/__tests__/credential-security-e2e.test.ts +0 -362
  546. package/src/__tests__/credential-vault-unit.test.ts +0 -1528
  547. package/src/__tests__/credential-vault.test.ts +0 -1706
  548. package/src/__tests__/identity-intro-cache.test.ts +0 -315
  549. package/src/__tests__/secret-onetime-send.test.ts +0 -182
  550. package/src/cli/commands/__tests__/task.test.ts +0 -914
  551. package/src/cli/commands/task.ts +0 -771
  552. package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
  553. package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
  554. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
  555. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
  556. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
  557. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
  558. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
  559. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
  560. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
  561. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
  562. package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
  563. package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
  564. package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
  565. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
  566. package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
  567. package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
  568. package/src/memory/preloaded-apps.ts +0 -116
  569. package/src/notifications/tool-approval-copy.ts +0 -142
  570. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
  571. package/src/runtime/routes/identity-intro-cache.ts +0 -172
  572. package/src/tools/credentials/vault.ts +0 -712
@@ -18,8 +18,8 @@
18
18
 
19
19
  import type { Command } from "commander";
20
20
 
21
- import { cliIpcCall } from "../../ipc/cli-client.js";
22
- import type { ComparisonReport } from "../../memory/v2/harness/runner.js";
21
+ import { cliIpcCall } from "../../../ipc/cli-client.js";
22
+ import type { ComparisonReport } from "../../../memory/v2/harness/runner.js";
23
23
  import type {
24
24
  MemoryV2BackfillOp,
25
25
  MemoryV2BackfillResult,
@@ -27,9 +27,9 @@ import type {
27
27
  MemoryV2ReembedSkillsResult,
28
28
  MemoryV2SimulateRouterResult,
29
29
  MemoryV2ValidateResult,
30
- } from "../../runtime/routes/memory-v2-routes.js";
31
- import { registerCommand } from "../lib/register-command.js";
32
- import { log } from "../logger.js";
30
+ } from "../../../runtime/routes/memory-v2-routes.js";
31
+ import { registerCommand } from "../../lib/register-command.js";
32
+ import { log } from "../../logger.js";
33
33
  import {
34
34
  renderComparisonReport,
35
35
  renderTurnTrace,
@@ -63,16 +63,7 @@ async function runBackfillOp(op: MemoryV2BackfillOp): Promise<void> {
63
63
  // Registration
64
64
  // ---------------------------------------------------------------------------
65
65
 
66
- export function registerMemoryV2Command(program: Command): void {
67
- // Reuse an existing `memory` parent if some other registrar attached to it
68
- // first; otherwise create one. This keeps the registration order between
69
- // sibling memory registrars unconstrained.
70
- const memory =
71
- program.commands.find((c) => c.name() === "memory") ??
72
- program
73
- .command("memory")
74
- .description("Manage the v2 memory subsystem (concept-page model)");
75
-
66
+ export function registerMemoryV2Command(memory: Command): void {
76
67
  registerCommand(memory, {
77
68
  name: "v2",
78
69
  transport: "ipc",
@@ -17,13 +17,14 @@
17
17
 
18
18
  import type { Command } from "commander";
19
19
 
20
- import { cliIpcCall } from "../../ipc/cli-client.js";
20
+ import { cliIpcCall } from "../../../ipc/cli-client.js";
21
+ import type { MemoryEvalRunResult } from "../../../runtime/routes/memory-eval-routes.js";
21
22
  import type {
22
23
  MemoryV3BackfillSectionsResult,
23
24
  MemoryV3RebuildIndexResult,
24
- } from "../../runtime/routes/memory-v3-routes.js";
25
- import { registerCommand } from "../lib/register-command.js";
26
- import { log } from "../logger.js";
25
+ } from "../../../runtime/routes/memory-v3-routes.js";
26
+ import { registerCommand } from "../../lib/register-command.js";
27
+ import { log } from "../../logger.js";
27
28
 
28
29
  /**
29
30
  * IPC timeout for `backfill-sections`. The one-time full-corpus section embed
@@ -34,14 +35,14 @@ import { log } from "../logger.js";
34
35
  */
35
36
  const BACKFILL_IPC_TIMEOUT_MS = 30 * 60 * 1000;
36
37
 
37
- export function registerMemoryV3Command(program: Command): void {
38
- // Reuse an existing `memory` parent if some other registrar attached to it
39
- // first; otherwise create one. This keeps the registration order between
40
- // sibling memory registrars unconstrained.
41
- const memory =
42
- program.commands.find((c) => c.name() === "memory") ??
43
- program.command("memory").description("Manage the memory subsystem");
38
+ /**
39
+ * IPC timeout for `eval`. Embedding both corpora's sections runs through the
40
+ * embedder and easily outlasts the default 60s, so allow the same generous
41
+ * ceiling as the backfill.
42
+ */
43
+ const EVAL_IPC_TIMEOUT_MS = 30 * 60 * 1000;
44
44
 
45
+ export function registerMemoryV3Command(memory: Command): void {
45
46
  registerCommand(memory, {
46
47
  name: "v3",
47
48
  transport: "ipc",
@@ -134,6 +135,91 @@ Examples:
134
135
  : "."),
135
136
  );
136
137
  });
138
+
139
+ // ── eval ──────────────────────────────────────────────────────────────
140
+
141
+ v3.command("eval")
142
+ .description(
143
+ "Build blinded A/B retrieval-eval packets (snapshot corpus vs staged wiki)",
144
+ )
145
+ .requiredOption(
146
+ "--staging <dir>",
147
+ "Staged v3 wiki dir (relative to the workspace, or absolute)",
148
+ )
149
+ .requiredOption(
150
+ "--snapshot <dir>",
151
+ "Read-only v2 snapshot dir (relative to the workspace, or absolute)",
152
+ )
153
+ .requiredOption("--out <dir>", "Output dir for packets.json + key.json")
154
+ .option("--turns <n>", "Number of recent turns to mine", "30")
155
+ .option("--k <n>", "Pages per memory set", "8")
156
+ .option(
157
+ "--seed <n>",
158
+ "Blinding seed (reproducible A/B assignment)",
159
+ "1",
160
+ )
161
+ .option(
162
+ "--no-dense",
163
+ "Needle-only: skip section embedding (fast, cheaper, lower fidelity)",
164
+ )
165
+ .option("--json", "Emit raw JSON instead of a formatted summary")
166
+ .addHelpText(
167
+ "after",
168
+ `
169
+ Mines recent user turns, retrieves the top pages from each corpus per turn, and
170
+ writes blinded A/B packets (plus a separate unblinding key) for a blind-judge
171
+ workflow. Both corpora are read in memory — nothing in the live lanes or Qdrant
172
+ is touched. With the dense lane on (default) it embeds every section of both
173
+ corpora, which can take a while on a large corpus; use --no-dense for a fast
174
+ lexical-only pass.
175
+
176
+ Examples:
177
+ $ assistant memory v3 eval --snapshot .mv3/snapshot/concepts --staging .mv3/staging --out .mv3/eval
178
+ $ assistant memory v3 eval --snapshot .mv3/snapshot/concepts --staging .mv3/staging --out .mv3/eval --turns 50 --no-dense`,
179
+ )
180
+ .action(
181
+ async (opts: {
182
+ staging: string;
183
+ snapshot: string;
184
+ out: string;
185
+ turns: string;
186
+ k: string;
187
+ seed: string;
188
+ dense: boolean;
189
+ json?: boolean;
190
+ }) => {
191
+ const result = await cliIpcCall<MemoryEvalRunResult>(
192
+ "memory_eval_run",
193
+ {
194
+ body: {
195
+ stagingDir: opts.staging,
196
+ snapshotDir: opts.snapshot,
197
+ outDir: opts.out,
198
+ turns: Number(opts.turns),
199
+ k: Number(opts.k),
200
+ seed: Number(opts.seed),
201
+ dense: opts.dense,
202
+ },
203
+ },
204
+ { timeoutMs: EVAL_IPC_TIMEOUT_MS },
205
+ );
206
+ if (!result.ok) {
207
+ log.error(result.error ?? "Failed to build eval packets");
208
+ process.exitCode = 1;
209
+ return;
210
+ }
211
+ const payload = result.result!;
212
+ if (opts.json === true) {
213
+ log.info(JSON.stringify(payload, null, 2));
214
+ return;
215
+ }
216
+ log.info(
217
+ `Wrote ${payload.packetsWritten} packets from ${payload.turnsMined} turns ` +
218
+ `(snapshot ${payload.snapshotPages} pages vs staged ${payload.stagingPages} pages, ` +
219
+ `dense=${payload.dense}).\n packets: ${payload.packetsPath}\n key: ${payload.keyPath}`,
220
+ );
221
+ },
222
+ );
137
223
  },
138
224
  });
139
225
  }
@@ -0,0 +1,36 @@
1
+ import { afterEach, describe, expect, test } from "bun:test";
2
+
3
+ import { noConnectionsMessage } from "./status.js";
4
+
5
+ const original = process.env.__RESOLVED_MODEL;
6
+
7
+ afterEach(() => {
8
+ if (original === undefined) delete process.env.__RESOLVED_MODEL;
9
+ else process.env.__RESOLVED_MODEL = original;
10
+ });
11
+
12
+ describe("noConnectionsMessage", () => {
13
+ test("capable models get the terse default", () => {
14
+ process.env.__RESOLVED_MODEL = "claude-opus-4-8";
15
+ const msg = noConnectionsMessage("google");
16
+ expect(msg).toBe(
17
+ "No active connections for google.\n" +
18
+ "Connect with `assistant oauth connect google`.\n",
19
+ );
20
+ });
21
+
22
+ test("no resolved model falls back to the terse default", () => {
23
+ delete process.env.__RESOLVED_MODEL;
24
+ expect(noConnectionsMessage("google")).toContain(
25
+ "Connect with `assistant oauth connect google`.",
26
+ );
27
+ });
28
+
29
+ test("weak open models are steered to the oauth_connect surface", () => {
30
+ process.env.__RESOLVED_MODEL = "accounts/fireworks/models/minimax-m3";
31
+ const msg = noConnectionsMessage("google");
32
+ expect(msg).toContain('surface_type "oauth_connect"');
33
+ expect(msg).toContain('data.providerKey "google"');
34
+ expect(msg).not.toContain("assistant oauth connect google");
35
+ });
36
+ });
@@ -1,8 +1,30 @@
1
1
  import type { Command } from "commander";
2
2
 
3
3
  import { cliIpcCall, exitFromIpcResult } from "../../../ipc/cli-client.js";
4
+ import { isWeakOpenModel } from "../../../providers/weak-open-model.js";
4
5
  import { shouldOutputJson, writeOutput } from "../../output.js";
5
6
 
7
+ /**
8
+ * Message shown when a provider has no active connections. Weak open models
9
+ * loop through redundant discovery commands (channel checks, `oauth providers
10
+ * get`, loading the OAuth setup skill) before rendering the connect button, so
11
+ * they get an explicit single next action: render the core `oauth_connect`
12
+ * surface directly. Capable models keep the terse default.
13
+ */
14
+ export function noConnectionsMessage(provider: string): string {
15
+ const base = `No active connections for ${provider}.`;
16
+ if (isWeakOpenModel(process.env.__RESOLVED_MODEL)) {
17
+ return (
18
+ `${base}\nTo let the user connect, render the connect button: call ` +
19
+ `\`ui_show\` with surface_type "oauth_connect" and ` +
20
+ `data.providerKey "${provider}". That surface is always available — do ` +
21
+ `not run further \`oauth\`/\`channels\` commands or load a setup skill ` +
22
+ `just to display it.\n`
23
+ );
24
+ }
25
+ return `${base}\nConnect with \`assistant oauth connect ${provider}\`.\n`;
26
+ }
27
+
6
28
  // ---------------------------------------------------------------------------
7
29
  // Types
8
30
  // ---------------------------------------------------------------------------
@@ -91,9 +113,7 @@ Examples:
91
113
 
92
114
  // Text output
93
115
  if (connections.length === 0) {
94
- process.stdout.write(
95
- `No active connections for ${provider}.\nConnect with \`assistant oauth connect ${provider}\`.\n`,
96
- );
116
+ process.stdout.write(noConnectionsMessage(provider));
97
117
  return;
98
118
  }
99
119
 
@@ -10,6 +10,11 @@
10
10
  import type { Command } from "commander";
11
11
 
12
12
  import { confirmPrompt } from "../lib/confirm-prompt.js";
13
+ import {
14
+ diffPlugin,
15
+ type PluginDiffResult,
16
+ PluginDiffUnavailableError,
17
+ } from "../lib/diff-plugin.js";
13
18
  import {
14
19
  inspectPlugin,
15
20
  type PluginInspection,
@@ -35,8 +40,12 @@ import {
35
40
  uninstallPlugin,
36
41
  } from "../lib/uninstall-plugin.js";
37
42
  import {
43
+ DEFAULT_PLUGIN_UPGRADE_STRATEGY,
44
+ PLUGIN_UPGRADE_STRATEGIES,
45
+ PluginMergeBaselineError,
38
46
  PluginNotUpgradableError,
39
47
  type PluginUpgradeResult,
48
+ type PluginUpgradeStrategy,
40
49
  upgradePlugin,
41
50
  } from "../lib/upgrade-plugin.js";
42
51
  import { getCliLogger } from "../logger.js";
@@ -60,8 +69,13 @@ Examples:
60
69
  $ assistant plugins list --json
61
70
  $ assistant plugins inspect example
62
71
  $ assistant plugins inspect example --json
72
+ $ assistant plugins diff example
73
+ $ assistant plugins diff example --json
63
74
  $ assistant plugins upgrade example
64
75
  $ assistant plugins upgrade example --dry-run
76
+ $ assistant plugins upgrade example --strategy ours
77
+ $ assistant plugins upgrade example --strategy theirs
78
+ $ assistant plugins upgrade example --strategy assistant
65
79
  $ assistant plugins search example
66
80
  $ assistant plugins search "^example"
67
81
  $ assistant plugins search example --json
@@ -166,7 +180,7 @@ Examples:
166
180
  plugins
167
181
  .command("inspect <name>")
168
182
  .description(
169
- "Show a plugin's local install metadata and the marketplace pin, and whether an update is available",
183
+ "Show a plugin's local install metadata, the marketplace pin, whether an update is available, and the surfaces (skills, hooks, tools) it contributes",
170
184
  )
171
185
  .option("--json", "Emit machine-readable JSON instead of a summary")
172
186
  .action(async (name: string, opts: { json?: boolean }) => {
@@ -212,6 +226,73 @@ Examples:
212
226
  }
213
227
  });
214
228
 
229
+ plugins
230
+ .command("diff <name>")
231
+ .description(
232
+ "Show a unified diff of local edits to an installed plugin against the commit it was installed at",
233
+ )
234
+ .option(
235
+ "--json",
236
+ "Emit the machine-readable diff result as JSON (files: { path, status, diff, binary, reconstructed }[]) instead of a unified diff",
237
+ )
238
+ .addHelpText(
239
+ "after",
240
+ `
241
+ Arguments:
242
+ name Install name (kebab-case directory under the workspace plugins dir);
243
+ run 'assistant plugins list' to see installed names.
244
+
245
+ The baseline is the exact commit the plugin was installed at (recorded in its
246
+ install-meta.json), re-materialized through the install pipeline — so an
247
+ install-time adapter transform never reads as a local change. To compare
248
+ against the marketplace's current pin instead, use 'plugins upgrade --dry-run'.
249
+
250
+ Examples:
251
+ $ assistant plugins diff example
252
+ $ assistant plugins diff example --json`,
253
+ )
254
+ .action(async (name: string, opts: { json?: boolean }) => {
255
+ try {
256
+ const result = await diffPlugin(
257
+ { name },
258
+ { fetch: globalThis.fetch.bind(globalThis) },
259
+ );
260
+
261
+ if (opts.json) {
262
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
263
+ return;
264
+ }
265
+
266
+ // Logged after the JSON early-return: the CLI logger writes
267
+ // info to stdout, which would otherwise corrupt --json output.
268
+ log.info(
269
+ {
270
+ name: result.name,
271
+ clean: result.clean,
272
+ files: result.files.length,
273
+ },
274
+ "plugin diff",
275
+ );
276
+
277
+ for (const line of formatDiff(result)) {
278
+ console.log(line);
279
+ }
280
+ } catch (err) {
281
+ if (
282
+ err instanceof PluginNotInstalledError ||
283
+ err instanceof PluginDiffUnavailableError ||
284
+ err instanceof InvalidPluginNameError
285
+ ) {
286
+ console.error(err.message);
287
+ process.exitCode = 1;
288
+ return;
289
+ }
290
+ const message = err instanceof Error ? err.message : String(err);
291
+ console.error(`Plugin diff failed: ${message}`);
292
+ process.exitCode = 1;
293
+ }
294
+ });
295
+
215
296
  plugins
216
297
  .command("search <query>")
217
298
  .description(
@@ -327,12 +408,36 @@ Examples:
327
408
  "--dry-run",
328
409
  "Show what would change without modifying the install",
329
410
  )
411
+ .option(
412
+ "--strategy <strategy>",
413
+ `How to reconcile local edits with the pin: ${PLUGIN_UPGRADE_STRATEGIES.join(", ")} (default: ${DEFAULT_PLUGIN_UPGRADE_STRATEGY})`,
414
+ )
330
415
  .option("--json", "Emit machine-readable JSON instead of a summary")
331
416
  .action(
332
- async (name: string, opts: { dryRun?: boolean; json?: boolean }) => {
417
+ async (
418
+ name: string,
419
+ opts: { dryRun?: boolean; strategy?: string; json?: boolean },
420
+ ) => {
421
+ const strategy = opts.strategy;
422
+ if (
423
+ strategy !== undefined &&
424
+ !(PLUGIN_UPGRADE_STRATEGIES as readonly string[]).includes(
425
+ strategy,
426
+ )
427
+ ) {
428
+ console.error(
429
+ `Invalid --strategy "${strategy}". Expected one of: ${PLUGIN_UPGRADE_STRATEGIES.join(", ")}.`,
430
+ );
431
+ process.exitCode = 1;
432
+ return;
433
+ }
333
434
  try {
334
435
  const result = await upgradePlugin(
335
- { name, dryRun: opts.dryRun },
436
+ {
437
+ name,
438
+ dryRun: opts.dryRun,
439
+ strategy: strategy as PluginUpgradeStrategy | undefined,
440
+ },
336
441
  { fetch: globalThis.fetch.bind(globalThis) },
337
442
  );
338
443
 
@@ -360,6 +465,7 @@ Examples:
360
465
  if (
361
466
  err instanceof PluginNotInstalledError ||
362
467
  err instanceof PluginNotUpgradableError ||
468
+ err instanceof PluginMergeBaselineError ||
363
469
  err instanceof InvalidPluginNameError
364
470
  ) {
365
471
  console.error(err.message);
@@ -443,12 +549,20 @@ function remoteLocation(remote: PluginRemoteInfo): string {
443
549
  * `location`, with a `drift` line under the installed copy.
444
550
  */
445
551
  function formatInspection(inspection: PluginInspection): string[] {
446
- const { name, status, local, remote, remoteError } = inspection;
552
+ const { name, status, local, remote, remoteError, surfaces } = inspection;
447
553
  const lines: string[] = [name, "─".repeat(44)];
448
554
  const topRow = (label: string, value: string) =>
449
555
  lines.push(`${label.padEnd(11)} ${value}`);
450
556
  const blockRow = (label: string, value: string) =>
451
557
  lines.push(` ${label.padEnd(9)} ${value}`);
558
+ // A surface block: the surface type as a heading, then its items indented
559
+ // under it. Omitted entirely when the plugin contributes none of that type,
560
+ // so the listing only ever shows what the plugin actually contributes.
561
+ const surfaceBlock = (label: string, items: readonly string[]) => {
562
+ if (items.length === 0) return;
563
+ lines.push(label);
564
+ for (const item of items) lines.push(` ${item}`);
565
+ };
452
566
 
453
567
  topRow("status", statusLine(status));
454
568
 
@@ -483,6 +597,12 @@ function formatInspection(inspection: PluginInspection): string[] {
483
597
  const description = remote?.description ?? local?.description ?? null;
484
598
  if (description) topRow("description", description);
485
599
 
600
+ if (surfaces) {
601
+ surfaceBlock("skills", surfaces.skills);
602
+ surfaceBlock("hooks", surfaces.hooks);
603
+ surfaceBlock("tools", surfaces.tools);
604
+ }
605
+
486
606
  for (const issue of local?.issues ?? []) topRow("issue", issue);
487
607
 
488
608
  return lines;
@@ -521,14 +641,87 @@ function formatUpgrade(result: PluginUpgradeResult): string[] {
521
641
  result.fileCount === null
522
642
  ? ""
523
643
  : `(${result.fileCount} file${result.fileCount === 1 ? "" : "s"}) `;
644
+ const hasConflicts =
645
+ result.conflicts.length > 0 || result.binaryConflicts.length > 0;
646
+
647
+ // Under `assistant`, an unresolved merge leaves conflicts in the tree —
648
+ // the plugin would fail to load while any remain, so the usual "restart
649
+ // now" guidance is replaced with resolution instructions. Most conflicts
650
+ // carry git markers, but a modify/delete divergence (a file edited on one
651
+ // side and deleted on the other) keeps the surviving content with no
652
+ // markers, so the guidance covers both rather than assuming markers.
653
+ if (result.strategy === "assistant" && hasConflicts) {
654
+ const lines = [
655
+ `Merged "${name}" ${move} with conflicts`,
656
+ "",
657
+ `${count}→ ${result.target}`,
658
+ ];
659
+ if (result.conflicts.length > 0) {
660
+ lines.push(
661
+ "",
662
+ `Resolve ${result.conflicts.length} conflicted file${result.conflicts.length === 1 ? "" : "s"} (open each: resolve its git conflict markers, or — if a modify/delete divergence kept the file with none — decide whether to keep or remove it):`,
663
+ ...result.conflicts.map((p) => ` ${p}`),
664
+ );
665
+ }
666
+ if (result.binaryConflicts.length > 0) {
667
+ lines.push(
668
+ "",
669
+ `Binary conflict${result.binaryConflicts.length === 1 ? "" : "s"} (kept the local copy — choose a version manually):`,
670
+ ...result.binaryConflicts.map((p) => ` ${p}`),
671
+ );
672
+ }
673
+ lines.push(
674
+ "",
675
+ "Resolve the conflicts, then restart the assistant to pick up the upgrade.",
676
+ );
677
+ if (provenanceNote) lines.push(provenanceNote);
678
+ return lines;
679
+ }
680
+
681
+ const mergeNote =
682
+ result.strategy === "ours" || result.strategy === "theirs"
683
+ ? `Local edits were merged (--strategy ${result.strategy}).`
684
+ : result.strategy === "assistant"
685
+ ? "Local edits were merged with no conflicts (--strategy assistant)."
686
+ : null;
524
687
  const lines = [
525
688
  `Upgraded "${name}" ${move}`,
526
689
  "",
527
690
  `${count}→ ${result.target}`,
528
691
  "Restart the assistant to pick up the upgrade.",
529
692
  ];
693
+ if (mergeNote) lines.push(mergeNote);
530
694
  if (provenanceNote) lines.push(provenanceNote);
531
695
  return lines;
532
696
  }
533
697
  }
534
698
  }
699
+
700
+ /**
701
+ * Render a diff result: a one-line "no local changes" when clean, otherwise a
702
+ * header naming the install-commit baseline followed by each file's unified
703
+ * diff (blank-line separated, mirroring how `git diff` stacks file patches).
704
+ */
705
+ function formatDiff(result: PluginDiffResult): string[] {
706
+ const baseline = `${formatTimestamp(result.committedAt)} (${shortSha(result.commit)})`;
707
+ if (result.clean) {
708
+ return [
709
+ `"${result.name}" has no local changes (matches install commit ${baseline}).`,
710
+ ];
711
+ }
712
+ const count = result.files.length;
713
+ const lines = [
714
+ `"${result.name}" — ${count} file${count === 1 ? "" : "s"} changed vs install commit ${baseline}`,
715
+ "",
716
+ ];
717
+ for (const file of result.files) {
718
+ // A non-reconstructed baseline carries an explanatory marker, not a patch
719
+ // with `a/`–`b/` headers, so name the file it refers to.
720
+ if (!file.reconstructed) {
721
+ lines.push(`${file.path}: ${file.diff.trimEnd()}`, "");
722
+ continue;
723
+ }
724
+ lines.push(file.diff.trimEnd(), "");
725
+ }
726
+ return lines;
727
+ }