@vellumai/assistant 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (666) hide show
  1. package/ARCHITECTURE.md +6 -7
  2. package/Dockerfile +1 -0
  3. package/README.md +2 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
  5. package/bun.lock +3 -0
  6. package/docs/architecture/security.md +18 -16
  7. package/knip.json +1 -0
  8. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
  9. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
  10. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
  11. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
  12. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
  13. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  14. package/node_modules/@vellumai/slack-text/package.json +18 -0
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  16. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  17. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  18. package/openapi.yaml +294 -107
  19. package/package.json +4 -2
  20. package/scripts/generate-openapi.ts +16 -111
  21. package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
  22. package/src/__tests__/anthropic-provider.test.ts +56 -13
  23. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  24. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  25. package/src/__tests__/approval-cascade.test.ts +0 -15
  26. package/src/__tests__/approval-routes-http.test.ts +6 -17
  27. package/src/__tests__/assistant-event-hub.test.ts +126 -77
  28. package/src/__tests__/assistant-event.test.ts +0 -5
  29. package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
  31. package/src/__tests__/background-shell-host-bash.test.ts +34 -43
  32. package/src/__tests__/call-controller.test.ts +1 -1
  33. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  34. package/src/__tests__/channel-approval-routes.test.ts +10 -296
  35. package/src/__tests__/channel-approvals.test.ts +25 -17
  36. package/src/__tests__/channel-guardian.test.ts +100 -146
  37. package/src/__tests__/checker.test.ts +20 -34
  38. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/config-schema.test.ts +6 -48
  41. package/src/__tests__/config-watcher.test.ts +12 -0
  42. package/src/__tests__/connection-policy.test.ts +1 -52
  43. package/src/__tests__/contacts-write.test.ts +2 -64
  44. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  45. package/src/__tests__/context-search-memory-source.test.ts +120 -1
  46. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  47. package/src/__tests__/context-search-pkb-source.test.ts +49 -0
  48. package/src/__tests__/context-search-workspace-source.test.ts +9 -22
  49. package/src/__tests__/context-window-manager.test.ts +46 -0
  50. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
  51. package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
  52. package/src/__tests__/conversation-agent-loop.test.ts +980 -13
  53. package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
  54. package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
  55. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
  56. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  57. package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
  58. package/src/__tests__/conversation-lifecycle.test.ts +4 -4
  59. package/src/__tests__/conversation-process-callsite.test.ts +79 -2
  60. package/src/__tests__/conversation-queue.test.ts +3 -8
  61. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
  62. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
  63. package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
  64. package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
  65. package/src/__tests__/conversation-slash-commands.test.ts +24 -4
  66. package/src/__tests__/conversation-slash-queue.test.ts +2 -0
  67. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  68. package/src/__tests__/conversation-starter-routes.test.ts +79 -2
  69. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  70. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  71. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  72. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
  73. package/src/__tests__/conversation-usage.test.ts +253 -3
  74. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  75. package/src/__tests__/credential-health-service.test.ts +68 -0
  76. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  77. package/src/__tests__/credential-security-invariants.test.ts +1 -5
  78. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  79. package/src/__tests__/cu-unified-flow.test.ts +33 -16
  80. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  81. package/src/__tests__/daemon-credential-client.test.ts +4 -1
  82. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  83. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  84. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  85. package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
  86. package/src/__tests__/document-conversations.test.ts +332 -0
  87. package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
  88. package/src/__tests__/emit-event-signal.test.ts +4 -6
  89. package/src/__tests__/events-client-registration.test.ts +193 -49
  90. package/src/__tests__/filing-service.test.ts +58 -7
  91. package/src/__tests__/first-greeting.test.ts +156 -150
  92. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  93. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  94. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  95. package/src/__tests__/guardian-dispatch.test.ts +1 -1
  96. package/src/__tests__/guardian-grant-minting.test.ts +7 -2
  97. package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
  98. package/src/__tests__/guardian-routing-state.test.ts +1 -1
  99. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
  100. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
  101. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  102. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  103. package/src/__tests__/heartbeat-service.test.ts +289 -7
  104. package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
  105. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  106. package/src/__tests__/host-bash-proxy.test.ts +46 -122
  107. package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
  108. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
  109. package/src/__tests__/host-browser-proxy.test.ts +111 -185
  110. package/src/__tests__/host-browser-routes.test.ts +45 -75
  111. package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
  112. package/src/__tests__/host-cu-proxy.test.ts +56 -111
  113. package/src/__tests__/host-file-proxy.test.ts +44 -98
  114. package/src/__tests__/host-file-read-tool.test.ts +42 -21
  115. package/src/__tests__/host-shell-tool.test.ts +33 -68
  116. package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
  117. package/src/__tests__/host-transfer-proxy.test.ts +43 -53
  118. package/src/__tests__/http-user-message-parity.test.ts +0 -6
  119. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  120. package/src/__tests__/injector-chain.test.ts +10 -5
  121. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  122. package/src/__tests__/inline-command-runner.test.ts +0 -66
  123. package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
  124. package/src/__tests__/install-skill-routing.test.ts +1 -13
  125. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  126. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  127. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  128. package/src/__tests__/llm-resolver.test.ts +80 -12
  129. package/src/__tests__/llm-usage-store.test.ts +269 -4
  130. package/src/__tests__/log-export-routes.test.ts +89 -0
  131. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  132. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
  133. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  134. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  135. package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
  136. package/src/__tests__/migration-export-http.test.ts +33 -26
  137. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  138. package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
  139. package/src/__tests__/migration-import-commit-http.test.ts +66 -21
  140. package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
  141. package/src/__tests__/migration-import-from-url.test.ts +20 -6
  142. package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
  143. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  144. package/src/__tests__/migration-transport.test.ts +115 -23
  145. package/src/__tests__/migration-validate-http.test.ts +105 -80
  146. package/src/__tests__/migration-wizard.test.ts +133 -27
  147. package/src/__tests__/non-member-access-request.test.ts +1 -1
  148. package/src/__tests__/notification-guardian-path.test.ts +1 -1
  149. package/src/__tests__/oauth-store.test.ts +19 -0
  150. package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
  151. package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
  152. package/src/__tests__/pricing.test.ts +68 -4
  153. package/src/__tests__/process-message-background-slack.test.ts +331 -0
  154. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  155. package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
  156. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  157. package/src/__tests__/reaction-persistence.test.ts +9 -6
  158. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  159. package/src/__tests__/recording-handler.test.ts +64 -81
  160. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  161. package/src/__tests__/relay-server.test.ts +18 -13
  162. package/src/__tests__/require-fresh-approval.test.ts +13 -22
  163. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  164. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  165. package/src/__tests__/runtime-events-sse.test.ts +3 -12
  166. package/src/__tests__/search-skills-unified.test.ts +9 -15
  167. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  168. package/src/__tests__/secret-ingress-http.test.ts +0 -4
  169. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  170. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  171. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  172. package/src/__tests__/secret-response-routing.test.ts +29 -15
  173. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
  174. package/src/__tests__/secret-scanner.test.ts +2 -545
  175. package/src/__tests__/send-endpoint-busy.test.ts +9 -24
  176. package/src/__tests__/settings-routes.test.ts +1 -1
  177. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  178. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
  179. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
  180. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  181. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
  182. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  183. package/src/__tests__/slack-inbound-verification.test.ts +1 -62
  184. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  185. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  186. package/src/__tests__/subagent-notify-parent.test.ts +80 -83
  187. package/src/__tests__/system-prompt.test.ts +115 -13
  188. package/src/__tests__/terminal-tools.test.ts +0 -89
  189. package/src/__tests__/thread-backfill.test.ts +945 -31
  190. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
  191. package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
  192. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
  193. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
  194. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
  195. package/src/__tests__/tool-executor.test.ts +12 -19
  196. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  197. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  198. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  199. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  200. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
  201. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
  202. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  203. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  204. package/src/__tests__/usage-attribution.test.ts +247 -0
  205. package/src/__tests__/usage-cli.test.ts +143 -0
  206. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  207. package/src/__tests__/usage-routes.test.ts +150 -0
  208. package/src/__tests__/validation-results-screen.test.ts +39 -16
  209. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  210. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
  211. package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
  212. package/src/__tests__/voice-session-bridge.test.ts +5 -5
  213. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  214. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  215. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  216. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
  217. package/src/acp/index.ts +0 -15
  218. package/src/acp/session-manager.ts +37 -34
  219. package/src/agent/loop.ts +16 -1
  220. package/src/approvals/AGENTS.md +4 -0
  221. package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
  222. package/src/approvals/guardian-request-resolvers.ts +10 -2
  223. package/src/backup/__tests__/backup-worker.test.ts +36 -8
  224. package/src/backup/__tests__/paths.test.ts +2 -2
  225. package/src/backup/__tests__/restore.test.ts +45 -28
  226. package/src/backup/backup-worker.ts +36 -2
  227. package/src/backup/paths.ts +9 -6
  228. package/src/browser-session/events.ts +0 -9
  229. package/src/calls/call-store.ts +1 -34
  230. package/src/calls/guardian-question-copy.ts +0 -108
  231. package/src/calls/relay-server.ts +0 -24
  232. package/src/calls/twilio-rest.ts +0 -38
  233. package/src/calls/twilio-routes.ts +1 -1
  234. package/src/calls/voice-session-bridge.ts +7 -38
  235. package/src/channels/types.ts +1 -36
  236. package/src/cli/commands/__tests__/cache.test.ts +152 -5
  237. package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
  238. package/src/cli/commands/__tests__/trust.test.ts +21 -387
  239. package/src/cli/commands/backup.ts +4 -4
  240. package/src/cli/commands/cache-fs.ts +8 -0
  241. package/src/cli/commands/cache.ts +153 -82
  242. package/src/cli/commands/clients.ts +63 -5
  243. package/src/cli/commands/completions.ts +3 -3
  244. package/src/cli/commands/contacts.ts +231 -76
  245. package/src/cli/commands/keys.ts +4 -1
  246. package/src/cli/commands/memory-v2.ts +24 -52
  247. package/src/cli/commands/oauth/shared.ts +2 -29
  248. package/src/cli/commands/pending.ts +102 -0
  249. package/src/cli/commands/skills.ts +77 -35
  250. package/src/cli/commands/trust.ts +70 -430
  251. package/src/cli/commands/usage.ts +25 -16
  252. package/src/cli/lib/daemon-credential-client.ts +14 -0
  253. package/src/cli/program.ts +2 -0
  254. package/src/cli.ts +0 -21
  255. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  256. package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
  257. package/src/config/env-registry.ts +12 -2
  258. package/src/config/env.ts +3 -14
  259. package/src/config/feature-flag-registry.json +30 -30
  260. package/src/config/llm-callsite-catalog.ts +12 -0
  261. package/src/config/llm-context-resolution.ts +80 -0
  262. package/src/config/llm-resolver.ts +58 -22
  263. package/src/config/loader.ts +3 -3
  264. package/src/config/schema.ts +2 -158
  265. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
  266. package/src/config/schemas/call-site-catalog.ts +271 -0
  267. package/src/config/schemas/calls.ts +5 -5
  268. package/src/config/schemas/inference.ts +1 -1
  269. package/src/config/schemas/ingress.ts +1 -1
  270. package/src/config/schemas/llm.ts +31 -3
  271. package/src/config/schemas/memory-retrieval.ts +2 -2
  272. package/src/config/schemas/memory-v2.ts +9 -0
  273. package/src/config/schemas/security.ts +1 -42
  274. package/src/config/schemas/services.ts +6 -6
  275. package/src/config/schemas/skills.ts +5 -5
  276. package/src/config/schemas/tts.ts +1 -1
  277. package/src/config/seed-inference-profiles.ts +117 -0
  278. package/src/config/skills.ts +0 -90
  279. package/src/config/types.ts +3 -6
  280. package/src/contacts/contact-store.ts +0 -17
  281. package/src/contacts/contacts-write.ts +1 -105
  282. package/src/context/window-manager.ts +44 -5
  283. package/src/credential-execution/process-manager.ts +34 -10
  284. package/src/credential-health/credential-health-service.ts +21 -16
  285. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
  286. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
  287. package/src/daemon/connection-policy.ts +1 -26
  288. package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
  289. package/src/daemon/conversation-agent-loop.ts +277 -36
  290. package/src/daemon/conversation-history.ts +8 -8
  291. package/src/daemon/conversation-launch.ts +20 -135
  292. package/src/daemon/conversation-lifecycle.ts +1 -1
  293. package/src/daemon/conversation-messaging.ts +1 -0
  294. package/src/daemon/conversation-process.ts +83 -163
  295. package/src/daemon/conversation-runtime-assembly.ts +219 -76
  296. package/src/daemon/conversation-slash.ts +47 -5
  297. package/src/daemon/conversation-store.ts +7 -31
  298. package/src/daemon/conversation-surfaces.ts +22 -28
  299. package/src/daemon/conversation-tool-setup.ts +3 -33
  300. package/src/daemon/conversation-usage.ts +36 -0
  301. package/src/daemon/conversation.ts +117 -233
  302. package/src/daemon/daemon-control.ts +3 -71
  303. package/src/daemon/daemon-skill-host.ts +8 -11
  304. package/src/daemon/dictation-profile-store.ts +2 -26
  305. package/src/daemon/first-greeting.ts +44 -156
  306. package/src/daemon/handlers/config-channels.ts +12 -12
  307. package/src/daemon/handlers/config-ingress.ts +4 -165
  308. package/src/daemon/handlers/config-model.ts +1 -1
  309. package/src/daemon/handlers/config-voice.ts +0 -42
  310. package/src/daemon/handlers/conversations.ts +11 -190
  311. package/src/daemon/handlers/recording.ts +26 -158
  312. package/src/daemon/handlers/shared.ts +23 -71
  313. package/src/daemon/handlers/skills.ts +42 -93
  314. package/src/daemon/host-bash-proxy.ts +67 -45
  315. package/src/daemon/host-browser-proxy.ts +65 -27
  316. package/src/daemon/host-cu-proxy.ts +40 -39
  317. package/src/daemon/host-file-proxy.ts +58 -37
  318. package/src/daemon/host-transfer-proxy.ts +84 -46
  319. package/src/daemon/lifecycle.ts +49 -15
  320. package/src/daemon/message-types/conversations.ts +7 -0
  321. package/src/daemon/message-types/host-bash.ts +1 -0
  322. package/src/daemon/message-types/host-cu.ts +1 -0
  323. package/src/daemon/message-types/host-file.ts +1 -0
  324. package/src/daemon/message-types/host-transfer.ts +1 -0
  325. package/src/daemon/message-types/messages.ts +10 -9
  326. package/src/daemon/message-types/workspace.ts +1 -1
  327. package/src/daemon/process-message.ts +102 -239
  328. package/src/daemon/server.ts +13 -462
  329. package/src/daemon/shutdown-handlers.ts +2 -2
  330. package/src/daemon/tool-side-effects.ts +125 -107
  331. package/src/daemon/trust-context.ts +13 -0
  332. package/src/daemon/wake-target-adapter.ts +4 -9
  333. package/src/events/domain-events.ts +0 -8
  334. package/src/events/tool-audit-listener.ts +3 -1
  335. package/src/events/tool-domain-event-publisher.ts +0 -10
  336. package/src/events/tool-metrics-listener.ts +0 -17
  337. package/src/events/tool-trace-listener.ts +0 -14
  338. package/src/filing/filing-service.ts +13 -1
  339. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
  340. package/src/heartbeat/heartbeat-service.ts +23 -5
  341. package/src/home/__tests__/feed-writer.test.ts +0 -4
  342. package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
  343. package/src/home/feed-writer.ts +1 -2
  344. package/src/home/relationship-state-writer.ts +16 -3
  345. package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
  346. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
  347. package/src/ipc/assistant-server.ts +3 -10
  348. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
  349. package/src/ipc/routes/route-adapter.ts +1 -1
  350. package/src/ipc/routes/trust-rules.test.ts +0 -95
  351. package/src/ipc/skill-ipc-types.ts +41 -0
  352. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
  353. package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
  354. package/src/ipc/skill-routes/events.ts +12 -23
  355. package/src/ipc/skill-routes/identity.ts +4 -17
  356. package/src/ipc/skill-routes/index.ts +1 -1
  357. package/src/ipc/skill-server.ts +6 -39
  358. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
  359. package/src/live-voice/protocol.ts +4 -13
  360. package/src/mcp/manager.ts +0 -5
  361. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  362. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  363. package/src/memory/app-git-service.ts +0 -32
  364. package/src/memory/app-store.ts +154 -0
  365. package/src/memory/attachments-store.ts +6 -0
  366. package/src/memory/context-search/sources/memory-v2.ts +578 -0
  367. package/src/memory/context-search/sources/memory.ts +5 -0
  368. package/src/memory/context-search/sources/pkb.ts +10 -1
  369. package/src/memory/context-search/sources/workspace.ts +3 -2
  370. package/src/memory/conversation-crud.ts +29 -4
  371. package/src/memory/conversation-disk-view.ts +1 -5
  372. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  373. package/src/memory/db-connection.ts +62 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +3 -21
  376. package/src/memory/embedding-gemini.ts +0 -2
  377. package/src/memory/embedding-local.ts +6 -6
  378. package/src/memory/embedding-ollama.ts +6 -6
  379. package/src/memory/embedding-openai.ts +6 -6
  380. package/src/memory/embedding-types.ts +21 -0
  381. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
  382. package/src/memory/graph/conversation-graph-memory.ts +35 -13
  383. package/src/memory/graph/injection.test.ts +2 -2
  384. package/src/memory/graph/injection.ts +1 -1
  385. package/src/memory/guardian-action-store.ts +0 -83
  386. package/src/memory/guardian-approvals.ts +0 -48
  387. package/src/memory/indexer.ts +1 -15
  388. package/src/memory/job-handlers/conversation-starters.ts +36 -53
  389. package/src/memory/job-utils.ts +0 -6
  390. package/src/memory/jobs-store.ts +0 -1
  391. package/src/memory/jobs-worker.ts +2 -16
  392. package/src/memory/llm-request-log-store.ts +0 -41
  393. package/src/memory/llm-usage-store.ts +129 -43
  394. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  395. package/src/memory/migrations/233-document-conversations.ts +54 -0
  396. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  397. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  398. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  399. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  400. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  401. package/src/memory/migrations/index.ts +14 -0
  402. package/src/memory/migrations/registry.ts +24 -0
  403. package/src/memory/raw-query.ts +2 -68
  404. package/src/memory/schema/conversations.ts +7 -0
  405. package/src/memory/schema/infrastructure.ts +25 -0
  406. package/src/memory/search/semantic.ts +5 -16
  407. package/src/memory/tool-usage-store.ts +2 -0
  408. package/src/memory/usage-buckets.ts +40 -1
  409. package/src/memory/usage-grouped-buckets.ts +127 -0
  410. package/src/memory/v2/__tests__/activation.test.ts +289 -90
  411. package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
  412. package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
  413. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  414. package/src/memory/v2/__tests__/injection.test.ts +384 -15
  415. package/src/memory/v2/__tests__/migration.test.ts +64 -36
  416. package/src/memory/v2/__tests__/page-store.test.ts +191 -8
  417. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  418. package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
  419. package/src/memory/v2/__tests__/static-context.test.ts +153 -0
  420. package/src/memory/v2/activation.ts +168 -97
  421. package/src/memory/v2/backfill-jobs.ts +15 -100
  422. package/src/memory/v2/consolidation-job.ts +14 -12
  423. package/src/memory/v2/edge-index.ts +191 -0
  424. package/src/memory/v2/injection.ts +182 -58
  425. package/src/memory/v2/migration.ts +57 -64
  426. package/src/memory/v2/now-text.ts +2 -3
  427. package/src/memory/v2/page-store.ts +168 -31
  428. package/src/memory/v2/prompts/consolidation.ts +118 -42
  429. package/src/memory/v2/prompts/sweep.ts +3 -3
  430. package/src/memory/v2/skill-store.ts +55 -7
  431. package/src/memory/v2/static-context.ts +62 -0
  432. package/src/memory/v2/types.ts +10 -20
  433. package/src/memory/validation.ts +0 -11
  434. package/src/messaging/draft-store.ts +0 -6
  435. package/src/messaging/provider-types.ts +8 -0
  436. package/src/messaging/provider.ts +7 -0
  437. package/src/messaging/providers/gmail/client.ts +1 -121
  438. package/src/messaging/providers/outlook/client.ts +0 -73
  439. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  440. package/src/messaging/providers/slack/adapter.ts +122 -21
  441. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  442. package/src/messaging/providers/slack/backfill.ts +89 -11
  443. package/src/messaging/providers/slack/client.ts +10 -124
  444. package/src/messaging/providers/slack/message-metadata.ts +12 -2
  445. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  446. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  447. package/src/messaging/providers/slack/types.ts +1 -0
  448. package/src/oauth/connection-resolver.test.ts +8 -0
  449. package/src/oauth/connection-resolver.ts +8 -16
  450. package/src/oauth/credential-token-resolver.ts +97 -0
  451. package/src/oauth/manual-token-connection.ts +30 -34
  452. package/src/oauth/oauth-store.ts +6 -4
  453. package/src/outbound-proxy/certs.ts +0 -7
  454. package/src/outbound-proxy/config.ts +0 -74
  455. package/src/outbound-proxy/health.ts +0 -44
  456. package/src/outbound-proxy/index.ts +0 -22
  457. package/src/permissions/approval-provenance.test.ts +184 -0
  458. package/src/permissions/approval-provenance.ts +70 -0
  459. package/src/permissions/checker.ts +4 -1
  460. package/src/permissions/gateway-threshold-reader.ts +4 -1
  461. package/src/permissions/prompter.ts +9 -2
  462. package/src/permissions/secret-prompter.ts +21 -48
  463. package/src/permissions/types.ts +33 -0
  464. package/src/permissions/workspace-policy.ts +0 -5
  465. package/src/platform/sync-identity.ts +0 -8
  466. package/src/plugins/defaults/injectors.ts +69 -2
  467. package/src/plugins/defaults/overflow-reduce.ts +3 -2
  468. package/src/plugins/types.ts +8 -0
  469. package/src/prompts/system-prompt.ts +34 -70
  470. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  471. package/src/prompts/update-bulletin-job.ts +2 -0
  472. package/src/providers/__tests__/retry-callsite.test.ts +138 -1
  473. package/src/providers/anthropic/client.ts +72 -33
  474. package/src/providers/call-site-routing.ts +42 -3
  475. package/src/providers/gemini/client.ts +18 -2
  476. package/src/providers/managed-proxy/context.ts +0 -5
  477. package/src/providers/model-catalog.ts +105 -19
  478. package/src/providers/openai/chat-completions-provider.ts +6 -0
  479. package/src/providers/openai/responses-provider.ts +7 -1
  480. package/src/providers/provider-send-message.ts +45 -2
  481. package/src/providers/ratelimit.ts +7 -2
  482. package/src/providers/registry.ts +14 -9
  483. package/src/providers/retry.ts +96 -8
  484. package/src/providers/types.ts +13 -0
  485. package/src/providers/usage-tracking.ts +96 -0
  486. package/src/runtime/AGENTS.md +10 -6
  487. package/src/runtime/__tests__/agent-wake.test.ts +89 -0
  488. package/src/runtime/agent-wake.ts +39 -2
  489. package/src/runtime/assistant-event-hub.ts +541 -45
  490. package/src/runtime/assistant-event.ts +1 -6
  491. package/src/runtime/auth/context.ts +0 -9
  492. package/src/runtime/auth/middleware.ts +1 -1
  493. package/src/runtime/auth/route-policy.ts +11 -9
  494. package/src/runtime/auth/token-service.ts +0 -11
  495. package/src/runtime/channel-approvals.ts +6 -2
  496. package/src/runtime/channel-verification-service.ts +3 -5
  497. package/src/runtime/http-errors.ts +0 -34
  498. package/src/runtime/http-router.ts +6 -3
  499. package/src/runtime/http-server.ts +22 -82
  500. package/src/runtime/http-types.ts +5 -0
  501. package/src/runtime/interactive-ui.ts +0 -1
  502. package/src/runtime/middleware/auth.ts +0 -20
  503. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  504. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  505. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  506. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  507. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  508. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  509. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
  510. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  511. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
  512. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
  513. package/src/runtime/migrations/migration-transport.ts +46 -13
  514. package/src/runtime/migrations/migration-wizard.ts +2 -2
  515. package/src/runtime/migrations/origin-mode.ts +40 -0
  516. package/src/runtime/migrations/vbundle-builder.ts +133 -79
  517. package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
  518. package/src/runtime/migrations/vbundle-importer.ts +7 -7
  519. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  520. package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
  521. package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
  522. package/src/runtime/migrations/vbundle-validator.ts +214 -41
  523. package/src/runtime/pending-interactions.ts +13 -4
  524. package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
  525. package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
  526. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
  527. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  528. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  529. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  530. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  531. package/src/runtime/routes/acp-routes.test.ts +0 -3
  532. package/src/runtime/routes/acp-routes.ts +3 -7
  533. package/src/runtime/routes/app-management-routes.ts +18 -9
  534. package/src/runtime/routes/approval-routes.ts +55 -14
  535. package/src/runtime/routes/avatar-routes.ts +3 -5
  536. package/src/runtime/routes/browser-routes.ts +1 -15
  537. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  538. package/src/runtime/routes/channel-readiness-routes.ts +3 -7
  539. package/src/runtime/routes/channel-route-shared.ts +2 -28
  540. package/src/runtime/routes/client-routes.ts +45 -12
  541. package/src/runtime/routes/consolidation-routes.ts +115 -0
  542. package/src/runtime/routes/conversation-list-routes.ts +12 -29
  543. package/src/runtime/routes/conversation-management-routes.ts +14 -51
  544. package/src/runtime/routes/conversation-query-routes.ts +120 -8
  545. package/src/runtime/routes/conversation-routes.ts +44 -528
  546. package/src/runtime/routes/conversation-starter-routes.ts +19 -40
  547. package/src/runtime/routes/documents-routes.ts +53 -18
  548. package/src/runtime/routes/events-routes.ts +59 -91
  549. package/src/runtime/routes/filing-routes.ts +18 -1
  550. package/src/runtime/routes/guardian-action-routes.ts +4 -9
  551. package/src/runtime/routes/host-bash-routes.ts +3 -2
  552. package/src/runtime/routes/host-browser-routes.ts +9 -33
  553. package/src/runtime/routes/host-cu-routes.ts +6 -1
  554. package/src/runtime/routes/host-file-routes.ts +3 -2
  555. package/src/runtime/routes/host-transfer-routes.ts +11 -15
  556. package/src/runtime/routes/identity-routes.ts +78 -6
  557. package/src/runtime/routes/inbound-message-handler.ts +580 -137
  558. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
  559. package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
  560. package/src/runtime/routes/index.ts +4 -0
  561. package/src/runtime/routes/integrations/slack/channel.ts +0 -24
  562. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  563. package/src/runtime/routes/memory-v2-routes.ts +10 -15
  564. package/src/runtime/routes/migration-routes.ts +188 -31
  565. package/src/runtime/routes/playground/guard.ts +1 -1
  566. package/src/runtime/routes/playground/index.ts +0 -2
  567. package/src/runtime/routes/recording-routes.ts +4 -24
  568. package/src/runtime/routes/rename-conversation-routes.ts +2 -6
  569. package/src/runtime/routes/schedule-routes.ts +3 -6
  570. package/src/runtime/routes/secret-routes.ts +87 -18
  571. package/src/runtime/routes/settings-routes.ts +29 -28
  572. package/src/runtime/routes/skills-routes.ts +12 -31
  573. package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
  574. package/src/runtime/routes/task-routes.ts +6 -6
  575. package/src/runtime/routes/trust-rules-routes.ts +3 -94
  576. package/src/runtime/routes/types.ts +4 -4
  577. package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
  578. package/src/runtime/routes/usage-routes.ts +87 -10
  579. package/src/runtime/routes/user-routes.ts +17 -31
  580. package/src/runtime/routes/work-items-routes.ts +1 -4
  581. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
  582. package/src/runtime/services/analyze-conversation.ts +7 -17
  583. package/src/runtime/services/conversation-serializer.ts +2 -4
  584. package/src/runtime/verification-outbound-actions.ts +1 -1
  585. package/src/runtime/verification-rate-limiter.ts +1 -1
  586. package/src/schedule/schedule-store.ts +0 -16
  587. package/src/security/secret-scanner.ts +14 -547
  588. package/src/security/secure-keys.ts +31 -11
  589. package/src/security/token-manager.ts +7 -3
  590. package/src/signals/cancel.ts +16 -25
  591. package/src/signals/conversation-undo.ts +2 -27
  592. package/src/signals/emit-event.ts +1 -2
  593. package/src/signals/user-message.ts +108 -22
  594. package/src/skills/catalog-install.ts +1 -0
  595. package/src/skills/clawhub.ts +2 -2
  596. package/src/skills/inline-command-runner.ts +1 -7
  597. package/src/subagent/manager.ts +67 -84
  598. package/src/tasks/task-store.ts +1 -28
  599. package/src/telemetry/types.ts +6 -0
  600. package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
  601. package/src/telemetry/usage-telemetry-reporter.ts +3 -5
  602. package/src/tools/acp/spawn.test.ts +1 -2
  603. package/src/tools/acp/steer.test.ts +1 -2
  604. package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
  605. package/src/tools/browser/browser-execution.ts +31 -147
  606. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
  607. package/src/tools/browser/cdp-client/factory.ts +48 -76
  608. package/src/tools/browser/cdp-client/index.ts +1 -14
  609. package/src/tools/executor.ts +44 -31
  610. package/src/tools/host-filesystem/edit.ts +3 -2
  611. package/src/tools/host-filesystem/read.ts +3 -2
  612. package/src/tools/host-filesystem/transfer.test.ts +45 -42
  613. package/src/tools/host-filesystem/transfer.ts +4 -3
  614. package/src/tools/host-filesystem/write.ts +3 -2
  615. package/src/tools/host-terminal/host-shell.ts +4 -3
  616. package/src/tools/network/script-proxy/index.ts +1 -10
  617. package/src/tools/permission-checker.ts +66 -1
  618. package/src/tools/skills/sandbox-runner.ts +1 -6
  619. package/src/tools/skills/skill-tool-factory.ts +32 -0
  620. package/src/tools/terminal/safe-env.ts +1 -0
  621. package/src/tools/terminal/shell.ts +2 -78
  622. package/src/tools/types.ts +12 -39
  623. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  624. package/src/tts/provider-catalog.ts +1 -1
  625. package/src/usage/actors.ts +2 -1
  626. package/src/usage/attribution.ts +185 -0
  627. package/src/usage/pricing.ts +166 -0
  628. package/src/usage/types.ts +14 -0
  629. package/src/util/json.ts +13 -0
  630. package/src/util/logger.ts +3 -3
  631. package/src/util/pricing.ts +50 -3
  632. package/src/work-items/work-item-runner.ts +15 -42
  633. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
  634. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
  635. package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
  636. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
  637. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  638. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  639. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  640. package/src/workspace/migrations/registry.ts +8 -0
  641. package/src/workspace/provider-commit-message-generator.ts +3 -3
  642. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  643. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  644. package/src/__tests__/secret-detection-handler.test.ts +0 -67
  645. package/src/__tests__/secret-scanner-executor.test.ts +0 -450
  646. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  647. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  648. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  649. package/src/context/__tests__/microcompact.test.ts +0 -805
  650. package/src/context/microcompact.ts +0 -443
  651. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  652. package/src/events/tool-notification-listener.ts +0 -17
  653. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
  654. package/src/memory/v2/__tests__/edges.test.ts +0 -435
  655. package/src/memory/v2/edges.ts +0 -217
  656. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
  657. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  658. package/src/runtime/__tests__/client-registry.test.ts +0 -271
  659. package/src/runtime/chrome-extension-registry.ts +0 -368
  660. package/src/runtime/client-registry.ts +0 -254
  661. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
  662. package/src/tools/secret-detection-handler.ts +0 -269
  663. package/src/tools/terminal/backends/native.ts +0 -327
  664. package/src/tools/terminal/backends/types.ts +0 -37
  665. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  666. package/src/tools/terminal/sandbox.ts +0 -40
