@suveren/gateway 0.8.7 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (856) hide show
  1. package/README.md +33 -1
  2. package/bin/suveren-gateway.js +363 -9
  3. package/content/integrations/erp.json +184 -0
  4. package/content/integrations/index.json +2 -1
  5. package/dist/control-plane/index.mjs +835 -118
  6. package/dist/mcp-server/http.mjs +876 -193
  7. package/dist/ui/assets/{index-tzStUGuj.js → index-B1qNl7zo.js} +21 -21
  8. package/dist/ui/index.html +1 -1
  9. package/lib/as-pairing.mjs +77 -0
  10. package/lib/config.d.mts +37 -0
  11. package/lib/config.mjs +198 -0
  12. package/node_modules/@hap/core/dist/index.d.mts +33 -2
  13. package/node_modules/@hap/core/dist/index.d.ts +33 -2
  14. package/node_modules/@hap/core/dist/index.js +26 -2
  15. package/node_modules/@hap/core/dist/index.mjs +25 -2
  16. package/node_modules/@hap/core/package.json +1 -1
  17. package/node_modules/@hap/core/src/gatekeeper.ts +36 -2
  18. package/node_modules/@hap/core/src/types.ts +21 -1
  19. package/node_modules/@hono/node-server/README.md +21 -10
  20. package/node_modules/@hono/node-server/dist/early-hints.cjs +1 -1
  21. package/node_modules/@hono/node-server/dist/early-hints.mjs +1 -1
  22. package/node_modules/@hono/node-server/dist/index.cjs +41 -19
  23. package/node_modules/@hono/node-server/dist/index.mjs +42 -20
  24. package/node_modules/@hono/node-server/dist/serve-static.cjs +1 -0
  25. package/node_modules/@hono/node-server/dist/serve-static.d.cts +2 -1
  26. package/node_modules/@hono/node-server/dist/serve-static.d.mts +2 -1
  27. package/node_modules/@hono/node-server/dist/serve-static.mjs +1 -0
  28. package/node_modules/@hono/node-server/package.json +3 -2
  29. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.d.ts +43 -2
  30. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.d.ts.map +1 -1
  31. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.js +26 -5
  32. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.js.map +1 -1
  33. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.d.ts +11 -0
  34. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.d.ts.map +1 -1
  35. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js +96 -14
  36. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js.map +1 -1
  37. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.d.ts +1 -0
  38. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.d.ts.map +1 -1
  39. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.js +11 -2
  40. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.js.map +1 -1
  41. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/demoInMemoryOAuthProvider.d.ts +2 -0
  42. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/demoInMemoryOAuthProvider.d.ts.map +1 -1
  43. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/providers/proxyProvider.d.ts.map +1 -1
  44. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/providers/proxyProvider.js +6 -3
  45. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/providers/proxyProvider.js.map +1 -1
  46. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.d.ts +3 -0
  47. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.d.ts.map +1 -1
  48. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.js +12 -2
  49. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.js.map +1 -1
  50. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.d.ts +43 -2
  51. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.d.ts.map +1 -1
  52. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.js +26 -5
  53. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.js.map +1 -1
  54. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts +11 -0
  55. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts.map +1 -1
  56. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js +96 -14
  57. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js.map +1 -1
  58. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.d.ts +1 -0
  59. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.d.ts.map +1 -1
  60. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.js +11 -2
  61. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.js.map +1 -1
  62. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/demoInMemoryOAuthProvider.d.ts +2 -0
  63. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/demoInMemoryOAuthProvider.d.ts.map +1 -1
  64. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/providers/proxyProvider.d.ts.map +1 -1
  65. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/providers/proxyProvider.js +6 -3
  66. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/providers/proxyProvider.js.map +1 -1
  67. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.d.ts +3 -0
  68. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.d.ts.map +1 -1
  69. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js +12 -2
  70. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js.map +1 -1
  71. package/node_modules/@modelcontextprotocol/sdk/package.json +1 -1
  72. package/node_modules/@types/node/README.md +1 -1
  73. package/node_modules/@types/node/crypto.d.ts +2 -2
  74. package/node_modules/@types/node/dgram.d.ts +1 -1
  75. package/node_modules/@types/node/package.json +2 -2
  76. package/node_modules/hono/dist/_virtual/_rolldown/runtime.js +13 -0
  77. package/node_modules/hono/dist/adapter/aws-lambda/conninfo.js +42 -23
  78. package/node_modules/hono/dist/adapter/aws-lambda/handler.js +318 -344
  79. package/node_modules/hono/dist/adapter/aws-lambda/index.js +2 -8
  80. package/node_modules/hono/dist/adapter/aws-lambda/types.js +1 -0
  81. package/node_modules/hono/dist/adapter/bun/conninfo.js +20 -25
  82. package/node_modules/hono/dist/adapter/bun/index.js +3 -13
  83. package/node_modules/hono/dist/adapter/bun/serve-static.js +27 -27
  84. package/node_modules/hono/dist/adapter/bun/server.js +11 -5
  85. package/node_modules/hono/dist/adapter/bun/ssg.js +25 -15
  86. package/node_modules/hono/dist/adapter/bun/websocket.js +61 -68
  87. package/node_modules/hono/dist/adapter/cloudflare-pages/conninfo.js +24 -9
  88. package/node_modules/hono/dist/adapter/cloudflare-pages/handler.js +59 -62
  89. package/node_modules/hono/dist/adapter/cloudflare-pages/index.js +2 -8
  90. package/node_modules/hono/dist/adapter/cloudflare-workers/conninfo.js +7 -9
  91. package/node_modules/hono/dist/adapter/cloudflare-workers/index.js +3 -8
  92. package/node_modules/hono/dist/adapter/cloudflare-workers/serve-static-module.js +5 -6
  93. package/node_modules/hono/dist/adapter/cloudflare-workers/serve-static.js +26 -20
  94. package/node_modules/hono/dist/adapter/cloudflare-workers/utils.js +21 -34
  95. package/node_modules/hono/dist/adapter/cloudflare-workers/websocket.js +31 -39
  96. package/node_modules/hono/dist/adapter/deno/conninfo.js +16 -13
  97. package/node_modules/hono/dist/adapter/deno/deno.d.js +1 -0
  98. package/node_modules/hono/dist/adapter/deno/index.js +3 -10
  99. package/node_modules/hono/dist/adapter/deno/serve-static.js +33 -38
  100. package/node_modules/hono/dist/adapter/deno/ssg.js +27 -16
  101. package/node_modules/hono/dist/adapter/deno/websocket.js +30 -30
  102. package/node_modules/hono/dist/adapter/lambda-edge/conninfo.js +7 -9
  103. package/node_modules/hono/dist/adapter/lambda-edge/handler.js +102 -101
  104. package/node_modules/hono/dist/adapter/lambda-edge/index.js +2 -6
  105. package/node_modules/hono/dist/adapter/netlify/conninfo.js +24 -9
  106. package/node_modules/hono/dist/adapter/netlify/handler.js +10 -8
  107. package/node_modules/hono/dist/adapter/netlify/index.js +3 -2
  108. package/node_modules/hono/dist/adapter/netlify/mod.js +2 -6
  109. package/node_modules/hono/dist/adapter/service-worker/handler.js +15 -19
  110. package/node_modules/hono/dist/adapter/service-worker/index.js +23 -7
  111. package/node_modules/hono/dist/adapter/service-worker/types.js +1 -0
  112. package/node_modules/hono/dist/adapter/vercel/conninfo.js +7 -10
  113. package/node_modules/hono/dist/adapter/vercel/handler.js +8 -6
  114. package/node_modules/hono/dist/adapter/vercel/index.js +2 -6
  115. package/node_modules/hono/dist/cjs/_virtual/_rolldown/runtime.js +33 -0
  116. package/node_modules/hono/dist/cjs/adapter/aws-lambda/conninfo.js +42 -44
  117. package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +326 -373
  118. package/node_modules/hono/dist/cjs/adapter/aws-lambda/index.js +7 -34
  119. package/node_modules/hono/dist/cjs/adapter/aws-lambda/types.js +0 -15
  120. package/node_modules/hono/dist/cjs/adapter/bun/conninfo.js +21 -47
  121. package/node_modules/hono/dist/cjs/adapter/bun/index.js +14 -45
  122. package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +29 -50
  123. package/node_modules/hono/dist/cjs/adapter/bun/server.js +11 -26
  124. package/node_modules/hono/dist/cjs/adapter/bun/ssg.js +24 -35
  125. package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +63 -91
  126. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/conninfo.js +25 -31
  127. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/handler.js +61 -85
  128. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/index.js +7 -34
  129. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/conninfo.js +8 -31
  130. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/index.js +7 -33
  131. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/serve-static-module.js +7 -29
  132. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/serve-static.js +27 -42
  133. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/utils.js +21 -55
  134. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/websocket.js +33 -62
  135. package/node_modules/hono/dist/cjs/adapter/deno/conninfo.js +16 -34
  136. package/node_modules/hono/dist/cjs/adapter/deno/index.js +10 -38
  137. package/node_modules/hono/dist/cjs/adapter/deno/serve-static.js +33 -59
  138. package/node_modules/hono/dist/cjs/adapter/deno/ssg.js +27 -37
  139. package/node_modules/hono/dist/cjs/adapter/deno/websocket.js +32 -53
  140. package/node_modules/hono/dist/cjs/adapter/lambda-edge/conninfo.js +8 -31
  141. package/node_modules/hono/dist/cjs/adapter/lambda-edge/handler.js +102 -130
  142. package/node_modules/hono/dist/cjs/adapter/lambda-edge/index.js +5 -30
  143. package/node_modules/hono/dist/cjs/adapter/netlify/conninfo.js +25 -31
  144. package/node_modules/hono/dist/cjs/adapter/netlify/handler.js +10 -29
  145. package/node_modules/hono/dist/cjs/adapter/netlify/index.js +5 -21
  146. package/node_modules/hono/dist/cjs/adapter/netlify/mod.js +5 -30
  147. package/node_modules/hono/dist/cjs/adapter/service-worker/handler.js +16 -41
  148. package/node_modules/hono/dist/cjs/adapter/service-worker/index.js +25 -30
  149. package/node_modules/hono/dist/cjs/adapter/service-worker/types.js +0 -15
  150. package/node_modules/hono/dist/cjs/adapter/vercel/conninfo.js +8 -32
  151. package/node_modules/hono/dist/cjs/adapter/vercel/handler.js +8 -27
  152. package/node_modules/hono/dist/cjs/adapter/vercel/index.js +5 -30
  153. package/node_modules/hono/dist/cjs/client/client.js +139 -212
  154. package/node_modules/hono/dist/cjs/client/fetch-result-please.js +62 -80
  155. package/node_modules/hono/dist/cjs/client/index.js +7 -32
  156. package/node_modules/hono/dist/cjs/client/types.js +0 -15
  157. package/node_modules/hono/dist/cjs/client/utils.js +54 -92
  158. package/node_modules/hono/dist/cjs/compose.js +49 -66
  159. package/node_modules/hono/dist/cjs/context.js +379 -450
  160. package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +47 -72
  161. package/node_modules/hono/dist/cjs/helper/accepts/index.js +3 -27
  162. package/node_modules/hono/dist/cjs/helper/adapter/index.js +33 -73
  163. package/node_modules/hono/dist/cjs/helper/conninfo/index.js +0 -15
  164. package/node_modules/hono/dist/cjs/helper/conninfo/types.js +0 -15
  165. package/node_modules/hono/dist/cjs/helper/cookie/index.js +75 -116
  166. package/node_modules/hono/dist/cjs/helper/css/common.js +165 -244
  167. package/node_modules/hono/dist/cjs/helper/css/index.js +136 -151
  168. package/node_modules/hono/dist/cjs/helper/dev/index.js +45 -71
  169. package/node_modules/hono/dist/cjs/helper/factory/index.js +30 -51
  170. package/node_modules/hono/dist/cjs/helper/html/index.js +32 -62
  171. package/node_modules/hono/dist/cjs/helper/proxy/index.js +113 -106
  172. package/node_modules/hono/dist/cjs/helper/route/index.js +123 -66
  173. package/node_modules/hono/dist/cjs/helper/ssg/index.js +19 -43
  174. package/node_modules/hono/dist/cjs/helper/ssg/middleware.js +56 -64
  175. package/node_modules/hono/dist/cjs/helper/ssg/plugins.js +55 -57
  176. package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +196 -296
  177. package/node_modules/hono/dist/cjs/helper/ssg/utils.js +47 -90
  178. package/node_modules/hono/dist/cjs/helper/streaming/index.js +8 -35
  179. package/node_modules/hono/dist/cjs/helper/streaming/sse.js +53 -85
  180. package/node_modules/hono/dist/cjs/helper/streaming/stream.js +23 -53
  181. package/node_modules/hono/dist/cjs/helper/streaming/text.js +10 -32
  182. package/node_modules/hono/dist/cjs/helper/streaming/utils.js +13 -32
  183. package/node_modules/hono/dist/cjs/helper/testing/index.js +16 -31
  184. package/node_modules/hono/dist/cjs/helper/websocket/index.js +51 -76
  185. package/node_modules/hono/dist/cjs/hono-base.js +345 -403
  186. package/node_modules/hono/dist/cjs/hono.js +28 -42
  187. package/node_modules/hono/dist/cjs/http-exception.js +55 -56
  188. package/node_modules/hono/dist/cjs/index.js +22 -30
  189. package/node_modules/hono/dist/cjs/jsx/base.js +237 -366
  190. package/node_modules/hono/dist/cjs/jsx/children.js +16 -41
  191. package/node_modules/hono/dist/cjs/jsx/components.js +119 -192
  192. package/node_modules/hono/dist/cjs/jsx/constants.js +15 -42
  193. package/node_modules/hono/dist/cjs/jsx/context.js +144 -162
  194. package/node_modules/hono/dist/cjs/jsx/dom/client.js +49 -69
  195. package/node_modules/hono/dist/cjs/jsx/dom/components.js +23 -52
  196. package/node_modules/hono/dist/cjs/jsx/dom/context.js +39 -67
  197. package/node_modules/hono/dist/cjs/jsx/dom/css.js +143 -158
  198. package/node_modules/hono/dist/cjs/jsx/dom/hooks/index.js +55 -64
  199. package/node_modules/hono/dist/cjs/jsx/dom/index.js +114 -173
  200. package/node_modules/hono/dist/cjs/jsx/dom/intrinsic-element/components.js +282 -375
  201. package/node_modules/hono/dist/cjs/jsx/dom/jsx-dev-runtime.js +14 -49
  202. package/node_modules/hono/dist/cjs/jsx/dom/jsx-runtime.js +5 -32
  203. package/node_modules/hono/dist/cjs/jsx/dom/render.js +469 -623
  204. package/node_modules/hono/dist/cjs/jsx/dom/server.js +37 -64
  205. package/node_modules/hono/dist/cjs/jsx/dom/utils.js +7 -30
  206. package/node_modules/hono/dist/cjs/jsx/hooks/index.js +225 -318
  207. package/node_modules/hono/dist/cjs/jsx/index.js +86 -135
  208. package/node_modules/hono/dist/cjs/jsx/intrinsic-element/common.js +20 -43
  209. package/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +117 -168
  210. package/node_modules/hono/dist/cjs/jsx/intrinsic-elements.js +0 -15
  211. package/node_modules/hono/dist/cjs/jsx/jsx-dev-runtime.js +14 -39
  212. package/node_modules/hono/dist/cjs/jsx/jsx-runtime.js +34 -68
  213. package/node_modules/hono/dist/cjs/jsx/streaming.js +123 -166
  214. package/node_modules/hono/dist/cjs/jsx/types.js +0 -15
  215. package/node_modules/hono/dist/cjs/jsx/utils.js +91 -175
  216. package/node_modules/hono/dist/cjs/middleware/basic-auth/index.js +98 -86
  217. package/node_modules/hono/dist/cjs/middleware/bearer-auth/index.js +92 -109
  218. package/node_modules/hono/dist/cjs/middleware/body-limit/index.js +66 -72
  219. package/node_modules/hono/dist/cjs/middleware/cache/index.js +153 -199
  220. package/node_modules/hono/dist/cjs/middleware/combine/index.js +135 -95
  221. package/node_modules/hono/dist/cjs/middleware/compress/index.js +73 -88
  222. package/node_modules/hono/dist/cjs/middleware/context-storage/index.js +49 -41
  223. package/node_modules/hono/dist/cjs/middleware/cors/index.js +107 -107
  224. package/node_modules/hono/dist/cjs/middleware/csrf/index.js +101 -72
  225. package/node_modules/hono/dist/cjs/middleware/etag/digest.js +58 -97
  226. package/node_modules/hono/dist/cjs/middleware/etag/index.js +71 -91
  227. package/node_modules/hono/dist/cjs/middleware/ip-restriction/index.js +161 -169
  228. package/node_modules/hono/dist/cjs/middleware/jsx-renderer/index.js +99 -77
  229. package/node_modules/hono/dist/cjs/middleware/jwk/index.js +3 -27
  230. package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +118 -135
  231. package/node_modules/hono/dist/cjs/middleware/jwt/index.js +9 -38
  232. package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +120 -141
  233. package/node_modules/hono/dist/cjs/middleware/language/index.js +7 -35
  234. package/node_modules/hono/dist/cjs/middleware/language/language.js +184 -182
  235. package/node_modules/hono/dist/cjs/middleware/logger/index.js +41 -62
  236. package/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +82 -88
  237. package/node_modules/hono/dist/cjs/middleware/method-override/index.js +101 -102
  238. package/node_modules/hono/dist/cjs/middleware/powered-by/index.js +23 -30
  239. package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +38 -42
  240. package/node_modules/hono/dist/cjs/middleware/request-id/index.js +3 -27
  241. package/node_modules/hono/dist/cjs/middleware/request-id/request-id.js +34 -42
  242. package/node_modules/hono/dist/cjs/middleware/secure-headers/index.js +4 -29
  243. package/node_modules/hono/dist/cjs/middleware/secure-headers/permissions-policy.js +0 -15
  244. package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +142 -174
  245. package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +56 -93
  246. package/node_modules/hono/dist/cjs/middleware/serve-static/path.js +15 -38
  247. package/node_modules/hono/dist/cjs/middleware/timeout/index.js +40 -45
  248. package/node_modules/hono/dist/cjs/middleware/timing/index.js +7 -35
  249. package/node_modules/hono/dist/cjs/middleware/timing/timing.js +177 -118
  250. package/node_modules/hono/dist/cjs/middleware/trailing-slash/index.js +85 -58
  251. package/node_modules/hono/dist/cjs/preset/quick.js +18 -37
  252. package/node_modules/hono/dist/cjs/preset/tiny.js +15 -33
  253. package/node_modules/hono/dist/cjs/request/constants.js +5 -27
  254. package/node_modules/hono/dist/cjs/request.js +334 -346
  255. package/node_modules/hono/dist/cjs/router/linear-router/index.js +3 -27
  256. package/node_modules/hono/dist/cjs/router/linear-router/router.js +95 -143
  257. package/node_modules/hono/dist/cjs/router/pattern-router/index.js +3 -27
  258. package/node_modules/hono/dist/cjs/router/pattern-router/router.js +41 -63
  259. package/node_modules/hono/dist/cjs/router/reg-exp-router/index.js +7 -34
  260. package/node_modules/hono/dist/cjs/router/reg-exp-router/matcher.js +18 -45
  261. package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +91 -135
  262. package/node_modules/hono/dist/cjs/router/reg-exp-router/prepared-router.js +92 -161
  263. package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +98 -147
  264. package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +73 -89
  265. package/node_modules/hono/dist/cjs/router/smart-router/index.js +3 -27
  266. package/node_modules/hono/dist/cjs/router/smart-router/router.js +49 -79
  267. package/node_modules/hono/dist/cjs/router/trie-router/index.js +3 -27
  268. package/node_modules/hono/dist/cjs/router/trie-router/node.js +134 -186
  269. package/node_modules/hono/dist/cjs/router/trie-router/router.js +15 -39
  270. package/node_modules/hono/dist/cjs/router/utils.js +5 -27
  271. package/node_modules/hono/dist/cjs/router.js +37 -37
  272. package/node_modules/hono/dist/cjs/types.js +5 -28
  273. package/node_modules/hono/dist/cjs/utils/accept.js +177 -225
  274. package/node_modules/hono/dist/cjs/utils/basic-auth.js +16 -40
  275. package/node_modules/hono/dist/cjs/utils/body.js +84 -110
  276. package/node_modules/hono/dist/cjs/utils/buffer.js +43 -91
  277. package/node_modules/hono/dist/cjs/utils/color.js +35 -44
  278. package/node_modules/hono/dist/cjs/utils/compress.js +11 -26
  279. package/node_modules/hono/dist/cjs/utils/concurrent.js +29 -59
  280. package/node_modules/hono/dist/cjs/utils/constants.js +7 -26
  281. package/node_modules/hono/dist/cjs/utils/cookie.js +107 -177
  282. package/node_modules/hono/dist/cjs/utils/crypto.js +30 -61
  283. package/node_modules/hono/dist/cjs/utils/encode.js +31 -48
  284. package/node_modules/hono/dist/cjs/utils/filepath.js +23 -54
  285. package/node_modules/hono/dist/cjs/utils/handler.js +11 -33
  286. package/node_modules/hono/dist/cjs/utils/headers.js +0 -15
  287. package/node_modules/hono/dist/cjs/utils/html.js +96 -137
  288. package/node_modules/hono/dist/cjs/utils/http-status.js +0 -15
  289. package/node_modules/hono/dist/cjs/utils/ipaddr.js +213 -286
  290. package/node_modules/hono/dist/cjs/utils/jwt/index.js +14 -27
  291. package/node_modules/hono/dist/cjs/utils/jwt/jwa.js +25 -42
  292. package/node_modules/hono/dist/cjs/utils/jwt/jws.js +119 -199
  293. package/node_modules/hono/dist/cjs/utils/jwt/jwt.js +122 -206
  294. package/node_modules/hono/dist/cjs/utils/jwt/types.js +122 -159
  295. package/node_modules/hono/dist/cjs/utils/jwt/utf8.js +9 -28
  296. package/node_modules/hono/dist/cjs/utils/mime.js +75 -101
  297. package/node_modules/hono/dist/cjs/utils/stream.js +88 -111
  298. package/node_modules/hono/dist/cjs/utils/types.js +0 -15
  299. package/node_modules/hono/dist/cjs/utils/url.js +185 -234
  300. package/node_modules/hono/dist/cjs/validator/index.js +3 -27
  301. package/node_modules/hono/dist/cjs/validator/utils.js +0 -15
  302. package/node_modules/hono/dist/cjs/validator/validator.js +60 -103
  303. package/node_modules/hono/dist/client/client.js +138 -197
  304. package/node_modules/hono/dist/client/fetch-result-please.js +59 -56
  305. package/node_modules/hono/dist/client/index.js +3 -7
  306. package/node_modules/hono/dist/client/types.js +1 -0
  307. package/node_modules/hono/dist/client/utils.js +51 -68
  308. package/node_modules/hono/dist/compose.js +49 -45
  309. package/node_modules/hono/dist/context.js +376 -426
  310. package/node_modules/hono/dist/helper/accepts/accepts.js +47 -51
  311. package/node_modules/hono/dist/helper/accepts/index.js +1 -4
  312. package/node_modules/hono/dist/helper/adapter/index.js +33 -52
  313. package/node_modules/hono/dist/helper/conninfo/index.js +1 -0
  314. package/node_modules/hono/dist/helper/conninfo/types.js +1 -0
  315. package/node_modules/hono/dist/helper/cookie/index.js +74 -94
  316. package/node_modules/hono/dist/helper/css/common.js +167 -225
  317. package/node_modules/hono/dist/helper/css/index.js +132 -137
  318. package/node_modules/hono/dist/helper/dev/index.js +44 -49
  319. package/node_modules/hono/dist/helper/factory/index.js +27 -27
  320. package/node_modules/hono/dist/helper/html/index.js +30 -39
  321. package/node_modules/hono/dist/helper/proxy/index.js +116 -88
  322. package/node_modules/hono/dist/helper/route/index.js +121 -43
  323. package/node_modules/hono/dist/helper/ssg/index.js +3 -18
  324. package/node_modules/hono/dist/helper/ssg/middleware.js +53 -40
  325. package/node_modules/hono/dist/helper/ssg/plugins.js +55 -36
  326. package/node_modules/hono/dist/helper/ssg/ssg.js +198 -283
  327. package/node_modules/hono/dist/helper/ssg/utils.js +53 -75
  328. package/node_modules/hono/dist/helper/streaming/index.js +2 -8
  329. package/node_modules/hono/dist/helper/streaming/sse.js +50 -61
  330. package/node_modules/hono/dist/helper/streaming/stream.js +22 -31
  331. package/node_modules/hono/dist/helper/streaming/text.js +9 -10
  332. package/node_modules/hono/dist/helper/streaming/utils.js +9 -12
  333. package/node_modules/hono/dist/helper/testing/index.js +16 -10
  334. package/node_modules/hono/dist/helper/websocket/index.js +49 -53
  335. package/node_modules/hono/dist/hono-base.js +342 -379
  336. package/node_modules/hono/dist/hono.js +27 -20
  337. package/node_modules/hono/dist/http-exception.js +53 -33
  338. package/node_modules/hono/dist/index.js +19 -6
  339. package/node_modules/hono/dist/jsx/base.js +231 -340
  340. package/node_modules/hono/dist/jsx/children.js +16 -20
  341. package/node_modules/hono/dist/jsx/components.js +118 -170
  342. package/node_modules/hono/dist/jsx/constants.js +9 -15
  343. package/node_modules/hono/dist/jsx/context.js +153 -150
  344. package/node_modules/hono/dist/jsx/dom/client.js +45 -48
  345. package/node_modules/hono/dist/jsx/dom/components.js +21 -29
  346. package/node_modules/hono/dist/jsx/dom/context.js +37 -44
  347. package/node_modules/hono/dist/jsx/dom/css.js +142 -147
  348. package/node_modules/hono/dist/jsx/dom/hooks/index.js +52 -40
  349. package/node_modules/hono/dist/jsx/dom/index.js +71 -134
  350. package/node_modules/hono/dist/jsx/dom/intrinsic-element/components.js +275 -359
  351. package/node_modules/hono/dist/jsx/dom/jsx-dev-runtime.js +14 -18
  352. package/node_modules/hono/dist/jsx/dom/jsx-runtime.js +2 -8
  353. package/node_modules/hono/dist/jsx/dom/render.js +492 -631
  354. package/node_modules/hono/dist/jsx/dom/server.js +32 -32
  355. package/node_modules/hono/dist/jsx/dom/utils.js +6 -8
  356. package/node_modules/hono/dist/jsx/hooks/index.js +236 -308
  357. package/node_modules/hono/dist/jsx/index.js +45 -98
  358. package/node_modules/hono/dist/jsx/intrinsic-element/common.js +20 -22
  359. package/node_modules/hono/dist/jsx/intrinsic-element/components.js +113 -154
  360. package/node_modules/hono/dist/jsx/intrinsic-elements.js +1 -0
  361. package/node_modules/hono/dist/jsx/jsx-dev-runtime.js +12 -16
  362. package/node_modules/hono/dist/jsx/jsx-runtime.js +29 -42
  363. package/node_modules/hono/dist/jsx/streaming.js +120 -142
  364. package/node_modules/hono/dist/jsx/types.js +1 -0
  365. package/node_modules/hono/dist/jsx/utils.js +105 -168
  366. package/node_modules/hono/dist/middleware/basic-auth/index.js +96 -63
  367. package/node_modules/hono/dist/middleware/bearer-auth/index.js +93 -89
  368. package/node_modules/hono/dist/middleware/body-limit/index.js +66 -51
  369. package/node_modules/hono/dist/middleware/cache/index.js +165 -190
  370. package/node_modules/hono/dist/middleware/combine/index.js +134 -73
  371. package/node_modules/hono/dist/middleware/compress/index.js +75 -69
  372. package/node_modules/hono/dist/middleware/context-storage/index.js +49 -19
  373. package/node_modules/hono/dist/middleware/cors/index.js +107 -86
  374. package/node_modules/hono/dist/middleware/csrf/index.js +103 -53
  375. package/node_modules/hono/dist/middleware/etag/digest.js +59 -77
  376. package/node_modules/hono/dist/middleware/etag/index.js +71 -70
  377. package/node_modules/hono/dist/middleware/ip-restriction/index.js +163 -158
  378. package/node_modules/hono/dist/middleware/jsx-renderer/index.js +97 -54
  379. package/node_modules/hono/dist/middleware/jwk/index.js +1 -4
  380. package/node_modules/hono/dist/middleware/jwk/jwk.js +116 -112
  381. package/node_modules/hono/dist/middleware/jwt/index.js +2 -10
  382. package/node_modules/hono/dist/middleware/jwt/jwt.js +114 -114
  383. package/node_modules/hono/dist/middleware/language/index.js +2 -15
  384. package/node_modules/hono/dist/middleware/language/language.js +180 -157
  385. package/node_modules/hono/dist/middleware/logger/index.js +43 -37
  386. package/node_modules/hono/dist/middleware/method-not-allowed/index.js +81 -66
  387. package/node_modules/hono/dist/middleware/method-override/index.js +101 -81
  388. package/node_modules/hono/dist/middleware/powered-by/index.js +23 -9
  389. package/node_modules/hono/dist/middleware/pretty-json/index.js +39 -22
  390. package/node_modules/hono/dist/middleware/request-id/index.js +1 -4
  391. package/node_modules/hono/dist/middleware/request-id/request-id.js +33 -20
  392. package/node_modules/hono/dist/middleware/secure-headers/index.js +1 -5
  393. package/node_modules/hono/dist/middleware/secure-headers/permissions-policy.js +1 -0
  394. package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +144 -155
  395. package/node_modules/hono/dist/middleware/serve-static/index.js +56 -72
  396. package/node_modules/hono/dist/middleware/serve-static/path.js +15 -17
  397. package/node_modules/hono/dist/middleware/timeout/index.js +40 -23
  398. package/node_modules/hono/dist/middleware/timing/index.js +2 -9
  399. package/node_modules/hono/dist/middleware/timing/timing.js +177 -97
  400. package/node_modules/hono/dist/middleware/trailing-slash/index.js +85 -37
  401. package/node_modules/hono/dist/preset/quick.js +17 -15
  402. package/node_modules/hono/dist/preset/tiny.js +14 -11
  403. package/node_modules/hono/dist/request/constants.js +4 -5
  404. package/node_modules/hono/dist/request.js +328 -319
  405. package/node_modules/hono/dist/router/linear-router/index.js +1 -4
  406. package/node_modules/hono/dist/router/linear-router/router.js +93 -120
  407. package/node_modules/hono/dist/router/pattern-router/index.js +1 -4
  408. package/node_modules/hono/dist/router/pattern-router/router.js +39 -40
  409. package/node_modules/hono/dist/router/reg-exp-router/index.js +1 -7
  410. package/node_modules/hono/dist/router/reg-exp-router/matcher.js +17 -23
  411. package/node_modules/hono/dist/router/reg-exp-router/node.js +87 -110
  412. package/node_modules/hono/dist/router/reg-exp-router/prepared-router.js +89 -137
  413. package/node_modules/hono/dist/router/reg-exp-router/router.js +92 -129
  414. package/node_modules/hono/dist/router/reg-exp-router/trie.js +69 -64
  415. package/node_modules/hono/dist/router/smart-router/index.js +1 -4
  416. package/node_modules/hono/dist/router/smart-router/router.js +46 -55
  417. package/node_modules/hono/dist/router/trie-router/index.js +1 -4
  418. package/node_modules/hono/dist/router/trie-router/node.js +131 -162
  419. package/node_modules/hono/dist/router/trie-router/router.js +11 -14
  420. package/node_modules/hono/dist/router/utils.js +4 -5
  421. package/node_modules/hono/dist/router.js +35 -14
  422. package/node_modules/hono/dist/types/adapter/aws-lambda/conninfo.d.ts +4 -1
  423. package/node_modules/hono/dist/types/adapter/aws-lambda/handler.d.ts +150 -104
  424. package/node_modules/hono/dist/types/adapter/aws-lambda/index.d.ts +4 -8
  425. package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +152 -122
  426. package/node_modules/hono/dist/types/adapter/bun/conninfo.d.ts +4 -1
  427. package/node_modules/hono/dist/types/adapter/bun/index.d.ts +6 -10
  428. package/node_modules/hono/dist/types/adapter/bun/serve-static.d.ts +7 -2
  429. package/node_modules/hono/dist/types/adapter/bun/server.d.ts +4 -5
  430. package/node_modules/hono/dist/types/adapter/bun/ssg.d.ts +5 -1
  431. package/node_modules/hono/dist/types/adapter/bun/websocket.d.ts +31 -16
  432. package/node_modules/hono/dist/types/adapter/cloudflare-pages/conninfo.d.ts +4 -1
  433. package/node_modules/hono/dist/types/adapter/cloudflare-pages/handler.d.ts +29 -17
  434. package/node_modules/hono/dist/types/adapter/cloudflare-pages/index.d.ts +3 -7
  435. package/node_modules/hono/dist/types/adapter/cloudflare-workers/conninfo.d.ts +6 -1
  436. package/node_modules/hono/dist/types/adapter/cloudflare-workers/index.d.ts +4 -7
  437. package/node_modules/hono/dist/types/adapter/cloudflare-workers/serve-static-module.d.ts +5 -2
  438. package/node_modules/hono/dist/types/adapter/cloudflare-workers/serve-static.d.ts +10 -5
  439. package/node_modules/hono/dist/types/adapter/cloudflare-workers/utils.d.ts +10 -2
  440. package/node_modules/hono/dist/types/adapter/cloudflare-workers/websocket.d.ts +6 -1
  441. package/node_modules/hono/dist/types/adapter/deno/conninfo.d.ts +4 -1
  442. package/node_modules/hono/dist/types/adapter/deno/deno.d.ts +1 -0
  443. package/node_modules/hono/dist/types/adapter/deno/index.d.ts +5 -8
  444. package/node_modules/hono/dist/types/adapter/deno/serve-static.d.ts +7 -2
  445. package/node_modules/hono/dist/types/adapter/deno/ssg.d.ts +5 -1
  446. package/node_modules/hono/dist/types/adapter/deno/websocket.d.ts +6 -1
  447. package/node_modules/hono/dist/types/adapter/lambda-edge/conninfo.d.ts +6 -1
  448. package/node_modules/hono/dist/types/adapter/lambda-edge/handler.d.ts +83 -57
  449. package/node_modules/hono/dist/types/adapter/lambda-edge/index.d.ts +3 -7
  450. package/node_modules/hono/dist/types/adapter/netlify/conninfo.d.ts +4 -1
  451. package/node_modules/hono/dist/types/adapter/netlify/handler.d.ts +6 -1
  452. package/node_modules/hono/dist/types/adapter/netlify/index.d.ts +3 -5
  453. package/node_modules/hono/dist/types/adapter/netlify/mod.d.ts +3 -2
  454. package/node_modules/hono/dist/types/adapter/service-worker/handler.d.ts +9 -7
  455. package/node_modules/hono/dist/types/adapter/service-worker/index.d.ts +7 -9
  456. package/node_modules/hono/dist/types/adapter/service-worker/types.d.ts +12 -7
  457. package/node_modules/hono/dist/types/adapter/vercel/conninfo.d.ts +6 -1
  458. package/node_modules/hono/dist/types/adapter/vercel/handler.d.ts +6 -1
  459. package/node_modules/hono/dist/types/adapter/vercel/index.d.ts +3 -6
  460. package/node_modules/hono/dist/types/client/client.d.ts +5 -3
  461. package/node_modules/hono/dist/types/client/fetch-result-please.d.ts +21 -19
  462. package/node_modules/hono/dist/types/client/index.d.ts +5 -7
  463. package/node_modules/hono/dist/types/client/types.d.ts +134 -159
  464. package/node_modules/hono/dist/types/client/utils.d.ts +6 -4
  465. package/node_modules/hono/dist/types/compose.d.ts +4 -2
  466. package/node_modules/hono/dist/types/context.d.ts +335 -335
  467. package/node_modules/hono/dist/types/helper/accepts/accepts.d.ts +11 -9
  468. package/node_modules/hono/dist/types/helper/accepts/index.d.ts +2 -5
  469. package/node_modules/hono/dist/types/helper/adapter/index.d.ts +4 -6
  470. package/node_modules/hono/dist/types/helper/conninfo/index.d.ts +2 -5
  471. package/node_modules/hono/dist/types/helper/conninfo/types.d.ts +25 -23
  472. package/node_modules/hono/dist/types/helper/cookie/index.d.ts +10 -12
  473. package/node_modules/hono/dist/types/helper/css/common.d.ts +11 -9
  474. package/node_modules/hono/dist/types/helper/css/index.d.ts +26 -28
  475. package/node_modules/hono/dist/types/helper/dev/index.d.ts +10 -12
  476. package/node_modules/hono/dist/types/helper/factory/index.d.ts +26 -73
  477. package/node_modules/hono/dist/types/helper/html/index.d.ts +4 -7
  478. package/node_modules/hono/dist/types/helper/proxy/index.d.ts +19 -21
  479. package/node_modules/hono/dist/types/helper/route/index.d.ts +4 -2
  480. package/node_modules/hono/dist/types/helper/ssg/index.d.ts +4 -7
  481. package/node_modules/hono/dist/types/helper/ssg/middleware.d.ts +8 -6
  482. package/node_modules/hono/dist/types/helper/ssg/plugins.d.ts +3 -1
  483. package/node_modules/hono/dist/types/helper/ssg/ssg.d.ts +38 -36
  484. package/node_modules/hono/dist/types/helper/ssg/utils.d.ts +5 -3
  485. package/node_modules/hono/dist/types/helper/streaming/index.d.ts +4 -8
  486. package/node_modules/hono/dist/types/helper/streaming/sse.d.ts +10 -8
  487. package/node_modules/hono/dist/types/helper/streaming/stream.d.ts +4 -2
  488. package/node_modules/hono/dist/types/helper/streaming/text.d.ts +4 -2
  489. package/node_modules/hono/dist/types/helper/streaming/utils.d.ts +2 -0
  490. package/node_modules/hono/dist/types/helper/testing/index.d.ts +7 -9
  491. package/node_modules/hono/dist/types/helper/websocket/index.d.ts +30 -33
  492. package/node_modules/hono/dist/types/hono-base.d.ts +208 -210
  493. package/node_modules/hono/dist/types/hono.d.ts +11 -10
  494. package/node_modules/hono/dist/types/http-exception.d.ts +20 -22
  495. package/node_modules/hono/dist/types/index.d.ts +6 -37
  496. package/node_modules/hono/dist/types/jsx/base.d.ts +36 -34
  497. package/node_modules/hono/dist/types/jsx/children.d.ts +8 -6
  498. package/node_modules/hono/dist/types/jsx/components.d.ts +8 -5
  499. package/node_modules/hono/dist/types/jsx/constants.d.ts +2 -0
  500. package/node_modules/hono/dist/types/jsx/context.d.ts +9 -6
  501. package/node_modules/hono/dist/types/jsx/dom/client.d.ts +9 -10
  502. package/node_modules/hono/dist/types/jsx/dom/components.d.ts +9 -6
  503. package/node_modules/hono/dist/types/jsx/dom/context.d.ts +3 -1
  504. package/node_modules/hono/dist/types/jsx/dom/css.d.ts +27 -30
  505. package/node_modules/hono/dist/types/jsx/dom/hooks/index.d.ts +11 -12
  506. package/node_modules/hono/dist/types/jsx/dom/index.d.ts +79 -83
  507. package/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +9 -5
  508. package/node_modules/hono/dist/types/jsx/dom/jsx-dev-runtime.d.ts +4 -6
  509. package/node_modules/hono/dist/types/jsx/dom/jsx-runtime.d.ts +3 -7
  510. package/node_modules/hono/dist/types/jsx/dom/render.d.ts +32 -50
  511. package/node_modules/hono/dist/types/jsx/dom/server.d.ts +87 -85
  512. package/node_modules/hono/dist/types/jsx/dom/utils.d.ts +2 -0
  513. package/node_modules/hono/dist/types/jsx/hooks/index.d.ts +16 -16
  514. package/node_modules/hono/dist/types/jsx/index.d.ts +71 -73
  515. package/node_modules/hono/dist/types/jsx/intrinsic-element/common.d.ts +3 -1
  516. package/node_modules/hono/dist/types/jsx/intrinsic-element/components.d.ts +7 -4
  517. package/node_modules/hono/dist/types/jsx/intrinsic-elements.d.ts +708 -708
  518. package/node_modules/hono/dist/types/jsx/jsx-dev-runtime.d.ts +4 -7
  519. package/node_modules/hono/dist/types/jsx/jsx-runtime.d.ts +7 -10
  520. package/node_modules/hono/dist/types/jsx/streaming.d.ts +9 -10
  521. package/node_modules/hono/dist/types/jsx/types.d.ts +12 -13
  522. package/node_modules/hono/dist/types/jsx/utils.d.ts +2 -0
  523. package/node_modules/hono/dist/types/middleware/basic-auth/index.d.ts +17 -19
  524. package/node_modules/hono/dist/types/middleware/bearer-auth/index.d.ts +46 -48
  525. package/node_modules/hono/dist/types/middleware/body-limit/index.d.ts +6 -8
  526. package/node_modules/hono/dist/types/middleware/cache/index.d.ts +13 -15
  527. package/node_modules/hono/dist/types/middleware/combine/index.d.ts +4 -6
  528. package/node_modules/hono/dist/types/middleware/compress/index.d.ts +9 -10
  529. package/node_modules/hono/dist/types/middleware/context-storage/index.d.ts +4 -6
  530. package/node_modules/hono/dist/types/middleware/cors/index.d.ts +10 -12
  531. package/node_modules/hono/dist/types/middleware/csrf/index.d.ts +6 -8
  532. package/node_modules/hono/dist/types/middleware/etag/digest.d.ts +2 -0
  533. package/node_modules/hono/dist/types/middleware/etag/index.d.ts +6 -8
  534. package/node_modules/hono/dist/types/middleware/ip-restriction/index.d.ts +11 -12
  535. package/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +11 -11
  536. package/node_modules/hono/dist/types/middleware/jwk/index.d.ts +2 -1
  537. package/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +20 -23
  538. package/node_modules/hono/dist/types/middleware/jwt/index.d.ts +7 -6
  539. package/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +28 -30
  540. package/node_modules/hono/dist/types/middleware/language/index.d.ts +6 -5
  541. package/node_modules/hono/dist/types/middleware/language/language.d.ts +42 -44
  542. package/node_modules/hono/dist/types/middleware/logger/index.d.ts +3 -5
  543. package/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +7 -9
  544. package/node_modules/hono/dist/types/middleware/method-override/index.d.ts +14 -16
  545. package/node_modules/hono/dist/types/middleware/powered-by/index.d.ts +8 -10
  546. package/node_modules/hono/dist/types/middleware/pretty-json/index.d.ts +18 -20
  547. package/node_modules/hono/dist/types/middleware/request-id/index.d.ts +6 -5
  548. package/node_modules/hono/dist/types/middleware/request-id/request-id.d.ts +9 -11
  549. package/node_modules/hono/dist/types/middleware/secure-headers/index.d.ts +6 -6
  550. package/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +2 -0
  551. package/node_modules/hono/dist/types/middleware/secure-headers/secure-headers.d.ts +55 -57
  552. package/node_modules/hono/dist/types/middleware/serve-static/index.d.ts +24 -24
  553. package/node_modules/hono/dist/types/middleware/serve-static/path.d.ts +2 -0
  554. package/node_modules/hono/dist/types/middleware/timeout/index.d.ts +5 -7
  555. package/node_modules/hono/dist/types/middleware/timing/index.d.ts +6 -5
  556. package/node_modules/hono/dist/types/middleware/timing/timing.d.ts +17 -20
  557. package/node_modules/hono/dist/types/middleware/trailing-slash/index.d.ts +35 -37
  558. package/node_modules/hono/dist/types/preset/quick.d.ts +6 -9
  559. package/node_modules/hono/dist/types/preset/tiny.d.ts +6 -9
  560. package/node_modules/hono/dist/types/request/constants.d.ts +2 -0
  561. package/node_modules/hono/dist/types/request.d.ts +288 -286
  562. package/node_modules/hono/dist/types/router/linear-router/index.d.ts +2 -5
  563. package/node_modules/hono/dist/types/router/linear-router/router.d.ts +7 -5
  564. package/node_modules/hono/dist/types/router/pattern-router/index.d.ts +2 -5
  565. package/node_modules/hono/dist/types/router/pattern-router/router.d.ts +7 -5
  566. package/node_modules/hono/dist/types/router/reg-exp-router/index.d.ts +3 -6
  567. package/node_modules/hono/dist/types/router/reg-exp-router/matcher.d.ts +3 -1
  568. package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +6 -4
  569. package/node_modules/hono/dist/types/router/reg-exp-router/prepared-router.d.ts +11 -10
  570. package/node_modules/hono/dist/types/router/reg-exp-router/router.d.ts +10 -9
  571. package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +7 -5
  572. package/node_modules/hono/dist/types/router/smart-router/index.d.ts +2 -5
  573. package/node_modules/hono/dist/types/router/smart-router/router.d.ts +11 -9
  574. package/node_modules/hono/dist/types/router/trie-router/index.d.ts +2 -5
  575. package/node_modules/hono/dist/types/router/trie-router/node.d.ts +6 -4
  576. package/node_modules/hono/dist/types/router/trie-router/router.d.ts +7 -5
  577. package/node_modules/hono/dist/types/router/utils.d.ts +2 -0
  578. package/node_modules/hono/dist/types/router.d.ts +23 -22
  579. package/node_modules/hono/dist/types/types.d.ts +146 -505
  580. package/node_modules/hono/dist/types/utils/accept.d.ts +5 -3
  581. package/node_modules/hono/dist/types/utils/basic-auth.d.ts +4 -2
  582. package/node_modules/hono/dist/types/utils/body.d.ts +46 -50
  583. package/node_modules/hono/dist/types/utils/buffer.d.ts +7 -5
  584. package/node_modules/hono/dist/types/utils/color.d.ts +2 -0
  585. package/node_modules/hono/dist/types/utils/compress.d.ts +2 -0
  586. package/node_modules/hono/dist/types/utils/concurrent.d.ts +6 -4
  587. package/node_modules/hono/dist/types/utils/constants.d.ts +2 -0
  588. package/node_modules/hono/dist/types/utils/cookie.d.ts +20 -18
  589. package/node_modules/hono/dist/types/utils/crypto.d.ts +5 -7
  590. package/node_modules/hono/dist/types/utils/encode.d.ts +2 -0
  591. package/node_modules/hono/dist/types/utils/filepath.d.ts +5 -3
  592. package/node_modules/hono/dist/types/utils/handler.d.ts +2 -0
  593. package/node_modules/hono/dist/types/utils/headers.d.ts +2 -0
  594. package/node_modules/hono/dist/types/utils/html.d.ts +11 -9
  595. package/node_modules/hono/dist/types/utils/http-status.d.ts +2 -0
  596. package/node_modules/hono/dist/types/utils/ipaddr.d.ts +4 -6
  597. package/node_modules/hono/dist/types/utils/jwt/index.d.ts +18 -12
  598. package/node_modules/hono/dist/types/utils/jwt/jwa.d.ts +15 -13
  599. package/node_modules/hono/dist/types/utils/jwt/jws.d.ts +4 -7
  600. package/node_modules/hono/dist/types/utils/jwt/jwt.d.ts +26 -29
  601. package/node_modules/hono/dist/types/utils/jwt/types.d.ts +48 -45
  602. package/node_modules/hono/dist/types/utils/jwt/utf8.d.ts +2 -0
  603. package/node_modules/hono/dist/types/utils/mime.d.ts +60 -57
  604. package/node_modules/hono/dist/types/utils/stream.d.ts +27 -25
  605. package/node_modules/hono/dist/types/utils/types.d.ts +14 -26
  606. package/node_modules/hono/dist/types/utils/url.d.ts +2 -0
  607. package/node_modules/hono/dist/types/validator/index.d.ts +3 -7
  608. package/node_modules/hono/dist/types/validator/utils.d.ts +6 -8
  609. package/node_modules/hono/dist/types/validator/validator.d.ts +11 -9
  610. package/node_modules/hono/dist/types.js +4 -6
  611. package/node_modules/hono/dist/utils/accept.js +185 -212
  612. package/node_modules/hono/dist/utils/basic-auth.js +18 -21
  613. package/node_modules/hono/dist/utils/body.js +87 -92
  614. package/node_modules/hono/dist/utils/buffer.js +44 -71
  615. package/node_modules/hono/dist/utils/color.js +33 -21
  616. package/node_modules/hono/dist/utils/compress.js +11 -5
  617. package/node_modules/hono/dist/utils/concurrent.js +29 -38
  618. package/node_modules/hono/dist/utils/constants.js +7 -5
  619. package/node_modules/hono/dist/utils/cookie.js +114 -163
  620. package/node_modules/hono/dist/utils/crypto.js +30 -40
  621. package/node_modules/hono/dist/utils/encode.js +30 -26
  622. package/node_modules/hono/dist/utils/filepath.js +23 -33
  623. package/node_modules/hono/dist/utils/handler.js +10 -11
  624. package/node_modules/hono/dist/utils/headers.js +1 -0
  625. package/node_modules/hono/dist/utils/html.js +97 -117
  626. package/node_modules/hono/dist/utils/http-status.js +1 -0
  627. package/node_modules/hono/dist/utils/ipaddr.js +227 -279
  628. package/node_modules/hono/dist/utils/jwt/index.js +12 -4
  629. package/node_modules/hono/dist/utils/jwt/jwa.js +24 -20
  630. package/node_modules/hono/dist/utils/jwt/jws.js +115 -174
  631. package/node_modules/hono/dist/utils/jwt/jwt.js +120 -198
  632. package/node_modules/hono/dist/utils/jwt/types.js +79 -95
  633. package/node_modules/hono/dist/utils/jwt/utf8.js +9 -7
  634. package/node_modules/hono/dist/utils/mime.js +74 -79
  635. package/node_modules/hono/dist/utils/stream.js +86 -88
  636. package/node_modules/hono/dist/utils/types.js +1 -0
  637. package/node_modules/hono/dist/utils/url.js +187 -215
  638. package/node_modules/hono/dist/validator/index.js +1 -4
  639. package/node_modules/hono/dist/validator/utils.js +1 -0
  640. package/node_modules/hono/dist/validator/validator.js +61 -83
  641. package/node_modules/hono/package.json +27 -27
  642. package/node_modules/undici/LICENSE +21 -0
  643. package/node_modules/undici/README.md +741 -0
  644. package/node_modules/undici/docs/docs/api/Agent.md +84 -0
  645. package/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
  646. package/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
  647. package/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
  648. package/node_modules/undici/docs/docs/api/Client.md +288 -0
  649. package/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
  650. package/node_modules/undici/docs/docs/api/Connector.md +115 -0
  651. package/node_modules/undici/docs/docs/api/ContentType.md +57 -0
  652. package/node_modules/undici/docs/docs/api/Cookies.md +128 -0
  653. package/node_modules/undici/docs/docs/api/Debug.md +62 -0
  654. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +317 -0
  655. package/node_modules/undici/docs/docs/api/Dispatcher.md +1393 -0
  656. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  657. package/node_modules/undici/docs/docs/api/Errors.md +49 -0
  658. package/node_modules/undici/docs/docs/api/EventSource.md +45 -0
  659. package/node_modules/undici/docs/docs/api/Fetch.md +60 -0
  660. package/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
  661. package/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
  662. package/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
  663. package/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
  664. package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
  665. package/node_modules/undici/docs/docs/api/MockClient.md +81 -0
  666. package/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
  667. package/node_modules/undici/docs/docs/api/MockPool.md +555 -0
  668. package/node_modules/undici/docs/docs/api/Pool.md +84 -0
  669. package/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
  670. package/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
  671. package/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
  672. package/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
  673. package/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
  674. package/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
  675. package/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
  676. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +275 -0
  677. package/node_modules/undici/docs/docs/api/Util.md +25 -0
  678. package/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
  679. package/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
  680. package/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
  681. package/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
  682. package/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
  683. package/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
  684. package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
  685. package/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
  686. package/node_modules/undici/index-fetch.js +65 -0
  687. package/node_modules/undici/index.d.ts +3 -0
  688. package/node_modules/undici/index.js +234 -0
  689. package/node_modules/undici/lib/api/abort-signal.js +59 -0
  690. package/node_modules/undici/lib/api/api-connect.js +110 -0
  691. package/node_modules/undici/lib/api/api-pipeline.js +252 -0
  692. package/node_modules/undici/lib/api/api-request.js +214 -0
  693. package/node_modules/undici/lib/api/api-stream.js +209 -0
  694. package/node_modules/undici/lib/api/api-upgrade.js +111 -0
  695. package/node_modules/undici/lib/api/index.js +7 -0
  696. package/node_modules/undici/lib/api/readable.js +580 -0
  697. package/node_modules/undici/lib/cache/memory-cache-store.js +279 -0
  698. package/node_modules/undici/lib/cache/sqlite-cache-store.js +467 -0
  699. package/node_modules/undici/lib/core/connect.js +153 -0
  700. package/node_modules/undici/lib/core/constants.js +143 -0
  701. package/node_modules/undici/lib/core/diagnostics.js +227 -0
  702. package/node_modules/undici/lib/core/errors.js +477 -0
  703. package/node_modules/undici/lib/core/request.js +485 -0
  704. package/node_modules/undici/lib/core/socks5-client.js +422 -0
  705. package/node_modules/undici/lib/core/socks5-utils.js +212 -0
  706. package/node_modules/undici/lib/core/symbols.js +75 -0
  707. package/node_modules/undici/lib/core/tree.js +160 -0
  708. package/node_modules/undici/lib/core/util.js +992 -0
  709. package/node_modules/undici/lib/dispatcher/agent.js +158 -0
  710. package/node_modules/undici/lib/dispatcher/balanced-pool.js +221 -0
  711. package/node_modules/undici/lib/dispatcher/client-h1.js +1746 -0
  712. package/node_modules/undici/lib/dispatcher/client-h2.js +1060 -0
  713. package/node_modules/undici/lib/dispatcher/client.js +668 -0
  714. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +184 -0
  715. package/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  716. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
  717. package/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
  718. package/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
  719. package/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
  720. package/node_modules/undici/lib/dispatcher/pool.js +118 -0
  721. package/node_modules/undici/lib/dispatcher/proxy-agent.js +319 -0
  722. package/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  723. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
  724. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +260 -0
  725. package/node_modules/undici/lib/encoding/index.js +33 -0
  726. package/node_modules/undici/lib/global.js +59 -0
  727. package/node_modules/undici/lib/handler/cache-handler.js +776 -0
  728. package/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  729. package/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  730. package/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
  731. package/node_modules/undici/lib/handler/redirect-handler.js +238 -0
  732. package/node_modules/undici/lib/handler/retry-handler.js +504 -0
  733. package/node_modules/undici/lib/handler/unwrap-handler.js +106 -0
  734. package/node_modules/undici/lib/handler/wrap-handler.js +105 -0
  735. package/node_modules/undici/lib/interceptor/cache.js +621 -0
  736. package/node_modules/undici/lib/interceptor/decompress.js +551 -0
  737. package/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
  738. package/node_modules/undici/lib/interceptor/dns.js +571 -0
  739. package/node_modules/undici/lib/interceptor/dump.js +99 -0
  740. package/node_modules/undici/lib/interceptor/redirect.js +21 -0
  741. package/node_modules/undici/lib/interceptor/response-error.js +95 -0
  742. package/node_modules/undici/lib/interceptor/retry.js +19 -0
  743. package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  744. package/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
  745. package/node_modules/undici/lib/llhttp/constants.js +531 -0
  746. package/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  747. package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  748. package/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  749. package/node_modules/undici/lib/llhttp/utils.js +12 -0
  750. package/node_modules/undici/lib/mock/mock-agent.js +232 -0
  751. package/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  752. package/node_modules/undici/lib/mock/mock-client.js +68 -0
  753. package/node_modules/undici/lib/mock/mock-errors.js +29 -0
  754. package/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  755. package/node_modules/undici/lib/mock/mock-pool.js +68 -0
  756. package/node_modules/undici/lib/mock/mock-symbols.js +32 -0
  757. package/node_modules/undici/lib/mock/mock-utils.js +486 -0
  758. package/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  759. package/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
  760. package/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
  761. package/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
  762. package/node_modules/undici/lib/util/cache.js +676 -0
  763. package/node_modules/undici/lib/util/date.js +670 -0
  764. package/node_modules/undici/lib/util/promise.js +28 -0
  765. package/node_modules/undici/lib/util/runtime-features.js +124 -0
  766. package/node_modules/undici/lib/util/stats.js +32 -0
  767. package/node_modules/undici/lib/util/timers.js +425 -0
  768. package/node_modules/undici/lib/web/cache/cache.js +864 -0
  769. package/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  770. package/node_modules/undici/lib/web/cache/util.js +45 -0
  771. package/node_modules/undici/lib/web/cookies/constants.js +12 -0
  772. package/node_modules/undici/lib/web/cookies/index.js +199 -0
  773. package/node_modules/undici/lib/web/cookies/parse.js +314 -0
  774. package/node_modules/undici/lib/web/cookies/util.js +352 -0
  775. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +494 -0
  776. package/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
  777. package/node_modules/undici/lib/web/eventsource/util.js +29 -0
  778. package/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  779. package/node_modules/undici/lib/web/fetch/body.js +509 -0
  780. package/node_modules/undici/lib/web/fetch/constants.js +131 -0
  781. package/node_modules/undici/lib/web/fetch/data-url.js +596 -0
  782. package/node_modules/undici/lib/web/fetch/formdata-parser.js +586 -0
  783. package/node_modules/undici/lib/web/fetch/formdata.js +259 -0
  784. package/node_modules/undici/lib/web/fetch/global.js +40 -0
  785. package/node_modules/undici/lib/web/fetch/headers.js +719 -0
  786. package/node_modules/undici/lib/web/fetch/index.js +2413 -0
  787. package/node_modules/undici/lib/web/fetch/request.js +1115 -0
  788. package/node_modules/undici/lib/web/fetch/response.js +641 -0
  789. package/node_modules/undici/lib/web/fetch/util.js +1522 -0
  790. package/node_modules/undici/lib/web/infra/index.js +229 -0
  791. package/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
  792. package/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  793. package/node_modules/undici/lib/web/webidl/index.js +1006 -0
  794. package/node_modules/undici/lib/web/websocket/connection.js +339 -0
  795. package/node_modules/undici/lib/web/websocket/constants.js +126 -0
  796. package/node_modules/undici/lib/web/websocket/events.js +331 -0
  797. package/node_modules/undici/lib/web/websocket/frame.js +133 -0
  798. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +105 -0
  799. package/node_modules/undici/lib/web/websocket/receiver.js +507 -0
  800. package/node_modules/undici/lib/web/websocket/sender.js +109 -0
  801. package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
  802. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +496 -0
  803. package/node_modules/undici/lib/web/websocket/util.js +347 -0
  804. package/node_modules/undici/lib/web/websocket/websocket.js +758 -0
  805. package/node_modules/undici/package.json +152 -0
  806. package/node_modules/undici/scripts/strip-comments.js +10 -0
  807. package/node_modules/undici/types/README.md +6 -0
  808. package/node_modules/undici/types/agent.d.ts +32 -0
  809. package/node_modules/undici/types/api.d.ts +43 -0
  810. package/node_modules/undici/types/balanced-pool.d.ts +30 -0
  811. package/node_modules/undici/types/cache-interceptor.d.ts +179 -0
  812. package/node_modules/undici/types/cache.d.ts +36 -0
  813. package/node_modules/undici/types/client-stats.d.ts +15 -0
  814. package/node_modules/undici/types/client.d.ts +139 -0
  815. package/node_modules/undici/types/connector.d.ts +36 -0
  816. package/node_modules/undici/types/content-type.d.ts +21 -0
  817. package/node_modules/undici/types/cookies.d.ts +30 -0
  818. package/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
  819. package/node_modules/undici/types/dispatcher.d.ts +275 -0
  820. package/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
  821. package/node_modules/undici/types/errors.d.ts +177 -0
  822. package/node_modules/undici/types/eventsource.d.ts +66 -0
  823. package/node_modules/undici/types/fetch.d.ts +231 -0
  824. package/node_modules/undici/types/formdata.d.ts +114 -0
  825. package/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  826. package/node_modules/undici/types/global-origin.d.ts +7 -0
  827. package/node_modules/undici/types/h2c-client.d.ts +73 -0
  828. package/node_modules/undici/types/handlers.d.ts +14 -0
  829. package/node_modules/undici/types/header.d.ts +160 -0
  830. package/node_modules/undici/types/index.d.ts +91 -0
  831. package/node_modules/undici/types/interceptors.d.ts +82 -0
  832. package/node_modules/undici/types/mock-agent.d.ts +68 -0
  833. package/node_modules/undici/types/mock-call-history.d.ts +111 -0
  834. package/node_modules/undici/types/mock-client.d.ts +27 -0
  835. package/node_modules/undici/types/mock-errors.d.ts +12 -0
  836. package/node_modules/undici/types/mock-interceptor.d.ts +94 -0
  837. package/node_modules/undici/types/mock-pool.d.ts +27 -0
  838. package/node_modules/undici/types/patch.d.ts +29 -0
  839. package/node_modules/undici/types/pool-stats.d.ts +19 -0
  840. package/node_modules/undici/types/pool.d.ts +41 -0
  841. package/node_modules/undici/types/proxy-agent.d.ts +29 -0
  842. package/node_modules/undici/types/readable.d.ts +68 -0
  843. package/node_modules/undici/types/retry-agent.d.ts +8 -0
  844. package/node_modules/undici/types/retry-handler.d.ts +125 -0
  845. package/node_modules/undici/types/round-robin-pool.d.ts +41 -0
  846. package/node_modules/undici/types/snapshot-agent.d.ts +109 -0
  847. package/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
  848. package/node_modules/undici/types/util.d.ts +18 -0
  849. package/node_modules/undici/types/utility.d.ts +7 -0
  850. package/node_modules/undici/types/webidl.d.ts +347 -0
  851. package/node_modules/undici/types/websocket.d.ts +188 -0
  852. package/package.json +5 -3
  853. package/profiles/README.md +20 -0
  854. package/profiles/index.json +2 -1
  855. package/profiles/sales/0.1.profile.json +252 -0
  856. package/server.js +99 -0
