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
@@ -0,0 +1,192 @@
1
+ # Migrating from v8 to v9
2
+
3
+ v9 is a ground-up restructuring of the library with one iron-clad guarantee:
4
+ **generated codegen output is byte-identical to v8.6.0** (TypeScript, Kotlin,
5
+ and Swift targets, every mode). If you consume a generated client, regenerating
6
+ with v9 produces the same files — nothing to migrate on the consumer side.
7
+
8
+ Server-side and tooling APIs have breaking changes, listed exhaustively below.
9
+
10
+ ## TL;DR checklist
11
+
12
+ | v8 | v9 |
13
+ |---|---|
14
+ | `Procedures({ config: { noRuntimeValidation: true } })` | `Procedures({ validation: false })` |
15
+ | Suretype schemas | Removed — use TypeBox (or a custom `SchemaAdapter`) |
16
+ | `import { HonoAppBuilder } from 'ts-procedures/hono'` | unchanged |
17
+ | `TStreamProcedureRegistration.isStream` | Removed — branch on `kind: 'rpc-stream'` |
18
+ | Duplicate-name registration threw `Error` | Throws `ProcedureRegistrationError` (same message) |
19
+ | `TSchemaLib<T>` | Still exported; `Infer<T>` is the new primary name |
20
+ | `extractJsonSchema(schema)` | `extractJsonSchema(schema, adapters)` — or just use the factory |
21
+ | `schemaParser(...)` | Removed — `computeSchema(name, schema, { adapters, compile })` |
22
+ | `isSuretypeSchema` | Removed |
23
+ | `ts-procedures/http` types (`RPCConfig`, `APIConfig`, doc shapes) | unchanged (moved internally to `server/types`, same subpath) |
24
+ | `dispatchPreStreamError` returned a Hono `Response` | Returns `{ type: 'body', statusCode, body }` \| `{ type: 'response', response }` — adapters translate |
25
+ | — | New: `ts-procedures/server` subpath (transport-agnostic adapter toolkit) |
26
+
27
+ ## Core factory
28
+
29
+ ### `Procedures()` options
30
+
31
+ The v8 `builder` argument (`{ config, onCreate }`) is replaced by a flat
32
+ options bag:
33
+
34
+ ```ts
35
+ // v8
36
+ const { Create } = Procedures<Ctx>({ config: { noRuntimeValidation: true }, onCreate })
37
+
38
+ // v9
39
+ const { Create } = Procedures<Ctx>({
40
+ validation: false, // replaces noRuntimeValidation: true
41
+ onCreate, // unchanged signature
42
+ })
43
+ ```
44
+
45
+ New options (no v8 equivalent):
46
+
47
+ ```ts
48
+ Procedures<Ctx>({
49
+ // Customize AJV (options merged over the defaults, or pass an Ajv instance)
50
+ validation: { ajv: { coerceTypes: false } },
51
+
52
+ // Plug in another schema library (TypeBox remains built-in)
53
+ schema: { adapters: [myZodAdapter] },
54
+
55
+ // Factory-level defaults for CreateHttp / CreateHttpStream
56
+ http: { pathPrefix: '/v1', scope: 'billing' },
57
+ })
58
+ ```
59
+
60
+ `validation: false` keeps v8's `noRuntimeValidation` semantics exactly:
61
+ schemas and validators are still computed at registration (bad schemas fail
62
+ fast); only the per-call validation runs are skipped. The per-call
63
+ `ctx.isPrevalidated` escape hatch is unchanged.
64
+
65
+ ### Suretype removed
66
+
67
+ Suretype support (deprecated through v8) is gone: no `isSuretypeSchema`, no
68
+ Suretype branch in type inference. Migrate schemas to TypeBox
69
+ (`import { Type } from 'typebox'`). If you must keep another schema library,
70
+ implement the new `SchemaAdapter` interface:
71
+
72
+ ```ts
73
+ import type { SchemaAdapter } from 'ts-procedures'
74
+
75
+ const zodAdapter: SchemaAdapter = {
76
+ name: 'zod',
77
+ detect: (s) => s instanceof z.ZodType,
78
+ toJsonSchema: (s) => z.toJSONSchema(s as z.ZodType),
79
+ }
80
+ ```
81
+
82
+ Note: compile-time inference (`Infer<T>`) is built in only for TypeBox; custom
83
+ adapters get runtime validation + docs.
84
+
85
+ ### Stream registrations
86
+
87
+ `isStream: true` is removed from `TStreamProcedureRegistration` and from
88
+ `CreateStream(...).info`. Branch on the `kind` discriminant
89
+ (`'rpc' | 'rpc-stream' | 'http' | 'http-stream'`), which exists since v8 —
90
+ and which every creator's `info` now also carries (v8 only put it on
91
+ `CreateHttpStream`'s info).
92
+
93
+ ### Duplicate names
94
+
95
+ Registering the same name twice now throws `ProcedureRegistrationError`
96
+ instead of a bare `Error`. The message is unchanged
97
+ (`Procedure with name <name> is already registered`), so message-based
98
+ assertions keep passing; `instanceof Error` also still holds.
99
+
100
+ ### Error classes
101
+
102
+ Same four classes, same constructor signatures, same `instanceof` hierarchy.
103
+ New: every framework error carries a `kind` field
104
+ (`'procedure' | 'validation' | 'yield-validation' | 'registration'`) as an
105
+ alternative to `instanceof`.
106
+
107
+ ## Schema utilities (low-level)
108
+
109
+ Most users never call these directly; the factory does.
110
+
111
+ - `schemaParser` is gone. Its behavior lives in
112
+ `computeSchema(name, schema, { adapters, compile, definitionInfo? })`, which
113
+ throws `ProcedureRegistrationError` instead of taking an `onParseError`
114
+ callback.
115
+ - `extractJsonSchema(schema, adapters)` now takes the adapter list explicitly
116
+ (e.g. `[typeboxAdapter]`).
117
+ - AJV is no longer a module-level singleton. `createValidatorCompiler()`
118
+ builds a per-factory compiler; defaults (`allErrors`, `coerceTypes`,
119
+ `removeAdditional`, ajv-formats) are unchanged.
120
+
121
+ ## HTTP server layer
122
+
123
+ ### Same surface, new home
124
+
125
+ `HonoAppBuilder` keeps its v8 public surface verbatim: constructor config
126
+ stratification (`rpc.*`, `api.*`, `stream.*`, `errors`, `unknownError`,
127
+ `onError`, `onRequestError`, `onRequestStart/End`, `pathPrefix`, `app`),
128
+ `register()`, lazy `docs`, `build()`, `toDocEnvelope()`, `skippedProcedures`,
129
+ static `makeRoutePath`, and the `sse()` helper re-export. Wire behavior
130
+ (routes, status codes, SSE events, error bodies) is unchanged — verified by an
131
+ envelope-parity test against a captured v8 envelope and by the ported v8 test
132
+ suite.
133
+
134
+ The machinery behind it moved into the new transport-agnostic
135
+ `ts-procedures/server` subpath: route-doc builders, error taxonomy + dispatch,
136
+ request channel extraction, SSE metadata, path resolution, `DocRegistry`,
137
+ `writeDocEnvelope`. The `ts-procedures/http-docs`, `ts-procedures/http-errors`,
138
+ and `ts-procedures/http` subpaths re-export the same names as v8.
139
+
140
+ ### Writing your own adapter (new capability)
141
+
142
+ v8's dispatch produced Hono `Response` objects; v9's is data-in/data-out:
143
+
144
+ ```ts
145
+ import {
146
+ dispatchPreStreamError, // → { type: 'body', statusCode, body } | { type: 'response', response }
147
+ dispatchMidStreamError, // → { data, sseEvent?, runOnCatch? }
148
+ extractReqChannels, // RequestSource → declared schema.req channels
149
+ resolveFactoryContext,
150
+ buildRpcRouteDoc, // + buildHttpRouteDoc / buildStreamRouteDoc / buildHttpStreamRouteDoc
151
+ } from 'ts-procedures/server'
152
+ ```
153
+
154
+ A Fastify/Express adapter is now ~4 thin handlers translating between the
155
+ framework's request/response/streaming primitives and these helpers — use
156
+ `src/adapters/hono/` as the blueprint. Only the taxonomy callbacks' `raw`
157
+ parameter is typed `unknown` at the server layer (it is your framework's
158
+ request context; cast in your adapter).
159
+
160
+ ### SSE wire normalization (behavior fix)
161
+
162
+ `rpc-stream` and `http-stream` routes now share one SSE sequencer, which
163
+ removed two v8 inconsistencies: `sse(data, { event, id, retry })` metadata is
164
+ now honored on `http-stream` yields and error events (v8 silently ignored it
165
+ there), and a `null` yield serializes as empty SSE data on both route kinds
166
+ (v8's `http-stream` sent the string `null`). Yield/return/error event names,
167
+ id sequencing, and the `event: 'return'` envelope are unchanged.
168
+
169
+ ### Astro adapter
170
+
171
+ Unchanged (`createAstroHandler`, `getAstroContext` from `ts-procedures/astro`).
172
+
173
+ ## Client runtime and codegen
174
+
175
+ - `ts-procedures/client`: identical to v8.6.0 — the runtime files are
176
+ content-frozen because self-contained codegen bundles them verbatim.
177
+ - `ts-procedures/codegen` + `npx ts-procedures-codegen`: same options, flags,
178
+ config file, watch mode, orphan pruning. Output is byte-identical to v8.6.0
179
+ except the version stamp in the generated header comment.
180
+
181
+ ## New in v9 (non-breaking)
182
+
183
+ - `Procedures({ http: { pathPrefix, scope } })` — factory-level defaults that
184
+ remove per-route boilerplate on `CreateHttp` / `CreateHttpStream`. The
185
+ prefix becomes part of the route's identity (it shows up in `config.path`
186
+ and route docs), unlike the builder-level `pathPrefix`, which is a
187
+ deployment mount point.
188
+ - `Procedures({ validation: { ajv } })` — per-factory AJV configuration.
189
+ - `Procedures({ schema: { adapters } })` — pluggable schema libraries.
190
+ - `ts-procedures/server` — the adapter toolkit described above.
191
+ - `Infer<T>` as the primary inference type (alias `TSchemaLib` retained).
192
+ - `ProcedureError.kind` discriminant.
@@ -0,0 +1,130 @@
1
+ # ts-procedures v9 Rewrite — Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Build `v9/` — a self-contained next-major `ts-procedures` package with redesigned core/schema/server layers and byte-identical codegen output, verified by goldens captured from the v8 build.
6
+
7
+ **Architecture:** Golden-anchored rewrite (spec: `v9/docs/specs/2026-06-09-v9-rewrite-design.md`). Output-producing layers (codegen emitters, bundled client runtime, DocEnvelope shape) are ported content-faithfully; core/schema/server are redesigned for DX and pluggability.
8
+
9
+ **Tech Stack:** TypeScript (ES2024, NodeNext, tsc build), vitest, AJV + ajv-formats, TypeBox, Hono (peer), ajsc ^7.3.0 (optional).
10
+
11
+ **Port convention:** Tasks marked **PORT** copy the named v8 file(s) under `src/…` into the v9 path, adjusting only import paths and (where stated) renames. Tasks marked **PORT-VERBATIM** must be byte-identical copies. Tasks marked **NEW** are TDD'd from the signatures given. Every task ends with `npx vitest run <file>` green and a commit.
12
+
13
+ ---
14
+
15
+ ## Phase 0 — Scaffold, baseline capture, client freeze
16
+
17
+ ### Task 0.1: Package scaffold
18
+ **Files:** Create `v9/package.json`, `v9/tsconfig.json`, `v9/vitest.config.ts`, `v9/eslint.config.js`, `v9/.gitignore` (`build/`, `node_modules/`).
19
+ - [ ] `package.json`: name `ts-procedures`, version `9.0.0`, `type: module`, same exports-map subpaths as v8 root `package.json:21-53` but pointing at v9 layout (`./hono` → `build/adapters/hono/index.js`, `./astro` → `build/adapters/astro/index.js`, `./http` → types-only `build/server/types.d.ts`, `./http-docs` → `build/server/doc-registry.js`, `./http-errors` → `build/server/errors/taxonomy.js`, `./client` → `build/client/index.js`, `./codegen` → `build/codegen/index.js`, plus new `./server` → `build/server/index.js`); bin `ts-procedures-codegen` → `build/codegen/bin/cli.js`; deps copied from root (ajv, ajv-formats, typebox; peer hono; optional ajsc ^7.3.0).
20
+ - [ ] `tsconfig.json` / `vitest.config.ts` / `eslint.config.js`: mirror root configs (rootDir `src`, outDir `build`).
21
+ - [ ] Verify root test runner does NOT pick up `v9/` (`cat vitest.config.ts` at root; if its include would match `v9/**`, add `v9/**` to root exclude — the only permitted root touch, justified by isolation).
22
+ - [ ] `cd v9 && npm install` succeeds. Commit: `chore(v9): package scaffold`.
23
+
24
+ ### Task 0.2: Client runtime freeze (PORT-VERBATIM)
25
+ **Files:** Copy all of root `src/client/*.ts` (10 runtime files + tests) → `v9/src/client/`.
26
+ - [ ] Copy files byte-identically (runtime files MUST not change — they are bundled into generated `_client.ts`/`_types.ts`).
27
+ - [ ] Create `v9/src/client/freeze.test.ts`: hashes the 10 runtime files (`errors.ts, classify-error.ts, error-dispatch.ts, request-builder.ts, resolve-options.ts, hooks.ts, call.ts, stream.ts, fetch-adapter.ts, index.ts, types.ts`) and compares to recorded v8 sha256 values, with a message explaining the bundling contract.
28
+ - [ ] `npx vitest run src/client` green (ported client tests + freeze test). Commit.
29
+
30
+ ### Task 0.3: Fixture envelopes
31
+ **Files:** Copy root `src/codegen/__fixtures__/users-envelope.json` → `v9/src/codegen/__fixtures__/`; Create `v9/src/codegen/__fixtures__/models-envelope.json`.
32
+ - [ ] `models-envelope.json`: hand-authored DocEnvelope (same shape) with ≥2 scopes, `$id`-bearing shared models used across scopes (to exercise `_models.ts`, `x-named-type` referencing, collision-free naming), route-level `errors`, an `http-stream` route, and ErrorDocs with schemas.
33
+ - [ ] Validate it loads through the **v8** pipeline: `node` one-liner calling root `build/codegen` `generateClient({ envelope, outDir, dryRun: true })` without error. Commit.
34
+
35
+ ### Task 0.4: Golden baseline capture from v8
36
+ **Files:** Create `v9/tools/capture-goldens.mjs`; output `v9/src/codegen/__goldens__/<case>/…`.
37
+ - [ ] Run `npm run build` at root (produces `build/codegen`).
38
+ - [ ] Script imports root `../build/codegen/index.js` and runs the 7-case matrix from the spec §2 (ts-default / ts-flat / ts-external-runtime / ts-no-share-models / ts-shared-models-module / kotlin-default / swift-default) over BOTH fixture envelopes (kotlin/swift only need users-envelope), writing every generated file under `__goldens__/<case>-<envelope>/`.
39
+ - [ ] Commit captured goldens: `test(v9): capture v8.6.0 codegen golden baselines`.
40
+
41
+ ### Task 0.5: Golden test harness
42
+ **Files:** Create `v9/src/codegen/goldens.test.ts`, `v9/src/codegen/test-helpers/golden.ts` (PORT root `src/codegen/test-helpers/golden.ts`, extended).
43
+ - [ ] Harness normalizes two placeholders before byte-compare: envelope-hash comment line and the version inside `CODEGEN_HEADER`.
44
+ - [ ] `goldens.test.ts` iterates the matrix, calls v9 `generateClient` (not yet existing) and compares each file. Mark the whole suite `describe.todo`/skipped until Phase 5 starts, then it becomes the acceptance gate. Commit.
45
+
46
+ ## Phase 1 — Core (NEW, TDD)
47
+
48
+ ### Task 1.1: Errors + definition site
49
+ **Files:** Create `v9/src/core/errors.ts`, `v9/src/core/definition-site.ts` (PORT root `src/stack-utils.ts` logic), tests alongside.
50
+ - [ ] Keep four classes (`ProcedureError`, `ProcedureValidationError`, `ProcedureYieldValidationError`, `ProcedureRegistrationError`) with a shared base carrying `kind`, `procedureName`, `meta`, `definedAt`; definition-stack enrichment preserved. Port/adapt root `src/errors.test.ts` + `src/stack-utils.test.ts`.
51
+
52
+ ### Task 1.2: Schema layer
53
+ **Files:** Create `v9/src/schema/adapter.ts`, `typebox.ts`, `compile.ts`, `compute-schema.ts`, `types.ts`, tests.
54
+ - [ ] `adapter.ts`:
55
+ ```ts
56
+ export interface SchemaAdapter {
57
+ name: string
58
+ detect(schema: unknown): boolean
59
+ toJsonSchema(schema: unknown): TJSONSchema
60
+ }
61
+ ```
62
+ - [ ] `typebox.ts`: detection via `~kind` / `Symbol.for('TypeBox.Kind')` (port from root `src/schema/resolve-schema-lib.ts`); Suretype removed.
63
+ - [ ] `compile.ts`: `createValidatorCompiler(options?: { ajv?: Ajv | AjvOptions })` returning `compile(jsonSchema): (value) => { errors?: TSchemaValidationError[] }`; default AJV opts `allErrors+coerceTypes+removeAdditional` + ajv-formats (parity with root `src/schema/parser.ts:25-31`).
64
+ - [ ] `compute-schema.ts`: PORT semantics of root `src/schema/compute-schema.ts` + `parser.ts` channel handling (params XOR req, req channels pathParams/query/body/headers, res doc-only, yieldType) on top of the adapter + compiler. Port/adapt the four root schema test files (drop Suretype cases).
65
+
66
+ ### Task 1.3: Procedures factory + four creators
67
+ **Files:** Create `v9/src/core/procedures.ts`, `create.ts`, `create-stream.ts`, `create-http.ts`, `create-http-stream.ts`, `context.ts`, `types.ts`, tests.
68
+ - [ ] Factory options per spec §5: `{ onCreate?, validation?: false | { ajv? }, schema?: { adapter? }, http?: { pathPrefix?, scope? } }`.
69
+ - [ ] Behavior parity targets: dual return `{ [name], procedure, info }`; registration objects with `kind` discriminants identical to root `src/types.ts:30-133` (the hono layer + envelope depend on these); `ctx.error()`/`ctx.signal`/`isPrevalidated`; stream `validateYields`; CreateHttp path-param cross-check; duplicate-name `ProcedureRegistrationError`; `getProcedures()/getProcedure/removeProcedure/clear`.
70
+ - [ ] `http` factory defaults merge UNDER per-route config (route wins); `scope` default applies only when route omits it.
71
+ - [ ] Port/adapt root tests: `create.test.ts`, `create-stream.test.ts`, `create-http.test.ts`, `create-http-stream.test.ts`, `index.test.ts`, `migration.test.ts` (update for renamed options); NEW tests for `validation: false`, custom `SchemaAdapter`, `http` defaults.
72
+
73
+ ## Phase 2 — Server layer (NEW seam, PORTed semantics)
74
+
75
+ ### Task 2.1: Frozen doc types + route-doc builders
76
+ **Files:** Create `v9/src/server/types.ts` (PORT root `src/implementations/types.ts`), `v9/src/server/docs/{rpc,http,stream,http-stream}-doc.ts` (PORT root `src/implementations/http/hono/docs/*`), tests.
77
+ - [ ] Shapes unchanged (spec §2 corollary). SSE yieldType envelope wrapping preserved exactly (root `stream-doc.ts:20-30`).
78
+
79
+ ### Task 2.2: Error taxonomy + dispatch
80
+ **Files:** Create `v9/src/server/errors/taxonomy.ts` (PORT root `src/implementations/http/error-taxonomy.ts`), `v9/src/server/errors/dispatch.ts` (PORT root `error-dispatch.ts`), tests (PORT `error-taxonomy.test.ts`, `on-request-error.test.ts` relevant parts).
81
+
82
+ ### Task 2.3: Request helpers, SSE, paths, DocRegistry
83
+ **Files:** Create `v9/src/server/request/params.ts` + `query.ts` (de-duplicate root `hono/handlers/http.ts:18-66` / `http-stream.ts:11-59` copies into one), `v9/src/server/sse.ts` (`sse()`/`getSSEMeta` + a shared `writeSseSequence` iteration helper extracted from root `stream.ts:117-141` / `http-stream.ts:105-114`), `v9/src/server/paths.ts` (PORT root `hono/path.ts`), `v9/src/server/doc-registry.ts` (PORT root `doc-registry.ts`), `v9/src/server/doc-envelope.ts` (PORT root `src/doc-envelope.ts`), `v9/src/server/index.ts` barrel, tests (PORT `doc-registry.test.ts`, `doc-envelope.test.ts`; NEW for params/query/sse helpers).
84
+ - [ ] No Hono imports anywhere under `server/` (enforced by a lint-style test grepping imports).
85
+
86
+ ## Phase 3 — Adapters
87
+
88
+ ### Task 3.1: Hono builder
89
+ **Files:** Create `v9/src/adapters/hono/index.ts`, `types.ts`, `handlers/{rpc,http,stream,http-stream}.ts` — thin glue over `server/*`; tests PORTed from root `src/implementations/http/hono/**/*.test.ts` + `route-errors.test.ts`.
90
+ - [ ] Public surface parity: constructor config stratification, `register()`, lazy `docs`, `build()`, `toDocEnvelope()`, `makeRoutePath`, `sse` re-export.
91
+ - [ ] **Envelope parity test:** same factory set built via v9 builder produces `toDocEnvelope()` deep-equal to a captured v8 envelope (generate the v8 envelope with a small script against root build, commit as fixture).
92
+
93
+ ### Task 3.2: Astro adapter (PORT)
94
+ **Files:** `v9/src/adapters/astro/*` from root `src/implementations/http/astro/*` + its test.
95
+
96
+ ## Phase 4 — Codegen (PORT with internal split; goldens are the gate)
97
+
98
+ ### Task 4.1: Foundation modules (PORT)
99
+ **Files:** `v9/src/codegen/`: `constants.ts`, `naming.ts`, `schema-walk.ts`, `resolve-envelope.ts`, `group-routes.ts`, `collect-models.ts`, `model-refs.ts`, `emit-types.ts`, `targets/_shared/*` — each with its root test file.
100
+
101
+ ### Task 4.2: emit split (PORT emit-scope.ts → `emit/`)
102
+ **Files:** `v9/src/codegen/emit/scope-file.ts`, `rpc-route.ts`, `api-route.ts`, `stream-route.ts`, `http-stream-route.ts`, `format-types.ts`, `declarations.ts`.
103
+ - [ ] Move code verbatim by responsibility; every emitted string literal unchanged. Port `emit-scope.test.ts` against the new module boundaries.
104
+
105
+ ### Task 4.3: Remaining emitters + targets (PORT)
106
+ **Files:** `emit-models.ts`, `emit-errors.ts`, `emit-index.ts`, `emit-client-types.ts`, `emit-client-runtime.ts` (reads `v9/src/client/*.ts` — frozen in Task 0.2), `targets/ts/run.ts`, `targets/kotlin/*`, `targets/swift/*`, `pipeline.ts`, `index.ts` — each with root tests (incl. kotlin/swift integration goldens + `e2e.test.ts`).
107
+
108
+ ### Task 4.4: Goldens green (acceptance gate)
109
+ - [ ] Unskip Task 0.5 suite; `npx vitest run src/codegen/goldens.test.ts` → every file in every case byte-identical. Fix v9 until green. Commit: `test(v9): golden parity with v8.6.0 codegen output`.
110
+
111
+ ### Task 4.5: CLI (PORT + FLAG_SPECS unification)
112
+ **Files:** `v9/src/codegen/bin/flag-specs.ts` (PORT, extended with per-flag `takesValue`/`configKey`), `v9/src/codegen/bin/cli.ts` (parseArgs driven by FLAG_SPECS; behavior identical — strict unknown-flag error, did-you-mean, `--help`, config file, watch mode), tests PORT `cli.test.ts` + `flag-specs.test.ts`.
113
+
114
+ ## Phase 5 — Finishing
115
+
116
+ ### Task 5.1: Root barrel + build
117
+ **Files:** `v9/src/exports.ts` (mirror root `src/exports.ts` minus Suretype, plus new server exports). `cd v9 && npm run build` clean; `npm run lint` clean.
118
+
119
+ ### Task 5.2: Docs
120
+ **Files:** `v9/README.md` (full library README: quickstart, four kinds, hono builder, error taxonomy, client, codegen), `v9/docs/migration-v8-to-v9.md` (every breaking change with before/after).
121
+
122
+ ### Task 5.3: Full verification
123
+ - [ ] `cd v9 && npx vitest run` — all green; `npm run build`; goldens re-verified; final commit.
124
+
125
+ ---
126
+
127
+ ## Self-review notes
128
+ - Spec coverage: §2→Tasks 0.3-0.5/4.4; §5→1.1-1.3; §6→2.1-2.3/3.1; §7→4.1-4.5; §8 woven through; §9 exclusions respected (no client changes beyond verbatim port, no agent_config).
129
+ - Port tasks intentionally reference v8 source files as the code source of truth instead of inlining thousands of lines.
130
+ - Type consistency: registration/doc/descriptor shapes pinned to root `src/types.ts` / `src/implementations/types.ts` / client `types.ts` by the freeze decisions.
@@ -0,0 +1,221 @@
1
+ # ts-procedures v9 — Ground-Up Rewrite Design
2
+
3
+ **Date:** 2026-06-09
4
+ **Status:** Approved for implementation (autonomous /goal directive; final review with user at the end)
5
+ **Location:** `v9/` — a self-contained package directory inside the repo, fully separate from the root v8 project.
6
+
7
+ ## 1. Goal
8
+
9
+ Build the next major version (9.0.0) of `ts-procedures` as a brand-new package in `v9/`, with its own
10
+ `package.json`, free to break any API — **except generated codegen output, which must remain exactly what
11
+ v8.6.0 emits today** (TS, Kotlin, Swift; all mode combinations). Downstream apps depend on that polished output.
12
+
13
+ Quality bar: most readable, well-structured, best-DX, extendable, configurable, pluggable version of the
14
+ library possible.
15
+
16
+ ## 2. The one hard constraint, made executable
17
+
18
+ "Codegen output that currently exists" becomes a byte-level golden contract:
19
+
20
+ 1. **Capture baselines from v8 first.** A capture script runs the *current root build's* codegen
21
+ (`../build/codegen`) against fixture envelopes and writes every generated file to
22
+ `v9/src/codegen/__goldens__/<case>/`.
23
+ 2. **Golden matrix** (each case = full output dir):
24
+ - `ts-default` — namespace mode, selfContained, shareModels, jsdoc (all defaults)
25
+ - `ts-flat` — `namespaceTypes: false`
26
+ - `ts-external-runtime` — `selfContained: false`
27
+ - `ts-no-share-models` — `shareModels: false`
28
+ - `ts-shared-models-module` — `sharedModelsModule` convention path
29
+ - `kotlin-default` — kotlinx serializer
30
+ - `swift-default` — codable serializer
31
+ 3. **Fixture envelopes:** the existing `users-envelope.json` plus a richer `models-envelope.json`
32
+ (adds `$id`-bearing shared models across scopes, route-level `errors`, http-stream routes) so the
33
+ shareModels/`_models.ts` paths are pinned too.
34
+ 4. **Golden test harness** in v9 compares v9 output byte-for-byte against the captured baselines, splicing
35
+ two placeholders: the envelope hash comment (already supported by v8's golden helper) and the package
36
+ version in `CODEGEN_HEADER` (v9 emits `9.x`; everything else must match exactly).
37
+ 5. These tests are written **before** any v9 codegen code and stay red until the port is faithful.
38
+
39
+ Two corollaries that fall out of the constraint:
40
+
41
+ - **Bundled client runtime is content-frozen.** Self-contained mode concatenates `src/client/*.ts`
42
+ verbatim (imports stripped) into `_client.ts`/`_types.ts`. Therefore v9's `src/client/` keeps the same
43
+ ten files with byte-identical content. Client improvements are out of scope for 9.0 and gated on a
44
+ future bundler change.
45
+ - **DocEnvelope JSON shape is frozen.** It is codegen's input. Server-side APIs may change freely as long
46
+ as `toDocEnvelope()` emits the same shapes (`kind` discriminants, `jsonSchema` channel layout, SSE
47
+ envelope wrapping, `fullPath`, `errors: string[]`, ErrorDoc/HeaderDoc).
48
+
49
+ ## 3. What changes vs. what is preserved
50
+
51
+ | Area | v9 disposition |
52
+ |---|---|
53
+ | Codegen emitted output | **Frozen** (golden-verified) |
54
+ | Codegen internals | Restructured: `emit-scope.ts` (1049 LOC) split into per-kind emitters + shared formatting modules; CLI parsing derived from `FLAG_SPECS` instead of a parallel hand-written switch |
55
+ | Client runtime (`src/client/`) | **Frozen content** (bundling), ported verbatim |
56
+ | DocEnvelope shape | **Frozen** |
57
+ | Core factory / Create* API | Redesigned for DX (see §5) |
58
+ | Schema layer | Pluggable adapters; **Suretype dropped**; AJV configurable |
59
+ | HTTP server layer | Split into transport-agnostic `server/` + thin framework adapters (`hono/`, `astro/`) |
60
+ | Error taxonomy | Kept (it's good); relocated to `server/errors/`; same semantics |
61
+ | Subpath exports | Same names kept (`.`/`./hono`/`./astro`/`./http`/`./http-docs`/`./http-errors`/`./client`/`./codegen`), plus new `./server` |
62
+ | agent_config | Out of scope for the v9 directory (release-time copy; root owns it today) |
63
+
64
+ ## 4. Package layout
65
+
66
+ ```
67
+ v9/
68
+ ├── package.json # name: ts-procedures, version: 9.0.0, type: module
69
+ ├── tsconfig.json # ES2024, NodeNext, strict — mirrors root
70
+ ├── vitest.config.ts
71
+ ├── eslint.config.js
72
+ ├── docs/
73
+ │ └── specs/2026-06-09-v9-rewrite-design.md (this file)
74
+ ├── tools/
75
+ │ └── capture-goldens.mjs # runs root v8 build's codegen → __goldens__
76
+ └── src/
77
+ ├── exports.ts # root barrel
78
+ ├── core/ # framework-agnostic procedure definitions
79
+ │ ├── procedures.ts # Procedures() factory + registry
80
+ │ ├── create.ts / create-stream.ts / create-http.ts / create-http-stream.ts
81
+ │ ├── context.ts # ctx.error(), signal contracts
82
+ │ ├── errors.ts # ProcedureError family (4 classes, shared base)
83
+ │ ├── definition-site.ts # stack-capture (was stack-utils.ts)
84
+ │ └── types.ts
85
+ ├── schema/
86
+ │ ├── adapter.ts # SchemaAdapter interface (extract + infer hooks)
87
+ │ ├── typebox.ts # built-in TypeBox adapter (auto-detected default)
88
+ │ ├── compile.ts # AJV compilation, factory-configurable instance
89
+ │ └── compute-schema.ts
90
+ ├── server/ # transport-agnostic HTTP machinery (NEW seam)
91
+ │ ├── types.ts # DocEnvelope, route docs (frozen shapes)
92
+ │ ├── docs/ # buildRpc/Api/Stream/HttpStream route docs
93
+ │ ├── doc-registry.ts
94
+ │ ├── doc-envelope.ts # writeDocEnvelope
95
+ │ ├── errors/
96
+ │ │ ├── taxonomy.ts # defineErrorTaxonomy, defaults, topo sort
97
+ │ │ └── dispatch.ts # pre-stream / mid-stream dispatch
98
+ │ ├── request/
99
+ │ │ ├── params.ts # extractParams (pathParams/query/body/headers)
100
+ │ │ └── query.ts # parseQueryNative + QueryParser type
101
+ │ ├── sse.ts # sse() metadata, SSE event sequencing helper
102
+ │ └── paths.ts # makeRoutePath, resolveFullPath
103
+ ├── adapters/
104
+ │ ├── hono/ # thin HonoAppBuilder over server/*
105
+ │ └── astro/ # port of the astro handler
106
+ ├── client/ # FROZEN content (ten files, verbatim from v8)
107
+ └── codegen/
108
+ ├── pipeline.ts, resolve-envelope.ts, group-routes.ts, ...
109
+ ├── emit/ # was emit-scope.ts — split:
110
+ │ ├── scope-file.ts # orchestration (namespace/flat assembly)
111
+ │ ├── rpc-route.ts / api-route.ts / stream-route.ts / http-stream-route.ts
112
+ │ ├── format-types.ts # formatTypes/formatSubNamespace/rename
113
+ │ └── declarations.ts # DeclarationCollector
114
+ ├── targets/{_shared,ts,kotlin,swift}/
115
+ ├── bin/{cli.ts,flag-specs.ts}
116
+ ├── __fixtures__/ # users-envelope.json + models-envelope.json
117
+ └── __goldens__/ # captured v8 output (the contract)
118
+ ```
119
+
120
+ Build = plain `tsc` to `build/`, ESM-only — same as v8 (it works and keeps publishing simple).
121
+ Root `vitest.config.ts` excludes `v9/`; v9 has its own config (complete separation).
122
+
123
+ ## 5. Core API design
124
+
125
+ The four kinds stay (`rpc`, `rpc-stream`, `http`, `http-stream`) and the dual-return shape stays — both
126
+ are proven DX:
127
+
128
+ ```ts
129
+ const { GetUser, procedure, info } = Create('GetUser', { schema: { params, returnType } }, handler)
130
+ ```
131
+
132
+ Changes:
133
+
134
+ 1. **Single options bag for the factory** with named sub-configs replacing scattered flags:
135
+ ```ts
136
+ const { Create, CreateStream, CreateHttp, CreateHttpStream, getProcedures } =
137
+ Procedures<Ctx, Ext>({
138
+ onCreate?: (registration) => void,
139
+ validation?: false | { ajv?: AjvLike | AjvOptions }, // replaces noRuntimeValidation: true
140
+ schema?: { adapter?: SchemaAdapter }, // pluggable; TypeBox auto-detected default
141
+ http?: { pathPrefix?: string, scope?: string }, // factory-level defaults for CreateHttp*
142
+ })
143
+ ```
144
+ `validation: false` reads better than `noRuntimeValidation: true`; AJV options/instance become
145
+ injectable instead of a hardcoded module singleton (default stays `allErrors + coerceTypes +
146
+ removeAdditional` for behavioral parity).
147
+ 2. **Factory-level HTTP defaults** (`http.pathPrefix`, `http.scope`) merge under each `CreateHttp` config —
148
+ addresses the documented per-route boilerplate pain without changing envelope output shape.
149
+ 3. **Error classes:** keep the four (`ProcedureError`, `ProcedureValidationError`,
150
+ `ProcedureYieldValidationError`, `ProcedureRegistrationError`) because taxonomy dispatch and docs key
151
+ off `instanceof` and class names; unify internals on one base with a `kind` field, keep definition-site
152
+ stack enrichment (genuinely good v8 feature).
153
+ 4. **Schema layer:** `SchemaAdapter = { detect(schema): boolean; toJsonSchema(schema): TJSONSchema }`.
154
+ TypeBox adapter ships built-in and is the default; Suretype is removed (deprecated since v8). The AJV
155
+ compile step lives in `schema/compile.ts` behind a small `Validator` type so a future non-AJV engine is
156
+ a config swap, not a rewrite.
157
+ 5. **Context contract unchanged** (`ctx.error()`, `ctx.signal?` on rpc/http, guaranteed `ctx.signal` on
158
+ streams, `isPrevalidated` escape hatch kept for builders).
159
+
160
+ ## 6. Server layer design
161
+
162
+ The v8 hono directory mixes three concerns: framework binding, HTTP semantics, and doc generation. v9
163
+ separates them:
164
+
165
+ - **`server/`** is pure: no Hono imports. It owns param extraction, query parsing, success-status
166
+ defaults, SSE event sequencing (auto-incrementing ids, `event: 'return'` envelope, `sse()` metadata via
167
+ WeakMap), error taxonomy + pre/mid-stream dispatch, route-doc builders, DocRegistry, and path resolution.
168
+ This kills the v8 duplication (query/param extraction copy-pasted between http.ts and http-stream.ts;
169
+ near-identical SSE loops in stream.ts and http-stream.ts) once, in one place.
170
+ - **`adapters/hono/`** keeps the v8 `HonoAppBuilder` surface users like — chainable `register()`,
171
+ stratified config (`rpc.*`, `api.*`, `stream.*`, cross-cutting `errors`/`unknownError`/`onError`/
172
+ `onRequestError`/`onRequestStart/End`), lazy `docs`, `build()`, `toDocEnvelope()` — but each handler is
173
+ ~20 lines of Hono-specific glue (read request, call server/* helpers, write response). Writing a
174
+ Fastify/Express adapter becomes a contained exercise against documented seams rather than a fork.
175
+ - **Envelope parity test:** build the same factories through the v9 hono builder and assert deep-equality
176
+ of `toDocEnvelope()` against a captured v8 envelope for the same procedure set.
177
+
178
+ ## 7. Codegen design
179
+
180
+ Port with internal restructuring, never output restructuring:
181
+
182
+ 1. Goldens first (see §2) — red until faithful.
183
+ 2. Modules port nearly as-is where already clean (`pipeline.ts`, `group-routes.ts`, `collect-models.ts`,
184
+ `model-refs.ts`, `emit-models.ts`, `emit-errors.ts`, `emit-index.ts`, `targets/*`).
185
+ 3. `emit-scope.ts` is split into `emit/` per-kind modules (§4 layout). Every emitted string literal moves
186
+ verbatim; only file boundaries and shared helpers change.
187
+ 4. `emit-client-runtime.ts` / `emit-client-types.ts` read v9's `src/client/*.ts` — identical content by
188
+ the freeze in §2 — so `_client.ts`/`_types.ts` match.
189
+ 5. CLI: `parseArgs` is generated from `FLAG_SPECS` (single source of truth; v8 had a hand-written switch
190
+ plus a parallel spec table that could drift). Flags, defaults, help text, error messages, and
191
+ did-you-mean behavior remain identical and are covered by ported CLI tests.
192
+ 6. `generateClient` options, config-file loading, watch mode, orphan pruning (`CODEGEN_SIGNATURE`
193
+ version-agnostic) all keep v8 semantics.
194
+
195
+ ## 8. Testing strategy
196
+
197
+ - **Goldens** (§2) are the spine — they encode the only hard requirement.
198
+ - **Envelope parity** test for the hono builder (§6).
199
+ - **Ported unit tests:** v8's co-located tests move with each module (adapted imports/APIs). Target: the
200
+ full behavioral surface of core/schema/server/client/codegen covered; client tests port verbatim since
201
+ the runtime is verbatim.
202
+ - **New tests** for new seams: SchemaAdapter plug-in, factory `validation`/`http` defaults, server/*
203
+ helpers in isolation.
204
+ - TDD discipline for all newly designed code (core/schema/server); port-then-verify for frozen code.
205
+
206
+ ## 9. Out of scope for 9.0.0
207
+
208
+ - Client runtime improvements (frozen by the bundling contract; revisit with an AST-based bundler in 9.x).
209
+ - New codegen targets, new emit options.
210
+ - agent_config refresh, README/marketing docs rewrite (a migration guide `docs/migration-v8-to-v9.md` IS
211
+ in scope).
212
+ - Suretype support (removed), Express builder (the v9 seam makes it easy later, not built now).
213
+
214
+ ## 10. Risks
215
+
216
+ | Risk | Mitigation |
217
+ |---|---|
218
+ | Hidden output drift in untested codegen paths | Two fixture envelopes × 7-case matrix; richer than v8's own coverage; e2e content tests also ported |
219
+ | Client verbatim port silently diverges | A test hashes each of the ten client files against recorded v8 hashes |
220
+ | Envelope drift from redesigned server layer | Deep-equality envelope parity test |
221
+ | ajsc version behavior | Same dependency pin (`^7.3.0`), same dynamic-import pattern |
package/docs/streaming.md CHANGED
@@ -109,6 +109,18 @@ for await (const item of CancellableStream({}, {})) {
109
109
 
110
110
  For the built-in Hono streaming integration, see [HTTP Integrations](./http-integrations.md). `HonoAppBuilder` dispatches `CreateStream` and `CreateHttpStream` procedures as SSE or text streams from the same `register()` call as your RPC and REST routes.
111
111
 
112
+ Wrap a yield with the `sse()` helper to attach SSE metadata (`event:`, `id:`, `retry:` fields). The value is returned unchanged — metadata rides in a WeakMap, never on the payload:
113
+
114
+ ```typescript
115
+ import { sse } from 'ts-procedures/hono'
116
+
117
+ async function* (ctx, params) {
118
+ yield sse({ progress: 0.5 }, { event: 'progress', id: 'p-1' })
119
+ }
120
+ ```
121
+
122
+ SSE wire behavior is identical for `rpc-stream` (`CreateStream`) and `http-stream` (`CreateHttpStream`) routes — both are served by the same event sequencer. `sse()` metadata is honored on both kinds, and a `null` yield serializes as empty SSE data on both. (Through v8, `http-stream` routes ignored `sse()` metadata and wrote the string `null` for null yields; v9 normalized this.)
123
+
112
124
  ## Stream Errors
113
125
 
114
126
  Streaming procedures support the same error handling as regular procedures (see [Error Handling](./core.md#error-handling)).