llmtxt 2026.4.5 → 2026.4.7

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 (287) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +242 -54
  3. package/dist/__tests__/a2a.test.d.ts +14 -0
  4. package/dist/__tests__/a2a.test.d.ts.map +1 -0
  5. package/dist/__tests__/a2a.test.js +217 -0
  6. package/dist/__tests__/a2a.test.js.map +1 -0
  7. package/dist/__tests__/backend-contract.test.d.ts +18 -7
  8. package/dist/__tests__/backend-contract.test.d.ts.map +1 -1
  9. package/dist/__tests__/backend-contract.test.js +634 -29
  10. package/dist/__tests__/backend-contract.test.js.map +1 -1
  11. package/dist/__tests__/backend-factory.test.d.ts +18 -0
  12. package/dist/__tests__/backend-factory.test.d.ts.map +1 -0
  13. package/dist/__tests__/backend-factory.test.js +254 -0
  14. package/dist/__tests__/backend-factory.test.js.map +1 -0
  15. package/dist/__tests__/blob-5-agent-hub-spoke.test.d.ts +26 -0
  16. package/dist/__tests__/blob-5-agent-hub-spoke.test.d.ts.map +1 -0
  17. package/dist/__tests__/blob-5-agent-hub-spoke.test.js +262 -0
  18. package/dist/__tests__/blob-5-agent-hub-spoke.test.js.map +1 -0
  19. package/dist/__tests__/blob-backend.test.d.ts +16 -0
  20. package/dist/__tests__/blob-backend.test.d.ts.map +1 -0
  21. package/dist/__tests__/blob-backend.test.js +271 -0
  22. package/dist/__tests__/blob-backend.test.js.map +1 -0
  23. package/dist/__tests__/blob-changeset.test.d.ts +10 -0
  24. package/dist/__tests__/blob-changeset.test.d.ts.map +1 -0
  25. package/dist/__tests__/blob-changeset.test.js +286 -0
  26. package/dist/__tests__/blob-changeset.test.js.map +1 -0
  27. package/dist/__tests__/blob-cli.test.d.ts +20 -0
  28. package/dist/__tests__/blob-cli.test.d.ts.map +1 -0
  29. package/dist/__tests__/blob-cli.test.js +178 -0
  30. package/dist/__tests__/blob-cli.test.js.map +1 -0
  31. package/dist/__tests__/blob-fs-adapter.test.d.ts +16 -0
  32. package/dist/__tests__/blob-fs-adapter.test.d.ts.map +1 -0
  33. package/dist/__tests__/blob-fs-adapter.test.js +385 -0
  34. package/dist/__tests__/blob-fs-adapter.test.js.map +1 -0
  35. package/dist/__tests__/crdt-primitives.test.d.ts +20 -0
  36. package/dist/__tests__/crdt-primitives.test.d.ts.map +1 -0
  37. package/dist/__tests__/crdt-primitives.test.js +255 -0
  38. package/dist/__tests__/crdt-primitives.test.js.map +1 -0
  39. package/dist/__tests__/crdt-sdk.test.d.ts +30 -0
  40. package/dist/__tests__/crdt-sdk.test.d.ts.map +1 -0
  41. package/dist/__tests__/crdt-sdk.test.js +380 -0
  42. package/dist/__tests__/crdt-sdk.test.js.map +1 -0
  43. package/dist/__tests__/crsqlite-loader.test.d.ts +15 -0
  44. package/dist/__tests__/crsqlite-loader.test.d.ts.map +1 -0
  45. package/dist/__tests__/crsqlite-loader.test.js +116 -0
  46. package/dist/__tests__/crsqlite-loader.test.js.map +1 -0
  47. package/dist/__tests__/discovery.test.d.ts +15 -0
  48. package/dist/__tests__/discovery.test.d.ts.map +1 -0
  49. package/dist/__tests__/discovery.test.js +174 -0
  50. package/dist/__tests__/discovery.test.js.map +1 -0
  51. package/dist/__tests__/export-backend.test.d.ts +15 -0
  52. package/dist/__tests__/export-backend.test.d.ts.map +1 -0
  53. package/dist/__tests__/export-backend.test.js +316 -0
  54. package/dist/__tests__/export-backend.test.js.map +1 -0
  55. package/dist/__tests__/export-determinism.test.d.ts +19 -0
  56. package/dist/__tests__/export-determinism.test.d.ts.map +1 -0
  57. package/dist/__tests__/export-determinism.test.js +253 -0
  58. package/dist/__tests__/export-determinism.test.js.map +1 -0
  59. package/dist/__tests__/export.test.d.ts +11 -0
  60. package/dist/__tests__/export.test.d.ts.map +1 -0
  61. package/dist/__tests__/export.test.js +297 -0
  62. package/dist/__tests__/export.test.js.map +1 -0
  63. package/dist/__tests__/helpers/test-pg.d.ts +150 -0
  64. package/dist/__tests__/helpers/test-pg.d.ts.map +1 -0
  65. package/dist/__tests__/helpers/test-pg.js +836 -0
  66. package/dist/__tests__/helpers/test-pg.js.map +1 -0
  67. package/dist/__tests__/hub-spoke-topology.test.d.ts +24 -0
  68. package/dist/__tests__/hub-spoke-topology.test.d.ts.map +1 -0
  69. package/dist/__tests__/hub-spoke-topology.test.js +299 -0
  70. package/dist/__tests__/hub-spoke-topology.test.js.map +1 -0
  71. package/dist/__tests__/local-backend-crr.test.d.ts +25 -0
  72. package/dist/__tests__/local-backend-crr.test.d.ts.map +1 -0
  73. package/dist/__tests__/local-backend-crr.test.js +197 -0
  74. package/dist/__tests__/local-backend-crr.test.js.map +1 -0
  75. package/dist/__tests__/local-backend-sync.test.d.ts +20 -0
  76. package/dist/__tests__/local-backend-sync.test.d.ts.map +1 -0
  77. package/dist/__tests__/local-backend-sync.test.js +373 -0
  78. package/dist/__tests__/local-backend-sync.test.js.map +1 -0
  79. package/dist/__tests__/local-multi-agent.test.d.ts +20 -0
  80. package/dist/__tests__/local-multi-agent.test.d.ts.map +1 -0
  81. package/dist/__tests__/local-multi-agent.test.js +229 -0
  82. package/dist/__tests__/local-multi-agent.test.js.map +1 -0
  83. package/dist/__tests__/loro-crsqlite-integration.test.d.ts +32 -0
  84. package/dist/__tests__/loro-crsqlite-integration.test.d.ts.map +1 -0
  85. package/dist/__tests__/loro-crsqlite-integration.test.js +340 -0
  86. package/dist/__tests__/loro-crsqlite-integration.test.js.map +1 -0
  87. package/dist/__tests__/mesh-5-peer.test.d.ts +35 -0
  88. package/dist/__tests__/mesh-5-peer.test.d.ts.map +1 -0
  89. package/dist/__tests__/mesh-5-peer.test.js +435 -0
  90. package/dist/__tests__/mesh-5-peer.test.js.map +1 -0
  91. package/dist/__tests__/mesh-cli.test.d.ts +18 -0
  92. package/dist/__tests__/mesh-cli.test.d.ts.map +1 -0
  93. package/dist/__tests__/mesh-cli.test.js +143 -0
  94. package/dist/__tests__/mesh-cli.test.js.map +1 -0
  95. package/dist/__tests__/presence.test.d.ts +13 -0
  96. package/dist/__tests__/presence.test.d.ts.map +1 -0
  97. package/dist/__tests__/presence.test.js +198 -0
  98. package/dist/__tests__/presence.test.js.map +1 -0
  99. package/dist/__tests__/session-crash-recovery.test.d.ts +28 -0
  100. package/dist/__tests__/session-crash-recovery.test.d.ts.map +1 -0
  101. package/dist/__tests__/session-crash-recovery.test.js +689 -0
  102. package/dist/__tests__/session-crash-recovery.test.js.map +1 -0
  103. package/dist/__tests__/session-swarm.test.d.ts +35 -0
  104. package/dist/__tests__/session-swarm.test.d.ts.map +1 -0
  105. package/dist/__tests__/session-swarm.test.js +734 -0
  106. package/dist/__tests__/session-swarm.test.js.map +1 -0
  107. package/dist/__tests__/session.test.d.ts +13 -0
  108. package/dist/__tests__/session.test.d.ts.map +1 -0
  109. package/dist/__tests__/session.test.js +1187 -0
  110. package/dist/__tests__/session.test.js.map +1 -0
  111. package/dist/__tests__/standalone-topology.test.d.ts +18 -0
  112. package/dist/__tests__/standalone-topology.test.d.ts.map +1 -0
  113. package/dist/__tests__/standalone-topology.test.js +297 -0
  114. package/dist/__tests__/standalone-topology.test.js.map +1 -0
  115. package/dist/__tests__/sync-engine.test.d.ts +15 -0
  116. package/dist/__tests__/sync-engine.test.d.ts.map +1 -0
  117. package/dist/__tests__/sync-engine.test.js +286 -0
  118. package/dist/__tests__/sync-engine.test.js.map +1 -0
  119. package/dist/__tests__/topology-failure.test.d.ts +23 -0
  120. package/dist/__tests__/topology-failure.test.d.ts.map +1 -0
  121. package/dist/__tests__/topology-failure.test.js +357 -0
  122. package/dist/__tests__/topology-failure.test.js.map +1 -0
  123. package/dist/__tests__/topology.test.d.ts +17 -0
  124. package/dist/__tests__/topology.test.d.ts.map +1 -0
  125. package/dist/__tests__/topology.test.js +346 -0
  126. package/dist/__tests__/topology.test.js.map +1 -0
  127. package/dist/__tests__/transport.test.d.ts +18 -0
  128. package/dist/__tests__/transport.test.d.ts.map +1 -0
  129. package/dist/__tests__/transport.test.js +305 -0
  130. package/dist/__tests__/transport.test.js.map +1 -0
  131. package/dist/backend/factory.d.ts +379 -0
  132. package/dist/backend/factory.d.ts.map +1 -0
  133. package/dist/backend/factory.js +824 -0
  134. package/dist/backend/factory.js.map +1 -0
  135. package/dist/cli/llmtxt.js +1232 -8
  136. package/dist/cli/llmtxt.js.map +1 -1
  137. package/dist/compression.d.ts +1 -1
  138. package/dist/compression.d.ts.map +1 -1
  139. package/dist/compression.js +1 -1
  140. package/dist/compression.js.map +1 -1
  141. package/dist/core/backend.d.ts +678 -2
  142. package/dist/core/backend.d.ts.map +1 -1
  143. package/dist/core/backend.js +16 -1
  144. package/dist/core/backend.js.map +1 -1
  145. package/dist/core/errors.d.ts +59 -0
  146. package/dist/core/errors.d.ts.map +1 -0
  147. package/dist/core/errors.js +81 -0
  148. package/dist/core/errors.js.map +1 -0
  149. package/dist/crdt-primitives.d.ts +87 -45
  150. package/dist/crdt-primitives.d.ts.map +1 -1
  151. package/dist/crdt-primitives.js +140 -94
  152. package/dist/crdt-primitives.js.map +1 -1
  153. package/dist/crdt.d.ts +58 -13
  154. package/dist/crdt.d.ts.map +1 -1
  155. package/dist/crdt.js +140 -67
  156. package/dist/crdt.js.map +1 -1
  157. package/dist/crsqlite-loader.d.ts +35 -0
  158. package/dist/crsqlite-loader.d.ts.map +1 -0
  159. package/dist/crsqlite-loader.js +56 -0
  160. package/dist/crsqlite-loader.js.map +1 -0
  161. package/dist/embeddings.d.ts.map +1 -1
  162. package/dist/embeddings.js +9 -4
  163. package/dist/embeddings.js.map +1 -1
  164. package/dist/export/backend-export.d.ts +58 -0
  165. package/dist/export/backend-export.d.ts.map +1 -0
  166. package/dist/export/backend-export.js +193 -0
  167. package/dist/export/backend-export.js.map +1 -0
  168. package/dist/export/canonical.d.ts +69 -0
  169. package/dist/export/canonical.d.ts.map +1 -0
  170. package/dist/export/canonical.js +82 -0
  171. package/dist/export/canonical.js.map +1 -0
  172. package/dist/export/import-parser.d.ts +36 -0
  173. package/dist/export/import-parser.d.ts.map +1 -0
  174. package/dist/export/import-parser.js +209 -0
  175. package/dist/export/import-parser.js.map +1 -0
  176. package/dist/export/index.d.ts +17 -0
  177. package/dist/export/index.d.ts.map +1 -0
  178. package/dist/export/index.js +17 -0
  179. package/dist/export/index.js.map +1 -0
  180. package/dist/export/json.d.ts +52 -0
  181. package/dist/export/json.d.ts.map +1 -0
  182. package/dist/export/json.js +103 -0
  183. package/dist/export/json.js.map +1 -0
  184. package/dist/export/llmtxt.d.ts +56 -0
  185. package/dist/export/llmtxt.d.ts.map +1 -0
  186. package/dist/export/llmtxt.js +110 -0
  187. package/dist/export/llmtxt.js.map +1 -0
  188. package/dist/export/markdown.d.ts +36 -0
  189. package/dist/export/markdown.d.ts.map +1 -0
  190. package/dist/export/markdown.js +67 -0
  191. package/dist/export/markdown.js.map +1 -0
  192. package/dist/export/txt.d.ts +29 -0
  193. package/dist/export/txt.d.ts.map +1 -0
  194. package/dist/export/txt.js +33 -0
  195. package/dist/export/txt.js.map +1 -0
  196. package/dist/export/types.d.ts +76 -0
  197. package/dist/export/types.d.ts.map +1 -0
  198. package/dist/export/types.js +11 -0
  199. package/dist/export/types.js.map +1 -0
  200. package/dist/index.d.ts +7 -1
  201. package/dist/index.d.ts.map +1 -1
  202. package/dist/index.js +9 -1
  203. package/dist/index.js.map +1 -1
  204. package/dist/local/blob-changeset.d.ts +106 -0
  205. package/dist/local/blob-changeset.d.ts.map +1 -0
  206. package/dist/local/blob-changeset.js +169 -0
  207. package/dist/local/blob-changeset.js.map +1 -0
  208. package/dist/local/blob-fs-adapter.d.ts +86 -0
  209. package/dist/local/blob-fs-adapter.d.ts.map +1 -0
  210. package/dist/local/blob-fs-adapter.js +293 -0
  211. package/dist/local/blob-fs-adapter.js.map +1 -0
  212. package/dist/local/local-backend.d.ts +157 -2
  213. package/dist/local/local-backend.d.ts.map +1 -1
  214. package/dist/local/local-backend.js +829 -20
  215. package/dist/local/local-backend.js.map +1 -1
  216. package/dist/local/migrations/20260417220000_crdt_state_rename/migration.sql +15 -0
  217. package/dist/local/migrations/20260417220000_crdt_state_rename/snapshot.json +1594 -0
  218. package/dist/local/migrations/20260417230000_crsql_as_crr/migration.sql +45 -0
  219. package/dist/local/migrations/20260417230000_crsql_as_crr/snapshot.json +1593 -0
  220. package/dist/local/migrations/20260417240000_blob_attachments/migration.sql +54 -0
  221. package/dist/local/schema-local.d.ts +162 -1
  222. package/dist/local/schema-local.d.ts.map +1 -1
  223. package/dist/local/schema-local.js +44 -1
  224. package/dist/local/schema-local.js.map +1 -1
  225. package/dist/mesh/a2a.d.ts +93 -0
  226. package/dist/mesh/a2a.d.ts.map +1 -0
  227. package/dist/mesh/a2a.js +326 -0
  228. package/dist/mesh/a2a.js.map +1 -0
  229. package/dist/mesh/discovery.d.ts +134 -0
  230. package/dist/mesh/discovery.d.ts.map +1 -0
  231. package/dist/mesh/discovery.js +290 -0
  232. package/dist/mesh/discovery.js.map +1 -0
  233. package/dist/mesh/index.d.ts +16 -0
  234. package/dist/mesh/index.d.ts.map +1 -0
  235. package/dist/mesh/index.js +16 -0
  236. package/dist/mesh/index.js.map +1 -0
  237. package/dist/mesh/presence.d.ts +94 -0
  238. package/dist/mesh/presence.d.ts.map +1 -0
  239. package/dist/mesh/presence.js +219 -0
  240. package/dist/mesh/presence.js.map +1 -0
  241. package/dist/mesh/server-peer-adapter.d.ts +248 -0
  242. package/dist/mesh/server-peer-adapter.d.ts.map +1 -0
  243. package/dist/mesh/server-peer-adapter.js +269 -0
  244. package/dist/mesh/server-peer-adapter.js.map +1 -0
  245. package/dist/mesh/sync-engine.d.ts +116 -0
  246. package/dist/mesh/sync-engine.d.ts.map +1 -0
  247. package/dist/mesh/sync-engine.js +349 -0
  248. package/dist/mesh/sync-engine.js.map +1 -0
  249. package/dist/mesh/transport.d.ts +196 -0
  250. package/dist/mesh/transport.d.ts.map +1 -0
  251. package/dist/mesh/transport.js +795 -0
  252. package/dist/mesh/transport.js.map +1 -0
  253. package/dist/pg/index.d.ts +11 -0
  254. package/dist/pg/index.d.ts.map +1 -0
  255. package/dist/pg/index.js +10 -0
  256. package/dist/pg/index.js.map +1 -0
  257. package/dist/pg/pg-backend.d.ts +434 -0
  258. package/dist/pg/pg-backend.d.ts.map +1 -0
  259. package/dist/pg/pg-backend.js +2749 -0
  260. package/dist/pg/pg-backend.js.map +1 -0
  261. package/dist/remote/remote-backend.d.ts +82 -2
  262. package/dist/remote/remote-backend.d.ts.map +1 -1
  263. package/dist/remote/remote-backend.js +374 -2
  264. package/dist/remote/remote-backend.js.map +1 -1
  265. package/dist/sdk/index.d.ts +2 -0
  266. package/dist/sdk/index.d.ts.map +1 -1
  267. package/dist/sdk/index.js +1 -0
  268. package/dist/sdk/index.js.map +1 -1
  269. package/dist/sdk/session.d.ts +285 -0
  270. package/dist/sdk/session.d.ts.map +1 -0
  271. package/dist/sdk/session.js +403 -0
  272. package/dist/sdk/session.js.map +1 -0
  273. package/dist/topology.d.ts +210 -0
  274. package/dist/topology.d.ts.map +1 -0
  275. package/dist/topology.js +153 -0
  276. package/dist/topology.js.map +1 -0
  277. package/dist/wasm.d.ts +8 -0
  278. package/dist/wasm.d.ts.map +1 -1
  279. package/dist/wasm.js +10 -0
  280. package/dist/wasm.js.map +1 -1
  281. package/package.json +32 -7
  282. package/wasm/README.md +61 -5
  283. package/wasm/llmtxt_core.d.ts +130 -0
  284. package/wasm/llmtxt_core.js +238 -0
  285. package/wasm/llmtxt_core_bg.wasm +0 -0
  286. package/wasm/llmtxt_core_bg.wasm.d.ts +35 -26
  287. package/wasm/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [2026.4.7] — 2026-04-17
