nodehammer 0.2.0rc3__tar.gz → 0.2.0rc6__tar.gz

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 (509) hide show
  1. nodehammer-0.2.0rc6/.agents/skills/nodehammer/SKILL.md +249 -0
  2. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.gitignore +1 -1
  3. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/CMakeLists.txt +91 -123
  4. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/PKG-INFO +66 -19
  5. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/README.md +65 -18
  6. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/check_shared_exports.py +3 -3
  7. nodehammer-0.2.0rc6/ci/ingest_consumer/CMakeLists.txt +54 -0
  8. nodehammer-0.2.0rc6/ci/ingest_consumer/main.cpp +40 -0
  9. nodehammer-0.2.0rc6/ci/package_components/CMakeLists.txt +48 -0
  10. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/shared_consumer/CMakeLists.txt +2 -2
  11. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/shared_consumer/main.cpp +38 -35
  12. nodehammer-0.2.0rc6/ci/verify-ingest.sh +40 -0
  13. nodehammer-0.2.0rc6/ci/verify-package-components.cmake +32 -0
  14. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/verify-shared-install.sh +10 -0
  15. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/Dependencies.cmake +3 -90
  16. nodehammer-0.2.0rc6/cmake/GenerateSkillsData.cmake +165 -0
  17. nodehammer-0.2.0rc6/cmake/Ingestion.cmake +146 -0
  18. nodehammer-0.2.0rc6/cmake/IngestionDependencies.cmake +127 -0
  19. nodehammer-0.2.0rc6/cmake/IngestionOnly.cmake +31 -0
  20. nodehammer-0.2.0rc6/cmake/InstallPackage.cmake +24 -0
  21. nodehammer-0.2.0rc6/cmake/PublicBackendHeaders.cmake +16 -0
  22. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/nodehammer-config.cmake.in +47 -25
  23. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/conanfile.py +2 -2
  24. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/kitchen_sink.lua +1 -1
  25. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd.lua +2 -2
  26. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/include/nodehammer/build.hpp +1 -1
  27. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/include/nodehammer/cli.hpp +33 -8
  28. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/include/nodehammer/config.hpp +13 -60
  29. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/include/nodehammer/diagnostics.hpp +2 -6
  30. nodehammer-0.2.0rc6/include/nodehammer/io.hpp +41 -0
  31. nodehammer-0.2.0rc6/include/nodehammer/nhb.hpp +14 -0
  32. nodehammer-0.2.0rc6/include/nodehammer/nhr.hpp +10 -0
  33. nodehammer-0.2.0rc6/include/nodehammer/render_scene.hpp +40 -0
  34. nodehammer-0.2.0rc6/include/nodehammer/semantic_scene.hpp +43 -0
  35. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/packaging/web/README.md +1 -1
  36. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/packaging/web/src/nodehammer_web/__init__.py +1 -1
  37. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/pyproject.toml +1 -1
  38. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/python/nodehammer/__init__.py +43 -6
  39. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/python/nodehammer/__main__.py +7 -1
  40. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/python/nodehammer/cli.py +29 -5
  41. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/check_pages_site.py +1 -1
  42. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/check_web_serve.py +10 -4
  43. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/make_nhproj.py +6 -0
  44. nodehammer-0.2.0rc6/skills/nodehammer/SKILL.md +249 -0
  45. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/api/build.cpp +4 -1
  46. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/api/config.cpp +7 -7
  47. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/api/diagnostics.cpp +1 -1
  48. nodehammer-0.2.0rc6/src/api/handles_config.hpp +92 -0
  49. nodehammer-0.2.0rc6/src/api/handles_render.hpp +50 -0
  50. nodehammer-0.2.0rc6/src/api/handles_semantic.hpp +79 -0
  51. nodehammer-0.2.0rc6/src/api/public/dd4hep.hpp +11 -0
  52. nodehammer-0.2.0rc6/src/api/public/dd4hep_disabled.hpp +4 -0
  53. nodehammer-0.2.0rc6/src/api/public/tgeo.hpp +9 -0
  54. nodehammer-0.2.0rc6/src/api/public/tgeo_disabled.hpp +4 -0
  55. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/api/render_scene.cpp +41 -54
  56. nodehammer-0.2.0rc6/src/api/semantic_scene.cpp +104 -0
  57. nodehammer-0.2.0rc6/src/api/semantic_scene_formats.cpp +99 -0
  58. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/cli_common.hpp +53 -0
  59. nodehammer-0.2.0rc6/src/cli/cmd_config.cpp +160 -0
  60. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/cmd_convert.cpp +163 -58
  61. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/cmd_inspect.cpp +216 -42
  62. nodehammer-0.2.0rc6/src/cli/cmd_project.cpp +238 -0
  63. nodehammer-0.2.0rc6/src/cli/cmd_skills.cpp +510 -0
  64. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/cmd_viewer_native.cpp +212 -135
  65. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/cmd_viewer_web.cpp +108 -73
  66. nodehammer-0.2.0rc6/src/cli/config_input.hpp +53 -0
  67. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/main.cpp +8 -2
  68. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/pager.cpp +3 -27
  69. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/pager.hpp +1 -1
  70. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/run.cpp +40 -13
  71. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/cli/run_internal.hpp +28 -21
  72. nodehammer-0.2.0rc6/src/cli/skills_data.hpp +48 -0
  73. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_ast.hpp +3 -3
  74. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_loader.cpp +18 -15
  75. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_loader.hpp +1 -1
  76. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_writer.cpp +30 -33
  77. nodehammer-0.2.0rc6/src/detail/env.cpp +39 -0
  78. nodehammer-0.2.0rc6/src/detail/env.hpp +29 -0
  79. nodehammer-0.2.0rc6/src/detail/json_value.hpp +231 -0
  80. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/detail/zstd_io.hpp +9 -2
  81. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/diagnostic_codes.hpp +23 -5
  82. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/dd4hep/semantic/importer.cpp +48 -25
  83. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/dd4hep/semantic/importer.hpp +7 -0
  84. nodehammer-0.2.0rc6/src/ir/fb/render/exporter.cpp +43 -0
  85. nodehammer-0.2.0rc6/src/ir/fb/render/exporter.hpp +25 -0
  86. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/exporter.cpp +2 -1
  87. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/importer.cpp +5 -5
  88. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/importer.hpp +3 -3
  89. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/gltf/render/exporter.cpp +40 -38
  90. nodehammer-0.2.0rc6/src/ir/id_order.hpp +48 -0
  91. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/json/semantic/exporter.cpp +1 -1
  92. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/render/exporter.hpp +2 -1
  93. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/render/exporter_registry.cpp +14 -0
  94. nodehammer-0.2.0rc6/src/ir/render/json_exporter.cpp +25 -0
  95. nodehammer-0.2.0rc6/src/ir/render/json_exporter.hpp +25 -0
  96. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/render.hpp +3 -3
  97. nodehammer-0.2.0rc6/src/ir/render_json.cpp +119 -0
  98. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/render_json.hpp +3 -2
  99. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic/exporter.hpp +3 -1
  100. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic_json.cpp +15 -8
  101. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/lua/lua_config.cpp +17 -16
  102. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/lua/lua_config.hpp +2 -2
  103. nodehammer-0.2.0rc6/src/project/pack.cpp +217 -0
  104. nodehammer-0.2.0rc6/src/project/pack.hpp +63 -0
  105. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/python/bindings.cpp +138 -232
  106. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/project_manifest.hpp +7 -0
  107. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/zip_working_set.cpp +67 -5
  108. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/runtime_locator.cpp +3 -30
  109. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/runtime_locator.hpp +2 -2
  110. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/stage.cpp +7 -66
  111. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/CMakeLists.txt +61 -14
  112. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/api/test_api_equivalence.cpp +18 -15
  113. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/api/test_api_surface.cpp +36 -33
  114. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/api/test_config_wrapper.cpp +25 -25
  115. nodehammer-0.2.0rc6/tests/cli/cli_test_support.hpp +122 -0
  116. nodehammer-0.2.0rc6/tests/cli/test_cli_config.cpp +191 -0
  117. nodehammer-0.2.0rc6/tests/cli/test_cli_convert_stages.cpp +198 -0
  118. nodehammer-0.2.0rc6/tests/cli/test_cli_inspect_json.cpp +234 -0
  119. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/cli/test_cli_run.cpp +103 -93
  120. nodehammer-0.2.0rc6/tests/cli/test_cli_skills.cpp +347 -0
  121. nodehammer-0.2.0rc6/tests/cmake/generate_skills_data_test.cmake +106 -0
  122. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/config/test_config_loader.cpp +1 -1
  123. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/config/test_config_writer.cpp +7 -7
  124. nodehammer-0.2.0rc6/tests/fixtures/skills/plain/SKILL.md +4 -0
  125. nodehammer-0.2.0rc6/tests/fixtures/skills/with-dash/SKILL.md +4 -0
  126. nodehammer-0.2.0rc6/tests/fixtures/skills/with-dash/references/nested.md +1 -0
  127. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/import/test_dd4hep_importer.cpp +25 -0
  128. nodehammer-0.2.0rc6/tests/ingest/CMakeLists.txt +69 -0
  129. nodehammer-0.2.0rc6/tests/ingest/compare.cmake +43 -0
  130. nodehammer-0.2.0rc6/tests/ingest/core.cpp +84 -0
  131. nodehammer-0.2.0rc6/tests/ingest/dd4hep.cpp +24 -0
  132. nodehammer-0.2.0rc6/tests/ingest/geometry.hpp +53 -0
  133. nodehammer-0.2.0rc6/tests/ingest/golden.cpp +5 -0
  134. nodehammer-0.2.0rc6/tests/ingest/golden_body.hpp +54 -0
  135. nodehammer-0.2.0rc6/tests/ingest/transport.cpp +60 -0
  136. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/ir/test_flatbuffer_roundtrip.cpp +1 -1
  137. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/ir/test_json_roundtrip.cpp +1 -1
  138. nodehammer-0.2.0rc6/tests/ir/test_render_nhr_exporter.cpp +141 -0
  139. nodehammer-0.2.0rc6/tests/project/test_pack.cpp +249 -0
  140. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/public_fixture.hpp +2 -2
  141. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/test_public_build.cpp +2 -2
  142. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/test_public_cli.cpp +6 -6
  143. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/test_public_config.cpp +22 -22
  144. nodehammer-0.2.0rc6/tests/public/test_public_dd4hep.cpp +148 -0
  145. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/test_public_diagnostics.cpp +5 -4
  146. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/test_public_render_scene.cpp +48 -25
  147. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/test_public_semantic_scene.cpp +64 -32
  148. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/public/test_public_tgeo.cpp +14 -24
  149. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/python/test_build.py +6 -6
  150. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/python/test_cli.py +127 -12
  151. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/python/test_config_and_diagnostics.py +34 -38
  152. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/python/test_semantic_scene.py +37 -21
  153. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_zip_working_set.cpp +41 -0
  154. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/wasm_lua_smoke.cpp +8 -7
  155. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/web/test_runtime_locator.cpp +1 -1
  156. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/web/test_static_server.cpp +1 -1
  157. nodehammer-0.2.0rc3/include/nodehammer/render_scene.hpp +0 -104
  158. nodehammer-0.2.0rc3/include/nodehammer/semantic_scene.hpp +0 -144
  159. nodehammer-0.2.0rc3/src/api/handles.hpp +0 -214
  160. nodehammer-0.2.0rc3/src/api/semantic_scene.cpp +0 -155
  161. nodehammer-0.2.0rc3/src/cli/cmd_config_flatten.cpp +0 -63
  162. nodehammer-0.2.0rc3/src/cli/cmd_config_lua.cpp +0 -80
  163. nodehammer-0.2.0rc3/src/cli/cmd_dump_render.cpp +0 -80
  164. nodehammer-0.2.0rc3/src/cli/cmd_dump_semantic.cpp +0 -327
  165. nodehammer-0.2.0rc3/src/cli/cmd_validate_config.cpp +0 -45
  166. nodehammer-0.2.0rc3/src/ir/render_json.cpp +0 -81
  167. nodehammer-0.2.0rc3/tests/public/test_public_dd4hep.cpp +0 -99
  168. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.clang-format +0 -0
  169. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.clang-tidy +0 -0
  170. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.gitattributes +0 -0
  171. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.pre-commit-config.yaml +0 -0
  172. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.vscode/launch.json +0 -0
  173. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.vscode/settings.json +0 -0
  174. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/.vscode/tasks.json +0 -0
  175. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/Justfile +0 -0
  176. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/LICENSE +0 -0
  177. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/LICENSES/MIT.txt +0 -0
  178. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/LICENSES/OFL-1.1.txt +0 -0
  179. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/LICENSES/Zlib.txt +0 -0
  180. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/REUSE.toml +0 -0
  181. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/STYLE.md +0 -0
  182. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/bench-summary.py +0 -0
  183. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/bench.sh +0 -0
  184. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/build.sh +0 -0
  185. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/ci/shared-build.sh +0 -0
  186. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/CompilerOptions.cmake +0 -0
  187. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/PicProbe.cmake +0 -0
  188. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/Sokol.cmake +0 -0
  189. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/ThirdPartyLicenses.cmake +0 -0
  190. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/Version.cmake +0 -0
  191. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/patch_sokol_wgpu.cmake +0 -0
  192. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/pic_probe.cpp +0 -0
  193. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/validate_shader_hlsl.cmake +0 -0
  194. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/cmake/validate_shader_wgsl.cmake +0 -0
  195. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/full_example.toml +0 -0
  196. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/include_bad_path.toml +0 -0
  197. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/include_basic.toml +0 -0
  198. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/include_cycle.toml +0 -0
  199. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/include_diamond.toml +0 -0
  200. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/include_nested.toml +0 -0
  201. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/cycle_a.toml +0 -0
  202. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/cycle_b.toml +0 -0
  203. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/diamond_base.toml +0 -0
  204. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/diamond_left.toml +0 -0
  205. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/diamond_right.toml +0 -0
  206. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/materials.toml +0 -0
  207. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/nested_inner.toml +0 -0
  208. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/nested_outer.toml +0 -0
  209. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/includes/rules.toml +0 -0
  210. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/invalid_bad_tolerance.toml +0 -0
  211. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/invalid_missing_material_ref.toml +0 -0
  212. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/calorimeters.lua +0 -0
  213. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/lib/constants.lua +0 -0
  214. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/materials.lua +0 -0
  215. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/muon.lua +0 -0
  216. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/base.lua +0 -0
  217. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/calorimeters.lua +0 -0
  218. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/materials.lua +0 -0
  219. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/muon.lua +0 -0
  220. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/tracker.lua +0 -0
  221. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/parity.lua +0 -0
  222. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/parity.toml +0 -0
  223. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/lua/tracker.lua +0 -0
  224. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/minimal.toml +0 -0
  225. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/base.toml +0 -0
  226. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/calorimeters.toml +0 -0
  227. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/calorimeters_simple.toml +0 -0
  228. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/materials.toml +0 -0
  229. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/muon.toml +0 -0
  230. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/muon_simple.toml +0 -0
  231. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/simple_materials.toml +0 -0
  232. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd/tracker.toml +0 -0
  233. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd.toml +0 -0
  234. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_drop_coincident_faces.toml +0 -0
  235. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_merged.toml +0 -0
  236. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_simple.toml +0 -0
  237. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_ecal_barrel_stave.toml +0 -0
  238. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_hcal_barrel_stave.toml +0 -0
  239. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_long_strip_barrel_module.toml +0 -0
  240. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_long_strip_barrel_stave.toml +0 -0
  241. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_muon_barrel_chamber.toml +0 -0
  242. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_pixel_barrel_module.toml +0 -0
  243. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_pixel_barrel_stave.toml +0 -0
  244. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_short_strip_barrel_module.toml +0 -0
  245. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_short_strip_barrel_stave.toml +0 -0
  246. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/configs/odd_tracker.toml +0 -0
  247. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/dd4hep/sensitive_detector.xml +0 -0
  248. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/fixtures/dd4hep/simple_box.xml +0 -0
  249. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/include/nodehammer/version.hpp.in +0 -0
  250. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/include/nodehammer/visibility.hpp +0 -0
  251. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/packaging/plugins/nh_web_pin.py +0 -0
  252. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/packaging/web/.gitignore +0 -0
  253. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/packaging/web/LICENSE +0 -0
  254. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/packaging/web/pyproject.toml +0 -0
  255. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/profiles/emscripten +0 -0
  256. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/python/nodehammer/py.typed +0 -0
  257. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/cli11/conandata.yml +0 -0
  258. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/cli11/conanfile.py +0 -0
  259. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/imgui/CMakeLists.txt +0 -0
  260. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/imgui/conandata.yml +0 -0
  261. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/imgui/conanfile.py +0 -0
  262. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/implot/CMakeLists.txt +0 -0
  263. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/implot/conandata.yml +0 -0
  264. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/implot/conanfile.py +0 -0
  265. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/nfd/conandata.yml +0 -0
  266. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/nfd/conanfile.py +0 -0
  267. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/sokol/conandata.yml +0 -0
  268. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/sokol/conanfile.py +0 -0
  269. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/sokol-shdc/conandata.yml +0 -0
  270. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/recipes/sokol-shdc/conanfile.py +0 -0
  271. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/schemas/render.fbs +0 -0
  272. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/schemas/semantic.fbs +0 -0
  273. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/build_pages_site.sh +0 -0
  274. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/check_cli_no_exit.py +0 -0
  275. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/check_em_js_closure.py +0 -0
  276. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/check_wasm_module_linkage.py +0 -0
  277. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/check_wheel_pair.py +0 -0
  278. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/serve_nocache.py +0 -0
  279. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/stage_wasm_viewer.sh +0 -0
  280. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/wasm_compute_smoke.js +0 -0
  281. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/scripts/windows-msvc-cmake.ps1 +0 -0
  282. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/CMakeLists.txt +0 -0
  283. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/ao.glsl +0 -0
  284. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/ao_denoise.glsl +0 -0
  285. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/blit.glsl +0 -0
  286. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/composite.glsl +0 -0
  287. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/depth_helpers.glsl.h +0 -0
  288. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/ibl_bake.glsl +0 -0
  289. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/shaders/scene.glsl +0 -0
  290. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/color_parse.cpp +0 -0
  291. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/color_parse.hpp +0 -0
  292. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_enums.hpp +0 -0
  293. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_keys.hpp +0 -0
  294. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_validator.cpp +0 -0
  295. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_validator.hpp +0 -0
  296. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/config_writer.hpp +0 -0
  297. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/predicate_parser.cpp +0 -0
  298. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/config/predicate_parser.hpp +0 -0
  299. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/detail/file_io.hpp +0 -0
  300. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/detail/glm_json.hpp +0 -0
  301. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/detail/markup.cpp +0 -0
  302. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/detail/markup.hpp +0 -0
  303. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/detail/overloaded.hpp +0 -0
  304. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/detail/timing.hpp +0 -0
  305. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/diagnostics.hpp +0 -0
  306. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/export_resolve.cpp +0 -0
  307. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/export_resolve.hpp +0 -0
  308. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/render/flatbuffer.cpp +0 -0
  309. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/render/flatbuffer.hpp +0 -0
  310. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/exporter.hpp +0 -0
  311. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/flatbuffer.cpp +0 -0
  312. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/flatbuffer.hpp +0 -0
  313. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/gltf/render/exporter.hpp +0 -0
  314. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/json/semantic/exporter.hpp +0 -0
  315. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/json/semantic/importer.cpp +0 -0
  316. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/json/semantic/importer.hpp +0 -0
  317. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/obj/render/exporter.cpp +0 -0
  318. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/obj/render/exporter.hpp +0 -0
  319. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/provenance.hpp +0 -0
  320. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic/exporter_registry.cpp +0 -0
  321. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic/importer.hpp +0 -0
  322. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic/importer_registry.cpp +0 -0
  323. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic.cpp +0 -0
  324. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic.hpp +0 -0
  325. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/semantic_json.hpp +0 -0
  326. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/synthetic/semantic/importer.cpp +0 -0
  327. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/synthetic/semantic/importer.hpp +0 -0
  328. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/importer.cpp +0 -0
  329. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/importer.hpp +0 -0
  330. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/shape_dispatch.cpp +0 -0
  331. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/shape_dispatch.hpp +0 -0
  332. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/python/CMakeLists.txt +0 -0
  333. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/scene_build.cpp +0 -0
  334. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/scene_build.hpp +0 -0
  335. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/selection/predicate.cpp +0 -0
  336. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/selection/predicate.hpp +0 -0
  337. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/selection/selector.cpp +0 -0
  338. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/selection/selector.hpp +0 -0
  339. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/sokol/sokol_imgui_impl.cc +0 -0
  340. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/sokol/sokol_imgui_impl.mm +0 -0
  341. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/sokol/sokol_impl.c +0 -0
  342. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/sokol/sokol_impl.mm +0 -0
  343. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/boolean_tessellator.cpp +0 -0
  344. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/boolean_tessellator.hpp +0 -0
  345. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/build_pipeline.cpp +0 -0
  346. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/build_pipeline.hpp +0 -0
  347. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/primitive_tessellator.cpp +0 -0
  348. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/primitive_tessellator.hpp +0 -0
  349. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/tessellation_job.hpp +0 -0
  350. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/tessellation_pass.cpp +0 -0
  351. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/tessellation_pass.hpp +0 -0
  352. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/tessellator.hpp +0 -0
  353. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/wedge_cut.cpp +0 -0
  354. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tessellation/wedge_cut.hpp +0 -0
  355. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/tools/imgui_kitchen_sink_main.cpp +0 -0
  356. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/version.cpp +0 -0
  357. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/CMakeLists.txt +0 -0
  358. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ao_denoise_pass.cpp +0 -0
  359. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ao_denoise_pass.hpp +0 -0
  360. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ao_pass.cpp +0 -0
  361. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ao_pass.hpp +0 -0
  362. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ao_render_target.cpp +0 -0
  363. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ao_render_target.hpp +0 -0
  364. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/app.cpp +0 -0
  365. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/app.hpp +0 -0
  366. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/app_state.cpp +0 -0
  367. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/app_state.hpp +0 -0
  368. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/archive_export.cpp +0 -0
  369. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/archive_export.hpp +0 -0
  370. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/archive_project_fs.cpp +0 -0
  371. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/archive_project_fs.hpp +0 -0
  372. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/backend_caps.hpp +0 -0
  373. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/bag_project_fs.cpp +0 -0
  374. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/bag_project_fs.hpp +0 -0
  375. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/bench_runner.cpp +0 -0
  376. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/bench_runner.hpp +0 -0
  377. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/blit_pass.cpp +0 -0
  378. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/blit_pass.hpp +0 -0
  379. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/build_controller.cpp +0 -0
  380. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/build_controller.hpp +0 -0
  381. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/build_session.cpp +0 -0
  382. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/build_session.hpp +0 -0
  383. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/byte_buffer.hpp +0 -0
  384. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/camera.cpp +0 -0
  385. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/camera.hpp +0 -0
  386. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/composite_pass.cpp +0 -0
  387. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/composite_pass.hpp +0 -0
  388. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/config.hpp +0 -0
  389. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/dynamic_render_scale.cpp +0 -0
  390. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/dynamic_render_scale.hpp +0 -0
  391. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/filesystem_project_fs.cpp +0 -0
  392. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/filesystem_project_fs.hpp +0 -0
  393. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/gpu_pass_timer.hpp +0 -0
  394. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/gpu_pass_timer_d3d11.cpp +0 -0
  395. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/gpu_pass_timer_noop.cpp +0 -0
  396. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ibl.cpp +0 -0
  397. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ibl.hpp +0 -0
  398. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ibl_baker.cpp +0 -0
  399. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ibl_baker.hpp +0 -0
  400. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/imgui_backend.cpp +0 -0
  401. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/imgui_backend.hpp +0 -0
  402. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/log_sink.hpp +0 -0
  403. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/native_bag_project_fs.cpp +0 -0
  404. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/native_bag_project_fs.hpp +0 -0
  405. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/platform.hpp +0 -0
  406. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/platform_macos.mm +0 -0
  407. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/platform_native_common.cpp +0 -0
  408. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/platform_native_common.hpp +0 -0
  409. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/platform_native_default.cpp +0 -0
  410. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/platform_web.cpp +0 -0
  411. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_export.cpp +0 -0
  412. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_export.hpp +0 -0
  413. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback.hpp +0 -0
  414. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_d3d11.cpp +0 -0
  415. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_gl.cpp +0 -0
  416. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_metal.mm +0 -0
  417. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_wgpu.cpp +0 -0
  418. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_exporter.cpp +0 -0
  419. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/png_exporter.hpp +0 -0
  420. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/project_fs.hpp +0 -0
  421. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/project_manifest.cpp +0 -0
  422. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/render_quality.hpp +0 -0
  423. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job.hpp +0 -0
  424. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_common.cpp +0 -0
  425. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_internal.hpp +0 -0
  426. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_native.cpp +0 -0
  427. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_web.cpp +0 -0
  428. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_web_backend.hpp +0 -0
  429. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_web_worker.cpp +0 -0
  430. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_render_target.cpp +0 -0
  431. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_render_target.hpp +0 -0
  432. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_renderer.cpp +0 -0
  433. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/scene_renderer.hpp +0 -0
  434. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/shared_image.hpp +0 -0
  435. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/stb_image_write_impl.cpp +0 -0
  436. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/debug_panel.cpp +0 -0
  437. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/debug_panel.hpp +0 -0
  438. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/icon_font.cpp +0 -0
  439. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/icon_font.hpp +0 -0
  440. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/menu_bar.cpp +0 -0
  441. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/menu_bar.hpp +0 -0
  442. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/notifications.cpp +0 -0
  443. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/notifications.hpp +0 -0
  444. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/perf_history.hpp +0 -0
  445. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/project_panel.cpp +0 -0
  446. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/project_panel.hpp +0 -0
  447. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/status_ui.cpp +0 -0
  448. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/status_ui.hpp +0 -0
  449. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/ui_context.hpp +0 -0
  450. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/view_panel.cpp +0 -0
  451. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/view_panel.hpp +0 -0
  452. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/viewer_ui.cpp +0 -0
  453. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/ui/viewer_ui.hpp +0 -0
  454. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/watched_filesystem_project_fs.cpp +0 -0
  455. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/watched_filesystem_project_fs.hpp +0 -0
  456. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/viewer/zip_working_set.hpp +0 -0
  457. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/compute_worker.js +0 -0
  458. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/compute_worker_main.cpp +0 -0
  459. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/executable_path.cpp +0 -0
  460. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/open_browser.cpp +0 -0
  461. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/open_browser.hpp +0 -0
  462. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/stage.hpp +0 -0
  463. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/static_server.cpp +0 -0
  464. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/static_server.hpp +0 -0
  465. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/src/web/viewer_main.cpp +0 -0
  466. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/bench_main.cpp +0 -0
  467. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/config/test_config_fixtures.cpp +0 -0
  468. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/config/test_config_validator.cpp +0 -0
  469. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/config/test_lua_config.cpp +0 -0
  470. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/config/test_predicate_parser.cpp +0 -0
  471. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/export/test_export_resolve.cpp +0 -0
  472. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/export/test_gltf_exporter.cpp +0 -0
  473. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/export/test_render_exporter_registry.cpp +0 -0
  474. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/export/test_semantic_exporter_registry.cpp +0 -0
  475. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/import/test_synthetic_importer.cpp +0 -0
  476. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/import/test_tgeo_importer.cpp +0 -0
  477. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/ir/test_render_flatbuffer_roundtrip.cpp +0 -0
  478. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/ir/test_semantic_ir.cpp +0 -0
  479. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/ir/test_shape_variant.cpp +0 -0
  480. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/selection/test_predicate.cpp +0 -0
  481. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/selection/test_selector.cpp +0 -0
  482. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/tessellation/test_boolean_tessellator.cpp +0 -0
  483. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/tessellation/test_build_pipeline.cpp +0 -0
  484. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/tessellation/test_obj_writer.hpp +0 -0
  485. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/tessellation/test_primitive_tessellator.cpp +0 -0
  486. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/tessellation/test_tessellation_pass.cpp +0 -0
  487. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/tessellation/test_tgeo_tessellation.cpp +0 -0
  488. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/tessellation/test_wedge_cut.cpp +0 -0
  489. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/test_compute_pipeline.cpp +0 -0
  490. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/test_main.cpp +0 -0
  491. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/test_markup.cpp +0 -0
  492. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/test_scene_build.cpp +0 -0
  493. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/test_timing.cpp +0 -0
  494. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_app_state.cpp +0 -0
  495. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_archive_export.cpp +0 -0
  496. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_archive_project_fs.cpp +0 -0
  497. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_bag_project_fs.cpp +0 -0
  498. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_build_session.cpp +0 -0
  499. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_byte_buffer.cpp +0 -0
  500. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_dynamic_render_scale.cpp +0 -0
  501. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_filesystem_project_fs.cpp +0 -0
  502. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_native_bag_project_fs.cpp +0 -0
  503. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_project_manifest.cpp +0 -0
  504. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/viewer/test_watched_filesystem_project_fs.cpp +0 -0
  505. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/tests/web/test_stage.cpp +0 -0
  506. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/third_party/fontawesome7/IconsFontAwesome7.h +0 -0
  507. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/third_party/fontawesome7/README.md +0 -0
  508. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/third_party/fontawesome7/fa-solid-900.h +0 -0
  509. {nodehammer-0.2.0rc3 → nodehammer-0.2.0rc6}/third_party/stb/stb_image_write.h +0 -0
