permdock 0.3.1 → 0.4.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 (323) hide show
  1. package/dist/a2a/index.d.ts +7 -5
  2. package/dist/a2a/index.js +14 -21
  3. package/dist/ai-sdk/index.d.ts +18 -6
  4. package/dist/ai-sdk/index.js +8 -5
  5. package/dist/app-data-CV8pqqMi.js +59 -0
  6. package/dist/approvals/index.d.ts +2 -2
  7. package/dist/approvals/index.js +3 -3
  8. package/dist/{approvals-DbYAuNkG.js → approvals-DZL76lKW.js} +35 -19
  9. package/dist/{approvers-DT4AVyIg.js → approvers-CqPOLD-o.js} +1 -1
  10. package/dist/{arazzo-BAgw9ap6.js → arazzo-C4BcskbX.js} +6 -5
  11. package/dist/{arazzo-C9chp3ST.js → arazzo-CD8d0WLb.js} +2 -2
  12. package/dist/authzen/index.d.ts +3 -3
  13. package/dist/authzen/index.js +161 -23
  14. package/dist/better-auth/index.d.ts +2 -2
  15. package/dist/better-auth/index.js +6 -19
  16. package/dist/better-supabase/index.d.ts +112 -87
  17. package/dist/better-supabase/index.js +257 -156
  18. package/dist/{bind-C_ob3LKa.d.ts → bind-BzqG8SMb.d.ts} +16 -5
  19. package/dist/{bind-CuzGytRf.js → bind-kk-uyCwH.js} +14 -6
  20. package/dist/build-instance-DIIV9DbC.js +51 -0
  21. package/dist/{canonical-json-DemiK4Vp.js → canonical-json-CFKyFOke.js} +1 -3
  22. package/dist/{capability-2kYTMWDv.d.ts → capability-CksyCWDH.d.ts} +2 -2
  23. package/dist/{capability-4qPdO9gk.js → capability-txATtKV4.js} +3 -2
  24. package/dist/catalog/index.d.ts +1 -1
  25. package/dist/catalog/index.js +1 -1
  26. package/dist/catalog-6yWAX6Ps.js +2 -0
  27. package/dist/{catalog-CYj-mX2O.js → catalog-WHG4kBq7.js} +2 -2
  28. package/dist/{catalog-doc-DdGm82XT.js → catalog-doc-DWtg0gGR.js} +17 -10
  29. package/dist/{catalog-DWF5cYqB.js → catalog-tZUyOfOv.js} +4 -4
  30. package/dist/claude-agent/index.d.ts +4 -4
  31. package/dist/claude-agent/index.js +4 -5
  32. package/dist/clerk/index.d.ts +3 -3
  33. package/dist/clerk/index.js +8 -33
  34. package/dist/cli/bin.js +1 -1
  35. package/dist/cli/index.d.ts +3 -3
  36. package/dist/cli/index.js +3 -3
  37. package/dist/cloud/index.d.ts +4 -4
  38. package/dist/cloud/index.js +9 -15
  39. package/dist/{cloud-CfwZ39Rl.js → cloud-C7bSDgX4.js} +2 -2
  40. package/dist/{cloud-DWLXO2af.js → cloud-PeBN3IEn.js} +5 -5
  41. package/dist/{collect-DSTE3ml9.js → collect-2SrB7lfk.js} +6 -8
  42. package/dist/collect-Bw2Jdq1q.js +2 -0
  43. package/dist/{collect-CHB22Sx4.js → collect-CQx4hX4N.js} +3 -3
  44. package/dist/{commands-BeaGNj_o.js → commands-Cpip4ULx.js} +13 -13
  45. package/dist/{compact-y6vfu2_f.js → compact-CAf557ZB.js} +11 -1
  46. package/dist/compile/index.d.ts +1 -1
  47. package/dist/compile/index.js +1 -1
  48. package/dist/{compile-Ba4blROR.js → compile-CcEu2ZQ1.js} +6 -5
  49. package/dist/{compile-BkRyBDBw.d.ts → compile-CtTP7eur.d.ts} +2 -2
  50. package/dist/{config-BJiM-xAm.js → config-BIjREpyE.js} +4 -4
  51. package/dist/{config-ir40y8m0.js → config-DLt6BvV7.js} +2 -2
  52. package/dist/{config-report-CdCgbRnV.js → config-report--Xb9APJS.js} +5 -6
  53. package/dist/{connection-CU8MQxRi.js → connection-DUsczpB5.js} +3 -2
  54. package/dist/constants-DcJABbLW.js +20 -0
  55. package/dist/{context-Bcy85rGi.js → context-DieZVJXu.js} +16 -5
  56. package/dist/convex/index.d.ts +4 -4
  57. package/dist/convex/index.js +14 -16
  58. package/dist/create-BBO24vj6.js +324 -0
  59. package/dist/{credential-8P81ff4u.js → credential-kue0qpbm.js} +4 -4
  60. package/dist/deciding-columns-Sq12mEA6.js +123 -0
  61. package/dist/delegation-input-FTxMK3ji.js +19 -0
  62. package/dist/denied-text-DfRk15uw.d.ts +19 -0
  63. package/dist/{describe-DMYiCjJV.d.ts → describe-C3ldA9os.d.ts} +11 -2
  64. package/dist/{describe-B_gVZEVi.js → describe-Cgkp7eP0.js} +5 -4
  65. package/dist/{diff-C9RDjjhs.js → diff-Cnghh_Ip.js} +2 -2
  66. package/dist/{diff-2VaeChzX.js → diff-rpqoe7Ag.js} +9 -9
  67. package/dist/{doctor-Djh6JDEk.js → doctor-CuVJvhV_.js} +2 -2
  68. package/dist/doctor-owlv6ddh.js +2166 -0
  69. package/dist/drizzle/index.d.ts +2 -2
  70. package/dist/drizzle/index.js +6 -14
  71. package/dist/elysia/index.d.ts +4 -4
  72. package/dist/elysia/index.js +7 -7
  73. package/dist/{errors-DPdqI50v.d.ts → errors-OD_4c__H.d.ts} +2 -2
  74. package/dist/{errors-Cz5zn0mW.js → errors-drnfxYtm.js} +3 -3
  75. package/dist/{evaluations-tz6D9A2G.js → evaluations-C9YJsv3H.js} +45 -7
  76. package/dist/eve/index.d.ts +5 -5
  77. package/dist/eve/index.js +5 -5
  78. package/dist/express/index.d.ts +4 -4
  79. package/dist/express/index.js +8 -7
  80. package/dist/fastify/index.d.ts +15 -5
  81. package/dist/fastify/index.js +9 -29
  82. package/dist/fields-fwfXN01n.js +1016 -0
  83. package/dist/{files-DWUN9PzI.js → files-D_JIzUrP.js} +12 -3
  84. package/dist/{fixtures-ht28Cplr.js → fixtures-h2eG2OZV.js} +5 -6
  85. package/dist/{from-snapshot-CTLijvdm.js → from-snapshot-7REQZe0H.js} +32 -22
  86. package/dist/{generate-CH7ThJ14.js → generate-CNU1pIOo.js} +1 -3
  87. package/dist/grantee-CXY-0C87.js +254 -0
  88. package/dist/grantee-conditions-MQs5NIuX.js +270 -0
  89. package/dist/grantee-match-fxYp9Nmt.js +141 -0
  90. package/dist/{helpers-H_KARDVC.js → helpers-C9YmyBIa.js} +7 -6
  91. package/dist/hono/index.d.ts +4 -4
  92. package/dist/hono/index.js +8 -8
  93. package/dist/hosted-CBHgkzDl.js +655 -0
  94. package/dist/{http-SO7qGttf.js → http-BBoKefeS.js} +35 -2
  95. package/dist/{http-BIhmLfCc.js → http-BEbdMZ05.js} +2 -24
  96. package/dist/{rls-import-4lLW_pbb.js → import-BFIlhetD.js} +86 -80
  97. package/dist/{openapi-import-cmwetbzw.js → import-UHk1N7vH.js} +6 -7
  98. package/dist/{index-C8z4RjQV.d.ts → index-BwMe94Xq.d.ts} +1 -1
  99. package/dist/{index-0nNqHspG.d.ts → index-DgM7w96K.d.ts} +2 -2
  100. package/dist/{index-C7Tw7MaW.d.ts → index-Dz7didpC.d.ts} +3 -3
  101. package/dist/{index-BNc7Wer_.d.ts → index-UdVQgq48.d.ts} +105 -38
  102. package/dist/index.d.ts +15 -13
  103. package/dist/index.js +22 -22
  104. package/dist/{instance-options-jARdwfPN.d.ts → instance-options-plkrsAog.d.ts} +1 -1
  105. package/dist/{json-schema-BsAflUGW.js → json-schema-DBkdUuCO.js} +1 -3
  106. package/dist/jwt/index.d.ts +4 -4
  107. package/dist/jwt/index.js +13 -13
  108. package/dist/{kernel-_RRHmnMY.js → kernel-CB3LrIJM.js} +81 -32
  109. package/dist/kysely/index.d.ts +2 -2
  110. package/dist/kysely/index.js +6 -14
  111. package/dist/{live-options-H2eG8dfJ.js → live-options-BaAFCIiu.js} +16 -3
  112. package/dist/load-B_shHrmd.js +2 -0
  113. package/dist/{load-DhWEB9P1.js → load-C3_oTHyO.js} +11 -3
  114. package/dist/{manifest-iaoBXHKc.js → manifest-BngWKryL.js} +5 -18
  115. package/dist/{map-claims-Z4QZOiFF.js → map-claims-AVlBaJoa.js} +7 -16
  116. package/dist/{map-error-pgUWNNtG.js → map-error-BE27PYkE.js} +5 -5
  117. package/dist/{markers-B0hYLvMD.js → markers-CiwAOZtO.js} +6 -2
  118. package/dist/{may-use-DndQ5tQ-.js → may-use-BOn_dR_w.js} +4 -3
  119. package/dist/mcp/index.d.ts +26 -9
  120. package/dist/mcp/index.js +456 -446
  121. package/dist/{rls-migrate-CN4TlJTO.js → migrate-BwlB5-Wk.js} +75 -15
  122. package/dist/nest/index.d.ts +4 -4
  123. package/dist/nest/index.js +11 -12
  124. package/dist/next/index.d.ts +31 -8
  125. package/dist/next/index.js +29 -33
  126. package/dist/next/plugin.d.ts +1 -1
  127. package/dist/next/plugin.js +1 -1
  128. package/dist/node/index.d.ts +4 -4
  129. package/dist/node/index.js +4 -4
  130. package/dist/ocsf-uYFXGVw2.js +115 -0
  131. package/dist/openai/index.d.ts +5 -5
  132. package/dist/openai/index.js +4 -4
  133. package/dist/openapi/index.d.ts +3 -3
  134. package/dist/openapi/index.js +1 -1
  135. package/dist/{openapi-CqqEbHsL.js → openapi-BJdBmYDG.js} +19 -23
  136. package/dist/{openapi-BqRBvAng.js → openapi-DBzHQbov.js} +2 -5
  137. package/dist/{openapi-CQTsgKoB.js → openapi-DcQ1Kg40.js} +3 -3
  138. package/dist/orpc/index.d.ts +5 -5
  139. package/dist/orpc/index.js +9 -11
  140. package/dist/otel/index.d.ts +2 -2
  141. package/dist/otel/index.js +26 -23
  142. package/dist/output-files-CgIsvdSa.js +140 -0
  143. package/dist/{rls-ownership-DcYlZ09B.js → ownership-BgnbOJFT.js} +387 -379
  144. package/dist/{package-root-zGkxO3oN.js → package-root-DtNnpmUd.js} +3 -2
  145. package/dist/{parse-BuyjxhZV.js → parse-CVFQHk6c.js} +3 -3
  146. package/dist/{parse-local-manifest-BrMozJCo.js → parse-local-manifest-C-q02Pal.js} +2 -4
  147. package/dist/{parse-local-manifest-JLnaBH0S.d.ts → parse-local-manifest-DvYUR0QL.d.ts} +1 -1
  148. package/dist/pdp/index.d.ts +2 -2
  149. package/dist/pdp/index.js +8 -9
  150. package/dist/{permdock-CbgvLnuo.js → permdock-L26udHSk.js} +1387 -1220
  151. package/dist/{rls-fields-CZOMlwHl.js → permission-keys-B26jeyUv.js} +1268 -2053
  152. package/dist/permission-registry-BsblpB-z.js +385 -0
  153. package/dist/{permissions-DttnqqxC.d.ts → permission-types-Dg39z9Kv.d.ts} +59 -31
  154. package/dist/{permissions-RJrovw98.js → permissions-CCJ6lmxB.js} +3 -3
  155. package/dist/{permissions-CDgvKG5L.d.ts → permissions-COH-KRgT.d.ts} +2 -2
  156. package/dist/{policy-IB6yxpC3.d.ts → policy-types-sp9P1iIV.d.ts} +661 -582
  157. package/dist/{policy-D2W7uv19.d.ts → policy-ur0BBK_e.d.ts} +2 -2
  158. package/dist/{powersync-DE19b9dT.js → powersync-BFSbSElQ.js} +2 -2
  159. package/dist/powersync-DCDgZgfZ.js +2 -0
  160. package/dist/{powersync-Dv1_aWF7.js → powersync-cZe4kzhL.js} +26 -27
  161. package/dist/prisma/index.d.ts +1 -1
  162. package/dist/prisma/index.js +6 -12
  163. package/dist/{problem-B43ztKIm.js → problem-CnWraVhC.js} +8 -7
  164. package/dist/{problem-details-_AMOYz-w.js → problem-details-DECUnXAn.js} +2 -2
  165. package/dist/{problem-details-DX075l9V.d.ts → problem-details-rIIo8B2C.d.ts} +1 -1
  166. package/dist/{protected-BdnIEFkY.d.ts → protected-B3_P7xuw.d.ts} +9 -6
  167. package/dist/{protected-utU-SLuy.js → protected-BN7BUdY1.js} +20 -8
  168. package/dist/{provider-CSQd7m92.js → provider-Bi-0HNL3.js} +23 -10
  169. package/dist/{provider-DZY281jO.d.ts → provider-kwHC9CZD.d.ts} +1 -1
  170. package/dist/{provider-store-Cfbvo4DE.js → provider-store-Ctt-81Ni.js} +6 -3
  171. package/dist/react/index.d.ts +7 -7
  172. package/dist/react/index.js +5 -5
  173. package/dist/react/provider-client.d.ts +1 -1
  174. package/dist/react/provider-client.js +1 -1
  175. package/dist/react-native/index.d.ts +20 -11
  176. package/dist/react-native/index.js +33 -17
  177. package/dist/{refs-KYb4ntaz.js → refs-f3imMjNW.js} +1 -1
  178. package/dist/relation-walk-BXnlLtg2.js +186 -0
  179. package/dist/relations-CvmSpG67.js +163 -0
  180. package/dist/{replay-CYyiLiwO.d.ts → replay-COpmZUfx.d.ts} +1 -1
  181. package/dist/request-context-BVM7aWNs.js +71 -0
  182. package/dist/request-context-C2_1lchh.d.ts +5 -0
  183. package/dist/resource-relations-D1Un3pcz.js +243 -0
  184. package/dist/retire-BFcxL6un.js +240 -0
  185. package/dist/{rls-P-BeBx0n.js → rls-55DQTuf5.js} +14 -2
  186. package/dist/{rls-DiinlRML.js → rls-BEktUaqg.js} +884 -484
  187. package/dist/{policy-xyWg7QdR.js → role-builder-B4GbKM-i.js} +235 -541
  188. package/dist/{rpc-DL9Sqvb1.js → rpc-nYC3cR_u.js} +15 -5
  189. package/dist/{run-BWc9qqvE.js → run-DMcNW_8T.js} +3 -3
  190. package/dist/{runtime-CB8gQFvS.js → runtime-D_tMXnsq.js} +1 -1
  191. package/dist/{saas-DhpJjnBA.js → saas-DtaA4JuW.js} +9 -8
  192. package/dist/{openapi-schema--ARjyfQr.js → schema-Bol6gqXA.js} +3 -5
  193. package/dist/{schema-D3MnDMxa.js → schema-DjQBcAP9.js} +4 -2
  194. package/dist/scim/index.d.ts +1 -1
  195. package/dist/scim/index.js +1 -1
  196. package/dist/{scim-BFGBBAqR.js → scim-vFR1O5oG.js} +6 -12
  197. package/dist/{scopes-CVdPrWN-.js → scopes-tvpa34ep.js} +10 -2
  198. package/dist/server/index.d.ts +18 -8
  199. package/dist/server/index.js +8 -8
  200. package/dist/{server-DlZ28Oz5.js → server-ZYEHtNHS.js} +4 -4
  201. package/dist/{create-B1d519XK.d.ts → server-types-DdqBwZN_.d.ts} +69 -33
  202. package/dist/shared-1uhI-e-b.js +294 -0
  203. package/dist/{shared-DRu8VFVM.js → shared-JhMeOsDF.js} +1 -1
  204. package/dist/{sink-Bd9PSyfq.js → sink-BTtmfPnE.js} +1 -1
  205. package/dist/{sink-B1fZzIMf.d.ts → sink-CPN4zLfs.d.ts} +1 -1
  206. package/dist/{skills-Biq5uup3.js → skills-BZdRQkxs.js} +4 -3
  207. package/dist/{skills-C5CbhhpG.js → skills-Dle4ZoLF.js} +2 -2
  208. package/dist/{snapshot-Enxd0n-s.js → snapshot-Dc9CHPME.js} +116 -13
  209. package/dist/{snapshot-cache-D6jLelln.js → snapshot-cache-Cod40D-X.js} +1 -1
  210. package/dist/{snapshot-cache-B-LxUahj.d.ts → snapshot-cache-J5T7t_vD.d.ts} +1 -1
  211. package/dist/solid/index.d.ts +22 -22
  212. package/dist/solid/index.js +40 -10
  213. package/dist/{sources-4p0-4xQm.js → sources-B1-b-R0t.js} +25 -26
  214. package/dist/{sources-BdOYLw9j.d.ts → sources-Dljy06zL.d.ts} +6 -2
  215. package/dist/{sql-xdg5f4Fi.js → sql-t8teWOfo.js} +19 -3
  216. package/dist/{src-BDwEZWrZ.js → src-Bb7no-hS.js} +194 -123
  217. package/dist/ssf/index.d.ts +3 -3
  218. package/dist/ssf/index.js +58 -61
  219. package/dist/store-9KO4BlkB.d.ts +147 -0
  220. package/dist/{store-DMAWwAJV.js → store-ILkLUj_o.js} +4 -4
  221. package/dist/{store-options-ByhZq1jV.js → store-options-CbUHDoSe.js} +16 -7
  222. package/dist/{stores-BT2pSCub.js → stores-BHXdSbw9.js} +7 -3
  223. package/dist/stores-Cxz_80g-.d.ts +31 -0
  224. package/dist/{stream-DDpvynSB.js → stream-BMui98KK.js} +2 -1
  225. package/dist/{stream-D1RXubw2.d.ts → stream-Dwsg6WwE.d.ts} +2 -2
  226. package/dist/{subject-settings-BwBmCdTR.js → subject-settings-CkEwrw3W.js} +23 -5
  227. package/dist/supabase/index.d.ts +4 -4
  228. package/dist/supabase/index.js +3 -3
  229. package/dist/supabase/middleware.d.ts +11 -5
  230. package/dist/supabase/middleware.js +10 -7
  231. package/dist/{supabase-C0qESOa-.js → supabase-C1TWlnYt.js} +36 -52
  232. package/dist/{supabase-s4o9s1O1.js → supabase-Dbqr141s.js} +2 -2
  233. package/dist/supabase-hook-BULg7Ut_.js +2 -0
  234. package/dist/{supabase-hook-ntETYCQu.js → supabase-hook-Cva3ikXz.js} +730 -781
  235. package/dist/{supautils-u8jXTGrt.js → supautils-B6HYL9eL.js} +2 -2
  236. package/dist/svelte/Protected.svelte +9 -2
  237. package/dist/svelte/index.d.ts +6 -6
  238. package/dist/svelte/index.js +25 -11
  239. package/dist/svelte/runtime.d.ts +10 -3
  240. package/dist/svelte/runtime.js +4 -3
  241. package/dist/svelte/source.d.ts +6 -6
  242. package/dist/svelte/source.js +4 -4
  243. package/dist/{validity-uOp8UpYn.js → tenancy-DshjqY0n.js} +3 -39
  244. package/dist/terminal/index.d.ts +5 -5
  245. package/dist/terminal/index.js +18 -34
  246. package/dist/testing/index.d.ts +89 -77
  247. package/dist/testing/index.js +1276 -1262
  248. package/dist/testing/saas/index.d.ts +4 -4
  249. package/dist/testing/saas/index.js +2 -2
  250. package/dist/testing/saas/permissions.d.ts +1 -1
  251. package/dist/testing/saas/permissions.js +1 -1
  252. package/dist/thenable-QSmvt-vZ.js +65 -0
  253. package/dist/{token-CIWxJOCh.js → token-Bx9qy30p.js} +1 -1
  254. package/dist/tool-refusal-CQ7OEia9.js +41 -0
  255. package/dist/trpc/index.d.ts +5 -5
  256. package/dist/trpc/index.js +7 -8
  257. package/dist/{types-DbjRN55U.d.ts → types-7rJVLWe5.d.ts} +82 -4
  258. package/dist/{types-aqOHTHcp.d.ts → types-Br9IXUBG.d.ts} +1 -1
  259. package/dist/types-ByUo56un.d.ts +88 -0
  260. package/dist/{types-Cq_H8N_X.d.ts → types-C0dee0Qf.d.ts} +2 -2
  261. package/dist/{types-DxiCGmmd.d.ts → types-CIlTojhq.d.ts} +2 -2
  262. package/dist/{types-QCuYJh4q.d.ts → types-CUcFZfpU.d.ts} +1 -1
  263. package/dist/{types-C97IskBw.d.ts → types-CqrjB9o6.d.ts} +1 -1
  264. package/dist/{types-BnIEz1sU.d.ts → types-DHrmBJLH.d.ts} +24 -6
  265. package/dist/{types-Dnemwd77.d.ts → types-DpWfQdSh.d.ts} +5 -1
  266. package/dist/{types-Bvc4oWT6.d.ts → types-DvupZE0w.d.ts} +1 -1
  267. package/dist/unplugin/index.d.ts +1 -1
  268. package/dist/unplugin/index.js +1 -1
  269. package/dist/{usage-B0YuTQRO.js → usage-4G6t643F.js} +2 -2
  270. package/dist/{usage-ItS7nLcl.js → usage-CG9nOYZw.js} +7 -7
  271. package/dist/usage-iFLJ0-rr.js +2 -0
  272. package/dist/{validation-error-Ba264OaJ.d.ts → validation-error-BSSw0l_8.d.ts} +1 -1
  273. package/dist/{validation-error-CnjZ4t92.js → validation-error-ZfUHbKvf.js} +1 -1
  274. package/dist/validity-dVrUEPJt.js +62 -0
  275. package/dist/{verifier-BxBo6I44.js → verifier-DMr_Zmb_.js} +51 -15
  276. package/dist/{rls-verify-CMv9H3wV.js → verify-BztUB3GX.js} +668 -239
  277. package/dist/{version-BvacVTZR.js → version-BEogC-rB.js} +1 -1
  278. package/dist/{views-Soe7bGSC.js → views-CJsrBS1f.js} +23 -1
  279. package/dist/{vocabulary-DA8a8zif.d.ts → vocabulary-hhEFLFoL.d.ts} +15 -6
  280. package/dist/vue/index.d.ts +24 -19
  281. package/dist/vue/index.js +24 -8
  282. package/dist/watch-C8TpsAl4.js +2 -0
  283. package/dist/{watch-DVBJ9cBq.js → watch-zeucB7eF.js} +6 -6
  284. package/dist/webmcp/index.d.ts +2 -2
  285. package/dist/webmcp/index.js +13 -37
  286. package/dist/wrap-Cr93qqdP.d.ts +14 -0
  287. package/dist/wrap-DWsU_5Bd.js +26 -0
  288. package/package.json +8 -8
  289. package/schemas/catalog-v1.json +6 -0
  290. package/skills/permdock-credentials/SKILL.md +1 -1
  291. package/skills/permdock-credentials/references/tokens-keys-links.md +7 -2
  292. package/skills/permdock-data/references/queries-and-rls.md +4 -0
  293. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +1 -0
  294. package/skills/permdock-wire/SKILL.md +2 -2
  295. package/skills/permdock-wire/references/adapters.md +9 -1
  296. package/skills/permdock-wire/references/policy-options.md +10 -1
  297. package/dist/catalog-CRW5Mx_B.js +0 -2
  298. package/dist/collect-DSWOk19R.js +0 -2
  299. package/dist/create-CMwIl-w2.js +0 -253
  300. package/dist/delegation-D8pUEuce.js +0 -103
  301. package/dist/doctor-DvH0IQff.js +0 -1194
  302. package/dist/doctor-collect-CjdO0wQX.js +0 -665
  303. package/dist/evaluation-items-CfCCejQd.js +0 -40
  304. package/dist/fields-BMl1RxoX.js +0 -26
  305. package/dist/grantee-Cv5Sogfv.js +0 -602
  306. package/dist/hosted-DJQw46hn.js +0 -266
  307. package/dist/instance-options-Dhhcnm3y.js +0 -22
  308. package/dist/load-DwJUafYN.js +0 -2
  309. package/dist/map-AcxK9o_D.js +0 -147
  310. package/dist/permissions-DVoF6dMt.js +0 -662
  311. package/dist/powersync-CrBX8hY6.js +0 -2
  312. package/dist/protected-xAr24FEC.d.ts +0 -40
  313. package/dist/relations-cjOL01hZ.js +0 -505
  314. package/dist/rls-graph-CHwx0V8q.js +0 -435
  315. package/dist/rls-shared-Cewd_-zI.js +0 -495
  316. package/dist/store-jOBYpiXC.d.ts +0 -36
  317. package/dist/stores-C0IMQrGI.d.ts +0 -52
  318. package/dist/supabase-config-Bj3iDH2I.js +0 -472
  319. package/dist/supabase-hook-gd3s8bxB.js +0 -2
  320. package/dist/thenable-okc2xDsj.js +0 -10
  321. package/dist/types-CKNSyIf_.d.ts +0 -52
  322. package/dist/usage-DorAJiU_.js +0 -2
  323. package/dist/watch-BwxLTYMZ.js +0 -2
