permdock 0.8.0 → 0.10.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 (277) hide show
  1. package/dist/a2a/index.d.ts +4 -4
  2. package/dist/a2a/index.js +3 -3
  3. package/dist/{action-result-CL-QCITA.d.ts → action-result-BcudBQOF.d.ts} +1 -1
  4. package/dist/active-tenant-DVee32-T.js +39 -0
  5. package/dist/{adoption-scan-BLs67P1l.js → adoption-scan-0oFt2RD5.js} +1 -1
  6. package/dist/agent/index.d.ts +2 -2
  7. package/dist/agent/index.js +1 -1
  8. package/dist/ai-sdk/index.d.ts +3 -3
  9. package/dist/ai-sdk/index.js +3 -3
  10. package/dist/{approval-prompt-PYagyQUj.d.ts → approval-prompt-3BqWczTt.d.ts} +1 -1
  11. package/dist/approvals/index.d.ts +3 -3
  12. package/dist/{arazzo-3RhGfkAK.js → arazzo-DA9PCXew.js} +1 -1
  13. package/dist/{arazzo-B5-ulWif.js → arazzo-DhxDfYt-.js} +2 -2
  14. package/dist/astro/index.d.ts +4 -4
  15. package/dist/astro/index.js +1 -1
  16. package/dist/{audience-BAkBDMqn.js → audience-DTjR8xet.js} +1 -1
  17. package/dist/authzen/index.d.ts +5 -5
  18. package/dist/authzen/index.js +1 -1
  19. package/dist/{automation-DqEoWHBc.d.ts → automation-C6Jg75xq.d.ts} +1 -1
  20. package/dist/better-auth/index.d.ts +1 -1
  21. package/dist/better-supabase/index.d.ts +192 -27
  22. package/dist/better-supabase/index.js +248 -64
  23. package/dist/{bind-D_sZSVA3.js → bind-BNQA9JK9.js} +7 -3
  24. package/dist/{bind-Cp2hBHzP.d.ts → bind-YYjvfpB9.d.ts} +12 -7
  25. package/dist/{build-instance-CNWaYJyr.js → build-instance-BWXqwQYU.js} +1 -1
  26. package/dist/{capability-ChuiONQU.d.ts → capability-Di9tiUvi.d.ts} +1 -1
  27. package/dist/{casbin-H0rKxBx2.js → casbin-BJu2liqU.js} +1 -1
  28. package/dist/{casbin-cbSbhT_k.js → casbin-BkhqGh2z.js} +1 -1
  29. package/dist/catalog/index.d.ts +4 -4
  30. package/dist/catalog/index.js +2 -2
  31. package/dist/{catalog-BFpz2EmT.js → catalog-CGlSwU6j.js} +2 -2
  32. package/dist/catalog-D3oS2GH3.js +1 -0
  33. package/dist/{catalog-DCspHDc8.js → catalog-amPDr0JQ.js} +1 -1
  34. package/dist/{catalog-operations-Dadrl7Z-.js → catalog-operations-DeHTrJSV.js} +1 -1
  35. package/dist/chat/index.d.ts +1 -1
  36. package/dist/chat/index.js +1 -1
  37. package/dist/chat-sdk/index.d.ts +3 -3
  38. package/dist/claude-agent/index.d.ts +3 -3
  39. package/dist/claude-agent/index.js +2 -2
  40. package/dist/clerk/index.d.ts +2 -2
  41. package/dist/cli/bin.js +1 -1
  42. package/dist/cli/index.d.ts +9 -4
  43. package/dist/cli/index.js +11 -3
  44. package/dist/cloud/index.d.ts +8 -8
  45. package/dist/{cloud-BFlGMaak.js → cloud-3RIuS4E9.js} +2 -2
  46. package/dist/{codemod-DLQ9Zpo4.js → codemod-DLcp-B6v.js} +2 -2
  47. package/dist/{codemod-DWSN2erG.js → codemod-DRl_w-bY.js} +1 -1
  48. package/dist/collect-D-eroIfV.js +1 -0
  49. package/dist/{collect-Bzv3le0A.js → collect-D9Tt0Bcx.js} +2 -2
  50. package/dist/{collect-B7ZFAJU3.js → collect-WCl8cJQV.js} +1 -1
  51. package/dist/compile/index.d.ts +1 -1
  52. package/dist/{compile-BFzysW3o.d.ts → compile-BEklRUYo.d.ts} +2 -2
  53. package/dist/{completion-saoYiRFO.js → completion-VSWvaaPO.js} +1 -1
  54. package/dist/{config-BwPBfN0t.js → config-BR23fL8m.js} +2 -2
  55. package/dist/{config-DBeXXmBF.js → config-kL36AxkE.js} +1 -1
  56. package/dist/{config-report-BipSWA6V.js → config-report-osnfUNg5.js} +3 -3
  57. package/dist/{config-shape-ykV0Vm2n.js → config-shape-tsxHx71E.js} +2 -1
  58. package/dist/convex/index.d.ts +4 -4
  59. package/dist/convex/index.js +2 -2
  60. package/dist/{core-hWIARPDz.d.ts → core-CFepFiDP.d.ts} +2 -2
  61. package/dist/{core-H-mbhpZc.js → core-DzVINFbU.js} +3 -3
  62. package/dist/{create-Cq4Uox0f.js → create-6EwRQlig.js} +3 -3
  63. package/dist/{create-_noSrY1T.js → create-BLPKnJKa.js} +23 -7
  64. package/dist/{create-BSNrVuxh.d.ts → create-BPUopdfL.d.ts} +7 -7
  65. package/dist/{create-CM1FciYG.d.ts → create-CDd9c22W.d.ts} +15 -6
  66. package/dist/{create-BVq1lNQE.d.ts → create-DBvUsgzK.d.ts} +4 -4
  67. package/dist/delivery/index.d.ts +4 -4
  68. package/dist/delivery/index.js +1 -1
  69. package/dist/{denied-text-CHNlVInN.d.ts → denied-text-DHldhVUv.d.ts} +1 -1
  70. package/dist/{describe-ByS9LgHK.d.ts → describe-BbFPBSms.d.ts} +1 -1
  71. package/dist/{diff-CN8IYhC_.js → diff-BwR1JdP2.js} +1 -1
  72. package/dist/{diff-iZWV65nC.js → diff-CQegtBAo.js} +2 -2
  73. package/dist/{doctor-D3wo-yuz.js → doctor-B9FY9H0F.js} +2 -2
  74. package/dist/{doctor-CHD1M9R5.js → doctor-DfTnMaUt.js} +144 -16
  75. package/dist/drizzle/index.d.ts +3 -3
  76. package/dist/elysia/index.d.ts +4 -4
  77. package/dist/elysia/index.js +1 -1
  78. package/dist/{errors-zi_4T-rx.d.ts → errors-BIM4MFsJ.d.ts} +1 -1
  79. package/dist/{evaluate-Dd8Ta0Ie.js → evaluate-BAmf_AQd.js} +13 -4
  80. package/dist/{evaluations-z8dQFDaN.d.ts → evaluations-DOWuBpWv.d.ts} +3 -3
  81. package/dist/eve/index.d.ts +4 -4
  82. package/dist/eve/index.js +2 -2
  83. package/dist/express/index.d.ts +4 -4
  84. package/dist/express/index.js +1 -1
  85. package/dist/fastify/index.d.ts +4 -4
  86. package/dist/fastify/index.js +1 -1
  87. package/dist/{fetch-adapter-C1DCvpqV.d.ts → fetch-adapter-BIbBAtPZ.d.ts} +2 -2
  88. package/dist/{fetch-adapter-JL43jD3E.js → fetch-adapter-dPTgJVHd.js} +1 -1
  89. package/dist/{fields-D0vUI6dq.js → fields-DI8s3cPl.js} +1 -1
  90. package/dist/{gen-DWCYcMQM.js → gen-DuAhghDw.js} +2 -2
  91. package/dist/{gen-B5kvbAoZ.js → gen-DwgCSC6V.js} +1 -1
  92. package/dist/h3/index.d.ts +4 -4
  93. package/dist/h3/index.js +2 -2
  94. package/dist/hono/index.d.ts +4 -4
  95. package/dist/hono/index.js +1 -1
  96. package/dist/{hosted-Cmtxogd0.d.ts → hosted-DVxlLZMe.d.ts} +1 -1
  97. package/dist/{import-CST57XLp.js → import-CNBF96hB.js} +2 -2
  98. package/dist/{import-_YqhhwvX.js → import-Iuk9mx8A.js} +1 -1
  99. package/dist/{index-BhxEUY9J.d.ts → index-BinlXeU-.d.ts} +2 -2
  100. package/dist/{index-B8s204GL.d.ts → index-CV-7DWeD.d.ts} +4 -4
  101. package/dist/{index-BW_0MZOS.d.ts → index-Cay5-Kvx.d.ts} +13 -8
  102. package/dist/{index-_9UiQIkt.d.ts → index-DJwEgYzA.d.ts} +4 -4
  103. package/dist/{index-BT5-1VsX.d.ts → index-Dj2qF9VC.d.ts} +1 -1
  104. package/dist/{index-Bv5iXPqU.d.ts → index-ymept53A.d.ts} +4 -4
  105. package/dist/index.d.ts +16 -15
  106. package/dist/index.js +6 -6
  107. package/dist/{init-cE3A8aXq.js → init-DeoSvkh2.js} +1 -1
  108. package/dist/{init-Dz_PsHdv.js → init-fNF_XmTa.js} +3 -3
  109. package/dist/{instance-options-B0KXqTrJ.d.ts → instance-options-CoHn-0e8.d.ts} +1 -1
  110. package/dist/{instance-snapshot--JWiTrvO.js → instance-snapshot-DuWf1cT3.js} +13 -8
  111. package/dist/jwt/index.d.ts +4 -4
  112. package/dist/jwt/index.js +1 -1
  113. package/dist/{kernel-C-fYydV2.js → kernel-qv4cr9w8.js} +4 -4
  114. package/dist/kysely/index.d.ts +3 -3
  115. package/dist/{login-DplQ0s84.js → login-CutVtcmQ.js} +1 -1
  116. package/dist/{login-D-8tMqzo.js → login-DYazeWc9.js} +3 -3
  117. package/dist/{manifest-Cgiq5oqc.js → manifest-B4ENCp2I.js} +35 -35
  118. package/dist/{manifest-CzzWtnAb.d.ts → manifest-B5yF3CIq.d.ts} +19 -0
  119. package/dist/{manifest-wg8WkkpD.js → manifest-BXTbHNIV.js} +1 -1
  120. package/dist/{manifest-schema-2r37XRhD.js → manifest-schema-DQkBK2Mr.js} +28 -1
  121. package/dist/{map-claims-BNWCJtmP.js → map-claims-C-nv08_n.js} +2 -1
  122. package/dist/mcp/index.d.ts +8 -8
  123. package/dist/mcp/index.js +4 -4
  124. package/dist/{migrate-B7oP_sQU.js → migrate-BJHxQqT5.js} +2 -2
  125. package/dist/{module-values-BJTBdo6y.js → module-values-B1EVTkHP.js} +1 -1
  126. package/dist/nest/index.d.ts +4 -4
  127. package/dist/nest/index.js +1 -1
  128. package/dist/next/index.d.ts +32 -12
  129. package/dist/next/index.js +15 -8
  130. package/dist/next/plugin.d.ts +1 -1
  131. package/dist/next/plugin.js +1 -1
  132. package/dist/node/index.d.ts +4 -4
  133. package/dist/node/index.js +1 -1
  134. package/dist/openai/index.d.ts +4 -4
  135. package/dist/openai/index.js +3 -3
  136. package/dist/openapi/index.d.ts +2 -2
  137. package/dist/{openapi-VeHHU2l9.js → openapi-C-ADypaY.js} +1 -1
  138. package/dist/{openapi-CBZUhA3l.js → openapi-DFj0cirS.js} +2 -2
  139. package/dist/orpc/index.d.ts +5 -5
  140. package/dist/orpc/index.js +2 -2
  141. package/dist/otel/index.d.ts +3 -3
  142. package/dist/{output-tkju6U7R.js → output-LsbLe41I.js} +1 -1
  143. package/dist/{ownership-B4L59T9u.js → ownership-qqBuGJXr.js} +11 -6
  144. package/dist/{parse-local-manifest-BQhTlLQS.d.ts → parse-local-manifest-CCmbhnxP.d.ts} +1 -1
  145. package/dist/pdp/index.d.ts +3 -3
  146. package/dist/pdp/index.js +1 -1
  147. package/dist/{permdock-L-_I_3zP.js → permdock-BvjivVb9.js} +143 -107
  148. package/dist/{permdock-B6Sf4T_S.d.ts → permdock-CprAPN3w.d.ts} +9 -2
  149. package/dist/{permissions-mDcTWoBs.js → permissions-CYcHj_w7.js} +1 -1
  150. package/dist/{policy-Ba4bDhaj.d.ts → policy-BycVKnXv.d.ts} +1 -1
  151. package/dist/{policy-from-catalog-CJgOm6aq.js → policy-from-catalog-CU3An8uP.js} +1 -1
  152. package/dist/{policy-types-CCiDRZBH.d.ts → policy-types-DGIO_gxq.d.ts} +54 -18
  153. package/dist/{postgrest-DicQyqm-.d.ts → postgrest-D5nUGm-c.d.ts} +4 -3
  154. package/dist/{postgrest-D4nuPXIQ.js → postgrest-DAxFltvO.js} +35 -56
  155. package/dist/{powersync-DXqGuq9A.js → powersync-B_8uwz7f.js} +2 -2
  156. package/dist/powersync-CSzDCHRu.js +1 -0
  157. package/dist/{powersync-DHNQX06W.js → powersync-DUT-UKgw.js} +190 -38
  158. package/dist/prisma/index.d.ts +2 -2
  159. package/dist/{protected-action-BE7N_Luo.d.ts → protected-action-D8x73IGm.d.ts} +6 -6
  160. package/dist/{provider-DXfq5c2d.d.ts → provider-DfLeek9O.d.ts} +1 -1
  161. package/dist/{pull-CwpGaQSi.js → pull-DQCgvJSC.js} +2 -2
  162. package/dist/pull-DYbyod1f.js +1 -0
  163. package/dist/{push-DgssgzkK.js → push-Dq_ca4-j.js} +3 -3
  164. package/dist/{pushed-policy-ITwYKvvH.js → pushed-policy-CDuOL2de.js} +1 -1
  165. package/dist/{pushed-policy-D1Eoi6NM.d.ts → pushed-policy-CryQheKq.d.ts} +1 -1
  166. package/dist/react/index.d.ts +7 -7
  167. package/dist/react/provider-client.d.ts +1 -1
  168. package/dist/react-native/index.d.ts +9 -9
  169. package/dist/{replay-DNftIb_R.d.ts → replay-Bs9Df2fQ.d.ts} +1 -1
  170. package/dist/{request-context-C25ilqiJ.js → request-context-Duzdf0cd.js} +1 -1
  171. package/dist/resend/index.d.ts +4 -4
  172. package/dist/{resolve-names-CF7xXLSG.js → resolve-names-Y1Cb22cp.js} +4 -4
  173. package/dist/{rls-CNEH2_BG.js → rls-B57mIeVq.js} +34 -20
  174. package/dist/{rls-Ca8Jz9b5.js → rls-j0YrFPpW.js} +1 -1
  175. package/dist/{rpc-fNqAIqQk.js → rpc-vHIwyXCp.js} +1 -1
  176. package/dist/run-BATawNVH.js +1 -0
  177. package/dist/{run-Bz26OTfO.js → run-CLP_fQUF.js} +3 -3
  178. package/dist/{run-ticket-Dv7aF7Dk.js → run-ticket-DfnZCh-u.js} +19 -6
  179. package/dist/{run-ticket-DbWI9f99.d.ts → run-ticket-ylovhyFQ.d.ts} +18 -3
  180. package/dist/{saas-iWnUdwCt.js → saas-DK4V-3Is.js} +2 -2
  181. package/dist/{scan-DCj1KQfn.js → scan-B7xrAvRm.js} +1 -1
  182. package/dist/{schema-Dst9I9Gs.js → schema-3PJ8wAeL.js} +1 -1
  183. package/dist/scim/index.d.ts +1 -1
  184. package/dist/server/index.d.ts +11 -11
  185. package/dist/server/index.js +2 -2
  186. package/dist/{server-types-CIlpSA2G.d.ts → server-types-CyRN0-Cd.d.ts} +15 -8
  187. package/dist/{shared-Afctg7B0.js → shared-DrGLwM3s.js} +1 -1
  188. package/dist/{sink-Dvi7YZG_.d.ts → sink-B5zoUW_O.d.ts} +2 -2
  189. package/dist/{skills-OuoMR49L.js → skills-BUI8DMqy.js} +1 -1
  190. package/dist/{skills-Bjj7BNEQ.js → skills-iwbRxavw.js} +1 -1
  191. package/dist/{snapshot-cache-BAXZ0KOp.d.ts → snapshot-cache-BjAWkchD.d.ts} +1 -1
  192. package/dist/solid/index.d.ts +6 -6
  193. package/dist/solid-start/index.d.ts +4 -4
  194. package/dist/solid-start/index.js +2 -2
  195. package/dist/{sources-CMAM-2A3.js → sources-C4vkzZJV.js} +12 -7
  196. package/dist/{types-ah9NlU6j.d.ts → sources-oB1Hg1Fm.d.ts} +316 -2
  197. package/dist/{src-DZ0l9UAg.js → src-C_pi2Rnh.js} +106 -5
  198. package/dist/ssf/index.d.ts +3 -3
  199. package/dist/{standard-webhooks-C-qX4mJW.d.ts → standard-webhooks-DOYEuOLx.d.ts} +2 -2
  200. package/dist/{stores-C0Kta5Ft.d.ts → stores-DZJvxFIZ.d.ts} +6 -6
  201. package/dist/{stream-ltuLdtTG.d.ts → stream-9y9qw51m.d.ts} +1 -1
  202. package/dist/supabase/index.d.ts +5 -6
  203. package/dist/supabase/index.js +4 -4
  204. package/dist/supabase/middleware.d.ts +5 -5
  205. package/dist/supabase/middleware.js +4 -4
  206. package/dist/{supabase-BL1qJzzY.js → supabase-B1EfuD47.js} +2 -2
  207. package/dist/{supabase-D39cuGPt.js → supabase-BaizG0n7.js} +2 -2
  208. package/dist/{supabase-hook-B-yXnzUl.js → supabase-hook-BT2P9wah.js} +110 -47
  209. package/dist/supabase-hook-CbvGAutK.js +1 -0
  210. package/dist/{supautils-BU-pAEpf.js → supautils-DBKOoyjn.js} +247 -200
  211. package/dist/svelte/index.d.ts +6 -6
  212. package/dist/svelte/runtime.d.ts +3 -3
  213. package/dist/svelte/source.d.ts +6 -6
  214. package/dist/sveltekit/index.d.ts +4 -4
  215. package/dist/sveltekit/index.js +1 -1
  216. package/dist/{tables-DeMNEy6V.js → tables-DimBcVWY.js} +3 -3
  217. package/dist/tanstack-start/index.d.ts +4 -4
  218. package/dist/tanstack-start/index.js +1 -1
  219. package/dist/terminal/index.d.ts +5 -5
  220. package/dist/terminal/index.js +2 -2
  221. package/dist/testing/core.d.ts +1 -1
  222. package/dist/testing/core.js +1 -1
  223. package/dist/testing/fixtures/index.d.ts +1 -1
  224. package/dist/testing/fixtures/index.js +26 -28
  225. package/dist/testing/index.d.ts +23 -21
  226. package/dist/testing/index.js +64 -10
  227. package/dist/testing/saas/index.d.ts +3 -3
  228. package/dist/testing/saas/index.js +2 -2
  229. package/dist/testing/saas/permissions.js +1 -1
  230. package/dist/trpc/index.d.ts +5 -5
  231. package/dist/trpc/index.js +2 -2
  232. package/dist/{type-helpers-BIPIDa6a.d.ts → type-helpers-c7Xo_2Cu.d.ts} +1 -1
  233. package/dist/{types-B2mlGuhW.d.ts → types-B2efzoSX.d.ts} +1 -1
  234. package/dist/{types-DHKPcqzr.d.ts → types-B6ExllNo.d.ts} +2 -2
  235. package/dist/{types-AMJ5qoU_.d.ts → types-BB-zWDcR.d.ts} +4 -4
  236. package/dist/{types-djVzLlIV.d.ts → types-CEinc15V.d.ts} +4 -4
  237. package/dist/{types-yUuPR5Hy.d.ts → types-CN0LsqbK.d.ts} +3 -3
  238. package/dist/{types-HzqOtvsJ.d.ts → types-CWBsAwqn.d.ts} +4 -4
  239. package/dist/{types-DC1Loeh3.d.ts → types-Cklw5hJo.d.ts} +26 -3
  240. package/dist/{types-B_tiYvk8.d.ts → types-DLvhVm1r.d.ts} +1 -1
  241. package/dist/{types-B4uqKDnp.d.ts → types-DlelvQk4.d.ts} +2 -2
  242. package/dist/{types-DjuMBNF9.d.ts → types-DsHGPtkR.d.ts} +2 -2
  243. package/dist/{types-BJk0BKRX.d.ts → types-rCRV4Ge-.d.ts} +4 -4
  244. package/dist/{types-B_d_g7T3.d.ts → types-tQB2CEnY.d.ts} +4 -4
  245. package/dist/unplugin/index.d.ts +1 -1
  246. package/dist/unplugin/index.js +1 -1
  247. package/dist/{usage-ab0PdusX.js → usage-B1ZJOUdr.js} +1 -1
  248. package/dist/{usage-CxEzS4ey.js → usage-t_nXnwCW.js} +3 -3
  249. package/dist/usage-weohzv2f.js +1 -0
  250. package/dist/{validation-error-YGg2mXyH.d.ts → validation-error-uvp-kyfO.d.ts} +1 -1
  251. package/dist/{verify-DZeqoWu5.js → verify-jHrbmn-E.js} +9 -9
  252. package/dist/version-cache-Df11C2Qp.d.ts +51 -0
  253. package/dist/vue/index.d.ts +6 -6
  254. package/dist/{waiter-Bu9zAlE0.d.ts → waiter-CqUKX6CY.d.ts} +2 -2
  255. package/dist/{watch-Cx_WciLE.js → watch-Bpci3hBY.js} +2 -2
  256. package/dist/watch-COuvly20.js +1 -0
  257. package/dist/webmcp/index.d.ts +1 -1
  258. package/dist/{who-can-rI7dCR9Q.js → who-can-BoDJm0Nc.js} +1 -1
  259. package/dist/workflow/index.d.ts +3 -3
  260. package/dist/workflow/index.js +23 -7
  261. package/dist/workflow-sdk/index.d.ts +4 -4
  262. package/dist/{wrap-DlJE3gS_.d.ts → wrap-DxXB54Wu.d.ts} +2 -2
  263. package/package.json +3 -3
  264. package/schemas/run-v1.json +16 -0
  265. package/schemas/supabase-manifest-v1.json +28 -0
  266. package/skills/permdock-agents/references/operations-automations-chat.md +1 -0
  267. package/skills/permdock-data/references/queries-and-rls.md +1 -1
  268. package/skills/permdock-wire/references/adapters.md +4 -3
  269. package/dist/catalog-mRQQQhNK.js +0 -1
  270. package/dist/collect-B5BL3klN.js +0 -1
  271. package/dist/powersync-Djf-zCpB.js +0 -1
  272. package/dist/pull-B65ndFNZ.js +0 -1
  273. package/dist/run-D-JE8QWb.js +0 -1
  274. package/dist/sources-B1Os_YUu.d.ts +0 -312
  275. package/dist/supabase-hook-H-MtE9Wd.js +0 -1
  276. package/dist/usage-CYeXek0p.js +0 -1
  277. package/dist/watch-DB42U1ib.js +0 -1
