hyperweave 0.2.4__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 (353) hide show
  1. {hyperweave-0.2.4 → hyperweave-0.2.6}/.gitignore +0 -1
  2. hyperweave-0.2.6/.pre-commit-config.yaml +31 -0
  3. {hyperweave-0.2.4 → hyperweave-0.2.6}/CHANGELOG.md +41 -0
  4. {hyperweave-0.2.4 → hyperweave-0.2.6}/PKG-INFO +9 -3
  5. {hyperweave-0.2.4 → hyperweave-0.2.6}/README.md +7 -1
  6. {hyperweave-0.2.4 → hyperweave-0.2.6}/pyproject.toml +6 -0
  7. hyperweave-0.2.6/scripts/extract_font_metrics.py +192 -0
  8. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/_version.py +2 -2
  9. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/resolver.py +123 -84
  10. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/resolvers/chart.py +15 -15
  11. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/resolvers/stats.py +60 -11
  12. hyperweave-0.2.6/src/hyperweave/compose/validate_paradigms.py +58 -0
  13. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/config/loader.py +34 -0
  14. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/config/registry.py +9 -0
  15. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/connectors/github.py +2 -7
  16. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/contracts.py +3 -3
  17. hyperweave-0.2.6/src/hyperweave/core/font_metrics.py +114 -0
  18. hyperweave-0.2.6/src/hyperweave/core/paradigm.py +120 -0
  19. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/schema.py +0 -12
  20. hyperweave-0.2.6/src/hyperweave/core/text.py +65 -0
  21. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/font-metrics/inter.json +3 -0
  22. hyperweave-0.2.6/src/hyperweave/data/font-metrics/jetbrains-mono.json +113 -0
  23. hyperweave-0.2.6/src/hyperweave/data/font-metrics/orbitron.json +108 -0
  24. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/genomes/chrome-horizon.json +0 -6
  25. hyperweave-0.2.6/src/hyperweave/data/paradigms/brutalist.yaml +42 -0
  26. hyperweave-0.2.6/src/hyperweave/data/paradigms/chrome.yaml +54 -0
  27. hyperweave-0.2.6/src/hyperweave/data/paradigms/default.yaml +46 -0
  28. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/profiles/chrome.contract.json +0 -2
  29. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/render/chart_engine.py +106 -46
  30. hyperweave-0.2.6/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +9 -0
  31. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/badge/chrome-content.j2 +1 -1
  32. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/badge/chrome-defs.j2 +6 -10
  33. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/banner/brutalist-defs.j2 +2 -1
  34. hyperweave-0.2.6/src/hyperweave/templates/frames/banner/chrome-content.j2 +80 -0
  35. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/banner/chrome-defs.j2 +4 -4
  36. hyperweave-0.2.6/src/hyperweave/templates/frames/banner/default-content.j2 +114 -0
  37. hyperweave-0.2.6/src/hyperweave/templates/frames/banner.svg.j2 +23 -0
  38. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/chart/chrome-content.j2 +21 -14
  39. hyperweave-0.2.6/src/hyperweave/templates/frames/chart/chrome-defs.j2 +141 -0
  40. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/icon/chrome-content.j2 +4 -4
  41. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/icon/chrome-defs.j2 +4 -4
  42. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-counter/chrome-content.j2 +1 -1
  43. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-counter/chrome-defs.j2 +2 -2
  44. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-counter.svg.j2 +4 -4
  45. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-horizontal/chrome-content.j2 +1 -1
  46. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-horizontal/chrome-defs.j2 +7 -7
  47. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-horizontal.svg.j2 +6 -6
  48. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-vertical/chrome-content.j2 +1 -1
  49. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-vertical/chrome-defs.j2 +6 -6
  50. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-vertical.svg.j2 +7 -7
  51. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/stats/chrome-content.j2 +31 -16
  52. hyperweave-0.2.6/src/hyperweave/templates/frames/stats/chrome-defs.j2 +96 -0
  53. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/brutalist-defs.j2 +4 -1
  54. hyperweave-0.2.6/src/hyperweave/templates/frames/strip/chrome-content.j2 +33 -0
  55. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/chrome-defs.j2 +6 -6
  56. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip.svg.j2 +9 -7
  57. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/fixtures/session.json +1 -1
  58. hyperweave-0.2.6/tests/helpers.py +58 -0
  59. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_chart_engine.py +40 -3
  60. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_chart_frame.py +3 -11
  61. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_core.py +36 -2
  62. hyperweave-0.2.6/tests/test_paradigm_extensibility.py +157 -0
  63. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_serve_live_state.py +3 -9
  64. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_telemetry_integration.py +71 -0
  65. {hyperweave-0.2.4 → hyperweave-0.2.6}/uv.lock +174 -0
  66. hyperweave-0.2.4/src/hyperweave/core/text.py +0 -152
  67. hyperweave-0.2.4/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +0 -5
  68. hyperweave-0.2.4/src/hyperweave/templates/frames/banner.svg.j2 +0 -224
  69. hyperweave-0.2.4/src/hyperweave/templates/frames/chart/chrome-defs.j2 +0 -154
  70. hyperweave-0.2.4/src/hyperweave/templates/frames/stats/chrome-defs.j2 +0 -133
  71. hyperweave-0.2.4/src/hyperweave/templates/frames/strip/chrome-content.j2 +0 -29
  72. {hyperweave-0.2.4 → hyperweave-0.2.6}/.dockerignore +0 -0
  73. {hyperweave-0.2.4 → hyperweave-0.2.6}/.github/workflows/ci.yml +0 -0
  74. {hyperweave-0.2.4 → hyperweave-0.2.6}/.github/workflows/deploy.yml +0 -0
  75. {hyperweave-0.2.4 → hyperweave-0.2.6}/.github/workflows/publish.yml +0 -0
  76. {hyperweave-0.2.4 → hyperweave-0.2.6}/Dockerfile +0 -0
  77. {hyperweave-0.2.4 → hyperweave-0.2.6}/LICENSE +0 -0
  78. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/buttons/button-liquid.svg +0 -0
  79. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/cards/card-butterfly.svg +0 -0
  80. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/cards/card-python.svg +0 -0
  81. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/cards/card-sunflower.svg +0 -0
  82. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/cards/card-waves.svg +0 -0
  83. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/badge_critical.svg +0 -0
  84. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/badge_passing.svg +0 -0
  85. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/badge_warning.svg +0 -0
  86. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/banner.svg +0 -0
  87. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/icons/discord.svg +0 -0
  88. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/icons/notion.svg +0 -0
  89. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/icons/reddit.svg +0 -0
  90. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/icons/spotify.svg +0 -0
  91. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/icons/youtube.svg +0 -0
  92. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/marquee_counter.svg +0 -0
  93. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/marquee_horizontal.svg +0 -0
  94. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/marquee_vertical.svg +0 -0
  95. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/profile-cards/chart_stars_full.svg +0 -0
  96. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/profile-cards/stats.svg +0 -0
  97. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/brutalist-emerald/strip.svg +0 -0
  98. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/badge_critical.svg +0 -0
  99. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/badge_passing.svg +0 -0
  100. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/badge_warning.svg +0 -0
  101. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/banner.svg +0 -0
  102. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/icons/bluesky.svg +0 -0
  103. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/icons/github.svg +0 -0
  104. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/icons/instagram.svg +0 -0
  105. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/icons/mastodon.svg +0 -0
  106. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/icons/x.svg +0 -0
  107. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/marquee_counter.svg +0 -0
  108. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/marquee_horizontal.svg +0 -0
  109. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/marquee_vertical.svg +0 -0
  110. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/profile-cards/chart_stars_full.svg +0 -0
  111. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/profile-cards/stats.svg +0 -0
  112. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/chrome-horizon/strip.svg +0 -0
  113. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/telemetry/master_card.svg +0 -0
  114. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/telemetry/receipt.svg +0 -0
  115. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/examples/telemetry/rhythm_strip.svg +0 -0
  116. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/footers/inneraura-footer-liquid.svg +0 -0
  117. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/footers/inneraura-footer-purple.svg +0 -0
  118. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/footers/inneraura-footer.svg +0 -0
  119. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/hyperweave-banner.svg +0 -0
  120. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-discord.svg +0 -0
  121. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-docs.svg +0 -0
  122. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-github.svg +0 -0
  123. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-instagram.svg +0 -0
  124. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-linkedin.svg +0 -0
  125. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-tiktok.svg +0 -0
  126. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-x.svg +0 -0
  127. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/icons/cobalt-sapphire-youtube.svg +0 -0
  128. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/marquees/badge-showcase-triple.svg +0 -0
  129. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/marquees/genome-marquee-triple.svg +0 -0
  130. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/marquees/sample-badges.svg +0 -0
  131. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/404.svg +0 -0
  132. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/callout-icons.svg +0 -0
  133. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/divider.svg +0 -0
  134. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/favicon.svg +0 -0
  135. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/hero-banner.svg +0 -0
  136. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/hyperweave-banner-v2.svg +0 -0
  137. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/hyperweave-navbar-logo.svg +0 -0
  138. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/loader.svg +0 -0
  139. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/mintlify-assets/og-image.svg +0 -0
  140. {hyperweave-0.2.4 → hyperweave-0.2.6}/assets/timelines/hyperweave-roadmap.svg +0 -0
  141. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/assets/favicon.svg +0 -0
  142. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/assets/hyperweave-banner.svg +0 -0
  143. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/assets/hyperweave-navbar-logo.svg +0 -0
  144. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/assets/og-image.svg +0 -0
  145. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/explanation/architecture.mdx +0 -0
  146. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/explanation/camo-compatibility.mdx +0 -0
  147. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/explanation/cim-compliance.mdx +0 -0
  148. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/explanation/genome-profile-system.mdx +0 -0
  149. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/explanation/metadata-tiers.mdx +0 -0
  150. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/how-to/add-motion-to-badges.mdx +0 -0
  151. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/how-to/create-session-receipts.mdx +0 -0
  152. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/how-to/set-up-claude-code-hooks.mdx +0 -0
  153. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/how-to/use-live-data-badges.mdx +0 -0
  154. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/introduction.mdx +0 -0
  155. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/mint.json +0 -0
  156. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/quickstart.mdx +0 -0
  157. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/reference/cli.mdx +0 -0
  158. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/reference/compose-spec.mdx +0 -0
  159. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/reference/genomes.mdx +0 -0
  160. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/reference/http-api.mdx +0 -0
  161. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/reference/mcp-tools.mdx +0 -0
  162. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/reference/motions.mdx +0 -0
  163. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/reference/telemetry-contract.mdx +0 -0
  164. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/spec/hyperweave-protocol.mdx +0 -0
  165. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/tutorials/build-an-artifact-kit.mdx +0 -0
  166. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/tutorials/compose-your-first-badge.mdx +0 -0
  167. {hyperweave-0.2.4 → hyperweave-0.2.6}/docs/tutorials/install-session-telemetry.mdx +0 -0
  168. {hyperweave-0.2.4 → hyperweave-0.2.6}/fly.toml +0 -0
  169. {hyperweave-0.2.4 → hyperweave-0.2.6}/hooks/install.py +0 -0
  170. {hyperweave-0.2.4 → hyperweave-0.2.6}/hooks/session_end.sh +0 -0
  171. {hyperweave-0.2.4 → hyperweave-0.2.6}/justfile +0 -0
  172. {hyperweave-0.2.4 → hyperweave-0.2.6}/scripts/extract_glyphs.py +0 -0
  173. {hyperweave-0.2.4 → hyperweave-0.2.6}/scripts/generate_hw_compliant.py +0 -0
  174. {hyperweave-0.2.4 → hyperweave-0.2.6}/scripts/generate_proofset.py +0 -0
  175. {hyperweave-0.2.4 → hyperweave-0.2.6}/scripts/stress_test.py +0 -0
  176. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/__init__.py +0 -0
  177. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/__main__.py +0 -0
  178. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/cli.py +0 -0
  179. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/__init__.py +0 -0
  180. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/assembler.py +0 -0
  181. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/context.py +0 -0
  182. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/engine.py +0 -0
  183. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/lanes.py +0 -0
  184. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/resolvers/__init__.py +0 -0
  185. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/compose/resolvers/timeline.py +0 -0
  186. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/config/__init__.py +0 -0
  187. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/config/genome_validator.py +0 -0
  188. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/config/settings.py +0 -0
  189. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/connectors/__init__.py +0 -0
  190. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/connectors/arxiv.py +0 -0
  191. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/connectors/base.py +0 -0
  192. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/connectors/cache.py +0 -0
  193. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/connectors/rest.py +0 -0
  194. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/__init__.py +0 -0
  195. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/color.py +0 -0
  196. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/enums.py +0 -0
  197. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/models.py +0 -0
  198. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/state.py +0 -0
  199. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/core/thresholds.py +0 -0
  200. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/css/accessibility.css +0 -0
  201. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/css/bridge.css +0 -0
  202. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/css/expression.css +0 -0
  203. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/css/phase-colors.css +0 -0
  204. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/css/status.css +0 -0
  205. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/css/telemetry.css +0 -0
  206. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/fonts/jetbrains-mono.b64 +0 -0
  207. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/fonts/jetbrains-mono.meta.json +0 -0
  208. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/fonts/orbitron.b64 +0 -0
  209. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/fonts/orbitron.meta.json +0 -0
  210. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/genomes/brutalist-emerald.json +0 -0
  211. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/genomes/telemetry-void.json +0 -0
  212. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/glyphs.json +0 -0
  213. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/border/chromatic-pulse.yaml +0 -0
  214. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/border/corner-trace.yaml +0 -0
  215. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/border/dual-orbit.yaml +0 -0
  216. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/border/entanglement.yaml +0 -0
  217. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/border/rimrun.yaml +0 -0
  218. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/bars.yaml +0 -0
  219. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/breach.yaml +0 -0
  220. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/broadcast.yaml +0 -0
  221. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/cascade.yaml +0 -0
  222. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/collapse.yaml +0 -0
  223. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/converge.yaml +0 -0
  224. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/crash.yaml +0 -0
  225. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/drop.yaml +0 -0
  226. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/kinetic/pulse.yaml +0 -0
  227. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/motions/static.yaml +0 -0
  228. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/policies/normal.json +0 -0
  229. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/policies/permissive.json +0 -0
  230. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/policies/ungoverned.json +0 -0
  231. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/profiles/brutalist.contract.json +0 -0
  232. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/profiles/brutalist.yaml +0 -0
  233. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/profiles/chrome.yaml +0 -0
  234. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/specimens.yaml +0 -0
  235. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/telemetry/model-pricing.yaml +0 -0
  236. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/telemetry/stage-config.yaml +0 -0
  237. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/telemetry/stage-labels.yaml +0 -0
  238. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/telemetry/tool-classes.yaml +0 -0
  239. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/telemetry/tool-colors.yaml +0 -0
  240. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/arrow.json +0 -0
  241. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/aurora.json +0 -0
  242. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/beacon.json +0 -0
  243. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/bracket3d.json +0 -0
  244. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/chevron.json +0 -0
  245. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/crosshair.json +0 -0
  246. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/diamond.json +0 -0
  247. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/rocket.json +0 -0
  248. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/rules/bar.json +0 -0
  249. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/rules/dashed.json +0 -0
  250. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/rules/five-wave.json +0 -0
  251. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/rules/spectral.json +0 -0
  252. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/rules/straight.json +0 -0
  253. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/rules/wave.json +0 -0
  254. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/data/terminals/stijl.json +0 -0
  255. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/kit.py +0 -0
  256. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/mcp/__init__.py +0 -0
  257. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/mcp/__main__.py +0 -0
  258. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/mcp/server.py +0 -0
  259. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/py.typed +0 -0
  260. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/render/__init__.py +0 -0
  261. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/render/fonts.py +0 -0
  262. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/render/glyphs.py +0 -0
  263. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/render/motion.py +0 -0
  264. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/render/templates.py +0 -0
  265. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/serve/__init__.py +0 -0
  266. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/serve/app.py +0 -0
  267. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/__init__.py +0 -0
  268. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/capture.py +0 -0
  269. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/contract.py +0 -0
  270. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/corrections.py +0 -0
  271. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/cost.py +0 -0
  272. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/models.py +0 -0
  273. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/parser.py +0 -0
  274. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/telemetry/stages.py +0 -0
  275. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/filter.svg.j2 +0 -0
  276. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/glyph-inline.svg.j2 +0 -0
  277. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/glyph.svg.j2 +0 -0
  278. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/gradient.svg.j2 +0 -0
  279. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/metadata.svg.j2 +0 -0
  280. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/metric.svg.j2 +0 -0
  281. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/phase-segment.svg.j2 +0 -0
  282. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/rule.svg.j2 +0 -0
  283. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/status.svg.j2 +0 -0
  284. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/terminal.svg.j2 +0 -0
  285. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/components/treemap.svg.j2 +0 -0
  286. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/document.svg.j2 +0 -0
  287. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/error-badge.svg.j2 +0 -0
  288. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/badge/brutalist-content.j2 +0 -0
  289. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/badge/default-content.j2 +0 -0
  290. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/badge/default-defs.j2 +0 -0
  291. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/badge.svg.j2 +0 -0
  292. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/banner/default-defs.j2 +0 -0
  293. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/catalog.svg.j2 +0 -0
  294. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/chart/brutalist-content.j2 +0 -0
  295. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/chart/brutalist-defs.j2 +0 -0
  296. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/chart.svg.j2 +0 -0
  297. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/divider.svg.j2 +0 -0
  298. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/icon/brutalist-content.j2 +0 -0
  299. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/icon/brutalist-defs.j2 +0 -0
  300. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/icon/default-content.j2 +0 -0
  301. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/icon/default-defs.j2 +0 -0
  302. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/icon.svg.j2 +0 -0
  303. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-counter/brutalist-content.j2 +0 -0
  304. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-counter/brutalist-defs.j2 +0 -0
  305. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-content.j2 +0 -0
  306. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-defs.j2 +0 -0
  307. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-vertical/brutalist-content.j2 +0 -0
  308. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/marquee-vertical/brutalist-defs.j2 +0 -0
  309. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/master-card.svg.j2 +0 -0
  310. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/receipt.svg.j2 +0 -0
  311. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/rhythm-strip.svg.j2 +0 -0
  312. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/stats/brutalist-content.j2 +0 -0
  313. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/stats/brutalist-defs.j2 +0 -0
  314. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/stats.svg.j2 +0 -0
  315. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/brutalist-content.j2 +0 -0
  316. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/brutalist-status.j2 +0 -0
  317. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/chrome-status.j2 +0 -0
  318. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/default-content.j2 +0 -0
  319. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/default-defs.j2 +0 -0
  320. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/strip/default-status.j2 +0 -0
  321. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/timeline/default-content.j2 +0 -0
  322. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/frames/timeline.svg.j2 +0 -0
  323. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/border/chromatic-pulse.svg.j2 +0 -0
  324. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/border/corner-trace.svg.j2 +0 -0
  325. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/border/dual-orbit.svg.j2 +0 -0
  326. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/border/entanglement.svg.j2 +0 -0
  327. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/border/rimrun.svg.j2 +0 -0
  328. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/bars.svg.j2 +0 -0
  329. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/breach.svg.j2 +0 -0
  330. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/broadcast.svg.j2 +0 -0
  331. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/cascade.svg.j2 +0 -0
  332. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/collapse.svg.j2 +0 -0
  333. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/converge.svg.j2 +0 -0
  334. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/crash.svg.j2 +0 -0
  335. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/drop.svg.j2 +0 -0
  336. {hyperweave-0.2.4 → hyperweave-0.2.6}/src/hyperweave/templates/motions/kinetic/pulse.svg.j2 +0 -0
  337. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/__init__.py +0 -0
  338. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/conftest.py +0 -0
  339. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/fixtures/github_contributions/synthetic.html +0 -0
  340. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/fixtures/session.jsonl +0 -0
  341. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_assembler.py +0 -0
  342. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_connectors.py +0 -0
  343. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_github_scrape.py +0 -0
  344. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_kit.py +0 -0
  345. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_mcp.py +0 -0
  346. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_paradigm_dispatch.py +0 -0
  347. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_proofset.py +0 -0
  348. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_render.py +0 -0
  349. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_serve.py +0 -0
  350. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_state_inference.py +0 -0
  351. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_stats_card.py +0 -0
  352. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_telemetry.py +0 -0
  353. {hyperweave-0.2.4 → hyperweave-0.2.6}/tests/test_timeline.py +0 -0
