permdock 0.1.0 → 0.3.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 (350) hide show
  1. package/README.md +106 -47
  2. package/dist/a2a/index.d.ts +7 -16
  3. package/dist/a2a/index.js +59 -98
  4. package/dist/adapter-context-mlWsVGGg.js +23 -0
  5. package/dist/ai-sdk/index.d.ts +37 -16
  6. package/dist/ai-sdk/index.js +30 -13
  7. package/dist/approvals/index.d.ts +3 -3
  8. package/dist/approvals/index.js +5 -4
  9. package/dist/{approvals-DaxY-Bdg.js → approvals-DbYAuNkG.js} +17 -11
  10. package/dist/approvers-DT4AVyIg.js +52 -0
  11. package/dist/{arazzo-CTeVuXr5.js → arazzo-BAgw9ap6.js} +2 -2
  12. package/dist/{arazzo-aoTkqYsJ.js → arazzo-CKwwqFWz.js} +2 -2
  13. package/dist/authzen/index.d.ts +4 -13
  14. package/dist/authzen/index.js +16 -50
  15. package/dist/better-auth/index.d.ts +20 -3
  16. package/dist/better-auth/index.js +27 -7
  17. package/dist/better-supabase/index.d.ts +223 -0
  18. package/dist/better-supabase/index.js +648 -0
  19. package/dist/bind-C_ob3LKa.d.ts +25 -0
  20. package/dist/bind-CuzGytRf.js +97 -0
  21. package/dist/boundary-BM8a_P6E.js +13 -0
  22. package/dist/boundary-BmHxVH1J.d.ts +15 -0
  23. package/dist/canonical-json-DemiK4Vp.js +26 -0
  24. package/dist/{capability-BDG_nkxt.d.ts → capability-2kYTMWDv.d.ts} +2 -2
  25. package/dist/{capability-B68OFnZx.js → capability-4qPdO9gk.js} +7 -5
  26. package/dist/catalog/index.d.ts +1 -1
  27. package/dist/catalog/index.js +1 -1
  28. package/dist/catalog-CRW5Mx_B.js +2 -0
  29. package/dist/{catalog-H-vFGwWK.js → catalog-DWF5cYqB.js} +4 -4
  30. package/dist/{catalog-B0E6bggc.js → catalog-dFZdWCGN.js} +2 -2
  31. package/dist/{catalog-doc-BSo_Q_-6.js → catalog-doc-DdGm82XT.js} +20 -32
  32. package/dist/claude-agent/index.d.ts +5 -14
  33. package/dist/claude-agent/index.js +4 -10
  34. package/dist/clerk/index.d.ts +12 -3
  35. package/dist/clerk/index.js +26 -5
  36. package/dist/cli/bin.js +1 -1
  37. package/dist/cli/index.d.ts +3 -3
  38. package/dist/cli/index.js +2 -2
  39. package/dist/clients-C7zLFuWT.d.ts +12 -0
  40. package/dist/clients-DjU5ABMy.js +23 -0
  41. package/dist/cloud/index.d.ts +4 -5
  42. package/dist/cloud/index.js +20 -6
  43. package/dist/{cloud-BNQTrmrr.js → cloud-CB_ELYuX.js} +2 -2
  44. package/dist/{cloud-Cuxr6Czw.js → cloud-DWLXO2af.js} +7 -6
  45. package/dist/collect-DClJsheJ.js +83 -0
  46. package/dist/{collect-O-tOtbnk.js → collect-DSTE3ml9.js} +194 -42
  47. package/dist/collect-DSWOk19R.js +2 -0
  48. package/dist/{commands-BMh_Etm2.js → commands-DSxCqG9A.js} +16 -12
  49. package/dist/compile/index.d.ts +3 -0
  50. package/dist/compile/index.js +2 -0
  51. package/dist/{compile-D22iwvuV.js → compile-Ba4blROR.js} +85 -30
  52. package/dist/compile-BkRyBDBw.d.ts +94 -0
  53. package/dist/config-BJiM-xAm.js +157 -0
  54. package/dist/config-Dnszbv-6.js +36 -0
  55. package/dist/config-report-DMvWKUxL.js +44 -0
  56. package/dist/{connection-JvqwHODC.js → connection-CU8MQxRi.js} +1 -1
  57. package/dist/{context-CKEAabd7.js → context-Bcy85rGi.js} +36 -27
  58. package/dist/convex/index.d.ts +9 -4
  59. package/dist/convex/index.js +14 -4
  60. package/dist/create-B1d519XK.d.ts +245 -0
  61. package/dist/create-CMwIl-w2.js +253 -0
  62. package/dist/{credential-B_rkUNlY.js → credential-8P81ff4u.js} +26 -46
  63. package/dist/delegation-D8pUEuce.js +103 -0
  64. package/dist/{describe-Bt1YD5uS.js → describe-B_gVZEVi.js} +10 -15
  65. package/dist/{describe-DernyItf.d.ts → describe-DMYiCjJV.d.ts} +9 -10
  66. package/dist/{diff-x5Il8LVa.js → diff-2VaeChzX.js} +44 -11
  67. package/dist/{diff-BUzf5Poi.js → diff-DBIhz_f2.js} +2 -2
  68. package/dist/{doctor-Bqo6FwUa.js → doctor-BwCAMLx_.js} +2 -2
  69. package/dist/doctor-collect-CHk6XWOA.js +665 -0
  70. package/dist/doctor-igIiM_Hl.js +1194 -0
  71. package/dist/drizzle/index.d.ts +4 -3
  72. package/dist/drizzle/index.js +3 -3
  73. package/dist/elysia/index.d.ts +6 -28
  74. package/dist/elysia/index.js +16 -60
  75. package/dist/{errors-DSMnAVNa.js → errors-CWfoNg9N.js} +8 -4
  76. package/dist/{errors-Iy71s7Oj.js → errors-Cz5zn0mW.js} +17 -71
  77. package/dist/{errors-DbZ1YOnb.d.ts → errors-DPdqI50v.d.ts} +8 -21
  78. package/dist/{errors-m3u9TmDu.js → errors-DRnGZHzF.js} +4 -1
  79. package/dist/evaluation-items-CfCCejQd.js +40 -0
  80. package/dist/{evaluations-DsAU9ppl.js → evaluations-tz6D9A2G.js} +28 -46
  81. package/dist/eve/index.d.ts +6 -15
  82. package/dist/eve/index.js +7 -12
  83. package/dist/expiry-BoBJ8Tvc.js +7 -0
  84. package/dist/express/index.d.ts +6 -29
  85. package/dist/express/index.js +28 -58
  86. package/dist/fastify/index.d.ts +6 -29
  87. package/dist/fastify/index.js +16 -65
  88. package/dist/fields-BMl1RxoX.js +26 -0
  89. package/dist/{files-B_wAGYmt.js → files-DWUN9PzI.js} +5 -1
  90. package/dist/{fixtures-Cvaw0gDG.js → fixtures-ht28Cplr.js} +5 -2
  91. package/dist/{freeze-y1_jQL4v.js → freeze-CrU8nQeX.js} +31 -2
  92. package/dist/{from-snapshot-BMGnhmgv.js → from-snapshot-CTLijvdm.js} +66 -48
  93. package/dist/{grantee-Bv04_Vzf.js → grantee-Cv5Sogfv.js} +88 -7
  94. package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
  95. package/dist/{headers-B5RRv3Xm.js → headers-BZSDieNT.js} +1 -1
  96. package/dist/{headers-C8SHQccD.d.ts → headers-Cf-zWvsO.d.ts} +1 -1
  97. package/dist/helpers-H_KARDVC.js +421 -0
  98. package/dist/hono/index.d.ts +6 -28
  99. package/dist/hono/index.js +11 -43
  100. package/dist/{hosted-BwKQ1BTA.js → hosted-DJQw46hn.js} +6 -5
  101. package/dist/{http-GgVApX1k.js → http-BIhmLfCc.js} +4 -20
  102. package/dist/http-SO7qGttf.js +44 -0
  103. package/dist/ids-DC4V4CFu.js +18 -0
  104. package/dist/index-0nNqHspG.d.ts +6 -0
  105. package/dist/{index-xIxJLwOQ.d.ts → index-BNc7Wer_.d.ts} +75 -7
  106. package/dist/{index-CltcQ4Bf.d.ts → index-C7Tw7MaW.d.ts} +68 -5
  107. package/dist/{index-LF_hS-yn.d.ts → index-C8z4RjQV.d.ts} +1 -1
  108. package/dist/index.d.ts +14 -9
  109. package/dist/index.js +22 -17
  110. package/dist/instance-options-Dhhcnm3y.js +22 -0
  111. package/dist/instance-options-jARdwfPN.d.ts +11 -0
  112. package/dist/{parse-DPfIvFMU.js → json-schema-BsAflUGW.js} +28 -57
  113. package/dist/jwt/index.d.ts +10 -6
  114. package/dist/jwt/index.js +32 -13
  115. package/dist/kernel-_RRHmnMY.js +208 -0
  116. package/dist/kysely/index.d.ts +4 -3
  117. package/dist/kysely/index.js +3 -3
  118. package/dist/live-options-H2eG8dfJ.js +60 -0
  119. package/dist/{load-BZ24CpZP.js → load-DhWEB9P1.js} +16 -10
  120. package/dist/load-DwJUafYN.js +2 -0
  121. package/dist/manifest-iaoBXHKc.js +783 -0
  122. package/dist/manifest-uDS9y5de.d.ts +206 -0
  123. package/dist/{map-DowSO96j.js → map-AcxK9o_D.js} +4 -15
  124. package/dist/{map-claims-B_6I1Rn-.js → map-claims-Z4QZOiFF.js} +13 -4
  125. package/dist/map-error-pgUWNNtG.js +23 -0
  126. package/dist/may-use-DndQ5tQ-.js +77 -0
  127. package/dist/mcp/index.d.ts +54 -22
  128. package/dist/mcp/index.js +218 -178
  129. package/dist/nest/index.d.ts +26 -31
  130. package/dist/nest/index.js +75 -84
  131. package/dist/next/client.d.ts +7 -8
  132. package/dist/next/client.js +11 -9
  133. package/dist/next/index.d.ts +30 -47
  134. package/dist/next/index.js +45 -60
  135. package/dist/next/plugin.d.ts +1 -1
  136. package/dist/next/plugin.js +32 -1
  137. package/dist/node/index.d.ts +9 -28
  138. package/dist/node/index.js +11 -43
  139. package/dist/openai/index.d.ts +6 -15
  140. package/dist/openai/index.js +7 -20
  141. package/dist/openapi/index.d.ts +87 -4
  142. package/dist/openapi/index.js +3 -3
  143. package/dist/{openapi-DcqM8nU7.js → openapi-BqRBvAng.js} +237 -5
  144. package/dist/{openapi-DWD0Uc_4.js → openapi-CqqEbHsL.js} +5 -5
  145. package/dist/{openapi-import-BWRUNNeW.js → openapi-import-cmwetbzw.js} +1 -1
  146. package/dist/{openapi-CwePaF7C.js → openapi-l0xYHkcv.js} +3 -3
  147. package/dist/{openapi-schema-D8j_T9tO.js → openapi-schema--ARjyfQr.js} +2 -2
  148. package/dist/orpc/index.d.ts +15 -28
  149. package/dist/orpc/index.js +74 -117
  150. package/dist/otel/index.d.ts +2 -2
  151. package/dist/parse-BuyjxhZV.js +53 -0
  152. package/dist/parse-local-manifest-BrMozJCo.js +36 -0
  153. package/dist/parse-local-manifest-JLnaBH0S.d.ts +10 -0
  154. package/dist/pdp/index.d.ts +2 -2
  155. package/dist/pdp/index.js +14 -127
  156. package/dist/{permdock-yoZ7EjxX.js → permdock-CbgvLnuo.js} +672 -149
  157. package/dist/{permissions-B8vCg_bI.d.ts → permissions-CDgvKG5L.d.ts} +2 -2
  158. package/dist/{permissions-DC7GROPA.js → permissions-DVoF6dMt.js} +77 -15
  159. package/dist/{permissions-B4apnahQ.d.ts → permissions-DttnqqxC.d.ts} +34 -5
  160. package/dist/{permissions-CofRqesP.js → permissions-RJrovw98.js} +3 -3
  161. package/dist/{pins-CqE1jZuF.js → pins-8ILTftC9.js} +2 -2
  162. package/dist/{policy-Cq2fB8Q5.d.ts → policy-D2W7uv19.d.ts} +2 -2
  163. package/dist/{policy-CInmNGkM.d.ts → policy-IB6yxpC3.d.ts} +351 -42
  164. package/dist/{policy-ANp36PnI.js → policy-xyWg7QdR.js} +173 -22
  165. package/dist/powersync-BylawD_U.js +540 -0
  166. package/dist/powersync-DliZK_-y.js +62 -0
  167. package/dist/powersync-e_AZrKbg.js +2 -0
  168. package/dist/prisma/index.d.ts +3 -2
  169. package/dist/prisma/index.js +45 -20
  170. package/dist/{problem-Cgp9-KZA.js → problem-B43ztKIm.js} +74 -109
  171. package/dist/problem-details-DX075l9V.d.ts +7 -0
  172. package/dist/problem-details-_AMOYz-w.js +144 -0
  173. package/dist/{protected-BuPAycJT.d.ts → protected-BdnIEFkY.d.ts} +5 -4
  174. package/dist/protected-utU-SLuy.js +100 -0
  175. package/dist/protected-xAr24FEC.d.ts +40 -0
  176. package/dist/provider-CSQd7m92.js +52 -0
  177. package/dist/{provider-wTAUda2v.d.ts → provider-DZY281jO.d.ts} +1 -1
  178. package/dist/provider-store-Cfbvo4DE.js +43 -0
  179. package/dist/react/index.d.ts +7 -5
  180. package/dist/react/index.js +5 -4
  181. package/dist/react/provider-client.d.ts +1 -1
  182. package/dist/react/provider-client.js +1 -1
  183. package/dist/react-native/index.d.ts +166 -10
  184. package/dist/react-native/index.js +607 -85
  185. package/dist/{refs-ChLSxbST.js → refs-KYb4ntaz.js} +4 -3
  186. package/dist/{relations-r4soIFZB.js → relations-cjOL01hZ.js} +110 -31
  187. package/dist/replay-BsOyTrdV.js +28 -0
  188. package/dist/replay-CYyiLiwO.d.ts +5 -0
  189. package/dist/resource-ref-CaS9yVPi.js +20 -0
  190. package/dist/revocations-Bhr0aMIC.js +27 -0
  191. package/dist/{rls-BOFU3chG.js → rls-B4ur8nKQ.js} +8 -3
  192. package/dist/rls-DQtdgTHB.js +2521 -0
  193. package/dist/rls-fields-74oZPXWL.js +3582 -0
  194. package/dist/{rls-graph-DxQ39PJj.js → rls-graph-CHwx0V8q.js} +100 -36
  195. package/dist/{rls-import-CXV6LBlS.js → rls-import-BTFVk3jH.js} +7 -6
  196. package/dist/{rls-migrate-DrFPbf8p.js → rls-migrate-CN4TlJTO.js} +6 -5
  197. package/dist/rls-ownership-RuFqaqGz.js +843 -0
  198. package/dist/rls-shared-Cewd_-zI.js +495 -0
  199. package/dist/rls-verify-CVQTHTh5.js +746 -0
  200. package/dist/{row-check-BajTgQZ-.d.ts → row-check-Dt35czLy.d.ts} +12 -15
  201. package/dist/row-conditions-h2HythXQ.js +27 -0
  202. package/dist/rpc-DL9Sqvb1.js +89 -0
  203. package/dist/{run-CJ6UvS3a.js → run-DKDbM4Du.js} +31 -12
  204. package/dist/runtime-CB8gQFvS.js +11 -0
  205. package/dist/{saas-BRrZzJkM.js → saas-DhpJjnBA.js} +17 -7
  206. package/dist/{schema-P8yoma__.js → schema-D3MnDMxa.js} +8 -4
  207. package/dist/scim/index.d.ts +1 -1
  208. package/dist/scim/index.js +1 -1
  209. package/dist/{scim-9NFa0XVZ.js → scim-BFGBBAqR.js} +1 -1
  210. package/dist/{scopes-cKVp_WTw.js → scopes-CVdPrWN-.js} +35 -8
  211. package/dist/server/index.d.ts +22 -11
  212. package/dist/server/index.js +11 -8
  213. package/dist/{credentials-BgRX3WEg.js → server-DlZ28Oz5.js} +1 -1
  214. package/dist/shared-DRu8VFVM.js +123 -0
  215. package/dist/{sink-Cfr9-7YC.d.ts → sink-B1fZzIMf.d.ts} +1 -1
  216. package/dist/skills-Biq5uup3.js +192 -0
  217. package/dist/{skills-C_lpV4Jx.js → skills-Bx-U0irG.js} +10 -4
  218. package/dist/{snapshot-DE8dE_hz.js → snapshot-Enxd0n-s.js} +138 -214
  219. package/dist/snapshot-cache-B-LxUahj.d.ts +45 -0
  220. package/dist/snapshot-cache-D6jLelln.js +44 -0
  221. package/dist/solid/index.d.ts +39 -9
  222. package/dist/solid/index.js +76 -85
  223. package/dist/sources-4p0-4xQm.js +545 -0
  224. package/dist/sources-BdOYLw9j.d.ts +192 -0
  225. package/dist/{sql-Bll1d7y0.js → sql-xdg5f4Fi.js} +6 -1
  226. package/dist/{src-CTNT-PBW.js → src-BDwEZWrZ.js} +149 -11
  227. package/dist/ssf/index.d.ts +3 -2
  228. package/dist/ssf/index.js +3 -29
  229. package/dist/store-DMAWwAJV.js +371 -0
  230. package/dist/{store-Bq90395i.d.ts → store-jOBYpiXC.d.ts} +13 -4
  231. package/dist/store-options-ByhZq1jV.js +716 -0
  232. package/dist/{stores-CkG2HrSg.js → stores-BT2pSCub.js} +10 -63
  233. package/dist/{stores-CvOnu_2T.d.ts → stores-C0IMQrGI.d.ts} +20 -9
  234. package/dist/{stream-BhMfZOwr.d.ts → stream-D1RXubw2.d.ts} +2 -2
  235. package/dist/{stream-Q_xlB6Ko.js → stream-DDpvynSB.js} +16 -2
  236. package/dist/subject-settings-BwBmCdTR.js +128 -0
  237. package/dist/supabase/index.d.ts +133 -6
  238. package/dist/supabase/index.js +4 -3
  239. package/dist/supabase/middleware.d.ts +32 -27
  240. package/dist/supabase/middleware.js +56 -22
  241. package/dist/{supabase-D8UlBA7Z.js → supabase-Boqb9a_Y.js} +3 -3
  242. package/dist/{supabase-DTxGtYdi.js → supabase-C0qESOa-.js} +347 -367
  243. package/dist/supabase-config-BpPXt3x1.js +472 -0
  244. package/dist/supabase-hook-6sYLXg_u.js +2 -0
  245. package/dist/{supabase-hook-D_OqGb_V.js → supabase-hook-CSLQ4zJ3.js} +1037 -705
  246. package/dist/supautils-Cn4R4cJ4.js +91 -0
  247. package/dist/svelte/PermissionBoundary.svelte +37 -0
  248. package/dist/svelte/Protected.svelte +8 -2
  249. package/dist/svelte/index.d.ts +9 -6
  250. package/dist/svelte/index.js +61 -7
  251. package/dist/svelte/runtime.d.ts +4 -3
  252. package/dist/svelte/runtime.js +4 -3
  253. package/dist/svelte/source.d.ts +9 -6
  254. package/dist/svelte/source.js +7 -4
  255. package/dist/terminal/index.d.ts +6 -14
  256. package/dist/terminal/index.js +44 -32
  257. package/dist/testing/index.d.ts +105 -16
  258. package/dist/testing/index.js +504 -40
  259. package/dist/testing/saas/index.d.ts +4 -4
  260. package/dist/testing/saas/index.js +2 -2
  261. package/dist/testing/saas/permissions.d.ts +1 -1
  262. package/dist/testing/saas/permissions.js +1 -1
  263. package/dist/token-CIWxJOCh.js +50 -0
  264. package/dist/trpc/index.d.ts +7 -26
  265. package/dist/trpc/index.js +17 -100
  266. package/dist/types-BnIEz1sU.d.ts +48 -0
  267. package/dist/{types-CxquUByI.d.ts → types-Bvc4oWT6.d.ts} +1 -1
  268. package/dist/{sources-DOpW5Ila.d.ts → types-C97IskBw.d.ts} +86 -127
  269. package/dist/types-CKNSyIf_.d.ts +52 -0
  270. package/dist/types-Cq_H8N_X.d.ts +197 -0
  271. package/dist/{types-D6Z6-rKJ.d.ts → types-DbjRN55U.d.ts} +273 -22
  272. package/dist/{types-BBK-exvJ.d.ts → types-Dnemwd77.d.ts} +7 -1
  273. package/dist/{types-BvBk1wgn.d.ts → types-DxiCGmmd.d.ts} +5 -3
  274. package/dist/{types-B9dmiiab.d.ts → types-QCuYJh4q.d.ts} +1 -1
  275. package/dist/{types-B8w5PFtS.d.ts → types-aqOHTHcp.d.ts} +17 -1
  276. package/dist/unplugin/index.d.ts +1 -1
  277. package/dist/unplugin/index.js +10 -9
  278. package/dist/usage-DorAJiU_.js +2 -0
  279. package/dist/{usage-1ozMubLY.js → usage-GTixvDDU.js} +2 -2
  280. package/dist/{usage-CUnK6Ou9.js → usage-ItS7nLcl.js} +225 -62
  281. package/dist/validation-error-Ba264OaJ.d.ts +26 -0
  282. package/dist/validation-error-CnjZ4t92.js +33 -0
  283. package/dist/{validity-D0uRmJKJ.js → validity-uOp8UpYn.js} +57 -36
  284. package/dist/{verifier-B90agnhl.js → verifier-BxBo6I44.js} +10 -5
  285. package/dist/version-BvacVTZR.js +17 -0
  286. package/dist/views-Soe7bGSC.js +95 -0
  287. package/dist/{vocabulary-Dk0fs-Jk.d.ts → vocabulary-DA8a8zif.d.ts} +1 -1
  288. package/dist/vue/index.d.ts +35 -13
  289. package/dist/vue/index.js +86 -93
  290. package/dist/watch-BwxLTYMZ.js +2 -0
  291. package/dist/watch-DVBJ9cBq.js +128 -0
  292. package/dist/webmcp/index.d.ts +2 -2
  293. package/dist/webmcp/index.js +7 -13
  294. package/package.json +62 -36
  295. package/schemas/approval-request-v1.json +175 -0
  296. package/schemas/catalog-v1.json +29 -1
  297. package/schemas/supabase-claims-v1.json +6 -1
  298. package/schemas/supabase-manifest-v1.json +150 -6
  299. package/skills/permdock/SKILL.md +7 -7
  300. package/skills/permdock-agents/SKILL.md +5 -5
  301. package/skills/permdock-agents/references/runtimes.md +12 -10
  302. package/skills/permdock-approvals/SKILL.md +4 -4
  303. package/skills/permdock-approvals/references/stores-and-resume.md +15 -4
  304. package/skills/permdock-audit/SKILL.md +3 -3
  305. package/skills/permdock-credentials/SKILL.md +4 -4
  306. package/skills/permdock-credentials/references/tokens-keys-links.md +7 -2
  307. package/skills/permdock-data/SKILL.md +4 -4
  308. package/skills/permdock-data/references/queries-and-rls.md +14 -6
  309. package/skills/permdock-data/references/relationships.md +5 -3
  310. package/skills/permdock-tenancy/SKILL.md +9 -6
  311. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +14 -8
  312. package/skills/permdock-wire/SKILL.md +4 -4
  313. package/skills/permdock-wire/references/adapters.md +42 -30
  314. package/skills/permdock-wire/references/policy-options.md +5 -3
  315. package/dist/approvers-aH0PJkmf.js +0 -20
  316. package/dist/catalog-idsHc0vo.js +0 -2
  317. package/dist/collect-B7_TIfmg.js +0 -49
  318. package/dist/collect-fRPAQIWb.js +0 -2
  319. package/dist/compile-CQbvyIBr.d.ts +0 -30
  320. package/dist/config-BPYmjTOp.js +0 -26
  321. package/dist/context-gtAwAILx.js +0 -6
  322. package/dist/create-BKF3dgFk.d.ts +0 -162
  323. package/dist/create-CSkhDU9T.js +0 -222
  324. package/dist/doctor-BGle8Gqi.js +0 -1314
  325. package/dist/helpers-DnSOrhB9.js +0 -682
  326. package/dist/index-fG6NSXlc.d.ts +0 -9
  327. package/dist/kernel-YOGCWNLf.js +0 -211
  328. package/dist/load-QOOm1z70.js +0 -2
  329. package/dist/manifest-DDQbC6K0.d.ts +0 -118
  330. package/dist/map-error-RJ3ZsUyA.js +0 -16
  331. package/dist/may-use-CnFEjVEp.js +0 -37
  332. package/dist/pg-4GJWDUxG.js +0 -953
  333. package/dist/plugin-4gr7IxFJ.js +0 -65
  334. package/dist/protected-B4K3BKoX.js +0 -138
  335. package/dist/protected-wY7nXhY9.d.ts +0 -23
  336. package/dist/provider-_wx46HpB.js +0 -48
  337. package/dist/rls-CJVja9Ww.js +0 -2119
  338. package/dist/rls-helpers-BxRuif0l.js +0 -1346
  339. package/dist/runtime-DP9ttFh1.js +0 -27
  340. package/dist/skills-Dx3QLnMY.js +0 -110
  341. package/dist/source-DoBBYJi2.js +0 -6
  342. package/dist/sources-DVHM3Mwq.js +0 -284
  343. package/dist/store-C6hFW6ta.js +0 -508
  344. package/dist/subject-settings-xt7V845g.js +0 -82
  345. package/dist/supabase-hook-DW-xP4hU.js +0 -2
  346. package/dist/types-DbWdEfcm.d.ts +0 -87
  347. package/dist/types-bva3i4Gf.d.ts +0 -98
  348. package/dist/types-i4BAOvdb.d.ts +0 -97
  349. package/dist/usage-PyEor6GA.js +0 -2
  350. package/dist/version-CnSh33Fj.js +0 -16
