hyperweave 0.3.8__tar.gz → 0.3.9__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 (437) hide show
  1. {hyperweave-0.3.8 → hyperweave-0.3.9}/.gitignore +4 -0
  2. {hyperweave-0.3.8 → hyperweave-0.3.9}/CHANGELOG.md +26 -0
  3. {hyperweave-0.3.8 → hyperweave-0.3.9}/PKG-INFO +6 -2
  4. {hyperweave-0.3.8 → hyperweave-0.3.9}/README.md +5 -1
  5. {hyperweave-0.3.8 → hyperweave-0.3.9}/justfile +7 -3
  6. {hyperweave-0.3.8 → hyperweave-0.3.9}/scripts/extract_font_metrics.py +122 -20
  7. hyperweave-0.3.9/scripts/generate_proofset.py +4588 -0
  8. hyperweave-0.3.9/scripts/proofset_harness.py +287 -0
  9. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/_version.py +2 -2
  10. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/cli.py +1 -1
  11. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/assembler.py +12 -1
  12. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/context.py +27 -5
  13. hyperweave-0.3.9/src/hyperweave/compose/layout.py +831 -0
  14. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/resolver.py +251 -159
  15. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/resolvers/chart.py +13 -1
  16. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/resolvers/stats.py +227 -3
  17. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/connectors/base.py +6 -0
  18. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/connectors/rest.py +5 -1
  19. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/font_metrics.py +15 -0
  20. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/paradigm.py +171 -4
  21. hyperweave-0.3.9/src/hyperweave/core/text.py +196 -0
  22. hyperweave-0.3.9/src/hyperweave/data/font-metrics/barlow-condensed-900.json +1934 -0
  23. hyperweave-0.3.9/src/hyperweave/data/font-metrics/chakra-petch.json +1933 -0
  24. hyperweave-0.3.9/src/hyperweave/data/font-metrics/jetbrains-mono.json +495 -0
  25. hyperweave-0.3.9/src/hyperweave/data/font-metrics/orbitron.json +2386 -0
  26. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/genomes/chrome.json +0 -10
  27. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/paradigms/brutalist.yaml +43 -9
  28. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/paradigms/cellular.yaml +48 -3
  29. hyperweave-0.3.9/src/hyperweave/data/paradigms/chrome.yaml +167 -0
  30. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/mcp/server.py +5 -3
  31. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/render/chart_engine.py +233 -66
  32. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-markers/endpoint-diamond.svg.j2 +1 -1
  33. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/glyph-inline.svg.j2 +3 -2
  34. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/brutalist-dark-content.j2 +2 -2
  35. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/brutalist-light-content.j2 +2 -2
  36. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/cellular-content.j2 +2 -2
  37. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/chrome-content.j2 +19 -8
  38. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/chrome-defs.j2 +3 -3
  39. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/brutalist-dark-content.j2 +1 -1
  40. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/brutalist-defs.j2 +2 -2
  41. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/cellular-content.j2 +9 -10
  42. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/cellular-defs.j2 +1 -1
  43. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/chrome-content.j2 +6 -3
  44. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/chrome-defs.j2 +26 -7
  45. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/cellular-content.j2 +1 -1
  46. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/cellular-content.j2 +1 -1
  47. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/brutalist-dark-content.j2 +7 -3
  48. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/brutalist-light-content.j2 +6 -3
  49. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/cellular-content.j2 +29 -26
  50. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/cellular-defs.j2 +1 -1
  51. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/chrome-content.j2 +6 -2
  52. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/chrome-defs.j2 +2 -2
  53. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/brutalist-dark-content.j2 +18 -5
  54. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/brutalist-light-content.j2 +14 -5
  55. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/cellular-content.j2 +2 -2
  56. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/chrome-content.j2 +9 -5
  57. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/chrome-defs.j2 +5 -5
  58. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip.svg.j2 +35 -63
  59. hyperweave-0.3.9/tests/fixtures/proofset_data.json +811 -0
  60. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/snapshots/url_stability/divider_band_chrome_static.svg +0 -19
  61. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/snapshots/url_stability/icon_github_chrome_static.svg +0 -19
  62. hyperweave-0.3.9/tests/test_algorithmic_geometry.py +455 -0
  63. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_assembler.py +42 -0
  64. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_badge_cellular.py +9 -8
  65. hyperweave-0.3.9/tests/test_badge_layout.py +356 -0
  66. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_chart_engine.py +64 -11
  67. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_font_gating.py +2 -3
  68. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_font_metrics_chakra.py +30 -7
  69. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_marquee_v0_2_16.py +10 -8
  70. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_mcp.py +9 -0
  71. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_paradigm_cellular.py +2 -1
  72. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_proofset.py +47 -30
  73. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_strip_brutalist_grammar.py +59 -19
  74. hyperweave-0.3.9/tests/test_strip_invariance.py +280 -0
  75. {hyperweave-0.3.8 → hyperweave-0.3.9}/uv.lock +4 -0
  76. hyperweave-0.3.8/hooks/session_end.sh +0 -6
  77. hyperweave-0.3.8/scripts/generate_proofset.py +0 -1722
  78. hyperweave-0.3.8/src/hyperweave/compose/layout.py +0 -353
  79. hyperweave-0.3.8/src/hyperweave/core/text.py +0 -65
  80. hyperweave-0.3.8/src/hyperweave/data/font-metrics/chakra-petch.json +0 -110
  81. hyperweave-0.3.8/src/hyperweave/data/font-metrics/jetbrains-mono.json +0 -113
  82. hyperweave-0.3.8/src/hyperweave/data/font-metrics/orbitron.json +0 -108
  83. hyperweave-0.3.8/src/hyperweave/data/paradigms/chrome.yaml +0 -100
  84. hyperweave-0.3.8/tests/test_badge_layout.py +0 -301
  85. {hyperweave-0.3.8 → hyperweave-0.3.9}/.dockerignore +0 -0
  86. {hyperweave-0.3.8 → hyperweave-0.3.9}/.github/workflows/ci.yml +0 -0
  87. {hyperweave-0.3.8 → hyperweave-0.3.9}/.github/workflows/deploy.yml +0 -0
  88. {hyperweave-0.3.8 → hyperweave-0.3.9}/.github/workflows/publish.yml +0 -0
  89. {hyperweave-0.3.8 → hyperweave-0.3.9}/.pre-commit-config.yaml +0 -0
  90. {hyperweave-0.3.8 → hyperweave-0.3.9}/Dockerfile +0 -0
  91. {hyperweave-0.3.8 → hyperweave-0.3.9}/LICENSE +0 -0
  92. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/buttons/button-liquid.svg +0 -0
  93. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/cards/card-butterfly.svg +0 -0
  94. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/cards/card-python.svg +0 -0
  95. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/cards/card-sunflower.svg +0 -0
  96. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/cards/card-waves.svg +0 -0
  97. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/badge_critical.svg +0 -0
  98. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/badge_passing.svg +0 -0
  99. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/badge_warning.svg +0 -0
  100. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/banner.svg +0 -0
  101. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/icons/discord.svg +0 -0
  102. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/icons/notion.svg +0 -0
  103. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/icons/reddit.svg +0 -0
  104. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/icons/spotify.svg +0 -0
  105. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/icons/youtube.svg +0 -0
  106. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/marquee_counter.svg +0 -0
  107. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/marquee_horizontal.svg +0 -0
  108. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/marquee_vertical.svg +0 -0
  109. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/profile-cards/chart_stars_full.svg +0 -0
  110. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/profile-cards/stats.svg +0 -0
  111. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/brutalist-emerald/strip.svg +0 -0
  112. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/badge_critical.svg +0 -0
  113. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/badge_passing.svg +0 -0
  114. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/badge_warning.svg +0 -0
  115. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/banner.svg +0 -0
  116. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/icons/bluesky.svg +0 -0
  117. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/icons/github.svg +0 -0
  118. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/icons/instagram.svg +0 -0
  119. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/icons/mastodon.svg +0 -0
  120. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/icons/x.svg +0 -0
  121. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/marquee_counter.svg +0 -0
  122. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/marquee_horizontal.svg +0 -0
  123. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/marquee_vertical.svg +0 -0
  124. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/profile-cards/chart_stars_full.svg +0 -0
  125. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/profile-cards/stats.svg +0 -0
  126. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/chrome-horizon/strip.svg +0 -0
  127. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/telemetry/master_card.svg +0 -0
  128. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/telemetry/receipt.svg +0 -0
  129. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/telemetry/receipt_claude-code_medium.svg +0 -0
  130. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/telemetry/receipt_codex_large.svg +0 -0
  131. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/telemetry/receipt_voltage_xlarge.svg +0 -0
  132. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/telemetry/rhythm_strip.svg +0 -0
  133. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/examples/telemetry/rhythm_strip_voltage_xlarge.svg +0 -0
  134. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/footers/inneraura-footer-liquid.svg +0 -0
  135. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/footers/inneraura-footer-purple.svg +0 -0
  136. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/footers/inneraura-footer.svg +0 -0
  137. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/hyperweave-banner.svg +0 -0
  138. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-discord.svg +0 -0
  139. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-docs.svg +0 -0
  140. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-github.svg +0 -0
  141. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-instagram.svg +0 -0
  142. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-linkedin.svg +0 -0
  143. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-tiktok.svg +0 -0
  144. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-x.svg +0 -0
  145. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/icons/cobalt-sapphire-youtube.svg +0 -0
  146. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/marquees/badge-showcase-triple.svg +0 -0
  147. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/marquees/genome-marquee-triple.svg +0 -0
  148. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/marquees/sample-badges.svg +0 -0
  149. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/404.svg +0 -0
  150. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/callout-icons.svg +0 -0
  151. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/divider.svg +0 -0
  152. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/favicon.svg +0 -0
  153. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/hero-banner.svg +0 -0
  154. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/hyperweave-banner-v2.svg +0 -0
  155. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/hyperweave-navbar-logo.svg +0 -0
  156. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/loader.svg +0 -0
  157. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/mintlify-assets/og-image.svg +0 -0
  158. {hyperweave-0.3.8 → hyperweave-0.3.9}/assets/timelines/hyperweave-roadmap.svg +0 -0
  159. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/assets/favicon.svg +0 -0
  160. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/assets/hyperweave-banner.svg +0 -0
  161. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/assets/hyperweave-navbar-logo.svg +0 -0
  162. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/assets/og-image.svg +0 -0
  163. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/explanation/architecture.mdx +0 -0
  164. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/explanation/camo-compatibility.mdx +0 -0
  165. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/explanation/cim-compliance.mdx +0 -0
  166. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/explanation/genome-profile-system.mdx +0 -0
  167. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/explanation/metadata-tiers.mdx +0 -0
  168. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/how-to/add-motion-to-badges.mdx +0 -0
  169. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/how-to/create-session-receipts.mdx +0 -0
  170. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/how-to/set-up-claude-code-hooks.mdx +0 -0
  171. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/how-to/use-live-data-badges.mdx +0 -0
  172. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/introduction.mdx +0 -0
  173. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/mint.json +0 -0
  174. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/quickstart.mdx +0 -0
  175. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/reference/cli.mdx +0 -0
  176. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/reference/compose-spec.mdx +0 -0
  177. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/reference/genomes.mdx +0 -0
  178. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/reference/http-api.mdx +0 -0
  179. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/reference/mcp-tools.mdx +0 -0
  180. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/reference/motions.mdx +0 -0
  181. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/reference/telemetry-contract.mdx +0 -0
  182. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/spec/hyperweave-protocol.mdx +0 -0
  183. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/tutorials/build-an-artifact-kit.mdx +0 -0
  184. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/tutorials/compose-your-first-badge.mdx +0 -0
  185. {hyperweave-0.3.8 → hyperweave-0.3.9}/docs/tutorials/install-session-telemetry.mdx +0 -0
  186. {hyperweave-0.3.8 → hyperweave-0.3.9}/fly.toml +0 -0
  187. {hyperweave-0.3.8 → hyperweave-0.3.9}/hooks/install.py +0 -0
  188. {hyperweave-0.3.8 → hyperweave-0.3.9}/pyproject.toml +0 -0
  189. {hyperweave-0.3.8 → hyperweave-0.3.9}/scripts/extract_glyphs.py +0 -0
  190. {hyperweave-0.3.8 → hyperweave-0.3.9}/scripts/probe_live_stats.py +0 -0
  191. {hyperweave-0.3.8 → hyperweave-0.3.9}/scripts/probe_star_history.py +0 -0
  192. {hyperweave-0.3.8 → hyperweave-0.3.9}/scripts/stress_test.py +0 -0
  193. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/__init__.py +0 -0
  194. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/__main__.py +0 -0
  195. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/__init__.py +0 -0
  196. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/bar_chart.py +0 -0
  197. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/engine.py +0 -0
  198. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/lanes.py +0 -0
  199. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/palette.py +0 -0
  200. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/reasoning.py +0 -0
  201. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/resolvers/__init__.py +0 -0
  202. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/rhythm.py +0 -0
  203. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/rhythm_strip.py +0 -0
  204. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/treemap.py +0 -0
  205. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/compose/validate_paradigms.py +0 -0
  206. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/config/__init__.py +0 -0
  207. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/config/genome_validator.py +0 -0
  208. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/config/loader.py +0 -0
  209. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/config/registry.py +0 -0
  210. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/config/settings.py +0 -0
  211. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/connectors/__init__.py +0 -0
  212. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/connectors/arxiv.py +0 -0
  213. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/connectors/cache.py +0 -0
  214. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/connectors/github.py +0 -0
  215. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/__init__.py +0 -0
  216. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/cell_layout.py +0 -0
  217. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/color.py +0 -0
  218. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/contracts.py +0 -0
  219. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/enums.py +0 -0
  220. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/models.py +0 -0
  221. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/schema.py +0 -0
  222. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/state.py +0 -0
  223. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/core/thresholds.py +0 -0
  224. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/badge_modes.yaml +0 -0
  225. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/css/accessibility.css +0 -0
  226. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/css/bridge.css +0 -0
  227. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/css/expression.css +0 -0
  228. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/css/status.css +0 -0
  229. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/font-embedding.yaml +0 -0
  230. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/font-metrics/inter.json +0 -0
  231. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/barlow-condensed-700.b64 +0 -0
  232. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/barlow-condensed-700.meta.json +0 -0
  233. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/barlow-condensed-900.b64 +0 -0
  234. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/barlow-condensed-900.meta.json +0 -0
  235. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/chakra-petch.b64 +0 -0
  236. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/chakra-petch.meta.json +0 -0
  237. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/jetbrains-mono.b64 +0 -0
  238. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/jetbrains-mono.meta.json +0 -0
  239. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/orbitron.b64 +0 -0
  240. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/fonts/orbitron.meta.json +0 -0
  241. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/genomes/automata.json +0 -0
  242. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/genomes/brutalist.json +0 -0
  243. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/genomes/telemetry-claude-code.json +0 -0
  244. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/genomes/telemetry-codex.json +0 -0
  245. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/genomes/telemetry-cream.json +0 -0
  246. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/genomes/telemetry-voltage.json +0 -0
  247. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/glyphs.json +0 -0
  248. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/motions/border/chromatic-pulse.yaml +0 -0
  249. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/motions/border/corner-trace.yaml +0 -0
  250. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/motions/border/dual-orbit.yaml +0 -0
  251. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/motions/border/entanglement.yaml +0 -0
  252. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/motions/border/rimrun.yaml +0 -0
  253. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/motions/static.yaml +0 -0
  254. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/paradigms/default.yaml +0 -0
  255. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/policies/normal.json +0 -0
  256. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/policies/permissive.json +0 -0
  257. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/policies/ungoverned.json +0 -0
  258. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/profiles/brutalist.contract.json +0 -0
  259. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/profiles/brutalist.yaml +0 -0
  260. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/profiles/chrome.contract.json +0 -0
  261. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/profiles/chrome.yaml +0 -0
  262. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/reasoning/__init__.py +0 -0
  263. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/reasoning/brutalist.yaml +0 -0
  264. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/specimens.yaml +0 -0
  265. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/telemetry/model-pricing.yaml +0 -0
  266. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/telemetry/runtimes/claude-code.yaml +0 -0
  267. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/telemetry/runtimes/codex.yaml +0 -0
  268. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/telemetry/stage-config.yaml +0 -0
  269. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/telemetry/stage-labels.yaml +0 -0
  270. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/telemetry/tool-colors.yaml +0 -0
  271. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/arrow.json +0 -0
  272. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/aurora.json +0 -0
  273. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/beacon.json +0 -0
  274. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/bracket3d.json +0 -0
  275. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/chevron.json +0 -0
  276. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/crosshair.json +0 -0
  277. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/diamond.json +0 -0
  278. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/rocket.json +0 -0
  279. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/rules/bar.json +0 -0
  280. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/rules/dashed.json +0 -0
  281. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/rules/five-wave.json +0 -0
  282. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/rules/spectral.json +0 -0
  283. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/rules/straight.json +0 -0
  284. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/rules/wave.json +0 -0
  285. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/data/terminals/stijl.json +0 -0
  286. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/kit.py +0 -0
  287. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/mcp/__init__.py +0 -0
  288. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/mcp/__main__.py +0 -0
  289. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/py.typed +0 -0
  290. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/render/__init__.py +0 -0
  291. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/render/fonts.py +0 -0
  292. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/render/glyphs.py +0 -0
  293. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/render/motion.py +0 -0
  294. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/render/templates.py +0 -0
  295. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/serve/__init__.py +0 -0
  296. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/serve/app.py +0 -0
  297. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/serve/data_tokens.py +0 -0
  298. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/__init__.py +0 -0
  299. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/capture.py +0 -0
  300. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/codex_parser.py +0 -0
  301. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/contract.py +0 -0
  302. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/corrections.py +0 -0
  303. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/cost.py +0 -0
  304. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/models.py +0 -0
  305. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/parser.py +0 -0
  306. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/receipt_paths.py +0 -0
  307. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/runtimes.py +0 -0
  308. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/telemetry/stages.py +0 -0
  309. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-area.svg.j2 +0 -0
  310. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-axes.svg.j2 +0 -0
  311. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-empty-state.svg.j2 +0 -0
  312. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-gridlines.svg.j2 +0 -0
  313. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-markers/circle.svg.j2 +0 -0
  314. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-markers/diamond.svg.j2 +0 -0
  315. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-markers/endpoint-rect.svg.j2 +0 -0
  316. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-markers/rect.svg.j2 +0 -0
  317. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-milestone-brutalist.svg.j2 +0 -0
  318. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-milestone.svg.j2 +0 -0
  319. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/chart-polyline.svg.j2 +0 -0
  320. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/filter.svg.j2 +0 -0
  321. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/glyph.svg.j2 +0 -0
  322. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/gradient.svg.j2 +0 -0
  323. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/metadata.svg.j2 +0 -0
  324. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/metric.svg.j2 +0 -0
  325. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/phase-segment.svg.j2 +0 -0
  326. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/rule.svg.j2 +0 -0
  327. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/status.svg.j2 +0 -0
  328. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/components/terminal.svg.j2 +0 -0
  329. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/document.svg.j2 +0 -0
  330. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/error-badge.svg.j2 +0 -0
  331. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/brutalist-content.j2 +0 -0
  332. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +0 -0
  333. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/cellular-defs.j2 +0 -0
  334. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/default-content.j2 +0 -0
  335. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge/default-defs.j2 +0 -0
  336. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/badge.svg.j2 +0 -0
  337. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/catalog.svg.j2 +0 -0
  338. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/brutalist-content.j2 +0 -0
  339. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart/brutalist-light-content.j2 +0 -0
  340. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/chart.svg.j2 +0 -0
  341. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/divider/brutalist-seam.svg.j2 +0 -0
  342. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/divider/chrome-band.svg.j2 +0 -0
  343. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/divider.svg.j2 +0 -0
  344. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/brutalist-content.j2 +0 -0
  345. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/brutalist-defs.j2 +0 -0
  346. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/cellular-defs.j2 +0 -0
  347. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/chrome-content.j2 +0 -0
  348. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/chrome-defs.j2 +0 -0
  349. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/default-content.j2 +0 -0
  350. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon/default-defs.j2 +0 -0
  351. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/icon.svg.j2 +0 -0
  352. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-content.j2 +0 -0
  353. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-defs.j2 +0 -0
  354. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-overlay.j2 +0 -0
  355. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/cellular-defs.j2 +0 -0
  356. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/cellular-overlay.j2 +0 -0
  357. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/chrome-content.j2 +0 -0
  358. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/chrome-defs.j2 +0 -0
  359. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/chrome-overlay.j2 +0 -0
  360. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/default-content.j2 +0 -0
  361. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal/default-defs.j2 +0 -0
  362. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/marquee-horizontal.svg.j2 +0 -0
  363. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/master-card.svg.j2 +0 -0
  364. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/receipt.svg.j2 +0 -0
  365. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/rhythm-strip.svg.j2 +0 -0
  366. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/brutalist-content.j2 +0 -0
  367. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats/brutalist-defs.j2 +0 -0
  368. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/stats.svg.j2 +0 -0
  369. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/brutalist-content.j2 +0 -0
  370. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/brutalist-defs.j2 +0 -0
  371. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/brutalist-status.j2 +0 -0
  372. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/cellular-defs.j2 +0 -0
  373. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/cellular-status.j2 +0 -0
  374. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/chrome-status.j2 +0 -0
  375. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/default-content.j2 +0 -0
  376. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/default-defs.j2 +0 -0
  377. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/frames/strip/default-status.j2 +0 -0
  378. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/motions/border/chromatic-pulse.svg.j2 +0 -0
  379. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/motions/border/corner-trace.svg.j2 +0 -0
  380. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/motions/border/dual-orbit.svg.j2 +0 -0
  381. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/motions/border/entanglement.svg.j2 +0 -0
  382. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/motions/border/rimrun.svg.j2 +0 -0
  383. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/partials/provider-glyphs.svg.j2 +0 -0
  384. {hyperweave-0.3.8 → hyperweave-0.3.9}/src/hyperweave/templates/partials/state-signal-cascade.j2 +0 -0
  385. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/__init__.py +0 -0
  386. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/conftest.py +0 -0
  387. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/fixtures/codex_session.jsonl +0 -0
  388. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/fixtures/codex_session_patches.jsonl +0 -0
  389. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/fixtures/github_contributions/synthetic.html +0 -0
  390. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/fixtures/session.json +0 -0
  391. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/fixtures/session.jsonl +0 -0
  392. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/fixtures/synthetic_session.jsonl +0 -0
  393. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/helpers.py +0 -0
  394. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_badge_brutalist_dark.py +0 -0
  395. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_badge_mode.py +0 -0
  396. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_chart_frame.py +0 -0
  397. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_chromatic_coverage_validator.py +0 -0
  398. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_chrome_variants.py +0 -0
  399. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_codex_parser.py +0 -0
  400. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_compose_bar_chart.py +0 -0
  401. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_compose_rhythm_strip.py +0 -0
  402. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_compose_treemap.py +0 -0
  403. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_compose_variant_field.py +0 -0
  404. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_connectors.py +0 -0
  405. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_core.py +0 -0
  406. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_data_tokens.py +0 -0
  407. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_divider_cellular.py +0 -0
  408. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_divider_genome_specific.py +0 -0
  409. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_doctor.py +0 -0
  410. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_font_subsetting.py +0 -0
  411. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_genome_automata.py +0 -0
  412. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_github_scrape.py +0 -0
  413. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_install_hook.py +0 -0
  414. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_kit.py +0 -0
  415. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_paradigm_dispatch.py +0 -0
  416. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_paradigm_extensibility.py +0 -0
  417. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_parse_transcript_auto.py +0 -0
  418. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_receipt_paths.py +0 -0
  419. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_receipt_token_compliance.py +0 -0
  420. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_render.py +0 -0
  421. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_resolver_rhythm.py +0 -0
  422. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_runtime_registries.py +0 -0
  423. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_serve.py +0 -0
  424. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_serve_live_state.py +0 -0
  425. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_slot_metric_state.py +0 -0
  426. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_state_inference.py +0 -0
  427. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_stats_brutalist.py +0 -0
  428. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_stats_card.py +0 -0
  429. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_strip_cellular.py +0 -0
  430. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_strip_status_toggle.py +0 -0
  431. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_telemetry.py +0 -0
  432. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_telemetry_contract_per_stage.py +0 -0
  433. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_telemetry_integration.py +0 -0
  434. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_telemetry_skin_dispatch.py +0 -0
  435. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_tool_class_completeness.py +0 -0
  436. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_url_stability.py +0 -0
  437. {hyperweave-0.3.8 → hyperweave-0.3.9}/tests/test_variant_default_resolution.py +0 -0
