aimakeall-mcp 0.14.4 → 0.14.6

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 (610) hide show
  1. package/README.md +117 -1
  2. package/lib/cloud-tools.mjs +131 -51
  3. package/lib/config.mjs +1 -1
  4. package/lib/durable-channel-contract.mjs +16 -6
  5. package/lib/durable-channel-journal.mjs +10 -5
  6. package/lib/durable-channel-request.mjs +4 -4
  7. package/lib/durable-remake-contract.mjs +88 -0
  8. package/lib/durable-remake-request.mjs +375 -0
  9. package/lib/durable-speech.mjs +2 -2
  10. package/lib/durable-voice-contract.mjs +62 -0
  11. package/lib/narration-timeline.mjs +189 -0
  12. package/lib/review-plan-client.mjs +73 -0
  13. package/lib/review-production-contract.mjs +198 -0
  14. package/lib/review-tools.mjs +40 -11
  15. package/lib/speech-production-journal.mjs +109 -0
  16. package/lib/speech-production.mjs +161 -0
  17. package/lib/studio-plan-client.mjs +64 -0
  18. package/lib/studio-plan-contract.mjs +128 -0
  19. package/lib/studio-plan-request.mjs +372 -0
  20. package/lib/voice-catalog.mjs +33 -0
  21. package/lib/voice-recommendation-client.mjs +40 -0
  22. package/node_modules/fast-uri/index.js +10 -6
  23. package/node_modules/fast-uri/package.json +1 -1
  24. package/node_modules/fast-uri/test/security-normalization.test.js +38 -0
  25. package/node_modules/hono/README.md +1 -1
  26. package/node_modules/hono/dist/_virtual/_rolldown/runtime.js +13 -0
  27. package/node_modules/hono/dist/adapter/aws-lambda/conninfo.js +42 -23
  28. package/node_modules/hono/dist/adapter/aws-lambda/handler.js +320 -342
  29. package/node_modules/hono/dist/adapter/aws-lambda/index.js +2 -8
  30. package/node_modules/hono/dist/adapter/aws-lambda/types.js +1 -0
  31. package/node_modules/hono/dist/adapter/bun/conninfo.js +20 -25
  32. package/node_modules/hono/dist/adapter/bun/index.js +3 -13
  33. package/node_modules/hono/dist/adapter/bun/serve-static.js +27 -27
  34. package/node_modules/hono/dist/adapter/bun/server.js +11 -5
  35. package/node_modules/hono/dist/adapter/bun/ssg.js +25 -15
  36. package/node_modules/hono/dist/adapter/bun/websocket.js +61 -68
  37. package/node_modules/hono/dist/adapter/cloudflare-pages/conninfo.js +24 -9
  38. package/node_modules/hono/dist/adapter/cloudflare-pages/handler.js +59 -62
  39. package/node_modules/hono/dist/adapter/cloudflare-pages/index.js +2 -8
  40. package/node_modules/hono/dist/adapter/cloudflare-workers/conninfo.js +7 -9
  41. package/node_modules/hono/dist/adapter/cloudflare-workers/index.js +3 -8
  42. package/node_modules/hono/dist/adapter/cloudflare-workers/serve-static-module.js +5 -6
  43. package/node_modules/hono/dist/adapter/cloudflare-workers/serve-static.js +26 -20
  44. package/node_modules/hono/dist/adapter/cloudflare-workers/utils.js +21 -34
  45. package/node_modules/hono/dist/adapter/cloudflare-workers/websocket.js +31 -39
  46. package/node_modules/hono/dist/adapter/deno/conninfo.js +16 -13
  47. package/node_modules/hono/dist/adapter/deno/deno.d.js +1 -0
  48. package/node_modules/hono/dist/adapter/deno/index.js +3 -10
  49. package/node_modules/hono/dist/adapter/deno/serve-static.js +33 -38
  50. package/node_modules/hono/dist/adapter/deno/ssg.js +27 -16
  51. package/node_modules/hono/dist/adapter/deno/websocket.js +30 -30
  52. package/node_modules/hono/dist/adapter/lambda-edge/conninfo.js +7 -9
  53. package/node_modules/hono/dist/adapter/lambda-edge/handler.js +102 -87
  54. package/node_modules/hono/dist/adapter/lambda-edge/index.js +2 -6
  55. package/node_modules/hono/dist/adapter/netlify/conninfo.js +24 -9
  56. package/node_modules/hono/dist/adapter/netlify/handler.js +10 -8
  57. package/node_modules/hono/dist/adapter/netlify/index.js +3 -2
  58. package/node_modules/hono/dist/adapter/netlify/mod.js +2 -6
  59. package/node_modules/hono/dist/adapter/service-worker/handler.js +15 -19
  60. package/node_modules/hono/dist/adapter/service-worker/index.js +23 -7
  61. package/node_modules/hono/dist/adapter/service-worker/types.js +1 -0
  62. package/node_modules/hono/dist/adapter/vercel/conninfo.js +7 -10
  63. package/node_modules/hono/dist/adapter/vercel/handler.js +8 -6
  64. package/node_modules/hono/dist/adapter/vercel/index.js +2 -6
  65. package/node_modules/hono/dist/cjs/_virtual/_rolldown/runtime.js +33 -0
  66. package/node_modules/hono/dist/cjs/adapter/aws-lambda/conninfo.js +42 -44
  67. package/node_modules/hono/dist/cjs/adapter/aws-lambda/handler.js +328 -371
  68. package/node_modules/hono/dist/cjs/adapter/aws-lambda/index.js +7 -34
  69. package/node_modules/hono/dist/cjs/adapter/aws-lambda/types.js +0 -15
  70. package/node_modules/hono/dist/cjs/adapter/bun/conninfo.js +21 -47
  71. package/node_modules/hono/dist/cjs/adapter/bun/index.js +14 -45
  72. package/node_modules/hono/dist/cjs/adapter/bun/serve-static.js +29 -50
  73. package/node_modules/hono/dist/cjs/adapter/bun/server.js +11 -26
  74. package/node_modules/hono/dist/cjs/adapter/bun/ssg.js +24 -35
  75. package/node_modules/hono/dist/cjs/adapter/bun/websocket.js +63 -91
  76. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/conninfo.js +25 -31
  77. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/handler.js +61 -85
  78. package/node_modules/hono/dist/cjs/adapter/cloudflare-pages/index.js +7 -34
  79. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/conninfo.js +8 -31
  80. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/index.js +7 -33
  81. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/serve-static-module.js +7 -29
  82. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/serve-static.js +27 -42
  83. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/utils.js +21 -55
  84. package/node_modules/hono/dist/cjs/adapter/cloudflare-workers/websocket.js +33 -62
  85. package/node_modules/hono/dist/cjs/adapter/deno/conninfo.js +16 -34
  86. package/node_modules/hono/dist/cjs/adapter/deno/index.js +10 -38
  87. package/node_modules/hono/dist/cjs/adapter/deno/serve-static.js +33 -59
  88. package/node_modules/hono/dist/cjs/adapter/deno/ssg.js +27 -37
  89. package/node_modules/hono/dist/cjs/adapter/deno/websocket.js +32 -53
  90. package/node_modules/hono/dist/cjs/adapter/lambda-edge/conninfo.js +8 -31
  91. package/node_modules/hono/dist/cjs/adapter/lambda-edge/handler.js +105 -119
  92. package/node_modules/hono/dist/cjs/adapter/lambda-edge/index.js +5 -30
  93. package/node_modules/hono/dist/cjs/adapter/netlify/conninfo.js +25 -31
  94. package/node_modules/hono/dist/cjs/adapter/netlify/handler.js +10 -29
  95. package/node_modules/hono/dist/cjs/adapter/netlify/index.js +5 -21
  96. package/node_modules/hono/dist/cjs/adapter/netlify/mod.js +5 -30
  97. package/node_modules/hono/dist/cjs/adapter/service-worker/handler.js +16 -41
  98. package/node_modules/hono/dist/cjs/adapter/service-worker/index.js +25 -30
  99. package/node_modules/hono/dist/cjs/adapter/service-worker/types.js +0 -15
  100. package/node_modules/hono/dist/cjs/adapter/vercel/conninfo.js +8 -32
  101. package/node_modules/hono/dist/cjs/adapter/vercel/handler.js +8 -27
  102. package/node_modules/hono/dist/cjs/adapter/vercel/index.js +5 -30
  103. package/node_modules/hono/dist/cjs/client/client.js +139 -212
  104. package/node_modules/hono/dist/cjs/client/fetch-result-please.js +62 -80
  105. package/node_modules/hono/dist/cjs/client/index.js +7 -32
  106. package/node_modules/hono/dist/cjs/client/types.js +0 -15
  107. package/node_modules/hono/dist/cjs/client/utils.js +54 -92
  108. package/node_modules/hono/dist/cjs/compose.js +49 -66
  109. package/node_modules/hono/dist/cjs/context.js +379 -450
  110. package/node_modules/hono/dist/cjs/helper/accepts/accepts.js +47 -70
  111. package/node_modules/hono/dist/cjs/helper/accepts/index.js +3 -27
  112. package/node_modules/hono/dist/cjs/helper/adapter/index.js +33 -73
  113. package/node_modules/hono/dist/cjs/helper/conninfo/index.js +0 -15
  114. package/node_modules/hono/dist/cjs/helper/conninfo/types.js +0 -15
  115. package/node_modules/hono/dist/cjs/helper/cookie/index.js +75 -116
  116. package/node_modules/hono/dist/cjs/helper/css/common.js +165 -244
  117. package/node_modules/hono/dist/cjs/helper/css/index.js +136 -151
  118. package/node_modules/hono/dist/cjs/helper/dev/index.js +45 -71
  119. package/node_modules/hono/dist/cjs/helper/factory/index.js +30 -51
  120. package/node_modules/hono/dist/cjs/helper/html/index.js +32 -62
  121. package/node_modules/hono/dist/cjs/helper/proxy/index.js +113 -106
  122. package/node_modules/hono/dist/cjs/helper/route/index.js +123 -66
  123. package/node_modules/hono/dist/cjs/helper/ssg/index.js +19 -43
  124. package/node_modules/hono/dist/cjs/helper/ssg/middleware.js +56 -64
  125. package/node_modules/hono/dist/cjs/helper/ssg/plugins.js +55 -57
  126. package/node_modules/hono/dist/cjs/helper/ssg/ssg.js +196 -296
  127. package/node_modules/hono/dist/cjs/helper/ssg/utils.js +47 -90
  128. package/node_modules/hono/dist/cjs/helper/streaming/index.js +8 -35
  129. package/node_modules/hono/dist/cjs/helper/streaming/sse.js +53 -85
  130. package/node_modules/hono/dist/cjs/helper/streaming/stream.js +23 -53
  131. package/node_modules/hono/dist/cjs/helper/streaming/text.js +10 -32
  132. package/node_modules/hono/dist/cjs/helper/streaming/utils.js +13 -32
  133. package/node_modules/hono/dist/cjs/helper/testing/index.js +16 -31
  134. package/node_modules/hono/dist/cjs/helper/websocket/index.js +51 -76
  135. package/node_modules/hono/dist/cjs/hono-base.js +347 -402
  136. package/node_modules/hono/dist/cjs/hono.js +28 -42
  137. package/node_modules/hono/dist/cjs/http-exception.js +55 -56
  138. package/node_modules/hono/dist/cjs/index.js +22 -30
  139. package/node_modules/hono/dist/cjs/jsx/base.js +241 -353
  140. package/node_modules/hono/dist/cjs/jsx/children.js +16 -41
  141. package/node_modules/hono/dist/cjs/jsx/components.js +120 -194
  142. package/node_modules/hono/dist/cjs/jsx/constants.js +15 -42
  143. package/node_modules/hono/dist/cjs/jsx/context.js +144 -162
  144. package/node_modules/hono/dist/cjs/jsx/dom/client.js +49 -69
  145. package/node_modules/hono/dist/cjs/jsx/dom/components.js +23 -52
  146. package/node_modules/hono/dist/cjs/jsx/dom/context.js +39 -67
  147. package/node_modules/hono/dist/cjs/jsx/dom/css.js +143 -158
  148. package/node_modules/hono/dist/cjs/jsx/dom/hooks/index.js +55 -64
  149. package/node_modules/hono/dist/cjs/jsx/dom/index.js +114 -173
  150. package/node_modules/hono/dist/cjs/jsx/dom/intrinsic-element/components.js +282 -375
  151. package/node_modules/hono/dist/cjs/jsx/dom/jsx-dev-runtime.js +14 -49
  152. package/node_modules/hono/dist/cjs/jsx/dom/jsx-runtime.js +5 -32
  153. package/node_modules/hono/dist/cjs/jsx/dom/render.js +471 -589
  154. package/node_modules/hono/dist/cjs/jsx/dom/server.js +37 -60
  155. package/node_modules/hono/dist/cjs/jsx/dom/utils.js +7 -30
  156. package/node_modules/hono/dist/cjs/jsx/hooks/index.js +225 -318
  157. package/node_modules/hono/dist/cjs/jsx/index.js +86 -135
  158. package/node_modules/hono/dist/cjs/jsx/intrinsic-element/common.js +20 -43
  159. package/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +117 -168
  160. package/node_modules/hono/dist/cjs/jsx/intrinsic-elements.js +0 -15
  161. package/node_modules/hono/dist/cjs/jsx/jsx-dev-runtime.js +14 -39
  162. package/node_modules/hono/dist/cjs/jsx/jsx-runtime.js +34 -68
  163. package/node_modules/hono/dist/cjs/jsx/streaming.js +123 -167
  164. package/node_modules/hono/dist/cjs/jsx/types.js +0 -15
  165. package/node_modules/hono/dist/cjs/jsx/utils.js +91 -175
  166. package/node_modules/hono/dist/cjs/middleware/basic-auth/index.js +98 -86
  167. package/node_modules/hono/dist/cjs/middleware/bearer-auth/index.js +92 -109
  168. package/node_modules/hono/dist/cjs/middleware/body-limit/index.js +66 -72
  169. package/node_modules/hono/dist/cjs/middleware/cache/index.js +153 -199
  170. package/node_modules/hono/dist/cjs/middleware/combine/index.js +135 -95
  171. package/node_modules/hono/dist/cjs/middleware/compress/index.js +73 -88
  172. package/node_modules/hono/dist/cjs/middleware/context-storage/index.js +49 -41
  173. package/node_modules/hono/dist/cjs/middleware/cors/index.js +107 -107
  174. package/node_modules/hono/dist/cjs/middleware/csrf/index.js +101 -72
  175. package/node_modules/hono/dist/cjs/middleware/etag/digest.js +58 -97
  176. package/node_modules/hono/dist/cjs/middleware/etag/index.js +71 -91
  177. package/node_modules/hono/dist/cjs/middleware/ip-restriction/index.js +161 -169
  178. package/node_modules/hono/dist/cjs/middleware/jsx-renderer/index.js +99 -77
  179. package/node_modules/hono/dist/cjs/middleware/jwk/index.js +3 -27
  180. package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +118 -135
  181. package/node_modules/hono/dist/cjs/middleware/jwt/index.js +9 -38
  182. package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +120 -141
  183. package/node_modules/hono/dist/cjs/middleware/language/index.js +7 -35
  184. package/node_modules/hono/dist/cjs/middleware/language/language.js +184 -179
  185. package/node_modules/hono/dist/cjs/middleware/logger/index.js +41 -62
  186. package/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +82 -88
  187. package/node_modules/hono/dist/cjs/middleware/method-override/index.js +101 -102
  188. package/node_modules/hono/dist/cjs/middleware/mount/index.js +71 -0
  189. package/node_modules/hono/dist/cjs/middleware/powered-by/index.js +23 -30
  190. package/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +38 -36
  191. package/node_modules/hono/dist/cjs/middleware/request-id/index.js +3 -27
  192. package/node_modules/hono/dist/cjs/middleware/request-id/request-id.js +34 -42
  193. package/node_modules/hono/dist/cjs/middleware/secure-headers/index.js +4 -29
  194. package/node_modules/hono/dist/cjs/middleware/secure-headers/permissions-policy.js +0 -15
  195. package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +142 -174
  196. package/node_modules/hono/dist/cjs/middleware/serve-static/index.js +56 -93
  197. package/node_modules/hono/dist/cjs/middleware/serve-static/path.js +15 -38
  198. package/node_modules/hono/dist/cjs/middleware/timeout/index.js +40 -45
  199. package/node_modules/hono/dist/cjs/middleware/timing/index.js +7 -35
  200. package/node_modules/hono/dist/cjs/middleware/timing/timing.js +177 -118
  201. package/node_modules/hono/dist/cjs/middleware/trailing-slash/index.js +85 -58
  202. package/node_modules/hono/dist/cjs/preset/quick.js +18 -37
  203. package/node_modules/hono/dist/cjs/preset/tiny.js +15 -33
  204. package/node_modules/hono/dist/cjs/request/constants.js +5 -27
  205. package/node_modules/hono/dist/cjs/request.js +334 -343
  206. package/node_modules/hono/dist/cjs/router/linear-router/index.js +3 -27
  207. package/node_modules/hono/dist/cjs/router/linear-router/router.js +95 -143
  208. package/node_modules/hono/dist/cjs/router/pattern-router/index.js +3 -27
  209. package/node_modules/hono/dist/cjs/router/pattern-router/router.js +41 -63
  210. package/node_modules/hono/dist/cjs/router/reg-exp-router/index.js +7 -34
  211. package/node_modules/hono/dist/cjs/router/reg-exp-router/matcher.js +18 -45
  212. package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +91 -135
  213. package/node_modules/hono/dist/cjs/router/reg-exp-router/prepared-router.js +92 -161
  214. package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +98 -147
  215. package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +73 -89
  216. package/node_modules/hono/dist/cjs/router/smart-router/index.js +3 -27
  217. package/node_modules/hono/dist/cjs/router/smart-router/router.js +49 -79
  218. package/node_modules/hono/dist/cjs/router/trie-router/index.js +3 -27
  219. package/node_modules/hono/dist/cjs/router/trie-router/node.js +134 -186
  220. package/node_modules/hono/dist/cjs/router/trie-router/router.js +15 -39
  221. package/node_modules/hono/dist/cjs/router/utils.js +5 -27
  222. package/node_modules/hono/dist/cjs/router.js +37 -37
  223. package/node_modules/hono/dist/cjs/types.js +5 -28
  224. package/node_modules/hono/dist/cjs/utils/accept.js +177 -228
  225. package/node_modules/hono/dist/cjs/utils/basic-auth.js +16 -40
  226. package/node_modules/hono/dist/cjs/utils/body.js +84 -110
  227. package/node_modules/hono/dist/cjs/utils/buffer.js +43 -91
  228. package/node_modules/hono/dist/cjs/utils/color.js +35 -44
  229. package/node_modules/hono/dist/cjs/utils/compress.js +11 -26
  230. package/node_modules/hono/dist/cjs/utils/concurrent.js +29 -59
  231. package/node_modules/hono/dist/cjs/utils/constants.js +7 -26
  232. package/node_modules/hono/dist/cjs/utils/cookie.js +107 -177
  233. package/node_modules/hono/dist/cjs/utils/crypto.js +30 -61
  234. package/node_modules/hono/dist/cjs/utils/encode.js +31 -48
  235. package/node_modules/hono/dist/cjs/utils/filepath.js +23 -54
  236. package/node_modules/hono/dist/cjs/utils/handler.js +11 -33
  237. package/node_modules/hono/dist/cjs/utils/headers.js +0 -15
  238. package/node_modules/hono/dist/cjs/utils/html.js +96 -137
  239. package/node_modules/hono/dist/cjs/utils/http-status.js +0 -15
  240. package/node_modules/hono/dist/cjs/utils/ipaddr.js +213 -286
  241. package/node_modules/hono/dist/cjs/utils/jwt/index.js +14 -27
  242. package/node_modules/hono/dist/cjs/utils/jwt/jwa.js +25 -42
  243. package/node_modules/hono/dist/cjs/utils/jwt/jws.js +119 -199
  244. package/node_modules/hono/dist/cjs/utils/jwt/jwt.js +122 -205
  245. package/node_modules/hono/dist/cjs/utils/jwt/types.js +122 -159
  246. package/node_modules/hono/dist/cjs/utils/jwt/utf8.js +9 -28
  247. package/node_modules/hono/dist/cjs/utils/mime.js +75 -101
  248. package/node_modules/hono/dist/cjs/utils/stream.js +88 -111
  249. package/node_modules/hono/dist/cjs/utils/types.js +0 -15
  250. package/node_modules/hono/dist/cjs/utils/url.js +185 -234
  251. package/node_modules/hono/dist/cjs/validator/index.js +3 -27
  252. package/node_modules/hono/dist/cjs/validator/utils.js +0 -15
  253. package/node_modules/hono/dist/cjs/validator/validator.js +60 -103
  254. package/node_modules/hono/dist/client/client.js +138 -197
  255. package/node_modules/hono/dist/client/fetch-result-please.js +59 -56
  256. package/node_modules/hono/dist/client/index.js +3 -7
  257. package/node_modules/hono/dist/client/types.js +1 -0
  258. package/node_modules/hono/dist/client/utils.js +51 -68
  259. package/node_modules/hono/dist/compose.js +49 -45
  260. package/node_modules/hono/dist/context.js +376 -426
  261. package/node_modules/hono/dist/helper/accepts/accepts.js +47 -49
  262. package/node_modules/hono/dist/helper/accepts/index.js +1 -4
  263. package/node_modules/hono/dist/helper/adapter/index.js +33 -52
  264. package/node_modules/hono/dist/helper/conninfo/index.js +1 -0
  265. package/node_modules/hono/dist/helper/conninfo/types.js +1 -0
  266. package/node_modules/hono/dist/helper/cookie/index.js +74 -94
  267. package/node_modules/hono/dist/helper/css/common.js +167 -225
  268. package/node_modules/hono/dist/helper/css/index.js +132 -137
  269. package/node_modules/hono/dist/helper/dev/index.js +44 -49
  270. package/node_modules/hono/dist/helper/factory/index.js +27 -27
  271. package/node_modules/hono/dist/helper/html/index.js +30 -39
  272. package/node_modules/hono/dist/helper/proxy/index.js +116 -88
  273. package/node_modules/hono/dist/helper/route/index.js +121 -43
  274. package/node_modules/hono/dist/helper/ssg/index.js +3 -18
  275. package/node_modules/hono/dist/helper/ssg/middleware.js +53 -40
  276. package/node_modules/hono/dist/helper/ssg/plugins.js +55 -36
  277. package/node_modules/hono/dist/helper/ssg/ssg.js +198 -283
  278. package/node_modules/hono/dist/helper/ssg/utils.js +53 -75
  279. package/node_modules/hono/dist/helper/streaming/index.js +2 -8
  280. package/node_modules/hono/dist/helper/streaming/sse.js +50 -61
  281. package/node_modules/hono/dist/helper/streaming/stream.js +22 -31
  282. package/node_modules/hono/dist/helper/streaming/text.js +9 -10
  283. package/node_modules/hono/dist/helper/streaming/utils.js +9 -12
  284. package/node_modules/hono/dist/helper/testing/index.js +16 -10
  285. package/node_modules/hono/dist/helper/websocket/index.js +49 -53
  286. package/node_modules/hono/dist/hono-base.js +344 -378
  287. package/node_modules/hono/dist/hono.js +27 -20
  288. package/node_modules/hono/dist/http-exception.js +53 -33
  289. package/node_modules/hono/dist/index.js +19 -6
  290. package/node_modules/hono/dist/jsx/base.js +233 -328
  291. package/node_modules/hono/dist/jsx/children.js +16 -20
  292. package/node_modules/hono/dist/jsx/components.js +118 -171
  293. package/node_modules/hono/dist/jsx/constants.js +9 -15
  294. package/node_modules/hono/dist/jsx/context.js +153 -150
  295. package/node_modules/hono/dist/jsx/dom/client.js +45 -48
  296. package/node_modules/hono/dist/jsx/dom/components.js +21 -29
  297. package/node_modules/hono/dist/jsx/dom/context.js +37 -44
  298. package/node_modules/hono/dist/jsx/dom/css.js +142 -147
  299. package/node_modules/hono/dist/jsx/dom/hooks/index.js +52 -40
  300. package/node_modules/hono/dist/jsx/dom/index.js +71 -134
  301. package/node_modules/hono/dist/jsx/dom/intrinsic-element/components.js +275 -359
  302. package/node_modules/hono/dist/jsx/dom/jsx-dev-runtime.js +14 -18
  303. package/node_modules/hono/dist/jsx/dom/jsx-runtime.js +2 -8
  304. package/node_modules/hono/dist/jsx/dom/render.js +492 -595
  305. package/node_modules/hono/dist/jsx/dom/server.js +33 -29
  306. package/node_modules/hono/dist/jsx/dom/utils.js +6 -8
  307. package/node_modules/hono/dist/jsx/hooks/index.js +236 -308
  308. package/node_modules/hono/dist/jsx/index.js +45 -98
  309. package/node_modules/hono/dist/jsx/intrinsic-element/common.js +20 -22
  310. package/node_modules/hono/dist/jsx/intrinsic-element/components.js +113 -154
  311. package/node_modules/hono/dist/jsx/intrinsic-elements.js +1 -0
  312. package/node_modules/hono/dist/jsx/jsx-dev-runtime.js +12 -16
  313. package/node_modules/hono/dist/jsx/jsx-runtime.js +29 -42
  314. package/node_modules/hono/dist/jsx/streaming.js +120 -143
  315. package/node_modules/hono/dist/jsx/types.js +1 -0
  316. package/node_modules/hono/dist/jsx/utils.js +105 -168
  317. package/node_modules/hono/dist/middleware/basic-auth/index.js +96 -63
  318. package/node_modules/hono/dist/middleware/bearer-auth/index.js +93 -89
  319. package/node_modules/hono/dist/middleware/body-limit/index.js +66 -51
  320. package/node_modules/hono/dist/middleware/cache/index.js +165 -190
  321. package/node_modules/hono/dist/middleware/combine/index.js +134 -73
  322. package/node_modules/hono/dist/middleware/compress/index.js +75 -69
  323. package/node_modules/hono/dist/middleware/context-storage/index.js +49 -19
  324. package/node_modules/hono/dist/middleware/cors/index.js +107 -86
  325. package/node_modules/hono/dist/middleware/csrf/index.js +103 -53
  326. package/node_modules/hono/dist/middleware/etag/digest.js +59 -77
  327. package/node_modules/hono/dist/middleware/etag/index.js +71 -70
  328. package/node_modules/hono/dist/middleware/ip-restriction/index.js +163 -158
  329. package/node_modules/hono/dist/middleware/jsx-renderer/index.js +97 -54
  330. package/node_modules/hono/dist/middleware/jwk/index.js +1 -4
  331. package/node_modules/hono/dist/middleware/jwk/jwk.js +116 -112
  332. package/node_modules/hono/dist/middleware/jwt/index.js +2 -10
  333. package/node_modules/hono/dist/middleware/jwt/jwt.js +114 -114
  334. package/node_modules/hono/dist/middleware/language/index.js +2 -15
  335. package/node_modules/hono/dist/middleware/language/language.js +180 -154
  336. package/node_modules/hono/dist/middleware/logger/index.js +43 -37
  337. package/node_modules/hono/dist/middleware/method-not-allowed/index.js +81 -66
  338. package/node_modules/hono/dist/middleware/method-override/index.js +101 -81
  339. package/node_modules/hono/dist/middleware/mount/index.js +70 -0
  340. package/node_modules/hono/dist/middleware/powered-by/index.js +23 -9
  341. package/node_modules/hono/dist/middleware/pretty-json/index.js +39 -16
  342. package/node_modules/hono/dist/middleware/request-id/index.js +1 -4
  343. package/node_modules/hono/dist/middleware/request-id/request-id.js +33 -20
  344. package/node_modules/hono/dist/middleware/secure-headers/index.js +1 -5
  345. package/node_modules/hono/dist/middleware/secure-headers/permissions-policy.js +1 -0
  346. package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +144 -155
  347. package/node_modules/hono/dist/middleware/serve-static/index.js +56 -72
  348. package/node_modules/hono/dist/middleware/serve-static/path.js +15 -17
  349. package/node_modules/hono/dist/middleware/timeout/index.js +40 -23
  350. package/node_modules/hono/dist/middleware/timing/index.js +2 -9
  351. package/node_modules/hono/dist/middleware/timing/timing.js +177 -97
  352. package/node_modules/hono/dist/middleware/trailing-slash/index.js +85 -37
  353. package/node_modules/hono/dist/preset/quick.js +17 -15
  354. package/node_modules/hono/dist/preset/tiny.js +14 -11
  355. package/node_modules/hono/dist/request/constants.js +4 -5
  356. package/node_modules/hono/dist/request.js +328 -316
  357. package/node_modules/hono/dist/router/linear-router/index.js +1 -4
  358. package/node_modules/hono/dist/router/linear-router/router.js +93 -120
  359. package/node_modules/hono/dist/router/pattern-router/index.js +1 -4
  360. package/node_modules/hono/dist/router/pattern-router/router.js +39 -40
  361. package/node_modules/hono/dist/router/reg-exp-router/index.js +1 -7
  362. package/node_modules/hono/dist/router/reg-exp-router/matcher.js +17 -23
  363. package/node_modules/hono/dist/router/reg-exp-router/node.js +87 -110
  364. package/node_modules/hono/dist/router/reg-exp-router/prepared-router.js +89 -137
  365. package/node_modules/hono/dist/router/reg-exp-router/router.js +92 -129
  366. package/node_modules/hono/dist/router/reg-exp-router/trie.js +69 -64
  367. package/node_modules/hono/dist/router/smart-router/index.js +1 -4
  368. package/node_modules/hono/dist/router/smart-router/router.js +46 -55
  369. package/node_modules/hono/dist/router/trie-router/index.js +1 -4
  370. package/node_modules/hono/dist/router/trie-router/node.js +131 -162
  371. package/node_modules/hono/dist/router/trie-router/router.js +11 -14
  372. package/node_modules/hono/dist/router/utils.js +4 -5
  373. package/node_modules/hono/dist/router.js +35 -14
  374. package/node_modules/hono/dist/types/adapter/aws-lambda/conninfo.d.ts +4 -1
  375. package/node_modules/hono/dist/types/adapter/aws-lambda/handler.d.ts +150 -104
  376. package/node_modules/hono/dist/types/adapter/aws-lambda/index.d.ts +4 -8
  377. package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +152 -122
  378. package/node_modules/hono/dist/types/adapter/bun/conninfo.d.ts +4 -1
  379. package/node_modules/hono/dist/types/adapter/bun/index.d.ts +6 -10
  380. package/node_modules/hono/dist/types/adapter/bun/serve-static.d.ts +7 -2
  381. package/node_modules/hono/dist/types/adapter/bun/server.d.ts +4 -5
  382. package/node_modules/hono/dist/types/adapter/bun/ssg.d.ts +5 -1
  383. package/node_modules/hono/dist/types/adapter/bun/websocket.d.ts +31 -16
  384. package/node_modules/hono/dist/types/adapter/cloudflare-pages/conninfo.d.ts +4 -1
  385. package/node_modules/hono/dist/types/adapter/cloudflare-pages/handler.d.ts +29 -17
  386. package/node_modules/hono/dist/types/adapter/cloudflare-pages/index.d.ts +3 -7
  387. package/node_modules/hono/dist/types/adapter/cloudflare-workers/conninfo.d.ts +6 -1
  388. package/node_modules/hono/dist/types/adapter/cloudflare-workers/index.d.ts +4 -7
  389. package/node_modules/hono/dist/types/adapter/cloudflare-workers/serve-static-module.d.ts +5 -2
  390. package/node_modules/hono/dist/types/adapter/cloudflare-workers/serve-static.d.ts +10 -5
  391. package/node_modules/hono/dist/types/adapter/cloudflare-workers/utils.d.ts +10 -2
  392. package/node_modules/hono/dist/types/adapter/cloudflare-workers/websocket.d.ts +6 -1
  393. package/node_modules/hono/dist/types/adapter/deno/conninfo.d.ts +4 -1
  394. package/node_modules/hono/dist/types/adapter/deno/deno.d.ts +1 -0
  395. package/node_modules/hono/dist/types/adapter/deno/index.d.ts +5 -8
  396. package/node_modules/hono/dist/types/adapter/deno/serve-static.d.ts +7 -2
  397. package/node_modules/hono/dist/types/adapter/deno/ssg.d.ts +5 -1
  398. package/node_modules/hono/dist/types/adapter/deno/websocket.d.ts +6 -1
  399. package/node_modules/hono/dist/types/adapter/lambda-edge/conninfo.d.ts +6 -1
  400. package/node_modules/hono/dist/types/adapter/lambda-edge/handler.d.ts +83 -57
  401. package/node_modules/hono/dist/types/adapter/lambda-edge/index.d.ts +3 -7
  402. package/node_modules/hono/dist/types/adapter/netlify/conninfo.d.ts +4 -1
  403. package/node_modules/hono/dist/types/adapter/netlify/handler.d.ts +6 -1
  404. package/node_modules/hono/dist/types/adapter/netlify/index.d.ts +3 -5
  405. package/node_modules/hono/dist/types/adapter/netlify/mod.d.ts +3 -2
  406. package/node_modules/hono/dist/types/adapter/service-worker/handler.d.ts +9 -7
  407. package/node_modules/hono/dist/types/adapter/service-worker/index.d.ts +7 -9
  408. package/node_modules/hono/dist/types/adapter/service-worker/types.d.ts +12 -7
  409. package/node_modules/hono/dist/types/adapter/vercel/conninfo.d.ts +6 -1
  410. package/node_modules/hono/dist/types/adapter/vercel/handler.d.ts +6 -1
  411. package/node_modules/hono/dist/types/adapter/vercel/index.d.ts +3 -6
  412. package/node_modules/hono/dist/types/client/client.d.ts +5 -3
  413. package/node_modules/hono/dist/types/client/fetch-result-please.d.ts +21 -19
  414. package/node_modules/hono/dist/types/client/index.d.ts +5 -7
  415. package/node_modules/hono/dist/types/client/types.d.ts +134 -159
  416. package/node_modules/hono/dist/types/client/utils.d.ts +6 -4
  417. package/node_modules/hono/dist/types/compose.d.ts +4 -2
  418. package/node_modules/hono/dist/types/context.d.ts +335 -335
  419. package/node_modules/hono/dist/types/helper/accepts/accepts.d.ts +11 -9
  420. package/node_modules/hono/dist/types/helper/accepts/index.d.ts +2 -5
  421. package/node_modules/hono/dist/types/helper/adapter/index.d.ts +4 -6
  422. package/node_modules/hono/dist/types/helper/conninfo/index.d.ts +2 -5
  423. package/node_modules/hono/dist/types/helper/conninfo/types.d.ts +25 -23
  424. package/node_modules/hono/dist/types/helper/cookie/index.d.ts +10 -12
  425. package/node_modules/hono/dist/types/helper/css/common.d.ts +11 -9
  426. package/node_modules/hono/dist/types/helper/css/index.d.ts +26 -28
  427. package/node_modules/hono/dist/types/helper/dev/index.d.ts +10 -12
  428. package/node_modules/hono/dist/types/helper/factory/index.d.ts +26 -73
  429. package/node_modules/hono/dist/types/helper/html/index.d.ts +4 -7
  430. package/node_modules/hono/dist/types/helper/proxy/index.d.ts +20 -22
  431. package/node_modules/hono/dist/types/helper/route/index.d.ts +6 -4
  432. package/node_modules/hono/dist/types/helper/ssg/index.d.ts +4 -7
  433. package/node_modules/hono/dist/types/helper/ssg/middleware.d.ts +8 -6
  434. package/node_modules/hono/dist/types/helper/ssg/plugins.d.ts +3 -1
  435. package/node_modules/hono/dist/types/helper/ssg/ssg.d.ts +38 -36
  436. package/node_modules/hono/dist/types/helper/ssg/utils.d.ts +5 -3
  437. package/node_modules/hono/dist/types/helper/streaming/index.d.ts +4 -8
  438. package/node_modules/hono/dist/types/helper/streaming/sse.d.ts +10 -8
  439. package/node_modules/hono/dist/types/helper/streaming/stream.d.ts +4 -2
  440. package/node_modules/hono/dist/types/helper/streaming/text.d.ts +4 -2
  441. package/node_modules/hono/dist/types/helper/streaming/utils.d.ts +2 -0
  442. package/node_modules/hono/dist/types/helper/testing/index.d.ts +7 -9
  443. package/node_modules/hono/dist/types/helper/websocket/index.d.ts +30 -33
  444. package/node_modules/hono/dist/types/hono-base.d.ts +210 -210
  445. package/node_modules/hono/dist/types/hono.d.ts +11 -10
  446. package/node_modules/hono/dist/types/http-exception.d.ts +20 -22
  447. package/node_modules/hono/dist/types/index.d.ts +6 -37
  448. package/node_modules/hono/dist/types/jsx/base.d.ts +40 -35
  449. package/node_modules/hono/dist/types/jsx/children.d.ts +8 -6
  450. package/node_modules/hono/dist/types/jsx/components.d.ts +8 -5
  451. package/node_modules/hono/dist/types/jsx/constants.d.ts +2 -0
  452. package/node_modules/hono/dist/types/jsx/context.d.ts +9 -6
  453. package/node_modules/hono/dist/types/jsx/dom/client.d.ts +9 -10
  454. package/node_modules/hono/dist/types/jsx/dom/components.d.ts +9 -6
  455. package/node_modules/hono/dist/types/jsx/dom/context.d.ts +3 -1
  456. package/node_modules/hono/dist/types/jsx/dom/css.d.ts +27 -30
  457. package/node_modules/hono/dist/types/jsx/dom/hooks/index.d.ts +11 -12
  458. package/node_modules/hono/dist/types/jsx/dom/index.d.ts +79 -83
  459. package/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +9 -5
  460. package/node_modules/hono/dist/types/jsx/dom/jsx-dev-runtime.d.ts +4 -6
  461. package/node_modules/hono/dist/types/jsx/dom/jsx-runtime.d.ts +3 -7
  462. package/node_modules/hono/dist/types/jsx/dom/render.d.ts +32 -50
  463. package/node_modules/hono/dist/types/jsx/dom/server.d.ts +87 -85
  464. package/node_modules/hono/dist/types/jsx/dom/utils.d.ts +2 -0
  465. package/node_modules/hono/dist/types/jsx/hooks/index.d.ts +16 -16
  466. package/node_modules/hono/dist/types/jsx/index.d.ts +71 -73
  467. package/node_modules/hono/dist/types/jsx/intrinsic-element/common.d.ts +3 -1
  468. package/node_modules/hono/dist/types/jsx/intrinsic-element/components.d.ts +7 -4
  469. package/node_modules/hono/dist/types/jsx/intrinsic-elements.d.ts +708 -708
  470. package/node_modules/hono/dist/types/jsx/jsx-dev-runtime.d.ts +4 -7
  471. package/node_modules/hono/dist/types/jsx/jsx-runtime.d.ts +7 -10
  472. package/node_modules/hono/dist/types/jsx/streaming.d.ts +9 -10
  473. package/node_modules/hono/dist/types/jsx/types.d.ts +12 -13
  474. package/node_modules/hono/dist/types/jsx/utils.d.ts +2 -0
  475. package/node_modules/hono/dist/types/middleware/basic-auth/index.d.ts +17 -19
  476. package/node_modules/hono/dist/types/middleware/bearer-auth/index.d.ts +46 -48
  477. package/node_modules/hono/dist/types/middleware/body-limit/index.d.ts +6 -8
  478. package/node_modules/hono/dist/types/middleware/cache/index.d.ts +13 -15
  479. package/node_modules/hono/dist/types/middleware/combine/index.d.ts +7 -7
  480. package/node_modules/hono/dist/types/middleware/compress/index.d.ts +9 -10
  481. package/node_modules/hono/dist/types/middleware/context-storage/index.d.ts +4 -6
  482. package/node_modules/hono/dist/types/middleware/cors/index.d.ts +10 -12
  483. package/node_modules/hono/dist/types/middleware/csrf/index.d.ts +6 -8
  484. package/node_modules/hono/dist/types/middleware/etag/digest.d.ts +2 -0
  485. package/node_modules/hono/dist/types/middleware/etag/index.d.ts +6 -8
  486. package/node_modules/hono/dist/types/middleware/ip-restriction/index.d.ts +11 -12
  487. package/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +11 -11
  488. package/node_modules/hono/dist/types/middleware/jwk/index.d.ts +2 -1
  489. package/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +20 -23
  490. package/node_modules/hono/dist/types/middleware/jwt/index.d.ts +7 -6
  491. package/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +28 -30
  492. package/node_modules/hono/dist/types/middleware/language/index.d.ts +6 -5
  493. package/node_modules/hono/dist/types/middleware/language/language.d.ts +42 -44
  494. package/node_modules/hono/dist/types/middleware/logger/index.d.ts +3 -5
  495. package/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +7 -9
  496. package/node_modules/hono/dist/types/middleware/method-override/index.d.ts +14 -16
  497. package/node_modules/hono/dist/types/middleware/mount/index.d.ts +46 -0
  498. package/node_modules/hono/dist/types/middleware/powered-by/index.d.ts +8 -10
  499. package/node_modules/hono/dist/types/middleware/pretty-json/index.d.ts +18 -20
  500. package/node_modules/hono/dist/types/middleware/request-id/index.d.ts +6 -5
  501. package/node_modules/hono/dist/types/middleware/request-id/request-id.d.ts +9 -11
  502. package/node_modules/hono/dist/types/middleware/secure-headers/index.d.ts +6 -6
  503. package/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +2 -0
  504. package/node_modules/hono/dist/types/middleware/secure-headers/secure-headers.d.ts +55 -57
  505. package/node_modules/hono/dist/types/middleware/serve-static/index.d.ts +24 -24
  506. package/node_modules/hono/dist/types/middleware/serve-static/path.d.ts +2 -0
  507. package/node_modules/hono/dist/types/middleware/timeout/index.d.ts +5 -7
  508. package/node_modules/hono/dist/types/middleware/timing/index.d.ts +6 -5
  509. package/node_modules/hono/dist/types/middleware/timing/timing.d.ts +17 -20
  510. package/node_modules/hono/dist/types/middleware/trailing-slash/index.d.ts +35 -37
  511. package/node_modules/hono/dist/types/preset/quick.d.ts +6 -9
  512. package/node_modules/hono/dist/types/preset/tiny.d.ts +6 -9
  513. package/node_modules/hono/dist/types/request/constants.d.ts +2 -0
  514. package/node_modules/hono/dist/types/request.d.ts +288 -286
  515. package/node_modules/hono/dist/types/router/linear-router/index.d.ts +2 -5
  516. package/node_modules/hono/dist/types/router/linear-router/router.d.ts +7 -5
  517. package/node_modules/hono/dist/types/router/pattern-router/index.d.ts +2 -5
  518. package/node_modules/hono/dist/types/router/pattern-router/router.d.ts +7 -5
  519. package/node_modules/hono/dist/types/router/reg-exp-router/index.d.ts +3 -6
  520. package/node_modules/hono/dist/types/router/reg-exp-router/matcher.d.ts +3 -1
  521. package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +6 -4
  522. package/node_modules/hono/dist/types/router/reg-exp-router/prepared-router.d.ts +11 -10
  523. package/node_modules/hono/dist/types/router/reg-exp-router/router.d.ts +10 -9
  524. package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +7 -5
  525. package/node_modules/hono/dist/types/router/smart-router/index.d.ts +2 -5
  526. package/node_modules/hono/dist/types/router/smart-router/router.d.ts +11 -9
  527. package/node_modules/hono/dist/types/router/trie-router/index.d.ts +2 -5
  528. package/node_modules/hono/dist/types/router/trie-router/node.d.ts +6 -4
  529. package/node_modules/hono/dist/types/router/trie-router/router.d.ts +7 -5
  530. package/node_modules/hono/dist/types/router/utils.d.ts +2 -0
  531. package/node_modules/hono/dist/types/router.d.ts +23 -22
  532. package/node_modules/hono/dist/types/types.d.ts +146 -505
  533. package/node_modules/hono/dist/types/utils/accept.d.ts +5 -3
  534. package/node_modules/hono/dist/types/utils/basic-auth.d.ts +4 -2
  535. package/node_modules/hono/dist/types/utils/body.d.ts +46 -50
  536. package/node_modules/hono/dist/types/utils/buffer.d.ts +7 -5
  537. package/node_modules/hono/dist/types/utils/color.d.ts +2 -0
  538. package/node_modules/hono/dist/types/utils/compress.d.ts +2 -0
  539. package/node_modules/hono/dist/types/utils/concurrent.d.ts +6 -4
  540. package/node_modules/hono/dist/types/utils/constants.d.ts +2 -0
  541. package/node_modules/hono/dist/types/utils/cookie.d.ts +20 -18
  542. package/node_modules/hono/dist/types/utils/crypto.d.ts +5 -7
  543. package/node_modules/hono/dist/types/utils/encode.d.ts +2 -0
  544. package/node_modules/hono/dist/types/utils/filepath.d.ts +5 -3
  545. package/node_modules/hono/dist/types/utils/handler.d.ts +2 -0
  546. package/node_modules/hono/dist/types/utils/headers.d.ts +2 -0
  547. package/node_modules/hono/dist/types/utils/html.d.ts +11 -9
  548. package/node_modules/hono/dist/types/utils/http-status.d.ts +2 -0
  549. package/node_modules/hono/dist/types/utils/ipaddr.d.ts +4 -6
  550. package/node_modules/hono/dist/types/utils/jwt/index.d.ts +18 -12
  551. package/node_modules/hono/dist/types/utils/jwt/jwa.d.ts +15 -13
  552. package/node_modules/hono/dist/types/utils/jwt/jws.d.ts +4 -7
  553. package/node_modules/hono/dist/types/utils/jwt/jwt.d.ts +26 -29
  554. package/node_modules/hono/dist/types/utils/jwt/types.d.ts +48 -45
  555. package/node_modules/hono/dist/types/utils/jwt/utf8.d.ts +2 -0
  556. package/node_modules/hono/dist/types/utils/mime.d.ts +60 -57
  557. package/node_modules/hono/dist/types/utils/stream.d.ts +27 -25
  558. package/node_modules/hono/dist/types/utils/types.d.ts +15 -27
  559. package/node_modules/hono/dist/types/utils/url.d.ts +2 -0
  560. package/node_modules/hono/dist/types/validator/index.d.ts +3 -7
  561. package/node_modules/hono/dist/types/validator/utils.d.ts +6 -8
  562. package/node_modules/hono/dist/types/validator/validator.d.ts +11 -9
  563. package/node_modules/hono/dist/types.js +4 -6
  564. package/node_modules/hono/dist/utils/accept.js +185 -215
  565. package/node_modules/hono/dist/utils/basic-auth.js +18 -21
  566. package/node_modules/hono/dist/utils/body.js +87 -92
  567. package/node_modules/hono/dist/utils/buffer.js +44 -71
  568. package/node_modules/hono/dist/utils/color.js +33 -21
  569. package/node_modules/hono/dist/utils/compress.js +11 -5
  570. package/node_modules/hono/dist/utils/concurrent.js +29 -38
  571. package/node_modules/hono/dist/utils/constants.js +7 -5
  572. package/node_modules/hono/dist/utils/cookie.js +114 -163
  573. package/node_modules/hono/dist/utils/crypto.js +30 -40
  574. package/node_modules/hono/dist/utils/encode.js +30 -26
  575. package/node_modules/hono/dist/utils/filepath.js +23 -33
  576. package/node_modules/hono/dist/utils/handler.js +10 -11
  577. package/node_modules/hono/dist/utils/headers.js +1 -0
  578. package/node_modules/hono/dist/utils/html.js +97 -117
  579. package/node_modules/hono/dist/utils/http-status.js +1 -0
  580. package/node_modules/hono/dist/utils/ipaddr.js +227 -279
  581. package/node_modules/hono/dist/utils/jwt/index.js +12 -4
  582. package/node_modules/hono/dist/utils/jwt/jwa.js +24 -20
  583. package/node_modules/hono/dist/utils/jwt/jws.js +115 -174
  584. package/node_modules/hono/dist/utils/jwt/jwt.js +120 -197
  585. package/node_modules/hono/dist/utils/jwt/types.js +79 -95
  586. package/node_modules/hono/dist/utils/jwt/utf8.js +9 -7
  587. package/node_modules/hono/dist/utils/mime.js +74 -79
  588. package/node_modules/hono/dist/utils/stream.js +86 -88
  589. package/node_modules/hono/dist/utils/types.js +1 -0
  590. package/node_modules/hono/dist/utils/url.js +187 -215
  591. package/node_modules/hono/dist/validator/index.js +1 -4
  592. package/node_modules/hono/dist/validator/utils.js +1 -0
  593. package/node_modules/hono/dist/validator/validator.js +61 -83
  594. package/node_modules/hono/package.json +36 -28
  595. package/node_modules/ip-address/README.md +114 -114
  596. package/node_modules/ip-address/dist/common.d.ts +5 -0
  597. package/node_modules/ip-address/dist/common.js +12 -0
  598. package/node_modules/ip-address/dist/common.js.map +1 -1
  599. package/node_modules/ip-address/dist/ipv4.d.ts +10 -3
  600. package/node_modules/ip-address/dist/ipv4.js +27 -5
  601. package/node_modules/ip-address/dist/ipv4.js.map +1 -1
  602. package/node_modules/ip-address/dist/ipv6.d.ts +5 -1
  603. package/node_modules/ip-address/dist/ipv6.js +18 -3
  604. package/node_modules/ip-address/dist/ipv6.js.map +1 -1
  605. package/node_modules/ip-address/package.json +1 -1
  606. package/node_modules/proxy-addr/HISTORY.md +60 -54
  607. package/node_modules/proxy-addr/README.md +1 -1
  608. package/node_modules/proxy-addr/index.js +32 -0
  609. package/node_modules/proxy-addr/package.json +8 -4
  610. package/package.json +1 -1