11
+
12
+ ### Fixed
13
+ - **Bundler compatibility for `onnxruntime-node`**: dynamic import in `embeddings.ts` now uses a runtime-constructed specifier + `/* @vite-ignore */` + `/* webpackIgnore: true */` hints. esbuild, webpack, vite, and rollup no longer try to inline the `.node` native addon. Verified with esbuild 0.28 bundle of `llmtxt` + `llmtxt/embeddings` — exit 0, no `--external` flag needed for the onnxruntime path.
14
+
15
+ ### Changed
16
+ - `better-sqlite3`, `drizzle-orm`, `postgres` moved from `optionalDependencies` to `peerDependencies` + `peerDependenciesMeta.optional: true`. pnpm no longer auto-installs them — consumers must opt in per topology. Matches treatment of `onnxruntime-node` and `@vlcn.io/crsqlite`.
17
+ - README adds install matrix + esbuild/webpack/vite externalize list.
18
+
10
19
  ## [2026.4.5] - 2026-04-16
11
20
 
12
21
  This release ships the full Round 1+2+3 multi-agent foundation: CRDT/Yrs, signed Ed25519 identity, append-only event log, real-time presence/leases/diff-subscriptions (W1+W2), BFT consensus, agent scratchpad, A2A envelope routing (W3), a self-hosted observability stack (Grafana / Loki / Tempo / Prometheus / OTel collector / GlitchTip on Railway), OpenAPI schema generation with forge-ts integration, local semantic embeddings via pgvector + ONNX, four reference agents plus a `/demo` page, and a fully portable SDK offering `LocalBackend`, `RemoteBackend`, and `llmtxt` CLI — including a complete CLEO integration example. Also upgrades drizzle-orm/kit to `1.0.0-beta.21` and zod to `^4`.
