foundation-ai-agent 1.0.0

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 (306) hide show
  1. package/README.md +338 -0
  2. package/dist/compat/butler-cloud.d.ts +33 -0
  3. package/dist/compat/butler-cloud.d.ts.map +1 -0
  4. package/dist/compat/butler-cloud.js +69 -0
  5. package/dist/compat/butler-cloud.js.map +1 -0
  6. package/dist/compat/butler-edge.d.ts +34 -0
  7. package/dist/compat/butler-edge.d.ts.map +1 -0
  8. package/dist/compat/butler-edge.js +62 -0
  9. package/dist/compat/butler-edge.js.map +1 -0
  10. package/dist/compat/butler-pair.d.ts +27 -0
  11. package/dist/compat/butler-pair.d.ts.map +1 -0
  12. package/dist/compat/butler-pair.js +23 -0
  13. package/dist/compat/butler-pair.js.map +1 -0
  14. package/dist/compat/entry.d.ts +26 -0
  15. package/dist/compat/entry.d.ts.map +1 -0
  16. package/dist/compat/entry.js +35 -0
  17. package/dist/compat/entry.js.map +1 -0
  18. package/dist/compat/index.d.ts +12 -0
  19. package/dist/compat/index.d.ts.map +1 -0
  20. package/dist/compat/index.js +12 -0
  21. package/dist/compat/index.js.map +1 -0
  22. package/dist/compat/queue.d.ts +31 -0
  23. package/dist/compat/queue.d.ts.map +1 -0
  24. package/dist/compat/queue.js +54 -0
  25. package/dist/compat/queue.js.map +1 -0
  26. package/dist/index.d.ts +37 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +53 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/ledger.d.ts +28 -0
  31. package/dist/ledger.d.ts.map +1 -0
  32. package/dist/ledger.js +62 -0
  33. package/dist/ledger.js.map +1 -0
  34. package/dist/observability/index.d.ts +4 -0
  35. package/dist/observability/index.d.ts.map +1 -0
  36. package/dist/observability/index.js +2 -0
  37. package/dist/observability/index.js.map +1 -0
  38. package/dist/observability/observer.d.ts +37 -0
  39. package/dist/observability/observer.d.ts.map +1 -0
  40. package/dist/observability/observer.js +53 -0
  41. package/dist/observability/observer.js.map +1 -0
  42. package/dist/observability/types.d.ts +92 -0
  43. package/dist/observability/types.d.ts.map +1 -0
  44. package/dist/observability/types.js +9 -0
  45. package/dist/observability/types.js.map +1 -0
  46. package/dist/s01-realtime/index.d.ts +3 -0
  47. package/dist/s01-realtime/index.d.ts.map +1 -0
  48. package/dist/s01-realtime/index.js +2 -0
  49. package/dist/s01-realtime/index.js.map +1 -0
  50. package/dist/s01-realtime/signaling.d.ts +78 -0
  51. package/dist/s01-realtime/signaling.d.ts.map +1 -0
  52. package/dist/s01-realtime/signaling.js +20 -0
  53. package/dist/s01-realtime/signaling.js.map +1 -0
  54. package/dist/s01-realtime/types.d.ts +40 -0
  55. package/dist/s01-realtime/types.d.ts.map +1 -0
  56. package/dist/s01-realtime/types.js +8 -0
  57. package/dist/s01-realtime/types.js.map +1 -0
  58. package/dist/s02-crdt/index.d.ts +3 -0
  59. package/dist/s02-crdt/index.d.ts.map +1 -0
  60. package/dist/s02-crdt/index.js +2 -0
  61. package/dist/s02-crdt/index.js.map +1 -0
  62. package/dist/s02-crdt/types.d.ts +45 -0
  63. package/dist/s02-crdt/types.d.ts.map +1 -0
  64. package/dist/s02-crdt/types.js +10 -0
  65. package/dist/s02-crdt/types.js.map +1 -0
  66. package/dist/s02-crdt/yjs.d.ts +9 -0
  67. package/dist/s02-crdt/yjs.d.ts.map +1 -0
  68. package/dist/s02-crdt/yjs.js +67 -0
  69. package/dist/s02-crdt/yjs.js.map +1 -0
  70. package/dist/s03-streaming/index.d.ts +3 -0
  71. package/dist/s03-streaming/index.d.ts.map +1 -0
  72. package/dist/s03-streaming/index.js +2 -0
  73. package/dist/s03-streaming/index.js.map +1 -0
  74. package/dist/s03-streaming/playlist.d.ts +8 -0
  75. package/dist/s03-streaming/playlist.d.ts.map +1 -0
  76. package/dist/s03-streaming/playlist.js +49 -0
  77. package/dist/s03-streaming/playlist.js.map +1 -0
  78. package/dist/s03-streaming/types.d.ts +69 -0
  79. package/dist/s03-streaming/types.d.ts.map +1 -0
  80. package/dist/s03-streaming/types.js +8 -0
  81. package/dist/s03-streaming/types.js.map +1 -0
  82. package/dist/s04-messaging/index.d.ts +3 -0
  83. package/dist/s04-messaging/index.d.ts.map +1 -0
  84. package/dist/s04-messaging/index.js +2 -0
  85. package/dist/s04-messaging/index.js.map +1 -0
  86. package/dist/s04-messaging/serializer.d.ts +11 -0
  87. package/dist/s04-messaging/serializer.d.ts.map +1 -0
  88. package/dist/s04-messaging/serializer.js +45 -0
  89. package/dist/s04-messaging/serializer.js.map +1 -0
  90. package/dist/s04-messaging/types.d.ts +54 -0
  91. package/dist/s04-messaging/types.d.ts.map +1 -0
  92. package/dist/s04-messaging/types.js +8 -0
  93. package/dist/s04-messaging/types.js.map +1 -0
  94. package/dist/s05-rendering/index.d.ts +3 -0
  95. package/dist/s05-rendering/index.d.ts.map +1 -0
  96. package/dist/s05-rendering/index.js +3 -0
  97. package/dist/s05-rendering/index.js.map +1 -0
  98. package/dist/s05-rendering/state-machine.d.ts +20 -0
  99. package/dist/s05-rendering/state-machine.d.ts.map +1 -0
  100. package/dist/s05-rendering/state-machine.js +47 -0
  101. package/dist/s05-rendering/state-machine.js.map +1 -0
  102. package/dist/s05-rendering/types.d.ts +13 -0
  103. package/dist/s05-rendering/types.d.ts.map +1 -0
  104. package/dist/s05-rendering/types.js +16 -0
  105. package/dist/s05-rendering/types.js.map +1 -0
  106. package/dist/s06-payments/billing.d.ts +9 -0
  107. package/dist/s06-payments/billing.d.ts.map +1 -0
  108. package/dist/s06-payments/billing.js +79 -0
  109. package/dist/s06-payments/billing.js.map +1 -0
  110. package/dist/s06-payments/index.d.ts +4 -0
  111. package/dist/s06-payments/index.d.ts.map +1 -0
  112. package/dist/s06-payments/index.js +3 -0
  113. package/dist/s06-payments/index.js.map +1 -0
  114. package/dist/s06-payments/stripe.d.ts +52 -0
  115. package/dist/s06-payments/stripe.d.ts.map +1 -0
  116. package/dist/s06-payments/stripe.js +103 -0
  117. package/dist/s06-payments/stripe.js.map +1 -0
  118. package/dist/s06-payments/types.d.ts +80 -0
  119. package/dist/s06-payments/types.d.ts.map +1 -0
  120. package/dist/s06-payments/types.js +13 -0
  121. package/dist/s06-payments/types.js.map +1 -0
  122. package/dist/s07-identity/index.d.ts +2 -0
  123. package/dist/s07-identity/index.d.ts.map +1 -0
  124. package/dist/s07-identity/index.js +2 -0
  125. package/dist/s07-identity/index.js.map +1 -0
  126. package/dist/s07-identity/session.d.ts +53 -0
  127. package/dist/s07-identity/session.d.ts.map +1 -0
  128. package/dist/s07-identity/session.js +114 -0
  129. package/dist/s07-identity/session.js.map +1 -0
  130. package/dist/s08-containers/docker.d.ts +39 -0
  131. package/dist/s08-containers/docker.d.ts.map +1 -0
  132. package/dist/s08-containers/docker.js +72 -0
  133. package/dist/s08-containers/docker.js.map +1 -0
  134. package/dist/s08-containers/index.d.ts +4 -0
  135. package/dist/s08-containers/index.d.ts.map +1 -0
  136. package/dist/s08-containers/index.js +3 -0
  137. package/dist/s08-containers/index.js.map +1 -0
  138. package/dist/s08-containers/sandbox.d.ts +10 -0
  139. package/dist/s08-containers/sandbox.d.ts.map +1 -0
  140. package/dist/s08-containers/sandbox.js +68 -0
  141. package/dist/s08-containers/sandbox.js.map +1 -0
  142. package/dist/s08-containers/types.d.ts +66 -0
  143. package/dist/s08-containers/types.d.ts.map +1 -0
  144. package/dist/s08-containers/types.js +8 -0
  145. package/dist/s08-containers/types.js.map +1 -0
  146. package/dist/s09-persistence/cold.d.ts +43 -0
  147. package/dist/s09-persistence/cold.d.ts.map +1 -0
  148. package/dist/s09-persistence/cold.js +135 -0
  149. package/dist/s09-persistence/cold.js.map +1 -0
  150. package/dist/s09-persistence/hot.d.ts +32 -0
  151. package/dist/s09-persistence/hot.d.ts.map +1 -0
  152. package/dist/s09-persistence/hot.js +63 -0
  153. package/dist/s09-persistence/hot.js.map +1 -0
  154. package/dist/s09-persistence/index.d.ts +6 -0
  155. package/dist/s09-persistence/index.d.ts.map +1 -0
  156. package/dist/s09-persistence/index.js +6 -0
  157. package/dist/s09-persistence/index.js.map +1 -0
  158. package/dist/s09-persistence/pg-warm.d.ts +30 -0
  159. package/dist/s09-persistence/pg-warm.d.ts.map +1 -0
  160. package/dist/s09-persistence/pg-warm.js +139 -0
  161. package/dist/s09-persistence/pg-warm.js.map +1 -0
  162. package/dist/s09-persistence/s3-cold.d.ts +39 -0
  163. package/dist/s09-persistence/s3-cold.d.ts.map +1 -0
  164. package/dist/s09-persistence/s3-cold.js +102 -0
  165. package/dist/s09-persistence/s3-cold.js.map +1 -0
  166. package/dist/s09-persistence/warm.d.ts +33 -0
  167. package/dist/s09-persistence/warm.d.ts.map +1 -0
  168. package/dist/s09-persistence/warm.js +169 -0
  169. package/dist/s09-persistence/warm.js.map +1 -0
  170. package/dist/s10-inference/action.d.ts +39 -0
  171. package/dist/s10-inference/action.d.ts.map +1 -0
  172. package/dist/s10-inference/action.js +73 -0
  173. package/dist/s10-inference/action.js.map +1 -0
  174. package/dist/s10-inference/agents/index.d.ts +3 -0
  175. package/dist/s10-inference/agents/index.d.ts.map +1 -0
  176. package/dist/s10-inference/agents/index.js +3 -0
  177. package/dist/s10-inference/agents/index.js.map +1 -0
  178. package/dist/s10-inference/agents/mirror.d.ts +73 -0
  179. package/dist/s10-inference/agents/mirror.d.ts.map +1 -0
  180. package/dist/s10-inference/agents/mirror.js +106 -0
  181. package/dist/s10-inference/agents/mirror.js.map +1 -0
  182. package/dist/s10-inference/agents/registry.d.ts +64 -0
  183. package/dist/s10-inference/agents/registry.d.ts.map +1 -0
  184. package/dist/s10-inference/agents/registry.js +92 -0
  185. package/dist/s10-inference/agents/registry.js.map +1 -0
  186. package/dist/s10-inference/context.d.ts +39 -0
  187. package/dist/s10-inference/context.d.ts.map +1 -0
  188. package/dist/s10-inference/context.js +36 -0
  189. package/dist/s10-inference/context.js.map +1 -0
  190. package/dist/s10-inference/index.d.ts +7 -0
  191. package/dist/s10-inference/index.d.ts.map +1 -0
  192. package/dist/s10-inference/index.js +6 -0
  193. package/dist/s10-inference/index.js.map +1 -0
  194. package/dist/s10-inference/loop.d.ts +42 -0
  195. package/dist/s10-inference/loop.d.ts.map +1 -0
  196. package/dist/s10-inference/loop.js +104 -0
  197. package/dist/s10-inference/loop.js.map +1 -0
  198. package/dist/s10-inference/provider.d.ts +43 -0
  199. package/dist/s10-inference/provider.d.ts.map +1 -0
  200. package/dist/s10-inference/provider.js +9 -0
  201. package/dist/s10-inference/provider.js.map +1 -0
  202. package/dist/s10-inference/providers/anthropic.d.ts +13 -0
  203. package/dist/s10-inference/providers/anthropic.d.ts.map +1 -0
  204. package/dist/s10-inference/providers/anthropic.js +168 -0
  205. package/dist/s10-inference/providers/anthropic.js.map +1 -0
  206. package/dist/s10-inference/providers/ollama.d.ts +9 -0
  207. package/dist/s10-inference/providers/ollama.d.ts.map +1 -0
  208. package/dist/s10-inference/providers/ollama.js +102 -0
  209. package/dist/s10-inference/providers/ollama.js.map +1 -0
  210. package/dist/s10-inference/providers/openai.d.ts +14 -0
  211. package/dist/s10-inference/providers/openai.d.ts.map +1 -0
  212. package/dist/s10-inference/providers/openai.js +172 -0
  213. package/dist/s10-inference/providers/openai.js.map +1 -0
  214. package/dist/s11-transport/index.d.ts +4 -0
  215. package/dist/s11-transport/index.d.ts.map +1 -0
  216. package/dist/s11-transport/index.js +4 -0
  217. package/dist/s11-transport/index.js.map +1 -0
  218. package/dist/s11-transport/room.d.ts +28 -0
  219. package/dist/s11-transport/room.d.ts.map +1 -0
  220. package/dist/s11-transport/room.js +69 -0
  221. package/dist/s11-transport/room.js.map +1 -0
  222. package/dist/s11-transport/transport.d.ts +20 -0
  223. package/dist/s11-transport/transport.d.ts.map +1 -0
  224. package/dist/s11-transport/transport.js +39 -0
  225. package/dist/s11-transport/transport.js.map +1 -0
  226. package/dist/s11-transport/ws.d.ts +15 -0
  227. package/dist/s11-transport/ws.d.ts.map +1 -0
  228. package/dist/s11-transport/ws.js +71 -0
  229. package/dist/s11-transport/ws.js.map +1 -0
  230. package/dist/s12-versioncontrol/index.d.ts +4 -0
  231. package/dist/s12-versioncontrol/index.d.ts.map +1 -0
  232. package/dist/s12-versioncontrol/index.js +3 -0
  233. package/dist/s12-versioncontrol/index.js.map +1 -0
  234. package/dist/s12-versioncontrol/ledger-dag.d.ts +25 -0
  235. package/dist/s12-versioncontrol/ledger-dag.d.ts.map +1 -0
  236. package/dist/s12-versioncontrol/ledger-dag.js +84 -0
  237. package/dist/s12-versioncontrol/ledger-dag.js.map +1 -0
  238. package/dist/s12-versioncontrol/merkle.d.ts +16 -0
  239. package/dist/s12-versioncontrol/merkle.d.ts.map +1 -0
  240. package/dist/s12-versioncontrol/merkle.js +81 -0
  241. package/dist/s12-versioncontrol/merkle.js.map +1 -0
  242. package/dist/s12-versioncontrol/types.d.ts +50 -0
  243. package/dist/s12-versioncontrol/types.d.ts.map +1 -0
  244. package/dist/s12-versioncontrol/types.js +8 -0
  245. package/dist/s12-versioncontrol/types.js.map +1 -0
  246. package/dist/touches/audio-tap.d.ts +32 -0
  247. package/dist/touches/audio-tap.d.ts.map +1 -0
  248. package/dist/touches/audio-tap.js +54 -0
  249. package/dist/touches/audio-tap.js.map +1 -0
  250. package/dist/touches/avatar-state.d.ts +22 -0
  251. package/dist/touches/avatar-state.d.ts.map +1 -0
  252. package/dist/touches/avatar-state.js +35 -0
  253. package/dist/touches/avatar-state.js.map +1 -0
  254. package/dist/touches/container-room.d.ts +17 -0
  255. package/dist/touches/container-room.d.ts.map +1 -0
  256. package/dist/touches/container-room.js +34 -0
  257. package/dist/touches/container-room.js.map +1 -0
  258. package/dist/touches/cost-billing.d.ts +20 -0
  259. package/dist/touches/cost-billing.d.ts.map +1 -0
  260. package/dist/touches/cost-billing.js +26 -0
  261. package/dist/touches/cost-billing.js.map +1 -0
  262. package/dist/touches/cost-track.d.ts +19 -0
  263. package/dist/touches/cost-track.d.ts.map +1 -0
  264. package/dist/touches/cost-track.js +20 -0
  265. package/dist/touches/cost-track.js.map +1 -0
  266. package/dist/touches/crdt-sync.d.ts +14 -0
  267. package/dist/touches/crdt-sync.d.ts.map +1 -0
  268. package/dist/touches/crdt-sync.js +49 -0
  269. package/dist/touches/crdt-sync.js.map +1 -0
  270. package/dist/touches/identity-gate.d.ts +22 -0
  271. package/dist/touches/identity-gate.d.ts.map +1 -0
  272. package/dist/touches/identity-gate.js +24 -0
  273. package/dist/touches/identity-gate.js.map +1 -0
  274. package/dist/touches/index.d.ts +14 -0
  275. package/dist/touches/index.d.ts.map +1 -0
  276. package/dist/touches/index.js +14 -0
  277. package/dist/touches/index.js.map +1 -0
  278. package/dist/touches/memory-persist.d.ts +29 -0
  279. package/dist/touches/memory-persist.d.ts.map +1 -0
  280. package/dist/touches/memory-persist.js +49 -0
  281. package/dist/touches/memory-persist.js.map +1 -0
  282. package/dist/touches/messenger-bridge.d.ts +19 -0
  283. package/dist/touches/messenger-bridge.d.ts.map +1 -0
  284. package/dist/touches/messenger-bridge.js +49 -0
  285. package/dist/touches/messenger-bridge.js.map +1 -0
  286. package/dist/touches/sentiment-tap.d.ts +43 -0
  287. package/dist/touches/sentiment-tap.d.ts.map +1 -0
  288. package/dist/touches/sentiment-tap.js +81 -0
  289. package/dist/touches/sentiment-tap.js.map +1 -0
  290. package/dist/touches/stichwort.d.ts +46 -0
  291. package/dist/touches/stichwort.d.ts.map +1 -0
  292. package/dist/touches/stichwort.js +64 -0
  293. package/dist/touches/stichwort.js.map +1 -0
  294. package/dist/touches/transport-signal.d.ts +26 -0
  295. package/dist/touches/transport-signal.d.ts.map +1 -0
  296. package/dist/touches/transport-signal.js +49 -0
  297. package/dist/touches/transport-signal.js.map +1 -0
  298. package/dist/touches/version-persist.d.ts +18 -0
  299. package/dist/touches/version-persist.d.ts.map +1 -0
  300. package/dist/touches/version-persist.js +38 -0
  301. package/dist/touches/version-persist.js.map +1 -0
  302. package/dist/types.d.ts +61 -0
  303. package/dist/types.d.ts.map +1 -0
  304. package/dist/types.js +13 -0
  305. package/dist/types.js.map +1 -0
  306. package/package.json +117 -0