@@ -112,6 +112,262 @@ function clientVersionHeaders() {
112
112
  };
113
113
  }
114
114
 
115
+ // src/lib/as-pairing.ts
116
+ import { createHash } from "crypto";
117
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, unlinkSync, writeFileSync } from "fs";
118
+ import { dirname, join as join2 } from "path";
119
+ function pairingPath(dataDir2) {
120
+ return join2(dataDir2, "as-pairing.json");
121
+ }
122
+ function readPairing(dataDir2) {
123
+ const path = pairingPath(dataDir2);
124
+ if (!existsSync2(path)) return null;
125
+ try {
126
+ const data = JSON.parse(readFileSync2(path, "utf-8"));
127
+ if (typeof data.asUrl !== "string" || typeof data.publicKeyHex !== "string") return null;
128
+ return {
129
+ asUrl: data.asUrl,
130
+ publicKeyHex: data.publicKeyHex,
131
+ pairedAt: data.pairedAt ?? "",
132
+ ...typeof data.tlsSpkiPinHex === "string" ? { tlsSpkiPinHex: data.tlsSpkiPinHex } : {}
133
+ };
134
+ } catch {
135
+ return null;
136
+ }
137
+ }
138
+ function fingerprintOf(publicKeyHex) {
139
+ const raw = Buffer.from(publicKeyHex, "hex");
140
+ const digest = createHash("sha256").update(raw).digest("hex").toUpperCase();
141
+ return digest.match(/.{1,4}/g)?.join(":") ?? digest;
142
+ }
143
+
144
+ // src/lib/as-config.ts
145
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
146
+ import { dirname as dirname2, join as join3 } from "path";
147
+ var DEFAULT_AS_URL = "https://www.suveren.ai";
148
+ function configPath(dataDir2) {
149
+ return join3(dataDir2, "config.json");
150
+ }
151
+ function readAsConfigStrict(dataDir2) {
152
+ const path = configPath(dataDir2);
153
+ if (!existsSync3(path)) return {};
154
+ let data;
155
+ try {
156
+ data = JSON.parse(readFileSync3(path, "utf-8"));
157
+ } catch (err) {
158
+ throw new Error(
159
+ `Could not parse ${path}: ${err instanceof Error ? err.message : String(err)}`
160
+ );
161
+ }
162
+ const out = {};
163
+ if (typeof data.asUrl === "string") out.asUrl = data.asUrl;
164
+ if (typeof data.caFile === "string") out.caFile = data.caFile;
165
+ if (typeof data.pinTls === "boolean") out.pinTls = data.pinTls;
166
+ if (typeof data.pinTlsExpectedFingerprint === "string") out.pinTlsExpectedFingerprint = data.pinTlsExpectedFingerprint;
167
+ return out;
168
+ }
169
+ function readAsConfig(dataDir2) {
170
+ const path = configPath(dataDir2);
171
+ if (!existsSync3(path)) return {};
172
+ try {
173
+ const data = JSON.parse(readFileSync3(path, "utf-8"));
174
+ const out = {};
175
+ if (typeof data.asUrl === "string") out.asUrl = data.asUrl;
176
+ if (typeof data.caFile === "string") out.caFile = data.caFile;
177
+ if (typeof data.pinTls === "boolean") out.pinTls = data.pinTls;
178
+ if (typeof data.pinTlsExpectedFingerprint === "string") out.pinTlsExpectedFingerprint = data.pinTlsExpectedFingerprint;
179
+ return out;
180
+ } catch {
181
+ return {};
182
+ }
183
+ }
184
+ function validateAsUrl(candidate) {
185
+ const trimmed = candidate.trim();
186
+ if (!trimmed) return { ok: false, error: "The Authority Server URL is empty." };
187
+ let parsed;
188
+ try {
189
+ parsed = new URL(trimmed);
190
+ } catch {
191
+ return { ok: false, error: `"${trimmed}" is not a valid URL.` };
192
+ }
193
+ const isLocalHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
194
+ if (parsed.protocol !== "https:" && !isLocalHttp) {
195
+ return {
196
+ ok: false,
197
+ error: `"${trimmed}" must use https:// (http:// is only allowed for http://localhost or http://127.0.0.1).`
198
+ };
199
+ }
200
+ let normalized = `${parsed.origin}${parsed.pathname}${parsed.search}${parsed.hash}`;
201
+ if (normalized.endsWith("/") && normalized !== `${parsed.origin}/`) {
202
+ normalized = normalized.slice(0, -1);
203
+ } else if (normalized === `${parsed.origin}/`) {
204
+ normalized = parsed.origin;
205
+ }
206
+ return { ok: true, url: normalized };
207
+ }
208
+ function resolveAsUrl(dataDir2, flag) {
209
+ if (flag) {
210
+ const v = validateAsUrl(flag);
211
+ if (!v.ok) throw new Error(`Invalid --as-url: ${v.error}`);
212
+ return v.url;
213
+ }
214
+ const envUrl = process.env.SUVEREN_AS_URL;
215
+ if (envUrl) {
216
+ const v = validateAsUrl(envUrl);
217
+ if (!v.ok) throw new Error(`Invalid SUVEREN_AS_URL: ${v.error}`);
218
+ return v.url;
219
+ }
220
+ const saved = readAsConfigStrict(dataDir2).asUrl;
221
+ if (saved) {
222
+ const v = validateAsUrl(saved);
223
+ if (!v.ok) throw new Error(`Invalid saved as-url "${saved}" in ${dataDir2}/config.json: ${v.error}`);
224
+ return v.url;
225
+ }
226
+ return DEFAULT_AS_URL;
227
+ }
228
+ function resolvePinTls(dataDir2) {
229
+ return readAsConfig(dataDir2).pinTls === true;
230
+ }
231
+ function validatePinTlsForUrl(pinTls, asUrl) {
232
+ if (!pinTls) return;
233
+ if (!asUrl.startsWith("https:")) {
234
+ throw new Error(
235
+ `config.json sets "pinTls": true, but the Authority Server URL (${asUrl}) is not https:// \u2014 there is no TLS certificate to pin. Fix the saved as-url, or turn pin-tls off: \`suveren-gateway config set pin-tls off\`.`
236
+ );
237
+ }
238
+ }
239
+
240
+ // src/lib/as-tls-pin.ts
241
+ import { createHash as createHash2 } from "crypto";
242
+ import { checkServerIdentity as defaultCheckServerIdentity, rootCertificates } from "tls";
243
+ import { Agent as HttpsAgent } from "https";
244
+ import { readFileSync as readFileSync4 } from "fs";
245
+ import { Agent, fetch as undiciFetch } from "undici";
246
+ function effectiveCa() {
247
+ const path = process.env.NODE_EXTRA_CA_CERTS;
248
+ if (!path) return void 0;
249
+ try {
250
+ return [...rootCertificates, readFileSync4(path, "utf-8")];
251
+ } catch {
252
+ return void 0;
253
+ }
254
+ }
255
+ var PIN_CHECK_ERROR_CODE = "EAS_TLS_PIN_CHECK";
256
+ function taggedCheckError(err) {
257
+ err.code = PIN_CHECK_ERROR_CODE;
258
+ return err;
259
+ }
260
+ function isPinCheckError(err) {
261
+ let cur = err;
262
+ for (let i = 0; i < 5 && cur; i++) {
263
+ if (cur instanceof Error && cur.code === PIN_CHECK_ERROR_CODE) return true;
264
+ cur = cur instanceof Error ? cur.cause : void 0;
265
+ }
266
+ return false;
267
+ }
268
+ var AsTlsMismatchError = class extends Error {
269
+ constructor(message) {
270
+ super(message);
271
+ this.name = "AsTlsMismatchError";
272
+ }
273
+ };
274
+ function spkiSha256Hex(cert) {
275
+ if (!cert.pubkey) {
276
+ throw new Error("peer certificate carries no pubkey (expected the detailed certificate object)");
277
+ }
278
+ return createHash2("sha256").update(cert.pubkey).digest("hex");
279
+ }
280
+ function formatPinFingerprint(hex) {
281
+ const upper = hex.toUpperCase();
282
+ return upper.match(/.{1,4}/g)?.join(":") ?? upper;
283
+ }
284
+ function pinnedCheckServerIdentity(pinnedSpkiHex) {
285
+ const wantHex = pinnedSpkiHex.toLowerCase();
286
+ return (hostname, cert) => {
287
+ const defaultErr = defaultCheckServerIdentity(hostname, cert);
288
+ if (defaultErr) return taggedCheckError(defaultErr);
289
+ let actualHex;
290
+ try {
291
+ actualHex = spkiSha256Hex(cert);
292
+ } catch (err) {
293
+ return taggedCheckError(new Error(
294
+ `could not read the server certificate's public key to check the TLS pin \u2014 ${err instanceof Error ? err.message : String(err)}`
295
+ ));
296
+ }
297
+ if (actualHex !== wantHex) {
298
+ return taggedCheckError(new Error(
299
+ `TLS certificate pin mismatch for ${hostname}: expected SPKI sha256 ${formatPinFingerprint(wantHex)}, got ${formatPinFingerprint(actualHex)}.`
300
+ ));
301
+ }
302
+ return void 0;
303
+ };
304
+ }
305
+ function buildPinnedDispatcher(pinnedSpkiHex) {
306
+ return new Agent({
307
+ connect: {
308
+ ca: effectiveCa(),
309
+ checkServerIdentity: pinnedCheckServerIdentity(pinnedSpkiHex)
310
+ }
311
+ });
312
+ }
313
+ function buildCapturingDispatcher() {
314
+ let captured;
315
+ const dispatcher = new Agent({
316
+ connect: {
317
+ ca: effectiveCa(),
318
+ checkServerIdentity: (hostname, cert) => {
319
+ captured = cert;
320
+ const defaultErr = defaultCheckServerIdentity(hostname, cert);
321
+ return defaultErr ? taggedCheckError(defaultErr) : void 0;
322
+ }
323
+ }
324
+ });
325
+ return { dispatcher, getCapturedCert: () => captured };
326
+ }
327
+ async function fetchAs(url, init, pinning) {
328
+ if (!pinning.enforce && !pinning.capture) {
329
+ const res2 = await fetch(url, init);
330
+ return { res: res2 };
331
+ }
332
+ if (pinning.enforce && !pinning.capture && !pinning.pinnedSpkiHex) {
333
+ throw new AsTlsMismatchError(
334
+ `pin-tls is on but no certificate is pinned yet for ${url} \u2014 sign in again to establish it (re-pairing required).`
335
+ );
336
+ }
337
+ if (pinning.pinnedSpkiHex && (pinning.enforce || !pinning.capture)) {
338
+ const dispatcher2 = buildPinnedDispatcher(pinning.pinnedSpkiHex);
339
+ try {
340
+ const res2 = await undiciFetch(url, { ...init, dispatcher: dispatcher2 });
341
+ return { res: res2 };
342
+ } catch (err) {
343
+ if (!isPinCheckError(err)) throw err;
344
+ throw new AsTlsMismatchError(
345
+ `TLS pin check failed for ${url} \u2014 ${describeFetchError(err)}. Refusing the connection; the API key / session cookie were never sent. If the Authority Server's certificate changed intentionally (a new key, not just renewal), an operator must clear the pairing and sign in again to re-pin it.`
346
+ );
347
+ }
348
+ }
349
+ const { dispatcher, getCapturedCert } = buildCapturingDispatcher();
350
+ let res;
351
+ try {
352
+ res = await undiciFetch(url, { ...init, dispatcher });
353
+ } catch (err) {
354
+ if (!isPinCheckError(err)) throw err;
355
+ throw new AsTlsMismatchError(
356
+ `could not verify the Authority Server at ${url} while establishing its TLS pin \u2014 ${describeFetchError(err)}.`
357
+ );
358
+ }
359
+ const cert = getCapturedCert();
360
+ return { res, capturedSpkiHex: cert ? spkiSha256Hex(cert) : void 0 };
361
+ }
362
+ function describeFetchError(err) {
363
+ if (err instanceof Error) {
364
+ const cause = err.cause;
365
+ if (cause instanceof Error) return cause.message;
366
+ return err.message;
367
+ }
368
+ return String(err);
369
+ }
370
+
115
371
  // src/lib/sp-client.ts