package/dist/mcp/index.js CHANGED
@@ -1,83 +1,28 @@
1
- import { t as compact } from "../compact-y6vfu2_f.js";
1
+ import { r as isRecord, t as compact } from "../compact-CAf557ZB.js";
2
2
  import { n as freezeDeep } from "../freeze-CrU8nQeX.js";
3
- import { t as annotationsFor } from "../permissions-DVoF6dMt.js";
4
- import { a as wireDenials, i as stepUpOf } from "../problem-details-_AMOYz-w.js";
5
- import { t as describe } from "../describe-B_gVZEVi.js";
6
- import { i as scopesReaching, r as challengeScope } from "../permdock-CbgvLnuo.js";
3
+ import { i as stepUpOf } from "../problem-details-DECUnXAn.js";
4
+ import { t as describe } from "../describe-Cgkp7eP0.js";
5
+ import { m as annotationsFor } from "../permission-registry-BsblpB-z.js";
6
+ import { a as scopesReaching, i as hasScope, r as challengeScope } from "../permdock-L26udHSk.js";
7
7
  import { n as resourceRef } from "../resource-ref-CaS9yVPi.js";
8
8
  import { t as anonymousSubject } from "../subject-C6dLxqHU.js";
9
- import { t as mayUse } from "../may-use-DndQ5tQ-.js";
10
- import { c as protectedResourceMetadataUrl, n as bearerChallenge } from "../problem-B43ztKIm.js";
9
+ import { t as composeWraps } from "../wrap-DWsU_5Bd.js";
10
+ import { t as mayUse } from "../may-use-BOn_dR_w.js";
11
+ import { l as protectedResourceMetadataUrl, r as bearerChallenge } from "../problem-CnWraVhC.js";
11
12
  import { t as clientNameOf } from "../clients-DjU5ABMy.js";
