nodehammer 0.2.0rc5__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 (504) hide show
  1. nodehammer-0.2.0rc6/.agents/skills/nodehammer/SKILL.md +249 -0
  2. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/CMakeLists.txt +80 -113
  3. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/PKG-INFO +45 -6
  4. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/README.md +44 -5
  5. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/check_shared_exports.py +3 -3
  6. nodehammer-0.2.0rc6/ci/ingest_consumer/CMakeLists.txt +54 -0
  7. nodehammer-0.2.0rc6/ci/ingest_consumer/main.cpp +40 -0
  8. nodehammer-0.2.0rc6/ci/package_components/CMakeLists.txt +48 -0
  9. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/shared_consumer/CMakeLists.txt +2 -2
  10. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/shared_consumer/main.cpp +37 -35
  11. nodehammer-0.2.0rc6/ci/verify-ingest.sh +40 -0
  12. nodehammer-0.2.0rc6/ci/verify-package-components.cmake +32 -0
  13. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/verify-shared-install.sh +10 -0
  14. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/Dependencies.cmake +1 -88
  15. nodehammer-0.2.0rc6/cmake/GenerateSkillsData.cmake +165 -0
  16. nodehammer-0.2.0rc6/cmake/Ingestion.cmake +146 -0
  17. nodehammer-0.2.0rc6/cmake/IngestionDependencies.cmake +127 -0
  18. nodehammer-0.2.0rc6/cmake/IngestionOnly.cmake +31 -0
  19. nodehammer-0.2.0rc6/cmake/InstallPackage.cmake +24 -0
  20. nodehammer-0.2.0rc6/cmake/PublicBackendHeaders.cmake +16 -0
  21. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/nodehammer-config.cmake.in +47 -25
  22. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/include/nodehammer/build.hpp +1 -1
  23. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/include/nodehammer/cli.hpp +6 -6
  24. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/include/nodehammer/config.hpp +13 -60
  25. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/include/nodehammer/diagnostics.hpp +2 -6
  26. nodehammer-0.2.0rc6/include/nodehammer/io.hpp +41 -0
  27. nodehammer-0.2.0rc6/include/nodehammer/nhb.hpp +14 -0
  28. nodehammer-0.2.0rc6/include/nodehammer/nhr.hpp +10 -0
  29. nodehammer-0.2.0rc6/include/nodehammer/render_scene.hpp +40 -0
  30. nodehammer-0.2.0rc6/include/nodehammer/semantic_scene.hpp +43 -0
  31. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/python/nodehammer/__init__.py +43 -6
  32. nodehammer-0.2.0rc6/skills/nodehammer/SKILL.md +249 -0
  33. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/api/build.cpp +4 -1
  34. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/api/config.cpp +7 -7
  35. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/api/diagnostics.cpp +1 -1
  36. nodehammer-0.2.0rc6/src/api/handles_config.hpp +92 -0
  37. nodehammer-0.2.0rc6/src/api/handles_render.hpp +50 -0
  38. nodehammer-0.2.0rc6/src/api/handles_semantic.hpp +79 -0
  39. nodehammer-0.2.0rc6/src/api/public/dd4hep.hpp +11 -0
  40. nodehammer-0.2.0rc6/src/api/public/dd4hep_disabled.hpp +4 -0
  41. nodehammer-0.2.0rc6/src/api/public/tgeo.hpp +9 -0
  42. nodehammer-0.2.0rc6/src/api/public/tgeo_disabled.hpp +4 -0
  43. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/api/render_scene.cpp +36 -17
  44. nodehammer-0.2.0rc6/src/api/semantic_scene.cpp +104 -0
  45. nodehammer-0.2.0rc6/src/api/semantic_scene_formats.cpp +99 -0
  46. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/cli_common.hpp +4 -4
  47. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/cmd_config.cpp +4 -48
  48. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/cmd_convert.cpp +4 -4
  49. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/cmd_inspect.cpp +1 -1
  50. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/cmd_project.cpp +1 -1
  51. nodehammer-0.2.0rc6/src/cli/cmd_skills.cpp +510 -0
  52. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/cmd_viewer_native.cpp +1 -1
  53. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/cmd_viewer_web.cpp +2 -2
  54. nodehammer-0.2.0rc6/src/cli/config_input.hpp +53 -0
  55. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/main.cpp +2 -2
  56. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/pager.cpp +3 -27
  57. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/pager.hpp +1 -1
  58. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/run.cpp +10 -6
  59. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/cli/run_internal.hpp +16 -10
  60. nodehammer-0.2.0rc6/src/cli/skills_data.hpp +48 -0
  61. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_ast.hpp +3 -3
  62. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_loader.cpp +18 -15
  63. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_loader.hpp +1 -1
  64. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_writer.cpp +30 -33
  65. nodehammer-0.2.0rc6/src/detail/env.cpp +39 -0
  66. nodehammer-0.2.0rc6/src/detail/env.hpp +29 -0
  67. nodehammer-0.2.0rc6/src/detail/json_value.hpp +231 -0
  68. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/detail/zstd_io.hpp +9 -2
  69. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/diagnostic_codes.hpp +16 -5
  70. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/dd4hep/semantic/importer.cpp +48 -25
  71. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/dd4hep/semantic/importer.hpp +7 -0
  72. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/render/exporter.cpp +1 -1
  73. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/render/exporter.hpp +2 -2
  74. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/exporter.cpp +2 -1
  75. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/importer.cpp +4 -4
  76. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/importer.hpp +2 -2
  77. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/gltf/render/exporter.cpp +40 -38
  78. nodehammer-0.2.0rc6/src/ir/id_order.hpp +48 -0
  79. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/json/semantic/exporter.cpp +1 -1
  80. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/render/exporter.hpp +2 -1
  81. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/render/json_exporter.cpp +1 -1
  82. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/render.hpp +3 -3
  83. nodehammer-0.2.0rc6/src/ir/render_json.cpp +119 -0
  84. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/render_json.hpp +3 -2
  85. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic/exporter.hpp +3 -1
  86. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic_json.cpp +15 -8
  87. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/lua/lua_config.cpp +16 -15
  88. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/lua/lua_config.hpp +1 -1
  89. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/project/pack.cpp +4 -3
  90. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/python/bindings.cpp +129 -230
  91. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/runtime_locator.cpp +3 -30
  92. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/runtime_locator.hpp +1 -1
  93. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/CMakeLists.txt +24 -7
  94. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/api/test_api_equivalence.cpp +18 -15
  95. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/api/test_api_surface.cpp +35 -32
  96. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/api/test_config_wrapper.cpp +25 -25
  97. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/cli/cli_test_support.hpp +2 -2
  98. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/cli/test_cli_config.cpp +13 -3
  99. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/cli/test_cli_convert_stages.cpp +50 -0
  100. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/cli/test_cli_run.cpp +5 -5
  101. nodehammer-0.2.0rc6/tests/cli/test_cli_skills.cpp +347 -0
  102. nodehammer-0.2.0rc6/tests/cmake/generate_skills_data_test.cmake +106 -0
  103. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/config/test_config_loader.cpp +1 -1
  104. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/config/test_config_writer.cpp +6 -6
  105. nodehammer-0.2.0rc6/tests/fixtures/skills/plain/SKILL.md +4 -0
  106. nodehammer-0.2.0rc6/tests/fixtures/skills/with-dash/SKILL.md +4 -0
  107. nodehammer-0.2.0rc6/tests/fixtures/skills/with-dash/references/nested.md +1 -0
  108. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/import/test_dd4hep_importer.cpp +25 -0
  109. nodehammer-0.2.0rc6/tests/ingest/CMakeLists.txt +69 -0
  110. nodehammer-0.2.0rc6/tests/ingest/compare.cmake +43 -0
  111. nodehammer-0.2.0rc6/tests/ingest/core.cpp +84 -0
  112. nodehammer-0.2.0rc6/tests/ingest/dd4hep.cpp +24 -0
  113. nodehammer-0.2.0rc6/tests/ingest/geometry.hpp +53 -0
  114. nodehammer-0.2.0rc6/tests/ingest/golden.cpp +5 -0
  115. nodehammer-0.2.0rc6/tests/ingest/golden_body.hpp +54 -0
  116. nodehammer-0.2.0rc6/tests/ingest/transport.cpp +60 -0
  117. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/ir/test_json_roundtrip.cpp +1 -1
  118. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/ir/test_render_nhr_exporter.cpp +4 -3
  119. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/public_fixture.hpp +2 -2
  120. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/test_public_build.cpp +2 -2
  121. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/test_public_cli.cpp +6 -6
  122. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/test_public_config.cpp +22 -22
  123. nodehammer-0.2.0rc6/tests/public/test_public_dd4hep.cpp +148 -0
  124. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/test_public_diagnostics.cpp +5 -4
  125. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/test_public_render_scene.cpp +48 -25
  126. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/test_public_semantic_scene.cpp +63 -32
  127. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/public/test_public_tgeo.cpp +14 -24
  128. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/python/test_build.py +6 -6
  129. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/python/test_cli.py +35 -0
  130. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/python/test_config_and_diagnostics.py +34 -38
  131. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/python/test_semantic_scene.py +36 -20
  132. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/wasm_lua_smoke.cpp +8 -7
  133. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/web/test_runtime_locator.cpp +1 -1
  134. nodehammer-0.2.0rc5/include/nodehammer/render_scene.hpp +0 -104
  135. nodehammer-0.2.0rc5/include/nodehammer/semantic_scene.hpp +0 -145
  136. nodehammer-0.2.0rc5/src/api/handles.hpp +0 -214
  137. nodehammer-0.2.0rc5/src/api/semantic_scene.cpp +0 -155
  138. nodehammer-0.2.0rc5/src/ir/render_json.cpp +0 -81
  139. nodehammer-0.2.0rc5/tests/public/test_public_dd4hep.cpp +0 -99
  140. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.clang-format +0 -0
  141. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.clang-tidy +0 -0
  142. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.gitattributes +0 -0
  143. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.gitignore +0 -0
  144. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.pre-commit-config.yaml +0 -0
  145. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.vscode/launch.json +0 -0
  146. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.vscode/settings.json +0 -0
  147. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/.vscode/tasks.json +0 -0
  148. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/Justfile +0 -0
  149. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/LICENSE +0 -0
  150. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/LICENSES/MIT.txt +0 -0
  151. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/LICENSES/OFL-1.1.txt +0 -0
  152. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/LICENSES/Zlib.txt +0 -0
  153. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/REUSE.toml +0 -0
  154. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/STYLE.md +0 -0
  155. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/bench-summary.py +0 -0
  156. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/bench.sh +0 -0
  157. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/build.sh +0 -0
  158. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/ci/shared-build.sh +0 -0
  159. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/CompilerOptions.cmake +0 -0
  160. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/PicProbe.cmake +0 -0
  161. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/Sokol.cmake +0 -0
  162. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/ThirdPartyLicenses.cmake +0 -0
  163. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/Version.cmake +0 -0
  164. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/patch_sokol_wgpu.cmake +0 -0
  165. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/pic_probe.cpp +0 -0
  166. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/validate_shader_hlsl.cmake +0 -0
  167. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/cmake/validate_shader_wgsl.cmake +0 -0
  168. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/conanfile.py +0 -0
  169. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/full_example.toml +0 -0
  170. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/include_bad_path.toml +0 -0
  171. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/include_basic.toml +0 -0
  172. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/include_cycle.toml +0 -0
  173. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/include_diamond.toml +0 -0
  174. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/include_nested.toml +0 -0
  175. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/cycle_a.toml +0 -0
  176. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/cycle_b.toml +0 -0
  177. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/diamond_base.toml +0 -0
  178. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/diamond_left.toml +0 -0
  179. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/diamond_right.toml +0 -0
  180. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/materials.toml +0 -0
  181. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/nested_inner.toml +0 -0
  182. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/nested_outer.toml +0 -0
  183. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/includes/rules.toml +0 -0
  184. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/invalid_bad_tolerance.toml +0 -0
  185. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/invalid_missing_material_ref.toml +0 -0
  186. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/calorimeters.lua +0 -0
  187. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/kitchen_sink.lua +0 -0
  188. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/lib/constants.lua +0 -0
  189. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/materials.lua +0 -0
  190. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/muon.lua +0 -0
  191. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/base.lua +0 -0
  192. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/calorimeters.lua +0 -0
  193. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/materials.lua +0 -0
  194. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/muon.lua +0 -0
  195. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd/tracker.lua +0 -0
  196. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/odd.lua +0 -0
  197. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/parity.lua +0 -0
  198. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/parity.toml +0 -0
  199. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/lua/tracker.lua +0 -0
  200. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/minimal.toml +0 -0
  201. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/base.toml +0 -0
  202. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/calorimeters.toml +0 -0
  203. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/calorimeters_simple.toml +0 -0
  204. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/materials.toml +0 -0
  205. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/muon.toml +0 -0
  206. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/muon_simple.toml +0 -0
  207. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/simple_materials.toml +0 -0
  208. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd/tracker.toml +0 -0
  209. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd.toml +0 -0
  210. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_drop_coincident_faces.toml +0 -0
  211. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_merged.toml +0 -0
  212. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_simple.toml +0 -0
  213. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_ecal_barrel_stave.toml +0 -0
  214. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_hcal_barrel_stave.toml +0 -0
  215. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_long_strip_barrel_module.toml +0 -0
  216. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_long_strip_barrel_stave.toml +0 -0
  217. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_muon_barrel_chamber.toml +0 -0
  218. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_pixel_barrel_module.toml +0 -0
  219. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_pixel_barrel_stave.toml +0 -0
  220. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_short_strip_barrel_module.toml +0 -0
  221. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_single_short_strip_barrel_stave.toml +0 -0
  222. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/configs/odd_tracker.toml +0 -0
  223. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/dd4hep/sensitive_detector.xml +0 -0
  224. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/fixtures/dd4hep/simple_box.xml +0 -0
  225. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/include/nodehammer/version.hpp.in +0 -0
  226. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/include/nodehammer/visibility.hpp +0 -0
  227. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/packaging/plugins/nh_web_pin.py +0 -0
  228. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/packaging/web/.gitignore +0 -0
  229. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/packaging/web/LICENSE +0 -0
  230. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/packaging/web/README.md +0 -0
  231. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/packaging/web/pyproject.toml +0 -0
  232. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/packaging/web/src/nodehammer_web/__init__.py +0 -0
  233. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/profiles/emscripten +0 -0
  234. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/pyproject.toml +0 -0
  235. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/python/nodehammer/__main__.py +0 -0
  236. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/python/nodehammer/cli.py +0 -0
  237. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/python/nodehammer/py.typed +0 -0
  238. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/cli11/conandata.yml +0 -0
  239. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/cli11/conanfile.py +0 -0
  240. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/imgui/CMakeLists.txt +0 -0
  241. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/imgui/conandata.yml +0 -0
  242. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/imgui/conanfile.py +0 -0
  243. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/implot/CMakeLists.txt +0 -0
  244. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/implot/conandata.yml +0 -0
  245. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/implot/conanfile.py +0 -0
  246. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/nfd/conandata.yml +0 -0
  247. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/nfd/conanfile.py +0 -0
  248. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/sokol/conandata.yml +0 -0
  249. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/sokol/conanfile.py +0 -0
  250. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/sokol-shdc/conandata.yml +0 -0
  251. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/recipes/sokol-shdc/conanfile.py +0 -0
  252. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/schemas/render.fbs +0 -0
  253. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/schemas/semantic.fbs +0 -0
  254. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/build_pages_site.sh +0 -0
  255. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/check_cli_no_exit.py +0 -0
  256. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/check_em_js_closure.py +0 -0
  257. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/check_pages_site.py +0 -0
  258. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/check_wasm_module_linkage.py +0 -0
  259. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/check_web_serve.py +0 -0
  260. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/check_wheel_pair.py +0 -0
  261. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/make_nhproj.py +0 -0
  262. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/serve_nocache.py +0 -0
  263. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/stage_wasm_viewer.sh +0 -0
  264. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/wasm_compute_smoke.js +0 -0
  265. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/scripts/windows-msvc-cmake.ps1 +0 -0
  266. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/CMakeLists.txt +0 -0
  267. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/ao.glsl +0 -0
  268. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/ao_denoise.glsl +0 -0
  269. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/blit.glsl +0 -0
  270. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/composite.glsl +0 -0
  271. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/depth_helpers.glsl.h +0 -0
  272. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/ibl_bake.glsl +0 -0
  273. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/shaders/scene.glsl +0 -0
  274. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/color_parse.cpp +0 -0
  275. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/color_parse.hpp +0 -0
  276. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_enums.hpp +0 -0
  277. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_keys.hpp +0 -0
  278. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_validator.cpp +0 -0
  279. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_validator.hpp +0 -0
  280. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/config_writer.hpp +0 -0
  281. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/predicate_parser.cpp +0 -0
  282. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/config/predicate_parser.hpp +0 -0
  283. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/detail/file_io.hpp +0 -0
  284. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/detail/glm_json.hpp +0 -0
  285. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/detail/markup.cpp +0 -0
  286. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/detail/markup.hpp +0 -0
  287. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/detail/overloaded.hpp +0 -0
  288. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/detail/timing.hpp +0 -0
  289. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/diagnostics.hpp +0 -0
  290. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/export_resolve.cpp +0 -0
  291. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/export_resolve.hpp +0 -0
  292. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/render/flatbuffer.cpp +0 -0
  293. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/render/flatbuffer.hpp +0 -0
  294. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/exporter.hpp +0 -0
  295. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/flatbuffer.cpp +0 -0
  296. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/fb/semantic/flatbuffer.hpp +0 -0
  297. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/gltf/render/exporter.hpp +0 -0
  298. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/json/semantic/exporter.hpp +0 -0
  299. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/json/semantic/importer.cpp +0 -0
  300. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/json/semantic/importer.hpp +0 -0
  301. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/obj/render/exporter.cpp +0 -0
  302. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/obj/render/exporter.hpp +0 -0
  303. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/provenance.hpp +0 -0
  304. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/render/exporter_registry.cpp +0 -0
  305. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/render/json_exporter.hpp +0 -0
  306. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic/exporter_registry.cpp +0 -0
  307. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic/importer.hpp +0 -0
  308. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic/importer_registry.cpp +0 -0
  309. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic.cpp +0 -0
  310. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic.hpp +0 -0
  311. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/semantic_json.hpp +0 -0
  312. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/synthetic/semantic/importer.cpp +0 -0
  313. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/synthetic/semantic/importer.hpp +0 -0
  314. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/importer.cpp +0 -0
  315. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/importer.hpp +0 -0
  316. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/shape_dispatch.cpp +0 -0
  317. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/ir/tgeo/semantic/shape_dispatch.hpp +0 -0
  318. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/project/pack.hpp +0 -0
  319. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/python/CMakeLists.txt +0 -0
  320. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/scene_build.cpp +0 -0
  321. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/scene_build.hpp +0 -0
  322. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/selection/predicate.cpp +0 -0
  323. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/selection/predicate.hpp +0 -0
  324. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/selection/selector.cpp +0 -0
  325. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/selection/selector.hpp +0 -0
  326. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/sokol/sokol_imgui_impl.cc +0 -0
  327. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/sokol/sokol_imgui_impl.mm +0 -0
  328. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/sokol/sokol_impl.c +0 -0
  329. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/sokol/sokol_impl.mm +0 -0
  330. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/boolean_tessellator.cpp +0 -0
  331. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/boolean_tessellator.hpp +0 -0
  332. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/build_pipeline.cpp +0 -0
  333. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/build_pipeline.hpp +0 -0
  334. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/primitive_tessellator.cpp +0 -0
  335. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/primitive_tessellator.hpp +0 -0
  336. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/tessellation_job.hpp +0 -0
  337. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/tessellation_pass.cpp +0 -0
  338. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/tessellation_pass.hpp +0 -0
  339. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/tessellator.hpp +0 -0
  340. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/wedge_cut.cpp +0 -0
  341. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tessellation/wedge_cut.hpp +0 -0
  342. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/tools/imgui_kitchen_sink_main.cpp +0 -0
  343. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/version.cpp +0 -0
  344. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/CMakeLists.txt +0 -0
  345. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ao_denoise_pass.cpp +0 -0
  346. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ao_denoise_pass.hpp +0 -0
  347. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ao_pass.cpp +0 -0
  348. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ao_pass.hpp +0 -0
  349. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ao_render_target.cpp +0 -0
  350. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ao_render_target.hpp +0 -0
  351. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/app.cpp +0 -0
  352. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/app.hpp +0 -0
  353. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/app_state.cpp +0 -0
  354. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/app_state.hpp +0 -0
  355. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/archive_export.cpp +0 -0
  356. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/archive_export.hpp +0 -0
  357. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/archive_project_fs.cpp +0 -0
  358. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/archive_project_fs.hpp +0 -0
  359. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/backend_caps.hpp +0 -0
  360. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/bag_project_fs.cpp +0 -0
  361. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/bag_project_fs.hpp +0 -0
  362. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/bench_runner.cpp +0 -0
  363. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/bench_runner.hpp +0 -0
  364. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/blit_pass.cpp +0 -0
  365. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/blit_pass.hpp +0 -0
  366. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/build_controller.cpp +0 -0
  367. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/build_controller.hpp +0 -0
  368. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/build_session.cpp +0 -0
  369. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/build_session.hpp +0 -0
  370. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/byte_buffer.hpp +0 -0
  371. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/camera.cpp +0 -0
  372. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/camera.hpp +0 -0
  373. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/composite_pass.cpp +0 -0
  374. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/composite_pass.hpp +0 -0
  375. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/config.hpp +0 -0
  376. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/dynamic_render_scale.cpp +0 -0
  377. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/dynamic_render_scale.hpp +0 -0
  378. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/filesystem_project_fs.cpp +0 -0
  379. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/filesystem_project_fs.hpp +0 -0
  380. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/gpu_pass_timer.hpp +0 -0
  381. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/gpu_pass_timer_d3d11.cpp +0 -0
  382. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/gpu_pass_timer_noop.cpp +0 -0
  383. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ibl.cpp +0 -0
  384. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ibl.hpp +0 -0
  385. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ibl_baker.cpp +0 -0
  386. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ibl_baker.hpp +0 -0
  387. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/imgui_backend.cpp +0 -0
  388. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/imgui_backend.hpp +0 -0
  389. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/log_sink.hpp +0 -0
  390. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/native_bag_project_fs.cpp +0 -0
  391. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/native_bag_project_fs.hpp +0 -0
  392. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/platform.hpp +0 -0
  393. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/platform_macos.mm +0 -0
  394. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/platform_native_common.cpp +0 -0
  395. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/platform_native_common.hpp +0 -0
  396. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/platform_native_default.cpp +0 -0
  397. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/platform_web.cpp +0 -0
  398. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_export.cpp +0 -0
  399. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_export.hpp +0 -0
  400. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback.hpp +0 -0
  401. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_d3d11.cpp +0 -0
  402. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_gl.cpp +0 -0
  403. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_metal.mm +0 -0
  404. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_export_readback_wgpu.cpp +0 -0
  405. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_exporter.cpp +0 -0
  406. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/png_exporter.hpp +0 -0
  407. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/project_fs.hpp +0 -0
  408. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/project_manifest.cpp +0 -0
  409. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/project_manifest.hpp +0 -0
  410. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/render_quality.hpp +0 -0
  411. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job.hpp +0 -0
  412. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_common.cpp +0 -0
  413. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_internal.hpp +0 -0
  414. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_native.cpp +0 -0
  415. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_web.cpp +0 -0
  416. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_web_backend.hpp +0 -0
  417. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_build_job_web_worker.cpp +0 -0
  418. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_render_target.cpp +0 -0
  419. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_render_target.hpp +0 -0
  420. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_renderer.cpp +0 -0
  421. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/scene_renderer.hpp +0 -0
  422. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/shared_image.hpp +0 -0
  423. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/stb_image_write_impl.cpp +0 -0
  424. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/debug_panel.cpp +0 -0
  425. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/debug_panel.hpp +0 -0
  426. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/icon_font.cpp +0 -0
  427. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/icon_font.hpp +0 -0
  428. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/menu_bar.cpp +0 -0
  429. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/menu_bar.hpp +0 -0
  430. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/notifications.cpp +0 -0
  431. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/notifications.hpp +0 -0
  432. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/perf_history.hpp +0 -0
  433. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/project_panel.cpp +0 -0
  434. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/project_panel.hpp +0 -0
  435. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/status_ui.cpp +0 -0
  436. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/status_ui.hpp +0 -0
  437. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/ui_context.hpp +0 -0
  438. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/view_panel.cpp +0 -0
  439. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/view_panel.hpp +0 -0
  440. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/viewer_ui.cpp +0 -0
  441. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/ui/viewer_ui.hpp +0 -0
  442. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/watched_filesystem_project_fs.cpp +0 -0
  443. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/watched_filesystem_project_fs.hpp +0 -0
  444. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/zip_working_set.cpp +0 -0
  445. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/viewer/zip_working_set.hpp +0 -0
  446. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/compute_worker.js +0 -0
  447. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/compute_worker_main.cpp +0 -0
  448. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/executable_path.cpp +0 -0
  449. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/open_browser.cpp +0 -0
  450. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/open_browser.hpp +0 -0
  451. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/stage.cpp +0 -0
  452. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/stage.hpp +0 -0
  453. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/static_server.cpp +0 -0
  454. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/static_server.hpp +0 -0
  455. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/src/web/viewer_main.cpp +0 -0
  456. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/bench_main.cpp +0 -0
  457. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/cli/test_cli_inspect_json.cpp +0 -0
  458. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/config/test_config_fixtures.cpp +0 -0
  459. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/config/test_config_validator.cpp +0 -0
  460. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/config/test_lua_config.cpp +0 -0
  461. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/config/test_predicate_parser.cpp +0 -0
  462. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/export/test_export_resolve.cpp +0 -0
  463. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/export/test_gltf_exporter.cpp +0 -0
  464. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/export/test_render_exporter_registry.cpp +0 -0
  465. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/export/test_semantic_exporter_registry.cpp +0 -0
  466. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/import/test_synthetic_importer.cpp +0 -0
  467. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/import/test_tgeo_importer.cpp +0 -0
  468. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/ir/test_flatbuffer_roundtrip.cpp +0 -0
  469. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/ir/test_render_flatbuffer_roundtrip.cpp +0 -0
  470. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/ir/test_semantic_ir.cpp +0 -0
  471. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/ir/test_shape_variant.cpp +0 -0
  472. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/project/test_pack.cpp +0 -0
  473. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/selection/test_predicate.cpp +0 -0
  474. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/selection/test_selector.cpp +0 -0
  475. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/tessellation/test_boolean_tessellator.cpp +0 -0
  476. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/tessellation/test_build_pipeline.cpp +0 -0
  477. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/tessellation/test_obj_writer.hpp +0 -0
  478. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/tessellation/test_primitive_tessellator.cpp +0 -0
  479. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/tessellation/test_tessellation_pass.cpp +0 -0
  480. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/tessellation/test_tgeo_tessellation.cpp +0 -0
  481. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/tessellation/test_wedge_cut.cpp +0 -0
  482. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/test_compute_pipeline.cpp +0 -0
  483. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/test_main.cpp +0 -0
  484. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/test_markup.cpp +0 -0
  485. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/test_scene_build.cpp +0 -0
  486. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/test_timing.cpp +0 -0
  487. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_app_state.cpp +0 -0
  488. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_archive_export.cpp +0 -0
  489. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_archive_project_fs.cpp +0 -0
  490. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_bag_project_fs.cpp +0 -0
  491. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_build_session.cpp +0 -0
  492. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_byte_buffer.cpp +0 -0
  493. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_dynamic_render_scale.cpp +0 -0
  494. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_filesystem_project_fs.cpp +0 -0
  495. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_native_bag_project_fs.cpp +0 -0
  496. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_project_manifest.cpp +0 -0
  497. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_watched_filesystem_project_fs.cpp +0 -0
  498. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/viewer/test_zip_working_set.cpp +0 -0
  499. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/web/test_stage.cpp +0 -0
  500. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/tests/web/test_static_server.cpp +0 -0
  501. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/third_party/fontawesome7/IconsFontAwesome7.h +0 -0
  502. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/third_party/fontawesome7/README.md +0 -0
  503. {nodehammer-0.2.0rc5 → nodehammer-0.2.0rc6}/third_party/fontawesome7/fa-solid-900.h +0 -0
  504. {nodehammer-0.2.0rc5 → 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
+ ```
@@ -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,6 +141,24 @@ 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
@@ -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
@@ -258,6 +258,7 @@ set(NH_CORE_SOURCES
258
258
  src/ir/json/semantic/exporter.cpp
259
259
  src/ir/fb/semantic/exporter.cpp
260
260
  src/ir/semantic/exporter_registry.cpp
261
+ src/detail/env.cpp
261
262
  src/detail/markup.cpp
262
263
  # Host-side, despite the directory: locating and vetting the wasm runtime is
263
264
  # something the *serving* process does. src/web/'s other two TUs are the
@@ -266,12 +267,10 @@ set(NH_CORE_SOURCES
266
267
  src/web/executable_path.cpp
267
268
  src/scene_build.cpp
268
269
  src/export_resolve.cpp
269
- src/version.cpp
270
270
  # The public API bridge: the only translation units that see both a public
271
- # 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).
272
272
  # Core, not app — these *are* what the installed library publishes.
273
- src/api/diagnostics.cpp
274
- src/api/semantic_scene.cpp
273
+ src/api/semantic_scene_formats.cpp
275
274
  src/api/config.cpp
276
275
  src/api/render_scene.cpp
277
276
  src/api/build.cpp
@@ -330,12 +329,6 @@ set(NH_APP_SOURCES
330
329
  set(NH_APP_DEPS "")
331
330
  set(NH_APP_DEFINES "")
332
331
 
333
- configure_file(
334
- ${CMAKE_CURRENT_SOURCE_DIR}/include/nodehammer/version.hpp.in
335
- ${CMAKE_CURRENT_BINARY_DIR}/include/nodehammer/version.hpp
336
- @ONLY
337
- )
338
-
339
332
  # PUBLIC on the archive, because an internal header names the dependency where an
340
333
  # out-of-core target sees it. Each entry cites the header that justifies it;
341
334
  # remove one and the build fails. (Scope on the shared library is a different
@@ -417,23 +410,9 @@ list(APPEND NH_CORE_SOURCES src/lua/lua_config.cpp)
417
410
  # binding stay inside the core's implementation.
418
411
  list(APPEND NH_CORE_PRIVATE_DEPS lua::lua sol2::sol2)
419
412
 
420
- if(NODEHAMMER_WITH_TGEO OR NODEHAMMER_WITH_DD4HEP)
421
- find_package(ROOT REQUIRED COMPONENTS Geom)
422
- list(APPEND NH_CORE_SOURCES src/ir/tgeo/semantic/shape_dispatch.cpp)
423
- list(APPEND NH_CORE_DEPS ROOT::Geom)
424
- list(APPEND NH_CORE_DEFINES NH_WITH_TGEO=1)
425
- endif()
426
-
427
- if(NODEHAMMER_WITH_TGEO)
428
- list(APPEND NH_CORE_SOURCES src/ir/tgeo/semantic/importer.cpp)
429
- endif()
430
-
431
- if(NODEHAMMER_WITH_DD4HEP)
432
- find_package(DD4hep REQUIRED)
433
- list(APPEND NH_CORE_SOURCES src/ir/dd4hep/semantic/importer.cpp)
434
- list(APPEND NH_CORE_DEPS DD4hep::DDCore)
435
- list(APPEND NH_CORE_DEFINES NH_WITH_DD4HEP=1)
436
- 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})
437
416
 
438
417
  if(NODEHAMMER_WITH_GEANT4)
439
418
  find_package(Geant4 REQUIRED)
@@ -491,6 +470,37 @@ if(NOT EMSCRIPTEN)
491
470
  # least of all a header. Header-only, so the shared library gains no link
492
471
  # dependency and its package config gains no requirement.
493
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
+ )
494
504
  endif()
495
505
 
496
506
  # WatchedFilesystemProjectFs (strategy doc step 4) decorates FilesystemProjectFs
@@ -603,7 +613,8 @@ endif()
603
613
  # What every in-tree target links — CLI, viewer, tests, benchmarks. Core + app
604
614
  # sources. Never installed, so its dependencies are PUBLIC: in-tree targets reach
605
615
  # toml++, glm and nlohmann through this link.
606
- 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>)
607
618
  nh_core_common(nodehammer_lib)
608
619
 
609
620
  target_link_libraries(nodehammer_lib PUBLIC ${NH_CORE_DEPS} ${NH_APP_DEPS})
@@ -643,7 +654,10 @@ if(NODEHAMMER_BUILD_SHARED)
643
654
 
644
655
  # Core only — no NH_APP_SOURCES. NH_CORE_INPUT is either the sources or the
645
656
  # shared objects, per the OBJECT block above.
646
- 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)
647
661
  nh_core_common(nodehammer_shared)
648
662
 
649
663
  # Plain PRIVATE is enough to keep the generated export empty, so a consumer
@@ -697,11 +711,10 @@ if(NODEHAMMER_BUILD_SHARED)
697
711
  # library itself; PRIVATE, since a consumer must see dllimport instead.
698
712
  target_compile_definitions(nodehammer_shared PRIVATE NH_EXPORTS)
699
713
 
700
- # The exported name is `nodehammer`; the target cannot be, because the CLI
701
- # executable already owns that target name.
714
+ # A consistent component target name in source and installed consumers.
702
715
  set_target_properties(nodehammer_shared PROPERTIES
703
716
  OUTPUT_NAME nodehammer
704
- EXPORT_NAME nodehammer
717
+ EXPORT_NAME shared
705
718
  )
706
719
 
707
720
  # Version the library only when it is going to be installed as a system
@@ -878,6 +891,7 @@ endif()
878
891
  if(NODEHAMMER_BUILD_TESTS)
879
892
  enable_testing()
880
893
  add_subdirectory(tests)
894
+ add_subdirectory(tests/ingest)
881
895
  endif()
882
896
 
883
897
  # ── Python extension ───────────────────────────────────────────────────────────
@@ -1008,7 +1022,7 @@ if(NODEHAMMER_BUILD_SHARED)
1008
1022
  # linker resolving -lnodehammer reads it). Windows has no namelink; its
1009
1023
  # equivalent is .dll against .lib, stated by RUNTIME and ARCHIVE below.
1010
1024
  install(TARGETS nodehammer_shared
1011
- EXPORT nodehammer-targets
1025
+ EXPORT nodehammer-shared-targets
1012
1026
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
1013
1027
  COMPONENT Runtime
1014
1028
  NAMELINK_COMPONENT Development
@@ -1046,59 +1060,12 @@ if(NODEHAMMER_BUILD_SHARED)
1046
1060
  COMPONENT Development
1047
1061
  )
1048
1062
 
1049
- install(EXPORT nodehammer-targets
1050
- FILE nodehammer-targets.cmake
1063
+ install(EXPORT nodehammer-shared-targets
1064
+ FILE nodehammer-shared-targets.cmake
1051
1065
  NAMESPACE nodehammer::
1052
1066
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1053
1067
  COMPONENT Development
1054
1068
  )
1055
-
1056
- # Baked into the package config so a consumer's mismatched C runtime fails at
1057
- # configure time rather than as a segmentation fault on the first call that
1058
- # returns a container (see cmake/nodehammer-config.cmake.in).
1059
- #
1060
- # Evaluated by CMake rather than parsed by us. `CMAKE_MSVC_RUNTIME_LIBRARY`
1061
- # is normally a generator expression, and its shape varies by who set it —
1062
- # CMake's own default is "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL" while
1063
- # Conan writes "$<$<CONFIG:Release>:MultiThreadedDLL>". A hand-rolled
1064
- # substitution for one of those spellings reported the other as a mismatch
1065
- # and blocked a legitimate build, which is worse than the failure it exists
1066
- # to catch. `file(GENERATE)` resolves whatever is there, exactly.
1067
- #
1068
- # The full runtime name, not a debug flag: /MT and /MD are different heaps
1069
- # even when neither is a debug runtime, so a static-CRT library and a
1070
- # dynamic-CRT consumer must not pass.
1071
- if(MSVC)
1072
- set(_nh_runtime_stamp "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-msvc-runtime.txt")
1073
- file(GENERATE OUTPUT "${_nh_runtime_stamp}"
1074
- CONTENT "$<TARGET_PROPERTY:nodehammer_shared,MSVC_RUNTIME_LIBRARY>")
1075
- install(FILES "${_nh_runtime_stamp}"
1076
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1077
- COMPONENT Development
1078
- )
1079
- endif()
1080
-
1081
- include(CMakePackageConfigHelpers)
1082
- configure_package_config_file(
1083
- "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nodehammer-config.cmake.in"
1084
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config.cmake"
1085
- INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1086
- )
1087
- # SameMinorVersion, not the usual SameMajorVersion: pre-1.0, the major
1088
- # version conveys nothing, and treating every 0.x as interchangeable would
1089
- # promise compatibility across exactly the releases where the API is
1090
- # expected to move. Revisit at 1.0.
1091
- write_basic_package_version_file(
1092
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config-version.cmake"
1093
- VERSION ${PROJECT_VERSION}
1094
- COMPATIBILITY SameMinorVersion
1095
- )
1096
- install(FILES
1097
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config.cmake"
1098
- "${CMAKE_CURRENT_BINARY_DIR}/nodehammer-config-version.cmake"
1099
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/nodehammer"
1100
- COMPONENT Development
1101
- )
1102
1069
  endif()
1103
1070
 
1104
1071
  # Reads the manifest produced by conanfile.py's generate(), assembles
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nodehammer
3
- Version: 0.2.0rc5
3
+ Version: 0.2.0rc6
4
4
  Summary: Detector geometry tessellation and export
5
5
  Author: Paul Gessinger
6
6
  License-Expression: MIT
@@ -166,9 +166,10 @@ nodehammer inspect # summary | tree | tags — ask about a scene
166
166
  nodehammer config # validate | flatten — TOML and Lua configs
167
167
  nodehammer project # pack | publish | info — .nhproj archives
168
168
  nodehammer viewer # open | serve | shot | bench — the app
169
+ nodehammer skills # list | install — the agent skills shipped in the binary
169
170
  ```
170
171
 
171
- Four nouns and one verb. The design of record, including the vocabulary and why
172
+ Five nouns and one verb. The design of record, including the vocabulary and why
172
173
  each old name went, is [docs/cli-design.md](docs/cli-design.md).
173
174
 
174
175
  `convert` spans the whole pipeline, and **the output format decides how far it
@@ -183,6 +184,38 @@ nodehammer viewer odd.nhproj serve # open it in a browser
183
184
  nodehammer project publish odd.nhproj -o site/
184
185
  ```
185
186
 
187
+ ### Agent skills
188
+
189
+ `--help` says what the flags are. It does not say which command blocks until a
190
+ human closes a window, which output is a stable contract and which is prose for
191
+ a reader, or that a missing importer is a compile-time option rather than a
192
+ broken file. [`skills/nodehammer/SKILL.md`](skills/nodehammer/SKILL.md) says
193
+ those things, and it ships **inside the binary** — so installing nodehammer,
194
+ by any route, is enough to have it:
195
+
196
+ ```bash
197
+ nodehammer skills install # ~/.agents/skills, linked from ~/.claude
198
+ nodehammer skills install --scope project # this repository instead
199
+ nodehammer skills list # what this build carries
200
+ ```
201
+
202
+ The real copy goes to `.agents/skills/<name>/`, the cross-agent location read by
203
+ Claude Code, Codex CLI, Gemini CLI, Copilot and Cursor alike. `.claude/skills/`
204
+ gets a **symlink** to it — Claude Code reads only its own directory but follows a
205
+ link out of it, so one copy serves both and they cannot drift. That link is
206
+ created only if `.claude/` already exists; inventing a config directory for a
207
+ tool you may not have is not this command's business.
208
+
209
+ Because the bytes are compiled in, `uvx nodehammer skills install` works exactly
210
+ the same way — the wheel's `nodehammer` command and the compiled executable are
211
+ one implementation, so there is no packaging knob to get wrong and no way for a
212
+ development install to carry a different skill than a released one.
213
+
214
+ This repository links its own skill into `.agents/skills/` and `.claude/skills/`,
215
+ so a checkout is already live. That also means `skills install --scope project`
216
+ *here* refuses without `--force`, which is the point: those links go to the
217
+ source file, and writing through one would edit the tree.
218
+
186
219
  ## Building
187
220
 
188
221
  Dependencies are managed with [Conan](https://conan.io/); builds with CMake + Ninja.
@@ -211,14 +244,14 @@ Key CMake options:
211
244
  | `NODEHAMMER_WITH_GEANT4` | GDML/Geant4 importer | 🚧 links Geant4 only, no importer yet |
212
245
  | `NODEHAMMER_WITH_GEOMODEL` | GeoModel importer | 🚧 declared only |
213
246
  | `NODEHAMMER_BUILD_TESTS` | Build the Catch2 unit-test binary | ✅ |
214
- | `NODEHAMMER_BUILD_SHARED` | Also build and install `libnodehammer` + the public headers + a CMake package config | 🚧 packaging works; the API it exposes is still being written |
247
+ | `NODEHAMMER_BUILD_SHARED` | Also build and install `libnodehammer` and `libnodehammer_ingest` + the public headers + a CMake package config | 🚧 packaging works; the API it exposes is still being written |
215
248
 
216
- With `NODEHAMMER_BUILD_SHARED=ON`, `cmake --install` adds the shared library,
249
+ With `NODEHAMMER_BUILD_SHARED=ON`, `cmake --install` adds both shared libraries,
217
250
  `include/nodehammer/`, and a package config, so a consumer needs only:
218
251
 
219
252
  ```cmake
220
- find_package(nodehammer REQUIRED)
221
- target_link_libraries(app PRIVATE nodehammer::nodehammer)
253
+ find_package(nodehammer CONFIG REQUIRED COMPONENTS Shared)
254
+ target_link_libraries(app PRIVATE nodehammer::shared)
222
255
  ```
223
256
 
224
257
  No `find_dependency` for zstd, flatbuffers, manifold or the rest — the shared
@@ -281,3 +314,9 @@ web/ browser viewer entry point
281
314
 
282
315
  MIT © Paul Gessinger — see [LICENSE](LICENSE). Third-party license texts
283
316
  for vendored/bundled assets live under [LICENSES/](LICENSES).
317
+
318
+ ### Embedding geometry ingestion
319
+
320
+ For experiment integration without the processing/viewer dependency stack, see
321
+ [the C++20 ingestion library](docs/ingestion-library.md). It reuses existing ROOT
322
+ and DD4hep installations and provides `nodehammer::ingest`.