@@ -1,38 +1,11 @@
1
1
  import { n as isReadonlyArray, t as compact } from "./compact-y6vfu2_f.js";
2
- import { n as freezeDeep } from "./freeze-y1_jQL4v.js";
3
- import { a as formerKeys, g as listPermissions } from "./permissions-DC7GROPA.js";
4
- import { u as coveredByDelegation } from "./snapshot-DE8dE_hz.js";
2
+ import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
3
+ import { _ as listPermissions, a as formerKeys } from "./permissions-DVoF6dMt.js";
5
4
  import { n as sha256, t as bytesToBase64Url } from "./sha256-BO0swRXL.js";
5
+ import { t as coveredByDelegation } from "./delegation-D8pUEuce.js";
6
6
  import { t as anonymousSubject } from "./subject-C6dLxqHU.js";
7
- import { a as ownRecord, n as idList, r as isId } from "./capability-B68OFnZx.js";
8
- //#region src/core/revocations.ts
9
- function isRevocationEvent(value) {
10
- if (value === null || typeof value !== "object") return false;
11
- const event = value;
12
- return typeof event["principal"] === "string" && event["principal"].length > 0 && (event["kind"] === "session-revoked" || event["kind"] === "changed") && (event["session"] === void 0 || typeof event["session"] === "string") && (event["tenant"] === void 0 || typeof event["tenant"] === "string");
13
- }
14
- /** In-process feed; a multi-replica app bridges `revoke` to its own pub/sub. */
15
- function memoryRevocationFeed() {
16
- const listeners = /* @__PURE__ */ new Set();
17
- return Object.freeze({
18
- subscribe(listener) {
19
- listeners.add(listener);
20
- return () => {
21
- listeners.delete(listener);
22
- };
23
- },
24
- revoke(event) {
25
- if (!isRevocationEvent(event)) throw new TypeError("PermDock: invalid revocation event.");
26
- const frozen = Object.freeze({ ...event });
27
- for (const listener of listeners) try {
28
- listener(frozen);
29
- } catch {}
30
- }
31
- });
32
- }
33
- //#endregion
7
+ import { a as ownRecord, n as idList, r as isId } from "./capability-4qPdO9gk.js";
34
8
  //#region src/core/credential.ts
