ts-procedures 7.2.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +65 -3
  2. package/agent_config/claude-code/agents/ts-procedures-architect.md +6 -8
  3. package/agent_config/claude-code/skills/ts-procedures/SKILL.md +30 -33
  4. package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +139 -53
  5. package/agent_config/claude-code/skills/ts-procedures/api-reference.md +208 -231
  6. package/agent_config/claude-code/skills/ts-procedures/patterns.md +80 -153
  7. package/agent_config/claude-code/skills/ts-procedures-review/SKILL.md +1 -1
  8. package/agent_config/claude-code/skills/ts-procedures-review/checklist.md +4 -5
  9. package/agent_config/claude-code/skills/ts-procedures-scaffold/SKILL.md +4 -7
  10. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono.md +223 -0
  11. package/agent_config/copilot/copilot-instructions.md +36 -48
  12. package/agent_config/cursor/cursorrules +36 -48
  13. package/build/client/call.js +4 -1
  14. package/build/client/call.js.map +1 -1
  15. package/build/client/call.test.js +23 -0
  16. package/build/client/call.test.js.map +1 -1
  17. package/build/client/fetch-adapter.js +3 -1
  18. package/build/client/fetch-adapter.js.map +1 -1
  19. package/build/client/fetch-adapter.test.js +11 -1
  20. package/build/client/fetch-adapter.test.js.map +1 -1
  21. package/build/client/index.test.js +7 -7
  22. package/build/client/index.test.js.map +1 -1
  23. package/build/client/request-builder.d.ts +1 -1
  24. package/build/client/request-builder.js +2 -2
  25. package/build/client/request-builder.js.map +1 -1
  26. package/build/client/stream.js +13 -2
  27. package/build/client/stream.js.map +1 -1
  28. package/build/client/stream.test.js +32 -7
  29. package/build/client/stream.test.js.map +1 -1
  30. package/build/client/typed-error-dispatch.test.js +8 -92
  31. package/build/client/typed-error-dispatch.test.js.map +1 -1
  32. package/build/client/types.d.ts +21 -3
  33. package/build/codegen/bin/cli.js +0 -0
  34. package/build/codegen/e2e.test.js +87 -23
  35. package/build/codegen/e2e.test.js.map +1 -1
  36. package/build/codegen/emit-errors.integration.test.js +1 -1
  37. package/build/codegen/emit-errors.integration.test.js.map +1 -1
  38. package/build/codegen/emit-scope.js +308 -47
  39. package/build/codegen/emit-scope.js.map +1 -1
  40. package/build/codegen/emit-scope.test.js +363 -110
  41. package/build/codegen/emit-scope.test.js.map +1 -1
  42. package/build/codegen/pipeline.test.js +7 -7
  43. package/build/codegen/pipeline.test.js.map +1 -1
  44. package/build/codegen/resolve-envelope.js +1 -1
  45. package/build/codegen/resolve-envelope.js.map +1 -1
  46. package/build/codegen/resolve-envelope.test.js +5 -5
  47. package/build/codegen/resolve-envelope.test.js.map +1 -1
  48. package/build/codegen/targets/_shared/route-slots.d.ts +8 -3
  49. package/build/codegen/targets/_shared/route-slots.js +49 -8
  50. package/build/codegen/targets/_shared/route-slots.js.map +1 -1
  51. package/build/codegen/targets/_shared/route-slots.test.js +99 -26
  52. package/build/codegen/targets/_shared/route-slots.test.js.map +1 -1
  53. package/build/codegen/targets/kotlin/emit-route-kotlin.test.js +88 -17
  54. package/build/codegen/targets/kotlin/emit-route-kotlin.test.js.map +1 -1
  55. package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js +9 -6
  56. package/build/codegen/targets/kotlin/emit-scope-kotlin.test.js.map +1 -1
  57. package/build/codegen/targets/kotlin/integration.test.js +6 -0
  58. package/build/codegen/targets/kotlin/integration.test.js.map +1 -1
  59. package/build/codegen/targets/swift/access-level.test.js +8 -11
  60. package/build/codegen/targets/swift/access-level.test.js.map +1 -1
  61. package/build/codegen/targets/swift/emit-route-swift.test.js +91 -20
  62. package/build/codegen/targets/swift/emit-route-swift.test.js.map +1 -1
  63. package/build/codegen/targets/swift/emit-scope-swift.test.js +12 -9
  64. package/build/codegen/targets/swift/emit-scope-swift.test.js.map +1 -1
  65. package/build/codegen/targets/swift/integration.test.js +6 -0
  66. package/build/codegen/targets/swift/integration.test.js.map +1 -1
  67. package/build/create-http-stream.d.ts +58 -0
  68. package/build/create-http-stream.js +122 -0
  69. package/build/create-http-stream.js.map +1 -0
  70. package/build/create-http-stream.test.js +88 -0
  71. package/build/create-http-stream.test.js.map +1 -0
  72. package/build/create-http.d.ts +49 -0
  73. package/build/create-http.js +108 -0
  74. package/build/create-http.js.map +1 -0
  75. package/build/create-http.test.js +137 -0
  76. package/build/create-http.test.js.map +1 -0
  77. package/build/create-stream.d.ts +35 -0
  78. package/build/create-stream.js +123 -0
  79. package/build/create-stream.js.map +1 -0
  80. package/build/create-stream.test.js +428 -0
  81. package/build/create-stream.test.js.map +1 -0
  82. package/build/create.d.ts +28 -0
  83. package/build/create.js +82 -0
  84. package/build/create.js.map +1 -0
  85. package/build/create.test.js +483 -0
  86. package/build/create.test.js.map +1 -0
  87. package/build/exports.d.ts +2 -0
  88. package/build/implementations/http/astro/index.test.js +20 -12
  89. package/build/implementations/http/astro/index.test.js.map +1 -1
  90. package/build/implementations/http/doc-registry.js +1 -1
  91. package/build/implementations/http/doc-registry.js.map +1 -1
  92. package/build/implementations/http/doc-registry.test.js +36 -5
  93. package/build/implementations/http/doc-registry.test.js.map +1 -1
  94. package/build/implementations/http/error-dispatch.d.ts +76 -0
  95. package/build/implementations/http/error-dispatch.js +77 -0
  96. package/build/implementations/http/error-dispatch.js.map +1 -0
  97. package/build/implementations/http/error-dispatch.test.js +254 -0
  98. package/build/implementations/http/error-dispatch.test.js.map +1 -0
  99. package/build/implementations/http/error-taxonomy.d.ts +5 -5
  100. package/build/implementations/http/hono/docs/http-doc.d.ts +6 -0
  101. package/build/implementations/http/hono/docs/http-doc.js +42 -0
  102. package/build/implementations/http/hono/docs/http-doc.js.map +1 -0
  103. package/build/implementations/http/hono/docs/http-stream-doc.d.ts +6 -0
  104. package/build/implementations/http/hono/docs/http-stream-doc.js +40 -0
  105. package/build/implementations/http/hono/docs/http-stream-doc.js.map +1 -0
  106. package/build/implementations/http/hono/docs/rpc-doc.d.ts +6 -0
  107. package/build/implementations/http/hono/docs/rpc-doc.js +24 -0
  108. package/build/implementations/http/hono/docs/rpc-doc.js.map +1 -0
  109. package/build/implementations/http/hono/docs/stream-doc.d.ts +6 -0
  110. package/build/implementations/http/hono/docs/stream-doc.js +42 -0
  111. package/build/implementations/http/hono/docs/stream-doc.js.map +1 -0
  112. package/build/implementations/http/hono/handlers/http-stream.d.ts +10 -0
  113. package/build/implementations/http/hono/handlers/http-stream.js +123 -0
  114. package/build/implementations/http/hono/handlers/http-stream.js.map +1 -0
  115. package/build/implementations/http/hono/handlers/http-stream.test.js +128 -0
  116. package/build/implementations/http/hono/handlers/http-stream.test.js.map +1 -0
  117. package/build/implementations/http/hono/handlers/http.d.ts +10 -0
  118. package/build/implementations/http/hono/handlers/http.js +115 -0
  119. package/build/implementations/http/hono/handlers/http.js.map +1 -0
  120. package/build/implementations/http/hono/handlers/http.test.js +118 -0
  121. package/build/implementations/http/hono/handlers/http.test.js.map +1 -0
  122. package/build/implementations/http/hono/handlers/rpc.d.ts +11 -0
  123. package/build/implementations/http/hono/handlers/rpc.js +32 -0
  124. package/build/implementations/http/hono/handlers/rpc.js.map +1 -0
  125. package/build/implementations/http/hono/handlers/rpc.test.js +73 -0
  126. package/build/implementations/http/hono/handlers/rpc.test.js.map +1 -0
  127. package/build/implementations/http/hono/handlers/stream.d.ts +23 -0
  128. package/build/implementations/http/hono/handlers/stream.js +147 -0
  129. package/build/implementations/http/hono/handlers/stream.js.map +1 -0
  130. package/build/implementations/http/hono/handlers/stream.test.d.ts +1 -0
  131. package/build/implementations/http/hono/handlers/stream.test.js +177 -0
  132. package/build/implementations/http/hono/handlers/stream.test.js.map +1 -0
  133. package/build/implementations/http/hono/index.d.ts +57 -0
  134. package/build/implementations/http/hono/index.js +149 -0
  135. package/build/implementations/http/hono/index.js.map +1 -0
  136. package/build/implementations/http/hono/index.test.d.ts +1 -0
  137. package/build/implementations/http/hono/index.test.js +274 -0
  138. package/build/implementations/http/hono/index.test.js.map +1 -0
  139. package/build/implementations/http/hono/path.d.ts +17 -0
  140. package/build/implementations/http/hono/path.js +39 -0
  141. package/build/implementations/http/hono/path.js.map +1 -0
  142. package/build/implementations/http/hono/path.test.d.ts +1 -0
  143. package/build/implementations/http/hono/path.test.js +83 -0
  144. package/build/implementations/http/hono/path.test.js.map +1 -0
  145. package/build/implementations/http/hono/types.d.ts +51 -0
  146. package/build/implementations/http/hono/types.js.map +1 -0
  147. package/build/implementations/http/on-request-error.test.js +6 -96
  148. package/build/implementations/http/on-request-error.test.js.map +1 -1
  149. package/build/implementations/http/route-errors.test.js +11 -59
  150. package/build/implementations/http/route-errors.test.js.map +1 -1
  151. package/build/implementations/types.d.ts +43 -9
  152. package/build/index.d.ts +125 -115
  153. package/build/index.js +10 -222
  154. package/build/index.js.map +1 -1
  155. package/build/index.test.js +30 -822
  156. package/build/index.test.js.map +1 -1
  157. package/build/migration.test.d.ts +1 -0
  158. package/build/migration.test.js +34 -0
  159. package/build/migration.test.js.map +1 -0
  160. package/build/schema/compute-schema.d.ts +11 -3
  161. package/build/schema/compute-schema.js +13 -7
  162. package/build/schema/compute-schema.js.map +1 -1
  163. package/build/schema/parser.d.ts +11 -3
  164. package/build/schema/parser.js +49 -9
  165. package/build/schema/parser.js.map +1 -1
  166. package/build/stack-utils.js +8 -0
  167. package/build/stack-utils.js.map +1 -1
  168. package/build/types.d.ts +142 -0
  169. package/build/types.js.map +1 -0
  170. package/docs/astro-adapter.md +5 -5
  171. package/docs/core.md +34 -17
  172. package/docs/http-integrations.md +83 -170
  173. package/docs/streaming.md +3 -60
  174. package/docs/superpowers/plans/2026-05-07-astro-adapter.md +2 -7
  175. package/docs/superpowers/plans/2026-05-08-create-http.md +3355 -0
  176. package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +3365 -0
  177. package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +1 -3
  178. package/docs/superpowers/specs/2026-05-08-create-http-design.md +409 -0
  179. package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +411 -0
  180. package/package.json +4 -22
  181. package/src/client/call.test.ts +26 -0
  182. package/src/client/call.ts +4 -1
  183. package/src/client/fetch-adapter.test.ts +14 -1
  184. package/src/client/fetch-adapter.ts +3 -1
  185. package/src/client/index.test.ts +7 -7
  186. package/src/client/request-builder.ts +2 -2
  187. package/src/client/stream.test.ts +39 -7
  188. package/src/client/stream.ts +16 -2
  189. package/src/client/typed-error-dispatch.test.ts +7 -97
  190. package/src/client/types.ts +21 -3
  191. package/src/codegen/__fixtures__/users-envelope.json +119 -38
  192. package/src/codegen/e2e.test.ts +98 -24
  193. package/src/codegen/emit-errors.integration.test.ts +1 -1
  194. package/src/codegen/emit-scope.test.ts +395 -110
  195. package/src/codegen/emit-scope.ts +350 -55
  196. package/src/codegen/pipeline.test.ts +7 -7
  197. package/src/codegen/resolve-envelope.test.ts +5 -5
  198. package/src/codegen/resolve-envelope.ts +1 -1
  199. package/src/codegen/targets/_shared/route-slots.test.ts +109 -26
  200. package/src/codegen/targets/_shared/route-slots.ts +48 -11
  201. package/src/codegen/targets/kotlin/__fixtures__/users-golden.kt +73 -0
  202. package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +100 -17
  203. package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +9 -6
  204. package/src/codegen/targets/kotlin/integration.test.ts +19 -0
  205. package/src/codegen/targets/swift/__fixtures__/users-golden.swift +79 -0
  206. package/src/codegen/targets/swift/access-level.test.ts +8 -11
  207. package/src/codegen/targets/swift/emit-route-swift.test.ts +103 -20
  208. package/src/codegen/targets/swift/emit-scope-swift.test.ts +12 -9
  209. package/src/codegen/targets/swift/integration.test.ts +17 -0
  210. package/src/create-http-stream.test.ts +97 -0
  211. package/src/create-http-stream.ts +191 -0
  212. package/src/create-http.test.ts +163 -0
  213. package/src/create-http.ts +211 -0
  214. package/src/create-stream.test.ts +565 -0
  215. package/src/create-stream.ts +228 -0
  216. package/src/create.test.ts +658 -0
  217. package/src/create.ts +172 -0
  218. package/src/exports.ts +2 -0
  219. package/src/implementations/http/README.md +135 -95
  220. package/src/implementations/http/astro/README.md +4 -5
  221. package/src/implementations/http/astro/index.test.ts +25 -18
  222. package/src/implementations/http/doc-registry.test.ts +42 -5
  223. package/src/implementations/http/doc-registry.ts +1 -1
  224. package/src/implementations/http/error-dispatch.test.ts +283 -0
  225. package/src/implementations/http/error-dispatch.ts +176 -0
  226. package/src/implementations/http/error-taxonomy.ts +5 -5
  227. package/src/implementations/http/hono/docs/http-doc.ts +43 -0
  228. package/src/implementations/http/hono/docs/http-stream-doc.ts +44 -0
  229. package/src/implementations/http/hono/docs/rpc-doc.ts +34 -0
  230. package/src/implementations/http/hono/docs/stream-doc.ts +53 -0
  231. package/src/implementations/http/hono/handlers/http-stream.test.ts +150 -0
  232. package/src/implementations/http/hono/handlers/http-stream.ts +152 -0
  233. package/src/implementations/http/hono/handlers/http.test.ts +130 -0
  234. package/src/implementations/http/hono/handlers/http.ts +147 -0
  235. package/src/implementations/http/hono/handlers/rpc.test.ts +81 -0
  236. package/src/implementations/http/hono/handlers/rpc.ts +54 -0
  237. package/src/implementations/http/hono/handlers/stream.test.ts +198 -0
  238. package/src/implementations/http/hono/handlers/stream.ts +208 -0
  239. package/src/implementations/http/hono/index.test.ts +329 -0
  240. package/src/implementations/http/hono/index.ts +204 -0
  241. package/src/implementations/http/hono/path.test.ts +96 -0
  242. package/src/implementations/http/hono/path.ts +59 -0
  243. package/src/implementations/http/hono/types.ts +93 -0
  244. package/src/implementations/http/on-request-error.test.ts +10 -116
  245. package/src/implementations/http/route-errors.test.ts +11 -77
  246. package/src/implementations/types.ts +44 -9
  247. package/src/index.test.ts +35 -1091
  248. package/src/index.ts +50 -474
  249. package/src/migration.test.ts +48 -0
  250. package/src/schema/compute-schema.ts +26 -12
  251. package/src/schema/parser.ts +62 -12
  252. package/src/stack-utils.ts +8 -0
  253. package/src/types.ts +133 -0
  254. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/express-rpc.md +0 -137
  255. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-api.md +0 -173
  256. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-rpc.md +0 -142
  257. package/agent_config/claude-code/skills/ts-procedures-scaffold/templates/hono-stream.md +0 -147
  258. package/build/implementations/http/express-rpc/error-taxonomy.test.js +0 -83
  259. package/build/implementations/http/express-rpc/error-taxonomy.test.js.map +0 -1
  260. package/build/implementations/http/express-rpc/index.d.ts +0 -125
  261. package/build/implementations/http/express-rpc/index.js +0 -216
  262. package/build/implementations/http/express-rpc/index.js.map +0 -1
  263. package/build/implementations/http/express-rpc/index.test.js +0 -684
  264. package/build/implementations/http/express-rpc/index.test.js.map +0 -1
  265. package/build/implementations/http/express-rpc/types.d.ts +0 -11
  266. package/build/implementations/http/express-rpc/types.js.map +0 -1
  267. package/build/implementations/http/hono-api/error-taxonomy.test.js +0 -137
  268. package/build/implementations/http/hono-api/error-taxonomy.test.js.map +0 -1
  269. package/build/implementations/http/hono-api/index.d.ts +0 -151
  270. package/build/implementations/http/hono-api/index.js +0 -344
  271. package/build/implementations/http/hono-api/index.js.map +0 -1
  272. package/build/implementations/http/hono-api/index.test.js +0 -992
  273. package/build/implementations/http/hono-api/index.test.js.map +0 -1
  274. package/build/implementations/http/hono-api/types.d.ts +0 -13
  275. package/build/implementations/http/hono-api/types.js.map +0 -1
  276. package/build/implementations/http/hono-rpc/error-taxonomy.test.js +0 -64
  277. package/build/implementations/http/hono-rpc/error-taxonomy.test.js.map +0 -1
  278. package/build/implementations/http/hono-rpc/index.d.ts +0 -130
  279. package/build/implementations/http/hono-rpc/index.js +0 -209
  280. package/build/implementations/http/hono-rpc/index.js.map +0 -1
  281. package/build/implementations/http/hono-rpc/index.test.js +0 -828
  282. package/build/implementations/http/hono-rpc/index.test.js.map +0 -1
  283. package/build/implementations/http/hono-rpc/types.d.ts +0 -11
  284. package/build/implementations/http/hono-rpc/types.js +0 -2
  285. package/build/implementations/http/hono-rpc/types.js.map +0 -1
  286. package/build/implementations/http/hono-stream/error-taxonomy.test.js +0 -159
  287. package/build/implementations/http/hono-stream/error-taxonomy.test.js.map +0 -1
  288. package/build/implementations/http/hono-stream/index.d.ts +0 -171
  289. package/build/implementations/http/hono-stream/index.js +0 -415
  290. package/build/implementations/http/hono-stream/index.js.map +0 -1
  291. package/build/implementations/http/hono-stream/index.test.js +0 -1383
  292. package/build/implementations/http/hono-stream/index.test.js.map +0 -1
  293. package/build/implementations/http/hono-stream/types.d.ts +0 -15
  294. package/build/implementations/http/hono-stream/types.js +0 -2
  295. package/build/implementations/http/hono-stream/types.js.map +0 -1
  296. package/src/implementations/http/express-rpc/README.md +0 -280
  297. package/src/implementations/http/express-rpc/error-taxonomy.test.ts +0 -103
  298. package/src/implementations/http/express-rpc/index.test.ts +0 -957
  299. package/src/implementations/http/express-rpc/index.ts +0 -327
  300. package/src/implementations/http/express-rpc/types.ts +0 -16
  301. package/src/implementations/http/hono-api/README.md +0 -284
  302. package/src/implementations/http/hono-api/error-taxonomy.test.ts +0 -179
  303. package/src/implementations/http/hono-api/index.test.ts +0 -1341
  304. package/src/implementations/http/hono-api/index.ts +0 -519
  305. package/src/implementations/http/hono-api/types.ts +0 -16
  306. package/src/implementations/http/hono-rpc/README.md +0 -357
  307. package/src/implementations/http/hono-rpc/error-taxonomy.test.ts +0 -82
  308. package/src/implementations/http/hono-rpc/index.test.ts +0 -1107
  309. package/src/implementations/http/hono-rpc/index.ts +0 -320
  310. package/src/implementations/http/hono-rpc/types.ts +0 -16
  311. package/src/implementations/http/hono-stream/README.md +0 -559
  312. package/src/implementations/http/hono-stream/error-taxonomy.test.ts +0 -178
  313. package/src/implementations/http/hono-stream/index.test.ts +0 -1804
  314. package/src/implementations/http/hono-stream/index.ts +0 -622
  315. package/src/implementations/http/hono-stream/types.ts +0 -20
  316. /package/build/{implementations/http/express-rpc/error-taxonomy.test.d.ts → create-http-stream.test.d.ts} +0 -0
  317. /package/build/{implementations/http/express-rpc/index.test.d.ts → create-http.test.d.ts} +0 -0
  318. /package/build/{implementations/http/hono-api/error-taxonomy.test.d.ts → create-stream.test.d.ts} +0 -0
  319. /package/build/{implementations/http/hono-api/index.test.d.ts → create.test.d.ts} +0 -0
  320. /package/build/implementations/http/{hono-rpc/error-taxonomy.test.d.ts → error-dispatch.test.d.ts} +0 -0
  321. /package/build/implementations/http/{hono-rpc/index.test.d.ts → hono/handlers/http-stream.test.d.ts} +0 -0
  322. /package/build/implementations/http/{hono-stream/error-taxonomy.test.d.ts → hono/handlers/http.test.d.ts} +0 -0
  323. /package/build/implementations/http/{hono-stream/index.test.d.ts → hono/handlers/rpc.test.d.ts} +0 -0
  324. /package/build/implementations/http/{express-rpc → hono}/types.js +0 -0
  325. /package/build/{implementations/http/hono-api/types.js → types.js} +0 -0
