bobframes 0.1.0__tar.gz → 0.2.6__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 (405) hide show
  1. bobframes-0.2.6/CHANGELOG.md +127 -0
  2. bobframes-0.2.6/PKG-INFO +237 -0
  3. bobframes-0.2.6/README.md +206 -0
  4. bobframes-0.2.6/bobframes/_default_config.toml +61 -0
  5. bobframes-0.2.6/bobframes/_version.py +1 -0
  6. bobframes-0.2.6/bobframes/aggregates.py +165 -0
  7. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/catalog.py +15 -15
  8. bobframes-0.2.6/bobframes/cli.py +449 -0
  9. bobframes-0.2.6/bobframes/config.py +528 -0
  10. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/derive_post_merge.py +22 -44
  11. bobframes-0.2.6/bobframes/derives/classifier.py +142 -0
  12. bobframes-0.2.6/bobframes/derives/draw_classifier.toml +78 -0
  13. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/derives/pass_class_breakdown.py +3 -1
  14. bobframes-0.2.6/bobframes/derives/presets/custom-template.toml +52 -0
  15. bobframes-0.2.6/bobframes/derives/presets/godot.toml +60 -0
  16. bobframes-0.2.6/bobframes/derives/presets/unity.toml +61 -0
  17. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/discovery.py +18 -2
  18. bobframes-0.2.6/bobframes/errors.py +65 -0
  19. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/global_entities.py +24 -10
  20. bobframes-0.2.6/bobframes/health.py +233 -0
  21. bobframes-0.2.6/bobframes/html/template.py +734 -0
  22. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/lint.py +8 -20
  23. bobframes-0.2.6/bobframes/lint_banlist.toml +70 -0
  24. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/manifest.py +25 -4
  25. bobframes-0.2.6/bobframes/package.py +580 -0
  26. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/parquetize.py +107 -64
  27. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/parsers/parse_init_state.py +13 -3
  28. bobframes-0.2.6/bobframes/paths.py +158 -0
  29. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/qrd_harness.py +3 -13
  30. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/rdcmd.py +4 -14
  31. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/replay/replay_main.py +21 -41
  32. bobframes-0.2.6/bobframes/reports/__init__.py +42 -0
  33. bobframes-0.2.6/bobframes/reports/_tokens.py +69 -0
  34. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/reports/ab.py +26 -16
  35. bobframes-0.2.6/bobframes/reports/assets/Inter-OFL.txt +92 -0
  36. bobframes-0.2.6/bobframes/reports/assets/README.md +32 -0
  37. bobframes-0.2.6/bobframes/reports/assets/chrome.css +353 -0
  38. bobframes-0.2.6/bobframes/reports/assets/components.css +153 -0
  39. bobframes-0.2.6/bobframes/reports/assets/components.js +174 -0
  40. bobframes-0.2.6/bobframes/reports/assets/container.css +34 -0
  41. bobframes-0.2.6/bobframes/reports/assets/design_tokens.css +79 -0
  42. bobframes-0.2.6/bobframes/reports/assets/icon_sprite.html +27 -0
  43. bobframes-0.2.6/bobframes/reports/assets/inter-subset.woff2 +0 -0
  44. bobframes-0.2.6/bobframes/reports/assets/link_kind.css +75 -0
  45. bobframes-0.2.6/bobframes/reports/assets/per_drop.css +102 -0
  46. bobframes-0.2.6/bobframes/reports/assets/print.css +73 -0
  47. bobframes-0.2.6/bobframes/reports/assets/rdc_table.css +154 -0
  48. bobframes-0.2.6/bobframes/reports/assets/rdc_table.js +665 -0
  49. bobframes-0.2.6/bobframes/reports/assets/sticky.css +48 -0
  50. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/reports/base.py +85 -12
  51. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/reports/cache.py +91 -5
  52. bobframes-0.2.6/bobframes/reports/charts.py +549 -0
  53. bobframes-0.2.6/bobframes/reports/chrome.py +1068 -0
  54. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/reports/cli.py +32 -13
  55. bobframes-0.2.6/bobframes/reports/dashboard.py +560 -0
  56. bobframes-0.2.6/bobframes/reports/delta.py +223 -0
  57. bobframes-0.2.6/bobframes/reports/design_tokens.toml +149 -0
  58. bobframes-0.2.6/bobframes/reports/discovery.py +231 -0
  59. bobframes-0.2.6/bobframes/reports/draws_by_class.py +191 -0
  60. bobframes-0.2.6/bobframes/reports/formatters.py +163 -0
  61. bobframes-0.2.6/bobframes/reports/instancing_opportunities.py +362 -0
  62. bobframes-0.2.6/bobframes/reports/orchestrator.py +98 -0
  63. bobframes-0.2.6/bobframes/reports/overdraw.py +343 -0
  64. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/reports/pass_gpu.py +97 -42
  65. bobframes-0.2.6/bobframes/reports/preview.py +226 -0
  66. bobframes-0.2.6/bobframes/reports/shader_hotlist.py +356 -0
  67. bobframes-0.2.6/bobframes/reports/summary.py +302 -0
  68. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/reports/trend_table.py +132 -104
  69. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/run.py +139 -52
  70. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/schemas.py +64 -33
  71. bobframes-0.2.6/bobframes/tests/_render_util.py +220 -0
  72. bobframes-0.2.6/bobframes/tests/data/golden/_pagedata/catalog.js +1 -0
  73. bobframes-0.2.6/bobframes/tests/data/golden/_reports/draws_by_class.html +799 -0
  74. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
  75. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
  76. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
  77. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
  78. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
  79. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
  80. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
  81. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
  82. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
  83. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
  84. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
  85. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
  86. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
  87. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
  88. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
  89. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
  90. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
  91. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
  92. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
  93. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
  94. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
  95. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
  96. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
  97. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
  98. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
  99. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
  100. bobframes-0.2.6/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/index.html +1842 -0
  101. bobframes-0.2.6/bobframes/tests/data/golden/_reports/index.html +787 -0
  102. bobframes-0.2.6/bobframes/tests/data/golden/_reports/instancing_opportunities.html +789 -0
  103. bobframes-0.2.6/bobframes/tests/data/golden/_reports/overdraw.html +798 -0
  104. bobframes-0.2.6/bobframes/tests/data/golden/_reports/pass_gpu.html +799 -0
  105. bobframes-0.2.6/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/draws_by_class.html +798 -0
  106. bobframes-0.2.6/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/index.html +788 -0
  107. bobframes-0.2.6/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/instancing_opportunities.html +787 -0
  108. bobframes-0.2.6/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/overdraw.html +797 -0
  109. bobframes-0.2.6/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/pass_gpu.html +796 -0
  110. bobframes-0.2.6/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/shader_hotlist.html +787 -0
  111. bobframes-0.2.6/bobframes/tests/data/golden/_reports/run/2026-05-27_r110565/summary.html +787 -0
  112. bobframes-0.2.6/bobframes/tests/data/golden/_reports/shader_hotlist.html +789 -0
  113. bobframes-0.2.6/bobframes/tests/data/golden/_reports/summary.html +789 -0
  114. bobframes-0.2.6/bobframes/tests/data/golden/_reports/trend_table.html +800 -0
  115. bobframes-0.2.6/bobframes/tests/data/golden/index.html +1762 -0
  116. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/README.txt +7 -0
  117. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_pagedata/catalog.js +1 -0
  118. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/draws_by_class.html +799 -0
  119. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
  120. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
  121. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
  122. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
  123. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
  124. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
  125. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
  126. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
  127. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
  128. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
  129. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
  130. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
  131. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
  132. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
  133. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
  134. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
  135. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
  136. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
  137. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
  138. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
  139. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
  140. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
  141. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
  142. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
  143. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
  144. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
  145. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/drill/District 01/2026-05-28_r110600/index.html +1842 -0
  146. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/index.html +787 -0
  147. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/instancing_opportunities.html +789 -0
  148. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/overdraw.html +798 -0
  149. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/pass_gpu.html +799 -0
  150. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/draws_by_class.html +798 -0
  151. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/index.html +788 -0
  152. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/instancing_opportunities.html +787 -0
  153. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/overdraw.html +797 -0
  154. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/pass_gpu.html +796 -0
  155. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/shader_hotlist.html +787 -0
  156. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/run/2026-05-27_r110565/summary.html +787 -0
  157. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/shader_hotlist.html +789 -0
  158. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/summary.html +789 -0
  159. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/_reports/trend_table.html +800 -0
  160. bobframes-0.2.6/bobframes/tests/data/golden_package/redacted/index.html +1762 -0
  161. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/README.txt +7 -0
  162. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_assets/catalog.css +1073 -0
  163. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_assets/catalog.js +665 -0
  164. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_assets/report.css +1 -0
  165. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_assets/report.js +744 -0
  166. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_pagedata/catalog.js +1 -0
  167. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/draws_by_class.html +56 -0
  168. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
  169. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
  170. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
  171. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
  172. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
  173. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
  174. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
  175. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
  176. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
  177. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
  178. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
  179. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
  180. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
  181. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
  182. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
  183. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
  184. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
  185. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
  186. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
  187. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
  188. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
  189. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
  190. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
  191. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
  192. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
  193. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
  194. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/drill/District 01/2026-05-28_r110600/index.html +104 -0
  195. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/index.html +44 -0
  196. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/instancing_opportunities.html +46 -0
  197. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/overdraw.html +55 -0
  198. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/pass_gpu.html +56 -0
  199. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/draws_by_class.html +55 -0
  200. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/index.html +45 -0
  201. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/instancing_opportunities.html +44 -0
  202. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/overdraw.html +54 -0
  203. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/pass_gpu.html +53 -0
  204. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/shader_hotlist.html +44 -0
  205. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/run/2026-05-27_r110565/summary.html +44 -0
  206. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/shader_hotlist.html +46 -0
  207. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/summary.html +46 -0
  208. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/_reports/trend_table.html +57 -0
  209. bobframes-0.2.6/bobframes/tests/data/golden_package/shared/index.html +24 -0
  210. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/README.txt +7 -0
  211. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_assets/catalog.css +1073 -0
  212. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_assets/catalog.js +665 -0
  213. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_assets/report.css +1 -0
  214. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_assets/report.js +744 -0
  215. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_pagedata/catalog.js +1 -0
  216. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/draws_by_class.html +56 -0
  217. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/buffers.js +1 -0
  218. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/clears.js +1 -0
  219. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/counters_per_event.js +1 -0
  220. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/descriptor_access.js +1 -0
  221. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/dispatches.js +1 -0
  222. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draw_bindings.js +1 -0
  223. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/draws.js +1 -0
  224. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/events.js +1 -0
  225. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/fbos.js +1 -0
  226. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/frame_totals.js +1 -0
  227. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/ibo_samples.js +1 -0
  228. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/passes.js +1 -0
  229. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/pixel_history.js +1 -0
  230. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/post_vs_samples.js +1 -0
  231. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/program_transitions.js +1 -0
  232. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/programs.js +1 -0
  233. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/render_targets.js +1 -0
  234. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/resource_creation.js +1 -0
  235. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/rt_event_timeline.js +1 -0
  236. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/samplers.js +1 -0
  237. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/shaders.js +1 -0
  238. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/state_change_events.js +1 -0
  239. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/texture_samples.js +1 -0
  240. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/textures.js +1 -0
  241. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vbo_samples.js +1 -0
  242. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/_pagedata/vertex_inputs.js +1 -0
  243. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/drill/District 01/2026-05-28_r110600/index.html +104 -0
  244. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/index.html +44 -0
  245. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/instancing_opportunities.html +46 -0
  246. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/overdraw.html +55 -0
  247. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/pass_gpu.html +56 -0
  248. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/draws_by_class.html +55 -0
  249. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/index.html +45 -0
  250. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/instancing_opportunities.html +44 -0
  251. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/overdraw.html +54 -0
  252. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/pass_gpu.html +53 -0
  253. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/shader_hotlist.html +44 -0
  254. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/run/2026-05-27_r110565/summary.html +44 -0
  255. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/shader_hotlist.html +46 -0
  256. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/summary.html +46 -0
  257. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/_reports/trend_table.html +57 -0
  258. bobframes-0.2.6/bobframes/tests/data/golden_package/shared_redacted/index.html +24 -0
  259. bobframes-0.2.6/bobframes/tests/data/golden_parquet/digests.json +4966 -0
  260. bobframes-0.2.6/bobframes/tests/data/golden_preview/_chrome_preview.html +810 -0
  261. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/_manifest.json +11 -0
  262. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/_manifest.json +11 -0
  263. bobframes-0.2.6/bobframes/tests/make_golden.py +44 -0
  264. bobframes-0.2.6/bobframes/tests/make_package_golden.py +78 -0
  265. bobframes-0.2.6/bobframes/tests/make_parquet_golden.py +37 -0
  266. bobframes-0.2.6/bobframes/tests/make_preview_golden.py +23 -0
  267. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/make_synthetic.py +20 -3
  268. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/smoke.py +4 -4
  269. bobframes-0.2.6/bobframes/tests/test_aggregates.py +108 -0
  270. bobframes-0.2.6/bobframes/tests/test_assets.py +63 -0
  271. bobframes-0.2.6/bobframes/tests/test_browser_shots.py +49 -0
  272. bobframes-0.2.6/bobframes/tests/test_cache.py +68 -0
  273. bobframes-0.2.6/bobframes/tests/test_catalog_backup_dedup.py +70 -0
  274. bobframes-0.2.6/bobframes/tests/test_charts.py +147 -0
  275. bobframes-0.2.6/bobframes/tests/test_classifier.py +189 -0
  276. bobframes-0.2.6/bobframes/tests/test_components.py +55 -0
  277. bobframes-0.2.6/bobframes/tests/test_config.py +347 -0
  278. bobframes-0.2.6/bobframes/tests/test_contrast.py +102 -0
  279. bobframes-0.2.6/bobframes/tests/test_delta.py +33 -0
  280. bobframes-0.2.6/bobframes/tests/test_design_tokens.py +304 -0
  281. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_discovery.py +2 -1
  282. bobframes-0.2.6/bobframes/tests/test_element_builder.py +88 -0
  283. bobframes-0.2.6/bobframes/tests/test_fonts.py +56 -0
  284. bobframes-0.2.6/bobframes/tests/test_hardening.py +278 -0
  285. bobframes-0.2.6/bobframes/tests/test_head_assets.py +126 -0
  286. bobframes-0.2.6/bobframes/tests/test_health.py +163 -0
  287. bobframes-0.2.6/bobframes/tests/test_js_coupled_classes.py +54 -0
  288. bobframes-0.2.6/bobframes/tests/test_manifest_guard.py +68 -0
  289. bobframes-0.2.6/bobframes/tests/test_multicapture_normalize.py +95 -0
  290. bobframes-0.2.6/bobframes/tests/test_package.py +533 -0
  291. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_parity.py +15 -0
  292. bobframes-0.2.6/bobframes/tests/test_parquet_parity.py +36 -0
  293. bobframes-0.2.6/bobframes/tests/test_parquetize.py +107 -0
  294. bobframes-0.2.6/bobframes/tests/test_report_polish.py +102 -0
  295. bobframes-0.2.6/bobframes/tests/test_report_structure.py +521 -0
  296. bobframes-0.2.6/bobframes/tests/test_run_model.py +241 -0
  297. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_schemas_unit.py +7 -5
  298. bobframes-0.2.6/bobframes/tests/test_summary.py +136 -0
  299. bobframes-0.2.6/bobframes/tests/test_table_component.py +224 -0
  300. bobframes-0.2.6/bobframes/tests/test_theme.py +97 -0
  301. bobframes-0.2.6/bobframes/tests/test_token_guard.py +48 -0
  302. {bobframes-0.1.0 → bobframes-0.2.6}/pyproject.toml +16 -0
  303. bobframes-0.1.0/CHANGELOG.md +0 -45
  304. bobframes-0.1.0/PKG-INFO +0 -144
  305. bobframes-0.1.0/README.md +0 -114
  306. bobframes-0.1.0/bobframes/_version.py +0 -1
  307. bobframes-0.1.0/bobframes/cli.py +0 -266
  308. bobframes-0.1.0/bobframes/html/template.py +0 -1056
  309. bobframes-0.1.0/bobframes/paths.py +0 -111
  310. bobframes-0.1.0/bobframes/reports/_dashboard.py +0 -425
  311. bobframes-0.1.0/bobframes/reports/chrome.py +0 -1306
  312. bobframes-0.1.0/bobframes/reports/delta.py +0 -167
  313. bobframes-0.1.0/bobframes/reports/discovery.py +0 -118
  314. bobframes-0.1.0/bobframes/reports/draws_by_class.py +0 -165
  315. bobframes-0.1.0/bobframes/reports/formatters.py +0 -122
  316. bobframes-0.1.0/bobframes/reports/instancing_opportunities.py +0 -276
  317. bobframes-0.1.0/bobframes/reports/orchestrator.py +0 -59
  318. bobframes-0.1.0/bobframes/reports/overdraw.py +0 -293
  319. bobframes-0.1.0/bobframes/reports/shader_hotlist.py +0 -240
  320. bobframes-0.1.0/bobframes/tests/__init__.py +0 -0
  321. bobframes-0.1.0/bobframes/tests/_render_util.py +0 -84
  322. bobframes-0.1.0/bobframes/tests/data/golden/_reports/draws_by_class.html +0 -323
  323. bobframes-0.1.0/bobframes/tests/data/golden/_reports/drill/District 01/2026-05-28_r110600/index.html +0 -1560
  324. bobframes-0.1.0/bobframes/tests/data/golden/_reports/index.html +0 -264
  325. bobframes-0.1.0/bobframes/tests/data/golden/_reports/instancing_opportunities.html +0 -266
  326. bobframes-0.1.0/bobframes/tests/data/golden/_reports/overdraw.html +0 -275
  327. bobframes-0.1.0/bobframes/tests/data/golden/_reports/pass_gpu.html +0 -277
  328. bobframes-0.1.0/bobframes/tests/data/golden/_reports/shader_hotlist.html +0 -265
  329. bobframes-0.1.0/bobframes/tests/data/golden/_reports/trend_table.html +0 -390
  330. bobframes-0.1.0/bobframes/tests/data/golden/index.html +0 -1175
  331. bobframes-0.1.0/bobframes/tests/test_hardening.py +0 -142
  332. {bobframes-0.1.0 → bobframes-0.2.6}/.gitignore +0 -0
  333. {bobframes-0.1.0 → bobframes-0.2.6}/LICENSE +0 -0
  334. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/__init__.py +0 -0
  335. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/derives/__init__.py +0 -0
  336. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/derives/texture_usage.py +0 -0
  337. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/html/__init__.py +0 -0
  338. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/parsers/__init__.py +0 -0
  339. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/parsers/derive_program_transitions.py +0 -0
  340. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/probes/__init__.py +0 -0
  341. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/probes/whatif.py +0 -0
  342. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/query_examples.py +0 -0
  343. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/replay/__init__.py +0 -0
  344. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/resource_labels.py +0 -0
  345. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/stable_keys.py +0 -0
  346. {bobframes-0.1.0/bobframes/reports → bobframes-0.2.6/bobframes/tests}/__init__.py +0 -0
  347. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/buffers.parquet +0 -0
  348. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/clears.parquet +0 -0
  349. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/counters_per_event.parquet +0 -0
  350. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/descriptor_access.parquet +0 -0
  351. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/dispatches.parquet +0 -0
  352. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/draw_bindings.parquet +0 -0
  353. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/draws.parquet +0 -0
  354. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/events.parquet +0 -0
  355. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/fbos.parquet +0 -0
  356. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/frame_totals.parquet +0 -0
  357. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/ibo_samples.parquet +0 -0
  358. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/indirect_args.parquet +0 -0
  359. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/passes.parquet +0 -0
  360. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/pixel_history.parquet +0 -0
  361. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/post_vs_samples.parquet +0 -0
  362. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/program_transitions.parquet +0 -0
  363. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/programs.parquet +0 -0
  364. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/render_targets.parquet +0 -0
  365. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/resource_creation.parquet +0 -0
  366. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/rt_event_timeline.parquet +0 -0
  367. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/samplers.parquet +0 -0
  368. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/shaders.parquet +0 -0
  369. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/state_change_events.parquet +0 -0
  370. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/texture_samples.parquet +0 -0
  371. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/textures.parquet +0 -0
  372. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/vbo_samples.parquet +0 -0
  373. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-27_r110565/vertex_inputs.parquet +0 -0
  374. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/buffers.parquet +0 -0
  375. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/clears.parquet +0 -0
  376. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/counters_per_event.parquet +0 -0
  377. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/descriptor_access.parquet +0 -0
  378. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/dispatches.parquet +0 -0
  379. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/draw_bindings.parquet +0 -0
  380. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/draws.parquet +0 -0
  381. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/events.parquet +0 -0
  382. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/fbos.parquet +0 -0
  383. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/frame_totals.parquet +0 -0
  384. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/ibo_samples.parquet +0 -0
  385. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/indirect_args.parquet +0 -0
  386. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/passes.parquet +0 -0
  387. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/pixel_history.parquet +0 -0
  388. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/post_vs_samples.parquet +0 -0
  389. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/program_transitions.parquet +0 -0
  390. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/programs.parquet +0 -0
  391. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/render_targets.parquet +0 -0
  392. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/resource_creation.parquet +0 -0
  393. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/rt_event_timeline.parquet +0 -0
  394. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/samplers.parquet +0 -0
  395. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/shaders.parquet +0 -0
  396. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/state_change_events.parquet +0 -0
  397. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/texture_samples.parquet +0 -0
  398. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/textures.parquet +0 -0
  399. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/vbo_samples.parquet +0 -0
  400. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/data/synthetic/_data/District 01/2026-05-28_r110600/vertex_inputs.parquet +0 -0
  401. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_determinism.py +0 -0
  402. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_perf.py +0 -0
  403. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_replay_drift.py +0 -0
  404. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_schemas.py +0 -0
  405. {bobframes-0.1.0 → bobframes-0.2.6}/bobframes/tests/test_stable_keys.py +0 -0