@@ -1,4 +1,4 @@
1
- import { a as ProblemDetails } from "./errors-zi_4T-rx.js";
1
+ import { a as ProblemDetails } from "./errors-BIM4MFsJ.js";
2
2
  import { StandardSchemaV1 } from "@standard-schema/spec";
3
3
  //#region src/core/validation-error.d.ts
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import { a as sole, r as isRecord } from "./compact-CAf557ZB.js";
2
2
  import { l as isConditionRef, o as hasConditionOp } from "./refs-C8BKxc_e.js";
3
- import { A as memoryCustomRoleSource, b as memoryRelationSource } from "./src-DZ0l9UAg.js";
3
+ import { j as memoryCustomRoleSource, x as memoryRelationSource } from "./src-C_pi2Rnh.js";
4
4
  import { c as listPermissions, h as formerKeys, n as findPermission } from "./permission-registry-B8tYxPIt.js";
5
5
  import { c as isEdgeRelation, l as isFieldRelation, u as isPrincipalRelation } from "./resource-relations-8-pCScBO.js";
6
6
  import { f as nowMillis, u as isoAt } from "./time-nR1JesoH.js";
@@ -10,8 +10,8 @@ import { o as requiresStandIn } from "./delegation-CDB6_keF.js";
10
10
  import { p as scopeField } from "./tenancy-5d1zVBvK.js";