@@ -36,3 +36,7 @@ assets/cards/cards-2x2-v2.svg
36
36
  assets/cards/cards-2x2-v3.svg
37
37
  assets/cards/cards-2x2.svg
38
38
  assets/cards/halftone-card-triangle.svg
39
+ assets/demos/
40
+ scripts/analyze_audio.py
41
+ scripts/generate_demo_charts.py
42
+ scripts/render_demo_video.py
@@ -5,6 +5,32 @@ All notable changes to HyperWeave are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.3.9] - 2026-05-22
9
+
10
+ Badge, strip, stat card, and star chart frames now measure rendered content before placing text, glyphs, seams, and markers. Chrome, brutalist, and automata outputs share more consistent typography, spacing, and variant colors across frame types.
11
+
12
+ ### Fixed
13
+
14
+ - **Badges** — Missing glyph/status zones collapse, provider glyphs align to text, and long chrome status labels keep even padding.
15
+ - **Chrome frames** — Badge, strip, stat card, and chart identity slots share Orbitron typography and variant glyph color.
16
+ - **Font metrics** — Chakra Petch and Barlow Condensed now use real per-weight advance widths instead of scalar bold expansion.
17
+ - **Stats cards** — Header identity, bio text, metric slots, and language footer placement measure content before positioning.
18
+ - **Star charts** — Date labels use even calendar spacing, milestone labels avoid collisions, and chrome markers use variant color instead of fixed green.
19
+ - **Strips** — Metric cells and identity zones adapt to measured labels, values, subtitles, and glyph presence.
20
+ - **Connectors** — npm download metrics use the public stats endpoint.
21
+
22
+ ### Added
23
+
24
+ - **Font metrics** — Per-weight measurements and visible text bounds for Orbitron, JetBrains Mono, Chakra Petch, and Barlow Condensed.
25
+ - **Render checks** — Direct, HTTP, and MCP outputs are compared across the release matrix.
26
+
27
+ ### Changed
28
+
29
+ - **Automata help text** — MCP help now lists all 16 automata tones.
30
+ - **Automata badges** — Default badge output now uses the compact 20px form; explicit larger requests still use the 32px form.
31
+ - **Strip rendering** — Identity glyph, icon box, divider, and status coordinates now flow from resolver context.
32
+ - **Release tooling** — `just tag` accepts versions with or without the leading `v` and refreshes package version metadata after tagging.
33
+
8
34
  ## [0.3.8] - 2026-05-19