@@ -0,0 +1,249 @@
1
+ ---
2
+ name: nodehammer
3
+ description: Drive the nodehammer CLI — convert HEP detector geometry (DD4hep XML, ROOT TGeo, .nhb) to glTF/OBJ/JSON, inspect a scene as JSON, validate and flatten TOML/Lua scene configs, pack and publish .nhproj project archives, and render or serve the 3D viewer. Use for nodehammer, nhb, nhr, .nhproj, nodehammer.toml, "convert geometry", "tessellate", "detector geometry", "wedge cut", NH#### diagnostic codes, or `uvx nodehammer`.
4
+ ---
5
+
6
+ # nodehammer
7
+
8
+ A pipeline that imports detector geometry, applies a config that selects and
9
+ styles parts of it, and writes it out — as a mesh (glTF/OBJ), as an intermediate
10
+ scene, as a JSON report, or into an interactive viewer.
11
+
12
+ Same program either way: the compiled `nodehammer` executable and the
13
+ `nodehammer` command from the Python wheel are one implementation (`cli::run`
14
+ inside `libnodehammer`), so every command here behaves identically under
15
+ `uvx nodehammer`. Differences that do exist are noted as such.
16
+
17
+ ## The output contract — read this before parsing anything
18
+
19
+ **stdout is the answer. stderr is everything about producing it.**
20
+
21
+ stdout carries the thing you would substitute into the next command: the
22
+ flattened document, the JSON report, the path to the archive that was written,
23
+ the URL being served. stderr carries diagnostics, progress and summaries.
24
+
25
+ ```bash
26
+ archive=$(nodehammer project pack -c scene.toml -i det.root -o det.nhproj)
27
+ ```
28
+
29
+ That yields the archive path, not a report about one. Two consequences:
30
+
31
+ - **Never parse stderr.** It is prose for a human and is not a stable format.
32
+ - **`-q` silences narration only.** Diagnostics, and the line a failing command
33
+ prints before it exits non-zero, are never affected. A flag that hid errors
34
+ would be a trap. `-v` restores narration; `-q`/`-v` may be typed before or
35
+ after the subcommand.
36
+
37
+ When calling `nodehammer` from a script, quiet is already the default for the
38
+ library entry point; the executable defaults to narrating because a person typed
39
+ it.
40
+
41
+ ## Commands
42
+
43
+ Five groups. Every one takes `-h`.
44
+
45
+ | | |
46
+ |---|---|
47
+ | `convert` | import → config → write. The **output extension decides how far the pipeline runs** |
48
+ | `inspect summary\|tree\|tags` | report on a geometry file; `--output-format json` |
49
+ | `config validate\|flatten` | check a config, or resolve it to one self-contained TOML |
50
+ | `project pack\|publish\|info` | build, publish and read `.nhproj` archives |
51
+ | `viewer open\|serve\|shot\|bench` | the 3D viewer, in four postures |
52
+
53
+ Option spellings are consistent across the tree: `-i/--input`, `-c/--config`,
54
+ `-o/--output`, `--input-format`, `--output-format`, `--color`, `--depth/-d`,
55
+ `--filter/-f` mean the same thing everywhere they appear.
56
+
57
+ ### Commands that block — do not run these unprompted
58
+
59
+ | Command | What it does | Use instead |
60
+ |---|---|---|
61
+ | `viewer open` | opens a **native window and blocks** until the user closes it | `viewer shot -o out.png` |
62
+ | `viewer` (bare, with a path) | same — `open` is the default mode | `viewer shot` |
63
+ | `viewer serve` | starts an HTTP server, **opens a browser, and blocks** | `viewer serve --no-browser` in a background job, or `project publish` for static output |
64
+ | `viewer bench` | runs a GPU benchmark; needs a display | only when the user asked for numbers |
65
+
66
+ To *see* what a scene looks like, `nodehammer viewer shot <project> -o shot.png
67
+ --shot-width 1920` renders one PNG once the scene settles and quits. That is the
68
+ agent-appropriate way to check a geometry visually. It still needs a working GPU
69
+ context, so it will fail on a headless machine with no display.
70
+
71
+ Everything else in the tree runs to completion and exits.
72
+
73
+ ### convert
74
+
75
+ ```bash
76
+ nodehammer convert -i det.root -c scene.toml -o det.glb
77
+ nodehammer convert -i det.root -o scene.nhb # stop at the semantic scene
78
+ nodehammer convert -i det.root -o a.glb -o b.obj # several outputs, one import
79
+ ```
80
+
81
+ The output extension picks the writer *and* the depth of the pipeline:
82
+
83
+ - `.nhb`, `.json` — the **semantic** scene. No tessellation. Fast.
84
+ - `.glb`/`.gltf`, `.obj`, `.nhr`, render-JSON — **tessellated** first.
85
+
86
+ `--timing` prints per-step wall clock, `--size-report` a payload breakdown; both
87
+ to stderr, and both survive `-q` because naming a report is asking for it.
88
+ `--strict` turns warnings into errors. `--wedge-cut START END` performs a real
89
+ Manifold boolean, removing the azimuthal sector from START to END degrees
90
+ measured from +x counter-clockwise — this is geometry, not a display effect.
91
+
92
+ ### inspect — the machine-readable one
93
+
94
+ ```bash
95
+ nodehammer inspect --output-format json summary -i det.root
96
+ nodehammer inspect --output-format json tree -i det.root --depth 3 --filter '*/Pixel*'
97
+ nodehammer inspect --output-format json tags -i det.root
98
+ ```
99
+
100
+ **Text and JSON are not the same content in two skins.** The text view draws
101
+ tree lines, samples a tag key down to five values once it passes ten, and
102
+ appends a "(n shown, m filtered)" footer. Parse the JSON, which carries the
103
+ whole set and no drawing. Every document is stamped `"schema": 1`.
104
+
105
+ ```jsonc
106
+ // summary
107
+ { "schema": 1, "kind": "summary", "format": "tgeo",
108
+ "nodes": 12043, "shapes": { "Box": 900, ... },
109
+ "materials": ["Air", ...], // sorted
110
+ "diagnostics": { "warnings": 3, "errors": 0 } }
111
+
112
+ // tree
113
+ { "schema": 1, "kind": "tree", "shown": 40, "filtered": 12003,
114
+ "maxDepth": 3, // null when no limit applied — present, not absent
115
+ "filter": "*/Pixel*", // null when none
116
+ "nodes": [ { "path": "/World/Det", "name": "Det", "depth": 1,
117
+ "children": 4, "leaf": false, "tags": {...} } ] }
118
+
119
+ // tags
120
+ { "schema": 1, "kind": "tags", "nodeCount": 12043, "nodesWithTags": 800,
121
+ "keys": { "subdetector": ["pixel", "strip"] } } // every value, not a sample
122
+ ```
123
+
124
+ `maxDepth` and `filter` are **present-and-null** rather than absent, so read them
125
+ unconditionally. `tags` is absent from a tree node that has none.
126
+
127
+ ### config
128
+
129
+ Configs come in two spellings, and the file decides which: `.toml` (with an
130
+ `include` chain) or `.lua` (a script that is evaluated). Both commands take
131
+ either — **do not look for a separate Lua command, there isn't one**.
132
+
133
+ ```bash
134
+ nodehammer config validate -c scene.lua
135
+ nodehammer config flatten -c scene.toml -o flat.toml # -o optional; stdout otherwise
136
+ ```
137
+
138
+ `config flatten` is the tool to reach for whenever you need to know what a config
139
+ *actually* says: it resolves the include tree (or runs the script) and emits one
140
+ self-contained TOML that needs no companion files. Its output is round-trippable.
141
+
142
+ ### project — `.nhproj` archives
143
+
144
+ A `.nhproj` is a ZIP holding a config, the geometry it names, and a manifest.
145
+
146
+ ```bash
147
+ nodehammer project pack -c scene.toml -i det.root -o det.nhproj
148
+ nodehammer project info det.nhproj
149
+ nodehammer project publish det.nhproj -o site/ # static site, no server
150
+ ```
151
+
152
+ **`nodehammer.toml` inside an archive is a reserved key.** It is the manifest
153
+ naming the entry config and geometry. `project pack` refuses rather than
154
+ overwriting when a config is actually named that, or an include resolves to it.
155
+ Do not hand-write it, and do not unzip an archive, edit, and re-zip — repack from
156
+ sources instead.
157
+
158
+ `project publish` produces a directory you can serve with any static file server
159
+ (GitHub Pages included). Prefer it over `viewer serve` for anything an agent
160
+ produces, because it terminates.
161
+
162
+ ## Inherent limitations — not bugs to work around
163
+
164
+ **The importable set is smaller than the file types people assume.** Built in
165
+ unconditionally: `.nhb` / `.nhb.zst`, `.json` / `.json.zst`, and the synthetic
166
+ generator. Compile-time gated: `.root` (TGeo) and DD4hep XML. There is **no GDML
167
+ importer** — a `.gdml` path will not resolve however you spell `--input-format`.
168
+
169
+ **Heavy importers are compile-time options, not runtime ones.** `NODEHAMMER_WITH_TGEO`,
170
+ `NODEHAMMER_WITH_DD4HEP`, `NODEHAMMER_WITH_GEANT4`, `NODEHAMMER_WITH_GEOMODEL` are
171
+ **off by default**, and the released Python wheel is built without them. So
172
+ `cannot determine input format for 'det.root'` from a wheel install is the build
173
+ configuration, not a broken file and not a bug — the fix is a build with the
174
+ backend enabled, never a different flag. Check with
175
+ `nodehammer convert -i x.root -o /dev/null` and read the code, not the extension.
176
+
177
+ **DD4hep XML has no extension of its own.** It is recognised by sniffing for
178
+ `<lccdd` in the first 512 bytes, or by `--input-format dd4hep` when the sniff
179
+ fails. A generic `.xml` that is not DD4hep will not resolve.
180
+
181
+ **`viewer serve` needs a wasm runtime this build cannot produce.** It comes from
182
+ the separate `nodehammer-web` distribution, which the Python package depends on.
183
+ `NH1000` means it was not found; the command prints the search ladder it walked.
184
+ `--web-assets DIR` points at a locally built one.
185
+
186
+ **A wasm build has no `project` or `viewer serve`.** There is no host to serve
187
+ from — the wasm module *is* the viewer.
188
+
189
+ ## Diagnostics
190
+
191
+ Every failure carries a stable `NH####` code, greppable and safe to match on.
192
+ Ranges: `NH00xx` config · `NH01xx` import · `NH02xx` scene ops · `NH03xx` TGeo ·
193
+ `NH04xx` selection · `NH05xx` tessellation · `NH06xx` export · `NH08xx` public
194
+ API · `NH09xx` CLI usage · `NH10xx` web runtime · `NH11xx` project archives.
195
+
196
+ The prefix in the code's *name* says how far it goes: fatal (the call could not
197
+ deliver), error (the result exists and part of it is wrong), warning (complete,
198
+ something was assumed).
199
+
200
+ | You see | It means | Do |
201
+ |---|---|---|
202
+ | `NH0101 cannot determine input format for '…'` | extension unknown **or backend not compiled in** | check the limitations above before anything else |
203
+ | `NH0900 positional path must be a .nhproj archive or a directory` | `viewer <path>` got something else | pass a `.nhproj` or a directory |
204
+ | `NH0901 path not found` / `input file not found` | a typo, before any window opens | — |
205
+ | `NH1000` | wasm runtime missing | `pip install nodehammer-web`, or `--web-assets DIR` |
206
+ | `NH1001` | runtime and library disagree | rebuild both halves together |
207
+ | `NH1100` | archive could not be assembled or read | `project info` on it; do not unzip by hand |
208
+ | `NH0008 drop_coincident_faces … without merge_descendants` | the option is silently a no-op | enable `merge_descendants` in the same scope |
209
+
210
+ ## Recipes
211
+
212
+ **"What is in this file?"** → `nodehammer inspect --output-format json summary -i FILE`
213
+
214
+ **"What does this config actually do?"** → `nodehammer config flatten -c FILE`
215
+ (resolves includes and Lua), then read the TOML.
216
+
217
+ **"Show me the geometry."** → `nodehammer viewer shot FILE -o /tmp/shot.png
218
+ --shot-width 1920`, then look at the PNG. Never `viewer open`.
219
+
220
+ **"Make something I can share."** → `project pack` then `project publish -o site/`.
221
+
222
+ **"Is this config valid?"** → `nodehammer config validate -c FILE`; exit code is
223
+ the verdict, the report is on stderr.
224
+
225
+ **"Convert for a web page."** → `-o out.glb` (glTF binary), not `.obj`.
226
+
227
+ ## Do not
228
+
229
+ - **Do not run `viewer open`, bare `viewer <path>`, or `viewer serve` without
230
+ being asked.** They block until a human intervenes.
231
+ - **Do not parse stderr**, or the text form of `inspect`. Use
232
+ `--output-format json`.
233
+ - **Do not unzip, edit and re-zip a `.nhproj`.** Repack from sources.
234
+ - **Do not hand-write `nodehammer.toml` inside an archive** — `project pack`
235
+ owns that key.
236
+ - **Do not treat a missing importer as a broken file.** Check the compile-time
237
+ gates first.
238
+ - **Do not add `-q` to make output parseable.** It only removes narration from
239
+ stderr; stdout was already clean.
240
+
241
+ ## Getting this skill
242
+
243
+ It ships inside the binary and is installed with:
244
+
245
+ ```bash
246
+ nodehammer skills install # into ~/.agents/skills, linked from ~/.claude
247
+ nodehammer skills install --scope project
248
+ nodehammer skills list
249
+ ```
@@ -14,7 +14,7 @@
14
14
  # Project archives packed by the viewer / make_nhproj.py — always generated.