11
11
  import { l as policyLevels, t as coveredLevels } from "./policy-CLQ8__GF.js";
12
12
  import { t as requiresApproval } from "./approval-required-TzNB9oQA.js";
13
- import { c as andWhere, m as customRoleScope, v as leveled, y as membershipsClaim } from "./evaluate-Dd8Ta0Ie.js";
14
- import { t as getPermDock } from "./permdock-L-_I_3zP.js";
13
+ import { c as andWhere, m as customRoleScope, v as leveled, y as membershipsClaim } from "./evaluate-BAmf_AQd.js";
14
+ import { t as getPermDock } from "./permdock-BvjivVb9.js";
15
15
  import { a as describeError, i as configError, u as usageResult } from "./errors-Vpu6rKHl.js";
16
16
  import { t as policyRowConditionKeys } from "./row-conditions-BAGHOmVq.js";
17
17
  import { s as writeFileEnsuringDir } from "./files-BSjrtIHw.js";
@@ -20,16 +20,16 @@ import { o as loadPolicyAt } from "./load-DjSU5KXO.js";
20
20
  import { i as qualifySqlTable, n as defaultSqlCommand, t as SQL_IDENT } from "./sql-0WjxIp9g.js";
21
21
  import { a as scopeMembershipTable, i as scopeColumn } from "./compile-EzEMB-7v.js";
22
22
  import "./budget-BELja5A9.js";
23
- import "./sources-CMAM-2A3.js";
23
+ import "./sources-C4vkzZJV.js";
24
24
  import { t as beforeFirst } from "./text-BMFRfBqc.js";