12
- import { n as mapClaimsToSubject } from "../map-claims-Z4QZOiFF.js";
13
- import { t as instanceOptions } from "../instance-options-Dhhcnm3y.js";
14
- import { n as createAgentKernel } from "../kernel-_RRHmnMY.js";
13
+ import { n as mapClaimsToSubject } from "../map-claims-AVlBaJoa.js";
14
+ import { r as instanceOptions } from "../build-instance-DIIV9DbC.js";
15
+ import { n as createAgentKernel, r as deniedText } from "../kernel-CB3LrIJM.js";
15
16
  import { t as boundedMap } from "../lru-8q4WZjBV.js";
16
- //#region src/mcp/subject.ts
17
- const DEFAULT_MCP_ACTOR_KIND = "mcp-client";
18
- /** `kind`, or the default when absent; `undefined` for a kind that is not a non-empty string. */
19
- function mcpActorKind(kind) {
20
- if (kind === void 0) return DEFAULT_MCP_ACTOR_KIND;
21
- return typeof kind === "string" && kind !== "" ? kind : void 0;
22
- }
23
- function isRecord$1(value) {
24
- return value !== null && typeof value === "object" && !Array.isArray(value);
25
- }
26
- /**
27
- * Maps the `AuthInfo` the MCP SDK's bearer verification produced to a
28
- * `Subject`: the principal from the verified claims in `extra`, the client
29
- * as an actor of kind `actorKind` (`mcp-client` by default), the granted
30
- * scopes as the delegation. Never verifies and never throws; anything
31
- * unusable, including an `actorKind` that is not a non-empty string, is
32
- * the anonymous subject.
33
- */
34
- function subjectFromMcp(authInfo, options = {}) {
35
- try {
36
- const kind = mcpActorKind(options.actorKind);
37
- if (authInfo === void 0 || !isRecord$1(authInfo.extra) || kind === void 0) return anonymousSubject();
38
- const claims = compact({
39
- ...authInfo.extra,
40
- authorization_details: authInfo.extra["authorizationDetails"] ?? authInfo.extra["authorization_details"],
41
- scope: authInfo.scopes?.join(" "),
42
- client_id: authInfo.clientId,
43
- exp: authInfo.expiresAt
44
- });
45
- const mapped = mapClaimsToSubject(claims, options);
46
- if (mapped.invalidClaims || mapped.invalidChain || mapped.subject.principal === null) return anonymousSubject();
47
- const clientId = authInfo.clientId;
48
- return freezeDeep(compact({
49
- ...mapped.subject,
50
- actor: typeof clientId === "string" && clientId !== "" ? compact({
51
- id: clientId,
52
- kind,
53
- client: clientNameOf(options.clients, clientId)
54
- }) : mapped.subject.actor
55
- }));
56
- } catch {
57
- return anonymousSubject();
58
- }
59
- }
60
- //#endregion
61
- //#region src/mcp/create.ts
17
+ import { t as delegationFrom } from "../delegation-input-FTxMK3ji.js";
18
+ import { n as deniedToolRefusal, r as toolErrorResult, t as approvalToolRefusal } from "../tool-refusal-CQ7OEia9.js";
19
+ //#region src/mcp/mcp-auth.ts
62
20
  /** `_meta` key on `tools/call`, `resources/read` and `prompts/get` carrying an approval token. */