9
35
 
10
36
  Every artifact request now emits one greppable `HW_REQUEST` access-log line to stdout, so Fly.io's log stream reveals which GitHub repos embed HyperWeave SVGs via Camo's referer header. Health and metrics probes stay silent so 30-second checks don't drown the signal.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperweave
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: Headless visual output layer for AI agents. One API call → self-contained SVG.
5
5
  Project-URL: Repository, https://github.com/InnerAura/hyperweave
6
6
  Project-URL: Issues, https://github.com/InnerAura/hyperweave/issues
@@ -57,6 +57,10 @@ Description-Content-Type: text/markdown
57
57
  </p>
58
58
 
59
59
  <!--
60
+ AI agents need to explain what they did, what they found, and what changed — HyperWeave gives them a visual language that works anywhere.
61
+
62
+ ---
63
+
60
64
  A brand agent for repos.
61
65
  Generate a cohesive visual identity layer for README, profile, status, and releases — automatically.
62
66
 
@@ -730,7 +734,7 @@ Every artifact ships with:
730
734
  | Glyphs | 99 (93 Simple Icons + 6 geometric) |
731
735
  | Divider variants | 8 &mdash; 3 genome-themed (`band` chrome, `seam` brutalist, `dissolve` automata) + 5 genome-agnostic (`block`, `current`, `takeoff`, `void`, `zeropoint`) at <code>/a/inneraura/dividers/</code> |
