@developerz.ai/ts23d 0.0.0-stage → 0.2.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 (567) hide show
  1. package/.claude/agents/bug-hunter.md +21 -0
  2. package/.claude/agents/docs-author.md +13 -0
  3. package/.claude/agents/dx-auditor.md +14 -0
  4. package/.claude/agents/primitive-author.md +22 -0
  5. package/.claude/agents/recipe-author.md +36 -0
  6. package/.claude/agents/visual-reviewer.md +23 -0
  7. package/.claude/commands/feature.md +28 -0
  8. package/.claude/commands/new-recipe.md +19 -0
  9. package/.claude/commands/release.md +14 -0
  10. package/.claude/commands/verify.md +9 -0
  11. package/.claude/skills/author-recipe/SKILL.md +93 -0
  12. package/CHANGELOG.md +90 -0
  13. package/CLAUDE.md +85 -0
  14. package/LICENSE +21 -0
  15. package/README.md +385 -2
  16. package/dist/chunk-6b05mnmx.js +19 -0
  17. package/dist/chunk-6b05mnmx.js.map +11 -0
  18. package/dist/chunk-7rtfjh9f.js +45 -0
  19. package/dist/chunk-7rtfjh9f.js.map +10 -0
  20. package/dist/chunk-8j4c28jt.js +4085 -0
  21. package/dist/chunk-8j4c28jt.js.map +46 -0
  22. package/dist/chunk-d1fv6hrm.js +2532 -0
  23. package/dist/chunk-d1fv6hrm.js.map +43 -0
  24. package/dist/chunk-dbq4qf52.js +902 -0
  25. package/dist/chunk-dbq4qf52.js.map +25 -0
  26. package/dist/chunk-drna2rny.js +836 -0
  27. package/dist/chunk-drna2rny.js.map +17 -0
  28. package/dist/chunk-dxvypr7y.js +89 -0
  29. package/dist/chunk-dxvypr7y.js.map +11 -0
  30. package/dist/chunk-f6yme003.js +1589 -0
  31. package/dist/chunk-f6yme003.js.map +30 -0
  32. package/dist/chunk-hg7pf34j.js +465 -0
  33. package/dist/chunk-hg7pf34j.js.map +19 -0
  34. package/dist/chunk-jq4e17tj.js +1031 -0
  35. package/dist/chunk-jq4e17tj.js.map +21 -0
  36. package/dist/chunk-y63c6zcv.js +2668 -0
  37. package/dist/chunk-y63c6zcv.js.map +53 -0
  38. package/dist/cli/args.d.ts +30 -0
  39. package/dist/cli/bin.d.ts +2 -0
  40. package/dist/cli/bin.js +348 -0
  41. package/dist/cli/bin.js.map +15 -0
  42. package/dist/cli/load.d.ts +2 -0
  43. package/dist/cli/manifest.d.ts +53 -0
  44. package/dist/cli/render-cmds.d.ts +12 -0
  45. package/dist/cli/run.d.ts +1 -0
  46. package/dist/cli/texture-cache.d.ts +4 -0
  47. package/dist/core/asset.d.ts +10 -0
  48. package/dist/core/definition.d.ts +155 -0
  49. package/dist/core/errors.d.ts +17 -0
  50. package/dist/core/family.d.ts +23 -0
  51. package/dist/core/index.d.ts +9 -0
  52. package/dist/core/index.js +69 -0
  53. package/dist/core/index.js.map +9 -0
  54. package/dist/core/mesh.d.ts +35 -0
  55. package/dist/core/part.d.ts +114 -0
  56. package/dist/core/png.d.ts +1 -0
  57. package/dist/core/rng.d.ts +12 -0
  58. package/dist/core/transform.d.ts +20 -0
  59. package/dist/core/vec.d.ts +11 -0
  60. package/dist/core/world.d.ts +16 -0
  61. package/dist/export/bin-writer.d.ts +16 -0
  62. package/dist/export/container.d.ts +3 -0
  63. package/dist/export/credits.d.ts +4 -0
  64. package/dist/export/glb-options.d.ts +48 -0
  65. package/dist/export/glb.d.ts +8 -0
  66. package/dist/export/hierarchy.d.ts +23 -0
  67. package/dist/export/index.d.ts +5 -0
  68. package/dist/export/index.js +40 -0
  69. package/dist/export/index.js.map +9 -0
  70. package/dist/export/lights.d.ts +8 -0
  71. package/dist/export/lod-coverage.d.ts +12 -0
  72. package/dist/export/materials.d.ts +23 -0
  73. package/dist/export/merge-pivots.d.ts +6 -0
  74. package/dist/export/metadata.d.ts +21 -0
  75. package/dist/export/motion.d.ts +9 -0
  76. package/dist/export/optimize-parts.d.ts +26 -0
  77. package/dist/export/primitive.d.ts +3 -0
  78. package/dist/export/tangents.d.ts +2 -0
  79. package/dist/export/textures.d.ts +22 -0
  80. package/dist/export/version.d.ts +2 -0
  81. package/dist/grammar/index.d.ts +2 -0
  82. package/dist/grammar/index.js +16 -0
  83. package/dist/grammar/index.js.map +9 -0
  84. package/dist/grammar/split.d.ts +21 -0
  85. package/dist/grammar/whyte.d.ts +5 -0
  86. package/dist/index.d.ts +11 -0
  87. package/dist/index.js +457 -0
  88. package/dist/index.js.map +9 -0
  89. package/dist/kinds/building.d.ts +44 -0
  90. package/dist/kinds/faces.d.ts +27 -0
  91. package/dist/kinds/head-armour.d.ts +5 -0
  92. package/dist/kinds/head-beard.d.ts +6 -0
  93. package/dist/kinds/head-bust.d.ts +5 -0
  94. package/dist/kinds/head-extras.d.ts +15 -0
  95. package/dist/kinds/head-face.d.ts +8 -0
  96. package/dist/kinds/head-garb.d.ts +4 -0
  97. package/dist/kinds/head-geom.d.ts +7 -0
  98. package/dist/kinds/head-hair.d.ts +4 -0
  99. package/dist/kinds/head-layout.d.ts +29 -0
  100. package/dist/kinds/head-mesh.d.ts +31 -0
  101. package/dist/kinds/head-mouth.d.ts +4 -0
  102. package/dist/kinds/head-params.d.ts +116 -0
  103. package/dist/kinds/head-presets.d.ts +19 -0
  104. package/dist/kinds/head-rim.d.ts +10 -0
  105. package/dist/kinds/head-tone.d.ts +10 -0
  106. package/dist/kinds/head-torso.d.ts +35 -0
  107. package/dist/kinds/head.d.ts +39 -0
  108. package/dist/kinds/hull-lines.d.ts +65 -0
  109. package/dist/kinds/hull-skin.d.ts +6 -0
  110. package/dist/kinds/hull.d.ts +14 -0
  111. package/dist/kinds/index.d.ts +16 -0
  112. package/dist/kinds/index.js +78 -0
  113. package/dist/kinds/index.js.map +9 -0
  114. package/dist/kinds/mass.d.ts +15 -0
  115. package/dist/kinds/openings.d.ts +30 -0
  116. package/dist/kinds/planned.d.ts +6 -0
  117. package/dist/kinds/roof-chimney.d.ts +16 -0
  118. package/dist/kinds/roof-shape.d.ts +64 -0
  119. package/dist/kinds/roof.d.ts +31 -0
  120. package/dist/kinds/vegetation-fronds.d.ts +15 -0
  121. package/dist/kinds/vegetation-impostor.d.ts +9 -0
  122. package/dist/kinds/vegetation-leaves.d.ts +15 -0
  123. package/dist/kinds/vegetation-mesh.d.ts +21 -0
  124. package/dist/kinds/vegetation-params.d.ts +90 -0
  125. package/dist/kinds/vegetation-presets.d.ts +20 -0
  126. package/dist/kinds/vegetation-skeleton.d.ts +20 -0
  127. package/dist/kinds/vegetation.d.ts +42 -0
  128. package/dist/kinds/vehicle.d.ts +42 -0
  129. package/dist/material/cc0.d.ts +4 -0
  130. package/dist/material/define.d.ts +34 -0
  131. package/dist/material/generator.d.ts +4 -0
  132. package/dist/material/index.d.ts +9 -0
  133. package/dist/material/index.js +70 -0
  134. package/dist/material/index.js.map +9 -0
  135. package/dist/material/library.d.ts +7 -0
  136. package/dist/material/material-def.d.ts +30 -0
  137. package/dist/material/paint/bond.d.ts +3 -0
  138. package/dist/material/paint/canvas.d.ts +39 -0
  139. package/dist/material/paint/cell.d.ts +4 -0
  140. package/dist/material/paint/cells-round.d.ts +5 -0
  141. package/dist/material/paint/cells.d.ts +7 -0
  142. package/dist/material/paint/compose.d.ts +5 -0
  143. package/dist/material/paint/concrete.d.ts +3 -0
  144. package/dist/material/paint/courses.d.ts +31 -0
  145. package/dist/material/paint/decode-png.d.ts +6 -0
  146. package/dist/material/paint/default-sheet.d.ts +4 -0
  147. package/dist/material/paint/fabric.d.ts +4 -0
  148. package/dist/material/paint/foliage-broad.d.ts +5 -0
  149. package/dist/material/paint/foliage-common.d.ts +35 -0
  150. package/dist/material/paint/foliage-compound.d.ts +4 -0
  151. package/dist/material/paint/foliage-conifer.d.ts +5 -0
  152. package/dist/material/paint/foliage-raster.d.ts +26 -0
  153. package/dist/material/paint/foliage.d.ts +3 -0
  154. package/dist/material/paint/image-strip.d.ts +4 -0
  155. package/dist/material/paint/kit.d.ts +5 -0
  156. package/dist/material/paint/masks.d.ts +3 -0
  157. package/dist/material/paint/metal.d.ts +3 -0
  158. package/dist/material/paint/noise.d.ts +9 -0
  159. package/dist/material/paint/normal.d.ts +8 -0
  160. package/dist/material/paint/orm.d.ts +8 -0
  161. package/dist/material/paint/planks.d.ts +3 -0
  162. package/dist/material/paint/plates.d.ts +3 -0
  163. package/dist/material/paint/shapes.d.ts +8 -0
  164. package/dist/material/paint/slate.d.ts +3 -0
  165. package/dist/material/paint/stamp.d.ts +3 -0
  166. package/dist/material/paint/strip.d.ts +3 -0
  167. package/dist/material/paint/surface.d.ts +5 -0
  168. package/dist/material/paint/types.d.ts +65 -0
  169. package/dist/material/paint/validate.d.ts +3 -0
  170. package/dist/material/palette.d.ts +14 -0
  171. package/dist/material/shader-godot.d.ts +2 -0
  172. package/dist/material/shader-three.d.ts +2 -0
  173. package/dist/material/shader.d.ts +46 -0
  174. package/dist/material/slots.d.ts +5 -0
  175. package/dist/material/texture-source.d.ts +34 -0
  176. package/dist/material/trim-sheet.d.ts +38 -0
  177. package/dist/neural/generator.d.ts +25 -0
  178. package/dist/neural/images.d.ts +17 -0
  179. package/dist/neural/index.d.ts +2 -0
  180. package/dist/neural/index.js +14 -0
  181. package/dist/neural/index.js.map +9 -0
  182. package/dist/passes/bake-ao.d.ts +17 -0
  183. package/dist/passes/grime.d.ts +15 -0
  184. package/dist/passes/index.d.ts +6 -0
  185. package/dist/passes/index.js +22 -0
  186. package/dist/passes/index.js.map +9 -0
  187. package/dist/passes/livery.d.ts +19 -0
  188. package/dist/passes/optimize-cache.d.ts +15 -0
  189. package/dist/passes/optimize-weld.d.ts +15 -0
  190. package/dist/passes/optimize.d.ts +28 -0
  191. package/dist/passes/ray-grid.d.ts +23 -0
  192. package/dist/passes/weighted-normals.d.ts +8 -0
  193. package/dist/primitives/beam.d.ts +17 -0
  194. package/dist/primitives/bevel-box.d.ts +13 -0
  195. package/dist/primitives/box.d.ts +16 -0
  196. package/dist/primitives/cell.d.ts +20 -0
  197. package/dist/primitives/check.d.ts +12 -0
  198. package/dist/primitives/closed.d.ts +11 -0
  199. package/dist/primitives/erosion.d.ts +22 -0
  200. package/dist/primitives/font-5x7.d.ts +3 -0
  201. package/dist/primitives/heightfield.d.ts +16 -0
  202. package/dist/primitives/index.d.ts +23 -0
  203. package/dist/primitives/index.js +81 -0
  204. package/dist/primitives/index.js.map +9 -0
  205. package/dist/primitives/lathe-facets.d.ts +8 -0
  206. package/dist/primitives/lathe.d.ts +26 -0
  207. package/dist/primitives/lattice.d.ts +30 -0
  208. package/dist/primitives/loft.d.ts +15 -0
  209. package/dist/primitives/mc-table.d.ts +2 -0
  210. package/dist/primitives/member.d.ts +19 -0
  211. package/dist/primitives/noise.d.ts +34 -0
  212. package/dist/primitives/planar.d.ts +10 -0
  213. package/dist/primitives/prism.d.ts +13 -0
  214. package/dist/primitives/sculpt-edit.d.ts +56 -0
  215. package/dist/primitives/sculpt-tree.d.ts +23 -0
  216. package/dist/primitives/sculpt.d.ts +27 -0
  217. package/dist/primitives/sdf-grid.d.ts +17 -0
  218. package/dist/primitives/sdf-ops.d.ts +37 -0
  219. package/dist/primitives/sdf.d.ts +21 -0
  220. package/dist/primitives/strip-uv.d.ts +11 -0
  221. package/dist/primitives/surface-nets.d.ts +7 -0
  222. package/dist/primitives/sweep.d.ts +19 -0
  223. package/dist/primitives/terrain-color.d.ts +30 -0
  224. package/dist/primitives/terrain-grid.d.ts +36 -0
  225. package/dist/primitives/text-layout.d.ts +22 -0
  226. package/dist/primitives/text.d.ts +27 -0
  227. package/dist/primitives/tiled.d.ts +22 -0
  228. package/dist/primitives/transport.d.ts +17 -0
  229. package/dist/primitives/triangulate.d.ts +2 -0
  230. package/dist/primitives/value-noise.d.ts +10 -0
  231. package/dist/qa/checks.d.ts +11 -0
  232. package/dist/qa/clash.d.ts +2 -0
  233. package/dist/qa/floating.d.ts +5 -0
  234. package/dist/qa/gates.d.ts +12 -0
  235. package/dist/qa/geometry.d.ts +21 -0
  236. package/dist/qa/index.d.ts +12 -0
  237. package/dist/qa/index.js +78 -0
  238. package/dist/qa/index.js.map +9 -0
  239. package/dist/qa/inside.d.ts +12 -0
  240. package/dist/qa/inspect.d.ts +18 -0
  241. package/dist/qa/lods.d.ts +12 -0
  242. package/dist/qa/measures.d.ts +4 -0
  243. package/dist/qa/occlusion.d.ts +3 -0
  244. package/dist/qa/sanity.d.ts +7 -0
  245. package/dist/qa/types.d.ts +12 -0
  246. package/dist/render/beauty.d.ts +40 -0
  247. package/dist/render/camera.d.ts +33 -0
  248. package/dist/render/depth-map.d.ts +38 -0
  249. package/dist/render/font.d.ts +1 -0
  250. package/dist/render/ground.d.ts +13 -0
  251. package/dist/render/index.d.ts +10 -0
  252. package/dist/render/index.js +47 -0
  253. package/dist/render/index.js.map +9 -0
  254. package/dist/render/lighting.d.ts +27 -0
  255. package/dist/render/lod-strip.d.ts +5 -0
  256. package/dist/render/metrics.d.ts +37 -0
  257. package/dist/render/options.d.ts +28 -0
  258. package/dist/render/photo-match.d.ts +19 -0
  259. package/dist/render/raster.d.ts +25 -0
  260. package/dist/render/resolve.d.ts +11 -0
  261. package/dist/render/review-prompt.d.ts +2 -0
  262. package/dist/render/review-warnings.d.ts +34 -0
  263. package/dist/render/review.d.ts +24 -0
  264. package/dist/render/scene.d.ts +18 -0
  265. package/dist/render/shade.d.ts +22 -0
  266. package/dist/render/sheet.d.ts +15 -0
  267. package/dist/render/texture.d.ts +15 -0
  268. package/dist/render/thumbnail.d.ts +8 -0
  269. package/dist/render/vis-buffer.d.ts +18 -0
  270. package/dist/testing/assert.d.ts +21 -0
  271. package/dist/testing/compiled.d.ts +15 -0
  272. package/dist/testing/hash.d.ts +1 -0
  273. package/dist/testing/index.d.ts +4 -0
  274. package/dist/testing/index.js +134 -0
  275. package/dist/testing/index.js.map +13 -0
  276. package/dist/testing/snapshot.d.ts +13 -0
  277. package/docs/README.md +56 -0
  278. package/docs/architecture/README.md +68 -0
  279. package/docs/architecture/adding-a-kind.md +44 -0
  280. package/docs/architecture/adding-a-primitive.md +49 -0
  281. package/docs/architecture/errors.md +47 -0
  282. package/docs/architecture/glb-production.md +214 -0
  283. package/docs/architecture/gltf-capabilities.md +117 -0
  284. package/docs/architecture/materials.md +151 -0
  285. package/docs/decisions/001-recipe-compiler-over-ai-meshes.md +27 -0
  286. package/docs/decisions/002-typescript-not-json.md +22 -0
  287. package/docs/decisions/003-shared-trim-sheet.md +21 -0
  288. package/docs/decisions/004-z-up-metres.md +21 -0
  289. package/docs/decisions/005-zero-runtime-deps.md +21 -0
  290. package/docs/decisions/006-single-package-subpath-exports.md +20 -0
  291. package/docs/decisions/007-cpu-contact-sheets.md +21 -0
  292. package/docs/decisions/008-surface-materials.md +21 -0
  293. package/docs/decisions/009-gltf-front-axis.md +21 -0
  294. package/docs/decisions/README.md +15 -0
  295. package/docs/idea/01-vision.md +117 -0
  296. package/docs/idea/02-dsl.md +343 -0
  297. package/docs/idea/03-ir.md +97 -0
  298. package/docs/idea/04-materials.md +114 -0
  299. package/docs/idea/05-agent-loop.md +141 -0
  300. package/docs/idea/06-qa.md +101 -0
  301. package/docs/idea/07-what-fits.md +45 -0
  302. package/docs/idea/08-neural-adapters.md +78 -0
  303. package/docs/idea/09-kinds.md +105 -0
  304. package/docs/idea/10-sculpting.md +166 -0
  305. package/docs/idea/11-materials-authoring.md +132 -0
  306. package/docs/idea/12-blender-bridge.md +136 -0
  307. package/docs/idea/13-asset-pipeline-research.md +89 -0
  308. package/docs/landscape.md +49 -0
  309. package/docs/plans/roadmap.md +139 -0
  310. package/examples/build-with-bun.ts +41 -0
  311. package/llms.txt +47 -0
  312. package/package.json +100 -4
  313. package/recipes/README.md +38 -0
  314. package/recipes/asteroid/README.md +46 -0
  315. package/recipes/asteroid/asteroid.ts +336 -0
  316. package/recipes/boulders/README.md +28 -0
  317. package/recipes/boulders/boulders.ts +117 -0
  318. package/recipes/boxcar/README.md +53 -0
  319. package/recipes/boxcar/boxcar.ts +1000 -0
  320. package/recipes/cargo_container_scifi/README.md +52 -0
  321. package/recipes/cargo_container_scifi/cargo_container_scifi.ts +461 -0
  322. package/recipes/dropship/README.md +84 -0
  323. package/recipes/dropship/dropship.ts +1144 -0
  324. package/recipes/eiffel_tower/README.md +110 -0
  325. package/recipes/eiffel_tower/eiffel_tower.ts +781 -0
  326. package/recipes/goblin_head/README.md +75 -0
  327. package/recipes/goblin_head/goblin_head.ts +38 -0
  328. package/recipes/human_head/README.md +68 -0
  329. package/recipes/human_head/human_head.ts +38 -0
  330. package/recipes/loco_440/README.md +32 -0
  331. package/recipes/loco_440/loco_440.ts +1404 -0
  332. package/recipes/material_swatches/README.md +21 -0
  333. package/recipes/material_swatches/material_swatches.ts +189 -0
  334. package/recipes/mountain_range/README.md +45 -0
  335. package/recipes/mountain_range/mountain_range.ts +128 -0
  336. package/recipes/oak/README.md +30 -0
  337. package/recipes/oak/oak.ts +19 -0
  338. package/recipes/orc_head/README.md +78 -0
  339. package/recipes/orc_head/orc_head.ts +41 -0
  340. package/recipes/palm/README.md +30 -0
  341. package/recipes/palm/palm.ts +19 -0
  342. package/recipes/pine/README.md +29 -0
  343. package/recipes/pine/pine.ts +19 -0
  344. package/recipes/signal_gantry/README.md +36 -0
  345. package/recipes/signal_gantry/signal_gantry.ts +522 -0
  346. package/recipes/station_halt/README.md +39 -0
  347. package/recipes/station_halt/station_halt.ts +722 -0
  348. package/recipes/t34/README.md +44 -0
  349. package/recipes/t34/t34.ts +1068 -0
  350. package/recipes/tiger_1/README.md +75 -0
  351. package/recipes/tiger_1/tiger_1.ts +1370 -0
  352. package/recipes/water_tower/README.md +40 -0
  353. package/recipes/water_tower/water_tower.ts +542 -0
  354. package/src/cli/args.ts +125 -0
  355. package/src/cli/bin.ts +7 -0
  356. package/src/cli/load.ts +17 -0
  357. package/src/cli/manifest.ts +95 -0
  358. package/src/cli/render-cmds.ts +66 -0
  359. package/src/cli/run.ts +192 -0
  360. package/src/cli/texture-cache.ts +24 -0
  361. package/src/core/asset.ts +129 -0
  362. package/src/core/definition.ts +156 -0
  363. package/src/core/errors.ts +50 -0
  364. package/src/core/family.ts +50 -0
  365. package/src/core/index.ts +66 -0
  366. package/src/core/mesh.ts +114 -0
  367. package/src/core/part.ts +130 -0
  368. package/src/core/png.ts +49 -0
  369. package/src/core/rng.ts +49 -0
  370. package/src/core/transform.ts +90 -0
  371. package/src/core/vec.ts +26 -0
  372. package/src/core/world.ts +80 -0
  373. package/src/export/bin-writer.ts +79 -0
  374. package/src/export/container.ts +35 -0
  375. package/src/export/credits.ts +25 -0
  376. package/src/export/glb-options.ts +53 -0
  377. package/src/export/glb.ts +187 -0
  378. package/src/export/hierarchy.ts +122 -0
  379. package/src/export/index.ts +34 -0
  380. package/src/export/lights.ts +49 -0
  381. package/src/export/lod-coverage.ts +71 -0
  382. package/src/export/materials.ts +126 -0
  383. package/src/export/merge-pivots.ts +146 -0
  384. package/src/export/metadata.ts +62 -0
  385. package/src/export/motion.ts +70 -0
  386. package/src/export/optimize-parts.ts +80 -0
  387. package/src/export/primitive.ts +35 -0
  388. package/src/export/tangents.ts +75 -0
  389. package/src/export/textures.ts +88 -0
  390. package/src/export/version.ts +6 -0
  391. package/src/grammar/index.ts +4 -0
  392. package/src/grammar/split.ts +87 -0
  393. package/src/grammar/whyte.ts +20 -0
  394. package/src/index.ts +14 -0
  395. package/src/kinds/building.ts +153 -0
  396. package/src/kinds/faces.ts +138 -0
  397. package/src/kinds/head-armour.ts +181 -0
  398. package/src/kinds/head-beard.ts +133 -0
  399. package/src/kinds/head-bust.ts +184 -0
  400. package/src/kinds/head-extras.ts +150 -0
  401. package/src/kinds/head-face.ts +242 -0
  402. package/src/kinds/head-garb.ts +181 -0
  403. package/src/kinds/head-geom.ts +31 -0
  404. package/src/kinds/head-hair.ts +193 -0
  405. package/src/kinds/head-layout.ts +63 -0
  406. package/src/kinds/head-mesh.ts +195 -0
  407. package/src/kinds/head-mouth.ts +111 -0
  408. package/src/kinds/head-params.ts +162 -0
  409. package/src/kinds/head-presets.ts +155 -0
  410. package/src/kinds/head-rim.ts +128 -0
  411. package/src/kinds/head-tone.ts +52 -0
  412. package/src/kinds/head-torso.ts +230 -0
  413. package/src/kinds/head.ts +176 -0
  414. package/src/kinds/hull-lines.ts +160 -0
  415. package/src/kinds/hull-skin.ts +83 -0
  416. package/src/kinds/hull.ts +209 -0
  417. package/src/kinds/index.ts +63 -0
  418. package/src/kinds/mass.ts +110 -0
  419. package/src/kinds/openings.ts +141 -0
  420. package/src/kinds/planned.ts +12 -0
  421. package/src/kinds/roof-chimney.ts +100 -0
  422. package/src/kinds/roof-shape.ts +230 -0
  423. package/src/kinds/roof.ts +250 -0
  424. package/src/kinds/vegetation-fronds.ts +126 -0
  425. package/src/kinds/vegetation-impostor.ts +118 -0
  426. package/src/kinds/vegetation-leaves.ts +168 -0
  427. package/src/kinds/vegetation-mesh.ts +174 -0
  428. package/src/kinds/vegetation-params.ts +147 -0
  429. package/src/kinds/vegetation-presets.ts +184 -0
  430. package/src/kinds/vegetation-skeleton.ts +168 -0
  431. package/src/kinds/vegetation.ts +199 -0
  432. package/src/kinds/vehicle.ts +144 -0
  433. package/src/material/cc0.ts +41 -0
  434. package/src/material/define.ts +130 -0
  435. package/src/material/generator.ts +63 -0
  436. package/src/material/index.ts +60 -0
  437. package/src/material/library.ts +196 -0
  438. package/src/material/material-def.ts +84 -0
  439. package/src/material/paint/bond.ts +60 -0
  440. package/src/material/paint/canvas.ts +101 -0
  441. package/src/material/paint/cell.ts +39 -0
  442. package/src/material/paint/cells-round.ts +119 -0
  443. package/src/material/paint/cells.ts +111 -0
  444. package/src/material/paint/compose.ts +53 -0
  445. package/src/material/paint/concrete.ts +62 -0
  446. package/src/material/paint/courses.ts +85 -0
  447. package/src/material/paint/decode-png.ts +106 -0
  448. package/src/material/paint/default-sheet.ts +73 -0
  449. package/src/material/paint/fabric.ts +63 -0
  450. package/src/material/paint/foliage-broad.ts +126 -0
  451. package/src/material/paint/foliage-common.ts +93 -0
  452. package/src/material/paint/foliage-compound.ts +135 -0
  453. package/src/material/paint/foliage-conifer.ts +143 -0
  454. package/src/material/paint/foliage-raster.ts +196 -0
  455. package/src/material/paint/foliage.ts +23 -0
  456. package/src/material/paint/image-strip.ts +88 -0
  457. package/src/material/paint/kit.ts +37 -0
  458. package/src/material/paint/masks.ts +46 -0
  459. package/src/material/paint/metal.ts +109 -0
  460. package/src/material/paint/noise.ts +52 -0
  461. package/src/material/paint/normal.ts +52 -0
  462. package/src/material/paint/orm.ts +108 -0
  463. package/src/material/paint/planks.ts +101 -0
  464. package/src/material/paint/plates.ts +72 -0
  465. package/src/material/paint/shapes.ts +28 -0
  466. package/src/material/paint/slate.ts +52 -0
  467. package/src/material/paint/stamp.ts +40 -0
  468. package/src/material/paint/strip.ts +48 -0
  469. package/src/material/paint/surface.ts +60 -0
  470. package/src/material/paint/types.ts +94 -0
  471. package/src/material/paint/validate.ts +74 -0
  472. package/src/material/palette.ts +46 -0
  473. package/src/material/shader-godot.ts +77 -0
  474. package/src/material/shader-three.ts +103 -0
  475. package/src/material/shader.ts +100 -0
  476. package/src/material/slots.ts +18 -0
  477. package/src/material/texture-source.ts +86 -0
  478. package/src/material/trim-sheet.ts +166 -0
  479. package/src/neural/generator.ts +37 -0
  480. package/src/neural/images.ts +27 -0
  481. package/src/neural/index.ts +10 -0
  482. package/src/passes/bake-ao.ts +183 -0
  483. package/src/passes/grime.ts +37 -0
  484. package/src/passes/index.ts +8 -0
  485. package/src/passes/livery.ts +66 -0
  486. package/src/passes/optimize-cache.ts +175 -0
  487. package/src/passes/optimize-weld.ts +147 -0
  488. package/src/passes/optimize.ts +85 -0
  489. package/src/passes/ray-grid.ts +237 -0
  490. package/src/passes/weighted-normals.ts +125 -0
  491. package/src/primitives/beam.ts +60 -0
  492. package/src/primitives/bevel-box.ts +140 -0
  493. package/src/primitives/box.ts +90 -0
  494. package/src/primitives/cell.ts +115 -0
  495. package/src/primitives/check.ts +49 -0
  496. package/src/primitives/closed.ts +74 -0
  497. package/src/primitives/erosion.ts +183 -0
  498. package/src/primitives/font-5x7.ts +117 -0
  499. package/src/primitives/heightfield.ts +101 -0
  500. package/src/primitives/index.ts +56 -0
  501. package/src/primitives/lathe-facets.ts +45 -0
  502. package/src/primitives/lathe.ts +174 -0
  503. package/src/primitives/lattice.ts +131 -0
  504. package/src/primitives/loft.ts +174 -0
  505. package/src/primitives/mc-table.ts +41 -0
  506. package/src/primitives/member.ts +130 -0
  507. package/src/primitives/noise.ts +157 -0
  508. package/src/primitives/planar.ts +55 -0
  509. package/src/primitives/prism.ts +85 -0
  510. package/src/primitives/sculpt-edit.ts +212 -0
  511. package/src/primitives/sculpt-tree.ts +226 -0
  512. package/src/primitives/sculpt.ts +80 -0
  513. package/src/primitives/sdf-grid.ts +131 -0
  514. package/src/primitives/sdf-ops.ts +145 -0
  515. package/src/primitives/sdf.ts +83 -0
  516. package/src/primitives/strip-uv.ts +26 -0
  517. package/src/primitives/surface-nets.ts +161 -0
  518. package/src/primitives/sweep.ts +162 -0
  519. package/src/primitives/terrain-color.ts +85 -0
  520. package/src/primitives/terrain-grid.ts +137 -0
  521. package/src/primitives/text-layout.ts +85 -0
  522. package/src/primitives/text.ts +197 -0
  523. package/src/primitives/tiled.ts +93 -0
  524. package/src/primitives/transport.ts +85 -0
  525. package/src/primitives/triangulate.ts +42 -0
  526. package/src/primitives/value-noise.ts +62 -0
  527. package/src/qa/checks.ts +110 -0
  528. package/src/qa/clash.ts +177 -0
  529. package/src/qa/floating.ts +63 -0
  530. package/src/qa/gates.ts +126 -0
  531. package/src/qa/geometry.ts +187 -0
  532. package/src/qa/index.ts +28 -0
  533. package/src/qa/inside.ts +114 -0
  534. package/src/qa/inspect.ts +107 -0
  535. package/src/qa/lods.ts +97 -0
  536. package/src/qa/measures.ts +67 -0
  537. package/src/qa/occlusion.ts +166 -0
  538. package/src/qa/sanity.ts +137 -0
  539. package/src/qa/types.ts +17 -0
  540. package/src/render/beauty.ts +115 -0
  541. package/src/render/camera.ts +142 -0
  542. package/src/render/depth-map.ts +191 -0
  543. package/src/render/font.ts +76 -0
  544. package/src/render/ground.ts +87 -0
  545. package/src/render/index.ts +34 -0
  546. package/src/render/lighting.ts +121 -0
  547. package/src/render/lod-strip.ts +34 -0
  548. package/src/render/metrics.ts +147 -0
  549. package/src/render/options.ts +81 -0
  550. package/src/render/photo-match.ts +28 -0
  551. package/src/render/raster.ts +143 -0
  552. package/src/render/resolve.ts +109 -0
  553. package/src/render/review-prompt.ts +59 -0
  554. package/src/render/review-warnings.ts +92 -0
  555. package/src/render/review.ts +103 -0
  556. package/src/render/scene.ts +119 -0
  557. package/src/render/shade.ts +204 -0
  558. package/src/render/sheet.ts +88 -0
  559. package/src/render/texture.ts +97 -0
  560. package/src/render/thumbnail.ts +75 -0
  561. package/src/render/vis-buffer.ts +119 -0
  562. package/src/testing/assert.ts +115 -0
  563. package/src/testing/compiled.ts +31 -0
  564. package/src/testing/hash.ts +14 -0
  565. package/src/testing/index.ts +14 -0
  566. package/src/testing/snapshot.ts +37 -0
  567. package/src/types/gltf-validator.d.ts +13 -0