116
372
  var SPReceiptError = class extends Error {
117
373
  constructor(message, statusCode, body) {
@@ -127,8 +383,9 @@ var DEFAULT_RECEIPT_RETRY = {
127
383
  };
128
384
  var sleep = (ms) => ms > 0 ? new Promise((resolve3) => setTimeout(resolve3, ms)) : Promise.resolve();
129
385
  var SPClient = class {
130
- constructor(baseUrl, receiptRetry = {}) {
386
+ constructor(baseUrl, receiptRetry = {}, dataDir2) {
131
387
  this.baseUrl = baseUrl;
388
+ this.dataDir = dataDir2;
132
389
  this.receiptRetry = { ...DEFAULT_RECEIPT_RETRY, ...receiptRetry };
133
390
  }
134
391
  sessionCookie = "";
@@ -141,6 +398,22 @@ var SPClient = class {
141
398
  * was active tells the control plane. Concurrent in-flight calls that were
142
399
  * all sent under the same now-dead cookie would otherwise all report it. */
143
400
  sessionExpiredNotified = false;
401
+ /** Same single-flight shape, for a TLS pin mismatch (as-tls-pin.ts). */
402
+ tlsMismatchNotified = false;
403
+ /** Opt-in TLS pinning (as-tls-pin.ts) for every call THIS client makes.
404
+ * Re-read live on each call rather than cached — same reasoning as
405
+ * AttestationCache.getPublicKey's pin check: a pin or setting change
406
+ * must take effect on the very next call, not the next restart. Never
407
+ * allowed to CAPTURE a new pin here — only the control plane's sign-in
408
+ * exchange (as-challenge.ts) does that; this client only enforces. */
409
+ tlsPinning() {
410
+ if (!this.dataDir) return { enforce: false };
411
+ const pin = readPairing(this.dataDir);
412
+ return {
413
+ enforce: resolvePinTls(this.dataDir),
414
+ pinnedSpkiHex: pin && pin.asUrl === this.baseUrl ? pin.tlsSpkiPinHex : void 0
415
+ };
416
+ }
144
417
  /** The AS base URL this client talks to (for provenance records). */
145
418
  get url() {
146
419
  return this.baseUrl;
@@ -152,15 +425,23 @@ var SPClient = class {
152
425
  this.sessionCookie = cookie;
153
426
  this.lockReason = null;
154
427
  this.sessionExpiredNotified = false;
428
+ this.tlsMismatchNotified = false;
155
429
  }
156
430
  /**
157
431
  * Drop the session because the control plane learned (by whatever path —
158
- * one of OUR calls 401ing, or its own AS proxy 401ing) that it ended.
159
- * Idempotent: safe to call redundantly from the control-plane's push.
432
+ * one of OUR calls 401ing, its own AS proxy 401ing, or an AS key mismatch)
433
+ * that it ended. Idempotent: safe to call redundantly from the
434
+ * control-plane's push.
435
+ *
436
+ * @param reason Defaults to 'expired' for the original caller (a 401 really
437
+ * does mean the session ended) — but the control plane's own lock
438
+ * procedures (session-lock.ts) know the REAL reason and must pass it, or
439
+ * an agent told "your sign-in ended, sign in again" for an AS key
440
+ * mismatch would be sent to a sign-in that is itself refused.
160
441
  */
161
- clearSession() {
442
+ clearSession(reason = "expired") {
162
443
  this.sessionCookie = "";
163
- this.lockReason = "expired";
444
+ this.lockReason = reason;
164
445
  }
165
446
  /** Why we are currently locked, if known. `null` means the default
166
447
  * boot-locked case (nobody has signed in yet this run). */
@@ -198,10 +479,21 @@ var SPClient = class {
198
479
  headers["X-API-Key"] = this.apiKey;
199
480
  }
200
481
  const hadSession = this.sessionCookie !== "";
201
- const res = await globalThis.fetch(url, {
202
- ...init,
203
- headers
204
- });
482
+ let res;
483
+ try {
484
+ const result = await fetchAs(url, { ...init, headers }, this.tlsPinning());
485
+ res = result.res;
486
+ } catch (err) {
487
+ if (err instanceof AsTlsMismatchError) {
488
+ this.sessionCookie = "";
489
+ this.lockReason = "as-tls-mismatch";
490
+ if (!this.tlsMismatchNotified) {
491
+ this.tlsMismatchNotified = true;
492
+ void notifyControlPlane("as-tls-mismatch");
493
+ }
494
+ }
495
+ throw err;
496
+ }
205
497
  if (res.status === 401 && hadSession) {
206
498
  this.sessionCookie = "";
207
499
  this.lockReason = "expired";
@@ -364,13 +656,26 @@ var SPClient = class {
364
656
 
365
657
  // src/lib/attestation-cache.ts
366
658
  import { decodeAttestationBlob } from "@hap/core";
659
+ var AsKeyMismatchError = class extends Error {
660
+ constructor(message) {
661
+ super(message);
662
+ this.name = "AsKeyMismatchError";
663
+ }
664
+ };
367
665
  function isCommitmentDowngrade(auth) {
368
666
  const requiresReview = auth.signedCommitmentMode === "review" || auth.signedCommitmentMode === "review_above_cap";
369
667
  return requiresReview && (auth.deferredCommitmentDomains ?? []).length === 0;
370
668
  }
371
669
  var AttestationCache = class {
372
- constructor(spClient) {
670
+ /**
671
+ * @param dataDir Where to look for a pinned key (as-pairing.json). Optional
672
+ * and defaults to "no pin enforced" — kept optional so existing
673
+ * constructions (and this class's own unit tests) that pass only an
674
+ * SPClient keep working unpinned, exactly as before pinning existed.
675
+ */
676
+ constructor(spClient, dataDir2) {
373
677
  this.spClient = spClient;
678
+ this.dataDir = dataDir2;
374
679
  }
375
680
  spPublicKey = null;
376
681
  spPublicKeyFetchedAt = 0;
@@ -380,15 +685,29 @@ var AttestationCache = class {
380
685
  authorizations = /* @__PURE__ */ new Map();
381
686
  lastSync = 0;
382
687
  /**
383
- * Get the SP public key, fetching from SP if not cached or expired.
688
+ * Get the SP public key, fetching from SP if not cached or expired, then —
689
+ * when a pin exists for this exact AS URL — verifying the live key still
690
+ * matches it.
691
+ *
692
+ * Trust-on-first-use before any pairing exists (or when no `dataDir` was
693
+ * given): the fetched key is cached and returned, same as before pinning.
694
+ * Once paired, a live key that differs from the pin throws
695
+ * {@link AsKeyMismatchError} — fail closed, never silently re-pin.
384
696
  */
385
697
  async getPublicKey() {
386
698
  const now = Math.floor(Date.now() / 1e3);
387
- if (this.spPublicKey && now - this.spPublicKeyFetchedAt < this.SP_PUBKEY_TTL) {
388
- return this.spPublicKey;
699
+ if (!(this.spPublicKey && now - this.spPublicKeyFetchedAt < this.SP_PUBKEY_TTL)) {
700
+ this.spPublicKey = await this.spClient.getPublicKey();
701
+ this.spPublicKeyFetchedAt = now;
702
+ }
703
+ if (this.dataDir) {
704
+ const pin = readPairing(this.dataDir);
705
+ if (pin && pin.asUrl === this.spClient.url && pin.publicKeyHex !== this.spPublicKey) {
706
+ throw new AsKeyMismatchError(
707
+ `The Authority Server at ${this.spClient.url} presented a signing key that does not match the one pinned at pairing (pinned fingerprint ${fingerprintOf(pin.publicKeyHex)}). Refusing to trust it. Re-pair (sign in again) only if you expect this key to have changed.`
708
+ );
709
+ }
389
710
  }
390
- this.spPublicKey = await this.spClient.getPublicKey();
391
- this.spPublicKeyFetchedAt = now;
392
711
  return this.spPublicKey;
393
712
  }
394
713
  /**
@@ -498,18 +817,18 @@ var AttestationCache = class {
498
817
  };
499
818
 
500
819
  // src/lib/gate-store.ts
501
- import { mkdirSync, readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, unlinkSync } from "fs";
820
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync4, unlinkSync as unlinkSync2 } from "fs";
502
821
  import { homedir } from "os";
503
- import { dirname, join as join2 } from "path";
822
+ import { dirname as dirname3, join as join4 } from "path";
504
823
  import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
505
- var DEFAULT_DIR = process.env.SUVEREN_DATA_DIR ?? join2(homedir(), ".suveren");
824
+ var DEFAULT_DIR = process.env.SUVEREN_DATA_DIR ?? join4(homedir(), ".suveren");
506
825
  var GateStore = class {
507
826
  entries = /* @__PURE__ */ new Map();
508
827
  baseDir;
509
828
  vaultKey = null;
510
829
  constructor(filePath) {
511
830
  if (filePath && filePath.endsWith(".json")) {
512
- this.baseDir = dirname(filePath);
831
+ this.baseDir = dirname3(filePath);
513
832
  } else {
514
833
  this.baseDir = filePath ?? DEFAULT_DIR;
515
834
  }
@@ -520,13 +839,13 @@ var GateStore = class {
520
839
  */
521
840
  setVaultKey(key) {
522
841
  this.vaultKey = key;
523
- if (existsSync2(this.encryptedFilePath)) {
842
+ if (existsSync4(this.encryptedFilePath)) {
524
843
  this.loadEncrypted();
525
844
  } else if (this.entries.size > 0) {
526
845
  this.persistEncrypted();
527
- if (existsSync2(this.plaintextFilePath)) {
846
+ if (existsSync4(this.plaintextFilePath)) {
528
847
  try {
529
- unlinkSync(this.plaintextFilePath);
848
+ unlinkSync2(this.plaintextFilePath);
530
849
  } catch {
531
850
  }
532
851
  }
@@ -546,6 +865,30 @@ var GateStore = class {
546
865
  this.entries.delete(path);
547
866
  this.persist();
548
867
  }
868
+ /**
869
+ * Wipe every locally cached gate. Used when the Authority Server this
870
+ * gateway points at changes (re-pairing, see as-pairing.ts): a stored
871
+ * authorization id and its intent/context are meaningless against a
872
+ * different AS's grants, and keeping them around risks a `getAll()` caller
873
+ * (e.g. list-authorizations) advertising authority that no longer exists.
874
+ *
875
+ * Removes BOTH the plaintext and encrypted files, not just the one
876
+ * currently active — this runs at boot, before any vault key is set, so
877
+ * `persist()` would otherwise only touch `gates.json` and leave a stale
878
+ * `gates.enc.json` in place for `setVaultKey()` to resurrect on the next
879
+ * unlock.
880
+ */
881
+ clearAll() {
882
+ this.entries = /* @__PURE__ */ new Map();
883
+ try {
884
+ if (existsSync4(this.plaintextFilePath)) unlinkSync2(this.plaintextFilePath);
885
+ } catch {
886
+ }
887
+ try {
888
+ if (existsSync4(this.encryptedFilePath)) unlinkSync2(this.encryptedFilePath);
889
+ } catch {
890
+ }
891
+ }
549
892
  // ─── Encryption helpers ─────────────────────────────────────────────────
550
893
  encrypt(plaintext) {
551
894
  if (!this.vaultKey) throw new Error("No vault key");
@@ -575,19 +918,19 @@ var GateStore = class {
575
918
  }
576
919
  // ─── File paths ─────────────────────────────────────────────────────────
577
920
  get plaintextFilePath() {
578
- return join2(this.baseDir, "gates.json");
921
+ return join4(this.baseDir, "gates.json");
579
922
  }
580
923
  get encryptedFilePath() {
581
- return join2(this.baseDir, "gates.enc.json");
924
+ return join4(this.baseDir, "gates.enc.json");
582
925
  }
583
926
  // ─── Load / Persist ─────────────────────────────────────────────────────
584
927
  loadPlaintext() {
585
- if (!existsSync2(this.plaintextFilePath)) {
586
- mkdirSync(this.baseDir, { recursive: true });
928
+ if (!existsSync4(this.plaintextFilePath)) {
929
+ mkdirSync3(this.baseDir, { recursive: true });
587
930
  return;
588
931
  }
589
932
  try {
590
- const raw = readFileSync2(this.plaintextFilePath, "utf-8");
933
+ const raw = readFileSync5(this.plaintextFilePath, "utf-8");
591
934
  const data = JSON.parse(raw);
592
935
  this.entries = new Map(Object.entries(data.entries));
593
936
  } catch {
@@ -596,9 +939,9 @@ var GateStore = class {
596
939
  }
597
940
  }
598
941
  loadEncrypted() {
599
- if (!existsSync2(this.encryptedFilePath)) return;
942
+ if (!existsSync4(this.encryptedFilePath)) return;
600
943
  try {
601
- const raw = readFileSync2(this.encryptedFilePath, "utf-8");
944
+ const raw = readFileSync5(this.encryptedFilePath, "utf-8");
602
945
  const data = JSON.parse(raw);
603
946
  this.entries = /* @__PURE__ */ new Map();
604
947
  for (const [key, blob] of Object.entries(data.entries)) {
@@ -622,8 +965,8 @@ var GateStore = class {
622
965
  version: 1,
623
966
  entries: Object.fromEntries(this.entries)
624
967
  };
625
- mkdirSync(this.baseDir, { recursive: true, mode: 448 });
626
- writeFileSync(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
968
+ mkdirSync3(this.baseDir, { recursive: true, mode: 448 });
969
+ writeFileSync3(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
627
970
  }
628
971
  persistEncrypted() {
629
972
  const data = {
@@ -633,17 +976,17 @@ var GateStore = class {
633
976
  for (const [key, entry] of this.entries) {
634
977
  data.entries[key] = this.encrypt(JSON.stringify(entry));
635
978
  }
636
- mkdirSync(this.baseDir, { recursive: true, mode: 448 });
637
- writeFileSync(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
979
+ mkdirSync3(this.baseDir, { recursive: true, mode: 448 });
980
+ writeFileSync3(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
638
981
  }
639
982
  };
640
983
 
641
984
  // src/lib/execution-log.ts
642
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, unlinkSync as unlinkSync2 } from "fs";
985
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync5, unlinkSync as unlinkSync3 } from "fs";
643
986
  import { homedir as homedir2 } from "os";
644
- import { dirname as dirname2, join as join3 } from "path";
987
+ import { dirname as dirname4, join as join5 } from "path";
645
988
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes2 } from "crypto";
646
- var DEFAULT_DIR2 = process.env.SUVEREN_DATA_DIR ?? join3(homedir2(), ".suveren");
989
+ var DEFAULT_DIR2 = process.env.SUVEREN_DATA_DIR ?? join5(homedir2(), ".suveren");
647
990
  var MAX_AGE_SECONDS = 31 * 24 * 60 * 60;
648
991
  var ExecutionLog = class {
649
992
  entries = [];
@@ -651,7 +994,7 @@ var ExecutionLog = class {
651
994
  vaultKey = null;
652
995
  constructor(filePath) {
653
996
  if (filePath && filePath.endsWith(".json")) {
654
- this.baseDir = dirname2(filePath);
997
+ this.baseDir = dirname4(filePath);
655
998
  } else {
656
999
  this.baseDir = filePath ?? DEFAULT_DIR2;
657
1000
  }
@@ -662,13 +1005,13 @@ var ExecutionLog = class {
662
1005
  */
663
1006
  setVaultKey(key) {
664
1007
  this.vaultKey = key;
665
- if (existsSync3(this.encryptedFilePath)) {
1008
+ if (existsSync5(this.encryptedFilePath)) {
666
1009
  this.loadEncrypted();
667
1010
  } else if (this.entries.length > 0) {
668
1011
  this.persistEncrypted();
669
- if (existsSync3(this.plaintextFilePath)) {
1012
+ if (existsSync5(this.plaintextFilePath)) {
670
1013
  try {
671
- unlinkSync2(this.plaintextFilePath);
1014
+ unlinkSync3(this.plaintextFilePath);
672
1015
  } catch {
673
1016
  }
674
1017
  }
@@ -690,14 +1033,23 @@ var ExecutionLog = class {
690
1033
  * @param field - The execution field to sum ("_count" for plain counting)
691
1034
  * @param window - Time window (daily, weekly, monthly)
692
1035
  * @param now - Current timestamp in seconds (for testing)
1036
+ * @param actionTypes - Only count entries whose `execution.action_type` is one
1037
+ * of these (omitted → all). Consumption is partitioned by action type, as at
1038
+ * the Authority Server: without it, the usage shown for sales' "orders per
1039
+ * day" counted every quote and send. An entry with no action_type counts against every filter —
1040
+ * an unknown action is not evidence of headroom.
693
1041
  */
694
- sumByWindow(profileId, path, field, window, now = Math.floor(Date.now() / 1e3)) {
1042
+ sumByWindow(profileId, path, field, window, now = Math.floor(Date.now() / 1e3), actionTypes) {
695
1043
  const cutoff = windowCutoff(window, now);
696
1044
  let total = 0;
697
1045
  for (const entry of this.entries) {
698
1046
  if (entry.profileId !== profileId) continue;
699
1047
  if (entry.path !== path) continue;
700
1048
  if (entry.timestamp < cutoff) continue;
1049
+ if (actionTypes) {
1050
+ const at = entry.execution.action_type;
1051
+ if (typeof at === "string" && !actionTypes.includes(at)) continue;
1052
+ }
701
1053
  if (field === "_count") {
702
1054
  total += 1;
703
1055
  } else {
@@ -761,19 +1113,19 @@ var ExecutionLog = class {
761
1113
  }
762
1114
  // ─── File paths ─────────────────────────────────────────────────────────
763
1115
  get plaintextFilePath() {
764
- return join3(this.baseDir, "execution-log.json");
1116
+ return join5(this.baseDir, "execution-log.json");
765
1117
  }
766
1118
  get encryptedFilePath() {
767
- return join3(this.baseDir, "execution-log.enc.json");
1119
+ return join5(this.baseDir, "execution-log.enc.json");
768
1120
  }
769
1121
  // ─── Load / Persist ─────────────────────────────────────────────────────
770
1122
  loadPlaintext() {
771
- if (!existsSync3(this.plaintextFilePath)) {
772
- mkdirSync2(this.baseDir, { recursive: true });
1123
+ if (!existsSync5(this.plaintextFilePath)) {
1124
+ mkdirSync4(this.baseDir, { recursive: true });
773
1125
  return;
774
1126
  }
775
1127
  try {
776
- const raw = readFileSync3(this.plaintextFilePath, "utf-8");
1128
+ const raw = readFileSync6(this.plaintextFilePath, "utf-8");
777
1129
  const data = JSON.parse(raw);
778
1130
  this.entries = data.entries;
779
1131
  this.prune();
@@ -783,9 +1135,9 @@ var ExecutionLog = class {
783
1135
  }
784
1136
  }
785
1137
  loadEncrypted() {
786
- if (!existsSync3(this.encryptedFilePath)) return;
1138
+ if (!existsSync5(this.encryptedFilePath)) return;
787
1139
  try {
788
- const raw = readFileSync3(this.encryptedFilePath, "utf-8");
1140
+ const raw = readFileSync6(this.encryptedFilePath, "utf-8");
789
1141
  const data = JSON.parse(raw);
790
1142
  const decrypted = this.decrypt(data.blob);
791
1143
  const logFile = JSON.parse(decrypted);
@@ -805,8 +1157,8 @@ var ExecutionLog = class {
805
1157
  }
806
1158
  persistPlaintext() {
807
1159
  const data = { version: 1, entries: this.entries };
808
- mkdirSync2(this.baseDir, { recursive: true, mode: 448 });
809
- writeFileSync2(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1160
+ mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1161
+ writeFileSync4(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
810
1162
  }
811
1163
  persistEncrypted() {
812
1164
  const logFile = { version: 1, entries: this.entries };
@@ -814,8 +1166,8 @@ var ExecutionLog = class {
814
1166
  version: 1,
815
1167
  blob: this.encrypt(JSON.stringify(logFile))
816
1168
  };
817
- mkdirSync2(this.baseDir, { recursive: true, mode: 448 });
818
- writeFileSync2(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1169
+ mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1170
+ writeFileSync4(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
819
1171
  }
820
1172
  };
821
1173
  function windowCutoff(window, now) {
@@ -832,11 +1184,11 @@ function windowCutoff(window, now) {
832
1184
  }
833
1185
 
834
1186
  // src/lib/denial-log.ts
835
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4, unlinkSync as unlinkSync3 } from "fs";
1187
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync6, unlinkSync as unlinkSync4 } from "fs";
836
1188
  import { homedir as homedir3 } from "os";
837
- import { dirname as dirname3, join as join4 } from "path";
1189
+ import { dirname as dirname5, join as join6 } from "path";
838
1190
  import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes3 } from "crypto";
839
- var DEFAULT_DIR3 = process.env.SUVEREN_DATA_DIR ?? join4(homedir3(), ".suveren");
1191
+ var DEFAULT_DIR3 = process.env.SUVEREN_DATA_DIR ?? join6(homedir3(), ".suveren");
840
1192
  var MAX_RECORDS = 200;
841
1193
  var MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
842
1194
  var DenialLog = class {
@@ -844,18 +1196,18 @@ var DenialLog = class {
844
1196
  baseDir;
845
1197
  vaultKey = null;
846
1198
  constructor(filePath) {
847
- this.baseDir = filePath && filePath.endsWith(".json") ? dirname3(filePath) : filePath ?? DEFAULT_DIR3;
1199
+ this.baseDir = filePath && filePath.endsWith(".json") ? dirname5(filePath) : filePath ?? DEFAULT_DIR3;
848
1200
  this.loadPlaintext();
849
1201
  }
850
1202
  setVaultKey(key) {
851
1203
  this.vaultKey = key;
852
- if (existsSync4(this.encryptedFilePath)) {
1204
+ if (existsSync6(this.encryptedFilePath)) {
853
1205
  this.loadEncrypted();
854
1206
  } else if (this.records.length > 0) {
855
1207
  this.persistEncrypted();
856
- if (existsSync4(this.plaintextFilePath)) {
1208
+ if (existsSync6(this.plaintextFilePath)) {
857
1209
  try {
858
- unlinkSync3(this.plaintextFilePath);
1210
+ unlinkSync4(this.plaintextFilePath);
859
1211
  } catch {
860
1212
  }
861
1213
  }
@@ -903,18 +1255,18 @@ var DenialLog = class {
903
1255
  return Buffer.concat([decipher.update(Buffer.from(blob.ciphertext, "hex")), decipher.final()]).toString("utf8");
904
1256
  }
905
1257
  get plaintextFilePath() {
906
- return join4(this.baseDir, "denials.json");
1258
+ return join6(this.baseDir, "denials.json");
907
1259
  }
908
1260
  get encryptedFilePath() {
909
- return join4(this.baseDir, "denials.enc.json");
1261
+ return join6(this.baseDir, "denials.enc.json");
910
1262
  }
911
1263
  loadPlaintext() {
912
- if (!existsSync4(this.plaintextFilePath)) {
913
- mkdirSync3(this.baseDir, { recursive: true });
1264
+ if (!existsSync6(this.plaintextFilePath)) {
1265
+ mkdirSync5(this.baseDir, { recursive: true });
914
1266
  return;
915
1267
  }
916
1268
  try {
917
- const data = JSON.parse(readFileSync4(this.plaintextFilePath, "utf-8"));
1269
+ const data = JSON.parse(readFileSync7(this.plaintextFilePath, "utf-8"));
918
1270
  this.records = data.records ?? [];
919
1271
  } catch {
920
1272
  console.error(`[DenialLog] Could not parse ${this.plaintextFilePath}, starting fresh`);
@@ -922,9 +1274,9 @@ var DenialLog = class {
922
1274
  }
923
1275
  }
924
1276
  loadEncrypted() {
925
- if (!existsSync4(this.encryptedFilePath)) return;
1277
+ if (!existsSync6(this.encryptedFilePath)) return;
926
1278
  try {
927
- const data = JSON.parse(readFileSync4(this.encryptedFilePath, "utf-8"));
1279
+ const data = JSON.parse(readFileSync7(this.encryptedFilePath, "utf-8"));
928
1280
  const logFile = JSON.parse(this.decrypt(data.blob));
929
1281
  this.records = logFile.records ?? [];
930
1282
  } catch (err) {
@@ -938,23 +1290,23 @@ var DenialLog = class {
938
1290
  }
939
1291
  persistPlaintext() {
940
1292
  const data = { version: 1, records: this.records };
941
- mkdirSync3(this.baseDir, { recursive: true, mode: 448 });
942
- writeFileSync3(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1293
+ mkdirSync5(this.baseDir, { recursive: true, mode: 448 });
1294
+ writeFileSync5(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
943
1295
  }
944
1296
  persistEncrypted() {
945
1297
  const logFile = { version: 1, records: this.records };
946
1298
  const data = { version: 1, blob: this.encrypt(JSON.stringify(logFile)) };
947
- mkdirSync3(this.baseDir, { recursive: true, mode: 448 });
948
- writeFileSync3(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1299
+ mkdirSync5(this.baseDir, { recursive: true, mode: 448 });
1300
+ writeFileSync5(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
949
1301
  }
950
1302
  };
951
1303
 
952
1304
  // src/lib/receipt-archive.ts
953
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, unlinkSync as unlinkSync4 } from "fs";
1305
+ import { mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync7, unlinkSync as unlinkSync5 } from "fs";
954
1306
  import { homedir as homedir4 } from "os";
955
- import { dirname as dirname4, join as join5 } from "path";
1307
+ import { dirname as dirname6, join as join7 } from "path";
956
1308
  import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes4 } from "crypto";
957
- var DEFAULT_DIR4 = process.env.SUVEREN_DATA_DIR ?? join5(homedir4(), ".suveren");
1309
+ var DEFAULT_DIR4 = process.env.SUVEREN_DATA_DIR ?? join7(homedir4(), ".suveren");
958
1310
  function stripPreviews(proposal) {
959
1311
  const args = proposal.toolArgs;
960
1312
  if (!args || typeof args !== "object") return proposal;
@@ -968,7 +1320,7 @@ var ReceiptArchive = class {
968
1320
  vaultKey = null;
969
1321
  constructor(filePath) {
970
1322
  if (filePath && filePath.endsWith(".json")) {
971
- this.baseDir = dirname4(filePath);
1323
+ this.baseDir = dirname6(filePath);
972
1324
  } else {
973
1325
  this.baseDir = filePath ?? DEFAULT_DIR4;
974
1326
  }
@@ -979,13 +1331,13 @@ var ReceiptArchive = class {
979
1331
  */
980
1332
  setVaultKey(key) {
981
1333
  this.vaultKey = key;
982
- if (existsSync5(this.encryptedFilePath)) {
1334
+ if (existsSync7(this.encryptedFilePath)) {
983
1335
  this.loadEncrypted();
984
1336
  } else if (this.data.receipts.length > 0 || Object.keys(this.data.authorizations).length > 0) {
985
1337
  this.persistEncrypted();
986
- if (existsSync5(this.plaintextFilePath)) {
1338
+ if (existsSync7(this.plaintextFilePath)) {
987
1339
  try {
988
- unlinkSync4(this.plaintextFilePath);
1340
+ unlinkSync5(this.plaintextFilePath);
989
1341
  } catch {
990
1342
  }
991
1343
  }
@@ -997,7 +1349,7 @@ var ReceiptArchive = class {
997
1349
  * this state — that would report a hollow success over unreadable evidence.
998
1350
  */
999
1351
  isLocked() {
1000
- return this.vaultKey === null && existsSync5(this.encryptedFilePath);
1352
+ return this.vaultKey === null && existsSync7(this.encryptedFilePath);
1001
1353
  }
1002
1354
  /**
1003
1355
  * Archive a signed receipt (and the grant it was issued under).
@@ -1098,19 +1450,19 @@ var ReceiptArchive = class {
1098
1450
  }
1099
1451
  // ─── File paths ─────────────────────────────────────────────────────────
1100
1452
  get plaintextFilePath() {
1101
- return join5(this.baseDir, "receipt-archive.json");
1453
+ return join7(this.baseDir, "receipt-archive.json");
1102
1454
  }
1103
1455
  get encryptedFilePath() {
1104
- return join5(this.baseDir, "receipt-archive.enc.json");
1456
+ return join7(this.baseDir, "receipt-archive.enc.json");
1105
1457
  }
1106
1458
  // ─── Load / Persist ─────────────────────────────────────────────────────
1107
1459
  loadPlaintext() {
1108
- if (!existsSync5(this.plaintextFilePath)) {
1109
- mkdirSync4(this.baseDir, { recursive: true });
1460
+ if (!existsSync7(this.plaintextFilePath)) {
1461
+ mkdirSync6(this.baseDir, { recursive: true });
1110
1462
  return;
1111
1463
  }
1112
1464
  try {
1113
- const raw = readFileSync5(this.plaintextFilePath, "utf-8");
1465
+ const raw = readFileSync8(this.plaintextFilePath, "utf-8");
1114
1466
  const parsed = JSON.parse(raw);
1115
1467
  this.data = {
1116
1468
  version: 1,
@@ -1120,18 +1472,18 @@ var ReceiptArchive = class {
1120
1472
  } catch {
1121
1473
  console.error(`[ReceiptArchive] Could not parse ${this.plaintextFilePath} \u2014 preserving as .corrupt`);
1122
1474
  try {
1123
- writeFileSync4(
1475
+ writeFileSync6(
1124
1476
  `${this.plaintextFilePath}.corrupt-${Date.now()}`,
1125
- readFileSync5(this.plaintextFilePath)
1477
+ readFileSync8(this.plaintextFilePath)
1126
1478
  );
1127
1479
  } catch {
1128
1480
  }
1129
1481
  }
1130
1482
  }
1131
1483
  loadEncrypted() {
1132
- if (!existsSync5(this.encryptedFilePath)) return;
1484
+ if (!existsSync7(this.encryptedFilePath)) return;
1133
1485
  try {
1134
- const raw = readFileSync5(this.encryptedFilePath, "utf-8");
1486
+ const raw = readFileSync8(this.encryptedFilePath, "utf-8");
1135
1487
  const data = JSON.parse(raw);
1136
1488
  const decrypted = this.decrypt(data.blob);
1137
1489
  const parsed = JSON.parse(decrypted);
@@ -1143,9 +1495,9 @@ var ReceiptArchive = class {
1143
1495
  } catch (err) {
1144
1496
  console.error(`[ReceiptArchive] Could not decrypt ${this.encryptedFilePath} \u2014 preserving as .corrupt:`, err);
1145
1497
  try {
1146
- writeFileSync4(
1498
+ writeFileSync6(
1147
1499
  `${this.encryptedFilePath}.corrupt-${Date.now()}`,
1148
- readFileSync5(this.encryptedFilePath)
1500
+ readFileSync8(this.encryptedFilePath)
1149
1501
  );
1150
1502
  } catch {
1151
1503
  }
@@ -1159,29 +1511,29 @@ var ReceiptArchive = class {
1159
1511
  }
1160
1512
  }
1161
1513
  persistPlaintext() {
1162
- mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1163
- writeFileSync4(this.plaintextFilePath, JSON.stringify(this.data, null, 2), { encoding: "utf-8", mode: 384 });
1514
+ mkdirSync6(this.baseDir, { recursive: true, mode: 448 });
1515
+ writeFileSync6(this.plaintextFilePath, JSON.stringify(this.data, null, 2), { encoding: "utf-8", mode: 384 });
1164
1516
  }
1165
1517
  persistEncrypted() {
1166
1518
  const data = {
1167
1519
  version: 1,
1168
1520
  blob: this.encrypt(JSON.stringify(this.data))
1169
1521
  };
1170
- mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1171
- writeFileSync4(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1522
+ mkdirSync6(this.baseDir, { recursive: true, mode: 448 });
1523
+ writeFileSync6(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1172
1524
  }
1173
1525
  };
1174
1526
 
1175
1527
  // src/lib/execution-journal.ts
1176
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync6, renameSync } from "fs";
1528
+ import { mkdirSync as mkdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync7, existsSync as existsSync8, renameSync } from "fs";
1177
1529
  import { homedir as homedir5 } from "os";
1178
- import { dirname as dirname5, join as join6 } from "path";
1179
- import { createHash } from "crypto";
1180
- var DEFAULT_DIR5 = process.env.SUVEREN_DATA_DIR ?? join6(homedir5(), ".suveren");
1530
+ import { dirname as dirname7, join as join8 } from "path";
1531
+ import { createHash as createHash3 } from "crypto";
1532
+ var DEFAULT_DIR5 = process.env.SUVEREN_DATA_DIR ?? join8(homedir5(), ".suveren");
1181
1533
  var FILE_NAME = "execution-journal.json";
1182
1534
  var MAX_AGE_SECONDS2 = 90 * 24 * 60 * 60;
1183
1535
  function hashToolArgs(args) {
1184
- return "sha256:" + createHash("sha256").update(stableStringify(args)).digest("hex");
1536
+ return "sha256:" + createHash3("sha256").update(stableStringify(args)).digest("hex");
1185
1537
  }
1186
1538
  function stableStringify(value) {
1187
1539
  if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "undefined";
@@ -1193,8 +1545,8 @@ function stableStringify(value) {
1193
1545
  var ExecutionJournal = class {
1194
1546
  filePath;
1195
1547
  constructor(filePath) {
1196
- const baseDir = filePath && filePath.endsWith(".json") ? dirname5(filePath) : filePath ?? DEFAULT_DIR5;
1197
- this.filePath = join6(baseDir, FILE_NAME);
1548
+ const baseDir = filePath && filePath.endsWith(".json") ? dirname7(filePath) : filePath ?? DEFAULT_DIR5;
1549
+ this.filePath = join8(baseDir, FILE_NAME);
1198
1550
  }
1199
1551
  /** Look a ticket up. Always reads from disk — another process may have written. */
1200
1552
  get(ticketId) {
@@ -1233,9 +1585,9 @@ var ExecutionJournal = class {
1233
1585
  }
1234
1586
  // ─── Persistence ────────────────────────────────────────────────────────
1235
1587
  load() {
1236
- if (!existsSync6(this.filePath)) return { version: 1, entries: [] };
1588
+ if (!existsSync8(this.filePath)) return { version: 1, entries: [] };
1237
1589
  try {
1238
- const parsed = JSON.parse(readFileSync6(this.filePath, "utf8"));
1590
+ const parsed = JSON.parse(readFileSync9(this.filePath, "utf8"));
1239
1591
  if (parsed?.version !== 1 || !Array.isArray(parsed.entries)) {
1240
1592
  throw new Error("unexpected shape");
1241
1593
  }
@@ -1249,9 +1601,9 @@ var ExecutionJournal = class {
1249
1601
  persist(file) {
1250
1602
  const cutoff = nowSec() - MAX_AGE_SECONDS2;
1251
1603
  file.entries = file.entries.filter((e) => e.startedAt >= cutoff);
1252
- mkdirSync5(dirname5(this.filePath), { recursive: true, mode: 448 });
1604
+ mkdirSync7(dirname7(this.filePath), { recursive: true, mode: 448 });
1253
1605
  const tmp = this.filePath + ".tmp";
1254
- writeFileSync5(tmp, JSON.stringify(file, null, 2), { mode: 384 });
1606
+ writeFileSync7(tmp, JSON.stringify(file, null, 2), { mode: 384 });
1255
1607
  renameSync(tmp, this.filePath);
1256
1608
  }
1257
1609
  };
@@ -1259,6 +1611,61 @@ function nowSec() {
1259
1611
  return Math.floor(Date.now() / 1e3);
1260
1612
  }
1261
1613
 
1614
+ // src/lib/proposal-submission-store.ts
1615
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync9, renameSync as renameSync2 } from "fs";
1616
+ import { homedir as homedir6 } from "os";
1617
+ import { dirname as dirname8, join as join9 } from "path";
1618
+ var DEFAULT_DIR6 = process.env.SUVEREN_DATA_DIR ?? join9(homedir6(), ".suveren");
1619
+ var FILE_NAME2 = "proposal-submissions.json";
1620
+ var MAX_AGE_SECONDS3 = 90 * 24 * 60 * 60;
1621
+ function nowSec2() {
1622
+ return Math.floor(Date.now() / 1e3);
1623
+ }
1624
+ var ProposalSubmissionStore = class {
1625
+ filePath;
1626
+ constructor(filePath) {
1627
+ const baseDir = filePath && filePath.endsWith(".json") ? dirname8(filePath) : filePath ?? DEFAULT_DIR6;
1628
+ this.filePath = join9(baseDir, FILE_NAME2);
1629
+ }
1630
+ /** Record what was submitted, right after a successful submitProposal(). */
1631
+ record(entry) {
1632
+ const file = this.load();
1633
+ file.entries = file.entries.filter((e) => e.proposalId !== entry.proposalId);
1634
+ file.entries.push({
1635
+ proposalId: entry.proposalId,
1636
+ tool: entry.tool,
1637
+ toolArgsHash: hashToolArgs(entry.toolArgs),
1638
+ executionContextHash: hashToolArgs(entry.executionContext),
1639
+ authorizationId: entry.authorizationId,
1640
+ profileId: entry.profileId,
1641
+ submittedAt: nowSec2()
1642
+ });
1643
+ this.persist(file);
1644
+ }
1645
+ /** Always reads from disk — another process (the poll loop lives in the
1646
+ * same process, but this stays consistent with execution-journal.ts). */
1647
+ get(proposalId) {
1648
+ return this.load().entries.find((e) => e.proposalId === proposalId);
1649
+ }
1650
+ load() {
1651
+ if (!existsSync9(this.filePath)) return { version: 1, entries: [] };
1652
+ try {
1653
+ const parsed = JSON.parse(readFileSync10(this.filePath, "utf-8"));
1654
+ const cutoff = nowSec2() - MAX_AGE_SECONDS3;
1655
+ parsed.entries = (parsed.entries ?? []).filter((e) => e.submittedAt >= cutoff);
1656
+ return parsed;
1657
+ } catch {
1658
+ return { version: 1, entries: [] };
1659
+ }
1660
+ }
1661
+ persist(file) {
1662
+ mkdirSync8(dirname8(this.filePath), { recursive: true, mode: 448 });
1663
+ const tmpPath = `${this.filePath}.tmp`;
1664
+ writeFileSync8(tmpPath, JSON.stringify(file, null, 2), { encoding: "utf-8", mode: 384 });
1665
+ renameSync2(tmpPath, this.filePath);
1666
+ }
1667
+ };
1668
+
1262
1669
  // src/lib/gatekeeper.ts
1263
1670
  import { verify } from "@hap/core";
1264
1671
  var MCPGatekeeper = class {
@@ -1309,7 +1716,26 @@ var MCPGatekeeper = class {
1309
1716
  authorization: auth
1310
1717
  };
1311
1718
  }
1312
- const publicKeyHex = await this.cache.getPublicKey();
1719
+ let publicKeyHex;
1720
+ try {
1721
+ publicKeyHex = await this.cache.getPublicKey();
1722
+ } catch (err) {
1723
+ if (err instanceof AsKeyMismatchError) {
1724
+ void notifyControlPlane("as-key-mismatch");
1725
+ return {
1726
+ result: {
1727
+ approved: false,
1728
+ // No dedicated GatekeeperError code exists for this (hap-core's
1729
+ // union predates gateway-side key pinning) — INVALID_SIGNATURE is
1730
+ // the closest fit: it's exactly the claim being made here ("we
1731
+ // will not trust a signature made under this key").
1732
+ errors: [{ code: "INVALID_SIGNATURE", message: err.message }]
1733
+ },
1734
+ authorization: auth
1735
+ };
1736
+ }
1737
+ throw err;
1738
+ }
1313
1739
  const resolvedBounds = override?.bounds ?? auth.bounds ?? auth.frame;
1314
1740
  const resolvedContext = override?.context ?? auth.context;
1315
1741
  const frame = { ...resolvedBounds, profile: auth.profileId };
@@ -1341,15 +1767,26 @@ var SharedState = class {
1341
1767
  receiptArchive;
1342
1768
  /** Which tickets this Gatekeeper has executed — the "one execution per ticket" half of exactly-once. */
1343
1769
  executionJournal;
1770
+ /** What THIS gateway submitted for each review-mode proposal it created —
1771
+ * see ticket-verify.ts / commitments.ts. */
1772
+ proposalSubmissions;
1344
1773
  gatekeeper;
1345
- constructor(spUrl2, gateStorePath) {
1346
- this.spClient = new SPClient(spUrl2);
1347
- this.cache = new AttestationCache(this.spClient);
1774
+ /**
1775
+ * @param dataDir Passed to the AttestationCache so it can enforce AS key
1776
+ * pinning (as-pairing.ts), and to the SPClient so it can enforce opt-in
1777
+ * TLS pinning (as-tls-pin.ts). Optional for backward compat with
1778
+ * existing constructions/tests that pass only a URL — those get
1779
+ * unpinned trust-on-first-use behavior, same as before pinning existed.
1780
+ */
1781
+ constructor(spUrl2, gateStorePath, dataDir2) {
1782
+ this.spClient = new SPClient(spUrl2, void 0, dataDir2);
1783
+ this.cache = new AttestationCache(this.spClient, dataDir2);
1348
1784
  this.gateStore = new GateStore(gateStorePath);
1349
1785
  this.executionLog = new ExecutionLog(gateStorePath);
1350
1786
  this.denialLog = new DenialLog(gateStorePath);
1351
1787
  this.receiptArchive = new ReceiptArchive(gateStorePath);
1352
1788
  this.executionJournal = new ExecutionJournal(gateStorePath);
1789
+ this.proposalSubmissions = new ProposalSubmissionStore(gateStorePath);
1353
1790
  this.gatekeeper = new MCPGatekeeper(this.cache);
1354
1791
  }
1355
1792
  /**
@@ -1365,7 +1802,8 @@ var SharedState = class {
1365
1802
  let asPublicKey;
1366
1803
  try {
1367
1804
  asPublicKey = await this.cache.getPublicKey();
1368
- } catch {
1805
+ } catch (err) {
1806
+ if (err instanceof AsKeyMismatchError) throw err;
1369
1807
  }
1370
1808
  this.receiptArchive.record({
1371
1809
  receipt,
@@ -1387,6 +1825,7 @@ var SharedState = class {
1387
1825
  } : void 0
1388
1826
  });
1389
1827
  } catch (err) {
1828
+ if (err instanceof AsKeyMismatchError) throw err;
1390
1829
  console.error(
1391
1830
  "[Suveren MCP] Receipt archive write failed (execution proceeds \u2014 AS retains authoritative copy):",
1392
1831
  err
@@ -1435,6 +1874,7 @@ import { z } from "zod";
1435
1874
  import { getProfile } from "@hap/core";
1436
1875
 
1437
1876
  // src/lib/consumption.ts
1877
+ import { boundActionTypes } from "@hap/core";
1438
1878
  function getConsumptionState(auth, executionLog, profile) {
1439
1879
  if (!profile?.boundsSchema?.fields) return [];
1440
1880
  const entries = [];
@@ -1454,7 +1894,8 @@ function getConsumptionState(auth, executionLog, profile) {
1454
1894
  auth.path,
1455
1895
  cumulativeField,
1456
1896
  bt.window,
1457
- now
1897
+ now,
1898
+ boundActionTypes(fieldName, fieldDef)
1458
1899
  );
1459
1900
  entries.push({
1460
1901
  // displayName FIRST: description is prose meant for a human reading the
@@ -1498,24 +1939,24 @@ function formatConsumptionFull(entries) {
1498
1939
  }
1499
1940
 
1500
1941
  // src/lib/context-loader.ts
1501
- import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
1502
- import { homedir as homedir6 } from "os";
1503
- import { join as join7 } from "path";
1504
- var DEFAULT_DIR6 = process.env.SUVEREN_DATA_DIR ?? join7(homedir6(), ".suveren");
1942
+ import { readFileSync as readFileSync11, existsSync as existsSync10 } from "fs";
1943
+ import { homedir as homedir7 } from "os";
1944
+ import { join as join10 } from "path";
1945
+ var DEFAULT_DIR7 = process.env.SUVEREN_DATA_DIR ?? join10(homedir7(), ".suveren");
1505
1946
  var BRIEF_MAX_CHARS = 16 * 1024;
1506
- function readContextFile(dataDir) {
1507
- const dir = dataDir ?? DEFAULT_DIR6;
1508
- const filePath = join7(dir, "context.md");
1509
- if (!existsSync7(filePath)) return null;
1947
+ function readContextFile(dataDir2) {
1948
+ const dir = dataDir2 ?? DEFAULT_DIR7;
1949
+ const filePath = join10(dir, "context.md");
1950
+ if (!existsSync10(filePath)) return null;
1510
1951
  try {
1511
- const content = readFileSync7(filePath, "utf-8").trim();
1952
+ const content = readFileSync11(filePath, "utf-8").trim();
1512
1953
  return content || null;
1513
1954
  } catch {
1514
1955
  return null;
1515
1956
  }
1516
1957
  }
1517
- function getContextForBrief(dataDir) {
1518
- const full = readContextFile(dataDir);
1958
+ function getContextForBrief(dataDir2) {
1959
+ const full = readContextFile(dataDir2);
1519
1960
  if (!full) return { brief: null, truncated: false };
1520
1961
  if (full.length <= BRIEF_MAX_CHARS) {
1521
1962
  return { brief: full, truncated: false };
@@ -1623,9 +2064,35 @@ function expiredSessionNotice(what) {
1623
2064
 
1624
2065
  TELL THE USER: open ${uiUrl()} and enter your Suveren API key to sign in again. Your mandates are safe; nothing ran.`;
1625
2066
  }
2067
+ function asKeyMismatchNotice(what) {
2068
+ return `${what} Suveren gateway is LOCKED because the Authority Server it is configured to use presented a signing key that does not match the one pinned when this gateway last signed in. This is NOT an ended sign-in \u2014 signing in again will be refused until the mismatch is resolved.
2069
+
2070
+ TELL THE USER: this needs an operator to check whether the Authority Server's key changed intentionally (e.g. a reinstall) or something else is answering at that address, at ${uiUrl()}. Nothing ran under the unrecognized key.`;
2071
+ }
2072
+ function asTlsMismatchNotice(what) {
2073
+ return `${what} Suveren gateway is LOCKED because a connection to the Authority Server presented a TLS certificate that does not match the one pinned when this gateway last signed in (opt-in pin-tls). This is NOT an ended sign-in \u2014 signing in again will be refused until the mismatch is resolved.
2074
+
2075
+ TELL THE USER: this needs an operator to check whether the Authority Server's certificate changed intentionally (e.g. a new TLS key, not just a renewal) or something else is answering at that address, at ${uiUrl()}. Nothing was sent under the unrecognized certificate.`;
2076
+ }
2077
+ function asUrlChangedNotice(what) {
2078
+ return `${what} Suveren gateway is LOCKED because the Authority Server it points at has changed since it last signed in. Cached mandates from the old server were cleared.
2079
+
2080
+ TELL THE USER: open ${uiUrl()} and sign in again to pair with the new Authority Server.`;
2081
+ }
1626
2082
  function lockedNotice(action, reason = "restart") {
1627
2083
  const what = action ? `Cannot ${action}: the` : "The";
1628
- return reason === "expired" ? expiredSessionNotice(what) : bootLockedNotice(what);
2084
+ switch (reason) {
2085
+ case "expired":
2086
+ return expiredSessionNotice(what);
2087
+ case "as-key-mismatch":
2088
+ return asKeyMismatchNotice(what);
2089
+ case "as-tls-mismatch":
2090
+ return asTlsMismatchNotice(what);
2091
+ case "as-url-changed":
2092
+ return asUrlChangedNotice(what);
2093
+ default:
2094
+ return bootLockedNotice(what);
2095
+ }
1629
2096
  }
1630
2097
 
1631
2098
  // src/tools/authorizations.ts
@@ -1634,6 +2101,9 @@ import { getProfile as getProfile4 } from "@hap/core";
1634
2101
  // src/lib/receipt-footer.ts
1635
2102
  import { deriveIdentityLine } from "@hap/core";
1636
2103
  var AS_BASE = (process.env.SUVEREN_AS_URL ?? "https://www.suveren.ai").replace(/\/$/, "");
2104
+ function setAsBaseUrl(url) {
2105
+ AS_BASE = url.replace(/\/$/, "");
2106
+ }
1637
2107
  var OPERATOR_NAME = process.env.SUVEREN_OPERATOR_NAME ?? "Suveren";
1638
2108
  var HAP_URL = "https://www.humanagencyprotocol.org/";
1639
2109
  var FOOTER_PROFILES = /* @__PURE__ */ new Set(["email", "calendar", "publish"]);
@@ -1739,6 +2209,88 @@ function attachReceiptId(tool, args, receiptId) {
1739
2209
  return { ...args, receipt_id: receiptId };
1740
2210
  }
1741
2211
 
2212
+ // src/lib/ticket-verify.ts
2213
+ import { verifyReceiptSignature } from "@hap/core";
2214
+ var TicketBindingMismatchError = class extends Error {
2215
+ constructor(message) {
2216
+ super(message);
2217
+ this.name = "TicketBindingMismatchError";
2218
+ }
2219
+ };
2220
+ var TICKET_MAX_AGE_SECONDS = 5 * 60;
2221
+ var TICKET_MAX_CLOCK_SKEW_SECONDS = 30;
2222
+ async function verifyTicket(cache, receipt, expected) {
2223
+ const publicKeyHex = await cache.getPublicKey();
2224
+ if (typeof receipt.signature !== "string" || !receipt.signature) {
2225
+ throw new AsKeyMismatchError("Ticket carries no signature \u2014 refusing to trust it.");
2226
+ }
2227
+ try {
2228
+ await verifyReceiptSignature(receipt, publicKeyHex);
2229
+ } catch (err) {
2230
+ throw new AsKeyMismatchError(
2231
+ `Ticket signature does not verify against the pinned Authority Server key \u2014 ${err instanceof Error ? err.message : String(err)}. Refusing to execute.`
2232
+ );
2233
+ }
2234
+ if (receipt.action !== expected.action) {
2235
+ throw new TicketBindingMismatchError(
2236
+ `Ticket action "${String(receipt.action)}" does not match the requested action "${expected.action}" \u2014 refusing to execute.`
2237
+ );
2238
+ }
2239
+ if (expected.executionContext !== void 0 && hashToolArgs(receipt.executionContext ?? {}) !== hashToolArgs(expected.executionContext)) {
2240
+ throw new TicketBindingMismatchError(
2241
+ "Ticket executionContext does not match what this call requested \u2014 refusing to execute."
2242
+ );
2243
+ }
2244
+ if (expected.authorizationId !== void 0 && receipt.authorizationId !== expected.authorizationId) {
2245
+ throw new TicketBindingMismatchError(
2246
+ `Ticket authorizationId "${String(receipt.authorizationId)}" does not match the requested grant "${expected.authorizationId}" \u2014 refusing to execute.`
2247
+ );
2248
+ }
2249
+ if (expected.profileId !== void 0 && receipt.profileId !== expected.profileId) {
2250
+ throw new TicketBindingMismatchError(
2251
+ `Ticket profileId "${String(receipt.profileId)}" does not match the requested profile "${expected.profileId}" \u2014 refusing to execute.`
2252
+ );
2253
+ }
2254
+ if (expected.proposalId !== void 0 && receipt.proposalId !== expected.proposalId) {
2255
+ throw new TicketBindingMismatchError(
2256
+ `Ticket proposalId "${String(receipt.proposalId)}" does not match the proposal being executed "${expected.proposalId}" \u2014 refusing to execute.`
2257
+ );
2258
+ }
2259
+ if (expected.idempotencyKey !== void 0 && receipt.idempotencyKey !== expected.idempotencyKey) {
2260
+ throw new TicketBindingMismatchError(
2261
+ `Ticket idempotencyKey "${String(receipt.idempotencyKey)}" does not match the one this call sent "${expected.idempotencyKey}" \u2014 refusing to execute.`
2262
+ );
2263
+ }
2264
+ if (expected.contentHash !== void 0) {
2265
+ if (receipt.contentHash !== expected.contentHash) {
2266
+ throw new TicketBindingMismatchError(
2267
+ "Ticket contentHash does not match the content this call is bound to \u2014 refusing to execute."
2268
+ );
2269
+ }
2270
+ if (expected.contentBinding !== void 0 && hashToolArgs(receipt.contentBinding ?? {}) !== hashToolArgs(expected.contentBinding)) {
2271
+ throw new TicketBindingMismatchError(
2272
+ "Ticket contentBinding does not match what this call requested \u2014 refusing to execute."
2273
+ );
2274
+ }
2275
+ }
2276
+ const timestamp = receipt.timestamp;
2277
+ if (typeof timestamp !== "number" || !Number.isFinite(timestamp)) {
2278
+ throw new TicketBindingMismatchError("Ticket carries no valid timestamp \u2014 refusing to execute.");
2279
+ }
2280
+ const nowSec3 = Math.floor(Date.now() / 1e3);
2281
+ const ageSec = nowSec3 - timestamp;
2282
+ if (ageSec > TICKET_MAX_AGE_SECONDS) {
2283
+ throw new TicketBindingMismatchError(
2284
+ `Ticket is ${ageSec}s old, older than the ${TICKET_MAX_AGE_SECONDS}s freshness window \u2014 refusing to execute.`
2285
+ );
2286
+ }
2287
+ if (ageSec < -TICKET_MAX_CLOCK_SKEW_SECONDS) {
2288
+ throw new TicketBindingMismatchError(
2289
+ `Ticket is timestamped ${-ageSec}s in the future, beyond the ${TICKET_MAX_CLOCK_SKEW_SECONDS}s clock-skew tolerance \u2014 refusing to execute.`
2290
+ );
2291
+ }
2292
+ }
2293
+
1742
2294
  // src/lib/arg-encoding.ts
1743
2295
  function rfc2047Encode(value) {
1744
2296
  if (!/[^\x00-\x7F]/.test(value)) return value;
@@ -2454,6 +3006,14 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
2454
3006
  toolArgs: enrichedArgs,
2455
3007
  executionContext: { ...execution }
2456
3008
  });
3009
+ state2.proposalSubmissions.record({
3010
+ proposalId: proposal.id,
3011
+ tool: tool.namespacedName,
3012
+ toolArgs: enrichedArgs,
3013
+ executionContext: { ...execution },
3014
+ authorizationId: authzId,
3015
+ profileId: auth.profileId
3016
+ });
2457
3017
  return {
2458
3018
  content: [{
2459
3019
  type: "text",
@@ -2478,6 +3038,7 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2478
3038
  try {
2479
3039
  const actionType = declaredActionType;
2480
3040
  const binding = computeContentBinding(auth.profileId, tool, args, actionType);
3041
+ const idempotencyKey = randomUUID();
2481
3042
  const { receipt } = await state2.spClient.postReceipt({
2482
3043
  authorizationId: authzId,
2483
3044
  // Optional cross-check — the AS fails closed on a mismatch.
@@ -2487,7 +3048,7 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2487
3048
  actionType,
2488
3049
  executionContext: { ...execution },
2489
3050
  amount: typeof execution.amount === "number" ? execution.amount : void 0,
2490
- idempotencyKey: randomUUID(),
3051
+ idempotencyKey,
2491
3052
  // Privacy: send the hash and how to reproduce it — never the
2492
3053
  // preimage. `binding` also carries `boundContent`, the plaintext
2493
3054
  // that was hashed (an email's to/cc/subject/body); it stays on
@@ -2496,6 +3057,15 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2496
3057
  ...binding ? { contentHash: binding.contentHash, contentBinding: binding.contentBinding } : {}
2497
3058
  });
2498
3059
  receiptId = typeof receipt?.id === "string" ? receipt.id : void 0;
3060
+ await verifyTicket(state2.cache, receipt, {
3061
+ action: tool.namespacedName,
3062
+ executionContext: { ...execution },
3063
+ authorizationId: authzId,
3064
+ profileId: auth.profileId,
3065
+ idempotencyKey,
3066
+ contentHash: binding?.contentHash,
3067
+ contentBinding: binding?.contentBinding
3068
+ });
2499
3069
  await state2.archiveReceipt(receipt, {
2500
3070
  authorizationId: authzId,
2501
3071
  profileId: auth.profileId,
@@ -2510,6 +3080,13 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2510
3080
  boundContent: binding?.boundContent
2511
3081
  });
2512
3082
  } catch (err) {
3083
+ if (err instanceof AsKeyMismatchError || err instanceof TicketBindingMismatchError) {
3084
+ void notifyControlPlane("as-key-mismatch");
3085
+ return {
3086
+ content: [{ type: "text", text: `Blocked: ${err.message}` }],
3087
+ isError: true
3088
+ };
3089
+ }
2513
3090
  if (err instanceof ContentBindingError) {
2514
3091
  return {
2515
3092
  content: [{
@@ -2555,6 +3132,14 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2555
3132
  executionContext: { ...execution },
2556
3133
  pendingApprovers: uniqueApprovers
2557
3134
  });
3135
+ state2.proposalSubmissions.record({
3136
+ proposalId: proposal.id,
3137
+ tool: tool.namespacedName,
3138
+ toolArgs: enrichedArgs,
3139
+ executionContext: { ...execution },
3140
+ authorizationId: authzId,
3141
+ profileId: auth.profileId
3142
+ });
2558
3143
  return {
2559
3144
  content: [{
2560
3145
  type: "text",
@@ -2962,6 +3547,9 @@ function listIntegrationsHandler(state2, integrationManager2) {
2962
3547
 
2963
3548
  // src/tools/commitments.ts
2964
3549
  import { ContentBindingError as ContentBindingError2 } from "@hap/core";
3550
+ function buildSkippedProposalNote(proposalId) {
3551
+ return `Proposal ${proposalId} was approved, but was submitted from another device/installation of this operator (or one whose local record is gone) \u2014 this gateway will not execute it. Re-run the same request here to execute it from this gateway.`;
3552
+ }
2965
3553
  var installedExecutor = null;
2966
3554
  function installCommittedExecutor(executor) {
2967
3555
  installedExecutor = executor;
@@ -2987,6 +3575,28 @@ async function executeCommitted(proposal, state2, integrationManager2) {
2987
3575
  );
2988
3576
  }
2989
3577
  const cachedAuth = state2.cache.getAllAuthorizations().find((a) => a.authorizationId === proposal.authorizationId);
3578
+ const submitted = state2.proposalSubmissions.get(proposal.id);
3579
+ if (!submitted) {
3580
+ console.error(
3581
+ `[Suveren MCP] Proposal ${proposal.id} is committed but has no local submission record on this gateway \u2014 leaving it for whichever gateway submitted it (this is normal for a different device of the same operator, or the AS lists a proposal we never submitted).`
3582
+ );
3583
+ return { text: buildSkippedProposalNote(proposal.id) };
3584
+ }
3585
+ {
3586
+ const mismatches = [];
3587
+ if (submitted.tool !== proposal.tool) mismatches.push("tool");
3588
+ if (submitted.toolArgsHash !== hashToolArgs(proposal.toolArgs)) mismatches.push("arguments");
3589
+ if (submitted.executionContextHash !== hashToolArgs(proposal.executionContext)) mismatches.push("executionContext");
3590
+ if (submitted.authorizationId !== proposal.authorizationId) mismatches.push("authorizationId");
3591
+ if (submitted.profileId !== proposal.profileId) mismatches.push("profileId");
3592
+ if (mismatches.length > 0) {
3593
+ void notifyControlPlane("as-key-mismatch");
3594
+ return {
3595
+ text: `Blocked: proposal ${proposal.id} no longer matches what this gateway submitted (${mismatches.join(", ")} differ) \u2014 refusing to execute.`,
3596
+ isError: true
3597
+ };
3598
+ }
3599
+ }
2990
3600
  let receiptId;
2991
3601
  let replayed = false;
2992
3602
  try {
@@ -3022,6 +3632,15 @@ async function executeCommitted(proposal, state2, integrationManager2) {
3022
3632
  });
3023
3633
  receiptId = typeof receipt?.id === "string" ? receipt.id : void 0;
3024
3634
  replayed = idempotent;
3635
+ await verifyTicket(state2.cache, receipt, {
3636
+ action: proposal.tool,
3637
+ executionContext: proposal.executionContext,
3638
+ authorizationId: proposal.authorizationId,
3639
+ profileId: proposal.profileId,
3640
+ proposalId: proposal.id,
3641
+ contentHash: binding?.contentHash,
3642
+ contentBinding: binding?.contentBinding
3643
+ });
3025
3644
  await state2.archiveReceipt(receipt, {
3026
3645
  authorizationId: proposal.authorizationId,
3027
3646
  profileId: proposal.profileId,
@@ -3036,6 +3655,13 @@ async function executeCommitted(proposal, state2, integrationManager2) {
3036
3655
  boundContent: binding?.boundContent
3037
3656
  });
3038
3657
  } catch (err) {
3658
+ if (err instanceof AsKeyMismatchError || err instanceof TicketBindingMismatchError) {
3659
+ void notifyControlPlane("as-key-mismatch");
3660
+ return {
3661
+ text: `Proposal ${proposal.id}: blocked \u2014 ${err.message}`,
3662
+ isError: true
3663
+ };
3664
+ }
3039
3665
  if (err instanceof ContentBindingError2) {
3040
3666
  return {
3041
3667
  text: `Proposal ${proposal.id}: blocked \u2014 the approved content cannot be bound to the receipt. ${err.message}`,
@@ -3195,9 +3821,13 @@ Wait for the human to approve; do not re-submit the tool call.`
3195
3821
  }]
3196
3822
  };
3197
3823
  }
3198
- const lines = committed.map(
3199
- (p) => `${p.id}: tool=${p.tool}, status=${p.status}, committed=[${Object.keys(p.committedBy).join(",")}]`
3200
- );
3824
+ const lines = committed.map((p) => {
3825
+ const base = `${p.id}: tool=${p.tool}, status=${p.status}, committed=[${Object.keys(p.committedBy).join(",")}]`;
3826
+ if (p.status === "committed" && !state2.proposalSubmissions.get(p.id)) {
3827
+ return `${base} \u2014 SKIPPED HERE: ${buildSkippedProposalNote(p.id)}`;
3828
+ }
3829
+ return base;
3830
+ });
3201
3831
  return {
3202
3832
  content: [{
3203
3833
  type: "text",
@@ -3394,16 +4024,16 @@ function verifyGateContentHashes(content, auth) {
3394
4024
  }
3395
4025
 
3396
4026
  // src/lib/integration-registry.ts
3397
- import { mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync8 } from "fs";
3398
- import { homedir as homedir7 } from "os";
3399
- import { dirname as dirname6, join as join8 } from "path";
3400
- var DEFAULT_DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join8(homedir7(), ".suveren");
4027
+ import { mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync9, existsSync as existsSync11 } from "fs";
4028
+ import { homedir as homedir8 } from "os";
4029
+ import { dirname as dirname9, join as join11 } from "path";
4030
+ var DEFAULT_DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join11(homedir8(), ".suveren");
3401
4031
  var IntegrationRegistry = class {
3402
4032
  integrations = /* @__PURE__ */ new Map();
3403
4033
  filePath;
3404
- constructor(dataDir) {
3405
- const dir = dataDir ?? DEFAULT_DATA_DIR;
3406
- this.filePath = join8(dir, "integrations.json");
4034
+ constructor(dataDir2) {
4035
+ const dir = dataDir2 ?? DEFAULT_DATA_DIR;
4036
+ this.filePath = join11(dir, "integrations.json");
3407
4037
  this.load();
3408
4038
  }
3409
4039
  // ─── CRUD ───────────────────────────────────────────────────────────────
@@ -3434,12 +4064,12 @@ var IntegrationRegistry = class {
3434
4064
  }
3435
4065
  // ─── Load / Save ────────────────────────────────────────────────────────
3436
4066
  load() {
3437
- if (!existsSync8(this.filePath)) {
3438
- mkdirSync6(dirname6(this.filePath), { recursive: true });
4067
+ if (!existsSync11(this.filePath)) {
4068
+ mkdirSync9(dirname9(this.filePath), { recursive: true });
3439
4069
  return;
3440
4070
  }
3441
4071
  try {
3442
- const raw = readFileSync8(this.filePath, "utf-8");
4072
+ const raw = readFileSync12(this.filePath, "utf-8");
3443
4073
  const data = JSON.parse(raw);
3444
4074
  const migrated = data.integrations.map((i) => {
3445
4075
  if ("toolGating" in i && !("profile" in i)) {
@@ -3468,45 +4098,45 @@ var IntegrationRegistry = class {
3468
4098
  version: 1,
3469
4099
  integrations: Array.from(this.integrations.values())
3470
4100
  };
3471
- mkdirSync6(dirname6(this.filePath), { recursive: true });
3472
- writeFileSync6(this.filePath, JSON.stringify(data, null, 2), { encoding: "utf-8" });
4101
+ mkdirSync9(dirname9(this.filePath), { recursive: true });
4102
+ writeFileSync9(this.filePath, JSON.stringify(data, null, 2), { encoding: "utf-8" });
3473
4103
  }
3474
4104
  };
3475
4105
 
3476
4106
  // src/lib/integration-manager.ts
3477
- import { homedir as homedir8 } from "os";
3478
- import { join as join10, delimiter } from "path";
3479
- import { existsSync as existsSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, readFileSync as readFileSync10, rmSync } from "fs";
4107
+ import { homedir as homedir9 } from "os";
4108
+ import { join as join13, delimiter } from "path";
4109
+ import { existsSync as existsSync13, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, readFileSync as readFileSync14, rmSync } from "fs";
3480
4110
  import { execFile } from "child_process";
3481
4111
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3482
4112
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3483
4113
  import { getProfile as getProfile5 } from "@hap/core";
3484
4114
 
3485
4115
  // src/lib/manifest-loader.ts
3486
- import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
3487
- import { join as join9, resolve } from "path";
4116
+ import { readFileSync as readFileSync13, existsSync as existsSync12 } from "fs";
4117
+ import { join as join12, resolve } from "path";
3488
4118
  var manifests = /* @__PURE__ */ new Map();
3489
4119
  function loadManifests(integrationsDir) {
3490
4120
  const dir = resolve(
3491
- integrationsDir ?? process.env.SUVEREN_MANIFESTS_DIR ?? join9(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "content", "integrations")
4121
+ integrationsDir ?? process.env.SUVEREN_MANIFESTS_DIR ?? join12(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "content", "integrations")
3492
4122
  );
3493
- const indexPath = join9(dir, "index.json");
3494
- if (!existsSync9(indexPath)) {
4123
+ const indexPath = join12(dir, "index.json");
4124
+ if (!existsSync12(indexPath)) {
3495
4125
  console.error(`[ManifestLoader] No index.json found at ${indexPath}, skipping manifest loading`);
3496
4126
  return 0;
3497
4127
  }
3498
4128
  let index;
3499
4129
  try {
3500
- index = JSON.parse(readFileSync9(indexPath, "utf-8"));
4130
+ index = JSON.parse(readFileSync13(indexPath, "utf-8"));
3501
4131
  } catch (err) {
3502
4132
  console.error(`[ManifestLoader] Failed to parse ${indexPath}:`, err);
3503
4133
  return 0;
3504
4134
  }
3505
4135
  let loaded = 0;
3506
4136
  for (const [id, relativePath] of Object.entries(index.integrations)) {
3507
- const manifestPath = join9(dir, relativePath);
4137
+ const manifestPath = join12(dir, relativePath);
3508
4138
  try {
3509
- const manifest = JSON.parse(readFileSync9(manifestPath, "utf-8"));
4139
+ const manifest = JSON.parse(readFileSync13(manifestPath, "utf-8"));
3510
4140
  manifests.set(id, manifest);
3511
4141
  loaded++;
3512
4142
  } catch (err) {
@@ -3594,26 +4224,26 @@ function safeHost(url) {
3594
4224
  }
3595
4225
 
3596
4226
  // src/lib/integration-manager.ts
3597
- var DEFAULT_DATA_DIR2 = process.env.SUVEREN_DATA_DIR ?? join10(homedir8(), ".suveren");
3598
- var INTEGRATIONS_DIR = process.env.SUVEREN_INTEGRATIONS_DIR ?? join10(DEFAULT_DATA_DIR2, "integrations");
4227
+ var DEFAULT_DATA_DIR2 = process.env.SUVEREN_DATA_DIR ?? join13(homedir9(), ".suveren");
4228
+ var INTEGRATIONS_DIR = process.env.SUVEREN_INTEGRATIONS_DIR ?? join13(DEFAULT_DATA_DIR2, "integrations");
3599
4229
  var installLock = Promise.resolve();
3600
4230
  function withInstallLock(task) {
3601
4231
  const run = installLock.then(task, task);
3602
4232
  installLock = run.then(() => void 0, () => void 0);
3603
4233
  return run;
3604
4234
  }
3605
- var INTEGRATIONS_BIN = join10(INTEGRATIONS_DIR, "node_modules", ".bin");
4235
+ var INTEGRATIONS_BIN = join13(INTEGRATIONS_DIR, "node_modules", ".bin");
3606
4236
  function buildPath() {
3607
4237
  const base = process.env.PATH ?? "";
3608
4238
  return [INTEGRATIONS_BIN, base].join(delimiter);
3609
4239
  }
3610
4240
  function ensureIntegrationsDir() {
3611
- if (!existsSync10(INTEGRATIONS_DIR)) {
3612
- mkdirSync7(INTEGRATIONS_DIR, { recursive: true });
4241
+ if (!existsSync13(INTEGRATIONS_DIR)) {
4242
+ mkdirSync10(INTEGRATIONS_DIR, { recursive: true });
3613
4243
  }
3614
- const pkgPath = join10(INTEGRATIONS_DIR, "package.json");
3615
- if (!existsSync10(pkgPath)) {
3616
- writeFileSync7(pkgPath, JSON.stringify({ name: "suveren-integrations", version: "1.0.0", private: true }, null, 2));
4244
+ const pkgPath = join13(INTEGRATIONS_DIR, "package.json");
4245
+ if (!existsSync13(pkgPath)) {
4246
+ writeFileSync10(pkgPath, JSON.stringify({ name: "suveren-integrations", version: "1.0.0", private: true }, null, 2));
3617
4247
  }
3618
4248
  }
3619
4249
  function readAgeOf(config) {
@@ -3679,19 +4309,19 @@ var IntegrationManager = class {
3679
4309
  * exist, and treat anything else as not-installed (and reinstallable).
3680
4310
  */
3681
4311
  isUsableInstall(npmPackage) {
3682
- const pkgDir = join10(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
3683
- const pkgJson = join10(pkgDir, "package.json");
3684
- if (!existsSync10(pkgDir) || !existsSync10(pkgJson)) return false;
4312
+ const pkgDir = join13(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
4313
+ const pkgJson = join13(pkgDir, "package.json");
4314
+ if (!existsSync13(pkgDir) || !existsSync13(pkgJson)) return false;
3685
4315
  try {
3686
- const pkg = JSON.parse(readFileSync10(pkgJson, "utf8"));
4316
+ const pkg = JSON.parse(readFileSync14(pkgJson, "utf8"));
3687
4317
  const defaultBinName = (pkg.name ?? npmPackage).split("/").pop() ?? "";
3688
4318
  const binMap = typeof pkg.bin === "string" ? { [defaultBinName]: pkg.bin } : pkg.bin ?? {};
3689
4319
  const binEntries = Object.entries(binMap);
3690
4320
  for (const [binName, target] of binEntries) {
3691
- if (!existsSync10(join10(pkgDir, target))) return false;
4321
+ if (!existsSync13(join13(pkgDir, target))) return false;
3692
4322
  if (!this.binShimExists(binName)) return false;
3693
4323
  }
3694
- if (binEntries.length === 0 && pkg.main && !existsSync10(join10(pkgDir, pkg.main))) return false;
4324
+ if (binEntries.length === 0 && pkg.main && !existsSync13(join13(pkgDir, pkg.main))) return false;
3695
4325
  return true;
3696
4326
  } catch {
3697
4327
  return false;
@@ -3705,7 +4335,7 @@ var IntegrationManager = class {
3705
4335
  binShimExists(binName) {
3706
4336
  if (!binName) return false;
3707
4337
  const candidates = process.platform === "win32" ? [binName, `${binName}.cmd`, `${binName}.CMD`, `${binName}.ps1`] : [binName];
3708
- return candidates.some((c) => existsSync10(join10(INTEGRATIONS_BIN, c)));
4338
+ return candidates.some((c) => existsSync13(join13(INTEGRATIONS_BIN, c)));
3709
4339
  }
3710
4340
  /**
3711
4341
  * Install an npm package into the managed integrations directory if not
@@ -3729,8 +4359,8 @@ var IntegrationManager = class {
3729
4359
  }
3730
4360
  /** The actual install. Callers MUST hold the install lock. */
3731
4361
  async installNow(npmPackage) {
3732
- const pkgDir = join10(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
3733
- if (existsSync10(pkgDir)) {
4362
+ const pkgDir = join13(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
4363
+ if (existsSync13(pkgDir)) {
3734
4364
  console.error(`[IntegrationManager] Removing unusable install of ${npmPackage}`);
3735
4365
  try {
3736
4366
  rmSync(pkgDir, { recursive: true, force: true });
@@ -3844,6 +4474,11 @@ var IntegrationManager = class {
3844
4474
  const transport = new StdioClientTransport({
3845
4475
  command: config.command,
3846
4476
  args,
4477
+ // `...process.env` is also how a saved `--ca-file` reaches an
4478
+ // integration: NODE_EXTRA_CA_CERTS (read by Node only at process
4479
+ // start) is already set on THIS process by bundle/server.js before
4480
+ // the MCP server ever starts, so every integration this manager spawns
4481
+ // inherits it here for free — no separate handling needed.
3847
4482
  env: {
3848
4483
  ...process.env,
3849
4484
  PATH: buildPath(),
@@ -4160,28 +4795,28 @@ var IntegrationManager = class {
4160
4795
  };
4161
4796
 
4162
4797
  // src/lib/profile-loader.ts
4163
- import { readFileSync as readFileSync11, existsSync as existsSync11 } from "fs";
4164
- import { join as join11, resolve as resolve2 } from "path";
4798
+ import { readFileSync as readFileSync15, existsSync as existsSync14 } from "fs";
4799
+ import { join as join14, resolve as resolve2 } from "path";
4165
4800
  import { registerProfile } from "@hap/core";
4166
4801
  function loadProfiles(profilesDir) {
4167
- const dir = resolve2(profilesDir ?? process.env.SUVEREN_PROFILES_DIR ?? join11(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "..", "hap-profiles"));
4168
- const indexPath = join11(dir, "index.json");
4169
- if (!existsSync11(indexPath)) {
4802
+ const dir = resolve2(profilesDir ?? process.env.SUVEREN_PROFILES_DIR ?? join14(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "..", "hap-profiles"));
4803
+ const indexPath = join14(dir, "index.json");
4804
+ if (!existsSync14(indexPath)) {
4170
4805
  warnNoProfiles(`No index.json at ${indexPath}`);
4171
4806
  return 0;
4172
4807
  }
4173
4808
  let index;
4174
4809
  try {
4175
- index = JSON.parse(readFileSync11(indexPath, "utf-8"));
4810
+ index = JSON.parse(readFileSync15(indexPath, "utf-8"));
4176
4811
  } catch (err) {
4177
4812
  console.error(`[ProfileLoader] Failed to parse ${indexPath}:`, err);
4178
4813
  return 0;
4179
4814
  }
4180
4815
  let loaded = 0;
4181
4816
  for (const [profileId, relativePath] of Object.entries(index.profiles)) {
4182
- const profilePath = join11(dir, relativePath);
4817
+ const profilePath = join14(dir, relativePath);
4183
4818
  try {
4184
- const profile = JSON.parse(readFileSync11(profilePath, "utf-8"));
4819
+ const profile = JSON.parse(readFileSync15(profilePath, "utf-8"));
4185
4820
  registerProfile(profileId, profile);
4186
4821
  const shortName = profileId.split("/").pop()?.replace(/@.*$/, "");
4187
4822
  if (shortName && shortName !== profileId) {
@@ -4217,8 +4852,8 @@ function warnNoProfiles(reason) {
4217
4852
  import { decodeAttestationBlob as decodeAttestationBlob3 } from "@hap/core";
4218
4853
 
4219
4854
  // src/lib/committed-executor.ts
4220
- import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync12, unlinkSync as unlinkSync5, writeFileSync as writeFileSync8 } from "fs";
4221
- import { dirname as dirname7, join as join12 } from "path";
4855
+ import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync16, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
4856
+ import { dirname as dirname10, join as join15 } from "path";
4222
4857
  var CommittedExecutor = class {
4223
4858
  constructor(run) {
4224
4859
  this.run = run;
@@ -4245,8 +4880,8 @@ var CommittedExecutor = class {
4245
4880
  var ExecutorLock = class {
4246
4881
  path;
4247
4882
  held = false;
4248
- constructor(dataDir) {
4249
- this.path = join12(dataDir, "executor.lock");
4883
+ constructor(dataDir2) {
4884
+ this.path = join15(dataDir2, "executor.lock");
4250
4885
  }
4251
4886
  /** Try to take the lock. Returns the holder's pid when someone else has it. */
4252
4887
  acquire() {
@@ -4254,9 +4889,9 @@ var ExecutorLock = class {
4254
4889
  if (current && current.pid !== process.pid && isAlive(current.pid)) {
4255
4890
  return { held: false, holderPid: current.pid };
4256
4891
  }
4257
- mkdirSync8(dirname7(this.path), { recursive: true, mode: 448 });
4892
+ mkdirSync11(dirname10(this.path), { recursive: true, mode: 448 });
4258
4893
  const lock = { pid: process.pid, startedAt: Math.floor(Date.now() / 1e3) };
4259
- writeFileSync8(this.path, JSON.stringify(lock), { mode: 384 });
4894
+ writeFileSync11(this.path, JSON.stringify(lock), { mode: 384 });
4260
4895
  this.held = true;
4261
4896
  return { held: true };
4262
4897
  }
@@ -4272,15 +4907,15 @@ var ExecutorLock = class {
4272
4907
  const current = this.read();
4273
4908
  if (current?.pid === process.pid) {
4274
4909
  try {
4275
- unlinkSync5(this.path);
4910
+ unlinkSync6(this.path);
4276
4911
  } catch {
4277
4912
  }
4278
4913
  }
4279
4914
  }
4280
4915
  read() {
4281
- if (!existsSync12(this.path)) return null;
4916
+ if (!existsSync15(this.path)) return null;
4282
4917
  try {
4283
- const parsed = JSON.parse(readFileSync12(this.path, "utf8"));
4918
+ const parsed = JSON.parse(readFileSync16(this.path, "utf8"));
4284
4919
  return typeof parsed?.pid === "number" ? parsed : null;
4285
4920
  } catch {
4286
4921
  return null;
@@ -4297,11 +4932,48 @@ function isAlive(pid) {
4297
4932
  }
4298
4933
 
4299
4934
  // bin/http.ts
4300
- import { homedir as homedir9 } from "os";
4301
- import { join as join13 } from "path";
4302
- var spUrl = process.env.SUVEREN_AS_URL ?? "https://www.suveren.ai";
4935
+ import { homedir as homedir10 } from "os";
4936
+ import { join as join17 } from "path";
4937
+
4938
+ // src/lib/mcp-as-tracker.ts
4939
+ import { existsSync as existsSync16, mkdirSync as mkdirSync12, readFileSync as readFileSync17, writeFileSync as writeFileSync12 } from "fs";
4940
+ import { dirname as dirname11, join as join16 } from "path";
4941
+ function trackerPath(dataDir2) {
4942
+ return join16(dataDir2, "mcp-as-pairing.json");
4943
+ }
4944
+ function readMcpPairedAsUrl(dataDir2) {
4945
+ const path = trackerPath(dataDir2);
4946
+ if (!existsSync16(path)) return null;
4947
+ try {
4948
+ const data = JSON.parse(readFileSync17(path, "utf-8"));
4949
+ return typeof data.asUrl === "string" ? data.asUrl : null;
4950
+ } catch {
4951
+ return null;
4952
+ }
4953
+ }
4954
+ function writeMcpPairedAsUrl(dataDir2, asUrl) {
4955
+ const path = trackerPath(dataDir2);
4956
+ mkdirSync12(dirname11(path), { recursive: true, mode: 448 });
4957
+ writeFileSync12(path, JSON.stringify({ asUrl }, null, 2), { encoding: "utf-8", mode: 384 });
4958
+ }
4959
+
4960
+ // bin/http.ts
4961
+ var dataDir = process.env.SUVEREN_DATA_DIR ?? join17(homedir10(), ".suveren");
4962
+ var spUrl = resolveAsUrl(dataDir);
4963
+ validatePinTlsForUrl(resolvePinTls(dataDir), spUrl);
4303
4964
  var port = parseInt(process.env.SUVEREN_MCP_PORT ?? "3430", 10);
4304
- var state = new SharedState(spUrl);
4965
+ setAsBaseUrl(spUrl);
4966
+ var state = new SharedState(spUrl, void 0, dataDir);
4967
+ (function repairIfAsUrlChanged() {
4968
+ const lastKnown = readMcpPairedAsUrl(dataDir);
4969
+ if (lastKnown !== null && lastKnown !== spUrl) {
4970
+ console.error(
4971
+ `[Suveren MCP] Authority Server changed (${lastKnown} \u2192 ${spUrl}) \u2014 clearing cached mandates. Sign in again to re-pair.`
4972
+ );
4973
+ state.gateStore.clearAll();
4974
+ }
4975
+ writeMcpPairedAsUrl(dataDir, spUrl);
4976
+ })();
4305
4977
  var spApiKey = process.env.SUVEREN_AS_API_KEY ?? "";
4306
4978
  if (spApiKey) {
4307
4979
  state.spClient.setApiKey(spApiKey);
@@ -4371,9 +5043,11 @@ app.post("/internal/configure", internalOnly, (req, res) => {
4371
5043
  }
4372
5044
  res.json({ ok: true });
4373
5045
  });
4374
- app.post("/internal/clear-session", internalOnly, (_req, res) => {
4375
- state.spClient.clearSession();
4376
- console.error("[Suveren MCP] Session cleared by control-plane (AS session ended)");
5046
+ app.post("/internal/clear-session", internalOnly, (req, res) => {
5047
+ const reason = req.body?.reason;
5048
+ const validReason = reason === "as-key-mismatch" || reason === "as-tls-mismatch" || reason === "as-url-changed" ? reason : void 0;
5049
+ state.spClient.clearSession(validReason);
5050
+ console.error(`[Suveren MCP] Session cleared by control-plane (${validReason ?? "expired"})`);
4377
5051
  res.json({ ok: true });
4378
5052
  });
4379
5053
  app.post("/internal/gate-content", internalOnly, async (req, res) => {
@@ -4665,6 +5339,15 @@ app.get("/internal/authorizations", internalOnly, (_req, res) => {
4665
5339
  app.get("/internal/manifests", internalOnly, (_req, res) => {
4666
5340
  res.json({ manifests: getAllManifests() });
4667
5341
  });
5342
+ app.get("/internal/skipped-commitments", internalOnly, async (_req, res) => {
5343
+ try {
5344
+ const committed = await state.spClient.getCommittedProposals();
5345
+ const skipped = committed.filter((p) => !state.proposalSubmissions.get(p.id)).map((p) => ({ id: p.id, tool: p.tool, note: buildSkippedProposalNote(p.id) }));
5346
+ res.json({ skipped });
5347
+ } catch (err) {
5348
+ res.status(502).json({ error: err instanceof Error ? err.message : "Could not reach the Authority Server" });
5349
+ }
5350
+ });
4668
5351
  app.get("/internal/evidence", internalOnly, (_req, res) => {
4669
5352
  if (state.receiptArchive.isLocked()) {
4670
5353
  res.status(503).json({ error: "Vault locked \u2014 the evidence archive is encrypted until sign-in." });
@@ -4798,12 +5481,12 @@ app.listen(port, "0.0.0.0", () => {
4798
5481
  (proposal) => executeCommitted(proposal, state, integrationManager)
4799
5482
  );
4800
5483
  installCommittedExecutor(committedExecutor);
4801
- const dataDir = process.env.SUVEREN_DATA_DIR ?? join13(homedir9(), ".suveren");
4802
- const executorLock = new ExecutorLock(dataDir);
5484
+ const dataDir2 = process.env.SUVEREN_DATA_DIR ?? join17(homedir10(), ".suveren");
5485
+ const executorLock = new ExecutorLock(dataDir2);
4803
5486
  const lock = executorLock.acquire();
4804
5487
  if (!lock.held) {
4805
5488
  console.error(
4806
- `[Suveren MCP] Committed-proposal execution is DISABLED in this process: pid ${lock.holderPid} holds ${dataDir}/executor.lock. Approved proposals will run there. Stop that gateway if this one should execute.`
5489
+ `[Suveren MCP] Committed-proposal execution is DISABLED in this process: pid ${lock.holderPid} holds ${dataDir2}/executor.lock. Approved proposals will run there. Stop that gateway if this one should execute.`
4807
5490
  );
4808
5491
  }
4809
5492
  for (const sig of ["SIGINT", "SIGTERM", "exit"]) {