732
736
  | Metadata tiers | 5 (Tier 0 silent &rarr; Tier 4 reasoning) |
733
- | Bundled fonts | 3 (JetBrains Mono, Orbitron, Chakra Petch — base64-embedded) |
737
+ | Bundled fonts | 4 families / 5 weights (JetBrains Mono, Orbitron, Chakra Petch, Barlow Condensed 700/900 — base64-embedded) |
734
738
 
735
739
  Stack: Pydantic, FastAPI, FastMCP v3, Jinja2, Typer.
736
740
 
@@ -23,6 +23,10 @@
23
23
  </p>
24
24
 
25
25
  <!--
26
+ AI agents need to explain what they did, what they found, and what changed — HyperWeave gives them a visual language that works anywhere.
27
+
28
+ ---
29
+
26
30
  A brand agent for repos.
27
31
  Generate a cohesive visual identity layer for README, profile, status, and releases — automatically.
28
32
 
@@ -696,7 +700,7 @@ Every artifact ships with:
696
700
  | Glyphs | 99 (93 Simple Icons + 6 geometric) |
697
701
  | Divider variants | 8 &mdash; 3 genome-themed (`band` chrome, `seam` brutalist, `dissolve` automata) + 5 genome-agnostic (`block`, `current`, `takeoff`, `void`, `zeropoint`) at <code>/a/inneraura/dividers/</code> |