package/README.md CHANGED
@@ -1,3 +1,386 @@
1
- # Temporary Holding Version
1
+ # ts23d
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Free 3D asset generator for coding agents. Your agent writes TypeScript; ts23d compiles it to game-ready glTF — for Unity, Unreal, Godot, three.js, Babylon, or anything that reads glTF.**
4
+
5
+ [![npm](https://img.shields.io/npm/v/@developerz.ai/ts23d)](https://www.npmjs.com/package/@developerz.ai/ts23d)
6
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
7
+
8
+ <table>
9
+ <tr>
10
+ <td align="center" width="25%"><a href="recipes/tiger_1/"><img src="recipes/tiger_1/out/tiger_1/hero.png" alt="Tiger I, rendered by ts23d"></a><br><sub><a href="recipes/tiger_1/"><code>tiger_1</code></a> · Tiger I</sub></td>
11
+ <td align="center" width="25%"><a href="recipes/loco_440/"><img src="recipes/loco_440/out/loco_440/hero.png" alt="4-4-0 “Jupiter”, rendered by ts23d"></a><br><sub><a href="recipes/loco_440/"><code>loco_440</code></a> · 4-4-0 “Jupiter”</sub></td>
12
+ <td align="center" width="25%"><a href="recipes/station_halt/"><img src="recipes/station_halt/out/station_halt/hero.png" alt="Station halt, rendered by ts23d"></a><br><sub><a href="recipes/station_halt/"><code>station_halt</code></a> · Station halt</sub></td>
13
+ <td align="center" width="25%"><a href="recipes/eiffel_tower/"><img src="recipes/eiffel_tower/out/eiffel_tower/hero.png" alt="Eiffel Tower, rendered by ts23d"></a><br><sub><a href="recipes/eiffel_tower/"><code>eiffel_tower</code></a> · Eiffel Tower</sub></td>
14
+ </tr>
15
+ <tr>
16
+ <td align="center" width="25%"><a href="recipes/orc_head/"><img src="recipes/orc_head/out/orc_head/hero.png" alt="Orc bust (sculpt), rendered by ts23d"></a><br><sub><a href="recipes/orc_head/"><code>orc_head</code></a> · Orc bust (sculpt)</sub></td>
17
+ <td align="center" width="25%"><a href="recipes/goblin_head/"><img src="recipes/goblin_head/out/goblin_head/hero.png" alt="Goblin bust (sculpt), rendered by ts23d"></a><br><sub><a href="recipes/goblin_head/"><code>goblin_head</code></a> · Goblin bust (sculpt)</sub></td>
18
+ <td align="center" width="25%"><a href="recipes/mountain_range/"><img src="recipes/mountain_range/out/mountain_range/hero.png" alt="Eroded mountains, rendered by ts23d"></a><br><sub><a href="recipes/mountain_range/"><code>mountain_range</code></a> · Eroded mountains</sub></td>
19
+ <td align="center" width="25%"><a href="recipes/oak/"><img src="recipes/oak/out/oak/hero.png" alt="Oak, rendered by ts23d"></a><br><sub><a href="recipes/oak/"><code>oak</code></a> · Oak</sub></td>
20
+ </tr>
21
+ <tr>
22
+ <td align="center" width="25%"><a href="recipes/water_tower/"><img src="recipes/water_tower/out/water_tower/hero.png" alt="Water tower, rendered by ts23d"></a><br><sub><a href="recipes/water_tower/"><code>water_tower</code></a> · Water tower</sub></td>
23
+ <td align="center" width="25%"><a href="recipes/boxcar/"><img src="recipes/boxcar/out/boxcar/hero.png" alt="USRA boxcar, rendered by ts23d"></a><br><sub><a href="recipes/boxcar/"><code>boxcar</code></a> · USRA boxcar</sub></td>
24
+ <td align="center" width="25%"><a href="recipes/signal_gantry/"><img src="recipes/signal_gantry/out/signal_gantry_4/hero.png" alt="Signal gantry, rendered by ts23d"></a><br><sub><a href="recipes/signal_gantry/"><code>signal_gantry_4</code></a> · Signal gantry</sub></td>
25
+ <td align="center" width="25%"><a href="recipes/t34/"><img src="recipes/t34/out/t34/hero.png" alt="T-34/76 1943, rendered by ts23d"></a><br><sub><a href="recipes/t34/"><code>t34</code></a> · T-34/76 1943</sub></td>
26
+ </tr>
27
+ <tr>
28
+ <td align="center" width="25%"><a href="recipes/asteroid/"><img src="recipes/asteroid/out/asteroid/hero.png" alt="Asteroid, rendered by ts23d"></a><br><sub><a href="recipes/asteroid/"><code>asteroid</code></a> · Asteroid</sub></td>
29
+ <td align="center" width="25%"><a href="recipes/cargo_container_scifi/"><img src="recipes/cargo_container_scifi/out/cargo_container_scifi/hero.png" alt="Sci-fi cargo pod, rendered by ts23d"></a><br><sub><a href="recipes/cargo_container_scifi/"><code>cargo_container_scifi</code></a> · Sci-fi cargo pod</sub></td>
30
+ <td align="center" width="25%"><a href="recipes/boulders/"><img src="recipes/boulders/out/boulders/hero.png" alt="Boulders (SDF), rendered by ts23d"></a><br><sub><a href="recipes/boulders/"><code>boulders</code></a> · Boulders (SDF)</sub></td>
31
+ <td align="center" width="25%"><a href="recipes/dropship/"><img src="recipes/dropship/out/dropship/hero.png" alt="VTOL dropship, rendered by ts23d"></a><br><sub><a href="recipes/dropship/"><code>dropship</code></a> · VTOL dropship</sub></td>
32
+ </tr>
33
+ </table>
34
+
35
+ <sub>Every image above is a real render: the committed <code>hero.png</code> next to each recipe, made on the CPU by <code>t3d hero</code> (regenerate with <code>bun run shots &lt;name&gt;</code>). Click one for its recipe, reference dossier and contact sheet.</sub>
36
+
37
+ [![The ts23d gallery site: a live, orbiting Tiger I compiled in the browser](docs/media/site.png)](https://developerz-ai.github.io/ts23d/)
38
+
39
+ **[Open the gallery →](https://developerz-ai.github.io/ts23d/)** Every asset compiles live in your browser: orbit it, switch LOD0/1/2, toggle wireframe, play its motion or stage it in a scene, check its measures against the real thing, and download the GLB.
40
+
41
+
42
+ **Use the LLM you already pay for to write the assets your project needs (vehicles, buildings, props, whole streets), optimised by construction.** ts23d ends at the GLB, its textures and a manifest. The engine is yours.
43
+
44
+ Each asset is a TypeScript module. `t3d build` compiles it, deterministically, to GLB. Free: no GPU, no credits, no service. **[Browse the asset gallery](https://developerz-ai.github.io/ts23d/)**: every recipe, compiled in your browser, with its source.
45
+
46
+ - **Named, pivoted, animatable parts.** `turret`, `gun`, `road_wheel_l_0`: your engine code binds to node names.
47
+ - **Families.** One typed build, many assets: `family.variant({ name, params })` turns T-34 1941 into 1943 with one key; `extend` derives new families. Plain functions all the way down, no plugin API.
48
+ - **Sockets and surfaces.** `ctx.socket` exports seats, mounts, cameras and spawn points as named nodes. A part can be `opaque`, `cutout`, `glass` or `translucent`; a GLB holds at most 4 materials over one texture set (a shampoo bottle is 2 draw calls).
49
+ - **Emitters and motion.** `ctx.emitter` exports smoke, steam, dust, muzzle and fire sources as named nodes your engine's particles bind to; parts `spin`, `slide` or `sway`.
50
+ - **3 LODs from one source.** The recipe reads `ctx.lod` and drops detail. Nothing is decimated.
51
+ - **One shared material, batched geometry.** Every asset maps into one trim sheet, and the exporter merges static geometry into its nearest pivot. Draw calls = the parts an engine moves: a static prop or building is 1; a tank with independently spinning road wheels is one per wheel plus turret, gun and hull.
52
+ - **A QA gate.** Exit 1 on: a part not in surface contact with anything grounded (2 cm), a moving part that cuts through another anywhere in its motion, a blown triangle budget, non-finite or inside-out geometry, hidden parts, an LOD that grows instead of shrinks.
53
+ - **Code-level checks.** The recipe states its physical intent and QA enforces it at every LOD: `checks: [clear('track_*', 'hull_*'), noOverlap('road_wheel_l_*'), touches('turret_body', 'hull_top'), symmetric('_l', '_r', 'y')]`. "The track hits the frame" becomes a failing build.
54
+ - **Textures from code.** A procedural albedo / normal / ORM trim sheet (bricks, planks, plates, slate, foliage), written once and shared by every GLB, plus three.js TSL and Godot shader sources.
55
+ - **Spec-sheet fidelity.** Declare `real: { length, width, height, measures }` with `sources`. QA holds the overall size to ±5% and each named dimension (driver diameter, gauge, wheelbase) to ±2%. Fix the model, never the spec.
56
+ - **A contact sheet.** One PNG, six labelled orthographic views on a metre grid, rendered on the CPU. A vision-capable agent reads it once, sees what's wrong and fixes it.
57
+ - **A beauty render and an AI review pack.** `t3d hero` renders a textured, lit, soft-shadowed 3/4 product shot on the CPU (the images above). `t3d review` writes hero, sheet, close-ups, an LOD strip, a checklist prompt for a vision agent and image metrics: QA with pictures, no GPU.
58
+ - **Organic modelling.** `sdf` (surface nets / marching cubes) with `sd.*` combinators and `sculpt`, an ordered add / subtract / paint edit list with smooth blends: busts, rocks, asteroids.
59
+ - **Terrain.** Seeded noise (`fbm`, `ridged`, domain `warp`, `terrace`), droplet `hydraulicErosion` and `thermalErosion`, and `terrainColor` by altitude, slope and flow.
60
+ - **Architecture and hulls.** `roof` (gable, hip, mansard, gambrel, …), `opening` window/door kits for `facade`, true-scale masonry `mass`, lofted vessel `hull`; `tiled`, `cell` and `lattice` (Warren / Pratt / Howe trusses) primitives, `box({ bevel })`, and `text` lettering as geometry.
61
+ - **An optimiser on by default.** Weld, degenerate removal, vertex-cache and vertex-fetch order (tiger_1 LOD0: 15.4 → 6.3 MB, ACMR 2.88 → 1.16), weighted normals, baked per-vertex AO.
62
+ - **Lights, glow and provenance in the GLB.** `KHR_lights_punctual` from light sockets, emissive glow materials, licence / creators / sources as `KHR_xmp_json_ld`. Zero glTF-Validator warnings.
63
+ - **Test helpers.** `@developerz.ai/ts23d/testing`: `assertQaPass`, `assertBudget`, `assertParts`, `assertMeasure`, `assertMotionClear`, `assertDeterministic`, `snapshotHash` for your own recipe tests.
64
+
65
+ **The goal: high-definition detail up close, cheap to draw everywhere.** One texture set, batched static geometry, LODs, compact core-glTF buffers (u16 indices and colours), welded, cache-optimised meshes.
66
+
67
+ **No Blender for most hard-surface asset production.** For vehicles, buildings, props and whole scenes, the LLM writes TypeScript that does the modelling, LODs, UVs onto the trim sheet, batching, QA and export. Stylised organic shapes (busts, rocks, terrain) are code too, through `sculpt` and `sdf`; realistic sculpting stays a job for Blender or the planned [`/neural` adapter or `importGlb`](docs/idea/08-neural-adapters.md).
68
+
69
+ ## Generate assets with your agent
70
+
71
+ ### 1. Install
72
+
73
+ ```sh
74
+ bun add @developerz.ai/ts23d
75
+ ```
76
+
77
+ Then give your agent the loop:
78
+
79
+ | Agent | Copy into your project |
80
+ |---|---|
81
+ | Claude Code | `cp -r node_modules/@developerz.ai/ts23d/.claude/skills/author-recipe .claude/skills/` (the loop) and `.claude/commands/new-recipe.md` (the `/new-recipe` command), both shipped in the package |
82
+ | Codex, others | Point your `AGENTS.md` at `node_modules/@developerz.ai/ts23d/CLAUDE.md` and `…/docs/` ([details](#use-it-with-any-agent)) |
83
+
84
+ ### 2. Ask
85
+
86
+ ```text
87
+ /new-recipe Tiger I, mid-production 1943, fully stowed
88
+ ```
89
+ ```text
90
+ /new-recipe 4-4-0 steam loco with tender, wheels and rods animated on a loop
91
+ ```
92
+ ```text
93
+ /new-recipe 1940s city street with townhouses and gas lamps (townhouse, lamp, street recipes: landing)
94
+ ```
95
+
96
+ The agent looks up real dimensions and photos into `recipes/<name>/README.md`, writes `recipes/<name>/<name>.ts`, builds until `QA PASS`, reads the contact sheet, and fixes the worst thing until two shots in a row find nothing ([the loop](docs/idea/05-agent-loop.md)).
97
+
98
+ ### 3. Use the GLB in your engine
99
+
100
+ `out/<asset>/lod0.glb` (and `lod1`, `lod2`) are plain glTF 2.0; `out/<asset>/<asset>.glb` holds all three in one file (LOD0 in the scene, LOD1/2 as `MSFT_lod` alternates with screen-coverage switch hints; viewers without the extension show LOD0 only; `--lods split|single|both`, default both). The hooks your engine code can use:
101
+
102
+ | Hook | In the GLB |
103
+ |---|---|
104
+ | Movable parts | Named nodes with pivots at the hinge: `turret`, `gun`, `wheel_*`, `door_*` |
105
+ | Attachment points | Socket nodes with `extras.ts23d.socket` (seat, mount, camera, …) |
106
+ | Particle sources | Emitter nodes with `extras.ts23d.emitter` (smoke, steam, dust, muzzle, …) |
107
+ | Baked loop | Clip `run` (after a static `rest` clip) when built with `t3d build` |
108
+ | Everything else | `out/<asset>/manifest.json`: pivots, sockets, emitters, triangles, draw calls |
109
+
110
+ three.js, as an example:
111
+
112
+ ```ts
113
+ const gltf = await new GLTFLoader().loadAsync('out/t34/lod0.glb');
114
+ const turret = gltf.scene.getObjectByName('turret'); // rotate about its local Z
115
+ const run = THREE.AnimationClip.findByName(gltf.animations, 'run');
116
+ const emitters = [];
117
+ gltf.scene.traverse((o) => o.userData.ts23d?.emitter && emitters.push(o));
118
+ ```
119
+
120
+ Godot: node names import unchanged, and `extras` are available as node metadata when that import option is on. Unity (glTFast), Unreal and Babylon read the same names. ts23d ships no engine code; per-engine notes are in [glb-production.md](docs/architecture/glb-production.md#c-per-engine-import-table).
121
+
122
+ ## What you get that a generated mesh doesn't
123
+
124
+ Each ts23d row names how it's verified. The image-to-3D column cites only what vendors' own pages state, as collected in [docs/landscape.md](docs/landscape.md) (as of Oct 2026). Image-to-3D is the better tool for organic and sculpted shapes; for those, see the planned [`/neural` adapter](docs/idea/08-neural-adapters.md).
125
+
126
+ | Property | ts23d | How it's verified | Typical image-to-3D output (per vendor docs) |
127
+ |---|---|---|---|
128
+ | Draw calls per asset | Static assets: 1. Vehicles: one per movable part (one shared material; static geometry batched into its pivot) | `toGlb` merges static parts by default (`mergeToPivots`); counts measured by `bun run bench` | One PBR material per generated model (e.g. Meshy: albedo / normal / metal / rough) |
129
+ | LODs | 3 from the same source | `t3d build` writes `lod0/1/2` plus one `MSFT_lod` file holding all three, each under its own triangle budget | One mesh per generation; polycount presets or a low-poly mode (Rodin, Meshy) |
130
+ | Named, pivoted, animatable parts | Yes | `part-names` gate; `clashes` gate sweeps every moving part | Usually one mesh; part-based output reported for CSM (3rd-party source) |
131
+ | Deterministic rebuild | Byte-identical | `scripts/recipes.ts` builds every recipe twice and compares hashes, in CI | Not stated |
132
+ | Real-world dimensions | Gated: ±5% overall, ±2% per measure | `proportions` and `measures` gates | Not stated |
133
+ | Parts that float or clash | Gated | `floating-parts` (surface contact, 2 cm), `clashes` (1 cm) | Not stated |
134
+ | Cost per asset or variant | $0 | MIT, runs locally, a variant is a new seed | Credits, e.g. Meshy ~20–25 credits per generation; Rodin $1.50/credit pay-per-result |
135
+ | GPU needed | No | CPU compile and CPU contact sheet | Hosted: no. Self-hosted open weights: yes (TRELLIS.2 ≥ 24 GB) |
136
+ | Editable by an LLM | A TypeScript diff | Code review, `bun run verify` | A binary mesh; edit by regenerating or in a DCC tool |
137
+ | Repair / retopo step | None: authored with pivots, units and budgets | QA gates fail the build instead | Remesh / retopology tools offered (Meshy Smart Topology, quad remesh; CSM AI retopology, 3rd-party) |
138
+ | Texture memory per asset | Shares one trim sheet: with `--sheet external` every GLB references the same three PNGs | `out/trim_sheet_*.png` written once per build | Own texture set per asset, up to 4K (TRELLIS.2) |
139
+
140
+ ### Benchmarks
141
+
142
+ To be measured: `bun run bench --write` fills the block below (triangles per LOD, compile + QA time, GLB size, parts, draw calls per gallery recipe) from real runs. Nothing in it is typed by hand; empty means not yet run.
143
+
144
+ <!-- bench:start -->
145
+ _Measured by `bun run bench` on 1.4.3 (Bun)._
146
+
147
+ | asset | tris LOD0 / 1 / 2 | GLB KiB LOD0 / 1 / 2 | parts | animated | draw calls (1 material) | compile + QA, 3 LODs | QA |
148
+ |---|---|---|---|---|---|---|---|
149
+ | `eiffel_tower` | 188016 / 21860 / 1062 | 16863 / 1819 / 85 | 28 | 0 | 1 | 1543 ms | PASS |
150
+ | `loco_440` | 23868 / 13552 / 1400 | 1035 / 614 / 104 | 80 | 14 | 17 | 521 ms | PASS |
151
+ | `material_swatches` | 10926 / 226 / 226 | 921 / 23 / 23 | 52 | 0 | 3 | 71 ms | PASS |
152
+ | `oak` | 12408 / 2536 / 180 | 649 / 135 / 8 | 5 | 1 | 2 | 297 ms | PASS |
153
+ | `palm` | 5032 / 1986 / 211 | 371 / 174 / 19 | 5 | 1 | 2 | 103 ms | PASS |
154
+ | `pine` | 6496 / 1212 / 180 | 322 / 64 / 8 | 5 | 1 | 2 | 95 ms | PASS |
155
+ | `t34` | 36452 / 9960 / 556 | 1761 / 415 / 35 | 28 | 16 | 17 | 360 ms | PASS |
156
+ | `t34_1941` | 35060 / 9460 / 500 | 1694 / 391 / 33 | 28 | 16 | 17 | 315 ms | PASS |
157
+ | `tiger_1` | 88176 / 16304 / 648 | 10709 / 1975 / 41 | 37 | 22 | 23 | 1827 ms | PASS |
158
+ <!-- bench:end -->
159
+
160
+ Draw calls column: static assets (the Eiffel Tower) are 1; vehicles are one per movable part. Trim-sheet painting: 512² ≈ 0.22 s, 1024² ≈ 0.8 s, 2048² ≈ 2.95 s. The predecessor's reference loco (below) is about 16k triangles at LOD0.
161
+
162
+ ## One asset pipeline, no other libraries
163
+
164
+ **Asset production needs nothing else between "describe the asset" and "a GLB your engine imports".** Honest status per stage:
165
+
166
+ | Stage | Module | Status (2026-10) | Replaces |
167
+ |---|---|---|---|
168
+ | Geometry | `primitives`, `kinds` | Shipped: `box` (bevel), `lathe`, `prism`, `beam`, `planar`, `sweep`, `loft`, `tiled`, `cell`, `lattice`, `text`, `heightfield`, `sdf` + `sculpt`, terrain + erosion, facades with openings, roofs, hulls, vehicles, Weber–Penn trees. Planned: creatures | Blender modelling |
169
+ | Materials and textures | `material` (generator) | Shipped: procedural albedo / normal / ORM trim sheet, embedded or shared PNGs, palettes, `grime`. No KTX2 yet | Substance / texture tools |
170
+ | Optimisation | `passes/optimize`, `export` | Shipped: weld, degenerate removal, Forsyth vertex-cache + vertex-fetch order (ACMR reported), weighted normals, baked AO, u16 indices and colours, batching. Planned: opt-in `web` profile (quantisation + meshopt) | meshoptimizer / gltfpack |
171
+ | LODs | `ctx.lod` | Shipped | Decimators |
172
+ | QA | `qa` | Shipped: budget, surface-contact floating parts, motion clashes, names, proportions, spec measures, non-finite, winding, hidden parts, degenerate triangles, cross-LOD triangles; opt-in z-fighting, LOD silhouette and pivots. `/testing` helpers | Manual review |
173
+ | Renders and photo match | `render` | Shipped: contact sheet, beauty `hero` render, `review` pack for a vision agent. Photo match planned | — |
174
+ | GLB export | `export` | Shipped: faces +Z, seamless loops, trim-sheet textures, punctual lights, emissive glow, XMP provenance, 0 glTF-Validator errors and warnings (tested) | — |
175
+ | Engine import adapters | `threeMaterialSource` (TSL), `godotShaderSource` | Shipped: shader sources with wind, window glow, wear. Planned, M3: import settings and collision naming per engine, as hooks, not runtime | — |
176
+
177
+ Every stage has zero runtime dependencies ([ADR 005](docs/decisions/005-zero-runtime-deps.md)).
178
+
179
+ > **Status: early (0.x).** The core loop works: write, build, QA, shot, hero, review, with
180
+ > textures, trees, sculpt, terrain and the gallery's passing recipes. Still declared and throwing
181
+ > `T3D_NOT_IMPLEMENTED`: creatures, photo match, neural adapters. See the [roadmap](docs/plans/roadmap.md). Expect breaking changes.
182
+
183
+ ## A recipe
184
+
185
+ ```ts
186
+ import { axle, box, defineAsset, palettes } from '@developerz.ai/ts23d';
187
+
188
+ const { paint, iron, trim } = palettes.victorianRail;
189
+
190
+ export const handcart = defineAsset({
191
+ name: 'handcart',
192
+ kind: 'vehicle',
193
+ budget: { triangles: [2000, 800, 300] }, // LOD0 / LOD1 / LOD2 ceilings, enforced by QA
194
+ build(ctx) {
195
+ for (const [i, x] of [0.8, -0.8].entries()) {
196
+ axle(ctx, { name: `axle_${i}`, at: [x, 0, 0.35], radius: 0.35, gauge: 1.2,
197
+ width: 0.08, color: iron, rps: 1 }); // wheels spin in the baked clip
198
+ }
199
+ ctx.part('bed', box({ size: [2.4, 1.3, 0.12], at: [0, 0, 0.62], color: trim, strip: 'wood' }));
200
+ const posts = ctx.lod === 2 ? 2 : 6; // LOD drops detail; it never decimates
201
+ for (let i = 0; i < posts; i++) {
202
+ const x = -1.1 + (2.2 * i) / (posts - 1);
203
+ ctx.part(`post_${i}`, box({ size: [0.08, 0.08, 0.5], at: [x, 0.6, 0.74], color: paint }));
204
+ }
205
+ },
206
+ });
207
+ ```
208
+
209
+ Metres, Z up, +X is the front. Loops, functions and types, because a recipe is code, not data
210
+ ([why](docs/decisions/002-typescript-not-json.md)).
211
+
212
+ ## What the agent sees
213
+
214
+ `t3d shot recipes/tiger_1/tiger_1.ts` → `out/tiger_1/sheet.png`, from [`recipes/tiger_1/tiger_1.ts`](recipes/tiger_1/tiger_1.ts). Every recipe folder commits its sheet, hero render and manifest under `out/`:
215
+
216
+ ![Tiger I contact sheet: six orthographic views on a metre grid](recipes/tiger_1/out/tiger_1/sheet.png)
217
+
218
+ Header: name, bounding box in metres, grid step, LOD. Row 1: 3/4 front, front (+X), side (−Y).
219
+ Row 2: top, 3/4 rear, LOD2 at distance. Layout: [docs/idea/05-agent-loop.md](docs/idea/05-agent-loop.md).
220
+ `t3d hero` adds the beauty shot, and `t3d review` packs hero, sheet, close-ups, an LOD strip and a
221
+ checklist prompt into `out/<asset>/review/` for a second, fresh-eyes vision pass.
222
+
223
+ ## Materials
224
+
225
+ ![The material library: woods, metals, rubber, canvas, leather on one trim sheet](docs/media/materials.png)
226
+
227
+ One shared 2048² trim sheet holds 24 physically based materials: oak, pine, weathered and painted
228
+ wood; rusty, cast, painted and galvanised iron and steel; brass, copper, aluminium, chrome; rubber,
229
+ canvas, leather, plastic; plus brick, stone, slate, concrete and glass. Each has its own roughness and
230
+ metalness, so chrome mirrors and wood stays matte. Projects add their own with `defineMaterial`, or
231
+ pull a CC0 photo set from Poly Haven with `bun run textures` (hash-pinned, credited in the GLB). See
232
+ [materials.md](docs/architecture/materials.md).
233
+
234
+ ## Quickstart
235
+
236
+ Needs Bun ≥ 1.4.4 (Node ≥ 22 for the compiled `dist/`).
237
+
238
+ ```sh
239
+ bun add @developerz.ai/ts23d
240
+ bunx t3d build recipes/*/*.ts # GLB × 3 LODs + sheet + manifest per asset; exit 1 on a QA finding
241
+ bunx t3d shot recipes/*/*.ts # sheet + manifest only: the fast look
242
+ bunx t3d hero recipes/*/*.ts # beauty render: textured, lit, soft shadows (1600×900)
243
+ bunx t3d review recipes/*/*.ts # AI review pack: hero, sheet, close-ups, LOD strip, review.md
244
+ bunx t3d list recipes/*/*.ts --json # the assets each module exports
245
+ ```
246
+
247
+ | Flag | Effect |
248
+ |---|---|
249
+ | `--out <dir>` | Output directory (default `out`) |
250
+ | `--no-shot` | `build` without rendering the contact sheet |
251
+ | `--sheet external\|embed\|none` | Trim-sheet textures. `external` (default): `out/trim_sheet_{albedo,normal,orm}.png` written once, every GLB references `../trim_sheet_*.png`. `embed`: inside each GLB. `none`: vertex colour only |
252
+ | `--sheet-size 512\|1024\|2048` | Sheet resolution (default 1024) |
253
+ | `--lods 0,1,2` | Which detail levels to build (default all three). `--lods 0` = hero mesh only, `--lods 0,2` = near + far. QA and the manifest cover exactly what was built |
254
+ | `--no-animations` | Skip the baked `run` clip. `t3d build` bakes it by default so viewers (e.g. VS Code glTF Tools) show play controls |
255
+ | `--json` | Machine-readable `{ ok, data }` / `{ ok: false, error: { code, message, fix } }` |
256
+
257
+ Output, one folder per asset (stable paths for agents and pipelines):
258
+
259
+ ```
260
+ out/
261
+ ├── index.json every asset built in this run, with its QA verdict
262
+ └── <asset>/
263
+ ├── lod0.glb lod1.glb lod2.glb
264
+ ├── hero.png the beauty render
265
+ ├── sheet.png the contact sheet
266
+ └── manifest.json files; triangles + draw calls per LOD; pivots, emitters, sockets,
267
+ surfaces; real + measures with measured values; sources; QA
268
+ ```
269
+
270
+ Library calls differ on one default: `toGlb(asset)` exports no animation unless `{ animations: true }`.
271
+
272
+ Every exported asset in a module is built (`defineAsset` or `family.variant`). Every error prints a stable `T3D_*` code and its fix ([errors](docs/architecture/errors.md)).
273
+
274
+ ## Programmatic: no CLI, just Bun
275
+
276
+ `t3d` is a convenience. Everything it does is a function call: compile, QA, export, render.
277
+ A plain script builds exactly what you want, and the same code runs in Node ≥ 22 (against the
278
+ built `dist/`), in a browser, or in a Web Worker (the [asset gallery](https://developerz-ai.github.io/ts23d/)
279
+ compiles every recipe in a worker).
280
+
281
+ ```ts
282
+ // build.ts → bun build.ts
283
+ import { compile, contactSheet, DEFAULT_SHEET, paintTrimSheet, runQa, toGlb } from '@developerz.ai/ts23d';
284
+ import { tiger_1 } from './recipes/tiger_1/tiger_1.ts';
285
+
286
+ const sheet = paintTrimSheet({ ...DEFAULT_SHEET, size: 512 }); // textures are optional
287
+
288
+ for (const lod of [0, 2] as const) { // only the detail levels you need
289
+ const asset = compile(tiger_1, { lod });
290
+ const findings = runQa(asset); // gate it your way, or skip it
291
+ if (findings.length) throw new Error(findings.map((f) => `${f.message} — fix: ${f.fix}`).join('\n'));
292
+ await Bun.write(`out/tiger_1.lod${lod}.glb`, toGlb(asset, { sheet, animations: true }));
293
+ }
294
+ await Bun.write('out/tiger_1.png', contactSheet(compile(tiger_1, { lod: 0 }))); // for your agent's eyes
295
+ ```
296
+
297
+ Runnable copy: [`examples/build-with-bun.ts`](examples/build-with-bun.ts) — executed in CI, so this path can't rot.
298
+
299
+ | Building block | What it gives you |
300
+ |---|---|
301
+ | `compile(asset, { lod, seed })` | the compiled parts for one LOD (deterministic) |
302
+ | `runQa(compiled)` / single gates / `inspect(compiled)` | findings with fixes; geometry queries for your own checks |
303
+ | `toGlb(compiled, { sheet, animations, keepParts })` | GLB bytes (`Uint8Array`) — write them anywhere |
304
+ | `mergeToPivots(compiled)` | the batched part list the GLB uses (draw calls = movable parts) |
305
+ | `contactSheet(compiled, { far, cell })` | six-view PNG bytes |
306
+ | `paintTrimSheet(recipe)` + `sheetPngs(sheet)` | the texture set (albedo / normal / ORM) as RGBA or PNG |
307
+ | `threeMaterialSource(hints)` / `godotShaderSource(hints)` | shader source strings for your engine |
308
+ | `manifest` data | build it from `compiled.parts` (pivots, emitters, sockets) — see `src/cli/manifest.ts` |
309
+
310
+ ## Use it with any agent
311
+
312
+ **The docs ship inside the package, versioned with the code, readable offline.** After `bun add`, everything an agent needs is at `node_modules/@developerz.ai/ts23d/`: `CLAUDE.md` (the agent brain; `AGENTS.md` in the repo is a link to it), `llms.txt`, `docs/`, `recipes/` (worked examples), `CHANGELOG.md` and `.claude/{skills,agents,commands}`.
313
+
314
+ Point your agent at them. Add to your project's `CLAUDE.md` or `AGENTS.md`:
315
+
316
+ ```md
317
+ 3D assets: @developerz.ai/ts23d. Read node_modules/@developerz.ai/ts23d/CLAUDE.md first;
318
+ docs in node_modules/@developerz.ai/ts23d/docs/, example recipes in …/recipes/.
319
+ ```
320
+
321
+ Claude Code skill (and the `/new-recipe` command):
322
+
323
+ ```sh
324
+ mkdir -p .claude/skills .claude/commands
325
+ cp -r node_modules/@developerz.ai/ts23d/.claude/skills/author-recipe .claude/skills/
326
+ cp node_modules/@developerz.ai/ts23d/.claude/commands/new-recipe.md .claude/commands/
327
+ ```
328
+
329
+
330
+ Works with any agent that writes TypeScript and can run a shell: Claude Code, Codex, Cursor, Aider, a local model. If it can read images, it closes the loop on its own. No skill files? Paste this:
331
+
332
+ ```text
333
+ Using @developerz.ai/ts23d, write recipes/<name>/<name>.ts: a <thing>, real dimensions in metres,
334
+ Z up, +X front. Put the sources in `sources` and the key dimensions in `real.measures`.
335
+ Block out the masses, then details. Name every part that moves (axle_*, door_*, rotor_*)
336
+ and pivot it where it hinges. Loop until done:
337
+ 1. bunx t3d build recipes/<name>/<name>.ts (fix every finding until it prints QA PASS;
338
+ a measures finding means rebuild the part, never edit the spec)
339
+ 2. Read out/<name>/sheet.png (build writes it).
340
+ 3. Name the single biggest error, fix it, go to 1.
341
+ Stop when two consecutive shots show nothing worth fixing. Never use Math.random; use ctx.rng.
342
+ ```
343
+
344
+ ## What fits, what doesn't
345
+
346
+ As of 2026-10. Full matrix: [docs/idea/07-what-fits.md](docs/idea/07-what-fits.md).
347
+
348
+ | Fit | Asset categories |
349
+ |---|---|
350
+ | **Strong** | Hard-surface props, architecture (facades, towers), vehicles (tracked, wheeled, rail), modular kits, anything with real dimensions or repeated parts |
351
+ | **Shipped, early** | Vegetation: Weber–Penn trees (oak, pine, palm, birch, willow); LOD2 impostors are crude |
352
+ | **Shipped, early** | Stylised organic: `sculpt` busts, SDF rocks and asteroids, eroded terrain. Boats: lofted `hull` |
353
+ | **Planned** | Stylised creatures (SDF over a skeleton, M4) |
354
+ | **Weak** | Realistic people and animals, realistic sculpted organic forms, cloth. Use an image-to-3D tool, or the planned [`/neural` adapter](docs/idea/08-neural-adapters.md) that runs open-weight models on your own GPU and caches the result |
355
+
356
+ Not a replacement for AI mesh generators: a different approach with different strengths. Neutral comparison: [docs/landscape.md](docs/landscape.md).
357
+
358
+ ## Gallery
359
+
360
+ **https://developerz-ai.github.io/ts23d/**: every recipe in `recipes/`, filterable by category (vehicles, railway, architecture, nature and terrain, characters, sci-fi). The grid shows the committed renders; opening an asset compiles it in your browser with an orbit viewer, LOD switch, wireframe, its motion, a scene, named parts, measures against the real spec, the recipe source and GLB downloads.
361
+
362
+ Each recipe is a folder: `recipes/<name>/<name>.ts` (the asset), `README.md` (the reference dossier: sources, specs, photo links) and `out/<asset>/` (committed `hero.png`, `sheet.png`, `manifest.json`).
363
+
364
+ [![An asset page: the Jupiter 4-4-0 running in a scene, with its stats and measures](docs/media/site-scene.png)](https://developerz-ai.github.io/ts23d/#loco_440)
365
+
366
+ ## Docs
367
+
368
+ | Read | For |
369
+ |---|---|
370
+ | [docs/README.md](docs/README.md) | The index |
371
+ | [docs/idea/](docs/idea/01-vision.md) | Vision, DSL, IR, materials, agent loop, QA, kinds |
372
+ | [docs/decisions/](docs/decisions/README.md) | Why: ADRs with the rejected options |
373
+ | [docs/architecture/](docs/architecture/README.md) | Module tiers, adding a primitive or kind, error codes |
374
+ | [docs/plans/roadmap.md](docs/plans/roadmap.md) | M0–M6 |
375
+ | [CONTRIBUTING.md](CONTRIBUTING.md) | `bun run setup`, `bun run verify` |
376
+
377
+ ## Pairs well with
378
+
379
+ | | |
380
+ |---|---|
381
+ | **[kubeez.com](https://kubeez.com)** | Partner. Generate reference and concept images, decals and texture source images. The sheet painter's image-stamped cells will consume them (planned) ([materials](docs/idea/04-materials.md)) |
382
+ | **[developerz.ai](https://www.developerz.ai)** | 100% AI-managed software engineering. ts23d is built and maintained by AI agents |
383
+
384
+ ## License
385
+
386
+ [MIT](LICENSE). Outputs are yours: no attribution, no licence conditions on generated assets.
@@ -0,0 +1,19 @@
1
+ import {
2
+ notImplemented2
3
+ } from "./chunk-hg7pf34j.js";
4
+
5
+ // src/neural/generator.ts
6
+ function localGenerator2(_o) {
7
+ return notImplemented2("localGenerator (local GPU model adapter)", "docs/idea/08-neural-adapters.md");
8
+ }
9
+ function importGlb2(_bytes, _o) {
10
+ return notImplemented2("importGlb", "docs/idea/08-neural-adapters.md");
11
+ }
12
+ // src/neural/images.ts
13
+ function kubeezImages2(_o) {
14
+ return notImplemented2("kubeezImages (kubeez.com image source)", "docs/idea/08-neural-adapters.md");
15
+ }
16
+ export { localGenerator2, importGlb2, kubeezImages2 };
17
+
18
+ //# debugId=FD2490AA59A2DB1D64756E2164756E21
19
+ //# sourceMappingURL=chunk-6b05mnmx.js.map
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/neural/generator.ts", "../src/neural/images.ts"],
4
+ "sourcesContent": [
5
+ "// Optional seam for organic shapes the recipe approach handles poorly: people, animals, sculpted\n// rocks. Runs an open-weight image/text-to-3D model on the USER's GPU (TRELLIS, Hunyuan3D, SF3D…)\n// behind a local HTTP endpoint, then wraps the result as an ordinary part. Never a core dependency.\n//\n// Determinism: a generated mesh is cached by (model, prompt/image hash, seed) under\n// .ts23d/neural/ and committed or published like any asset, so CI rebuilds without a GPU.\n\nimport { type Mesh, notImplemented, type Vec3 } from '../core/index.ts';\n\nexport interface GenerateRequest {\n readonly prompt?: string;\n /** PNG/JPEG bytes of a reference or concept image. */\n readonly image?: Uint8Array;\n readonly seed: number;\n /** Fit the result into this box (metres), Z up, base on the ground. */\n readonly fit: Vec3;\n readonly targetTriangles: number;\n}\n\nexport interface MeshGenerator {\n /** e.g. 'trellis-2', 'hunyuan3d-2.1', 'sf3d'. Part of the cache key. */\n readonly model: string;\n generate(request: GenerateRequest): Promise<Mesh>;\n}\n\n/** Talks to a local server (e.g. a ComfyUI / gradio wrapper) at `endpoint`. Planned: M5. */\nexport function localGenerator(_o: { model: string; endpoint: string }): MeshGenerator {\n return notImplemented(\n 'localGenerator (local GPU model adapter)',\n 'docs/idea/08-neural-adapters.md',\n );\n}\n\n/** Import an existing GLB (a CC0 base mesh, a sculpt, a generator's output) as a part. Planned: M5. */\nexport function importGlb(_bytes: Uint8Array, _o: { fit: Vec3; recolor?: Vec3 }): Mesh {\n return notImplemented('importGlb', 'docs/idea/08-neural-adapters.md');\n}\n",
6
+ "// Image sources for the material generator and the agent loop: reference/concept images, decals,\n// texture source photos. kubeez.com is the recommended hosted source; any function returning PNG\n// bytes fits. Results are cached by (source, prompt, seed) like generated meshes. Planned: M5.\n\nimport { notImplemented } from '../core/index.ts';\n\nexport interface ImageRequest {\n readonly prompt: string;\n readonly seed: number;\n readonly width: number;\n readonly height: number;\n /** e.g. 'decal', 'tileable', 'reference', 'concept'. */\n readonly purpose: 'decal' | 'tileable' | 'reference' | 'concept';\n}\n\nexport interface ImageSource {\n readonly name: string;\n generate(request: ImageRequest): Promise<Uint8Array>;\n}\n\n/** kubeez.com image generation. Reads the key from the caller, never from ambient env. */\nexport function kubeezImages(_o: { apiKey: string; model?: string }): ImageSource {\n return notImplemented(\n 'kubeezImages (kubeez.com image source)',\n 'docs/idea/08-neural-adapters.md',\n );\n}\n"
7
+ ],
8
+ "mappings": ";;;;;AA0BO,SAAS,eAAc,CAAC,IAAwD;AAAA,EACrF,OAAO,gBACL,4CACA,iCACF;AAAA;AAIK,SAAS,UAAS,CAAC,QAAoB,IAAyC;AAAA,EACrF,OAAO,gBAAe,aAAa,iCAAiC;AAAA;;ACd/D,SAAS,aAAY,CAAC,IAAqD;AAAA,EAChF,OAAO,gBACL,0CACA,iCACF;AAAA;",
9
+ "debugId": "FD2490AA59A2DB1D64756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,45 @@
1
+ import {
2
+ mergeToPivots2
3
+ } from "./chunk-dbq4qf52.js";
4
+ import {
5
+ measure2
6
+ } from "./chunk-jq4e17tj.js";
7
+
8
+ // src/cli/manifest.ts
9
+ var tris = (a) => a.parts.reduce((s, p) => s + (p.mesh ? p.mesh.indices.length / 3 : 0), 0);
10
+ function manifestOf2(asset, lods, files, findings, lodCoverage) {
11
+ const top = lods[0];
12
+ const merged = top ? mergeToPivots2(top) : null;
13
+ return {
14
+ name: asset.name,
15
+ kind: asset.kind,
16
+ ...asset.description ? { description: asset.description } : {},
17
+ tags: asset.tags ?? [],
18
+ files,
19
+ triangles: lods.map(tris),
20
+ ...lodCoverage?.length ? { lodCoverage } : {},
21
+ drawCalls: lods.map((l) => mergeToPivots2(l, (l.glow ?? []).map((g) => g.parts)).parts.filter((p) => p.mesh).length),
22
+ pivots: (merged?.parts ?? []).filter((p) => !p.emitter && !p.socket).map((p) => ({
23
+ name: p.name,
24
+ parent: p.parent,
25
+ ...p.motion ? { motion: p.motion.kind } : {}
26
+ })),
27
+ emitters: (top?.parts ?? []).flatMap((p) => p.emitter ? [{ name: p.name, kind: p.emitter.kind, when: p.emitter.when ?? "always" }] : []),
28
+ sockets: (top?.parts ?? []).flatMap((p) => p.socket ? [{ name: p.name, kind: p.socket.kind, parent: p.parent }] : []),
29
+ surfaces: [...new Set((top?.parts ?? []).map((p) => p.surface ?? "opaque"))].sort(),
30
+ ...asset.real ? { real: { length: asset.real.length, width: asset.real.width, height: asset.real.height } } : {},
31
+ measures: (asset.real?.measures ?? []).map((m) => ({
32
+ label: m.label,
33
+ spec: m.value,
34
+ measured: top ? measure2(top, m) : null,
35
+ ...m.source ? { source: m.source } : {}
36
+ })),
37
+ sources: asset.sources ?? [],
38
+ qa: { pass: findings.length === 0, findings }
39
+ };
40
+ }
41
+
42
+ export { manifestOf2 };
43
+
44
+ //# debugId=DCAF218A5B7D9F6B64756E2164756E21
45
+ //# sourceMappingURL=chunk-7rtfjh9f.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/cli/manifest.ts"],
4
+ "sourcesContent": [
5
+ "// manifest.json per asset: what an engine pipeline or an agent needs without opening a GLB —\n// files, triangles per LOD, pivots (the names game code binds to), emitters, surfaces, QA,\n// measures with their measured values, sources.\n\nimport type { Asset, CompiledAsset } from '../core/index.ts';\nimport { mergeToPivots } from '../export/index.ts';\nimport { type Finding, measure } from '../qa/index.ts';\n\nexport interface AssetManifest {\n readonly name: string;\n readonly kind: string;\n readonly description?: string;\n readonly tags: readonly string[];\n readonly files: {\n readonly lods: readonly string[];\n /** All built LODs in one GLB (MSFT_lod), when `--lods single|both`. */\n readonly single?: string;\n readonly hero?: string;\n readonly sheet?: string;\n readonly thumb?: string;\n };\n readonly triangles: readonly number[];\n /** MSFT_screencoverage written into `files.single`: where each LOD hands over (last = cull). */\n readonly lodCoverage?: readonly number[];\n readonly drawCalls: readonly number[];\n readonly pivots: readonly { name: string; parent: string | null; motion?: string }[];\n readonly emitters: readonly { name: string; kind: string; when: string }[];\n readonly sockets: readonly { name: string; kind: string; parent: string | null }[];\n readonly surfaces: readonly string[];\n readonly real?: { length: number; width: number; height: number };\n readonly measures: readonly {\n label: string;\n spec: number;\n measured: number | null;\n source?: string;\n }[];\n readonly sources: readonly string[];\n readonly qa: { readonly pass: boolean; readonly findings: readonly Finding[] };\n}\n\nconst tris = (a: CompiledAsset): number =>\n a.parts.reduce((s, p) => s + (p.mesh ? p.mesh.indices.length / 3 : 0), 0);\n\nexport function manifestOf(\n asset: Asset,\n lods: readonly CompiledAsset[],\n files: AssetManifest['files'],\n findings: readonly Finding[],\n lodCoverage?: readonly number[],\n): AssetManifest {\n const top = lods[0];\n const merged = top ? mergeToPivots(top) : null;\n return {\n name: asset.name,\n kind: asset.kind,\n ...(asset.description ? { description: asset.description } : {}),\n tags: asset.tags ?? [],\n files,\n triangles: lods.map(tris),\n ...(lodCoverage?.length ? { lodCoverage } : {}),\n // One draw per merged mesh, glowing parts in their own emissive layer (as the GLB writes them).\n drawCalls: lods.map(\n (l) =>\n mergeToPivots(\n l,\n (l.glow ?? []).map((g) => g.parts),\n ).parts.filter((p) => p.mesh).length,\n ),\n pivots: (merged?.parts ?? [])\n .filter((p) => !p.emitter && !p.socket)\n .map((p) => ({\n name: p.name,\n parent: p.parent,\n ...(p.motion ? { motion: p.motion.kind } : {}),\n })),\n emitters: (top?.parts ?? []).flatMap((p) =>\n p.emitter ? [{ name: p.name, kind: p.emitter.kind, when: p.emitter.when ?? 'always' }] : [],\n ),\n sockets: (top?.parts ?? []).flatMap((p) =>\n p.socket ? [{ name: p.name, kind: p.socket.kind, parent: p.parent }] : [],\n ),\n surfaces: [...new Set((top?.parts ?? []).map((p) => p.surface ?? 'opaque'))].sort(),\n ...(asset.real\n ? { real: { length: asset.real.length, width: asset.real.width, height: asset.real.height } }\n : {}),\n measures: (asset.real?.measures ?? []).map((m) => ({\n label: m.label,\n spec: m.value,\n measured: top ? measure(top, m) : null,\n ...(m.source ? { source: m.source } : {}),\n })),\n sources: asset.sources ?? [],\n qa: { pass: findings.length === 0, findings },\n };\n}\n"
6
+ ],
7
+ "mappings": ";;;;;;;;AAwCA,IAAM,OAAO,CAAC,MACZ,EAAE,MAAM,OAAO,CAAC,GAAG,MAAM,KAAK,EAAE,OAAO,EAAE,KAAK,QAAQ,SAAS,IAAI,IAAI,CAAC;AAEnE,SAAS,WAAU,CACxB,OACA,MACA,OACA,UACA,aACe;AAAA,EACf,MAAM,MAAM,KAAK;AAAA,EACjB,MAAM,SAAS,MAAM,eAAc,GAAG,IAAI;AAAA,EAC1C,OAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,OACR,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAC9D,MAAM,MAAM,QAAQ,CAAC;AAAA,IACrB;AAAA,IACA,WAAW,KAAK,IAAI,IAAI;AAAA,OACpB,aAAa,SAAS,EAAE,YAAY,IAAI,CAAC;AAAA,IAE7C,WAAW,KAAK,IACd,CAAC,MACC,eACE,IACC,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CACnC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,MAClC;AAAA,IACA,SAAS,QAAQ,SAAS,CAAC,GACxB,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,EACrC,IAAI,CAAC,OAAO;AAAA,MACX,MAAM,EAAE;AAAA,MACR,QAAQ,EAAE;AAAA,SACN,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,IAC9C,EAAE;AAAA,IACJ,WAAW,KAAK,SAAS,CAAC,GAAG,QAAQ,CAAC,MACpC,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,QAAQ,SAAS,CAAC,IAAI,CAAC,CAC5F;AAAA,IACA,UAAU,KAAK,SAAS,CAAC,GAAG,QAAQ,CAAC,MACnC,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,OAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAC1E;AAAA,IACA,UAAU,CAAC,GAAG,IAAI,KAAK,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,QAAQ,CAAC,CAAC,EAAE,KAAK;AAAA,OAC9E,MAAM,OACN,EAAE,MAAM,EAAE,QAAQ,MAAM,KAAK,QAAQ,OAAO,MAAM,KAAK,OAAO,QAAQ,MAAM,KAAK,OAAO,EAAE,IAC1F,CAAC;AAAA,IACL,WAAW,MAAM,MAAM,YAAY,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,MACjD,OAAO,EAAE;AAAA,MACT,MAAM,EAAE;AAAA,MACR,UAAU,MAAM,SAAQ,KAAK,CAAC,IAAI;AAAA,SAC9B,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,IACzC,EAAE;AAAA,IACF,SAAS,MAAM,WAAW,CAAC;AAAA,IAC3B,IAAI,EAAE,MAAM,SAAS,WAAW,GAAG,SAAS;AAAA,EAC9C;AAAA;",
8
+ "debugId": "DCAF218A5B7D9F6B64756E2164756E21",
9
+ "names": []
10
+ }