25
- import { t as DOCS_BASE } from "./manifest-Cgiq5oqc.js";
25
+ import { t as DOCS_BASE } from "./manifest-B4ENCp2I.js";
26
26
  import { n as fixtureSubject, r as loadFixtures, t as fixtureRow } from "./fixtures-A1_sp_tR.js";
27
- import { A as quoteQualified, N as arrayColumnsOf, O as quoteIdent, P as columnTypesOf, _ as subjectClaimJsonSql, a as customRolesOn, j as quoteTable, k as quoteLiteral, r as HELPERS, v as subjectClaimSql } from "./shared-Afctg7B0.js";
28
- import { C as accessSql, D as tokenScopeAllowsCall, S as requiresSql, ht as scopeTable, k as capabilityAccessSql, n as tableNameOf, o as graphPlan, q as apiKeyAllowsCall, r as tableNames } from "./tables-DeMNEy6V.js";
29
- import { c as breakGlassKey, f as compileConditionSql, l as collectGrants, m as sqlFunctionNames, p as contextRefs, s as breakGlassHolder } from "./ownership-B4L59T9u.js";
27
+ import { A as quoteQualified, N as arrayColumnsOf, O as quoteIdent, P as columnTypesOf, _ as subjectClaimJsonSql, a as customRolesOn, j as quoteTable, k as quoteLiteral, r as HELPERS, v as subjectClaimSql } from "./shared-DrGLwM3s.js";
28
+ import { C as accessSql, D as tokenScopeAllowsCall, S as requiresSql, ht as scopeTable, k as capabilityAccessSql, n as tableNameOf, o as graphPlan, q as apiKeyAllowsCall, r as tableNames } from "./tables-DimBcVWY.js";
29
+ import { c as breakGlassKey, f as compileConditionSql, l as collectGrants, m as sqlFunctionNames, p as contextRefs, s as breakGlassHolder } from "./ownership-qqBuGJXr.js";
30
30
  import { t as membershipSourcesOf } from "./sources-qoIJQrJv.js";
31
31
  import { n as pgConnector, t as connectPgPool } from "./pg-DQTqRrou.js";
32
- import { _ as wrapSql, g as validitySql, m as andSql, s as viewName, t as FIELD_VIEWS } from "./fields-D0vUI6dq.js";
32
+ import { _ as wrapSql, g as validitySql, m as andSql, s as viewName, t as FIELD_VIEWS } from "./fields-DI8s3cPl.js";
33
33
  import { resolve } from "node:path";
34
34
  import { createHash, randomUUID } from "node:crypto";
35
35
  //#region src/cli/rls/indexes.ts
@@ -0,0 +1,51 @@
1
+ import { Wt as Instant, yt as VersionQuery } from "./policy-types-DGIO_gxq.js";
2
+ //#region src/core/version-cache.d.ts
3
+ type VersionCacheStats = {
4
+ /** Version reads the cache started. */
5
+ readonly reads: number;
6
+ /** Calls answered by a read already in flight. */
7
+ readonly shared: number;
8
+ /** Calls answered from an entry or a token claim, with no read. */
9
+ readonly hits: number;
10
+ readonly evictions: number;
11
+ readonly size: number;
12
+ };
13
+ /**
14
+ * Current authorization versions shared by every instance in a process:
15
+ * `claimsFirst(source, { versions })` reads through it.
16
+ */
17
+ type VersionCache = {
18
+ readonly name?: string;
19
+ /** How old an entry may be when an instance with intent `read` uses it. */
20
+ readonly maxStaleMs: number;
21
+ /**
22
+ * The current version of `principal`. With `live: false`, an entry at most
23
+ * `maxStaleMs` old answers, a read in flight is shared, and a token claim
24
+ * newer than the entry raises it; with `live: true`, `read` runs.
25
+ */
26
+ current: (principal: VersionQuery, read: () => number | undefined | Promise<number | undefined>, options: {
27
+ readonly live: boolean;
28
+ }) => number | undefined | Promise<number | undefined>;
29
+ /** Drops `principal`'s entry, so the next instance reads the version. */
30
+ evict: (principal: string) => void;
31
+ stats: () => VersionCacheStats;
32
+ };
33
+ type MemoryVersionCacheOptions = {
34
+ /**
35
+ * How stale a read may be, in milliseconds: the entry lifetime and the
36
+ * longest a removed member keeps read access. Clamped to 0 to 60,000.
37
+ */
38
+ readonly maxStaleMs: number;
39
+ /** Principals kept; the least recently used goes first. Default 10,000. */
40
+ readonly maxEntries?: number;
41
+ /** The clock, read only when an instance asks for a version. */
42
+ readonly now?: () => Instant;
43
+ };
44
+ /**
45
+ * An in-process `VersionCache`: a bounded LRU keyed by principal id that keeps
46
+ * resolved versions and shares reads in flight. Create it once at module
47
+ * scope.
48
+ */
49
+ declare function memoryVersionCache(options: MemoryVersionCacheOptions): VersionCache;
50
+ //#endregion
51
+ export { memoryVersionCache as i, VersionCache as n, VersionCacheStats as r, MemoryVersionCacheOptions as t };
@@ -1,13 +1,13 @@
1
- import { Gt as Snapshot, In as ApprovalRequiredDecision, Ln as Decision, dt as TokenVerifier, j as PolicyVocabulary, or as Membership } from "../policy-types-CCiDRZBH.js";
1
+ import { Hn as ApprovalRequiredDecision, Un as Decision, Zt as Snapshot, fr as Membership, ht as TokenVerifier, j as PolicyVocabulary } from "../policy-types-DGIO_gxq.js";
2
2
  import { u as Permission } from "../permission-types-CAY-GU7e.js";
3
3
  import { r as Role } from "../vocabulary-DEJ5j4mR.js";
4
- import { d as UncheckedData, s as RowData } from "../permdock-B6Sf4T_S.js";
5
- import { c as requiredPlans } from "../errors-zi_4T-rx.js";
6
- import { i as describe, r as DescribeOptions, t as DecisionDescription } from "../describe-ByS9LgHK.js";
4
+ import { d as UncheckedData, s as RowData } from "../permdock-CprAPN3w.js";
5
+ import { c as requiredPlans } from "../errors-BIM4MFsJ.js";
6
+ import { i as describe, r as DescribeOptions, t as DecisionDescription } from "../describe-BbFPBSms.js";
7
7
  import { t as PermissionBoundaryState } from "../boundary-C9ck-3uK.js";
8
- import { n as ProtectedAction, t as ActionResult } from "../action-result-CL-QCITA.js";
8
+ import { n as ProtectedAction, t as ActionResult } from "../action-result-BcudBQOF.js";
9
9
  import { t as approvalHeaders } from "../headers-B9jQxjtW.js";
10
- import { a as FilterResult, b as eventSourceRefresh, c as PermissionSet, d as ProtectedActionView, f as ProviderOptionsBase, h as TenantView, i as ClientStatus, l as PermissionState, m as SubjectView, n as ApprovalState, o as GateMode, p as RolesOptions, r as ClientPermDock, s as GateView, t as ApprovalHandle, v as EventSourceRefreshOptions, y as RefreshTrigger } from "../types-B_d_g7T3.js";
10
+ import { a as FilterResult, b as eventSourceRefresh, c as PermissionSet, d as ProtectedActionView, f as ProviderOptionsBase, h as TenantView, i as ClientStatus, l as PermissionState, m as SubjectView, n as ApprovalState, o as GateMode, p as RolesOptions, r as ClientPermDock, s as GateView, t as ApprovalHandle, v as EventSourceRefreshOptions, y as RefreshTrigger } from "../types-tQB2CEnY.js";
11
11
  import { ComputedRef, DefineComponent, MaybeRefOrGetter, Plugin, VNode } from "vue";
12
12
  //#region src/vue/types.d.ts