@@ -7,6 +7,9 @@ Factory function that creates a scoped procedure registration system.
7
7
  ```typescript
8
8
  function Procedures<TContext = unknown, TExtendedConfig = unknown>(
9
9
  builder?: {
10
+ config?: {
11
+ noRuntimeValidation?: true
12
+ }
10
13
  onCreate?: (procedure: {
11
14
  name: string
12
15
  isStream?: boolean
@@ -26,14 +29,17 @@ function Procedures<TContext = unknown, TExtendedConfig = unknown>(
26
29
 
27
30
  ### Parameters
28
31
 
32
+ - `builder.config.noRuntimeValidation` — When `true`, every procedure registered through this factory skips AJV validation at call time. Applies to all four creators: `Create` and `CreateStream` skip `schema.params` validation; `CreateHttp` and `CreateHttpStream` skip per-channel `schema.req.{pathParams,query,body,headers}` validation. JSON Schema is still computed at registration time, so `info.schema` and codegen are unaffected. Shape is `noRuntimeValidation?: true` — only `true` is accepted, making the opt-out explicit. Use only for trusted internal factories whose callers are already type-checked at build time; do **not** enable for procedures that accept input from public clients or untyped JSON bodies.
29
33
  - `builder.onCreate` — Called each time a procedure is registered. Use for framework integration, route registration, or logging.
30
34
 
31
35
  ### Return Value
32
36
 
33
37
  | Method | Description |
34
38
  |--------|-------------|
35
- | `Create(name, config, handler)` | Register a standard async procedure |
36
- | `CreateStream(name, config, handler)` | Register a streaming async generator procedure |
39
+ | `Create(name, config, handler)` | Register a standard async RPC procedure |
40
+ | `CreateStream(name, config, handler)` | Register a streaming async generator RPC procedure |
41
+ | `CreateHttp(name, config, handler)` | Register a unary HTTP procedure (`path`, `method`, `schema.req`, `schema.res`) |
42
+ | `CreateHttpStream(name, config, handler)` | Register a streaming HTTP procedure |
37
43
  | `getProcedures()` | Returns array of all registered procedure metadata |
38
44
  | `getProcedure(name)` | Returns single procedure by name, or `undefined` |
39
45
  | `removeProcedure(name)` | Removes procedure, returns `true` if found |
@@ -90,7 +96,7 @@ function Create<TName extends string, TParams, TReturnType>(
90
96
  |----------|------|-------------|
91
97
  | `...TContext` | varies | All base context fields |
92
98
  | `error(message, meta?)` | `Function` | Creates `ProcedureError` — throw this for business logic errors |
93
- | `signal?` | `AbortSignal` | Present when HTTP implementation injects it (Express/Hono do this automatically) |
99
+ | `signal?` | `AbortSignal` | Present when HTTP implementation injects it (`HonoAppBuilder` does this automatically) |
94
100
 
95
101
 
96
102
  ### Return Value
@@ -99,31 +105,6 @@ function Create<TName extends string, TParams, TReturnType>(
99
105
  - `{ procedure: handler }` — Same handler under a fixed key
100
106
  - `{ info: metadata }` — Registration metadata with computed JSON schemas and validation functions
101
107
 
102
- ### schema.input (Structured Multi-Channel Input)
103
-
104
- `schema.input` is an alternative to `schema.params` for multi-channel input. Mutually exclusive with `schema.params`.
105
-
106
- ```typescript
107
- Create('UpdateUser', {
108
- path: '/users/:id',
109
- method: 'put',
110
- schema: {
111
- input: {
112
- pathParams: Type.Object({ id: Type.String() }),
113
- body: Type.Object({ name: Type.String() }),
114
- },
115
- returnType: Type.Object({ ok: Type.Boolean() }),
116
- },
117
- }, async (ctx, { pathParams, body }) => {
118
- // Each channel independently typed via TInput generic
119
- return { ok: true }
120
- })
121
- ```
122
-
123
- - Each key in `input` is independently validated with per-channel error messages
124
- - `ProcedureRegistrationError` thrown at registration if both `params` and `input` defined
125
- - `TInput` generic inferred from `schema.input` — handler params type computed as `{ [K in keyof TInput]: TSchemaLib<TInput[K]> }`
126
-
127
108
  ### Throws
128
109
 
129
110
  - `ProcedureRegistrationError` — If schema extraction/compilation fails, or duplicate name
@@ -195,6 +176,85 @@ When `validateYields: true`:
195
176
 
196
177
  ---
197
178
 
179
+ ## CreateHttp\<TName, TReq, TRes, TErrorKey\>(name, config, handler)
180
+
181
+ Registers a unary HTTP procedure (v8+). First-class surface for REST-style routes with per-channel input (`schema.req`) and structured response (`schema.res`).
182
+
183
+ ```typescript
184
+ function CreateHttp<
185
+ TName extends string,
186
+ TReq extends { pathParams?: unknown; query?: unknown; body?: unknown; headers?: unknown } = {},
187
+ TRes extends { body?: unknown; headers?: unknown } = {},
188
+ TErrorKey extends string = string
189
+ >(
190
+ name: TName,
191
+ config: {
192
+ path: string
193
+ method: HttpMethod
194
+ successStatus?: number
195
+ scope?: string
196
+ errors?: TErrorKey[]
197
+ description?: string
198
+ schema: {
199
+ req?: TReq
200
+ res?: TRes
201
+ }
202
+ },
203
+ handler: (
204
+ ctx: TContext & TLocalContext,
205
+ req: { [K in keyof TReq]: TSchemaLib<TReq[K]> }
206
+ ) => Promise<HttpReturn<TRes>>
207
+ ): {
208
+ [K in TName]: typeof handler
209
+ procedure: typeof handler
210
+ info: THttpProcedureRegistration
211
+ }
212
+ ```
213
+
214
+ ### Parameters
215
+
216
+ - `config.path` — Route path. Supports Hono-style path params (`:id`).
217
+ - `config.method` — HTTP method.
218
+ - `config.schema.req` — Per-channel input schemas. Channels: `pathParams`, `query`, `body`, `headers`. Each channel independently validated.
219
+ - `config.schema.res.body` — Response body schema (documentation; not runtime-validated).
220
+ - `config.schema.res.headers` — When declared, handler **must** return `{ body, headers }` instead of the body bare. The builder reads `headers` and forwards them to the HTTP response.
221
+ - `config.errors` — Taxonomy keys this route may emit (populates DocEnvelope for codegen).
222
+
223
+ ### Return Shape
224
+
225
+ - **No `schema.res.headers`:** handler returns body bare (`T`).
226
+ - **`schema.res.headers` declared:** handler returns `{ body: B, headers: H }`.
227
+
228
+ ### Throws
229
+
230
+ - `ProcedureRegistrationError` — Path param names don't match `schema.req.pathParams`; or `schema.params` provided on a `CreateHttp` call (wrong creator).
231
+ - `ProcedureValidationError` — At call time if any req channel fails validation.
232
+ - `ProcedureError` — At call time if handler throws.
233
+
234
+ ### Example
235
+
236
+ ```typescript
237
+ const API = Procedures<AppContext>()
238
+
239
+ API.CreateHttp('GetUser', {
240
+ path: '/users/:id',
241
+ method: 'get',
242
+ schema: {
243
+ req: {
244
+ pathParams: Type.Object({ id: Type.String() }),
245
+ query: Type.Object({ include: Type.Optional(Type.String()) }),
246
+ },
247
+ res: {
248
+ body: Type.Object({ id: Type.String(), name: Type.String() }),
249
+ },
250
+ },
251
+ }, async (ctx, { pathParams, query }) => {
252
+ return await fetchUser(pathParams.id, { include: query.include })
253
+ })
254
+ ```
255
+
256
+ ---
257
+
198
258
  ## Error Classes
199
259
 
200
260
  ### ProcedureError
@@ -246,7 +306,7 @@ class ProcedureYieldValidationError extends ProcedureError {
246
306
 
247
307
  ### ProcedureRegistrationError extends ProcedureError
248
308
 
249
- Thrown at registration time (schema extraction/compilation failure, duplicate name, or `schema.params` and `schema.input` both defined).
309
+ Thrown at registration time. Common v8 sources: schema extraction/compilation failure, duplicate procedure name, using the removed v7 `schema.input` field (rejected with a migration message pointing to `CreateHttp` / `CreateHttpStream`), declaring both `schema.params` and `schema.req` on the same procedure (mutually exclusive — RPC vs HTTP), passing `schema.params` to `CreateHttp` / `CreateHttpStream` (use `schema.req.body` or `schema.req.query` instead), and path/schema mismatches on HTTP procedures (path declares params not in `schema.req.pathParams`, or vice versa).
250
310
 
251
311
  ```typescript