698
702
  | Metadata tiers | 5 (Tier 0 silent &rarr; Tier 4 reasoning) |
699
- | Bundled fonts | 3 (JetBrains Mono, Orbitron, Chakra Petch — base64-embedded) |
703
+ | Bundled fonts | 4 families / 5 weights (JetBrains Mono, Orbitron, Chakra Petch, Barlow Condensed 700/900 — base64-embedded) |
700
704
 
701
705
  Stack: Pydantic, FastAPI, FastMCP v3, Jinja2, Typer.
702
706
 
@@ -54,7 +54,11 @@ version-refresh:
54
54
  @uv run python -c "import hyperweave; print(f'_version.py refreshed to {hyperweave.__version__}')"
55
55
 
56
56
  tag VERSION MESSAGE:
57
- git tag -a {{VERSION}} -m "{{MESSAGE}}"
57
+ #!/usr/bin/env bash
58
+ set -euo pipefail
59
+ VER="{{VERSION}}"
60
+ [[ "$VER" == v* ]] || VER="v$VER"
61
+ git tag -a "$VER" -m "{{MESSAGE}}"
58
62
  just version-refresh
59
- @echo ""
60
- @echo "Tagged {{VERSION}}. Push with: git push --follow-tags"
63
+ echo ""
64
+ echo "Tagged $VER. Push with: git push --follow-tags"
@@ -12,7 +12,7 @@ reads its ``hmtx`` table via ``fontTools``, and emits a JSON file at
12
12
  "font_family": "Orbitron",