35
- const MAX_ENTRIES = 64;
36
9
  const MAX_NAME = 256;
37
10
  function policies(policy) {
38
11
  return isReadonlyArray(policy) ? policy : [policy];
@@ -52,7 +25,7 @@ function credentialPolicyViolation(credential, policy) {
52
25
  }
53
26
  }
54
27
  function parsePermissions(value) {
55
- if (!Array.isArray(value) || value.length === 0 || value.length > MAX_ENTRIES) return;
28
+ if (!Array.isArray(value) || value.length === 0) return;
56
29
  const out = [];
57
30
  for (const item of value) {
58
31
  const entry = ownRecord(item);
@@ -73,7 +46,7 @@ function isTime(value) {
73
46
  * Validates an untrusted credential record and returns a frozen copy with
74
47
  * only the v1 fields, or `undefined`. Unknown fields are dropped; a wrong
75
48
  * type in a known field, a service credential without `tenant` and `roles`,
76
- * or a user credential with either, rejects the whole record.
49
+ * or a user credential with `roles`, rejects the whole record.
77
50
  */
78
51
  function parseCredential(input) {
79
52
  const value = ownRecord(input);
@@ -90,7 +63,8 @@ function parseCredential(input) {
90
63
  roles = idList(value["roles"]);
91
64
  if (!isId(value["tenant"]) || roles === void 0) return;
92
65
  tenant = value["tenant"];
93
- } else if (value["tenant"] !== void 0 || value["roles"] !== void 0) return;
66
+ } else if (value["roles"] !== void 0 || value["tenant"] !== void 0 && !isId(value["tenant"])) return;
67
+ else tenant = value["tenant"];
94
68
  return freezeDeep(compact({
95
69
  v: 1,
96
70
  id: value["id"],
@@ -145,7 +119,9 @@ function credentialDelegation(credential, permissions) {
145
119
  * The subject a verified credential acts as. A `user` credential is its
146
120
  * owner, passed live as `owner` (roles and memberships as of this request),
147
121
  * with the credential's delegation: every check is the owner's rights
148
- * intersected with the key's. A `service` credential is a `service`
122
+ * intersected with the key's. One that names a `tenant` makes it the active
123
+ * tenant, and `createPermDock` then keeps only the owner's memberships
124
+ * inside it and no global role. A `service` credential is a `service`
149
125
  * principal whose only membership is `roles` in `tenant`. An owner whose id
150
126
  * is not the credential's `principal`, or who is not a user, is anonymous.
151
127
  */
@@ -158,11 +134,12 @@ function credentialSubject(credential, options) {
158
134
  kind: "user"
159
135
  };
160
136
  if (owner.id !== credential.principal || owner.kind !== void 0 && owner.kind !== "user") return anonymousSubject();
161
- principal = {
137
+ principal = compact({
162
138
  ...owner,
163
139
  kind: "user",
140
+ tenant: credential.tenant ?? owner.tenant,
164
141
  credential
165
- };
142
+ });
166
143
  } else {
167
144
  const membership = compact({
168
145
  tenant: credential.tenant,
@@ -210,7 +187,7 @@ function denied(reason, detail) {
210
187
  });
211
188
  }
212
189
  function permissionEntries(request, declared) {
213
- if (!isReadonlyArray(request.permissions) || request.permissions.length === 0 || request.permissions.length > MAX_ENTRIES) return;
190
+ if (!isReadonlyArray(request.permissions) || request.permissions.length === 0) return;
214
191
  const out = [];
215
192
  for (const item of request.permissions) {
216
193
  const entry = permissionEntry(item);
@@ -249,7 +226,7 @@ function checkRequest(permdock, request, now) {
249
226
  id: request.id,
250
227
  kind: request.kind,
251
228
  principal: request.kind === "service" ? request.principal ?? request.id : creator.id,
252
- tenant: request.kind === "service" ? request.tenant : void 0,
229
+ tenant: request.tenant,
253
230
  roles: request.kind === "service" ? request.roles : void 0,
254
231
  permissions: entries.map((entry) => compact({
255
232
  permission: entry.leaf.key,
@@ -264,6 +241,9 @@ function checkRequest(permdock, request, now) {
264
241
  if (credential.tenant !== void 0) {
265
242
  const tenant = credential.tenant;
266
243
  if (!permdock.tenants().includes(tenant)) return refuse("exceeds-creator", { tenant });
244
+ }
245
+ if (credential.kind === "service" && credential.tenant !== void 0) {
246
+ const tenant = credential.tenant;
267
247
  const roles = new Set(permdock.assignableRoles({ tenant }).map((role) => role.key));
268
248
  for (const name of credential.roles ?? []) if (!roles.has(name)) return refuse("exceeds-creator", { role: name });
269
249
  const ceiling = new Set(permdock.assignablePermissions({ tenant }).map((leaf) => leaf.key));
@@ -275,8 +255,8 @@ function checkRequest(permdock, request, now) {
275
255
  };
276
256
  }
277
257
  /**
278
- * The tenant whose `credentials` policy governs a credential: a service
279
- * key's own tenant, otherwise `active` (the creator's or the request's).
258
+ * The tenant whose `credentials` policy governs a credential: the key's own
259
+ * tenant, otherwise `active` (the creator's or the request's).
280
260
  */
281
261
  function credentialTenant(credential, active) {
282
262
  return credential.tenant ?? active;
@@ -285,11 +265,11 @@ function credentialTenant(credential, active) {
285
265
  * Decides whether the subject of `permdock` may create the credential in
286
266
  * `request`. The creator must be a signed-in user or service that is not
287
267
  * itself a link or a credential; a delegated creator hands out only what its
288
- * delegation covers. A service key's tenant must be one the creator is a
289
- * member of, its roles among the creator's `assignableRoles` there and its
268
+ * delegation covers. A key's tenant must be one the creator is a member of;
269
+ * a service key's roles among the creator's `assignableRoles` there and its
290
270
  * permissions within `assignablePermissions` there (`exceeds-creator`). The
291
- * `credentials` policy of the key's tenant (a service key's own, a user
292
- * key's the creator's active tenant) then applies (`credential-policy`; a
271
+ * `credentials` policy of the key's tenant (its own, or for a user key
272
+ * without one the creator's active tenant) then applies (`credential-policy`; a
293
273
  * settings source that throws denies with `rule: 'unavailable'`), and
294
274
  * `approval` makes the result `approval-required` until `approved` carries
295
275
  * its token. PermDock never stores the credential; the application does,
@@ -323,4 +303,4 @@ async function decideCredential(permdock, request, options = {}) {
323
303
  });
324
304
  }
325
305
  //#endregion
326
- export { decideCredential as a, credentialTenant as i, credentialPolicyViolation as n, parseCredential as o, credentialSubject as r, memoryRevocationFeed as s, credentialDelegation as t };
306
+ export { decideCredential as a, credentialTenant as i, credentialPolicyViolation as n, parseCredential as o, credentialSubject as r, credentialDelegation as t };
@@ -0,0 +1,103 @@
1
+ import { i as findPermission, o as formerScopes, t as annotationsFor } from "./permissions-DVoF6dMt.js";
2
+ import { d as matchGrantee, s as flattenGrantee } from "./grantee-Cv5Sogfv.js";
3
+ import { t as isActive } from "./validity-uOp8UpYn.js";
4
+ //#region src/core/delegation.ts
5
+ /** The permission's scope and any scope it was renamed from: tokens issued before a rename keep working. */
6
+ function scopeNames(permission) {
7
+ return [permission.scope, ...formerScopes(permission)];
8
+ }
9
+ /**
10
+ * Whether a delegated caller may use a permission its principal holds, through
11
+ * OAuth `scopes`, RFC 9396 `authorizationDetails` or GNAP `access`.
12
+ * `undefined` means covered; otherwise the denial reason `decide` would add.
13
+ */
14
+ function coveredByDelegation(permission, delegation, resourceId, hasActor = false) {
15
+ const unscoped = hasActor ? "no-delegation" : void 0;
16
+ if (delegation === void 0) return unscoped;
17
+ const hasScopes = delegation.scopes !== void 0;
18
+ const hasDetails = delegation.authorizationDetails !== void 0;
19
+ const hasAccess = delegation.access !== void 0;
20
+ if (!hasScopes && !hasDetails && !hasAccess) return unscoped;
21
+ const emptyScopes = hasScopes && (delegation.scopes?.length ?? 0) === 0;
22
+ const emptyAccess = hasAccess && (delegation.access?.length ?? 0) === 0;
23
+ if (emptyScopes && !hasDetails && !hasAccess) return "no-delegation";
24
+ if (emptyAccess && !hasScopes && !hasDetails) return "no-delegation";
25
+ if (emptyScopes && emptyAccess && !hasDetails) return "no-delegation";
26
+ const scopes = scopeNames(permission);
27
+ const scopeOk = delegation.scopes?.some((scope) => scopes.includes(scope)) ?? false;
28
+ const detailOk = delegation.authorizationDetails?.some((detail) => {
29
+ if (detail.type !== permission.resource) return false;
30
+ const identifier = detail["identifier"];
31
+ if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
32
+ const actions = detail.actions;
33
+ if (actions === void 0) return true;
34
+ return Array.isArray(actions) && actions.includes(permission.action);
35
+ }) ?? false;
36
+ const accessOk = accessCovers(permission, delegation.access, resourceId);
37
+ if (scopeOk || detailOk || accessOk) return;
38
+ return "not-delegated";
39
+ }
40
+ function coversRequirements(tree, requires, delegation, resourceId, hasActor = false) {
41
+ return (requires ?? []).every((key) => {
42
+ const leaf = findPermission(tree, key);
43
+ return leaf !== void 0 && coveredByDelegation(leaf, delegation, resourceId, hasActor) === void 0;
44
+ });
45
+ }
46
+ function requiresStandIn(grant) {
47
+ return (grant.requires ?? []).length > 0 && annotationsFor(grant.permission).readOnlyHint && !flattenGrantee(grant.to).some((item) => item.kind === "role");
48
+ }
49
+ function accessCovers(permission, access, resourceId) {
50
+ if (access === void 0) return false;
51
+ return access.some((entry) => {
52
+ if (typeof entry === "string") return scopeNames(permission).includes(entry);
53
+ if (entry === null || typeof entry !== "object") return false;
54
+ const type = entry["type"];
55
+ if (typeof type !== "string" || !typeMatches(type, permission.resource)) return false;
56
+ const actions = entry["actions"];
57
+ if (actions !== void 0 && (!Array.isArray(actions) || !actions.includes(permission.action))) return false;
58
+ const identifier = entry["identifier"];
59
+ if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
60
+ return true;
61
+ });
62
+ }
63
+ function typeMatches(type, resource) {
64
+ if (type === resource) return true;
65
+ return type.endsWith(`/${resource}`);
66
+ }
67
+ /**
68
+ * Whether the subject's principal is a `from` of the delegation: every item
69
+ * matches, with roles checked against the roles the principal holds here
70
+ * (`matchGrantee` leaves role holding to the caller) and nothing that needs a
71
+ * row.
72
+ */
73
+ function handsOver(delegation, subject, heldRoles, now) {
74
+ const items = flattenGrantee(delegation.from);
75
+ if (items.length === 0 || subject.principal === null) return false;
76
+ return items.every((item) => {
77
+ if (item.kind === "role") return heldRoles.has(item.role);
78
+ if (item.kind === "relation") return false;
79
+ const match = matchGrantee(item, subject, now, void 0);
80
+ return match.matched && match.where === void 0;
81
+ });
82
+ }
83
+ /**
84
+ * The permission keys the policy's delegations let `subject.actor` use for
85
+ * `subject.principal` right now: the union over every active delegation whose
86
+ * `to` matches the actor and whose `from` the principal holds. `undefined`
87
+ * when none applies, so the call falls back to the token delegation alone.
88
+ * An actor with `readOnly: true` gets only each delegation's read-only keys.
89
+ * Attenuation only: a key here still needs a matching allow and no deny.
90
+ */
91
+ function delegatedPermissions(delegations, subject, heldRoles, now) {
92
+ const actor = subject.actor;
93
+ if (actor === void 0 || delegations === void 0) return;
94
+ let keys;
95
+ for (const delegation of delegations) {
96
+ if (delegation.to.kind !== actor.kind || delegation.to.id !== void 0 && delegation.to.id !== actor.id || delegation.to.client !== void 0 && delegation.to.client !== actor.client || !isActive(delegation.validity, now) || !handsOver(delegation, subject, heldRoles, now)) continue;
97
+ keys ??= /* @__PURE__ */ new Set();
98
+ for (const key of actor.readOnly === true ? delegation.readOnly : delegation.permissions) keys.add(key);
99
+ }
100
+ return keys;
101
+ }
102
+ //#endregion
103
+ export { requiresStandIn as i, coversRequirements as n, delegatedPermissions as r, coveredByDelegation as t };
@@ -1,5 +1,5 @@
1
- import { t as flattenApprovers } from "./approvers-aH0PJkmf.js";
2
- import { s as flattenGrantee } from "./grantee-Bv04_Vzf.js";
1
+ import { i as flattenApprovers } from "./approvers-DT4AVyIg.js";
2
+ import { r as requiredPlans } from "./problem-details-_AMOYz-w.js";
3
3
  //#region src/core/describe.ts
4
4
  const TENANT_REASONS = /* @__PURE__ */ new Set([
5
5
  "tenant-mismatch",
@@ -16,6 +16,7 @@ function labelGrantee(grantee) {
16
16
  case "authenticated": return "an authenticated user";
17
17
  case "anyone": return "anyone";
18
18
  case "relation": return grantee.relation;
19
+ case "inherit": return grantee.permission;
19
20
  case "assurance": {
20
21
  const parts = [];
21
22
  if (grantee.acr !== void 0 && grantee.acr.length > 0) parts.push(`acr ${grantee.acr.join("/")}`);
@@ -25,16 +26,6 @@ function labelGrantee(grantee) {
25
26
  default: return grantee;
26
27
  }
27
28
  }
28
- /**
29
- * The plans named by the `not-entitled` denials of a decision, when every
30
- * denial is `not-entitled`; otherwise empty, since a plan alone would not grant.
31
- */
32
- function requiredPlans(decision) {
33
- if (decision.outcome !== "denied" || decision.denials.length === 0 || decision.denials.some((denial) => denial.reason !== "not-entitled")) return [];
34
- const plans = /* @__PURE__ */ new Set();
35
- for (const denial of decision.denials) for (const item of flattenGrantee(denial.to)) if (item.kind === "plan") plans.add(item.plan);
36
- return [...plans];
37
- }
38
29
  const TITLES = {
39
30
  granted: "Granted",
40
31
  denied: "Denied",
@@ -45,7 +36,10 @@ const TITLES = {
45
36
  upgrade: "Upgrade required"
46
37
  };
47
38
  function labelApprover(approver) {
48
- return approver.kind === "user" ? `user ${approver.id}` : labelGrantee(approver);
39
+ if (approver.kind === "user") return `user ${approver.id}`;
40
+ if (approver.kind === "permission") return `a holder of ${approver.permission}`;
41
+ if (approver.kind === "any-of") return `one of (${approver.of.map((entry) => flattenApprovers(entry).map(labelApprover).join(" and ")).join(", ")})`;
42
+ return labelGrantee(approver);
49
43
  }
50
44
  function approvers(approval) {
51
45
  if (approval === void 0 || approval === "human") return [];
@@ -87,7 +81,8 @@ function describe(decision, options) {
87
81
  };
88
82
  const reasons = decision.denials.map((denial) => denial.reason);
89
83
  const kind = reasons.some((reason) => TENANT_REASONS.has(reason)) ? "tenant" : reasons.some((reason) => DELEGATION_REASONS.has(reason)) ? "delegation" : reasons.includes("opaque-condition") || reasons.includes("server-only") ? "server-only" : "denied";
90
- const detail = reasons.map((reason) => messages?.reasons?.[reason] ?? reason).join(messages?.separator ?? ", ");
84
+ const texts = messages?.reasons;
85
+ const detail = reasons.map((reason) => (typeof texts === "function" ? texts(reason, decision) : texts?.[reason]) ?? reason).join(messages?.separator ?? ", ");
91
86
  return {
92
87
  kind,
93
88
  title: titleOf(kind),
@@ -96,4 +91,4 @@ function describe(decision, options) {
96
91
  };
97
92
  }
98
93
  //#endregion
99
- export { requiredPlans as n, describe as t };
94
+ export { describe as t };
@@ -1,5 +1,5 @@
1
- import { Mn as Decision, Pn as DenialReason } from "./policy-CInmNGkM.js";
2
- import { d as Permission } from "./permissions-B4apnahQ.js";
1
+ import { Qn as DeniedDecision, Yn as Decision, Zn as DenialReason } from "./policy-IB6yxpC3.js";
2
+ import { f as Permission } from "./permissions-DttnqqxC.js";
3
3
  //#region src/core/describe.d.ts
4
4
  type DecisionDescription = {
5
5
  readonly kind: "granted" | "denied" | "approval" | "tenant" | "delegation" | "server-only" | "upgrade";
@@ -9,19 +9,18 @@ type DecisionDescription = {
9
9
  /** On `upgrade`: the plans any of which would grant the permission. */
10
10
  readonly plans?: readonly string[];
11
11
  };
12
- /**
13
- * The plans named by the `not-entitled` denials of a decision, when every
14
- * denial is `not-entitled`; otherwise empty, since a plan alone would not grant.
15
- */
16
- declare function requiredPlans(decision: Decision): readonly string[];
17
12
  /**
18
13
  * Localised text for `describe`. Every entry is optional and falls back to the
19
14
  * English default; `kind` and `alternatives` never change.
20
15
  */
21
16
  type DescribeMessages = {
22
17
  readonly titles?: Partial<Record<DecisionDescription["kind"], string>>;
23
- /** Text per denial reason; a denied detail joins the texts of its reasons with `separator`. */
24
- readonly reasons?: Partial<Record<DenialReason, string>>;
18
+ /**
19
+ * Text per denial reason; a denied detail joins the texts of its reasons
20
+ * with `separator`. The function form also sees the decision; `undefined`
21
+ * keeps the reason code, as a missing record entry does.
22
+ */
23
+ readonly reasons?: Partial<Record<DenialReason, string>> | ((reason: DenialReason, decision: DeniedDecision) => string | undefined);
25
24
  /** Joins denial reason texts. Default `', '`. */
26
25
  readonly separator?: string;
27
26
  readonly granted?: (permission: string) => string;
@@ -34,4 +33,4 @@ type DescribeOptions = {
34
33
  };
35
34
  declare function describe(decision: Decision, options?: DescribeOptions): DecisionDescription;
36
35
  //#endregion
37
- export { requiredPlans as a, describe as i, DescribeMessages as n, DescribeOptions as r, DecisionDescription as t };
36
+ export { describe as i, DescribeMessages as n, DescribeOptions as r, DecisionDescription as t };
@@ -1,12 +1,12 @@
1
- import { i as findPermission } from "./permissions-DC7GROPA.js";
2
- import { m as memoryRoleSource } from "./src-CTNT-PBW.js";
3
- import { l as canonicalJson } from "./snapshot-DE8dE_hz.js";
4
- import { t as createPermDock } from "./permdock-yoZ7EjxX.js";
5
- import { t as buildCatalog } from "./catalog-doc-BSo_Q_-6.js";
6
- import { a as loadModule, n as asPolicy, o as pickNamed } from "./load-BZ24CpZP.js";
7
- import { t as parseCatalog } from "./parse-DPfIvFMU.js";
8
- import { a as usageResult } from "./errors-DSMnAVNa.js";
9
- import { n as fixtureSubject, r as loadFixtures, t as fixtureRow } from "./fixtures-Cvaw0gDG.js";
1
+ import { i as findPermission } from "./permissions-DVoF6dMt.js";
2
+ import { _ as memoryRoleSource } from "./src-BDwEZWrZ.js";
3
+ import { t as canonicalJson } from "./canonical-json-DemiK4Vp.js";
4
+ import { t as createPermDock } from "./permdock-CbgvLnuo.js";
5
+ import { o as usageResult } from "./errors-CWfoNg9N.js";
6
+ import { t as buildCatalog } from "./catalog-doc-DdGm82XT.js";
7
+ import { a as loadModule, n as asPolicy, o as pickNamed } from "./load-DhWEB9P1.js";
8
+ import { t as parseCatalog } from "./parse-BuyjxhZV.js";
9
+ import { n as fixtureSubject, r as loadFixtures, t as fixtureRow } from "./fixtures-ht28Cplr.js";
10
10
  import { existsSync, readFileSync } from "node:fs";
11
11
  import { resolve } from "node:path";
12
12
  //#region src/cli/diff.ts
@@ -19,7 +19,8 @@ const EMPTY_SCAN = {
19
19
  roleNames: [],
20
20
  planNames: [],
21
21
  allowKeys: [],
22
- snapshots: []
22
+ snapshots: [],
23
+ unparsed: []
23
24
  };
24
25
  async function loadSide(cwd, source, now) {
25
26
  const abs = resolve(cwd, source);
@@ -109,7 +110,8 @@ function delegationIdentity(delegation) {
109
110
  });
110
111
  }
111
112
  function describeDelegation(delegation) {
112
- const to = delegation.to.id === void 0 ? delegation.to.kind : `${delegation.to.kind} ${delegation.to.id}`;
113
+ const narrowed = delegation.to.id ?? delegation.to.client;
114
+ const to = narrowed === void 0 ? delegation.to.kind : `${delegation.to.kind} ${narrowed}`;
113
115
  return `delegation ${canonicalJson(delegation.from)} → ${to} (${delegation.permissions.join(", ")})`;
114
116
  }
115
117
  function delegationChanges(before, after) {
@@ -187,6 +189,29 @@ function underNames(a, aliases) {
187
189
  }
188
190
  };
189
191
  }
192
+ /** Levels of permissions on both sides, with `a`'s keys under `b`'s names. */
193
+ function diffLevels(a, b, aliases) {
194
+ const after = new Map(b.permissions.map((item) => [item.key, new Set(item.levels ?? [])]));
195
+ const before = new Map(a.permissions.map((item) => [aliases.get(item.key) ?? item.key, new Set(item.levels ?? [])]));
196
+ const added = [];
197
+ const removed = [];
198
+ for (const [permission, levels] of before) {
199
+ const kept = after.get(permission);
200
+ if (kept === void 0) continue;
201
+ for (const level of levels) if (!kept.has(level)) removed.push({
202
+ permission,
203
+ level
204
+ });
205
+ for (const level of kept) if (!levels.has(level)) added.push({
206
+ permission,
207
+ level
208
+ });
209
+ }
210
+ return {
211
+ added,
212
+ removed
213
+ };
214
+ }
190
215
  function diffCatalogs(original, b) {
191
216
  const breaking = [];
192
217
  const aliasesA = aliasesOf(original.catalog);
@@ -219,6 +244,12 @@ function diffCatalogs(original, b) {
219
244
  permission: to,
220
245
  detail: `${old} no longer resolves to ${to}: stored custom roles, tokens and SQL that still name it now deny`
221
246
  });
247
+ const levels = diffLevels(a.catalog, b.catalog, aliasesB);
248
+ for (const item of levels.removed) breaking.push({
249
+ kind: "level-removed",
250
+ permission: item.permission,
251
+ detail: `level ${item.level} of ${item.permission} no longer exists: stored custom roles that pick it now deny the permission`
252
+ });
222
253
  const scopes = setDiff((a.catalog.scopes ?? []).map((scope) => scope.name), (b.catalog.scopes ?? []).map((scope) => scope.name));
223
254
  for (const name of scopes.removed) breaking.push({
224
255
  kind: "scope-removed",
@@ -301,6 +332,7 @@ function diffCatalogs(original, b) {
301
332
  a: sideRef(a),
302
333
  b: sideRef(b),
303
334
  permissions,
335
+ levels,
304
336
  scopes,
305
337
  roles: {
306
338
  ...roleNames,
@@ -353,6 +385,7 @@ function formatText(diff) {
353
385
  for (const item of changed) lines.push(` ~ ${item}`);
354
386
  };
355
387
  section("permissions", diff.permissions.added, diff.permissions.removed, diff.permissions.renamed.map((rename) => `${rename.from} → ${rename.to} (renamed)`));
388
+ section("levels", diff.levels.added.map((item) => `${item.permission}@${item.level}`), diff.levels.removed.map((item) => `${item.permission}@${item.level}`));
356
389
  section("scopes", diff.scopes.added, diff.scopes.removed);
357
390
  section("roles", diff.roles.added, diff.roles.removed, diff.roles.changed.map((name) => `${name}: declaration changed`));
358
391
  if (diff.grants === void 0) lines.push("grants: not compared (a catalog was built without its policy; run `permdock collect` with `policy` configured)");
@@ -1,4 +1,4 @@
1
- import { i as globalArgs, s as stringArg, t as COMMAND_DESCRIPTIONS } from "./commands-BMh_Etm2.js";
1
+ import { i as globalArgs, s as stringArg, t as COMMAND_DESCRIPTIONS } from "./commands-DSxCqG9A.js";
2
2
  import { defineCommand } from "citty";
3
3
  //#region src/cli/commands/diff.ts
4
4
  function diff(ctx) {
@@ -30,7 +30,7 @@ function diff(ctx) {
30
30
  }
31
31
  },
32
32
  async run({ args: parsed }) {
33
- const result = await (await import("./diff-x5Il8LVa.js")).runDiff({
33
+ const result = await (await import("./diff-2VaeChzX.js")).runDiff({
34
34
  cwd: ctx.cwd,
35
35
  config: ctx.config,
36
36
  sources: parsed._,
@@ -1,4 +1,4 @@
1
- import { a as listArg, i as globalArgs, t as COMMAND_DESCRIPTIONS } from "./commands-BMh_Etm2.js";
1
+ import { a as listArg, i as globalArgs, t as COMMAND_DESCRIPTIONS } from "./commands-DSxCqG9A.js";
2
2
  import { n as ask, t as CANCELLED } from "./prompt-CXYhLfsS.js";
3
3
  import { defineCommand } from "citty";
4
4
  //#region src/cli/commands/doctor.ts
@@ -34,7 +34,7 @@ function doctor(ctx) {
34
34
  }
35
35
  fix = answer;
36
36
  }
37
- const result = await (await import("./doctor-BGle8Gqi.js")).runDoctor({
37
+ const result = await (await import("./doctor-igIiM_Hl.js")).runDoctor({
38
38
  cwd: ctx.cwd,
39
39
  config: ctx.config,
40
40
  only: listArg(rawArgs, "only"),