63
21
  const APPROVAL_META_KEY = "dev.permdock/approval";
64
- const SESSIONS_PER_SERVER = 1e3;
65
22
  const CLIENT_CAPABILITIES = "io.modelcontextprotocol/clientCapabilities";
66
23
  const PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion";
67
24
  /** The first protocol revision whose list results define `ttlMs` and `cacheScope`. */
68
25
  const CACHEABLE_LISTS_SINCE = "2026-07-28";
69
- /** What a completion re-check still accepts after the handler ran. */
70
- function stillAllowed(decision, approved) {
71
- switch (decision.outcome) {
72
- case "granted": return true;
73
- case "approval-required": return approved !== void 0 && decision.token === approved;
74
- case "denied": return decision.denials.length > 0 && decision.denials.every((denial) => denial.reason === "limit");
75
- default: return decision;
76
- }
77
- }
78
- function isRecord(value) {
79
- return value !== null && typeof value === "object" && !Array.isArray(value);
80
- }
81
26
  function contextOf(value) {
82
27
  return isRecord(value) ? value : {};
83
28
  }
@@ -94,19 +39,6 @@ function approvalTokenOf(context) {
94
39
  const fromAuth = context.http?.authInfo?.extra?.["approval"];
95
40
  return typeof fromAuth === "string" && fromAuth !== "" ? fromAuth : void 0;
96
41
  }
97
- function authorizationDetailsOf(authInfo) {
98
- const details = authInfo.extra?.["authorizationDetails"] ?? authInfo.extra?.["authorization_details"];
99
- return Array.isArray(details) ? details : void 0;
100
- }
101
- function delegationOf(authInfo) {
102
- return compact({
103
- scopes: authInfo.scopes,
104
- authorizationDetails: authorizationDetailsOf(authInfo)
105
- });
106
- }
107
- function hasScope(authInfo, scopes) {
108
- return scopes.some((scope) => (authInfo.scopes ?? []).includes(scope));
109
- }
110
42
  function resourceMetadataOf(authInfo) {
111
43
  if (authInfo.resourceMetadataUrl !== void 0) return authInfo.resourceMetadataUrl;
112
44
  const resource = authInfo.resource;
@@ -129,6 +61,41 @@ function definesCacheScope(context) {
129
61
  const version = context.mcpReq?.envelope?.[PROTOCOL_VERSION];
130
62
  return typeof version === "string" && version >= CACHEABLE_LISTS_SINCE;
131
63
  }
64
+ function tenantOf(tenant) {
65
+ if (typeof tenant !== "function") return tenant;
66
+ return (call) => tenant(call.authInfo ?? {});
67
+ }
68
+ function sessionKey(context) {
69
+ return context.sessionId ?? "";
70
+ }
71
+ function declaredScopes(name, value) {
72
+ if (value === void 0) return;
73
+ const scopes = Array.isArray(value) ? value : [];
74
+ const names = scopes.filter((scope) => typeof scope === "string" && scope !== "");
75
+ const [first, ...rest] = names;
76
+ if (first === void 0 || names.length !== scopes.length) throw new TypeError(`permdock/mcp: tool ${name} sets oauthScopes, which must be a non-empty list of scope names.`);
77
+ return Object.freeze([first, ...rest]);
78
+ }
79
+ function challengeFor(own, reaching, challenged) {
80
+ return async (context) => {
81
+ const first = await own?.(context);
82
+ if (first !== void 0) return first;
83
+ const authInfo = context.authInfo;
84
+ if (authInfo === void 0 || hasScope(authInfo.scopes, reaching)) return;
85
+ return { scopes: [challenged] };
86
+ };
87
+ }
88
+ //#endregion
89
+ //#region src/mcp/refusals.ts
90
+ /** What a completion re-check still accepts after the handler ran. */
91
+ function stillAllowed(decision, approved) {
92
+ switch (decision.outcome) {
93
+ case "granted": return true;
94
+ case "approval-required": return approved !== void 0 && decision.token === approved;
95
+ case "denied": return decision.denials.length > 0 && decision.denials.every((denial) => denial.reason === "limit");
96
+ default: return decision;
97
+ }
98
+ }
132
99
  function acceptsUrlElicitation(context, fallback) {
133
100
  const fromEnvelope = context.mcpReq?.envelope?.[CLIENT_CAPABILITIES];
134
101
  const capabilities = isRecord(fromEnvelope) ? fromEnvelope : fallback?.();
@@ -160,30 +127,10 @@ function urlElicitation(key, message, url, requestState) {
160
127
  });
161
128
  }
162
129
  function deniedRefusal(decision, permission, data) {
163
- const alternatives = decision.alternatives.map((leaf) => leaf.key);
164
- const resource = resourceRef(permission, data);
165
- return {
166
- text: `Denied: ${resource.id === void 0 ? permission.key : `${permission.key} on ${resource.id}`}.${alternatives.length === 0 ? "" : ` You may: ${alternatives.join(", ")}.`}`,
167
- structured: {
168
- outcome: "denied",
169
- permission: permission.key,
170
- resource,
171
- denials: wireDenials(decision.denials),
172
- alternatives,
173
- detail: describe(decision).detail
174
- }
175
- };
130
+ return deniedToolRefusal(decision, permission, resourceRef(permission, data));
176
131
  }
177
132
  function approvalRefusal(decision, permission, data) {
178
- return {
179
- text: describe(decision).detail,
180
- structured: {
181
- outcome: "approval-required",
182
- permission: permission.key,
183
- resource: resourceRef(permission, data),
184
- token: decision.token
185
- }
186
- };
133
+ return approvalToolRefusal(decision, permission, resourceRef(permission, data));
187
134
  }
188
135
  function plainRefusal(permission, text, extra) {
189
136
  return {
@@ -197,10 +144,6 @@ function plainRefusal(permission, text, extra) {
197
144
  }
198
145
  };
199
146
  }
