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
@@ -1,659 +0,0 @@
1
- # Shared-Models Convention + Diagnostics 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:** Make the v8.4.0 `sharedTypesImport` single-source-of-truth path self-maintaining and footgun-free — collapse the hand-maintained `$id → {module,name}` map to a one-value `sharedModelsModule` convention, surface the silent generated-twin fallback via an always-on summary plus an opt-in `--strict-shared-models` hard-fail, and give all three a CLI flag + config + programmatic surface.
6
-
7
- **Architecture:** Keep the codegen **pure-envelope** — no consumer source-tree scanning. The convention and diagnostics live entirely in `collect-models.ts` (`resolveModelImports`) and `targets/ts/run.ts`, fed by two new options threaded through the existing `GenerateClientOptions → PipelineOptions → TargetRunInput` chain and the CLI. Precedence in `resolveModelImports`: explicit `sharedTypesImport[$id]` → `sharedModelsModule` convention → generate locally. The existing per-`$id` map stays as the multi-consumer / rename escape hatch (unchanged).
8
-
9
- **Tech Stack:** TypeScript (ESM, `.js` import specifiers), Vitest, ajsc (dynamic import). Branch: `dx-feedback` (already checked out).
10
-
11
- **Explicitly out of scope (decided with the user):**
12
- - `--shared-types-from <dir|glob>` source scanning — declined; breaks the envelope-decoupling invariant. Reasoning written up for downstream in Task 7.
13
- - `x-shared-import` schema keyword — deferred (adds a third overlapping mechanism; the convention + existing map cover the spectrum). Not built this round.
14
- - ts-channels parity / cross-package coordination — not this project's concern.
15
-
16
- **Conventions to follow:**
17
- - Run a single test file: `npx vitest run <path>`. Full suite: `npm run test`. Lint: `npm run lint`. Build: `npm run build`.
18
- - ESM imports use `.js` specifiers even for `.ts` sources.
19
- - Commit after each green task.
20
-
21
- ---
22
-
23
- ## File Structure
24
-
25
- | File | Responsibility | Tasks |
26
- |------|----------------|-------|
27
- | `src/codegen/collect-models.ts` (modify) | `resolveModelImports` gains the `sharedModelsModule` convention fallback | 1 |
28
- | `src/codegen/collect-models.test.ts` (modify) | Unit coverage for the convention precedence | 1 |
29
- | `src/codegen/targets/_shared/target-run.ts` (modify) | `TargetRunInput` carries `sharedModelsModule` + `strictSharedModels` | 2, 3 |
30
- | `src/codegen/pipeline.ts` (modify) | `PipelineOptions` + `base` thread both options | 2, 3 |
31
- | `src/codegen/index.ts` (modify) | `GenerateClientOptions` + `generateClient` pass-through | 2, 3 |
32
- | `src/codegen/targets/ts/run.ts` (modify) | Pass convention to `resolveModelImports`; emit summary log; strict hard-fail | 2, 3 |
33
- | `src/codegen/targets/ts/shared-models.test.ts` (modify) | End-to-end coverage for convention + diagnostics | 2, 3 |
34
- | `src/codegen/bin/flag-specs.ts` (modify) | `--shared-models-module` + `--strict-shared-models` spec entries | 4 |
35
- | `src/codegen/bin/flag-specs.test.ts` (modify) | Assert the new flags are catalogued | 4 |
36
- | `src/codegen/bin/cli.ts` (modify) | Config keys, `parseArgs` branches, `ParsedArgs`, watch + main pass-through | 5 |
37
- | `src/codegen/bin/cli.test.ts` (modify) | CLI parse coverage | 5 |
38
- | `CLAUDE.md` (modify) | Document the convention + diagnostics in the codegen section | 6 |
39
- | `docs/client-and-codegen.md` (modify) | Consumer-facing guidance for the convention | 6 |
40
- | `docs/handoffs/shared-models-auto-resolve-response.md` (new) | Downstream response: what shipped + why the scanner was declined | 7 |
41
-
42
- ---
43
-
44
- ## #A — `sharedModelsModule` convention
45
-
46
- ### Task 1: `resolveModelImports` convention fallback
47
-
48
- **Files:**
49
- - Modify: `src/codegen/collect-models.ts:100-108`
50
- - Test: `src/codegen/collect-models.test.ts`
51
-
52
- - [ ] **Step 1: Write the failing test**
53
-
54
- Append to `src/codegen/collect-models.test.ts`:
55
-
56
- ```ts
57
- it('resolveModelImports falls back to sharedModelsModule when no map entry matches', () => {
58
- const models = collectModels([
59
- { jsonSchema: { res: { body: { $id: 'urn:msg', title: 'Message', type: 'object', properties: {} } } } } as never,
60
- ])
61
- const resolved = resolveModelImports(models, {}, '@app/schemas')
62
- expect(resolved[0]?.import).toEqual({ module: '@app/schemas', name: 'Message' })
63
- })
64
-
65
- it('resolveModelImports: explicit map entry wins over the convention', () => {
66
- const models = collectModels([
67
- { jsonSchema: { res: { body: { $id: 'urn:msg', title: 'Message', type: 'object', properties: {} } } } } as never,
68
- ])
69
- const resolved = resolveModelImports(
70
- models,
71
- { 'urn:msg': { module: '@override/pkg', name: 'Msg' } },
72
- '@app/schemas',
73
- )
74
- expect(resolved[0]?.import).toEqual({ module: '@override/pkg', name: 'Msg' })
75
- })
76
-
77
- it('resolveModelImports: empty-string convention is treated as unset (generated locally)', () => {
78
- const models = collectModels([
79
- { jsonSchema: { res: { body: { $id: 'urn:msg', title: 'Message', type: 'object', properties: {} } } } } as never,
80
- ])
81
- expect(resolveModelImports(models, {}, '')[0]?.import).toBeUndefined()
82
- })
83
- ```
84
-
85
- - [ ] **Step 2: Run test to verify it fails**
86
-
87
- Run: `npx vitest run src/codegen/collect-models.test.ts`
88
- Expected: FAIL — `resolveModelImports` ignores the third argument; the first two new tests' `import` is `undefined`.
89
-
90
- - [ ] **Step 3: Implement the convention fallback**
91
-
92
- Replace `resolveModelImports` in `src/codegen/collect-models.ts` (lines 100-108):
93
-
94
- ```ts
95
- /**
96
- * Tags each collected model with its external import. Precedence:
97
- * 1. an explicit `sharedTypesImport[$id]` entry (per-type override / rename),
98
- * 2. otherwise, when `sharedModelsModule` is set, the convention
99
- * `{ module: sharedModelsModule, name: model.name }` — every shared model
100
- * re-exports from one module under its derived name (`$id`/`title` === export),
101
- * 3. otherwise `import` stays undefined and the model is generated locally.
102
- */
103
- export function resolveModelImports(
104
- models: CollectedModel[],
105
- map: SharedTypesImportMap = {},
106
- sharedModelsModule?: string,
107
- ): ResolvedModel[] {
108
- return models.map((model) => {
109
- const mapped = map[model.id]
110
- if (mapped) return { ...model, import: mapped }
111
- if (sharedModelsModule != null && sharedModelsModule !== '') {
112
- return { ...model, import: { module: sharedModelsModule, name: model.name } }
113
- }
114
- return { ...model }
115
- })
116
- }
117
- ```
118
-
119
- - [ ] **Step 4: Run test to verify it passes**
120
-
121
- Run: `npx vitest run src/codegen/collect-models.test.ts`
122
- Expected: PASS (all existing + 3 new tests).
123
-
124
- - [ ] **Step 5: Commit**
125
-
126
- ```bash
127
- git add src/codegen/collect-models.ts src/codegen/collect-models.test.ts
128
- git commit -m "feat(codegen): sharedModelsModule convention fallback in resolveModelImports"
129
- ```
130
-
131
- ---
132
-
133
- ### Task 2: Thread `sharedModelsModule` end-to-end and consume it in the TS run
134
-
135
- **Files:**
136
- - Modify: `src/codegen/targets/_shared/target-run.ts:14-33`
137
- - Modify: `src/codegen/pipeline.ts:14-36,61-75`
138
- - Modify: `src/codegen/index.ts:8-31,33-56`
139
- - Modify: `src/codegen/targets/ts/run.ts:22-64`
140
- - Test: `src/codegen/targets/ts/shared-models.test.ts`
141
-
142
- - [ ] **Step 1: Write the failing test**
143
-
144
- Append inside the existing `describe('shared models ...')` block in `src/codegen/targets/ts/shared-models.test.ts`:
145
-
146
- ```ts
147
- it('sharedModelsModule re-exports every $id model from the convention module', async () => {
148
- const files = await runPipeline({
149
- envelope: modelEnvelope(),
150
- outDir: 'out',
151
- dryRun: true,
152
- shareModels: true,
153
- namespaceTypes: true,
154
- selfContained: false,
155
- sharedModelsModule: '@app/schemas',
156
- })
157
-
158
- const modelsFile = findFile(files, '_models.ts')!
159
- // Re-exported, not generated.
160
- expect(modelsFile.code).toContain("export { Message } from '@app/schemas'")
161
- expect(countMatches(modelsFile.code, /export type Message =/g)).toBe(0)
162
-
163
- // Scopes still import the shared name from ./_models.
164
- expect(findFile(files, 'messages.ts')!.code).toContain("from './_models'")
165
- })
166
-
167
- it('explicit sharedTypesImport overrides the sharedModelsModule convention per $id', async () => {
168
- const files = await runPipeline({
169
- envelope: modelEnvelope(),
170
- outDir: 'out',
171
- dryRun: true,
172
- shareModels: true,
173
- namespaceTypes: true,
174
- selfContained: false,
175
- sharedModelsModule: '@app/schemas',
176
- sharedTypesImport: { 'urn:msg': { module: '@override/pkg', name: 'Message' } },
177
- })
178
- expect(findFile(files, '_models.ts')!.code).toContain("export { Message } from '@override/pkg'")
179
- })
180
- ```
181
-
182
- - [ ] **Step 2: Run test to verify it fails**
183
-
184
- Run: `npx vitest run src/codegen/targets/ts/shared-models.test.ts`
185
- Expected: FAIL — `runPipeline` does not accept/forward `sharedModelsModule`; `_models.ts` still generates `export type Message = …` rather than re-exporting.
186
-
187
- - [ ] **Step 3a: Add the field to `TargetRunInput`**
188
-
189
- In `src/codegen/targets/_shared/target-run.ts`, add to the `TargetRunInput` interface (after the `sharedTypesImport` field, line 32):
190
-
191
- ```ts
192
- /** Single module every $id-bearing model re-exports from (convention; map entries override). */
193
- sharedModelsModule?: string
194
- ```
195
-
196
- - [ ] **Step 3b: Add to `PipelineOptions` and forward in `base`**
197
-
198
- In `src/codegen/pipeline.ts`, add to the `PipelineOptions` interface (after line 25, `sharedTypesImport?`):
199
-
200
- ```ts
201
- sharedModelsModule?: string
202
- ```
203
-
204
- And add to the `base` object (after line 74, `sharedTypesImport: options.sharedTypesImport,`):
205
-
206
- ```ts
207
- sharedModelsModule: options.sharedModelsModule,
208
- ```
209
-
210
- - [ ] **Step 3c: Add to `GenerateClientOptions` and forward in `generateClient`**
211
-
212
- In `src/codegen/index.ts`, add to `GenerateClientOptions` (after line 20, `sharedTypesImport?`):
213
-
214
- ```ts
215
- /** Single module every $id-bearing model re-exports from (convention; `sharedTypesImport` entries override). */
216
- sharedModelsModule?: string
217
- ```
218
-
219
- And in the `runPipeline({ ... })` call (after line 46, `sharedTypesImport: options.sharedTypesImport,`):
220
-
221
- ```ts
222
- sharedModelsModule: options.sharedModelsModule,
223
- ```
224
-
225
- - [ ] **Step 3d: Consume in the TS run**
226
-
227
- In `src/codegen/targets/ts/run.ts`, add `sharedModelsModule` to the destructure (after line 35, `sharedTypesImport,`):
228
-
229
- ```ts
230
- sharedModelsModule,
231
- ```
232
-
233
- And pass it to `resolveModelImports` (replace lines 62-64):
234
-
235
- ```ts
236
- const models = shareModels
237
- ? resolveModelImports(collectModels(envelope.routes), sharedTypesImport, sharedModelsModule)
238
- : []
239
- ```
240
-
241
- - [ ] **Step 4: Run test to verify it passes**
242
-
243
- Run: `npx vitest run src/codegen/targets/ts/shared-models.test.ts`
244
- Expected: PASS (existing + 2 new tests).
245
-
246
- - [ ] **Step 5: Commit**
247
-
248
- ```bash
249
- git add src/codegen/targets/_shared/target-run.ts src/codegen/pipeline.ts src/codegen/index.ts src/codegen/targets/ts/run.ts src/codegen/targets/ts/shared-models.test.ts
250
- git commit -m "feat(codegen): thread sharedModelsModule convention through pipeline to TS run"
251
- ```
252
-
253
- ---
254
-
255
- ## #B — Footgun diagnostics
256
-
257
- ### Task 3: Always-on summary + `--strict-shared-models` hard-fail
258
-
259
- **Files:**
260
- - Modify: `src/codegen/targets/_shared/target-run.ts` (add `strictSharedModels?: boolean`)
261
- - Modify: `src/codegen/pipeline.ts` (`PipelineOptions` + `base`)
262
- - Modify: `src/codegen/index.ts` (`GenerateClientOptions` + pass-through)
263
- - Modify: `src/codegen/targets/ts/run.ts` (summary log + strict throw)
264
- - Test: `src/codegen/targets/ts/shared-models.test.ts`
265
-
266
- - [ ] **Step 1: Write the failing test**
267
-
268
- Append inside the existing `describe('shared models ...')` block in `src/codegen/targets/ts/shared-models.test.ts`:
269
-
270
- ```ts
271
- it('logs a neutral summary of the re-exported / generated split', async () => {
272
- const log = vi.spyOn(console, 'log').mockImplementation(() => {})
273
- try {
274
- await runPipeline({
275
- envelope: modelEnvelope(),
276
- outDir: 'out',
277
- dryRun: true,
278
- shareModels: true,
279
- namespaceTypes: true,
280
- selfContained: false,
281
- })
282
- expect(log).toHaveBeenCalledWith(
283
- expect.stringContaining('Shared models: 1 total — 0 re-exported, 1 generated locally.'),
284
- )
285
- } finally {
286
- log.mockRestore()
287
- }
288
- })
289
-
290
- it('does not log a summary when there are no $id-bearing models', async () => {
291
- const log = vi.spyOn(console, 'log').mockImplementation(() => {})
292
- try {
293
- await runPipeline({
294
- envelope: noModelEnvelope(),
295
- outDir: 'out',
296
- dryRun: true,
297
- shareModels: true,
298
- namespaceTypes: true,
299
- selfContained: false,
300
- })
301
- expect(log.mock.calls.flat().join('\n')).not.toContain('Shared models:')
302
- } finally {
303
- log.mockRestore()
304
- }
305
- })
306
-
307
- it('strictSharedModels throws listing every $id generated as a local twin', async () => {
308
- await expect(
309
- runPipeline({
310
- envelope: modelEnvelope(),
311
- outDir: 'out',
312
- dryRun: true,
313
- shareModels: true,
314
- namespaceTypes: true,
315
- selfContained: false,
316
- strictSharedModels: true,
317
- }),
318
- ).rejects.toThrow(/--strict-shared-models/)
319
- })
320
-
321
- it('strictSharedModels passes once every model is covered by the convention', async () => {
322
- await expect(
323
- runPipeline({
324
- envelope: modelEnvelope(),
325
- outDir: 'out',
326
- dryRun: true,
327
- shareModels: true,
328
- namespaceTypes: true,
329
- selfContained: false,
330
- strictSharedModels: true,
331
- sharedModelsModule: '@app/schemas',
332
- }),
333
- ).resolves.toBeDefined()
334
- })
335
- ```
336
-
337
- Ensure `vi` is imported at the top of the file (change `import { describe, it, expect } from 'vitest'` to include `vi`):
338
-
339
- ```ts
340
- import { describe, it, expect, vi } from 'vitest'
341
- ```
342
-
343
- - [ ] **Step 2: Run test to verify it fails**
344
-
345
- Run: `npx vitest run src/codegen/targets/ts/shared-models.test.ts`
346
- Expected: FAIL — no summary log is emitted; `strictSharedModels` is not accepted/enforced so the strict-throw test does not reject.
347
-
348
- - [ ] **Step 3a: Thread `strictSharedModels` through the type chain**
349
-
350
- In `src/codegen/targets/_shared/target-run.ts`, add to `TargetRunInput` (after the `sharedModelsModule` field added in Task 2):
351
-
352
- ```ts
353
- /** When true, hard-fail if any $id-bearing model has no shared-type mapping (would be a local twin). */
354
- strictSharedModels?: boolean
355
- ```
356
-
357
- In `src/codegen/pipeline.ts`, add to `PipelineOptions` (after `sharedModelsModule?: string`):
358
-
359
- ```ts
360
- strictSharedModels?: boolean
361
- ```
362
-
363
- And to `base` (after `sharedModelsModule: options.sharedModelsModule,`):
364
-
365
- ```ts
366
- strictSharedModels: options.strictSharedModels,
367
- ```
368
-
369
- In `src/codegen/index.ts`, add to `GenerateClientOptions` (after `sharedModelsModule?: string`):
370
-
371
- ```ts
372
- /** Hard-fail codegen if any $id-bearing model would be generated as a local structural twin. */
373
- strictSharedModels?: boolean
374
- ```
375
-
376
- And to the `runPipeline({ ... })` call (after `sharedModelsModule: options.sharedModelsModule,`):
377
-
378
- ```ts
379
- strictSharedModels: options.strictSharedModels,
380
- ```
381
-
382
- - [ ] **Step 3b: Emit the summary + strict check in the TS run**
383
-
384
- In `src/codegen/targets/ts/run.ts`, add `strictSharedModels` to the destructure (after `sharedModelsModule,`):
385
-
386
- ```ts
387
- strictSharedModels = false,
388
- ```
389
-
390
- Then insert this block immediately after the `_models` reserved-filename loop (after the closing `}` of the `if (shareModels) { for (const group of groups) { … } }` at line 75):
391
-
392
- ```ts
393
- if (shareModels && models.length > 0) {
394
- const generated = models.filter((m) => m.import == null)
395
- if (strictSharedModels && generated.length > 0) {
396
- const list = generated.map((m) => `"${m.id}" (${m.name})`).join(', ')
397
- throw new Error(
398
- `[ts-procedures-codegen] --strict-shared-models: ${generated.length} $id-bearing schema(s) have no shared-type mapping and would be generated as local structural twins: ${list}. Add a sharedTypesImport entry, set sharedModelsModule, or drop --strict-shared-models.`,
399
- )
400
- }
401
- const reExported = models.length - generated.length
402
- console.log(
403
- `[ts-procedures-codegen] Shared models: ${models.length} total — ${reExported} re-exported, ${generated.length} generated locally.`,
404
- )
405
- }
406
- ```
407
-
408
- - [ ] **Step 4: Run test to verify it passes**
409
-
410
- Run: `npx vitest run src/codegen/targets/ts/shared-models.test.ts`
411
- Expected: PASS (existing + 4 new tests).
412
-
413
- - [ ] **Step 5: Commit**
414
-
415
- ```bash
416
- git add src/codegen/targets/_shared/target-run.ts src/codegen/pipeline.ts src/codegen/index.ts src/codegen/targets/ts/run.ts src/codegen/targets/ts/shared-models.test.ts
417
- git commit -m "feat(codegen): shared-models summary log + --strict-shared-models hard-fail"
418
- ```
419
-
420
- ---
421
-
422
- ## #C — CLI surface
423
-
424
- ### Task 4: Flag catalog entries
425
-
426
- **Files:**
427
- - Modify: `src/codegen/bin/flag-specs.ts:9-43`
428
- - Test: `src/codegen/bin/flag-specs.test.ts`
429
-
430
- - [ ] **Step 1: Write the failing test**
431
-
432
- Append to `src/codegen/bin/flag-specs.test.ts` (inside the existing `describe('flag-specs', …)` block):
433
-
434
- ```ts
435
- it('catalogs the shared-models convention + strict flags', () => {
436
- expect(KNOWN_FLAGS).toContain('--shared-models-module')
437
- expect(KNOWN_FLAGS).toContain('--strict-shared-models')
438
- })
439
-
440
- it('documents the new flags in --help output', () => {
441
- const help = formatHelp()
442
- expect(help).toContain('--shared-models-module')
443
- expect(help).toContain('--strict-shared-models')
444
- })
445
- ```
446
-
447
- - [ ] **Step 2: Run test to verify it fails**
448
-
449
- Run: `npx vitest run src/codegen/bin/flag-specs.test.ts`
450
- Expected: FAIL — neither flag is in `FLAG_SPECS`, so `KNOWN_FLAGS`/`formatHelp` lack them.
451
-
452
- - [ ] **Step 3: Add the spec entries**
453
-
454
- In `src/codegen/bin/flag-specs.ts`, add to the `FLAG_SPECS` array in the `Codegen` group (after the `--no-share-models` entry, line 29):
455
-
456
- ```ts
457
- { name: '--shared-models-module', arg: '<module>', description: 'Re-export every $id model from one module (convention; sharedTypesImport overrides)', group: 'Codegen' },
458
- { name: '--strict-shared-models', description: 'Fail if any $id model would be generated as a local twin', group: 'Codegen' },
459
- ```
460
-
461
- - [ ] **Step 4: Run test to verify it passes**
462
-
463
- Run: `npx vitest run src/codegen/bin/flag-specs.test.ts`
464
- Expected: PASS.
465
-
466
- - [ ] **Step 5: Commit**
467
-
468
- ```bash
469
- git add src/codegen/bin/flag-specs.ts src/codegen/bin/flag-specs.test.ts
470
- git commit -m "feat(codegen): catalog --shared-models-module and --strict-shared-models flags"
471
- ```
472
-
473
- ---
474
-
475
- ### Task 5: CLI parse, config, watch + main wiring
476
-
477
- **Files:**
478
- - Modify: `src/codegen/bin/cli.ts:14-33` (`CodegenConfig`), `35-54` (`ParsedArgs`), `152-340` (`parseArgs`), `360-441` (`runWithWatch`), `496-568` (`main`)
479
- - Test: `src/codegen/bin/cli.test.ts`
480
-
481
- - [ ] **Step 1: Write the failing test**
482
-
483
- Append to `src/codegen/bin/cli.test.ts` (match the file's existing `parseArgs` describe/import style):
484
-
485
- ```ts
486
- it('parses --shared-models-module into sharedModelsModule', () => {
487
- const parsed = parseArgs(['--out', 'gen', '--file', 'e.json', '--shared-models-module', '@app/schemas'])
488
- expect(parsed.sharedModelsModule).toBe('@app/schemas')
489
- })
490
-
491
- it('parses --strict-shared-models as a boolean (default false)', () => {
492
- expect(parseArgs(['--out', 'gen', '--file', 'e.json']).strictSharedModels).toBe(false)
493
- expect(
494
- parseArgs(['--out', 'gen', '--file', 'e.json', '--strict-shared-models']).strictSharedModels,
495
- ).toBe(true)
496
- })
497
-
498
- it('CLI --shared-models-module overrides a config value', () => {
499
- const parsed = parseArgs(
500
- ['--out', 'gen', '--file', 'e.json', '--shared-models-module', '@cli/pkg'],
501
- { sharedModelsModule: '@config/pkg' },
502
- )
503
- expect(parsed.sharedModelsModule).toBe('@cli/pkg')
504
- })
505
- ```
506
-
507
- - [ ] **Step 2: Run test to verify it fails**
508
-
509
- Run: `npx vitest run src/codegen/bin/cli.test.ts`
510
- Expected: FAIL — `parseArgs` rejects `--shared-models-module` as an unknown flag (and `ParsedArgs` lacks the fields).
511
-
512
- - [ ] **Step 3a: Extend `CodegenConfig` and `ParsedArgs`**
513
-
514
- In `src/codegen/bin/cli.ts`, add to `CodegenConfig` (after `sharedTypesImport?: SharedTypesImportMap`, line 32):
515
-
516
- ```ts
517
- sharedModelsModule?: string
518
- strictSharedModels?: boolean
519
- ```
520
-
521
- Add to `ParsedArgs` (after `sharedTypesImport?: SharedTypesImportMap`, line 53):
522
-
523
- ```ts
524
- sharedModelsModule?: string
525
- strictSharedModels: boolean
526
- ```
527
-
528
- - [ ] **Step 3b: Read config defaults + add parse branches**
529
-
530
- In `parseArgs`, add config-seeded locals (after line 172, `const sharedTypesImport = config?.sharedTypesImport`):
531
-
532
- ```ts
533
- let sharedModelsModule: string | undefined = config?.sharedModelsModule
534
- let strictSharedModels = config?.strictSharedModels ?? false
535
- ```
536
-
537
- Add parse branches (after the `--share-models` / `--no-share-models` branches, line 262):
538
-
539
- ```ts
540
- } else if (arg === '--shared-models-module') {
541
- sharedModelsModule = argv[++i]
542
- } else if (arg === '--strict-shared-models') {
543
- strictSharedModels = true
544
- ```
545
-
546
- Add to the returned object (after `...(sharedTypesImport !== undefined ? { sharedTypesImport } : {}),`, line 338):
547
-
548
- ```ts
549
- ...(sharedModelsModule !== undefined ? { sharedModelsModule } : {}),
550
- strictSharedModels,
551
- ```
552
-
553
- - [ ] **Step 3c: Forward through `runWithWatch` and `main`**
554
-
555
- In `runWithWatch`, add to the `runPipeline({ … })` call (after `...(parsed.sharedTypesImport !== undefined ? { sharedTypesImport: parsed.sharedTypesImport } : {}),`, line 427):
556
-
557
- ```ts
558
- ...(parsed.sharedModelsModule !== undefined ? { sharedModelsModule: parsed.sharedModelsModule } : {}),
559
- strictSharedModels: parsed.strictSharedModels,
560
- ```
561
-
562
- In `main`, add to the `generateClient({ … })` call (after `...(parsed.sharedTypesImport !== undefined ? { sharedTypesImport: parsed.sharedTypesImport } : {}),`, line 557):
563
-
564
- ```ts
565
- ...(parsed.sharedModelsModule !== undefined ? { sharedModelsModule: parsed.sharedModelsModule } : {}),
566
- strictSharedModels: parsed.strictSharedModels,
567
- ```
568
-
569
- - [ ] **Step 4: Run test to verify it passes**
570
-
571
- Run: `npx vitest run src/codegen/bin/cli.test.ts`
572
- Expected: PASS.
573
-
574
- - [ ] **Step 5: Full suite + lint + build**
575
-
576
- Run: `npm run test && npm run lint && npm run build`
577
- Expected: all green (catches any missed threading site, e.g. a type error in `runWithWatch`/`main`).
578
-
579
- - [ ] **Step 6: Commit**
580
-
581
- ```bash
582
- git add src/codegen/bin/cli.ts src/codegen/bin/cli.test.ts
583
- git commit -m "feat(codegen): CLI flags for sharedModelsModule + strict-shared-models"
584
- ```
585
-
586
- ---
587
-
588
- ## #D — Documentation & downstream response
589
-
590
- ### Task 6: Update repo docs
591
-
592
- **Files:**
593
- - Modify: `CLAUDE.md` (the `Client Code Generation` section, around the `shareModels` / `sharedTypesImport` bullets)
594
- - Modify: `docs/client-and-codegen.md`
595
-
596
- - [ ] **Step 1: Update CLAUDE.md**
597
-
598
- In the `Client Code Generation` section, after the existing `sharedTypesImport` bullet, add:
599
-
600
- ```markdown
601
- - `sharedModelsModule` (config / `--shared-models-module <module>`) is the convention form of `sharedTypesImport`: every `$id`-bearing model with no explicit map entry is re-exported from this single module under its derived name (`$id`/`title` === export). Precedence in `resolveModelImports`: explicit `sharedTypesImport[$id]` → `sharedModelsModule` → generate locally. Use the per-`$id` map only for overrides (rename, a different package per type, multi-consumer setups).
602
- - **Shared-models diagnostics:** every run with `$id`-bearing models logs a neutral one-line summary (`Shared models: N total — X re-exported, Y generated locally.`) so a silently-generated structural twin is visible. `strictSharedModels` (`--strict-shared-models`, default off) turns that into a hard error listing each `$id` that would be generated locally — a CI guard against the single-source-of-truth silently degrading. (Source-tree scanning, e.g. `--shared-types-from <dir>`, was deliberately rejected: codegen stays pure-envelope so `--url`/offline `--file` codegen never depends on a local source tree.)
603
- ```
604
-
605
- - [ ] **Step 2: Update docs/client-and-codegen.md**
606
-
607
- Locate the shared-types / `sharedTypesImport` subsection and add a short subsection documenting `sharedModelsModule` (the one-value convention) with a config + CLI example, plus the summary log and `--strict-shared-models` CI usage. Match the surrounding heading depth and prose style. Example block to include:
608
-
609
- ```jsonc
610
- // ts-procedures-codegen.config.json — collapse the per-$id map to one module
611
- { "sharedModelsModule": "@app/schemas" }
612
- ```
613
- ```bash
614
- # CI: fail the build if any domain entity is generated as a structural twin
615
- npx ts-procedures-codegen --file envelope.json --out gen --strict-shared-models
616
- ```
617
-
618
- - [ ] **Step 3: Verify the docs gate passes**
619
-
620
- Run: `npm run lint`
621
- Expected: PASS (also satisfies any `check-docs` gate referenced in recent commits).
622
-
623
- - [ ] **Step 4: Commit**
624
-
625
- ```bash
626
- git add CLAUDE.md docs/client-and-codegen.md
627
- git commit -m "docs: document sharedModelsModule convention + shared-models diagnostics"
628
- ```
629
-
630
- ---
631
-
632
- ### Task 7: Downstream response write-up
633
-
634
- **Files:**
635
- - Create: `docs/handoffs/shared-models-auto-resolve-response.md`
636
-
637
- - [ ] **Step 1: Write the response doc**
638
-
639
- Create `docs/handoffs/shared-models-auto-resolve-response.md` with:
640
- - **What shipped:** `sharedModelsModule` (one value replaces the hand-maintained map for the common single-module case), the always-on summary, and `--strict-shared-models` (replaces their hand-written `toEqualTypeOf` drift test with a CI flag). All available as CLI flag + config + `generateClient()` option.
641
- - **Maps their three pain points to the fix:** (1) two-places-in-lockstep → one `sharedModelsModule` value, derived not hand-maintained; (2) silent fallback → always-on summary + strict hard-fail; (3) redundant map → convention (`name = $id`, module supplied once).
642
- - **Why `--shared-types-from <dir|glob>` was declined:** the codegen's input contract is the DocEnvelope only — it never reads the consumer source tree. Scanning source breaks `--url`/offline `--file` (local source can disagree with the envelope, yielding a silently-wrong-but-typechecking single source of truth), fails for published-package consumers, and drags a TS parser/loader + glob + export-resolution heuristics into codegen. The convention achieves the same "define-once, no second table" goal without any of that.
643
- - **Escape hatch unchanged:** the per-`$id` `sharedTypesImport` map remains for rename / different-package-per-type / multi-consumer.
644
-
645
- - [ ] **Step 2: Commit**
646
-
647
- ```bash
648
- git add docs/handoffs/shared-models-auto-resolve-response.md
649
- git commit -m "docs(handoff): shared-models auto-resolve response; rationale for declining source scanning"
650
- ```
651
-
652
- ---
653
-
654
- ## Self-Review
655
-
656
- - **Spec coverage:** Pain #1 (two-places-in-lockstep, redundant map) → Tasks 1–2 (`sharedModelsModule` convention) + Task 5 (CLI) + Task 6 (docs). Pain #2 (silent fallback) → Task 3 (summary + strict). Secondary ask (config-only / no CLI flag) → Tasks 4–5. Declined primary (`--shared-types-from`) → Task 7 rationale. Out-of-scope items called out in the header. ✅
657
- - **Placeholder scan:** every code step shows the exact insertion; Task 6 step 2 references "the surrounding style" but provides concrete example blocks. No TODO/TBD. ✅
658
- - **Type consistency:** option names are identical across every layer — `sharedModelsModule: string`, `strictSharedModels: boolean` — in `TargetRunInput`, `PipelineOptions`, `GenerateClientOptions`, `CodegenConfig`, `ParsedArgs`; CLI flags `--shared-models-module`, `--strict-shared-models`; `resolveModelImports(models, map, sharedModelsModule)`. ✅
659
- - **Backward compatibility:** all new options default to unset/false; when neither is set, `resolveModelImports` and emitted output are byte-identical to today (summary only prints when `$id` models exist). ✅