@@ -0,0 +1,127 @@
1
+ # Changelog
2
+
3
+ Changes to this project are documented here, newest first.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.6] - 2026-06-06
11
+
12
+ A build-health one-pager, a shareable `package` bundle, a server-side component system, and a full visual
13
+ redesign. No schema change (still schema 3); parquet digests stay byte-identical to 0.1.0/0.2.0 on the same
14
+ captures. Per ADR-43 there is no standalone 0.2.5 -- this release carries the c16q-c16x foundation AND the
15
+ redesign, so `_version` jumps `0.2.0 -> 0.2.6`.
16
+
17
+ ### Added
18
+ - Build-health one-pager (`bobframes report summary`): a presentation-independent verdict/trend module
19
+ (`health.py` -- ordered OK<UNKNOWN<AT_RISK<ALARM so a real alarm is never masked yet missing data is
20
+ never a false green) feeding a print-first exec summary (verdict bar, averaged KPIs with vs-prior pills +
21
+ sparklines, a baseline-gated movement card, a worst-first by-area table). (ADR-39)
22
+ - `bobframes package`: a non-mutating transform of a rendered tree into a shareable `<project>-<date>-report.zip`
23
+ (reproducible bytes) + a standalone self-contained `summary.html`. `--shared-assets` (the default) dedupes
24
+ chrome into `_assets/` linked per page (built at the render seam, not by scraping HTML); `--inline` opts out;
25
+ `--redact` scrubs device/host provenance at the data seam (whole-tree drop-sidecars excluded). (ADR-40/41)
26
+ - Server-side component system (`reports/chrome.py`): an escape-by-construction element builder (`el`/`raw`/
27
+ `el_void`/`classes`), a normalized table-component family (`Column`/`data_table`/`static_table` + a virtual
28
+ `table_controls`/`virtual_host`/`virtual_table_section` host), a delta-column factory, and a token-validity
29
+ guard (`undefined_tokens()` -- a typo'd `var(--x)` is a CI failure + a `preview` warning). CSS/JS now live as
30
+ real `reports/assets/*.{css,js}` files. A `bobframes preview` gallery documents every component. (ADR-42)
31
+ - User theme override for pip installs: a `.bobframes.toml [theme]` section + `render/preview --accent`/
32
+ `--accent-data` flags re-hue the accent/status/chart colors WITHOUT editing the packaged `design_tokens.toml`
33
+ (deep-merged through the existing config cascade; color-key allowlist; ASCII/injection-guarded). `export-tokens
34
+ --theme-template` emits a paste-ready starter; `--watch` polls `.bobframes.toml`. (ADR-45)
35
+ - Dev-only screenshot harness `tools/shoot.py` (headless-Chrome over CDP, light/dark/print; not shipped) + a
36
+ `-m browser` opt-in matrix + a dependency-free oklch->WCAG contrast test, for the redesign's visual gate.
37
+
38
+ ### Changed
39
+ - Visual redesign anchored on shadcn/ui + Grafana density (ADR-43/44): a neutral grayscale palette (chroma 0),
40
+ WCAG-AA tertiary text, FLAT border-led surfaces (reverses the ADR-34 depth -- a 1px border + a `--radius`
41
+ 6/8/10 token scale replaces the elevation shadows + the hardcoded 2/3/4px radii), `:focus-visible` rings,
42
+ reduced-motion-safe `:active`, container-query responsive, and a print pass. Restrained type tune with hero
43
+ numerals scoped to the summary one-pager; Grafana-dense rows/cards everywhere else; the catalog/drill data
44
+ browser widened (max data-per-screen).
45
+ - "Everything is a component": the summary, dashboard minis, the 6 detail reports, and the catalog/drill virtual
46
+ hosts all render through the component family; the remaining hand-written chrome leaves were migrated onto `el`
47
+ (the bespoke-markup long-tail is closed -- only the fixed page scaffold remains, by necessity). `data_table`
48
+ normalizes the previously hand-written report tables (the visual-parity gate is intentionally replaced by a
49
+ structural + data-preservation gate per ADR-43).
50
+ - Per-frame normalization for multi-capture runs (instancing repeat + shader cost read per distinct capture,
51
+ no-op for 1-capture data so it stays byte-identical) and a single `aggregates.py` data layer feeding the
52
+ dashboard/reports/verdict so they cannot disagree.
53
+ - Run model + sharing surfaced in the root catalog (build-health + dashboard chips, A/B pair lists).
54
+
55
+ ### Fixed
56
+ - Single-drop trend-table crash (`'str' object has no attribute 'get'`); `--force` rotation-backup
57
+ double-counting in the catalog + global-entities walkers (canonical-basename reconstruction).
58
+ - WCAG-AA contrast on tertiary text; print no longer hugs the paper edge.
59
+
60
+ ## [0.2.0] - 2026-06-03
61
+
62
+ De-hardcoding + a full report overhaul. No schema change (still schema 3); extraction output is stable
63
+ where the pipeline is unchanged, so parquet digests are byte-identical to 0.1.0 on the same captures.
64
+
65
+ ### Added
66
+ - Inline-SVG chart toolkit (`reports/charts.py`): a flagship chart per report (pass-GPU treemap,
67
+ draws-by-class donut, shader complexity-vs-cost scatter, overdraw reject-rate bars, instancing
68
+ wasted-index bars, per-KPI trend lines), deterministic and dependency-free (no `random`/`Date`).
69
+ - Report design language: hero KPI strip, callouts with config-driven severity, provenance/device
70
+ strip, section cards, sticky section headers, copy buttons on long IDs, vendored Inter subset font
71
+ (offline, base64-inlined), and an auto-tint heatmap on ranked numeric columns.
72
+ - Run model: per-run truth (each report names "run N of M"), a run picker, A/B compare, and a trend
73
+ table across runs; older runs are pre-rendered up to a configurable limit.
74
+ - One unified `rdc-table` engine (progressive enhancement, two modes): server-baked `static` for reports
75
+ (JS-off / print / Ctrl-F / golden all hold) and windowed `virtual` for the catalog + per-drop drill.
76
+ Shared natural-numeric sort, type-split, heatmap, column groups, search/filter, controllable cell
77
+ truncation with hover-reveal, and full sort/filter a11y (aria-sort + keyboard-operable headers + a
78
+ labelled filter input) across both modes.
79
+ - TOML config (`.bobframes.toml`, `[report]`/`[pipeline]` sections), `design_tokens.toml` token system,
80
+ and a state-capable draw classifier driven by table columns.
81
+ - Reports cache with a SHA256 sidecar (corrupt/missing/mismatch falls back to a live scan, never
82
+ silent-empty); manifest schema-version guard (`ingest --force` hint on mismatch).
83
+
84
+ ### Changed
85
+ - Catalog + drill readability: roomier rows, type-split mono/sans, and the heavy per-table row data moved
86
+ out of the HTML into `_pagedata/*.js` companions (the ~21 MB time-to-interactive fix) loaded via a
87
+ file://-safe `<script defer src>`.
88
+ - External tool resolution + clearer pipeline error messages and exit codes; environment variables
89
+ renamed `RDC_*` -> `BOBFRAMES_*` (one-release legacy fallback with a deprecation warning).
90
+ - Project paths, the report registry, and the drill-size budget are configurable rather than hardcoded.
91
+
92
+ ## [0.1.0] - 2026-05-31
93
+
94
+ First standalone release. v1 is Windows-only (the replay stage drives `qrenderdoc`).
95
+
96
+ ### Added
97
+ - Single `bobframes` binary with subcommands `ingest`, `render`, `ab`, `report`, `catalog`, `lint`,
98
+ `check`, `serve`, `smoke`, and `version`. Positional `root` (default `.`) across verbs; long-flag
99
+ only; exit codes `0`/`1`/`2`/`3`/`4`. stdlib `logging` at INFO by default, `--verbose` for DEBUG,
100
+ `[HH:MM:SS]` line format (G-8).
101
+ - Replay script located via `importlib.resources` (`bobframes.replay.replay_script_path`) so replay
102
+ works from an installed wheel, not just an in-tree checkout.
103
+ - Reliability hardening: atomic writes for `_manifest.json`, Parquet+CSV pairs, and `done.marker`
104
+ (`.tmp` + `os.replace`, rollback on failure); process-tree kill (`taskkill /T /F`) when a
105
+ `qrenderdoc` replay times out; per-capture replay-failure isolation
106
+ (`capture_status='replay_failed'` instead of aborting the whole drop); subprocess stderr logged on
107
+ convert-timeout and on every parse; manifest provenance fields `tool_versions` and `host_info`.
108
+ - Test gates: golden-snapshot parity, schema regression, determinism, performance, and a replay
109
+ column-drift guard against `schemas.py` (H-6); mocked-subprocess tests for the hardening branches
110
+ the GPU-less runner cannot exercise; a data-driven `smoke` (render-only against a bundled synthetic
111
+ fixture by default); unit tests for stable keys, schemas, and drop discovery.
112
+ - GitHub Actions CI across a Windows / Python / pyarrow matrix, with a tag-gated PyPI publish job.
113
+
114
+ ### Changed
115
+ - **Stable-key format upgrade:** stable keys now carry a `KEY_VERSION = 1` version byte in the hash
116
+ input. Keys produced before this release are not comparable with `0.1.0` keys; rebuild affected
117
+ data with `bobframes ingest --force`. `KEY_VERSION` bumps on any future key-derivation rule change.
118
+ - Timestamps unified to a single UTC `now_iso()` helper (`bobframes.manifest.now_iso`); the
119
+ local-time variant in `reports/cli` was dropped.
120
+
121
+ ### Removed
122
+ - The project-embedded `_analysis` package. `python -m _analysis.run` and the other
123
+ `python -m _analysis.*` entry points no longer work; switch to the `bobframes` commands (see the
124
+ migration table in the README). This is a hard rename with no compatibility shim.
125
+
126
+ [Unreleased]: https://github.com/altpsyche/bobframes/compare/v0.1.0...HEAD
127
+ [0.1.0]: https://github.com/altpsyche/bobframes/releases/tag/v0.1.0
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: bobframes
3
+ Version: 0.2.6
4
+ Summary: RenderDoc capture pipeline: ingest, analyze, render.
5
+ Project-URL: Homepage, https://github.com/altpsyche/bobframes
6
+ Project-URL: Issues, https://github.com/altpsyche/bobframes/issues
7
+ Project-URL: Changelog, https://github.com/altpsyche/bobframes/blob/main/CHANGELOG.md
8
+ Author-email: Siva Subramanyam <sivasubramanyam@mayhem-studios.com>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: gpu,parquet,profiling,renderdoc
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Multimedia :: Graphics
21
+ Classifier: Topic :: Software Development :: Debuggers
22
+ Requires-Python: <3.15,>=3.10
23
+ Requires-Dist: pyarrow<22,>=17
24
+ Requires-Dist: tomli>=2.0; python_version < '3.11'
25
+ Provides-Extra: dev
26
+ Requires-Dist: build; extra == 'dev'
27
+ Requires-Dist: hatchling; extra == 'dev'
28
+ Requires-Dist: pytest; extra == 'dev'
29
+ Requires-Dist: twine; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # BobFrames
33
+
34
+ RenderDoc capture pipeline: ingest, analyze, render. Point it at a folder of `.rdc` captures and it
35
+ produces `_data/` (Parquet tables) plus `_reports/` -- static, offline, `file://`-safe HTML you can
36
+ browse: a one-page **build-health summary**, a reports dashboard, per-aspect reports (overdraw, shader
37
+ hotlist, instancing, draws-by-class, pass-GPU, cross-run trend), and a per-drop drill-down data browser.
38
+ Reports are self-contained, printable, Ctrl-F-able, and work with JavaScript off. Windows-only in v1.
39
+
40
+ > Built for **Mayhem Studios** -- see [Built for Mayhem Studios](#built-for-mayhem-studios) below.
41
+
42
+ ## Requirements
43
+
44
+ - Windows 10 or later (the replay stage drives `qrenderdoc`, which is Windows-only in v1).
45
+ - Python 3.10 - 3.13.
46
+ - RenderDoc 1.x, or Arm Performance Studio, providing `renderdoccmd` and `qrenderdoc` on disk.
47
+
48
+ ## Install
49
+
50
+ ```
51
+ pipx install bobframes
52
+ bobframes check
53
+ ```
54
+
55
+ `bobframes check` prints the resolved paths for `renderdoccmd` and `qrenderdoc` and exits non-zero if
56
+ either is missing, so you can confirm the toolchain before a long ingest.
57
+
58
+ ## Quickstart
59
+
60
+ ```
61
+ cd path\to\captures # a folder of <Area>\<YYYY-MM-DD[_label]>\*.rdc
62
+ bobframes ingest . # export, parse, replay, parquetize, derive, render
63
+ bobframes serve . # open a local static preview of the reports
64
+ ```
65
+
66
+ `ingest` writes Parquet under `_data/` and HTML under `_reports/`. Re-run `bobframes render .` any
67
+ time to rebuild the HTML from existing Parquet without re-replaying captures.
68
+
69
+ ## Commands
70
+
71
+ | Command | Purpose |
72
+ |---|---|
73
+ | `ingest [root] [--area X] [--label Y] [--capture N] [--force] [--pixel-grid 4] [--render-only]` | Full pipeline: export, parse, replay, parquetize, derive, manifest, commit, catalog, render. |
74
+ | `render [root] [--area X] [--label Y] [--accent OKLCH] [--accent-data OKLCH] [--watch]` | Rebuild HTML and catalog from existing Parquet. `--accent`/`--accent-data` re-hue the theme for this render (ADR-45). `--watch` re-renders on `design_tokens.toml`, chrome, or `.bobframes.toml` edits (alpha). |
75
+ | `ab [root] --baseline-label X --compare-label Y` | All reports for one drop pair under `_reports/ab/<pair>/`. |
76
+ | `report [root] <name>` | Build one named report (summary, draws-by-class, trend, instancing, pass-gpu, shader, overdraw, dashboard). `summary` is the exec build-health one-pager. |
77
+ | `catalog [root]` | Rebuild `_data/_catalog.parquet` only. |
78
+ | `lint <file>...` | Check HTML or markdown against the banlist. |
79
+ | `check` | Print resolved tool paths; non-zero when a tool is missing. |
80
+ | `serve [root] [--port 8000] [--bind 127.0.0.1]` | Static preview via the stdlib HTTP server. |
81
+ | `package [root] [--inline] [--light] [--redact] [--redact-paths {strip,fail}] [--out PATH] [--run KEY] [--no-summary-file] [--stage]` | Bundle a rendered tree into a shareable `<project>-<rundate>-report.zip` + a standalone `<project>-<rundate>-summary.html`, both written OUTSIDE `<root>` (non-mutating). `--redact` scrubs device/host provenance + absolute paths for external sharing. |
82
+ | `preview [root] [--accent OKLCH] [--accent-data OKLCH]` | Render the chrome gallery to `_reports/_chrome_preview.html`; no capture data needed. `--accent` previews a theme override before you commit it. |
83
+ | `export-tokens [--format toml\|json\|css] [--theme-template]` | Print the design tokens to stdout in the chosen format. `--theme-template` emits a paste-ready `[theme]` block for `.bobframes.toml`. |
84
+ | `smoke [--data DIR]` | End-to-end check; render-only against the bundled fixture when `--data` is omitted. |
85
+ | `version` | Print `bobframes`, schema, and pyarrow versions. |
86
+
87
+ `<root>` is positional and defaults to `.`. Flags are long-form only. Exit codes: `0` success,
88
+ `1` pipeline or build failure, `2` usage error, `3` external tool missing, `4` interrupted.
89
+
90
+ ## Sharing a report
91
+
92
+ `bobframes package <root>` turns a rendered tree into two friendly artifacts beside it (it only READS
93
+ `<root>`):
94
+
95
+ - `<project>-<rundate>-report.zip` -- the full explorable tree. **Extract the whole folder before
96
+ opening** (`index.html`, then the Build Health Summary): the pages link each other and a shared
97
+ `_assets/` folder by relative path, so opening one file straight out of the zip breaks those links.
98
+ - `<project>-<rundate>-summary.html` -- a standalone, self-contained one-pager. Email it, double-click
99
+ it, or `Ctrl-P -> Save as PDF`; no unzip needed. (Its deep links into the reports only resolve when
100
+ the zip is shipped alongside.)
101
+
102
+ The zip DEFAULTS to **shared assets**: the ~95 KB of chrome (font + CSS + JS) lives once in `_assets/`
103
+ and every page links it, so a multi-run bundle is markedly smaller. Because the pages share that
104
+ folder, **no single page is portable on its own** -- keep the extracted folder together, or send the
105
+ standalone `summary.html` when you need just one file. `--inline` opts out and makes each page
106
+ self-contained (larger, but any single report file is portable). `--light` bundles only `index.html`
107
+ + the top-level reports (no drill pages or data) for a quick "read, don't drill" share.
108
+
109
+ ### Sharing externally -- `--redact`
110
+
111
+ `bobframes package <root> --redact` produces a bundle safe to hand to someone outside your team. It
112
+ scrubs the GPU / driver / CPU / OS + capture-tool versions from every page's device strip (replaced with
113
+ `redacted`), drops the raw provenance sidecars (`_manifest.json`, `frame_metadata.jsonl`) from the
114
+ bundle, and replaces absolute Windows paths (`C:\...`) with `<path redacted>` across the pages and the
115
+ downloadable CSVs. Redaction re-renders the tree, so `--inline --redact` is no longer a fast copy.
116
+
117
+ - `--redact-paths=strip` (default) -- replace the path tokens; the bundle stays usable on a real capture.
118
+ - `--redact-paths=fail` -- a CI completeness check: exit nonzero (don't write the zip) if any absolute
119
+ path remains in a rendered page, so a leak fails the build.
120
+
121
+ **Caveat:** the pages and the downloadable CSVs are sanitized, but the **binary `.parquet`** tables still
122
+ contain resource paths (they can't be string-edited safely) -- strip `_data/` if the parquet itself must
123
+ leave your team. UNC (`\\host\share`) and forward-slash (`C:/...`) paths are not auto-stripped.
124
+
125
+ ## Customizing reports
126
+
127
+ The look is shadcn-clean, neutral, and flat by default. Two ways to re-color it:
128
+
129
+ ### Pip installs -- re-hue without editing source (recommended)
130
+
131
+ `pip install bobframes` puts the design tokens in site-packages, where edits are lost on upgrade -- so
132
+ re-hue the accent / status / chart colors through the config cascade instead:
133
+
134
+ - **Persistent:** add a `[theme]` section to `.bobframes.toml` in your capture root (or
135
+ `%APPDATA%/bobframes/config.toml`). `bobframes export-tokens --theme-template` prints a ready-to-paste
136
+ starter with just the overridable color knobs.
137
+ - **One-shot:** `bobframes render . --accent '<oklch>'` (and `--accent-data '<oklch>'`) -- the top
138
+ precedence tier (CLI > env > config > bundled default). `bobframes preview --accent '<oklch>'` previews
139
+ it with no capture data.
140
+
141
+ Only color hues (accent, the four status colors, the draw-class + chart palette) are overridable; layout,
142
+ spacing, type, and the table engine stay bundled, so an override can never desync the rendering. A bad or
143
+ non-color value warns and is ignored. `--watch` live-reloads on `.bobframes.toml` edits too.
144
+
145
+ ### Source checkouts -- edit the bundled tokens
146
+
147
+ The full palette lives in `bobframes/reports/design_tokens.toml` (colors, spacing, type, motion, radius,
148
+ and base layout sizes). The CSS variable name is fixed by its key: `surface_0` becomes `--surface-0`,
149
+ `accent_primary` becomes `--accent-primary`.
150
+
151
+ ```
152
+ bobframes preview # writes _reports/_chrome_preview.html (every component, no data)
153
+ # edit a value in design_tokens.toml
154
+ bobframes preview # under a second; reload the page in a browser
155
+ bobframes render C:\captures # apply the change to real reports from existing Parquet
156
+ ```
157
+
158
+ `bobframes render --watch` re-runs render-only whenever `design_tokens.toml`, a chrome module, or
159
+ `.bobframes.toml` changes (alpha; a 500ms poll, no extra dependency). `bobframes export-tokens --format
160
+ css` prints the live `:root` block; `--format json` the nested table; `--format toml` the file itself.
161
+
162
+ ## External tools
163
+
164
+ The export stage runs `renderdoccmd convert`; the replay stage runs `qrenderdoc --python`. bobframes
165
+ resolves both from (in order) a config file (`.bobframes.toml`), version-globbed Arm Performance Studio
166
+ install paths, and `PATH`. Install RenderDoc / Arm Performance Studio anywhere on those, or point a
167
+ config entry at it. Run `bobframes check` to see what was resolved.
168
+
169
+ ## Output layout
170
+
171
+ ```
172
+ <root>/
173
+ index.html root catalog view
174
+ <area>/<drop>/ raw RDC inputs (left untouched)
175
+ _data/ pipeline outputs
176
+ _catalog.parquet (+ .csv, .json)
177
+ _global_entities.parquet (+ .csv)
178
+ _query_examples.md
179
+ <area>/<drop>/ per-drop data (29 Parquet tables)
180
+ *.parquet (+ matching .csv)
181
+ _manifest.json, _resource_labels.json
182
+ shader_src/*.glsl, jsonl sidecars
183
+ done.marker
184
+ _reports/ rendered HTML
185
+ *.html (dashboard + reports)
186
+ ab/<pair>/*.html
187
+ drill/<area>/<drop>/index.html per-drop browser
188
+ _cache/
189
+ ```
190
+
191
+ The catalog stores each drop's path relative to `<root>` for portability.
192
+
193
+ ## Migrating from `_analysis`
194
+
195
+ v1 is a hard rename of the older project-embedded `_analysis` package, with no compatibility shim:
196
+ `python -m _analysis.*` stops working once `bobframes` is installed. Map old invocations to new ones:
197
+
198
+ | Old (`_analysis`) | New (`bobframes`) |
199
+ |---|---|
200
+ | `python -m _analysis.run --root . --area X --label Y` | `bobframes ingest . --area X --label Y` |
201
+ | `python -m _analysis.reports.ab --root . --baseline-label X --compare-label Y` | `bobframes ab . --baseline-label X --compare-label Y` |
202
+ | `python -m _analysis.lint <file>` | `bobframes lint <file>` |
203
+ | `python -m _analysis.tests.smoke` | `bobframes smoke` |
204
+
205
+ ## Troubleshooting
206
+
207
+ | Symptom | Resolution |
208
+ |---|---|
209
+ | `renderdoccmd not found` (exit 3) | Install RenderDoc or Arm Performance Studio, or put the executable on `PATH`; confirm with `bobframes check`. |
210
+ | `qrenderdoc` replay hangs | v1 kills the replay process tree on timeout and records `capture_status='replay_failed'` for that capture; the rest of the drop still completes. Re-run with `--force` to retry. |
211
+ | Lint failure during render | The emitted HTML contains a banned token. Run `bobframes lint <file>` to see the line and label. |
212
+ | `schema mismatch` (exit 1) | A drop's `_manifest.json` schema version differs from the installed schema. Rebuild it with `bobframes ingest --force` (the v1 schema-migration path; see G-3). |
213
+ | Permission denied on `_data` | Close any viewer holding a Parquet open, then re-run; writes are staged and renamed atomically. |
214
+
215
+ ## Advanced
216
+
217
+ - A/B reports: `bobframes ab . --baseline-label OLD --compare-label NEW` builds a side-by-side set.
218
+ - Programmatic use: import `bobframes.schemas`, `bobframes.discovery`, and `bobframes.paths` to drive
219
+ table lookups, drop discovery, and path resolution from your own scripts.
220
+ - `bobframes/probes/whatif.py` is a manual qrenderdoc-side probe and is not wired as a CLI command.
221
+ - TOML config (`.bobframes.toml`), an externalized draw classifier, and design-token theming
222
+ (`[theme]` / `--accent`) shipped in v0.2.6. `bobframes package` produces shareable, optionally
223
+ redacted bundles (see [Sharing a report](#sharing-a-report)).
224
+
225
+ ## Built for Mayhem Studios
226
+
227
+ BobFrames is built and maintained for **Mayhem Studios** -- it powers the studio's GPU
228
+ capture-analysis and frame-performance work, and is open-sourced here for the wider RenderDoc and
229
+ graphics community.
230
+
231
+ If BobFrames helps your work, please **support Mayhem Studios** -- the studio that makes this tool
232
+ possible. Follow the studio, play and wishlist our games, and tell a friend who fights frame times.
233
+ A on the [GitHub repo](https://github.com/altpsyche/bobframes) helps too. Thank you.
234
+
235
+ ## License
236
+
237
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,206 @@
1
+ # BobFrames
2
+
3
+ RenderDoc capture pipeline: ingest, analyze, render. Point it at a folder of `.rdc` captures and it
4
+ produces `_data/` (Parquet tables) plus `_reports/` -- static, offline, `file://`-safe HTML you can
5
+ browse: a one-page **build-health summary**, a reports dashboard, per-aspect reports (overdraw, shader
6
+ hotlist, instancing, draws-by-class, pass-GPU, cross-run trend), and a per-drop drill-down data browser.
7
+ Reports are self-contained, printable, Ctrl-F-able, and work with JavaScript off. Windows-only in v1.
8
+
9
+ > Built for **Mayhem Studios** -- see [Built for Mayhem Studios](#built-for-mayhem-studios) below.
10
+
11
+ ## Requirements
12
+
13
+ - Windows 10 or later (the replay stage drives `qrenderdoc`, which is Windows-only in v1).
14
+ - Python 3.10 - 3.13.
15
+ - RenderDoc 1.x, or Arm Performance Studio, providing `renderdoccmd` and `qrenderdoc` on disk.
16
+
17
+ ## Install
18
+
19
+ ```
20
+ pipx install bobframes
21
+ bobframes check
22
+ ```
23
+
24
+ `bobframes check` prints the resolved paths for `renderdoccmd` and `qrenderdoc` and exits non-zero if
25
+ either is missing, so you can confirm the toolchain before a long ingest.
26
+
27
+ ## Quickstart
28
+
29
+ ```
30
+ cd path\to\captures # a folder of <Area>\<YYYY-MM-DD[_label]>\*.rdc
31
+ bobframes ingest . # export, parse, replay, parquetize, derive, render
32
+ bobframes serve . # open a local static preview of the reports
33
+ ```
34
+
35
+ `ingest` writes Parquet under `_data/` and HTML under `_reports/`. Re-run `bobframes render .` any
36
+ time to rebuild the HTML from existing Parquet without re-replaying captures.
37
+
38
+ ## Commands
39
+
40
+ | Command | Purpose |
41
+ |---|---|
42
+ | `ingest [root] [--area X] [--label Y] [--capture N] [--force] [--pixel-grid 4] [--render-only]` | Full pipeline: export, parse, replay, parquetize, derive, manifest, commit, catalog, render. |
43
+ | `render [root] [--area X] [--label Y] [--accent OKLCH] [--accent-data OKLCH] [--watch]` | Rebuild HTML and catalog from existing Parquet. `--accent`/`--accent-data` re-hue the theme for this render (ADR-45). `--watch` re-renders on `design_tokens.toml`, chrome, or `.bobframes.toml` edits (alpha). |
44
+ | `ab [root] --baseline-label X --compare-label Y` | All reports for one drop pair under `_reports/ab/<pair>/`. |
45
+ | `report [root] <name>` | Build one named report (summary, draws-by-class, trend, instancing, pass-gpu, shader, overdraw, dashboard). `summary` is the exec build-health one-pager. |
46
+ | `catalog [root]` | Rebuild `_data/_catalog.parquet` only. |
47
+ | `lint <file>...` | Check HTML or markdown against the banlist. |
48
+ | `check` | Print resolved tool paths; non-zero when a tool is missing. |
49
+ | `serve [root] [--port 8000] [--bind 127.0.0.1]` | Static preview via the stdlib HTTP server. |
50
+ | `package [root] [--inline] [--light] [--redact] [--redact-paths {strip,fail}] [--out PATH] [--run KEY] [--no-summary-file] [--stage]` | Bundle a rendered tree into a shareable `<project>-<rundate>-report.zip` + a standalone `<project>-<rundate>-summary.html`, both written OUTSIDE `<root>` (non-mutating). `--redact` scrubs device/host provenance + absolute paths for external sharing. |
51
+ | `preview [root] [--accent OKLCH] [--accent-data OKLCH]` | Render the chrome gallery to `_reports/_chrome_preview.html`; no capture data needed. `--accent` previews a theme override before you commit it. |
52
+ | `export-tokens [--format toml\|json\|css] [--theme-template]` | Print the design tokens to stdout in the chosen format. `--theme-template` emits a paste-ready `[theme]` block for `.bobframes.toml`. |
53
+ | `smoke [--data DIR]` | End-to-end check; render-only against the bundled fixture when `--data` is omitted. |
54
+ | `version` | Print `bobframes`, schema, and pyarrow versions. |
55
+
56
+ `<root>` is positional and defaults to `.`. Flags are long-form only. Exit codes: `0` success,
57
+ `1` pipeline or build failure, `2` usage error, `3` external tool missing, `4` interrupted.
58
+
59
+ ## Sharing a report
60
+
61
+ `bobframes package <root>` turns a rendered tree into two friendly artifacts beside it (it only READS
62
+ `<root>`):
63
+
64
+ - `<project>-<rundate>-report.zip` -- the full explorable tree. **Extract the whole folder before
65
+ opening** (`index.html`, then the Build Health Summary): the pages link each other and a shared
66
+ `_assets/` folder by relative path, so opening one file straight out of the zip breaks those links.
67
+ - `<project>-<rundate>-summary.html` -- a standalone, self-contained one-pager. Email it, double-click
68
+ it, or `Ctrl-P -> Save as PDF`; no unzip needed. (Its deep links into the reports only resolve when
69
+ the zip is shipped alongside.)
70
+
71
+ The zip DEFAULTS to **shared assets**: the ~95 KB of chrome (font + CSS + JS) lives once in `_assets/`
72
+ and every page links it, so a multi-run bundle is markedly smaller. Because the pages share that
73
+ folder, **no single page is portable on its own** -- keep the extracted folder together, or send the
74
+ standalone `summary.html` when you need just one file. `--inline` opts out and makes each page
75
+ self-contained (larger, but any single report file is portable). `--light` bundles only `index.html`
76
+ + the top-level reports (no drill pages or data) for a quick "read, don't drill" share.
77
+
78
+ ### Sharing externally -- `--redact`
79
+
80
+ `bobframes package <root> --redact` produces a bundle safe to hand to someone outside your team. It
81
+ scrubs the GPU / driver / CPU / OS + capture-tool versions from every page's device strip (replaced with
82
+ `redacted`), drops the raw provenance sidecars (`_manifest.json`, `frame_metadata.jsonl`) from the
83
+ bundle, and replaces absolute Windows paths (`C:\...`) with `<path redacted>` across the pages and the
84
+ downloadable CSVs. Redaction re-renders the tree, so `--inline --redact` is no longer a fast copy.
85
+
86
+ - `--redact-paths=strip` (default) -- replace the path tokens; the bundle stays usable on a real capture.
87
+ - `--redact-paths=fail` -- a CI completeness check: exit nonzero (don't write the zip) if any absolute
88
+ path remains in a rendered page, so a leak fails the build.
89
+
90
+ **Caveat:** the pages and the downloadable CSVs are sanitized, but the **binary `.parquet`** tables still
91
+ contain resource paths (they can't be string-edited safely) -- strip `_data/` if the parquet itself must
92
+ leave your team. UNC (`\\host\share`) and forward-slash (`C:/...`) paths are not auto-stripped.
93
+
94
+ ## Customizing reports
95
+
96
+ The look is shadcn-clean, neutral, and flat by default. Two ways to re-color it:
97
+
98
+ ### Pip installs -- re-hue without editing source (recommended)
99
+
100
+ `pip install bobframes` puts the design tokens in site-packages, where edits are lost on upgrade -- so
101
+ re-hue the accent / status / chart colors through the config cascade instead:
102
+
103
+ - **Persistent:** add a `[theme]` section to `.bobframes.toml` in your capture root (or
104
+ `%APPDATA%/bobframes/config.toml`). `bobframes export-tokens --theme-template` prints a ready-to-paste
105
+ starter with just the overridable color knobs.
106
+ - **One-shot:** `bobframes render . --accent '<oklch>'` (and `--accent-data '<oklch>'`) -- the top
107
+ precedence tier (CLI > env > config > bundled default). `bobframes preview --accent '<oklch>'` previews
108
+ it with no capture data.
109
+
110
+ Only color hues (accent, the four status colors, the draw-class + chart palette) are overridable; layout,
111
+ spacing, type, and the table engine stay bundled, so an override can never desync the rendering. A bad or
112
+ non-color value warns and is ignored. `--watch` live-reloads on `.bobframes.toml` edits too.
113
+
114
+ ### Source checkouts -- edit the bundled tokens
115
+
116
+ The full palette lives in `bobframes/reports/design_tokens.toml` (colors, spacing, type, motion, radius,
117
+ and base layout sizes). The CSS variable name is fixed by its key: `surface_0` becomes `--surface-0`,
118
+ `accent_primary` becomes `--accent-primary`.
119
+
120
+ ```
121
+ bobframes preview # writes _reports/_chrome_preview.html (every component, no data)
122
+ # edit a value in design_tokens.toml
123
+ bobframes preview # under a second; reload the page in a browser
124
+ bobframes render C:\captures # apply the change to real reports from existing Parquet
125
+ ```
126
+
127
+ `bobframes render --watch` re-runs render-only whenever `design_tokens.toml`, a chrome module, or
128
+ `.bobframes.toml` changes (alpha; a 500ms poll, no extra dependency). `bobframes export-tokens --format
129
+ css` prints the live `:root` block; `--format json` the nested table; `--format toml` the file itself.
130
+
131
+ ## External tools
132
+
133
+ The export stage runs `renderdoccmd convert`; the replay stage runs `qrenderdoc --python`. bobframes
134
+ resolves both from (in order) a config file (`.bobframes.toml`), version-globbed Arm Performance Studio
135
+ install paths, and `PATH`. Install RenderDoc / Arm Performance Studio anywhere on those, or point a
136
+ config entry at it. Run `bobframes check` to see what was resolved.
137
+
138
+ ## Output layout
139
+
140
+ ```
141
+ <root>/
142
+ index.html root catalog view
143
+ <area>/<drop>/ raw RDC inputs (left untouched)
144
+ _data/ pipeline outputs
145
+ _catalog.parquet (+ .csv, .json)
146
+ _global_entities.parquet (+ .csv)
147
+ _query_examples.md
148
+ <area>/<drop>/ per-drop data (29 Parquet tables)
149
+ *.parquet (+ matching .csv)
150
+ _manifest.json, _resource_labels.json
151
+ shader_src/*.glsl, jsonl sidecars
152
+ done.marker
153
+ _reports/ rendered HTML
154
+ *.html (dashboard + reports)
155
+ ab/<pair>/*.html
156
+ drill/<area>/<drop>/index.html per-drop browser
157
+ _cache/
158
+ ```
159
+
160
+ The catalog stores each drop's path relative to `<root>` for portability.
161
+
162
+ ## Migrating from `_analysis`
163
+
164
+ v1 is a hard rename of the older project-embedded `_analysis` package, with no compatibility shim:
165
+ `python -m _analysis.*` stops working once `bobframes` is installed. Map old invocations to new ones:
166
+
167
+ | Old (`_analysis`) | New (`bobframes`) |
168
+ |---|---|
169
+ | `python -m _analysis.run --root . --area X --label Y` | `bobframes ingest . --area X --label Y` |
170
+ | `python -m _analysis.reports.ab --root . --baseline-label X --compare-label Y` | `bobframes ab . --baseline-label X --compare-label Y` |
171
+ | `python -m _analysis.lint <file>` | `bobframes lint <file>` |
172
+ | `python -m _analysis.tests.smoke` | `bobframes smoke` |
173
+
174
+ ## Troubleshooting
175
+
176
+ | Symptom | Resolution |
177
+ |---|---|
178
+ | `renderdoccmd not found` (exit 3) | Install RenderDoc or Arm Performance Studio, or put the executable on `PATH`; confirm with `bobframes check`. |
179
+ | `qrenderdoc` replay hangs | v1 kills the replay process tree on timeout and records `capture_status='replay_failed'` for that capture; the rest of the drop still completes. Re-run with `--force` to retry. |
180
+ | Lint failure during render | The emitted HTML contains a banned token. Run `bobframes lint <file>` to see the line and label. |
181
+ | `schema mismatch` (exit 1) | A drop's `_manifest.json` schema version differs from the installed schema. Rebuild it with `bobframes ingest --force` (the v1 schema-migration path; see G-3). |
182
+ | Permission denied on `_data` | Close any viewer holding a Parquet open, then re-run; writes are staged and renamed atomically. |
183
+
184
+ ## Advanced
185
+
186
+ - A/B reports: `bobframes ab . --baseline-label OLD --compare-label NEW` builds a side-by-side set.
187
+ - Programmatic use: import `bobframes.schemas`, `bobframes.discovery`, and `bobframes.paths` to drive
188
+ table lookups, drop discovery, and path resolution from your own scripts.
189
+ - `bobframes/probes/whatif.py` is a manual qrenderdoc-side probe and is not wired as a CLI command.
190
+ - TOML config (`.bobframes.toml`), an externalized draw classifier, and design-token theming
191
+ (`[theme]` / `--accent`) shipped in v0.2.6. `bobframes package` produces shareable, optionally
192
+ redacted bundles (see [Sharing a report](#sharing-a-report)).
193
+
194
+ ## Built for Mayhem Studios
195
+
196
+ BobFrames is built and maintained for **Mayhem Studios** -- it powers the studio's GPU
197
+ capture-analysis and frame-performance work, and is open-sourced here for the wider RenderDoc and
198
+ graphics community.
199
+
200
+ If BobFrames helps your work, please **support Mayhem Studios** -- the studio that makes this tool
201
+ possible. Follow the studio, play and wishlist our games, and tell a friend who fights frame times.
202
+ A on the [GitHub repo](https://github.com/altpsyche/bobframes) helps too. Thank you.
203
+
204
+ ## License
205
+
206
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,61 @@
1
+ # bobframes bundled default config (c07). Single source of truth for de-hardcoded literals.
2
+ # Values here reproduce today's output byte-identically (ADR-6). A user .bobframes.toml is
3
+ # deep-merged ON TOP of this (override one key without restating the rest — ADR-25).
4
+ #
5
+ # Regex / format-string values MUST be TOML *literal* (single-quoted) strings: a basic
6
+ # (double-quoted) string interprets backslash escapes and breaks on \d. Do NOT "fix" a decode
7
+ # error by double-escaping — that silently changes the pattern (ADR-23 trap).
8
+
9
+ schema_version = 1
10
+
11
+ [tools]
12
+ # renderdoccmd = "..." # unset by default; resolve_tool falls through to PATH / known paths
13
+ # qrenderdoc = "..."
14
+
15
+ [pipeline]
16
+ replay_timeout_s = 600.0 # H-12 — per-capture qrenderdoc replay budget (seconds)
17
+ convert_timeout_s = 120.0 # H-13 — per-file renderdoccmd convert budget (seconds)
18
+ # workers / pixel_grid / keep_stage are §6 keys but NOT wired in c07 (argparse remains the
19
+ # source; workers default is min(4, os.cpu_count()), so wiring it would change behavior).
20
+
21
+ [discovery]
22
+ dated_re = '^(\d{4}-\d{2}-\d{2})(?:_(.*))?$' # H-30 — dated drop-folder pattern
23
+
24
+ [formatting]
25
+ id_short_n = 12 # H-23 — id/hash truncation length
26
+ text_trunc_max = 60 # H-23 — mid/left text truncation length
27
+ chrome_scrub_chars = '[—–…“”‘’→←↑↓×·]' # H-16 — chars scrubbed from rendered chrome
28
+
29
+ [delta]
30
+ fmt = '{:+,.0f}' # H-22 — default signed delta format
31
+ bar_label_min_pct = 8.0 # H-21 — min segment % to draw an inline label
32
+
33
+ [scoring.complexity] # H-17 / Q-3 — shader complexity_score weights
34
+ w_texture_samples = 2.0
35
+ w_branches = 0.5
36
+ w_loops = 2.0
37
+ w_discards = 0.3
38
+ w_dfdx_dfdy = 0.5
39
+ w_mat4 = 0.3
40
+ src_len_divisor = 100.0
41
+ src_len_cap = 50.0
42
+
43
+ [lint]
44
+ # User-appended banned tokens, same shape as lint_banlist.toml [[banned]] entries:
45
+ # [[lint.extra_banned]]
46
+ # pattern = 'foo'
47
+ # label = 'why'
48
+ # flags = ['I']
49
+ extra_banned = []
50
+
51
+ [classifier] # c09 — draw-classification preset (H-1..H-5)
52
+ preset = "ue" # draw_classifier.toml (UE default); "unity"/"godot"/... -> presets/<name>.toml
53
+ # custom_path = "C:/path/to/my_engine.toml" # absolute path to a custom preset (wins over `preset`)
54
+
55
+ [report] # c16 — thresholds that drive report callout severity. Tune per project.
56
+ shader_complexity_high = 60.0 # fragment shaders at/above this complexity are flagged
57
+ overdraw_reject_warn_pct = 40.0 # RT sample-rejection % -> warn callout
58
+ overdraw_reject_alarm_pct = 70.0 # RT sample-rejection % -> alarm callout
59
+ instancing_repeat_min = 4 # min mesh repeat PER FRAME to flag an instancing candidate (c16v: repeat + shader cost are per-frame rates, normalized by the drop's captured-frame count)
60
+ gpu_regression_pct = 10.0 # latest-vs-previous GPU increase % -> regression callout
61
+ max_prerendered_runs = 10 # c16f — cap on pre-rendered older-run pages (run selector)
@@ -0,0 +1 @@
1
+ __version__ = "0.2.6"