package/README.md CHANGED
@@ -1,16 +1,219 @@
1
1
  # llmtxt
2
2
 
3
+ [![v2026.4.7](https://img.shields.io/badge/version-2026.4.7-blue)](https://www.npmjs.com/package/llmtxt)
4
+
3
5
  Primitives and SDK for LLM agent content workflows.
4
6
 
5
7
  `llmtxt` wraps the Rust `llmtxt-core` crate through WASM so TypeScript
6
8
  consumers use the same single-source-of-truth logic as native Rust consumers.
7
9
 
10
+ **v2026.4.7** (patch): bundler-friendly dynamic import of `onnxruntime-node`; `drizzle-orm` / `better-sqlite3` / `postgres` moved from `optionalDependencies` to optional `peerDependencies` so consumers no longer auto-install them. Docs add the required externalize list for esbuild / webpack / vite / rollup.
11
+
12
+ **v2026.4.6**: Loro CRDT (replaces Yrs — binary-incompatible), AgentSession lifecycle, document export/import (4 formats), binary blob attachments, `createBackend()` topology factory, cr-sqlite changeset sync, P2P mesh, and new CLI commands.
13
+
8
14
  ## Install
9
15
 
10
16
  ```bash
11
17
  npm install llmtxt
12
18
  ```
13
19
 
20
+ All database/embedding drivers are **optional peer dependencies** — install only the ones your topology needs:
21
+
22
+ | Topology / feature | Extra install |
23
+ |---|---|
24
+ | `standalone` (local SQLite) | `pnpm add better-sqlite3 drizzle-orm` |
25
+ | `hub-spoke` (Postgres hub) | `pnpm add postgres drizzle-orm` |
26
+ | `mesh` + cr-sqlite CRR | `pnpm add @vlcn.io/crsqlite` |
27
+ | Semantic embeddings | `pnpm add onnxruntime-node` |
28
+ | RemoteBackend-only consumer (no local DB) | nothing extra |
29
+
30
+ ## Bundling with esbuild / webpack / vite / rollup
31
+
32
+ `llmtxt` keeps optional peer deps opaque to static bundler analysis where possible, but deep imports inside `LocalBackend` (drizzle-orm) and native addons (onnxruntime-node) must be marked **external** by consumers who bundle. Minimum external list:
33
+
34
+ ```js
35
+ // esbuild
36
+ esbuild.build({
37
+ bundle: true,
38
+ platform: 'node',
39
+ external: [
40
+ 'onnxruntime-node', // native .node addon
41
+ 'better-sqlite3', // native .node addon
42
+ '@vlcn.io/crsqlite', // native extension + ESM-only
43
+ 'drizzle-orm', // transitively pulls mssql, @opentelemetry/api
44
+ 'drizzle-orm/*', // subpath imports
45
+ 'postgres',
46
+ 'mssql',
47
+ '@opentelemetry/api',
48
+ ],
49
+ });
50
+ ```
51
+
52
+ Same list works as `externals` in webpack/rollup and `build.rollupOptions.external` in vite. If your deployment does NOT use LocalBackend (e.g. RemoteBackend only), you may also externalize `llmtxt/local`.
53
+
54
+ ## Topology Factory
55
+
56
+ The entry point for all deployments. Returns a `Backend` configured for the chosen topology.
57
+
58
+ ```ts
59
+ import { createBackend } from 'llmtxt';
60
+
61
+ // Standalone — local SQLite, no network
62
+ const backend = await createBackend({ topology: 'standalone', storagePath: './.llmtxt' });
63
+
64
+ // Hub-spoke — ephemeral worker pointing at shared hub
65
+ const backend2 = await createBackend({
66
+ topology: 'hub-spoke',
67
+ hubUrl: 'https://api.llmtxt.my',
68
+ apiKey: process.env.LLMTXT_API_KEY,
69
+ });
70
+
71
+ // Mesh — P2P, no server required
72
+ const backend3 = await createBackend({
73
+ topology: 'mesh',
74
+ storagePath: './.llmtxt',
75
+ });
76
+ ```
77
+
78
+ Note: `createBackend` is `async` (returns `Promise<Backend>`). Always `await` it.
79
+
80
+ See [docs.llmtxt.my/architecture/topology](https://docs.llmtxt.my/architecture/topology) and [docs/specs/ARCH-T429-hub-spoke-topology.md](../../docs/specs/ARCH-T429-hub-spoke-topology.md).
81
+
82
+ ## AgentSession Lifecycle
83
+
84
+ Gives every agent an explicit, auditable lifecycle with crash recovery and signed contribution receipts.
85
+
86
+ ```ts
87
+ import { AgentSession } from 'llmtxt/sdk';
88
+ import type { ContributionReceipt } from 'llmtxt/sdk';
89
+
90
+ const session = new AgentSession({ backend, agentId: 'agent-1' });
91
+ await session.open(); // registers presence, allocates temp .db for LocalBackend sessions
92
+
93
+ // contribute() returns T (whatever fn returns); receipt is from close()
94
+ const doc = await session.contribute(async (b) => {
95
+ const created = await b.createDocument({ title: 'Spec', createdBy: 'agent-1' });
96
+ await b.publishVersion({
97
+ documentId: created.id,
98
+ content: '# Spec',
99
+ patchText: '',
100
+ createdBy: 'agent-1',
101
+ changelog: 'Initial',
102
+ });
103
+ return created;
104
+ });
105
+
106
+ const contributionReceipt: ContributionReceipt = await session.close();
107
+ // Releases leases, drains inbox, deletes temp .db, emits signed ContributionReceipt
108
+ ```
109
+
110
+ `ContributionReceipt` fields: `sessionId`, `agentId`, `documentIds`, `eventCount`, `sessionDurationMs`, `openedAt`, `closedAt`, `signature` (Ed25519 when RemoteBackend).
111
+
112
+ See [docs.llmtxt.my/multi-agent/session-lifecycle](https://docs.llmtxt.my/multi-agent/session-lifecycle) and [docs/specs/ARCH-T426-ephemeral-agent-lifecycle.md](../../docs/specs/ARCH-T426-ephemeral-agent-lifecycle.md).
113
+
114
+ ## Document Export / Import
115
+
116
+ ```ts
117
+ // Export a document to disk
118
+ const result = await backend.exportDocument({
119
+ slug: 'my-spec',
120
+ format: 'markdown', // 'markdown' | 'json' | 'txt' | 'llmtxt'
121
+ outputPath: './exports/my-spec.md',
122
+ sign: true, // Ed25519-sign the export manifest
123
+ });
124
+ // result: { filePath, slug, version, fileHash, byteCount, exportedAt, signatureHex }
125
+
126
+ // Export all documents
127
+ const allResult = await backend.exportAll({ format: 'json', outputDir: './exports/' });
128
+
129
+ // Import from file — creates doc or appends new version if slug exists
130
+ const imported = await backend.importDocument({
131
+ filePath: './exports/my-spec.md',
132
+ importedBy: 'agent-1',
133
+ onConflict: 'new_version', // 'new_version' | 'create'
134
+ });
135
+ ```
136
+
137
+ Formats: `markdown` (YAML frontmatter + body), `json` (structured), `txt` (body only), `llmtxt` (round-trippable with chain reference). Output is deterministic: same document state always produces identical file bytes.
138
+
139
+ See [docs.llmtxt.my/sdk/export-import](https://docs.llmtxt.my/sdk/export-import) and [docs/specs/ARCH-T427-document-export-ssot.md](../../docs/specs/ARCH-T427-document-export-ssot.md).
140
+
141
+ ## Binary Blob Attachments
142
+
143
+ ```ts
144
+ import * as fs from 'node:fs';
145
+
146
+ // Attach a binary file to a document
147
+ const attachment = await backend.attachBlob({
148
+ docSlug: 'my-spec',
149
+ name: 'diagram.png',
150
+ data: fs.readFileSync('./diagram.png'),
151
+ contentType: 'image/png',
152
+ uploadedBy: 'agent-1',
153
+ });
154
+
155
+ // Read back — hash verified on every read when includeData=true
156
+ const blob = await backend.getBlob('my-spec', 'diagram.png', { includeData: true });
157
+
158
+ // List attachments (metadata only, no bytes)
159
+ const blobs = await backend.listBlobs('my-spec');
160
+
161
+ // Remove
162
+ await backend.detachBlob('my-spec', 'diagram.png', 'agent-1');
163
+ ```
164
+
165
+ Blobs are content-addressed (SHA-256). Hash verification is mandatory on read — corrupt bytes are never returned. Max default size: 100 MB. Conflict resolution: Last Write Wins per attachment name.
166
+
167
+ See [docs.llmtxt.my/sdk/blob-attachments](https://docs.llmtxt.my/sdk/blob-attachments) and [docs/specs/ARCH-T428-binary-blob-attachments.md](../../docs/specs/ARCH-T428-binary-blob-attachments.md).
168
+
169
+ ## cr-sqlite LocalBackend (Changeset Sync)
170
+
171
+ Install the optional peer dependency to enable changeset-based sync between LocalBackend instances:
172
+
173
+ ```bash
174
+ npm install @vlcn.io/crsqlite
175
+ ```
176
+
177
+ ```ts
178
+ import { createBackend } from 'llmtxt';
179
+
180
+ const backend = await createBackend({
181
+ topology: 'standalone',
182
+ storagePath: './.llmtxt',
183
+ crsqlite: true, // requires @vlcn.io/crsqlite peer dep
184
+ });
185
+
186
+ // Exchange changesets with another agent
187
+ const changes = await backend.getChangesSince({ version: lastSyncVersion });
188
+ await otherBackend.applyChanges({ changes });
189
+ ```
190
+
191
+ Single-tenant only (one agent per `.db`). Loro CRDT state in the `crdt_state` column is merged at the application level (not via cr-sqlite row merge). See [docs/specs/P2-cr-sqlite.md](../../docs/specs/P2-cr-sqlite.md).
192
+
193
+ ## P2P Mesh
194
+
195
+ ```ts
196
+ import { createBackend } from 'llmtxt';
197
+
198
+ const backend = await createBackend({
199
+ topology: 'mesh',
200
+ storagePath: './.llmtxt',
201
+ peers: ['unix:/tmp/agent-b.sock', 'http://192.168.1.5:7642'],
202
+ });
203
+ await backend.open();
204
+ // Sync engine starts; Ed25519 mutual handshake required for each peer connection
205
+ ```
206
+
207
+ See [docs.llmtxt.my/mesh](https://docs.llmtxt.my/mesh) and [docs/specs/P3-p2p-mesh.md](../../docs/specs/P3-p2p-mesh.md).
208
+
209
+ ## Loro CRDT (replaces Yrs)
210
+
211
+ v2026.4.6 replaced `yrs` with `loro` 1.0 in `crates/llmtxt-core`. The six WASM function names are unchanged (`crdt_new_doc`, `crdt_encode_state_as_update`, `crdt_apply_update`, `crdt_merge_updates`, `crdt_state_vector`, `crdt_diff_update`) but their binary format is incompatible with previous versions.
212
+
213
+ **Wire protocol change**: 1-byte message prefix `0x01`/`0x02`/`0x03`/`0x04` replaces the y-sync `0x00`/`0x01`/`0x02`/`0x03` framing. Legacy Yjs clients will be rejected.
214
+
215
+ **Migration**: No data migration path. Drop all `section_crdt_states` and `section_crdt_updates` rows on deploy. See [docs/specs/P1-loro-migration.md](../../docs/specs/P1-loro-migration.md).
216
+
14
217
  ## Primitives
15
218
 
16
219
  ```ts
@@ -27,16 +230,9 @@ const hash = hashContent(text);
27
230
 
28
231
  const patch = createPatch('hello\n', 'hello world\n');
29
232
  const rebuilt = applyPatch('hello\n', patch);
30
- ```
31
-
32
- ## Multi-Way Diff and Cherry-Pick Merge
33
233
 
34
- ```ts
35
- import { multiWayDiff, cherryPickMerge } from 'llmtxt';
36
-
37
- // Compare multiple agent versions against a base using LCS alignment
234
+ // LCS-aligned multi-way diff across agent versions
38
235
  const diff = multiWayDiff(base, JSON.stringify([v2Content, v3Content, v4Content]));
39
- // Returns MultiDiffResult: { sections, totalVersions, baseTokenCount }
40
236
 
41
237
  // Selectively merge sections from different versions
42
238
  const merged = cherryPickMerge(
@@ -47,80 +243,72 @@ const merged = cherryPickMerge(
47
243
  { section: 'API Reference', fromVersion: 2 },
48
244
  ])
49
245
  );
50
- // Returns CherryPickResult: { content, provenance, stats }
51
- ```
52
-
53
- ## SDK (Collaborative Documents)
54
-
55
- ```ts
56
- import {
57
- isValidTransition, evaluateApprovals, planRetrieval,
58
- reconstructVersion, attributeVersion, buildContributorSummary,
59
- } from 'llmtxt/sdk';
60
246
  ```
61
247
 
62
- ### Subpath Exports
248
+ ## Subpath Exports
63
249
 
64
250
  ```ts
251
+ import { AgentSession } from 'llmtxt/sdk';
252
+ import { createBackend } from 'llmtxt/topology';
253
+ import { LocalBackend } from 'llmtxt/local';
254
+ import { RemoteBackend } from 'llmtxt/remote';
65
255
  import { generateOverview, getSection } from 'llmtxt/disclosure';
66
256
  import { textSimilarity, rankBySimilarity } from 'llmtxt/similarity';
67
257
  import { buildGraph } from 'llmtxt/graph';
68
258
  ```
69
259
 
70
- ## LocalBackend (Embedded, Zero-Network)
71
-
72
- ```ts
73
- import { LocalBackend } from 'llmtxt/local';
74
-
75
- const backend = new LocalBackend({ storagePath: './.llmtxt' });
76
- await backend.open();
77
-
78
- const doc = await backend.createDocument({ title: 'My Spec', createdBy: 'agent-1' });
79
- await backend.publishVersion({ documentId: doc.id, content: '# Spec', patchText: '', createdBy: 'agent-1', changelog: 'Initial' });
80
- await backend.close();
81
- ```
82
-
83
- ## RemoteBackend (HTTP/WS Client)
84
-
85
- ```ts
86
- import { RemoteBackend } from 'llmtxt/remote';
87
-
88
- const backend = new RemoteBackend({ baseUrl: 'https://api.llmtxt.my', apiKey: process.env.LLMTXT_API_KEY });
89
- await backend.open();
90
- // Same calls as LocalBackend — same Backend interface.
91
- await backend.close();
92
- ```
93
-
94
- ## CLI
260
+ ## CLI Reference
95
261
 
96
262
  ```bash
97
- # Initialise local storage + identity keypair
263
+ # Core
98
264
  llmtxt init
99
-
100
- # Create a document
101
265
  llmtxt create-doc "My Specification"
102
-
103
- # Push a version from stdin
104
- cat spec.md | llmtxt push-version my-specification "First draft"
105
-
106
- # Sync local ↔ remote
266
+ cat spec.md | llmtxt push-version my-spec "First draft"
107
267
  llmtxt sync --remote https://api.llmtxt.my --api-key $KEY
268
+
269
+ # Export / Import
270
+ llmtxt export <slug> --format md --output ./specs/
271
+ llmtxt export <slug> --format json --output ./exports/ --sign
272
+ llmtxt export-all --format md --output ./docs/
273
+ llmtxt import ./specs/my-doc.md
274
+
275
+ # Binary blob attachments
276
+ llmtxt attach <slug> ./diagram.png --name diagram.png
277
+ llmtxt blobs <slug>
278
+ llmtxt detach <slug> diagram.png
279
+
280
+ # Agent session lifecycle
281
+ llmtxt session start <agentId>
282
+ llmtxt session end <sessionId>
283
+
284
+ # P2P mesh
285
+ llmtxt mesh start
286
+ llmtxt mesh stop
287
+ llmtxt mesh status
288
+ llmtxt mesh peers
289
+ llmtxt mesh sync
108
290
  ```
109
291
 
110
292
  ## What Ships
111
293
 
112
294
  - Compression, hashing, base62, token estimation (Rust WASM)
113
- - Signed URL generation and verification
295
+ - Signed URL generation and verification (HMAC-SHA256, Ed25519)
114
296
  - Unified diff patch creation, application, version reconstruction
297
+ - Loro CRDT via WASM (crdt_new_doc, crdt_apply_update, crdt_merge_updates, crdt_diff_update)
115
298
  - Multi-way diff across up to 5 agent versions (LCS-aligned, WASM)
116
299
  - Cherry-pick merge: selectively assemble sections from multiple versions (WASM)
117
300
  - Progressive disclosure: overview, section extraction, content search
118
301
  - Collaborative document lifecycle (DRAFT, REVIEW, LOCKED, ARCHIVED)
302
+ - AgentSession: open / contribute / close with signed ContributionReceipt
303
+ - Document export (4 formats, deterministic, signed) and import
304
+ - Binary blob attachments (content-addressed SHA-256, hash-verify-on-read)
305
+ - Topology factory: standalone / hub-spoke / mesh via `createBackend()`
306
+ - cr-sqlite changeset sync (optional peer dep `@vlcn.io/crsqlite`)
307
+ - P2P mesh sync engine (Ed25519 mutual handshake, Unix socket + HTTP transports)
119
308
  - Version stack management with attribution tracking
120
309
  - Consensus/approval evaluation with stale review handling
121
310
  - Token-budget-aware retrieval planning
122
311
  - Storage content reference abstractions (inline vs object-store)
123
- - Attachment client helpers for upload, fetch, reshare, versioning
124
312
 
125
313
  ## Release Model
126
314
 
@@ -0,0 +1,14 @@
1
+ /**
2
+ * a2a.test.ts — T419: A2A over Mesh tests
3
+ *
4
+ * 5 tests covering:
5
+ * 1. Direct send: signed message delivered to directly-connected peer.
6
+ * 2. SECURITY: unsigned/invalid-sig message is rejected before delivery.
7
+ * 3. Relay path: message forwarded via connected peer when target not direct.
8
+ * 4. Queue: message queued locally when no relay path found.
9
+ * 5. Payload size limit: payload >1 MB is rejected at send.
10
+ *
11
+ * Spec: P3-p2p-mesh.md §7, §10
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=a2a.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2a.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/a2a.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * a2a.test.ts — T419: A2A over Mesh tests
3
+ *
4
+ * 5 tests covering:
5
+ * 1. Direct send: signed message delivered to directly-connected peer.
6
+ * 2. SECURITY: unsigned/invalid-sig message is rejected before delivery.
7
+ * 3. Relay path: message forwarded via connected peer when target not direct.
8
+ * 4. Queue: message queued locally when no relay path found.
9
+ * 5. Payload size limit: payload >1 MB is rejected at send.
10
+ *
11
+ * Spec: P3-p2p-mesh.md §7, §10
12
+ */
13
+ import { describe, it, before } from 'node:test';
14
+ import assert from 'node:assert/strict';
15
+ import { AgentIdentity } from '../identity.js';
16
+ import { MeshMessenger } from '../mesh/a2a.js';
17
+ // ── Helpers ───────────────────────────────────────────────────────
18
+ const MSG_TYPE_A2A = 0x10;
19
+ function buildA2AFrame(envelope) {
20
+ const json = JSON.stringify(envelope);
21
+ const jsonBytes = new TextEncoder().encode(json);
22
+ const out = new Uint8Array(1 + jsonBytes.length);
23
+ out[0] = MSG_TYPE_A2A;
24
+ out.set(jsonBytes, 1);
25
+ return out;
26
+ }
27
+ function mockTransport(opts) {
28
+ const sent = [];
29
+ let listener;
30
+ return {
31
+ type: 'mock-a2a',
32
+ sent,
33
+ simulateInbound(peerId, data) {
34
+ listener?.(peerId, data);
35
+ },
36
+ async listen(cb) {
37
+ listener = cb;
38
+ },
39
+ async sendChangeset(peerId, _address, data) {
40
+ if (opts?.failForPeer && peerId === opts.failForPeer) {
41
+ throw new Error(`[mock] peer ${peerId} unreachable`);
42
+ }
43
+ sent.push({ peerId, data });
44
+ await opts?.onSend?.(peerId, data);
45
+ },
46
+ async close() {
47
+ // no-op
48
+ },
49
+ };
50
+ }
51
+ function mockDiscovery(peers) {
52
+ return {
53
+ async discover() {
54
+ return peers;
55
+ },
56
+ markInactive(_id) { },
57
+ };
58
+ }
59
+ async function makeIdentity() {
60
+ const seed = new Uint8Array(32);
61
+ globalThis.crypto.getRandomValues(seed);
62
+ return AgentIdentity.fromSeed(seed);
63
+ }
64
+ // ── Tests ─────────────────────────────────────────────────────────
65
+ describe('MeshMessenger', () => {
66
+ let senderIdentity;
67
+ let recipientIdentity;
68
+ before(async () => {
69
+ senderIdentity = await makeIdentity();
70
+ recipientIdentity = await makeIdentity();
71
+ });
72
+ it('test-1: direct send — signed message delivered to directly-connected peer', async () => {
73
+ const transport = mockTransport();
74
+ const peers = [
75
+ {
76
+ agentId: recipientIdentity.pubkeyHex,
77
+ address: 'unix:/tmp/recv.sock',
78
+ pubkeyBase64: Buffer.from(recipientIdentity.pk).toString('base64'),
79
+ },
80
+ ];
81
+ const discovery = mockDiscovery(peers);
82
+ const received = [];
83
+ const messenger = new MeshMessenger({
84
+ identity: senderIdentity,
85
+ transport,
86
+ discovery,
87
+ onMessage: (env) => received.push(env),
88
+ });
89
+ await messenger.start();
90
+ await messenger.send(recipientIdentity.pubkeyHex, { action: 'ping' });
91
+ await messenger.stop();
92
+ assert.equal(transport.sent.length, 1, 'one send call expected');
93
+ const frame = transport.sent[0];
94
+ assert.equal(frame.peerId, recipientIdentity.pubkeyHex);
95
+ assert.equal(frame.data[0], MSG_TYPE_A2A);
96
+ // Decode envelope.
97
+ const json = new TextDecoder().decode(frame.data.slice(1));
98
+ const env = JSON.parse(json);
99
+ assert.equal(env.type, 'a2a');
100
+ assert.equal(env.from, senderIdentity.pubkeyHex);
101
+ assert.equal(env.to, recipientIdentity.pubkeyHex);
102
+ assert.ok(typeof env.sig === 'string' && env.sig.length > 0, 'message must be signed');
103
+ assert.deepEqual(env.payload, { action: 'ping' });
104
+ });
105
+ it('test-2: SECURITY — unsigned/invalid-sig inbound message is rejected', async () => {
106
+ const transport = mockTransport();
107
+ const discovery = mockDiscovery([]);
108
+ const received = [];
109
+ const rejections = [];
110
+ const messenger = new MeshMessenger({
111
+ identity: recipientIdentity,
112
+ transport,
113
+ discovery,
114
+ onMessage: (env) => received.push(env),
115
+ });
116
+ messenger.on('security-rejection', (r) => rejections.push(r));
117
+ await messenger.start();
118
+ // Build a message with an invalid signature.
119
+ const badEnvelope = {
120
+ type: 'a2a',
121
+ from: senderIdentity.pubkeyHex,
122
+ to: recipientIdentity.pubkeyHex,
123
+ payload: { action: 'malicious' },
124
+ sig: Buffer.from('invalid-sig-bytes-xxxx').toString('base64'),
125
+ sentAt: new Date().toISOString(),
126
+ };
127
+ const frame = buildA2AFrame(badEnvelope);
128
+ transport.simulateInbound('attacker', frame);
129
+ // Allow async verification to complete.
130
+ await new Promise((r) => setTimeout(r, 100));
131
+ await messenger.stop();
132
+ assert.equal(received.length, 0, 'message with invalid sig MUST NOT be delivered');
133
+ assert.ok(rejections.length >= 1, 'security-rejection event must be emitted');
134
+ });
135
+ it('test-3: relay path — message forwarded through connected peer', async () => {
136
+ // senderIdentity → relay agent → recipientIdentity
137
+ const relayAgentId = 'relay-agent-hex-pubkey';
138
+ const transport = mockTransport();
139
+ // Only relay is directly connected; recipient is NOT in peer list.
140
+ const peers = [
141
+ {
142
+ agentId: relayAgentId,
143
+ address: 'unix:/tmp/relay.sock',
144
+ pubkeyBase64: Buffer.alloc(32, 0x44).toString('base64'),
145
+ },
146
+ ];
147
+ const discovery = mockDiscovery(peers);
148
+ const messenger = new MeshMessenger({
149
+ identity: senderIdentity,
150
+ transport,
151
+ discovery,
152
+ });
153
+ await messenger.start();
154
+ // Should relay since recipient not directly connected.
155
+ await messenger.send(recipientIdentity.pubkeyHex, { action: 'routed-task' });
156
+ await messenger.stop();
157
+ // Message should have been sent to relay agent.
158
+ const relaySends = transport.sent.filter((s) => s.peerId === relayAgentId);
159
+ assert.ok(relaySends.length >= 1, 'message must be forwarded to relay peer');
160
+ // Verify the relay frame contains the inner envelope.
161
+ const relayFrame = relaySends[0];
162
+ assert.equal(relayFrame.data[0], MSG_TYPE_A2A);
163
+ const json = new TextDecoder().decode(relayFrame.data.slice(1));
164
+ const parsed = JSON.parse(json);
165
+ // The relay wraps in a relay frame.
166
+ assert.equal(parsed.type, 'relay', 'relay frame type must be "relay"');
167
+ assert.ok(parsed.inner, 'relay frame must contain inner envelope');
168
+ assert.equal(parsed.inner.to, recipientIdentity.pubkeyHex);
169
+ });
170
+ it('test-4: no-path — message queued locally when no relay found', async () => {
171
+ const transport = mockTransport();
172
+ // No peers at all — no direct or relay path.
173
+ const discovery = mockDiscovery([]);
174
+ const queued = [];
175
+ const messenger = new MeshMessenger({
176
+ identity: senderIdentity,
177
+ transport,
178
+ discovery,
179
+ });
180
+ messenger.on('queued', (e) => queued.push(e));
181
+ await messenger.start();
182
+ await messenger.send(recipientIdentity.pubkeyHex, { action: 'offline-task' });
183
+ await messenger.stop();
184
+ assert.equal(transport.sent.length, 0, 'nothing must be sent when no path exists');
185
+ const status = messenger.getQueueStatus();
186
+ const totalQueued = Object.values(status).reduce((a, b) => a + b, 0);
187
+ assert.ok(totalQueued >= 1, 'message must be queued locally');
188
+ assert.ok(queued.length >= 1, 'queued event must be emitted');
189
+ });
190
+ it('test-5: payload >1 MB is rejected at send', async () => {
191
+ const transport = mockTransport();
192
+ const peers = [
193
+ {
194
+ agentId: recipientIdentity.pubkeyHex,
195
+ address: 'unix:/tmp/recv.sock',
196
+ pubkeyBase64: Buffer.from(recipientIdentity.pk).toString('base64'),
197
+ },
198
+ ];
199
+ const discovery = mockDiscovery(peers);
200
+ const messenger = new MeshMessenger({
201
+ identity: senderIdentity,
202
+ transport,
203
+ discovery,
204
+ });
205
+ await messenger.start();
206
+ // Build a payload just over 1 MB.
207
+ const bigString = 'x'.repeat(1024 * 1024 + 1);
208
+ await assert.rejects(() => messenger.send(recipientIdentity.pubkeyHex, { data: bigString }), (err) => {
209
+ assert.ok(err instanceof Error, 'must throw an Error');
210
+ assert.ok(err.message.includes('1 MB'), `error message must mention 1 MB limit, got: ${err.message}`);
211
+ return true;
212
+ }, 'send must reject payloads over 1 MB');
213
+ assert.equal(transport.sent.length, 0, 'oversized payload must not be sent');
214
+ await messenger.stop();
215
+ });
216
+ });
217
+ //# sourceMappingURL=a2a.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2a.test.js","sourceRoot":"","sources":["../../src/__tests__/a2a.test.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,24 @@
1
1
  /**
2
- * Backend contract test suite.
2
+ * Backend contract test suite — parametrized over LocalBackend and PostgresBackend.
3
3
  *
4
- * Runs the same set of behavioural assertions against any Backend
5
- * implementation. Currently validates LocalBackend; RemoteBackend is
6
- * validated against a mock HTTP server when one is available (skipped
7
- * in CI without a running server).
4
+ * Runs the same set of behavioural assertions against any Backend implementation.
5
+ * Each describe block receives a BackendFactory and runs identical assertions
6
+ * regardless of which backend is under test.
8
7
  *
9
- * Pattern: each `describe` block receives a `BackendFactory` and runs
10
- * identical assertions regardless of which implementation is under test.
8
+ * Backends:
9
+ * - LocalBackend (SQLite, temp dir) always runs.
10
+ * - PostgresBackend (Postgres via DATABASE_URL_PG env) — skipped with WARN if
11
+ * DATABASE_URL_PG is not set. Never fails the suite when absent.
12
+ *
13
+ * Output format:
14
+ * [LocalBackend] documents.create …
15
+ * [PostgresBackend] documents.create … (or SKIPPED if no PG)
16
+ *
17
+ * Multi-agent semantic tests (added in T361):
18
+ * - Lease contention: agent-1 acquires, agent-2 blocked, release, agent-2 acquires.
19
+ * - A2A round-trip: send + pollInbox + markRead (deleteA2AMessage).
20
+ * - Scratchpad round-trip: send + poll + delete.
21
+ * - Identity: register + lookup + revoke + nonce replay prevention.
11
22
  */
12
23
  export {};
13
24
  //# sourceMappingURL=backend-contract.test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backend-contract.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/backend-contract.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
1
+ {"version":3,"file":"backend-contract.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/backend-contract.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}