@vellumai/assistant 0.9.0 → 0.10.0-dev.202606192226.8ed8a6a

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 (624) hide show
  1. package/ARCHITECTURE.md +19 -35
  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 +1128 -119
  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__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
  28. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
  29. package/src/__tests__/app-compiler.test.ts +15 -1
  30. package/src/__tests__/app-dir-path-guard.test.ts +0 -1
  31. package/src/__tests__/approval-cascade.test.ts +6 -0
  32. package/src/__tests__/approval-routes-http.test.ts +128 -0
  33. package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
  34. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
  35. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  36. package/src/__tests__/avatar-identity-sync.test.ts +2 -27
  37. package/src/__tests__/btw-routes.test.ts +6 -8
  38. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  39. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  40. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  41. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  42. package/src/__tests__/checker.test.ts +0 -3
  43. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  44. package/src/__tests__/compaction-events.test.ts +6 -0
  45. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  46. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  47. package/src/__tests__/config-loader-backfill.test.ts +268 -27
  48. package/src/__tests__/config-schema.test.ts +35 -0
  49. package/src/__tests__/config-watcher.test.ts +0 -18
  50. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  51. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  52. package/src/__tests__/contacts-tools.test.ts +29 -0
  53. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  54. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
  55. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  56. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  57. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  58. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
  59. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  60. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  61. package/src/__tests__/conversation-process-callsite.test.ts +6 -0
  62. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  63. package/src/__tests__/conversation-queue.test.ts +6 -0
  64. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  65. package/src/__tests__/conversation-slash-queue.test.ts +6 -0
  66. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  67. package/src/__tests__/conversation-speed-override.test.ts +6 -0
  68. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  69. package/src/__tests__/conversation-title-service.test.ts +62 -0
  70. package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
  71. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  72. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  73. package/src/__tests__/credential-broker.test.ts +449 -1
  74. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  75. package/src/__tests__/credential-execution-tools.test.ts +0 -1
  76. package/src/__tests__/credential-prompt-route.test.ts +4 -4
  77. package/src/__tests__/credential-routes.test.ts +360 -0
  78. package/src/__tests__/credential-security-invariants.test.ts +4 -13
  79. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  80. package/src/__tests__/disk-pressure-tools.test.ts +41 -1
  81. package/src/__tests__/disk-usage.test.ts +65 -0
  82. package/src/__tests__/document-tool-security.test.ts +9 -6
  83. package/src/__tests__/document-update-default-surface.test.ts +202 -0
  84. package/src/__tests__/dynamic-page-surface.test.ts +152 -1
  85. package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
  86. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  87. package/src/__tests__/gateway-only-guard.test.ts +3 -7
  88. package/src/__tests__/gemini-count-tokens.test.ts +70 -0
  89. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  90. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  91. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  92. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  93. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  94. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  95. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  96. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  97. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  98. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  99. package/src/__tests__/identity-routes.test.ts +0 -189
  100. package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
  101. package/src/__tests__/injector-disk-pressure.test.ts +10 -5
  102. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  103. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  104. package/src/__tests__/invite-redemption-service.test.ts +4 -7
  105. package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
  106. package/src/__tests__/llm-catalog-parity.test.ts +30 -23
  107. package/src/__tests__/llm-resolver.test.ts +70 -24
  108. package/src/__tests__/llm-schema.test.ts +1 -0
  109. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  110. package/src/__tests__/mcp-health-check.test.ts +6 -7
  111. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  112. package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
  113. package/src/__tests__/onboarding-persona-write.test.ts +1 -1
  114. package/src/__tests__/path-policy.test.ts +34 -0
  115. package/src/__tests__/persona-resolver.test.ts +49 -14
  116. package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
  117. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  118. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  119. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  120. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  121. package/src/__tests__/reaction-persistence.test.ts +150 -29
  122. package/src/__tests__/registry.test.ts +2 -7
  123. package/src/__tests__/relay-server.test.ts +285 -0
  124. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  125. package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
  126. package/src/__tests__/schedule-routes.test.ts +0 -30
  127. package/src/__tests__/schedule-tools.test.ts +2 -18
  128. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  129. package/src/__tests__/secret-response-routing.test.ts +35 -0
  130. package/src/__tests__/secret-routes-platform-proxy.test.ts +16 -2
  131. package/src/__tests__/skill-execute-input.test.ts +177 -1
  132. package/src/__tests__/skill-load-tool.test.ts +72 -0
  133. package/src/__tests__/skill-runtime-path.test.ts +2 -3
  134. package/src/__tests__/skills.test.ts +51 -0
  135. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  136. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  137. package/src/__tests__/subagent-tools.test.ts +266 -0
  138. package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
  139. package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
  140. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  141. package/src/__tests__/title-generate-hook.test.ts +100 -3
  142. package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
  143. package/src/__tests__/token-manager.test.ts +519 -0
  144. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  145. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  146. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  147. package/src/__tests__/tool-executor.test.ts +0 -79
  148. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  149. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  150. package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
  151. package/src/__tests__/trusted-contact-verification.test.ts +8 -10
  152. package/src/__tests__/twilio-routes.test.ts +81 -1
  153. package/src/__tests__/voice-invite-redemption.test.ts +2 -3
  154. package/src/__tests__/weak-open-model.test.ts +30 -0
  155. package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
  156. package/src/__tests__/workspace-greetings.test.ts +152 -0
  157. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  158. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  159. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  160. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  161. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  162. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  163. package/src/agent/loop.ts +75 -29
  164. package/src/api/README.md +6 -6
  165. package/src/api/events/tool-result.ts +6 -0
  166. package/src/api/events/workflow-completed.ts +53 -0
  167. package/src/api/events/workflow-leaf-finished.ts +38 -0
  168. package/src/api/events/workflow-leaf-started.ts +35 -0
  169. package/src/api/events/workflow-progress.ts +32 -0
  170. package/src/api/events/workflow-started.ts +31 -0
  171. package/src/api/index.ts +40 -0
  172. package/src/api/responses/conversation-message.ts +28 -4
  173. package/src/api/responses/home.ts +26 -4
  174. package/src/api/responses/workflow-journal.ts +53 -0
  175. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  176. package/src/approvals/guardian-decision-primitive.ts +26 -3
  177. package/src/approvals/guardian-request-resolvers.ts +183 -80
  178. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  179. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  180. package/src/calls/call-pointer-messages.ts +10 -4
  181. package/src/calls/channel-admission-reader.ts +104 -0
  182. package/src/calls/guardian-dispatch.ts +17 -45
  183. package/src/calls/media-stream-server.ts +84 -2
  184. package/src/calls/relay-access-wait.ts +1 -1
  185. package/src/calls/relay-server.ts +66 -0
  186. package/src/calls/relay-setup-router.ts +82 -1
  187. package/src/calls/twilio-routes.ts +17 -8
  188. package/src/calls/voice-session-bridge.ts +2 -2
  189. package/src/cli/commands/clients.ts +3 -0
  190. package/src/cli/commands/db/status.ts +37 -3
  191. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  192. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  193. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  194. package/src/cli/commands/memory/index.ts +30 -0
  195. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  196. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  197. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  198. package/src/cli/commands/oauth/status.test.ts +36 -0
  199. package/src/cli/commands/oauth/status.ts +23 -3
  200. package/src/cli/commands/plugins.ts +400 -14
  201. package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
  202. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  203. package/src/cli/lib/__tests__/install-from-github.test.ts +31 -0
  204. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
  205. package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
  206. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  207. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
  208. package/src/cli/lib/diff-plugin.ts +346 -0
  209. package/src/cli/lib/inspect-plugin.ts +12 -1
  210. package/src/cli/lib/install-from-github.ts +128 -19
  211. package/src/cli/lib/merge-plugin-tree.ts +328 -0
  212. package/src/cli/lib/plugin-fingerprint.ts +14 -0
  213. package/src/cli/lib/plugin-marketplace.ts +11 -0
  214. package/src/cli/lib/plugin-pin-history.ts +257 -0
  215. package/src/cli/lib/plugin-surfaces.ts +104 -0
  216. package/src/cli/lib/upgrade-plugin.ts +298 -10
  217. package/src/cli/program.ts +2 -6
  218. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  219. package/src/config/assistant-feature-flags.ts +22 -7
  220. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  221. package/src/config/bundled-skills/document-editor/SKILL.md +3 -3
  222. package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
  223. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  224. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  225. package/src/config/bundled-skills/subagent/SKILL.md +4 -0
  226. package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
  227. package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
  228. package/src/config/bundled-skills/workflows/SKILL.md +14 -8
  229. package/src/config/bundled-tool-registry.ts +2 -7
  230. package/src/config/call-site-defaults.ts +15 -2
  231. package/src/config/feature-flag-registry.json +46 -31
  232. package/src/config/inference-profile-validation.ts +26 -0
  233. package/src/config/llm-resolver.ts +3 -0
  234. package/src/config/loader.ts +4 -0
  235. package/src/config/memory-v3-gate.ts +11 -0
  236. package/src/config/profile-order.ts +28 -0
  237. package/src/config/schema.ts +8 -6
  238. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  239. package/src/config/schemas/call-site-catalog.ts +7 -0
  240. package/src/config/schemas/channels.ts +11 -0
  241. package/src/config/schemas/elevenlabs.ts +0 -1
  242. package/src/config/schemas/llm.ts +31 -0
  243. package/src/config/schemas/memory-lifecycle.ts +3 -7
  244. package/src/config/schemas/memory-v3.ts +6 -0
  245. package/src/config/schemas/platform.ts +0 -8
  246. package/src/config/schemas/services.ts +18 -0
  247. package/src/config/seed-inference-profiles.ts +109 -44
  248. package/src/config/skills.ts +21 -0
  249. package/src/config/sync-gated-profiles.ts +220 -0
  250. package/src/contacts/contact-store.ts +89 -106
  251. package/src/contacts/contacts-write.ts +5 -22
  252. package/src/contacts/types.ts +0 -1
  253. package/src/context/compactor.ts +88 -54
  254. package/src/context/strip-injections.ts +58 -10
  255. package/src/context/token-estimator.ts +1 -1
  256. package/src/credential-execution/process-manager.ts +55 -14
  257. package/src/credential-execution/prompted-credential.ts +2 -3
  258. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  259. package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
  260. package/src/daemon/config-watcher.ts +0 -4
  261. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  262. package/src/daemon/conversation-agent-loop.ts +114 -22
  263. package/src/daemon/conversation-history.ts +1 -1
  264. package/src/daemon/conversation-lifecycle.ts +3 -5
  265. package/src/daemon/conversation-process.ts +13 -5
  266. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  267. package/src/daemon/conversation-slash.ts +2 -23
  268. package/src/daemon/conversation-surfaces.ts +26 -0
  269. package/src/daemon/conversation-tool-setup.ts +53 -19
  270. package/src/daemon/conversation.ts +131 -20
  271. package/src/daemon/disk-pressure-policy.ts +5 -3
  272. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  273. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  274. package/src/daemon/handlers/config-a2a.ts +0 -2
  275. package/src/daemon/handlers/config-channels.ts +15 -16
  276. package/src/daemon/handlers/config-slack-channel.ts +22 -3
  277. package/src/daemon/handlers/conversations.ts +107 -0
  278. package/src/daemon/host-browser-proxy.ts +41 -0
  279. package/src/daemon/lifecycle.ts +55 -27
  280. package/src/daemon/memory-v2-startup.test.ts +131 -0
  281. package/src/daemon/memory-v2-startup.ts +100 -1
  282. package/src/daemon/message-provenance.ts +2 -0
  283. package/src/daemon/message-types/contacts.ts +0 -1
  284. package/src/daemon/message-types/conversations.ts +3 -3
  285. package/src/daemon/message-types/sync.ts +0 -1
  286. package/src/daemon/message-types/web-activity.ts +7 -1
  287. package/src/daemon/message-types/workflows.ts +83 -1
  288. package/src/daemon/orphan-reaper.test.ts +0 -19
  289. package/src/daemon/orphan-reaper.ts +2 -24
  290. package/src/daemon/server.ts +0 -10
  291. package/src/daemon/tool-setup-types.ts +4 -0
  292. package/src/daemon/trust-context.ts +1 -1
  293. package/src/daemon/wake-conversation-ops.ts +1 -0
  294. package/src/events/tool-audit-listener.ts +2 -2
  295. package/src/home/feed-source-enrichment.test.ts +151 -0
  296. package/src/home/feed-source-enrichment.ts +176 -0
  297. package/src/home/relationship-state.ts +2 -4
  298. package/src/instrument.ts +18 -6
  299. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  300. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  301. package/src/ipc/assistant-server.ts +37 -4
  302. package/src/ipc/gateway-flag-listener.ts +18 -2
  303. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  304. package/src/memory/__tests__/db-logs-attach.test.ts +122 -0
  305. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  306. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  307. package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
  308. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  309. package/src/memory/auth-fallback-events-store.ts +2 -2
  310. package/src/memory/auto-analysis-enqueue.ts +3 -5
  311. package/src/memory/bookmark-crud.ts +1 -2
  312. package/src/memory/canonical-guardian-store.ts +39 -1
  313. package/src/memory/conversation-crud.ts +9 -4
  314. package/src/memory/conversation-key-store.ts +17 -2
  315. package/src/memory/conversation-title-service.ts +64 -7
  316. package/src/memory/db-async-query.ts +20 -2
  317. package/src/memory/db-connection.ts +49 -5
  318. package/src/memory/db-init.ts +17 -17
  319. package/src/memory/embedding-backend.ts +38 -1
  320. package/src/memory/embedding-billing-breaker.ts +96 -0
  321. package/src/memory/jobs-store.ts +25 -13
  322. package/src/memory/jobs-worker.ts +54 -1
  323. package/src/memory/lifecycle-events-store.ts +2 -2
  324. package/src/memory/memory-retrospective-constants.ts +4 -4
  325. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  326. package/src/memory/memory-retrospective-job.ts +28 -227
  327. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  328. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  329. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  330. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
  331. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  332. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  333. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  334. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  335. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  336. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  337. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  338. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  339. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  340. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
  341. package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
  342. package/src/memory/migrations/index.ts +6 -0
  343. package/src/memory/migrations/run-migrations.ts +41 -0
  344. package/src/memory/migrations/validate-migration-state.ts +1 -1
  345. package/src/memory/onboarding-events-store.ts +3 -3
  346. package/src/memory/schema/contacts.ts +0 -5
  347. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  348. package/src/memory/skill-loaded-events-store.ts +2 -2
  349. package/src/memory/tool-executed-events-store.test.ts +7 -7
  350. package/src/memory/turn-trace-store.test.ts +736 -0
  351. package/src/memory/turn-trace-store.ts +364 -0
  352. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  353. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  354. package/src/memory/v2/consolidation-job.ts +2 -2
  355. package/src/memory/v2/skill-content.ts +25 -7
  356. package/src/memory/v2/skill-store.ts +7 -1
  357. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  358. package/src/memory/v3-eval/eval-packets.ts +546 -0
  359. package/src/messaging/providers/slack/adapter.ts +1 -1
  360. package/src/messaging/providers/slack/api.ts +31 -0
  361. package/src/messaging/providers/slack/send.test.ts +114 -2
  362. package/src/messaging/providers/slack/send.ts +30 -7
  363. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  364. package/src/messaging/providers/slack/withdraw.ts +161 -0
  365. package/src/notifications/AGENTS.md +2 -0
  366. package/src/notifications/access-request-copy.ts +72 -59
  367. package/src/notifications/adapters/shared.ts +29 -0
  368. package/src/notifications/adapters/slack.ts +58 -103
  369. package/src/notifications/adapters/telegram.ts +2 -20
  370. package/src/notifications/approval-card-data.ts +333 -0
  371. package/src/notifications/broadcaster.ts +16 -3
  372. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  373. package/src/notifications/copy-composer.ts +3 -3
  374. package/src/notifications/decision-engine.ts +4 -2
  375. package/src/notifications/destination-resolver.ts +4 -6
  376. package/src/notifications/guardian-question-mode.ts +10 -0
  377. package/src/notifications/home-feed-side-effect.ts +7 -16
  378. package/src/notifications/notification-utils.ts +19 -20
  379. package/src/notifications/signal.ts +79 -43
  380. package/src/notifications/types.ts +98 -121
  381. package/src/oauth/AGENTS.md +5 -24
  382. package/src/permissions/checker.test.ts +51 -0
  383. package/src/permissions/checker.ts +185 -26
  384. package/src/permissions/ipc-risk-types.ts +24 -0
  385. package/src/permissions/question-prompter.test.ts +27 -0
  386. package/src/permissions/question-prompter.ts +4 -0
  387. package/src/permissions/secret-prompter.ts +15 -1
  388. package/src/platform/client.test.ts +119 -0
  389. package/src/platform/client.ts +66 -0
  390. package/src/platform/consent-cache.test.ts +267 -0
  391. package/src/platform/consent-cache.ts +174 -0
  392. package/src/plugin-api/constants.ts +1 -1
  393. package/src/plugin-api/index.ts +33 -1
  394. package/src/plugin-api/model-profiles.ts +33 -0
  395. package/src/plugin-api/types.ts +50 -2
  396. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  397. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  398. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  399. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  400. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  401. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  402. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  403. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  404. package/src/plugins/defaults/advisor/config.ts +21 -0
  405. package/src/plugins/defaults/advisor/consult.ts +93 -0
  406. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  407. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  408. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  409. package/src/plugins/defaults/advisor/package.json +14 -0
  410. package/src/plugins/defaults/advisor/steering.ts +67 -0
  411. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  412. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  413. package/src/plugins/defaults/compaction/window-manager.ts +18 -0
  414. package/src/plugins/defaults/index.ts +60 -0
  415. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  416. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  417. package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
  418. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  419. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  420. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  421. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  422. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
  423. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  424. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  425. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  426. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  427. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
  428. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  429. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  430. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  431. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
  432. package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
  433. package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
  434. package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
  435. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
  436. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  437. package/src/prompts/persona-resolver.ts +14 -4
  438. package/src/prompts/templates/system-sections.ts +7 -2
  439. package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
  440. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  441. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  442. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  443. package/src/providers/anthropic/client.ts +230 -175
  444. package/src/providers/atlascloud/client.ts +85 -0
  445. package/src/providers/call-site-routing.ts +10 -0
  446. package/src/providers/fetch-provider-catalog.ts +85 -0
  447. package/src/providers/gemini/client.ts +43 -0
  448. package/src/providers/inference/adapter-factory.ts +3 -0
  449. package/src/providers/model-catalog.ts +58 -0
  450. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  451. package/src/providers/openai/chat-completions-provider.ts +7 -0
  452. package/src/providers/openai/responses-provider.ts +10 -0
  453. package/src/providers/provider-send-message.ts +11 -3
  454. package/src/providers/ratelimit.ts +9 -0
  455. package/src/providers/retry.ts +62 -12
  456. package/src/providers/search-provider-catalog.ts +10 -0
  457. package/src/providers/types.ts +16 -0
  458. package/src/providers/usage-tracking.ts +7 -0
  459. package/src/providers/weak-open-model.ts +22 -0
  460. package/src/runtime/AGENTS.md +0 -1
  461. package/src/runtime/__tests__/agent-wake.test.ts +227 -0
  462. package/src/runtime/__tests__/client-health.test.ts +44 -0
  463. package/src/runtime/access-request-helper.ts +21 -53
  464. package/src/runtime/actor-trust-resolver.ts +59 -63
  465. package/src/runtime/agent-wake.ts +71 -0
  466. package/src/runtime/assistant-event-hub.ts +18 -4
  467. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  468. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  469. package/src/runtime/btw-sidechain.ts +3 -6
  470. package/src/runtime/capabilities.test.ts +120 -0
  471. package/src/runtime/capabilities.ts +197 -0
  472. package/src/runtime/channel-approval-types.ts +22 -45
  473. package/src/runtime/channel-invite-transports/telegram.ts +4 -4
  474. package/src/runtime/channel-retry-sweep.ts +1 -0
  475. package/src/runtime/channel-verification-service.ts +3 -3
  476. package/src/runtime/client-health.ts +26 -0
  477. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  478. package/src/runtime/effective-capabilities.test.ts +128 -0
  479. package/src/runtime/effective-capabilities.ts +84 -0
  480. package/src/runtime/guardian-reply-router.ts +106 -21
  481. package/src/runtime/invite-redemption-service.ts +9 -25
  482. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +126 -0
  483. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  484. package/src/runtime/pending-interactions.ts +35 -0
  485. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  486. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  487. package/src/runtime/routes/__tests__/plugins-routes.test.ts +383 -1
  488. package/src/runtime/routes/app-routes.ts +1 -1
  489. package/src/runtime/routes/approval-routes.ts +40 -9
  490. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
  491. package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
  492. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  493. package/src/runtime/routes/btw-routes.ts +1 -27
  494. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  495. package/src/runtime/routes/client-routes.ts +10 -0
  496. package/src/runtime/routes/contact-routes.ts +31 -8
  497. package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
  498. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  499. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  500. package/src/runtime/routes/conversation-routes.ts +39 -14
  501. package/src/runtime/routes/credential-routes.ts +40 -16
  502. package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
  503. package/src/runtime/routes/events-routes.ts +1 -3
  504. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  505. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  506. package/src/runtime/routes/home-feed-routes.ts +8 -3
  507. package/src/runtime/routes/identity-routes.ts +1 -296
  508. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  509. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
  510. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  511. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  512. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  513. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  514. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  515. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  516. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  517. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  518. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  519. package/src/runtime/routes/index.ts +2 -0
  520. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  521. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  522. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  523. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  524. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  525. package/src/runtime/routes/notification-routes.ts +122 -133
  526. package/src/runtime/routes/platform-routes.ts +2 -2
  527. package/src/runtime/routes/plugins-routes.ts +366 -11
  528. package/src/runtime/routes/schedule-routes.ts +0 -22
  529. package/src/runtime/routes/secret-routes.ts +15 -0
  530. package/src/runtime/routes/surface-action-routes.ts +2 -1
  531. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  532. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  533. package/src/runtime/routes/workflow-routes.test.ts +229 -44
  534. package/src/runtime/routes/workflow-routes.ts +131 -29
  535. package/src/runtime/routes/workspace-greetings.ts +55 -0
  536. package/src/runtime/sync/resource-sync-events.ts +1 -11
  537. package/src/runtime/tool-grant-request-helper.ts +18 -16
  538. package/src/runtime/trust-context-resolver.ts +8 -5
  539. package/src/schedule/inference-profile.ts +2 -14
  540. package/src/schedule/schedule-store.ts +1 -1
  541. package/src/schedule/scheduler-types.ts +5 -1
  542. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  543. package/src/security/secret-patterns.ts +3 -0
  544. package/src/subagent/manager.ts +17 -4
  545. package/src/subagent/types.ts +6 -0
  546. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  547. package/src/telemetry/trace-collection-policy.ts +30 -0
  548. package/src/telemetry/types.ts +89 -0
  549. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  550. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  551. package/src/tools/AGENTS.md +3 -3
  552. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  553. package/src/tools/browser/browser-execution.ts +30 -19
  554. package/src/tools/document/document-tool.ts +30 -6
  555. package/src/tools/executor.ts +5 -3
  556. package/src/tools/host-terminal/host-shell.ts +5 -4
  557. package/src/tools/memory/register.ts +2 -2
  558. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  559. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  560. package/src/tools/network/web-fetch.ts +372 -1
  561. package/src/tools/network/web-search-error.ts +1 -1
  562. package/src/tools/network/web-search.ts +213 -10
  563. package/src/tools/permission-checker.ts +4 -3
  564. package/src/tools/registry.ts +20 -0
  565. package/src/tools/schedule/create.ts +7 -12
  566. package/src/tools/schedule/update.ts +4 -11
  567. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  568. package/src/tools/side-effects.ts +2 -17
  569. package/src/tools/skills/execute.ts +99 -2
  570. package/src/tools/skills/load.ts +43 -2
  571. package/src/tools/subagent/spawn.ts +64 -15
  572. package/src/tools/terminal/shell.ts +10 -4
  573. package/src/tools/tool-approval-handler.ts +18 -13
  574. package/src/tools/tool-manifest.ts +0 -2
  575. package/src/tools/types.ts +10 -0
  576. package/src/tools/ui-surface/definitions.ts +64 -3
  577. package/src/tools/verification-control-plane-policy.ts +3 -1
  578. package/src/tools/workflows/run-workflow.test.ts +8 -18
  579. package/src/tools/workflows/run-workflow.ts +1 -0
  580. package/src/util/disk-usage.ts +78 -23
  581. package/src/util/logs-db-path.ts +22 -0
  582. package/src/util/platform.ts +10 -3
  583. package/src/watcher/telemetry.ts +2 -2
  584. package/src/workflows/capabilities.ts +2 -3
  585. package/src/workflows/engine.test.ts +175 -1
  586. package/src/workflows/engine.ts +82 -0
  587. package/src/workflows/journal-store.test.ts +70 -0
  588. package/src/workflows/journal-store.ts +18 -3
  589. package/src/workflows/run-manager.test.ts +171 -28
  590. package/src/workflows/run-manager.ts +66 -24
  591. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  592. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  593. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  594. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  595. package/src/workspace/migrations/registry.ts +8 -0
  596. package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
  597. package/src/__tests__/credential-security-e2e.test.ts +0 -362
  598. package/src/__tests__/credential-vault-unit.test.ts +0 -1528
  599. package/src/__tests__/credential-vault.test.ts +0 -1706
  600. package/src/__tests__/identity-intro-cache.test.ts +0 -315
  601. package/src/__tests__/secret-onetime-send.test.ts +0 -182
  602. package/src/cli/commands/__tests__/task.test.ts +0 -914
  603. package/src/cli/commands/task.ts +0 -771
  604. package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
  605. package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
  606. package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
  607. package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
  608. package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
  609. package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
  610. package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
  611. package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
  612. package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
  613. package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
  614. package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
  615. package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
  616. package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
  617. package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
  618. package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
  619. package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
  620. package/src/memory/preloaded-apps.ts +0 -116
  621. package/src/notifications/tool-approval-copy.ts +0 -142
  622. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
  623. package/src/runtime/routes/identity-intro-cache.ts +0 -172
  624. package/src/tools/credentials/vault.ts +0 -712
