ts-procedures 8.6.0 → 9.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 (627) hide show
  1. package/README.md +166 -101
  2. package/agent_config/claude-code/.claude-plugin/plugin.json +1 -1
  3. package/agent_config/claude-code/agents/ts-procedures-architect.md +11 -10
  4. package/agent_config/claude-code/skills/ts-procedures/SKILL.md +25 -12
  5. package/agent_config/claude-code/skills/ts-procedures/anti-patterns.md +10 -12
  6. package/agent_config/claude-code/skills/ts-procedures/api-reference.md +141 -45
  7. package/agent_config/claude-code/skills/ts-procedures/checklist.md +7 -6
  8. package/agent_config/claude-code/skills/ts-procedures/patterns.md +45 -6
  9. package/agent_config/claude-code/skills/ts-procedures/templates/client.md +1 -1
  10. package/agent_config/claude-code/skills/ts-procedures/templates/hono.md +1 -1
  11. package/agent_config/copilot/copilot-instructions.md +50 -33
  12. package/agent_config/cursor/cursorrules +50 -33
  13. package/build/adapters/astro/astro-context.js.map +1 -0
  14. package/build/adapters/astro/create-handler.js.map +1 -0
  15. package/build/adapters/astro/index.js.map +1 -0
  16. package/build/{implementations/http → adapters}/astro/index.test.js +1 -1
  17. package/build/adapters/astro/index.test.js.map +1 -0
  18. package/build/adapters/astro/rewrite-request.js.map +1 -0
  19. package/build/adapters/hono/envelope-parity.test.js +98 -0
  20. package/build/adapters/hono/envelope-parity.test.js.map +1 -0
  21. package/build/{implementations/http → adapters}/hono/handlers/http-stream.d.ts +1 -1
  22. package/build/adapters/hono/handlers/http-stream.js +55 -0
  23. package/build/adapters/hono/handlers/http-stream.js.map +1 -0
  24. package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.js +1 -1
  25. package/build/adapters/hono/handlers/http-stream.test.js.map +1 -0
  26. package/build/{implementations/http → adapters}/hono/handlers/http.d.ts +1 -1
  27. package/build/adapters/hono/handlers/http.js +50 -0
  28. package/build/adapters/hono/handlers/http.js.map +1 -0
  29. package/build/{implementations/http → adapters}/hono/handlers/http.test.js +1 -1
  30. package/build/adapters/hono/handlers/http.test.js.map +1 -0
  31. package/build/{implementations/http → adapters}/hono/handlers/rpc.d.ts +2 -2
  32. package/build/adapters/hono/handlers/rpc.js +23 -0
  33. package/build/adapters/hono/handlers/rpc.js.map +1 -0
  34. package/build/{implementations/http → adapters}/hono/handlers/rpc.test.js +1 -1
  35. package/build/adapters/hono/handlers/rpc.test.js.map +1 -0
  36. package/build/adapters/hono/handlers/stream.d.ts +12 -0
  37. package/build/adapters/hono/handlers/stream.js +89 -0
  38. package/build/adapters/hono/handlers/stream.js.map +1 -0
  39. package/build/{implementations/http → adapters}/hono/handlers/stream.test.js +3 -2
  40. package/build/adapters/hono/handlers/stream.test.js.map +1 -0
  41. package/build/{implementations/http → adapters}/hono/index.d.ts +24 -12
  42. package/build/{implementations/http → adapters}/hono/index.js +19 -8
  43. package/build/adapters/hono/index.js.map +1 -0
  44. package/build/{implementations/http → adapters}/hono/index.test.js +2 -4
  45. package/build/adapters/hono/index.test.js.map +1 -0
  46. package/build/{implementations/http → adapters/hono}/on-request-error.test.js +2 -2
  47. package/build/adapters/hono/on-request-error.test.js.map +1 -0
  48. package/build/adapters/hono/request.d.ts +7 -0
  49. package/build/adapters/hono/request.js +22 -0
  50. package/build/adapters/hono/request.js.map +1 -0
  51. package/build/{implementations/http → adapters/hono}/route-errors.test.js +4 -4
  52. package/build/adapters/hono/route-errors.test.js.map +1 -0
  53. package/build/adapters/hono/types.d.ts +55 -0
  54. package/build/adapters/hono/types.js +19 -0
  55. package/build/adapters/hono/types.js.map +1 -0
  56. package/build/client/freeze.test.js +39 -0
  57. package/build/client/freeze.test.js.map +1 -0
  58. package/build/client/typed-error-dispatch.test.js +2 -2
  59. package/build/client/typed-error-dispatch.test.js.map +1 -1
  60. package/build/codegen/__fixtures__/make-envelope.d.ts +1 -1
  61. package/build/codegen/bin/cli.d.ts +5 -0
  62. package/build/codegen/bin/cli.js +139 -182
  63. package/build/codegen/bin/cli.js.map +1 -1
  64. package/build/codegen/bin/cli.test.js +12 -2
  65. package/build/codegen/bin/cli.test.js.map +1 -1
  66. package/build/codegen/bin/flag-specs.d.ts +9 -0
  67. package/build/codegen/bin/flag-specs.js +33 -31
  68. package/build/codegen/bin/flag-specs.js.map +1 -1
  69. package/build/codegen/bin/flag-specs.test.js +14 -1
  70. package/build/codegen/bin/flag-specs.test.js.map +1 -1
  71. package/build/codegen/collect-models.d.ts +1 -1
  72. package/build/codegen/emit/api-route.d.ts +8 -0
  73. package/build/codegen/emit/api-route.js +156 -0
  74. package/build/codegen/emit/api-route.js.map +1 -0
  75. package/build/codegen/emit/context.d.ts +30 -0
  76. package/build/codegen/emit/context.js +2 -0
  77. package/build/codegen/emit/context.js.map +1 -0
  78. package/build/codegen/emit/declarations.d.ts +24 -0
  79. package/build/codegen/emit/declarations.js +48 -0
  80. package/build/codegen/emit/declarations.js.map +1 -0
  81. package/build/codegen/emit/format-types.d.ts +61 -0
  82. package/build/codegen/emit/format-types.js +188 -0
  83. package/build/codegen/emit/format-types.js.map +1 -0
  84. package/build/codegen/emit/http-stream-route.d.ts +7 -0
  85. package/build/codegen/emit/http-stream-route.js +138 -0
  86. package/build/codegen/emit/http-stream-route.js.map +1 -0
  87. package/build/codegen/emit/route-shared.d.ts +35 -0
  88. package/build/codegen/emit/route-shared.js +88 -0
  89. package/build/codegen/emit/route-shared.js.map +1 -0
  90. package/build/codegen/emit/rpc-route.d.ts +7 -0
  91. package/build/codegen/emit/rpc-route.js +37 -0
  92. package/build/codegen/emit/rpc-route.js.map +1 -0
  93. package/build/codegen/emit/scope-file.d.ts +39 -0
  94. package/build/codegen/emit/scope-file.js +166 -0
  95. package/build/codegen/emit/scope-file.js.map +1 -0
  96. package/build/codegen/emit/stream-route.d.ts +7 -0
  97. package/build/codegen/emit/stream-route.js +62 -0
  98. package/build/codegen/emit/stream-route.js.map +1 -0
  99. package/build/codegen/emit-errors.d.ts +1 -1
  100. package/build/codegen/emit-errors.integration.test.js +1 -1
  101. package/build/codegen/emit-errors.integration.test.js.map +1 -1
  102. package/build/codegen/emit-scope.d.ts +13 -30
  103. package/build/codegen/emit-scope.js +15 -844
  104. package/build/codegen/emit-scope.js.map +1 -1
  105. package/build/codegen/goldens.test.js +69 -0
  106. package/build/codegen/goldens.test.js.map +1 -0
  107. package/build/codegen/group-routes.d.ts +1 -1
  108. package/build/codegen/pipeline.d.ts +1 -1
  109. package/build/codegen/resolve-envelope.d.ts +1 -1
  110. package/build/codegen/targets/_shared/error-schemas.d.ts +1 -1
  111. package/build/codegen/targets/_shared/route-slots.d.ts +1 -1
  112. package/build/codegen/targets/_shared/target-run.d.ts +1 -1
  113. package/build/codegen/targets/kotlin/emit-route-kotlin.d.ts +1 -1
  114. package/build/codegen/targets/swift/emit-route-swift.d.ts +1 -1
  115. package/build/core/create-http-stream.d.ts +50 -0
  116. package/build/core/create-http-stream.js +108 -0
  117. package/build/core/create-http-stream.js.map +1 -0
  118. package/build/{create-http-stream.test.js → core/create-http-stream.test.js} +1 -1
  119. package/build/core/create-http-stream.test.js.map +1 -0
  120. package/build/core/create-http.d.ts +51 -0
  121. package/build/core/create-http.js +65 -0
  122. package/build/core/create-http.js.map +1 -0
  123. package/build/{create-http.test.js → core/create-http.test.js} +13 -4
  124. package/build/core/create-http.test.js.map +1 -0
  125. package/build/core/create-stream.d.ts +26 -0
  126. package/build/core/create-stream.js +80 -0
  127. package/build/core/create-stream.js.map +1 -0
  128. package/build/{create-stream.test.js → core/create-stream.test.js} +23 -28
  129. package/build/core/create-stream.test.js.map +1 -0
  130. package/build/core/create.d.ts +22 -0
  131. package/build/core/create.js +71 -0
  132. package/build/core/create.js.map +1 -0
  133. package/build/{create.test.js → core/create.test.js} +25 -46
  134. package/build/core/create.test.js.map +1 -0
  135. package/build/core/definition-site.d.ts +24 -0
  136. package/build/{stack-utils.js → core/definition-site.js} +20 -20
  137. package/build/core/definition-site.js.map +1 -0
  138. package/build/{stack-utils.test.js → core/definition-site.test.js} +12 -3
  139. package/build/core/definition-site.test.js.map +1 -0
  140. package/build/{errors.d.ts → core/errors.d.ts} +19 -8
  141. package/build/{errors.js → core/errors.js} +21 -26
  142. package/build/core/errors.js.map +1 -0
  143. package/build/core/errors.test.js.map +1 -0
  144. package/build/core/factory-options.test.js +82 -0
  145. package/build/core/factory-options.test.js.map +1 -0
  146. package/build/core/http-route.d.ts +13 -0
  147. package/build/core/http-route.js +54 -0
  148. package/build/core/http-route.js.map +1 -0
  149. package/build/core/internal.d.ts +72 -0
  150. package/build/core/internal.js +128 -0
  151. package/build/core/internal.js.map +1 -0
  152. package/build/{migration.test.js → core/migration.test.js} +17 -1
  153. package/build/core/migration.test.js.map +1 -0
  154. package/build/core/procedures.d.ts +143 -0
  155. package/build/core/procedures.js +64 -0
  156. package/build/core/procedures.js.map +1 -0
  157. package/build/{index.test.js → core/procedures.test.js} +14 -11
  158. package/build/core/procedures.test.js.map +1 -0
  159. package/build/core/types.d.ts +182 -0
  160. package/build/{schema → core}/types.js.map +1 -1
  161. package/build/exports.d.ts +31 -11
  162. package/build/exports.js +23 -8
  163. package/build/exports.js.map +1 -1
  164. package/build/schema/adapter.d.ts +35 -0
  165. package/build/schema/adapter.js +13 -0
  166. package/build/schema/adapter.js.map +1 -0
  167. package/build/schema/adapter.test.js +53 -0
  168. package/build/schema/adapter.test.js.map +1 -0
  169. package/build/schema/compile.d.ts +37 -0
  170. package/build/schema/compile.js +38 -0
  171. package/build/schema/compile.js.map +1 -0
  172. package/build/schema/compile.test.js +78 -0
  173. package/build/schema/compile.test.js.map +1 -0
  174. package/build/schema/compute-schema.d.ts +47 -37
  175. package/build/schema/compute-schema.js +86 -29
  176. package/build/schema/compute-schema.js.map +1 -1
  177. package/build/schema/compute-schema.test.js +158 -40
  178. package/build/schema/compute-schema.test.js.map +1 -1
  179. package/build/schema/json-schema.d.ts +17 -0
  180. package/build/schema/json-schema.js +2 -0
  181. package/build/schema/json-schema.js.map +1 -0
  182. package/build/schema/typebox.d.ts +11 -0
  183. package/build/schema/typebox.js +24 -0
  184. package/build/schema/typebox.js.map +1 -0
  185. package/build/schema/typebox.test.js +34 -0
  186. package/build/schema/typebox.test.js.map +1 -0
  187. package/build/server/context.d.ts +8 -0
  188. package/build/server/context.js +7 -0
  189. package/build/server/context.js.map +1 -0
  190. package/build/server/context.test.js +16 -0
  191. package/build/server/context.test.js.map +1 -0
  192. package/build/{doc-envelope.d.ts → server/doc-envelope.d.ts} +1 -1
  193. package/build/server/doc-envelope.js.map +1 -0
  194. package/build/server/doc-envelope.test.d.ts +1 -0
  195. package/build/server/doc-envelope.test.js.map +1 -0
  196. package/build/{implementations/http → server}/doc-registry.d.ts +7 -2
  197. package/build/{implementations/http → server}/doc-registry.js +9 -5
  198. package/build/server/doc-registry.js.map +1 -0
  199. package/build/server/doc-registry.test.d.ts +1 -0
  200. package/build/{implementations/http → server}/doc-registry.test.js +27 -24
  201. package/build/server/doc-registry.test.js.map +1 -0
  202. package/build/server/docs/docs.test.d.ts +1 -0
  203. package/build/server/docs/docs.test.js +237 -0
  204. package/build/server/docs/docs.test.js.map +1 -0
  205. package/build/{implementations/http/hono → server}/docs/http-doc.d.ts +2 -2
  206. package/build/{implementations/http/hono → server}/docs/http-doc.js +1 -1
  207. package/build/server/docs/http-doc.js.map +1 -0
  208. package/build/{implementations/http/hono → server}/docs/http-stream-doc.d.ts +2 -2
  209. package/build/{implementations/http/hono → server}/docs/http-stream-doc.js +1 -1
  210. package/build/server/docs/http-stream-doc.js.map +1 -0
  211. package/build/{implementations/http/hono → server}/docs/rpc-doc.d.ts +2 -2
  212. package/build/{implementations/http/hono → server}/docs/rpc-doc.js +1 -1
  213. package/build/server/docs/rpc-doc.js.map +1 -0
  214. package/build/{implementations/http/hono → server}/docs/stream-doc.d.ts +2 -2
  215. package/build/{implementations/http/hono → server}/docs/stream-doc.js +1 -1
  216. package/build/server/docs/stream-doc.js.map +1 -0
  217. package/build/server/errors/dispatch.d.ts +96 -0
  218. package/build/{implementations/http/error-dispatch.js → server/errors/dispatch.js} +20 -10
  219. package/build/server/errors/dispatch.js.map +1 -0
  220. package/build/server/errors/dispatch.test.d.ts +1 -0
  221. package/build/server/errors/dispatch.test.js +418 -0
  222. package/build/server/errors/dispatch.test.js.map +1 -0
  223. package/build/{implementations/http/error-taxonomy.d.ts → server/errors/taxonomy.d.ts} +8 -17
  224. package/build/{implementations/http/error-taxonomy.js → server/errors/taxonomy.js} +6 -15
  225. package/build/server/errors/taxonomy.js.map +1 -0
  226. package/build/server/errors/taxonomy.test.d.ts +1 -0
  227. package/build/{implementations/http/error-taxonomy.test.js → server/errors/taxonomy.test.js} +45 -39
  228. package/build/server/errors/taxonomy.test.js.map +1 -0
  229. package/build/server/index.d.ts +29 -0
  230. package/build/server/index.js +27 -0
  231. package/build/server/index.js.map +1 -0
  232. package/build/server/no-framework-imports.test.d.ts +1 -0
  233. package/build/server/no-framework-imports.test.js +40 -0
  234. package/build/server/no-framework-imports.test.js.map +1 -0
  235. package/build/{implementations/http/hono/path.d.ts → server/paths.d.ts} +2 -3
  236. package/build/{implementations/http/hono/path.js → server/paths.js} +1 -1
  237. package/build/server/paths.js.map +1 -0
  238. package/build/server/paths.test.d.ts +1 -0
  239. package/build/server/paths.test.js +111 -0
  240. package/build/server/paths.test.js.map +1 -0
  241. package/build/server/request/params.d.ts +29 -0
  242. package/build/server/request/params.js +43 -0
  243. package/build/server/request/params.js.map +1 -0
  244. package/build/server/request/params.test.d.ts +1 -0
  245. package/build/server/request/params.test.js +91 -0
  246. package/build/server/request/params.test.js.map +1 -0
  247. package/build/server/request/query.d.ts +9 -0
  248. package/build/server/request/query.js +22 -0
  249. package/build/server/request/query.js.map +1 -0
  250. package/build/server/request/query.test.d.ts +1 -0
  251. package/build/server/request/query.test.js +60 -0
  252. package/build/server/request/query.test.js.map +1 -0
  253. package/build/server/sse.d.ts +70 -0
  254. package/build/server/sse.js +94 -0
  255. package/build/server/sse.js.map +1 -0
  256. package/build/server/sse.test.d.ts +1 -0
  257. package/build/server/sse.test.js +98 -0
  258. package/build/server/sse.test.js.map +1 -0
  259. package/build/{implementations → server}/types.d.ts +17 -15
  260. package/build/{implementations → server}/types.js.map +1 -1
  261. package/docs/astro-adapter.md +8 -9
  262. package/docs/client-and-codegen.md +4 -4
  263. package/docs/client-error-handling.md +5 -5
  264. package/docs/codegen-kotlin.md +2 -3
  265. package/docs/codegen-swift.md +1 -2
  266. package/docs/core.md +135 -54
  267. package/docs/http-integrations.md +58 -6
  268. package/docs/migration-v8-to-v9.md +192 -0
  269. package/docs/plans/2026-06-09-v9-rewrite.md +130 -0
  270. package/docs/specs/2026-06-09-v9-rewrite-design.md +221 -0
  271. package/docs/streaming.md +12 -0
  272. package/package.json +23 -47
  273. package/src/{implementations/http → adapters}/astro/index.test.ts +2 -2
  274. package/src/adapters/hono/__fixtures__/parity-envelope.json +389 -0
  275. package/src/adapters/hono/envelope-parity.test.ts +126 -0
  276. package/src/{implementations/http → adapters}/hono/handlers/http-stream.test.ts +1 -1
  277. package/src/adapters/hono/handlers/http-stream.ts +73 -0
  278. package/src/{implementations/http → adapters}/hono/handlers/http.test.ts +1 -1
  279. package/src/adapters/hono/handlers/http.ts +70 -0
  280. package/src/{implementations/http → adapters}/hono/handlers/rpc.test.ts +2 -2
  281. package/src/adapters/hono/handlers/rpc.ts +39 -0
  282. package/src/{implementations/http → adapters}/hono/handlers/stream.test.ts +4 -3
  283. package/src/{implementations/http → adapters}/hono/handlers/stream.ts +19 -92
  284. package/src/{implementations/http → adapters}/hono/index.test.ts +14 -16
  285. package/src/{implementations/http → adapters}/hono/index.ts +35 -30
  286. package/src/{implementations/http → adapters/hono}/on-request-error.test.ts +3 -3
  287. package/src/adapters/hono/request.ts +28 -0
  288. package/src/{implementations/http → adapters/hono}/route-errors.test.ts +5 -5
  289. package/src/{implementations/http → adapters}/hono/types.ts +43 -20
  290. package/src/client/freeze.test.ts +41 -0
  291. package/src/client/typed-error-dispatch.test.ts +3 -3
  292. package/src/codegen/__fixtures__/make-envelope.ts +1 -1
  293. package/src/codegen/__fixtures__/models-envelope.json +310 -0
  294. package/src/codegen/__goldens__/MANIFEST.json +85 -0
  295. package/src/codegen/__goldens__/kotlin-default--models/Billing.kt +112 -0
  296. package/src/codegen/__goldens__/kotlin-default--models/BillingReports.kt +26 -0
  297. package/src/codegen/__goldens__/kotlin-default--models/Orders.kt +88 -0
  298. package/src/codegen/__goldens__/kotlin-default--users/Users.kt +189 -0
  299. package/src/codegen/__goldens__/swift-default--models/Billing.swift +97 -0
  300. package/src/codegen/__goldens__/swift-default--models/BillingReports.swift +20 -0
  301. package/src/codegen/__goldens__/swift-default--models/Orders.swift +81 -0
  302. package/src/codegen/__goldens__/swift-default--users/Users.swift +204 -0
  303. package/src/codegen/__goldens__/ts-default--models/_client.ts +1319 -0
  304. package/src/codegen/__goldens__/ts-default--models/_errors.ts +90 -0
  305. package/src/codegen/__goldens__/ts-default--models/_models.ts +10 -0
  306. package/src/codegen/__goldens__/ts-default--models/_types.ts +502 -0
  307. package/src/codegen/__goldens__/ts-default--models/billing-reports.ts +29 -0
  308. package/src/codegen/__goldens__/ts-default--models/billing.ts +67 -0
  309. package/src/codegen/__goldens__/ts-default--models/index.ts +48 -0
  310. package/src/codegen/__goldens__/ts-default--models/orders.ts +80 -0
  311. package/src/codegen/__goldens__/ts-default--users/_client.ts +1319 -0
  312. package/src/codegen/__goldens__/ts-default--users/_errors.ts +90 -0
  313. package/src/codegen/__goldens__/ts-default--users/_types.ts +502 -0
  314. package/src/codegen/__goldens__/ts-default--users/index.ts +38 -0
  315. package/src/codegen/__goldens__/ts-default--users/users.ts +169 -0
  316. package/src/codegen/__goldens__/ts-external-runtime--models/_errors.ts +90 -0
  317. package/src/codegen/__goldens__/ts-external-runtime--models/_models.ts +10 -0
  318. package/src/codegen/__goldens__/ts-external-runtime--models/billing-reports.ts +29 -0
  319. package/src/codegen/__goldens__/ts-external-runtime--models/billing.ts +67 -0
  320. package/src/codegen/__goldens__/ts-external-runtime--models/index.ts +48 -0
  321. package/src/codegen/__goldens__/ts-external-runtime--models/orders.ts +80 -0
  322. package/src/codegen/__goldens__/ts-external-runtime--users/_errors.ts +90 -0
  323. package/src/codegen/__goldens__/ts-external-runtime--users/index.ts +38 -0
  324. package/src/codegen/__goldens__/ts-external-runtime--users/users.ts +169 -0
  325. package/src/codegen/__goldens__/ts-flat--models/_client.ts +1319 -0
  326. package/src/codegen/__goldens__/ts-flat--models/_errors.ts +87 -0
  327. package/src/codegen/__goldens__/ts-flat--models/_models.ts +10 -0
  328. package/src/codegen/__goldens__/ts-flat--models/_types.ts +502 -0
  329. package/src/codegen/__goldens__/ts-flat--models/billing-reports.ts +28 -0
  330. package/src/codegen/__goldens__/ts-flat--models/billing.ts +51 -0
  331. package/src/codegen/__goldens__/ts-flat--models/index.ts +42 -0
  332. package/src/codegen/__goldens__/ts-flat--models/orders.ts +73 -0
  333. package/src/codegen/__goldens__/ts-flat--users/_client.ts +1319 -0
  334. package/src/codegen/__goldens__/ts-flat--users/_errors.ts +87 -0
  335. package/src/codegen/__goldens__/ts-flat--users/_types.ts +502 -0
  336. package/src/codegen/__goldens__/ts-flat--users/index.ts +34 -0
  337. package/src/codegen/__goldens__/ts-flat--users/users.ts +126 -0
  338. package/src/codegen/__goldens__/ts-no-share-models--models/_client.ts +1319 -0
  339. package/src/codegen/__goldens__/ts-no-share-models--models/_errors.ts +90 -0
  340. package/src/codegen/__goldens__/ts-no-share-models--models/_types.ts +502 -0
  341. package/src/codegen/__goldens__/ts-no-share-models--models/billing-reports.ts +29 -0
  342. package/src/codegen/__goldens__/ts-no-share-models--models/billing.ts +111 -0
  343. package/src/codegen/__goldens__/ts-no-share-models--models/index.ts +48 -0
  344. package/src/codegen/__goldens__/ts-no-share-models--models/orders.ts +112 -0
  345. package/src/codegen/__goldens__/ts-no-share-models--users/_client.ts +1319 -0
  346. package/src/codegen/__goldens__/ts-no-share-models--users/_errors.ts +90 -0
  347. package/src/codegen/__goldens__/ts-no-share-models--users/_types.ts +502 -0
  348. package/src/codegen/__goldens__/ts-no-share-models--users/index.ts +38 -0
  349. package/src/codegen/__goldens__/ts-no-share-models--users/users.ts +169 -0
  350. package/src/codegen/__goldens__/ts-shared-models-module--models/_client.ts +1319 -0
  351. package/src/codegen/__goldens__/ts-shared-models-module--models/_errors.ts +90 -0
  352. package/src/codegen/__goldens__/ts-shared-models-module--models/_models.ts +7 -0
  353. package/src/codegen/__goldens__/ts-shared-models-module--models/_types.ts +502 -0
  354. package/src/codegen/__goldens__/ts-shared-models-module--models/billing-reports.ts +29 -0
  355. package/src/codegen/__goldens__/ts-shared-models-module--models/billing.ts +67 -0
  356. package/src/codegen/__goldens__/ts-shared-models-module--models/index.ts +48 -0
  357. package/src/codegen/__goldens__/ts-shared-models-module--models/orders.ts +80 -0
  358. package/src/codegen/bin/cli.test.ts +13 -2
  359. package/src/codegen/bin/cli.ts +181 -144
  360. package/src/codegen/bin/flag-specs.test.ts +16 -1
  361. package/src/codegen/bin/flag-specs.ts +43 -31
  362. package/src/codegen/bundle-size.test.ts +1 -1
  363. package/src/codegen/collect-models.ts +1 -1
  364. package/src/codegen/e2e.test.ts +1 -1
  365. package/src/codegen/emit/api-route.ts +184 -0
  366. package/src/codegen/emit/context.ts +32 -0
  367. package/src/codegen/emit/declarations.ts +49 -0
  368. package/src/codegen/emit/format-types.ts +232 -0
  369. package/src/codegen/emit/http-stream-route.ts +162 -0
  370. package/src/codegen/emit/route-shared.ts +102 -0
  371. package/src/codegen/emit/rpc-route.ts +49 -0
  372. package/src/codegen/emit/scope-file.ts +226 -0
  373. package/src/codegen/emit/stream-route.ts +81 -0
  374. package/src/codegen/emit-errors.integration.test.ts +2 -2
  375. package/src/codegen/emit-errors.test.ts +1 -1
  376. package/src/codegen/emit-errors.ts +1 -1
  377. package/src/codegen/emit-scope.test.ts +2 -2
  378. package/src/codegen/emit-scope.ts +15 -1048
  379. package/src/codegen/goldens.test.ts +89 -0
  380. package/src/codegen/group-routes.test.ts +1 -1
  381. package/src/codegen/group-routes.ts +1 -1
  382. package/src/codegen/pipeline.test.ts +1 -1
  383. package/src/codegen/pipeline.ts +1 -1
  384. package/src/codegen/resolve-envelope.test.ts +1 -1
  385. package/src/codegen/resolve-envelope.ts +1 -1
  386. package/src/codegen/targets/_shared/error-schemas.test.ts +1 -1
  387. package/src/codegen/targets/_shared/error-schemas.ts +1 -1
  388. package/src/codegen/targets/_shared/route-slots.test.ts +1 -1
  389. package/src/codegen/targets/_shared/route-slots.ts +1 -1
  390. package/src/codegen/targets/_shared/target-run.ts +1 -1
  391. package/src/codegen/targets/kotlin/emit-route-kotlin.test.ts +1 -1
  392. package/src/codegen/targets/kotlin/emit-route-kotlin.ts +1 -1
  393. package/src/codegen/targets/kotlin/emit-scope-kotlin.test.ts +1 -1
  394. package/src/codegen/targets/swift/access-level.test.ts +1 -1
  395. package/src/codegen/targets/swift/emit-route-swift.test.ts +1 -1
  396. package/src/codegen/targets/swift/emit-route-swift.ts +1 -1
  397. package/src/codegen/targets/swift/emit-scope-swift.test.ts +1 -1
  398. package/src/codegen/targets/ts/shared-models.test.ts +1 -1
  399. package/src/{create-http-stream.test.ts → core/create-http-stream.test.ts} +1 -1
  400. package/src/core/create-http-stream.ts +207 -0
  401. package/src/{create-http.test.ts → core/create-http.test.ts} +15 -4
  402. package/src/core/create-http.ts +126 -0
  403. package/src/{create-stream.test.ts → core/create-stream.test.ts} +28 -31
  404. package/src/core/create-stream.ts +142 -0
  405. package/src/{create.test.ts → core/create.test.ts} +25 -57
  406. package/src/core/create.ts +121 -0
  407. package/src/{stack-utils.test.ts → core/definition-site.test.ts} +14 -3
  408. package/src/{stack-utils.ts → core/definition-site.ts} +20 -23
  409. package/src/{errors.test.ts → core/errors.test.ts} +1 -1
  410. package/src/{errors.ts → core/errors.ts} +30 -28
  411. package/src/core/factory-options.test.ts +112 -0
  412. package/src/core/http-route.ts +73 -0
  413. package/src/core/internal.ts +203 -0
  414. package/src/{migration.test.ts → core/migration.test.ts} +23 -1
  415. package/src/{index.test.ts → core/procedures.test.ts} +13 -11
  416. package/src/core/procedures.ts +75 -0
  417. package/src/core/types.ts +195 -0
  418. package/src/exports.ts +60 -11
  419. package/src/schema/adapter.test.ts +58 -0
  420. package/src/schema/adapter.ts +45 -0
  421. package/src/schema/compile.test.ts +95 -0
  422. package/src/schema/compile.ts +64 -0
  423. package/src/schema/compute-schema.test.ts +222 -41
  424. package/src/schema/compute-schema.ts +145 -71
  425. package/src/schema/json-schema.ts +21 -0
  426. package/src/schema/typebox.test.ts +40 -0
  427. package/src/schema/typebox.ts +27 -0
  428. package/src/server/context.test.ts +22 -0
  429. package/src/server/context.ts +18 -0
  430. package/src/{doc-envelope.test.ts → server/doc-envelope.test.ts} +2 -2
  431. package/src/{doc-envelope.ts → server/doc-envelope.ts} +1 -1
  432. package/src/{implementations/http → server}/doc-registry.test.ts +32 -26
  433. package/src/{implementations/http → server}/doc-registry.ts +11 -7
  434. package/src/server/docs/docs.test.ts +287 -0
  435. package/src/{implementations/http/hono → server}/docs/http-doc.ts +3 -3
  436. package/src/{implementations/http/hono → server}/docs/http-stream-doc.ts +3 -3
  437. package/src/{implementations/http/hono → server}/docs/rpc-doc.ts +3 -3
  438. package/src/{implementations/http/hono → server}/docs/stream-doc.ts +3 -3
  439. package/src/server/errors/dispatch.test.ts +450 -0
  440. package/src/server/errors/dispatch.ts +189 -0
  441. package/src/{implementations/http/error-taxonomy.test.ts → server/errors/taxonomy.test.ts} +45 -39
  442. package/src/{implementations/http/error-taxonomy.ts → server/errors/taxonomy.ts} +8 -17
  443. package/src/server/index.ts +29 -0
  444. package/src/server/no-framework-imports.test.ts +43 -0
  445. package/src/server/paths.test.ts +141 -0
  446. package/src/{implementations/http/hono/path.ts → server/paths.ts} +2 -13
  447. package/src/server/request/params.test.ts +143 -0
  448. package/src/server/request/params.ts +68 -0
  449. package/src/server/request/query.test.ts +70 -0
  450. package/src/server/request/query.ts +24 -0
  451. package/src/server/sse.test.ts +113 -0
  452. package/src/server/sse.ts +117 -0
  453. package/src/{implementations → server}/types.ts +17 -16
  454. package/build/create-http-stream.d.ts +0 -58
  455. package/build/create-http-stream.js +0 -122
  456. package/build/create-http-stream.js.map +0 -1
  457. package/build/create-http-stream.test.js.map +0 -1
  458. package/build/create-http.d.ts +0 -49
  459. package/build/create-http.js +0 -108
  460. package/build/create-http.js.map +0 -1
  461. package/build/create-http.test.js.map +0 -1
  462. package/build/create-stream.d.ts +0 -35
  463. package/build/create-stream.js +0 -123
  464. package/build/create-stream.js.map +0 -1
  465. package/build/create-stream.test.js.map +0 -1
  466. package/build/create.d.ts +0 -28
  467. package/build/create.js +0 -82
  468. package/build/create.js.map +0 -1
  469. package/build/create.test.js.map +0 -1
  470. package/build/doc-envelope.js.map +0 -1
  471. package/build/doc-envelope.test.js.map +0 -1
  472. package/build/errors.js.map +0 -1
  473. package/build/errors.test.js.map +0 -1
  474. package/build/implementations/http/astro/astro-context.js.map +0 -1
  475. package/build/implementations/http/astro/create-handler.js.map +0 -1
  476. package/build/implementations/http/astro/index.js.map +0 -1
  477. package/build/implementations/http/astro/index.test.js.map +0 -1
  478. package/build/implementations/http/astro/rewrite-request.js.map +0 -1
  479. package/build/implementations/http/doc-registry.js.map +0 -1
  480. package/build/implementations/http/doc-registry.test.js.map +0 -1
  481. package/build/implementations/http/error-dispatch.d.ts +0 -76
  482. package/build/implementations/http/error-dispatch.js.map +0 -1
  483. package/build/implementations/http/error-dispatch.test.js +0 -254
  484. package/build/implementations/http/error-dispatch.test.js.map +0 -1
  485. package/build/implementations/http/error-taxonomy.js.map +0 -1
  486. package/build/implementations/http/error-taxonomy.test.js.map +0 -1
  487. package/build/implementations/http/hono/docs/http-doc.js.map +0 -1
  488. package/build/implementations/http/hono/docs/http-stream-doc.js.map +0 -1
  489. package/build/implementations/http/hono/docs/rpc-doc.js.map +0 -1
  490. package/build/implementations/http/hono/docs/stream-doc.js.map +0 -1
  491. package/build/implementations/http/hono/handlers/http-stream.js +0 -123
  492. package/build/implementations/http/hono/handlers/http-stream.js.map +0 -1
  493. package/build/implementations/http/hono/handlers/http-stream.test.js.map +0 -1
  494. package/build/implementations/http/hono/handlers/http.js +0 -110
  495. package/build/implementations/http/hono/handlers/http.js.map +0 -1
  496. package/build/implementations/http/hono/handlers/http.test.js.map +0 -1
  497. package/build/implementations/http/hono/handlers/rpc.js +0 -32
  498. package/build/implementations/http/hono/handlers/rpc.js.map +0 -1
  499. package/build/implementations/http/hono/handlers/rpc.test.js.map +0 -1
  500. package/build/implementations/http/hono/handlers/stream.d.ts +0 -23
  501. package/build/implementations/http/hono/handlers/stream.js +0 -147
  502. package/build/implementations/http/hono/handlers/stream.js.map +0 -1
  503. package/build/implementations/http/hono/handlers/stream.test.js.map +0 -1
  504. package/build/implementations/http/hono/index.js.map +0 -1
  505. package/build/implementations/http/hono/index.test.js.map +0 -1
  506. package/build/implementations/http/hono/path.js.map +0 -1
  507. package/build/implementations/http/hono/path.test.js +0 -83
  508. package/build/implementations/http/hono/path.test.js.map +0 -1
  509. package/build/implementations/http/hono/types.d.ts +0 -51
  510. package/build/implementations/http/hono/types.js.map +0 -1
  511. package/build/implementations/http/on-request-error.test.js.map +0 -1
  512. package/build/implementations/http/route-errors.test.js.map +0 -1
  513. package/build/index.d.ts +0 -175
  514. package/build/index.js +0 -47
  515. package/build/index.js.map +0 -1
  516. package/build/index.test.js.map +0 -1
  517. package/build/migration.test.js.map +0 -1
  518. package/build/schema/extract-json-schema.d.ts +0 -2
  519. package/build/schema/extract-json-schema.js +0 -12
  520. package/build/schema/extract-json-schema.js.map +0 -1
  521. package/build/schema/extract-json-schema.test.js +0 -23
  522. package/build/schema/extract-json-schema.test.js.map +0 -1
  523. package/build/schema/parser.d.ts +0 -36
  524. package/build/schema/parser.js +0 -210
  525. package/build/schema/parser.js.map +0 -1
  526. package/build/schema/parser.test.js +0 -120
  527. package/build/schema/parser.test.js.map +0 -1
  528. package/build/schema/resolve-schema-lib.d.ts +0 -12
  529. package/build/schema/resolve-schema-lib.js +0 -11
  530. package/build/schema/resolve-schema-lib.js.map +0 -1
  531. package/build/schema/resolve-schema-lib.test.js +0 -17
  532. package/build/schema/resolve-schema-lib.test.js.map +0 -1
  533. package/build/schema/types.d.ts +0 -8
  534. package/build/schema/types.js +0 -2
  535. package/build/stack-utils.d.ts +0 -25
  536. package/build/stack-utils.js.map +0 -1
  537. package/build/stack-utils.test.js.map +0 -1
  538. package/build/types.d.ts +0 -142
  539. package/build/types.js +0 -2
  540. package/build/types.js.map +0 -1
  541. package/docs/decisions/2026-06-02-monorepo-split-evaluation.md +0 -80
  542. package/docs/handoffs/2026-06-08-dx-round2-declines.md +0 -45
  543. package/docs/handoffs/ajsc-named-type-collision.md +0 -134
  544. package/docs/handoffs/ajsc-named-type-support.md +0 -181
  545. package/docs/handoffs/shared-models-auto-resolve-response.md +0 -181
  546. package/docs/npm-workspaces-migration-plan.md +0 -611
  547. package/docs/superpowers/plans/2026-04-24-doc-registry-simplification.md +0 -886
  548. package/docs/superpowers/plans/2026-04-24-kotlin-codegen-target.md +0 -1265
  549. package/docs/superpowers/plans/2026-04-25-ajsc-v7-kotlin-polish.md +0 -1993
  550. package/docs/superpowers/plans/2026-04-29-safe-result-api.md +0 -2293
  551. package/docs/superpowers/plans/2026-05-07-astro-adapter.md +0 -1391
  552. package/docs/superpowers/plans/2026-05-08-create-http.md +0 -3355
  553. package/docs/superpowers/plans/2026-05-08-hono-app-builder-convergence.md +0 -3365
  554. package/docs/superpowers/plans/2026-06-05-dx-feedback-round.md +0 -1292
  555. package/docs/superpowers/plans/2026-06-06-shared-models-convention-and-diagnostics.md +0 -659
  556. package/docs/superpowers/plans/2026-06-08-codegen-dx-surfacing.md +0 -428
  557. package/docs/superpowers/specs/2026-04-24-kotlin-swift-codegen-design.md +0 -401
  558. package/docs/superpowers/specs/2026-04-25-ajsc-v7-kotlin-polish-design.md +0 -314
  559. package/docs/superpowers/specs/2026-04-25-swift-codegen-design.md +0 -264
  560. package/docs/superpowers/specs/2026-04-29-safe-result-api-design.md +0 -324
  561. package/docs/superpowers/specs/2026-05-07-astro-adapter-design.md +0 -252
  562. package/docs/superpowers/specs/2026-05-08-create-http-design.md +0 -409
  563. package/docs/superpowers/specs/2026-05-08-hono-app-builder-convergence-design.md +0 -411
  564. package/docs/superpowers/specs/2026-06-05-dx-feedback-round-design.md +0 -285
  565. package/docs/superpowers/specs/2026-06-08-dx-feedback-round-2-design.md +0 -376
  566. package/src/create-http-stream.ts +0 -191
  567. package/src/create-http.ts +0 -210
  568. package/src/create-stream.ts +0 -228
  569. package/src/create.ts +0 -172
  570. package/src/implementations/http/README.md +0 -390
  571. package/src/implementations/http/error-dispatch.test.ts +0 -283
  572. package/src/implementations/http/error-dispatch.ts +0 -176
  573. package/src/implementations/http/hono/handlers/http-stream.ts +0 -152
  574. package/src/implementations/http/hono/handlers/http.ts +0 -145
  575. package/src/implementations/http/hono/handlers/rpc.ts +0 -54
  576. package/src/implementations/http/hono/path.test.ts +0 -96
  577. package/src/index.ts +0 -101
  578. package/src/schema/extract-json-schema.test.ts +0 -25
  579. package/src/schema/extract-json-schema.ts +0 -15
  580. package/src/schema/parser.test.ts +0 -182
  581. package/src/schema/parser.ts +0 -265
  582. package/src/schema/resolve-schema-lib.test.ts +0 -19
  583. package/src/schema/resolve-schema-lib.ts +0 -29
  584. package/src/schema/types.ts +0 -20
  585. package/src/types.ts +0 -133
  586. /package/build/{implementations/http → adapters}/astro/astro-context.d.ts +0 -0
  587. /package/build/{implementations/http → adapters}/astro/astro-context.js +0 -0
  588. /package/build/{implementations/http → adapters}/astro/create-handler.d.ts +0 -0
  589. /package/build/{implementations/http → adapters}/astro/create-handler.js +0 -0
  590. /package/build/{implementations/http → adapters}/astro/index.d.ts +0 -0
  591. /package/build/{implementations/http → adapters}/astro/index.js +0 -0
  592. /package/build/{implementations/http → adapters}/astro/index.test.d.ts +0 -0
  593. /package/build/{implementations/http → adapters}/astro/rewrite-request.d.ts +0 -0
  594. /package/build/{implementations/http → adapters}/astro/rewrite-request.js +0 -0
  595. /package/build/{create-http-stream.test.d.ts → adapters/hono/envelope-parity.test.d.ts} +0 -0
  596. /package/build/{implementations/http → adapters}/hono/handlers/http-stream.test.d.ts +0 -0
  597. /package/build/{implementations/http → adapters}/hono/handlers/http.test.d.ts +0 -0
  598. /package/build/{implementations/http → adapters}/hono/handlers/rpc.test.d.ts +0 -0
  599. /package/build/{implementations/http → adapters}/hono/handlers/stream.test.d.ts +0 -0
  600. /package/build/{implementations/http → adapters}/hono/index.test.d.ts +0 -0
  601. /package/build/{implementations/http → adapters/hono}/on-request-error.test.d.ts +0 -0
  602. /package/build/{implementations/http → adapters/hono}/route-errors.test.d.ts +0 -0
  603. /package/build/{create-http.test.d.ts → client/freeze.test.d.ts} +0 -0
  604. /package/build/{create-stream.test.d.ts → codegen/goldens.test.d.ts} +0 -0
  605. /package/build/{create.test.d.ts → core/create-http-stream.test.d.ts} +0 -0
  606. /package/build/{doc-envelope.test.d.ts → core/create-http.test.d.ts} +0 -0
  607. /package/build/{errors.test.d.ts → core/create-stream.test.d.ts} +0 -0
  608. /package/build/{implementations/http/doc-registry.test.d.ts → core/create.test.d.ts} +0 -0
  609. /package/build/{implementations/http/error-dispatch.test.d.ts → core/definition-site.test.d.ts} +0 -0
  610. /package/build/{implementations/http/error-taxonomy.test.d.ts → core/errors.test.d.ts} +0 -0
  611. /package/build/{errors.test.js → core/errors.test.js} +0 -0
  612. /package/build/{implementations/http/hono/path.test.d.ts → core/factory-options.test.d.ts} +0 -0
  613. /package/build/{migration.test.d.ts → core/migration.test.d.ts} +0 -0
  614. /package/build/{index.test.d.ts → core/procedures.test.d.ts} +0 -0
  615. /package/build/{implementations/http/hono → core}/types.js +0 -0
  616. /package/build/schema/{extract-json-schema.test.d.ts → adapter.test.d.ts} +0 -0
  617. /package/build/schema/{parser.test.d.ts → compile.test.d.ts} +0 -0
  618. /package/build/schema/{resolve-schema-lib.test.d.ts → typebox.test.d.ts} +0 -0
  619. /package/build/{stack-utils.test.d.ts → server/context.test.d.ts} +0 -0
  620. /package/build/{doc-envelope.js → server/doc-envelope.js} +0 -0
  621. /package/build/{doc-envelope.test.js → server/doc-envelope.test.js} +0 -0
  622. /package/build/{implementations → server}/types.js +0 -0
  623. /package/src/{implementations/http → adapters}/astro/README.md +0 -0
  624. /package/src/{implementations/http → adapters}/astro/astro-context.ts +0 -0
  625. /package/src/{implementations/http → adapters}/astro/create-handler.ts +0 -0
  626. /package/src/{implementations/http → adapters}/astro/index.ts +0 -0
  627. /package/src/{implementations/http → adapters}/astro/rewrite-request.ts +0 -0