@@ -5,9 +5,14 @@ const hash = value => createHash('sha256').update(value).digest('hex');
5
5
  const fail = () => { throw Object.assign(new Error('채널 분석 기록을 확인하지 못했습니다. 자동 재제출하지 않습니다.'), { code: 'DURABLE_CHANNEL_JOURNAL_UNAVAILABLE', paidReplayAllowed: false }); };
6
6
  // Immutable files with exclusive creation. No truncation, overwrite, stale-lock
7
7
  // removal, expiry, TTL or ambiguous-write replay; never stores a PAT or media.
8
- export function createChannelFileJournal({ stateDir, authorityFingerprint }) {
8
+ export function createChannelFileJournal({ stateDir, authorityFingerprint, namespace = 'channel-analysis-v1' }) {
9
9
  if (typeof stateDir !== 'string' || !path.isAbsolute(stateDir) || !/^[a-f0-9]{64}$/u.test(authorityFingerprint || '')) fail();
10
- const handles = new WeakMap(), root = path.join(stateDir, 'channel-analysis-v1');
10
+ if (!['channel-analysis-v1', 'voice-recommendation-v1', 'review-plan-v1', 'studio-plan-v1'].includes(namespace)) fail();
11
+ const handles = new WeakMap(), root = path.join(stateDir, namespace);
12
+ const maxEntries = namespace === 'voice-recommendation-v1' ? 4096 : 32;
13
+ // Review output includes full source evidence (16 MiB artifact budget).
14
+ // Keep the original channel/voice bounds; never trim evidence to fit them.
15
+ const maxResultBytes = namespace === 'review-plan-v1' ? 20 * 1024 * 1024 : namespace === 'studio-plan-v1' ? 10 * 1024 * 1024 : namespace === 'voice-recommendation-v1' ? 65536 : 1200000;
11
16
  function directory(dir, create = false, privateOnly = true) {
12
17
  if (create) { try { mkdirSync(dir, { mode: 0o700 }); } catch (e) { if (e.code !== 'EEXIST') fail(); } }
13
18
  const st = lstatSync(dir); if (!st.isDirectory() || st.isSymbolicLink() || st.uid !== process.getuid() || st.mode & (privateOnly ? 0o077 : 0o022)) fail();
@@ -40,14 +45,14 @@ export function createChannelFileJournal({ stateDir, authorityFingerprint }) {
40
45
  async lookup(identity, { assertCurrent }) { assertCurrent(); directory(root); const value = loaded(identity); return value ? envelope(value, assertCurrent) : null; },
41
46
  async claim(identity, { assertCurrent }) { assertCurrent(); directory(root); const existing = loaded(identity); if (existing) return envelope(existing, assertCurrent);
42
47
  // A full journal is recoverable, never silently pruned to make room.
43
- if (readdirSync(root).length >= 32) fail(); const dir = location(identity);
48
+ if (readdirSync(root).length >= maxEntries) fail(); const dir = location(identity);
44
49
  try { mkdirSync(dir, { mode: 0o700 }); } catch (e) { if (e.code !== 'EEXIST') fail(); const raced = loaded(identity); if (!raced) fail(); return envelope(raced, assertCurrent); }
45
- if (readdirSync(root).length > 32) fail();
50
+ if (readdirSync(root).length > maxEntries) fail();
46
51
  const record = { version: 1, ...identity, localSubmissionId: randomUUID(), createdAt: Date.now(), state: 'submitted', jobId: '' };
47
52
  assertCurrent(); exclusive(path.join(dir, 'intent.json'), { authorityFingerprint, record }); assertCurrent(); return envelope({ dir, record }, assertCurrent, true);
48
53
  },
49
54
  async rememberJob(handle, jobId) { const s = state(handle); if (!/^epoch-v2-[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u.test(jobId || '')) fail(); exclusive(path.join(s.dir, 'accepted.json'), { authorityFingerprint, jobId }); s.record = { ...s.record, jobId }; s.check(); },
50
55
  async markResult(handle, { state: status }) { const s = state(handle); if (!s.record.jobId || !['unknown', 'completed', 'failed'].includes(status)) fail(); exclusive(path.join(s.dir, 'terminal.json'), { jobId: s.record.jobId, state: status }); s.check(); },
51
- async persistResult(identity, result, check) { check(); const value = loaded(identity); if (!value || value.record.jobId !== result.backgroundJobId) fail(); exclusive(path.join(value.dir, 'result.json'), result, 1200000); check(); return true; },
56
+ async persistResult(identity, result, check) { check(); const value = loaded(identity); if (!value || value.record.jobId !== result.backgroundJobId) fail(); exclusive(path.join(value.dir, 'result.json'), result, maxResultBytes); check(); return true; },
52
57
  });
53
58
  }
@@ -1,5 +1,5 @@
1
1
  import { captureDurableChannelInput, captureDurableChannelOutput, DURABLE_CHANNEL_CONTRACT_VERSION,
2
- DURABLE_CHANNEL_MODEL, DURABLE_CHANNEL_LIMITS, DURABLE_CHANNEL_TYPES, DURABLE_CHANNEL_OUTPUT_FIELDS, DURABLE_CHANNEL_PATHS } from './durable-channel-contract.mjs';
2
+ DURABLE_CHANNEL_MODEL, durableChannelCapabilityModels, DURABLE_CHANNEL_LIMITS, DURABLE_CHANNEL_TYPES, DURABLE_CHANNEL_OUTPUT_FIELDS, DURABLE_CHANNEL_PATHS } from './durable-channel-contract.mjs';
3
3
 
4
4
  export const durableChannelPath = operation => DURABLE_CHANNEL_PATHS[operation];
5
5
  export const durableChannelCapabilityPath = operation => `${durableChannelPath(operation)}/execution-capability`;
@@ -85,7 +85,7 @@ export function validateDurableChannelCapability(value, operation) {
85
85
  const captured = object(value);
86
86
  if (captured.version !== 1 || captured.contractVersion !== DURABLE_CHANNEL_CONTRACT_VERSION || captured.operation !== operation
87
87
  || !['legacy-sync', 'queue-v2', 'unavailable'].includes(captured.mode)) fail('RESPONSE_INVALID');
88
- exactConstants(captured.model, DURABLE_CHANNEL_MODEL); exactConstants(captured.limits, DURABLE_CHANNEL_LIMITS);
88
+ exactConstants(captured.model, durableChannelCapabilityModels(operation)); exactConstants(captured.limits, DURABLE_CHANNEL_LIMITS);
89
89
  const allowed = ['version', 'contractVersion', 'operation', 'mode', 'model', 'limits', ...(captured.mode === 'queue-v2'
90
90
  ? ['paidReplayAllowed', 'recovery'] : captured.mode === 'unavailable' ? ['reason'] : [])];
91
91
  if (Object.keys(captured).some(key => !allowed.includes(key)) || captured.mode === 'queue-v2'
@@ -116,8 +116,8 @@ export function validateCompletedDurableChannelJob(value, id) {
116
116
  || !Array.isArray(result.accountCostEvents) || result.accountCostEvents.length > DURABLE_CHANNEL_LIMITS.maxStages) fail('RESPONSE_INVALID');
117
117
  const count = result.accountCostEvents.length;
118
118
  if (result.operation === 'channel-style' && (count < 1 || count > 2)
119
- || count > 0 && result.provider !== 'evolink'
120
- || (count ? result.provider !== 'evolink' : result.provider !== 'none')) fail('RESPONSE_INVALID');
119
+ || result.operation === 'voice-recommend' && (count > 2 || count === 0 && (!['edge', 'supertonic2'].includes(result.voiceRecommendation?.ttsProvider) || result.voiceRecommendation?.sampleVoiceProfile !== null))
120
+ || (count ? !(result.operation === 'voice-recommend' ? ['evolink', 'kie'] : ['evolink']).includes(result.provider) : result.provider !== 'none')) fail('RESPONSE_INVALID');
121
121
  let output; try { output = captureDurableChannelOutput(Object.fromEntries(DURABLE_CHANNEL_OUTPUT_FIELDS
122
122
  .filter(key => result[key] !== undefined).map(key => [key, result[key]]))); } catch { fail('RESPONSE_INVALID'); }
123
123
  const ids = new Set();
@@ -0,0 +1,88 @@
1
+ // Native cut/review planning only; media analysis, TTS and rendering are separate.
2
+ import { normalizeReviewProductionInput, validateReviewProductionPlan } from './review-production-contract.mjs';
3
+ export const DURABLE_REMAKE_CONTRACT_VERSION = 1;
4
+ export const DURABLE_REMAKE_PATHS = Object.freeze({ 'remake-versions': '/api/tracker/gemini/remake-versions', 'review-plan': '/api/tracker/review/plan' });
5
+ export const DURABLE_REMAKE_TYPES = Object.freeze({ 'remake-versions': 'durable-remake:versions', 'review-plan': 'durable-remake:review-plan' });
6
+ export const DURABLE_REMAKE_MODEL = Object.freeze({ 'remake-versions': 'gemini-3-flash', 'review-plan': 'gemini-3.8-flash' });
7
+ const legacyModels = Object.freeze({ 'remake-versions': 'gemini-3-flash' });
8
+ // Already-installed remake clients compare the complete capability map.
9
+ export const durableRemakeCapabilityModels = operation => operation === 'remake-versions' ? legacyModels : DURABLE_REMAKE_MODEL;
10
+ export const DURABLE_REMAKE_LIMITS = Object.freeze({ maxInputBytes: 25 * 1024 * 1024, maxOutputBytes: 16 * 1024 * 1024, maxProjectId: 160, maxTargetId: 240, maxStages: 66 });
11
+ export const DURABLE_REMAKE_OUTPUT_FIELDS = Object.freeze(['operation','projectId','targetId','analysisId','inputKey','presetId','preserveOrder','rerollCount','targetTime','versionCount','promptFrameworks','summaryBody','summaryHeadline','sourceVideos','versions','reviewPlan']);
12
+ const inputFields = ['operation','projectId','targetId','analysisId','inputKey','analysis','presetId','preserveOrder','rerollCount','targetTime','versionCount'];
13
+ const presets = ['tikitaka','snack','recap','deep','shopping','tts','tutorial','highlight','cinema'];
14
+ const invalid = output => Object.assign(new Error(`DURABLE_REMAKE_${output ? 'OUTPUT' : 'INPUT'}_INVALID`), { code: `DURABLE_REMAKE_${output ? 'OUTPUT' : 'INPUT'}_INVALID`, statusCode: output ? 502 : 400 });
15
+ function reject() { throw invalid(false); }
16
+ function clone(value, state, depth = 0) {
17
+ if (++state.nodes > 1_500_000 || depth > 40) reject();
18
+ if (value === null || typeof value === 'boolean') return value;
19
+ if (typeof value === 'number') { if (!Number.isFinite(value)) reject(); return value; }
20
+ if (typeof value === 'string') { if (!value.isWellFormed() || /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/u.test(value)) reject(); return value; }
21
+ if (!value || typeof value !== 'object' || state.seen.has(value)) reject();
22
+ state.seen.add(value); const d = Object.getOwnPropertyDescriptors(value); let out;
23
+ if (Array.isArray(value)) {
24
+ const n = d.length.value;
25
+ if (Object.getPrototypeOf(value) !== Array.prototype || n > 100000 || Reflect.ownKeys(d).length !== n + 1) reject();
26
+ out = Array.from({ length: n }, (_, i) => { if (!d[i]?.enumerable || !('value' in d[i])) reject(); return clone(d[i].value, state, depth + 1); });
27
+ } else {
28
+ if (![Object.prototype, null].includes(Object.getPrototypeOf(value)) || Reflect.ownKeys(d).some(k => typeof k !== 'string' || ['__proto__','constructor','prototype'].includes(k) || !d[k].enumerable || !('value' in d[k]))) reject();
29
+ out = Object.fromEntries(Object.entries(d).map(([key, field]) => [key, clone(field.value, state, depth + 1)]));
30
+ }
31
+ state.seen.delete(value); return Object.freeze(out);
32
+ }
33
+ function capture(value, fields, maxBytes) {
34
+ const body = clone(value, { nodes: 0, seen: new WeakSet() });
35
+ if (!body || Array.isArray(body) || typeof body !== 'object' || Object.keys(body).some(k => !fields.includes(k)) || new TextEncoder().encode(JSON.stringify(body)).byteLength > maxBytes) reject();
36
+ return body;
37
+ }
38
+ function text(value, limit, empty = false) { if (typeof value !== 'string' || value.length > limit || !empty && !value.trim()) reject(); }
39
+ function identity(body) {
40
+ if (!Object.hasOwn(DURABLE_REMAKE_TYPES, body.operation)) reject();
41
+ for (const [key, limit] of [['projectId',160],['targetId',240], ...(body.operation === 'review-plan' ? [] : [['analysisId',240],['inputKey',4096]])]) {
42
+ text(body[key], limit); if (body[key].trim() !== body[key] || /[\u0000-\u001f\u007f]/u.test(body[key])) reject();
43
+ }
44
+ if (body.operation === 'review-plan') return;
45
+ if (!presets.includes(body.presetId) || typeof body.preserveOrder !== 'boolean' || !Number.isSafeInteger(body.rerollCount) || body.rerollCount < 0 || body.rerollCount > 1e6) reject();
46
+ text(body.targetTime, 32); text(body.versionCount, 16);
47
+ if (!/^(?:original|[1-9][0-9]{0,4}(?:s|m)?)$/u.test(body.targetTime) || !/^(?:[1-9]|10)(?:개)?$/u.test(body.versionCount)) reject();
48
+ }
49
+ export function captureDurableRemakeInput(value) {
50
+ const body = capture(value, [...inputFields, 'reviewInput'], DURABLE_REMAKE_LIMITS.maxInputBytes); identity(body);
51
+ if (body.operation === 'review-plan') {
52
+ if (Object.keys(body).some(key => !['operation','projectId','targetId','reviewInput'].includes(key)) || !body.reviewInput
53
+ || Object.keys(body.reviewInput).some(key => !['version','workType','workTitle','episode','targetDurationSec','spoilerPolicy','deliveryStyle','reviewAngle','sourceCatalog','globalStory','fullTranscriptSegments'].includes(key))) reject();
54
+ normalizeReviewProductionInput(body.reviewInput);
55
+ return Object.freeze({ body, jobType: DURABLE_REMAKE_TYPES[body.operation] });
56
+ }
57
+ if (Object.hasOwn(body, 'reviewInput')) reject();
58
+ if (!body.analysis || !Array.isArray(body.analysis.videos) || !body.analysis.videos.length || body.analysis.videos.length > 5) reject();
59
+ return Object.freeze({ body, jobType: DURABLE_REMAKE_TYPES[body.operation] });
60
+ }
61
+ export function captureDurableRemakeOutput(value) {
62
+ try {
63
+ const out = capture(value, DURABLE_REMAKE_OUTPUT_FIELDS, DURABLE_REMAKE_LIMITS.maxOutputBytes); identity(out);
64
+ if (out.operation === 'review-plan') {
65
+ if (Object.keys(out).some(key => !['operation','projectId','targetId','reviewPlan'].includes(key)) || !out.reviewPlan) reject();
66
+ const plan = out.reviewPlan;
67
+ const normalized = validateReviewProductionPlan({ ...plan.reviewProfile, sourceCatalog: plan.sourceCatalog,
68
+ ...(plan.globalStory === undefined ? {} : { globalStory: plan.globalStory, fullTranscriptSegments: plan.fullTranscriptSegments }) }, plan.version);
69
+ // Closed, canonical result: no provider-injected identity, file, URL or
70
+ // hidden result fields. Validation is shared with the original service.
71
+ const canonical = item => JSON.stringify(item, (_key, child) => child && !Array.isArray(child) && typeof child === 'object'
72
+ ? Object.fromEntries(Object.keys(child).sort().map(key => [key, child[key]])) : child);
73
+ if (canonical(plan) !== canonical(normalized)) reject();
74
+ return out;
75
+ }
76
+ if (Object.hasOwn(out, 'reviewPlan')) reject();
77
+ if (!Array.isArray(out.sourceVideos) || !out.sourceVideos.length || out.sourceVideos.length > 5 || !Array.isArray(out.versions) || !out.versions.length || out.versions.length > 10
78
+ || !Array.isArray(out.promptFrameworks) || out.promptFrameworks.length !== 2 || out.promptFrameworks[0] !== '티키타카 편집점' || out.promptFrameworks[1] !== '바이럴 마스터 PD') reject();
79
+ text(out.summaryBody, 64000, true); text(out.summaryHeadline, 16000, true);
80
+ const ids = new Set();
81
+ for (const version of out.versions) {
82
+ text(version.id, 240); if (ids.has(version.id) || Object.hasOwn(version, 'sourceVideos') || !Array.isArray(version.rows) || version.rows.length > 1000) reject();
83
+ ids.add(version.id);
84
+ for (const row of version.rows) if (!['N','S','A','SN'].includes(row.mode) || !Number.isFinite(row.durationSec) || row.durationSec <= 0 || !Array.isArray(row.clipRefs)) reject();
85
+ }
86
+ return out;
87
+ } catch { throw invalid(true); }
88
+ }
@@ -0,0 +1,375 @@
1
+ import { captureDurableRemakeInput, captureDurableRemakeOutput, DURABLE_REMAKE_CONTRACT_VERSION,
2
+ DURABLE_REMAKE_MODEL, DURABLE_REMAKE_LIMITS, DURABLE_REMAKE_TYPES, DURABLE_REMAKE_OUTPUT_FIELDS, DURABLE_REMAKE_PATHS, durableRemakeCapabilityModels } from './durable-remake-contract.mjs';
3
+
4
+ export const durableRemakePath = operation => DURABLE_REMAKE_PATHS[operation];
5
+ export const durableRemakeCapabilityPath = operation => `${durableRemakePath(operation)}/execution-capability`;
6
+ export const DURABLE_REMAKE_REQUEST_LIMITS = Object.freeze({ maxResponseBytes: DURABLE_REMAKE_LIMITS.maxOutputBytes + 262144, maxReadChunks: 65536 });
7
+ const JOB = /^epoch-v2-[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u;
8
+ const COST = /^bg-durable-remake-v1:[a-f0-9]{64}:(?:[1-9]|[1-5][0-9]|6[0-6])$/u;
9
+ const encoder = new TextEncoder(), failures = new WeakMap();
10
+ const messages = Object.freeze({
11
+ INVALID: '리뷰 기획 요청을 안전하게 확인하지 못했습니다.',
12
+ AUTHORITY_CHANGED: '계정·프로젝트·입력이 변경되어 이전 리뷰 기획 작업을 중단했습니다.',
13
+ SESSION_REQUIRED: '로그인 후 리뷰 기획를 생성해 주세요.',
14
+ UNAVAILABLE: '현재 서버에서는 안전한 리뷰 기획 생성을 사용할 수 없습니다.',
15
+ RESPONSE_INVALID: '리뷰 기획 응답을 안전하게 확인하지 못했습니다. 자동 재생성하지 않습니다.',
16
+ JOURNAL_UNAVAILABLE: '제출 기록을 확인하지 못했습니다. 자동 재생성하지 않습니다.',
17
+ JOURNAL_FULL: '안전한 제출 기록 한도(계정당 32건)에 도달했습니다. 기존 작업 조회는 가능하지만 새 생성은 차단됩니다. 기록을 삭제하지 말고 고객지원에 문의해 주세요.',
18
+ UNRESOLVED: '이전 제출 결과가 확정되지 않았습니다. 자동 재생성하지 않습니다.',
19
+ MISSING: '이전 작업을 찾을 수 없습니다. 새 생성 요청을 보내지 않았습니다.',
20
+ WAIT_ABORTED: '기다리기를 중단했습니다. 생성 취소가 확인된 것은 아닙니다.',
21
+ WAIT_TIMEOUT: '대기 시간이 초과되었습니다. 기존 작업만 다시 조회할 수 있습니다.',
22
+ DIFFERENT_EDITOR: '이 프로젝트에 다른 제작 화면의 미확정 작업이 있습니다. 원래 화면에서 먼저 기존 작업을 조회해 주세요.',
23
+ APPLY_UNCONFIRMED: '작업 결과는 완료됐지만 프로젝트 저장을 확인하지 못했습니다. 다음에 기존 작업만 다시 조회합니다.',
24
+ STORAGE_BUDGET: '리메이크 결과 저장 한도(결과당 20 MiB·계정 전체 48 MiB)에 도달했습니다. 기존 결과와 제출 기록은 보존하며 자동 재생성하지 않습니다. 고객지원에 문의해 주세요.',
25
+ ACTIVE: '리뷰 기획 작업이 이미 진행 중입니다.',
26
+ });
27
+ function failure(kind) {
28
+ const error = Object.assign(new Error(messages[kind] || messages.INVALID), {
29
+ code: `DURABLE_REMAKE_${kind}`, paidReplayAllowed: false,
30
+ }); failures.set(error, kind); return error;
31
+ }
32
+ const fail = kind => { throw failure(kind); };
33
+ const own = (value, key) => value && typeof value === 'object' ? Object.getOwnPropertyDescriptor(value, key)?.value : undefined;
34
+ // Legacy transport already projects usage; copy only its bounded public fields.
35
+ // Never copy an error message, request, headers, arbitrary object or credential.
36
+ function legacyUsage(value, depth = 0) {
37
+ if (!value || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) return undefined;
38
+ const output = {};
39
+ for (const key of ['aiCalls', 'costUsd', 'inputTokens', 'outputTokens', 'totalTokens', 'credits', 'creditsConsumed']) {
40
+ const number = own(value, key);
41
+ if (typeof number === 'number' && Number.isFinite(number) && number >= 0 && number <= Number.MAX_SAFE_INTEGER) output[key] = number;
42
+ }
43
+ for (const key of ['model', 'provider', 'stage']) {
44
+ const item = own(value, key); if (text(item, 160)) output[key] = item;
45
+ }
46
+ const stages = own(value, 'stages');
47
+ if (depth === 0 && Array.isArray(stages) && stages.length > 0 && stages.length <= 66) {
48
+ output.stages = Array.from({ length: stages.length }, (_, i) => legacyUsage(own(stages, String(i)), 1)).filter(Boolean);
49
+ if (!output.stages.length) delete output.stages;
50
+ }
51
+ return Object.keys(output).length ? Object.freeze(output) : undefined;
52
+ }
53
+ function object(value) {
54
+ if (!value || typeof value !== 'object' || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) fail('RESPONSE_INVALID');
55
+ const descriptors = Object.getOwnPropertyDescriptors(value);
56
+ if (Reflect.ownKeys(descriptors).some(key => typeof key !== 'string' || !('value' in descriptors[key]) || !descriptors[key].enumerable)) fail('RESPONSE_INVALID');
57
+ return Object.fromEntries(Object.entries(descriptors).map(([key, item]) => [key, item.value]));
58
+ }
59
+ function text(value, maximum = 255) {
60
+ return typeof value === 'string' && value.length > 0 && value.length <= maximum && value.trim() === value
61
+ && value.isWellFormed() && !/[\u0000-\u001f\u007f]/u.test(value);
62
+ }
63
+ function origin(value) {
64
+ if (!text(value, 2048)) fail('INVALID');
65
+ let url; try { url = new URL(value); } catch { fail('INVALID'); }
66
+ if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash || url.pathname !== '/'
67
+ || ![url.origin, `${url.origin}/`].includes(value)) fail('INVALID');
68
+ return url.origin;
69
+ }
70
+ function authority(getAuthority) {
71
+ const value = getAuthority(), ownerUserId = own(value, 'ownerUserId'), sessionRevision = own(value, 'sessionRevision');
72
+ if (!text(ownerUserId) || ownerUserId.startsWith('deleted:')
73
+ || !(text(sessionRevision, 512) || Number.isSafeInteger(sessionRevision) && sessionRevision >= 0)) fail('SESSION_REQUIRED');
74
+ return Object.freeze({ ownerUserId, sessionRevision });
75
+ }
76
+ function synchronous(callback) {
77
+ const result = callback();
78
+ if (result && typeof result.then === 'function') { Promise.resolve(result).catch(() => {}); fail('AUTHORITY_CHANGED'); }
79
+ if (result === false) fail('AUTHORITY_CHANGED');
80
+ }
81
+ function exactConstants(value, expected) {
82
+ const captured = object(value), keys = Object.keys(expected);
83
+ if (Object.keys(captured).length !== keys.length || keys.some(key => captured[key] !== expected[key])) fail('RESPONSE_INVALID');
84
+ }
85
+ export function validateDurableRemakeCapability(value, operation) {
86
+ const captured = object(value);
87
+ if (captured.version !== 1 || captured.contractVersion !== DURABLE_REMAKE_CONTRACT_VERSION || captured.operation !== operation
88
+ || !['legacy-sync', 'queue-v2', 'unavailable'].includes(captured.mode)) fail('RESPONSE_INVALID');
89
+ exactConstants(captured.model, durableRemakeCapabilityModels(operation)); exactConstants(captured.limits, DURABLE_REMAKE_LIMITS);
90
+ const allowed = ['version', 'contractVersion', 'operation', 'mode', 'model', 'limits', ...(captured.mode === 'queue-v2'
91
+ ? ['paidReplayAllowed', 'recovery'] : captured.mode === 'unavailable' ? ['reason'] : [])];
92
+ if (Object.keys(captured).some(key => !allowed.includes(key)) || captured.mode === 'queue-v2'
93
+ && (captured.paidReplayAllowed !== false || captured.recovery !== 'read-only-known-job')
94
+ || captured.reason !== undefined && !text(captured.reason, 128)) fail('RESPONSE_INVALID');
95
+ return captured.mode;
96
+ }
97
+ function captureUsage(value, provider, model, { total = false } = {}) {
98
+ const item = object(value);
99
+ if (item.aiCalls !== 1 || !Number.isSafeInteger(item.inputTokens) || item.inputTokens < 0
100
+ || !Number.isSafeInteger(item.outputTokens) || item.outputTokens < 0
101
+ || !Number.isSafeInteger(item.inputTokens + item.outputTokens)
102
+ || typeof item.costUsd !== 'number' || !Number.isFinite(item.costUsd) || item.costUsd < 0
103
+ || item.model !== undefined && item.model !== model
104
+ || item.provider !== undefined && item.provider !== provider
105
+ || (total || item.totalTokens !== undefined) && item.totalTokens !== item.inputTokens + item.outputTokens) fail('RESPONSE_INVALID');
106
+ return Object.freeze({ aiCalls: 1, inputTokens: item.inputTokens, outputTokens: item.outputTokens, costUsd: item.costUsd,
107
+ ...(item.totalTokens === undefined ? {} : { totalTokens: item.totalTokens }),
108
+ ...(item.model === undefined ? {} : { model: item.model }), ...(item.provider === undefined ? {} : { provider: item.provider }) });
109
+ }
110
+ export function validateCompletedDurableRemakeJob(value, id) {
111
+ const job = object(value);
112
+ if (!JOB.test(id) || job.id !== id || !Object.values(DURABLE_REMAKE_TYPES).includes(job.type) || job.status !== 'completed') fail('RESPONSE_INVALID');
113
+ const result = object(job.result), model = DURABLE_REMAKE_MODEL[result.operation];
114
+ if (DURABLE_REMAKE_TYPES[result.operation] !== job.type || result.kind !== 'durable-remake-v2'
115
+ || result.model !== model
116
+ || result.accountingState !== 'settled' || result.hasAccountCostEvents !== true
117
+ || !Array.isArray(result.accountCostEvents) || result.accountCostEvents.length > DURABLE_REMAKE_LIMITS.maxStages) fail('RESPONSE_INVALID');
118
+ const count = result.accountCostEvents.length;
119
+ if (result.operation === 'review-plan' && count !== 1) fail('RESPONSE_INVALID');
120
+ if (count < 1 || count > 66 || !['evolink','kie'].includes(result.provider)) fail('RESPONSE_INVALID');
121
+ let output; try { output = captureDurableRemakeOutput(Object.fromEntries(DURABLE_REMAKE_OUTPUT_FIELDS
122
+ .filter(key => result[key] !== undefined).map(key => [key, result[key]]))); } catch { fail('RESPONSE_INVALID'); }
123
+ const ids = new Set();
124
+ const receipts = result.accountCostEvents.map(raw => {
125
+ const event = object(raw), provider = event.provider;
126
+ const committed = event.accountCostRecorded === true && event.accountCostSuppressedByReset !== true;
127
+ const suppressed = event.accountCostRecorded === false && event.accountCostSuppressedByReset === true;
128
+ if (!COST.test(event.accountCostEventId || '') || ids.has(event.accountCostEventId) || !(committed || suppressed)
129
+ || event.accountCostSuppressedByReset !== undefined && typeof event.accountCostSuppressedByReset !== 'boolean'
130
+ || event.model !== model || provider !== result.provider || !Number.isSafeInteger(event.createdAt)
131
+ || event.createdAt <= 0 || event.createdAt > 253402300799999 || typeof event.costUsd !== 'number'
132
+ || !Number.isFinite(event.costUsd) || event.costUsd < 0) fail('RESPONSE_INVALID');
133
+ ids.add(event.accountCostEventId);
134
+ const usage = captureUsage(event.usage, provider, model);
135
+ if (usage.costUsd !== event.costUsd) fail('RESPONSE_INVALID');
136
+ return Object.freeze({ accountCostEventId: event.accountCostEventId, createdAt: event.createdAt,
137
+ provider, model, costUsd: event.costUsd, accountCostRecorded: committed,
138
+ ...(suppressed ? { accountCostSuppressedByReset: true } : {}), usage });
139
+ });
140
+ const total = object(result.usage), sum = key => receipts.reduce((n, item) => n + item.usage[key], 0);
141
+ if (total.aiCalls !== receipts.length || total.inputTokens !== sum('inputTokens') || total.outputTokens !== sum('outputTokens')
142
+ || total.totalTokens !== total.inputTokens + total.outputTokens || !Number.isSafeInteger(total.totalTokens)
143
+ || typeof total.costUsd !== 'number' || !Number.isFinite(total.costUsd) || total.costUsd < 0
144
+ || Math.abs(total.costUsd - sum('costUsd')) > 0.000001) fail('RESPONSE_INVALID');
145
+ const usage = Object.freeze({ aiCalls: total.aiCalls, inputTokens: total.inputTokens, outputTokens: total.outputTokens,
146
+ totalTokens: total.totalTokens, costUsd: total.costUsd });
147
+ return Object.freeze({ ...output, ok: true, kind: 'durable-remake-v2', model, provider: result.provider, usage, hasAccountCostEvents: true,
148
+ accountingState: 'settled', accountCostEvents: Object.freeze(receipts), backgroundJobId: id });
149
+ }
150
+
151
+ // Strict stream EOF, fatal UTF-8 and declared-byte checks. Abort starts reader
152
+ // cancellation immediately, but does not detach an admitted read/cancel promise.
153
+ async function readJson(response, { check, signal, url }) {
154
+ let reader, cancellation, complete = false;
155
+ const cancel = () => {
156
+ if (cancellation || complete) return;
157
+ try { cancellation = Promise.resolve(reader ? reader.cancel() : response?.body?.cancel()).catch(() => {}); }
158
+ catch { cancellation = Promise.resolve(); }
159
+ };
160
+ const abort = () => cancel();
161
+ try {
162
+ check();
163
+ if (!response || response.redirected || response.type === 'opaqueredirect' || response.type === 'opaque'
164
+ || response.url && response.url !== url
165
+ || !Number.isInteger(response.status) || typeof response.body?.getReader !== 'function') fail('RESPONSE_INVALID');
166
+ const mime = (response.headers.get('content-type') || '').split(';', 1)[0].trim().toLowerCase();
167
+ if (mime !== 'application/json') fail('RESPONSE_INVALID');
168
+ const length = response.headers.get('content-length'), encoding = response.headers.get('content-encoding');
169
+ if (length !== null && (!/^(0|[1-9][0-9]*)$/u.test(length) || !Number.isSafeInteger(Number(length))
170
+ || Number(length) > DURABLE_REMAKE_REQUEST_LIMITS.maxResponseBytes)) fail('RESPONSE_INVALID');
171
+ reader = response.body.getReader(); signal.addEventListener('abort', abort, { once: true });
172
+ if (signal.aborted) { cancel(); check(); }
173
+ const decoder = new TextDecoder('utf-8', { fatal: true }), blocks = []; let bytes = 0, chunks = 0;
174
+ for (;;) {
175
+ check(); const part = await reader.read(); check();
176
+ if (part.done) break;
177
+ if (!(part.value instanceof Uint8Array) || ++chunks > DURABLE_REMAKE_REQUEST_LIMITS.maxReadChunks
178
+ || (bytes += part.value.byteLength) > DURABLE_REMAKE_REQUEST_LIMITS.maxResponseBytes) fail('RESPONSE_INVALID');
179
+ blocks.push(decoder.decode(part.value, { stream: true }));
180
+ }
181
+ if (!bytes || length !== null && (!encoding || encoding === 'identity') && Number(length) !== bytes) fail('RESPONSE_INVALID');
182
+ blocks.push(decoder.decode()); const value = JSON.parse(blocks.join('')); check(); complete = true;
183
+ return { status: response.status, body: value };
184
+ } catch (error) { cancel(); throw failures.has(error) ? error : failure('RESPONSE_INVALID'); }
185
+ finally { signal.removeEventListener('abort', abort); await cancellation; reader?.releaseLock(); }
186
+ }
187
+
188
+ /** A journal intent is consumed before the one paid POST. Restored intentions
189
+ * with an ID can only GET it; no ID, a missing job, failure or mode downgrade
190
+ * never permits another POST or the legacy callback. Browser storage loss is
191
+ * not server-side idempotency; this API offers no reset/new-intent escape. */
192
+ export function createDurableRemakeRequest({ journal, apiOrigin, fetchImpl = globalThis.fetch, getAuthority,
193
+ getHeaders, ensureSession, crypto = globalThis.crypto, pollMs = 1000, timeoutMs = 240000 } = {}) {
194
+ const base = origin(apiOrigin), digest = typeof crypto?.subtle?.digest === 'function' ? crypto.subtle.digest.bind(crypto.subtle) : null;
195
+ if ([fetchImpl, getAuthority, getHeaders, ensureSession, ...['lookup', 'claim', 'rememberJob', 'markResult'].map(key => journal?.[key])]
196
+ .some(fn => typeof fn !== 'function') || !digest || !Number.isSafeInteger(pollMs) || pollMs < 1 || pollMs > 10000
197
+ || !Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 900000) throw failure('INVALID');
198
+ const storage = Object.fromEntries(['lookup', 'claim', 'rememberJob', 'markResult'].map(key => [key, journal[key].bind(journal)]));
199
+ let active = false;
200
+ return Object.freeze({ async readCapability({ operation, assertCurrent, signal, assertQueueReady } = {}) {
201
+ if (!Object.hasOwn(DURABLE_REMAKE_TYPES, operation) || typeof assertCurrent !== 'function'
202
+ || signal !== undefined && !(signal instanceof AbortSignal)) fail('INVALID');
203
+ const captured = authority(getAuthority), controller = new AbortController();
204
+ const abort = () => controller.abort(failure('WAIT_ABORTED'));
205
+ const timer = setTimeout(() => controller.abort(failure('WAIT_TIMEOUT')), Math.min(timeoutMs, 15000));
206
+ signal?.addEventListener('abort', abort, { once: true }); if (signal?.aborted) abort();
207
+ const check = () => { const current = authority(getAuthority); synchronous(assertCurrent);
208
+ if (current.ownerUserId !== captured.ownerUserId || current.sessionRevision !== captured.sessionRevision) fail('AUTHORITY_CHANGED');
209
+ if (controller.signal.aborted) throw controller.signal.reason;
210
+ };
211
+ try {
212
+ check(); if (await ensureSession() === false) fail('SESSION_REQUIRED'); check();
213
+ const headers = new Headers(await getHeaders()); headers.set('Accept', 'application/json'); check();
214
+ const url = `${base}${durableRemakeCapabilityPath(operation)}`;
215
+ const response = await fetchImpl(url, { method: 'GET', headers, credentials: 'include', redirect: 'error', cache: 'no-store', signal: controller.signal });
216
+ const reply = await readJson(response, { check, signal: controller.signal, url }); check();
217
+ if (reply.status !== 200) fail('UNAVAILABLE');
218
+ const mode = validateDurableRemakeCapability(reply.body, operation);
219
+ if (mode === 'unavailable') fail('UNAVAILABLE');
220
+ if (mode === 'queue-v2') {
221
+ if (typeof assertQueueReady !== 'function' || await assertQueueReady() !== true) fail('INVALID'); check();
222
+ }
223
+ return mode;
224
+ } catch (caught) { if (own(caught, 'code') === 'DURABLE_REMAKE_STORAGE_BUDGET_EXCEEDED') fail('STORAGE_BUDGET'); throw failures.has(caught) ? caught : failure('RESPONSE_INVALID'); }
225
+ finally { clearTimeout(timer); signal?.removeEventListener('abort', abort); }
226
+ }, async run(rawBody, { projectId, assertCurrent, signal, onState = () => {}, onAccountCost = () => {}, legacy,
227
+ recoveryOnly = false, operation, targetId, applyResult, assertQueueReady } = {}) {
228
+ if (active) throw failure('ACTIVE');
229
+ if (!Object.hasOwn(DURABLE_REMAKE_TYPES, operation) || !text(targetId, 240) || !text(projectId, 160) || [assertCurrent, onState, onAccountCost].some(fn => typeof fn !== 'function')
230
+ || signal !== undefined && !(signal instanceof AbortSignal) || typeof recoveryOnly !== 'boolean') throw failure('INVALID');
231
+ let body;
232
+ // Legacy accepts its original inputs, which may exceed the new queue's
233
+ // bounded contract. Defer only this v2 validation error until transport
234
+ // selection; even invalid edited inputs must first recover pending work.
235
+ if (!recoveryOnly) { try { body = captureDurableRemakeInput(rawBody).body; if (body.operation !== operation || body.targetId !== targetId || body.projectId !== projectId) body = undefined; } catch { body = undefined; } }
236
+ const captured = authority(getAuthority); active = true;
237
+ const controller = new AbortController(), deadline = performance.now() + timeoutMs;
238
+ const abort = () => controller.abort(failure('WAIT_ABORTED'));
239
+ const timer = setTimeout(() => controller.abort(failure('WAIT_TIMEOUT')), timeoutMs);
240
+ signal?.addEventListener('abort', abort, { once: true }); if (signal?.aborted) abort();
241
+ let jobId = null, status = 'checking', handle, claimStarted = false, legacyStarted = false, recovering = false;
242
+ const check = () => {
243
+ let current; try { current = authority(getAuthority); synchronous(assertCurrent); } catch { fail('AUTHORITY_CHANGED'); }
244
+ if (current.ownerUserId !== captured.ownerUserId || current.sessionRevision !== captured.sessionRevision) fail('AUTHORITY_CHANGED');
245
+ if (!controller.signal.aborted && performance.now() >= deadline) controller.abort(failure('WAIT_TIMEOUT'));
246
+ if (controller.signal.aborted) throw controller.signal.reason;
247
+ };
248
+ const checked = async operation => { check(); const value = await operation(); check(); return value; };
249
+ const publish = next => { check(); status = next; try { Promise.resolve(onState(Object.freeze({ version: 1, status,
250
+ jobId, recovering, paidReplayAllowed: false }))).catch(() => {}); } catch { /* UI cannot authorize a replay. */ } };
251
+ const persist = async operation => { try { return await checked(operation); } catch (error) {
252
+ check(); throw failures.has(error) ? error : failure(own(error, 'code') === 'UPLOAD_METADATA_JOURNAL_FULL' ? 'JOURNAL_FULL' : 'JOURNAL_UNAVAILABLE');
253
+ } };
254
+ async function request(path, method = 'GET') {
255
+ if (recoveryOnly && method !== 'GET') fail('INVALID');
256
+ const rawHeaders = await checked(() => getHeaders()), headers = new Headers(rawHeaders);
257
+ headers.set('Accept', 'application/json'); if (method === 'POST') headers.set('Content-Type', 'application/json');
258
+ let response;
259
+ try {
260
+ check(); response = await fetchImpl(`${base}${path}`, { method, headers, credentials: 'include', redirect: 'error',
261
+ cache: 'no-store', signal: controller.signal, ...(method === 'POST' ? { body: JSON.stringify(body) } : {}) });
262
+ return await readJson(response, { check, signal: controller.signal, url: `${base}${path}` });
263
+ } catch (error) { check(); throw failures.has(error) ? error : failure('RESPONSE_INVALID'); }
264
+ }
265
+ const envelope = (value, identity) => {
266
+ const item = object(value), record = object(item.record);
267
+ if (typeof item.canSubmit !== 'boolean' || !item.handle || typeof item.handle !== 'object'
268
+ || record.version !== 1 || ['ownerUserId', 'apiOrigin', 'projectId'].some(key => record[key] !== identity[key])
269
+ || typeof record.inputDigest !== 'string' || !/^[a-f0-9]{64}$/u.test(record.inputDigest)
270
+ || item.canSubmit && record.inputDigest !== identity.inputDigest
271
+ || typeof record.jobId !== 'string' || record.jobId && !JOB.test(record.jobId)
272
+ || !['submitted', 'unknown', 'completed', 'failed'].includes(record.state)
273
+ || item.canSubmit && (record.jobId || record.state !== 'submitted')) fail('JOURNAL_UNAVAILABLE');
274
+ return { handle: item.handle, canSubmit: item.canSubmit, jobId: record.jobId || null };
275
+ };
276
+ const pause = () => checked(() => new Promise(resolve => {
277
+ let waiting;
278
+ const done = () => { clearTimeout(waiting); controller.signal.removeEventListener('abort', done); resolve(); };
279
+ waiting = setTimeout(done, pollMs); controller.signal.addEventListener('abort', done, { once: true });
280
+ if (controller.signal.aborted) done();
281
+ }));
282
+ try {
283
+ check(); publish('checking');
284
+ // A read-only pending-project probe has no input/body to persist. Its
285
+ // sentinel digest is never claimed, posted or used for legacy fallback.
286
+ const bytes = recoveryOnly || !body ? new Uint8Array(32)
287
+ : new Uint8Array(await checked(() => digest('SHA-256', encoder.encode(JSON.stringify(body)))));
288
+ if (bytes.byteLength !== 32) fail('INVALID');
289
+ const scopeBytes = new Uint8Array(await checked(() => digest('SHA-256', encoder.encode(JSON.stringify([operation, projectId, targetId])))));
290
+ if (scopeBytes.byteLength !== 32) fail('INVALID');
291
+ const identity = Object.freeze({ ownerUserId: captured.ownerUserId, apiOrigin: base, projectId: `durable-remake:v1:${Array.from(scopeBytes, byte => byte.toString(16).padStart(2, '0')).join('')}`,
292
+ inputDigest: Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('') });
293
+ let found = await persist(() => storage.lookup(identity, { assertCurrent: check }));
294
+ if (!found && recoveryOnly) return null;
295
+ if (await checked(() => ensureSession()) === false) fail('SESSION_REQUIRED');
296
+ if (!found) {
297
+ const capability = await request(durableRemakeCapabilityPath(operation));
298
+ if (capability.status !== 200) fail('UNAVAILABLE');
299
+ const mode = validateDurableRemakeCapability(capability.body, operation);
300
+ // Re-observe after the capability await, including a deployment change.
301
+ found = await persist(() => storage.lookup(identity, { assertCurrent: check }));
302
+ if (!found && mode === 'legacy-sync') {
303
+ if (typeof legacy !== 'function') fail('UNAVAILABLE');
304
+ // This preserves the legacy callback; the journal does not provide
305
+ // atomic legacy/v2 exclusion during a mixed deployment mode switch.
306
+ publish('legacy-sync'); check(); legacyStarted = true;
307
+ return await checked(() => legacy(body || rawBody, { signal: controller.signal }));
308
+ }
309
+ if (!found && mode !== 'queue-v2') fail('UNAVAILABLE');
310
+ if (!found && !body) fail('INVALID');
311
+ if (!found) { if (typeof assertQueueReady !== 'function' || await checked(assertQueueReady) !== true) fail('INVALID'); claimStarted = true; found = await persist(() => storage.claim(identity, { assertCurrent: check })); }
312
+ }
313
+ const selected = envelope(found, identity); handle = selected.handle; jobId = selected.jobId;
314
+ recovering = !selected.canSubmit;
315
+ if (selected.canSubmit && !claimStarted) fail('JOURNAL_UNAVAILABLE');
316
+ if (selected.canSubmit) {
317
+ publish('submitting');
318
+ const reply = await request(`${durableRemakePath(operation)}/jobs`, 'POST'), value = object(reply.body);
319
+ const accepted = reply.status === 202 && value.ok === true && value.async === true;
320
+ const uncertain = reply.status === 503 && value.code === 'BACKGROUND_ENQUEUE_UNCONFIRMED';
321
+ const returnedId = accepted ? own(value.job, 'id') : uncertain ? value.jobId : undefined;
322
+ if (typeof returnedId !== 'string' || !JOB.test(returnedId)) fail('UNRESOLVED');
323
+ jobId = returnedId;
324
+ await persist(() => storage.rememberJob(handle, jobId));
325
+ }
326
+ if (!jobId) { publish('unknown'); fail('UNRESOLVED'); }
327
+ for (;;) {
328
+ publish('checking');
329
+ const reply = await request(`/api/tracker/review/plan/jobs/${jobId}`);
330
+ if (reply.status === 404) { publish('missing'); fail('MISSING'); }
331
+ const value = object(reply.body), job = object(value.job);
332
+ if (reply.status !== 200 || value.ok !== true || job.id !== jobId || !Object.values(DURABLE_REMAKE_TYPES).includes(job.type)
333
+ || !['queued', 'running', 'completed', 'failed', 'cancelled', 'unknown'].includes(job.status)) fail('RESPONSE_INVALID');
334
+ if (job.type !== DURABLE_REMAKE_TYPES[operation]) fail('DIFFERENT_EDITOR');
335
+ if (job.status === 'completed') {
336
+ const result = validateCompletedDurableRemakeJob(job, jobId);
337
+ if (result.targetId !== targetId || result.projectId !== projectId || result.operation !== operation) fail('DIFFERENT_EDITOR');
338
+ // A provider-completed job is not a durably applied browser result.
339
+ // Keep its known ID pending through UI/storage failures or page exits.
340
+ if (typeof applyResult !== 'function') fail('APPLY_UNCONFIRMED');
341
+ try { if (await checked(() => applyResult(Object.freeze({ ...result, recoveredPreviousRequest: recovering }))) !== true) fail('APPLY_UNCONFIRMED'); }
342
+ catch (error) { check(); if (own(error, 'code') === 'DURABLE_REMAKE_STORAGE_BUDGET_EXCEEDED') fail('STORAGE_BUDGET'); if (failures.has(error)) throw error; fail('APPLY_UNCONFIRMED'); }
343
+ try { if (await checked(() => onAccountCost(result)) !== true) fail('APPLY_UNCONFIRMED'); }
344
+ catch (error) { check(); if (own(error, 'code') === 'DURABLE_REMAKE_STORAGE_BUDGET_EXCEEDED') fail('STORAGE_BUDGET'); if (failures.has(error)) throw error; fail('APPLY_UNCONFIRMED'); }
345
+ await persist(() => storage.markResult(handle, { state: 'completed' })); publish('completed');
346
+ check(); return Object.freeze({ ...result, recoveredPreviousRequest: recovering });
347
+ }
348
+ publish(job.status);
349
+ if (!['queued', 'running'].includes(job.status)) {
350
+ await persist(() => storage.markResult(handle, { state: job.status === 'unknown' ? 'unknown' : 'failed' }));
351
+ fail('UNRESOLVED');
352
+ }
353
+ await pause();
354
+ }
355
+ } catch (caught) {
356
+ controller.abort(caught);
357
+ // Do not persist after a stopped authority. A submitted record without an
358
+ // ID already restores UNKNOWN, even if the POST never left this browser.
359
+ let changed = false; try { const fresh = authority(getAuthority); synchronous(assertCurrent);
360
+ changed = fresh.ownerUserId !== captured.ownerUserId || fresh.sessionRevision !== captured.sessionRevision; } catch { changed = true; }
361
+ const error = failure(changed ? 'AUTHORITY_CHANGED' : failures.get(caught) || 'RESPONSE_INVALID');
362
+ if (legacyStarted && !changed) {
363
+ const usage = legacyUsage(own(caught, 'providerUsage'));
364
+ if (usage) {
365
+ error.providerUsage = usage;
366
+ const model = own(caught, 'providerModel'); if (text(model, 160)) error.providerModel = model;
367
+ error.partialProviderUsage = own(caught, 'partialProviderUsage') === true;
368
+ }
369
+ }
370
+ if (jobId) error.backgroundJobId = jobId;
371
+ error.submissionState = jobId ? status : handle || claimStarted || legacyStarted ? 'unknown' : 'not-submitted';
372
+ throw error;
373
+ } finally { clearTimeout(timer); signal?.removeEventListener('abort', abort); active = false; }
374
+ } });
375
+ }
@@ -25,7 +25,7 @@ export const durableSpeechToolSchema = Object.freeze({
25
25
  text: z.string().min(1).max(10000).describe("전체 내레이션. 최대 5,000자, Supertone은 300자"),
26
26
  options: optionsSchema.optional().describe("해당 공급자의 보이스·모델·언어·속도 옵션. 비용 이벤트/실행 상태는 전달하지 마세요."),
27
27
  });
28
- function capture(value) {
28
+ export function captureDurableSpeechInput(value) {
29
29
  if (!value || typeof value !== "object" || ![Object.prototype, null].includes(Object.getPrototypeOf(value))) throw invalid();
30
30
  const props = Object.getOwnPropertyDescriptors(value);
31
31
  if (Reflect.ownKeys(props).some(key => !["requestId", "provider", "text", "options"].includes(key) || !Object.hasOwn(props[key], "value"))) throw invalid();
@@ -50,7 +50,7 @@ function capture(value) {
50
50
  /** One JSON submit only. Neither errors nor a missing shared backend may invoke
51
51
  * the legacy binary tool, switch provider, or create a replacement request ID. */
52
52
  export async function submitDurableSpeech(api, value) {
53
- const { requestId, input } = capture(value), base = { generationJobId: requestId, kind: "tts", paidReplayAllowed: false, nextTool: "get_generation_job" };
53
+ const { requestId, input } = captureDurableSpeechInput(value), base = { generationJobId: requestId, kind: "tts", paidReplayAllowed: false, nextTool: "get_generation_job" };
54
54
  try {
55
55
  const response = await api.request(GENERATION_JOB_PATH, { method: "POST", timeoutMs: 30000, body: { id: requestId, kind: "tts", input, includePreview: false } });
56
56
  if (response?.job?.id !== requestId || response.job.kind !== "tts" || !["pending", "running", "completed", "failed", "interrupted", "cancel_requested", "cancelled"].includes(response.job.status)) throw invalid();
@@ -0,0 +1,62 @@
1
+ // Called only after the enclosing durable contract has made an immutable,
2
+ // bounded plain-JSON snapshot. Catalogs are observations, never credentials.
3
+ export const VOICE_INPUT_FIELDS = Object.freeze(['ttsProvider', 'voiceCatalog', 'topic', 'scriptExcerpt', 'sampleVoiceHints', 'sampleAudioBase64', 'productionProfile']);
4
+ const PROVIDERS = ['typecast', 'elevenlabs', 'supertone', 'edge', 'supertonic2'];
5
+ const PROFILE_FIELDS = ['version', 'categoryId', 'tone', 'deliveryStyle', 'targetDurationSec', 'imageSourceMode', 'visualMotionMode', 'autoComposeEnabled', 'subtitleStylePresetId', 'titleStylePresetId'];
6
+ const invalid = () => { throw new Error('DURABLE_VOICE_CONTRACT_INVALID'); };
7
+ function fields(value, allowed) {
8
+ if (!value || typeof value !== 'object' || Array.isArray(value) || Object.keys(value).some(k => !allowed.includes(k))) invalid();
9
+ }
10
+ function text(value, max, required = false) {
11
+ if (typeof value !== 'string' || value.length > max || required && !value.trim()) invalid();
12
+ }
13
+ export function validateVoiceRecommendationInput(body) {
14
+ if (!PROVIDERS.includes(body.ttsProvider)) invalid();
15
+ for (const [key, max] of [['topic', 500], ['scriptExcerpt', 2000], ['sampleVoiceHints', 500]]) if (body[key] !== undefined) text(body[key], max);
16
+ const audio = body.sampleAudioBase64;
17
+ if (audio !== undefined && (typeof audio !== 'string' || audio.length > 11_000_000 || !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u.test(audio))) invalid();
18
+ if (![body.topic, body.scriptExcerpt, body.sampleVoiceHints, audio].some(v => v?.trim())) invalid();
19
+ const catalog = body.voiceCatalog;
20
+ if (!Array.isArray(catalog) || !catalog.length || catalog.length > 250) invalid();
21
+ const ids = new Set();
22
+ for (const voice of catalog) {
23
+ fields(voice, ['voiceId', 'name', 'nameKo', 'age', 'gender', 'language', 'tags']);
24
+ text(voice.voiceId, 160, true);
25
+ if (voice.voiceId.trim() !== voice.voiceId || /[\u0000-\u0020\u007f]/u.test(voice.voiceId) || ids.has(voice.voiceId)) invalid();
26
+ ids.add(voice.voiceId);
27
+ for (const [key, max] of [['name', 60], ['nameKo', 60], ['age', 24], ['gender', 16], ['language', 24]]) text(voice[key], max);
28
+ if (!voice.name.trim() && !voice.nameKo.trim() || !Array.isArray(voice.tags) || voice.tags.length > 4) invalid();
29
+ voice.tags.forEach(tag => text(tag, 40, true));
30
+ }
31
+ const profile = body.productionProfile;
32
+ if (profile != null) {
33
+ fields(profile, PROFILE_FIELDS);
34
+ if (profile.version !== 1 || !/^[a-z][a-z0-9-]{0,63}$/u.test(profile.categoryId) || !['casual-social', 'standard', 'news-briefing'].includes(profile.deliveryStyle)
35
+ || !Number.isFinite(profile.targetDurationSec) || profile.targetDurationSec <= 0 || profile.targetDurationSec > (['community-shorts', 'viral-shorts'].includes(profile.categoryId) ? 180 : 3600)) invalid();
36
+ if (profile.tone !== undefined) text(profile.tone, 300);
37
+ if (profile.imageSourceMode !== undefined && !['web', 'ai', 'mixed'].includes(profile.imageSourceMode)
38
+ || profile.visualMotionMode !== undefined && !['image-motion', 'i2v'].includes(profile.visualMotionMode)
39
+ || profile.autoComposeEnabled !== undefined && typeof profile.autoComposeEnabled !== 'boolean') invalid();
40
+ for (const key of ['subtitleStylePresetId', 'titleStylePresetId']) if (profile[key] !== undefined && !/^[a-z][a-z0-9-]{0,63}$/u.test(profile[key])) invalid();
41
+ }
42
+ }
43
+ export function validateVoiceRecommendationOutput(value) {
44
+ fields(value, ['ttsProvider', 'recommendations', 'sampleVoiceProfile', 'notes']);
45
+ if (!PROVIDERS.includes(value.ttsProvider) || !Array.isArray(value.recommendations) || !value.recommendations.length || value.recommendations.length > 3
46
+ || !Array.isArray(value.notes) || value.notes.length > 5) invalid();
47
+ value.notes.forEach(note => text(note, 500, true));
48
+ const ids = new Set();
49
+ for (const rec of value.recommendations) {
50
+ fields(rec, ['voiceId', 'name', 'nameKo', 'age', 'gender', 'reason']);
51
+ for (const [key, max] of [['voiceId', 160], ['name', 60], ['nameKo', 60], ['age', 24], ['gender', 16], ['reason', 300]]) text(rec[key], max, key === 'voiceId');
52
+ if (ids.has(rec.voiceId)) invalid(); ids.add(rec.voiceId);
53
+ }
54
+ const p = value.sampleVoiceProfile;
55
+ if (p !== null) {
56
+ const strings = ['ageImpression', 'energy', 'gender', 'mood', 'pace', 'styleSummary', 'tone'];
57
+ fields(p, [...strings, 'syntheticLikely']);
58
+ if (Object.keys(p).length !== 8) invalid();
59
+ for (const key of strings) if (p[key] !== null) text(p[key], 80, true);
60
+ if (p.syntheticLikely !== null && typeof p.syntheticLikely !== 'boolean') invalid();
61
+ }
62
+ }