200
- function tenantOf(tenant) {
201
- if (typeof tenant !== "function") return tenant;
202
- return (call) => tenant(call.authInfo ?? {});
203
- }
204
147
  function failedRefusal(permission, failure) {
205
148
  switch (failure) {
206
149
  case "load-failed": return plainRefusal(permission, `Denied: ${permission.key} failed closed.`, { denials: [{
@@ -216,388 +159,455 @@ function failedRefusal(permission, failure) {
216
159
  }
217
160
  }
218
161
  function toolRefusal(refusal) {
219
- if (refusal.inputRequired !== void 0) return refusal.inputRequired;
220
- return {
221
- isError: true,
222
- content: [{
223
- type: "text",
224
- text: refusal.text
225
- }],
226
- structuredContent: refusal.structured
227
- };
228
- }
229
- function requirePermission(kind, name, config) {
230
- const permission = isRecord(config) ? config["permission"] : void 0;
231
- if (!isRecord(permission) || typeof permission["key"] !== "string") throw new TypeError(`permdock/mcp: ${kind} ${name} has no permission; every guarded registration needs one.`);
232
- return permission;
233
- }
234
- function sessionKey(context) {
235
- return context.sessionId ?? "";
162
+ return refusal.inputRequired ?? toolErrorResult(refusal);
236
163
  }
237
164
  function throwRefusal(refusal) {
238
165
  if (refusal.inputRequired !== void 0) return refusal.inputRequired;
239
166
  throw new Error(refusal.text);
240
167
  }
241
- function declaredScopes(name, value) {
242
- if (value === void 0) return;
243
- const scopes = Array.isArray(value) ? value : [];
244
- const names = scopes.filter((scope) => typeof scope === "string" && scope !== "");
245
- const [first, ...rest] = names;
246
- if (first === void 0 || names.length !== scopes.length) throw new TypeError(`permdock/mcp: tool ${name} sets oauthScopes, which must be a non-empty list of scope names.`);
247
- return Object.freeze([first, ...rest]);
168
+ /** The MRTR URL elicitation that sends the user to `options.approval.at`, when the client accepts one. */
169
+ async function approvalInput(options, decision, handlerContext, context, capabilities) {
170
+ const at = options.approval?.at;
171
+ if (at === void 0 || !acceptsUrlElicitation(context, capabilities)) return;
172
+ const url = withParams(at, { token: decision.token });
173
+ if (url === void 0) return;
174
+ const requestState = options.requestState === void 0 ? decision.token : await options.requestState.mint(decision.token, handlerContext);
175
+ return urlElicitation("approval", options.approval?.hint ?? describe(decision).detail, url, requestState);
248
176
  }
249
- function challengeFor(own, reaching, challenged) {
250
- return async (context) => {
251
- const first = await own?.(context);
252
- if (first !== void 0) return first;
253
- const authInfo = context.authInfo;
254
- if (authInfo === void 0 || hasScope(authInfo, reaching)) return;
255
- return { scopes: [challenged] };
256
- };
257
- }
258
- function guardUpdates(registered, wrap, rename, currentName) {
259
- const update = registered.update.bind(registered);
260
- registered.update = (updates) => {
261
- const next = { ...updates };
262
- if (typeof updates["callback"] === "function") next["callback"] = wrap(updates["callback"]);
263
- if (rename !== void 0 && currentName !== void 0) {
264
- const to = updates["name"];
265
- if (typeof to === "string" || to === null) rename(currentName(), to);
266
- }
267
- update(next);
268
- };
177
+ /** A step-up denial: the RFC 9470 challenge, and a URL elicitation to `stepUpAt` when the client accepts one. */
178
+ function stepUpRefusal(stepUpAt, decision, permission, data, context, capabilities) {
179
+ const base = deniedRefusal(decision, permission, data);
180
+ const { acrValues, maxAge } = stepUpOf(decision);
181
+ const url = stepUpAt === void 0 || !acceptsUrlElicitation(context, capabilities) ? void 0 : withParams(stepUpAt, {
182
+ acr_values: acrValues?.join(" "),
183
+ max_age: maxAge === void 0 ? void 0 : String(maxAge)
184
+ });
185
+ return compact({
186
+ text: base.text,
187
+ structured: compact({
188
+ ...base.structured,
189
+ error: "insufficient_user_authentication",
190
+ acr_values: acrValues?.join(" "),
191
+ max_age: maxAge,
192
+ www_authenticate: bearerChallenge(compact({
193
+ error: "insufficient_user_authentication",
194
+ acrValues,
195
+ maxAge
196
+ }))
197
+ }),
198
+ inputRequired: url === void 0 ? void 0 : urlElicitation("step_up", `Sign in again to use ${permission.key}.`, url, void 0)
199
+ });
269
200
  }
270
- function createPermDock(policy, options) {
271
- const actorKind = mcpActorKind(options.actorKind);
272
- if (actorKind === void 0) throw new TypeError("permdock/mcp: actorKind must be a non-empty string");
273
- const kernel = createAgentKernel(policy, compact({
274
- subject: (call) => options.subject(call.authInfo ?? {}),
275
- actor: (call) => {
276
- const clientId = call.authInfo?.clientId;
277
- return typeof clientId === "string" && clientId !== "" ? compact({
278
- id: clientId,
279
- kind: actorKind,
280
- client: clientNameOf(options.clients, clientId)
281
- }) : void 0;
282
- },
283
- delegation: (call) => call.authInfo === void 0 ? void 0 : delegationOf(call.authInfo),
284
- tenant: tenantOf(options.tenant),
285
- store: options.store,
286
- adapter: "mcp",
287
- boundary: "mcp-args",
288
- wrap: options.otel,
289
- ...instanceOptions(options)
290
- }));
291
- const forThisServer = (authInfo) => options.resource === void 0 || sameResource(options.resource, authInfo.resource);
292
- const reachOf = (permission, declared) => declared === void 0 ? {
201
+ //#endregion
202
+ //#region src/mcp/call-check.ts
203
+ function reachOf(policy, permission, declared) {
204
+ return declared === void 0 ? {
293
205
  scopes: scopesReaching(policy, permission),
294
206
  challenge: challengeScope(policy, permission)
295
207
  } : {
296
208
  scopes: declared,
297
209
  challenge: declared[0]
298
210
  };
299
- const reachable = (authInfo, reach) => authInfo === void 0 ? options.requireAuthInfo !== true : forThisServer(authInfo) && hasScope(authInfo, reach.scopes);
300
- const approvalInput = async (decision, handlerContext, context, capabilities) => {
301
- const at = options.approval?.at;
302
- if (at === void 0 || !acceptsUrlElicitation(context, capabilities)) return;
303
- const url = withParams(at, { token: decision.token });
304
- if (url === void 0) return;
305
- const requestState = options.requestState === void 0 ? decision.token : await options.requestState.mint(decision.token, handlerContext);
306
- return urlElicitation("approval", options.approval?.hint ?? describe(decision).detail, url, requestState);
211
+ }
212
+ function forThisServer(checks, authInfo) {
213
+ return checks.options.resource === void 0 || sameResource(checks.options.resource, authInfo.resource);
214
+ }
215
+ function reachable(checks, authInfo, reach) {
216
+ return authInfo === void 0 ? checks.options.requireAuthInfo !== true : forThisServer(checks, authInfo) && hasScope(authInfo.scopes, reach.scopes);
217
+ }
218
+ /** The refusal a token earns before any decision: none, the wrong resource, or a missing scope. */
219
+ function credentialRefusal(checks, permission, reach, authInfo) {
220
+ if (authInfo === void 0) return checks.options.requireAuthInfo === true ? plainRefusal(permission, "Denied: no verified credentials.", { error: "invalid_token" }) : void 0;
221
+ if (!forThisServer(checks, authInfo)) return plainRefusal(permission, "Denied: the token was not issued for this server.", { error: "invalid_token" });
222
+ if (hasScope(authInfo.scopes, reach.scopes)) return;
223
+ const resourceMetadata = resourceMetadataOf(authInfo);
224
+ const challenged = reach.challenge;
225
+ return plainRefusal(permission, `Denied: ${permission.key} needs the ${challenged} scope.`, compact({
226
+ error: "insufficient_scope",
227
+ scope: challenged,
228
+ resource_metadata: resourceMetadata,
229
+ www_authenticate: bearerChallenge(compact({
230
+ error: "insufficient_scope",
231
+ scopes: [challenged],
232
+ resourceMetadata
233
+ }))
234
+ }));
235
+ }
236
+ /** The completion re-check of a long-running tool: the call must still be allowed, or approved with the same token. */
237
+ async function recheck(checks, binding, call, permission, approved) {
238
+ const rechecked = await checks.kernel.check(binding, void 0, call, { simulate: true });
239
+ if (!rechecked.ok) return {
240
+ ok: false,
241
+ refusal: failedRefusal(permission, rechecked.failure)
307
242
  };
308
- const stepUpRefusal = (decision, permission, data, context, capabilities) => {
309
- const base = deniedRefusal(decision, permission, data);
310
- const { acrValues, maxAge } = stepUpOf(decision);
311
- const at = options.stepUp?.at;
312
- const url = at === void 0 || !acceptsUrlElicitation(context, capabilities) ? void 0 : withParams(at, {
313
- acr_values: acrValues?.join(" "),
314
- max_age: maxAge === void 0 ? void 0 : String(maxAge)
315
- });
316
- return compact({
317
- text: base.text,
318
- structured: compact({
319
- ...base.structured,
320
- error: "insufficient_user_authentication",
321
- acr_values: acrValues?.join(" "),
322
- max_age: maxAge,
323
- www_authenticate: bearerChallenge(compact({
324
- error: "insufficient_user_authentication",
325
- acrValues,
326
- maxAge
327
- }))
328
- }),
329
- inputRequired: url === void 0 ? void 0 : urlElicitation("step_up", `Sign in again to use ${permission.key}.`, url, void 0)
330
- });
243
+ if (stillAllowed(rechecked.raw, approved)) return { ok: true };
244
+ return {
245
+ ok: false,
246
+ refusal: rechecked.raw.outcome === "denied" ? {
247
+ ...deniedRefusal(rechecked.raw, permission, rechecked.data),
248
+ decision: rechecked.raw,
249
+ permdock: rechecked.permdock
250
+ } : plainRefusal(permission, `Denied: ${permission.key} was revoked before the call completed.`, {})
331
251
  };
332
- const check = async (permission, reach, load, context, handlerContext, capabilities, completion) => {
333
- const authInfo = context.http?.authInfo;
334
- if (authInfo === void 0 && options.requireAuthInfo === true) return {
335
- ok: false,
336
- refusal: plainRefusal(permission, "Denied: no verified credentials.", { error: "invalid_token" })
337
- };
338
- if (authInfo !== void 0 && !forThisServer(authInfo)) return {
252
+ }
253
+ async function decideCall(checks, permission, reach, load, context, handlerContext, capabilities, completion) {
254
+ const authInfo = context.http?.authInfo;
255
+ const refused = credentialRefusal(checks, permission, reach, authInfo);
256
+ if (refused !== void 0) return {
257
+ ok: false,
258
+ refusal: refused
259
+ };
260
+ const binding = compact({
261
+ permission,
262
+ data: load === void 0 ? void 0 : () => load()
263
+ });
264
+ const call = compact({ authInfo });
265
+ if (completion !== void 0) return recheck(checks, binding, call, permission, completion.approved);
266
+ const checked = await checks.kernel.check(binding, void 0, call, compact({ resumeToken: approvalTokenOf(context) }));
267
+ if (!checked.ok) return {
268
+ ok: false,
269
+ refusal: failedRefusal(permission, checked.failure)
270
+ };
271
+ const { raw, decision, data } = checked;
272
+ switch (decision.outcome) {
273
+ case "granted": return raw.outcome === "approval-required" ? {
274
+ ok: true,
275
+ approved: raw.token
276
+ } : { ok: true };
277
+ case "denied": return {
339
278
  ok: false,
340
- refusal: plainRefusal(permission, "Denied: the token was not issued for this server.", { error: "invalid_token" })
279
+ refusal: {
280
+ ...decision.denials.some((denial) => denial.reason === "insufficient-user-authentication") ? stepUpRefusal(checks.options.stepUp?.at, decision, permission, data, context, capabilities) : deniedRefusal(decision, permission, data),
281
+ decision,
282
+ permdock: checked.permdock
283
+ }
341
284
  };
342
- if (authInfo !== void 0 && !hasScope(authInfo, reach.scopes)) {
343
- const resourceMetadata = resourceMetadataOf(authInfo);
344
- const challenged = reach.challenge;
285
+ case "approval-required": try {
345
286
  return {
346
287
  ok: false,
347
- refusal: plainRefusal(permission, `Denied: ${permission.key} needs the ${challenged} scope.`, compact({
348
- error: "insufficient_scope",
349
- scope: challenged,
350
- resource_metadata: resourceMetadata,
351
- www_authenticate: bearerChallenge(compact({
352
- error: "insufficient_scope",
353
- scopes: [challenged],
354
- resourceMetadata
355
- }))
356
- }))
357
- };
358
- }
359
- const binding = compact({
360
- permission,
361
- data: load === void 0 ? void 0 : () => load()
362
- });
363
- const call = compact({ authInfo });
364
- if (completion !== void 0) {
365
- const rechecked = await kernel.check(binding, void 0, call, { simulate: true });
366
- if (!rechecked.ok) return {
367
- ok: false,
368
- refusal: failedRefusal(permission, rechecked.failure)
288
+ refusal: compact({
289
+ ...approvalRefusal(decision, permission, data),
290
+ decision,
291
+ permdock: checked.permdock,
292
+ inputRequired: await approvalInput(checks.options, decision, handlerContext, context, capabilities)
293
+ })
369
294
  };
370
- if (stillAllowed(rechecked.raw, completion.approved)) return { ok: true };
295
+ } catch {
371
296
  return {
372
297
  ok: false,
373
- refusal: rechecked.raw.outcome === "denied" ? deniedRefusal(rechecked.raw, permission, rechecked.data) : plainRefusal(permission, `Denied: ${permission.key} was revoked before the call completed.`, {})
298
+ refusal: failedRefusal(permission, "failed")
374
299
  };
375
300
  }
376
- const checked = await kernel.check(binding, void 0, call, compact({ resumeToken: approvalTokenOf(context) }));
377
- if (!checked.ok) return {
378
- ok: false,
379
- refusal: failedRefusal(permission, checked.failure)
380
- };
381
- const { raw, decision, data } = checked;
382
- switch (decision.outcome) {
383
- case "granted": return raw.outcome === "approval-required" ? {
384
- ok: true,
385
- approved: raw.token
386
- } : { ok: true };
387
- case "denied": return {
388
- ok: false,
389
- refusal: decision.denials.some((denial) => denial.reason === "insufficient-user-authentication") ? stepUpRefusal(decision, permission, data, context, capabilities) : deniedRefusal(decision, permission, data)
390
- };
391
- case "approval-required": try {
392
- return {
393
- ok: false,
394
- refusal: compact({
395
- ...approvalRefusal(decision, permission, data),
396
- inputRequired: await approvalInput(decision, handlerContext, context, capabilities)
397
- })
398
- };
399
- } catch {
400
- return {
401
- ok: false,
402
- refusal: failedRefusal(permission, "failed")
403
- };
404
- }
405
- default: return decision;
301
+ default: return decision;
302
+ }
303
+ }
304
+ /** `decideCall` with the refusal text replaced by `onDenied`'s. */
305
+ async function checkCall(checks, permission, reach, load, context, handlerContext, capabilities, completion) {
306
+ const checked = await decideCall(checks, permission, reach, load, context, handlerContext, capabilities, completion);
307
+ const { onDenied } = checks.options;
308
+ if (checked.ok || onDenied === void 0) return checked;
309
+ const { refusal } = checked;
310
+ return {
311
+ ok: false,
312
+ refusal: {
313
+ ...refusal,
314
+ text: deniedText(onDenied, {
315
+ decision: refusal.decision ?? null,
316
+ permission,
317
+ text: refusal.text
318
+ }, (error) => {
319
+ checks.kernel.report(refusal.permdock, error);
320
+ })
406
321
  }
407
322
  };
408
- const visible = async (context, permissionOf, keys, declaredOf = () => void 0) => {
409
- const authInfo = context.http?.authInfo;
410
- const shown = /* @__PURE__ */ new Set();
411
- const guarded = [];
412
- for (const key of keys) {
413
- const permission = permissionOf(key);
414
- if (permission === void 0) shown.add(key);
415
- else if (reachable(authInfo, reachOf(permission, declaredOf(key)))) guarded.push({
416
- key,
417
- permission
418
- });
419
- }
420
- if (guarded.length === 0) return shown;
421
- let permdock;
422
- try {
423
- permdock = await kernel.instance(compact({ authInfo }));
424
- } catch {
425
- return shown;
426
- }
427
- for (const entry of guarded) if (mayUse(permdock, entry.permission)) shown.add(entry.key);
323
+ }
324
+ /** The keys a list shows: unguarded ones, and guarded ones the token reaches and the subject may use. */
325
+ async function visible(checks, context, permissionOf, keys, declaredOf = () => void 0) {
326
+ const authInfo = context.http?.authInfo;
327
+ const shown = /* @__PURE__ */ new Set();
328
+ const guarded = [];
329
+ for (const key of keys) {
330
+ const permission = permissionOf(key);
331
+ if (permission === void 0) shown.add(key);
332
+ else if (reachable(checks, authInfo, reachOf(checks.policy, permission, declaredOf(key)))) guarded.push({
333
+ key,
334
+ permission
335
+ });
336
+ }
337
+ if (guarded.length === 0) return shown;
338
+ let permdock;
339
+ try {
340
+ permdock = await checks.kernel.instance(compact({ authInfo }));
341
+ } catch {
428
342
  return shown;
429
- };
430
- const guard = (permission, load, handler, dataArgs, onRefusal, extra = {}) => async (...params) => {
343
+ }
344
+ for (const entry of guarded) if (mayUse(permdock, entry.permission)) shown.add(entry.key);
345
+ return shown;
346
+ }
347
+ /** `handler` behind the call check; a refusal goes to `onRefusal` instead. */
348
+ function guard(checks, permission, load, handler, dataArgs, onRefusal, extra = {}) {
349
+ return async (...params) => {
431
350
  const raw = params.at(-1);
432
351
  const context = contextOf(raw);
433
352
  const loader = load === void 0 ? void 0 : () => load(...dataArgs(params));
434
- const reach = extra.reach ?? reachOf(permission, void 0);
435
- const checked = await check(permission, reach, loader, context, raw, extra.capabilities);
353
+ const reach = extra.reach ?? reachOf(checks.policy, permission, void 0);
354
+ const checked = await checkCall(checks, permission, reach, loader, context, raw, extra.capabilities);
436
355
  let result;
437
356
  if (checked.ok) {
438
357
  result = await handler(...params);
439
358
  if (extra.longRunning === true) {
440
- const again = await check(permission, reach, loader, context, raw, extra.capabilities, { approved: checked.approved });
359
+ const again = await checkCall(checks, permission, reach, loader, context, raw, extra.capabilities, { approved: checked.approved });
441
360
  if (!again.ok) result = onRefusal(again.refusal);
442
361
  }
443
362
  } else result = onRefusal(checked.refusal);
444
363
  await extra.after?.(context);
445
364
  return result;
446
365
  };
447
- const protectServer = (server, enforcement) => {
448
- const tools = /* @__PURE__ */ new Map();
449
- const toolScopes = /* @__PURE__ */ new Map();
450
- const prompts = /* @__PURE__ */ new Map();
451
- const resources = /* @__PURE__ */ new Map();
452
- const templates = [];
453
- const lastListed = boundedMap(SESSIONS_PER_SERVER);
454
- const toolPermission = (name) => tools.get(name);
455
- const toolDeclared = (name) => toolScopes.get(name);
456
- const promptPermission = (name) => prompts.get(name);
457
- const resourcePermission = (uri) => {
458
- const direct = resources.get(uri);
459
- if (direct !== void 0) return direct;
460
- return templates.find((entry) => entry.template.uriTemplate.match(uri) !== null)?.permission;
461
- };
462
- const templatePermission = (uriTemplate) => templates.find((entry) => entry.template.uriTemplate.toString() === uriTemplate)?.permission;
463
- const listFilter = (field, keyOf, permissionOf, remember) => async (result, rawContext) => {
464
- if (!isRecord(result) || !Array.isArray(result[field])) return result;
465
- const context = contextOf(rawContext);
466
- const entries = result[field];
467
- const shown = await visible(context, permissionOf, entries.map(keyOf), remember ? toolDeclared : void 0);
468
- const kept = entries.filter((entry) => shown.has(keyOf(entry)));
469
- if (remember) lastListed.set(sessionKey(context), [...shown].toSorted().join(","));
470
- return definesCacheScope(context) ? {
471
- ...result,
472
- [field]: kept,
473
- cacheScope: "private"
474
- } : {
475
- ...result,
476
- [field]: kept
477
- };
478
- };
479
- const filters = {
480
- "tools/list": listFilter("tools", (entry) => entry.name, toolPermission, true),
481
- "prompts/list": listFilter("prompts", (entry) => entry.name, promptPermission, false),
482
- "resources/list": listFilter("resources", (entry) => entry.uri, resourcePermission, false),
483
- "resources/templates/list": listFilter("resourceTemplates", (entry) => entry.uriTemplate, templatePermission, false)
484
- };
485
- const inner = server.server;
486
- const capabilities = () => inner.getClientCapabilities?.();
487
- const set = inner.setRequestHandler.bind(inner);
488
- inner.setRequestHandler = (method, ...rest) => {
489
- const filter = Object.hasOwn(filters, method) ? filters[method] : void 0;
490
- const [handler] = rest;
491
- if (filter !== void 0 && rest.length === 1 && typeof handler === "function") {
492
- set(method, async (request, context) => filter(await handler(request, context), context));
493
- return;
494
- }
495
- set(method, ...rest);
496
- };
497
- for (const method of Object.keys(filters)) {
498
- const existing = inner._getRequestHandler?.(method);
499
- if (existing !== void 0) {
500
- inner.removeRequestHandler(method);
501
- inner.setRequestHandler(method, (request, context) => existing(request, context));
502
- }
366
+ }
367
+ //#endregion
368
+ //#region src/mcp/protect-server.ts
369
+ const SESSIONS_PER_SERVER = 1e3;
370
+ function requirePermission(kind, name, config) {
371
+ const permission = isRecord(config) ? config["permission"] : void 0;
372
+ if (!isRecord(permission) || typeof permission["key"] !== "string") throw new TypeError(`permdock/mcp: ${kind} ${name} has no permission; every guarded registration needs one.`);
373
+ return permission;
374
+ }
375
+ function guardUpdates(registered, wrap, rename, currentName) {
376
+ const update = registered.update.bind(registered);
377
+ registered.update = (updates) => {
378
+ const next = { ...updates };
379
+ if (typeof updates["callback"] === "function") next["callback"] = wrap(updates["callback"]);
380
+ if (rename !== void 0 && currentName !== void 0) {
381
+ const to = updates["name"];
382
+ if (typeof to === "string" || to === null) rename(currentName(), to);
503
383
  }
504
- const announce = async (context) => {
505
- const key = sessionKey(context);
506
- const before = lastListed.get(key);
507
- if (before === void 0) return;
508
- const after = [...await visible(context, toolPermission, [...tools.keys()], toolDeclared)].toSorted().join(",");
509
- if (after === before) return;
510
- lastListed.set(key, after);
511
- try {
512
- await (context.mcpReq?.notify?.({ method: "notifications/tools/list_changed" }) ?? inner.sendToolListChanged?.());
513
- } catch {}
384
+ update(next);
385
+ };
386
+ }
387
+ function protectServer(checks, server, enforcement) {
388
+ const tools = /* @__PURE__ */ new Map();
389
+ const toolScopes = /* @__PURE__ */ new Map();
390
+ const prompts = /* @__PURE__ */ new Map();
391
+ const resources = /* @__PURE__ */ new Map();
392
+ const templates = [];
393
+ const lastListed = boundedMap(SESSIONS_PER_SERVER);
394
+ const toolPermission = (name) => tools.get(name);
395
+ const toolDeclared = (name) => toolScopes.get(name);
396
+ const promptPermission = (name) => prompts.get(name);
397
+ const resourcePermission = (uri) => {
398
+ const direct = resources.get(uri);
399
+ if (direct !== void 0) return direct;
400
+ return templates.find((entry) => entry.template.uriTemplate.match(uri) !== null)?.permission;
401
+ };
402
+ const templatePermission = (uriTemplate) => templates.find((entry) => entry.template.uriTemplate.toString() === uriTemplate)?.permission;
403
+ const listFilter = (field, keyOf, permissionOf, remember) => async (result, rawContext) => {
404
+ if (!isRecord(result) || !Array.isArray(result[field])) return result;
405
+ const context = contextOf(rawContext);
406
+ const entries = result[field];
407
+ const shown = await visible(checks, context, permissionOf, entries.map(keyOf), remember ? toolDeclared : void 0);
408
+ const kept = entries.filter((entry) => shown.has(keyOf(entry)));
409
+ if (remember) lastListed.set(sessionKey(context), [...shown].toSorted().join(","));
410
+ return definesCacheScope(context) ? {
411
+ ...result,
412
+ [field]: kept,
413
+ cacheScope: "private"
414
+ } : {
415
+ ...result,
416
+ [field]: kept
514
417
  };
515
- const guardTool = (permission, reach, load, handler, longRunning) => guard(permission, load, handler, (params) => params.length >= 2 ? [params[0]] : [void 0], toolRefusal, {
516
- after: announce,
517
- longRunning,
518
- capabilities,
519
- reach
418
+ };
419
+ const filters = {
420
+ "tools/list": listFilter("tools", (entry) => entry.name, toolPermission, true),
421
+ "prompts/list": listFilter("prompts", (entry) => entry.name, promptPermission, false),
422
+ "resources/list": listFilter("resources", (entry) => entry.uri, resourcePermission, false),
423
+ "resources/templates/list": listFilter("resourceTemplates", (entry) => entry.uriTemplate, templatePermission, false)
424
+ };
425
+ const inner = server.server;
426
+ const capabilities = () => inner.getClientCapabilities?.();
427
+ const set = inner.setRequestHandler.bind(inner);
428
+ inner.setRequestHandler = (method, ...rest) => {
429
+ const filter = Object.hasOwn(filters, method) ? filters[method] : void 0;
430
+ const [handler] = rest;
431
+ if (filter !== void 0 && rest.length === 1 && typeof handler === "function") {
432
+ set(method, async (request, context) => filter(await handler(request, context), context));
433
+ return;
434
+ }
435
+ set(method, ...rest);
436
+ };
437
+ for (const method of Object.keys(filters)) {
438
+ const existing = inner._getRequestHandler?.(method);
439
+ if (existing !== void 0) {
440
+ inner.removeRequestHandler(method);
441
+ inner.setRequestHandler(method, (request, context) => existing(request, context));
442
+ }
443
+ }
444
+ const announce = async (context) => {
445
+ const key = sessionKey(context);
446
+ const before = lastListed.get(key);
447
+ if (before === void 0) return;
448
+ const after = [...await visible(checks, context, toolPermission, [...tools.keys()], toolDeclared)].toSorted().join(",");
449
+ if (after === before) return;
450
+ lastListed.set(key, after);
451
+ try {
452
+ await (context.mcpReq?.notify?.({ method: "notifications/tools/list_changed" }) ?? inner.sendToolListChanged?.());
453
+ } catch {}
454
+ };
455
+ const guardTool = (permission, reach, load, handler, longRunning) => guard(checks, permission, load, handler, (params) => params.length >= 2 ? [params[0]] : [void 0], toolRefusal, {
456
+ after: announce,
457
+ longRunning,
458
+ capabilities,
459
+ reach
460
+ });
461
+ const originalTool = server.registerTool.bind(server);
462
+ const toolPermissionOf = (name, config) => {
463
+ if (enforcement === void 0 || config["permission"] !== void 0) return requirePermission("tool", name, config);
464
+ for (const field of ["data", "longRunning"]) if (config[field] !== void 0) throw new TypeError(`permdock/mcp: tool ${name} sets ${field}, but with enforce: 'procedure' its procedure decides.`);
465
+ return requirePermission("tool", name, { permission: enforcement.permissionFor(name) });
466
+ };
467
+ /** With `enforce: 'procedure'` the handler runs undecided: the procedure it calls decides. */
468
+ const wrapTool = (permission, reach, load, handler, longRunning) => enforcement === void 0 ? guardTool(permission, reach, load, handler, longRunning) : async (...params) => {
469
+ const result = await handler(...params);
470
+ await announce(contextOf(params.at(-1)));
471
+ return result;
472
+ };
473
+ const registerTool = (name, config, handler) => {
474
+ const permission = toolPermissionOf(name, config);
475
+ const { permission: _permission, data, scopeChallenge, longRunning: rawLongRunning, oauthScopes: rawScopes, ...passthrough } = config;
476
+ const load = data;
477
+ const longRunning = rawLongRunning === true;
478
+ const declared = declaredScopes(name, rawScopes === void 0 ? enforcement?.oauthScopesFor?.(name) : rawScopes);
479
+ const reach = reachOf(checks.policy, permission, declared);
480
+ const registered = originalTool(name, {
481
+ ...passthrough,
482
+ annotations: {
483
+ ...annotationsFor(permission),
484
+ ...passthrough["annotations"]
485
+ },
486
+ scopeChallenge: challengeFor(scopeChallenge, reach.scopes, reach.challenge)
487
+ }, wrapTool(permission, reach, load, handler, longRunning));
488
+ tools.set(name, permission);
489
+ if (declared !== void 0) toolScopes.set(name, declared);
490
+ let current = name;
491
+ guardUpdates(registered, (callback) => wrapTool(permission, reach, load, callback, longRunning), (from, to) => {
492
+ tools.delete(from);
493
+ toolScopes.delete(from);
494
+ if (to !== null) {
495
+ tools.set(to, permission);
496
+ if (declared !== void 0) toolScopes.set(to, declared);
497
+ current = to;
498
+ }
499
+ }, () => current);
500
+ return registered;
501
+ };
502
+ const originalPrompt = server.registerPrompt.bind(server);
503
+ const registerPrompt = (name, config, handler) => {
504
+ const permission = requirePermission("prompt", name, config);
505
+ const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
506
+ const load = data;
507
+ const wrap = (callback) => guard(checks, permission, load, callback, (params) => params.length >= 2 ? [params[0]] : [void 0], throwRefusal, { capabilities });
508
+ const registered = originalPrompt(name, {
509
+ ...passthrough,
510
+ scopeChallenge: challengeFor(scopeChallenge, scopesReaching(checks.policy, permission), challengeScope(checks.policy, permission))
511
+ }, wrap(handler));
512
+ prompts.set(name, permission);
513
+ guardUpdates(registered, wrap);
514
+ return registered;
515
+ };
516
+ const originalResource = server.registerResource.bind(server);
517
+ const registerResource = (name, uriOrTemplate, config, read) => {
518
+ const permission = requirePermission("resource", name, config);
519
+ const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
520
+ const load = data;
521
+ const wrap = (callback) => guard(checks, permission, load, callback, (params) => params.slice(0, -1), throwRefusal, { capabilities });
522
+ const registered = originalResource(name, uriOrTemplate, {
523
+ ...passthrough,
524
+ scopeChallenge: challengeFor(scopeChallenge, scopesReaching(checks.policy, permission), challengeScope(checks.policy, permission))
525
+ }, wrap(read));
526
+ if (typeof uriOrTemplate === "string") resources.set(uriOrTemplate, permission);
527
+ else templates.push({
528
+ template: uriOrTemplate,
529
+ permission
520
530
  });
521
- const originalTool = server.registerTool.bind(server);
522
- const toolPermissionOf = (name, config) => {
523
- if (enforcement === void 0 || config["permission"] !== void 0) return requirePermission("tool", name, config);
524
- for (const field of ["data", "longRunning"]) if (config[field] !== void 0) throw new TypeError(`permdock/mcp: tool ${name} sets ${field}, but with enforce: 'procedure' its procedure decides.`);
525
- return requirePermission("tool", name, { permission: enforcement.permissionFor(name) });
526
- };
527
- /** With `enforce: 'procedure'` the handler runs undecided: the procedure it calls decides. */
528
- const wrapTool = (permission, reach, load, handler, longRunning) => enforcement === void 0 ? guardTool(permission, reach, load, handler, longRunning) : async (...params) => {
529
- const result = await handler(...params);
530
- await announce(contextOf(params.at(-1)));
531
- return result;
532
- };
533
- const registerTool = (name, config, handler) => {
534
- const permission = toolPermissionOf(name, config);
535
- const { permission: _permission, data, scopeChallenge, longRunning: rawLongRunning, oauthScopes: rawScopes, ...passthrough } = config;
536
- const load = data;
537
- const longRunning = rawLongRunning === true;
538
- const declared = declaredScopes(name, rawScopes === void 0 ? enforcement?.oauthScopesFor?.(name) : rawScopes);
539
- const reach = reachOf(permission, declared);
540
- const registered = originalTool(name, {
541
- ...passthrough,
542
- annotations: {
543
- ...annotationsFor(permission),
544
- ...passthrough["annotations"]
545
- },
546
- scopeChallenge: challengeFor(scopeChallenge, reach.scopes, reach.challenge)
547
- }, wrapTool(permission, reach, load, handler, longRunning));
548
- tools.set(name, permission);
549
- if (declared !== void 0) toolScopes.set(name, declared);
550
- let current = name;
551
- guardUpdates(registered, (callback) => wrapTool(permission, reach, load, callback, longRunning), (from, to) => {
552
- tools.delete(from);
553
- toolScopes.delete(from);
554
- if (to !== null) {
555
- tools.set(to, permission);
556
- if (declared !== void 0) toolScopes.set(to, declared);
557
- current = to;
558
- }
559
- }, () => current);
560
- return registered;
561
- };
562
- const originalPrompt = server.registerPrompt.bind(server);
563
- const registerPrompt = (name, config, handler) => {
564
- const permission = requirePermission("prompt", name, config);
565
- const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
566
- const load = data;
567
- const wrap = (callback) => guard(permission, load, callback, (params) => params.length >= 2 ? [params[0]] : [void 0], throwRefusal, { capabilities });
568
- const registered = originalPrompt(name, {
569
- ...passthrough,
570
- scopeChallenge: challengeFor(scopeChallenge, scopesReaching(policy, permission), challengeScope(policy, permission))
571
- }, wrap(handler));
572
- prompts.set(name, permission);
573
- guardUpdates(registered, wrap);
574
- return registered;
575
- };
576
- const originalResource = server.registerResource.bind(server);
577
- const registerResource = (name, uriOrTemplate, config, read) => {
578
- const permission = requirePermission("resource", name, config);
579
- const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
580
- const load = data;
581
- const wrap = (callback) => guard(permission, load, callback, (params) => params.slice(0, -1), throwRefusal, { capabilities });
582
- const registered = originalResource(name, uriOrTemplate, {
583
- ...passthrough,
584
- scopeChallenge: challengeFor(scopeChallenge, scopesReaching(policy, permission), challengeScope(policy, permission))
585
- }, wrap(read));
586
- if (typeof uriOrTemplate === "string") resources.set(uriOrTemplate, permission);
587
- else templates.push({
588
- template: uriOrTemplate,
589
- permission
590
- });
591
- guardUpdates(registered, wrap);
592
- return registered;
593
- };
594
- const guarded = server;
595
- guarded["registerTool"] = registerTool;
596
- guarded["registerPrompt"] = registerPrompt;
597
- guarded["registerResource"] = registerResource;
598
- return server;
531
+ guardUpdates(registered, wrap);
532
+ return registered;
533
+ };
534
+ const guarded = server;
535
+ guarded["registerTool"] = registerTool;
536
+ guarded["registerPrompt"] = registerPrompt;
537
+ guarded["registerResource"] = registerResource;
538
+ return server;
539
+ }
540
+ //#endregion
541
+ //#region src/mcp/subject.ts
542
+ const DEFAULT_MCP_ACTOR_KIND = "mcp-client";
543
+ /** `kind`, or the default when absent; `undefined` for a kind that is not a non-empty string. */
544
+ function mcpActorKind(kind) {
545
+ if (kind === void 0) return DEFAULT_MCP_ACTOR_KIND;
546
+ return typeof kind === "string" && kind !== "" ? kind : void 0;
547
+ }
548
+ /**
549
+ * Maps the `AuthInfo` the MCP SDK's bearer verification produced to a
550
+ * `Subject`: the principal from the verified claims in `extra`, the client
551
+ * as an actor of kind `actorKind` (`mcp-client` by default), the granted
552
+ * scopes as the delegation. Never verifies and never throws; anything
553
+ * unusable, including an `actorKind` that is not a non-empty string, is
554
+ * the anonymous subject.
555
+ */
556
+ function subjectFromMcp(authInfo, options = {}) {
557
+ try {
558
+ const kind = mcpActorKind(options.actorKind);
559
+ if (authInfo === void 0 || !isRecord(authInfo.extra) || kind === void 0) return anonymousSubject();
560
+ const claims = compact({
561
+ ...authInfo.extra,
562
+ authorization_details: authInfo.extra["authorizationDetails"] ?? authInfo.extra["authorization_details"],
563
+ scope: authInfo.scopes?.join(" "),
564
+ client_id: authInfo.clientId,
565
+ exp: authInfo.expiresAt
566
+ });
567
+ const mapped = mapClaimsToSubject(claims, options);
568
+ if (mapped.invalidClaims || mapped.invalidChain || mapped.subject.principal === null) return anonymousSubject();
569
+ const clientId = authInfo.clientId;
570
+ return freezeDeep(compact({
571
+ ...mapped.subject,
572
+ actor: typeof clientId === "string" && clientId !== "" ? compact({
573
+ id: clientId,
574
+ kind,
575
+ client: clientNameOf(options.clients, clientId)
576
+ }) : mapped.subject.actor
577
+ }));
578
+ } catch {
579
+ return anonymousSubject();
580
+ }
581
+ }
582
+ //#endregion
583
+ //#region src/mcp/create.ts
584
+ function createPermDock(policy, options) {
585
+ const actorKind = mcpActorKind(options.actorKind);
586
+ if (actorKind === void 0) throw new TypeError("permdock/mcp: actorKind must be a non-empty string");
587
+ const checks = {
588
+ policy,
589
+ options,
590
+ kernel: createAgentKernel(policy, compact({
591
+ subject: (call) => options.subject(call.authInfo ?? {}),
592
+ actor: (call) => {
593
+ const clientId = call.authInfo?.clientId;
594
+ return typeof clientId === "string" && clientId !== "" ? compact({
595
+ id: clientId,
596
+ kind: actorKind,
597
+ client: clientNameOf(options.clients, clientId)
598
+ }) : void 0;
599
+ },
600
+ delegation: (call) => call.authInfo === void 0 ? void 0 : delegationFrom(call.authInfo.scopes, call.authInfo.extra),
601
+ tenant: tenantOf(options.tenant),
602
+ store: options.store,
603
+ adapter: "mcp",
604
+ boundary: "mcp-args",
605
+ wrap: composeWraps(options.otel, options.wrap),
606
+ context: options.context === void 0 ? void 0 : (call) => options.context?.(call.authInfo ?? {}),
607
+ ...instanceOptions(options)
608
+ }))
599
609
  };
600
- return { protectServer };
610
+ return { protectServer: ((server, enforcement) => protectServer(checks, server, enforcement)) };
601
611
  }
602
612
  //#endregion
603
613
  export { APPROVAL_META_KEY, createPermDock, subjectFromMcp };