package/README.md CHANGED
@@ -1,146 +1,211 @@
1
1
  # ts-procedures
2
2
 
3
- A TypeScript RPC framework that creates type-safe, schema-validated procedure calls with a single function definition. Define your procedures once and get full type inference, runtime validation and procedure documentation/configuration.
3
+ A TypeScript RPC framework that creates type-safe, schema-validated procedure
4
+ calls from a single function definition. Define procedures once on the server
5
+ and get full type inference, runtime validation, HTTP serving, and generated
6
+ clients (TypeScript, Kotlin, Swift) — with typed errors end to end.
4
7
 
5
- ## Goals of this Project
6
-
7
- 1. Full type safety
8
- 2. Auto generated documentation and client api spec
9
- 3. Fast and performant
10
- 4. Excellent DX (and agent documentation)
8
+ ```ts
9
+ import { Type } from 'typebox'
10
+ import { Procedures } from 'ts-procedures'
11
11
 
12
+ type Ctx = { db: Db }
13
+ const { Create } = Procedures<Ctx>()
12
14
 
13
- ## Installation
15
+ export const { GetUser } = Create(
16
+ 'GetUser',
17
+ {
18
+ schema: {
19
+ params: Type.Object({ id: Type.String() }),
20
+ returnType: Type.Object({ id: Type.String(), name: Type.String() }),
21
+ },
22
+ },
23
+ async (ctx, params) => {
24
+ const user = await ctx.db.users.find(params.id)
25
+ if (!user) throw ctx.error('User not found', { id: params.id })
26
+ return user
27
+ },
28
+ )
14
29
 
15
- ```bash
16
- npm install ts-procedures
30
+ // Directly callable (great for tests), fully typed:
31
+ await GetUser({ db }, { id: 'u1' })
17
32
  ```
18
33
 
19
- The core package is dependency-light and the integrations are **optional** —
20
- install only what each one needs:
34
+ ## The four procedure kinds
21
35
 
22
- | You're using | Also install | Imported from |
36
+ | Creator | Kind | Shape |
23
37
  |---|---|---|
24
- | Core procedures, schema, client, codegen | _(nothing extra)_ | `ts-procedures`, `ts-procedures/client`, `ts-procedures/codegen` |
25
- | Hono server integration | `npm install hono` | `ts-procedures/hono` |
26
- | Astro adapter | `npm install astro hono` | `ts-procedures/astro` |
27
- | Kotlin / Swift codegen targets | `npm install ajsc` | `ts-procedures-codegen --target kotlin\|swift` |
38
+ | `Create` | `rpc` | `(ctx, params) => Promise<T>` POST, body in/JSON out |
39
+ | `CreateStream` | `rpc-stream` | async generator SSE (or text) stream |
40
+ | `CreateHttp` | `http` | REST route with per-channel input (`pathParams`, `query`, `body`, `headers`) |
41
+ | `CreateHttpStream` | `http-stream` | REST route streaming SSE, optional initial headers |
28
42
 
29
- `hono`, `astro`, and `ajsc` are declared as `optionalDependencies`, so a plain
30
- `npm install ts-procedures` never pulls them and the package is marked
31
- `sideEffects: false`, so bundlers tree-shake away any subpath you don't import.
32
-
33
- ## Quick Start
34
-
35
- ```typescript
36
- import { Procedures } from 'ts-procedures'
37
- import { Type } from 'typebox'
43
+ Every creator returns `{ [name]: handler, procedure: handler, info }`: the
44
+ named handler for direct calls, and `info` for introspection (computed JSON
45
+ Schema, validators, your extended config).
38
46
 