252
312
  class ProcedureRegistrationError extends ProcedureError {
@@ -258,7 +318,7 @@ class ProcedureRegistrationError extends ProcedureError {
258
318
 
259
319
  ## Error Taxonomy API
260
320
 
261
- Exported from `ts-procedures/http-errors` (and re-exported from every HTTP builder subpath: `ts-procedures/hono-api`, `ts-procedures/hono-rpc`, `ts-procedures/express-rpc`, `ts-procedures/hono-stream`).
321
+ Exported from `ts-procedures/http-errors` (and re-exported from `ts-procedures/hono`).
262
322
 
263
323
  ### defineErrorTaxonomy(entries)
264
324
 
@@ -630,136 +690,90 @@ Maps schema type to inferred TypeScript type:
630
690
 
631
691
  ---
632
692
 
633
- ## ExpressRPCAppBuilder
634
-
635
- HTTP implementation for Express.
636
-
637
- ```typescript
638
- class ExpressRPCAppBuilder {
639
- constructor(config?: {
640
- app?: express.Express
641
- pathPrefix?: string
642
- onRequestStart?: (req: express.Request) => void
643
- onRequestEnd?: (req: express.Request, res: express.Response) => void
644
- onSuccess?: (procedure: TProcedureRegistration, req: express.Request, res: express.Response) => void
645
- // Error handling — two peer modes plus a cross-cutting observer.
646
- errors?: ErrorTaxonomy
647
- unknownError?: UnknownErrorConfig
648
- onError?: (procedure: TProcedureRegistration, req: express.Request, res: express.Response, error: Error) => void
649
- onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
650
- })
651
-
652
- register<TFactory>(
653
- factory: TFactory,
654
- factoryContext: Context | ((req: Request) => Context | Promise<Context>),
655
- extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
656
- ): this
657
-
658
- build(): express.Application
659
-
660
- static makeRPCHttpRoutePath(params: { name: string; config: RPCConfig; prefix?: string }): string
693
+ ## HonoAppBuilder\<TStreamErrorData\>
661
694
 
662
- get app(): express.Express
663
- get docs(): RPCHttpRouteDoc[]
664
- }
665
- ```
666
-
667
- `OnRequestErrorContext` for Express: `{ err: unknown; procedure: TProcedureRegistration; raw: { req, res } }`.
668
-
669
- ### Route Path
670
-
671
- `POST {pathPrefix}/{scope}/{kebab-name}/{version}`
672
-
673
- - `scope` can be string or string array (joined as path segments)
674
- - Procedure name is converted to kebab-case
675
-
676
- ### Context Resolution
677
-
678
- - Static object: `builder.register(factory, { userId: 'system' })`
679
- - Sync function: `builder.register(factory, (req) => ({ auth: req.headers.authorization }))`
680
- - Async function: `builder.register(factory, async (req) => ({ user: await getUser(req) }))`
681
-
682
- ### Signal Injection
683
-
684
- Express builder creates a lazy AbortController and aborts on request close. The `signal` is injected into handler context automatically.
695
+ Unified Hono HTTP implementation for v8. A single builder dispatches all four procedure kinds (`Create` → RPC, `CreateStream` → streaming RPC, `CreateHttp` → REST-style, `CreateHttpStream` → streaming REST) from one `register()` call. Replaces v7's separate `HonoRPCAppBuilder` / `HonoStreamAppBuilder` / `HonoAPIAppBuilder` classes.
685
696
 
686
- ---
687
-
688
- ## HonoRPCAppBuilder
689
-
690
- HTTP implementation for Hono. Same API as ExpressRPCAppBuilder but receives Hono `Context` instead of Express `Request`.
697
+ Config is **stratified**: cross-cutting fields live at the top level, kind-specific fields live in `rpc:` / `api:` / `stream:` blocks.
691
698
 
692
699
  ```typescript
693
- class HonoRPCAppBuilder {
700
+ class HonoAppBuilder<TStreamErrorData = unknown> {
694
701
  constructor(config?: {
702
+ // Cross-cutting (apply to every kind)
695
703
  app?: Hono
696
704
  pathPrefix?: string
697
- onRequestStart?: (c: Context) => void
698
- onRequestEnd?: (c: Context) => void
699
- onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
705
+
700
706
  // Error handling — two peer modes plus a cross-cutting observer.
701
707
  errors?: ErrorTaxonomy
702
708
  unknownError?: UnknownErrorConfig
703
- onError?: (procedure: TProcedureRegistration, c: Context, error: Error) => Response | Promise<Response>
709
+ onError?: PreStreamOnError // imperative pre-stream / unary handler
704
710
  onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
705
- })
706
711
 
707
- register<TFactory>(
708
- factory: TFactory,
709
- factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
710
- extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
711
- ): this
712
-
713
- build(): Hono
714
- get app(): Hono
715
- get docs(): RPCHttpRouteDoc[]
716
- }
717
- ```
718
-
719
- `OnRequestErrorContext` for Hono RPC: `{ err: unknown; procedure: TProcedureRegistration; raw: Context }`.
720
-
721
- ### Signal Injection
722
-
723
- Uses `c.req.raw.signal` — the native Request signal from the Hono context.
724
-
725
- ---
712
+ // Lifecycle (every kind)
713
+ onRequestStart?: (c: Context) => void
714
+ onRequestEnd?: (c: Context) => void
726
715
 
727
- ## HonoStreamAppBuilder\<TErrorData\>
716
+ // RPC-specific (Create procedures)
717
+ rpc?: {
718
+ onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
719
+ }
728
720
 
729
- Streaming HTTP implementation for Hono. Supports SSE and text streaming modes.
721
+ // HTTP-specific (CreateHttp procedures)
722
+ api?: {
723
+ queryParser?: (queryString: string) => Record<string, unknown>
724
+ onSuccess?: (procedure: THttpProcedureRegistration, c: Context) => void
725
+ }
730
726
 
731
- ```typescript
732
- class HonoStreamAppBuilder<TErrorData = unknown> {
733
- constructor(config?: {
734
- app?: Hono
735
- pathPrefix?: string
736
- defaultStreamMode?: StreamMode // 'sse' | 'text', default 'sse'
737
- onRequestStart?: (c: Context) => void
738
- onRequestEnd?: (c: Context) => void
739
- onStreamStart?: (procedure: TStreamProcedureRegistration, c: Context, streamMode: StreamMode) => void
740
- onStreamEnd?: (procedure: TStreamProcedureRegistration, c: Context, streamMode: StreamMode) => void
741
- errors?: ErrorTaxonomy
742
- unknownError?: UnknownErrorConfig
743
- onError?: (procedure: TStreamProcedureRegistration, c: Context, error: Error) => Response | Promise<Response> // renamed from onPreStreamError in v6
744
- onRequestError?: (ctx: { err: unknown; procedure: TStreamProcedureRegistration; raw: Context }) => void | Promise<void>
745
- onMidStreamError?: (procedure: TStreamProcedureRegistration, c: Context, error: Error) => MidStreamErrorResult<TErrorData> | undefined
727
+ // Stream-specific (CreateStream + CreateHttpStream procedures)
728
+ stream?: {
729
+ defaultStreamMode?: StreamMode // 'sse' | 'text', default 'sse'
730
+ onStreamStart?: (
731
+ procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
732
+ c: Context,
733
+ streamMode: StreamMode,
734
+ ) => void
735
+ onStreamEnd?: (
736
+ procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
737
+ c: Context,
738
+ streamMode: StreamMode,
739
+ ) => void
740
+ onMidStreamError?: (
741
+ procedure: TStreamProcedureRegistration | THttpStreamProcedureRegistration,
742
+ c: Context,
743
+ error: Error,
744
+ ) => MidStreamErrorResult<TStreamErrorData> | undefined
745
+ }
746
746
  })
747
747
 
748
748
  register<TFactory>(
749
749
  factory: TFactory,
750
750
  factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
751
751
  options?: {
752
- streamMode?: StreamMode
752
+ streamMode?: StreamMode // per-registration override of stream.defaultStreamMode
753
753
  extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
754
754
  }
755
755
  ): this
756
756
 
757
757
  build(): Hono
758
+ toDocEnvelope(config?: DocRegistryConfig): DocEnvelope // single-app convenience
759
+
758
760
  get app(): Hono
759
- get docs(): StreamHttpRouteDoc[]
761
+ get docs(): AnyHttpRouteDoc[] // mixed RPC / HTTP / Stream route docs
760
762
  }
761
763
  ```
762
764
 
765
+ `OnRequestErrorContext`: `{ err: unknown; procedure: AnyProcedureRegistration; raw: Context }`.
766
+
767
+ ### Top-level keys (the only keys allowed at the root of the config)
768
+
769
+ `app`, `pathPrefix`, `errors`, `unknownError`, `onError`, `onRequestError`, `onRequestStart`, `onRequestEnd`, `rpc`, `api`, `stream`. Anything else is a typo or v7 vestige — `queryParser`, `onSuccess`, `defaultStreamMode`, `onStreamStart`, `onStreamEnd`, `onMidStreamError` belong inside their kind block, not at the root.
770
+
771
+ ### Error Handling
772
+
773
+ - **RPC + HTTP (unary):** `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
774
+ - **Pre-stream errors** (validation, context resolution failures before the first yield): Returns a JSON error response — no streaming started. Same dispatch as unary: `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
775
+ - **Mid-stream errors** (generator throws after the first yield): Yields error as final event, closes stream. Configure via `stream.onMidStreamError` (the only mid-stream path — the HTTP status is already committed).
776
+
763
777
  ### Stream Modes
764
778
 
765
779
  **SSE mode** (`'sse'`):
@@ -783,12 +797,14 @@ function sse<T extends object>(data: T, options?: {
783
797
  }): T
784
798
  ```
785
799
 
786
- ### HTTP Methods
800
+ ### HTTP Methods (RPC streams)
787
801
 
788
- Both GET and POST are registered for each streaming procedure:
802
+ For `CreateStream` procedures (RPC-style streams), both GET and POST are registered:
789
803
  - **GET**: params extracted from query string
790
804
  - **POST**: params extracted from JSON body
791
805
 
806
+ For `CreateHttpStream`, the method comes from `config.method` (no auto-pairing).
807
+
792
808
  ### MidStreamErrorResult
793
809
 
794
810
  ```typescript
@@ -798,63 +814,22 @@ type MidStreamErrorResult<TErrorData = unknown> = {
798
814
  }
799
815
  ```
800
816
 
801
- ### Error Handling
802
-
803
- - **Pre-stream errors** (validation, context): Returns a JSON error response (no streaming started). Handle via either peer mode — `errors` taxonomy or `onError` callback. Observe via `onRequestError`.
804
- - **Mid-stream errors** (generator throws): Yields error as final event, closes stream. Handle via `onMidStreamError` (the only mid-stream path — the HTTP status is already committed).
805
-
806
- ---
817
+ ### Route Paths
807
818
 
808
- ## HonoAPIAppBuilder
819
+ - **RPC (`Create`):** `POST {pathPrefix}/{scope}/{kebab-name}/{version}` (auto-generated).
820
+ - **RPC stream (`CreateStream`):** `GET|POST {pathPrefix}/{scope}/{kebab-name}/{version}`.
821
+ - **HTTP (`CreateHttp` / `CreateHttpStream`):** developer-defined via `config.path` — no auto-generation. Supports Hono path params (`:id`). Final path is `{pathPrefix}{path}` — e.g., `/api/users/:id`.
809
822
 
810
- REST-style HTTP implementation for Hono. Routes by HTTP method with `schema.input` per-channel validation.
811
-
812
- ```typescript
813
- class HonoAPIAppBuilder {
814
- constructor(config?: {
815
- app?: Hono
816
- pathPrefix?: string
817
- queryParser?: (queryString: string) => Record<string, unknown>
818
- onRequestStart?: (c: Context) => void
819
- onRequestEnd?: (c: Context) => void
820
- onSuccess?: (procedure: TProcedureRegistration, c: Context) => void
821
- // Error handling — two peer modes plus a cross-cutting observer.
822
- errors?: ErrorTaxonomy
823
- unknownError?: UnknownErrorConfig
824
- onError?: (procedure: TProcedureRegistration, c: Context, error: Error) => Response | Promise<Response>
825
- onRequestError?: (ctx: OnRequestErrorContext) => void | Promise<void>
826
- })
827
-
828
- register<TFactory>(
829
- factory: TFactory,
830
- factoryContext: Context | ((c: HonoContext) => Context | Promise<Context>),
831
- extendProcedureDoc?: ({ base, procedure }) => Record<string, any>
832
- ): this
833
-
834
- build(): Hono
835
- get app(): Hono
836
- get docs(): APIHttpRouteDoc[]
837
- }
838
- ```
839
-
840
- `OnRequestErrorContext` for Hono API: `{ err: unknown; procedure: TProcedureRegistration; raw: Context }`.
841
-
842
- ### Route Path
843
-
844
- Developer-defined via `APIConfig.path` — no auto-generation. Supports Hono path params (`:id`).
845
-
846
- `{pathPrefix}{path}` — e.g., `/api/users/:id`
847
-
848
- ### Input Channel Extraction
823
+ ### Input Channel Extraction (`schema.req` `CreateHttp` only)
849
824
 
850
825
  | Channel | HTTP Source | Used For |
851
826
  |---------|-----------|----------|
852
827
  | `pathParams` | URL path parameters (`c.req.param()`) | `/users/:id` → `{ id: '...' }` |
853
- | `query` | Query string (parsed via config `queryParser` or native `URLSearchParams`) | `?page=2` → `{ page: 2 }` |
828
+ | `query` | Query string (parsed via `api.queryParser` or native `URLSearchParams`) | `?page=2` → `{ page: 2 }` |
854
829
  | `body` | JSON request body (POST/PUT/PATCH only) | `{ name: 'John' }` |
855
830
  | `headers` | Request headers (AJV strips non-declared) | `{ 'x-api-key': '...' }` |
856
831
 
857
- ### Default Success Status
832
+ ### Default Success Status (`CreateHttp`)
858
833
 
859
834
  | Method | Default Status |
860
835
  |--------|---------------|
@@ -862,14 +837,14 @@ Developer-defined via `APIConfig.path` — no auto-generation. Supports Hono pat
862
837
  | DELETE | 204 (no body) |
863
838
  | Others | 200 |
864
839
 
865
- Override with `APIConfig.successStatus`.
840
+ Override with `config.successStatus` on the `CreateHttp` config.
866
841
 
867
- ### Build-Time Validation
842
+ ### Build-Time Validation (`CreateHttp`)
868
843
 
869
- - Path param names in path template must match `schema.input.pathParams` property names
870
- - `schema.input.pathParams` defined but path has no `:param` segments → error
871
- - Path has `:param` but `schema.input.pathParams` missing → error
872
- - Property name mismatch → error with clear message
844
+ - Path param names in path template must match `schema.req.pathParams` property names
845
+ - `schema.req.pathParams` defined but path has no `:param` segments → error
846
+ - Path has `:param` but `schema.req.pathParams` missing → error
847
+ - Property name mismatch → `ProcedureRegistrationError` at registration time
873
848
 
874
849
  ### Query Parsing
875
850
 
@@ -887,13 +862,15 @@ It does **not** interpret bracket/dot syntax — those stay as part of the liter
887
862
  | `?user.name=John` | `{ 'user.name': 'John' }` | `{ user: { name: 'John' } }` |
888
863
  | `?tags=a,b,c` | `{ tags: 'a,b,c' }` | `{ tags: ['a', 'b', 'c'] }` |
889
864
 
890
- For nested/bracket/dot/CSV parsing, install `qs` and opt in via `queryParser`:
865
+ For nested/bracket/dot/CSV parsing, install `qs` and opt in via `api.queryParser`:
891
866
 
892
867
  ```typescript
893
868
  import qs from 'qs'
894
869
 
895
- new HonoAPIAppBuilder({
896
- queryParser: (raw) => qs.parse(raw) as Record<string, unknown>,
870
+ new HonoAppBuilder({
871
+ api: {
872
+ queryParser: (raw) => qs.parse(raw) as Record<string, unknown>,
873
+ },
897
874
  })
898
875
  ```
899
876
 
@@ -901,6 +878,10 @@ new HonoAPIAppBuilder({
901
878
 
902
879
  Uses `c.req.raw.signal` — native Request signal from Hono context.
903
880
 
881
+ ### Single-App Doc Envelope
882
+
883
+ For apps that build all routes through one `HonoAppBuilder`, `builder.toDocEnvelope()` returns the full `DocEnvelope` directly — no `DocRegistry` wiring needed. `DocRegistry` is still preferred for multi-app aggregation.
884
+
904
885
  ---
905
886
 
906
887
  ## HTTP Types
@@ -949,48 +930,53 @@ interface StreamHttpRouteDoc extends RPCConfig {
949
930
  }
950
931
  ```
951
932
 
952
- ### APIConfig
933
+ ### TCreateHttpConfig (v8)
934
+
935
+ Config type for `CreateHttp`. HTTP fields are first-class — no `APIConfig` type parameter needed on the factory.
953
936
 
954
937
  ```typescript
955
- // Generic over valid taxonomy keys same pattern as RPCConfig.
956
- interface APIConfig<TErrorKey extends string = string> {
938
+ type TCreateHttpConfig<TReq, TRes, TErrorKey extends string = string> = {
957
939
  path: string
958
- method: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'
940
+ method: HttpMethod
959
941
  successStatus?: number
960
942
  scope?: string
961
943
  errors?: TErrorKey[]
944
+ description?: string
945
+ schema: {
946
+ req?: TReq // per-channel input: { pathParams?, query?, body?, headers? }
947
+ res?: TRes // structured response: { body?, headers? }
948
+ }
962
949
  }
963
950
  ```
964
951
 
965
- ### APIHttpRouteDoc
952
+ ### APIHttpRouteDoc (v8)
966
953
 
967
954
  ```typescript
968
- interface APIHttpRouteDoc extends APIConfig {
955
+ interface APIHttpRouteDoc {
969
956
  name: string
957
+ kind: 'http'
958
+ path: string
970
959
  fullPath: string
971
- jsonSchema: {
972
- pathParams?: Record<string, unknown>
973
- query?: Record<string, unknown>
974
- body?: Record<string, unknown>
975
- headers?: Record<string, unknown>
976
- response?: Record<string, unknown>
977
- }
960
+ method: HttpMethod
961
+ successStatus?: number
962
+ scope?: string
978
963
  errors?: string[]
964
+ jsonSchema?: {
965
+ req?: {
966
+ pathParams?: Record<string, unknown>
967
+ query?: Record<string, unknown>
968
+ body?: Record<string, unknown>
969
+ headers?: Record<string, unknown>
970
+ }
971
+ res?: {
972
+ body?: Record<string, unknown>
973
+ headers?: Record<string, unknown>
974
+ }
975
+ }
979
976
  }
980
977
  ```
981
978
 
982
- ### APIInput
983
-
984
- Channel constraint helper type. Use with `satisfies` for compile-time validation of channel names.
985
-
986
- ```typescript
987
- type APIInput<T extends {
988
- pathParams?: unknown
989
- query?: unknown
990
- body?: unknown
991
- headers?: unknown
992
- }> = T
993
- ```
979
+ > **v7 → v8 migration:** `APIConfig` and `APIInput` are removed. Replace `Procedures<Ctx, APIConfig>()` with `Procedures<Ctx>()` and replace `.Create(` with `.CreateHttp(`. Replace `schema.input` with `schema.req`.
994
980
 
995
981
  ### HttpMethod
996
982
 
@@ -1033,7 +1019,7 @@ class DocRegistry {
1033
1019
 
1034
1020
  ### DocSource
1035
1021
 
1036
- Any object with a `readonly docs` array. All four HTTP builders (`HonoRPCAppBuilder`, `HonoAPIAppBuilder`, `HonoStreamAppBuilder`, `ExpressRPCAppBuilder`) satisfy this interface.
1022
+ Any object with a `readonly docs` array. The built-in `HonoAppBuilder` satisfies this interface.
1037
1023
 
1038
1024
  ```typescript
1039
1025
  interface DocSource<T = AnyHttpRouteDoc> {
@@ -1331,7 +1317,7 @@ interface TypedStream<TYield, TReturn> extends AsyncIterable<TYield> {
1331
1317
  ### Type Parameters
1332
1318
 
1333
1319
  - `TYield` — Type of each yielded value (from `schema.yieldType`)
1334
- - `TReturn` — Type of the stream's return value (from `schema.returnType`). Sent as `event: 'return'` SSE message by `HonoStreamAppBuilder`.
1320
+ - `TReturn` — Type of the stream's return value (from `schema.returnType`). Sent as `event: 'return'` SSE message by `HonoAppBuilder`.
1335
1321
 
1336
1322
  ### Key Behavior
1337
1323
 
@@ -1412,7 +1398,7 @@ Inside factory-context closures, read Astro's APIContext via `getAstroContext`:
1412
1398
  ```ts
1413
1399
  import { getAstroContext } from 'ts-procedures/astro'
1414
1400
 
1415
- new HonoAPIAppBuilder()
1401
+ new HonoAppBuilder()
1416
1402
  .register(usersAPI, (c) => {
1417
1403
  const astro = getAstroContext(c)
1418
1404
  return { db, user: astro.locals.user ?? null }
@@ -1424,7 +1410,7 @@ Multi-app: pass an array; first non-404 response wins. All-404 falls back to the
1424
1410
 
1425
1411
  Constraints:
1426
1412
  - Astro 5+ in SSR (or `prerender = false`).
1427
- - Express builders are NOT supported by this adapter Hono builders only.
1413
+ - Hono builders only the adapter accepts `Request`/`Response` apps.
1428
1414
 
1429
1415
  ---
1430
1416
 
@@ -1459,20 +1445,11 @@ import { captureDefinitionInfo, formatDefinitionInfo } from 'ts-procedures'
1459
1445
  import type { DefinitionLocation, DefinitionInfo } from 'ts-procedures'
1460
1446
 
1461
1447
  // HTTP types (types only, no runtime)
1462
- import type { RPCConfig, RPCHttpRouteDoc, StreamHttpRouteDoc, StreamMode, APIConfig, APIHttpRouteDoc, APIInput, HttpMethod } from 'ts-procedures/http'
1463
-
1464
- // Express RPC
1465
- import { ExpressRPCAppBuilder } from 'ts-procedures/express-rpc'
1466
-
1467
- // Hono RPC
1468
- import { HonoRPCAppBuilder } from 'ts-procedures/hono-rpc'
1469
-
1470
- // Hono Streaming
1471
- import { HonoStreamAppBuilder, sse } from 'ts-procedures/hono-stream'
1448
+ import type { RPCConfig, RPCHttpRouteDoc, StreamHttpRouteDoc, StreamMode, HttpMethod } from 'ts-procedures/http'
1449
+ // Note: APIConfig and APIInput are removed in v8. Use CreateHttp with schema.req / schema.res instead.
1472
1450
 
1473
- // Hono API (REST-style)
1474
- import { HonoAPIAppBuilder } from 'ts-procedures/hono-api'
1475
- import type { APIConfig, APIHttpRouteDoc, APIInput, HttpMethod } from 'ts-procedures/hono-api'
1451
+ // Hono single unified builder dispatches RPC, HTTP, and streaming kinds
1452
+ import { HonoAppBuilder, sse } from 'ts-procedures/hono'
1476
1453
 
1477
1454
  // Client
1478
1455
  import {