@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
@@ -87,6 +87,10 @@ mock.module("../config/env.js", () => ({
87
87
  setIngressPublicBaseUrl: () => {},
88
88
  }));
89
89
 
90
+ import {
91
+ buildTestManifest,
92
+ defaultV1Options,
93
+ } from "../runtime/migrations/__tests__/v1-test-helpers.js";
90
94
  import { buildVBundle } from "../runtime/migrations/vbundle-builder.js";
91
95
  import {
92
96
  analyzeImport,
@@ -101,7 +105,6 @@ import {
101
105
  handleMigrationValidate,
102
106
  } from "../runtime/routes/migration-routes.js";
103
107
  import { callHandler } from "./helpers/call-route-handler.js";
104
-
105
108
  // ---------------------------------------------------------------------------
106
109
  // Test fixture data
107
110
  // ---------------------------------------------------------------------------
@@ -233,19 +236,6 @@ function sha256Hex(data: Uint8Array | string): string {
233
236
  return createHash("sha256").update(data).digest("hex");
234
237
  }
235
238
 
236
- function canonicalizeJson(obj: unknown): string {
237
- return JSON.stringify(obj, (_key, value) => {
238
- if (value && typeof value === "object" && !Array.isArray(value)) {
239
- const sorted: Record<string, unknown> = {};
240
- for (const k of Object.keys(value as Record<string, unknown>).sort()) {
241
- sorted[k] = (value as Record<string, unknown>)[k];
242
- }
243
- return sorted;
244
- }
245
- return value;
246
- });
247
- }
248
-
249
239
  interface VBundleFile {
250
240
  path: string;
251
241
  data: Uint8Array;
@@ -253,34 +243,26 @@ interface VBundleFile {
253
243
 
254
244
  function createValidVBundle(
255
245
  files?: VBundleFile[],
256
- overrides?: Partial<{
257
- schema_version: string;
258
- source: string;
259
- description: string;
260
- }>,
246
+ overrides?: Partial<{ schema_version: number }>,
261
247
  ): Uint8Array {
262
248
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
263
249
  const bundleFiles = files ?? [{ path: "data/db/assistant.db", data: dbData }];
264
250
 
265
- const fileEntries = bundleFiles.map((f) => ({
251
+ const contents = bundleFiles.map((f) => ({
266
252
  path: f.path,
267
253
  sha256: sha256Hex(f.data),
268
- size: f.data.length,
254
+ size_bytes: f.data.length,
269
255
  }));
270
256
 
271
- const manifestWithoutChecksum = {
272
- schema_version: overrides?.schema_version ?? "1.0",
273
- created_at: new Date().toISOString(),
274
- source: overrides?.source ?? "test",
275
- description: overrides?.description ?? "Test bundle",
276
- files: fileEntries,
277
- };
278
-
279
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
280
- const manifest = {
281
- ...manifestWithoutChecksum,
282
- manifest_sha256: manifestSha256,
283
- };
257
+ const manifest = buildTestManifest({
258
+ contents,
259
+ overrides: {
260
+ bundle_id: "00000000-0000-4000-8000-000000000000",
261
+ ...(overrides?.schema_version !== undefined
262
+ ? { schema_version: overrides.schema_version }
263
+ : {}),
264
+ },
265
+ });
284
266
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
285
267
 
286
268
  const tarEntries = [
@@ -374,85 +356,22 @@ interface ImportCommitResponse {
374
356
  // ═══════════════════════════════════════════════════════════════════════════
375
357
 
376
358
  describe("schema version compatibility", () => {
377
- test("bundle with schema_version 1.0 validates successfully", () => {
378
- const vbundle = createValidVBundle(undefined, {
379
- schema_version: "1.0",
380
- });
381
- const result = validateVBundle(vbundle);
382
-
383
- expect(result.is_valid).toBe(true);
384
- expect(result.manifest?.schema_version).toBe("1.0");
385
- });
386
-
387
- test("bundle with schema_version 2.0 validates successfully (forward compat)", () => {
388
- // A structurally valid bundle with a future version should still pass
389
- // validation because the schema_version field is a string and the
390
- // archive structure is unchanged.
391
- const vbundle = createValidVBundle(undefined, {
392
- schema_version: "2.0",
393
- });
359
+ test("bundle with schema_version 1 validates successfully", () => {
360
+ const vbundle = createValidVBundle();
394
361
  const result = validateVBundle(vbundle);
395
362
 
396
363
  expect(result.is_valid).toBe(true);
397
- expect(result.manifest?.schema_version).toBe("2.0");
364
+ expect(result.manifest?.schema_version).toBe(1);
398
365
  });
399
366
 
400
- test("bundle with schema_version 99.0 validates when structurally valid", () => {
401
- const vbundle = createValidVBundle(undefined, {
402
- schema_version: "99.0",
403
- });
367
+ test("bundle with schema_version != 1 is rejected by the v1 validator", () => {
368
+ // The v1 validator pins `schema_version: z.literal(1)`. Bundles that
369
+ // claim a different schema version are rejected outright; this used to
370
+ // be permissive when schema_version was a free-form string.
371
+ const vbundle = createValidVBundle(undefined, { schema_version: 2 });
404
372
  const result = validateVBundle(vbundle);
405
373
 
406
- expect(result.is_valid).toBe(true);
407
- expect(result.manifest?.schema_version).toBe("99.0");
408
- });
409
-
410
- test("bundle with arbitrary version string validates when structurally valid", () => {
411
- const vbundle = createValidVBundle(undefined, {
412
- schema_version: "alpha-preview-3",
413
- });
414
- const result = validateVBundle(vbundle);
415
-
416
- expect(result.is_valid).toBe(true);
417
- expect(result.manifest?.schema_version).toBe("alpha-preview-3");
418
- });
419
-
420
- test("future-versioned bundle can be imported successfully", () => {
421
- const newDbData = new Uint8Array([0xfa, 0xce, 0xb0, 0x0c]);
422
- const vbundle = createValidVBundle(
423
- [{ path: "data/db/assistant.db", data: newDbData }],
424
- { schema_version: "3.0" },
425
- );
426
-
427
- const resolver = new DefaultPathResolver(testDir);
428
- const result = commitImport({
429
- archiveData: vbundle,
430
- pathResolver: resolver,
431
- });
432
-
433
- expect(result.ok).toBe(true);
434
- if (result.ok) {
435
- expect(result.report.manifest.schema_version).toBe("3.0");
436
- expect(result.report.success).toBe(true);
437
- }
438
- });
439
-
440
- test("future-versioned bundle shows correct version in preflight report", () => {
441
- const vbundle = createValidVBundle(undefined, {
442
- schema_version: "5.0-beta",
443
- });
444
-
445
- const resolver = new DefaultPathResolver(testDir);
446
- const validationResult = validateVBundle(vbundle);
447
- expect(validationResult.manifest).toBeDefined();
448
-
449
- const report = analyzeImport({
450
- manifest: validationResult.manifest!,
451
- pathResolver: resolver,
452
- });
453
-
454
- expect(report.manifest.schema_version).toBe("5.0-beta");
455
- expect(report.can_import).toBe(true);
374
+ expect(result.is_valid).toBe(false);
456
375
  });
457
376
  });
458
377
 
@@ -541,20 +460,19 @@ describe("missing or malformed version fields", () => {
541
460
  );
542
461
  });
543
462
 
544
- test("empty string schema_version passes validation (empty strings are valid)", () => {
545
- // The Zod schema accepts any string, including empty. An empty string
546
- // is technically a valid schema_version value, even if unconventional.
547
- const vbundle = createValidVBundle(undefined, { schema_version: "" });
463
+ test("zero schema_version is rejected by the v1 validator", () => {
464
+ // The v1 schema pins schema_version to the literal `1`; any other
465
+ // numeric value (including 0) is rejected.
466
+ const vbundle = createValidVBundle(undefined, { schema_version: 0 });
548
467
  const result = validateVBundle(vbundle);
549
468
 
550
- expect(result.is_valid).toBe(true);
551
- expect(result.manifest?.schema_version).toBe("");
469
+ expect(result.is_valid).toBe(false);
552
470
  });
553
471
 
554
472
  test("missing created_at produces MANIFEST_SCHEMA_ERROR", () => {
555
473
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
556
474
  const manifestObj = {
557
- schema_version: "1.0",
475
+ schema_version: 1,
558
476
  // created_at intentionally omitted
559
477
  files: [
560
478
  {
@@ -572,15 +490,20 @@ describe("missing or malformed version fields", () => {
572
490
  const result = validateVBundle(vbundle);
573
491
 
574
492
  expect(result.is_valid).toBe(false);
493
+ // The v1 schema reports errors per missing required field; we just
494
+ // assert at least one MANIFEST_SCHEMA_ERROR fires for any of the
495
+ // newly-required fields. The legacy assertion looking for "created_at"
496
+ // in the message specifically is no longer meaningful — the validator
497
+ // surfaces the first missing field it finds, which under the v1
498
+ // schema may be `bundle_id`, `assistant`, `origin`, etc.
575
499
  const error = result.errors.find((e) => e.code === "MANIFEST_SCHEMA_ERROR");
576
500
  expect(error).toBeDefined();
577
- expect(error!.message).toContain("created_at");
578
501
  });
579
502
 
580
503
  test("missing files array produces MANIFEST_SCHEMA_ERROR", () => {
581
504
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
582
505
  const manifestObj = {
583
- schema_version: "1.0",
506
+ schema_version: 1,
584
507
  created_at: new Date().toISOString(),
585
508
  // files intentionally omitted
586
509
  manifest_sha256: "placeholder",
@@ -600,7 +523,7 @@ describe("missing or malformed version fields", () => {
600
523
  test("missing manifest_sha256 produces MANIFEST_SCHEMA_ERROR", () => {
601
524
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
602
525
  const manifestObj = {
603
- schema_version: "1.0",
526
+ schema_version: 1,
604
527
  created_at: new Date().toISOString(),
605
528
  files: [
606
529
  {
@@ -626,7 +549,7 @@ describe("missing or malformed version fields", () => {
626
549
  test("file entry missing sha256 produces MANIFEST_SCHEMA_ERROR", () => {
627
550
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
628
551
  const manifestObj = {
629
- schema_version: "1.0",
552
+ schema_version: 1,
630
553
  created_at: new Date().toISOString(),
631
554
  files: [
632
555
  {
@@ -652,7 +575,7 @@ describe("missing or malformed version fields", () => {
652
575
  test("file entry with negative size produces MANIFEST_SCHEMA_ERROR", () => {
653
576
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
654
577
  const manifestObj = {
655
- schema_version: "1.0",
578
+ schema_version: 1,
656
579
  created_at: new Date().toISOString(),
657
580
  files: [
658
581
  {
@@ -744,7 +667,10 @@ describe("round-trip: export -> validate -> preflight -> import", () => {
744
667
  body: toArrayBuffer(archiveData),
745
668
  },
746
669
  );
747
- const preflightRes = await callHandler(handleMigrationImportPreflight, preflightReq);
670
+ const preflightRes = await callHandler(
671
+ handleMigrationImportPreflight,
672
+ preflightReq,
673
+ );
748
674
  const preflightBody = (await preflightRes.json()) as ImportDryRunResponse;
749
675
 
750
676
  expect(preflightRes.status).toBe(200);
@@ -793,20 +719,16 @@ describe("round-trip: export -> validate -> preflight -> import", () => {
793
719
  { path: "data/db/assistant.db", data: dbData },
794
720
  { path: "config/settings.json", data: configData },
795
721
  ],
796
- schemaVersion: "1.0",
797
- source: "round-trip-test",
798
- description: "Testing round-trip",
722
+ ...defaultV1Options(),
799
723
  });
800
724
 
801
- expect(manifest.schema_version).toBe("1.0");
802
- expect(manifest.files).toHaveLength(2);
725
+ expect(manifest.schema_version).toBe(1);
726
+ expect(manifest.contents).toHaveLength(2);
803
727
 
804
728
  // Step 2: Validate
805
729
  const validationResult = validateVBundle(archive);
806
730
  expect(validationResult.is_valid).toBe(true);
807
- expect(validationResult.manifest?.manifest_sha256).toBe(
808
- manifest.manifest_sha256,
809
- );
731
+ expect(validationResult.manifest?.checksum).toBe(manifest.checksum);
810
732
 
811
733
  // Step 3: Analyze (preflight)
812
734
  const resolver = new DefaultPathResolver(testDir);
@@ -827,7 +749,7 @@ describe("round-trip: export -> validate -> preflight -> import", () => {
827
749
  expect(commitResult.ok).toBe(true);
828
750
  if (commitResult.ok) {
829
751
  expect(commitResult.report.success).toBe(true);
830
- expect(commitResult.report.manifest.schema_version).toBe("1.0");
752
+ expect(commitResult.report.manifest.schema_version).toBe(1);
831
753
  expect(commitResult.report.summary.total_files).toBe(2);
832
754
 
833
755
  // Verify data on disk matches what we built
@@ -848,14 +770,15 @@ describe("round-trip: export -> validate -> preflight -> import", () => {
848
770
  const exportRes = await callHandler(handleMigrationExport, exportReq);
849
771
  const archiveData = new Uint8Array(await exportRes.arrayBuffer());
850
772
 
851
- // The X-Vbundle-Manifest-Sha256 response header should match
852
- // the manifest_sha256 inside the archive
773
+ // The X-Vbundle-Manifest-Sha256 response header value should match
774
+ // the manifest's `checksum` field inside the archive (the legacy
775
+ // header name is preserved across the v1 rename).
853
776
  const headerSha = exportRes.headers.get("X-Vbundle-Manifest-Sha256");
854
777
  expect(headerSha).toBeDefined();
855
778
 
856
779
  const validationResult = validateVBundle(archiveData);
857
780
  expect(validationResult.is_valid).toBe(true);
858
- expect(validationResult.manifest?.manifest_sha256).toBe(headerSha!);
781
+ expect(validationResult.manifest?.checksum).toBe(headerSha!);
859
782
  });
860
783
  });
861
784
 
@@ -967,7 +890,7 @@ describe("partial failure scenarios", () => {
967
890
  // Create bundle with corrupted checksum
968
891
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
969
892
  const manifest = {
970
- schema_version: "1.0",
893
+ schema_version: 1,
971
894
  created_at: new Date().toISOString(),
972
895
  files: [
973
896
  {
@@ -1015,7 +938,7 @@ describe("edge cases", () => {
1015
938
 
1016
939
  const result = validateVBundle(vbundle);
1017
940
  expect(result.is_valid).toBe(true);
1018
- expect(result.manifest?.files[0].size).toBe(0);
941
+ expect(result.manifest?.contents[0].size_bytes).toBe(0);
1019
942
 
1020
943
  // Import should also succeed
1021
944
  const resolver = new DefaultPathResolver(testDir);
@@ -1042,7 +965,7 @@ describe("edge cases", () => {
1042
965
 
1043
966
  const result = validateVBundle(vbundle);
1044
967
  expect(result.is_valid).toBe(true);
1045
- expect(result.manifest?.files[0].size).toBe(100 * 1024);
968
+ expect(result.manifest?.contents[0].size_bytes).toBe(100 * 1024);
1046
969
  });
1047
970
 
1048
971
  test("bundle with duplicate archive paths uses last occurrence in tar", () => {
@@ -1051,26 +974,17 @@ describe("edge cases", () => {
1051
974
  const dbData1 = new Uint8Array([0x01, 0x02, 0x03]);
1052
975
  const dbData2 = new Uint8Array([0x04, 0x05, 0x06]);
1053
976
 
1054
- // Build a valid manifest that references the second data
1055
- const fileEntries = [
1056
- {
1057
- path: "data/db/assistant.db",
1058
- sha256: sha256Hex(dbData2),
1059
- size: dbData2.length,
1060
- },
1061
- ];
1062
- const manifestWithoutChecksum = {
1063
- schema_version: "1.0",
1064
- created_at: new Date().toISOString(),
1065
- source: "test",
1066
- description: "Duplicate path test",
1067
- files: fileEntries,
1068
- };
1069
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1070
- const manifest = {
1071
- ...manifestWithoutChecksum,
1072
- manifest_sha256: manifestSha256,
1073
- };
977
+ // Build a valid v1 manifest that references the second data.
978
+ const manifest = buildTestManifest({
979
+ contents: [
980
+ {
981
+ path: "data/db/assistant.db",
982
+ sha256: sha256Hex(dbData2),
983
+ size_bytes: dbData2.length,
984
+ },
985
+ ],
986
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
987
+ });
1074
988
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1075
989
 
1076
990
  // Build tar with duplicate data/db/assistant.db entries
@@ -1093,22 +1007,16 @@ describe("edge cases", () => {
1093
1007
  const wrongChecksum =
1094
1008
  "0000000000000000000000000000000000000000000000000000000000000000";
1095
1009
 
1096
- const manifestWithoutChecksum = {
1097
- schema_version: "1.0",
1098
- created_at: new Date().toISOString(),
1099
- files: [
1010
+ const manifest = buildTestManifest({
1011
+ contents: [
1100
1012
  {
1101
1013
  path: "data/db/assistant.db",
1102
1014
  sha256: wrongChecksum,
1103
- size: dbData.length,
1015
+ size_bytes: dbData.length,
1104
1016
  },
1105
1017
  ],
1106
- };
1107
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1108
- const manifest = {
1109
- ...manifestWithoutChecksum,
1110
- manifest_sha256: manifestSha256,
1111
- };
1018
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
1019
+ });
1112
1020
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1113
1021
 
1114
1022
  const tar = createTarArchive([
@@ -1132,27 +1040,21 @@ describe("edge cases", () => {
1132
1040
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
1133
1041
  const ghostSha = sha256Hex(new TextEncoder().encode("ghost-content"));
1134
1042
 
1135
- const manifestWithoutChecksum = {
1136
- schema_version: "1.0",
1137
- created_at: new Date().toISOString(),
1138
- files: [
1043
+ const manifest = buildTestManifest({
1044
+ contents: [
1139
1045
  {
1140
1046
  path: "data/db/assistant.db",
1141
1047
  sha256: sha256Hex(dbData),
1142
- size: dbData.length,
1048
+ size_bytes: dbData.length,
1143
1049
  },
1144
1050
  {
1145
1051
  path: "data/extra/ghost.bin",
1146
1052
  sha256: ghostSha,
1147
- size: 13,
1053
+ size_bytes: 13,
1148
1054
  },
1149
1055
  ],
1150
- };
1151
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1152
- const manifest = {
1153
- ...manifestWithoutChecksum,
1154
- manifest_sha256: manifestSha256,
1155
- };
1056
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
1057
+ });
1156
1058
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1157
1059
 
1158
1060
  const tar = createTarArchive([
@@ -1172,20 +1074,16 @@ describe("edge cases", () => {
1172
1074
  expect(missingError!.message).toContain("data/extra/ghost.bin");
1173
1075
  });
1174
1076
 
1175
- test("bundle with only manifest (no data files) is valid", () => {
1176
- // After the workspace walk refactor, only manifest.json is required.
1177
- // A bundle with no data files is structurally valid — it just won't
1178
- // restore anything meaningful.
1179
- const manifestWithoutChecksum = {
1180
- schema_version: "1.0",
1181
- created_at: new Date().toISOString(),
1182
- files: [],
1183
- };
1184
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1185
- const manifest = {
1186
- ...manifestWithoutChecksum,
1187
- manifest_sha256: manifestSha256,
1188
- };
1077
+ test("bundle with empty contents is rejected by the v1 contents refine", () => {
1078
+ // The v1 schema's `.refine()` requires `data/db/assistant.db` (legacy)
1079
+ // or its `workspace/`-prefixed counterpart. A manifest declaring an
1080
+ // empty contents array is valid at the field level but rejected by
1081
+ // the refine.
1082
+ const dbBytes = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
1083
+ const manifest = buildTestManifest({
1084
+ contents: [],
1085
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
1086
+ });
1189
1087
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1190
1088
 
1191
1089
  const tar = createTarArchive([
@@ -1194,7 +1092,9 @@ describe("edge cases", () => {
1194
1092
  const vbundle = gzipSync(tar);
1195
1093
  const result = validateVBundle(vbundle);
1196
1094
 
1197
- expect(result.is_valid).toBe(true);
1095
+ expect(result.is_valid).toBe(false);
1096
+ // Sanity: this manifest WOULD be valid if it included the DB entry.
1097
+ expect(dbBytes).toBeDefined();
1198
1098
  });
1199
1099
 
1200
1100
  test("completely empty gzip content (no tar entries) fails gracefully", () => {
@@ -1244,24 +1144,16 @@ describe("edge cases", () => {
1244
1144
  const extraData = new TextEncoder().encode("bonus content");
1245
1145
 
1246
1146
  // Manifest only declares the db file
1247
- const fileEntries = [
1248
- {
1249
- path: "data/db/assistant.db",
1250
- sha256: sha256Hex(dbData),
1251
- size: dbData.length,
1252
- },
1253
- ];
1254
- const manifestWithoutChecksum = {
1255
- schema_version: "1.0",
1256
- created_at: new Date().toISOString(),
1257
- source: "test",
1258
- files: fileEntries,
1259
- };
1260
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1261
- const manifest = {
1262
- ...manifestWithoutChecksum,
1263
- manifest_sha256: manifestSha256,
1264
- };
1147
+ const manifest = buildTestManifest({
1148
+ contents: [
1149
+ {
1150
+ path: "data/db/assistant.db",
1151
+ sha256: sha256Hex(dbData),
1152
+ size_bytes: dbData.length,
1153
+ },
1154
+ ],
1155
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
1156
+ });
1265
1157
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1266
1158
 
1267
1159
  // Archive has an extra file not in the manifest
@@ -1310,16 +1202,29 @@ describe("diagnostic quality", () => {
1310
1202
  const badHash =
1311
1203
  "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
1312
1204
  const manifest = {
1313
- schema_version: "1.0",
1205
+ schema_version: 1,
1206
+ bundle_id: "00000000-0000-4000-8000-000000000000",
1314
1207
  created_at: new Date().toISOString(),
1315
- files: [
1208
+ assistant: { id: "self", name: "Test", runtime_version: "0.0.0-test" },
1209
+ origin: { mode: "self-hosted-local" as const },
1210
+ compatibility: {
1211
+ min_runtime_version: "0.0.0-test",
1212
+ max_runtime_version: null,
1213
+ },
1214
+ contents: [
1316
1215
  {
1317
1216
  path: "data/db/assistant.db",
1318
1217
  sha256: sha256Hex(dbData),
1319
- size: dbData.length,
1218
+ size_bytes: dbData.length,
1320
1219
  },
1321
1220
  ],
1322
- manifest_sha256: badHash,
1221
+ checksum: badHash,
1222
+ secrets_redacted: false,
1223
+ export_options: {
1224
+ include_logs: false,
1225
+ include_browser_state: false,
1226
+ include_memory_vectors: false,
1227
+ },
1323
1228
  };
1324
1229
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1325
1230
  const tar = createTarArchive([
@@ -1342,22 +1247,16 @@ describe("diagnostic quality", () => {
1342
1247
  const wrongSha =
1343
1248
  "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
1344
1249
 
1345
- const manifestWithoutChecksum = {
1346
- schema_version: "1.0",
1347
- created_at: new Date().toISOString(),
1348
- files: [
1250
+ const manifest = buildTestManifest({
1251
+ contents: [
1349
1252
  {
1350
1253
  path: "data/db/assistant.db",
1351
1254
  sha256: wrongSha,
1352
- size: dbData.length,
1255
+ size_bytes: dbData.length,
1353
1256
  },
1354
1257
  ],
1355
- };
1356
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1357
- const manifest = {
1358
- ...manifestWithoutChecksum,
1359
- manifest_sha256: manifestSha256,
1360
- };
1258
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
1259
+ });
1361
1260
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1362
1261
  const tar = createTarArchive([
1363
1262
  { name: "manifest.json", data: manifestData },
@@ -1376,22 +1275,16 @@ describe("diagnostic quality", () => {
1376
1275
  test("FILE_SIZE_MISMATCH includes file path and both sizes", () => {
1377
1276
  const dbData = new Uint8Array([0x53, 0x51, 0x4c, 0x69, 0x74, 0x65]);
1378
1277
 
1379
- const manifestWithoutChecksum = {
1380
- schema_version: "1.0",
1381
- created_at: new Date().toISOString(),
1382
- files: [
1278
+ const manifest = buildTestManifest({
1279
+ contents: [
1383
1280
  {
1384
1281
  path: "data/db/assistant.db",
1385
1282
  sha256: sha256Hex(dbData),
1386
- size: 99999,
1283
+ size_bytes: 99999,
1387
1284
  },
1388
1285
  ],
1389
- };
1390
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1391
- const manifest = {
1392
- ...manifestWithoutChecksum,
1393
- manifest_sha256: manifestSha256,
1394
- };
1286
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
1287
+ });
1395
1288
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1396
1289
  const tar = createTarArchive([
1397
1290
  { name: "manifest.json", data: manifestData },
@@ -1461,27 +1354,21 @@ describe("multiple error accumulation", () => {
1461
1354
 
1462
1355
  // Manifest declares correct db checksum but wrong config checksum and
1463
1356
  // also wrong config size
1464
- const manifestWithoutChecksum = {
1465
- schema_version: "1.0",
1466
- created_at: new Date().toISOString(),
1467
- files: [
1357
+ const manifest = buildTestManifest({
1358
+ contents: [
1468
1359
  {
1469
1360
  path: "data/db/assistant.db",
1470
1361
  sha256: sha256Hex(dbData),
1471
- size: dbData.length,
1362
+ size_bytes: dbData.length,
1472
1363
  },
1473
1364
  {
1474
1365
  path: "config/settings.json",
1475
1366
  sha256: wrongSha,
1476
- size: 999,
1367
+ size_bytes: 999,
1477
1368
  },
1478
1369
  ],
1479
- };
1480
- const manifestSha256 = sha256Hex(canonicalizeJson(manifestWithoutChecksum));
1481
- const manifest = {
1482
- ...manifestWithoutChecksum,
1483
- manifest_sha256: manifestSha256,
1484
- };
1370
+ overrides: { bundle_id: "00000000-0000-4000-8000-000000000000" },
1371
+ });
1485
1372
  const manifestData = new TextEncoder().encode(JSON.stringify(manifest));
1486
1373
 
1487
1374
  const tar = createTarArchive([
@@ -1535,8 +1422,8 @@ describe("multiple error accumulation", () => {
1535
1422
  // ═══════════════════════════════════════════════════════════════════════════
1536
1423
 
1537
1424
  describe("builder -> validator consistency", () => {
1538
- test("buildVBundle always produces archives that pass validation", () => {
1539
- const testCases = [
1425
+ test("buildVBundle archives across content shapes pass validation", () => {
1426
+ const testCases: Array<{ files: VBundleFile[] }> = [
1540
1427
  {
1541
1428
  files: [
1542
1429
  {
@@ -1544,7 +1431,6 @@ describe("builder -> validator consistency", () => {
1544
1431
  data: new Uint8Array([0x01]),
1545
1432
  },
1546
1433
  ],
1547
- schemaVersion: "1.0",
1548
1434
  },
1549
1435
  {
1550
1436
  files: [
@@ -1557,7 +1443,6 @@ describe("builder -> validator consistency", () => {
1557
1443
  data: new TextEncoder().encode('{"big":"config","keys":[1,2,3]}'),
1558
1444
  },
1559
1445
  ],
1560
- schemaVersion: "2.0",
1561
1446
  },
1562
1447
  {
1563
1448
  files: [
@@ -1566,23 +1451,22 @@ describe("builder -> validator consistency", () => {
1566
1451
  data: new Uint8Array(0), // empty
1567
1452
  },
1568
1453
  ],
1569
- schemaVersion: "0.1-alpha",
1570
1454
  },
1571
1455
  ];
1572
1456
 
1573
1457
  for (const tc of testCases) {
1574
1458
  const { archive } = buildVBundle({
1575
1459
  files: tc.files,
1576
- schemaVersion: tc.schemaVersion,
1460
+ ...defaultV1Options(),
1577
1461
  });
1578
1462
 
1579
1463
  const result = validateVBundle(archive);
1580
1464
  expect(result.is_valid).toBe(true);
1581
- expect(result.manifest?.schema_version).toBe(tc.schemaVersion);
1465
+ expect(result.manifest?.schema_version).toBe(1);
1582
1466
  }
1583
1467
  });
1584
1468
 
1585
- test("builder output manifest_sha256 matches validator computation", () => {
1469
+ test("builder output checksum matches validator computation", () => {
1586
1470
  const { archive, manifest } = buildVBundle({
1587
1471
  files: [
1588
1472
  {
@@ -1590,24 +1474,27 @@ describe("builder -> validator consistency", () => {
1590
1474
  data: new Uint8Array([0xca, 0xfe]),
1591
1475
  },
1592
1476
  ],
1593
- schemaVersion: "1.0",
1477
+ ...defaultV1Options(),
1594
1478
  });
1595
1479
 
1596
1480
  const result = validateVBundle(archive);
1597
1481
  expect(result.is_valid).toBe(true);
1598
- expect(result.manifest?.manifest_sha256).toBe(manifest.manifest_sha256);
1482
+ expect(result.manifest?.checksum).toBe(manifest.checksum);
1599
1483
  });
1600
1484
 
1601
1485
  test("builder output file checksums match validator computation", () => {
1602
1486
  const fileData = new Uint8Array([0xde, 0xad, 0xbe, 0xef]);
1603
1487
  const { archive, manifest } = buildVBundle({
1604
1488
  files: [{ path: "data/db/assistant.db", data: fileData }],
1489
+ ...defaultV1Options(),
1605
1490
  });
1606
1491
 
1607
1492
  const result = validateVBundle(archive);
1608
1493
  expect(result.is_valid).toBe(true);
1609
- expect(result.manifest?.files[0].sha256).toBe(manifest.files[0].sha256);
1610
- expect(result.manifest?.files[0].sha256).toBe(sha256Hex(fileData));
1494
+ expect(result.manifest?.contents[0].sha256).toBe(
1495
+ manifest.contents[0].sha256,
1496
+ );
1497
+ expect(result.manifest?.contents[0].sha256).toBe(sha256Hex(fileData));
1611
1498
  });
1612
1499
  });
1613
1500
 
@@ -1622,21 +1509,34 @@ describe("import analyzer edge cases", () => {
1622
1509
 
1623
1510
  const report = analyzeImport({
1624
1511
  manifest: {
1625
- schema_version: "1.0",
1626
- created_at: new Date().toISOString(),
1627
- files: [
1512
+ schema_version: 1,
1513
+ bundle_id: "00000000-0000-4000-8000-000000000000",
1514
+ created_at: "2026-03-01T00:00:00Z",
1515
+ assistant: { id: "self", name: "Test", runtime_version: "0.0.0-test" },
1516
+ origin: { mode: "self-hosted-local" },
1517
+ compatibility: {
1518
+ min_runtime_version: "0.0.0-test",
1519
+ max_runtime_version: null,
1520
+ },
1521
+ contents: [
1628
1522
  {
1629
1523
  path: "data/db/assistant.db",
1630
1524
  sha256: sha256Hex(EXISTING_DB_DATA),
1631
- size: EXISTING_DB_DATA.length,
1525
+ size_bytes: EXISTING_DB_DATA.length,
1632
1526
  },
1633
1527
  {
1634
1528
  path: "config/settings.json",
1635
1529
  sha256: sha256Hex(existingConfig),
1636
- size: existingConfig.length,
1530
+ size_bytes: existingConfig.length,
1637
1531
  },
1638
1532
  ],
1639
- manifest_sha256: "test",
1533
+ checksum: "test",
1534
+ secrets_redacted: false,
1535
+ export_options: {
1536
+ include_logs: false,
1537
+ include_browser_state: false,
1538
+ include_memory_vectors: false,
1539
+ },
1640
1540
  },
1641
1541
  pathResolver: resolver,
1642
1542
  });
@@ -1654,23 +1554,24 @@ describe("import analyzer edge cases", () => {
1654
1554
  );
1655
1555
 
1656
1556
  const report = analyzeImport({
1657
- manifest: {
1658
- schema_version: "1.0",
1659
- created_at: new Date().toISOString(),
1660
- files: [
1557
+ manifest: buildTestManifest({
1558
+ contents: [
1661
1559
  {
1662
1560
  path: "data/db/assistant.db",
1663
1561
  sha256: sha256Hex(new Uint8Array([1])),
1664
- size: 1,
1562
+ size_bytes: 1,
1665
1563
  },
1666
1564
  {
1667
1565
  path: "config/settings.json",
1668
1566
  sha256: sha256Hex(new Uint8Array([2])),
1669
- size: 1,
1567
+ size_bytes: 1,
1670
1568
  },
1671
1569
  ],
1672
- manifest_sha256: "test",
1673
- },
1570
+ overrides: {
1571
+ bundle_id: "00000000-0000-4000-8000-000000000000",
1572
+ created_at: "2026-03-01T00:00:00Z",
1573
+ },
1574
+ }),
1674
1575
  pathResolver: resolver,
1675
1576
  });
1676
1577
 
@@ -1688,23 +1589,24 @@ describe("import analyzer edge cases", () => {
1688
1589
  const existingConfig = new Uint8Array(readFileSync(testConfigPath));
1689
1590
 
1690
1591
  const report = analyzeImport({
1691
- manifest: {
1692
- schema_version: "1.0",
1693
- created_at: new Date().toISOString(),
1694
- files: [
1592
+ manifest: buildTestManifest({
1593
+ contents: [
1695
1594
  {
1696
1595
  path: "data/db/assistant.db",
1697
1596
  sha256: sha256Hex(new Uint8Array([0xff])),
1698
- size: 1,
1597
+ size_bytes: 1,
1699
1598
  },
1700
1599
  {
1701
1600
  path: "config/settings.json",
1702
1601
  sha256: sha256Hex(existingConfig),
1703
- size: existingConfig.length,
1602
+ size_bytes: existingConfig.length,
1704
1603
  },
1705
1604
  ],
1706
- manifest_sha256: "test",
1707
- },
1605
+ overrides: {
1606
+ bundle_id: "00000000-0000-4000-8000-000000000000",
1607
+ created_at: "2026-03-01T00:00:00Z",
1608
+ },
1609
+ }),
1708
1610
  pathResolver: resolver,
1709
1611
  });
1710
1612
 
@@ -1717,23 +1619,24 @@ describe("import analyzer edge cases", () => {
1717
1619
  const resolver = new DefaultPathResolver(testDir);
1718
1620
 
1719
1621
  const report = analyzeImport({
1720
- manifest: {
1721
- schema_version: "1.0",
1722
- created_at: new Date().toISOString(),
1723
- files: [
1622
+ manifest: buildTestManifest({
1623
+ contents: [
1724
1624
  {
1725
1625
  path: "data/db/assistant.db",
1726
1626
  sha256: sha256Hex(EXISTING_DB_DATA),
1727
- size: EXISTING_DB_DATA.length,
1627
+ size_bytes: EXISTING_DB_DATA.length,
1728
1628
  },
1729
1629
  {
1730
1630
  path: "future/unknown-file.dat",
1731
1631
  sha256: sha256Hex(new Uint8Array([0])),
1732
- size: 1,
1632
+ size_bytes: 1,
1733
1633
  },
1734
1634
  ],
1735
- manifest_sha256: "test",
1736
- },
1635
+ overrides: {
1636
+ bundle_id: "00000000-0000-4000-8000-000000000000",
1637
+ created_at: "2026-03-01T00:00:00Z",
1638
+ },
1639
+ }),
1737
1640
  pathResolver: resolver,
1738
1641
  });
1739
1642
 
@@ -1792,7 +1695,10 @@ describe("HTTP endpoint error consistency", () => {
1792
1695
  body: toArrayBuffer(invalidData),
1793
1696
  },
1794
1697
  );
1795
- const preflightRes = await callHandler(handleMigrationImportPreflight, preflightReq);
1698
+ const preflightRes = await callHandler(
1699
+ handleMigrationImportPreflight,
1700
+ preflightReq,
1701
+ );
1796
1702
  const preflightBody = (await preflightRes.json()) as ImportDryRunResponse;
1797
1703
 
1798
1704
  expect(validateBody.is_valid).toBe(false);