39
- // Create a procedures factory
40
- const { Create } = Procedures()
47
+ ```ts
48
+ const { CreateHttp } = Procedures<Ctx>({ http: { pathPrefix: '/v1', scope: 'users' } })
41
49
 
42
- // Define a procedure with schema validation
43
- const { GetUser, procedure, info } = Create(
44
- 'GetUser',
50
+ export const { UpdateUser } = CreateHttp(
51
+ 'UpdateUser',
45
52
  {
46
- description: 'Fetches a user by ID',
53
+ path: '/users/:id',
54
+ method: 'put',
55
+ errors: ['NotFound'], // taxonomy keys → typed client errors
47
56
  schema: {
48
- params: Type.Object({ userId: Type.String() }),
49
- returnType: Type.Object({ id: Type.String(), name: Type.String() }),
57
+ req: {
58
+ pathParams: Type.Object({ id: Type.String() }),
59
+ body: Type.Object({ name: Type.String() }),
60
+ },
61
+ res: { body: Type.Object({ id: Type.String(), name: Type.String() }) },
50
62
  },
51
63
  },
52
- async (ctx, params /* typed as { userId: string } */) => {
53
-
54
- // returnType is inferred as { id: string; name: string }
55
- return { id: params.userId, name: 'John Doe' }
56
- },
64
+ async (ctx, req) => ctx.db.users.update(req.pathParams.id, req.body),
57
65
  )
58
-
59
- // Call the procedure directly
60
- const user = await GetUser({}, { userId: '123' })
61
- // Or use the generic reference
62
- const user2 = await procedure({}, { userId: '456' })
63
66
  ```
