hyperweave 0.3.6__tar.gz → 0.3.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.3.6 → hyperweave-0.3.7}/CHANGELOG.md +21 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/PKG-INFO +33 -18
- {hyperweave-0.3.6 → hyperweave-0.3.7}/README.md +30 -17
- {hyperweave-0.3.6 → hyperweave-0.3.7}/pyproject.toml +7 -2
- {hyperweave-0.3.6 → hyperweave-0.3.7}/scripts/generate_proofset.py +12 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/_version.py +2 -2
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/assembler.py +39 -53
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/context.py +177 -24
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/validate_paradigms.py +99 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/config/loader.py +46 -0
- hyperweave-0.3.7/src/hyperweave/data/font-embedding.yaml +75 -0
- hyperweave-0.3.7/src/hyperweave/render/fonts.py +126 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_chart_frame.py +5 -3
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_font_gating.py +68 -8
- hyperweave-0.3.7/tests/test_font_subsetting.py +240 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_paradigm_cellular.py +43 -14
- hyperweave-0.3.6/src/hyperweave/render/fonts.py +0 -48
- {hyperweave-0.3.6 → hyperweave-0.3.7}/.dockerignore +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/.github/workflows/ci.yml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/.github/workflows/deploy.yml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/.github/workflows/publish.yml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/.gitignore +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/.pre-commit-config.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/Dockerfile +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/LICENSE +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/buttons/button-liquid.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/cards/card-butterfly.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/cards/card-python.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/cards/card-sunflower.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/cards/card-waves.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/badge_critical.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/badge_passing.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/badge_warning.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/banner.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/discord.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/notion.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/reddit.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/spotify.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/youtube.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/marquee_counter.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/marquee_horizontal.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/marquee_vertical.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/profile-cards/stats.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/strip.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/badge_critical.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/badge_passing.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/badge_warning.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/banner.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/bluesky.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/github.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/instagram.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/mastodon.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/x.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/marquee_counter.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/marquee_horizontal.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/marquee_vertical.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/profile-cards/stats.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/chrome-horizon/strip.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/telemetry/master_card.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/telemetry/receipt.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/telemetry/receipt_claude-code_medium.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/telemetry/receipt_codex_large.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/telemetry/receipt_voltage_xlarge.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/telemetry/rhythm_strip.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/examples/telemetry/rhythm_strip_voltage_xlarge.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/footers/inneraura-footer-liquid.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/footers/inneraura-footer-purple.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/footers/inneraura-footer.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-discord.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-docs.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-github.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-instagram.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-linkedin.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-tiktok.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-x.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-youtube.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/marquees/badge-showcase-triple.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/marquees/genome-marquee-triple.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/marquees/sample-badges.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/404.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/callout-icons.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/divider.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/favicon.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/hero-banner.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/hyperweave-banner-v2.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/loader.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/mintlify-assets/og-image.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/assets/timelines/hyperweave-roadmap.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/assets/favicon.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/assets/og-image.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/explanation/architecture.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/explanation/camo-compatibility.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/explanation/cim-compliance.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/explanation/genome-profile-system.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/explanation/metadata-tiers.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/how-to/add-motion-to-badges.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/how-to/create-session-receipts.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/how-to/set-up-claude-code-hooks.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/how-to/use-live-data-badges.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/introduction.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/mint.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/quickstart.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/reference/cli.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/reference/compose-spec.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/reference/genomes.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/reference/http-api.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/reference/mcp-tools.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/reference/motions.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/reference/telemetry-contract.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/spec/hyperweave-protocol.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/tutorials/build-an-artifact-kit.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/tutorials/compose-your-first-badge.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/docs/tutorials/install-session-telemetry.mdx +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/fly.toml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/hooks/install.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/hooks/session_end.sh +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/justfile +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/scripts/extract_font_metrics.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/scripts/extract_glyphs.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/scripts/probe_live_stats.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/scripts/probe_star_history.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/scripts/stress_test.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/__main__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/cli.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/bar_chart.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/engine.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/lanes.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/layout.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/palette.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/reasoning.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/resolver.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/resolvers/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/resolvers/chart.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/resolvers/stats.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/rhythm.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/rhythm_strip.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/compose/treemap.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/config/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/config/genome_validator.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/config/registry.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/config/settings.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/connectors/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/connectors/arxiv.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/connectors/base.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/connectors/cache.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/connectors/github.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/connectors/rest.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/cell_layout.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/color.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/contracts.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/enums.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/font_metrics.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/models.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/paradigm.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/schema.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/state.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/text.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/core/thresholds.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/badge_modes.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/css/accessibility.css +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/css/bridge.css +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/css/expression.css +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/css/status.css +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/chakra-petch.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/inter.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/jetbrains-mono.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/orbitron.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-700.b64 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-700.meta.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-900.b64 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-900.meta.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/chakra-petch.b64 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/chakra-petch.meta.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/jetbrains-mono.b64 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/jetbrains-mono.meta.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/orbitron.b64 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/fonts/orbitron.meta.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/genomes/automata.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/genomes/brutalist.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/genomes/chrome.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-claude-code.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-codex.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-cream.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-voltage.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/glyphs.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/chromatic-pulse.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/corner-trace.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/dual-orbit.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/entanglement.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/rimrun.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/motions/static.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/brutalist.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/cellular.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/chrome.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/default.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/policies/normal.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/policies/permissive.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/policies/ungoverned.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/profiles/brutalist.contract.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/profiles/brutalist.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/profiles/chrome.contract.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/profiles/chrome.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/reasoning/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/reasoning/brutalist.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/specimens.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/model-pricing.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/runtimes/claude-code.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/runtimes/codex.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/stage-config.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/stage-labels.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/tool-colors.yaml +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/arrow.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/aurora.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/beacon.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/bracket3d.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/chevron.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/crosshair.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/diamond.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rocket.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/bar.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/dashed.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/five-wave.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/spectral.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/straight.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/wave.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/data/terminals/stijl.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/kit.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/mcp/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/mcp/__main__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/mcp/server.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/py.typed +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/render/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/render/chart_engine.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/render/glyphs.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/render/motion.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/render/templates.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/serve/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/serve/app.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/serve/data_tokens.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/capture.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/codex_parser.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/contract.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/corrections.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/cost.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/models.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/parser.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/receipt_paths.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/runtimes.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/telemetry/stages.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-area.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-axes.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-empty-state.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-gridlines.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/circle.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/diamond.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/endpoint-diamond.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/endpoint-rect.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/rect.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-milestone-brutalist.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-milestone.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-polyline.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/filter.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/glyph-inline.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/glyph.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/gradient.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/metadata.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/metric.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/phase-segment.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/rule.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/status.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/components/terminal.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/document.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/error-badge.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/cellular-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/cellular-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/chrome-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/chrome-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/default-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/default-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/catalog.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/cellular-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/cellular-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/chrome-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/chrome-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/divider/brutalist-seam.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/divider/chrome-band.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/divider.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/brutalist-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/cellular-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/cellular-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/chrome-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/chrome-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/default-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/default-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-overlay.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/cellular-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/cellular-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/cellular-overlay.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-overlay.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/default-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/default-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/master-card.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/receipt.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/rhythm-strip.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/cellular-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/cellular-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/chrome-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/chrome-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-status.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/cellular-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/cellular-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/cellular-status.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/chrome-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/chrome-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/chrome-status.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/default-content.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/default-defs.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/default-status.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/chromatic-pulse.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/corner-trace.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/dual-orbit.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/entanglement.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/rimrun.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/partials/provider-glyphs.svg.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/src/hyperweave/templates/partials/state-signal-cascade.j2 +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/__init__.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/conftest.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/fixtures/codex_session.jsonl +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/fixtures/codex_session_patches.jsonl +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/fixtures/github_contributions/synthetic.html +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/fixtures/session.json +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/fixtures/session.jsonl +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/fixtures/synthetic_session.jsonl +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/helpers.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/snapshots/url_stability/divider_band_chrome_static.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/snapshots/url_stability/icon_github_chrome_static.svg +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_assembler.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_badge_brutalist_dark.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_badge_cellular.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_badge_layout.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_badge_mode.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_chart_engine.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_chromatic_coverage_validator.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_chrome_variants.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_codex_parser.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_compose_bar_chart.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_compose_rhythm_strip.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_compose_treemap.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_compose_variant_field.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_connectors.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_core.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_data_tokens.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_divider_cellular.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_divider_genome_specific.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_doctor.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_font_metrics_chakra.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_genome_automata.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_github_scrape.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_install_hook.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_kit.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_marquee_v0_2_16.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_mcp.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_paradigm_dispatch.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_paradigm_extensibility.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_parse_transcript_auto.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_proofset.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_receipt_paths.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_receipt_token_compliance.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_render.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_resolver_rhythm.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_runtime_registries.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_serve.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_serve_live_state.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_slot_metric_state.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_state_inference.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_stats_brutalist.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_stats_card.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_strip_brutalist_grammar.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_strip_cellular.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_strip_status_toggle.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_telemetry.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_telemetry_contract_per_stage.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_telemetry_integration.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_telemetry_skin_dispatch.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_tool_class_completeness.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_url_stability.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/tests/test_variant_default_resolution.py +0 -0
- {hyperweave-0.3.6 → hyperweave-0.3.7}/uv.lock +4 -4
|
@@ -5,6 +5,27 @@ All notable changes to HyperWeave are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.7] - 2026-05-18
|
|
9
|
+
|
|
10
|
+
Font payloads now embed only the characters each artifact actually renders, and fonts an artifact never displays are no longer embedded at all. Across every text-bearing artifact type — badges, strips, stats cards, star charts, marquees, receipts, and rhythm strips — and across all three genomes, gzip size drops by an average of 59% per artifact.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Brutalist badge embedding** — single JetBrains Mono `@font-face` block. Barlow Condensed embeds only in stats, strips, and charts.
|
|
15
|
+
- **Automata badge embedding** — Orbitron + Chakra Petch only. JetBrains Mono no longer ships in badges since no badge text uses it.
|
|
16
|
+
- **Automata chart embedding** — Orbitron + JetBrains Mono only. Chakra Petch dropped since no chart text uses it.
|
|
17
|
+
- **Per-genome, per-frame embed list** — `data/font-embedding.yaml` declares which fonts ship for each genome-and-artifact combination. Adding a font is a single YAML edit, no Python changes.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Codex Stop hook crash on receipt render** — `fonttools` and `brotli` are now runtime dependencies, so `uv tool install` users no longer hit `ModuleNotFoundError: fontTools` when the hook fires.
|
|
22
|
+
|
|
23
|
+
### Notes
|
|
24
|
+
|
|
25
|
+
- Repeat renders of the same text reuse a cached subset, so the first request pays the subsetting cost and subsequent requests don't.
|
|
26
|
+
- CJK locale font embedding deferred to a future release.
|
|
27
|
+
- Icons and dividers continue to embed zero fonts.
|
|
28
|
+
|
|
8
29
|
## [0.3.6] - 2026-05-18
|
|
9
30
|
|
|
10
31
|
Receipt active-duration sources from per-turn compute when the runtime emits it; long-running sessions no longer inflate via stage-span summation. Codex hooks migrate to the wrapped-matcher GA layout shipped in the Codex CLI v0.129 release. The `data-hw-genome` root attribute reflects the resolved genome ID instead of raw spec input.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperweave
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.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
|
|
@@ -19,8 +19,10 @@ Classifier: Topic :: Multimedia :: Graphics
|
|
|
19
19
|
Classifier: Topic :: Software Development :: Libraries
|
|
20
20
|
Classifier: Typing :: Typed
|
|
21
21
|
Requires-Python: >=3.12
|
|
22
|
+
Requires-Dist: brotli>=1.2.0
|
|
22
23
|
Requires-Dist: fastapi>=0.115
|
|
23
24
|
Requires-Dist: fastmcp>=3.0
|
|
25
|
+
Requires-Dist: fonttools>=4.62.1
|
|
24
26
|
Requires-Dist: httpx[http2]>=0.28
|
|
25
27
|
Requires-Dist: jinja2>=3.1
|
|
26
28
|
Requires-Dist: pydantic-settings>=2.0
|
|
@@ -241,11 +243,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
241
243
|
<tr>
|
|
242
244
|
<th align="left">Icons<br/><sub>circle + square</sub></th>
|
|
243
245
|
<td>
|
|
244
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
245
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
246
|
+
<img src="https://hyperweave.app/v1/icon/spotify/brutalist.static?shape=circle&variant=celadon" alt="spotify — celadon" width="56"/>
|
|
247
|
+
<img src="https://hyperweave.app/v1/icon/github/brutalist.static?shape=circle&variant=carbon" alt="github — carbon" width="56"/>
|
|
246
248
|
<img src="https://hyperweave.app/v1/icon/docker/brutalist.static?shape=circle&variant=alloy" alt="docker — alloy" width="56"/>
|
|
247
249
|
<img src="https://hyperweave.app/v1/icon/npm/brutalist.static?shape=square&variant=temper" alt="npm — temper" width="56"/>
|
|
248
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
250
|
+
<img src="https://hyperweave.app/v1/icon/discord/brutalist.static?shape=square&variant=pigment" alt="discord — pigment" width="56"/>
|
|
249
251
|
<img src="https://hyperweave.app/v1/icon/anthropic/brutalist.static?shape=square&variant=ember" alt="anthropic — ember" width="56"/>
|
|
250
252
|
<br/>
|
|
251
253
|
<ul>
|
|
@@ -269,11 +271,23 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
269
271
|
<h3 id="automata">automata</h3>
|
|
270
272
|
|
|
271
273
|
<p align="center">
|
|
272
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
273
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
274
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
275
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
276
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
274
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=violet&size=compact" alt="PYPI — violet variant"/>
|
|
275
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=teal&size=compact" alt="PYPI — teal variant"/>
|
|
276
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=bone&size=compact" alt="PYPI — bone variant"/>
|
|
277
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=steel&size=compact" alt="PYPI — steel variant"/>
|
|
278
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=amber&size=compact" alt="PYPI — amber variant"/>
|
|
279
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=jade&size=compact" alt="PYPI — jade variant"/>
|
|
280
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=magenta&size=compact" alt="PYPI — magenta variant"/>
|
|
281
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=cobalt&size=compact" alt="PYPI — cobalt variant"/>
|
|
282
|
+
<br/>
|
|
283
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=toxic&size=compact" alt="PYPI — toxic variant"/>
|
|
284
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=solar&size=compact" alt="PYPI — solar variant"/>
|
|
285
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=abyssal&size=compact" alt="PYPI — abyssal variant"/>
|
|
286
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=crimson&size=compact" alt="PYPI — crimson variant"/>
|
|
287
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=sulfur&size=compact" alt="PYPI — sulfur variant"/>
|
|
288
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=indigo&size=compact" alt="PYPI — indigo variant"/>
|
|
289
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=burgundy&size=compact" alt="PYPI — burgundy variant"/>
|
|
290
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=copper&size=compact" alt="PYPI — copper variant"/>
|
|
277
291
|
</p>
|
|
278
292
|
|
|
279
293
|
<p align="center">
|
|
@@ -370,11 +384,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
370
384
|
<h3 id="chrome">chrome</h3>
|
|
371
385
|
|
|
372
386
|
<p align="center">
|
|
373
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
374
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
375
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
376
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
377
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
387
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=horizon" alt="PYPI — horizon variant"/>
|
|
388
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=abyssal" alt="PYPI — abyssal variant"/>
|
|
389
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=lightning" alt="PYPI — lightning variant"/>
|
|
390
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=graphite" alt="PYPI — graphite variant"/>
|
|
391
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=moth" alt="PYPI — moth variant"/>
|
|
378
392
|
</p>
|
|
379
393
|
|
|
380
394
|
<p align="center">
|
|
@@ -442,10 +456,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
442
456
|
<tr>
|
|
443
457
|
<th align="left">Icons<br/><sub>circle + square</sub></th>
|
|
444
458
|
<td>
|
|
445
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
446
|
-
<img src="https://hyperweave.app/v1/icon/notion/chrome.static?shape=circle&variant=
|
|
447
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
448
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
459
|
+
<img src="https://hyperweave.app/v1/icon/github/chrome.static?shape=circle&variant=horizon" alt="github — horizon" width="56"/>
|
|
460
|
+
<img src="https://hyperweave.app/v1/icon/notion/chrome.static?shape=circle&variant=graphite" alt="notion — graphite" width="56"/>
|
|
461
|
+
<img src="https://hyperweave.app/v1/icon/rust/chrome.static?shape=square&variant=moth" alt="rust — moth" width="56"/>
|
|
462
|
+
<img src="https://hyperweave.app/v1/icon/docker/chrome.static?shape=square&variant=lightning" alt="docker — lightning" width="56"/>
|
|
463
|
+
<img src="https://hyperweave.app/v1/icon/spotify/chrome.static?shape=square&variant=abyssal" alt="spotify — abyssal" width="56"/>
|
|
449
464
|
<br/>
|
|
450
465
|
<ul>
|
|
451
466
|
<li><sub><code>/v1/icon/{glyph}/{genome}.static?shape={circle|square}&variant={variant}</code></sub></li>
|
|
@@ -209,11 +209,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
209
209
|
<tr>
|
|
210
210
|
<th align="left">Icons<br/><sub>circle + square</sub></th>
|
|
211
211
|
<td>
|
|
212
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
213
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
212
|
+
<img src="https://hyperweave.app/v1/icon/spotify/brutalist.static?shape=circle&variant=celadon" alt="spotify — celadon" width="56"/>
|
|
213
|
+
<img src="https://hyperweave.app/v1/icon/github/brutalist.static?shape=circle&variant=carbon" alt="github — carbon" width="56"/>
|
|
214
214
|
<img src="https://hyperweave.app/v1/icon/docker/brutalist.static?shape=circle&variant=alloy" alt="docker — alloy" width="56"/>
|
|
215
215
|
<img src="https://hyperweave.app/v1/icon/npm/brutalist.static?shape=square&variant=temper" alt="npm — temper" width="56"/>
|
|
216
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
216
|
+
<img src="https://hyperweave.app/v1/icon/discord/brutalist.static?shape=square&variant=pigment" alt="discord — pigment" width="56"/>
|
|
217
217
|
<img src="https://hyperweave.app/v1/icon/anthropic/brutalist.static?shape=square&variant=ember" alt="anthropic — ember" width="56"/>
|
|
218
218
|
<br/>
|
|
219
219
|
<ul>
|
|
@@ -237,11 +237,23 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
237
237
|
<h3 id="automata">automata</h3>
|
|
238
238
|
|
|
239
239
|
<p align="center">
|
|
240
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
241
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
242
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
243
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
244
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
240
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=violet&size=compact" alt="PYPI — violet variant"/>
|
|
241
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=teal&size=compact" alt="PYPI — teal variant"/>
|
|
242
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=bone&size=compact" alt="PYPI — bone variant"/>
|
|
243
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=steel&size=compact" alt="PYPI — steel variant"/>
|
|
244
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=amber&size=compact" alt="PYPI — amber variant"/>
|
|
245
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=jade&size=compact" alt="PYPI — jade variant"/>
|
|
246
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=magenta&size=compact" alt="PYPI — magenta variant"/>
|
|
247
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=cobalt&size=compact" alt="PYPI — cobalt variant"/>
|
|
248
|
+
<br/>
|
|
249
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=toxic&size=compact" alt="PYPI — toxic variant"/>
|
|
250
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=solar&size=compact" alt="PYPI — solar variant"/>
|
|
251
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=abyssal&size=compact" alt="PYPI — abyssal variant"/>
|
|
252
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=crimson&size=compact" alt="PYPI — crimson variant"/>
|
|
253
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=sulfur&size=compact" alt="PYPI — sulfur variant"/>
|
|
254
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=indigo&size=compact" alt="PYPI — indigo variant"/>
|
|
255
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=burgundy&size=compact" alt="PYPI — burgundy variant"/>
|
|
256
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/automata.static?data=pypi:hyperweave.version&glyph=python&variant=copper&size=compact" alt="PYPI — copper variant"/>
|
|
245
257
|
</p>
|
|
246
258
|
|
|
247
259
|
<p align="center">
|
|
@@ -338,11 +350,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
338
350
|
<h3 id="chrome">chrome</h3>
|
|
339
351
|
|
|
340
352
|
<p align="center">
|
|
341
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
342
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
343
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
344
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
345
|
-
<img src="https://hyperweave.app/v1/badge/
|
|
353
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=horizon" alt="PYPI — horizon variant"/>
|
|
354
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=abyssal" alt="PYPI — abyssal variant"/>
|
|
355
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=lightning" alt="PYPI — lightning variant"/>
|
|
356
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=graphite" alt="PYPI — graphite variant"/>
|
|
357
|
+
<img src="https://hyperweave.app/v1/badge/PYPI/chrome.static?data=pypi:hyperweave.version&glyph=python&variant=moth" alt="PYPI — moth variant"/>
|
|
346
358
|
</p>
|
|
347
359
|
|
|
348
360
|
<p align="center">
|
|
@@ -410,10 +422,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
410
422
|
<tr>
|
|
411
423
|
<th align="left">Icons<br/><sub>circle + square</sub></th>
|
|
412
424
|
<td>
|
|
413
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
414
|
-
<img src="https://hyperweave.app/v1/icon/notion/chrome.static?shape=circle&variant=
|
|
415
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
416
|
-
<img src="https://hyperweave.app/v1/icon/
|
|
425
|
+
<img src="https://hyperweave.app/v1/icon/github/chrome.static?shape=circle&variant=horizon" alt="github — horizon" width="56"/>
|
|
426
|
+
<img src="https://hyperweave.app/v1/icon/notion/chrome.static?shape=circle&variant=graphite" alt="notion — graphite" width="56"/>
|
|
427
|
+
<img src="https://hyperweave.app/v1/icon/rust/chrome.static?shape=square&variant=moth" alt="rust — moth" width="56"/>
|
|
428
|
+
<img src="https://hyperweave.app/v1/icon/docker/chrome.static?shape=square&variant=lightning" alt="docker — lightning" width="56"/>
|
|
429
|
+
<img src="https://hyperweave.app/v1/icon/spotify/chrome.static?shape=square&variant=abyssal" alt="spotify — abyssal" width="56"/>
|
|
417
430
|
<br/>
|
|
418
431
|
<ul>
|
|
419
432
|
<li><sub><code>/v1/icon/{glyph}/{genome}.static?shape={circle|square}&variant={variant}</code></sub></li>
|
|
@@ -42,6 +42,13 @@ dependencies = [
|
|
|
42
42
|
"httpx[http2]>=0.28",
|
|
43
43
|
"fastmcp>=3.0",
|
|
44
44
|
"pyyaml>=6.0",
|
|
45
|
+
# Font subsetting (v0.3.7). Runtime — not dev-only — because
|
|
46
|
+
# render/fonts.py imports fontTools at module top-level, which
|
|
47
|
+
# executes on every receipt render. brotli is the WOFF2 codec
|
|
48
|
+
# fontTools uses inside font.save(flavor="woff2") and must be
|
|
49
|
+
# importable on every install (uv tool install, pip install, etc.).
|
|
50
|
+
"fonttools>=4.62.1",
|
|
51
|
+
"brotli>=1.2.0",
|
|
45
52
|
]
|
|
46
53
|
|
|
47
54
|
[project.urls]
|
|
@@ -81,8 +88,6 @@ dev = [
|
|
|
81
88
|
"mypy>=1.14",
|
|
82
89
|
"types-pyyaml>=6.0.12.20250915",
|
|
83
90
|
"pre-commit>=4.0",
|
|
84
|
-
"fonttools>=4.62.1",
|
|
85
|
-
"brotli>=1.2.0",
|
|
86
91
|
]
|
|
87
92
|
|
|
88
93
|
[tool.pytest.ini_options]
|
|
@@ -1691,6 +1691,18 @@ def main() -> None:
|
|
|
1691
1691
|
parser.add_argument("--live", action="store_true", help="Include network-dependent artifacts")
|
|
1692
1692
|
args = parser.parse_args()
|
|
1693
1693
|
|
|
1694
|
+
# Wipe outputs/proofset/ before regenerating so renamed/retired artifacts
|
|
1695
|
+
# (paired-variant pairings, telemetry size variants) don't carry stale
|
|
1696
|
+
# payloads forward and create false audit noise. READMEs live one level up
|
|
1697
|
+
# (outputs/README*.md) and are preserved.
|
|
1698
|
+
import shutil
|
|
1699
|
+
|
|
1700
|
+
proofset_dir = OUT / "proofset"
|
|
1701
|
+
if proofset_dir.exists():
|
|
1702
|
+
stale = sum(1 for _ in proofset_dir.rglob("*.svg"))
|
|
1703
|
+
shutil.rmtree(proofset_dir)
|
|
1704
|
+
print(f"Cleaned {stale} stale artifacts from {proofset_dir}")
|
|
1705
|
+
|
|
1694
1706
|
print("Generating static proof set...")
|
|
1695
1707
|
total = generate_static()
|
|
1696
1708
|
print(f" {total} static artifacts")
|
|
@@ -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.3.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 3,
|
|
21
|
+
__version__ = version = '0.3.7'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 3, 7)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -19,63 +19,49 @@ _BRIDGE_FRAMES: frozenset[str] = frozenset({FrameType.BADGE, FrameType.STRIP, Fr
|
|
|
19
19
|
# Marquee frame types — need frame_fill, status colors, ink tiers
|
|
20
20
|
_MARQUEE_FRAMES: frozenset[str] = frozenset({FrameType.MARQUEE_HORIZONTAL})
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
# Slugs match the keys in ``data/fonts/{slug}.b64`` and the entries in genome
|
|
30
|
-
# ``fonts`` lists. The intersection of the genome's font list and a frame's
|
|
31
|
-
# allowed slugs is what actually gets embedded.
|
|
22
|
+
|
|
23
|
+
# Font embedding gate: per-(genome_id, frame_type) lookup against the YAML
|
|
24
|
+
# config at ``data/font-embedding.yaml``. Replaces the v0.3.5 frozenset
|
|
25
|
+
# table that was keyed only by frame_type — which meant the brutalist
|
|
26
|
+
# badge embedded the genome's full font list (~28KB of unused Barlow
|
|
27
|
+
# Condensed base64) because the genome declared Barlow for stats/strip/
|
|
28
|
+
# chart and the badge frame's allowlist passed it through.
|
|
32
29
|
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
_TELEMETRY_FONTS: frozenset[str] = frozenset({"jetbrains-mono", "orbitron", "chakra-petch"})
|
|
50
|
-
|
|
51
|
-
_NEEDS_FONTS: dict[str, frozenset[str]] = {
|
|
52
|
-
FrameType.BADGE: _BRUTALIST_FONTS,
|
|
53
|
-
FrameType.STRIP: _BRUTALIST_FONTS,
|
|
54
|
-
FrameType.STATS: _BRUTALIST_FONTS,
|
|
55
|
-
FrameType.CHART: _CHART_FONTS,
|
|
56
|
-
FrameType.MARQUEE_HORIZONTAL: frozenset({"orbitron"}),
|
|
57
|
-
FrameType.RECEIPT: _TELEMETRY_FONTS,
|
|
58
|
-
FrameType.RHYTHM_STRIP: _TELEMETRY_FONTS,
|
|
59
|
-
FrameType.MASTER_CARD: _TELEMETRY_FONTS,
|
|
60
|
-
FrameType.CATALOG: _TELEMETRY_FONTS,
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def frame_needs_fonts(frame_type: str) -> bool:
|
|
65
|
-
"""Per-frame font-loading gate. Returns True if any fonts should be
|
|
66
|
-
embedded for this frame type. Frames absent from the ``_NEEDS_FONTS`` dict
|
|
67
|
-
return False — icon and divider render glyph-only with no ``<text>``
|
|
68
|
-
elements, so embedding fonts in them is pure payload waste.
|
|
30
|
+
# The genome-aware lookup lets the brutalist badge embed only JetBrains
|
|
31
|
+
# Mono (the one font its CSS classes actually reference) while the
|
|
32
|
+
# brutalist stats card continues to embed all three fonts it needs.
|
|
33
|
+
# Adding a new (genome, frame) binding is a YAML edit only (Invariant 12).
|
|
34
|
+
def fonts_for_frame(frame_type: str, genome_id: str = "") -> frozenset[str]:
|
|
35
|
+
"""Return the font slugs to embed for ``(frame_type, genome_id)``.
|
|
36
|
+
|
|
37
|
+
When ``genome_id`` matches a row in ``font-embedding.yaml``'s
|
|
38
|
+
``genomes`` block, returns that row's per-frame list. Otherwise
|
|
39
|
+
falls back to ``defaults.<frame_type>`` — an empty list in v0.3.7,
|
|
40
|
+
matching icon/divider semantics for callers without resolved genome
|
|
41
|
+
context (e.g. ``_error_badge``).
|
|
42
|
+
|
|
43
|
+
The composer further intersects this with the genome's declared
|
|
44
|
+
``fonts`` list at ``compose/context.py:_load_font_faces``, so a slug
|
|
45
|
+
listed here that the genome does not declare is a noop.
|
|
69
46
|
"""
|
|
70
|
-
|
|
47
|
+
from hyperweave.config.loader import load_font_embedding
|
|
48
|
+
|
|
49
|
+
embedding = load_font_embedding()
|
|
50
|
+
genome_block = embedding["genomes"].get(genome_id) if genome_id else None
|
|
51
|
+
if isinstance(genome_block, dict) and frame_type in genome_block:
|
|
52
|
+
slugs = genome_block.get(frame_type) or []
|
|
53
|
+
else:
|
|
54
|
+
slugs = embedding["defaults"].get(frame_type) or []
|
|
55
|
+
return frozenset(slugs)
|
|
71
56
|
|
|
72
57
|
|
|
73
|
-
def
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
58
|
+
def frame_needs_fonts(frame_type: str, genome_id: str = "") -> bool:
|
|
59
|
+
"""Per-(frame_type, genome_id) font-loading gate. Returns True when
|
|
60
|
+
any fonts should be embedded — used by context-builder to gate the
|
|
61
|
+
``data-hw-fonts="self-contained"`` SVG-root attribute and the
|
|
62
|
+
``hw:css-modules`` debug comment.
|
|
63
|
+
"""
|
|
64
|
+
return bool(fonts_for_frame(frame_type, genome_id))
|
|
79
65
|
|
|
80
66
|
|
|
81
67
|
# Genome fields that signal a telemetry skin (presence-gates the tool-color CSS block)
|
|
@@ -95,27 +95,164 @@ def _compute_contrast_ratio(fg_hex: str, bg_hex: str) -> str:
|
|
|
95
95
|
return f"{ratio:.1f}:1"
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
def _load_font_faces(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
98
|
+
def _load_font_faces(
|
|
99
|
+
genome: dict[str, Any],
|
|
100
|
+
frame_type: str,
|
|
101
|
+
char_set: frozenset[str] | None = None,
|
|
102
|
+
) -> str:
|
|
103
|
+
"""Load embedded font CSS for ``(frame_type, genome.id)``.
|
|
104
|
+
|
|
105
|
+
Intersects the genome's declared ``fonts`` list with the per-(genome,
|
|
106
|
+
frame) allowlist returned by :func:`fonts_for_frame`. The allowlist
|
|
107
|
+
is genome-aware (v0.3.7): the brutalist badge embeds JetBrains Mono
|
|
108
|
+
only even though the brutalist genome declares Barlow Condensed for
|
|
109
|
+
its stats/strip/chart frames. Frames whose ``(genome, frame)`` row
|
|
110
|
+
is empty (icons, dividers, error badges) embed zero fonts.
|
|
111
|
+
|
|
112
|
+
When ``char_set`` is provided each surviving font is subset to only
|
|
113
|
+
the codepoints the artifact actually renders. ``None`` embeds full
|
|
114
|
+
fonts (legacy behavior, ``_error_badge``).
|
|
115
|
+
|
|
116
|
+
The intersection is order-preserving against the genome's declared
|
|
117
|
+
list so ``@font-face`` declarations render in genome-author intent
|
|
118
|
+
order.
|
|
110
119
|
"""
|
|
111
120
|
declared = genome.get("fonts") or ["jetbrains-mono"]
|
|
112
121
|
if not isinstance(declared, list):
|
|
113
122
|
declared = ["jetbrains-mono"]
|
|
114
|
-
|
|
123
|
+
genome_id = genome.get("id", "")
|
|
124
|
+
allowed = fonts_for_frame(frame_type, genome_id)
|
|
115
125
|
if not allowed:
|
|
116
126
|
return ""
|
|
117
127
|
filtered = [slug for slug in declared if slug in allowed]
|
|
118
|
-
return load_font_face_css(filtered)
|
|
128
|
+
return load_font_face_css(filtered, char_set)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# Per-frame text-field maps for glyph subsetting. Each entry lists the
|
|
132
|
+
# context keys whose string content reaches a rendered <text> element
|
|
133
|
+
# and therefore must be present in the font subset. Glyph SVG paths,
|
|
134
|
+
# reasoning metadata, ARIA strings, and version/created/contract_id
|
|
135
|
+
# render via different paths (paths render as <path>, metadata renders
|
|
136
|
+
# in <hw:*> blocks read by no browser font) and stay outside the
|
|
137
|
+
# extraction surface.
|
|
138
|
+
_TEXT_FIELDS_BY_FRAME: dict[str, tuple[str, ...]] = {
|
|
139
|
+
"badge": ("title", "value", "label", "description"),
|
|
140
|
+
"strip": ("title", "value", "label", "description"),
|
|
141
|
+
"stats": (
|
|
142
|
+
"stats_username",
|
|
143
|
+
"stats_bio",
|
|
144
|
+
"stats_repo_label",
|
|
145
|
+
"stars_display",
|
|
146
|
+
"stars_delta_display",
|
|
147
|
+
"commits_display",
|
|
148
|
+
"prs_display",
|
|
149
|
+
"issues_display",
|
|
150
|
+
"contrib_display",
|
|
151
|
+
"streak_display",
|
|
152
|
+
"languages",
|
|
153
|
+
"activity_bars",
|
|
154
|
+
),
|
|
155
|
+
"chart": (
|
|
156
|
+
"chart_repo",
|
|
157
|
+
"chart_title",
|
|
158
|
+
"chart_current_stars",
|
|
159
|
+
"chart_axes",
|
|
160
|
+
"chart_milestones",
|
|
161
|
+
"chart_empty_state",
|
|
162
|
+
),
|
|
163
|
+
"marquee-horizontal": ("scroll_items",),
|
|
164
|
+
"receipt": (
|
|
165
|
+
"hero_headline",
|
|
166
|
+
"hero_subline",
|
|
167
|
+
"hero_right_stats",
|
|
168
|
+
"treemap_legend",
|
|
169
|
+
"metadata_left",
|
|
170
|
+
"metadata_right",
|
|
171
|
+
"footer_left",
|
|
172
|
+
"footer_right",
|
|
173
|
+
"dominant_profile",
|
|
174
|
+
"phase_legend",
|
|
175
|
+
),
|
|
176
|
+
"rhythm-strip": (
|
|
177
|
+
"session_id_short",
|
|
178
|
+
"elapsed_label",
|
|
179
|
+
"token_summary",
|
|
180
|
+
"velocity_value",
|
|
181
|
+
"loop_label",
|
|
182
|
+
"loop_detail",
|
|
183
|
+
"profile_label",
|
|
184
|
+
"stages",
|
|
185
|
+
),
|
|
186
|
+
"master-card": (
|
|
187
|
+
"mc_title",
|
|
188
|
+
"mc_subtitle",
|
|
189
|
+
"mc_total_tokens",
|
|
190
|
+
"mc_total_cost",
|
|
191
|
+
"mc_sessions",
|
|
192
|
+
"mc_skills",
|
|
193
|
+
"session_entries",
|
|
194
|
+
"footer_left",
|
|
195
|
+
"footer_right",
|
|
196
|
+
),
|
|
197
|
+
"catalog": (
|
|
198
|
+
"catalog_title",
|
|
199
|
+
"catalog_subtitle",
|
|
200
|
+
"catalog_items",
|
|
201
|
+
"catalog_footer_left",
|
|
202
|
+
"catalog_footer_right",
|
|
203
|
+
),
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
# Conservative baseline character set. Always included even when the
|
|
207
|
+
# template's resolved text is sparse — covers axis tick labels, %
|
|
208
|
+
# suffixes, numeric formatters, paren-wrapped clarifiers, and unicode
|
|
209
|
+
# arrows / dots used in chrome/brutalist label glyphs.
|
|
210
|
+
_SAFE_BASELINE: frozenset[str] = frozenset(
|
|
211
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .:,;-_/·→×%+()[]" # noqa: RUF001 middle-dot / right-arrow / multiplication-sign are deliberate
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _collect_text(value: Any, chars: set[str]) -> None:
|
|
216
|
+
"""Recursively walk ``value`` and absorb every string codepoint into ``chars``.
|
|
217
|
+
|
|
218
|
+
Lists, tuples, and dicts (keys + values) are traversed; ``None`` and
|
|
219
|
+
non-string scalars (numbers, bools) are skipped. The recursive shape
|
|
220
|
+
keeps the collector resilient against future context-field additions
|
|
221
|
+
that wrap text in additional dict/list layers — a new ``chart_axes``
|
|
222
|
+
entry shape doesn't need a corresponding extractor edit.
|
|
223
|
+
"""
|
|
224
|
+
if value is None:
|
|
225
|
+
return
|
|
226
|
+
if isinstance(value, str):
|
|
227
|
+
chars.update(value)
|
|
228
|
+
return
|
|
229
|
+
if isinstance(value, list | tuple):
|
|
230
|
+
for item in value:
|
|
231
|
+
_collect_text(item, chars)
|
|
232
|
+
return
|
|
233
|
+
if isinstance(value, dict):
|
|
234
|
+
for k, v in value.items():
|
|
235
|
+
if isinstance(k, str):
|
|
236
|
+
chars.update(k)
|
|
237
|
+
_collect_text(v, chars)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _extract_char_set(ctx: dict[str, Any], frame_type: str) -> frozenset[str]:
|
|
241
|
+
"""Return the union of the safe baseline and every rendered text char.
|
|
242
|
+
|
|
243
|
+
Reads the per-frame text-field map at :data:`_TEXT_FIELDS_BY_FRAME`
|
|
244
|
+
and recursively flattens each context value to its component codepoints.
|
|
245
|
+
Frames not in the map fall back to the baseline only.
|
|
246
|
+
|
|
247
|
+
Run AFTER the per-frame builder populates ``ctx`` (which means the
|
|
248
|
+
resolver-emitted text fields like ``chart_milestones`` and
|
|
249
|
+
``stats_username`` are visible) — see the ordering note on
|
|
250
|
+
:func:`build_context`.
|
|
251
|
+
"""
|
|
252
|
+
chars: set[str] = set(_SAFE_BASELINE)
|
|
253
|
+
for field in _TEXT_FIELDS_BY_FRAME.get(frame_type, ()):
|
|
254
|
+
_collect_text(ctx.get(field), chars)
|
|
255
|
+
return frozenset(chars)
|
|
119
256
|
|
|
120
257
|
|
|
121
258
|
def build_context(
|
|
@@ -123,7 +260,17 @@ def build_context(
|
|
|
123
260
|
resolved: ResolvedArtifact,
|
|
124
261
|
css_bundle: dict[str, str],
|
|
125
262
|
) -> dict[str, Any]:
|
|
126
|
-
"""Dispatch to the per-frame context builder.
|
|
263
|
+
"""Dispatch to the per-frame context builder, then wire font subsetting.
|
|
264
|
+
|
|
265
|
+
Per-frame builders fill ``ctx`` with the safe defaults and then merge
|
|
266
|
+
``resolved.frame_context`` (resolver output: ``chart_milestones``,
|
|
267
|
+
``stats_username``, ``scroll_items[*].text``, etc.). Only after that
|
|
268
|
+
merge runs does the rendered text surface become observable — which is
|
|
269
|
+
why v0.3.7 moves the ``font_faces`` assignment OUT of ``_base_context``
|
|
270
|
+
and INTO this post-builder step. The extractor at :func:`_extract_char_set`
|
|
271
|
+
then walks the fully-populated ctx and the subsetter at
|
|
272
|
+
:func:`_load_font_faces` emits a payload tuned to the actual glyph set.
|
|
273
|
+
"""
|
|
127
274
|
_BUILDERS: dict[str, _CtxBuilder] = {
|
|
128
275
|
FrameType.BADGE: _ctx_badge,
|
|
129
276
|
FrameType.STRIP: _ctx_strip,
|
|
@@ -140,6 +287,10 @@ def build_context(
|
|
|
140
287
|
builder = _BUILDERS.get(spec.type, _ctx_badge)
|
|
141
288
|
ctx = builder(spec, resolved, css_bundle)
|
|
142
289
|
_inject_motion(ctx, spec, resolved)
|
|
290
|
+
genome_id = resolved.genome.get("id", "")
|
|
291
|
+
if frame_needs_fonts(spec.type, genome_id):
|
|
292
|
+
char_set = _extract_char_set(ctx, spec.type)
|
|
293
|
+
ctx["font_faces"] = _load_font_faces(resolved.genome, spec.type, char_set)
|
|
143
294
|
return ctx
|
|
144
295
|
|
|
145
296
|
|
|
@@ -168,7 +319,7 @@ def _base_context(
|
|
|
168
319
|
# surfaces here too so `grep "hw:css-modules"` across outputs/proofset/ can
|
|
169
320
|
# confirm fonts were correctly excluded for icons/dividers.
|
|
170
321
|
module_names = [k for k, v in css_bundle.items() if v]
|
|
171
|
-
if frame_needs_fonts(spec.type):
|
|
322
|
+
if frame_needs_fonts(spec.type, resolved.genome.get("id", "")):
|
|
172
323
|
module_names.append("fonts")
|
|
173
324
|
css_debug = f"/* hw:css-modules: {','.join(module_names)} */"
|
|
174
325
|
css_assembled = css_debug + "\n" + "\n".join(p for p in css_parts if p)
|
|
@@ -310,14 +461,16 @@ def _base_context(
|
|
|
310
461
|
# enforced at load time; missing entries return None and the metadata
|
|
311
462
|
# template emits empty hw:reasoning fields gracefully.
|
|
312
463
|
**_resolve_reasoning_context(spec, resolved),
|
|
313
|
-
# Embedded fonts (base64 @font-face CSS) —
|
|
314
|
-
#
|
|
315
|
-
#
|
|
316
|
-
#
|
|
317
|
-
#
|
|
318
|
-
#
|
|
319
|
-
#
|
|
320
|
-
|
|
464
|
+
# Embedded fonts (base64 @font-face CSS) — placeholder. The real
|
|
465
|
+
# assignment lands in build_context() AFTER the per-frame builder
|
|
466
|
+
# merges resolver text fields into ctx, so the glyph subsetter
|
|
467
|
+
# at _extract_char_set + _load_font_faces sees the full rendered
|
|
468
|
+
# text surface (chart milestone labels, stats username, marquee
|
|
469
|
+
# scroll items, etc.). Setting the empty default here keeps
|
|
470
|
+
# Jinja's StrictUndefined happy for any code path that bypasses
|
|
471
|
+
# build_context (none exist today, but the default is defense
|
|
472
|
+
# against future drift).
|
|
473
|
+
"font_faces": "",
|
|
321
474
|
}
|
|
322
475
|
return ctx, uid, artifact_id
|
|
323
476
|
|