@suveren/gateway 0.8.7 → 0.9.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 (642) hide show
  1. package/bin/suveren-gateway.js +165 -9
  2. package/dist/control-plane/index.mjs +330 -87
  3. package/dist/mcp-server/http.mjs +662 -186
  4. package/dist/ui/assets/{index-tzStUGuj.js → index-CIiOCgjJ.js} +21 -21
  5. package/dist/ui/index.html +1 -1
  6. package/lib/config.d.mts +37 -0
  7. package/lib/config.mjs +150 -0
  8. package/node_modules/@hap/core/dist/index.d.mts +33 -2
  9. package/node_modules/@hap/core/dist/index.d.ts +33 -2
  10. package/node_modules/@hap/core/dist/index.js +26 -2
  11. package/node_modules/@hap/core/dist/index.mjs +25 -2
  12. package/node_modules/@hap/core/package.json +1 -1
  13. package/node_modules/@hap/core/src/gatekeeper.ts +36 -2
  14. package/node_modules/@hap/core/src/types.ts +21 -1
  15. package/node_modules/@hono/node-server/README.md +21 -10
  16. package/node_modules/@hono/node-server/dist/early-hints.cjs +1 -1
  17. package/node_modules/@hono/node-server/dist/early-hints.mjs +1 -1
  18. package/node_modules/@hono/node-server/dist/index.cjs +41 -19
  19. package/node_modules/@hono/node-server/dist/index.mjs +42 -20
  20. package/node_modules/@hono/node-server/dist/serve-static.cjs +1 -0
  21. package/node_modules/@hono/node-server/dist/serve-static.d.cts +2 -1
  22. package/node_modules/@hono/node-server/dist/serve-static.d.mts +2 -1
  23. package/node_modules/@hono/node-server/dist/serve-static.mjs +1 -0
  24. package/node_modules/@hono/node-server/package.json +3 -2
  25. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.d.ts +43 -2
  26. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.d.ts.map +1 -1
  27. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.js +26 -5
  28. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth-extensions.js.map +1 -1
  29. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.d.ts +11 -0
  30. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.d.ts.map +1 -1
  31. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js +96 -14
  32. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/client/auth.js.map +1 -1
  33. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.d.ts +1 -0
  34. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.d.ts.map +1 -1
  35. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.js +11 -2
  36. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/client/simpleClientCredentials.js.map +1 -1
  37. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/demoInMemoryOAuthProvider.d.ts +2 -0
  38. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/examples/server/demoInMemoryOAuthProvider.d.ts.map +1 -1
  39. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/providers/proxyProvider.d.ts.map +1 -1
  40. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/providers/proxyProvider.js +6 -3
  41. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/auth/providers/proxyProvider.js.map +1 -1
  42. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.d.ts +3 -0
  43. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.d.ts.map +1 -1
  44. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.js +12 -2
  45. package/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/auth.js.map +1 -1
  46. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.d.ts +43 -2
  47. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.d.ts.map +1 -1
  48. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.js +26 -5
  49. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth-extensions.js.map +1 -1
  50. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts +11 -0
  51. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.d.ts.map +1 -1
  52. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js +96 -14
  53. package/node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js.map +1 -1
  54. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.d.ts +1 -0
  55. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.d.ts.map +1 -1
  56. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.js +11 -2
  57. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/client/simpleClientCredentials.js.map +1 -1
  58. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/demoInMemoryOAuthProvider.d.ts +2 -0
  59. package/node_modules/@modelcontextprotocol/sdk/dist/esm/examples/server/demoInMemoryOAuthProvider.d.ts.map +1 -1
  60. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/providers/proxyProvider.d.ts.map +1 -1
  61. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/providers/proxyProvider.js +6 -3
  62. package/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/providers/proxyProvider.js.map +1 -1
  63. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.d.ts +3 -0
  64. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.d.ts.map +1 -1
  65. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js +12 -2
  66. package/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js.map +1 -1
  67. package/node_modules/@modelcontextprotocol/sdk/package.json +1 -1
  68. package/node_modules/@types/node/README.md +1 -1
  69. package/node_modules/@types/node/crypto.d.ts +2 -2
  70. package/node_modules/@types/node/dgram.d.ts +1 -1
  71. package/node_modules/@types/node/package.json +2 -2
  72. package/node_modules/hono/dist/_virtual/_rolldown/runtime.js +13 -0
  73. package/node_modules/hono/dist/adapter/aws-lambda/conninfo.js +42 -23
  74. package/node_modules/hono/dist/adapter/aws-lambda/handler.js +318 -344
  75. package/node_modules/hono/dist/adapter/aws-lambda/index.js +2 -8
  76. package/node_modules/hono/dist/adapter/aws-lambda/types.js +1 -0
  77. package/node_modules/hono/dist/adapter/bun/conninfo.js +20 -25
  78. package/node_modules/hono/dist/adapter/bun/index.js +3 -13
  79. package/node_modules/hono/dist/adapter/bun/serve-static.js +27 -27
  80. package/node_modules/hono/dist/adapter/bun/server.js +11 -5
  81. package/node_modules/hono/dist/adapter/bun/ssg.js +25 -15
  82. package/node_modules/hono/dist/adapter/bun/websocket.js +61 -68
  83. package/node_modules/hono/dist/adapter/cloudflare-pages/conninfo.js +24 -9
  84. package/node_modules/hono/dist/adapter/cloudflare-pages/handler.js +59 -62
  85. package/node_modules/hono/dist/adapter/cloudflare-pages/index.js +2 -8
  86. package/node_modules/hono/dist/adapter/cloudflare-workers/conninfo.js +7 -9
  87. package/node_modules/hono/dist/adapter/cloudflare-workers/index.js +3 -8
  88. package/node_modules/hono/dist/adapter/cloudflare-workers/serve-static-module.js +5 -6
  89. package/node_modules/hono/dist/adapter/cloudflare-workers/serve-static.js +26 -20
  90. package/node_modules/hono/dist/adapter/cloudflare-workers/utils.js +21 -34
  91. package/node_modules/hono/dist/adapter/cloudflare-workers/websocket.js +31 -39
  92. package/node_modules/hono/dist/adapter/deno/conninfo.js +16 -13
  93. package/node_modules/hono/dist/adapter/deno/deno.d.js +1 -0
  94. package/node_modules/hono/dist/adapter/deno/index.js +3 -10
  95. package/node_modules/hono/dist/adapter/deno/serve-static.js +33 -38
  96. package/node_modules/hono/dist/adapter/deno/ssg.js +27 -16
  97. package/node_modules/hono/dist/adapter/deno/websocket.js +30 -30
  98. package/node_modules/hono/dist/adapter/lambda-edge/conninfo.js +7 -9
  99. package/node_modules/hono/dist/adapter/lambda-edge/handler.js +102 -101
  100. package/node_modules/hono/dist/adapter/lambda-edge/index.js +2 -6
  101. package/node_modules/hono/dist/adapter/netlify/conninfo.js +24 -9
  102. package/node_modules/hono/dist/adapter/netlify/handler.js +10 -8
  103. package/node_modules/hono/dist/adapter/netlify/index.js +3 -2
  104. package/node_modules/hono/dist/adapter/netlify/mod.js +2 -6
  105. package/node_modules/hono/dist/adapter/service-worker/handler.js +15 -19
  106. package/node_modules/hono/dist/adapter/service-worker/index.js +23 -7
  107. package/node_modules/hono/dist/adapter/service-worker/types.js +1 -0
  108. package/node_modules/hono/dist/adapter/vercel/conninfo.js +7 -10
  109. package/node_modules/hono/dist/adapter/vercel/handler.js +8 -6
  110. package/node_modules/hono/dist/adapter/vercel/index.js +2 -6
  111. package/node_modules/hono/dist/cjs/_virtual/_rolldown/runtime.js +33 -0
  112. package/node_modules/hono/dist/cjs/adapter/aws-lambda/conninfo.js +42 -44
  113. package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +326 -373
  114. package/node_modules/hono/dist/cjs/adapter/aws-lambda/index.js +7 -34
  115. package/node_modules/hono/dist/cjs/adapter/aws-lambda/types.js +0 -15
  116. package/node_modules/hono/dist/cjs/adapter/bun/conninfo.js +21 -47
  117. package/node_modules/hono/dist/cjs/adapter/bun/index.js +14 -45
  118. package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +29 -50
  119. package/node_modules/hono/dist/cjs/adapter/bun/server.js +11 -26
  120. package/node_modules/hono/dist/cjs/adapter/bun/ssg.js +24 -35
  121. package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +63 -91
  122. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/conninfo.js +25 -31
  123. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/handler.js +61 -85
  124. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/index.js +7 -34
  125. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/conninfo.js +8 -31
  126. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/index.js +7 -33
  127. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/serve-static-module.js +7 -29
  128. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/serve-static.js +27 -42
  129. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/utils.js +21 -55
  130. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/websocket.js +33 -62
  131. package/node_modules/hono/dist/cjs/adapter/deno/conninfo.js +16 -34
  132. package/node_modules/hono/dist/cjs/adapter/deno/index.js +10 -38
  133. package/node_modules/hono/dist/cjs/adapter/deno/serve-static.js +33 -59
  134. package/node_modules/hono/dist/cjs/adapter/deno/ssg.js +27 -37
  135. package/node_modules/hono/dist/cjs/adapter/deno/websocket.js +32 -53
  136. package/node_modules/hono/dist/cjs/adapter/lambda-edge/conninfo.js +8 -31
  137. package/node_modules/hono/dist/cjs/adapter/lambda-edge/handler.js +102 -130
  138. package/node_modules/hono/dist/cjs/adapter/lambda-edge/index.js +5 -30
  139. package/node_modules/hono/dist/cjs/adapter/netlify/conninfo.js +25 -31
  140. package/node_modules/hono/dist/cjs/adapter/netlify/handler.js +10 -29
  141. package/node_modules/hono/dist/cjs/adapter/netlify/index.js +5 -21
  142. package/node_modules/hono/dist/cjs/adapter/netlify/mod.js +5 -30
  143. package/node_modules/hono/dist/cjs/adapter/service-worker/handler.js +16 -41
  144. package/node_modules/hono/dist/cjs/adapter/service-worker/index.js +25 -30
  145. package/node_modules/hono/dist/cjs/adapter/service-worker/types.js +0 -15
  146. package/node_modules/hono/dist/cjs/adapter/vercel/conninfo.js +8 -32
  147. package/node_modules/hono/dist/cjs/adapter/vercel/handler.js +8 -27
  148. package/node_modules/hono/dist/cjs/adapter/vercel/index.js +5 -30
  149. package/node_modules/hono/dist/cjs/client/client.js +139 -212
  150. package/node_modules/hono/dist/cjs/client/fetch-result-please.js +62 -80
  151. package/node_modules/hono/dist/cjs/client/index.js +7 -32
  152. package/node_modules/hono/dist/cjs/client/types.js +0 -15
  153. package/node_modules/hono/dist/cjs/client/utils.js +54 -92
  154. package/node_modules/hono/dist/cjs/compose.js +49 -66
  155. package/node_modules/hono/dist/cjs/context.js +379 -450
  156. package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +47 -72
  157. package/node_modules/hono/dist/cjs/helper/accepts/index.js +3 -27
  158. package/node_modules/hono/dist/cjs/helper/adapter/index.js +33 -73
  159. package/node_modules/hono/dist/cjs/helper/conninfo/index.js +0 -15
  160. package/node_modules/hono/dist/cjs/helper/conninfo/types.js +0 -15
  161. package/node_modules/hono/dist/cjs/helper/cookie/index.js +75 -116
  162. package/node_modules/hono/dist/cjs/helper/css/common.js +165 -244
  163. package/node_modules/hono/dist/cjs/helper/css/index.js +136 -151
  164. package/node_modules/hono/dist/cjs/helper/dev/index.js +45 -71
  165. package/node_modules/hono/dist/cjs/helper/factory/index.js +30 -51
  166. package/node_modules/hono/dist/cjs/helper/html/index.js +32 -62
  167. package/node_modules/hono/dist/cjs/helper/proxy/index.js +113 -106
  168. package/node_modules/hono/dist/cjs/helper/route/index.js +123 -66
  169. package/node_modules/hono/dist/cjs/helper/ssg/index.js +19 -43
  170. package/node_modules/hono/dist/cjs/helper/ssg/middleware.js +56 -64
  171. package/node_modules/hono/dist/cjs/helper/ssg/plugins.js +55 -57
  172. package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +196 -296
  173. package/node_modules/hono/dist/cjs/helper/ssg/utils.js +47 -90
  174. package/node_modules/hono/dist/cjs/helper/streaming/index.js +8 -35
  175. package/node_modules/hono/dist/cjs/helper/streaming/sse.js +53 -85
  176. package/node_modules/hono/dist/cjs/helper/streaming/stream.js +23 -53
  177. package/node_modules/hono/dist/cjs/helper/streaming/text.js +10 -32
  178. package/node_modules/hono/dist/cjs/helper/streaming/utils.js +13 -32
  179. package/node_modules/hono/dist/cjs/helper/testing/index.js +16 -31
  180. package/node_modules/hono/dist/cjs/helper/websocket/index.js +51 -76
  181. package/node_modules/hono/dist/cjs/hono-base.js +345 -403
  182. package/node_modules/hono/dist/cjs/hono.js +28 -42
  183. package/node_modules/hono/dist/cjs/http-exception.js +55 -56
  184. package/node_modules/hono/dist/cjs/index.js +22 -30
  185. package/node_modules/hono/dist/cjs/jsx/base.js +237 -366
  186. package/node_modules/hono/dist/cjs/jsx/children.js +16 -41
  187. package/node_modules/hono/dist/cjs/jsx/components.js +119 -192
  188. package/node_modules/hono/dist/cjs/jsx/constants.js +15 -42
  189. package/node_modules/hono/dist/cjs/jsx/context.js +144 -162
  190. package/node_modules/hono/dist/cjs/jsx/dom/client.js +49 -69
  191. package/node_modules/hono/dist/cjs/jsx/dom/components.js +23 -52
  192. package/node_modules/hono/dist/cjs/jsx/dom/context.js +39 -67
  193. package/node_modules/hono/dist/cjs/jsx/dom/css.js +143 -158
  194. package/node_modules/hono/dist/cjs/jsx/dom/hooks/index.js +55 -64
  195. package/node_modules/hono/dist/cjs/jsx/dom/index.js +114 -173
  196. package/node_modules/hono/dist/cjs/jsx/dom/intrinsic-element/components.js +282 -375
  197. package/node_modules/hono/dist/cjs/jsx/dom/jsx-dev-runtime.js +14 -49
  198. package/node_modules/hono/dist/cjs/jsx/dom/jsx-runtime.js +5 -32
  199. package/node_modules/hono/dist/cjs/jsx/dom/render.js +469 -623
  200. package/node_modules/hono/dist/cjs/jsx/dom/server.js +37 -64
  201. package/node_modules/hono/dist/cjs/jsx/dom/utils.js +7 -30
  202. package/node_modules/hono/dist/cjs/jsx/hooks/index.js +225 -318
  203. package/node_modules/hono/dist/cjs/jsx/index.js +86 -135
  204. package/node_modules/hono/dist/cjs/jsx/intrinsic-element/common.js +20 -43
  205. package/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +117 -168
  206. package/node_modules/hono/dist/cjs/jsx/intrinsic-elements.js +0 -15
  207. package/node_modules/hono/dist/cjs/jsx/jsx-dev-runtime.js +14 -39
  208. package/node_modules/hono/dist/cjs/jsx/jsx-runtime.js +34 -68
  209. package/node_modules/hono/dist/cjs/jsx/streaming.js +123 -166
  210. package/node_modules/hono/dist/cjs/jsx/types.js +0 -15
  211. package/node_modules/hono/dist/cjs/jsx/utils.js +91 -175
  212. package/node_modules/hono/dist/cjs/middleware/basic-auth/index.js +98 -86
  213. package/node_modules/hono/dist/cjs/middleware/bearer-auth/index.js +92 -109
  214. package/node_modules/hono/dist/cjs/middleware/body-limit/index.js +66 -72
  215. package/node_modules/hono/dist/cjs/middleware/cache/index.js +153 -199
  216. package/node_modules/hono/dist/cjs/middleware/combine/index.js +135 -95
  217. package/node_modules/hono/dist/cjs/middleware/compress/index.js +73 -88
  218. package/node_modules/hono/dist/cjs/middleware/context-storage/index.js +49 -41
  219. package/node_modules/hono/dist/cjs/middleware/cors/index.js +107 -107
  220. package/node_modules/hono/dist/cjs/middleware/csrf/index.js +101 -72
  221. package/node_modules/hono/dist/cjs/middleware/etag/digest.js +58 -97
  222. package/node_modules/hono/dist/cjs/middleware/etag/index.js +71 -91
  223. package/node_modules/hono/dist/cjs/middleware/ip-restriction/index.js +161 -169
  224. package/node_modules/hono/dist/cjs/middleware/jsx-renderer/index.js +99 -77
  225. package/node_modules/hono/dist/cjs/middleware/jwk/index.js +3 -27
  226. package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +118 -135
  227. package/node_modules/hono/dist/cjs/middleware/jwt/index.js +9 -38
  228. package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +120 -141
  229. package/node_modules/hono/dist/cjs/middleware/language/index.js +7 -35
  230. package/node_modules/hono/dist/cjs/middleware/language/language.js +184 -182
  231. package/node_modules/hono/dist/cjs/middleware/logger/index.js +41 -62
  232. package/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +82 -88
  233. package/node_modules/hono/dist/cjs/middleware/method-override/index.js +101 -102
  234. package/node_modules/hono/dist/cjs/middleware/powered-by/index.js +23 -30
  235. package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +38 -42
  236. package/node_modules/hono/dist/cjs/middleware/request-id/index.js +3 -27
  237. package/node_modules/hono/dist/cjs/middleware/request-id/request-id.js +34 -42
  238. package/node_modules/hono/dist/cjs/middleware/secure-headers/index.js +4 -29
  239. package/node_modules/hono/dist/cjs/middleware/secure-headers/permissions-policy.js +0 -15
  240. package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +142 -174
  241. package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +56 -93
  242. package/node_modules/hono/dist/cjs/middleware/serve-static/path.js +15 -38
  243. package/node_modules/hono/dist/cjs/middleware/timeout/index.js +40 -45
  244. package/node_modules/hono/dist/cjs/middleware/timing/index.js +7 -35
  245. package/node_modules/hono/dist/cjs/middleware/timing/timing.js +177 -118
  246. package/node_modules/hono/dist/cjs/middleware/trailing-slash/index.js +85 -58
  247. package/node_modules/hono/dist/cjs/preset/quick.js +18 -37
  248. package/node_modules/hono/dist/cjs/preset/tiny.js +15 -33
  249. package/node_modules/hono/dist/cjs/request/constants.js +5 -27
  250. package/node_modules/hono/dist/cjs/request.js +334 -346
  251. package/node_modules/hono/dist/cjs/router/linear-router/index.js +3 -27
  252. package/node_modules/hono/dist/cjs/router/linear-router/router.js +95 -143
  253. package/node_modules/hono/dist/cjs/router/pattern-router/index.js +3 -27
  254. package/node_modules/hono/dist/cjs/router/pattern-router/router.js +41 -63
  255. package/node_modules/hono/dist/cjs/router/reg-exp-router/index.js +7 -34
  256. package/node_modules/hono/dist/cjs/router/reg-exp-router/matcher.js +18 -45
  257. package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +91 -135
  258. package/node_modules/hono/dist/cjs/router/reg-exp-router/prepared-router.js +92 -161
  259. package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +98 -147
  260. package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +73 -89
  261. package/node_modules/hono/dist/cjs/router/smart-router/index.js +3 -27
  262. package/node_modules/hono/dist/cjs/router/smart-router/router.js +49 -79
  263. package/node_modules/hono/dist/cjs/router/trie-router/index.js +3 -27
  264. package/node_modules/hono/dist/cjs/router/trie-router/node.js +134 -186
  265. package/node_modules/hono/dist/cjs/router/trie-router/router.js +15 -39
  266. package/node_modules/hono/dist/cjs/router/utils.js +5 -27
  267. package/node_modules/hono/dist/cjs/router.js +37 -37
  268. package/node_modules/hono/dist/cjs/types.js +5 -28
  269. package/node_modules/hono/dist/cjs/utils/accept.js +177 -225
  270. package/node_modules/hono/dist/cjs/utils/basic-auth.js +16 -40
  271. package/node_modules/hono/dist/cjs/utils/body.js +84 -110
  272. package/node_modules/hono/dist/cjs/utils/buffer.js +43 -91
  273. package/node_modules/hono/dist/cjs/utils/color.js +35 -44
  274. package/node_modules/hono/dist/cjs/utils/compress.js +11 -26
  275. package/node_modules/hono/dist/cjs/utils/concurrent.js +29 -59
  276. package/node_modules/hono/dist/cjs/utils/constants.js +7 -26
  277. package/node_modules/hono/dist/cjs/utils/cookie.js +107 -177
  278. package/node_modules/hono/dist/cjs/utils/crypto.js +30 -61
  279. package/node_modules/hono/dist/cjs/utils/encode.js +31 -48
  280. package/node_modules/hono/dist/cjs/utils/filepath.js +23 -54
  281. package/node_modules/hono/dist/cjs/utils/handler.js +11 -33
  282. package/node_modules/hono/dist/cjs/utils/headers.js +0 -15
  283. package/node_modules/hono/dist/cjs/utils/html.js +96 -137
  284. package/node_modules/hono/dist/cjs/utils/http-status.js +0 -15
  285. package/node_modules/hono/dist/cjs/utils/ipaddr.js +213 -286
  286. package/node_modules/hono/dist/cjs/utils/jwt/index.js +14 -27
  287. package/node_modules/hono/dist/cjs/utils/jwt/jwa.js +25 -42
  288. package/node_modules/hono/dist/cjs/utils/jwt/jws.js +119 -199
  289. package/node_modules/hono/dist/cjs/utils/jwt/jwt.js +122 -206
  290. package/node_modules/hono/dist/cjs/utils/jwt/types.js +122 -159
  291. package/node_modules/hono/dist/cjs/utils/jwt/utf8.js +9 -28
  292. package/node_modules/hono/dist/cjs/utils/mime.js +75 -101
  293. package/node_modules/hono/dist/cjs/utils/stream.js +88 -111
  294. package/node_modules/hono/dist/cjs/utils/types.js +0 -15
  295. package/node_modules/hono/dist/cjs/utils/url.js +185 -234
  296. package/node_modules/hono/dist/cjs/validator/index.js +3 -27
  297. package/node_modules/hono/dist/cjs/validator/utils.js +0 -15
  298. package/node_modules/hono/dist/cjs/validator/validator.js +60 -103
  299. package/node_modules/hono/dist/client/client.js +138 -197
  300. package/node_modules/hono/dist/client/fetch-result-please.js +59 -56
  301. package/node_modules/hono/dist/client/index.js +3 -7
  302. package/node_modules/hono/dist/client/types.js +1 -0
  303. package/node_modules/hono/dist/client/utils.js +51 -68
  304. package/node_modules/hono/dist/compose.js +49 -45
  305. package/node_modules/hono/dist/context.js +376 -426
  306. package/node_modules/hono/dist/helper/accepts/accepts.js +47 -51
  307. package/node_modules/hono/dist/helper/accepts/index.js +1 -4
  308. package/node_modules/hono/dist/helper/adapter/index.js +33 -52
  309. package/node_modules/hono/dist/helper/conninfo/index.js +1 -0
  310. package/node_modules/hono/dist/helper/conninfo/types.js +1 -0
  311. package/node_modules/hono/dist/helper/cookie/index.js +74 -94
  312. package/node_modules/hono/dist/helper/css/common.js +167 -225
  313. package/node_modules/hono/dist/helper/css/index.js +132 -137
  314. package/node_modules/hono/dist/helper/dev/index.js +44 -49
  315. package/node_modules/hono/dist/helper/factory/index.js +27 -27
  316. package/node_modules/hono/dist/helper/html/index.js +30 -39
  317. package/node_modules/hono/dist/helper/proxy/index.js +116 -88
  318. package/node_modules/hono/dist/helper/route/index.js +121 -43
  319. package/node_modules/hono/dist/helper/ssg/index.js +3 -18
  320. package/node_modules/hono/dist/helper/ssg/middleware.js +53 -40
  321. package/node_modules/hono/dist/helper/ssg/plugins.js +55 -36
  322. package/node_modules/hono/dist/helper/ssg/ssg.js +198 -283
  323. package/node_modules/hono/dist/helper/ssg/utils.js +53 -75
  324. package/node_modules/hono/dist/helper/streaming/index.js +2 -8
  325. package/node_modules/hono/dist/helper/streaming/sse.js +50 -61
  326. package/node_modules/hono/dist/helper/streaming/stream.js +22 -31
  327. package/node_modules/hono/dist/helper/streaming/text.js +9 -10
  328. package/node_modules/hono/dist/helper/streaming/utils.js +9 -12
  329. package/node_modules/hono/dist/helper/testing/index.js +16 -10
  330. package/node_modules/hono/dist/helper/websocket/index.js +49 -53
  331. package/node_modules/hono/dist/hono-base.js +342 -379
  332. package/node_modules/hono/dist/hono.js +27 -20
  333. package/node_modules/hono/dist/http-exception.js +53 -33
  334. package/node_modules/hono/dist/index.js +19 -6
  335. package/node_modules/hono/dist/jsx/base.js +231 -340
  336. package/node_modules/hono/dist/jsx/children.js +16 -20
  337. package/node_modules/hono/dist/jsx/components.js +118 -170
  338. package/node_modules/hono/dist/jsx/constants.js +9 -15
  339. package/node_modules/hono/dist/jsx/context.js +153 -150
  340. package/node_modules/hono/dist/jsx/dom/client.js +45 -48
  341. package/node_modules/hono/dist/jsx/dom/components.js +21 -29
  342. package/node_modules/hono/dist/jsx/dom/context.js +37 -44
  343. package/node_modules/hono/dist/jsx/dom/css.js +142 -147
  344. package/node_modules/hono/dist/jsx/dom/hooks/index.js +52 -40
  345. package/node_modules/hono/dist/jsx/dom/index.js +71 -134
  346. package/node_modules/hono/dist/jsx/dom/intrinsic-element/components.js +275 -359
  347. package/node_modules/hono/dist/jsx/dom/jsx-dev-runtime.js +14 -18
  348. package/node_modules/hono/dist/jsx/dom/jsx-runtime.js +2 -8
  349. package/node_modules/hono/dist/jsx/dom/render.js +492 -631
  350. package/node_modules/hono/dist/jsx/dom/server.js +32 -32
  351. package/node_modules/hono/dist/jsx/dom/utils.js +6 -8
  352. package/node_modules/hono/dist/jsx/hooks/index.js +236 -308
  353. package/node_modules/hono/dist/jsx/index.js +45 -98
  354. package/node_modules/hono/dist/jsx/intrinsic-element/common.js +20 -22
  355. package/node_modules/hono/dist/jsx/intrinsic-element/components.js +113 -154
  356. package/node_modules/hono/dist/jsx/intrinsic-elements.js +1 -0
  357. package/node_modules/hono/dist/jsx/jsx-dev-runtime.js +12 -16
  358. package/node_modules/hono/dist/jsx/jsx-runtime.js +29 -42
  359. package/node_modules/hono/dist/jsx/streaming.js +120 -142
  360. package/node_modules/hono/dist/jsx/types.js +1 -0
  361. package/node_modules/hono/dist/jsx/utils.js +105 -168
  362. package/node_modules/hono/dist/middleware/basic-auth/index.js +96 -63
  363. package/node_modules/hono/dist/middleware/bearer-auth/index.js +93 -89
  364. package/node_modules/hono/dist/middleware/body-limit/index.js +66 -51
  365. package/node_modules/hono/dist/middleware/cache/index.js +165 -190
  366. package/node_modules/hono/dist/middleware/combine/index.js +134 -73
  367. package/node_modules/hono/dist/middleware/compress/index.js +75 -69
  368. package/node_modules/hono/dist/middleware/context-storage/index.js +49 -19
  369. package/node_modules/hono/dist/middleware/cors/index.js +107 -86
  370. package/node_modules/hono/dist/middleware/csrf/index.js +103 -53
  371. package/node_modules/hono/dist/middleware/etag/digest.js +59 -77
  372. package/node_modules/hono/dist/middleware/etag/index.js +71 -70
  373. package/node_modules/hono/dist/middleware/ip-restriction/index.js +163 -158
  374. package/node_modules/hono/dist/middleware/jsx-renderer/index.js +97 -54
  375. package/node_modules/hono/dist/middleware/jwk/index.js +1 -4
  376. package/node_modules/hono/dist/middleware/jwk/jwk.js +116 -112
  377. package/node_modules/hono/dist/middleware/jwt/index.js +2 -10
  378. package/node_modules/hono/dist/middleware/jwt/jwt.js +114 -114
  379. package/node_modules/hono/dist/middleware/language/index.js +2 -15
  380. package/node_modules/hono/dist/middleware/language/language.js +180 -157
  381. package/node_modules/hono/dist/middleware/logger/index.js +43 -37
  382. package/node_modules/hono/dist/middleware/method-not-allowed/index.js +81 -66
  383. package/node_modules/hono/dist/middleware/method-override/index.js +101 -81
  384. package/node_modules/hono/dist/middleware/powered-by/index.js +23 -9
  385. package/node_modules/hono/dist/middleware/pretty-json/index.js +39 -22
  386. package/node_modules/hono/dist/middleware/request-id/index.js +1 -4
  387. package/node_modules/hono/dist/middleware/request-id/request-id.js +33 -20
  388. package/node_modules/hono/dist/middleware/secure-headers/index.js +1 -5
  389. package/node_modules/hono/dist/middleware/secure-headers/permissions-policy.js +1 -0
  390. package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +144 -155
  391. package/node_modules/hono/dist/middleware/serve-static/index.js +56 -72
  392. package/node_modules/hono/dist/middleware/serve-static/path.js +15 -17
  393. package/node_modules/hono/dist/middleware/timeout/index.js +40 -23
  394. package/node_modules/hono/dist/middleware/timing/index.js +2 -9
  395. package/node_modules/hono/dist/middleware/timing/timing.js +177 -97
  396. package/node_modules/hono/dist/middleware/trailing-slash/index.js +85 -37
  397. package/node_modules/hono/dist/preset/quick.js +17 -15
  398. package/node_modules/hono/dist/preset/tiny.js +14 -11
  399. package/node_modules/hono/dist/request/constants.js +4 -5
  400. package/node_modules/hono/dist/request.js +328 -319
  401. package/node_modules/hono/dist/router/linear-router/index.js +1 -4
  402. package/node_modules/hono/dist/router/linear-router/router.js +93 -120
  403. package/node_modules/hono/dist/router/pattern-router/index.js +1 -4
  404. package/node_modules/hono/dist/router/pattern-router/router.js +39 -40
  405. package/node_modules/hono/dist/router/reg-exp-router/index.js +1 -7
  406. package/node_modules/hono/dist/router/reg-exp-router/matcher.js +17 -23
  407. package/node_modules/hono/dist/router/reg-exp-router/node.js +87 -110
  408. package/node_modules/hono/dist/router/reg-exp-router/prepared-router.js +89 -137
  409. package/node_modules/hono/dist/router/reg-exp-router/router.js +92 -129
  410. package/node_modules/hono/dist/router/reg-exp-router/trie.js +69 -64
  411. package/node_modules/hono/dist/router/smart-router/index.js +1 -4
  412. package/node_modules/hono/dist/router/smart-router/router.js +46 -55
  413. package/node_modules/hono/dist/router/trie-router/index.js +1 -4
  414. package/node_modules/hono/dist/router/trie-router/node.js +131 -162
  415. package/node_modules/hono/dist/router/trie-router/router.js +11 -14
  416. package/node_modules/hono/dist/router/utils.js +4 -5
  417. package/node_modules/hono/dist/router.js +35 -14
  418. package/node_modules/hono/dist/types/adapter/aws-lambda/conninfo.d.ts +4 -1
  419. package/node_modules/hono/dist/types/adapter/aws-lambda/handler.d.ts +150 -104
  420. package/node_modules/hono/dist/types/adapter/aws-lambda/index.d.ts +4 -8
  421. package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +152 -122
  422. package/node_modules/hono/dist/types/adapter/bun/conninfo.d.ts +4 -1
  423. package/node_modules/hono/dist/types/adapter/bun/index.d.ts +6 -10
  424. package/node_modules/hono/dist/types/adapter/bun/serve-static.d.ts +7 -2
  425. package/node_modules/hono/dist/types/adapter/bun/server.d.ts +4 -5
  426. package/node_modules/hono/dist/types/adapter/bun/ssg.d.ts +5 -1
  427. package/node_modules/hono/dist/types/adapter/bun/websocket.d.ts +31 -16
  428. package/node_modules/hono/dist/types/adapter/cloudflare-pages/conninfo.d.ts +4 -1
  429. package/node_modules/hono/dist/types/adapter/cloudflare-pages/handler.d.ts +29 -17
  430. package/node_modules/hono/dist/types/adapter/cloudflare-pages/index.d.ts +3 -7
  431. package/node_modules/hono/dist/types/adapter/cloudflare-workers/conninfo.d.ts +6 -1
  432. package/node_modules/hono/dist/types/adapter/cloudflare-workers/index.d.ts +4 -7
  433. package/node_modules/hono/dist/types/adapter/cloudflare-workers/serve-static-module.d.ts +5 -2
  434. package/node_modules/hono/dist/types/adapter/cloudflare-workers/serve-static.d.ts +10 -5
  435. package/node_modules/hono/dist/types/adapter/cloudflare-workers/utils.d.ts +10 -2
  436. package/node_modules/hono/dist/types/adapter/cloudflare-workers/websocket.d.ts +6 -1
  437. package/node_modules/hono/dist/types/adapter/deno/conninfo.d.ts +4 -1
  438. package/node_modules/hono/dist/types/adapter/deno/deno.d.ts +1 -0
  439. package/node_modules/hono/dist/types/adapter/deno/index.d.ts +5 -8
  440. package/node_modules/hono/dist/types/adapter/deno/serve-static.d.ts +7 -2
  441. package/node_modules/hono/dist/types/adapter/deno/ssg.d.ts +5 -1
  442. package/node_modules/hono/dist/types/adapter/deno/websocket.d.ts +6 -1
  443. package/node_modules/hono/dist/types/adapter/lambda-edge/conninfo.d.ts +6 -1
  444. package/node_modules/hono/dist/types/adapter/lambda-edge/handler.d.ts +83 -57
  445. package/node_modules/hono/dist/types/adapter/lambda-edge/index.d.ts +3 -7
  446. package/node_modules/hono/dist/types/adapter/netlify/conninfo.d.ts +4 -1
  447. package/node_modules/hono/dist/types/adapter/netlify/handler.d.ts +6 -1
  448. package/node_modules/hono/dist/types/adapter/netlify/index.d.ts +3 -5
  449. package/node_modules/hono/dist/types/adapter/netlify/mod.d.ts +3 -2
  450. package/node_modules/hono/dist/types/adapter/service-worker/handler.d.ts +9 -7
  451. package/node_modules/hono/dist/types/adapter/service-worker/index.d.ts +7 -9
  452. package/node_modules/hono/dist/types/adapter/service-worker/types.d.ts +12 -7
  453. package/node_modules/hono/dist/types/adapter/vercel/conninfo.d.ts +6 -1
  454. package/node_modules/hono/dist/types/adapter/vercel/handler.d.ts +6 -1
  455. package/node_modules/hono/dist/types/adapter/vercel/index.d.ts +3 -6
  456. package/node_modules/hono/dist/types/client/client.d.ts +5 -3
  457. package/node_modules/hono/dist/types/client/fetch-result-please.d.ts +21 -19
  458. package/node_modules/hono/dist/types/client/index.d.ts +5 -7
  459. package/node_modules/hono/dist/types/client/types.d.ts +134 -159
  460. package/node_modules/hono/dist/types/client/utils.d.ts +6 -4
  461. package/node_modules/hono/dist/types/compose.d.ts +4 -2
  462. package/node_modules/hono/dist/types/context.d.ts +335 -335
  463. package/node_modules/hono/dist/types/helper/accepts/accepts.d.ts +11 -9
  464. package/node_modules/hono/dist/types/helper/accepts/index.d.ts +2 -5
  465. package/node_modules/hono/dist/types/helper/adapter/index.d.ts +4 -6
  466. package/node_modules/hono/dist/types/helper/conninfo/index.d.ts +2 -5
  467. package/node_modules/hono/dist/types/helper/conninfo/types.d.ts +25 -23
  468. package/node_modules/hono/dist/types/helper/cookie/index.d.ts +10 -12
  469. package/node_modules/hono/dist/types/helper/css/common.d.ts +11 -9
  470. package/node_modules/hono/dist/types/helper/css/index.d.ts +26 -28
  471. package/node_modules/hono/dist/types/helper/dev/index.d.ts +10 -12
  472. package/node_modules/hono/dist/types/helper/factory/index.d.ts +26 -73
  473. package/node_modules/hono/dist/types/helper/html/index.d.ts +4 -7
  474. package/node_modules/hono/dist/types/helper/proxy/index.d.ts +19 -21
  475. package/node_modules/hono/dist/types/helper/route/index.d.ts +4 -2
  476. package/node_modules/hono/dist/types/helper/ssg/index.d.ts +4 -7
  477. package/node_modules/hono/dist/types/helper/ssg/middleware.d.ts +8 -6
  478. package/node_modules/hono/dist/types/helper/ssg/plugins.d.ts +3 -1
  479. package/node_modules/hono/dist/types/helper/ssg/ssg.d.ts +38 -36
  480. package/node_modules/hono/dist/types/helper/ssg/utils.d.ts +5 -3
  481. package/node_modules/hono/dist/types/helper/streaming/index.d.ts +4 -8
  482. package/node_modules/hono/dist/types/helper/streaming/sse.d.ts +10 -8
  483. package/node_modules/hono/dist/types/helper/streaming/stream.d.ts +4 -2
  484. package/node_modules/hono/dist/types/helper/streaming/text.d.ts +4 -2
  485. package/node_modules/hono/dist/types/helper/streaming/utils.d.ts +2 -0
  486. package/node_modules/hono/dist/types/helper/testing/index.d.ts +7 -9
  487. package/node_modules/hono/dist/types/helper/websocket/index.d.ts +30 -33
  488. package/node_modules/hono/dist/types/hono-base.d.ts +208 -210
  489. package/node_modules/hono/dist/types/hono.d.ts +11 -10
  490. package/node_modules/hono/dist/types/http-exception.d.ts +20 -22
  491. package/node_modules/hono/dist/types/index.d.ts +6 -37
  492. package/node_modules/hono/dist/types/jsx/base.d.ts +36 -34
  493. package/node_modules/hono/dist/types/jsx/children.d.ts +8 -6
  494. package/node_modules/hono/dist/types/jsx/components.d.ts +8 -5
  495. package/node_modules/hono/dist/types/jsx/constants.d.ts +2 -0
  496. package/node_modules/hono/dist/types/jsx/context.d.ts +9 -6
  497. package/node_modules/hono/dist/types/jsx/dom/client.d.ts +9 -10
  498. package/node_modules/hono/dist/types/jsx/dom/components.d.ts +9 -6
  499. package/node_modules/hono/dist/types/jsx/dom/context.d.ts +3 -1
  500. package/node_modules/hono/dist/types/jsx/dom/css.d.ts +27 -30
  501. package/node_modules/hono/dist/types/jsx/dom/hooks/index.d.ts +11 -12
  502. package/node_modules/hono/dist/types/jsx/dom/index.d.ts +79 -83
  503. package/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +9 -5
  504. package/node_modules/hono/dist/types/jsx/dom/jsx-dev-runtime.d.ts +4 -6
  505. package/node_modules/hono/dist/types/jsx/dom/jsx-runtime.d.ts +3 -7
  506. package/node_modules/hono/dist/types/jsx/dom/render.d.ts +32 -50
  507. package/node_modules/hono/dist/types/jsx/dom/server.d.ts +87 -85
  508. package/node_modules/hono/dist/types/jsx/dom/utils.d.ts +2 -0
  509. package/node_modules/hono/dist/types/jsx/hooks/index.d.ts +16 -16
  510. package/node_modules/hono/dist/types/jsx/index.d.ts +71 -73
  511. package/node_modules/hono/dist/types/jsx/intrinsic-element/common.d.ts +3 -1
  512. package/node_modules/hono/dist/types/jsx/intrinsic-element/components.d.ts +7 -4
  513. package/node_modules/hono/dist/types/jsx/intrinsic-elements.d.ts +708 -708
  514. package/node_modules/hono/dist/types/jsx/jsx-dev-runtime.d.ts +4 -7
  515. package/node_modules/hono/dist/types/jsx/jsx-runtime.d.ts +7 -10
  516. package/node_modules/hono/dist/types/jsx/streaming.d.ts +9 -10
  517. package/node_modules/hono/dist/types/jsx/types.d.ts +12 -13
  518. package/node_modules/hono/dist/types/jsx/utils.d.ts +2 -0
  519. package/node_modules/hono/dist/types/middleware/basic-auth/index.d.ts +17 -19
  520. package/node_modules/hono/dist/types/middleware/bearer-auth/index.d.ts +46 -48
  521. package/node_modules/hono/dist/types/middleware/body-limit/index.d.ts +6 -8
  522. package/node_modules/hono/dist/types/middleware/cache/index.d.ts +13 -15
  523. package/node_modules/hono/dist/types/middleware/combine/index.d.ts +4 -6
  524. package/node_modules/hono/dist/types/middleware/compress/index.d.ts +9 -10
  525. package/node_modules/hono/dist/types/middleware/context-storage/index.d.ts +4 -6
  526. package/node_modules/hono/dist/types/middleware/cors/index.d.ts +10 -12
  527. package/node_modules/hono/dist/types/middleware/csrf/index.d.ts +6 -8
  528. package/node_modules/hono/dist/types/middleware/etag/digest.d.ts +2 -0
  529. package/node_modules/hono/dist/types/middleware/etag/index.d.ts +6 -8
  530. package/node_modules/hono/dist/types/middleware/ip-restriction/index.d.ts +11 -12
  531. package/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +11 -11
  532. package/node_modules/hono/dist/types/middleware/jwk/index.d.ts +2 -1
  533. package/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +20 -23
  534. package/node_modules/hono/dist/types/middleware/jwt/index.d.ts +7 -6
  535. package/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +28 -30
  536. package/node_modules/hono/dist/types/middleware/language/index.d.ts +6 -5
  537. package/node_modules/hono/dist/types/middleware/language/language.d.ts +42 -44
  538. package/node_modules/hono/dist/types/middleware/logger/index.d.ts +3 -5
  539. package/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +7 -9
  540. package/node_modules/hono/dist/types/middleware/method-override/index.d.ts +14 -16
  541. package/node_modules/hono/dist/types/middleware/powered-by/index.d.ts +8 -10
  542. package/node_modules/hono/dist/types/middleware/pretty-json/index.d.ts +18 -20
  543. package/node_modules/hono/dist/types/middleware/request-id/index.d.ts +6 -5
  544. package/node_modules/hono/dist/types/middleware/request-id/request-id.d.ts +9 -11
  545. package/node_modules/hono/dist/types/middleware/secure-headers/index.d.ts +6 -6
  546. package/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +2 -0
  547. package/node_modules/hono/dist/types/middleware/secure-headers/secure-headers.d.ts +55 -57
  548. package/node_modules/hono/dist/types/middleware/serve-static/index.d.ts +24 -24
  549. package/node_modules/hono/dist/types/middleware/serve-static/path.d.ts +2 -0
  550. package/node_modules/hono/dist/types/middleware/timeout/index.d.ts +5 -7
  551. package/node_modules/hono/dist/types/middleware/timing/index.d.ts +6 -5
  552. package/node_modules/hono/dist/types/middleware/timing/timing.d.ts +17 -20
  553. package/node_modules/hono/dist/types/middleware/trailing-slash/index.d.ts +35 -37
  554. package/node_modules/hono/dist/types/preset/quick.d.ts +6 -9
  555. package/node_modules/hono/dist/types/preset/tiny.d.ts +6 -9
  556. package/node_modules/hono/dist/types/request/constants.d.ts +2 -0
  557. package/node_modules/hono/dist/types/request.d.ts +288 -286
  558. package/node_modules/hono/dist/types/router/linear-router/index.d.ts +2 -5
  559. package/node_modules/hono/dist/types/router/linear-router/router.d.ts +7 -5
  560. package/node_modules/hono/dist/types/router/pattern-router/index.d.ts +2 -5
  561. package/node_modules/hono/dist/types/router/pattern-router/router.d.ts +7 -5
  562. package/node_modules/hono/dist/types/router/reg-exp-router/index.d.ts +3 -6
  563. package/node_modules/hono/dist/types/router/reg-exp-router/matcher.d.ts +3 -1
  564. package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +6 -4
  565. package/node_modules/hono/dist/types/router/reg-exp-router/prepared-router.d.ts +11 -10
  566. package/node_modules/hono/dist/types/router/reg-exp-router/router.d.ts +10 -9
  567. package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +7 -5
  568. package/node_modules/hono/dist/types/router/smart-router/index.d.ts +2 -5
  569. package/node_modules/hono/dist/types/router/smart-router/router.d.ts +11 -9
  570. package/node_modules/hono/dist/types/router/trie-router/index.d.ts +2 -5
  571. package/node_modules/hono/dist/types/router/trie-router/node.d.ts +6 -4
  572. package/node_modules/hono/dist/types/router/trie-router/router.d.ts +7 -5
  573. package/node_modules/hono/dist/types/router/utils.d.ts +2 -0
  574. package/node_modules/hono/dist/types/router.d.ts +23 -22
  575. package/node_modules/hono/dist/types/types.d.ts +146 -505
  576. package/node_modules/hono/dist/types/utils/accept.d.ts +5 -3
  577. package/node_modules/hono/dist/types/utils/basic-auth.d.ts +4 -2
  578. package/node_modules/hono/dist/types/utils/body.d.ts +46 -50
  579. package/node_modules/hono/dist/types/utils/buffer.d.ts +7 -5
  580. package/node_modules/hono/dist/types/utils/color.d.ts +2 -0
  581. package/node_modules/hono/dist/types/utils/compress.d.ts +2 -0
  582. package/node_modules/hono/dist/types/utils/concurrent.d.ts +6 -4
  583. package/node_modules/hono/dist/types/utils/constants.d.ts +2 -0
  584. package/node_modules/hono/dist/types/utils/cookie.d.ts +20 -18
  585. package/node_modules/hono/dist/types/utils/crypto.d.ts +5 -7
  586. package/node_modules/hono/dist/types/utils/encode.d.ts +2 -0
  587. package/node_modules/hono/dist/types/utils/filepath.d.ts +5 -3
  588. package/node_modules/hono/dist/types/utils/handler.d.ts +2 -0
  589. package/node_modules/hono/dist/types/utils/headers.d.ts +2 -0
  590. package/node_modules/hono/dist/types/utils/html.d.ts +11 -9
  591. package/node_modules/hono/dist/types/utils/http-status.d.ts +2 -0
  592. package/node_modules/hono/dist/types/utils/ipaddr.d.ts +4 -6
  593. package/node_modules/hono/dist/types/utils/jwt/index.d.ts +18 -12
  594. package/node_modules/hono/dist/types/utils/jwt/jwa.d.ts +15 -13
  595. package/node_modules/hono/dist/types/utils/jwt/jws.d.ts +4 -7
  596. package/node_modules/hono/dist/types/utils/jwt/jwt.d.ts +26 -29
  597. package/node_modules/hono/dist/types/utils/jwt/types.d.ts +48 -45
  598. package/node_modules/hono/dist/types/utils/jwt/utf8.d.ts +2 -0
  599. package/node_modules/hono/dist/types/utils/mime.d.ts +60 -57
  600. package/node_modules/hono/dist/types/utils/stream.d.ts +27 -25
  601. package/node_modules/hono/dist/types/utils/types.d.ts +14 -26
  602. package/node_modules/hono/dist/types/utils/url.d.ts +2 -0
  603. package/node_modules/hono/dist/types/validator/index.d.ts +3 -7
  604. package/node_modules/hono/dist/types/validator/utils.d.ts +6 -8
  605. package/node_modules/hono/dist/types/validator/validator.d.ts +11 -9
  606. package/node_modules/hono/dist/types.js +4 -6
  607. package/node_modules/hono/dist/utils/accept.js +185 -212
  608. package/node_modules/hono/dist/utils/basic-auth.js +18 -21
  609. package/node_modules/hono/dist/utils/body.js +87 -92
  610. package/node_modules/hono/dist/utils/buffer.js +44 -71
  611. package/node_modules/hono/dist/utils/color.js +33 -21
  612. package/node_modules/hono/dist/utils/compress.js +11 -5
  613. package/node_modules/hono/dist/utils/concurrent.js +29 -38
  614. package/node_modules/hono/dist/utils/constants.js +7 -5
  615. package/node_modules/hono/dist/utils/cookie.js +114 -163
  616. package/node_modules/hono/dist/utils/crypto.js +30 -40
  617. package/node_modules/hono/dist/utils/encode.js +30 -26
  618. package/node_modules/hono/dist/utils/filepath.js +23 -33
  619. package/node_modules/hono/dist/utils/handler.js +10 -11
  620. package/node_modules/hono/dist/utils/headers.js +1 -0
  621. package/node_modules/hono/dist/utils/html.js +97 -117
  622. package/node_modules/hono/dist/utils/http-status.js +1 -0
  623. package/node_modules/hono/dist/utils/ipaddr.js +227 -279
  624. package/node_modules/hono/dist/utils/jwt/index.js +12 -4
  625. package/node_modules/hono/dist/utils/jwt/jwa.js +24 -20
  626. package/node_modules/hono/dist/utils/jwt/jws.js +115 -174
  627. package/node_modules/hono/dist/utils/jwt/jwt.js +120 -198
  628. package/node_modules/hono/dist/utils/jwt/types.js +79 -95
  629. package/node_modules/hono/dist/utils/jwt/utf8.js +9 -7
  630. package/node_modules/hono/dist/utils/mime.js +74 -79
  631. package/node_modules/hono/dist/utils/stream.js +86 -88
  632. package/node_modules/hono/dist/utils/types.js +1 -0
  633. package/node_modules/hono/dist/utils/url.js +187 -215
  634. package/node_modules/hono/dist/validator/index.js +1 -4
  635. package/node_modules/hono/dist/validator/utils.js +1 -0
  636. package/node_modules/hono/dist/validator/validator.js +61 -83
  637. package/node_modules/hono/package.json +27 -27
  638. package/package.json +2 -2
  639. package/profiles/README.md +20 -0
  640. package/profiles/index.json +2 -1
  641. package/profiles/sales/0.1.profile.json +252 -0
  642. package/server.js +99 -0
