permdock 0.3.1 → 0.5.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 (552) hide show
  1. package/README.md +37 -35
  2. package/dist/{openapi-schema--ARjyfQr.js → 2020-C9VN-x8c.js} +5 -132
  3. package/dist/a2a/index.d.ts +8 -6
  4. package/dist/a2a/index.js +21 -31
  5. package/dist/{adapter-context-mlWsVGGg.js → adapter-context-CRhqyzCk.js} +1 -1
  6. package/dist/adoption-scan-B4R5fnMU.js +107 -0
  7. package/dist/agent/index.d.ts +3 -0
  8. package/dist/agent/index.js +1 -0
  9. package/dist/ai-sdk/index.d.ts +18 -23
  10. package/dist/ai-sdk/index.js +38 -21
  11. package/dist/app-data-MuyzVqX8.js +60 -0
  12. package/dist/approval-header-CJACtHkv.js +23 -0
  13. package/dist/approval-prompt-Dg5LeAcT.js +62 -0
  14. package/dist/approval-prompt-Djo_PyZc.d.ts +57 -0
  15. package/dist/approvals/index.d.ts +5 -3
  16. package/dist/approvals/index.js +8 -5
  17. package/dist/approvals-DJ6Yd5z1.js +995 -0
  18. package/dist/{approvers-DT4AVyIg.js → approvers-CqPOLD-o.js} +1 -1
  19. package/dist/arazzo-B6lebmiQ.js +36 -0
  20. package/dist/{arazzo-BAgw9ap6.js → arazzo-BWhNF-k0.js} +24 -17
  21. package/dist/args-IIolxxKA.js +197 -0
  22. package/dist/astro/index.d.ts +43 -0
  23. package/dist/astro/index.js +27 -0
  24. package/dist/audience-Dg8XsRaO.js +55 -0
  25. package/dist/auth-DRLEizbL.js +178 -0
  26. package/dist/authzen/index.d.ts +26 -6
  27. package/dist/authzen/index.js +228 -75
  28. package/dist/automation-BMZPIVUM.d.ts +114 -0
  29. package/dist/automation-DVjOckjV.js +157 -0
  30. package/dist/better-auth/index.d.ts +8 -6
  31. package/dist/better-auth/index.js +11 -23
  32. package/dist/better-supabase/index.d.ts +438 -86
  33. package/dist/better-supabase/index.js +1027 -184
  34. package/dist/bind--9EFVYWF.d.ts +38 -0
  35. package/dist/{bind-CuzGytRf.js → bind-CZzhx-Vj.js} +22 -10
  36. package/dist/body-CH5of8Ne.js +10 -0
  37. package/dist/body-text-QcXok_SI.js +52 -0
  38. package/dist/build-instance-BMnAudHn.js +52 -0
  39. package/dist/{canonical-json-DemiK4Vp.js → canonical-json-BC8_nMTw.js} +6 -6
  40. package/dist/{capability-2kYTMWDv.d.ts → capability-BSslw1QV.d.ts} +44 -25
  41. package/dist/{capability-4qPdO9gk.js → capability-N1K9IpqS.js} +69 -42
  42. package/dist/casbin-Cr7RLtA3.js +30 -0
  43. package/dist/casbin-Dyu2gnUD.js +234 -0
  44. package/dist/casl-64gpT-8x.js +24 -0
  45. package/dist/casl-DjEDhTCP.js +299 -0
  46. package/dist/catalog/index.d.ts +74 -2
  47. package/dist/catalog/index.js +51 -2
  48. package/dist/catalog-BECMPrwc.js +100 -0
  49. package/dist/catalog-DjhMYYCq.js +1 -0
  50. package/dist/catalog-R_A__RsH.js +52 -0
  51. package/dist/{catalog-doc-DdGm82XT.js → catalog-doc-C9wjsfNY.js} +54 -25
  52. package/dist/catalog-fingerprint-CCP0-yQS.js +153 -0
  53. package/dist/chat/index.d.ts +2 -0
  54. package/dist/chat/index.js +224 -0
  55. package/dist/chat-sdk/index.d.ts +87 -0
  56. package/dist/chat-sdk/index.js +197 -0
  57. package/dist/claims-map-7oQ3ue4X.js +13 -0
  58. package/dist/claims-map-Ca-QX8C6.d.ts +32 -0
  59. package/dist/claude-agent/index.d.ts +7 -14
  60. package/dist/claude-agent/index.js +26 -30
  61. package/dist/clerk/index.d.ts +9 -8
  62. package/dist/clerk/index.js +15 -45
  63. package/dist/cli/bin.js +36 -17
  64. package/dist/cli/index.d.ts +20 -6
  65. package/dist/cli/index.js +164 -4
  66. package/dist/cloud/index.d.ts +102 -63
  67. package/dist/cloud/index.js +240 -347
  68. package/dist/cloud-CIoHNevm.js +87 -0
  69. package/dist/codemod-Bmj9dWMH.js +37 -0
  70. package/dist/codemod-Cxvvc70T.js +2084 -0
  71. package/dist/{collect-DSTE3ml9.js → collect-CrZJJnEF.js} +79 -17
  72. package/dist/collect-DloHbDVa.js +55 -0
  73. package/dist/collect-FlXJlhus.js +1 -0
  74. package/dist/command-L8EstFNm.js +6 -0
  75. package/dist/{compact-y6vfu2_f.js → compact-CAf557ZB.js} +11 -1
  76. package/dist/compile/index.d.ts +1 -1
  77. package/dist/compile/index.js +1 -2
  78. package/dist/{compile-Ba4blROR.js → compile-CMqMx_IN.js} +13 -9
  79. package/dist/{compile-BkRyBDBw.d.ts → compile-Ckm2HqBZ.d.ts} +5 -3
  80. package/dist/completion-BqhRBJD8.js +143 -0
  81. package/dist/config-B46rm9sc.js +26 -0
  82. package/dist/{config-BJiM-xAm.js → config-bs_kZeYq.js} +15 -10
  83. package/dist/{config-report-CdCgbRnV.js → config-report-DUgj62Ai.js} +17 -8
  84. package/dist/{connection-CU8MQxRi.js → connection-DjhIJSs2.js} +8 -6
  85. package/dist/constants-DcJABbLW.js +20 -0
  86. package/dist/{context-Bcy85rGi.js → context-bbFHR-0D.js} +16 -5
  87. package/dist/convex/index.d.ts +11 -10
  88. package/dist/convex/index.js +18 -18
  89. package/dist/create-0VZ7Pdiu.d.ts +107 -0
  90. package/dist/create-BDS7wc3y.d.ts +138 -0
  91. package/dist/create-BFfm17UA.d.ts +110 -0
  92. package/dist/create-BWRSXgOF.js +403 -0
  93. package/dist/create-C3b4B5eF.js +130 -0
  94. package/dist/create-DnrmLnLW.js +323 -0
  95. package/dist/{credential-8P81ff4u.js → credential-DM2um3ha.js} +153 -32
  96. package/dist/credentials-DPyHmYz5.js +74 -0
  97. package/dist/deciding-columns-Sq12mEA6.js +123 -0
  98. package/dist/delegation-DaXVdDhM.js +286 -0
  99. package/dist/delegation-input-FTxMK3ji.js +19 -0
  100. package/dist/delivery/index.d.ts +5 -0
  101. package/dist/delivery/index.js +5 -0
  102. package/dist/delivery-DCAgNyCn.js +499 -0
  103. package/dist/delivery-event-xX4obB8F.js +40 -0
  104. package/dist/denied-text-D8jDHgsl.d.ts +19 -0
  105. package/dist/{describe-DMYiCjJV.d.ts → describe-BZUsixiL.d.ts} +11 -2
  106. package/dist/{describe-B_gVZEVi.js → describe-BybMRY7A.js} +10 -5
  107. package/dist/device-BARQ8eYG.js +193 -0
  108. package/dist/diff-CxZo9pTq.js +37 -0
  109. package/dist/{diff-2VaeChzX.js → diff-DCePiN6M.js} +61 -55
  110. package/dist/doctor-CxiwSfqH.js +44 -0
  111. package/dist/doctor-DFjUxf2f.js +2361 -0
  112. package/dist/drizzle/index.d.ts +5 -3
  113. package/dist/drizzle/index.js +6 -14
  114. package/dist/elysia/index.d.ts +16 -13
  115. package/dist/elysia/index.js +14 -13
  116. package/dist/env-DJZrPjRi.js +8 -0
  117. package/dist/errors-BDUwg2qC.js +27 -0
  118. package/dist/{errors-Cz5zn0mW.js → errors-BKy0EfhN.js} +6 -10
  119. package/dist/errors-BWXBMaKK.d.ts +11 -0
  120. package/dist/{errors-DPdqI50v.d.ts → errors-C2PXIv4c.d.ts} +2 -2
  121. package/dist/errors-CWTY6uih.js +143 -0
  122. package/dist/evaluate-_R8QkWaf.js +1732 -0
  123. package/dist/evaluations-16UqqQ6W.d.ts +32 -0
  124. package/dist/{evaluations-tz6D9A2G.js → evaluations-DZ2CbV5k.js} +181 -32
  125. package/dist/eve/index.d.ts +12 -16
  126. package/dist/eve/index.js +23 -29
  127. package/dist/event-time-CsegxXxB.js +23 -0
  128. package/dist/expiry-D4_YKRKD.js +52 -0
  129. package/dist/express/index.d.ts +13 -10
  130. package/dist/express/index.js +14 -12
  131. package/dist/fastify/index.d.ts +26 -13
  132. package/dist/fastify/index.js +17 -36
  133. package/dist/fetch-adapter-g0ypLkID.js +120 -0
  134. package/dist/fetch-adapter-qKJBuRqy.d.ts +31 -0
  135. package/dist/fields-D9tPVUUS.js +203 -0
  136. package/dist/files-C5ZI27eV.js +124 -0
  137. package/dist/{files-DWUN9PzI.js → files-D_JIzUrP.js} +12 -3
  138. package/dist/{fixtures-ht28Cplr.js → fixtures-B7XrLeY7.js} +12 -12
  139. package/dist/flags-C3DktBDY.js +86 -0
  140. package/dist/{from-snapshot-CTLijvdm.js → from-snapshot-D2lZt4Dd.js} +78 -65
  141. package/dist/{generate-CH7ThJ14.js → generate-CNU1pIOo.js} +1 -3
  142. package/dist/grantee-Cn1HyUsI.js +254 -0
  143. package/dist/grantee-conditions-CcXf8hMM.js +271 -0
  144. package/dist/grantee-match-DHArqY82.js +142 -0
  145. package/dist/h3/index.d.ts +37 -0
  146. package/dist/h3/index.js +35 -0
  147. package/dist/headers-BIjfMaoC.js +8 -0
  148. package/dist/headers-CIbDTUTK.d.ts +7 -0
  149. package/dist/{helpers-H_KARDVC.js → helpers-DTcZOzhF.js} +47 -39
  150. package/dist/hono/index.d.ts +12 -9
  151. package/dist/hono/index.js +14 -13
  152. package/dist/{hosted-DJQw46hn.js → hosted-BZIAYvon.js} +64 -15
  153. package/dist/hosted-DBDX0M-P.d.ts +78 -0
  154. package/dist/{http-SO7qGttf.js → http-BBoKefeS.js} +35 -2
  155. package/dist/{http-DPuDaChb.d.ts → http-B_LphE5Y.d.ts} +1 -2
  156. package/dist/http-DXJ37RDA.js +46 -0
  157. package/dist/{http-BIhmLfCc.js → http-ujKm0JXE.js} +3 -26
  158. package/dist/{openapi-import-cmwetbzw.js → import-CNV7I2Dw.js} +30 -26
  159. package/dist/{rls-import-4lLW_pbb.js → import-DMmOG27O.js} +271 -128
  160. package/dist/index-BcHcPyIo.d.ts +110 -0
  161. package/dist/index-CaxrMD1A.d.ts +1 -0
  162. package/dist/index-Chrs5fQ-.d.ts +210 -0
  163. package/dist/index-CxGUswIC.d.ts +431 -0
  164. package/dist/index-D8EovfsP.d.ts +91 -0
  165. package/dist/index-DOVf7RJv.d.ts +900 -0
  166. package/dist/{index-C8z4RjQV.d.ts → index-SGdIQyzc.d.ts} +34 -16
  167. package/dist/index.d.ts +20 -14
  168. package/dist/index.js +33 -23
  169. package/dist/init-DeMYsnYJ.js +96 -0
  170. package/dist/init-GG6Jh8HD.js +95 -0
  171. package/dist/{instance-options-jARdwfPN.d.ts → instance-options-Omfd793B.d.ts} +2 -2
  172. package/dist/instance-snapshot-Cxq4ygFc.js +600 -0
  173. package/dist/instant-BluqDvyS.js +19 -0
  174. package/dist/internals-Dk8A8fX3.js +17 -0
  175. package/dist/{json-schema-BsAflUGW.js → json-schema-B-vAwlde.js} +46 -9
  176. package/dist/json-schema-CN_iLFH2.d.ts +40 -0
  177. package/dist/jwt/index.d.ts +18 -11
  178. package/dist/jwt/index.js +166 -145
  179. package/dist/{kernel-_RRHmnMY.js → kernel-5JatXyND.js} +120 -43
  180. package/dist/kysely/index.d.ts +5 -3
  181. package/dist/kysely/index.js +6 -14
  182. package/dist/{live-options-H2eG8dfJ.js → live-options-BaAFCIiu.js} +16 -3
  183. package/dist/load-BxEtwlBS.js +1 -0
  184. package/dist/{load-DhWEB9P1.js → load-DFS_ry0W.js} +31 -7
  185. package/dist/{load-jose-BL6LH4bL.js → load-jose-DZ4dnjri.js} +1 -4
  186. package/dist/login-Dfe5RlYk.js +68 -0
  187. package/dist/login-imhuwvn3.js +254 -0
  188. package/dist/manifest-C8IzW3Do.js +42 -0
  189. package/dist/manifest-CtKR3GXL.js +370 -0
  190. package/dist/manifest-json-CAGzls-C.js +9 -0
  191. package/dist/{manifest-uDS9y5de.d.ts → manifest-mx5ghSFM.d.ts} +9 -2
  192. package/dist/manifest-schema-C0kK_8V0.js +399 -0
  193. package/dist/{map-claims-Z4QZOiFF.js → map-claims-D3oRmTk0.js} +19 -25
  194. package/dist/{map-error-pgUWNNtG.js → map-error-TCAdw-eW.js} +5 -5
  195. package/dist/{markers-B0hYLvMD.js → markers-C6joDI3o.js} +8 -3
  196. package/dist/mcp/index.d.ts +36 -9
  197. package/dist/mcp/index.js +476 -448
  198. package/dist/{rls-migrate-CN4TlJTO.js → migrate-BShP7Vf4.js} +119 -20
  199. package/dist/nest/index.d.ts +12 -9
  200. package/dist/nest/index.js +20 -20
  201. package/dist/next/index.d.ts +40 -20
  202. package/dist/next/index.js +37 -39
  203. package/dist/next/plugin.d.ts +1 -1
  204. package/dist/next/plugin.js +2 -2
  205. package/dist/node/index.d.ts +10 -10
  206. package/dist/node/index.js +7 -9
  207. package/dist/ocsf-BFp-PZZA.js +126 -0
  208. package/dist/openai/index.d.ts +9 -16
  209. package/dist/openai/index.js +18 -25
  210. package/dist/openapi/index.d.ts +3 -3
  211. package/dist/openapi/index.js +1 -1
  212. package/dist/{openapi-BqRBvAng.js → openapi-B7HZ0f-r.js} +9 -12
  213. package/dist/{openapi-CqqEbHsL.js → openapi-DTaEmTSW.js} +23 -26
  214. package/dist/openapi-ahr8rHu3.js +138 -0
  215. package/dist/operation-findings-DgATDpvh.js +36 -0
  216. package/dist/operations-CxybZErY.d.ts +59 -0
  217. package/dist/orpc/index.d.ts +13 -10
  218. package/dist/orpc/index.js +23 -20
  219. package/dist/otel/index.d.ts +3 -2
  220. package/dist/otel/index.js +53 -27
  221. package/dist/output-Dyw8fyPF.js +88 -0
  222. package/dist/output-files-B3IZJksC.js +1 -0
  223. package/dist/output-files-DhRBBE4n.js +138 -0
  224. package/dist/{rls-fields-CZOMlwHl.js → ownership-BatFgAA4.js} +2393 -2349
  225. package/dist/{package-root-zGkxO3oN.js → package-root-Dk_ETdkp.js} +4 -3
  226. package/dist/{parse-BuyjxhZV.js → parse-Cxq0WxrA.js} +3 -3
  227. package/dist/{parse-local-manifest-BrMozJCo.js → parse-local-manifest-CVSs6J9I.js} +2 -4
  228. package/dist/{parse-local-manifest-JLnaBH0S.d.ts → parse-local-manifest-DgqtruPn.d.ts} +1 -1
  229. package/dist/parse-request-D_tUXG6M.js +26 -0
  230. package/dist/paths-DXSHAMIa.js +42 -0
  231. package/dist/pdp/index.d.ts +7 -3
  232. package/dist/pdp/index.js +47 -29
  233. package/dist/{peer-BOr_kJE1.js → peer-C8swJ2GH.js} +23 -4
  234. package/dist/peer-CRvC7Hg1.js +1 -0
  235. package/dist/permdock-B9JxkBwC.js +868 -0
  236. package/dist/permdock-D7eeLJER.d.ts +502 -0
  237. package/dist/permission-registry-Br4jSNVi.js +385 -0
  238. package/dist/permissions-B-wCP5ZC.js +30 -0
  239. package/dist/{permissions-RJrovw98.js → permissions-CZKiUfFM.js} +4 -3
  240. package/dist/{permissions-CDgvKG5L.d.ts → permissions-oEWfl-kl.d.ts} +1 -2
  241. package/dist/policies-CO1oOymN.js +295 -0
  242. package/dist/{policy-D2W7uv19.d.ts → policy-Czo4n3Hs.d.ts} +2 -2
  243. package/dist/policy-DLZJ5gAp.js +399 -0
  244. package/dist/policy-from-catalog-DzhEc3Y9.js +450 -0
  245. package/dist/policy-module-CTlwMvLI.js +89 -0
  246. package/dist/{policy-IB6yxpC3.d.ts → policy-types-DzwivBgR.d.ts} +939 -1057
  247. package/dist/postgrest-CW0IqC-U.js +566 -0
  248. package/dist/postgrest-NUqZT-RB.d.ts +100 -0
  249. package/dist/powersync-BHfuehf3.js +62 -0
  250. package/dist/powersync-CbzkqL_M.js +1 -0
  251. package/dist/{powersync-Dv1_aWF7.js → powersync-bYUDLOAO.js} +30 -32
  252. package/dist/preset/index.d.ts +146 -0
  253. package/dist/preset/index.js +1 -0
  254. package/dist/preset-DZdU0tne.js +1768 -0
  255. package/dist/principal-source-pHneukrx.js +103 -0
  256. package/dist/prisma/index.d.ts +6 -3
  257. package/dist/prisma/index.js +6 -12
  258. package/dist/{problem-B43ztKIm.js → problem-CTviyH5L.js} +18 -27
  259. package/dist/{problem-details-DX075l9V.d.ts → problem-details-DXlt-vks.d.ts} +1 -1
  260. package/dist/{problem-details-_AMOYz-w.js → problem-details-cn5X30gZ.js} +45 -42
  261. package/dist/problem-types-CJ2325SZ.js +5 -0
  262. package/dist/{prompt-CXYhLfsS.js → prompt-DfZLJLIn.js} +2 -2
  263. package/dist/protected-DEPHc2xV.d.ts +38 -0
  264. package/dist/{protected-utU-SLuy.js → protected-DfjY5mLA.js} +37 -8
  265. package/dist/{provider-CSQd7m92.js → provider-CC-u3bYP.js} +23 -10
  266. package/dist/{provider-DZY281jO.d.ts → provider-DMVt6yYn.d.ts} +1 -1
  267. package/dist/{provider-store-Cfbvo4DE.js → provider-store-B5Yrkhzr.js} +6 -3
  268. package/dist/pull-BgIfno6w.js +256 -0
  269. package/dist/pull-ByOks_Tg.js +1 -0
  270. package/dist/push-CmFVBOeI.js +116 -0
  271. package/dist/pushed-policy-BImMTTIM.d.ts +57 -0
  272. package/dist/pushed-policy-DobP7AHI.js +238 -0
  273. package/dist/react/index.d.ts +8 -8
  274. package/dist/react/index.js +6 -6
  275. package/dist/react/provider-client.d.ts +1 -1
  276. package/dist/react/provider-client.js +1 -2
  277. package/dist/react-native/index.d.ts +24 -63
  278. package/dist/react-native/index.js +45 -27
  279. package/dist/{refs-KYb4ntaz.js → refs-K6eWUJ0H.js} +1 -1
  280. package/dist/relation-walk-3OyDBF0S.js +186 -0
  281. package/dist/relations-BnCWnJGI.js +163 -0
  282. package/dist/renames-CGj7YwcQ.js +175 -0
  283. package/dist/{replay-CYyiLiwO.d.ts → replay-D7iKcLFe.d.ts} +1 -1
  284. package/dist/{replay-BsOyTrdV.js → replay-Du1tJjG7.js} +2 -1
  285. package/dist/request-context-BTRTG7OT.js +71 -0
  286. package/dist/request-context-C2_1lchh.d.ts +5 -0
  287. package/dist/request-schema-CMreVuFM.js +148 -0
  288. package/dist/resend/index.d.ts +126 -0
  289. package/dist/resend/index.js +379 -0
  290. package/dist/resource-relations-D_jw0BFx.js +243 -0
  291. package/dist/retire-CALjIQ7e.js +240 -0
  292. package/dist/{revocations-Cy06JNx2.d.ts → revocations-R07lFBnX.d.ts} +2 -0
  293. package/dist/rls-BA8an5Ap.js +336 -0
  294. package/dist/{rls-DiinlRML.js → rls-j6t43t7n.js} +1066 -1068
  295. package/dist/role-builder-CXbis5-X.js +623 -0
  296. package/dist/{rpc-DL9Sqvb1.js → rpc-aPyNi6tA.js} +18 -8
  297. package/dist/run-CNsApDpd.js +1 -0
  298. package/dist/run-DOfMtc9V.js +723 -0
  299. package/dist/run-ticket-BjhTOi6u.d.ts +124 -0
  300. package/dist/run-ticket-sxFI6LAk.js +337 -0
  301. package/dist/{runtime-CB8gQFvS.js → runtime-D3VTAiCA.js} +1 -1
  302. package/dist/{saas-DhpJjnBA.js → saas-FO-Q8oj0.js} +18 -15
  303. package/dist/scan-BOI5tJ-6.js +29 -0
  304. package/dist/{schema-D3MnDMxa.js → schema-B4v0Qrac.js} +106 -10
  305. package/dist/schema-yLuBWWsh.js +130 -0
  306. package/dist/scim/index.d.ts +2 -2
  307. package/dist/scim/index.js +1 -2
  308. package/dist/{scim-BFGBBAqR.js → scim-ClHtpyV3.js} +213 -87
  309. package/dist/{scopes-CVdPrWN-.js → scopes-CUPSjo9q.js} +20 -7
  310. package/dist/server/index.d.ts +13 -134
  311. package/dist/server/index.js +13 -10
  312. package/dist/server-DqCT4CgZ.js +453 -0
  313. package/dist/{create-B1d519XK.d.ts → server-types-BLd4MnBX.d.ts} +89 -70
  314. package/dist/{sha256-BO0swRXL.js → sha256-D9ihqmvd.js} +8 -1
  315. package/dist/shared-CD11nBbC.js +304 -0
  316. package/dist/{shared-DRu8VFVM.js → shared-DvvFzYXe.js} +8 -9
  317. package/dist/signals-D3NcTKUS.js +32 -0
  318. package/dist/sink-BEZSlMS_.js +957 -0
  319. package/dist/sink-Bj_lDUDq.d.ts +225 -0
  320. package/dist/{skills-Biq5uup3.js → skills-B6lVdD_W.js} +16 -8
  321. package/dist/skills-CTYwkl44.js +51 -0
  322. package/dist/snapshot-CXUWfsNy.js +269 -0
  323. package/dist/{snapshot-cache-D6jLelln.js → snapshot-cache-DZHQ0KF6.js} +11 -5
  324. package/dist/{snapshot-cache-B-LxUahj.d.ts → snapshot-cache-DqK9eDmM.d.ts} +7 -5
  325. package/dist/solid/index.d.ts +24 -25
  326. package/dist/solid/index.js +41 -11
  327. package/dist/solid-start/index.d.ts +52 -0
  328. package/dist/solid-start/index.js +49 -0
  329. package/dist/{sources-BdOYLw9j.d.ts → sources-BV9j0DeZ.d.ts} +11 -13
  330. package/dist/{sources-4p0-4xQm.js → sources-vs5dGOsS.js} +147 -142
  331. package/dist/sql-B5T1IL83.js +55 -0
  332. package/dist/src-DLfUWFAI.js +1851 -0
  333. package/dist/ssf/index.d.ts +4 -4
  334. package/dist/ssf/index.js +440 -106
  335. package/dist/standard-webhooks-6lg8v_is.d.ts +88 -0
  336. package/dist/standard-webhooks-DgFFD-Ga.js +228 -0
  337. package/dist/storage-C2bWdvJH.js +132 -0
  338. package/dist/{store-DMAWwAJV.js → store-4u_hxjWa.js} +42 -55
  339. package/dist/{store-options-ByhZq1jV.js → store-options-BqEakYRa.js} +38 -24
  340. package/dist/{stores-BT2pSCub.js → stores-BbsD4fAR.js} +7 -3
  341. package/dist/stores-ClZUgeoP.d.ts +30 -0
  342. package/dist/{stream-D1RXubw2.d.ts → stream-7-xmnf3U.d.ts} +2 -2
  343. package/dist/{stream-DDpvynSB.js → stream-CvdUS9V1.js} +10 -2
  344. package/dist/style-DiKWnAvn.js +1 -0
  345. package/dist/{style-CTm1AXDT.js → style-Uao76wO7.js} +3 -2
  346. package/dist/subject-BGoM5o8B.js +17 -0
  347. package/dist/{subject-settings-BwBmCdTR.js → subject-settings-CkEwrw3W.js} +23 -5
  348. package/dist/supabase/index.d.ts +23 -106
  349. package/dist/supabase/index.js +5 -4
  350. package/dist/supabase/middleware.d.ts +13 -6
  351. package/dist/supabase/middleware.js +16 -11
  352. package/dist/supabase-9pqI57pW.js +92 -0
  353. package/dist/{supabase-C0qESOa-.js → supabase-Dxlp8A94.js} +124 -247
  354. package/dist/supabase-hook-CXcGpHqq.js +1 -0
  355. package/dist/{supabase-hook-ntETYCQu.js → supabase-hook-DdDQhMlw.js} +1659 -819
  356. package/dist/{supautils-u8jXTGrt.js → supautils-B6HYL9eL.js} +2 -2
  357. package/dist/support-session-C6xJQYut.js +158 -0
  358. package/dist/svelte/Protected.svelte +11 -4
  359. package/dist/svelte/index.d.ts +7 -7
  360. package/dist/svelte/index.js +26 -12
  361. package/dist/svelte/runtime.d.ts +10 -3
  362. package/dist/svelte/runtime.js +4 -3
  363. package/dist/svelte/source.d.ts +7 -7
  364. package/dist/svelte/source.js +5 -5
  365. package/dist/sveltekit/index.d.ts +51 -0
  366. package/dist/sveltekit/index.js +27 -0
  367. package/dist/tanstack-start/index.d.ts +51 -0
  368. package/dist/tanstack-start/index.js +40 -0
  369. package/dist/target-Bw37TFNA.js +51 -0
  370. package/dist/{validity-uOp8UpYn.js → tenancy-DN2QAx9z.js} +6 -42
  371. package/dist/terminal/index.d.ts +11 -9
  372. package/dist/terminal/index.js +36 -316
  373. package/dist/testing/index.d.ts +391 -106
  374. package/dist/testing/index.js +4574 -1286
  375. package/dist/testing/saas/index.d.ts +9 -8
  376. package/dist/testing/saas/index.js +2 -2
  377. package/dist/testing/saas/permissions.d.ts +1 -1
  378. package/dist/testing/saas/permissions.js +1 -2
  379. package/dist/text-BMFRfBqc.js +8 -0
  380. package/dist/{text-diff-BdkkYSbi.js → text-diff-BQcUapOb.js} +1 -1
  381. package/dist/thenable-yD7SabqG.js +31 -0
  382. package/dist/time-DkWjdL98.js +71 -0
  383. package/dist/{token-CIWxJOCh.js → token-BLZcjQgt.js} +15 -6
  384. package/dist/tool-refusal-CMLN5xhn.js +41 -0
  385. package/dist/trpc/index.d.ts +12 -9
  386. package/dist/trpc/index.js +18 -17
  387. package/dist/{types-DbjRN55U.d.ts → types-5Ut_pbKy.d.ts} +141 -13
  388. package/dist/types-BNORmDM8.d.ts +172 -0
  389. package/dist/types-BjV-fqcA.d.ts +57 -0
  390. package/dist/{types-QCuYJh4q.d.ts → types-BqAKcRNW.d.ts} +2 -1
  391. package/dist/types-C8-KNsFf.d.ts +107 -0
  392. package/dist/{types-aqOHTHcp.d.ts → types-CCpc2Dcv.d.ts} +77 -17
  393. package/dist/{types-Dnemwd77.d.ts → types-CZTnPFzM.d.ts} +50 -11
  394. package/dist/{types-C97IskBw.d.ts → types-CdlxsYQh.d.ts} +23 -11
  395. package/dist/{types-DxiCGmmd.d.ts → types-ClZaWzfb.d.ts} +9 -6
  396. package/dist/types-DX0LaKTb.d.ts +157 -0
  397. package/dist/types-DiQjupG2.d.ts +332 -0
  398. package/dist/types-DqzsnlSA.js +67 -0
  399. package/dist/types-_sHy8BQf.d.ts +65 -0
  400. package/dist/types-fbZ7JEXr.d.ts +89 -0
  401. package/dist/types-tIgIeIKJ.d.ts +66 -0
  402. package/dist/unplugin/index.d.ts +1 -1
  403. package/dist/unplugin/index.js +2 -2
  404. package/dist/usage-CHOtwL19.js +1 -0
  405. package/dist/usage-DHtE8j4E.js +32 -0
  406. package/dist/{usage-ItS7nLcl.js → usage-T5mXq98v.js} +56 -13
  407. package/dist/{validation-error-Ba264OaJ.d.ts → validation-error-Bg5Tpluk.d.ts} +1 -1
  408. package/dist/{validation-error-CnjZ4t92.js → validation-error-ZfUHbKvf.js} +1 -1
  409. package/dist/validity-CZ7-y0Cj.js +79 -0
  410. package/dist/{verifier-BxBo6I44.js → verifier-DHuh-okk.js} +68 -21
  411. package/dist/verify-DbCL9bnB.js +1770 -0
  412. package/dist/{version-BvacVTZR.js → version-CEbQ5UeM.js} +4 -3
  413. package/dist/version-DXkYUISx.js +1 -0
  414. package/dist/{views-Soe7bGSC.js → views-DTIIO-oQ.js} +41 -2
  415. package/dist/{permissions-DttnqqxC.d.ts → vocabulary-D6lPdb4Z.d.ts} +120 -29
  416. package/dist/vue/index.d.ts +25 -21
  417. package/dist/vue/index.js +25 -9
  418. package/dist/waiter-BGUtGYoU.js +67 -0
  419. package/dist/waiter-CKy4MQSY.d.ts +36 -0
  420. package/dist/watch-Cb-NcaUw.js +1 -0
  421. package/dist/{watch-DVBJ9cBq.js → watch-CszoTJMq.js} +47 -8
  422. package/dist/webmcp/index.d.ts +2 -2
  423. package/dist/webmcp/index.js +13 -37
  424. package/dist/where-scope-Dv-WTP-w.js +306 -0
  425. package/dist/who-can-D0QoYbEb.js +364 -0
  426. package/dist/wire-delegation-Cv3W2eaM.js +36 -0
  427. package/dist/wire-denial-C7PaVYEM.js +27 -0
  428. package/dist/workflow/index.d.ts +5 -0
  429. package/dist/workflow/index.js +223 -0
  430. package/dist/workflow-sdk/index.d.ts +56 -0
  431. package/dist/workflow-sdk/index.js +78 -0
  432. package/dist/wrap-Bd1Tejur.d.ts +15 -0
  433. package/dist/wrap-gX61EtpB.js +27 -0
  434. package/package.json +140 -41
  435. package/schemas/access-event-v1.json +118 -0
  436. package/schemas/approval-request-v1.json +34 -1
  437. package/schemas/approval-signature-v1.json +94 -0
  438. package/schemas/automation-event-v1.json +113 -0
  439. package/schemas/capability-v1.json +84 -0
  440. package/schemas/catalog-event-v1.json +87 -0
  441. package/schemas/catalog-v1.json +129 -12
  442. package/schemas/cli-commands-v1.json +164 -0
  443. package/schemas/cli-result-v1.json +96 -0
  444. package/schemas/cloud-api-v1.json +5407 -0
  445. package/schemas/connector-v1.json +408 -0
  446. package/schemas/credential-event-v1.json +81 -0
  447. package/schemas/credential-v1.json +134 -0
  448. package/schemas/decision-event-v1.json +288 -0
  449. package/schemas/delivery-event-v1.json +117 -0
  450. package/schemas/directory-event-v1.json +85 -0
  451. package/schemas/evidence-export-v1.json +54 -0
  452. package/schemas/membership-event-v1.json +93 -0
  453. package/schemas/policy-v1.json +68 -0
  454. package/schemas/pushed-policy-v1.json +236 -0
  455. package/schemas/run-v1.json +162 -0
  456. package/schemas/snapshot-v1.json +138 -0
  457. package/schemas/supabase-claims-v1.json +4 -4
  458. package/schemas/supabase-manifest-v1.json +5 -1
  459. package/schemas/support-session-v1.json +111 -0
  460. package/skills/permdock/SKILL.md +16 -12
  461. package/skills/permdock-agents/SKILL.md +40 -23
  462. package/skills/permdock-agents/references/operations-automations-chat.md +221 -0
  463. package/skills/permdock-agents/references/runtimes.md +22 -18
  464. package/skills/permdock-approvals/SKILL.md +29 -13
  465. package/skills/permdock-approvals/references/delivery-and-waiters.md +172 -0
  466. package/skills/permdock-approvals/references/stores-and-resume.md +21 -7
  467. package/skills/permdock-audit/SKILL.md +3 -3
  468. package/skills/permdock-credentials/SKILL.md +5 -5
  469. package/skills/permdock-credentials/references/tokens-keys-links.md +19 -10
  470. package/skills/permdock-data/SKILL.md +6 -6
  471. package/skills/permdock-data/references/queries-and-rls.md +13 -8
  472. package/skills/permdock-data/references/relationships.md +3 -3
  473. package/skills/permdock-tenancy/SKILL.md +20 -7
  474. package/skills/permdock-tenancy/references/contacts-and-support-sessions.md +122 -0
  475. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +6 -4
  476. package/skills/permdock-wire/SKILL.md +18 -12
  477. package/skills/permdock-wire/references/adapters.md +146 -50
  478. package/skills/permdock-wire/references/policy-options.md +15 -6
  479. package/skills/permdock-wire/references/presets-and-recipes.md +58 -0
  480. package/dist/approvals-DbYAuNkG.js +0 -224
  481. package/dist/arazzo-C9chp3ST.js +0 -54
  482. package/dist/bind-C_ob3LKa.d.ts +0 -25
  483. package/dist/catalog-CRW5Mx_B.js +0 -2
  484. package/dist/catalog-CYj-mX2O.js +0 -48
  485. package/dist/catalog-DWF5cYqB.js +0 -55
  486. package/dist/cloud-CfwZ39Rl.js +0 -50
  487. package/dist/cloud-DWLXO2af.js +0 -118
  488. package/dist/collect-CHB22Sx4.js +0 -83
  489. package/dist/collect-DSWOk19R.js +0 -2
  490. package/dist/commands-BeaGNj_o.js +0 -97
  491. package/dist/config-ir40y8m0.js +0 -36
  492. package/dist/create-CMwIl-w2.js +0 -253
  493. package/dist/delegation-D8pUEuce.js +0 -103
  494. package/dist/diff-C9RDjjhs.js +0 -48
  495. package/dist/doctor-Djh6JDEk.js +0 -53
  496. package/dist/doctor-DvH0IQff.js +0 -1194
  497. package/dist/doctor-collect-CjdO0wQX.js +0 -665
  498. package/dist/duration-xK2jGFVc.js +0 -25
  499. package/dist/errors-CWfoNg9N.js +0 -47
  500. package/dist/errors-DRnGZHzF.js +0 -30
  501. package/dist/evaluation-items-CfCCejQd.js +0 -40
  502. package/dist/expiry-BoBJ8Tvc.js +0 -7
  503. package/dist/fields-BMl1RxoX.js +0 -26
  504. package/dist/grantee-Cv5Sogfv.js +0 -602
  505. package/dist/headers-BZSDieNT.js +0 -6
  506. package/dist/headers-Cf-zWvsO.d.ts +0 -6
  507. package/dist/ids-DC4V4CFu.js +0 -18
  508. package/dist/index-0nNqHspG.d.ts +0 -6
  509. package/dist/index-BNc7Wer_.d.ts +0 -483
  510. package/dist/index-C7Tw7MaW.d.ts +0 -201
  511. package/dist/instance-options-Dhhcnm3y.js +0 -22
  512. package/dist/load-DwJUafYN.js +0 -2
  513. package/dist/manifest-iaoBXHKc.js +0 -783
  514. package/dist/map-AcxK9o_D.js +0 -147
  515. package/dist/may-use-DndQ5tQ-.js +0 -77
  516. package/dist/openapi-CQTsgKoB.js +0 -164
  517. package/dist/permdock-CbgvLnuo.js +0 -3479
  518. package/dist/permissions-DVoF6dMt.js +0 -662
  519. package/dist/policy-xyWg7QdR.js +0 -1122
  520. package/dist/powersync-CrBX8hY6.js +0 -2
  521. package/dist/powersync-DE19b9dT.js +0 -62
  522. package/dist/protected-BdnIEFkY.d.ts +0 -27
  523. package/dist/protected-xAr24FEC.d.ts +0 -40
  524. package/dist/relations-cjOL01hZ.js +0 -505
  525. package/dist/rls-P-BeBx0n.js +0 -238
  526. package/dist/rls-graph-CHwx0V8q.js +0 -435
  527. package/dist/rls-ownership-DcYlZ09B.js +0 -843
  528. package/dist/rls-shared-Cewd_-zI.js +0 -495
  529. package/dist/rls-verify-CMv9H3wV.js +0 -746
  530. package/dist/run-BWc9qqvE.js +0 -174
  531. package/dist/server-DlZ28Oz5.js +0 -268
  532. package/dist/sink-B1fZzIMf.d.ts +0 -104
  533. package/dist/sink-Bd9PSyfq.js +0 -141
  534. package/dist/skills-C5CbhhpG.js +0 -56
  535. package/dist/snapshot-Enxd0n-s.js +0 -975
  536. package/dist/sql-xdg5f4Fi.js +0 -27
  537. package/dist/src-BDwEZWrZ.js +0 -568
  538. package/dist/store-jOBYpiXC.d.ts +0 -36
  539. package/dist/stores-C0IMQrGI.d.ts +0 -52
  540. package/dist/subject-C6dLxqHU.js +0 -24
  541. package/dist/supabase-config-Bj3iDH2I.js +0 -472
  542. package/dist/supabase-hook-gd3s8bxB.js +0 -2
  543. package/dist/supabase-s4o9s1O1.js +0 -83
  544. package/dist/thenable-okc2xDsj.js +0 -10
  545. package/dist/types-BnIEz1sU.d.ts +0 -48
  546. package/dist/types-Bvc4oWT6.d.ts +0 -9
  547. package/dist/types-CKNSyIf_.d.ts +0 -52
  548. package/dist/types-Cq_H8N_X.d.ts +0 -197
  549. package/dist/usage-B0YuTQRO.js +0 -42
  550. package/dist/usage-DorAJiU_.js +0 -2
  551. package/dist/vocabulary-DA8a8zif.d.ts +0 -56
  552. 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-cn5X30gZ.js";