package/README.md ADDED
@@ -0,0 +1,338 @@
1
+ # foundation
2
+
3
+ 12 layers. Native. Zero wrappers.
4
+
5
+ ```
6
+ S01 Realtime S05 Rendering S09 Persistence
7
+ S02 CRDTs S06 Payments S10 Inference
8
+ S03 Streaming S07 Identity S11 Transport
9
+ S04 Messaging S08 Containers S12 Version Control
10
+ ```
11
+
12
+ Foundation is not a framework. It is a protocol for AI agent systems.
13
+
14
+ TCP/IP defined what a network is. Foundation defines what an AI agent system is. Every provider, every transport, every memory tier, every consent model plugs in through the same interfaces. No vendor lock-in. No SDK dependencies. No wrappers.
15
+
16
+ ---
17
+
18
+ ## The Architecture
19
+
20
+ ```
21
+ src/
22
+ ├── sXX-name/ Layers. Each stands alone. No cross-imports.
23
+ ├── touches/ The only bridges between layers. Explicit coupling.
24
+ └── compat/ External system bridges. NOT part of the foundation.
25
+ ```
26
+
27
+ **One rule governs the entire system:** Layers never import from sibling layers. All cross-layer integration goes through `touches/` -- named, tested, explicit connection points. If two layers need to talk, there is a file in `touches/` that says exactly how.
28
+
29
+ ### The 12 Layers
30
+
31
+ | Layer | What it does | Key primitive |
32
+ |-------|-------------|---------------|
33
+ | **S01 Realtime** | WebRTC signaling, media types | `SignalingMessage` (11 types) |
34
+ | **S02 CRDTs** | Distributed state synchronization | `SharedDoc` (interface-first, yjs impl) |
35
+ | **S03 Streaming** | HLS/DASH segmentation, codecs | `Segmenter`, `PlaylistManager` |
36
+ | **S04 Messaging** | Chat, briefings, notifications | `Channel` (platform-agnostic) |
37
+ | **S05 Rendering** | State machines, avatar gestures | `StateMachine<S, E>` (generic) |
38
+ | **S06 Payments** | Billing, subscriptions, usage | `BillingService` (interface-first) |
39
+ | **S07 Identity** | Consent as authorization | `observe / assist / act` |
40
+ | **S08 Containers** | Process isolation, GPU scheduling | `Sandbox`, `GpuScheduler` |
41
+ | **S09 Persistence** | Three-tier cognitive memory | `HOT → WARM → COLD` |
42
+ | **S10 Inference** | Provider-agnostic agent loop | `Provider.stream()` → 4 Chunk types |
43
+ | **S11 Transport** | Network abstraction | `send()` + `receive()` |
44
+ | **S12 Version Control** | Merkle trees for decision audit | `buildTree()`, `verifyProof()` |
45
+
46
+ ### The Touch Points
47
+
48
+ Every connection between layers is a file. Every file is small. The average touch point is 60 lines.
49
+
50
+ ```
51
+ audio-tap.ts S01 ↔ S10 Audio → Transcript → Tokens
52
+ stichwort.ts S01 ↔ S10 Keyword detection (pure pipeline)
53
+ transport-signal.ts S01 ↔ S11 Signaling ↔ Transport events
54
+ crdt-sync.ts S02 ↔ S11 CRDT updates ↔ Transport events
55
+ messenger-bridge.ts S04 ↔ S10 Briefing generation via Loop
56
+ avatar-state.ts S05 ↔ S10 Inference events → Avatar transitions
57
+ cost-billing.ts S06 ↔ Ledger Consent tiers → Pricing tiers
58
+ identity-gate.ts S07 ↔ S10 observe=deny, assist=ask, act=allow
59
+ container-room.ts S08 ↔ S11 Room → Container isolation
60
+ memory-persist.ts S09 ↔ S10 HOT → compact → WARM → flush → COLD
61
+ cost-track.ts S10 ↔ Ledger Usage → Cost tracking
62
+ version-persist.ts S12 ↔ S09 Merkle DAG → COLD storage
63
+ sentiment-tap.ts S01 ↔ S10 Audio → Emotion → Dynamics
64
+ ```
65
+
66
+ ---
67
+
68
+ ## The Numbers
69
+
70
+ ```
71
+ 74 source files 43 test suites 376 tests
72
+ 12/12 layers 13 touch points 3 runtime deps
73
+ 3 providers 0 SDK wrappers 0 AI framework imports
74
+ 5 production backends (Postgres, S3, Stripe, Docker, Observability)
75
+ ```
76
+
77
+ Three runtime dependencies. Each is infrastructure, not abstraction:
78
+
79
+ | Dependency | Why |
80
+ |------------|-----|
81
+ | `better-sqlite3` | WARM memory (S09) |
82
+ | `ws` | WebSocket transport (S11) |
83
+ | `yjs` | CRDT implementation (S02) |
84
+
85
+ ---
86
+
87
+ ## Quick Start
88
+
89
+ ```bash
90
+ npm install
91
+ npm test # 347 tests
92
+ npm run check # tsc --noEmit
93
+ npm run build # emit dist/
94
+ ```
95
+
96
+ ### Use a provider
97
+
98
+ ```typescript
99
+ import { createOllamaProvider, loop, createContext } from 'foundation'
100
+
101
+ const provider = createOllamaProvider() // localhost:11434
102
+ const ctx = createContext({ model: 'qwen2.5:3b', root: '.' })
103
+
104
+ const gen = loop({
105
+ messages: [{ id: '1', role: 'user', content: 'Hello', ts: Date.now() }],
106
+ system: 'Be helpful.',
107
+ actions: [],
108
+ provider,
109
+ ctx,
110
+ })
111
+
112
+ for await (const msg of gen) {
113
+ console.log(msg.role, typeof msg.content === 'string' ? msg.content : '[blocks]')
114
+ }
115
+ ```
116
+
117
+ ### Add actions
118
+
119
+ ```typescript
120
+ import { ok, type Action } from 'foundation'
121
+
122
+ const search: Action = {
123
+ name: 'search',
124
+ schema: { name: 'search', description: 'Search', parameters: { type: 'object', properties: { q: { type: 'string' } } } },
125
+ concurrent: true,
126
+ validate: (input) => ok(input),
127
+ gate: () => 'allow',
128
+ execute: async (input) => ok(`Results for ${JSON.stringify(input)}`),
129
+ }
130
+
131
+ // Pass to loop({ ... actions: [search] })
132
+ // The loop calls validate → gate → execute, batches concurrent actions
133
+ ```
134
+
135
+ ### Three-tier memory
136
+
137
+ ```typescript
138
+ import { createHotMemory, createWarmMemory, createFsColdMemory, createMemoryStack } from 'foundation'
139
+
140
+ const hot = createHotMemory({ budget: 50_000 })
141
+ const warm = createWarmMemory('./data/warm.db')
142
+ const cold = createFsColdMemory('./data/cold')
143
+ const memory = createMemoryStack(hot, warm, cold)
144
+
145
+ // During session: memory.maintain(50_000) compacts when over budget
146
+ // End of session: memory.flushToCold('session-id') archives everything
147
+ ```
148
+
149
+ ### Consent as a layer
150
+
151
+ ```typescript
152
+ import { createIdentity, consentToGate } from 'foundation'
153
+
154
+ const identity = createIdentity()
155
+ const session = identity.initDefaults('user-1')
156
+
157
+ // Check: can this agent suggest queue items?
158
+ const gate = consentToGate(identity, session, { feature: 'queue_suggest', required: 'assist' })
159
+ // gate === 'ask' (assist level = host must approve)
160
+
161
+ // Upgrade to autonomous
162
+ identity.setScope(session, 'queue_suggest', 'act')
163
+ const gate2 = consentToGate(identity, session, { feature: 'queue_suggest', required: 'assist' })
164
+ // gate2 === 'allow' (act level = agent can act autonomously)
165
+ ```
166
+
167
+ ### Multi-agent
168
+
169
+ ```typescript
170
+ import { createAgentRegistry, createOllamaProvider, createAnthropicProvider } from 'foundation'
171
+
172
+ const registry = createAgentRegistry()
173
+
174
+ registry.register({
175
+ name: 'sebastian-edge',
176
+ role: 'classifier',
177
+ provider: createOllamaProvider(),
178
+ model: 'qwen2.5:3b',
179
+ mode: 'act',
180
+ budgetCents: 100,
181
+ })
182
+
183
+ registry.register({
184
+ name: 'sebastian-cloud',
185
+ role: 'researcher',
186
+ provider: createAnthropicProvider({ apiKey: '...' }),
187
+ model: 'claude-sonnet-4-6',
188
+ mode: 'assist',
189
+ budgetCents: 5000,
190
+ })
191
+
192
+ registry.perAgent() // cost breakdown per agent
193
+ registry.perOrg() // aggregated per organization
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Design Decisions
199
+
200
+ ### Errors are values
201
+
202
+ ```typescript
203
+ type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E }
204
+ ```
205
+
206
+ No exceptions for control flow. Every function that can fail returns `Result`. Pattern-match on `ok`, not try-catch.
207
+
208
+ ### 4 chunk types standardize all providers
209
+
210
+ ```typescript
211
+ type Chunk =
212
+ | { type: 'text'; text: string }
213
+ | { type: 'action_call'; id: string; name: string; input: unknown }
214
+ | { type: 'usage'; tokens: TokenUsage }
215
+ | { type: 'done'; reason: 'complete' | 'action_calls' }
216
+ ```
217
+
218
+ Ollama, Anthropic, OpenAI -- all produce the same 4 chunk types. The loop doesn't know which provider it's talking to.
219
+
220
+ ### Interface first, implementation second
221
+
222
+ Every layer defines its contract as a TypeScript type. The implementation is one of many possible:
223
+
224
+ - `Provider` interface → Ollama, Anthropic, OpenAI implementations
225
+ - `SharedDoc` interface → yjs implementation (Automerge, diamond-types possible)
226
+ - `Transport` interface → WebSocket, local, IPC implementations
227
+ - `ColdMemory` interface → Filesystem + S3/R2 implementations
228
+ - `BillingService` interface → In-memory + Stripe implementations
229
+ - `Sandbox` interface → In-memory + Docker implementations
230
+
231
+ ### Open unions
232
+
233
+ Every union type is extensible:
234
+
235
+ ```typescript
236
+ type EntryCategory = 'decision' | 'fact' | 'action_item' | ... | (string & {})
237
+ type ArtifactType = 'transcript' | 'document' | 'media' | ... | (string & {})
238
+ type Feature = 'listening' | 'mirror_mode' | ... | (string & {})
239
+ ```
240
+
241
+ No layer is closed. No external system is locked out.
242
+
243
+ ### Consent is not a feature -- it is infrastructure
244
+
245
+ Three levels. Three meanings. One mapping:
246
+
247
+ ```
248
+ observe → deny (can only watch)
249
+ assist → ask (can suggest, host approves)
250
+ act → allow (autonomous action)
251
+ ```
252
+
253
+ This maps 1:1 to pricing tiers (free/professional/enterprise), gate decisions (deny/ask/allow), and autonomy levels. It is the single most load-bearing abstraction in the system.
254
+
255
+ ---
256
+
257
+ ## What Emerges
258
+
259
+ Properties that no single layer has alone:
260
+
261
+ | Combination | Emergence |
262
+ |-------------|-----------|
263
+ | S07 + S10 | Ethical autonomy -- consent gates action execution |
264
+ | S09 HOT+WARM+COLD | Cognitive memory -- compaction = memory formation |
265
+ | S06 + S07 | Monetized autonomy -- consent levels = pricing tiers |
266
+ | S08 + S10 | Isolated execution -- each agent in its own sandbox |
267
+ | S12 + S09 | Auditable history -- Merkle proofs for every decision |
268
+ | All 12 layers | Mirror Mode -- autonomous agent with ethical boundary, cost limit, audit trail, visual transparency |
269
+
270
+ ---
271
+
272
+ ## The Proof
273
+
274
+ The architecture was validated empirically, not by argument:
275
+
276
+ **376 tests** prove that layers compose. Integration tests cross layer boundaries. E2E tests hit real Ollama and real WebSocket servers.
277
+
278
+ **4 Butler adapters under 100 lines each** prove that the interfaces match reality. The prediction was made before M1. The proof came at M13. Thin adapters = correct abstractions.
279
+
280
+ **0room0 imports Foundation** for Memory, Consent, Provider, StateMachine. The first external consumer confirmed: Foundation types flow cleanly into a real product with 346 tests.
281
+
282
+ ---
283
+
284
+ ## Project Structure
285
+
286
+ ```
287
+ foundation/
288
+ ├── src/
289
+ │ ├── index.ts Public API
290
+ │ ├── types.ts Result, Message, Entry, Event
291
+ │ ├── ledger.ts Cost tracking
292
+ │ │
293
+ │ ├── s01-realtime/ WebRTC signaling + media types
294
+ │ ├── s02-crdt/ SharedDoc interface + yjs
295
+ │ ├── s03-streaming/ HLS segmentation + playlists
296
+ │ ├── s04-messaging/ Chat, briefings, channels
297
+ │ ├── s05-rendering/ StateMachine + avatar gestures
298
+ │ ├── s06-payments/ Billing + subscriptions
299
+ │ ├── s07-identity/ Consent (observe/assist/act)
300
+ │ ├── s08-containers/ Sandbox + GPU scheduler
301
+ │ ├── s09-persistence/ HOT (memory) + WARM (SQLite) + COLD (fs)
302
+ │ ├── s10-inference/ Provider → Action → Loop
303
+ │ │ ├── providers/ Ollama, Anthropic, OpenAI (raw fetch)
304
+ │ │ └── agents/ Multi-agent registry, mirror mode
305
+ │ ├── s11-transport/ Transport + WebSocket + Room
306
+ │ ├── s12-versioncontrol/ Merkle trees + DAG
307
+ │ │
308
+ │ ├── touches/ 13 cross-layer bridges
309
+ │ └── compat/ External system bridges
310
+
311
+ ├── tests/
312
+ │ ├── s01/ ... s12/ Unit tests per layer
313
+ │ ├── touches/ Touch point tests
314
+ │ ├── integration/ Cross-layer composition tests
315
+ │ └── e2e/ Live Ollama + WebSocket tests
316
+
317
+ ├── ROADMAP.md 23-milestone plan (completed)
318
+ └── M14-PLAN.md 0room0 integration playbook
319
+ ```
320
+
321
+ ---
322
+
323
+ ## TypeScript
324
+
325
+ ```json
326
+ {
327
+ "strict": true,
328
+ "noUncheckedIndexedAccess": true,
329
+ "target": "ES2022",
330
+ "module": "NodeNext"
331
+ }
332
+ ```
333
+
334
+ No `any`. No unguarded index access. `Result<T,E>` everywhere. `Context<Ext>` is generic for type-safe domain extensions.
335
+
336
+ ---
337
+
338
+ *Built in one session. 23 milestones. Two parallel agents -- one builds, one observes. Every correction was applied. Every blind spot was closed. The foundation holds.*
@@ -0,0 +1,33 @@
1
+ /**
2
+ * COMPAT — Cloud Butler Adapter
3
+ *
4
+ * Wraps Foundation Provider + Loop + Actions als CloudButler Interface.
5
+ * Der Cloud-Butler exekutiert: research, draft, create, validate, summarize.
6
+ * Bekommt Query vom Edge-Butler, liefert Material für die Queue.
7
+ *
8
+ * Messpunkt: Unter 100 Zeilen = Interfaces stimmen.
9
+ */
10
+ import type { Provider } from '../s10-inference/provider.js';
11
+ import type { Context } from '../s10-inference/context.js';
12
+ import type { Action } from '../s10-inference/action.js';
13
+ import { type Result } from '../types.js';
14
+ export type CloudTaskType = 'research' | 'draft' | 'create' | 'validate' | 'summarize' | (string & {});
15
+ export type CloudTask = {
16
+ type: CloudTaskType;
17
+ query: string;
18
+ maxTokens?: number;
19
+ priority?: 'low' | 'normal' | 'high';
20
+ };
21
+ export type CloudOutput = {
22
+ title: string;
23
+ summary: string;
24
+ content: string;
25
+ confidence: number;
26
+ sources: string[];
27
+ gaps: string[];
28
+ };
29
+ export type CloudButler = {
30
+ execute(task: CloudTask, ledgerContext: string): Promise<Result<CloudOutput, string>>;
31
+ };
32
+ export declare function createCloudButler(provider: Provider, actions: readonly Action[], ctx: Context): CloudButler;
33
+ //# sourceMappingURL=butler-cloud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butler-cloud.d.ts","sourceRoot":"","sources":["../../src/compat/butler-cloud.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAExD,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEtG,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,aAAa,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;CACrC,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,MAAM,EAAE,CAAA;CACf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;CACtF,CAAA;AAQD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,GAAG,EAAE,OAAO,GACX,WAAW,CAkDb"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * COMPAT — Cloud Butler Adapter
3
+ *
4
+ * Wraps Foundation Provider + Loop + Actions als CloudButler Interface.
5
+ * Der Cloud-Butler exekutiert: research, draft, create, validate, summarize.
6
+ * Bekommt Query vom Edge-Butler, liefert Material für die Queue.
7
+ *
8
+ * Messpunkt: Unter 100 Zeilen = Interfaces stimmen.
9
+ */
10
+ import { loop } from '../s10-inference/loop.js';
11
+ import { ok, err } from '../types.js';
12
+ const CLOUD_SYSTEM_PROMPT = `Du bist Sebastian-Außen, ein Research-Butler.
13
+ Du erfindest NICHTS. Keine Quellen = keine Antwort. Wahrheit vor Höflichkeit.
14
+ Antworte als JSON: {"title":"...","summary":"...","content":"...","confidence":0.0-1.0,"sources":["..."],"gaps":["..."]}
15
+ confidence: high(>0.7), medium(0.4-0.7), low(<0.4). Sei ehrlich.
16
+ gaps: Was fehlt? Was konntest du nicht prüfen?`;
17
+ export function createCloudButler(provider, actions, ctx) {
18
+ return {
19
+ async execute(task, ledgerContext) {
20
+ const userMsg = [
21
+ `Aufgabe: ${task.type}`,
22
+ `Frage: ${task.query}`,
23
+ ledgerContext ? `Kontext:\n${ledgerContext}` : '',
24
+ ].filter(Boolean).join('\n');
25
+ const gen = loop({
26
+ messages: [{ id: 'cloud-in', role: 'user', content: userMsg, ts: Date.now() }],
27
+ system: CLOUD_SYSTEM_PROMPT,
28
+ actions,
29
+ provider,
30
+ ctx,
31
+ budget: 7, // ADR: Max 7 Tool-Calls pro Turn
32
+ });
33
+ let responseText = '';
34
+ for (;;) {
35
+ const { value, done } = await gen.next();
36
+ if (done)
37
+ break;
38
+ if (value.role === 'assistant' && typeof value.content === 'string') {
39
+ responseText = value.content;
40
+ }
41
+ // Bei ContentBlock[] den letzten Text extrahieren
42
+ if (value.role === 'assistant' && Array.isArray(value.content)) {
43
+ for (const block of value.content) {
44
+ if (block.type === 'text')
45
+ responseText = block.text;
46
+ }
47
+ }
48
+ }
49
+ try {
50
+ const match = responseText.match(/\{[\s\S]*\}/);
51
+ if (!match)
52
+ return err('Cloud-Butler: No JSON in response');
53
+ const parsed = JSON.parse(match[0]);
54
+ return ok({
55
+ title: parsed.title ?? task.query,
56
+ summary: parsed.summary ?? '',
57
+ content: parsed.content ?? '',
58
+ confidence: parsed.confidence ?? 0.5,
59
+ sources: Array.isArray(parsed.sources) ? parsed.sources : [],
60
+ gaps: Array.isArray(parsed.gaps) ? parsed.gaps : [],
61
+ });
62
+ }
63
+ catch {
64
+ return err('Cloud-Butler: Failed to parse response');
65
+ }
66
+ },
67
+ };
68
+ }
69
+ //# sourceMappingURL=butler-cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butler-cloud.js","sourceRoot":"","sources":["../../src/compat/butler-cloud.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * COMPAT — Edge Butler Adapter
3
+ *
4
+ * Wraps Foundation Provider + Loop als EdgeButler Interface.
5
+ * Der Edge-Butler klassifiziert: IGNORE, OBSERVE, ROUTE_CLOUD, ALERT.
6
+ * Kein Chat, kein Draft — nur Routing + Gesture + Ledger-Eintrag.
7
+ *
8
+ * Messpunkt: Unter 100 Zeilen = Interfaces stimmen.
9
+ */
10
+ import type { Provider } from '../s10-inference/provider.js';
11
+ import type { Context } from '../s10-inference/context.js';
12
+ import type { GestureType } from '../s05-rendering/types.js';
13
+ import { type Result } from '../types.js';
14
+ export type EdgeIntent = 'ignore' | 'observe' | 'route_cloud' | 'alert';
15
+ export type EdgeInput = {
16
+ triggeredKeyword?: string;
17
+ ledgerSnapshot: string;
18
+ roomContext: {
19
+ roomId: string;
20
+ participants: string[];
21
+ activeSpeaker?: string;
22
+ };
23
+ };
24
+ export type EdgeOutput = {
25
+ intent: EdgeIntent;
26
+ gesture?: GestureType;
27
+ ledgerEntry?: string;
28
+ cloudQuery?: string;
29
+ };
30
+ export type EdgeButler = {
31
+ process(input: EdgeInput): Promise<Result<EdgeOutput, string>>;
32
+ };
33
+ export declare function createEdgeButler(provider: Provider, ctx: Context): EdgeButler;
34
+ //# sourceMappingURL=butler-edge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butler-edge.d.ts","sourceRoot":"","sources":["../../src/compat/butler-edge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAA;AAE5D,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,CAAA;AAEvE,MAAM,MAAM,SAAS,GAAG;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE;QACX,MAAM,EAAE,MAAM,CAAA;QACd,YAAY,EAAE,MAAM,EAAE,CAAA;QACtB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,CAAA;IAClB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;CAC/D,CAAA;AASD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,UAAU,CA2C7E"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * COMPAT — Edge Butler Adapter
3
+ *
4
+ * Wraps Foundation Provider + Loop als EdgeButler Interface.
5
+ * Der Edge-Butler klassifiziert: IGNORE, OBSERVE, ROUTE_CLOUD, ALERT.
6
+ * Kein Chat, kein Draft — nur Routing + Gesture + Ledger-Eintrag.
7
+ *
8
+ * Messpunkt: Unter 100 Zeilen = Interfaces stimmen.
9
+ */
10
+ import { loop } from '../s10-inference/loop.js';
11
+ import { ok, err } from '../types.js';
12
+ const EDGE_SYSTEM_PROMPT = `Du bist Sebastian-Innen, ein Edge-Classifier.
13
+ Antworte NUR als JSON: {"intent":"ignore"|"observe"|"route_cloud"|"alert","gesture":"idle"|"nodding"|"bowing"|"hand_raise","ledgerEntry":"...oder null","cloudQuery":"...oder null"}
14
+ Kein Fließtext. Kein Markdown. Nur JSON.
15
+ Wenn Stichwort erkannt → intent: route_cloud, cloudQuery formulieren.
16
+ Wenn nichts relevant → intent: ignore.
17
+ Max 150 Zeichen für ledgerEntry.`;
18
+ export function createEdgeButler(provider, ctx) {
19
+ return {
20
+ async process(input) {
21
+ const userMsg = [
22
+ input.triggeredKeyword ? `Stichwort: "${input.triggeredKeyword}"` : '',
23
+ `Raum: ${input.roomContext.roomId}, ${input.roomContext.participants.length} Teilnehmer`,
24
+ input.roomContext.activeSpeaker ? `Spricht: ${input.roomContext.activeSpeaker}` : '',
25
+ `Ledger:\n${input.ledgerSnapshot}`,
26
+ ].filter(Boolean).join('\n');
27
+ const gen = loop({
28
+ messages: [{ id: 'edge-in', role: 'user', content: userMsg, ts: Date.now() }],
29
+ system: EDGE_SYSTEM_PROMPT,
30
+ actions: [],
31
+ provider,
32
+ ctx,
33
+ budget: 1,
34
+ });
35
+ let responseText = '';
36
+ for (;;) {
37
+ const { value, done } = await gen.next();
38
+ if (done)
39
+ break;
40
+ if (value.role === 'assistant' && typeof value.content === 'string') {
41
+ responseText = value.content;
42
+ }
43
+ }
44
+ try {
45
+ const match = responseText.match(/\{[\s\S]*\}/);
46
+ if (!match)
47
+ return err('Edge-Butler: No JSON in response');
48
+ const parsed = JSON.parse(match[0]);
49
+ return ok({
50
+ intent: parsed.intent ?? 'ignore',
51
+ gesture: parsed.gesture ?? 'idle',
52
+ ledgerEntry: parsed.ledgerEntry,
53
+ cloudQuery: parsed.cloudQuery,
54
+ });
55
+ }
56
+ catch {
57
+ return err('Edge-Butler: Failed to parse response');
58
+ }
59
+ },
60
+ };
61
+ }
62
+ //# sourceMappingURL=butler-edge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butler-edge.js","sourceRoot":"","sources":["../../src/compat/butler-edge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAA;AAC/C,OAAO,EAAE,EAAE,EAAE,GAAG,EAAe,MAAM,aAAa,CAAA;AAyBlD,MAAM,kBAAkB,GAAG;;;;;iCAKM,CAAA;AAEjC,MAAM,UAAU,gBAAgB,CAAC,QAAkB,EAAE,GAAY;IAC/D,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,MAAM,OAAO,GAAG;gBACd,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,eAAe,KAAK,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,EAAE;gBACtE,SAAS,KAAK,CAAC,WAAW,CAAC,MAAM,KAAK,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,MAAM,aAAa;gBACxF,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE;gBACpF,YAAY,KAAK,CAAC,cAAc,EAAE;aACnC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAE5B,MAAM,GAAG,GAAG,IAAI,CAAC;gBACf,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAC7E,MAAM,EAAE,kBAAkB;gBAC1B,OAAO,EAAE,EAAE;gBACX,QAAQ;gBACR,GAAG;gBACH,MAAM,EAAE,CAAC;aACV,CAAC,CAAA;YAEF,IAAI,YAAY,GAAG,EAAE,CAAA;YACrB,SAAS,CAAC;gBACR,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;gBACxC,IAAI,IAAI;oBAAE,MAAK;gBACf,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACpE,YAAY,GAAG,KAAK,CAAC,OAAO,CAAA;gBAC9B,CAAC;YACH,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;gBAC/C,IAAI,CAAC,KAAK;oBAAE,OAAO,GAAG,CAAC,kCAAkC,CAAC,CAAA;gBAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAA4B,CAAA;gBAC9D,OAAO,EAAE,CAAC;oBACR,MAAM,EAAG,MAAM,CAAC,MAAqB,IAAI,QAAQ;oBACjD,OAAO,EAAG,MAAM,CAAC,OAAuB,IAAI,MAAM;oBAClD,WAAW,EAAE,MAAM,CAAC,WAAiC;oBACrD,UAAU,EAAE,MAAM,CAAC,UAAgC;iBACpD,CAAC,CAAA;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,CAAC,uCAAuC,CAAC,CAAA;YACrD,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * COMPAT — Butler Pair Factory
3
+ *
4
+ * Erzeugt Edge + Cloud Butler Paar mit SharedDoc für State-Sync.
5
+ * Ein Aufruf, alles verdrahtet.
6
+ */
7
+ import type { Provider } from '../s10-inference/provider.js';
8
+ import type { Action } from '../s10-inference/action.js';
9
+ import { type Context, type GateMode } from '../s10-inference/context.js';
10
+ import type { SharedDocWithAccessors } from '../s02-crdt/types.js';
11
+ import { type EdgeButler } from './butler-edge.js';
12
+ import { type CloudButler } from './butler-cloud.js';
13
+ export type ButlerPair = {
14
+ edge: EdgeButler;
15
+ cloud: CloudButler;
16
+ shared: SharedDocWithAccessors;
17
+ edgeCtx: Context;
18
+ cloudCtx: Context;
19
+ };
20
+ export declare function createButlerPair(opts: {
21
+ edgeProvider: Provider;
22
+ cloudProvider: Provider;
23
+ cloudActions?: readonly Action[];
24
+ root: string;
25
+ mode?: GateMode;
26
+ }): ButlerPair;
27
+ //# sourceMappingURL=butler-pair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butler-pair.d.ts","sourceRoot":"","sources":["../../src/compat/butler-pair.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAiB,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAExF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACpE,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEvE,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,UAAU,CAAA;IAChB,KAAK,EAAE,WAAW,CAAA;IAClB,MAAM,EAAE,sBAAsB,CAAA;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,YAAY,EAAE,QAAQ,CAAA;IACtB,aAAa,EAAE,QAAQ,CAAA;IACvB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB,GAAG,UAAU,CAYb"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * COMPAT — Butler Pair Factory
3
+ *
4
+ * Erzeugt Edge + Cloud Butler Paar mit SharedDoc für State-Sync.
5
+ * Ein Aufruf, alles verdrahtet.
6
+ */
7
+ import { createContext } from '../s10-inference/context.js';
8
+ import { createYjsDoc } from '../s02-crdt/yjs.js';
9
+ import { createEdgeButler } from './butler-edge.js';
10
+ import { createCloudButler } from './butler-cloud.js';
11
+ export function createButlerPair(opts) {
12
+ const shared = createYjsDoc();
13
+ const edgeCtx = createContext({ model: 'edge', root: opts.root, mode: opts.mode });
14
+ const cloudCtx = createContext({ model: 'cloud', root: opts.root, mode: opts.mode });
15
+ return {
16
+ edge: createEdgeButler(opts.edgeProvider, edgeCtx),
17
+ cloud: createCloudButler(opts.cloudProvider, opts.cloudActions ?? [], cloudCtx),
18
+ shared,
19
+ edgeCtx,
20
+ cloudCtx,
21
+ };
22
+ }
23
+ //# sourceMappingURL=butler-pair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butler-pair.js","sourceRoot":"","sources":["../../src/compat/butler-pair.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,aAAa,EAA+B,MAAM,6BAA6B,CAAA;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAoB,MAAM,mBAAmB,CAAA;AAUvE,MAAM,UAAU,gBAAgB,CAAC,IAMhC;IACC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAA;IAC7B,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAClF,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAEpF,OAAO;QACL,IAAI,EAAE,gBAAgB,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;QAClD,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE,EAAE,QAAQ,CAAC;QAC/E,MAAM;QACN,OAAO;QACP,QAAQ;KACT,CAAA;AACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * COMPAT — Entry ↔ LedgerEntry Adapter
3
+ *
4
+ * Lebt in compat/, NICHT in touches/ oder sXX/.
5
+ * compat/ ist die Brücke zu externen Typsystemen.
6
+ * Foundation kennt keine externen Types.
7
+ * Dieser Adapter kennt beide Seiten.
8
+ *
9
+ * Observer-Korrektur #1: Klare Positionierung außerhalb des Schichten-Modells.
10
+ */
11
+ import type { Entry } from '../types.js';
12
+ /**
13
+ * 0room0's LedgerEntry Type (gespiegelt, nicht importiert).
14
+ * Foundation importiert NICHT aus 0room0. Die Struktur wird hier definiert.
15
+ */
16
+ export type LedgerEntry = {
17
+ text: string;
18
+ timestamp: Date;
19
+ participants: string[];
20
+ category: string;
21
+ sessionId: string;
22
+ embedding?: Float32Array;
23
+ };
24
+ export declare function ledgerToEntry(ledger: LedgerEntry): Entry;
25
+ export declare function entryToLedger(entry: Entry): LedgerEntry;
26
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/compat/entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAiB,MAAM,aAAa,CAAA;AAEvD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,IAAI,CAAA;IACf,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,YAAY,CAAA;CACzB,CAAA;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAWxD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,CAUvD"}