64
67
 
65
- ## v8 Migration Unified `HonoAppBuilder`
68
+ ## Serving over HTTP (Hono)
66
69
 
67
- The three Hono builders (`HonoRPCAppBuilder`, `HonoAPIAppBuilder`, `HonoStreamAppBuilder`) are replaced in v8 by a single `HonoAppBuilder` that accepts any `Procedures<>()` factory and dispatches all four procedure kinds (`rpc`, `rpc-stream`, `http`, `http-stream`) by `procedure.kind` from a single `register()` call.
70
+ ```ts
71
+ import { Hono } from 'hono'
72
+ import { HonoAppBuilder, defineErrorTaxonomy } from 'ts-procedures/hono'
68
73
 
69
- ```typescript
70
- // Before (v7)
71
- const rpc = new HonoRPCAppBuilder({ app, errors }).register(F1, ctx1)
72
- const api = new HonoAPIAppBuilder({ app, errors, queryParser }).register(F2, ctx2)
73
- const stream = new HonoStreamAppBuilder({ app, errors, onMidStreamError }).register(F3, ctx3)
74
+ const errors = defineErrorTaxonomy({
75
+ NotFound: { class: NotFoundError, statusCode: 404 },
76
+ })
74
77
 
75
- // After (v8)
76
- const builder = new HonoAppBuilder({
77
- app,
78
- errors,
79
- api: { queryParser },
80
- stream: { onMidStreamError },
81
- }).register(F1, ctx1).register(F2, ctx2).register(F3, ctx3)
78
+ const builder = new HonoAppBuilder({ pathPrefix: '/api', errors })
79
+ .register(factory, (c) => ({ db: makeDb(c) })) // context per request (sync or async)
80
+
81
+ const app = builder.build() // a Hono app — mount anywhere Hono runs
82
82
  ```
83
83
 
84
- Kind-specific config knobs are stratified into `rpc.*`, `api.*`, and `stream.*` blocks. Single-app users can call `builder.toDocEnvelope()` directly (no `DocRegistry` needed). `DocRegistry` remains for multi-app aggregation.
84
+ One builder serves all four kinds. Config is stratified: kind-specific blocks
85
+ (`rpc.onSuccess`, `api.queryParser`, `stream.defaultStreamMode` /
86
+ `onStreamStart` / `onStreamEnd` / `onMidStreamError`) plus cross-cutting
87
+ error handling (`errors` taxonomy, `unknownError`, imperative `onError`,
88
+ `onRequestError` observer) and lifecycle (`onRequestStart/End`).
85
89
 
86
- Subpath imports change from `ts-procedures/hono-rpc`, `ts-procedures/hono-api`, `ts-procedures/hono-stream` to `ts-procedures/hono`.
90
+ An Astro adapter ships too: `createAstroHandler` from `ts-procedures/astro`
91
+ serves built Hono apps from an Astro catch-all route.
87
92
 
88
- ## HTTP Routes (v8) — `CreateHttp`
93
+ ### Error taxonomy
89
94
 
90
- v8 introduces `CreateHttp` and `CreateHttpStream` as first-class HTTP creators. HTTP fields (`path`, `method`, `scope`, `errors`) live on the creator config directly; no factory type parameter is required.
95
+ Declarative, typo-proof error handling: map error classes (or predicates) to
96
+ status codes and wire bodies once, and the same source of truth drives runtime
97
+ responses, envelope docs, and generated typed client errors.
91
98
 
92
- ```typescript
93
- import { Procedures } from 'ts-procedures'
94
- import { HonoAppBuilder } from 'ts-procedures/hono'
95
- import { Type } from 'typebox'
99
+ ```ts
100
+ const errors = defineErrorTaxonomy({
101
+ NotFound: { class: NotFoundError, statusCode: 404 },
102
+ UseCase: { class: UseCaseError, statusCode: 422, toResponse: (e) => ({ message: e.publicMessage }) },
103
+ PgUnique: { match: (e): e is DatabaseError => isPgError(e, '23505'), statusCode: 409 },
104
+ })
105
+ ```
96
106
 