15
15
  *.nhproj
16
16
 
17
- # config-flatten output written to the repo root (generated from fixtures/).
17
+ # `config flatten` output written to the repo root (generated from fixtures/).
18
18
  /*_flat.toml
19
19
  CMakeUserPresets.json
20
20
 
@@ -10,6 +10,14 @@ project(nodehammer
10
10
  LANGUAGES C CXX
11
11
  )
12
12
 
13
+ # This branch returns before discovering or configuring any processing,
14
+ # application, Python, or viewer dependencies.
15
+ option(NODEHAMMER_INGEST_ONLY "Build only the C++20 geometry ingestion library" OFF)
16
+ if(NODEHAMMER_INGEST_ONLY)
17
+ include(cmake/IngestionOnly.cmake)
18
+ return()
19
+ endif()
20
+
13
21
  set(CMAKE_CXX_STANDARD 23)
14
22
  set(CMAKE_CXX_STANDARD_REQUIRED ON)
15
23
  set(CMAKE_CXX_EXTENSIONS OFF)
@@ -133,10 +141,28 @@ include(cmake/CompilerOptions.cmake)
133
141
  # Included early: the core-library helper below bakes CMAKE_INSTALL_INCLUDEDIR
134
142
  # into the shared target's INSTALL_INTERFACE include path.
135
143
  include(GNUInstallDirs)
144
+ include(cmake/PublicBackendHeaders.cmake)
145
+ # Profiling flags are additive on top of any build type (Release, RelWithDebInfo,
146
+ # Debug). Same interface across native and wasm; the flags differ per toolchain:
147
+ # Clang/GCC get -g + frame pointers; MSVC gets /Zi + /Oy-; emscripten gets
148
+ # --profiling-funcs on top so wasm function names survive the linker.
149
+ if(NODEHAMMER_PROFILING)
150
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
151
+ add_compile_options(-g -fno-omit-frame-pointer)
152
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
153
+ add_compile_options(/Zi /Oy-)
154
+ add_link_options(/DEBUG)
155
+ endif()
156
+ if(EMSCRIPTEN)
157
+ add_link_options(--profiling-funcs)
158
+ endif()
159
+ endif()
160
+
161
+ include(cmake/Ingestion.cmake)
136
162
 
137
163
  # ── The web runtime's contract ───────────────────────────────────────────────
138
164
  # The wasm viewer is delivered as a directory, not a program: a shell, a worker
139
- # script, three bundles and the stamp below. `nodehammer viewer --web` locates
165
+ # script, three bundles and the stamp below. `nodehammer viewer serve` locates
140
166
  # one through a ladder of candidate directories (a flag, an environment
141
167
  # variable, this install path, later a download cache), which means it can be
142
168
  # handed a directory that nobody validated — an old checkout's build tree is
@@ -162,21 +188,12 @@ set(NH_WEB_RUNTIME_DIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/web")
162
188
 
163
189
  # ── FlatBuffers code generation ──────────────────────────────────────────────
164
190
  set(NH_FBS_SCHEMAS
165
- ${CMAKE_CURRENT_SOURCE_DIR}/schemas/semantic.fbs
166
191
  ${CMAKE_CURRENT_SOURCE_DIR}/schemas/render.fbs
167
192
  )
168
193
  set(NH_FBS_GENERATED_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated/flatbuffers)
169
194
 
170
- # Conan tool_requires exposes flatbuffers::flatc; FetchContent builds a plain
171
- # flatc target; a system install is on PATH. Resolve to whichever is present.
172
- if(TARGET flatbuffers::flatc)
173
- set(NH_FLATC flatbuffers::flatc)
174
- elseif(TARGET flatc)
175
- set(NH_FLATC flatc)
176
- else()
177
- find_program(NH_FLATC_EXE flatc REQUIRED)
178
- set(NH_FLATC "${NH_FLATC_EXE}")
179
- endif()
195
+ # Use the same host schema compiler as the ingestion module.
196
+ set(NH_FLATC ${NH_INGEST_FLATC})
180
197
 
181
198
  set(NH_FBS_GENERATED_HEADERS "")
182
199
  foreach(schema ${NH_FBS_SCHEMAS})
@@ -192,22 +209,7 @@ foreach(schema ${NH_FBS_SCHEMAS})
192
209
  list(APPEND NH_FBS_GENERATED_HEADERS ${out})
193
210
  endforeach()
194
211
  add_custom_target(flatbuffers_generate DEPENDS ${NH_FBS_GENERATED_HEADERS})
195
-
196
- # Profiling flags are additive on top of any build type (Release, RelWithDebInfo,
197
- # Debug). Same interface across native and wasm; the flags differ per toolchain:
198
- # Clang/GCC get -g + frame pointers; MSVC gets /Zi + /Oy-; emscripten gets
199
- # --profiling-funcs on top so wasm function names survive the linker.
200
- if(NODEHAMMER_PROFILING)
201
- if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
202
- add_compile_options(-g -fno-omit-frame-pointer)
203
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
204
- add_compile_options(/Zi /Oy-)
205
- add_link_options(/DEBUG)
206
- endif()
207
- if(EMSCRIPTEN)
208
- add_link_options(--profiling-funcs)
209
- endif()
210
- endif()
212
+ add_dependencies(flatbuffers_generate nodehammer_semantic_generate)
211
213
 
212
214
  # ── Core library configuration ────────────────────────────────────────────────
213
215
  # Pipeline core: IR + config + selection + tessellation + importers/exporters
@@ -228,9 +230,9 @@ endif()
228
230
  # packaging build describes the core once and builds it twice: the static
229
231
  # archive every in-tree target links, and the installed shared library. Anything
230
232
  # appended to *this* list reaches both — that is where the "describe once"
231
- # guarantee lives. NH_APP_SOURCES below is the deliberate exception.
233
+ # guarantee lives. Ingestion sources are defined in Ingestion.cmake and reused
234
+ # as objects; NH_APP_SOURCES below is the executable-only exception.
232
235
  set(NH_CORE_SOURCES
233
- src/ir/semantic.cpp
234
236
  src/ir/semantic_json.cpp
235
237
  src/ir/render_json.cpp
236
238
  src/config/config_loader.cpp
@@ -241,8 +243,6 @@ set(NH_CORE_SOURCES
241
243
  src/ir/synthetic/semantic/importer.cpp
242
244
  src/ir/semantic/importer_registry.cpp
243
245
  src/ir/json/semantic/importer.cpp
244
- src/ir/fb/semantic/importer.cpp
245
- src/ir/fb/semantic/flatbuffer.cpp
246
246
  src/ir/fb/render/flatbuffer.cpp
247
247
  src/selection/predicate.cpp
248
248
  src/selection/selector.cpp
@@ -253,9 +253,12 @@ set(NH_CORE_SOURCES
253
253
  src/ir/gltf/render/exporter.cpp
254
254
  src/ir/obj/render/exporter.cpp
255
255
  src/ir/render/exporter_registry.cpp
256
+ src/ir/fb/render/exporter.cpp
257
+ src/ir/render/json_exporter.cpp
256
258
  src/ir/json/semantic/exporter.cpp
257
259
  src/ir/fb/semantic/exporter.cpp
258
260
  src/ir/semantic/exporter_registry.cpp
261
+ src/detail/env.cpp
259
262
  src/detail/markup.cpp
260
263
  # Host-side, despite the directory: locating and vetting the wasm runtime is
261
264
  # something the *serving* process does. src/web/'s other two TUs are the
@@ -264,12 +267,10 @@ set(NH_CORE_SOURCES
264
267
  src/web/executable_path.cpp
265
268
  src/scene_build.cpp
266
269
  src/export_resolve.cpp
267
- src/version.cpp
268
270
  # The public API bridge: the only translation units that see both a public
269
- # handle and its internals (src/api/handles.hpp is where the seam lives).
271
+ # handle and its internals (src/api/handles_semantic.hpp is where the seam lives).
270
272
  # Core, not app — these *are* what the installed library publishes.
271
- src/api/diagnostics.cpp
272
- src/api/semantic_scene.cpp
273
+ src/api/semantic_scene_formats.cpp
273
274
  src/api/config.cpp
274
275
  src/api/render_scene.cpp
275
276
  src/api/build.cpp
@@ -298,11 +299,7 @@ set(NH_CORE_SOURCES
298
299
  src/cli/pager.cpp
299
300
  src/cli/cmd_convert.cpp
300
301
  src/cli/cmd_inspect.cpp
301
- src/cli/cmd_validate_config.cpp
302
- src/cli/cmd_config_flatten.cpp
303
- src/cli/cmd_dump_semantic.cpp
304
- src/cli/cmd_dump_render.cpp
305
- src/cli/cmd_config_lua.cpp
302
+ src/cli/cmd_config.cpp
306
303
  )
307
304
 
308
305
  # ── Application sources ───────────────────────────────────────────────────────
@@ -332,12 +329,6 @@ set(NH_APP_SOURCES
332
329
  set(NH_APP_DEPS "")
333
330
  set(NH_APP_DEFINES "")
334
331
 
335
- configure_file(
336
- ${CMAKE_CURRENT_SOURCE_DIR}/include/nodehammer/version.hpp.in
337
- ${CMAKE_CURRENT_BINARY_DIR}/include/nodehammer/version.hpp
338
- @ONLY
339
- )
340
-
341
332
  # PUBLIC on the archive, because an internal header names the dependency where an
342
333
  # out-of-core target sees it. Each entry cites the header that justifies it;
343
334
  # remove one and the build fails. (Scope on the shared library is a different
@@ -419,23 +410,9 @@ list(APPEND NH_CORE_SOURCES src/lua/lua_config.cpp)
419
410
  # binding stay inside the core's implementation.
420
411
  list(APPEND NH_CORE_PRIVATE_DEPS lua::lua sol2::sol2)
421
412
 
422
- if(NODEHAMMER_WITH_TGEO OR NODEHAMMER_WITH_DD4HEP)
423
- find_package(ROOT REQUIRED COMPONENTS Geom)
424
- list(APPEND NH_CORE_SOURCES src/ir/tgeo/semantic/shape_dispatch.cpp)
425
- list(APPEND NH_CORE_DEPS ROOT::Geom)
426
- list(APPEND NH_CORE_DEFINES NH_WITH_TGEO=1)
427
- endif()
428
-
429
- if(NODEHAMMER_WITH_TGEO)
430
- list(APPEND NH_CORE_SOURCES src/ir/tgeo/semantic/importer.cpp)
431
- endif()
432
-
433
- if(NODEHAMMER_WITH_DD4HEP)
434
- find_package(DD4hep REQUIRED)
435
- list(APPEND NH_CORE_SOURCES src/ir/dd4hep/semantic/importer.cpp)
436
- list(APPEND NH_CORE_DEPS DD4hep::DDCore)
437
- list(APPEND NH_CORE_DEFINES NH_WITH_DD4HEP=1)
438
- endif()
413
+ # The ingestion module resolves the enabled experiment backends once.
414
+ list(APPEND NH_CORE_DEPS ${NH_INGEST_BACKEND_DEPS})
415
+ list(APPEND NH_CORE_DEFINES ${NH_INGEST_DEFINES})
439
416
 
440
417
  if(NODEHAMMER_WITH_GEANT4)
441
418
  find_package(Geant4 REQUIRED)
@@ -478,7 +455,11 @@ if(NOT EMSCRIPTEN)
478
455
  src/web/static_server.cpp
479
456
  src/web/stage.cpp
480
457
  src/web/open_browser.cpp
481
- # `viewer --web` itself. Excluded here rather than #ifdef'd inside:
458
+ # Packing mounts a FilesystemProjectFs, so it is gated here rather than
459
+ # beside the ZipWorkingSet it builds -- that half *is* cross-platform.
460
+ src/project/pack.cpp
461
+ src/cli/cmd_project.cpp
462
+ # `viewer serve` itself. Excluded here rather than #ifdef'd inside:
482
463
  # every line of it calls something in the three files above, so a wasm
483
464
  # build of this TU would be a shell around a refusal. `run.cpp` skips
484
465
  # the registration to match, and a wasm module simply has no `viewer`
@@ -489,6 +470,37 @@ if(NOT EMSCRIPTEN)
489
470
  # least of all a header. Header-only, so the shared library gains no link
490
471
  # dependency and its package config gains no requirement.
491
472
  list(APPEND NH_CORE_PRIVATE_DEPS httplib::httplib)
473
+
474
+ # ── Agent skills, compiled in ─────────────────────────────────────────────
475
+ #
476
+ # `skills install` writes files into $HOME or a repo, which under Emscripten
477
+ # would mean a virtual filesystem that vanishes with the tab -- so the whole
478
+ # feature is native-only, and a wasm module carries none of the bytes.
479
+ #
480
+ # CONFIGURE_DEPENDS so that *adding* a skill re-globs on the next build
481
+ # rather than needing a manual configure; the explicit DEPENDS below is what
482
+ # makes *editing* one regenerate. Both are needed: the glob answers "which
483
+ # files", the dependency answers "have they changed".
484
+ file(GLOB_RECURSE NH_SKILL_FILES CONFIGURE_DEPENDS
485
+ ${CMAKE_CURRENT_SOURCE_DIR}/skills/*)
486
+ set(NH_SKILLS_DATA ${CMAKE_CURRENT_BINARY_DIR}/generated/skills/skills_data.cpp)
487
+ add_custom_command(
488
+ OUTPUT ${NH_SKILLS_DATA}
489
+ COMMAND ${CMAKE_COMMAND}
490
+ -DNH_SKILLS_DIR=${CMAKE_CURRENT_SOURCE_DIR}/skills
491
+ "-DNH_SKILLS_FILES=${NH_SKILL_FILES}"
492
+ -DNH_SKILLS_OUT=${NH_SKILLS_DATA}
493
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateSkillsData.cmake
494
+ DEPENDS
495
+ ${NH_SKILL_FILES}
496
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateSkillsData.cmake
497
+ COMMENT "Embedding agent skills"
498
+ VERBATIM
499
+ )
500
+ list(APPEND NH_CORE_SOURCES
501
+ ${NH_SKILLS_DATA}
502
+ src/cli/cmd_skills.cpp
503
+ )
492
504
  endif()
493
505
 
494
506
  # WatchedFilesystemProjectFs (strategy doc step 4) decorates FilesystemProjectFs
@@ -601,7 +613,8 @@ endif()
601
613
  # What every in-tree target links — CLI, viewer, tests, benchmarks. Core + app
602
614
  # sources. Never installed, so its dependencies are PUBLIC: in-tree targets reach
603
615
  # toml++, glm and nlohmann through this link.
604
- add_library(nodehammer_lib STATIC ${NH_CORE_INPUT} ${NH_APP_SOURCES})
616
+ add_library(nodehammer_lib STATIC ${NH_CORE_INPUT} ${NH_APP_SOURCES}
617
+ $<TARGET_OBJECTS:nodehammer_ingest_objs>)
605
618
  nh_core_common(nodehammer_lib)
606
619
 
607
620
  target_link_libraries(nodehammer_lib PUBLIC ${NH_CORE_DEPS} ${NH_APP_DEPS})
@@ -641,7 +654,10 @@ if(NODEHAMMER_BUILD_SHARED)
641
654
 
642
655
  # Core only — no NH_APP_SOURCES. NH_CORE_INPUT is either the sources or the
643
656
  # shared objects, per the OBJECT block above.
644
- add_library(nodehammer_shared SHARED ${NH_CORE_INPUT})
657
+ add_library(nodehammer_shared SHARED ${NH_CORE_INPUT}
658
+ $<TARGET_OBJECTS:${NH_INGEST_SHARED_OBJECTS}>)
659
+ add_library(nodehammer::shared ALIAS nodehammer_shared)
660
+ add_library(nodehammer::nodehammer ALIAS nodehammer_shared)
645
661
  nh_core_common(nodehammer_shared)
646
662
 
647
663
  # Plain PRIVATE is enough to keep the generated export empty, so a consumer
@@ -695,11 +711,10 @@ if(NODEHAMMER_BUILD_SHARED)
695
711
  # library itself; PRIVATE, since a consumer must see dllimport instead.
696
712
  target_compile_definitions(nodehammer_shared PRIVATE NH_EXPORTS)
697
713
 
698
- # The exported name is `nodehammer`; the target cannot be, because the CLI
699
- # executable already owns that target name.
714
+ # A consistent component target name in source and installed consumers.
700
715
  set_target_properties(nodehammer_shared PROPERTIES
701
716
  OUTPUT_NAME nodehammer
702
- EXPORT_NAME nodehammer
717
+ EXPORT_NAME shared
703
718
  )
704
719
 
705
720
  # Version the library only when it is going to be installed as a system
@@ -868,7 +883,6 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
868
883
  src/scene_build.cpp
869
884
  src/selection/selector.cpp
870
885
  src/cli/cmd_convert.cpp
871
- src/cli/cmd_dump_semantic.cpp
872
886
  PROPERTIES COMPILE_OPTIONS "-Wno-maybe-uninitialized"
873
887
  )
874
888
  endif()
@@ -877,6 +891,7 @@ endif()
877
891
  if(NODEHAMMER_BUILD_TESTS)
878
892
  enable_testing()
879
893
  add_subdirectory(tests)
894
+ add_subdirectory(tests/ingest)
880
895
  endif()
881
896
 
882
897
  # ── Python extension ───────────────────────────────────────────────────────────
@@ -912,7 +927,7 @@ if(EMSCRIPTEN AND NODEHAMMER_WITH_VIEWER)
912
927
  # share/nodehammer/web is also the rung the asset ladder looks for relative
913
928
  # to the executable (docs/cli-and-web-viewer-plan.md Part 1), which is why
914
929
  # it is a datadir path and not an opaque one: a native install tree and a
915
- # wasm install tree merge into one directory that `nodehammer viewer --web`
930
+ # wasm install tree merge into one directory that `nodehammer viewer serve`
916
931
  # can resolve without being told where anything is.
917
932
  install(TARGETS nodehammer-gles3 nodehammer-wgpu nodehammer-compute
918
933
  RUNTIME DESTINATION "${NH_WEB_RUNTIME_DIR}"
@@ -942,7 +957,7 @@ if(EMSCRIPTEN AND NODEHAMMER_WITH_VIEWER)
942
957
 
943
958
  # The stamp, written beside the bundles in the build tree so that a build
944
959
  # directory and an install tree are the same shape — `just wasm-serve` and
945
- # `just pages-site` stage straight out of the former, and `viewer --web
960
+ # `just pages-site` stage straight out of the former, and `viewer serve
946
961
  # --web-assets build/emscripten/Release` is the first thing any developer
947
962
  # reaches for.
948
963
  file(GENERATE
@@ -1007,7 +1022,7 @@ if(NODEHAMMER_BUILD_SHARED)
1007
1022
  # linker resolving -lnodehammer reads it). Windows has no namelink; its
1008
1023
  # equivalent is .dll against .lib, stated by RUNTIME and ARCHIVE below.
1009
1024
  install(TARGETS nodehammer_shared
1010
- EXPORT nodehammer-targets
1025
+ EXPORT nodehammer-shared-targets
1011
1026
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
1012
1027
  COMPONENT Runtime
1013
1028
  NAMELINK_COMPONENT Development
@@ -1045,59 +1060,12 @@ if(NODEHAMMER_BUILD_SHARED)
1045
1060
  COMPONENT Development
1046
1061
  )
1047
1062
 
1048
- install(EXPORT nodehammer-targets
1049
- FILE nodehammer-targets.cmake
1063
+ install(EXPORT nodehammer-shared-targets
1064
+ FILE nodehammer-shared-targets.cmake
1050
1065
  NAMESPACE nodehammer::
1051
1066
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1052
1067
  COMPONENT Development
1053
1068
  )
1054
-
1055
- # Baked into the package config so a consumer's mismatched C runtime fails at
1056
- # configure time rather than as a segmentation fault on the first call that
1057
- # returns a container (see cmake/nodehammer-config.cmake.in).
1058
- #
1059
- # Evaluated by CMake rather than parsed by us. `CMAKE_MSVC_RUNTIME_LIBRARY`
1060
- # is normally a generator expression, and its shape varies by who set it —
1061
- # CMake's own default is "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" while
1062
- # Conan writes "$<$<CONFIG:Release>:MultiThreadedDLL>". A hand-rolled
1063
- # substitution for one of those spellings reported the other as a mismatch
1064
- # and blocked a legitimate build, which is worse than the failure it exists
1065
- # to catch. `file(GENERATE)` resolves whatever is there, exactly.
1066
- #
1067
- # The full runtime name, not a debug flag: /MT and /MD are different heaps
1068
- # even when neither is a debug runtime, so a static-CRT library and a
1069
- # dynamic-CRT consumer must not pass.
1070
- if(MSVC)
1071
- set(_nh_runtime_stamp "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-msvc-runtime.txt")
1072
- file(GENERATE OUTPUT "${_nh_runtime_stamp}"
1073
- CONTENT "$<TARGET_PROPERTY:nodehammer_shared,MSVC_RUNTIME_LIBRARY>")
1074
- install(FILES "${_nh_runtime_stamp}"
1075
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1076
- COMPONENT Development
1077
- )
1078
- endif()
1079
-
1080
- include(CMakePackageConfigHelpers)
1081
- configure_package_config_file(
1082
- "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nodehammer-config.cmake.in"
1083
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config.cmake"
1084
- INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1085
- )
1086
- # SameMinorVersion, not the usual SameMajorVersion: pre-1.0, the major
1087
- # version conveys nothing, and treating every 0.x as interchangeable would
1088
- # promise compatibility across exactly the releases where the API is
1089
- # expected to move. Revisit at 1.0.
1090
- write_basic_package_version_file(
1091
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config-version.cmake"
1092
- VERSION ${PROJECT_VERSION}
1093
- COMPATIBILITY SameMinorVersion
1094
- )
1095
- install(FILES
1096
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config.cmake"
1097
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config-version.cmake"
1098
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1099
- COMPONENT Development
1100
- )
1101
1069
  endif()
1102
1070
 
1103
1071
  # Reads the manifest produced by conanfile.py's generate(), assembles