13
13
  "baseline_size_px": 20,
14
14
  "units": "tenths_of_pixels",
15
- "bold_expansion_factor": 1.06,
15
+ "bold_expansion_factor": 1.0,
16
16
  "fallback_width": 110,
17
17
  "widths": { " ": 78, "A": 145, ... }
18
18
  }
@@ -38,7 +38,9 @@ import sys
38
38
  from io import BytesIO
39
39
  from pathlib import Path
40
40
 
41
+ from fontTools.pens.boundsPen import BoundsPen
41
42
  from fontTools.ttLib import TTFont
43
+ from fontTools.varLib.instancer import instantiateVariableFont
42
44
 
43
45
  ROOT = Path(__file__).resolve().parent.parent
44
46
  FONTS_DIR = ROOT / "src" / "hyperweave" / "data" / "fonts"
@@ -54,28 +56,61 @@ def load_font_from_b64(path: Path) -> TTFont:
54
56
  return TTFont(BytesIO(base64.b64decode(raw_b64)))
55
57
 
56
58
 
57
- def extract_widths(font: TTFont, baseline_size_px: int) -> dict[str, int]:
58
- """Return char -> width-in-tenths-of-pixels-at-baseline dict.
59
+ def extract_widths_and_bearings(font: TTFont, baseline_size_px: int) -> tuple[dict[str, int], dict[str, list[int]]]:
60
+ """Return per-char (advance_widths, ink_bearings) at the baseline size.
59
61
 