97
- type AppContext = { userId: string }
98
- const API = Procedures<AppContext>()
99
-
100
- // Input channels: pathParams, query, body, headers (schema.req)
101
- // Response: schema.res.body (docs) + schema.res.headers (makes handler return { body, headers })
102
- API.CreateHttp('GetUser', {
103
- path: '/users/:id',
104
- method: 'get',
105
- schema: {
106
- req: { pathParams: Type.Object({ id: Type.String() }) },
107
- res: { body: Type.Object({ id: Type.String(), name: Type.String() }) },
108
- },
109
- }, async (ctx, { pathParams }) => fetchUser(pathParams.id))
107
+ Subclasses are checked before base classes automatically (topological sort);
108
+ `{ name }` is injected into bodies so client dispatch always works; framework
109
+ defaults (`ProcedureValidationError` → 400, etc.) layer underneath yours.
110
110
 
111
- API.CreateHttp('CreateUser', {
112
- path: '/users',
113
- method: 'post',
114
- schema: {
115
- req: { body: Type.Object({ name: Type.String(), email: Type.String() }) },
116
- },
117
- }, async (ctx, { body }) => createUser(body))
111
+ ## Generated clients
118
112
 
119
- const app = new HonoAppBuilder({ pathPrefix: '/api' })
120
- .register(API, (c) => ({ userId: c.req.header('x-user-id') || 'anonymous' }))
121
- .build()
122
- // GET /api/users/:id → 200, POST /api/users → 201
123
- ```
113
+ Codegen consumes a `DocEnvelope` from a live URL or a file written with
114
+ `writeDocEnvelope(builder, 'envelope.json')`:
124
115
 
125
- **Migrating from v7?** Replace `Procedures<Ctx, APIConfig>()` → `Procedures<Ctx>()`, `.Create(` → `.CreateHttp(`, and `schema.input` → `schema.req`. Then re-run `npx ts-procedures-codegen`. See `CHANGELOG.md` for the full breaking-changes list.
116
+ ```bash
117
+ npx ts-procedures-codegen --url http://localhost:3000/api/docs --out src/generated
118
+ # or offline:
119
+ npx ts-procedures-codegen --file envelope.json --out src/generated
120
+ ```
126
121
 
127
- ## Features
122
+ ```ts
123
+ import { createApiClient } from './generated'
128
124
 
129
- - **[Core Procedures](docs/core.md)** Type-safe procedure definitions with `Procedures()`, `Create`, `CreateHttp`, and `CreateStream`. Includes schema validation with TypeBox, error handling, generics, testing patterns, and the full API reference.
125
+ const api = createApiClient({ basePath: 'https://api.example.com' })
130
126
 
131
- - **[Streaming](docs/streaming.md)** Async generator procedures with yield validation, abort signal integration, SSE examples, and stream error handling. `CreateHttpStream` supports response headers via `TypedStream.headers`.
127
+ const user = await api.users.GetUser({ id: 'u1' }) // throws typed errors
128
+ const result = await api.users.GetUser.safe({ id: 'u1' }) // Result<T, E> instead
132
129
 
133
- - **[HTTP Integrations](docs/http-integrations.md)** `HonoAppBuilder` with lifecycle hooks, route documentation, `DocRegistry` for composing docs, and per-channel input validation via `schema.req`.
130
+ for await (const event of api.users.WatchUsers({})) { ... } // TypedStream
131
+ ```
134
132
 
135
- - **[Client Code Generation](docs/client-and-codegen.md)** Generate type-safe client SDKs from your server's `DocRegistry`. CLI and programmatic API, adapters, hooks, streaming support, and self-contained mode.
133
+ - **Typed errors:** routes declaring `errors: [...]` get real error classes
134
+ `catch (e) { if (e instanceof ApiErrors.NotFound) ... }` — plus a named
135
+ `Errors` union per route.
136
+ - **Self-contained by default:** the generated directory bundles its own
137
+ runtime (`_client.ts` / `_types.ts`); no runtime dependency on this package.
138
+ - **Shared models:** schemas carrying `$id` are hoisted once into `_models.ts`
139
+ (or re-exported from your own package via `--shared-models-module`).
140
+ - **Kotlin / Swift:** `--target kotlin --kotlin-package com.example.api` or
141
+ `--target swift` emit types + route constants/path builders for mobile teams
142
+ (they own the HTTP layer).
143
+ - Watch mode, config file (`ts-procedures-codegen.config.json`), strict flags
144
+ with did-you-mean, orphaned-file pruning — see `npx ts-procedures-codegen --help`.
145
+
146
+ ## Validation & schemas
147
+
148
+ - TypeBox is built in (`import { Type } from 'typebox'`); `schema.params` /
149
+ `schema.req.*` are validated at runtime with AJV (`allErrors`, `coerceTypes`,
150
+ `removeAdditional`); `schema.returnType` / `schema.res` document and drive
151
+ codegen.
152
+ - Customize AJV per factory: `Procedures({ validation: { ajv: {...} } })`.
153
+ - Skip per-call validation for trusted internal factories:
154
+ `Procedures({ validation: false })` (schemas still computed; bad schemas
155
+ still fail fast at registration).
156
+ - Plug in another schema library with a 3-line `SchemaAdapter`
157
+ (`Procedures({ schema: { adapters: [zodAdapter] } })`).
158
+
159
+ ## Streaming
160
+
161
+ Stream handlers always receive `ctx.signal` — it aborts on client disconnect,
162
+ and with reason `'stream-completed'` on normal completion. Yields become SSE
163
+ events (customize with `sse(data, { event, id, retry })`); the generator's
164
+ return value arrives as the `event: 'return'` payload, surfaced by generated
165
+ clients as `await stream.result`. Opt into per-yield validation with
166
+ `validateYields: true`.
167
+
168
+ ## Build your own server adapter
169
+
170
+ Everything the Hono adapter uses lives in `ts-procedures/server`, framework-free:
171
+ route-doc builders, taxonomy dispatch (data in, data out), request channel
172
+ extraction (`RequestSource`), SSE metadata, `DocRegistry`. A Fastify or Express
173
+ adapter is a few thin handlers — `src/adapters/hono/` is the reference
174
+ implementation.
175
+
176
+ ## Subpaths
177
+
178
+ | Import | Contents |
179
+ |---|---|
180
+ | `ts-procedures` | `Procedures`, error classes, schema utilities, `writeDocEnvelope` |
181
+ | `ts-procedures/hono` | `HonoAppBuilder`, `defineErrorTaxonomy`, `sse`, `DocRegistry` |
182
+ | `ts-procedures/astro` | `createAstroHandler`, `getAstroContext` |
183
+ | `ts-procedures/server` | Transport-agnostic adapter toolkit |
184
+ | `ts-procedures/http` | HTTP doc/config types (type-only) |
185
+ | `ts-procedures/http-docs` | `DocRegistry` |
186
+ | `ts-procedures/http-errors` | Error taxonomy helpers |
187
+ | `ts-procedures/client` | Runtime client (`createClient`, adapters, hooks, errors) |
188
+ | `ts-procedures/codegen` | `generateClient` programmatic API |
189
+
190
+ ## AI assistant setup
191
+
192
+ The package ships rules and skills for Claude Code, Cursor, and GitHub
193
+ Copilot so your AI tooling knows the framework's patterns and footguns:
136
194
 
137
- - **[Typed Error Handling](docs/http-integrations.md#error-handling)** — Declarative `defineErrorTaxonomy` maps thrown error classes to HTTP responses across every builder; generated clients throw typed class instances you can catch with `instanceof`.
195
+ ```bash
196
+ npx ts-procedures-setup # all targets
197
+ npx ts-procedures-setup claude # Claude Code only
198
+ npx ts-procedures-setup --dry-run # preview
199
+ ```
138
200
 
139
- - **[Client Error Handling](docs/client-error-handling.md)** Normalized framework error classes (`ClientHttpError`, `ClientNetworkError`, `ClientTimeoutError`, `ClientAbortError`, `ClientParseError`), `.safe()` Result API for exhaustive narrowing without try/catch, and augmentable `ClientErrorMap` for custom error categories.
201
+ Installed files auto-update on subsequent `npm install` via the package's
202
+ postinstall hook.
140
203
 
141
- - **[AI Agent Setup](docs/ai-agent-setup.md)** — Built-in configuration for Claude Code, Cursor, and GitHub Copilot. Auto-updates on `npm install`.
204
+ ## Migrating from v8
142
205
 
143
- Full documentation is available on [GitHub](https://github.com/thermsio/ts-procedures).
206
+ Generated client output is byte-identical to v8.6.0 — consumers have nothing
207
+ to do. Server-side breaking changes are small and mechanical; see
208
+ [docs/migration-v8-to-v9.md](docs/migration-v8-to-v9.md).
144
209
 
145
210
  ## License
146
211
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "ts-procedures",
3
- "version": "1.1.0",
3
+ "version": "9.0.0",
4
4
  "description": "AI coding assistant plugin for ts-procedures — a TypeScript RPC framework for type-safe, schema-validated procedure calls with automatic validation, streaming support, and HTTP framework integrations."
5
5
  }
@@ -32,14 +32,16 @@ When asked to plan an API or procedure set:
32
32
  - Handlers receive `(ctx, params)` where ctx includes base context + `error()` function + optional `signal`.
33
33
  - Stream handlers always get `ctx.signal` (guaranteed `AbortSignal`). Standard handlers get it when provided by the HTTP implementation.
34
34
  - Pass `signal` to all downstream async calls (fetch, database queries) for cancellation support.
35
- - `onCreate` callback on the factory enables framework integration — use it for route registration, middleware setup, or documentation generation.
35
+ - `onCreate` callback on the factory enables framework integration — use it for route registration, middleware setup, or documentation generation. Every registration carries a `kind` discriminant (`'rpc' | 'rpc-stream' | 'http' | 'http-stream'`). For a full custom server adapter, build on the transport-agnostic `ts-procedures/server` toolkit (route-doc builders, error dispatch, request channel extraction, SSE sequencing).
36
36
  - `getProcedures()` returns all registered procedures for introspection (OpenAPI generation, testing, etc.).
37
- - AJV is configured with `allErrors: true`, `coerceTypes: true`, `removeAdditional: true`.
38
- - `schema.params` and `schema.input` are mutually exclusivedefining both throws `ProcedureRegistrationError`.
39
- - Path param names in route template (`:id`) must match `schema.input.pathParams` property names.
37
+ - AJV is configured with `allErrors: true`, `coerceTypes: true`, `removeAdditional: true` — customizable per factory via `Procedures({ validation: { ajv } })`; `validation: false` skips per-call validation for trusted internal factories only.
38
+ - TypeBox is the built-in schema library; other libraries plug in via `Procedures({ schema: { adapters: [SchemaAdapter] } })` (runtime validation + docs only `Infer<T>` works only for TypeBox).
39
+ - `Procedures({ http: { pathPrefix, scope } })` sets factory-level defaults for `CreateHttp` / `CreateHttpStream` routes (per-route values win).
40
+ - `schema.params` and `schema.req` are mutually exclusive — defining both throws `ProcedureRegistrationError`.
41
+ - Path param names in route template (`:id`) must match `schema.req.pathParams` property names.
40
42
  - Use `DocRegistry` to compose route docs from multiple builders — never manually wire `/docs` endpoints. Pass your taxonomy directly: `new DocRegistry({ errors: appErrors })` — framework defaults are auto-merged and deduped. For errors outside your taxonomy (middleware, infrastructure, doc-only), chain `.documentError(...docs)`.
41
43
  - Two first-class peer error-handling modes: **declarative taxonomy** (`defineErrorTaxonomy` + `errors` config) OR **imperative callback** (`onError`). Neither is deprecated. Pick the taxonomy for structured apps with typed client dispatch; pick `onError` for simple apps or full response control. Mixing both is allowed — the taxonomy handles what it covers, `onError` handles the tail. The anti-pattern is `instanceof` ladders inside `onError` (see anti-pattern #20 in the skill reference) — that's exactly what the taxonomy expresses declaratively.
42
- - Per-route `errors: ['UseCaseError', ...]` narrows typed errors on the generated client. Declare via `APIConfig<keyof typeof appErrors & string>` / `RPCConfig<keyof typeof appErrors & string>` for compile-time typo protection.
44
+ - Per-route `errors: ['UseCaseError', ...]` narrows typed errors on the generated client. For compile-time typo protection, narrow `RPCConfig<keyof typeof appErrors & string>` on RPC factories; on `CreateHttp` routes attach `satisfies (keyof typeof appErrors & string)[]` to the `errors` array (an explicit generic would bind `TName` and break `schema.req`/`schema.res` inference).
43
45
  - Generated `_errors.ts` emits real runtime classes extending `${Service}ProcedureError` — consumers catch with `instanceof ${Service}Errors.${Name}` and access `err.body`, `err.status`, `err.procedureName`, `err.scope`. Use the generated `create${Service}Client(config)` factory to wire the error registry automatically.
44
46
 
45
47
  ## Context Design Patterns
@@ -66,11 +68,10 @@ interface AppConfig extends RPCConfig {
66
68
  version: number
67
69
  }
68
70
 
69
- // REST-style: path + method (required for API builder)
70
- interface AppConfig extends APIConfig {
71
- path: string
72
- method: HttpMethod
73
- }
71
+ // REST-style: no extended config needed — path, method, scope, errors are
72
+ // first-class fields on the CreateHttp / CreateHttpStream config itself.
73
+ const API = Procedures<AppContext>()
74
+ API.CreateHttp('GetUser', { path: '/users/:id', method: 'get', schema: { /* req/res */ } }, handler)
74
75
  ```
75
76
 
76
77
  ## Output Format
@@ -39,7 +39,7 @@ This skill has three modes, selected by the **first whitespace-delimited word of
39
39
  Load the right reference for your task:
40
40
 
41
41
  - **Writing new procedures or HTTP routes?** Read [patterns.md](patterns.md) — prescribed code examples for every procedure type and HTTP integration
42
- - **Reviewing or debugging existing code?** Read [anti-patterns.md](anti-patterns.md) — 20 common mistakes with before/after fixes and severity ratings
42
+ - **Reviewing or debugging existing code?** Read [anti-patterns.md](anti-patterns.md) — 23 common mistakes with before/after fixes and severity ratings
43
43
  - **Need exact API signatures or type definitions?** Read [api-reference.md](api-reference.md) — complete API documentation with type signatures for every export
44
44
  - **Generating a Kotlin client for Android/JVM consumers?** See the **Kotlin Client Codegen** section below — it covers `--target kotlin` end-to-end.
45
45
  - **Generating a Swift client for iOS/macOS/Apple-platform consumers?** See the **Swift Client Codegen** section below — it covers `--target swift` end-to-end.
@@ -47,7 +47,7 @@ Load the right reference for your task:
47
47
  ## Core Flow
48
48
 
49
49
  ```
50
- Procedures<TContext, TExtendedConfig>(builder?)
50
+ Procedures<TContext, TExtendedConfig>(options?)
51
51
  |
52
52
  Create(name, config, handler) --> Standard async procedure
53
53
  CreateStream(name, config, handler) --> Streaming async generator
@@ -58,21 +58,29 @@ Returns: { [name]: handler, procedure: handler, info: metadata }
58
58
  ## Factory API
59
59
 
60
60
  ```typescript
61
- const { Create, CreateStream, getProcedures, getProcedure, removeProcedure, clear } =
61
+ const { Create, CreateStream, CreateHttp, CreateHttpStream, getProcedures, getProcedure, removeProcedure, clear } =
62
62
  Procedures<TContext, TExtendedConfig>({
63
- onCreate: (procedure) => { /* called on each registration */ }
63
+ onCreate: (procedure) => { /* called on each registration — narrow on procedure.kind */ },
64
+ validation: false, // optional: skip per-call AJV (replaces v8 noRuntimeValidation)
65
+ // validation: { ajv: { coerceTypes: false } }, // or per-factory AJV options / instance
66
+ schema: { adapters: [myZodAdapter] }, // optional: plug in other schema libraries (TypeBox built in)
67
+ http: { pathPrefix: '/v1', scope: 'billing' }, // optional: CreateHttp/CreateHttpStream defaults (per-route wins)
64
68
  })
65
69
  ```
66
70
 
67
71
  | Method | Purpose |
68
72
  |--------|---------|
69
- | `Create(name, config, handler)` | Register standard async procedure |
70
- | `CreateStream(name, config, handler)` | Register streaming procedure (async generator) |
73
+ | `Create(name, config, handler)` | Register standard async procedure (`kind: 'rpc'`) |
74
+ | `CreateStream(name, config, handler)` | Register streaming procedure (async generator, `kind: 'rpc-stream'`) |
75
+ | `CreateHttp(name, config, handler)` | Register REST-style HTTP procedure (`kind: 'http'`) |
76
+ | `CreateHttpStream(name, config, handler)` | Register streaming HTTP procedure (`kind: 'http-stream'`) |
71
77
  | `getProcedures()` | Returns array of all registered procedures |
72
78
  | `getProcedure(name)` | Get single procedure by name |
73
79
  | `removeProcedure(name)` | Remove procedure by name |
74
80
  | `clear()` | Remove all procedures |
75
81
 
82
+ Every registration (and every creator's `info`) carries a `kind` discriminant: `'rpc' | 'rpc-stream' | 'http' | 'http-stream'`. Registering the same name twice throws `ProcedureRegistrationError`.
83
+
76
84
  ## Context
77
85
 
78
86
  Handlers receive `(ctx, params)` where ctx includes:
@@ -94,7 +102,9 @@ Uses **TypeBox** for schema definitions (`import { Type } from 'typebox'`):
94
102
  | `schema.yieldType` | Validated only if `validateYields: true` in CreateStream config |
95
103
  | `schema.req` | Structured multi-channel HTTP input (`pathParams`, `query`, `body`, `headers`) — available on `CreateHttp` / `CreateHttpStream` only |
96
104
 
97
- AJV config: `allErrors: true`, `coerceTypes: true`, `removeAdditional: true`
105
+ AJV config: `allErrors: true`, `coerceTypes: true`, `removeAdditional: true` — customizable per factory via `Procedures({ validation: { ajv } })` (options merged over the defaults, or a configured `Ajv` instance).
106
+
107
+ TypeBox is the only built-in schema library. Other libraries plug in via the 3-member `SchemaAdapter` interface (`{ name, detect, toJsonSchema }`) passed as `Procedures({ schema: { adapters: [...] } })` — custom adapters get runtime validation + docs, but compile-time inference (`Infer<T>`) works only for TypeBox.
98
108
 
99
109
  > **Composing schemas:** the bundled TypeBox does **not** export `Type.Composite`. Extend a schema with a flat property spread — `Type.Object({ ...Base.properties, name: Type.String() })` — which also keeps the generated JSON Schema a single `object` instead of an `allOf`.
100
110
 
@@ -108,7 +118,7 @@ AJV config: `allErrors: true`, `coerceTypes: true`, `removeAdditional: true`
108
118
  | `ProcedureRegistrationError` | Invalid schema at registration time | `procedureName`, `message` |
109
119
  | `${Service}ProcedureError` (generated, client) | Base class for all generated client error classes | `status`, `procedureName`, `scope`, `body` |
110
120
 
111
- All errors include `definedAt` (file:line:column) and enhanced stack traces pointing to the procedure definition location.
121
+ All errors include `definedAt` (file:line:column) and enhanced stack traces pointing to the procedure definition location. Every framework error also carries a `kind` discriminant (`'procedure' | 'validation' | 'yield-validation' | 'registration'`) as an alternative to `instanceof`.
112
122
 
113
123
  ## Error Taxonomy (HTTP builders)
114
124
 
@@ -136,6 +146,8 @@ Full contract: `docs/http-integrations.md § Error Handling` (canonical) and `ap
136
146
  | `HonoAppBuilder` | `ts-procedures/hono` | RPC, REST-style HTTP, and streaming (SSE / newline-JSON) — one builder dispatches all four procedure kinds |
137
147
  | `DocRegistry` | `ts-procedures/http-docs` | Compose route docs from multiple builders (single-app users can also call `builder.toDocEnvelope()`) |
138
148
 
149
+ Building on another framework (Fastify, Express, raw http, ...)? Use the transport-agnostic **`ts-procedures/server`** toolkit — route-doc builders, data-in/data-out error dispatch (`dispatchPreStreamError` / `dispatchMidStreamError`), `RequestSource` channel extraction, `SseEventSequencer`, `DocRegistry`. A custom adapter is ~4 thin handlers; `src/adapters/hono/` is the reference. See `api-reference.md § Server Toolkit`.
150
+
139
151
  ### Route Path Format (RPC)
140
152
 
141
153
  ```
@@ -154,7 +166,7 @@ const app = new HonoAppBuilder({ pathPrefix: '/api' })
154
166
 
155
167
  ### Lifecycle Hooks (HTTP builders)
156
168
 
157
- For `HonoAppBuilder` (v8), hooks are stratified: cross-cutting hooks live at the top level, kind-specific hooks live inside `rpc:` / `api:` / `stream:` blocks.
169
+ For `HonoAppBuilder`, hooks are stratified: cross-cutting hooks live at the top level, kind-specific hooks live inside `rpc:` / `api:` / `stream:` blocks.
158
170
 
159
171
  | Hook | Block | When |
160
172
  |------|-------|------|
@@ -203,7 +215,8 @@ The npm package ships user-facing documentation with narrative explanations and
203
215
  | `docs/client-error-handling.md` | **Canonical guide** for 7.0+ client error surface: normalized error classes, `.safe()` Result API, `ClientErrorMap` augmentation, custom `ErrorClassifier`, migration from `ClientRequestError`. |
204
216
  | `docs/codegen-kotlin.md` | Kotlin target consumer setup (Gradle deps, contextual serializers, sealed interfaces) |
205
217
  | `docs/codegen-swift.md` | Swift target consumer setup (SPM/Xcode integration, JSONDecoder config, discriminated unions, error dispatch patterns) |
206
- | `CHANGELOG.md` | Release notes see `[7.0.0]` for the safe-result API, new error classes, and `ClientRequestError` `ClientHttpError` rename. See `[6.0.0]` for the peer error-handling model (taxonomy + `onError` + `onRequestError`). |
218
+ | `docs/migration-v8-to-v9.md` | Every v8 v9 breaking change with before/after (`validation: false` replaces `noRuntimeValidation`, Suretype removal, `kind` discriminants, `ts-procedures/server`) |
219
+ | `CHANGELOG.md` | Release notes — see `[9.0.0]` for the factory options bag, `SchemaAdapter`, the `ts-procedures/server` toolkit, and SSE wire normalization. See `[7.0.0]` for the safe-result API, new error classes, and `ClientRequestError` → `ClientHttpError` rename. See `[6.0.0]` for the peer error-handling model (taxonomy + `onError` + `onRequestError`). |
207
220
 
208
221
  ## Workflow
209
222
 
@@ -222,9 +235,9 @@ Parse the remainder of `$ARGUMENTS` (everything after `review`) as a file or dir
222
235
  ### Instructions
223
236
 
224
237
  1. Read the target file(s).
225
- 2. Identify ts-procedures imports (`ts-procedures`, `ts-procedures/hono`, `ts-procedures/http`, `ts-procedures/http-docs`, `ts-procedures/http-errors`, `ts-procedures/client`, `ts-procedures/codegen`) to determine file types.
238
+ 2. Identify ts-procedures imports (`ts-procedures`, `ts-procedures/hono`, `ts-procedures/astro`, `ts-procedures/server`, `ts-procedures/http`, `ts-procedures/http-docs`, `ts-procedures/http-errors`, `ts-procedures/client`, `ts-procedures/codegen`) to determine file types.
226
239
  3. Check each file against the categorized checklist in [checklist.md](checklist.md).
227
- 4. For detailed code examples of each violation pattern, reference [anti-patterns.md](anti-patterns.md) — it shows 20 common mistakes with before/after code fixes and severity ratings.
240
+ 4. For detailed code examples of each violation pattern, reference [anti-patterns.md](anti-patterns.md) — it shows 23 common mistakes with before/after code fixes and severity ratings.
228
241
  5. Output findings grouped by severity.
229
242
 
230
243
  ### Output Format
@@ -397,7 +397,7 @@ Create('GetUser', {
397
397
  }, handler)
398
398
  ```
399
399
 
400
- **Why:** ts-procedures detects schema type via TypeBox's `~kind` symbol. Plain JSON Schema objects are not recognized and will throw `ProcedureRegistrationError`.
400
+ **Why:** ts-procedures detects schemas via the adapter chain — the built-in `typeboxAdapter` recognizes TypeBox's `~kind` marker. Plain JSON Schema objects are not recognized (no adapter matches) and will throw `ProcedureRegistrationError`. If you must use another schema library, register a custom `SchemaAdapter` via `Procedures({ schema: { adapters: [...] } })` instead of passing raw objects.
401
401
 
402
402
  ---
403
403
 
@@ -705,17 +705,17 @@ Or use the `.safe()` sibling for exhaustive Result-based narrowing (see `pattern
705
705
 
706
706
  ---
707
707
 
708
- ## 22. Using `noRuntimeValidation` on a public-facing factory
708
+ ## 22. Using `validation: false` on a public-facing factory
709
709
 
710
- **Problem:** Setting `Procedures({ config: { noRuntimeValidation: true } })` on a factory whose procedures are exposed via HTTP, mounted on a public surface, or invoked with caller-supplied JSON. Schema validation is the only thing standing between untyped wire data and your handlers — turning it off lets malformed payloads reach business logic.
710
+ **Problem:** Setting `Procedures({ validation: false })` (which replaces v8's `config: { noRuntimeValidation: true }`) on a factory whose procedures are exposed via HTTP, mounted on a public surface, or invoked with caller-supplied JSON. Schema validation is the only thing standing between untyped wire data and your handlers — turning it off lets malformed payloads reach business logic.
711
711
 
712
712
  ```typescript
713
713
  // BAD — these procedures are mounted on Hono and called by browsers
714
- const { Create } = Procedures({ config: { noRuntimeValidation: true } })
714
+ const { CreateHttp } = Procedures({ validation: false })
715
715
 
716
- const { CreateUser } = Create('CreateUser', {
716
+ const { CreateUser } = CreateHttp('CreateUser', {
717
717
  path: '/users', method: 'post',
718
- schema: { input: { body: Type.Object({ email: Type.String() }) } },
718
+ schema: { req: { body: Type.Object({ email: Type.String() }) } },
719
719
  }, async (ctx, { body }) => {
720
720
  // body.email is typed `string`, but at runtime it can be anything —
721
721
  // the request validator was disabled at the factory level.
@@ -730,12 +730,10 @@ const { CreateUser } = Create('CreateUser', {
730
730
  const { Create: CreatePublic } = Procedures()
731
731
 
732
732
  // GOOD — internal factory used only from already-validated callers
733
- const { Create: CreateInternal } = Procedures({
734
- config: { noRuntimeValidation: true },
735
- })
733
+ const { Create: CreateInternal } = Procedures({ validation: false })
736
734
  ```
737
735
 
738
- **Why:** `noRuntimeValidation` skips both `schema.params` and `schema.input` AJV runs for every procedure on the factory — there is no per-procedure escape hatch. TypeScript types still flow, but TS types vanish at runtime. AJV is also what enforces `coerceTypes` and `removeAdditional`; once disabled, extra wire fields will leak through and string/number coercion stops happening. The flag is only `true` (no `false`) because the safe default — validation on — should never be expressed by a config value at all; an unset config is the safe path.
736
+ **Why:** `validation: false` skips both `schema.params` and `schema.req` AJV runs for every procedure on the factory — there is no per-procedure escape hatch (JSON Schema and validators are still computed at registration, so bad schemas still fail fast). TypeScript types still flow, but TS types vanish at runtime. AJV is also what enforces `coerceTypes` and `removeAdditional`; once disabled, extra wire fields will leak through and string/number coercion stops happening. The safe default — validation on — is expressed by leaving the option unset; the only opt-out value is the explicit literal `false`.
739
737
 
740
738
  ---
741
739
 
@@ -800,9 +798,9 @@ API.CreateHttp('GetUser', {
800
798
  | 15 | Manual doc building instead of extendProcedureDoc | Fragile, incomplete documentation | SUGGESTION |
801
799
  | 16 | Manual /docs endpoint instead of DocRegistry | Duplicated boilerplate, missing error schemas | SUGGESTION |
802
800
  | 17 | Unhandled async context factory | Request crashes | WARNING |
803
- | 18 | Both schema.params and schema.input | ProcedureRegistrationError at startup | CRITICAL |
801
+ | 18 | Both schema.params and schema.req | ProcedureRegistrationError at startup | CRITICAL |
804
802
  | 19 | Mismatched path param names | Build-time error or confusing validation failures | CRITICAL |
805
803
  | 20 | Hand-writing onError instanceof ladders | Drifting response shapes, untyped client errors | WARNING |
806
804
  | 21 | Catching raw DOMException/TypeError from generated callables | Framework normalizes these; raw platform errors won't reach catch blocks after 7.0.0 | WARNING |
807
- | 22 | `noRuntimeValidation` on a public-facing factory | Untrusted wire data reaches handlers without AJV; coerceTypes/removeAdditional also disabled | CRITICAL |
805
+ | 22 | `validation: false` on a public-facing factory | Untrusted wire data reaches handlers without AJV; coerceTypes/removeAdditional also disabled | CRITICAL |
808
806
  | 23 | Using `Create` for HTTP routes (v8+) | ProcedureRegistrationError at startup; HTTP fields require `CreateHttp` / `CreateHttpStream` | CRITICAL |