13
13
  type PermDockPluginOptions = ProviderOptionsBase & {
@@ -1,5 +1,5 @@
1
- import { Rt as Instant } from "./policy-types-CCiDRZBH.js";
2
- import { m as ApprovalStore } from "./types-B_tiYvk8.js";
1
+ import { Wt as Instant } from "./policy-types-DGIO_gxq.js";
2
+ import { m as ApprovalStore } from "./types-DLvhVm1r.js";
3
3
  //#region src/workflow/waiter.d.ts
4
4
  type ApprovalWaitOptions = {
5
5
  /**
@@ -1,8 +1,8 @@
1
1
  import { i as dateAt } from "./time-nR1JesoH.js";
2
2
  import { a as describeError } from "./errors-Vpu6rKHl.js";
3
3
  import { t as defaultSrcPath } from "./files-BSjrtIHw.js";
4
- import { r as runCollect } from "./collect-B7ZFAJU3.js";
5
- import { n as isConfigFile, r as loadConfig } from "./config-BwPBfN0t.js";
4
+ import { r as runCollect } from "./collect-WCl8cJQV.js";
5
+ import { n as isConfigFile, r as loadConfig } from "./config-BR23fL8m.js";
6
6
  import { watch } from "node:fs";
7
7
  import { basename, dirname, relative, resolve, sep } from "node:path";
8
8
  //#region src/cli/watch.ts
@@ -0,0 +1 @@
1
+ export { i as watchCollect } from "./watch-Bpci3hBY.js";
@@ -1,4 +1,4 @@
1
- import { Gt as Snapshot, Ln as Decision } from "../policy-types-CCiDRZBH.js";
1
+ import { Un as Decision, Zt as Snapshot } from "../policy-types-DGIO_gxq.js";
2
2
  import { f as PermissionTree, u as Permission } from "../permission-types-CAY-GU7e.js";
3
3
  import { StandardSchemaV1 } from "@standard-schema/spec";
4
4
  //#region src/webmcp/types.d.ts
@@ -10,7 +10,7 @@ import { o as flattenGrantee } from "./grantee-Dke-9rd1.js";
10
10
  import { t as byCodePoint } from "./compare-DTfyUunF.js";
11
11
  import { r as relationCondition } from "./grantee-conditions-BrYPe-w0.js";
12
12
  import { c as nowSeconds, p as scopeField } from "./tenancy-5d1zVBvK.js";
13
- import { D as emptyListeners, t as evaluate } from "./evaluate-Dd8Ta0Ie.js";
13
+ import { D as emptyListeners, t as evaluate } from "./evaluate-BAmf_AQd.js";
14
14
  import { n as relationId, t as pendingRelations } from "./relations-BxvRvDHK.js";
15
15
  import { t as relationWalk } from "./relation-walk-DK_gkgL7.js";
16
16
  //#region src/core/who-can.ts
@@ -1,5 +1,5 @@
1
- import { a as AutomationSource, i as AutomationRequest, l as memoryAutomationSource, n as AutomationDecision, r as AutomationMode, s as MemoryAutomationSource, t as Automation, u as parseAutomation } from "../automation-DqEoWHBc.js";
2
- import { i as pollingApprovalWaiter, n as ApprovalWaiter, r as PollingApprovalWaiterOptions, t as ApprovalWaitOptions } from "../waiter-Bu9zAlE0.js";
3
- import { a as WorkflowPermDockOptions, i as WorkflowPermDock, n as AwaitApprovalOptions, o as createPermDock, r as StartAutomationResult, t as AutomationOptions } from "../create-CM1FciYG.js";
1
+ import { a as AutomationSource, i as AutomationRequest, l as memoryAutomationSource, n as AutomationDecision, r as AutomationMode, s as MemoryAutomationSource, t as Automation, u as parseAutomation } from "../automation-C6Jg75xq.js";
2
+ import { i as pollingApprovalWaiter, n as ApprovalWaiter, r as PollingApprovalWaiterOptions, t as ApprovalWaitOptions } from "../waiter-CqUKX6CY.js";
3
+ import { a as WorkflowPermDockOptions, i as WorkflowPermDock, n as AwaitApprovalOptions, o as createPermDock, r as StartAutomationResult, t as AutomationOptions } from "../create-CDd9c22W.js";
4
4
  import "../index-CaxrMD1A.js";
5
5
  export { type ApprovalWaitOptions, type ApprovalWaiter, type Automation, type AutomationDecision, type AutomationMode, type AutomationOptions, type AutomationRequest, type AutomationSource, type AwaitApprovalOptions, type MemoryAutomationSource, type PollingApprovalWaiterOptions, type StartAutomationResult, type WorkflowPermDock, type WorkflowPermDockOptions, createPermDock, memoryAutomationSource, parseAutomation, pollingApprovalWaiter };
@@ -1,12 +1,13 @@
1
1
  import { t as compact } from "../compact-CAf557ZB.js";
2
2
  import { n as freezeDeep } from "../freeze-jjan0lCv.js";
3
+ import { a as isId } from "../expiry-6XByK0dm.js";
3
4
  import { n as findPermission } from "../permission-registry-B8tYxPIt.js";
4
5
  import { n as isThenable } from "../thenable-BNSM1U2R.js";
5
6
  import { n as memoryAutomationSource, r as parseAutomation } from "../automation-x3KEUusw.js";
6
- import { l as withApp, t as getPermDock } from "../permdock-L-_I_3zP.js";
7
+ import { l as withApp, t as getPermDock } from "../permdock-BvjivVb9.js";
7
8
  import { o as automationEvent } from "../sink-D9_vh372.js";
8
9
  import { a as requestApproval, s as resumeDecision } from "../helpers-DJicaG6f.js";
9
- import { i as subjectFromRunTicket, r as signRunTicket } from "../run-ticket-Dv7aF7Dk.js";
10
+ import { i as subjectFromRunTicket, r as signRunTicket } from "../run-ticket-DfnZCh-u.js";
10
11
  import { t as pollingApprovalWaiter } from "../waiter-aBLM63_f.js";
11
12
  //#region src/workflow/create.ts
12
13
  function writeQuietly(sink, event) {
@@ -121,12 +122,22 @@ function createPermDock(policy, given) {
121
122
  }]
122
123
  });
123
124
  }
125
+ const { resource } = startOptions;
126
+ if (resource !== void 0 && !(isId(resource.type) && isId(resource.id))) return deniedStart("validation", { cause: "resource-invalid" });
124
127
  const scopes = [];
128
+ const bound = [];
125
129
  for (const key of automation.permissions) {
126
130
  const leaf = findPermission(policy.permissions, key);
127
131
  if (leaf === void 0) return deniedStart("validation", { permission: key });
128
- scopes.push(leaf.scope);
132
+ if (resource !== void 0 && leaf.resource === resource.type) bound.push(leaf.action);
133
+ else scopes.push(leaf.scope);
129
134
  }
135
+ if (resource !== void 0 && bound.length === 0) return deniedStart("validation", { resource: resource.type });
136
+ const authorizationDetails = resource === void 0 ? void 0 : [{
137
+ type: resource.type,
138
+ identifier: resource.id,
139
+ actions: bound
140
+ }];
130
141
  const runId = startOptions.id ?? globalThis.crypto.randomUUID();
131
142
  const runAutomation = {
132
143
  id: automation.id,
@@ -139,11 +150,15 @@ function createPermDock(policy, given) {
139
150
  id: automation.id,
140
151
  kind: "automation"
141
152
  },
142
- delegation: { scopes },
153
+ delegation: compact({
154
+ scopes,
155
+ authorizationDetails
156
+ }),
143
157
  automation: runAutomation,
144
158
  tenant: automation.tenant,
145
159
  trigger: startOptions.trigger,
146
160
  binding: startOptions.binding,
161
+ resource,
147
162
  id: runId,
148
163
  expiresIn
149
164
  }), signer, compact({
@@ -158,10 +173,11 @@ function createPermDock(policy, given) {
158
173
  return freezeDeep({
159
174
  outcome: "started",
160
175
  ticket: signed,
161
- run: {
176
+ run: compact({
162
177
  id: runId,
163
- automation: runAutomation
164
- }
178
+ automation: runAutomation,
179
+ resource
180
+ })
165
181
  });
166
182
  };
167
183
  const opened = async (ticket, permission, data, decideOptions) => {
@@ -1,8 +1,8 @@
1
- import { Ln as Decision } from "../policy-types-CCiDRZBH.js";
1
+ import { Un as Decision } from "../policy-types-DGIO_gxq.js";
2
2
  import { u as Permission } from "../permission-types-CAY-GU7e.js";
3
- import { a as PermDock } from "../permdock-B6Sf4T_S.js";
4
- import { n as ApprovalWaiter } from "../waiter-Bu9zAlE0.js";
5
- import { i as WorkflowPermDock, r as StartAutomationResult, t as AutomationOptions } from "../create-CM1FciYG.js";
3
+ import { a as PermDock } from "../permdock-CprAPN3w.js";
4
+ import { n as ApprovalWaiter } from "../waiter-CqUKX6CY.js";
5
+ import { i as WorkflowPermDock, r as StartAutomationResult, t as AutomationOptions } from "../create-CDd9c22W.js";
6
6
  //#region src/workflow-sdk/index.d.ts
7
7
  /**
8
8
  * The part of a Workflow SDK `Hook` the waiter reads: awaiting it suspends the
@@ -1,5 +1,5 @@
1
- import { j as PolicyVocabulary } from "./policy-types-CCiDRZBH.js";
2
- import { a as PermDock } from "./permdock-B6Sf4T_S.js";
1
+ import { j as PolicyVocabulary } from "./policy-types-DGIO_gxq.js";
2
+ import { a as PermDock } from "./permdock-CprAPN3w.js";
3
3
  //#region src/core/wrap.d.ts
4
4
  /** A wrapper an adapter applies to each instance it builds, as `withOtel` does. */
5
5
  type PermDockWrap = <V extends PolicyVocabulary>(permdock: PermDock<V>) => PermDock<V>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "permdock",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Typed permissions for TypeScript apps, APIs, databases, and AI agents, with the permdock CLI and test runners.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -353,7 +353,7 @@
353
353
  "ajv": "8.20.0",
354
354
  "astro": "7.4.0",
355
355
  "babel-plugin-react-compiler": "1.0.0",
356
- "better-supabase": "0.13.0",
356
+ "better-supabase": "0.18.0",
357
357
  "better-supabase-floor": "npm:better-supabase@0.13.0",
358
358
  "chat": "4.42.0",
359
359
  "diff": "9.0.0",
@@ -364,7 +364,7 @@
364
364
  "fastest-levenshtein": "1.0.16",
365
365
  "fastify": "5.12.7",
366
366
  "h3": "2.0.2",
367
- "happy-dom": "20.14.5",
367
+ "happy-dom": "21.0.4",
368
368
  "hono": "4.13.13",
369
369
  "jose": "6.2.12",
370
370
  "kysely": "0.29.6",
@@ -121,6 +121,22 @@
121
121
  "maxItems": 64
122
122
  }
123
123
  }