4
+ import { t as describe } from "../describe-BybMRY7A.js";
5
+ import { m as annotationsFor } from "../permission-registry-Br4jSNVi.js";
6
+ import { t as actorMayCallTool } from "../delegation-DaXVdDhM.js";
7
7
  import { n as resourceRef } from "../resource-ref-CaS9yVPi.js";
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";
8
+ import { a as hasScope, c as withApp, i as challengeScope, o as scopesReaching } from "../permdock-B9JxkBwC.js";
9
+ import { t as anonymousSubject } from "../subject-BGoM5o8B.js";
10
+ import { t as composeWraps } from "../wrap-gX61EtpB.js";
11
+ import { l as protectedResourceMetadataUrl, r as bearerChallenge } from "../problem-CTviyH5L.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-D3oRmTk0.js";
14
+ import { r as instanceOptions } from "../build-instance-BMnAudHn.js";
15
+ import { n as createAgentKernel, r as refusalText } from "../kernel-5JatXyND.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-CMLN5xhn.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,473 @@ 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, args, call, permission, approved, tool) {
238
+ const rechecked = await checks.kernel.check(binding, args, call, compact({
239
+ simulate: true,
240
+ tool
241
+ }));
242
+ if (!rechecked.ok) return {
243
+ ok: false,
244
+ refusal: failedRefusal(permission, rechecked.failure)
307
245
  };
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
- });
246
+ if (stillAllowed(rechecked.raw, approved)) return { ok: true };
247
+ return {
248
+ ok: false,
249
+ refusal: rechecked.raw.outcome === "denied" ? {
250
+ ...deniedRefusal(rechecked.raw, permission, rechecked.data),
251
+ decision: rechecked.raw,
252
+ permdock: rechecked.permdock
253
+ } : plainRefusal(permission, `Denied: ${permission.key} was revoked before the call completed.`, {})
331
254
  };
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 {
255
+ }
256
+ async function decideCall(checks, permission, reach, args, load, context, handlerContext, capabilities, completion, tool) {
257
+ const authInfo = context.http?.authInfo;
258
+ const refused = credentialRefusal(checks, permission, reach, authInfo);
259
+ if (refused !== void 0) return {
260
+ ok: false,
261
+ refusal: refused
262
+ };
263
+ const binding = compact({
264
+ permission,
265
+ data: load === void 0 ? void 0 : () => load()
266
+ });
267
+ const call = compact({ authInfo });
268
+ if (completion !== void 0) return recheck(checks, binding, args, call, permission, completion.approved, tool);
269
+ const checked = await checks.kernel.check(binding, args, call, compact({
270
+ resumeToken: approvalTokenOf(context),
271
+ tool
272
+ }));
273
+ if (!checked.ok) return {
274
+ ok: false,
275
+ refusal: failedRefusal(permission, checked.failure)
276
+ };
277
+ const { raw, decision, data } = checked;
278
+ switch (decision.outcome) {
279
+ case "granted": return raw.outcome === "approval-required" ? {
280
+ ok: true,
281
+ approved: raw.token
282
+ } : { ok: true };
283
+ case "denied": return {
339
284
  ok: false,
340
- refusal: plainRefusal(permission, "Denied: the token was not issued for this server.", { error: "invalid_token" })
285
+ refusal: {
286
+ ...decision.denials.some((denial) => denial.reason === "insufficient-user-authentication") ? stepUpRefusal(checks.options.stepUp?.at, decision, permission, data, context, capabilities) : deniedRefusal(decision, permission, data),
287
+ decision,
288
+ permdock: checked.permdock
289
+ }
341
290
  };
342
- if (authInfo !== void 0 && !hasScope(authInfo, reach.scopes)) {
343
- const resourceMetadata = resourceMetadataOf(authInfo);
344
- const challenged = reach.challenge;
291
+ case "approval-required": try {
345
292
  return {
346
293
  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)
294
+ refusal: compact({
295
+ ...approvalRefusal(decision, permission, data),
296
+ decision,
297
+ permdock: checked.permdock,
298
+ inputRequired: await approvalInput(checks.options, decision, handlerContext, context, capabilities)
299
+ })
369
300
  };
370
- if (stillAllowed(rechecked.raw, completion.approved)) return { ok: true };
301
+ } catch {
371
302
  return {
372
303
  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.`, {})
304
+ refusal: failedRefusal(permission, "failed")
374
305
  };
375
306
  }
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;
307
+ default: return decision;
308
+ }
309
+ }
310
+ /** `decideCall` with the refusal text replaced by `deniedText`'s. */
311
+ async function checkCall(checks, permission, reach, args, load, context, handlerContext, capabilities, completion, tool) {
312
+ const checked = await decideCall(checks, permission, reach, args, load, context, handlerContext, capabilities, completion, tool);
313
+ const { deniedText } = checks.options;
314
+ if (checked.ok || deniedText === void 0) return checked;
315
+ const { refusal } = checked;
316
+ return {
317
+ ok: false,
318
+ refusal: {
319
+ ...refusal,
320
+ text: refusalText(deniedText, {
321
+ decision: refusal.decision ?? null,
322
+ permission,
323
+ text: refusal.text
324
+ }, (error) => {
325
+ checks.kernel.report(refusal.permdock, error);
326
+ })
406
327
  }
407
328
  };
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);
329
+ }
330
+ /**
331
+ * The keys a list shows: unguarded ones, and guarded ones the token reaches and the subject may use.
332
+ * With `tools`, a guarded key is also a tool name an `agent` actor's `tools` list must name.
333
+ */
334
+ async function visible(checks, context, permissionOf, keys, declaredOf = () => void 0, tools = false) {
335
+ const authInfo = context.http?.authInfo;
336
+ const shown = /* @__PURE__ */ new Set();
337
+ const guarded = [];
338
+ for (const key of keys) {
339
+ const permission = permissionOf(key);
340
+ if (permission === void 0) shown.add(key);
341
+ else if (reachable(checks, authInfo, reachOf(checks.policy, permission, declaredOf(key)))) guarded.push({
342
+ key,
343
+ permission
344
+ });
345
+ }
346
+ if (guarded.length === 0) return shown;
347
+ let permdock;
348
+ try {
349
+ permdock = await checks.kernel.instance(compact({ authInfo }));
350
+ } catch {
428
351
  return shown;
429
- };
430
- const guard = (permission, load, handler, dataArgs, onRefusal, extra = {}) => async (...params) => {
352
+ }
353
+ for (const entry of guarded) if ((!tools || actorMayCallTool(permdock.subject.actor, entry.key)) && permdock.mayUse(entry.permission)) shown.add(entry.key);
354
+ return shown;
355
+ }
356
+ /** `handler` behind the call check; a refusal goes to `onRefusal` instead. */
357
+ function guard(checks, permission, load, handler, dataArgs, onRefusal, extra = {}) {
358
+ return async (...params) => {
431
359
  const raw = params.at(-1);
432
360
  const context = contextOf(raw);
433
- 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);
361
+ const args = dataArgs(params);
362
+ const loader = load === void 0 ? void 0 : () => load(...args);
363
+ const reach = extra.reach ?? reachOf(checks.policy, permission, void 0);
364
+ const tool = extra.tool?.();
365
+ const checked = await checkCall(checks, permission, reach, args, loader, context, raw, extra.capabilities, void 0, tool);
436
366
  let result;
437
367
  if (checked.ok) {
438
368
  result = await handler(...params);
439
369
  if (extra.longRunning === true) {
440
- const again = await check(permission, reach, loader, context, raw, extra.capabilities, { approved: checked.approved });
370
+ const again = await checkCall(checks, permission, reach, args, loader, context, raw, extra.capabilities, { approved: checked.approved }, tool);
441
371
  if (!again.ok) result = onRefusal(again.refusal);
442
372
  }
443
373
  } else result = onRefusal(checked.refusal);
444
374
  await extra.after?.(context);
445
375
  return result;
446
376
  };
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
- }
377
+ }
378
+ //#endregion
379
+ //#region src/mcp/protect-server.ts
380
+ const SESSIONS_PER_SERVER = 1e3;
381
+ function requirePermission(kind, name, config) {
382
+ const permission = isRecord(config) ? config["permission"] : void 0;
383
+ if (!isRecord(permission) || typeof permission["key"] !== "string") throw new TypeError(`permdock/mcp: ${kind} ${name} has no permission; every guarded registration needs one.`);
384
+ return permission;
385
+ }
386
+ function guardUpdates(registered, wrap, rename, currentName) {
387
+ const update = registered.update.bind(registered);
388
+ registered.update = (updates) => {
389
+ const next = { ...updates };
390
+ if (typeof updates["callback"] === "function") next["callback"] = wrap(updates["callback"]);
391
+ if (rename !== void 0 && currentName !== void 0) {
392
+ const to = updates["name"];
393
+ if (typeof to === "string" || to === null) rename(currentName(), to);
503
394
  }
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 {}
395
+ update(next);
396
+ };
397
+ }
398
+ function protectServer(checks, server, enforcement) {
399
+ const tools = /* @__PURE__ */ new Map();
400
+ const toolScopes = /* @__PURE__ */ new Map();
401
+ const prompts = /* @__PURE__ */ new Map();
402
+ const resources = /* @__PURE__ */ new Map();
403
+ const templates = [];
404
+ const lastListed = boundedMap(SESSIONS_PER_SERVER);
405
+ const toolPermission = (name) => tools.get(name);
406
+ const toolDeclared = (name) => toolScopes.get(name);
407
+ const promptPermission = (name) => prompts.get(name);
408
+ const resourcePermission = (uri) => {
409
+ const direct = resources.get(uri);
410
+ if (direct !== void 0) return direct;
411
+ return templates.find((entry) => entry.template.uriTemplate.match(uri) !== null)?.permission;
412
+ };
413
+ const templatePermission = (uriTemplate) => templates.find((entry) => entry.template.uriTemplate.toString() === uriTemplate)?.permission;
414
+ const listFilter = (field, keyOf, permissionOf, remember) => async (result, rawContext) => {
415
+ if (!isRecord(result) || !Array.isArray(result[field])) return result;
416
+ const context = contextOf(rawContext);
417
+ const entries = result[field];
418
+ const shown = await visible(checks, context, permissionOf, entries.map(keyOf), remember ? toolDeclared : void 0, remember);
419
+ const kept = entries.filter((entry) => shown.has(keyOf(entry)));
420
+ if (remember) lastListed.set(sessionKey(context), [...shown].toSorted().join(","));
421
+ return definesCacheScope(context) ? {
422
+ ...result,
423
+ [field]: kept,
424
+ cacheScope: "private"
425
+ } : {
426
+ ...result,
427
+ [field]: kept
514
428
  };
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
429
+ };
430
+ const filters = {
431
+ "tools/list": listFilter("tools", (entry) => entry.name, toolPermission, true),
432
+ "prompts/list": listFilter("prompts", (entry) => entry.name, promptPermission, false),
433
+ "resources/list": listFilter("resources", (entry) => entry.uri, resourcePermission, false),
434
+ "resources/templates/list": listFilter("resourceTemplates", (entry) => entry.uriTemplate, templatePermission, false)
435
+ };
436
+ const inner = server.server;
437
+ const capabilities = () => inner.getClientCapabilities?.();
438
+ const set = inner.setRequestHandler.bind(inner);
439
+ inner.setRequestHandler = (method, ...rest) => {
440
+ const filter = Object.hasOwn(filters, method) ? filters[method] : void 0;
441
+ const [handler] = rest;
442
+ if (filter !== void 0 && rest.length === 1 && typeof handler === "function") {
443
+ set(method, async (request, context) => filter(await handler(request, context), context));
444
+ return;
445
+ }
446
+ set(method, ...rest);
447
+ };
448
+ for (const method of Object.keys(filters)) {
449
+ const existing = inner._getRequestHandler?.(method);
450
+ if (existing !== void 0) {
451
+ inner.removeRequestHandler(method);
452
+ inner.setRequestHandler(method, (request, context) => existing(request, context));
453
+ }
454
+ }
455
+ const announce = async (context) => {
456
+ const key = sessionKey(context);
457
+ const before = lastListed.get(key);
458
+ if (before === void 0) return;
459
+ const after = [...await visible(checks, context, toolPermission, [...tools.keys()], toolDeclared, true)].toSorted().join(",");
460
+ if (after === before) return;
461
+ lastListed.set(key, after);
462
+ try {
463
+ await (context.mcpReq?.notify?.({ method: "notifications/tools/list_changed" }) ?? inner.sendToolListChanged?.());
464
+ } catch {}
465
+ };
466
+ const guardTool = (tool, permission, reach, load, handler, longRunning) => guard(checks, permission, load, handler, (params) => params.length >= 2 ? [params[0]] : [void 0], toolRefusal, {
467
+ after: announce,
468
+ longRunning,
469
+ capabilities,
470
+ reach,
471
+ tool
472
+ });
473
+ const originalTool = server.registerTool.bind(server);
474
+ const toolPermissionOf = (name, config) => {
475
+ if (enforcement === void 0 || config["permission"] !== void 0) return requirePermission("tool", name, config);
476
+ 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.`);
477
+ return requirePermission("tool", name, { permission: enforcement.permissionFor(name) });
478
+ };
479
+ /** With `enforce: 'procedure'` the handler runs undecided: the procedure it calls decides. */
480
+ const wrapTool = (tool, permission, reach, load, handler, longRunning) => enforcement === void 0 ? guardTool(tool, permission, reach, load, handler, longRunning) : async (...params) => {
481
+ const result = await handler(...params);
482
+ await announce(contextOf(params.at(-1)));
483
+ return result;
484
+ };
485
+ const registerTool = (name, config, handler) => {
486
+ const permission = toolPermissionOf(name, config);
487
+ const { permission: _permission, data, scopeChallenge, longRunning: rawLongRunning, oauthScopes: rawScopes, ...passthrough } = config;
488
+ const load = data;
489
+ const longRunning = rawLongRunning === true;
490
+ const declared = declaredScopes(name, rawScopes === void 0 ? enforcement?.oauthScopesFor?.(name) : rawScopes);
491
+ const reach = reachOf(checks.policy, permission, declared);
492
+ let current = name;
493
+ const tool = () => current;
494
+ const registered = originalTool(name, {
495
+ ...passthrough,
496
+ annotations: {
497
+ ...annotationsFor(permission),
498
+ ...passthrough["annotations"]
499
+ },
500
+ scopeChallenge: challengeFor(scopeChallenge, reach.scopes, reach.challenge)
501
+ }, wrapTool(tool, permission, reach, load, handler, longRunning));
502
+ tools.set(name, permission);
503
+ if (declared !== void 0) toolScopes.set(name, declared);
504
+ guardUpdates(registered, (callback) => wrapTool(tool, permission, reach, load, callback, longRunning), (from, to) => {
505
+ tools.delete(from);
506
+ toolScopes.delete(from);
507
+ if (to !== null) {
508
+ tools.set(to, permission);
509
+ if (declared !== void 0) toolScopes.set(to, declared);
510
+ current = to;
511
+ }
512
+ }, () => current);
513
+ return registered;
514
+ };
515
+ const originalPrompt = server.registerPrompt.bind(server);
516
+ const registerPrompt = (name, config, handler) => {
517
+ const permission = requirePermission("prompt", name, config);
518
+ const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
519
+ const load = data;
520
+ const wrap = (callback) => guard(checks, permission, load, callback, (params) => params.length >= 2 ? [params[0]] : [void 0], throwRefusal, { capabilities });
521
+ const registered = originalPrompt(name, {
522
+ ...passthrough,
523
+ scopeChallenge: challengeFor(scopeChallenge, scopesReaching(checks.policy, permission), challengeScope(checks.policy, permission))
524
+ }, wrap(handler));
525
+ prompts.set(name, permission);
526
+ guardUpdates(registered, wrap);
527
+ return registered;
528
+ };
529
+ const originalResource = server.registerResource.bind(server);
530
+ const registerResource = (name, uriOrTemplate, config, read) => {
531
+ const permission = requirePermission("resource", name, config);
532
+ const { permission: _permission, data, scopeChallenge, ...passthrough } = config;
533
+ const load = data;
534
+ const wrap = (callback) => guard(checks, permission, load, callback, (params) => params.slice(0, -1), throwRefusal, { capabilities });
535
+ const registered = originalResource(name, uriOrTemplate, {
536
+ ...passthrough,
537
+ scopeChallenge: challengeFor(scopeChallenge, scopesReaching(checks.policy, permission), challengeScope(checks.policy, permission))
538
+ }, wrap(read));
539
+ if (typeof uriOrTemplate === "string") resources.set(uriOrTemplate, permission);
540
+ else templates.push({
541
+ template: uriOrTemplate,
542
+ permission
520
543
  });
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;
544
+ guardUpdates(registered, wrap);
545
+ return registered;
546
+ };
547
+ const guarded = server;
548
+ guarded["registerTool"] = registerTool;
549
+ guarded["registerPrompt"] = registerPrompt;
550
+ guarded["registerResource"] = registerResource;
551
+ return server;
552
+ }
553
+ //#endregion
554
+ //#region src/mcp/subject.ts
555
+ const DEFAULT_MCP_ACTOR_KIND = "mcp-client";
556
+ /** `kind`, or the default when absent; `undefined` for a kind that is not a non-empty string. */
557
+ function mcpActorKind(kind) {
558
+ if (kind === void 0) return DEFAULT_MCP_ACTOR_KIND;
559
+ return typeof kind === "string" && kind !== "" ? kind : void 0;
560
+ }
561
+ /**
562
+ * Maps the `AuthInfo` the MCP SDK's bearer verification produced to a
563
+ * `Subject`: the principal from the verified claims in `extra`, the client
564
+ * as an actor of kind `actorKind` (`mcp-client` by default), the granted
565
+ * scopes as the delegation. Never verifies and never throws; anything
566
+ * unusable, including an `actorKind` that is not a non-empty string, is
567
+ * the anonymous subject.
568
+ */
569
+ function subjectFromMcp(authInfo, options = {}) {
570
+ try {
571
+ const kind = mcpActorKind(options.actorKind);
572
+ if (authInfo === void 0 || !isRecord(authInfo.extra) || kind === void 0) return anonymousSubject();
573
+ const claims = compact({
574
+ ...authInfo.extra,
575
+ authorization_details: authInfo.extra["authorizationDetails"] ?? authInfo.extra["authorization_details"],
576
+ scope: authInfo.scopes?.join(" "),
577
+ client_id: authInfo.clientId,
578
+ exp: authInfo.expiresAt
579
+ });
580
+ const mapped = mapClaimsToSubject(claims, options);
581
+ if (mapped.invalidClaims || mapped.invalidChain || mapped.subject.principal === null) return anonymousSubject();
582
+ const clientId = authInfo.clientId;
583
+ return freezeDeep(compact({
584
+ ...mapped.subject,
585
+ actor: typeof clientId === "string" && clientId !== "" ? compact({
586
+ id: clientId,
587
+ kind,
588
+ client: clientNameOf(options.clients, clientId)
589
+ }) : mapped.subject.actor
590
+ }));
591
+ } catch {
592
+ return anonymousSubject();
593
+ }
594
+ }
595
+ //#endregion
596
+ //#region src/mcp/create.ts
597
+ function createPermDock(policy, given) {
598
+ const options = withApp(policy, given);
599
+ const actorKind = mcpActorKind(options.actorKind);
600
+ if (actorKind === void 0) throw new TypeError("permdock/mcp: actorKind must be a non-empty string");
601
+ const checks = {
602
+ policy,
603
+ options,
604
+ kernel: createAgentKernel(policy, compact({
605
+ subject: (call) => options.subject(call.authInfo ?? {}),
606
+ actor: (call) => {
607
+ if (options.actor !== void 0) return options.actor(call.authInfo ?? {});
608
+ const clientId = call.authInfo?.clientId;
609
+ return typeof clientId === "string" && clientId !== "" ? compact({
610
+ id: clientId,
611
+ kind: actorKind,
612
+ client: clientNameOf(options.clients, clientId)
613
+ }) : void 0;
614
+ },
615
+ delegation: (call) => {
616
+ if (options.delegation !== void 0) return options.delegation(call.authInfo ?? {});
617
+ return call.authInfo === void 0 ? void 0 : delegationFrom(call.authInfo.scopes, call.authInfo.extra);
618
+ },
619
+ tenant: tenantOf(options.tenant),
620
+ store: options.store,
621
+ adapter: "mcp",
622
+ boundary: "mcp-args",
623
+ wrap: composeWraps(options.otel, options.wrap),
624
+ context: options.context === void 0 ? void 0 : (call) => options.context?.(call.authInfo ?? {}),
625
+ ...instanceOptions(options)
626
+ }))
599
627
  };
600
- return { protectServer };
628
+ return { protectServer: ((server, enforcement) => protectServer(checks, server, enforcement)) };
601
629
  }
602
630
  //#endregion
603
631
  export { APPROVAL_META_KEY, createPermDock, subjectFromMcp };