@@ -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,
@@ -19,12 +24,20 @@ import {
19
24
  import {
20
25
  DEFAULT_PLUGIN_REF,
21
26
  installPlugin,
27
+ type InstallPluginOptions,
22
28
  InvalidPluginNameError,
23
29
  PluginAlreadyInstalledError,
24
30
  PluginNotFoundError,
25
31
  } from "../lib/install-from-github.js";
26
32
  import { listInstalledPlugins } from "../lib/list-installed-plugins.js";
27
33
  import type { FingerprintComparison } from "../lib/plugin-fingerprint.js";
34
+ import {
35
+ DEFAULT_PIN_HISTORY_LIMIT,
36
+ listPinHistory,
37
+ type PluginPinHistoryEntry,
38
+ PluginPinHistoryError,
39
+ resolvePinToMarketplaceCommit,
40
+ } from "../lib/plugin-pin-history.js";
28
41
  import { registerCommand } from "../lib/register-command.js";
29
42
  import {
30
43
  InvalidSearchPatternError,
@@ -35,8 +48,12 @@ import {
35
48
  uninstallPlugin,
36
49
  } from "../lib/uninstall-plugin.js";
37
50
  import {
51
+ DEFAULT_PLUGIN_UPGRADE_STRATEGY,
52
+ PLUGIN_UPGRADE_STRATEGIES,
53
+ PluginMergeBaselineError,
38
54
  PluginNotUpgradableError,
39
55
  type PluginUpgradeResult,
56
+ type PluginUpgradeStrategy,
40
57
  upgradePlugin,
41
58
  } from "../lib/upgrade-plugin.js";
42
59
  import { getCliLogger } from "../logger.js";
@@ -56,12 +73,20 @@ Examples:
56
73
  $ assistant plugins install example
57
74
  $ assistant plugins install example --force
58
75
  $ assistant plugins install example --ref my-feature-branch
76
+ $ assistant plugins versions example
77
+ $ assistant plugins versions example --json
78
+ $ assistant plugins install example --pin <sha> --force
59
79
  $ assistant plugins list
60
80
  $ assistant plugins list --json
61
81
  $ assistant plugins inspect example
62
82
  $ assistant plugins inspect example --json
83
+ $ assistant plugins diff example
84
+ $ assistant plugins diff example --json
63
85
  $ assistant plugins upgrade example
64
86
  $ assistant plugins upgrade example --dry-run
87
+ $ assistant plugins upgrade example --strategy ours
88
+ $ assistant plugins upgrade example --strategy theirs
89
+ $ assistant plugins upgrade example --strategy assistant
65
90
  $ assistant plugins search example
66
91
  $ assistant plugins search "^example"
67
92
  $ assistant plugins search example --json
@@ -76,19 +101,35 @@ Examples:
76
101
  .option("--force", "Overwrite an existing install")
77
102
  .option(
78
103
  "--ref <ref>",
79
- `Git ref to fetch from (default: ${DEFAULT_PLUGIN_REF})`,
104
+ `Marketplace manifest revision to read the pin from (default: ${DEFAULT_PLUGIN_REF})`,
105
+ )
106
+ .option(
107
+ "--pin <sha>",
108
+ "Install a specific reviewed marketplace pin (full commit SHA); run `plugins versions <name>` to list them",
109
+ )
110
+ .option(
111
+ "--allow-unreviewed",
112
+ "With --pin, install a SHA that is not in the reviewed marketplace history (advanced; the curated adapter may not match)",
80
113
  )
81
114
  .action(
82
- async (name: string, opts: { force?: boolean; ref?: string }) => {
115
+ async (
116
+ name: string,
117
+ opts: {
118
+ force?: boolean;
119
+ ref?: string;
120
+ pin?: string;
121
+ allowUnreviewed?: boolean;
122
+ },
123
+ ) => {
83
124
  try {
84
- const result = await installPlugin(
85
- {
86
- name,
87
- force: opts.force ?? false,
88
- ref: opts.ref ?? DEFAULT_PLUGIN_REF,
89
- },
90
- { fetch: globalThis.fetch.bind(globalThis) },
91
- );
125
+ const installOpts = await resolveInstallOptions(name, opts);
126
+ if (installOpts === null) {
127
+ process.exitCode = 1;
128
+ return;
129
+ }
130
+ const result = await installPlugin(installOpts, {
131
+ fetch: globalThis.fetch.bind(globalThis),
132
+ });
92
133
  log.info(
93
134
  {
94
135
  name: result.name,
@@ -117,6 +158,14 @@ Examples:
117
158
  process.exitCode = 1;
118
159
  return;
119
160
  }
161
+ if (
162
+ err instanceof InvalidPluginNameError ||
163
+ err instanceof PluginPinHistoryError
164
+ ) {
165
+ console.error(err.message);
166
+ process.exitCode = 1;
167
+ return;
168
+ }
120
169
  const message = err instanceof Error ? err.message : String(err);
121
170
  console.error(`Plugin install failed: ${message}`);
122
171
  process.exitCode = 1;
@@ -124,6 +173,61 @@ Examples:
124
173
  },
125
174
  );
126
175
 
176
+ plugins
177
+ .command("versions <name>")
178
+ .description(
179
+ "List the recent reviewed marketplace pins for a plugin, newest first. Install an older one with `plugins install <name> --pin <sha>`",
180
+ )
181
+ .option("--json", "Emit machine-readable JSON instead of a table")
182
+ .option(
183
+ "--limit <n>",
184
+ `Maximum number of pins to show (default: ${DEFAULT_PIN_HISTORY_LIMIT})`,
185
+ )
186
+ .action(
187
+ async (name: string, opts: { json?: boolean; limit?: string }) => {
188
+ let limit: number | undefined;
189
+ if (opts.limit !== undefined) {
190
+ limit = Number.parseInt(opts.limit, 10);
191
+ if (!Number.isInteger(limit) || limit < 1) {
192
+ console.error("--limit must be a positive integer.");
193
+ process.exitCode = 1;
194
+ return;
195
+ }
196
+ }
197
+ try {
198
+ const history = await listPinHistory(
199
+ name,
200
+ { fetch: globalThis.fetch.bind(globalThis) },
201
+ limit !== undefined ? { limit } : {},
202
+ );
203
+
204
+ if (opts.json) {
205
+ process.stdout.write(JSON.stringify(history, null, 2) + "\n");
206
+ return;
207
+ }
208
+
209
+ // Logged after the JSON early-return so the logger's stdout
210
+ // writes never corrupt --json output.
211
+ log.info({ name, count: history.length }, "plugin versions");
212
+ for (const line of formatVersions(name, history)) {
213
+ console.log(line);
214
+ }
215
+ } catch (err) {
216
+ if (
217
+ err instanceof InvalidPluginNameError ||
218
+ err instanceof PluginPinHistoryError
219
+ ) {
220
+ console.error(err.message);
221
+ process.exitCode = 1;
222
+ return;
223
+ }
224
+ const message = err instanceof Error ? err.message : String(err);
225
+ console.error(`Plugin versions failed: ${message}`);
226
+ process.exitCode = 1;
227
+ }
228
+ },
229
+ );
230
+
127
231
  plugins
128
232
  .command("list")
129
233
  .description("List plugins installed under <workspaceDir>/plugins/")
@@ -166,7 +270,7 @@ Examples:
166
270
  plugins
167
271
  .command("inspect <name>")
168
272
  .description(
169
- "Show a plugin's local install metadata and the marketplace pin, and whether an update is available",
273
+ "Show a plugin's local install metadata, the marketplace pin, whether an update is available, and the surfaces (skills, hooks, tools) it contributes",
170
274
  )
171
275
  .option("--json", "Emit machine-readable JSON instead of a summary")
172
276
  .action(async (name: string, opts: { json?: boolean }) => {
@@ -212,6 +316,73 @@ Examples:
212
316
  }
213
317
  });
214
318
 
319
+ plugins
320
+ .command("diff <name>")
321
+ .description(
322
+ "Show a unified diff of local edits to an installed plugin against the commit it was installed at",
323
+ )
324
+ .option(
325
+ "--json",
326
+ "Emit the machine-readable diff result as JSON (files: { path, status, diff, binary, reconstructed }[]) instead of a unified diff",
327
+ )
328
+ .addHelpText(
329
+ "after",
330
+ `
331
+ Arguments:
332
+ name Install name (kebab-case directory under the workspace plugins dir);
333
+ run 'assistant plugins list' to see installed names.
334
+
335
+ The baseline is the exact commit the plugin was installed at (recorded in its
336
+ install-meta.json), re-materialized through the install pipeline — so an
337
+ install-time adapter transform never reads as a local change. To compare
338
+ against the marketplace's current pin instead, use 'plugins upgrade --dry-run'.
339
+
340
+ Examples:
341
+ $ assistant plugins diff example
342
+ $ assistant plugins diff example --json`,
343
+ )
344
+ .action(async (name: string, opts: { json?: boolean }) => {
345
+ try {
346
+ const result = await diffPlugin(
347
+ { name },
348
+ { fetch: globalThis.fetch.bind(globalThis) },
349
+ );
350
+
351
+ if (opts.json) {
352
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
353
+ return;
354
+ }
355
+
356
+ // Logged after the JSON early-return: the CLI logger writes
357
+ // info to stdout, which would otherwise corrupt --json output.
358
+ log.info(
359
+ {
360
+ name: result.name,
361
+ clean: result.clean,
362
+ files: result.files.length,
363
+ },
364
+ "plugin diff",
365
+ );
366
+
367
+ for (const line of formatDiff(result)) {
368
+ console.log(line);
369
+ }
370
+ } catch (err) {
371
+ if (
372
+ err instanceof PluginNotInstalledError ||
373
+ err instanceof PluginDiffUnavailableError ||
374
+ err instanceof InvalidPluginNameError
375
+ ) {
376
+ console.error(err.message);
377
+ process.exitCode = 1;
378
+ return;
379
+ }
380
+ const message = err instanceof Error ? err.message : String(err);
381
+ console.error(`Plugin diff failed: ${message}`);
382
+ process.exitCode = 1;
383
+ }
384
+ });
385
+
215
386
  plugins
216
387
  .command("search <query>")
217
388
  .description(
@@ -327,12 +498,36 @@ Examples:
327
498
  "--dry-run",
328
499
  "Show what would change without modifying the install",
329
500
  )
501
+ .option(
502
+ "--strategy <strategy>",
503
+ `How to reconcile local edits with the pin: ${PLUGIN_UPGRADE_STRATEGIES.join(", ")} (default: ${DEFAULT_PLUGIN_UPGRADE_STRATEGY})`,
504
+ )
330
505
  .option("--json", "Emit machine-readable JSON instead of a summary")
331
506
  .action(
332
- async (name: string, opts: { dryRun?: boolean; json?: boolean }) => {
507
+ async (
508
+ name: string,
509
+ opts: { dryRun?: boolean; strategy?: string; json?: boolean },
510
+ ) => {
511
+ const strategy = opts.strategy;
512
+ if (
513
+ strategy !== undefined &&
514
+ !(PLUGIN_UPGRADE_STRATEGIES as readonly string[]).includes(
515
+ strategy,
516
+ )
517
+ ) {
518
+ console.error(
519
+ `Invalid --strategy "${strategy}". Expected one of: ${PLUGIN_UPGRADE_STRATEGIES.join(", ")}.`,
520
+ );
521
+ process.exitCode = 1;
522
+ return;
523
+ }
333
524
  try {
334
525
  const result = await upgradePlugin(
335
- { name, dryRun: opts.dryRun },
526
+ {
527
+ name,
528
+ dryRun: opts.dryRun,
529
+ strategy: strategy as PluginUpgradeStrategy | undefined,
530
+ },
336
531
  { fetch: globalThis.fetch.bind(globalThis) },
337
532
  );
338
533
 
@@ -360,6 +555,7 @@ Examples:
360
555
  if (
361
556
  err instanceof PluginNotInstalledError ||
362
557
  err instanceof PluginNotUpgradableError ||
558
+ err instanceof PluginMergeBaselineError ||
363
559
  err instanceof InvalidPluginNameError
364
560
  ) {
365
561
  console.error(err.message);
@@ -377,6 +573,109 @@ Examples:
377
573
  }
378
574
 
379
575
  /** Abbreviate a commit SHA for display; passes through non-SHA / null values. */
576
+ /** Full Git commit SHA — 40 hex (SHA-1) or 64 (SHA-256). */
577
+ const FULL_SHA_RE = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/i;
578
+
579
+ /**
580
+ * Resolve `plugins install` flags into {@link InstallPluginOptions}, or `null`
581
+ * when the flag combination is invalid (a message is printed in that case, and
582
+ * the caller exits non-zero). Network / marketplace failures raised while
583
+ * resolving a `--pin` propagate to the caller's catch.
584
+ *
585
+ * `--pin <sha>` installs a specific reviewed marketplace pin: the SHA is looked
586
+ * up in the plugin's pin history and installed from the marketplace commit that
587
+ * introduced it, so the curated adapter stub of that era comes along. With
588
+ * `--allow-unreviewed` the SHA is materialized directly (adapter from `main`),
589
+ * bypassing the history check — the advanced escape hatch.
590
+ */
591
+ async function resolveInstallOptions(
592
+ name: string,
593
+ opts: {
594
+ force?: boolean;
595
+ ref?: string;
596
+ pin?: string;
597
+ allowUnreviewed?: boolean;
598
+ },
599
+ ): Promise<InstallPluginOptions | null> {
600
+ const force = opts.force ?? false;
601
+
602
+ if (!opts.pin) {
603
+ if (opts.allowUnreviewed) {
604
+ console.error("--allow-unreviewed only applies together with --pin.");
605
+ return null;
606
+ }
607
+ return { name, force, ref: opts.ref ?? DEFAULT_PLUGIN_REF };
608
+ }
609
+
610
+ const pin = opts.pin.trim();
611
+ if (!FULL_SHA_RE.test(pin)) {
612
+ console.error(
613
+ `--pin must be a full commit SHA (40 or 64 hex chars); got ${JSON.stringify(opts.pin)}.`,
614
+ );
615
+ return null;
616
+ }
617
+ if (opts.ref) {
618
+ console.error(
619
+ "--ref and --pin cannot be combined; --pin already selects the revision.",
620
+ );
621
+ return null;
622
+ }
623
+
624
+ if (opts.allowUnreviewed) {
625
+ // Materialize the exact SHA from the plugin's current-manifest repo,
626
+ // bypassing the reviewed-history check. The adapter stub still comes from
627
+ // the default ref, so an adapted plugin may not reproduce faithfully.
628
+ return { name, force, ref: DEFAULT_PLUGIN_REF, commitOverride: pin };
629
+ }
630
+
631
+ const entry = await resolvePinToMarketplaceCommit(name, pin, {
632
+ fetch: globalThis.fetch.bind(globalThis),
633
+ });
634
+ if (!entry) {
635
+ console.error(
636
+ `"${pin}" is not a reviewed marketplace pin for "${name}".\n` +
637
+ `Run \`assistant plugins versions ${name}\` to see available pins, ` +
638
+ "or pass --allow-unreviewed to install it anyway.",
639
+ );
640
+ return null;
641
+ }
642
+ return { name, force, ref: entry.marketplaceCommit };
643
+ }
644
+
645
+ /**
646
+ * Render a plugin's marketplace-pin history as a table: the pinned commit (short
647
+ * SHA), when it was promoted, and a marker for the pin currently active. An
648
+ * empty history reports that none was found.
649
+ */
650
+ function formatVersions(
651
+ name: string,
652
+ history: readonly PluginPinHistoryEntry[],
653
+ ): string[] {
654
+ if (history.length === 0) {
655
+ return [`No marketplace pin history found for "${name}".`];
656
+ }
657
+ const rows = history.map((entry) => ({
658
+ pin: shortSha(entry.pin),
659
+ promoted: formatTimestamp(entry.promotedAt),
660
+ marker: entry.current ? "(current)" : "",
661
+ }));
662
+ const pinW = Math.max(3, ...rows.map((r) => r.pin.length));
663
+ const promotedW = Math.max(8, ...rows.map((r) => r.promoted.length));
664
+ const pad = (s: string, w: number) => s + " ".repeat(w - s.length);
665
+ const lines = [
666
+ `${pad("PIN", pinW)} ${pad("PROMOTED", promotedW)} `.trimEnd(),
667
+ ];
668
+ for (const r of rows) {
669
+ lines.push(
670
+ `${pad(r.pin, pinW)} ${pad(r.promoted, promotedW)} ${r.marker}`.trimEnd(),
671
+ );
672
+ }
673
+ lines.push("");
674
+ lines.push("Install an older pin with:");
675
+ lines.push(` assistant plugins install ${name} --pin <sha> --force`);
676
+ return lines;
677
+ }
678
+
380
679
  function shortSha(sha: string | null): string {
381
680
  return sha ? sha.slice(0, 7) : "—";
382
681
  }
@@ -443,12 +742,20 @@ function remoteLocation(remote: PluginRemoteInfo): string {
443
742
  * `location`, with a `drift` line under the installed copy.
444
743
  */
445
744
  function formatInspection(inspection: PluginInspection): string[] {
446
- const { name, status, local, remote, remoteError } = inspection;
745
+ const { name, status, local, remote, remoteError, surfaces } = inspection;
447
746
  const lines: string[] = [name, "─".repeat(44)];
448
747
  const topRow = (label: string, value: string) =>
449
748
  lines.push(`${label.padEnd(11)} ${value}`);
450
749
  const blockRow = (label: string, value: string) =>
451
750
  lines.push(` ${label.padEnd(9)} ${value}`);
751
+ // A surface block: the surface type as a heading, then its items indented
752
+ // under it. Omitted entirely when the plugin contributes none of that type,
753
+ // so the listing only ever shows what the plugin actually contributes.
754
+ const surfaceBlock = (label: string, items: readonly string[]) => {
755
+ if (items.length === 0) return;
756
+ lines.push(label);
757
+ for (const item of items) lines.push(` ${item}`);
758
+ };
452
759
 
453
760
  topRow("status", statusLine(status));
454
761
 
@@ -483,6 +790,12 @@ function formatInspection(inspection: PluginInspection): string[] {
483
790
  const description = remote?.description ?? local?.description ?? null;
484
791
  if (description) topRow("description", description);
485
792
 
793
+ if (surfaces) {
794
+ surfaceBlock("skills", surfaces.skills);
795
+ surfaceBlock("hooks", surfaces.hooks);
796
+ surfaceBlock("tools", surfaces.tools);
797
+ }
798
+
486
799
  for (const issue of local?.issues ?? []) topRow("issue", issue);
487
800
 
488
801
  return lines;
@@ -521,14 +834,87 @@ function formatUpgrade(result: PluginUpgradeResult): string[] {
521
834
  result.fileCount === null
522
835
  ? ""
523
836
  : `(${result.fileCount} file${result.fileCount === 1 ? "" : "s"}) `;
837
+ const hasConflicts =
838
+ result.conflicts.length > 0 || result.binaryConflicts.length > 0;
839
+
840
+ // Under `assistant`, an unresolved merge leaves conflicts in the tree —
841
+ // the plugin would fail to load while any remain, so the usual "restart
842
+ // now" guidance is replaced with resolution instructions. Most conflicts
843
+ // carry git markers, but a modify/delete divergence (a file edited on one
844
+ // side and deleted on the other) keeps the surviving content with no
845
+ // markers, so the guidance covers both rather than assuming markers.
846
+ if (result.strategy === "assistant" && hasConflicts) {
847
+ const lines = [
848
+ `Merged "${name}" ${move} with conflicts`,
849
+ "",
850
+ `${count}→ ${result.target}`,
851
+ ];
852
+ if (result.conflicts.length > 0) {
853
+ lines.push(
854
+ "",
855
+ `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):`,
856
+ ...result.conflicts.map((p) => ` ${p}`),
857
+ );
858
+ }
859
+ if (result.binaryConflicts.length > 0) {
860
+ lines.push(
861
+ "",
862
+ `Binary conflict${result.binaryConflicts.length === 1 ? "" : "s"} (kept the local copy — choose a version manually):`,
863
+ ...result.binaryConflicts.map((p) => ` ${p}`),
864
+ );
865
+ }
866
+ lines.push(
867
+ "",
868
+ "Resolve the conflicts, then restart the assistant to pick up the upgrade.",
869
+ );
870
+ if (provenanceNote) lines.push(provenanceNote);
871
+ return lines;
872
+ }
873
+
874
+ const mergeNote =
875
+ result.strategy === "ours" || result.strategy === "theirs"
876
+ ? `Local edits were merged (--strategy ${result.strategy}).`
877
+ : result.strategy === "assistant"
878
+ ? "Local edits were merged with no conflicts (--strategy assistant)."
879
+ : null;
524
880
  const lines = [
525
881
  `Upgraded "${name}" ${move}`,
526
882
  "",
527
883
  `${count}→ ${result.target}`,
528
884
  "Restart the assistant to pick up the upgrade.",
529
885
  ];
886
+ if (mergeNote) lines.push(mergeNote);
530
887
  if (provenanceNote) lines.push(provenanceNote);
531
888
  return lines;
532
889
  }
533
890
  }
534
891
  }
892
+
893
+ /**
894
+ * Render a diff result: a one-line "no local changes" when clean, otherwise a
895
+ * header naming the install-commit baseline followed by each file's unified
896
+ * diff (blank-line separated, mirroring how `git diff` stacks file patches).
897
+ */
898
+ function formatDiff(result: PluginDiffResult): string[] {
899
+ const baseline = `${formatTimestamp(result.committedAt)} (${shortSha(result.commit)})`;
900
+ if (result.clean) {
901
+ return [
902
+ `"${result.name}" has no local changes (matches install commit ${baseline}).`,
903
+ ];
904
+ }
905
+ const count = result.files.length;
906
+ const lines = [
907
+ `"${result.name}" — ${count} file${count === 1 ? "" : "s"} changed vs install commit ${baseline}`,
908
+ "",
909
+ ];
910
+ for (const file of result.files) {
911
+ // A non-reconstructed baseline carries an explanatory marker, not a patch
912
+ // with `a/`–`b/` headers, so name the file it refers to.
913
+ if (!file.reconstructed) {
914
+ lines.push(`${file.path}: ${file.diff.trimEnd()}`, "");
915
+ continue;
916
+ }
917
+ lines.push(file.diff.trimEnd(), "");
918
+ }
919
+ return lines;
920
+ }