@@ -27,7 +27,6 @@ htmlcov/
27
27
  archive/
28
28
  .claude/
29
29
  # CLAUDE.md
30
- docs/_notes/
31
30
  outputs/
32
31
  specs/
33
32
  # scripts/ is version-controlled (tests/test_proofset.py imports generate_proofset.py)
@@ -0,0 +1,31 @@
1
+ # Runs `ruff check` + `ruff format` automatically on every `git commit`.
2
+ # Mirrors the two lint steps CI enforces in .github/workflows/ci.yml so CI
3
+ # never surfaces formatting or lint failures that local commits should catch.
4
+ #
5
+ # One-time setup after cloning:
6
+ # uv sync --group dev
7
+ # uv run pre-commit install
8
+ #
9
+ # Manual run across the whole repo:
10
+ # uv run pre-commit run --all-files
11
+
12
+ repos:
13
+ - repo: https://github.com/astral-sh/ruff-pre-commit
14
+ rev: v0.9.0
15
+ hooks:
16
+ - id: ruff
17
+ args: [--fix]
18
+ - id: ruff-format
19
+
20
+ - repo: https://github.com/pre-commit/pre-commit-hooks
21
+ rev: v5.0.0
22
+ hooks:
23
+ - id: trailing-whitespace
24
+ exclude: \.svg$
25
+ - id: end-of-file-fixer
26
+ exclude: \.(svg|b64)$
27
+ - id: check-yaml
28
+ - id: check-toml
29
+ - id: check-merge-conflict
30
+ - id: check-added-large-files
31
+ args: [--maxkb=500]
@@ -5,6 +5,47 @@ 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.2.6] - 2026-04-19
9
+
10
+ ### Added
11
+
12
+ - **Font-aware text measurement.** `measure_text` dispatches to per-font LUTs via a `FontRegistry` (Inter, Orbitron, JetBrains Mono). Callers pass `font_family`, `font_size`, `font_weight`, `letter_spacing_em` — no more `bold` / `monospace` booleans. `scripts/extract_font_metrics.py` decodes base64 WOFF2 sources via fontTools and emits JSON matching the existing `inter.json` schema. The measurement contract (ASCII glyph set, linear size scaling, kerning and ligatures ignored, unknown family falls back to Inter with a one-shot warning) is documented verbatim at the top of `core/font_metrics.py`.
13
+ - **Paradigm config files.** `data/paradigms/{default,chrome,brutalist}.yaml` carry per-paradigm layout and typography config. `ParadigmSpec` Pydantic model with nested frame configs (`badge`, `strip`, `banner`, `chart`, `stats`, `icon`) in `core/paradigm.py`. Loader + registry parity via `load_paradigms()` and `get_paradigms()`.
14
+ - **Paradigm/genome cross-validation.** `compose/validate_paradigms.py::validate_genome_against_paradigms()` runs at `ConfigLoader.load`. Genomes that opt into a paradigm must declare every field in its `requires_genome_fields` or load raises `ValueError` with a structured message listing every missing `(paradigm, field)` pair. Kept out of `GenomeSpec` as a `@model_validator` to avoid a circular loader dependency.
15
+ - **Invariant 11** (CLAUDE.md Verify block): no specimen colors in template fallbacks. `grep "default('#"` in templates must be zero.
16
+ - **Invariant 12** (CLAUDE.md Verify block): adding a new paradigm within the existing frame contract requires zero Python edits. `grep 'paradigm == "'` in `.py` files and `grep '{% if paradigm'` in templates must both be zero.
17
+ - Six extensibility-proof tests in `tests/test_paradigm_extensibility.py`. `tests/helpers.py::build_partial_genome_for_testing` provides an explicit test-only bypass for the validator.
18
+ - `PROFILE_CONTRACTS.md` documents the paradigm contract: required genome fields per paradigm, how the dispatcher routes through `_resolve_paradigm` and `load_paradigms`, how to add a new paradigm from YAML + templates alone.
19
+
20
+ ### Fixed
21
+
22
+ - **Brutalist badge value text collided with the status indicator.** The pre-v0.2.6 resolver measured monospace text at a cross-platform-safe 7.2 px/char; per-font LUTs measure JetBrains Mono at its accurate 6.6 px/char, so the old safety margin is gone. Brutalist badge, strip, and banner defs now embed `@font-face` declarations via `{{ font_faces | safe }}` so rendered widths equal measured widths in any viewer — not just those that happen to have the system font installed. `default.yaml` font_family declarations corrected to JetBrains Mono to match what the default partials (which alias brutalist) actually render.
23
+ - **Chrome templates no longer carry chrome-horizon's palette as fallback.** Every `| default('#hex')` specimen-leak chain is stripped from stats, chart, strip, banner, badge, icon, and all three marquee chrome templates. A future chrome genome that omits `envelope_stops`, `well_top`, `well_bottom`, `chrome_text_gradient`, `hero_text_gradient`, or `highlight_color` now fails at load time instead of silently inheriting chrome-horizon's cyan.
24
+
25
+ ### Changed
26
+
27
+ - **`banner.svg.j2` split.** 224-line monolith with inline `{% if paradigm_banner == "chrome" %}` branches replaced by a 23-line dispatcher plus `frames/banner/{chrome,default}-content.j2` partials. Banner now matches the partial-dispatch pattern used by strip, badge, stats, and chart.
28
+ - **Resolvers consume `paradigm_spec` directly.** `resolve_badge`, `resolve_strip`, `resolve_chart`, `resolve_stats`, `resolve_icon`, and `resolve_banner` read `paradigm_spec.{frame}.{key}` instead of comparing the paradigm slug inline. `_PROFILE_SHAPES` and `_STATS_HEIGHTS` dicts are gone; their content lives in the paradigm YAMLs.
29
+ - **Strip inline paradigm branches replaced with context vars.** `divider_render_mode` and `status_shape_rendering` are injected by the resolver from paradigm config; the template branches on resolved values, not on slug strings.
30
+ - `_profile_visual_context` renamed to `_genome_material_context` — it has always read from `genome`, not `profile`.
31
+ - `measure_text` signature is now keyword-only after the leading `text` positional. `bold` and `monospace` kwargs removed.
32
+
33
+ ### Removed
34
+
35
+ - `text_metrics` field on `GenomeSpec`. The per-zone width multiplier (`badge_value_width_factor: 1.35` on chrome-horizon) was a workaround for the Inter-only LUT; with per-font LUTs it is redundant.
36
+ - `font_scale` heuristic in the marquee row-width helper. Replaced by font-family-aware measurement.
37
+ - Dead `specular_sweep_dur` and `specular_sweep_peak` fields from `GenomeSpec`, `chrome.contract.json`, and `chrome-horizon.json`. `highlight_opacity` is retained — it has live consumers in badge and strip chrome content.
38
+
39
+ ### Dev dependencies
40
+
41
+ - `fontTools` and `brotli` added so the font-metrics extraction script can decode WOFF2.
42
+
43
+ ## [0.2.5] - 2026-04-13
44
+
45
+ ### Fixed
46
+
47
+ - **Chart bezier regression on certain data ranges.** The chrome chart bezier path used horizontal tangents at every anchor, which produced a smooth curve only when input points were widely and evenly spaced. On tighter or uneven distributions — common with real GitHub stargazer data — the curve degenerated into flat-then-vertical segments. Replaced with Fritsch-Carlson monotonic cubic interpolation (the same algorithm D3's `curveMonotoneX` uses), which guarantees the curve passes through every anchor, never overshoots between points, and handles any point spacing robustly.
48
+
8
49
  ## [0.2.4] - 2026-04-13
9
50
 
10
51
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperweave
3
- Version: 0.2.4
3
+ Version: 0.2.6
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
@@ -8,7 +8,7 @@ Project-URL: Discord, https://discord.gg/wVmcAZPQZ8
8
8
  Author: InnerAura Labs
9
9
  License-Expression: Apache-2.0
10
10
  License-File: LICENSE
11
- Keywords: ai-agents,claude-code,design-system,developer-tools,fastapi,generative-ui,mcp,mcp-server,svg,svg-generation
11
+ Keywords: ai-agents,badges,claude-code,design-system,developer-tools,fastapi,generative-ui,github-profile,mcp,mcp-server,profile-readme,svg,svg-generation
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Intended Audience :: Developers
14
14
  Classifier: License :: OSI Approved :: Apache Software License
@@ -56,6 +56,12 @@ Description-Content-Type: text/markdown
56
56
  </p>
57
57
 
58
58
  <!--
59
+ HyperWeave is the generative visual identity system for the agentic era. A user defines a genome — their aesthetic DNA — and HyperWeave renders coherent visual artifacts across any surface, for any context, from any data. Badges for repos. Banners for profiles. Cards for stats. Charts for data. Artifact sets for research papers. Release kits for product launches. Marketing assets for startups. Static when static. Live when live. Generated when generative. Their brand, as infrastructure, for everything their agents will ever need to render.
60
+
61
+ The list in the middle ("Badges for repos. Banners for profiles. Cards for stats...") reads long. It proves the surface area is broad but it also reads like a features list. Investors skim past enumeration. You could collapse it: "Every surface agents render on, from repos to research papers to product launches." The breadth lands harder when it's a claim than when it's a list.
62
+
63
+ HyperWeave is the brand agent for engineering teams. Define your identity once; every artifact your team ships carries it wherever their work appears.
64
+
59
65
  Safe, Auditable, Drop-Anywhere Visuals for your Agents.
60
66
 
61
67
  ---
@@ -397,4 +403,4 @@ HyperWeave is early. If you're interested in building genomes, extending frame t
397
403
  [x]: https://x.com/InnerAuraLabs
398
404
  [youtube]: https://www.youtube.com/@InnerAuraLabs
399
405
 
400
- [return-top]: https://raw.githubusercontent.com/InnerAura/hyperweave/f36c8969d15d76da4400ebcfaa04ec1e2eacb170/assets/buttons/button-liquid.svg
406
+ [return-top]: https://raw.githubusercontent.com/InnerAura/hyperweave/f36c8969d15d76da4400ebcfaa04ec1e2eacb170/assets/buttons/button-liquid.svg
@@ -24,6 +24,12 @@
24
24
  </p>
25
25
 
26
26
  <!--
27
+ HyperWeave is the generative visual identity system for the agentic era. A user defines a genome — their aesthetic DNA — and HyperWeave renders coherent visual artifacts across any surface, for any context, from any data. Badges for repos. Banners for profiles. Cards for stats. Charts for data. Artifact sets for research papers. Release kits for product launches. Marketing assets for startups. Static when static. Live when live. Generated when generative. Their brand, as infrastructure, for everything their agents will ever need to render.
28
+
29
+ The list in the middle ("Badges for repos. Banners for profiles. Cards for stats...") reads long. It proves the surface area is broad but it also reads like a features list. Investors skim past enumeration. You could collapse it: "Every surface agents render on, from repos to research papers to product launches." The breadth lands harder when it's a claim than when it's a list.
30
+
31
+ HyperWeave is the brand agent for engineering teams. Define your identity once; every artifact your team ships carries it wherever their work appears.
32
+
27
33
  Safe, Auditable, Drop-Anywhere Visuals for your Agents.
28
34
 
29
35
  ---
@@ -365,4 +371,4 @@ HyperWeave is early. If you're interested in building genomes, extending frame t
365
371
  [x]: https://x.com/InnerAuraLabs
366
372
  [youtube]: https://www.youtube.com/@InnerAuraLabs
367
373
 
368
- [return-top]: https://raw.githubusercontent.com/InnerAura/hyperweave/f36c8969d15d76da4400ebcfaa04ec1e2eacb170/assets/buttons/button-liquid.svg
374
+ [return-top]: https://raw.githubusercontent.com/InnerAura/hyperweave/f36c8969d15d76da4400ebcfaa04ec1e2eacb170/assets/buttons/button-liquid.svg
@@ -17,6 +17,9 @@ keywords = [
17
17
  "developer-tools",
18
18
  "fastapi",
19
19
  "claude-code",
20
+ "badges",
21
+ "github-profile",
22
+ "profile-readme",
20
23
  ]
21
24
  classifiers = [
22
25
  "Development Status :: 4 - Beta",
@@ -77,6 +80,9 @@ dev = [
77
80
  "ruff>=0.9",
78
81
  "mypy>=1.14",
79
82
  "types-pyyaml>=6.0.12.20250915",
83
+ "pre-commit>=4.0",
84
+ "fonttools>=4.62.1",
85
+ "brotli>=1.2.0",
80
86
  ]
81
87
 
82
88
  [tool.pytest.ini_options]
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env python3
2
+ """Extract per-codepoint advance widths from bundled WOFF2 fonts.
3
+
4
+ HyperWeave bundles fonts as base64-encoded WOFF2 in
5
+ ``src/hyperweave/data/fonts/*.b64`` (so the whole font registry ships
6
+ as plain-text files, diffable in git). This script decodes each font,
7
+ reads its ``hmtx`` table via ``fontTools``, and emits a JSON file at
8
+ ``src/hyperweave/data/font-metrics/{slug}.json`` matching the existing
9
+ ``inter.json`` schema:
10
+
11
+ {
12
+ "font_family": "Orbitron",
13
+ "baseline_size_px": 20,
14
+ "units": "tenths_of_pixels",
15
+ "bold_expansion_factor": 1.06,
16
+ "fallback_width": 110,
17
+ "widths": { " ": 78, "A": 145, ... }
18
+ }
19
+
20
+ The baseline size is chosen close to the font's dominant rendered size
21
+ in HyperWeave (20px for Orbitron in stats hero values, 11px for
22
+ Inter in badge labels). Widths are stored in tenths-of-pixels at the
23
+ baseline size, so a glyph of 145 tenths at baseline 20px renders as
24
+ 14.5px wide at 20px and ~7.25px wide at 10px (linear scaling).
25
+
26
+ Usage:
27
+ uv run python scripts/extract_font_metrics.py orbitron --baseline 20
28
+ uv run python scripts/extract_font_metrics.py jetbrains-mono --baseline 11
29
+ uv run python scripts/extract_font_metrics.py --all
30
+ """
31
+
32
+ from __future__ import annotations
33
+
34
+ import argparse
35
+ import base64
36
+ import json
37
+ import sys
38
+ from io import BytesIO
39
+ from pathlib import Path
40
+
41
+ from fontTools.ttLib import TTFont
42
+
43
+ ROOT = Path(__file__).resolve().parent.parent
44
+ FONTS_DIR = ROOT / "src" / "hyperweave" / "data" / "fonts"
45
+ METRICS_DIR = ROOT / "src" / "hyperweave" / "data" / "font-metrics"
46
+
47
+ # ASCII printable characters we shipped in inter.json (space through ~).
48
+ SUPPORTED_ASCII = [chr(c) for c in range(0x20, 0x7F)]
49
+
50
+
51
+ def load_font_from_b64(path: Path) -> TTFont:
52
+ """Decode a base64-encoded WOFF2 payload and return a TTFont."""
53
+ raw_b64 = path.read_text()
54
+ return TTFont(BytesIO(base64.b64decode(raw_b64)))
55
+
56
+
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
+
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``.
65
+ """
66
+ cmap = font.getBestCmap()
67
+ hmtx = font["hmtx"]
68
+ units_per_em = font["head"].unitsPerEm
69
+ widths: dict[str, int] = {}
70
+ for ch in SUPPORTED_ASCII:
71
+ codepoint = ord(ch)
72
+ if codepoint not in cmap:
73
+ continue
74
+ 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
79
+
80
+
81
+ def compute_fallback_width(widths: dict[str, int]) -> int:
82
+ """Median-ish fallback width for codepoints outside the supported set."""
83
+ if not widths:
84
+ return 60
85
+ sorted_widths = sorted(widths.values())
86
+ return sorted_widths[len(sorted_widths) // 2]
87
+
88
+
89
+ def emit_metrics_json(
90
+ family: str,
91
+ baseline_size_px: int,
92
+ widths: dict[str, int],
93
+ bold_expansion_factor: float,
94
+ aliases: list[str],
95
+ is_monospace: bool = False,
96
+ char_width_px: float = 0.0,
97
+ ) -> dict[str, object]:
98
+ """Build the JSON dict matching inter.json schema (plus registry fields)."""
99
+ result: dict[str, object] = {
100
+ "font_family": family,
101
+ "baseline_size_px": baseline_size_px,
102
+ "units": "tenths_of_pixels",
103
+ "bold_expansion_factor": bold_expansion_factor,
104
+ "fallback_width": compute_fallback_width(widths),
105
+ "aliases": aliases,
106
+ "is_monospace": is_monospace,
107
+ "char_width_px": char_width_px,
108
+ "widths": widths,
109
+ }
110
+ return result
111
+
112
+
113
+ # Known font configs. Add entries here to extend.
114
+ FONT_CONFIGS: dict[str, dict[str, object]] = {
115
+ "orbitron": {
116
+ "family": "Orbitron",
117
+ "baseline_size_px": 20,
118
+ "bold_expansion_factor": 1.06,
119
+ "aliases": ["orbitron"],
120
+ "is_monospace": False,
121
+ "char_width_px": 0.0,
122
+ },
123
+ "jetbrains-mono": {
124
+ "family": "JetBrains Mono",
125
+ "baseline_size_px": 11,
126
+ "bold_expansion_factor": 1.0, # true monospace — no bold width change
127
+ "aliases": ["jetbrains mono", "jetbrains-mono", "sf mono", "menlo", "monospace"],
128
+ "is_monospace": True,
129
+ # char_width_px populated below from extracted widths (median).
130
+ "char_width_px": 0.0,
131
+ },
132
+ }
133
+
134
+
135
+ def extract_one(slug: str) -> Path:
136
+ """Extract one font to ``data/font-metrics/{slug}.json``."""
137
+ if slug not in FONT_CONFIGS:
138
+ raise ValueError(f"Unknown font slug '{slug}'. Known: {sorted(FONT_CONFIGS)}")
139
+ config = FONT_CONFIGS[slug]
140
+ b64_path = FONTS_DIR / f"{slug}.b64"
141
+ if not b64_path.exists():
142
+ raise FileNotFoundError(f"Missing font source: {b64_path}")
143
+
144
+ font = load_font_from_b64(b64_path)
145
+ baseline = int(config["baseline_size_px"])
146
+ widths = extract_widths(font, baseline)
147
+
148
+ char_width_px = float(config["char_width_px"])
149
+ is_mono = bool(config["is_monospace"])
150
+ if is_mono and char_width_px == 0.0 and widths:
151
+ # Monospace: all chars have the same advance; pick the first mapped width.
152
+ advance_tenths = next(iter(widths.values()))
153
+ char_width_px = advance_tenths / 10.0
154
+
155
+ data = emit_metrics_json(
156
+ family=str(config["family"]),
157
+ baseline_size_px=baseline,
158
+ widths=widths,
159
+ bold_expansion_factor=float(config["bold_expansion_factor"]),
160
+ aliases=list(config["aliases"]), # type: ignore[arg-type]
161
+ is_monospace=is_mono,
162
+ char_width_px=char_width_px,
163
+ )
164
+
165
+ out_path = METRICS_DIR / f"{slug}.json"
166
+ METRICS_DIR.mkdir(parents=True, exist_ok=True)
167
+ out_path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n")
168
+ return out_path
169
+
170
+
171
+ def main() -> int:
172
+ parser = argparse.ArgumentParser(description=__doc__)
173
+ parser.add_argument("slugs", nargs="*", help="Font slugs to extract (e.g. orbitron jetbrains-mono).")
174
+ parser.add_argument("--all", action="store_true", help="Extract every font in FONT_CONFIGS.")
175
+ args = parser.parse_args()
176
+
177
+ if args.all:
178
+ slugs = sorted(FONT_CONFIGS.keys())
179
+ elif args.slugs:
180
+ slugs = args.slugs
181
+ else:
182
+ parser.print_help()
183
+ return 1
184
+
185
+ for slug in slugs:
186
+ out = extract_one(slug)
187
+ sys.stdout.write(f" wrote {out.relative_to(ROOT)}\n")
188
+ return 0
189
+
190
+
191
+ if __name__ == "__main__":
192
+ sys.exit(main())
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.2.4'
22
- __version_tuple__ = version_tuple = (0, 2, 4)
21
+ __version__ = version = '0.2.6'
22
+ __version_tuple__ = version_tuple = (0, 2, 6)
23
23
 
24
24
  __commit_id__ = commit_id = None