124
+ },
125
+ "resource": {
126
+ "type": "object",
127
+ "required": ["type", "id"],
128
+ "properties": {
129
+ "type": {
130
+ "type": "string",
131
+ "minLength": 1,
132
+ "maxLength": 256
133
+ },
134
+ "id": {
135
+ "type": "string",
136
+ "minLength": 1,
137
+ "maxLength": 256
138
+ }
139
+ }
124
140
  }
125
141
  },
126
142
  "anyOf": [
@@ -43,6 +43,27 @@
43
43
  "type": "string",
44
44
  "pattern": "^[A-Za-z_][A-Za-z0-9_]*\\.[A-Za-z_][A-Za-z0-9_]*$"
45
45
  }
46
+ },
47
+ "activeFrom": {
48
+ "description": "Where the hook reads the active first-scope id (supabase.hook.activeFrom): an app_metadata key, or a column of a table joined on id. Absent from a manifest written before 0.10.",
49
+ "oneOf": [
50
+ {
51
+ "type": "object",
52
+ "required": ["appMetadata"],
53
+ "additionalProperties": false,
54
+ "properties": { "appMetadata": { "type": "string" } }
55
+ },
56
+ {
57
+ "type": "object",
58
+ "required": ["table", "column", "id"],
59
+ "additionalProperties": false,
60
+ "properties": {
61
+ "table": { "type": "string" },
62
+ "column": { "type": "string" },
63
+ "id": { "type": "string" }
64
+ }
65
+ }
66
+ ]
46
67
  }
47
68
  }
48
69
  },
@@ -562,6 +583,13 @@
562
583
  },
563
584
  "column": {
564
585
  "$ref": "#/$defs/identifier"
586
+ },
587
+ "on": {
588
+ "description": "Every referencing column to the column of table it matches, when the reference spans several columns.",
589
+ "type": "object",
590
+ "additionalProperties": {
591
+ "$ref": "#/$defs/identifier"
592
+ }
565
593
  }
566
594
  }
567
595
  }
@@ -127,6 +127,7 @@ run.can(permissions.invoice.send, invoice);
127
127
  ```
128
128
 
129
129
  - `start(id, { caller, trigger })` reads the live automation, checks the caller's `run` permission and signs a run ticket (`vnd.permdock.run+jwt`, 24 hours by default). Without `caller`, only server code starts it.
130
+ - `start(id, { resource: { type, id } })` binds the run to one record: its permissions on `type` go into an `authorization_details` entry with `identifier: id`, so they hold on that row only; a type none of its permissions is on denies the start.
130
131
  - `getPermDock(ticket)` rebuilds the run on every step. A new version, a revoked automation or a publisher who is gone gives an instance that denies everything.
131
132
  - `awaitApproval(ticket, permission, row)` decides, parks on the `waiter` while `approval-required`, then decides again with the token against the publisher's rights as of then.
132
133
  - `openApproval(ticket, permission, row)` and `resumeApproval(ticket, permission, token, row)` are the two halves, for runners that wait outside the call. A request still pending denies with reason `approval`.
@@ -36,7 +36,7 @@ pnpm exec permdock rls verify --introspect
36
36
  ```
37
37
 
38
38
  - List the scope instances a permission reaches in process with `permdock.permittedIds(permission, scope, { within })`, never a loop of `can` over memberships with a made-up row.
39
- - Generated policies call `permdock_has('<key>')` and one `permitted_<scope>_ids('<key>')` per declared scope, which Postgres runs once per statement. Hand-written policies that only need membership (an organization switcher) call `member_<scope>_ids()` instead of inventing a permission key. A policy that passes a user id, such as better-supabase's team sharing, calls `member_team_ids_of(<user>)` on Supabase: it answers only when the id is the caller's. Trusted SQL that acts for a stored user (a job, a trigger, a deferred approval) calls `permdock_has_for(p_user, '<key>')` and `permitted_<scope>_ids_for(p_user, '<key>')` in `database` mode, or the generated `permitted_<resource>_rows_for`, never a hand-written function that rewrites `request.jwt.claims`. With `rls.rowHelpers`, a hand-written policy or function that needs the rows a permission reaches through the graph calls `permitted_<resource>_rows('<permission key>')` instead of restating closure walks, link hops and `includes`. A table's own `select` or `insert` policy calls the row-valued `permitted_<resource>_row(<table>, '<permission key>')` instead, so `insert ... returning` sees the new row. Hand-written policies and functions that apply no row condition call `permitted_<scope>_ids_by_permission('<permission key>')` or `permdock_has_permission('<permission key>')` instead of spelling a positional `#n` grant key. A screen or RPC that checks many permissions on one organization calls `permitted_<scope>_permission_keys(<id>)` once (or `(<id>, array['<key>', ...])` for a few keys) instead of one helper call per key. A role editor or admin screen lists a role's keys with `permdock_role_permissions(p_role, p_scope, p_tenant, p_scope_id)` (declared roles, and custom roles of the caller's tenant in `database` mode) and the catalog with `permdock_permission_keys()` (`permdock_permission_keys('<scope>')` for the keys a role on that scope can hold), instead of joining `role_permissions` and the custom-role tables by hand; server code reads any tenant's roles with `permdock_trusted_role_permissions`, granted through `rls.trustedReaders`. Set `--tenant-type` (or `rls.scopeTypes`, keyed by scope name or `tenant` and `team`) to the scope columns' types.
39
+ - Generated policies call `permdock_has('<key>')` and one `permitted_<scope>_ids('<key>')` per declared scope, which Postgres runs once per statement. Hand-written policies that only need membership (an organization switcher) call `member_<scope>_ids()` instead of inventing a permission key. A policy that passes a user id, such as better-supabase's team sharing, calls `member_team_ids_of(<user>)` on Supabase: it answers only when the id is the caller's. Trusted SQL that acts for a stored user (a job, a trigger, a deferred approval) calls `permdock_has_for(p_user, '<key>')` and `permitted_<scope>_ids_for(p_user, '<key>')` in `database` mode, or the generated `permitted_<resource>_rows_for`, never a hand-written function that rewrites `request.jwt.claims`. With `rls.rowHelpers`, a hand-written policy or function that needs the rows a permission reaches through the graph calls `permitted_<resource>_rows('<permission key>')` instead of restating closure walks, link hops and `includes`. A table's own `select` or `insert` policy calls the row-valued `permitted_<resource>_row(<table>, '<permission key>')` instead, so `insert ... returning` sees the new row. A function that checks a known set of rows (one tenant's, a page, a batch) calls `permitted_<resource>_rows('<permission key>', <text[] of ids>)`, which reads only those ids, instead of the one-argument form, which reads the whole table, or a `permitted_<resource>_row` call per row. Hand-written policies and functions that apply no row condition call `permitted_<scope>_ids_by_permission('<permission key>')` or `permdock_has_permission('<permission key>')` instead of spelling a positional `#n` grant key. A screen or RPC that checks many permissions on one organization calls `permitted_<scope>_permission_keys(<id>)` once (or `(<id>, array['<key>', ...])` for a few keys) instead of one helper call per key. A role editor or admin screen lists a role's keys with `permdock_role_permissions(p_role, p_scope, p_tenant, p_scope_id)` (declared roles, and custom roles of the caller's tenant in `database` mode) and the catalog with `permdock_permission_keys()` (`permdock_permission_keys('<scope>')` for the keys a role on that scope can hold), instead of joining `role_permissions` and the custom-role tables by hand; server code reads any tenant's roles with `permdock_trusted_role_permissions`, granted through `rls.trustedReaders`. Set `--tenant-type` (or `rls.scopeTypes`, keyed by scope name or `tenant` and `team`) to the scope columns' types.
40
40
  - `--authorize database` (default) reads the membership tables per statement; map each under `rls.memberships.scopes.<scope>` with `columns` for its id and its ancestors', and `via` so roles with `for` apply: a column name, or `{ value: 'staff' }` when every row has that kind (never add a generated column for it). `--authorize jwt` reads token claims and stays stale until the token refreshes; keep the token lifetime at 3600 seconds or less (PD019).
41
41
  - When the role column holds values that are not role keys, give the membership source `role: { column, map: { value: 'role' } }`; a value mapped to `null` grants nothing. `permdock rls explain` prints the tables, membership sources, custom roles table and triggers a generate run binds to, without writing a file. `rls.seeds: 'function'` writes the `role_permissions` rows as `<schema>.seed()` instead of inserts; run `select <schema>.seed();` after each deploy, and PD054 checks the function body.