60
- Uses the font's ``cmap`` to map each supported ASCII codepoint to a
61
- glyph name, then reads the glyph's ``hmtx`` advance width in
62
- font-design units. Units are converted to pixels at
63
- ``baseline_size_px`` via ``units_per_em``, then scaled by 10 to
64
- match the ``tenths_of_pixels`` convention in ``inter.json``.
62
+ Advance widths follow the original schema tenths-of-pixels at
63
+ ``baseline_size_px``. Ink bearings are returned as
64
+ ``{char: [lsb_tenths, rsb_tenths]}`` where:
65
+
66
+ * ``lsb`` is the distance from the glyph's origin to the leftmost
67
+ visible ink (left side bearing in the OpenType sense)
68
+ * ``rsb`` is the distance from the rightmost visible ink to the
69
+ advance width (right side bearing)
70
+
71
+ These let the text-measurement layer compute *visible-ink width* as
72
+ ``advance - first_char.lsb - last_char.rsb`` — the corrected width
73
+ that places downstream cursor work (badge seam placement, stat card
74
+ bio_x derivation) at the actual visible end of text, not at the
75
+ advance position which includes invisible trailing side-bearing.
76
+
77
+ Whitespace glyphs (no ink) return ``[0, advance]`` so subtracting
78
+ them produces zero visible width — correct behavior for an
79
+ all-whitespace string.
65
80
  """
66
81
  cmap = font.getBestCmap()
67
82
  hmtx = font["hmtx"]
83
+ glyph_set = font.getGlyphSet()
68
84
  units_per_em = font["head"].unitsPerEm
85
+ scale = baseline_size_px / units_per_em
69
86
  widths: dict[str, int] = {}
87
+ bearings: dict[str, list[int]] = {}
70
88
  for ch in SUPPORTED_ASCII:
71
89
  codepoint = ord(ch)
72
90
  if codepoint not in cmap:
73
91
  continue
74
92
  glyph_name = cmap[codepoint]
75
- advance_design_units, _lsb = hmtx[glyph_name]
76
- advance_px_at_baseline = advance_design_units * baseline_size_px / units_per_em
77
- widths[ch] = round(advance_px_at_baseline * 10)
78
- return widths
93
+ advance_design_units, _lsb_design = hmtx[glyph_name]
94
+ widths[ch] = round(advance_design_units * scale * 10)
95
+
96
+ # Compute visible-ink bounds via BoundsPen. Whitespace glyphs draw
97
+ # nothing; pen.bounds is None — treat as "no visible ink" so the
98
+ # entire advance is left+right bearing (rsb consumes the advance).
99
+ pen = BoundsPen(glyph_set)
100
+ try:
101
+ glyph_set[glyph_name].draw(pen)
102
+ except Exception:
103
+ # Defensive: a malformed glyph shouldn't crash the extraction.
104
+ bearings[ch] = [0, widths[ch]]
105
+ continue
106
+ if pen.bounds is None:
107
+ bearings[ch] = [0, widths[ch]]
108
+ continue
109
+ xmin, _ymin, xmax, _ymax = pen.bounds
110
+ lsb_px_at_baseline = xmin * scale # ink-left from glyph origin
111
+ rsb_px_at_baseline = (advance_design_units - xmax) * scale # advance - ink-right
112
+ bearings[ch] = [round(lsb_px_at_baseline * 10), round(rsb_px_at_baseline * 10)]
113
+ return widths, bearings
79
114
 
80
115
 
81
116
  def compute_fallback_width(widths: dict[str, int]) -> int:
@@ -94,8 +129,16 @@ def emit_metrics_json(
94
129
  aliases: list[str],
95
130
  is_monospace: bool = False,
96
131
  char_width_px: float = 0.0,
132
+ bearings: dict[str, list[int]] | None = None,
133
+ widths_by_weight: dict[str, dict[str, int]] | None = None,
134
+ bearings_by_weight: dict[str, dict[str, list[int]]] | None = None,
97
135
  ) -> dict[str, object]:
98
- """Build the JSON dict matching inter.json schema (plus registry fields)."""
136
+ """Build the JSON dict matching inter.json schema (plus registry fields).
137
+
138
+ ``bearings`` is a v0.3.9 addition for per-glyph ink-width measurement
139
+ (used by ``measure_text_ink_width`` in core/text.py). Optional —
140
+ loaders that predate the field fall back to advance-width behavior.
141
+ """
99
142
  result: dict[str, object] = {
100
143
  "font_family": family,
101
144
  "baseline_size_px": baseline_size_px,
@@ -107,21 +150,28 @@ def emit_metrics_json(
107
150
  "char_width_px": char_width_px,
108
151
  "widths": widths,
109
152
  }
153
+ if bearings:
154
+ result["bearings"] = bearings
155
+ if widths_by_weight:
156
+ result["widths_by_weight"] = widths_by_weight
157
+ if bearings_by_weight:
158
+ result["bearings_by_weight"] = bearings_by_weight
110
159
  return result
111
160
 
112
161
 
113
162
  # Known font configs. Add entries here to extend.
114
163
  FONT_CONFIGS: dict[str, dict[str, object]] = {
115
164
  "orbitron": {
116
- "variant": "Orbitron",
165
+ "family": "Orbitron",
117
166
  "baseline_size_px": 20,
118
- "bold_expansion_factor": 1.06,
167
+ "bold_expansion_factor": 1.0,
119
168
  "aliases": ["orbitron"],
120
169
  "is_monospace": False,
121
170
  "char_width_px": 0.0,
171
+ "metric_weights": [400, 700, 800, 900],
122
172
  },
123
173
  "jetbrains-mono": {
124
- "variant": "JetBrains Mono",
174
+ "family": "JetBrains Mono",
125
175
  "baseline_size_px": 11,
126
176
  "bold_expansion_factor": 1.0, # true monospace — no bold width change
127
177
  "aliases": ["jetbrains mono", "jetbrains-mono", "sf mono", "menlo", "monospace"],
@@ -130,16 +180,54 @@ FONT_CONFIGS: dict[str, dict[str, object]] = {
130
180
  "char_width_px": 0.0,
131
181
  },
132
182
  "chakra-petch": {
133
- "variant": "Chakra Petch",
183
+ "family": "Chakra Petch",
134
184
  "baseline_size_px": 12, # dominant rendered size in automata badge value text
135
- "bold_expansion_factor": 1.04,
185
+ "bold_expansion_factor": 1.0,
136
186
  "aliases": ["chakra petch", "chakra-petch"],
137
187
  "is_monospace": False,
138
188
  "char_width_px": 0.0,
189
+ "metric_weights": [400, 700, 900],
190
+ "metric_weight_sources": {
191
+ "400": "chakra-petch",
192
+ "700": "chakra-petch",
193
+ "900": "chakra-petch",
194
+ },
195
+ },
196
+ "barlow-condensed-900": {
197
+ "family": "Barlow Condensed",
198
+ "baseline_size_px": 18, # dominant rendered size in brutalist strip value text
199
+ "bold_expansion_factor": 1.0, # 900 is the heaviest weight shipped; no further expansion
200
+ "aliases": ["barlow condensed", "barlow-condensed", "barlow condensed 900"],
201
+ "is_monospace": False,
202
+ "char_width_px": 0.0,
203
+ "metric_weights": [400, 700, 900],
204
+ "metric_weight_sources": {
205
+ "400": "barlow-condensed-700",
206
+ "700": "barlow-condensed-700",
207
+ "900": "barlow-condensed-900",
208
+ },
139
209
  },
140
210
  }
141
211
 
142
212
 
213
+ def load_metric_font_for_weight(slug: str, base_font: TTFont, config: dict[str, object], weight_int: int) -> TTFont:
214
+ """Return the font face used to extract metrics for ``weight_int``.
215
+
216
+ Variable fonts are instantiated by axis value. Static families can declare
217
+ ``metric_weight_sources`` to map weights to bundled font slugs.
218
+ """
219
+ weight_sources = config.get("metric_weight_sources")
220
+ if isinstance(weight_sources, dict):
221
+ source_slug = str(weight_sources.get(str(weight_int), slug))
222
+ source_path = FONTS_DIR / f"{source_slug}.b64"
223
+ if not source_path.exists():
224
+ raise FileNotFoundError(f"Missing font source for weight {weight_int}: {source_path}")
225
+ return load_font_from_b64(source_path)
226
+ if "fvar" in base_font:
227
+ return instantiateVariableFont(base_font, {"wght": weight_int}, inplace=False)
228
+ return base_font
229
+
230
+
143
231
  def extract_one(slug: str) -> Path:
144
232
  """Extract one font to ``data/font-metrics/{slug}.json``."""
145
233
  if slug not in FONT_CONFIGS:
@@ -151,7 +239,18 @@ def extract_one(slug: str) -> Path:
151
239
 
152
240
  font = load_font_from_b64(b64_path)
153
241
  baseline = int(config["baseline_size_px"])
154
- widths = extract_widths(font, baseline)
242
+ widths, bearings = extract_widths_and_bearings(font, baseline)
243
+ widths_by_weight: dict[str, dict[str, int]] = {}
244
+ bearings_by_weight: dict[str, dict[str, list[int]]] = {}
245
+ metric_weights = config.get("metric_weights")
246
+ if isinstance(metric_weights, list):
247
+ for weight in metric_weights:
248
+ weight_int = int(weight)
249
+ weight_font = load_metric_font_for_weight(slug, font, config, weight_int)
250
+ weight_widths, weight_bearings = extract_widths_and_bearings(weight_font, baseline)
251
+ key = str(weight_int)
252
+ widths_by_weight[key] = weight_widths
253
+ bearings_by_weight[key] = weight_bearings
155
254
 
156
255
  char_width_px = float(config["char_width_px"])
157
256
  is_mono = bool(config["is_monospace"])
@@ -161,13 +260,16 @@ def extract_one(slug: str) -> Path:
161
260
  char_width_px = advance_tenths / 10.0
162
261
 
163
262
  data = emit_metrics_json(
164
- variant=str(config["family"]),
263
+ family=str(config["family"]),
165
264
  baseline_size_px=baseline,
166
265
  widths=widths,
167
266
  bold_expansion_factor=float(config["bold_expansion_factor"]),
168
267
  aliases=list(config["aliases"]), # type: ignore[arg-type]
169
268
  is_monospace=is_mono,
170
269
  char_width_px=char_width_px,
270
+ bearings=bearings,
271
+ widths_by_weight=widths_by_weight,
272
+ bearings_by_weight=bearings_by_weight,
171
273
  )
172
274
 
173
275
  out_path = METRICS_DIR / f"{slug}.json"