@retinue/agentkit 0.1.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 (405) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +310 -0
  3. package/dist/adapters/bullmq/consumer.d.ts +33 -0
  4. package/dist/adapters/bullmq/consumer.js +41 -0
  5. package/dist/adapters/bullmq/dispatcher.d.ts +74 -0
  6. package/dist/adapters/bullmq/dispatcher.js +160 -0
  7. package/dist/adapters/bullmq/export.d.ts +31 -0
  8. package/dist/adapters/bullmq/export.js +53 -0
  9. package/dist/adapters/bullmq/extraction.d.ts +42 -0
  10. package/dist/adapters/bullmq/extraction.js +63 -0
  11. package/dist/adapters/bullmq/index.d.ts +13 -0
  12. package/dist/adapters/bullmq/index.js +13 -0
  13. package/dist/adapters/bullmq/lock.d.ts +77 -0
  14. package/dist/adapters/bullmq/lock.js +126 -0
  15. package/dist/adapters/bullmq/queue.d.ts +50 -0
  16. package/dist/adapters/bullmq/queue.js +81 -0
  17. package/dist/adapters/memory/artifact-exports.d.ts +11 -0
  18. package/dist/adapters/memory/artifact-exports.js +102 -0
  19. package/dist/adapters/memory/artifacts.d.ts +15 -0
  20. package/dist/adapters/memory/artifacts.js +134 -0
  21. package/dist/adapters/memory/blobs.d.ts +7 -0
  22. package/dist/adapters/memory/blobs.js +27 -0
  23. package/dist/adapters/memory/evaluation.d.ts +18 -0
  24. package/dist/adapters/memory/evaluation.js +148 -0
  25. package/dist/adapters/memory/files.d.ts +27 -0
  26. package/dist/adapters/memory/files.js +0 -0
  27. package/dist/adapters/memory/flows.d.ts +16 -0
  28. package/dist/adapters/memory/flows.js +117 -0
  29. package/dist/adapters/memory/hitl.d.ts +9 -0
  30. package/dist/adapters/memory/hitl.js +130 -0
  31. package/dist/adapters/memory/idempotency.d.ts +13 -0
  32. package/dist/adapters/memory/idempotency.js +32 -0
  33. package/dist/adapters/memory/index.d.ts +39 -0
  34. package/dist/adapters/memory/index.js +107 -0
  35. package/dist/adapters/memory/knowledge.d.ts +43 -0
  36. package/dist/adapters/memory/knowledge.js +248 -0
  37. package/dist/adapters/memory/mcp.d.ts +9 -0
  38. package/dist/adapters/memory/mcp.js +37 -0
  39. package/dist/adapters/memory/message-store.d.ts +17 -0
  40. package/dist/adapters/memory/message-store.js +70 -0
  41. package/dist/adapters/memory/principal-memory.d.ts +7 -0
  42. package/dist/adapters/memory/principal-memory.js +83 -0
  43. package/dist/adapters/memory/runtime.d.ts +29 -0
  44. package/dist/adapters/memory/runtime.js +0 -0
  45. package/dist/adapters/memory/sessions.d.ts +29 -0
  46. package/dist/adapters/memory/sessions.js +0 -0
  47. package/dist/adapters/memory/skills.d.ts +10 -0
  48. package/dist/adapters/memory/skills.js +41 -0
  49. package/dist/adapters/memory/thread-summary.d.ts +7 -0
  50. package/dist/adapters/memory/thread-summary.js +29 -0
  51. package/dist/adapters/memory/usage-limits.d.ts +13 -0
  52. package/dist/adapters/memory/usage-limits.js +72 -0
  53. package/dist/adapters/memory/usage.d.ts +16 -0
  54. package/dist/adapters/memory/usage.js +279 -0
  55. package/dist/adapters/otel/index.d.ts +111 -0
  56. package/dist/adapters/otel/index.js +133 -0
  57. package/dist/adapters/postgres/artifact-exports.d.ts +12 -0
  58. package/dist/adapters/postgres/artifact-exports.js +117 -0
  59. package/dist/adapters/postgres/artifacts.d.ts +16 -0
  60. package/dist/adapters/postgres/artifacts.js +172 -0
  61. package/dist/adapters/postgres/checkpoint-store.d.ts +16 -0
  62. package/dist/adapters/postgres/checkpoint-store.js +34 -0
  63. package/dist/adapters/postgres/config.d.ts +15 -0
  64. package/dist/adapters/postgres/config.js +187 -0
  65. package/dist/adapters/postgres/conversation-store.d.ts +4 -0
  66. package/dist/adapters/postgres/conversation-store.js +82 -0
  67. package/dist/adapters/postgres/evaluation.d.ts +17 -0
  68. package/dist/adapters/postgres/evaluation.js +193 -0
  69. package/dist/adapters/postgres/file-content.d.ts +30 -0
  70. package/dist/adapters/postgres/file-content.js +111 -0
  71. package/dist/adapters/postgres/files.d.ts +19 -0
  72. package/dist/adapters/postgres/files.js +209 -0
  73. package/dist/adapters/postgres/flows.d.ts +20 -0
  74. package/dist/adapters/postgres/flows.js +206 -0
  75. package/dist/adapters/postgres/hitl.d.ts +5 -0
  76. package/dist/adapters/postgres/hitl.js +247 -0
  77. package/dist/adapters/postgres/index.d.ts +35 -0
  78. package/dist/adapters/postgres/index.js +35 -0
  79. package/dist/adapters/postgres/knowledge.d.ts +48 -0
  80. package/dist/adapters/postgres/knowledge.js +255 -0
  81. package/dist/adapters/postgres/memory.d.ts +14 -0
  82. package/dist/adapters/postgres/memory.js +194 -0
  83. package/dist/adapters/postgres/message-store.d.ts +11 -0
  84. package/dist/adapters/postgres/message-store.js +145 -0
  85. package/dist/adapters/postgres/migrations.d.ts +69 -0
  86. package/dist/adapters/postgres/migrations.js +1594 -0
  87. package/dist/adapters/postgres/pg-executor.d.ts +19 -0
  88. package/dist/adapters/postgres/pg-executor.js +32 -0
  89. package/dist/adapters/postgres/retention.d.ts +26 -0
  90. package/dist/adapters/postgres/retention.js +59 -0
  91. package/dist/adapters/postgres/rollups.d.ts +17 -0
  92. package/dist/adapters/postgres/rollups.js +267 -0
  93. package/dist/adapters/postgres/run-coordinator.d.ts +5 -0
  94. package/dist/adapters/postgres/run-coordinator.js +98 -0
  95. package/dist/adapters/postgres/run-event-log.d.ts +26 -0
  96. package/dist/adapters/postgres/run-event-log.js +30 -0
  97. package/dist/adapters/postgres/run-store.d.ts +4 -0
  98. package/dist/adapters/postgres/run-store.js +199 -0
  99. package/dist/adapters/postgres/schema.d.ts +39 -0
  100. package/dist/adapters/postgres/schema.js +70 -0
  101. package/dist/adapters/postgres/session-state.d.ts +7 -0
  102. package/dist/adapters/postgres/session-state.js +99 -0
  103. package/dist/adapters/postgres/sql.d.ts +8 -0
  104. package/dist/adapters/postgres/sql.js +2 -0
  105. package/dist/adapters/postgres/transaction.d.ts +37 -0
  106. package/dist/adapters/postgres/transaction.js +93 -0
  107. package/dist/adapters/postgres/unit-of-work.d.ts +18 -0
  108. package/dist/adapters/postgres/unit-of-work.js +8 -0
  109. package/dist/adapters/postgres/usage-limits.d.ts +15 -0
  110. package/dist/adapters/postgres/usage-limits.js +136 -0
  111. package/dist/adapters/postgres/usage.d.ts +15 -0
  112. package/dist/adapters/postgres/usage.js +226 -0
  113. package/dist/adapters/redis/index.d.ts +9 -0
  114. package/dist/adapters/redis/index.js +9 -0
  115. package/dist/adapters/redis/realtime.d.ts +74 -0
  116. package/dist/adapters/redis/realtime.js +112 -0
  117. package/dist/adapters/supabase/index.d.ts +88 -0
  118. package/dist/adapters/supabase/index.js +84 -0
  119. package/dist/adapters/supabase/realtime.d.ts +30 -0
  120. package/dist/adapters/supabase/realtime.js +53 -0
  121. package/dist/adapters/supabase/rls.d.ts +99 -0
  122. package/dist/adapters/supabase/rls.js +216 -0
  123. package/dist/adapters/supabase/storage.d.ts +50 -0
  124. package/dist/adapters/supabase/storage.js +207 -0
  125. package/dist/agents/agent.d.ts +66 -0
  126. package/dist/agents/agent.js +209 -0
  127. package/dist/agents/define.d.ts +21 -0
  128. package/dist/agents/define.js +63 -0
  129. package/dist/agents/engine.d.ts +98 -0
  130. package/dist/agents/engine.js +462 -0
  131. package/dist/agents/index.d.ts +50 -0
  132. package/dist/agents/index.js +17 -0
  133. package/dist/artifacts/index.d.ts +114 -0
  134. package/dist/artifacts/index.js +219 -0
  135. package/dist/authorization/index.d.ts +76 -0
  136. package/dist/authorization/index.js +76 -0
  137. package/dist/capabilities/index.d.ts +120 -0
  138. package/dist/capabilities/index.js +167 -0
  139. package/dist/capabilities/runtime.d.ts +89 -0
  140. package/dist/capabilities/runtime.js +84 -0
  141. package/dist/citations/index.d.ts +161 -0
  142. package/dist/citations/index.js +182 -0
  143. package/dist/context/assembler.d.ts +82 -0
  144. package/dist/context/assembler.js +129 -0
  145. package/dist/context/compaction.d.ts +45 -0
  146. package/dist/context/compaction.js +55 -0
  147. package/dist/context/index.d.ts +75 -0
  148. package/dist/context/index.js +17 -0
  149. package/dist/core/content-parts.d.ts +194 -0
  150. package/dist/core/content-parts.js +23 -0
  151. package/dist/core/context.d.ts +51 -0
  152. package/dist/core/context.js +9 -0
  153. package/dist/core/env.d.ts +25 -0
  154. package/dist/core/env.js +41 -0
  155. package/dist/core/errors.d.ts +30 -0
  156. package/dist/core/errors.js +65 -0
  157. package/dist/core/events.d.ts +139 -0
  158. package/dist/core/events.js +99 -0
  159. package/dist/core/ids.d.ts +52 -0
  160. package/dist/core/ids.js +13 -0
  161. package/dist/core/index.d.ts +9 -0
  162. package/dist/core/index.js +9 -0
  163. package/dist/core/tokens.d.ts +22 -0
  164. package/dist/core/tokens.js +22 -0
  165. package/dist/core/validation.d.ts +34 -0
  166. package/dist/core/validation.js +176 -0
  167. package/dist/documents/extraction.d.ts +121 -0
  168. package/dist/documents/extraction.js +293 -0
  169. package/dist/documents/index.d.ts +199 -0
  170. package/dist/documents/index.js +65 -0
  171. package/dist/documents/parsers/pdf.d.ts +47 -0
  172. package/dist/documents/parsers/pdf.js +508 -0
  173. package/dist/documents/parsers/text.d.ts +59 -0
  174. package/dist/documents/parsers/text.js +325 -0
  175. package/dist/documents/read-tool.d.ts +52 -0
  176. package/dist/documents/read-tool.js +109 -0
  177. package/dist/documents/render.d.ts +29 -0
  178. package/dist/documents/render.js +59 -0
  179. package/dist/documents/vision.d.ts +159 -0
  180. package/dist/documents/vision.js +214 -0
  181. package/dist/entries/adapters-bullmq.d.ts +8 -0
  182. package/dist/entries/adapters-bullmq.js +8 -0
  183. package/dist/entries/adapters-otel.d.ts +13 -0
  184. package/dist/entries/adapters-otel.js +13 -0
  185. package/dist/entries/adapters-postgres.d.ts +10 -0
  186. package/dist/entries/adapters-postgres.js +10 -0
  187. package/dist/entries/adapters-redis.d.ts +3 -0
  188. package/dist/entries/adapters-redis.js +3 -0
  189. package/dist/entries/context.d.ts +20 -0
  190. package/dist/entries/context.js +20 -0
  191. package/dist/entries/flows.d.ts +15 -0
  192. package/dist/entries/flows.js +15 -0
  193. package/dist/entries/hitl.d.ts +10 -0
  194. package/dist/entries/hitl.js +10 -0
  195. package/dist/entries/knowledge.d.ts +18 -0
  196. package/dist/entries/knowledge.js +19 -0
  197. package/dist/entries/mcp.d.ts +10 -0
  198. package/dist/entries/mcp.js +10 -0
  199. package/dist/entries/observability.d.ts +14 -0
  200. package/dist/entries/observability.js +16 -0
  201. package/dist/entries/persistence.d.ts +11 -0
  202. package/dist/entries/persistence.js +11 -0
  203. package/dist/entries/providers.d.ts +14 -0
  204. package/dist/entries/providers.js +14 -0
  205. package/dist/entries/runtime.d.ts +13 -0
  206. package/dist/entries/runtime.js +13 -0
  207. package/dist/entries/server.d.ts +24 -0
  208. package/dist/entries/server.js +24 -0
  209. package/dist/entries/tools.d.ts +21 -0
  210. package/dist/entries/tools.js +21 -0
  211. package/dist/entries/usage.d.ts +10 -0
  212. package/dist/entries/usage.js +10 -0
  213. package/dist/evaluation/gate.d.ts +168 -0
  214. package/dist/evaluation/gate.js +180 -0
  215. package/dist/evaluation/graders.d.ts +125 -0
  216. package/dist/evaluation/graders.js +203 -0
  217. package/dist/evaluation/index.d.ts +120 -0
  218. package/dist/evaluation/index.js +183 -0
  219. package/dist/evaluation/judge.d.ts +75 -0
  220. package/dist/evaluation/judge.js +111 -0
  221. package/dist/export/index.d.ts +162 -0
  222. package/dist/export/index.js +363 -0
  223. package/dist/export/markdown.d.ts +19 -0
  224. package/dist/export/markdown.js +29 -0
  225. package/dist/export/pdf.d.ts +73 -0
  226. package/dist/export/pdf.js +407 -0
  227. package/dist/files/context.d.ts +97 -0
  228. package/dist/files/context.js +185 -0
  229. package/dist/files/index.d.ts +210 -0
  230. package/dist/files/index.js +338 -0
  231. package/dist/files/read-tool.d.ts +81 -0
  232. package/dist/files/read-tool.js +163 -0
  233. package/dist/files/turn-parts.d.ts +96 -0
  234. package/dist/files/turn-parts.js +171 -0
  235. package/dist/flows/index.d.ts +270 -0
  236. package/dist/flows/index.js +62 -0
  237. package/dist/flows/interpreter.d.ts +146 -0
  238. package/dist/flows/interpreter.js +426 -0
  239. package/dist/flows/runner.d.ts +145 -0
  240. package/dist/flows/runner.js +270 -0
  241. package/dist/graphql/index.d.ts +8 -0
  242. package/dist/graphql/index.js +8 -0
  243. package/dist/graphql/resolvers.d.ts +237 -0
  244. package/dist/graphql/resolvers.js +253 -0
  245. package/dist/graphql/schema.d.ts +11 -0
  246. package/dist/graphql/schema.js +258 -0
  247. package/dist/graphql/sse.d.ts +77 -0
  248. package/dist/graphql/sse.js +100 -0
  249. package/dist/hitl/approved-execution.d.ts +127 -0
  250. package/dist/hitl/approved-execution.js +177 -0
  251. package/dist/hitl/index.d.ts +79 -0
  252. package/dist/hitl/index.js +12 -0
  253. package/dist/hitl/service.d.ts +221 -0
  254. package/dist/hitl/service.js +268 -0
  255. package/dist/idempotency/index.d.ts +70 -0
  256. package/dist/idempotency/index.js +59 -0
  257. package/dist/index.d.ts +103 -0
  258. package/dist/index.js +60 -0
  259. package/dist/knowledge/chunking.d.ts +57 -0
  260. package/dist/knowledge/chunking.js +158 -0
  261. package/dist/knowledge/index.d.ts +119 -0
  262. package/dist/knowledge/index.js +166 -0
  263. package/dist/knowledge/retrieval.d.ts +146 -0
  264. package/dist/knowledge/retrieval.js +170 -0
  265. package/dist/loadtest/harness.d.ts +168 -0
  266. package/dist/loadtest/harness.js +507 -0
  267. package/dist/loadtest/index.d.ts +13 -0
  268. package/dist/loadtest/index.js +13 -0
  269. package/dist/loadtest/injection.d.ts +89 -0
  270. package/dist/loadtest/injection.js +147 -0
  271. package/dist/loadtest/metrics.d.ts +197 -0
  272. package/dist/loadtest/metrics.js +160 -0
  273. package/dist/loadtest/runbooks.d.ts +28 -0
  274. package/dist/loadtest/runbooks.js +159 -0
  275. package/dist/loadtest/scenario.d.ts +104 -0
  276. package/dist/loadtest/scenario.js +208 -0
  277. package/dist/mcp/egress.d.ts +53 -0
  278. package/dist/mcp/egress.js +115 -0
  279. package/dist/mcp/index.d.ts +93 -0
  280. package/dist/mcp/index.js +33 -0
  281. package/dist/mcp/provider.d.ts +62 -0
  282. package/dist/mcp/provider.js +0 -0
  283. package/dist/models/index.d.ts +98 -0
  284. package/dist/models/index.js +74 -0
  285. package/dist/models/pricing.d.ts +24 -0
  286. package/dist/models/pricing.js +37 -0
  287. package/dist/models/provider-factory.d.ts +31 -0
  288. package/dist/models/provider-factory.js +67 -0
  289. package/dist/models/streaming.d.ts +145 -0
  290. package/dist/models/streaming.js +272 -0
  291. package/dist/models/vision.d.ts +38 -0
  292. package/dist/models/vision.js +62 -0
  293. package/dist/persistence/index.d.ts +1654 -0
  294. package/dist/persistence/index.js +226 -0
  295. package/dist/principal-memory/index.d.ts +106 -0
  296. package/dist/principal-memory/index.js +89 -0
  297. package/dist/retention/index.d.ts +89 -0
  298. package/dist/retention/index.js +70 -0
  299. package/dist/runtime/checkpoint.d.ts +37 -0
  300. package/dist/runtime/checkpoint.js +22 -0
  301. package/dist/runtime/index.d.ts +118 -0
  302. package/dist/runtime/index.js +69 -0
  303. package/dist/runtime/retry.d.ts +95 -0
  304. package/dist/runtime/retry.js +126 -0
  305. package/dist/runtime/serialization.d.ts +85 -0
  306. package/dist/runtime/serialization.js +95 -0
  307. package/dist/runtime/streaming.d.ts +54 -0
  308. package/dist/runtime/streaming.js +115 -0
  309. package/dist/runtime/worker.d.ts +130 -0
  310. package/dist/runtime/worker.js +405 -0
  311. package/dist/security/checklist.d.ts +53 -0
  312. package/dist/security/checklist.js +204 -0
  313. package/dist/security/findings.d.ts +56 -0
  314. package/dist/security/findings.js +168 -0
  315. package/dist/security/index.d.ts +14 -0
  316. package/dist/security/index.js +14 -0
  317. package/dist/security/prompt-safety.d.ts +100 -0
  318. package/dist/security/prompt-safety.js +133 -0
  319. package/dist/server/boot.d.ts +32 -0
  320. package/dist/server/boot.js +36 -0
  321. package/dist/server/cli-worker.d.ts +37 -0
  322. package/dist/server/cli-worker.js +151 -0
  323. package/dist/server/cli.d.ts +27 -0
  324. package/dist/server/cli.js +74 -0
  325. package/dist/server/config.d.ts +42 -0
  326. package/dist/server/config.js +127 -0
  327. package/dist/server/health.d.ts +59 -0
  328. package/dist/server/health.js +90 -0
  329. package/dist/server/host.d.ts +39 -0
  330. package/dist/server/host.js +124 -0
  331. package/dist/server/index.d.ts +15 -0
  332. package/dist/server/index.js +15 -0
  333. package/dist/server/main.d.ts +16 -0
  334. package/dist/server/main.js +31 -0
  335. package/dist/server/sse-route.d.ts +21 -0
  336. package/dist/server/sse-route.js +282 -0
  337. package/dist/skills/index.d.ts +67 -0
  338. package/dist/skills/index.js +31 -0
  339. package/dist/skills/resolver.d.ts +54 -0
  340. package/dist/skills/resolver.js +121 -0
  341. package/dist/teams/index.d.ts +93 -0
  342. package/dist/teams/index.js +207 -0
  343. package/dist/telemetry/index.d.ts +157 -0
  344. package/dist/telemetry/index.js +71 -0
  345. package/dist/telemetry/instrument.d.ts +108 -0
  346. package/dist/telemetry/instrument.js +232 -0
  347. package/dist/telemetry/log-events.d.ts +17 -0
  348. package/dist/telemetry/log-events.js +58 -0
  349. package/dist/telemetry/metrics.d.ts +123 -0
  350. package/dist/telemetry/metrics.js +135 -0
  351. package/dist/telemetry/noop.d.ts +39 -0
  352. package/dist/telemetry/noop.js +143 -0
  353. package/dist/telemetry/redaction.d.ts +64 -0
  354. package/dist/telemetry/redaction.js +153 -0
  355. package/dist/telemetry/spans.d.ts +56 -0
  356. package/dist/telemetry/spans.js +78 -0
  357. package/dist/telemetry/trace-context.d.ts +55 -0
  358. package/dist/telemetry/trace-context.js +60 -0
  359. package/dist/toolkit/compute.d.ts +53 -0
  360. package/dist/toolkit/compute.js +152 -0
  361. package/dist/toolkit/data.d.ts +98 -0
  362. package/dist/toolkit/data.js +235 -0
  363. package/dist/toolkit/http.d.ts +113 -0
  364. package/dist/toolkit/http.js +205 -0
  365. package/dist/toolkit/index.d.ts +21 -0
  366. package/dist/toolkit/index.js +17 -0
  367. package/dist/toolkit/web.d.ts +107 -0
  368. package/dist/toolkit/web.js +147 -0
  369. package/dist/tools/define.d.ts +25 -0
  370. package/dist/tools/define.js +45 -0
  371. package/dist/tools/delegating.d.ts +132 -0
  372. package/dist/tools/delegating.js +211 -0
  373. package/dist/tools/index.d.ts +129 -0
  374. package/dist/tools/index.js +33 -0
  375. package/dist/tools/library/compute.d.ts +11 -0
  376. package/dist/tools/library/compute.js +46 -0
  377. package/dist/tools/library/data.d.ts +16 -0
  378. package/dist/tools/library/data.js +92 -0
  379. package/dist/tools/library/http.d.ts +28 -0
  380. package/dist/tools/library/http.js +71 -0
  381. package/dist/tools/library/index.d.ts +97 -0
  382. package/dist/tools/library/index.js +134 -0
  383. package/dist/tools/library/knowledge.d.ts +39 -0
  384. package/dist/tools/library/knowledge.js +58 -0
  385. package/dist/tools/library/web.d.ts +19 -0
  386. package/dist/tools/library/web.js +65 -0
  387. package/dist/tools/meta-tools.d.ts +19 -0
  388. package/dist/tools/meta-tools.js +36 -0
  389. package/dist/tools/registry.d.ts +146 -0
  390. package/dist/tools/registry.js +291 -0
  391. package/dist/usage/index.d.ts +105 -0
  392. package/dist/usage/index.js +20 -0
  393. package/dist/usage/quota.d.ts +258 -0
  394. package/dist/usage/quota.js +510 -0
  395. package/dist/usage/recorder.d.ts +29 -0
  396. package/dist/usage/recorder.js +96 -0
  397. package/dist/usage/rollups.d.ts +121 -0
  398. package/dist/usage/rollups.js +157 -0
  399. package/dist/worker/export.d.ts +57 -0
  400. package/dist/worker/export.js +81 -0
  401. package/dist/worker/extraction.d.ts +57 -0
  402. package/dist/worker/extraction.js +84 -0
  403. package/dist/worker/main.d.ts +103 -0
  404. package/dist/worker/main.js +159 -0
  405. package/package.json +187 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Supabase adapter — Postgres stores + RLS + Realtime (#104).
3
+ *
4
+ * Supabase *is* Postgres, so every store here is an **alias** of the PostgreSQL implementation rather
5
+ * than a second one. That is deliberate and it is the whole reason the Supabase column can be trusted:
6
+ * one implementation cannot drift from itself. The conformance suite still runs the column, because
7
+ * an alias can be repointed and because RLS changes the executor's effective privileges — "same code"
8
+ * is a claim worth re-checking rather than assuming.
9
+ *
10
+ * What is genuinely Supabase-specific lives in `rls.ts` (policies, tenant binding) and `realtime.ts`
11
+ * (the live event channel). Both carry no `@supabase/supabase-js` dependency: the host app adapts its
12
+ * client to the small interfaces here, so this package stays deployable without one.
13
+ */
14
+ import type { AdapterCapability } from "../../persistence/index.js";
15
+ export { createPostgresConversationStore as createSupabaseConversationStore } from "../postgres/conversation-store.js";
16
+ export { createPostgresSessionStateStore as createSupabaseSessionStateStore, createPostgresThreadSummaryStore as createSupabaseThreadSummaryStore, } from "../postgres/session-state.js";
17
+ export { createPostgresConversationBindingStore as createSupabaseConversationBindingStore, createPostgresMessageStore as createSupabaseMessageStore, createPostgresAgentStore as createSupabaseAgentStore, } from "../postgres/message-store.js";
18
+ export { createPostgresConversationRunCoordinator as createSupabaseConversationRunCoordinator } from "../postgres/run-coordinator.js";
19
+ export { createPostgresUnitOfWork as createSupabaseUnitOfWork } from "../postgres/unit-of-work.js";
20
+ export { createPostgresRunStore as createSupabaseRunStore } from "../postgres/run-store.js";
21
+ export { createPostgresRunEventLog as createSupabaseRunEventLog } from "../postgres/run-event-log.js";
22
+ export { createPostgresCheckpointStore as createSupabaseCheckpointStore } from "../postgres/checkpoint-store.js";
23
+ export { createPostgresInteractionStore as createSupabaseInteractionStore, createPostgresApprovalGrantStore as createSupabaseApprovalGrantStore, } from "../postgres/hitl.js";
24
+ export { createPostgresUsageStore as createSupabaseUsageStore, createPostgresIdempotencyStore as createSupabaseIdempotencyStore, } from "../postgres/usage.js";
25
+ export { createPostgresUsageLimitStore as createSupabaseUsageLimitStore } from "../postgres/usage-limits.js";
26
+ export { createPostgresSkillStore as createSupabaseSkillStore, createPostgresMcpConnectionStore as createSupabaseMcpConnectionStore, } from "../postgres/config.js";
27
+ export { createPostgresPrincipalMemoryStore as createSupabasePrincipalMemoryStore, createPostgresBlobStore as createSupabaseBlobStore, } from "../postgres/memory.js";
28
+ /**
29
+ * File *metadata* aliases to Postgres. File *bytes* do not, and this is the one port where Supabase is not
30
+ * simply Postgres under another name.
31
+ *
32
+ * `0013_files` keeps metadata only, so `FileMetadataStore` is an alias like every other port. The bytes live
33
+ * in Supabase Storage, which has its own adapter in `./storage.js` — a genuine second implementation, not an
34
+ * alias, because there is no Postgres factory to alias to. `notApplicable` in the matrix therefore belongs to
35
+ * **postgres alone**: file bytes in a relational column is the antipattern #102 rejected, whereas Supabase
36
+ * has a real home for them.
37
+ */
38
+ export { createPostgresFileMetadataStore as createSupabaseFileMetadataStore } from "../postgres/files.js";
39
+ export * from "./storage.js";
40
+ /**
41
+ * Artifacts alias to Postgres like every other relational port (#133).
42
+ *
43
+ * Their *content* does not live here at all — it is a `BlobRef`, and where those bytes sit is `BlobStore`'s
44
+ * business, which is itself an alias. So unlike `FileContentStore` there is nothing Supabase-specific to add:
45
+ * the artifact row is a relational row.
46
+ */
47
+ export { createPostgresArtifactStore as createSupabaseArtifactStore } from "../postgres/artifacts.js";
48
+ export { createPostgresArtifactExportStore as createSupabaseArtifactExportStore } from "../postgres/artifact-exports.js";
49
+ /**
50
+ * Knowledge and vector search alias to Postgres too (#135).
51
+ *
52
+ * Supabase ships pgvector, so this is the same adapter and not a second implementation — unlike
53
+ * `FileContentStore`, where Supabase Storage genuinely is a different service. The vector migrations are
54
+ * separate from the main list (`migrateVector`) because `CREATE EXTENSION vector` fails where the extension is
55
+ * absent, and a Supabase project has it while a bare Postgres may not.
56
+ */
57
+ export { createPostgresUsageRollupStore as createSupabaseUsageRollupStore } from "../postgres/rollups.js";
58
+ export { createPostgresEvaluationStore as createSupabaseEvaluationStore } from "../postgres/evaluation.js";
59
+ export { createPostgresKnowledgeStore as createSupabaseKnowledgeStore, createPostgresVectorIndex as createSupabaseVectorIndex, createPostgresKeywordIndex as createSupabaseKeywordIndex, } from "../postgres/knowledge.js";
60
+ export * from "./rls.js";
61
+ export * from "./realtime.js";
62
+ /**
63
+ * What a Supabase deployment can honestly advertise.
64
+ *
65
+ * **`distributed-locking` is included, and the SPEC expected it not to be.** #104 asks to declare it
66
+ * unsupported "if pooled connections make advisory locks unavailable" — but the premise no longer
67
+ * holds. #98 deliberately avoided advisory locks: a lock whose lifetime is a transaction cannot hold
68
+ * a run slot across a `waiting-for-approval` state that waits hours for a human, and the port
69
+ * promises a FIFO queue a lock cannot express. The coordinator is a slot table with
70
+ * `SELECT … FOR UPDATE` inside a short transaction, which is exactly what transaction pooling
71
+ * supports. Declaring it unsupported would skip real coverage for a reason that stopped being true.
72
+ *
73
+ * **`full-text-search` is removed.** Nothing implements it in either adapter, so it was a claim with
74
+ * nothing behind it — one of the two unproven capabilities flagged on #98. `POSTGRES_CAPABILITIES`
75
+ * still lists it; that is tracked separately rather than changed here, since Postgres is not this
76
+ * SPEC's subject.
77
+ */
78
+ export declare const SUPABASE_CAPABILITIES: readonly AdapterCapability[];
79
+ /**
80
+ * Flows — #187, #186.
81
+ *
82
+ * Aliased, like every other relational port: the tables are ordinary Postgres and there is nothing
83
+ * Supabase-specific about a flow definition or an execution. An alias rather than a wrapper keeps AC-5's
84
+ * "identical results" true by identity rather than by proof.
85
+ */
86
+ export { createPostgresFlowDefinitionStore as createSupabaseFlowDefinitionStore } from "../postgres/flows.js";
87
+ export { createPostgresFlowExecutionStore as createSupabaseFlowExecutionStore } from "../postgres/flows.js";
88
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,84 @@
1
+ // Conversation and session
2
+ export { createPostgresConversationStore as createSupabaseConversationStore } from "../postgres/conversation-store.js";
3
+ export { createPostgresSessionStateStore as createSupabaseSessionStateStore, createPostgresThreadSummaryStore as createSupabaseThreadSummaryStore, } from "../postgres/session-state.js";
4
+ export { createPostgresConversationBindingStore as createSupabaseConversationBindingStore, createPostgresMessageStore as createSupabaseMessageStore, createPostgresAgentStore as createSupabaseAgentStore, } from "../postgres/message-store.js";
5
+ export { createPostgresConversationRunCoordinator as createSupabaseConversationRunCoordinator } from "../postgres/run-coordinator.js";
6
+ export { createPostgresUnitOfWork as createSupabaseUnitOfWork } from "../postgres/unit-of-work.js";
7
+ // Run lifecycle
8
+ export { createPostgresRunStore as createSupabaseRunStore } from "../postgres/run-store.js";
9
+ export { createPostgresRunEventLog as createSupabaseRunEventLog } from "../postgres/run-event-log.js";
10
+ export { createPostgresCheckpointStore as createSupabaseCheckpointStore } from "../postgres/checkpoint-store.js";
11
+ // HITL, accounting and configuration
12
+ export { createPostgresInteractionStore as createSupabaseInteractionStore, createPostgresApprovalGrantStore as createSupabaseApprovalGrantStore, } from "../postgres/hitl.js";
13
+ export { createPostgresUsageStore as createSupabaseUsageStore, createPostgresIdempotencyStore as createSupabaseIdempotencyStore, } from "../postgres/usage.js";
14
+ // The limit store is the Postgres one: it is ordinary SQL over an ordinary table, and Supabase's differences
15
+ // (RLS, the connection mode) are handled by the executor rather than by the statement (#175).
16
+ export { createPostgresUsageLimitStore as createSupabaseUsageLimitStore } from "../postgres/usage-limits.js";
17
+ export { createPostgresSkillStore as createSupabaseSkillStore, createPostgresMcpConnectionStore as createSupabaseMcpConnectionStore, } from "../postgres/config.js";
18
+ export { createPostgresPrincipalMemoryStore as createSupabasePrincipalMemoryStore, createPostgresBlobStore as createSupabaseBlobStore, } from "../postgres/memory.js";
19
+ /**
20
+ * File *metadata* aliases to Postgres. File *bytes* do not, and this is the one port where Supabase is not
21
+ * simply Postgres under another name.
22
+ *
23
+ * `0013_files` keeps metadata only, so `FileMetadataStore` is an alias like every other port. The bytes live
24
+ * in Supabase Storage, which has its own adapter in `./storage.js` — a genuine second implementation, not an
25
+ * alias, because there is no Postgres factory to alias to. `notApplicable` in the matrix therefore belongs to
26
+ * **postgres alone**: file bytes in a relational column is the antipattern #102 rejected, whereas Supabase
27
+ * has a real home for them.
28
+ */
29
+ export { createPostgresFileMetadataStore as createSupabaseFileMetadataStore } from "../postgres/files.js";
30
+ export * from "./storage.js";
31
+ /**
32
+ * Artifacts alias to Postgres like every other relational port (#133).
33
+ *
34
+ * Their *content* does not live here at all — it is a `BlobRef`, and where those bytes sit is `BlobStore`'s
35
+ * business, which is itself an alias. So unlike `FileContentStore` there is nothing Supabase-specific to add:
36
+ * the artifact row is a relational row.
37
+ */
38
+ export { createPostgresArtifactStore as createSupabaseArtifactStore } from "../postgres/artifacts.js";
39
+ export { createPostgresArtifactExportStore as createSupabaseArtifactExportStore } from "../postgres/artifact-exports.js";
40
+ /**
41
+ * Knowledge and vector search alias to Postgres too (#135).
42
+ *
43
+ * Supabase ships pgvector, so this is the same adapter and not a second implementation — unlike
44
+ * `FileContentStore`, where Supabase Storage genuinely is a different service. The vector migrations are
45
+ * separate from the main list (`migrateVector`) because `CREATE EXTENSION vector` fails where the extension is
46
+ * absent, and a Supabase project has it while a bare Postgres may not.
47
+ */
48
+ export { createPostgresUsageRollupStore as createSupabaseUsageRollupStore } from "../postgres/rollups.js";
49
+ export { createPostgresEvaluationStore as createSupabaseEvaluationStore } from "../postgres/evaluation.js";
50
+ export { createPostgresKnowledgeStore as createSupabaseKnowledgeStore, createPostgresVectorIndex as createSupabaseVectorIndex, createPostgresKeywordIndex as createSupabaseKeywordIndex, } from "../postgres/knowledge.js";
51
+ export * from "./rls.js";
52
+ export * from "./realtime.js";
53
+ /**
54
+ * What a Supabase deployment can honestly advertise.
55
+ *
56
+ * **`distributed-locking` is included, and the SPEC expected it not to be.** #104 asks to declare it
57
+ * unsupported "if pooled connections make advisory locks unavailable" — but the premise no longer
58
+ * holds. #98 deliberately avoided advisory locks: a lock whose lifetime is a transaction cannot hold
59
+ * a run slot across a `waiting-for-approval` state that waits hours for a human, and the port
60
+ * promises a FIFO queue a lock cannot express. The coordinator is a slot table with
61
+ * `SELECT … FOR UPDATE` inside a short transaction, which is exactly what transaction pooling
62
+ * supports. Declaring it unsupported would skip real coverage for a reason that stopped being true.
63
+ *
64
+ * **`full-text-search` is removed.** Nothing implements it in either adapter, so it was a claim with
65
+ * nothing behind it — one of the two unproven capabilities flagged on #98. `POSTGRES_CAPABILITIES`
66
+ * still lists it; that is tracked separately rather than changed here, since Postgres is not this
67
+ * SPEC's subject.
68
+ */
69
+ export const SUPABASE_CAPABILITIES = [
70
+ "transactions",
71
+ "row-level-security",
72
+ "distributed-locking",
73
+ "realtime",
74
+ ];
75
+ /**
76
+ * Flows — #187, #186.
77
+ *
78
+ * Aliased, like every other relational port: the tables are ordinary Postgres and there is nothing
79
+ * Supabase-specific about a flow definition or an execution. An alias rather than a wrapper keeps AC-5's
80
+ * "identical results" true by identity rather than by proof.
81
+ */
82
+ export { createPostgresFlowDefinitionStore as createSupabaseFlowDefinitionStore } from "../postgres/flows.js";
83
+ export { createPostgresFlowExecutionStore as createSupabaseFlowExecutionStore } from "../postgres/flows.js";
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,30 @@
1
+ import type { RealtimePublisher } from "../../core/events.js";
2
+ import type { LiveEventSource } from "../../runtime/streaming.js";
3
+ /** The app adapts a Supabase channel's `send` to this (`channel.send({ type, event, payload })`). */
4
+ export interface RealtimeBroadcaster {
5
+ send(channel: string, event: string, payload: unknown): Promise<void> | void;
6
+ }
7
+ export declare const createSupabaseRealtimePublisher: (broadcaster: RealtimeBroadcaster) => RealtimePublisher;
8
+ /**
9
+ * The receive side the host adapts a subscribed channel to.
10
+ *
11
+ * The contract that matters is inherited from `LiveEventSource`: **buffering must begin at call
12
+ * time**, before the caller's first `next()`. `openRunEventStream` subscribes and *then* reads the
13
+ * durable log, and that ordering is the only thing stopping an event published during catch-up from
14
+ * being lost. An adapter that connects lazily on first `next()` silently breaks it.
15
+ */
16
+ export interface RealtimeSubscriber {
17
+ subscribe(channel: string): AsyncIterable<unknown>;
18
+ }
19
+ export type LiveEventSourceOptions = {
20
+ /**
21
+ * Whether this subscriber may read the channel. Rejected subscriptions yield nothing and end.
22
+ * Absent means every channel is allowed, which is only appropriate when the caller has already
23
+ * authorized — the GraphQL resolver path, for instance.
24
+ */
25
+ readonly authorize?: (channel: string) => Promise<boolean> | boolean;
26
+ /** Called for each payload that fails validation. Defaults to silence. */
27
+ readonly onInvalid?: (channel: string, payload: unknown) => void;
28
+ };
29
+ export declare const createSupabaseLiveEventSource: (subscriber: RealtimeSubscriber, options?: LiveEventSourceOptions) => LiveEventSource;
30
+ //# sourceMappingURL=realtime.d.ts.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Supabase Realtime — the publisher and, as of #104, the `LiveEventSource` half.
3
+ *
4
+ * Both sides are defined against tiny interfaces the host app adapts its Supabase client to, so this
5
+ * package carries no `@supabase/supabase-js` dependency and stays deployable without one.
6
+ *
7
+ * Two things the in-memory bus never had to worry about, and this does:
8
+ *
9
+ * **A Realtime payload is network input.** `openRunEventStream` feeds whatever the live source yields
10
+ * straight into `reduceRunEvents`, so an unvalidated payload would put attacker-shaped or merely
11
+ * corrupt data into a run's projected state. Every payload is parsed with `parseRunEvent` and dropped
12
+ * if it fails, rather than trusted because it arrived on the right channel.
13
+ *
14
+ * **Entitlement is checked at subscribe time, not on delivery.** Filtering events after subscribing
15
+ * would still reveal that a conversation exists and roughly how active it is. Refusing the
16
+ * subscription is the only version that leaks nothing.
17
+ */
18
+ import { parseRunEvent } from "../../core/validation.js";
19
+ export const createSupabaseRealtimePublisher = (broadcaster) => ({
20
+ async publish(channel, event) {
21
+ await broadcaster.send(channel, event.type, event);
22
+ },
23
+ });
24
+ export const createSupabaseLiveEventSource = (subscriber, options = {}) => ({
25
+ subscribe(channel) {
26
+ // Subscribe eagerly, before the authorization check resolves, so the buffering contract above
27
+ // holds. An unauthorized channel yields nothing regardless — see below.
28
+ const upstream = subscriber.subscribe(channel);
29
+ return {
30
+ async *[Symbol.asyncIterator]() {
31
+ const allowed = options.authorize === undefined ? true : await options.authorize(channel);
32
+ // Ending the stream rather than throwing: a subscriber that is not entitled should observe
33
+ // an ordinary empty stream, not an error that distinguishes "forbidden" from "no such run".
34
+ if (!allowed)
35
+ return;
36
+ for await (const payload of upstream) {
37
+ let event;
38
+ try {
39
+ event = parseRunEvent(payload);
40
+ }
41
+ catch {
42
+ // Dropped, not thrown: one malformed broadcast must not tear down a live stream that is
43
+ // otherwise healthy, and the durable log remains the source of truth for the run.
44
+ options.onInvalid?.(channel, payload);
45
+ continue;
46
+ }
47
+ yield event;
48
+ }
49
+ },
50
+ };
51
+ },
52
+ });
53
+ //# sourceMappingURL=realtime.js.map
@@ -0,0 +1,99 @@
1
+ import type { SqlExecutor } from "../postgres/sql.js";
2
+ import type { TransactionRunner } from "../postgres/transaction.js";
3
+ /**
4
+ * A table whose rows belong to a tenant, plus any predicate beyond the tenant match.
5
+ *
6
+ * `extraPredicate` exists for one case today. Tenant-only scoping on `principal_memory` would leak
7
+ * one user's memories to every other user of the same customer, which is the opposite of what
8
+ * per-principal memory is for.
9
+ */
10
+ export type RlsTable = {
11
+ readonly table: string;
12
+ readonly extraPredicate?: string;
13
+ };
14
+ /**
15
+ * Tenant-scoped tables that live behind the optional pgvector migration (#135).
16
+ *
17
+ * Separate from `TENANT_SCOPED_TABLES` because `knowledge_chunks` does not exist until `migrateVector` runs, and
18
+ * `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` on an absent table fails. A deployment that runs the vector
19
+ * migration runs `applyVectorRls` with it; one that does not has no table to protect. Listed rather than
20
+ * omitted so the requirement is recorded — a tenant-scoped table without RLS is the one omission that matters.
21
+ */
22
+ export declare const VECTOR_TENANT_SCOPED_TABLES: readonly {
23
+ readonly table: string;
24
+ }[];
25
+ export declare const TENANT_SCOPED_TABLES: readonly RlsTable[];
26
+ /**
27
+ * Tables that deliberately have no tenant policy, each with the reason.
28
+ *
29
+ * Classified rather than skipped. A silent omission is indistinguishable from a forgotten table,
30
+ * which is exactly what the coverage gate exists to catch — so an exemption has to be a decision
31
+ * someone wrote down.
32
+ */
33
+ export declare const RLS_EXEMPT_TABLES: readonly {
34
+ readonly table: string;
35
+ readonly reason: string;
36
+ }[];
37
+ export declare const RLS_STATEMENTS: readonly string[];
38
+ export declare const applyRls: (sql: SqlExecutor) => Promise<void>;
39
+ /** The same policies for the vector table, applied by whoever ran `migrateVector` (#135). */
40
+ export declare const VECTOR_RLS_STATEMENTS: readonly string[];
41
+ export declare const applyVectorRls: (sql: SqlExecutor) => Promise<void>;
42
+ /**
43
+ * Every table `MIGRATIONS` creates, in migration order.
44
+ *
45
+ * Derived rather than transcribed: the SPEC's hand-written list named `interactions` and `blob_refs`,
46
+ * neither of which exists, and missed `schema_migrations`. A list that can disagree with the schema
47
+ * will eventually disagree with the schema.
48
+ */
49
+ /**
50
+ * Every table any migration creates — **both** lists (#145).
51
+ *
52
+ * `VECTOR_MIGRATIONS` was missing, and that was a hole in the coverage gate rather than an oversight in a list:
53
+ * a table added there was never scanned, so it could ship with no RLS policy and no exemption and nothing would
54
+ * say so. `knowledge_chunks` happened to be covered because someone remembered; the *next* vector table would
55
+ * not have been.
56
+ *
57
+ * Found by auditing the gate rather than the list, which is the difference between checking the answer and
58
+ * checking the thing that produces it.
59
+ */
60
+ export declare const tablesInMigrations: () => readonly string[];
61
+ /**
62
+ * Bind the **session** to a tenant. Safe only on a direct connection.
63
+ *
64
+ * `is_local = false` makes the setting outlive the current transaction, which is right for a
65
+ * connection this process owns exclusively — and **dangerous behind a transaction-mode pooler**, which
66
+ * is how Supabase's pooler port works. There, a backend is handed to a different client after each
67
+ * transaction while the session GUC stays set, so tenant A's binding is still in place when tenant B's
68
+ * query lands on that backend, and B's queries are evaluated against A's tenant id.
69
+ *
70
+ * That is a cross-tenant read produced by the mechanism introduced to prevent cross-tenant reads, and
71
+ * it is worse than having no policy at all, because the policy makes it look handled.
72
+ *
73
+ * Prefer `withTenantContext` unless you are certain the connection is not pooled. See the open
74
+ * question on #104 about removing this entirely.
75
+ */
76
+ export declare const setTenantContext: (sql: SqlExecutor, tenantId: string) => Promise<void>;
77
+ /**
78
+ * Run `fn` with the tenant (and optionally the principal) bound **for the duration of one
79
+ * transaction**, which is the only binding that is safe behind a pooler.
80
+ *
81
+ * `is_local = true` scopes the setting to the transaction, so it is discarded at commit or rollback
82
+ * and cannot be observed by whoever gets the backend next. The transaction comes from #98's
83
+ * `TransactionRunner`, and the executor handed to `fn` is the transaction's — so stores built over a
84
+ * `scoped()` executor participate without knowing any of this exists.
85
+ */
86
+ export declare const withTenantContext: <T>(runner: TransactionRunner, scope: {
87
+ readonly tenantId: string;
88
+ readonly principalId?: string;
89
+ }, fn: (sql: SqlExecutor) => Promise<T>) => Promise<T>;
90
+ /**
91
+ * Bind the **session** to a principal. Same pooling caveat as `setTenantContext` — prefer passing
92
+ * `principalId` to `withTenantContext`.
93
+ *
94
+ * Separate from `setTenantContext` because most work has a tenant and no principal — a background
95
+ * reaper, a migration, a rollup. Those must not be able to read principal-scoped rows, and with this
96
+ * unset they cannot: the predicate compares against NULL and matches nothing.
97
+ */
98
+ export declare const setPrincipalContext: (sql: SqlExecutor, principalId: string) => Promise<void>;
99
+ //# sourceMappingURL=rls.d.ts.map
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Row-Level Security — `docs/02` + `docs/11`.
3
+ *
4
+ * Enforces tenant isolation *at the database*, independent of any app-level `WHERE`. The policy
5
+ * predicate `tenant_id = current_setting('app.tenant_id')` is exactly the filter the authorization
6
+ * `scope()` produces (see `tenantRlsFilter`), so the two agree by construction — and if the
7
+ * application filter is ever forgotten, the database still refuses.
8
+ *
9
+ * Until #103 this covered exactly one table, because `conversations` was the only table when it was
10
+ * written. There are now 19, and a table without a policy means a Supabase deployment relies on
11
+ * application filtering alone — the single point of failure REQ-014 exists to remove.
12
+ *
13
+ * **Policies are generated from the registry below rather than written out**, so adding a table's
14
+ * policy is a one-line entry and the statements cannot drift from the list. The coverage gate in
15
+ * `supabase-rls.test.ts` derives the table list from `MIGRATIONS`, so a new table cannot ship
16
+ * uncovered and a stale entry for a dropped table fails too.
17
+ */
18
+ import { MIGRATIONS, VECTOR_MIGRATIONS } from "../postgres/migrations.js";
19
+ /**
20
+ * The principal predicate is written so an **absent** setting matches nothing.
21
+ *
22
+ * `current_setting('app.principal_id', true)` returns NULL when unset, and `principal_id = NULL` is
23
+ * NULL — which the policy treats as false. That is the behaviour we want: a connection with no
24
+ * principal bound sees no memories at all, rather than seeing every row whose `principal_id` happens
25
+ * to equal the empty string. Getting this backwards is how a background job ends up able to read
26
+ * everyone's memory.
27
+ */
28
+ const PRINCIPAL_PREDICATE = `principal_id = current_setting('app.principal_id', true)`;
29
+ /**
30
+ * Tenant-scoped tables that live behind the optional pgvector migration (#135).
31
+ *
32
+ * Separate from `TENANT_SCOPED_TABLES` because `knowledge_chunks` does not exist until `migrateVector` runs, and
33
+ * `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` on an absent table fails. A deployment that runs the vector
34
+ * migration runs `applyVectorRls` with it; one that does not has no table to protect. Listed rather than
35
+ * omitted so the requirement is recorded — a tenant-scoped table without RLS is the one omission that matters.
36
+ */
37
+ export const VECTOR_TENANT_SCOPED_TABLES = [
38
+ { table: "knowledge_chunks" },
39
+ ];
40
+ export const TENANT_SCOPED_TABLES = [
41
+ { table: "conversations" },
42
+ { table: "runs" },
43
+ { table: "run_events" },
44
+ { table: "checkpoints" },
45
+ { table: "messages" },
46
+ { table: "agents" },
47
+ { table: "conversation_bindings" },
48
+ { table: "session_state" },
49
+ { table: "thread_summaries" },
50
+ { table: "conversation_run_slots" },
51
+ // Two tables, not one: #99 split questions from approvals because PendingQuestion and
52
+ // PendingApproval share only three fields. The SPEC's list named a single `interactions`.
53
+ { table: "interaction_questions" },
54
+ { table: "interaction_approvals" },
55
+ { table: "approval_grants" },
56
+ { table: "usage_records" },
57
+ { table: "usage_rollups" },
58
+ /**
59
+ * Tenant-scoped only, deliberately — #175.
60
+ *
61
+ * Not `PRINCIPAL_PREDICATE`, even though the table has a `principal_id`. A spend limit is a fact *about* a
62
+ * person that belongs to the tenant's administrator, not to the person it constrains: someone who could only
63
+ * see their own row could not be shown the tenant default they inherit, and — the part that matters — a
64
+ * limit nobody but its subject can read is a limit its subject can quietly delete.
65
+ *
66
+ * The principal column here is a dimension, not an owner. That distinction is why this needs saying: the
67
+ * neighbouring `principal_memory` has the same column and the opposite answer.
68
+ */
69
+ { table: "usage_limits" },
70
+ { table: "evaluation_runs" },
71
+ { table: "evaluation_case_results" },
72
+ { table: "idempotency_keys" },
73
+ { table: "skills" },
74
+ { table: "mcp_connections" },
75
+ { table: "principal_memory", extraPredicate: PRINCIPAL_PREDICATE },
76
+ // `blobs`, not the SPEC's `blob_refs`: BlobStore stores the value, and the metadata-and-pointer
77
+ // design belongs to FileMetadataStore (#129) / ArtifactStore (#133).
78
+ { table: "blobs" },
79
+ /**
80
+ * #129, revised by #185.
81
+ *
82
+ * This used to say "the bytes are not in Postgres at all, so this policy covers the metadata only". That was
83
+ * true when the only content stores were in-memory and Supabase Storage. `createPostgresFileContentStore`
84
+ * changed it: bytes can now live in `file_objects`, in the same database, and a metadata policy that implied
85
+ * the bytes were somebody else's problem would have been the most reassuring kind of wrong.
86
+ *
87
+ * Both are covered now. A Storage bucket still needs its own access rules, and RLS here says nothing about
88
+ * those — that part of the original comment stands.
89
+ */
90
+ { table: "files" },
91
+ { table: "file_objects" },
92
+ { table: "artifacts" },
93
+ { table: "artifact_versions" },
94
+ { table: "artifact_exports" },
95
+ /**
96
+ * #187, #186. A flow definition is a tenant's automation and an execution is a tenant's data — including its
97
+ * `state`, which routinely holds whatever the automation was working on.
98
+ */
99
+ { table: "flow_definitions" },
100
+ { table: "flow_executions" },
101
+ ];
102
+ /**
103
+ * Tables that deliberately have no tenant policy, each with the reason.
104
+ *
105
+ * Classified rather than skipped. A silent omission is indistinguishable from a forgotten table,
106
+ * which is exactly what the coverage gate exists to catch — so an exemption has to be a decision
107
+ * someone wrote down.
108
+ */
109
+ export const RLS_EXEMPT_TABLES = [
110
+ {
111
+ table: "schema_migrations",
112
+ reason: "Records which migrations have been applied. Deployment state, not customer data, and it holds " +
113
+ "no tenant_id to scope on. A migration runner must read it before any tenant context exists.",
114
+ },
115
+ ];
116
+ const policyFor = ({ table, extraPredicate }) => {
117
+ const tenant = `tenant_id = current_setting('app.tenant_id', true)`;
118
+ const predicate = extraPredicate === undefined ? tenant : `${tenant} AND ${extraPredicate}`;
119
+ return [
120
+ `ALTER TABLE ${table} ENABLE ROW LEVEL SECURITY`,
121
+ // FORCE matters more than it looks. Without it the table owner bypasses every policy — and the
122
+ // owner is the role that runs migrations, and in many deployments the role the app connects as.
123
+ // An isolation test would then pass while proving nothing.
124
+ `ALTER TABLE ${table} FORCE ROW LEVEL SECURITY`,
125
+ `DROP POLICY IF EXISTS tenant_isolation ON ${table}`,
126
+ `CREATE POLICY tenant_isolation ON ${table}
127
+ USING (${predicate})
128
+ WITH CHECK (${predicate})`,
129
+ ];
130
+ };
131
+ export const RLS_STATEMENTS = TENANT_SCOPED_TABLES.flatMap(policyFor);
132
+ export const applyRls = async (sql) => {
133
+ for (const stmt of RLS_STATEMENTS)
134
+ await sql.query(stmt);
135
+ };
136
+ /** The same policies for the vector table, applied by whoever ran `migrateVector` (#135). */
137
+ export const VECTOR_RLS_STATEMENTS = VECTOR_TENANT_SCOPED_TABLES.flatMap(policyFor);
138
+ export const applyVectorRls = async (sql) => {
139
+ for (const stmt of VECTOR_RLS_STATEMENTS)
140
+ await sql.query(stmt);
141
+ };
142
+ /**
143
+ * Every table `MIGRATIONS` creates, in migration order.
144
+ *
145
+ * Derived rather than transcribed: the SPEC's hand-written list named `interactions` and `blob_refs`,
146
+ * neither of which exists, and missed `schema_migrations`. A list that can disagree with the schema
147
+ * will eventually disagree with the schema.
148
+ */
149
+ /**
150
+ * Every table any migration creates — **both** lists (#145).
151
+ *
152
+ * `VECTOR_MIGRATIONS` was missing, and that was a hole in the coverage gate rather than an oversight in a list:
153
+ * a table added there was never scanned, so it could ship with no RLS policy and no exemption and nothing would
154
+ * say so. `knowledge_chunks` happened to be covered because someone remembered; the *next* vector table would
155
+ * not have been.
156
+ *
157
+ * Found by auditing the gate rather than the list, which is the difference between checking the answer and
158
+ * checking the thing that produces it.
159
+ */
160
+ export const tablesInMigrations = () => {
161
+ const names = [];
162
+ for (const migration of [...MIGRATIONS, ...VECTOR_MIGRATIONS]) {
163
+ for (const statement of migration.up) {
164
+ const match = /CREATE TABLE (?:IF NOT EXISTS )?([a-z_][a-z0-9_]*)/i.exec(statement);
165
+ if (match?.[1] && !names.includes(match[1]))
166
+ names.push(match[1]);
167
+ }
168
+ }
169
+ return names;
170
+ };
171
+ /**
172
+ * Bind the **session** to a tenant. Safe only on a direct connection.
173
+ *
174
+ * `is_local = false` makes the setting outlive the current transaction, which is right for a
175
+ * connection this process owns exclusively — and **dangerous behind a transaction-mode pooler**, which
176
+ * is how Supabase's pooler port works. There, a backend is handed to a different client after each
177
+ * transaction while the session GUC stays set, so tenant A's binding is still in place when tenant B's
178
+ * query lands on that backend, and B's queries are evaluated against A's tenant id.
179
+ *
180
+ * That is a cross-tenant read produced by the mechanism introduced to prevent cross-tenant reads, and
181
+ * it is worse than having no policy at all, because the policy makes it look handled.
182
+ *
183
+ * Prefer `withTenantContext` unless you are certain the connection is not pooled. See the open
184
+ * question on #104 about removing this entirely.
185
+ */
186
+ export const setTenantContext = async (sql, tenantId) => {
187
+ await sql.query(`SELECT set_config('app.tenant_id', $1, false)`, [tenantId]);
188
+ };
189
+ /**
190
+ * Run `fn` with the tenant (and optionally the principal) bound **for the duration of one
191
+ * transaction**, which is the only binding that is safe behind a pooler.
192
+ *
193
+ * `is_local = true` scopes the setting to the transaction, so it is discarded at commit or rollback
194
+ * and cannot be observed by whoever gets the backend next. The transaction comes from #98's
195
+ * `TransactionRunner`, and the executor handed to `fn` is the transaction's — so stores built over a
196
+ * `scoped()` executor participate without knowing any of this exists.
197
+ */
198
+ export const withTenantContext = async (runner, scope, fn) => runner.transaction(async (sql) => {
199
+ await sql.query(`SELECT set_config('app.tenant_id', $1, true)`, [scope.tenantId]);
200
+ if (scope.principalId !== undefined) {
201
+ await sql.query(`SELECT set_config('app.principal_id', $1, true)`, [scope.principalId]);
202
+ }
203
+ return fn(sql);
204
+ });
205
+ /**
206
+ * Bind the **session** to a principal. Same pooling caveat as `setTenantContext` — prefer passing
207
+ * `principalId` to `withTenantContext`.
208
+ *
209
+ * Separate from `setTenantContext` because most work has a tenant and no principal — a background
210
+ * reaper, a migration, a rollup. Those must not be able to read principal-scoped rows, and with this
211
+ * unset they cannot: the predicate compares against NULL and matches nothing.
212
+ */
213
+ export const setPrincipalContext = async (sql, principalId) => {
214
+ await sql.query(`SELECT set_config('app.principal_id', $1, false)`, [principalId]);
215
+ };
216
+ //# sourceMappingURL=rls.js.map
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `FileContentStore` over Supabase Storage — the production object-storage adapter (#129).
3
+ *
4
+ * This is the first store where Supabase is not simply Postgres. Every other port aliases straight to the
5
+ * Postgres implementation, and `supabase-conformance.test.ts` asserts that by identity. File bytes are the
6
+ * exception, and not incidentally: #102 declined to make `blobs` a pointer table, and `0013_files` keeps
7
+ * only metadata, precisely so that bytes live somewhere built for them.
8
+ *
9
+ * **Over `fetch`, not an SDK.** Supabase Storage is a plain REST API with a bearer token, so an SDK would
10
+ * add a dependency, a client lifecycle and an auth model for four HTTP calls. `fetch` is injected rather
11
+ * than reached for, so the conformance harness runs the real URL construction and status handling against
12
+ * an in-process double instead of a live bucket.
13
+ *
14
+ * **Two properties that are not obvious from the port:**
15
+ *
16
+ * - **The tenant is the path prefix, and a content key may not contain a separator.** `sanitizeMediaRefs` in
17
+ * ShareFlow is the cautionary tale this is written against — its workspace-prefix check was *"the ONLY
18
+ * thing standing between a forged path and a signed URL to another tenant's private object."* Here the
19
+ * key is validated to a character class, so `../` cannot be spelled at all.
20
+ * - **Listing is offset-paged, because the API is.** Unlike the metadata stores, which use keyset cursors
21
+ * deliberately, this one cannot: a concurrent upload can shift a page. That is tolerable only because the
22
+ * sole caller is reconciliation, which reports rather than deletes and runs again.
23
+ */
24
+ import type { FileContentStore } from "../../persistence/index.js";
25
+ /** The slice of `fetch` this adapter uses. Injected so the harness can run the real request building. */
26
+ export type FetchLike = (url: string, init?: {
27
+ method?: string;
28
+ headers?: Record<string, string>;
29
+ body?: Uint8Array | string;
30
+ }) => Promise<{
31
+ readonly status: number;
32
+ readonly ok: boolean;
33
+ text(): Promise<string>;
34
+ arrayBuffer(): Promise<ArrayBuffer>;
35
+ }>;
36
+ export type SupabaseStorageConfig = {
37
+ /** Project URL, e.g. `https://abc.supabase.co`. No trailing slash required. */
38
+ readonly url: string;
39
+ /**
40
+ * The service-role key.
41
+ *
42
+ * A `secret://` reference in a manifest, resolved by the host before it reaches here — the same rule
43
+ * #96 set for MCP credentials. Never logged: every error below reports status and path, never headers.
44
+ */
45
+ readonly serviceKey: string;
46
+ readonly bucket: string;
47
+ readonly fetch: FetchLike;
48
+ };
49
+ export declare const createSupabaseStorageFileContentStore: (config: SupabaseStorageConfig) => FileContentStore;
50
+ //# sourceMappingURL=storage.d.ts.map