42
42
  - `rls verify --introspect` checks each `security definer` helper by its full signature, so every overload is checked on its own. A helper finding id names the signature (`helper-definer:permdock.permdock_has(text):helper`); write `rls.verify.ignore` entries with it.
@@ -501,9 +501,9 @@ const subject = subjectFromSupabase(claims, {
501
501
 
502
502
  Write the claims with `permdock supabase hook generate`; `permdock supabase inspect --out` writes the manifest (helper names, tenant claim, budget, claims written) that `authorizationProvider` from `permdock/better-supabase` turns into better-supabase's `authorization` config. No `@supabase/supabase-js` peer. Pair with `permdock rls generate`, or keep SQL as authority and run `permdock rls verify --db-url-stdin` against `sqlFunction` twins ([database-first](https://permdock.com/docs/adapters/rls)); the generic RLS workflow is in the `permdock-data` skill.
503
503
 
504
- With better-supabase, set `authorization: authorizationProvider({ manifest, catalog })` in `better-supabase.config.ts` (with `rls.customRoles` its `canAssign` and `canAssignFor` call `permdock_can_assign_any` and its `_for` form, so custom roles are assignable through better-supabase; regenerate the manifest after turning custom roles on), pass `authorizer({ policy })` to the server (`createNext`, `createHono`, `createMcp`) so every `permission` a resource, action, route guard or tool declares is decided by PermDock from the verified claims (`operations` maps tables for `permissions: true`; a missing or anonymous claim denies), build bucket and topic `access` policies with `bucketPolicy` and `topicPolicy`, and map its session with `subjectFromBetterSupabase(session)` (all from `permdock/better-supabase`): the active tenant's `features` become `principal.plans`. Pass `plans: { keys }` when better-supabase's `entitlements.claim.keys` shortens feature keys, and `apiKeys: { permissions, manifest }` so an `apiKey` session maps to the key's credential subject instead of the anonymous one. For `createMcp` tools, put the permission in `meta` and spread `toolPolicy({ permdock })` into the options: tools without one are hidden and refused, and approval-required calls are refused because `createMcp` collects no approvals. Wrap a `CredentialProvider` with `credentialGuard(provider, { permdock, use, revoke? })` so PermDock decides each token use. `authorizationProvider({ ..., approver })` lets holders of that permission approve AI tool calls, never their own. `approvers: { 'ai-tool': holder(p), 'support-session': ..., 'invoice.send': ... }` fills `isApprover` through `permdock_is_approver` (needs `rls.approvals`); only `user()`, `holder()` and `anyOf()` approvers, and a kind it does not name has no approver. `accessReviewApplier({ client, reviews, policy, demoteTo?, email?, permdockFor? })` applies a review's revoked items: `update_member_role` to the `demoteTo` role when that role lacks the permission, else `remove_member`, plus `revoke_invitation` for the member's matching invitations, then `markApplied`; pass the reviewer's client so the blocks' own checks run. better-supabase's `createAgentRuntime({ toolApproval })` takes `toolApproval` from `permdock/ai-sdk` as it is. Validate its claims with `betterSupabase.claims(supabaseClaims().extend(appSchema))` (`supabaseClaims` from `permdock/supabase`, any Standard Schema as `appSchema`) instead of a hand-written copy of the claim shape. A `supabase.hook.claims` function that needs the user's organizations calls `<schema>.member_organization_ids_for(user_id)` (generated by `rls generate`, executable by `supabase_auth_admin` only) instead of querying the membership tables itself. With a scope named `team` or `teams`, `authorizationProvider` fills better-supabase's `teamIdsOf` with `<schema>.member_team_ids_of(user)`, which answers only for the caller, so with `blocks.access.model: 'provider'` better-supabase's `team_ids_of()` and team-sharing policies read PermDock's memberships. A token Supabase's OAuth server issued to a third-party app (`client_id`) becomes an `oauth-client` actor limited to its `scope`; `deny(permission, { to: actor('oauth-client') })` keeps such apps out, in the app and, through `rls generate`, in Postgres. A better-supabase support session (`act.kind: 'support'`) is actor kind `support` with `sessionId` and `readOnly`, and `actingAs` (`act.kind: 'impersonation'`) is kind `impersonation`; neither has a delegation, so they reach nothing until a policy delegation names `actor('support')` or `actor('impersonation')`, and `readOnly: true` (also when `read_only` is absent) narrows that to read-only permissions. Generated RLS reads memberships, not `act`, so a support token sent to the Data API writes as the user: add a restrictive `for update` (and `insert` / `delete`) policy per writable table that requires `act ->> 'read_only' = 'false'` when `act` is a support or session level ([support access](https://permdock.com/docs/guides/support-access)). With `rls.anonymousSignIns: 'deny'`, pass `anonymousSignIns: 'deny'` to the subject mapper too (doctor PD057). Check a deployed database against the generated policies with `permdock rls verify --introspect`.
504
+ With better-supabase, set `auth.authorization: authorizationProvider({ manifest, catalog })` in `better-supabase.config.ts` (top-level `authorization` before 0.15) (with `rls.customRoles` its `canAssign` and `canAssignFor` call `permdock_can_assign_any` and its `_for` form, so custom roles are assignable through better-supabase; regenerate the manifest after turning custom roles on), pass `authorizer({ policy })` to the server (`createNext`, `createHono`, `createMcp`) so every `permission` a resource, action, route guard or tool declares is decided by PermDock from the verified claims (`operations` maps tables for `permissions: true`; a missing or anonymous claim denies), build bucket and topic `access` policies with `bucketPolicy` and `topicPolicy`, and map its session with `subjectFromBetterSupabase(session)` (all from `permdock/better-supabase`): the active tenant's `features` become `principal.plans`. Pass `plans: { keys }` when better-supabase's `entitlements.claim.keys` shortens feature keys, and `apiKeys: { permissions, manifest }` so an `apiKey` session maps to the key's credential subject instead of the anonymous one. For `createMcp` tools, put the permission in `meta` and spread `toolPolicy({ permdock })` into the options: tools without one are hidden and refused, and approval-required calls are refused because `createMcp` collects no approvals. Wrap a `CredentialProvider` with `credentialGuard(provider, { permdock, use, revoke? })` so PermDock decides each token use. `authorizationProvider({ ..., approver })` lets holders of that permission approve AI tool calls, never their own. `approvers: { 'ai-tool': holder(p), 'support-session': ..., 'invoice.send': ... }` fills `isApprover` through `permdock_is_approver` (needs `rls.approvals`); only `user()`, `holder()` and `anyOf()` approvers, and a kind it does not name has no approver. `accessReviewApplier({ client, reviews, policy, demoteTo?, email?, permdockFor? })` applies a review's revoked items: `update_member_role` to the `demoteTo` role when that role lacks the permission, else `remove_member`, plus `revoke_invitation` for the member's matching invitations, then `markApplied`; pass the reviewer's client so the blocks' own checks run. better-supabase's `createAgentRuntime({ toolApproval })` takes `toolApproval` from `permdock/ai-sdk` as it is. Validate its claims with `betterSupabase.claims(supabaseClaims().extend(appSchema))` (`supabaseClaims` from `permdock/supabase`, any Standard Schema as `appSchema`) instead of a hand-written copy of the claim shape. A `supabase.hook.claims` function that needs the user's organizations calls `<schema>.member_organization_ids_for(user_id)` (generated by `rls generate`, executable by `supabase_auth_admin` only) instead of querying the membership tables itself. With a scope named `team` or `teams`, `authorizationProvider` fills better-supabase's `teamIdsOf` with `<schema>.member_team_ids_of(user)`, which answers only for the caller, so with `blocks.permissions.model: 'provider'` (`blocks.access` before 0.15) better-supabase's `team_ids_of()` and team-sharing policies read PermDock's memberships. A token Supabase's OAuth server issued to a third-party app (`client_id`) becomes an `oauth-client` actor limited to its `scope`; `deny(permission, { to: actor('oauth-client') })` keeps such apps out, in the app and, through `rls generate`, in Postgres. A better-supabase support session (`act.kind: 'support'`) is actor kind `support` with `sessionId` and `readOnly`, and `actingAs` (`act.kind: 'impersonation'`) is kind `impersonation`; neither has a delegation, so they reach nothing until a policy delegation names `actor('support')` or `actor('impersonation')`, and `readOnly: true` (also when `read_only` is absent) narrows that to read-only permissions. Generated RLS reads memberships, not `act`, so a support token sent to the Data API writes as the user: add a restrictive `for update` (and `insert` / `delete`) policy per writable table that requires `act ->> 'read_only' = 'false'` when `act` is a support or session level ([support access](https://permdock.com/docs/guides/support-access)). With `rls.anonymousSignIns: 'deny'`, pass `anonymousSignIns: 'deny'` to the subject mapper too (doctor PD057). Check a deployed database against the generated policies with `permdock rls verify --introspect`.
505
505
 
506
- The other better-supabase slots, all from `permdock/better-supabase` ([better-supabase](https://permdock.com/docs/adapters/better-supabase)): `hookCan(permdock)` and `handlerCan({ getPermDock })` are the `can` options of `authorizeHook` and `protectWebHandler` in `better-supabase/workflow-sdk`; they decide with no row, so a permission with a row condition denies there and is checked inside the handler, and `handlerCan` answers `undefined` (401) without a signed-in principal. `supportPolicy({ policy, options?, writable?, approval?, approved? })` is the `authorize` option of `supportSessions`; it decides each start with `decideSupportSession` as the admin, and an `approval-required` start passes only once `approved(input, pending)` returns `{ approvedBy }` for an approver other than the admin. `subscriberPolicy({ policy, principals, events, row?, sender? })` filters outbox, webhook or realtime subscribers to those who may read the event (exact type, then the longest `prefix.*`, then `*`; a type with no entry reaches no one). `principalSource({ claims, identities? })` is a `PrincipalSource` over the claims better-supabase mints, for `decideFor`, `subscribersFor` and delivery; only links the app created through a signed-in flow or a verified address go in `identities`. `authorizationHooks({ policy, claims, service?, principals?, events?, approvers?, support?, tickets? })` is the `authorization` option of `createServer`: it answers automation publish and run-as, delegated OAuth scopes, `approverOf`, identities, delivery audiences, support sessions and run tickets from the claims better-supabase mints now, never from the request.
506
+ The other better-supabase slots, all from `permdock/better-supabase` ([better-supabase](https://permdock.com/docs/adapters/better-supabase)): `hookCan(permdock)` and `handlerCan({ getPermDock })` are the `can` options of `authorizeHook` and `protectWebHandler` in `better-supabase/workflow-sdk`; they decide with no row unless the `data` option loads one (`hookCan(permdock, { data: (tenant, key) => row })`, `handlerCan(source, { data: (request, key) => row })`), so without it a permission with a row condition denies, and `handlerCan` answers `undefined` (401) without a signed-in principal. `supportPolicy({ policy, options?, writable?, approval?, approved? })` is the `authorize` option of `supportSessions`; it decides each start with `decideSupportSession` as the admin, and an `approval-required` start passes only once `approved(input, pending)` returns `{ approvedBy }` for an approver other than the admin. `subscriberPolicy({ policy, principals, events, row?, sender? })` filters outbox, webhook or realtime subscribers to those who may read the event (exact type, then the longest `prefix.*`, then `*`; a type with no entry reaches no one). `principalSource({ claims, identities? })` is a `PrincipalSource` over the claims better-supabase mints, for `decideFor`, `subscribersFor` and delivery; only links the app created through a signed-in flow or a verified address go in `identities`. `authorizationHooks({ policy, claims, service?, principals?, events?, approvers?, support?, tickets? })` is the `authorization` option of `createServer`: it answers automation publish and run-as, delegated OAuth scopes, `approverOf`, identities, delivery audiences, support sessions and run tickets from the claims better-supabase mints now, never from the request.
507
507
 
508
508
  `claims` is whatever Supabase verified: `data.claims` from `supabase.auth.getClaims()` on an `@supabase/ssr` server client, or `jwtClaims` from `@supabase/server` (`ctx.jwtClaims` in `withSupabase` or a `pipeline`, and `c.var.jwtClaims` after a framework bridge such as `toHono([withClaims(), withPermDock()])`). `@supabase/server/adapters/*` and `c.var.supabaseContext` are deprecated and removed on 1 December 2026; do not write new code against them ([Hono, H3, Elysia and NestJS](https://permdock.com/docs/adapters/supabase#hono-h3-elysia-and-nestjs)). Pass `null` for anonymous callers; never `getSession().access_token` (unverified). An API-key auth mode (`secret`, `publishable`) has `jwtClaims: null` and is the anonymous subject, not a user.
509
509
 
@@ -517,7 +517,8 @@ Supabase specifics for generated RLS (the generic flags and parity checks are in
517
517
  - Under `migra`, generate `--split helpers,seeds,policies,hook --out supabase/schemas/identity/056_permdock_{part}.sql --seeds-out supabase/migrations/` and write the schema and function privileges and the `security_invoker` view option with `--grants-out` into a migration created by `supabase migration new` after the first `db diff`; `db diff` drops those, so never append them to a migration by hand. Table grants and policies stay in the schema files, where `db diff` keeps them. Keep the helpers part ahead of every file that calls the helpers in `schema_paths` (`permdock doctor` PD042, PD043).
518
518
  - `--authorize jwt` reads the hook's claims: enable the printed `[auth.hook.custom_access_token]` stanza in `supabase/config.toml`. The generated hook writes the canonical `memberships` claim from the `rls.memberships.scopes` tables, so do not hand-write one.
519
519
  - For more than one membership table, declare `tableMembershipSource` / `junctionMembershipSource` sources once (from `permdock/supabase`, with a `query` on the server), pass the array as `memberships` (wrapped in `claimsFirst(sources, { version: authzVersion({ query }) })` to trust the token until it is truncated or stale), put the same sources under `supabase.hook.memberships` in `permdock.config.ts`, and run `permdock supabase hook generate`; add the printed `config.toml` block (`jwt_expiry = 900`). List member-removal and payout permissions in `definePolicy({ fresh })`.
520
- - When the server has only supabase-js (no `SqlQuery`), never re-read memberships, global roles or custom roles with the admin client: grant `subject_for(p_user)` and `authz_version_for(p_user)` (written next to the hook) to the backend role, expose them through `public` wrappers when `permdock` is not an exposed schema, and use `postgrestSources(admin, { schema, fn, versionFn, policy })`: `claimsFirst(sources.memberships)` (with `onStale: 'reread'` a fresh token costs one version call, and with `policy` a token that claims a custom role costs one `subject_for` call), `customRoles: sources.customRoles(principal)`, and `await sources.subject(userId)` for a job acting for a stored user.
520
+ - When the server has only supabase-js (no `SqlQuery`), never re-read memberships, global roles or custom roles with the admin client: grant `subject_for(p_user)` and `authz_version_for(p_user)` (written next to the hook) to the backend role, expose them through `public` wrappers when `permdock` is not an exposed schema, and use `postgrestSources(admin, { schema, fn, versionFn, policy })`: `claimsFirst(sources.memberships)` (with `onStale: 'reread'` a fresh token costs one version call, and with `policy` a token that claims a custom role costs one `subject_for` call), `customRoles: sources.customRoles(principal)`, and `await sources.subject(userId)` for a job acting for a stored user. Create `postgrestSources` and the `claimsFirst` source once at module scope, never per request or per cache scope: they keep no answers, and `getPermDock` shares each read within one instance.
521
+ - When a page builds many instances (Next.js `'use cache: private'` islands, PPR) or an API serves many `GET`s per user, add `versions: memoryVersionCache({ maxStaleMs: 5_000 })` to `claimsFirst(sources.memberships, { onStale: 'reread' })` at module scope. Rendering and `GET` / `HEAD` / `OPTIONS` use intent `read` and share one version call per `maxStaleMs`; `protectAction`, other HTTP methods and core `getPermDock` use `write` and read live. Before a mutation outside `protectAction` in Next.js, call `getPermDock({ intent: 'write' })`. After a role change call `versions.evict(userId)` ([freshness and the version cache](https://permdock.com/docs/adapters/supabase#freshness-and-the-version-cache)).
521
522
  - When a role table stores a role id (`user_roles.role_id`, `organization_users.role_id` referencing `roles`), read the key through it with `{ through: 'roles', on: { role_id: 'id' }, column: 'key' }`: in `rls.roles`, in `tableMembershipSource` `columns.role` or `junctionMembershipSource` `roles`, and in an `rls.memberships` table's `role`. Never copy keys into the membership table. Keep tenant custom-role keys apart from declared role names.
522
523
  - When one membership row holds roles in several columns (a `tier` and a `role_id`), list them instead of building a union view: `role: ['tier', { through: 'roles', on: { role_id: 'id' }, column: 'key' }]` in `rls.memberships` and `tableMembershipSource` `columns.role`, `roles: { sources: [...] }` in `junctionMembershipSource`. The row holds every non-null key, and the holder-count triggers stay on the real table.
523
524
  - When a membership table names a profile instead of a login (`customer_contacts.contact_profile_id` referencing `contact_profiles`, whose `user_id` is the login), read the user through it with `junctionMembershipSource` `user` or `tableMembershipSource` `columns.user`: `{ through: 'contact_profiles', on: { contact_profile_id: 'id' }, column: 'user_id' }`. Never copy `user_id` onto the membership rows. Keep `contact_profiles.user_id` server-owned (PD028).
@@ -1 +0,0 @@
1
- export { t as catalogFile, n as runCatalog } from "./catalog-BFpz2EmT.js";
@@ -1 +0,0 @@
1
- export { r as runCollect } from "./collect-B7ZFAJU3.js";
@@ -1 +0,0 @@
1
- export { n as runPowerSync } from "./powersync-DHNQX06W.js";
@@ -1 +0,0 @@
1
- export { n as runCloudPull } from "./pull-CwpGaQSi.js";
@@ -1 +0,0 @@
1
- export { t as run } from "./run-Bz26OTfO.js";