@@ -16,6 +16,7 @@ import { gunzipSync } from "node:zlib";
16
16
  import { describe, expect, test } from "bun:test";
17
17
 
18
18
  import { buildExportVBundle, streamExportVBundle } from "../vbundle-builder.js";
19
+ import { defaultV1Options } from "./v1-test-helpers.js";
19
20
 
20
21
  // ---------------------------------------------------------------------------
21
22
  // Helpers
@@ -111,6 +112,7 @@ describe("buildExportVBundle with credentials", () => {
111
112
  ];
112
113
 
113
114
  const result = buildExportVBundle({
115
+ ...defaultV1Options(),
114
116
  workspaceDir: workspace.dir,
115
117
  credentials,
116
118
  });
@@ -141,6 +143,7 @@ describe("buildExportVBundle with credentials", () => {
141
143
  ];
142
144
 
143
145
  const result = buildExportVBundle({
146
+ ...defaultV1Options(),
144
147
  workspaceDir: workspace.dir,
145
148
  credentials,
146
149
  });
@@ -149,12 +152,12 @@ describe("buildExportVBundle with credentials", () => {
149
152
  new TextEncoder().encode("secret-value-abc"),
150
153
  );
151
154
 
152
- const credEntry = result.manifest.files.find(
155
+ const credEntry = result.manifest.contents.find(
153
156
  (f) => f.path === "credentials/my-api-key",
154
157
  );
155
158
  expect(credEntry).toBeDefined();
156
159
  expect(credEntry!.sha256).toBe(expectedHash);
157
- expect(credEntry!.size).toBe(
160
+ expect(credEntry!.size_bytes).toBe(
158
161
  new TextEncoder().encode("secret-value-abc").length,
159
162
  );
160
163
  } finally {
@@ -166,6 +169,7 @@ describe("buildExportVBundle with credentials", () => {
166
169
  const workspace = createTestWorkspace();
167
170
  try {
168
171
  const result = buildExportVBundle({
172
+ ...defaultV1Options(),
169
173
  workspaceDir: workspace.dir,
170
174
  });
171
175
 
@@ -178,7 +182,7 @@ describe("buildExportVBundle with credentials", () => {
178
182
  expect(credentialEntries).toHaveLength(0);
179
183
 
180
184
  // Manifest should have no credential entries
181
- const credManifestEntries = result.manifest.files.filter((f) =>
185
+ const credManifestEntries = result.manifest.contents.filter((f) =>
182
186
  f.path.startsWith("credentials/"),
183
187
  );
184
188
  expect(credManifestEntries).toHaveLength(0);
@@ -191,6 +195,7 @@ describe("buildExportVBundle with credentials", () => {
191
195
  const workspace = createTestWorkspace();
192
196
  try {
193
197
  const result = buildExportVBundle({
198
+ ...defaultV1Options(),
194
199
  workspaceDir: workspace.dir,
195
200
  credentials: [],
196
201
  });
@@ -218,6 +223,7 @@ describe("streamExportVBundle with credentials", () => {
218
223
  ];
219
224
 
220
225
  result = await streamExportVBundle({
226
+ ...defaultV1Options(),
221
227
  workspaceDir: workspace.dir,
222
228
  credentials,
223
229
  });
@@ -237,7 +243,7 @@ describe("streamExportVBundle with credentials", () => {
237
243
  );
238
244
 
239
245
  // Verify manifest entry
240
- const credEntry = result.manifest.files.find(
246
+ const credEntry = result.manifest.contents.find(
241
247
  (f) => f.path === "credentials/stream-key",
242
248
  );
243
249
  expect(credEntry).toBeDefined();
@@ -255,6 +261,7 @@ describe("streamExportVBundle with credentials", () => {
255
261
  let result: Awaited<ReturnType<typeof streamExportVBundle>> | undefined;
256
262
  try {
257
263
  result = await streamExportVBundle({
264
+ ...defaultV1Options(),
258
265
  workspaceDir: workspace.dir,
259
266
  });
260
267
 
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Verifies that the buffered (`buildVBundle` / `buildExportVBundle`) and
3
+ * streaming (`streamExportVBundle`) emit paths both produce manifests
4
+ * conforming to the canonical v1 ten-field shape.
5
+ *
6
+ * Drift between the two emit paths is exactly how the prior schema
7
+ * mismatch went unnoticed — these tests pin both paths to the same shape
8
+ * and run a round-trip through `validateVBundle` so any future
9
+ * canonicalization drift fails loudly.
10
+ */
11
+
12
+ import { createHash } from "node:crypto";
13
+ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
14
+ import { tmpdir } from "node:os";
15
+ import { join } from "node:path";
16
+ import { gunzipSync } from "node:zlib";
17
+ import { describe, expect, test } from "bun:test";
18
+
19
+ import {
20
+ buildExportVBundle,
21
+ buildVBundle,
22
+ streamExportVBundle,
23
+ } from "../vbundle-builder.js";
24
+ import { canonicalizeJson, validateVBundle } from "../vbundle-validator.js";
25
+ import { defaultV1Options } from "./v1-test-helpers.js";
26
+
27
+ function sha256Hex(data: Uint8Array | string): string {
28
+ return createHash("sha256").update(data).digest("hex");
29
+ }
30
+
31
+ function createTestWorkspace(): { dir: string; cleanup: () => void } {
32
+ const dir = join(
33
+ tmpdir(),
34
+ `vbundle-v1-shape-${Date.now()}-${Math.random().toString(36).slice(2)}`,
35
+ );
36
+ mkdirSync(dir, { recursive: true });
37
+ writeFileSync(join(dir, "config.json"), JSON.stringify({ test: true }));
38
+ const dbDir = join(dir, "data", "db");
39
+ mkdirSync(dbDir, { recursive: true });
40
+ writeFileSync(join(dbDir, "assistant.db"), "fake-db-content");
41
+ return {
42
+ dir,
43
+ cleanup: () => rmSync(dir, { recursive: true, force: true }),
44
+ };
45
+ }
46
+
47
+ const UUID_V4_RE =
48
+ /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
49
+ const ISO_8601_RE =
50
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
51
+ const SHA256_HEX_RE = /^[0-9a-f]{64}$/;
52
+
53
+ describe("buildVBundle — v1 ten-field manifest shape", () => {
54
+ test("emits all ten required top-level fields with correct types", () => {
55
+ const { manifest } = buildVBundle({
56
+ files: [
57
+ {
58
+ path: "data/db/assistant.db",
59
+ data: new TextEncoder().encode("db-bytes"),
60
+ },
61
+ ],
62
+ ...defaultV1Options(),
63
+ });
64
+
65
+ expect(manifest.schema_version).toBe(1);
66
+ expect(typeof manifest.bundle_id).toBe("string");
67
+ expect(manifest.bundle_id).toMatch(UUID_V4_RE);
68
+ expect(manifest.created_at).toMatch(ISO_8601_RE);
69
+ expect(manifest.assistant.id).toBe("self");
70
+ expect(manifest.assistant.name).toBe("Test");
71
+ expect(manifest.assistant.runtime_version).toBe("0.0.0-test");
72
+ expect(manifest.origin.mode).toBe("self-hosted-local");
73
+ expect(manifest.compatibility.min_runtime_version).toBe("0.0.0-test");
74
+ expect(manifest.compatibility.max_runtime_version).toBeNull();
75
+ expect(Array.isArray(manifest.contents)).toBe(true);
76
+ expect(manifest.contents.length).toBeGreaterThan(0);
77
+ expect(manifest.checksum).toMatch(SHA256_HEX_RE);
78
+ expect(typeof manifest.secrets_redacted).toBe("boolean");
79
+ expect(typeof manifest.export_options.include_logs).toBe("boolean");
80
+ });
81
+
82
+ test("contents always declares data/db/assistant.db when the input includes it", () => {
83
+ const { manifest } = buildVBundle({
84
+ files: [
85
+ {
86
+ path: "data/db/assistant.db",
87
+ data: new TextEncoder().encode("db-bytes"),
88
+ },
89
+ {
90
+ path: "config/settings.json",
91
+ data: new TextEncoder().encode("{}"),
92
+ },
93
+ ],
94
+ ...defaultV1Options(),
95
+ });
96
+
97
+ const dbEntry = manifest.contents.find(
98
+ (f) => f.path === "data/db/assistant.db",
99
+ );
100
+ expect(dbEntry).toBeDefined();
101
+ expect(dbEntry!.size_bytes).toBe(
102
+ new TextEncoder().encode("db-bytes").length,
103
+ );
104
+ });
105
+
106
+ test("checksum is the sha256 of the canonicalized manifest with checksum=''", () => {
107
+ const { manifest } = buildVBundle({
108
+ files: [
109
+ {
110
+ path: "data/db/assistant.db",
111
+ data: new TextEncoder().encode("db-bytes"),
112
+ },
113
+ ],
114
+ ...defaultV1Options(),
115
+ });
116
+
117
+ const expected = sha256Hex(canonicalizeJson({ ...manifest, checksum: "" }));
118
+ expect(manifest.checksum).toBe(expected);
119
+ });
120
+
121
+ test("secrets_redacted reflects the input flag", () => {
122
+ const truthy = buildVBundle({
123
+ files: [
124
+ {
125
+ path: "data/db/assistant.db",
126
+ data: new TextEncoder().encode("db-bytes"),
127
+ },
128
+ ],
129
+ ...defaultV1Options(),
130
+ secretsRedacted: true,
131
+ });
132
+ expect(truthy.manifest.secrets_redacted).toBe(true);
133
+
134
+ const falsey = buildVBundle({
135
+ files: [
136
+ {
137
+ path: "data/db/assistant.db",
138
+ data: new TextEncoder().encode("db-bytes"),
139
+ },
140
+ ],
141
+ ...defaultV1Options(),
142
+ secretsRedacted: false,
143
+ });
144
+ expect(falsey.manifest.secrets_redacted).toBe(false);
145
+ });
146
+
147
+ test("bundle_id is a fresh UUID per export", () => {
148
+ const a = buildVBundle({
149
+ files: [
150
+ {
151
+ path: "data/db/assistant.db",
152
+ data: new TextEncoder().encode("db-bytes"),
153
+ },
154
+ ],
155
+ ...defaultV1Options(),
156
+ });
157
+ const b = buildVBundle({
158
+ files: [
159
+ {
160
+ path: "data/db/assistant.db",
161
+ data: new TextEncoder().encode("db-bytes"),
162
+ },
163
+ ],
164
+ ...defaultV1Options(),
165
+ });
166
+ expect(a.manifest.bundle_id).not.toBe(b.manifest.bundle_id);
167
+ });
168
+ });
169
+
170
+ describe("streamExportVBundle — v1 ten-field manifest shape", () => {
171
+ test("matches buildExportVBundle's manifest shape (modulo bundle_id and created_at)", async () => {
172
+ const workspace = createTestWorkspace();
173
+ let streamResult:
174
+ | Awaited<ReturnType<typeof streamExportVBundle>>
175
+ | undefined;
176
+ try {
177
+ const sync = buildExportVBundle({
178
+ workspaceDir: workspace.dir,
179
+ ...defaultV1Options(),
180
+ });
181
+ streamResult = await streamExportVBundle({
182
+ workspaceDir: workspace.dir,
183
+ ...defaultV1Options(),
184
+ });
185
+
186
+ expect(streamResult.manifest.schema_version).toBe(
187
+ sync.manifest.schema_version,
188
+ );
189
+ expect(streamResult.manifest.assistant).toEqual(sync.manifest.assistant);
190
+ expect(streamResult.manifest.origin).toEqual(sync.manifest.origin);
191
+ expect(streamResult.manifest.compatibility).toEqual(
192
+ sync.manifest.compatibility,
193
+ );
194
+ expect(streamResult.manifest.export_options).toEqual(
195
+ sync.manifest.export_options,
196
+ );
197
+ expect(streamResult.manifest.secrets_redacted).toBe(
198
+ sync.manifest.secrets_redacted,
199
+ );
200
+
201
+ // Same set of files (paths + sha + size).
202
+ const sortByPath = (a: { path: string }, b: { path: string }) =>
203
+ a.path.localeCompare(b.path);
204
+ expect(streamResult.manifest.contents.slice().sort(sortByPath)).toEqual(
205
+ sync.manifest.contents.slice().sort(sortByPath),
206
+ );
207
+ } finally {
208
+ await streamResult?.cleanup();
209
+ workspace.cleanup();
210
+ }
211
+ });
212
+ });
213
+
214
+ describe("buildExportVBundle round-trip", () => {
215
+ test("validateVBundle accepts the buffered emit", () => {
216
+ const workspace = createTestWorkspace();
217
+ try {
218
+ const result = buildExportVBundle({
219
+ workspaceDir: workspace.dir,
220
+ ...defaultV1Options(),
221
+ });
222
+ const validation = validateVBundle(result.archive);
223
+ expect(validation.is_valid).toBe(true);
224
+ expect(validation.errors).toHaveLength(0);
225
+ expect(validation.manifest?.checksum).toBe(result.manifest.checksum);
226
+ } finally {
227
+ workspace.cleanup();
228
+ }
229
+ });
230
+
231
+ test("validateVBundle accepts the streaming emit", async () => {
232
+ const workspace = createTestWorkspace();
233
+ let result: Awaited<ReturnType<typeof streamExportVBundle>> | undefined;
234
+ try {
235
+ result = await streamExportVBundle({
236
+ workspaceDir: workspace.dir,
237
+ ...defaultV1Options(),
238
+ });
239
+ const archive = new Uint8Array(
240
+ await Bun.file(result.tempPath).arrayBuffer(),
241
+ );
242
+ // Sanity: archive is valid gzip of a tar.
243
+ expect(gunzipSync(archive).length).toBeGreaterThan(0);
244
+ const validation = validateVBundle(archive);
245
+ expect(validation.is_valid).toBe(true);
246
+ expect(validation.errors).toHaveLength(0);
247
+ expect(validation.manifest?.checksum).toBe(result.manifest.checksum);
248
+ } finally {
249
+ await result?.cleanup();
250
+ workspace.cleanup();
251
+ }
252
+ });
253
+ });
@@ -24,16 +24,29 @@ function makeTarEntry(data: string): VBundleTarEntry {
24
24
 
25
25
  function makeManifest(paths: string[]): ManifestType {
26
26
  return {
27
- schema_version: "1.0.0",
27
+ schema_version: 1,
28
+ bundle_id: "00000000-0000-4000-8000-000000000000",
28
29
  created_at: new Date().toISOString(),
29
- source: "test",
30
- manifest_sha256: "test",
31
- files: paths.map((path) => ({
30
+ assistant: { id: "self", name: "Test", runtime_version: "0.0.0-test" },
31
+ origin: { mode: "self-hosted-local" },
32
+ compatibility: {
33
+ min_runtime_version: "0.0.0-test",
34
+ max_runtime_version: null,
35
+ },
36
+ contents: paths.map((path) => ({
32
37
  path,
33
- size: 0,
38
+ size_bytes: 0,
34
39
  sha256: "test",
35
40
  })),
36
- } as ManifestType;
41
+ checksum:
42
+ "0000000000000000000000000000000000000000000000000000000000000000",
43
+ secrets_redacted: false,
44
+ export_options: {
45
+ include_logs: false,
46
+ include_browser_state: false,
47
+ include_memory_vectors: false,
48
+ },
49
+ } as unknown as ManifestType;
37
50
  }
38
51
 
39
52
  // ---------------------------------------------------------------------------
@@ -29,6 +29,7 @@ import {
29
29
  DefaultPathResolver,
30
30
  } from "../vbundle-import-analyzer.js";
31
31
  import { commitImport } from "../vbundle-importer.js";
32
+ import { defaultV1Options } from "./v1-test-helpers.js";
32
33
 
33
34
  // ---------------------------------------------------------------------------
34
35
  // Shared fixture: per-test workspace under VELLUM_WORKSPACE_DIR.
@@ -139,10 +140,8 @@ describe("DefaultPathResolver prompts/USER.md translation", () => {
139
140
  });
140
141
 
141
142
  test("still resolves other prompt files (IDENTITY.md) to workspace root", () => {
142
- const resolver = new DefaultPathResolver(
143
- WORKSPACE_ROOT,
144
- undefined,
145
- () => join(USERS_DIR, "captain.md"),
143
+ const resolver = new DefaultPathResolver(WORKSPACE_ROOT, undefined, () =>
144
+ join(USERS_DIR, "captain.md"),
146
145
  );
147
146
 
148
147
  expect(resolver.resolve("prompts/IDENTITY.md")).toBe(
@@ -157,10 +156,8 @@ describe("DefaultPathResolver prompts/USER.md translation", () => {
157
156
  });
158
157
 
159
158
  test("skips unknown prompt filenames regardless of guardian state", () => {
160
- const resolver = new DefaultPathResolver(
161
- WORKSPACE_ROOT,
162
- undefined,
163
- () => join(USERS_DIR, "captain.md"),
159
+ const resolver = new DefaultPathResolver(WORKSPACE_ROOT, undefined, () =>
160
+ join(USERS_DIR, "captain.md"),
164
161
  );
165
162
 
166
163
  expect(resolver.resolve("prompts/SECRET.md")).toBeNull();
@@ -182,20 +179,25 @@ describe("analyzeImport for legacy prompts/USER.md", () => {
182
179
 
183
180
  const { archive, manifest } = buildVBundle({
184
181
  files: [
182
+ {
183
+ path: "data/db/assistant.db",
184
+ data: new Uint8Array(),
185
+ },
185
186
  {
186
187
  path: "prompts/USER.md",
187
188
  data: new TextEncoder().encode(LEGACY_USER_MD_CONTENT),
188
189
  },
189
190
  ],
191
+ ...defaultV1Options(),
190
192
  });
191
193
  expect(archive.length).toBeGreaterThan(0);
192
194
 
193
195
  const report = analyzeImport({ manifest, pathResolver: resolver });
194
196
 
195
197
  expect(report.can_import).toBe(true);
196
- expect(report.files).toHaveLength(1);
197
- expect(report.files[0].path).toBe("prompts/USER.md");
198
- expect(report.files[0].action).toBe("create");
198
+ const userMd = report.files.find((f) => f.path === "prompts/USER.md");
199
+ expect(userMd).toBeDefined();
200
+ expect(userMd!.action).toBe("create");
199
201
  });
200
202
 
201
203
  test("non-blocking skip when no guardian is resolvable (can_import stays true)", () => {
@@ -207,11 +209,16 @@ describe("analyzeImport for legacy prompts/USER.md", () => {
207
209
 
208
210
  const { manifest } = buildVBundle({
209
211
  files: [
212
+ {
213
+ path: "data/db/assistant.db",
214
+ data: new Uint8Array(),
215
+ },
210
216
  {
211
217
  path: "prompts/USER.md",
212
218
  data: new TextEncoder().encode(LEGACY_USER_MD_CONTENT),
213
219
  },
214
220
  ],
221
+ ...defaultV1Options(),
215
222
  });
216
223
 
217
224
  const report = analyzeImport({ manifest, pathResolver: resolver });
@@ -220,7 +227,8 @@ describe("analyzeImport for legacy prompts/USER.md", () => {
220
227
  // path warns and skips, so preflight mirrors that behavior.
221
228
  expect(report.can_import).toBe(true);
222
229
  expect(report.conflicts).toHaveLength(0);
223
- expect(report.files[0].action).toBe("skip");
230
+ const userMd = report.files.find((f) => f.path === "prompts/USER.md");
231
+ expect(userMd!.action).toBe("skip");
224
232
  });
225
233
  });
226
234
 
@@ -240,20 +248,31 @@ describe("commitImport for legacy prompts/USER.md", () => {
240
248
 
241
249
  const { archive } = buildVBundle({
242
250
  files: [
251
+ {
252
+ path: "data/db/assistant.db",
253
+ data: new Uint8Array(),
254
+ },
243
255
  {
244
256
  path: "prompts/USER.md",
245
257
  data: new TextEncoder().encode(LEGACY_USER_MD_CONTENT),
246
258
  },
247
259
  ],
260
+ ...defaultV1Options(),
248
261
  });
249
262
 
250
- const result = commitImport({ archiveData: archive, pathResolver: resolver });
263
+ const result = commitImport({
264
+ archiveData: archive,
265
+ pathResolver: resolver,
266
+ });
251
267
 
252
268
  expect(result.ok).toBe(true);
253
269
  if (result.ok) {
254
270
  expect(result.report.success).toBe(true);
255
- expect(result.report.summary.files_created).toBe(1);
256
- expect(result.report.summary.files_skipped).toBe(0);
271
+ // The bundle carries both data/db/assistant.db and prompts/USER.md;
272
+ // the legacy USER.md is the one we care about here.
273
+ expect(
274
+ result.report.files.find((f) => f.path === "prompts/USER.md")?.action,
275
+ ).toBe("created");
257
276
  }
258
277
 
259
278
  expect(existsSync(guardianPath)).toBe(true);
@@ -273,19 +292,28 @@ describe("commitImport for legacy prompts/USER.md", () => {
273
292
 
274
293
  const { archive } = buildVBundle({
275
294
  files: [
295
+ {
296
+ path: "data/db/assistant.db",
297
+ data: new Uint8Array(),
298
+ },
276
299
  {
277
300
  path: "prompts/USER.md",
278
301
  data: new TextEncoder().encode(LEGACY_USER_MD_CONTENT),
279
302
  },
280
303
  ],
304
+ ...defaultV1Options(),
281
305
  });
282
306
 
283
- const result = commitImport({ archiveData: archive, pathResolver: resolver });
307
+ const result = commitImport({
308
+ archiveData: archive,
309
+ pathResolver: resolver,
310
+ });
284
311
 
285
312
  expect(result.ok).toBe(true);
286
313
  if (result.ok) {
287
- expect(result.report.summary.files_overwritten).toBe(1);
288
- expect(result.report.summary.files_skipped).toBe(0);
314
+ expect(
315
+ result.report.files.find((f) => f.path === "prompts/USER.md")?.action,
316
+ ).toBe("overwritten");
289
317
  }
290
318
  expect(readFileSync(guardianPath, "utf-8")).toBe(LEGACY_USER_MD_CONTENT);
291
319
  });
@@ -299,19 +327,28 @@ describe("commitImport for legacy prompts/USER.md", () => {
299
327
 
300
328
  const { archive } = buildVBundle({
301
329
  files: [
330
+ {
331
+ path: "data/db/assistant.db",
332
+ data: new Uint8Array(),
333
+ },
302
334
  {
303
335
  path: "prompts/USER.md",
304
336
  data: new TextEncoder().encode(LEGACY_USER_MD_CONTENT),
305
337
  },
306
338
  ],
339
+ ...defaultV1Options(),
307
340
  });
308
341
 
309
- const result = commitImport({ archiveData: archive, pathResolver: resolver });
342
+ const result = commitImport({
343
+ archiveData: archive,
344
+ pathResolver: resolver,
345
+ });
310
346
 
311
347
  expect(result.ok).toBe(true);
312
348
  if (result.ok) {
313
- expect(result.report.summary.files_skipped).toBe(1);
314
- expect(result.report.summary.files_created).toBe(0);
349
+ expect(
350
+ result.report.files.find((f) => f.path === "prompts/USER.md")?.action,
351
+ ).toBe("skipped");
315
352
  expect(
316
353
  result.report.warnings.some((w) => w.includes("prompts/USER.md")),
317
354
  ).toBe(true);
@@ -334,23 +371,30 @@ describe("commitImport for legacy prompts/USER.md", () => {
334
371
 
335
372
  const { archive } = buildVBundle({
336
373
  files: [
374
+ {
375
+ path: "data/db/assistant.db",
376
+ data: new Uint8Array(),
377
+ },
337
378
  {
338
379
  path: "prompts/USER.md",
339
380
  data: new TextEncoder().encode(LEGACY_USER_MD_CONTENT),
340
381
  },
341
382
  ],
383
+ ...defaultV1Options(),
342
384
  });
343
385
 
344
- const result = commitImport({ archiveData: archive, pathResolver: resolver });
386
+ const result = commitImport({
387
+ archiveData: archive,
388
+ pathResolver: resolver,
389
+ });
345
390
 
346
391
  expect(result.ok).toBe(true);
347
392
  if (result.ok) {
348
- expect(result.report.summary.files_skipped).toBe(1);
349
- expect(result.report.summary.files_overwritten).toBe(0);
350
393
  expect(
351
- result.report.warnings.some((w) =>
352
- w.includes("guardian persona"),
353
- ),
394
+ result.report.files.find((f) => f.path === "prompts/USER.md")?.action,
395
+ ).toBe("skipped");
396
+ expect(
397
+ result.report.warnings.some((w) => w.includes("guardian persona")),
354
398
  ).toBe(true);
355
399
  }
356
400