@@ -155,12 +155,19 @@ var SPClient = class {
155
155
  }
156
156
  /**
157
157
  * 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.
158
+ * one of OUR calls 401ing, its own AS proxy 401ing, or an AS key mismatch)
159
+ * that it ended. Idempotent: safe to call redundantly from the
160
+ * control-plane's push.
161
+ *
162
+ * @param reason Defaults to 'expired' for the original caller (a 401 really
163
+ * does mean the session ended) — but the control plane's own lock
164
+ * procedures (session-lock.ts) know the REAL reason and must pass it, or
165
+ * an agent told "your sign-in ended, sign in again" for an AS key
166
+ * mismatch would be sent to a sign-in that is itself refused.
160
167
  */
161
- clearSession() {
168
+ clearSession(reason = "expired") {
162
169
  this.sessionCookie = "";
163
- this.lockReason = "expired";
170
+ this.lockReason = reason;
164
171
  }
165
172
  /** Why we are currently locked, if known. `null` means the default
166
173
  * boot-locked case (nobody has signed in yet this run). */
@@ -364,13 +371,52 @@ var SPClient = class {
364
371
 
365
372
  // src/lib/attestation-cache.ts
366
373
  import { decodeAttestationBlob } from "@hap/core";
374
+
375
+ // src/lib/as-pairing.ts
376
+ import { createHash } from "crypto";
377
+ import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, unlinkSync, writeFileSync } from "fs";
378
+ import { dirname, join as join2 } from "path";
379
+ function pairingPath(dataDir2) {
380
+ return join2(dataDir2, "as-pairing.json");
381
+ }
382
+ function readPairing(dataDir2) {
383
+ const path = pairingPath(dataDir2);
384
+ if (!existsSync2(path)) return null;
385
+ try {
386
+ const data = JSON.parse(readFileSync2(path, "utf-8"));
387
+ if (typeof data.asUrl !== "string" || typeof data.publicKeyHex !== "string") return null;
388
+ return { asUrl: data.asUrl, publicKeyHex: data.publicKeyHex, pairedAt: data.pairedAt ?? "" };
389
+ } catch {
390
+ return null;
391
+ }
392
+ }
393
+ function fingerprintOf(publicKeyHex) {
394
+ const raw = Buffer.from(publicKeyHex, "hex");
395
+ const digest = createHash("sha256").update(raw).digest("hex").toUpperCase();
396
+ return digest.match(/.{1,4}/g)?.join(":") ?? digest;
397
+ }
398
+
399
+ // src/lib/attestation-cache.ts
400
+ var AsKeyMismatchError = class extends Error {
401
+ constructor(message) {
402
+ super(message);
403
+ this.name = "AsKeyMismatchError";
404
+ }
405
+ };
367
406
  function isCommitmentDowngrade(auth) {
368
407
  const requiresReview = auth.signedCommitmentMode === "review" || auth.signedCommitmentMode === "review_above_cap";
369
408
  return requiresReview && (auth.deferredCommitmentDomains ?? []).length === 0;
370
409
  }
371
410
  var AttestationCache = class {
372
- constructor(spClient) {
411
+ /**
412
+ * @param dataDir Where to look for a pinned key (as-pairing.json). Optional
413
+ * and defaults to "no pin enforced" — kept optional so existing
414
+ * constructions (and this class's own unit tests) that pass only an
415
+ * SPClient keep working unpinned, exactly as before pinning existed.
416
+ */
417
+ constructor(spClient, dataDir2) {
373
418
  this.spClient = spClient;
419
+ this.dataDir = dataDir2;
374
420
  }
375
421
  spPublicKey = null;
376
422
  spPublicKeyFetchedAt = 0;
@@ -380,15 +426,29 @@ var AttestationCache = class {
380
426
  authorizations = /* @__PURE__ */ new Map();
381
427
  lastSync = 0;
382
428
  /**
383
- * Get the SP public key, fetching from SP if not cached or expired.
429
+ * Get the SP public key, fetching from SP if not cached or expired, then —
430
+ * when a pin exists for this exact AS URL — verifying the live key still
431
+ * matches it.
432
+ *
433
+ * Trust-on-first-use before any pairing exists (or when no `dataDir` was
434
+ * given): the fetched key is cached and returned, same as before pinning.
435
+ * Once paired, a live key that differs from the pin throws
436
+ * {@link AsKeyMismatchError} — fail closed, never silently re-pin.
384
437
  */
385
438
  async getPublicKey() {
386
439
  const now = Math.floor(Date.now() / 1e3);
387
- if (this.spPublicKey && now - this.spPublicKeyFetchedAt < this.SP_PUBKEY_TTL) {
388
- return this.spPublicKey;
440
+ if (!(this.spPublicKey && now - this.spPublicKeyFetchedAt < this.SP_PUBKEY_TTL)) {
441
+ this.spPublicKey = await this.spClient.getPublicKey();
442
+ this.spPublicKeyFetchedAt = now;
443
+ }
444
+ if (this.dataDir) {
445
+ const pin = readPairing(this.dataDir);
446
+ if (pin && pin.asUrl === this.spClient.url && pin.publicKeyHex !== this.spPublicKey) {
447
+ throw new AsKeyMismatchError(
448
+ `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.`
449
+ );
450
+ }
389
451
  }
390
- this.spPublicKey = await this.spClient.getPublicKey();
391
- this.spPublicKeyFetchedAt = now;
392
452
  return this.spPublicKey;
393
453
  }
394
454
  /**
@@ -498,18 +558,18 @@ var AttestationCache = class {
498
558
  };
499
559
 
500
560
  // src/lib/gate-store.ts
501
- import { mkdirSync, readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, unlinkSync } from "fs";
561
+ import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, unlinkSync as unlinkSync2 } from "fs";
502
562
  import { homedir } from "os";
503
- import { dirname, join as join2 } from "path";
563
+ import { dirname as dirname2, join as join3 } from "path";
504
564
  import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
505
- var DEFAULT_DIR = process.env.SUVEREN_DATA_DIR ?? join2(homedir(), ".suveren");
565
+ var DEFAULT_DIR = process.env.SUVEREN_DATA_DIR ?? join3(homedir(), ".suveren");
506
566
  var GateStore = class {
507
567
  entries = /* @__PURE__ */ new Map();
508
568
  baseDir;
509
569
  vaultKey = null;
510
570
  constructor(filePath) {
511
571
  if (filePath && filePath.endsWith(".json")) {
512
- this.baseDir = dirname(filePath);
572
+ this.baseDir = dirname2(filePath);
513
573
  } else {
514
574
  this.baseDir = filePath ?? DEFAULT_DIR;
515
575
  }
@@ -520,13 +580,13 @@ var GateStore = class {
520
580
  */
521
581
  setVaultKey(key) {
522
582
  this.vaultKey = key;
523
- if (existsSync2(this.encryptedFilePath)) {
583
+ if (existsSync3(this.encryptedFilePath)) {
524
584
  this.loadEncrypted();
525
585
  } else if (this.entries.size > 0) {
526
586
  this.persistEncrypted();
527
- if (existsSync2(this.plaintextFilePath)) {
587
+ if (existsSync3(this.plaintextFilePath)) {
528
588
  try {
529
- unlinkSync(this.plaintextFilePath);
589
+ unlinkSync2(this.plaintextFilePath);
530
590
  } catch {
531
591
  }
532
592
  }
@@ -546,6 +606,30 @@ var GateStore = class {
546
606
  this.entries.delete(path);
547
607
  this.persist();
548
608
  }
609
+ /**
610
+ * Wipe every locally cached gate. Used when the Authority Server this
611
+ * gateway points at changes (re-pairing, see as-pairing.ts): a stored
612
+ * authorization id and its intent/context are meaningless against a
613
+ * different AS's grants, and keeping them around risks a `getAll()` caller
614
+ * (e.g. list-authorizations) advertising authority that no longer exists.
615
+ *
616
+ * Removes BOTH the plaintext and encrypted files, not just the one
617
+ * currently active — this runs at boot, before any vault key is set, so
618
+ * `persist()` would otherwise only touch `gates.json` and leave a stale
619
+ * `gates.enc.json` in place for `setVaultKey()` to resurrect on the next
620
+ * unlock.
621
+ */
622
+ clearAll() {
623
+ this.entries = /* @__PURE__ */ new Map();
624
+ try {
625
+ if (existsSync3(this.plaintextFilePath)) unlinkSync2(this.plaintextFilePath);
626
+ } catch {
627
+ }
628
+ try {
629
+ if (existsSync3(this.encryptedFilePath)) unlinkSync2(this.encryptedFilePath);
630
+ } catch {
631
+ }
632
+ }
549
633
  // ─── Encryption helpers ─────────────────────────────────────────────────
550
634
  encrypt(plaintext) {
551
635
  if (!this.vaultKey) throw new Error("No vault key");
@@ -575,19 +659,19 @@ var GateStore = class {
575
659
  }
576
660
  // ─── File paths ─────────────────────────────────────────────────────────
577
661
  get plaintextFilePath() {
578
- return join2(this.baseDir, "gates.json");
662
+ return join3(this.baseDir, "gates.json");
579
663
  }
580
664
  get encryptedFilePath() {
581
- return join2(this.baseDir, "gates.enc.json");
665
+ return join3(this.baseDir, "gates.enc.json");
582
666
  }
583
667
  // ─── Load / Persist ─────────────────────────────────────────────────────
584
668
  loadPlaintext() {
585
- if (!existsSync2(this.plaintextFilePath)) {
586
- mkdirSync(this.baseDir, { recursive: true });
669
+ if (!existsSync3(this.plaintextFilePath)) {
670
+ mkdirSync2(this.baseDir, { recursive: true });
587
671
  return;
588
672
  }
589
673
  try {
590
- const raw = readFileSync2(this.plaintextFilePath, "utf-8");
674
+ const raw = readFileSync3(this.plaintextFilePath, "utf-8");
591
675
  const data = JSON.parse(raw);
592
676
  this.entries = new Map(Object.entries(data.entries));
593
677
  } catch {
@@ -596,9 +680,9 @@ var GateStore = class {
596
680
  }
597
681
  }
598
682
  loadEncrypted() {
599
- if (!existsSync2(this.encryptedFilePath)) return;
683
+ if (!existsSync3(this.encryptedFilePath)) return;
600
684
  try {
601
- const raw = readFileSync2(this.encryptedFilePath, "utf-8");
685
+ const raw = readFileSync3(this.encryptedFilePath, "utf-8");
602
686
  const data = JSON.parse(raw);
603
687
  this.entries = /* @__PURE__ */ new Map();
604
688
  for (const [key, blob] of Object.entries(data.entries)) {
@@ -622,8 +706,8 @@ var GateStore = class {
622
706
  version: 1,
623
707
  entries: Object.fromEntries(this.entries)
624
708
  };
625
- mkdirSync(this.baseDir, { recursive: true, mode: 448 });
626
- writeFileSync(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
709
+ mkdirSync2(this.baseDir, { recursive: true, mode: 448 });
710
+ writeFileSync2(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
627
711
  }
628
712
  persistEncrypted() {
629
713
  const data = {
@@ -633,17 +717,17 @@ var GateStore = class {
633
717
  for (const [key, entry] of this.entries) {
634
718
  data.entries[key] = this.encrypt(JSON.stringify(entry));
635
719
  }
636
- mkdirSync(this.baseDir, { recursive: true, mode: 448 });
637
- writeFileSync(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
720
+ mkdirSync2(this.baseDir, { recursive: true, mode: 448 });
721
+ writeFileSync2(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
638
722
  }
639
723
  };
640
724
 
641
725
  // src/lib/execution-log.ts
642
- import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3, unlinkSync as unlinkSync2 } from "fs";
726
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4, unlinkSync as unlinkSync3 } from "fs";
643
727
  import { homedir as homedir2 } from "os";
644
- import { dirname as dirname2, join as join3 } from "path";
728
+ import { dirname as dirname3, join as join4 } from "path";
645
729
  import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes2 } from "crypto";
646
- var DEFAULT_DIR2 = process.env.SUVEREN_DATA_DIR ?? join3(homedir2(), ".suveren");
730
+ var DEFAULT_DIR2 = process.env.SUVEREN_DATA_DIR ?? join4(homedir2(), ".suveren");
647
731
  var MAX_AGE_SECONDS = 31 * 24 * 60 * 60;
648
732
  var ExecutionLog = class {
649
733
  entries = [];
@@ -651,7 +735,7 @@ var ExecutionLog = class {
651
735
  vaultKey = null;
652
736
  constructor(filePath) {
653
737
  if (filePath && filePath.endsWith(".json")) {
654
- this.baseDir = dirname2(filePath);
738
+ this.baseDir = dirname3(filePath);
655
739
  } else {
656
740
  this.baseDir = filePath ?? DEFAULT_DIR2;
657
741
  }
@@ -662,13 +746,13 @@ var ExecutionLog = class {
662
746
  */
663
747
  setVaultKey(key) {
664
748
  this.vaultKey = key;
665
- if (existsSync3(this.encryptedFilePath)) {
749
+ if (existsSync4(this.encryptedFilePath)) {
666
750
  this.loadEncrypted();
667
751
  } else if (this.entries.length > 0) {
668
752
  this.persistEncrypted();
669
- if (existsSync3(this.plaintextFilePath)) {
753
+ if (existsSync4(this.plaintextFilePath)) {
670
754
  try {
671
- unlinkSync2(this.plaintextFilePath);
755
+ unlinkSync3(this.plaintextFilePath);
672
756
  } catch {
673
757
  }
674
758
  }
@@ -690,14 +774,23 @@ var ExecutionLog = class {
690
774
  * @param field - The execution field to sum ("_count" for plain counting)
691
775
  * @param window - Time window (daily, weekly, monthly)
692
776
  * @param now - Current timestamp in seconds (for testing)
777
+ * @param actionTypes - Only count entries whose `execution.action_type` is one
778
+ * of these (omitted → all). Consumption is partitioned by action type, as at
779
+ * the Authority Server: without it, the usage shown for sales' "orders per
780
+ * day" counted every quote and send. An entry with no action_type counts against every filter —
781
+ * an unknown action is not evidence of headroom.
693
782
  */
694
- sumByWindow(profileId, path, field, window, now = Math.floor(Date.now() / 1e3)) {
783
+ sumByWindow(profileId, path, field, window, now = Math.floor(Date.now() / 1e3), actionTypes) {
695
784
  const cutoff = windowCutoff(window, now);
696
785
  let total = 0;
697
786
  for (const entry of this.entries) {
698
787
  if (entry.profileId !== profileId) continue;
699
788
  if (entry.path !== path) continue;
700
789
  if (entry.timestamp < cutoff) continue;
790
+ if (actionTypes) {
791
+ const at = entry.execution.action_type;
792
+ if (typeof at === "string" && !actionTypes.includes(at)) continue;
793
+ }
701
794
  if (field === "_count") {
702
795
  total += 1;
703
796
  } else {
@@ -761,19 +854,19 @@ var ExecutionLog = class {
761
854
  }
762
855
  // ─── File paths ─────────────────────────────────────────────────────────
763
856
  get plaintextFilePath() {
764
- return join3(this.baseDir, "execution-log.json");
857
+ return join4(this.baseDir, "execution-log.json");
765
858
  }
766
859
  get encryptedFilePath() {
767
- return join3(this.baseDir, "execution-log.enc.json");
860
+ return join4(this.baseDir, "execution-log.enc.json");
768
861
  }
769
862
  // ─── Load / Persist ─────────────────────────────────────────────────────
770
863
  loadPlaintext() {
771
- if (!existsSync3(this.plaintextFilePath)) {
772
- mkdirSync2(this.baseDir, { recursive: true });
864
+ if (!existsSync4(this.plaintextFilePath)) {
865
+ mkdirSync3(this.baseDir, { recursive: true });
773
866
  return;
774
867
  }
775
868
  try {
776
- const raw = readFileSync3(this.plaintextFilePath, "utf-8");
869
+ const raw = readFileSync4(this.plaintextFilePath, "utf-8");
777
870
  const data = JSON.parse(raw);
778
871
  this.entries = data.entries;
779
872
  this.prune();
@@ -783,9 +876,9 @@ var ExecutionLog = class {
783
876
  }
784
877
  }
785
878
  loadEncrypted() {
786
- if (!existsSync3(this.encryptedFilePath)) return;
879
+ if (!existsSync4(this.encryptedFilePath)) return;
787
880
  try {
788
- const raw = readFileSync3(this.encryptedFilePath, "utf-8");
881
+ const raw = readFileSync4(this.encryptedFilePath, "utf-8");
789
882
  const data = JSON.parse(raw);
790
883
  const decrypted = this.decrypt(data.blob);
791
884
  const logFile = JSON.parse(decrypted);
@@ -805,8 +898,8 @@ var ExecutionLog = class {
805
898
  }
806
899
  persistPlaintext() {
807
900
  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 });
901
+ mkdirSync3(this.baseDir, { recursive: true, mode: 448 });
902
+ writeFileSync3(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
810
903
  }
811
904
  persistEncrypted() {
812
905
  const logFile = { version: 1, entries: this.entries };
@@ -814,8 +907,8 @@ var ExecutionLog = class {
814
907
  version: 1,
815
908
  blob: this.encrypt(JSON.stringify(logFile))
816
909
  };
817
- mkdirSync2(this.baseDir, { recursive: true, mode: 448 });
818
- writeFileSync2(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
910
+ mkdirSync3(this.baseDir, { recursive: true, mode: 448 });
911
+ writeFileSync3(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
819
912
  }
820
913
  };
821
914
  function windowCutoff(window, now) {
@@ -832,11 +925,11 @@ function windowCutoff(window, now) {
832
925
  }
833
926
 
834
927
  // src/lib/denial-log.ts
835
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4, unlinkSync as unlinkSync3 } from "fs";
928
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, unlinkSync as unlinkSync4 } from "fs";
836
929
  import { homedir as homedir3 } from "os";
837
- import { dirname as dirname3, join as join4 } from "path";
930
+ import { dirname as dirname4, join as join5 } from "path";
838
931
  import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes3 } from "crypto";
839
- var DEFAULT_DIR3 = process.env.SUVEREN_DATA_DIR ?? join4(homedir3(), ".suveren");
932
+ var DEFAULT_DIR3 = process.env.SUVEREN_DATA_DIR ?? join5(homedir3(), ".suveren");
840
933
  var MAX_RECORDS = 200;
841
934
  var MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
842
935
  var DenialLog = class {
@@ -844,18 +937,18 @@ var DenialLog = class {
844
937
  baseDir;
845
938
  vaultKey = null;
846
939
  constructor(filePath) {
847
- this.baseDir = filePath && filePath.endsWith(".json") ? dirname3(filePath) : filePath ?? DEFAULT_DIR3;
940
+ this.baseDir = filePath && filePath.endsWith(".json") ? dirname4(filePath) : filePath ?? DEFAULT_DIR3;
848
941
  this.loadPlaintext();
849
942
  }
850
943
  setVaultKey(key) {
851
944
  this.vaultKey = key;
852
- if (existsSync4(this.encryptedFilePath)) {
945
+ if (existsSync5(this.encryptedFilePath)) {
853
946
  this.loadEncrypted();
854
947
  } else if (this.records.length > 0) {
855
948
  this.persistEncrypted();
856
- if (existsSync4(this.plaintextFilePath)) {
949
+ if (existsSync5(this.plaintextFilePath)) {
857
950
  try {
858
- unlinkSync3(this.plaintextFilePath);
951
+ unlinkSync4(this.plaintextFilePath);
859
952
  } catch {
860
953
  }
861
954
  }
@@ -903,18 +996,18 @@ var DenialLog = class {
903
996
  return Buffer.concat([decipher.update(Buffer.from(blob.ciphertext, "hex")), decipher.final()]).toString("utf8");
904
997
  }
905
998
  get plaintextFilePath() {
906
- return join4(this.baseDir, "denials.json");
999
+ return join5(this.baseDir, "denials.json");
907
1000
  }
908
1001
  get encryptedFilePath() {
909
- return join4(this.baseDir, "denials.enc.json");
1002
+ return join5(this.baseDir, "denials.enc.json");
910
1003
  }
911
1004
  loadPlaintext() {
912
- if (!existsSync4(this.plaintextFilePath)) {
913
- mkdirSync3(this.baseDir, { recursive: true });
1005
+ if (!existsSync5(this.plaintextFilePath)) {
1006
+ mkdirSync4(this.baseDir, { recursive: true });
914
1007
  return;
915
1008
  }
916
1009
  try {
917
- const data = JSON.parse(readFileSync4(this.plaintextFilePath, "utf-8"));
1010
+ const data = JSON.parse(readFileSync5(this.plaintextFilePath, "utf-8"));
918
1011
  this.records = data.records ?? [];
919
1012
  } catch {
920
1013
  console.error(`[DenialLog] Could not parse ${this.plaintextFilePath}, starting fresh`);
@@ -922,9 +1015,9 @@ var DenialLog = class {
922
1015
  }
923
1016
  }
924
1017
  loadEncrypted() {
925
- if (!existsSync4(this.encryptedFilePath)) return;
1018
+ if (!existsSync5(this.encryptedFilePath)) return;
926
1019
  try {
927
- const data = JSON.parse(readFileSync4(this.encryptedFilePath, "utf-8"));
1020
+ const data = JSON.parse(readFileSync5(this.encryptedFilePath, "utf-8"));
928
1021
  const logFile = JSON.parse(this.decrypt(data.blob));
929
1022
  this.records = logFile.records ?? [];
930
1023
  } catch (err) {
@@ -938,23 +1031,23 @@ var DenialLog = class {
938
1031
  }
939
1032
  persistPlaintext() {
940
1033
  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 });
1034
+ mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1035
+ writeFileSync4(this.plaintextFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
943
1036
  }
944
1037
  persistEncrypted() {
945
1038
  const logFile = { version: 1, records: this.records };
946
1039
  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 });
1040
+ mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1041
+ writeFileSync4(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
949
1042
  }
950
1043
  };
951
1044
 
952
1045
  // src/lib/receipt-archive.ts
953
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync5, unlinkSync as unlinkSync4 } from "fs";
1046
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync6, unlinkSync as unlinkSync5 } from "fs";
954
1047
  import { homedir as homedir4 } from "os";
955
- import { dirname as dirname4, join as join5 } from "path";
1048
+ import { dirname as dirname5, join as join6 } from "path";
956
1049
  import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes4 } from "crypto";
957
- var DEFAULT_DIR4 = process.env.SUVEREN_DATA_DIR ?? join5(homedir4(), ".suveren");
1050
+ var DEFAULT_DIR4 = process.env.SUVEREN_DATA_DIR ?? join6(homedir4(), ".suveren");
958
1051
  function stripPreviews(proposal) {
959
1052
  const args = proposal.toolArgs;
960
1053
  if (!args || typeof args !== "object") return proposal;
@@ -968,7 +1061,7 @@ var ReceiptArchive = class {
968
1061
  vaultKey = null;
969
1062
  constructor(filePath) {
970
1063
  if (filePath && filePath.endsWith(".json")) {
971
- this.baseDir = dirname4(filePath);
1064
+ this.baseDir = dirname5(filePath);
972
1065
  } else {
973
1066
  this.baseDir = filePath ?? DEFAULT_DIR4;
974
1067
  }
@@ -979,13 +1072,13 @@ var ReceiptArchive = class {
979
1072
  */
980
1073
  setVaultKey(key) {
981
1074
  this.vaultKey = key;
982
- if (existsSync5(this.encryptedFilePath)) {
1075
+ if (existsSync6(this.encryptedFilePath)) {
983
1076
  this.loadEncrypted();
984
1077
  } else if (this.data.receipts.length > 0 || Object.keys(this.data.authorizations).length > 0) {
985
1078
  this.persistEncrypted();
986
- if (existsSync5(this.plaintextFilePath)) {
1079
+ if (existsSync6(this.plaintextFilePath)) {
987
1080
  try {
988
- unlinkSync4(this.plaintextFilePath);
1081
+ unlinkSync5(this.plaintextFilePath);
989
1082
  } catch {
990
1083
  }
991
1084
  }
@@ -997,7 +1090,7 @@ var ReceiptArchive = class {
997
1090
  * this state — that would report a hollow success over unreadable evidence.
998
1091
  */
999
1092
  isLocked() {
1000
- return this.vaultKey === null && existsSync5(this.encryptedFilePath);
1093
+ return this.vaultKey === null && existsSync6(this.encryptedFilePath);
1001
1094
  }
1002
1095
  /**
1003
1096
  * Archive a signed receipt (and the grant it was issued under).
@@ -1098,19 +1191,19 @@ var ReceiptArchive = class {
1098
1191
  }
1099
1192
  // ─── File paths ─────────────────────────────────────────────────────────
1100
1193
  get plaintextFilePath() {
1101
- return join5(this.baseDir, "receipt-archive.json");
1194
+ return join6(this.baseDir, "receipt-archive.json");
1102
1195
  }
1103
1196
  get encryptedFilePath() {
1104
- return join5(this.baseDir, "receipt-archive.enc.json");
1197
+ return join6(this.baseDir, "receipt-archive.enc.json");
1105
1198
  }
1106
1199
  // ─── Load / Persist ─────────────────────────────────────────────────────
1107
1200
  loadPlaintext() {
1108
- if (!existsSync5(this.plaintextFilePath)) {
1109
- mkdirSync4(this.baseDir, { recursive: true });
1201
+ if (!existsSync6(this.plaintextFilePath)) {
1202
+ mkdirSync5(this.baseDir, { recursive: true });
1110
1203
  return;
1111
1204
  }
1112
1205
  try {
1113
- const raw = readFileSync5(this.plaintextFilePath, "utf-8");
1206
+ const raw = readFileSync6(this.plaintextFilePath, "utf-8");
1114
1207
  const parsed = JSON.parse(raw);
1115
1208
  this.data = {
1116
1209
  version: 1,
@@ -1120,18 +1213,18 @@ var ReceiptArchive = class {
1120
1213
  } catch {
1121
1214
  console.error(`[ReceiptArchive] Could not parse ${this.plaintextFilePath} \u2014 preserving as .corrupt`);
1122
1215
  try {
1123
- writeFileSync4(
1216
+ writeFileSync5(
1124
1217
  `${this.plaintextFilePath}.corrupt-${Date.now()}`,
1125
- readFileSync5(this.plaintextFilePath)
1218
+ readFileSync6(this.plaintextFilePath)
1126
1219
  );
1127
1220
  } catch {
1128
1221
  }
1129
1222
  }
1130
1223
  }
1131
1224
  loadEncrypted() {
1132
- if (!existsSync5(this.encryptedFilePath)) return;
1225
+ if (!existsSync6(this.encryptedFilePath)) return;
1133
1226
  try {
1134
- const raw = readFileSync5(this.encryptedFilePath, "utf-8");
1227
+ const raw = readFileSync6(this.encryptedFilePath, "utf-8");
1135
1228
  const data = JSON.parse(raw);
1136
1229
  const decrypted = this.decrypt(data.blob);
1137
1230
  const parsed = JSON.parse(decrypted);
@@ -1143,9 +1236,9 @@ var ReceiptArchive = class {
1143
1236
  } catch (err) {
1144
1237
  console.error(`[ReceiptArchive] Could not decrypt ${this.encryptedFilePath} \u2014 preserving as .corrupt:`, err);
1145
1238
  try {
1146
- writeFileSync4(
1239
+ writeFileSync5(
1147
1240
  `${this.encryptedFilePath}.corrupt-${Date.now()}`,
1148
- readFileSync5(this.encryptedFilePath)
1241
+ readFileSync6(this.encryptedFilePath)
1149
1242
  );
1150
1243
  } catch {
1151
1244
  }
@@ -1159,29 +1252,29 @@ var ReceiptArchive = class {
1159
1252
  }
1160
1253
  }
1161
1254
  persistPlaintext() {
1162
- mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1163
- writeFileSync4(this.plaintextFilePath, JSON.stringify(this.data, null, 2), { encoding: "utf-8", mode: 384 });
1255
+ mkdirSync5(this.baseDir, { recursive: true, mode: 448 });
1256
+ writeFileSync5(this.plaintextFilePath, JSON.stringify(this.data, null, 2), { encoding: "utf-8", mode: 384 });
1164
1257
  }
1165
1258
  persistEncrypted() {
1166
1259
  const data = {
1167
1260
  version: 1,
1168
1261
  blob: this.encrypt(JSON.stringify(this.data))
1169
1262
  };
1170
- mkdirSync4(this.baseDir, { recursive: true, mode: 448 });
1171
- writeFileSync4(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1263
+ mkdirSync5(this.baseDir, { recursive: true, mode: 448 });
1264
+ writeFileSync5(this.encryptedFilePath, JSON.stringify(data, null, 2), { encoding: "utf-8", mode: 384 });
1172
1265
  }
1173
1266
  };
1174
1267
 
1175
1268
  // src/lib/execution-journal.ts
1176
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5, existsSync as existsSync6, renameSync } from "fs";
1269
+ import { mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6, existsSync as existsSync7, renameSync } from "fs";
1177
1270
  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");
1271
+ import { dirname as dirname6, join as join7 } from "path";
1272
+ import { createHash as createHash2 } from "crypto";
1273
+ var DEFAULT_DIR5 = process.env.SUVEREN_DATA_DIR ?? join7(homedir5(), ".suveren");
1181
1274
  var FILE_NAME = "execution-journal.json";
1182
1275
  var MAX_AGE_SECONDS2 = 90 * 24 * 60 * 60;
1183
1276
  function hashToolArgs(args) {
1184
- return "sha256:" + createHash("sha256").update(stableStringify(args)).digest("hex");
1277
+ return "sha256:" + createHash2("sha256").update(stableStringify(args)).digest("hex");
1185
1278
  }
1186
1279
  function stableStringify(value) {
1187
1280
  if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "undefined";
@@ -1193,8 +1286,8 @@ function stableStringify(value) {
1193
1286
  var ExecutionJournal = class {
1194
1287
  filePath;
1195
1288
  constructor(filePath) {
1196
- const baseDir = filePath && filePath.endsWith(".json") ? dirname5(filePath) : filePath ?? DEFAULT_DIR5;
1197
- this.filePath = join6(baseDir, FILE_NAME);
1289
+ const baseDir = filePath && filePath.endsWith(".json") ? dirname6(filePath) : filePath ?? DEFAULT_DIR5;
1290
+ this.filePath = join7(baseDir, FILE_NAME);
1198
1291
  }
1199
1292
  /** Look a ticket up. Always reads from disk — another process may have written. */
1200
1293
  get(ticketId) {
@@ -1233,9 +1326,9 @@ var ExecutionJournal = class {
1233
1326
  }
1234
1327
  // ─── Persistence ────────────────────────────────────────────────────────
1235
1328
  load() {
1236
- if (!existsSync6(this.filePath)) return { version: 1, entries: [] };
1329
+ if (!existsSync7(this.filePath)) return { version: 1, entries: [] };
1237
1330
  try {
1238
- const parsed = JSON.parse(readFileSync6(this.filePath, "utf8"));
1331
+ const parsed = JSON.parse(readFileSync7(this.filePath, "utf8"));
1239
1332
  if (parsed?.version !== 1 || !Array.isArray(parsed.entries)) {
1240
1333
  throw new Error("unexpected shape");
1241
1334
  }
@@ -1249,9 +1342,9 @@ var ExecutionJournal = class {
1249
1342
  persist(file) {
1250
1343
  const cutoff = nowSec() - MAX_AGE_SECONDS2;
1251
1344
  file.entries = file.entries.filter((e) => e.startedAt >= cutoff);
1252
- mkdirSync5(dirname5(this.filePath), { recursive: true, mode: 448 });
1345
+ mkdirSync6(dirname6(this.filePath), { recursive: true, mode: 448 });
1253
1346
  const tmp = this.filePath + ".tmp";
1254
- writeFileSync5(tmp, JSON.stringify(file, null, 2), { mode: 384 });
1347
+ writeFileSync6(tmp, JSON.stringify(file, null, 2), { mode: 384 });
1255
1348
  renameSync(tmp, this.filePath);
1256
1349
  }
1257
1350
  };
@@ -1259,6 +1352,61 @@ function nowSec() {
1259
1352
  return Math.floor(Date.now() / 1e3);
1260
1353
  }
1261
1354
 
1355
+ // src/lib/proposal-submission-store.ts
1356
+ import { mkdirSync as mkdirSync7, readFileSync as readFileSync8, writeFileSync as writeFileSync7, existsSync as existsSync8, renameSync as renameSync2 } from "fs";
1357
+ import { homedir as homedir6 } from "os";
1358
+ import { dirname as dirname7, join as join8 } from "path";
1359
+ var DEFAULT_DIR6 = process.env.SUVEREN_DATA_DIR ?? join8(homedir6(), ".suveren");
1360
+ var FILE_NAME2 = "proposal-submissions.json";
1361
+ var MAX_AGE_SECONDS3 = 90 * 24 * 60 * 60;
1362
+ function nowSec2() {
1363
+ return Math.floor(Date.now() / 1e3);
1364
+ }
1365
+ var ProposalSubmissionStore = class {
1366
+ filePath;
1367
+ constructor(filePath) {
1368
+ const baseDir = filePath && filePath.endsWith(".json") ? dirname7(filePath) : filePath ?? DEFAULT_DIR6;
1369
+ this.filePath = join8(baseDir, FILE_NAME2);
1370
+ }
1371
+ /** Record what was submitted, right after a successful submitProposal(). */
1372
+ record(entry) {
1373
+ const file = this.load();
1374
+ file.entries = file.entries.filter((e) => e.proposalId !== entry.proposalId);
1375
+ file.entries.push({
1376
+ proposalId: entry.proposalId,
1377
+ tool: entry.tool,
1378
+ toolArgsHash: hashToolArgs(entry.toolArgs),
1379
+ executionContextHash: hashToolArgs(entry.executionContext),
1380
+ authorizationId: entry.authorizationId,
1381
+ profileId: entry.profileId,
1382
+ submittedAt: nowSec2()
1383
+ });
1384
+ this.persist(file);
1385
+ }
1386
+ /** Always reads from disk — another process (the poll loop lives in the
1387
+ * same process, but this stays consistent with execution-journal.ts). */
1388
+ get(proposalId) {
1389
+ return this.load().entries.find((e) => e.proposalId === proposalId);
1390
+ }
1391
+ load() {
1392
+ if (!existsSync8(this.filePath)) return { version: 1, entries: [] };
1393
+ try {
1394
+ const parsed = JSON.parse(readFileSync8(this.filePath, "utf-8"));
1395
+ const cutoff = nowSec2() - MAX_AGE_SECONDS3;
1396
+ parsed.entries = (parsed.entries ?? []).filter((e) => e.submittedAt >= cutoff);
1397
+ return parsed;
1398
+ } catch {
1399
+ return { version: 1, entries: [] };
1400
+ }
1401
+ }
1402
+ persist(file) {
1403
+ mkdirSync7(dirname7(this.filePath), { recursive: true, mode: 448 });
1404
+ const tmpPath = `${this.filePath}.tmp`;
1405
+ writeFileSync7(tmpPath, JSON.stringify(file, null, 2), { encoding: "utf-8", mode: 384 });
1406
+ renameSync2(tmpPath, this.filePath);
1407
+ }
1408
+ };
1409
+
1262
1410
  // src/lib/gatekeeper.ts
1263
1411
  import { verify } from "@hap/core";
1264
1412
  var MCPGatekeeper = class {
@@ -1309,7 +1457,26 @@ var MCPGatekeeper = class {
1309
1457
  authorization: auth
1310
1458
  };
1311
1459
  }
1312
- const publicKeyHex = await this.cache.getPublicKey();
1460
+ let publicKeyHex;
1461
+ try {
1462
+ publicKeyHex = await this.cache.getPublicKey();
1463
+ } catch (err) {
1464
+ if (err instanceof AsKeyMismatchError) {
1465
+ void notifyControlPlane("as-key-mismatch");
1466
+ return {
1467
+ result: {
1468
+ approved: false,
1469
+ // No dedicated GatekeeperError code exists for this (hap-core's
1470
+ // union predates gateway-side key pinning) — INVALID_SIGNATURE is
1471
+ // the closest fit: it's exactly the claim being made here ("we
1472
+ // will not trust a signature made under this key").
1473
+ errors: [{ code: "INVALID_SIGNATURE", message: err.message }]
1474
+ },
1475
+ authorization: auth
1476
+ };
1477
+ }
1478
+ throw err;
1479
+ }
1313
1480
  const resolvedBounds = override?.bounds ?? auth.bounds ?? auth.frame;
1314
1481
  const resolvedContext = override?.context ?? auth.context;
1315
1482
  const frame = { ...resolvedBounds, profile: auth.profileId };
@@ -1341,15 +1508,25 @@ var SharedState = class {
1341
1508
  receiptArchive;
1342
1509
  /** Which tickets this Gatekeeper has executed — the "one execution per ticket" half of exactly-once. */
1343
1510
  executionJournal;
1511
+ /** What THIS gateway submitted for each review-mode proposal it created —
1512
+ * see ticket-verify.ts / commitments.ts. */
1513
+ proposalSubmissions;
1344
1514
  gatekeeper;
1345
- constructor(spUrl2, gateStorePath) {
1515
+ /**
1516
+ * @param dataDir Passed to the AttestationCache so it can enforce AS key
1517
+ * pinning (as-pairing.ts). Optional for backward compat with existing
1518
+ * constructions/tests that pass only a URL — those get unpinned
1519
+ * trust-on-first-use behavior, same as before pinning existed.
1520
+ */
1521
+ constructor(spUrl2, gateStorePath, dataDir2) {
1346
1522
  this.spClient = new SPClient(spUrl2);
1347
- this.cache = new AttestationCache(this.spClient);
1523
+ this.cache = new AttestationCache(this.spClient, dataDir2);
1348
1524
  this.gateStore = new GateStore(gateStorePath);
1349
1525
  this.executionLog = new ExecutionLog(gateStorePath);
1350
1526
  this.denialLog = new DenialLog(gateStorePath);
1351
1527
  this.receiptArchive = new ReceiptArchive(gateStorePath);
1352
1528
  this.executionJournal = new ExecutionJournal(gateStorePath);
1529
+ this.proposalSubmissions = new ProposalSubmissionStore(gateStorePath);
1353
1530
  this.gatekeeper = new MCPGatekeeper(this.cache);
1354
1531
  }
1355
1532
  /**
@@ -1365,7 +1542,8 @@ var SharedState = class {
1365
1542
  let asPublicKey;
1366
1543
  try {
1367
1544
  asPublicKey = await this.cache.getPublicKey();
1368
- } catch {
1545
+ } catch (err) {
1546
+ if (err instanceof AsKeyMismatchError) throw err;
1369
1547
  }
1370
1548
  this.receiptArchive.record({
1371
1549
  receipt,
@@ -1387,6 +1565,7 @@ var SharedState = class {
1387
1565
  } : void 0
1388
1566
  });
1389
1567
  } catch (err) {
1568
+ if (err instanceof AsKeyMismatchError) throw err;
1390
1569
  console.error(
1391
1570
  "[Suveren MCP] Receipt archive write failed (execution proceeds \u2014 AS retains authoritative copy):",
1392
1571
  err
@@ -1435,6 +1614,7 @@ import { z } from "zod";
1435
1614
  import { getProfile } from "@hap/core";
1436
1615
 
1437
1616
  // src/lib/consumption.ts
1617
+ import { boundActionTypes } from "@hap/core";
1438
1618
  function getConsumptionState(auth, executionLog, profile) {
1439
1619
  if (!profile?.boundsSchema?.fields) return [];
1440
1620
  const entries = [];
@@ -1454,7 +1634,8 @@ function getConsumptionState(auth, executionLog, profile) {
1454
1634
  auth.path,
1455
1635
  cumulativeField,
1456
1636
  bt.window,
1457
- now
1637
+ now,
1638
+ boundActionTypes(fieldName, fieldDef)
1458
1639
  );
1459
1640
  entries.push({
1460
1641
  // displayName FIRST: description is prose meant for a human reading the
@@ -1498,24 +1679,24 @@ function formatConsumptionFull(entries) {
1498
1679
  }
1499
1680
 
1500
1681
  // 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");
1682
+ import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
1683
+ import { homedir as homedir7 } from "os";
1684
+ import { join as join9 } from "path";
1685
+ var DEFAULT_DIR7 = process.env.SUVEREN_DATA_DIR ?? join9(homedir7(), ".suveren");
1505
1686
  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;
1687
+ function readContextFile(dataDir2) {
1688
+ const dir = dataDir2 ?? DEFAULT_DIR7;
1689
+ const filePath = join9(dir, "context.md");
1690
+ if (!existsSync9(filePath)) return null;
1510
1691
  try {
1511
- const content = readFileSync7(filePath, "utf-8").trim();
1692
+ const content = readFileSync9(filePath, "utf-8").trim();
1512
1693
  return content || null;
1513
1694
  } catch {
1514
1695
  return null;
1515
1696
  }
1516
1697
  }
1517
- function getContextForBrief(dataDir) {
1518
- const full = readContextFile(dataDir);
1698
+ function getContextForBrief(dataDir2) {
1699
+ const full = readContextFile(dataDir2);
1519
1700
  if (!full) return { brief: null, truncated: false };
1520
1701
  if (full.length <= BRIEF_MAX_CHARS) {
1521
1702
  return { brief: full, truncated: false };
@@ -1623,9 +1804,28 @@ function expiredSessionNotice(what) {
1623
1804
 
1624
1805
  TELL THE USER: open ${uiUrl()} and enter your Suveren API key to sign in again. Your mandates are safe; nothing ran.`;
1625
1806
  }
1807
+ function asKeyMismatchNotice(what) {
1808
+ 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.
1809
+
1810
+ 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.`;
1811
+ }
1812
+ function asUrlChangedNotice(what) {
1813
+ 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.
1814
+
1815
+ TELL THE USER: open ${uiUrl()} and sign in again to pair with the new Authority Server.`;
1816
+ }
1626
1817
  function lockedNotice(action, reason = "restart") {
1627
1818
  const what = action ? `Cannot ${action}: the` : "The";
1628
- return reason === "expired" ? expiredSessionNotice(what) : bootLockedNotice(what);
1819
+ switch (reason) {
1820
+ case "expired":
1821
+ return expiredSessionNotice(what);
1822
+ case "as-key-mismatch":
1823
+ return asKeyMismatchNotice(what);
1824
+ case "as-url-changed":
1825
+ return asUrlChangedNotice(what);
1826
+ default:
1827
+ return bootLockedNotice(what);
1828
+ }
1629
1829
  }
1630
1830
 
1631
1831
  // src/tools/authorizations.ts
@@ -1634,6 +1834,9 @@ import { getProfile as getProfile4 } from "@hap/core";
1634
1834
  // src/lib/receipt-footer.ts
1635
1835
  import { deriveIdentityLine } from "@hap/core";
1636
1836
  var AS_BASE = (process.env.SUVEREN_AS_URL ?? "https://www.suveren.ai").replace(/\/$/, "");
1837
+ function setAsBaseUrl(url) {
1838
+ AS_BASE = url.replace(/\/$/, "");
1839
+ }
1637
1840
  var OPERATOR_NAME = process.env.SUVEREN_OPERATOR_NAME ?? "Suveren";
1638
1841
  var HAP_URL = "https://www.humanagencyprotocol.org/";
1639
1842
  var FOOTER_PROFILES = /* @__PURE__ */ new Set(["email", "calendar", "publish"]);
@@ -1739,6 +1942,83 @@ function attachReceiptId(tool, args, receiptId) {
1739
1942
  return { ...args, receipt_id: receiptId };
1740
1943
  }
1741
1944
 
1945
+ // src/lib/ticket-verify.ts
1946
+ import { verifyReceiptSignature } from "@hap/core";
1947
+ var TicketBindingMismatchError = class extends Error {
1948
+ constructor(message) {
1949
+ super(message);
1950
+ this.name = "TicketBindingMismatchError";
1951
+ }
1952
+ };
1953
+ var TICKET_MAX_AGE_SECONDS = 5 * 60;
1954
+ var TICKET_MAX_CLOCK_SKEW_SECONDS = 30;
1955
+ async function verifyTicket(cache, receipt, expected) {
1956
+ const publicKeyHex = await cache.getPublicKey();
1957
+ if (typeof receipt.signature !== "string" || !receipt.signature) {
1958
+ throw new AsKeyMismatchError("Ticket carries no signature \u2014 refusing to trust it.");
1959
+ }
1960
+ try {
1961
+ await verifyReceiptSignature(receipt, publicKeyHex);
1962
+ } catch (err) {
1963
+ throw new AsKeyMismatchError(
1964
+ `Ticket signature does not verify against the pinned Authority Server key \u2014 ${err instanceof Error ? err.message : String(err)}. Refusing to execute.`
1965
+ );
1966
+ }
1967
+ if (receipt.action !== expected.action) {
1968
+ throw new TicketBindingMismatchError(
1969
+ `Ticket action "${String(receipt.action)}" does not match the requested action "${expected.action}" \u2014 refusing to execute.`
1970
+ );
1971
+ }
1972
+ if (expected.executionContext !== void 0 && hashToolArgs(receipt.executionContext ?? {}) !== hashToolArgs(expected.executionContext)) {
1973
+ throw new TicketBindingMismatchError(
1974
+ "Ticket executionContext does not match what this call requested \u2014 refusing to execute."
1975
+ );
1976
+ }
1977
+ if (expected.authorizationId !== void 0 && receipt.authorizationId !== expected.authorizationId) {
1978
+ throw new TicketBindingMismatchError(
1979
+ `Ticket authorizationId "${String(receipt.authorizationId)}" does not match the requested grant "${expected.authorizationId}" \u2014 refusing to execute.`
1980
+ );
1981
+ }
1982
+ if (expected.profileId !== void 0 && receipt.profileId !== expected.profileId) {
1983
+ throw new TicketBindingMismatchError(
1984
+ `Ticket profileId "${String(receipt.profileId)}" does not match the requested profile "${expected.profileId}" \u2014 refusing to execute.`
1985
+ );
1986
+ }
1987
+ if (expected.proposalId !== void 0 && receipt.proposalId !== expected.proposalId) {
1988
+ throw new TicketBindingMismatchError(
1989
+ `Ticket proposalId "${String(receipt.proposalId)}" does not match the proposal being executed "${expected.proposalId}" \u2014 refusing to execute.`
1990
+ );
1991
+ }
1992
+ if (expected.contentHash !== void 0) {
1993
+ if (receipt.contentHash !== expected.contentHash) {
1994
+ throw new TicketBindingMismatchError(
1995
+ "Ticket contentHash does not match the content this call is bound to \u2014 refusing to execute."
1996
+ );
1997
+ }
1998
+ if (expected.contentBinding !== void 0 && hashToolArgs(receipt.contentBinding ?? {}) !== hashToolArgs(expected.contentBinding)) {
1999
+ throw new TicketBindingMismatchError(
2000
+ "Ticket contentBinding does not match what this call requested \u2014 refusing to execute."
2001
+ );
2002
+ }
2003
+ }
2004
+ const timestamp = receipt.timestamp;
2005
+ if (typeof timestamp !== "number" || !Number.isFinite(timestamp)) {
2006
+ throw new TicketBindingMismatchError("Ticket carries no valid timestamp \u2014 refusing to execute.");
2007
+ }
2008
+ const nowSec3 = Math.floor(Date.now() / 1e3);
2009
+ const ageSec = nowSec3 - timestamp;
2010
+ if (ageSec > TICKET_MAX_AGE_SECONDS) {
2011
+ throw new TicketBindingMismatchError(
2012
+ `Ticket is ${ageSec}s old, older than the ${TICKET_MAX_AGE_SECONDS}s freshness window \u2014 refusing to execute.`
2013
+ );
2014
+ }
2015
+ if (ageSec < -TICKET_MAX_CLOCK_SKEW_SECONDS) {
2016
+ throw new TicketBindingMismatchError(
2017
+ `Ticket is timestamped ${-ageSec}s in the future, beyond the ${TICKET_MAX_CLOCK_SKEW_SECONDS}s clock-skew tolerance \u2014 refusing to execute.`
2018
+ );
2019
+ }
2020
+ }
2021
+
1742
2022
  // src/lib/arg-encoding.ts
1743
2023
  function rfc2047Encode(value) {
1744
2024
  if (!/[^\x00-\x7F]/.test(value)) return value;
@@ -2454,6 +2734,14 @@ function createGatedToolHandlerInner(tool, integrationManager2, state2) {
2454
2734
  toolArgs: enrichedArgs,
2455
2735
  executionContext: { ...execution }
2456
2736
  });
2737
+ state2.proposalSubmissions.record({
2738
+ proposalId: proposal.id,
2739
+ tool: tool.namespacedName,
2740
+ toolArgs: enrichedArgs,
2741
+ executionContext: { ...execution },
2742
+ authorizationId: authzId,
2743
+ profileId: auth.profileId
2744
+ });
2457
2745
  return {
2458
2746
  content: [{
2459
2747
  type: "text",
@@ -2496,6 +2784,14 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2496
2784
  ...binding ? { contentHash: binding.contentHash, contentBinding: binding.contentBinding } : {}
2497
2785
  });
2498
2786
  receiptId = typeof receipt?.id === "string" ? receipt.id : void 0;
2787
+ await verifyTicket(state2.cache, receipt, {
2788
+ action: tool.namespacedName,
2789
+ executionContext: { ...execution },
2790
+ authorizationId: authzId,
2791
+ profileId: auth.profileId,
2792
+ contentHash: binding?.contentHash,
2793
+ contentBinding: binding?.contentBinding
2794
+ });
2499
2795
  await state2.archiveReceipt(receipt, {
2500
2796
  authorizationId: authzId,
2501
2797
  profileId: auth.profileId,
@@ -2510,6 +2806,13 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2510
2806
  boundContent: binding?.boundContent
2511
2807
  });
2512
2808
  } catch (err) {
2809
+ if (err instanceof AsKeyMismatchError || err instanceof TicketBindingMismatchError) {
2810
+ void notifyControlPlane("as-key-mismatch");
2811
+ return {
2812
+ content: [{ type: "text", text: `Blocked: ${err.message}` }],
2813
+ isError: true
2814
+ };
2815
+ }
2513
2816
  if (err instanceof ContentBindingError) {
2514
2817
  return {
2515
2818
  content: [{
@@ -2555,6 +2858,14 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
2555
2858
  executionContext: { ...execution },
2556
2859
  pendingApprovers: uniqueApprovers
2557
2860
  });
2861
+ state2.proposalSubmissions.record({
2862
+ proposalId: proposal.id,
2863
+ tool: tool.namespacedName,
2864
+ toolArgs: enrichedArgs,
2865
+ executionContext: { ...execution },
2866
+ authorizationId: authzId,
2867
+ profileId: auth.profileId
2868
+ });
2558
2869
  return {
2559
2870
  content: [{
2560
2871
  type: "text",
@@ -2962,6 +3273,9 @@ function listIntegrationsHandler(state2, integrationManager2) {
2962
3273
 
2963
3274
  // src/tools/commitments.ts
2964
3275
  import { ContentBindingError as ContentBindingError2 } from "@hap/core";
3276
+ function buildSkippedProposalNote(proposalId) {
3277
+ 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.`;
3278
+ }
2965
3279
  var installedExecutor = null;
2966
3280
  function installCommittedExecutor(executor) {
2967
3281
  installedExecutor = executor;
@@ -2987,6 +3301,28 @@ async function executeCommitted(proposal, state2, integrationManager2) {
2987
3301
  );
2988
3302
  }
2989
3303
  const cachedAuth = state2.cache.getAllAuthorizations().find((a) => a.authorizationId === proposal.authorizationId);
3304
+ const submitted = state2.proposalSubmissions.get(proposal.id);
3305
+ if (!submitted) {
3306
+ console.error(
3307
+ `[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).`
3308
+ );
3309
+ return { text: buildSkippedProposalNote(proposal.id) };
3310
+ }
3311
+ {
3312
+ const mismatches = [];
3313
+ if (submitted.tool !== proposal.tool) mismatches.push("tool");
3314
+ if (submitted.toolArgsHash !== hashToolArgs(proposal.toolArgs)) mismatches.push("arguments");
3315
+ if (submitted.executionContextHash !== hashToolArgs(proposal.executionContext)) mismatches.push("executionContext");
3316
+ if (submitted.authorizationId !== proposal.authorizationId) mismatches.push("authorizationId");
3317
+ if (submitted.profileId !== proposal.profileId) mismatches.push("profileId");
3318
+ if (mismatches.length > 0) {
3319
+ void notifyControlPlane("as-key-mismatch");
3320
+ return {
3321
+ text: `Blocked: proposal ${proposal.id} no longer matches what this gateway submitted (${mismatches.join(", ")} differ) \u2014 refusing to execute.`,
3322
+ isError: true
3323
+ };
3324
+ }
3325
+ }
2990
3326
  let receiptId;
2991
3327
  let replayed = false;
2992
3328
  try {
@@ -3022,6 +3358,15 @@ async function executeCommitted(proposal, state2, integrationManager2) {
3022
3358
  });
3023
3359
  receiptId = typeof receipt?.id === "string" ? receipt.id : void 0;
3024
3360
  replayed = idempotent;
3361
+ await verifyTicket(state2.cache, receipt, {
3362
+ action: proposal.tool,
3363
+ executionContext: proposal.executionContext,
3364
+ authorizationId: proposal.authorizationId,
3365
+ profileId: proposal.profileId,
3366
+ proposalId: proposal.id,
3367
+ contentHash: binding?.contentHash,
3368
+ contentBinding: binding?.contentBinding
3369
+ });
3025
3370
  await state2.archiveReceipt(receipt, {
3026
3371
  authorizationId: proposal.authorizationId,
3027
3372
  profileId: proposal.profileId,
@@ -3036,6 +3381,13 @@ async function executeCommitted(proposal, state2, integrationManager2) {
3036
3381
  boundContent: binding?.boundContent
3037
3382
  });
3038
3383
  } catch (err) {
3384
+ if (err instanceof AsKeyMismatchError || err instanceof TicketBindingMismatchError) {
3385
+ void notifyControlPlane("as-key-mismatch");
3386
+ return {
3387
+ text: `Proposal ${proposal.id}: blocked \u2014 ${err.message}`,
3388
+ isError: true
3389
+ };
3390
+ }
3039
3391
  if (err instanceof ContentBindingError2) {
3040
3392
  return {
3041
3393
  text: `Proposal ${proposal.id}: blocked \u2014 the approved content cannot be bound to the receipt. ${err.message}`,
@@ -3195,9 +3547,13 @@ Wait for the human to approve; do not re-submit the tool call.`
3195
3547
  }]
3196
3548
  };
3197
3549
  }
3198
- const lines = committed.map(
3199
- (p) => `${p.id}: tool=${p.tool}, status=${p.status}, committed=[${Object.keys(p.committedBy).join(",")}]`
3200
- );
3550
+ const lines = committed.map((p) => {
3551
+ const base = `${p.id}: tool=${p.tool}, status=${p.status}, committed=[${Object.keys(p.committedBy).join(",")}]`;
3552
+ if (p.status === "committed" && !state2.proposalSubmissions.get(p.id)) {
3553
+ return `${base} \u2014 SKIPPED HERE: ${buildSkippedProposalNote(p.id)}`;
3554
+ }
3555
+ return base;
3556
+ });
3201
3557
  return {
3202
3558
  content: [{
3203
3559
  type: "text",
@@ -3394,16 +3750,16 @@ function verifyGateContentHashes(content, auth) {
3394
3750
  }
3395
3751
 
3396
3752
  // 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");
3753
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync10 } from "fs";
3754
+ import { homedir as homedir8 } from "os";
3755
+ import { dirname as dirname8, join as join10 } from "path";
3756
+ var DEFAULT_DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join10(homedir8(), ".suveren");
3401
3757
  var IntegrationRegistry = class {
3402
3758
  integrations = /* @__PURE__ */ new Map();
3403
3759
  filePath;
3404
- constructor(dataDir) {
3405
- const dir = dataDir ?? DEFAULT_DATA_DIR;
3406
- this.filePath = join8(dir, "integrations.json");
3760
+ constructor(dataDir2) {
3761
+ const dir = dataDir2 ?? DEFAULT_DATA_DIR;
3762
+ this.filePath = join10(dir, "integrations.json");
3407
3763
  this.load();
3408
3764
  }
3409
3765
  // ─── CRUD ───────────────────────────────────────────────────────────────
@@ -3434,12 +3790,12 @@ var IntegrationRegistry = class {
3434
3790
  }
3435
3791
  // ─── Load / Save ────────────────────────────────────────────────────────
3436
3792
  load() {
3437
- if (!existsSync8(this.filePath)) {
3438
- mkdirSync6(dirname6(this.filePath), { recursive: true });
3793
+ if (!existsSync10(this.filePath)) {
3794
+ mkdirSync8(dirname8(this.filePath), { recursive: true });
3439
3795
  return;
3440
3796
  }
3441
3797
  try {
3442
- const raw = readFileSync8(this.filePath, "utf-8");
3798
+ const raw = readFileSync10(this.filePath, "utf-8");
3443
3799
  const data = JSON.parse(raw);
3444
3800
  const migrated = data.integrations.map((i) => {
3445
3801
  if ("toolGating" in i && !("profile" in i)) {
@@ -3468,45 +3824,45 @@ var IntegrationRegistry = class {
3468
3824
  version: 1,
3469
3825
  integrations: Array.from(this.integrations.values())
3470
3826
  };
3471
- mkdirSync6(dirname6(this.filePath), { recursive: true });
3472
- writeFileSync6(this.filePath, JSON.stringify(data, null, 2), { encoding: "utf-8" });
3827
+ mkdirSync8(dirname8(this.filePath), { recursive: true });
3828
+ writeFileSync8(this.filePath, JSON.stringify(data, null, 2), { encoding: "utf-8" });
3473
3829
  }
3474
3830
  };
3475
3831
 
3476
3832
  // 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";
3833
+ import { homedir as homedir9 } from "os";
3834
+ import { join as join12, delimiter } from "path";
3835
+ import { existsSync as existsSync12, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, readFileSync as readFileSync12, rmSync } from "fs";
3480
3836
  import { execFile } from "child_process";
3481
3837
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3482
3838
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3483
3839
  import { getProfile as getProfile5 } from "@hap/core";
3484
3840
 
3485
3841
  // src/lib/manifest-loader.ts
3486
- import { readFileSync as readFileSync9, existsSync as existsSync9 } from "fs";
3487
- import { join as join9, resolve } from "path";
3842
+ import { readFileSync as readFileSync11, existsSync as existsSync11 } from "fs";
3843
+ import { join as join11, resolve } from "path";
3488
3844
  var manifests = /* @__PURE__ */ new Map();
3489
3845
  function loadManifests(integrationsDir) {
3490
3846
  const dir = resolve(
3491
- integrationsDir ?? process.env.SUVEREN_MANIFESTS_DIR ?? join9(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "content", "integrations")
3847
+ integrationsDir ?? process.env.SUVEREN_MANIFESTS_DIR ?? join11(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "content", "integrations")
3492
3848
  );
3493
- const indexPath = join9(dir, "index.json");
3494
- if (!existsSync9(indexPath)) {
3849
+ const indexPath = join11(dir, "index.json");
3850
+ if (!existsSync11(indexPath)) {
3495
3851
  console.error(`[ManifestLoader] No index.json found at ${indexPath}, skipping manifest loading`);
3496
3852
  return 0;
3497
3853
  }
3498
3854
  let index;
3499
3855
  try {
3500
- index = JSON.parse(readFileSync9(indexPath, "utf-8"));
3856
+ index = JSON.parse(readFileSync11(indexPath, "utf-8"));
3501
3857
  } catch (err) {
3502
3858
  console.error(`[ManifestLoader] Failed to parse ${indexPath}:`, err);
3503
3859
  return 0;
3504
3860
  }
3505
3861
  let loaded = 0;
3506
3862
  for (const [id, relativePath] of Object.entries(index.integrations)) {
3507
- const manifestPath = join9(dir, relativePath);
3863
+ const manifestPath = join11(dir, relativePath);
3508
3864
  try {
3509
- const manifest = JSON.parse(readFileSync9(manifestPath, "utf-8"));
3865
+ const manifest = JSON.parse(readFileSync11(manifestPath, "utf-8"));
3510
3866
  manifests.set(id, manifest);
3511
3867
  loaded++;
3512
3868
  } catch (err) {
@@ -3594,26 +3950,26 @@ function safeHost(url) {
3594
3950
  }
3595
3951
 
3596
3952
  // 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");
3953
+ var DEFAULT_DATA_DIR2 = process.env.SUVEREN_DATA_DIR ?? join12(homedir9(), ".suveren");
3954
+ var INTEGRATIONS_DIR = process.env.SUVEREN_INTEGRATIONS_DIR ?? join12(DEFAULT_DATA_DIR2, "integrations");
3599
3955
  var installLock = Promise.resolve();
3600
3956
  function withInstallLock(task) {
3601
3957
  const run = installLock.then(task, task);
3602
3958
  installLock = run.then(() => void 0, () => void 0);
3603
3959
  return run;
3604
3960
  }
3605
- var INTEGRATIONS_BIN = join10(INTEGRATIONS_DIR, "node_modules", ".bin");
3961
+ var INTEGRATIONS_BIN = join12(INTEGRATIONS_DIR, "node_modules", ".bin");
3606
3962
  function buildPath() {
3607
3963
  const base = process.env.PATH ?? "";
3608
3964
  return [INTEGRATIONS_BIN, base].join(delimiter);
3609
3965
  }
3610
3966
  function ensureIntegrationsDir() {
3611
- if (!existsSync10(INTEGRATIONS_DIR)) {
3612
- mkdirSync7(INTEGRATIONS_DIR, { recursive: true });
3967
+ if (!existsSync12(INTEGRATIONS_DIR)) {
3968
+ mkdirSync9(INTEGRATIONS_DIR, { recursive: true });
3613
3969
  }
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));
3970
+ const pkgPath = join12(INTEGRATIONS_DIR, "package.json");
3971
+ if (!existsSync12(pkgPath)) {
3972
+ writeFileSync9(pkgPath, JSON.stringify({ name: "suveren-integrations", version: "1.0.0", private: true }, null, 2));
3617
3973
  }
3618
3974
  }
3619
3975
  function readAgeOf(config) {
@@ -3679,19 +4035,19 @@ var IntegrationManager = class {
3679
4035
  * exist, and treat anything else as not-installed (and reinstallable).
3680
4036
  */
3681
4037
  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;
4038
+ const pkgDir = join12(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
4039
+ const pkgJson = join12(pkgDir, "package.json");
4040
+ if (!existsSync12(pkgDir) || !existsSync12(pkgJson)) return false;
3685
4041
  try {
3686
- const pkg = JSON.parse(readFileSync10(pkgJson, "utf8"));
4042
+ const pkg = JSON.parse(readFileSync12(pkgJson, "utf8"));
3687
4043
  const defaultBinName = (pkg.name ?? npmPackage).split("/").pop() ?? "";
3688
4044
  const binMap = typeof pkg.bin === "string" ? { [defaultBinName]: pkg.bin } : pkg.bin ?? {};
3689
4045
  const binEntries = Object.entries(binMap);
3690
4046
  for (const [binName, target] of binEntries) {
3691
- if (!existsSync10(join10(pkgDir, target))) return false;
4047
+ if (!existsSync12(join12(pkgDir, target))) return false;
3692
4048
  if (!this.binShimExists(binName)) return false;
3693
4049
  }
3694
- if (binEntries.length === 0 && pkg.main && !existsSync10(join10(pkgDir, pkg.main))) return false;
4050
+ if (binEntries.length === 0 && pkg.main && !existsSync12(join12(pkgDir, pkg.main))) return false;
3695
4051
  return true;
3696
4052
  } catch {
3697
4053
  return false;
@@ -3705,7 +4061,7 @@ var IntegrationManager = class {
3705
4061
  binShimExists(binName) {
3706
4062
  if (!binName) return false;
3707
4063
  const candidates = process.platform === "win32" ? [binName, `${binName}.cmd`, `${binName}.CMD`, `${binName}.ps1`] : [binName];
3708
- return candidates.some((c) => existsSync10(join10(INTEGRATIONS_BIN, c)));
4064
+ return candidates.some((c) => existsSync12(join12(INTEGRATIONS_BIN, c)));
3709
4065
  }
3710
4066
  /**
3711
4067
  * Install an npm package into the managed integrations directory if not
@@ -3729,8 +4085,8 @@ var IntegrationManager = class {
3729
4085
  }
3730
4086
  /** The actual install. Callers MUST hold the install lock. */
3731
4087
  async installNow(npmPackage) {
3732
- const pkgDir = join10(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
3733
- if (existsSync10(pkgDir)) {
4088
+ const pkgDir = join12(INTEGRATIONS_DIR, "node_modules", ...npmPackage.split("/"));
4089
+ if (existsSync12(pkgDir)) {
3734
4090
  console.error(`[IntegrationManager] Removing unusable install of ${npmPackage}`);
3735
4091
  try {
3736
4092
  rmSync(pkgDir, { recursive: true, force: true });
@@ -3844,6 +4200,11 @@ var IntegrationManager = class {
3844
4200
  const transport = new StdioClientTransport({
3845
4201
  command: config.command,
3846
4202
  args,
4203
+ // `...process.env` is also how a saved `--ca-file` reaches an
4204
+ // integration: NODE_EXTRA_CA_CERTS (read by Node only at process
4205
+ // start) is already set on THIS process by bundle/server.js before
4206
+ // the MCP server ever starts, so every integration this manager spawns
4207
+ // inherits it here for free — no separate handling needed.
3847
4208
  env: {
3848
4209
  ...process.env,
3849
4210
  PATH: buildPath(),
@@ -4160,28 +4521,28 @@ var IntegrationManager = class {
4160
4521
  };
4161
4522
 
4162
4523
  // 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";
4524
+ import { readFileSync as readFileSync13, existsSync as existsSync13 } from "fs";
4525
+ import { join as join13, resolve as resolve2 } from "path";
4165
4526
  import { registerProfile } from "@hap/core";
4166
4527
  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)) {
4528
+ const dir = resolve2(profilesDir ?? process.env.SUVEREN_PROFILES_DIR ?? join13(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "..", "hap-profiles"));
4529
+ const indexPath = join13(dir, "index.json");
4530
+ if (!existsSync13(indexPath)) {
4170
4531
  warnNoProfiles(`No index.json at ${indexPath}`);
4171
4532
  return 0;
4172
4533
  }
4173
4534
  let index;
4174
4535
  try {
4175
- index = JSON.parse(readFileSync11(indexPath, "utf-8"));
4536
+ index = JSON.parse(readFileSync13(indexPath, "utf-8"));
4176
4537
  } catch (err) {
4177
4538
  console.error(`[ProfileLoader] Failed to parse ${indexPath}:`, err);
4178
4539
  return 0;
4179
4540
  }
4180
4541
  let loaded = 0;
4181
4542
  for (const [profileId, relativePath] of Object.entries(index.profiles)) {
4182
- const profilePath = join11(dir, relativePath);
4543
+ const profilePath = join13(dir, relativePath);
4183
4544
  try {
4184
- const profile = JSON.parse(readFileSync11(profilePath, "utf-8"));
4545
+ const profile = JSON.parse(readFileSync13(profilePath, "utf-8"));
4185
4546
  registerProfile(profileId, profile);
4186
4547
  const shortName = profileId.split("/").pop()?.replace(/@.*$/, "");
4187
4548
  if (shortName && shortName !== profileId) {
@@ -4217,8 +4578,8 @@ function warnNoProfiles(reason) {
4217
4578
  import { decodeAttestationBlob as decodeAttestationBlob3 } from "@hap/core";
4218
4579
 
4219
4580
  // 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";
4581
+ import { existsSync as existsSync14, mkdirSync as mkdirSync10, readFileSync as readFileSync14, unlinkSync as unlinkSync6, writeFileSync as writeFileSync10 } from "fs";
4582
+ import { dirname as dirname9, join as join14 } from "path";
4222
4583
  var CommittedExecutor = class {
4223
4584
  constructor(run) {
4224
4585
  this.run = run;
@@ -4245,8 +4606,8 @@ var CommittedExecutor = class {
4245
4606
  var ExecutorLock = class {
4246
4607
  path;
4247
4608
  held = false;
4248
- constructor(dataDir) {
4249
- this.path = join12(dataDir, "executor.lock");
4609
+ constructor(dataDir2) {
4610
+ this.path = join14(dataDir2, "executor.lock");
4250
4611
  }
4251
4612
  /** Try to take the lock. Returns the holder's pid when someone else has it. */
4252
4613
  acquire() {
@@ -4254,9 +4615,9 @@ var ExecutorLock = class {
4254
4615
  if (current && current.pid !== process.pid && isAlive(current.pid)) {
4255
4616
  return { held: false, holderPid: current.pid };
4256
4617
  }
4257
- mkdirSync8(dirname7(this.path), { recursive: true, mode: 448 });
4618
+ mkdirSync10(dirname9(this.path), { recursive: true, mode: 448 });
4258
4619
  const lock = { pid: process.pid, startedAt: Math.floor(Date.now() / 1e3) };
4259
- writeFileSync8(this.path, JSON.stringify(lock), { mode: 384 });
4620
+ writeFileSync10(this.path, JSON.stringify(lock), { mode: 384 });
4260
4621
  this.held = true;
4261
4622
  return { held: true };
4262
4623
  }
@@ -4272,15 +4633,15 @@ var ExecutorLock = class {
4272
4633
  const current = this.read();
4273
4634
  if (current?.pid === process.pid) {
4274
4635
  try {
4275
- unlinkSync5(this.path);
4636
+ unlinkSync6(this.path);
4276
4637
  } catch {
4277
4638
  }
4278
4639
  }
4279
4640
  }
4280
4641
  read() {
4281
- if (!existsSync12(this.path)) return null;
4642
+ if (!existsSync14(this.path)) return null;
4282
4643
  try {
4283
- const parsed = JSON.parse(readFileSync12(this.path, "utf8"));
4644
+ const parsed = JSON.parse(readFileSync14(this.path, "utf8"));
4284
4645
  return typeof parsed?.pid === "number" ? parsed : null;
4285
4646
  } catch {
4286
4647
  return null;
@@ -4297,11 +4658,115 @@ function isAlive(pid) {
4297
4658
  }
4298
4659
 
4299
4660
  // 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";
4661
+ import { homedir as homedir10 } from "os";
4662
+ import { join as join17 } from "path";
4663
+
4664
+ // src/lib/as-config.ts
4665
+ import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync15, writeFileSync as writeFileSync11 } from "fs";
4666
+ import { dirname as dirname10, join as join15 } from "path";
4667
+ var DEFAULT_AS_URL = "https://www.suveren.ai";
4668
+ function configPath(dataDir2) {
4669
+ return join15(dataDir2, "config.json");
4670
+ }
4671
+ function readAsConfigStrict(dataDir2) {
4672
+ const path = configPath(dataDir2);
4673
+ if (!existsSync15(path)) return {};
4674
+ let data;
4675
+ try {
4676
+ data = JSON.parse(readFileSync15(path, "utf-8"));
4677
+ } catch (err) {
4678
+ throw new Error(
4679
+ `Could not parse ${path}: ${err instanceof Error ? err.message : String(err)}`
4680
+ );
4681
+ }
4682
+ const out = {};
4683
+ if (typeof data.asUrl === "string") out.asUrl = data.asUrl;
4684
+ if (typeof data.caFile === "string") out.caFile = data.caFile;
4685
+ return out;
4686
+ }
4687
+ function validateAsUrl(candidate) {
4688
+ const trimmed = candidate.trim();
4689
+ if (!trimmed) return { ok: false, error: "The Authority Server URL is empty." };
4690
+ let parsed;
4691
+ try {
4692
+ parsed = new URL(trimmed);
4693
+ } catch {
4694
+ return { ok: false, error: `"${trimmed}" is not a valid URL.` };
4695
+ }
4696
+ const isLocalHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1");
4697
+ if (parsed.protocol !== "https:" && !isLocalHttp) {
4698
+ return {
4699
+ ok: false,
4700
+ error: `"${trimmed}" must use https:// (http:// is only allowed for http://localhost or http://127.0.0.1).`
4701
+ };
4702
+ }
4703
+ let normalized = `${parsed.origin}${parsed.pathname}${parsed.search}${parsed.hash}`;
4704
+ if (normalized.endsWith("/") && normalized !== `${parsed.origin}/`) {
4705
+ normalized = normalized.slice(0, -1);
4706
+ } else if (normalized === `${parsed.origin}/`) {
4707
+ normalized = parsed.origin;
4708
+ }
4709
+ return { ok: true, url: normalized };
4710
+ }
4711
+ function resolveAsUrl(dataDir2, flag) {
4712
+ if (flag) {
4713
+ const v = validateAsUrl(flag);
4714
+ if (!v.ok) throw new Error(`Invalid --as-url: ${v.error}`);
4715
+ return v.url;
4716
+ }
4717
+ const envUrl = process.env.SUVEREN_AS_URL;
4718
+ if (envUrl) {
4719
+ const v = validateAsUrl(envUrl);
4720
+ if (!v.ok) throw new Error(`Invalid SUVEREN_AS_URL: ${v.error}`);
4721
+ return v.url;
4722
+ }
4723
+ const saved = readAsConfigStrict(dataDir2).asUrl;
4724
+ if (saved) {
4725
+ const v = validateAsUrl(saved);
4726
+ if (!v.ok) throw new Error(`Invalid saved as-url "${saved}" in ${dataDir2}/config.json: ${v.error}`);
4727
+ return v.url;
4728
+ }
4729
+ return DEFAULT_AS_URL;
4730
+ }
4731
+
4732
+ // src/lib/mcp-as-tracker.ts
4733
+ import { existsSync as existsSync16, mkdirSync as mkdirSync12, readFileSync as readFileSync16, writeFileSync as writeFileSync12 } from "fs";
4734
+ import { dirname as dirname11, join as join16 } from "path";
4735
+ function trackerPath(dataDir2) {
4736
+ return join16(dataDir2, "mcp-as-pairing.json");
4737
+ }
4738
+ function readMcpPairedAsUrl(dataDir2) {
4739
+ const path = trackerPath(dataDir2);
4740
+ if (!existsSync16(path)) return null;
4741
+ try {
4742
+ const data = JSON.parse(readFileSync16(path, "utf-8"));
4743
+ return typeof data.asUrl === "string" ? data.asUrl : null;
4744
+ } catch {
4745
+ return null;
4746
+ }
4747
+ }
4748
+ function writeMcpPairedAsUrl(dataDir2, asUrl) {
4749
+ const path = trackerPath(dataDir2);
4750
+ mkdirSync12(dirname11(path), { recursive: true, mode: 448 });
4751
+ writeFileSync12(path, JSON.stringify({ asUrl }, null, 2), { encoding: "utf-8", mode: 384 });
4752
+ }
4753
+
4754
+ // bin/http.ts
4755
+ var dataDir = process.env.SUVEREN_DATA_DIR ?? join17(homedir10(), ".suveren");
4756
+ var spUrl = resolveAsUrl(dataDir);
4303
4757
  var port = parseInt(process.env.SUVEREN_MCP_PORT ?? "3430", 10);
4304
- var state = new SharedState(spUrl);
4758
+ setAsBaseUrl(spUrl);
4759
+ var state = new SharedState(spUrl, void 0, dataDir);
4760
+ (function repairIfAsUrlChanged() {
4761
+ const lastKnown = readMcpPairedAsUrl(dataDir);
4762
+ if (lastKnown !== null && lastKnown !== spUrl) {
4763
+ console.error(
4764
+ `[Suveren MCP] Authority Server changed (${lastKnown} \u2192 ${spUrl}) \u2014 clearing cached mandates. Sign in again to re-pair.`
4765
+ );
4766
+ state.gateStore.clearAll();
4767
+ }
4768
+ writeMcpPairedAsUrl(dataDir, spUrl);
4769
+ })();
4305
4770
  var spApiKey = process.env.SUVEREN_AS_API_KEY ?? "";
4306
4771
  if (spApiKey) {
4307
4772
  state.spClient.setApiKey(spApiKey);
@@ -4371,9 +4836,11 @@ app.post("/internal/configure", internalOnly, (req, res) => {
4371
4836
  }
4372
4837
  res.json({ ok: true });
4373
4838
  });
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)");
4839
+ app.post("/internal/clear-session", internalOnly, (req, res) => {
4840
+ const reason = req.body?.reason;
4841
+ const validReason = reason === "as-key-mismatch" || reason === "as-url-changed" ? reason : void 0;
4842
+ state.spClient.clearSession(validReason);
4843
+ console.error(`[Suveren MCP] Session cleared by control-plane (${validReason ?? "expired"})`);
4377
4844
  res.json({ ok: true });
4378
4845
  });
4379
4846
  app.post("/internal/gate-content", internalOnly, async (req, res) => {
@@ -4665,6 +5132,15 @@ app.get("/internal/authorizations", internalOnly, (_req, res) => {
4665
5132
  app.get("/internal/manifests", internalOnly, (_req, res) => {
4666
5133
  res.json({ manifests: getAllManifests() });
4667
5134
  });
5135
+ app.get("/internal/skipped-commitments", internalOnly, async (_req, res) => {
5136
+ try {
5137
+ const committed = await state.spClient.getCommittedProposals();
5138
+ const skipped = committed.filter((p) => !state.proposalSubmissions.get(p.id)).map((p) => ({ id: p.id, tool: p.tool, note: buildSkippedProposalNote(p.id) }));
5139
+ res.json({ skipped });
5140
+ } catch (err) {
5141
+ res.status(502).json({ error: err instanceof Error ? err.message : "Could not reach the Authority Server" });
5142
+ }
5143
+ });
4668
5144
  app.get("/internal/evidence", internalOnly, (_req, res) => {
4669
5145
  if (state.receiptArchive.isLocked()) {
4670
5146
  res.status(503).json({ error: "Vault locked \u2014 the evidence archive is encrypted until sign-in." });
@@ -4798,12 +5274,12 @@ app.listen(port, "0.0.0.0", () => {
4798
5274
  (proposal) => executeCommitted(proposal, state, integrationManager)
4799
5275
  );
4800
5276
  installCommittedExecutor(committedExecutor);
4801
- const dataDir = process.env.SUVEREN_DATA_DIR ?? join13(homedir9(), ".suveren");
4802
- const executorLock = new ExecutorLock(dataDir);
5277
+ const dataDir2 = process.env.SUVEREN_DATA_DIR ?? join17(homedir10(), ".suveren");
5278
+ const executorLock = new ExecutorLock(dataDir2);
4803
5279
  const lock = executorLock.acquire();
4804
5280
  if (!lock.held) {
4805
5281
  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.`
5282
+ `[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
5283
  );
4808
5284
  }
4809
5285
  for (const sig of ["SIGINT", "SIGTERM", "exit"]) {