hyperweave 0.2.5__tar.gz → 0.2.7__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.
- {hyperweave-0.2.5 → hyperweave-0.2.7}/.gitignore +0 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/CHANGELOG.md +59 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/PKG-INFO +8 -2
- {hyperweave-0.2.5 → hyperweave-0.2.7}/README.md +6 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/pyproject.toml +5 -0
- hyperweave-0.2.7/scripts/extract_font_metrics.py +192 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/_version.py +2 -2
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/context.py +2 -2
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/resolver.py +176 -145
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/resolvers/chart.py +13 -5
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/resolvers/stats.py +60 -11
- hyperweave-0.2.7/src/hyperweave/compose/rhythm.py +109 -0
- hyperweave-0.2.7/src/hyperweave/compose/validate_paradigms.py +58 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/config/loader.py +34 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/config/registry.py +9 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/config/settings.py +5 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/connectors/github.py +19 -8
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/contracts.py +3 -3
- hyperweave-0.2.7/src/hyperweave/core/font_metrics.py +114 -0
- hyperweave-0.2.7/src/hyperweave/core/paradigm.py +120 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/schema.py +0 -12
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/state.py +6 -0
- hyperweave-0.2.7/src/hyperweave/core/text.py +65 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/font-metrics/inter.json +3 -0
- hyperweave-0.2.7/src/hyperweave/data/font-metrics/jetbrains-mono.json +113 -0
- hyperweave-0.2.7/src/hyperweave/data/font-metrics/orbitron.json +108 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/genomes/chrome-horizon.json +0 -6
- hyperweave-0.2.7/src/hyperweave/data/paradigms/brutalist.yaml +42 -0
- hyperweave-0.2.7/src/hyperweave/data/paradigms/chrome.yaml +54 -0
- hyperweave-0.2.7/src/hyperweave/data/paradigms/default.yaml +46 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/profiles/chrome.contract.json +0 -2
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/mcp/server.py +22 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/render/chart_engine.py +61 -90
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/contract.py +1 -1
- hyperweave-0.2.7/src/hyperweave/templates/components/chart-markers/circle.svg.j2 +2 -0
- hyperweave-0.2.7/src/hyperweave/templates/components/chart-markers/diamond.svg.j2 +7 -0
- hyperweave-0.2.7/src/hyperweave/templates/components/chart-markers/endpoint-diamond.svg.j2 +14 -0
- hyperweave-0.2.7/src/hyperweave/templates/components/chart-markers/endpoint-rect.svg.j2 +12 -0
- hyperweave-0.2.7/src/hyperweave/templates/components/chart-markers/rect.svg.j2 +12 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/treemap.svg.j2 +2 -2
- hyperweave-0.2.7/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +9 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/badge/chrome-content.j2 +1 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/badge/chrome-defs.j2 +6 -10
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/banner/brutalist-defs.j2 +2 -1
- hyperweave-0.2.7/src/hyperweave/templates/frames/banner/chrome-content.j2 +80 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/banner/chrome-defs.j2 +4 -4
- hyperweave-0.2.7/src/hyperweave/templates/frames/banner/default-content.j2 +114 -0
- hyperweave-0.2.7/src/hyperweave/templates/frames/banner.svg.j2 +23 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/chart/brutalist-content.j2 +6 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/chart/chrome-content.j2 +27 -15
- hyperweave-0.2.7/src/hyperweave/templates/frames/chart/chrome-defs.j2 +141 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/icon/chrome-content.j2 +4 -4
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/icon/chrome-defs.j2 +4 -4
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-counter/chrome-content.j2 +1 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-counter/chrome-defs.j2 +2 -2
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-counter.svg.j2 +4 -4
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-content.j2 +1 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-defs.j2 +7 -7
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-horizontal.svg.j2 +6 -6
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-vertical/chrome-content.j2 +1 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-vertical/chrome-defs.j2 +6 -6
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-vertical.svg.j2 +7 -7
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/receipt.svg.j2 +7 -1
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/stats/chrome-content.j2 +31 -16
- hyperweave-0.2.7/src/hyperweave/templates/frames/stats/chrome-defs.j2 +96 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/brutalist-defs.j2 +4 -1
- hyperweave-0.2.7/src/hyperweave/templates/frames/strip/chrome-content.j2 +33 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/chrome-defs.j2 +6 -6
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip.svg.j2 +9 -7
- hyperweave-0.2.7/tests/helpers.py +58 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_chart_engine.py +59 -30
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_chart_frame.py +5 -5
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_connectors.py +122 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_core.py +36 -2
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_mcp.py +23 -0
- hyperweave-0.2.7/tests/test_paradigm_extensibility.py +157 -0
- hyperweave-0.2.7/tests/test_resolver_rhythm.py +158 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_state_inference.py +22 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_telemetry.py +3 -3
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_telemetry_integration.py +237 -2
- {hyperweave-0.2.5 → hyperweave-0.2.7}/uv.lock +83 -0
- hyperweave-0.2.5/src/hyperweave/core/text.py +0 -152
- hyperweave-0.2.5/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +0 -5
- hyperweave-0.2.5/src/hyperweave/templates/frames/banner.svg.j2 +0 -224
- hyperweave-0.2.5/src/hyperweave/templates/frames/chart/chrome-defs.j2 +0 -154
- hyperweave-0.2.5/src/hyperweave/templates/frames/stats/chrome-defs.j2 +0 -133
- hyperweave-0.2.5/src/hyperweave/templates/frames/strip/chrome-content.j2 +0 -29
- {hyperweave-0.2.5 → hyperweave-0.2.7}/.dockerignore +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/.github/workflows/ci.yml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/.github/workflows/deploy.yml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/.github/workflows/publish.yml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/.pre-commit-config.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/Dockerfile +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/LICENSE +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/buttons/button-liquid.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/cards/card-butterfly.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/cards/card-python.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/cards/card-sunflower.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/cards/card-waves.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/badge_critical.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/badge_passing.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/badge_warning.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/banner.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/icons/discord.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/icons/notion.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/icons/reddit.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/icons/spotify.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/icons/youtube.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/marquee_counter.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/marquee_horizontal.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/marquee_vertical.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/profile-cards/stats.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/brutalist-emerald/strip.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/badge_critical.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/badge_passing.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/badge_warning.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/banner.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/icons/bluesky.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/icons/github.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/icons/instagram.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/icons/mastodon.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/icons/x.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/marquee_counter.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/marquee_horizontal.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/marquee_vertical.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/profile-cards/stats.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/chrome-horizon/strip.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/telemetry/master_card.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/telemetry/receipt.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/examples/telemetry/rhythm_strip.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/footers/inneraura-footer-liquid.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/footers/inneraura-footer-purple.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/footers/inneraura-footer.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-discord.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-docs.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-github.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-instagram.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-linkedin.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-tiktok.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-x.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/icons/cobalt-sapphire-youtube.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/marquees/badge-showcase-triple.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/marquees/genome-marquee-triple.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/marquees/sample-badges.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/404.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/callout-icons.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/divider.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/favicon.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/hero-banner.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/hyperweave-banner-v2.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/loader.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/mintlify-assets/og-image.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/assets/timelines/hyperweave-roadmap.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/assets/favicon.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/assets/og-image.svg +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/explanation/architecture.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/explanation/camo-compatibility.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/explanation/cim-compliance.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/explanation/genome-profile-system.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/explanation/metadata-tiers.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/how-to/add-motion-to-badges.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/how-to/create-session-receipts.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/how-to/set-up-claude-code-hooks.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/how-to/use-live-data-badges.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/introduction.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/mint.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/quickstart.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/reference/cli.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/reference/compose-spec.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/reference/genomes.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/reference/http-api.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/reference/mcp-tools.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/reference/motions.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/reference/telemetry-contract.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/spec/hyperweave-protocol.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/tutorials/build-an-artifact-kit.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/tutorials/compose-your-first-badge.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/docs/tutorials/install-session-telemetry.mdx +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/fly.toml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/hooks/install.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/hooks/session_end.sh +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/justfile +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/scripts/extract_glyphs.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/scripts/generate_hw_compliant.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/scripts/generate_proofset.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/scripts/stress_test.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/__main__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/cli.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/assembler.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/engine.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/lanes.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/resolvers/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/compose/resolvers/timeline.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/config/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/config/genome_validator.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/connectors/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/connectors/arxiv.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/connectors/base.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/connectors/cache.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/connectors/rest.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/color.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/enums.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/models.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/core/thresholds.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/css/accessibility.css +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/css/bridge.css +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/css/expression.css +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/css/phase-colors.css +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/css/status.css +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/css/telemetry.css +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/fonts/jetbrains-mono.b64 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/fonts/jetbrains-mono.meta.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/fonts/orbitron.b64 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/fonts/orbitron.meta.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/genomes/brutalist-emerald.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/genomes/telemetry-void.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/glyphs.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/border/chromatic-pulse.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/border/corner-trace.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/border/dual-orbit.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/border/entanglement.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/border/rimrun.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/bars.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/breach.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/broadcast.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/cascade.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/collapse.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/converge.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/crash.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/drop.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/kinetic/pulse.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/motions/static.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/policies/normal.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/policies/permissive.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/policies/ungoverned.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/profiles/brutalist.contract.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/profiles/brutalist.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/profiles/chrome.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/specimens.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/telemetry/model-pricing.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/telemetry/stage-config.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/telemetry/stage-labels.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/telemetry/tool-classes.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/telemetry/tool-colors.yaml +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/arrow.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/aurora.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/beacon.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/bracket3d.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/chevron.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/crosshair.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/diamond.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/rocket.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/rules/bar.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/rules/dashed.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/rules/five-wave.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/rules/spectral.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/rules/straight.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/rules/wave.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/data/terminals/stijl.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/kit.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/mcp/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/mcp/__main__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/py.typed +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/render/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/render/fonts.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/render/glyphs.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/render/motion.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/render/templates.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/serve/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/serve/app.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/capture.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/corrections.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/cost.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/models.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/parser.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/telemetry/stages.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/filter.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/glyph-inline.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/glyph.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/gradient.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/metadata.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/metric.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/phase-segment.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/rule.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/status.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/components/terminal.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/document.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/error-badge.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/badge/brutalist-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/badge/default-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/badge/default-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/badge.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/banner/default-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/catalog.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/chart/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/chart.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/divider.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/icon/brutalist-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/icon/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/icon/default-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/icon/default-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/icon.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-counter/brutalist-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-counter/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-vertical/brutalist-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/marquee-vertical/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/master-card.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/rhythm-strip.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/stats/brutalist-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/stats/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/stats.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/brutalist-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/brutalist-status.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/chrome-status.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/default-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/default-defs.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/strip/default-status.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/timeline/default-content.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/frames/timeline.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/border/chromatic-pulse.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/border/corner-trace.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/border/dual-orbit.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/border/entanglement.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/border/rimrun.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/bars.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/breach.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/broadcast.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/cascade.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/collapse.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/converge.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/crash.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/drop.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/src/hyperweave/templates/motions/kinetic/pulse.svg.j2 +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/__init__.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/conftest.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/fixtures/github_contributions/synthetic.html +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/fixtures/session.json +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/fixtures/session.jsonl +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_assembler.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_github_scrape.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_kit.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_paradigm_dispatch.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_proofset.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_render.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_serve.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_serve_live_state.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_stats_card.py +0 -0
- {hyperweave-0.2.5 → hyperweave-0.2.7}/tests/test_timeline.py +0 -0
|
@@ -5,6 +5,65 @@ 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.7] - 2026-04-20
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Star history charts now end at the current date.** On very large repositories (40k+ stars), GitHub caps stargazer pagination at roughly the first 40,000 stars, so the latest sample pulled from the API was often years old and the polyline terminated in the past. The chart now always appends a final data point stamped at the current time, while still reporting the real total star count. Small repos are unaffected.
|
|
13
|
+
- **Session receipt labels are honest again.** The "N corrections" line previously counted every user turn — any pushback, redirect, or elaboration — and rendered them next to tool-failure marks (`✗N`) on the token treemap, which created the impression that the two numbers should reconcile. They're now split into "N user turns" and "N tool errors", with tool-error counts tinted red to match the cell marks. A new legend — `✗N = failed tool calls` — appears above the token map so the red marks are self-explanatory.
|
|
14
|
+
- **Session receipt hero no longer misreports the dominant work phase.** The hero badge previously showed the label of the first detected stage, even when that stage lasted two minutes and a later stage dominated the session. It now uses the stage with the largest share of tool calls, and falls back to `MIXED` when no single stage exceeds 20%.
|
|
15
|
+
- **Rhythm bars stop overflowing their track on long sessions.** On sessions with many stages (~30+), the rightmost rhythm bar on the receipt could render hundreds of pixels past the track's right edge. Receipt and rhythm-strip now share a single layout routine with a proper gap budget and a post-hoc rescale, so bars always fit the track regardless of stage count.
|
|
16
|
+
- **Rhythm bars encode time, not tool-call share.** When the telemetry contract carries start and end timestamps per stage, bar widths are now proportional to stage duration, so the time-axis labels (`0m · 104m · 209m`) actually correspond to bar positions. Bar heights are now uniform; the previous height scaling was effectively noise because most bars hit the minimum-height floor.
|
|
17
|
+
- **Live badges now recognize `building` as a state.** A badge with `value="building"` (or `"rebuilding"` / `"build"`) now renders as the building state instead of falling through to the default `active`. Longer phrases containing the word "build" are not affected — only those three exact tokens.
|
|
18
|
+
- **Deploying `HW_GITHUB_TOKENS` no longer crashes the app.** A vestigial `github_tokens` field on the settings schema was trying to parse the environment variable as JSON on startup, so setting the plain comma-separated secret that the token-rotation code actually expects caused a 500. The field has been removed; the connector reads the secret directly, and plain comma-separated deployments now work as documented.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **`hw_discover` advertises the `stats`, `chart`, and `timeline` routes.** MCP clients calling `hw_discover(what="url_grammar")` now receive URL patterns, example URLs, and method hints for the three routes that shipped in v0.2.0 but were missing from discovery.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **Chart markers render through template partials.** Marker shapes (rect, circle, diamond, and their endpoint variants) now live as Jinja partials under `templates/components/chart-markers/`, matching how the rest of the rendering pipeline handles SVG. No visual change; output is byte-identical for the shipped genomes.
|
|
27
|
+
|
|
28
|
+
### Dev
|
|
29
|
+
|
|
30
|
+
- GitHub token pool rotation is now covered by unit tests (`HW_GITHUB_TOKENS` comma-separated list, `GITHUB_TOKEN` single-token fallback, whitespace tolerance, empty-env behavior).
|
|
31
|
+
|
|
32
|
+
## [0.2.6] - 2026-04-19
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- **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`.
|
|
37
|
+
- **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()`.
|
|
38
|
+
- **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.
|
|
39
|
+
- **Invariant 11** (CLAUDE.md Verify block): no specimen colors in template fallbacks. `grep "default('#"` in templates must be zero.
|
|
40
|
+
- **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.
|
|
41
|
+
- 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.
|
|
42
|
+
- `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.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **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.
|
|
47
|
+
- **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.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
- **`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.
|
|
52
|
+
- **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.
|
|
53
|
+
- **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.
|
|
54
|
+
- `_profile_visual_context` renamed to `_genome_material_context` — it has always read from `genome`, not `profile`.
|
|
55
|
+
- `measure_text` signature is now keyword-only after the leading `text` positional. `bold` and `monospace` kwargs removed.
|
|
56
|
+
|
|
57
|
+
### Removed
|
|
58
|
+
|
|
59
|
+
- `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.
|
|
60
|
+
- `font_scale` heuristic in the marquee row-width helper. Replaced by font-family-aware measurement.
|
|
61
|
+
- 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.
|
|
62
|
+
|
|
63
|
+
### Dev dependencies
|
|
64
|
+
|
|
65
|
+
- `fontTools` and `brotli` added so the font-metrics extraction script can decode WOFF2.
|
|
66
|
+
|
|
8
67
|
## [0.2.5] - 2026-04-13
|
|
9
68
|
|
|
10
69
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperweave
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.7
|
|
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
|
---
|
|
@@ -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
|
---
|
|
@@ -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",
|
|
@@ -78,6 +81,8 @@ dev = [
|
|
|
78
81
|
"mypy>=1.14",
|
|
79
82
|
"types-pyyaml>=6.0.12.20250915",
|
|
80
83
|
"pre-commit>=4.0",
|
|
84
|
+
"fonttools>=4.62.1",
|
|
85
|
+
"brotli>=1.2.0",
|
|
81
86
|
]
|
|
82
87
|
|
|
83
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.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
21
|
+
__version__ = version = '0.2.7'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 2, 7)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -341,7 +341,7 @@ def _ctx_chart(spec: ComposeSpec, resolved: ResolvedArtifact, css: dict[str, str
|
|
|
341
341
|
ctx["chart_gridlines"] = ""
|
|
342
342
|
ctx["chart_area"] = ""
|
|
343
343
|
ctx["chart_polyline"] = ""
|
|
344
|
-
ctx["chart_markers"] =
|
|
344
|
+
ctx["chart_markers"] = []
|
|
345
345
|
ctx["chart_milestones"] = ""
|
|
346
346
|
ctx["data_hw_status"] = "fresh"
|
|
347
347
|
ctx.update(resolved.frame_context)
|
|
@@ -371,7 +371,7 @@ def _ctx_stats(spec: ComposeSpec, resolved: ResolvedArtifact, css: dict[str, str
|
|
|
371
371
|
ctx["embedded_chart_defs"] = ""
|
|
372
372
|
ctx["embedded_chart_area"] = ""
|
|
373
373
|
ctx["embedded_chart_polyline"] = ""
|
|
374
|
-
ctx["embedded_chart_markers"] =
|
|
374
|
+
ctx["embedded_chart_markers"] = []
|
|
375
375
|
ctx.update(resolved.frame_context)
|
|
376
376
|
return ctx
|
|
377
377
|
|