hyperweave 0.3.2__tar.gz → 0.3.4__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.2 → hyperweave-0.3.4}/CHANGELOG.md +38 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/PKG-INFO +3 -3
- {hyperweave-0.3.2 → hyperweave-0.3.4}/README.md +2 -2
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/_version.py +2 -2
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/cli.py +266 -46
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/layout.py +72 -27
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/resolver.py +81 -16
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/models.py +11 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/paradigm.py +41 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/genomes/brutalist.json +36 -18
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/paradigms/brutalist.yaml +24 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/render/chart_engine.py +7 -1
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/receipt_paths.py +23 -13
- hyperweave-0.3.4/src/hyperweave/templates/components/chart-milestone-brutalist.svg.j2 +37 -0
- hyperweave-0.3.4/src/hyperweave/templates/frames/badge/brutalist-dark-content.j2 +95 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/brutalist-dark-content.j2 +15 -7
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/brutalist-defs.j2 +91 -9
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/brutalist-light-content.j2 +17 -7
- hyperweave-0.3.4/src/hyperweave/templates/frames/divider/brutalist-seam.svg.j2 +49 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/divider.svg.j2 +22 -10
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/brutalist-light-content.j2 +12 -3
- hyperweave-0.3.4/tests/test_badge_brutalist_dark.py +343 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_chart_engine.py +7 -3
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_chromatic_coverage_validator.py +29 -8
- hyperweave-0.3.4/tests/test_divider_genome_specific.py +244 -0
- hyperweave-0.3.4/tests/test_doctor.py +208 -0
- hyperweave-0.3.4/tests/test_install_hook.py +233 -0
- hyperweave-0.3.4/tests/test_receipt_paths.py +165 -0
- hyperweave-0.3.4/tests/test_stats_brutalist.py +125 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_telemetry_integration.py +76 -12
- hyperweave-0.3.2/src/hyperweave/templates/frames/badge/brutalist-dark-content.j2 +0 -55
- hyperweave-0.3.2/src/hyperweave/templates/frames/divider/brutalist-seam.svg.j2 +0 -39
- hyperweave-0.3.2/tests/test_divider_genome_specific.py +0 -93
- hyperweave-0.3.2/tests/test_receipt_paths.py +0 -129
- {hyperweave-0.3.2 → hyperweave-0.3.4}/.dockerignore +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/.github/workflows/ci.yml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/.github/workflows/deploy.yml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/.github/workflows/publish.yml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/.gitignore +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/.pre-commit-config.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/Dockerfile +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/LICENSE +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/buttons/button-liquid.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/cards/card-butterfly.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/cards/card-python.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/cards/card-sunflower.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/cards/card-waves.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/badge_critical.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/badge_passing.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/badge_warning.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/banner.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/icons/discord.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/icons/notion.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/icons/reddit.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/icons/spotify.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/icons/youtube.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/marquee_counter.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/marquee_horizontal.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/marquee_vertical.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/profile-cards/stats.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/brutalist-emerald/strip.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/badge_critical.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/badge_passing.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/badge_warning.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/banner.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/icons/bluesky.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/icons/github.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/icons/instagram.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/icons/mastodon.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/icons/x.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/marquee_counter.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/marquee_horizontal.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/marquee_vertical.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/profile-cards/stats.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/chrome-horizon/strip.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/telemetry/master_card.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/telemetry/receipt.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/telemetry/receipt_claude-code_medium.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/telemetry/receipt_codex_large.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/telemetry/receipt_voltage_xlarge.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/telemetry/rhythm_strip.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/examples/telemetry/rhythm_strip_voltage_xlarge.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/footers/inneraura-footer-liquid.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/footers/inneraura-footer-purple.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/footers/inneraura-footer.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-discord.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-docs.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-github.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-instagram.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-linkedin.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-tiktok.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-x.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/icons/cobalt-sapphire-youtube.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/marquees/badge-showcase-triple.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/marquees/genome-marquee-triple.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/marquees/sample-badges.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/404.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/callout-icons.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/divider.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/favicon.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/hero-banner.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/hyperweave-banner-v2.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/loader.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/mintlify-assets/og-image.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/assets/timelines/hyperweave-roadmap.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/assets/favicon.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/assets/og-image.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/explanation/architecture.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/explanation/camo-compatibility.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/explanation/cim-compliance.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/explanation/genome-profile-system.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/explanation/metadata-tiers.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/how-to/add-motion-to-badges.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/how-to/create-session-receipts.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/how-to/set-up-claude-code-hooks.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/how-to/use-live-data-badges.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/introduction.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/mint.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/quickstart.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/reference/cli.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/reference/compose-spec.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/reference/genomes.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/reference/http-api.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/reference/mcp-tools.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/reference/motions.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/reference/telemetry-contract.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/spec/hyperweave-protocol.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/tutorials/build-an-artifact-kit.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/tutorials/compose-your-first-badge.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/docs/tutorials/install-session-telemetry.mdx +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/fly.toml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/hooks/install.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/hooks/session_end.sh +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/justfile +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/pyproject.toml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/scripts/extract_font_metrics.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/scripts/extract_glyphs.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/scripts/generate_proofset.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/scripts/probe_live_stats.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/scripts/probe_star_history.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/scripts/stress_test.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/__main__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/assembler.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/bar_chart.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/context.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/engine.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/lanes.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/palette.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/reasoning.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/resolvers/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/resolvers/chart.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/resolvers/stats.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/rhythm.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/rhythm_strip.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/treemap.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/compose/validate_paradigms.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/config/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/config/genome_validator.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/config/loader.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/config/registry.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/config/settings.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/connectors/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/connectors/arxiv.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/connectors/base.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/connectors/cache.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/connectors/github.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/connectors/rest.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/cell_layout.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/color.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/contracts.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/enums.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/font_metrics.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/schema.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/state.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/text.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/core/thresholds.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/badge_modes.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/css/accessibility.css +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/css/bridge.css +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/css/expression.css +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/css/status.css +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/font-metrics/chakra-petch.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/font-metrics/inter.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/font-metrics/jetbrains-mono.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/font-metrics/orbitron.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/barlow-condensed-700.b64 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/barlow-condensed-700.meta.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/barlow-condensed-900.b64 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/barlow-condensed-900.meta.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/chakra-petch.b64 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/chakra-petch.meta.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/jetbrains-mono.b64 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/jetbrains-mono.meta.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/orbitron.b64 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/fonts/orbitron.meta.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/genomes/automata.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/genomes/chrome.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/genomes/telemetry-claude-code.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/genomes/telemetry-codex.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/genomes/telemetry-cream.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/genomes/telemetry-voltage.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/glyphs.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/motions/border/chromatic-pulse.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/motions/border/corner-trace.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/motions/border/dual-orbit.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/motions/border/entanglement.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/motions/border/rimrun.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/motions/static.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/paradigms/cellular.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/paradigms/chrome.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/paradigms/default.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/policies/normal.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/policies/permissive.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/policies/ungoverned.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/profiles/brutalist.contract.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/profiles/brutalist.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/profiles/chrome.contract.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/profiles/chrome.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/reasoning/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/reasoning/brutalist.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/specimens.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/telemetry/model-pricing.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/telemetry/runtimes/claude-code.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/telemetry/runtimes/codex.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/telemetry/stage-config.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/telemetry/stage-labels.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/telemetry/tool-colors.yaml +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/arrow.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/aurora.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/beacon.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/bracket3d.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/chevron.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/crosshair.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/diamond.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/rocket.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/rules/bar.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/rules/dashed.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/rules/five-wave.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/rules/spectral.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/rules/straight.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/rules/wave.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/data/terminals/stijl.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/kit.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/mcp/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/mcp/__main__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/mcp/server.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/py.typed +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/render/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/render/fonts.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/render/glyphs.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/render/motion.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/render/templates.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/serve/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/serve/app.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/serve/data_tokens.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/capture.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/codex_parser.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/contract.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/corrections.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/cost.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/models.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/parser.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/runtimes.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/telemetry/stages.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-area.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-axes.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-empty-state.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-gridlines.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-markers/circle.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-markers/diamond.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-markers/endpoint-diamond.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-markers/endpoint-rect.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-markers/rect.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-milestone.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/chart-polyline.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/filter.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/glyph-inline.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/glyph.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/gradient.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/metadata.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/metric.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/phase-segment.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/rule.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/status.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/components/terminal.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/document.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/error-badge.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/brutalist-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/cellular-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/cellular-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/chrome-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/chrome-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/default-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge/default-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/badge.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/catalog.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/brutalist-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/cellular-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/cellular-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/chrome-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart/chrome-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/chart.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/divider/chrome-band.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/brutalist-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/cellular-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/cellular-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/chrome-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/chrome-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/default-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon/default-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/icon.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-overlay.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/cellular-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/cellular-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/cellular-overlay.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/chrome-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/chrome-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/chrome-overlay.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/default-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal/default-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/marquee-horizontal.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/master-card.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/receipt.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/rhythm-strip.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/brutalist-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/cellular-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/cellular-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/chrome-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats/chrome-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/stats.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/brutalist-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/brutalist-status.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/cellular-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/cellular-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/cellular-status.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/chrome-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/chrome-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/chrome-status.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/default-content.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/default-defs.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip/default-status.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/frames/strip.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/motions/border/chromatic-pulse.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/motions/border/corner-trace.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/motions/border/dual-orbit.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/motions/border/entanglement.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/motions/border/rimrun.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/partials/provider-glyphs.svg.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/src/hyperweave/templates/partials/state-signal-cascade.j2 +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/__init__.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/conftest.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/fixtures/codex_session.jsonl +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/fixtures/codex_session_patches.jsonl +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/fixtures/github_contributions/synthetic.html +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/fixtures/session.json +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/fixtures/session.jsonl +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/fixtures/synthetic_session.jsonl +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/helpers.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/snapshots/url_stability/divider_band_chrome_static.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/snapshots/url_stability/icon_github_chrome_static.svg +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_assembler.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_badge_cellular.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_badge_layout.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_badge_mode.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_chart_frame.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_chrome_variants.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_codex_parser.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_compose_bar_chart.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_compose_rhythm_strip.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_compose_treemap.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_compose_variant_field.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_connectors.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_core.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_data_tokens.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_divider_cellular.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_font_gating.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_font_metrics_chakra.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_genome_automata.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_github_scrape.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_kit.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_marquee_v0_2_16.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_mcp.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_paradigm_cellular.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_paradigm_dispatch.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_paradigm_extensibility.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_parse_transcript_auto.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_proofset.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_receipt_token_compliance.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_render.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_resolver_rhythm.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_runtime_registries.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_serve.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_serve_live_state.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_slot_metric_state.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_state_inference.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_stats_card.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_strip_brutalist_grammar.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_strip_cellular.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_strip_status_toggle.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_telemetry.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_telemetry_contract_per_stage.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_telemetry_skin_dispatch.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_tool_class_completeness.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_url_stability.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/tests/test_variant_default_resolution.py +0 -0
- {hyperweave-0.3.2 → hyperweave-0.3.4}/uv.lock +0 -0
|
@@ -5,6 +5,44 @@ 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.4] - 2026-05-13
|
|
9
|
+
|
|
10
|
+
`install-hook` now detects Claude Code and Codex automatically. A new `hyperweave doctor` command shows hook status, transcripts, and recent receipts at a glance.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`hyperweave doctor`** — shows hook registration, transcript directories, recent receipts, and version info per runtime.
|
|
15
|
+
- **`install-hook --runtime all`** — registers hooks for both runtimes regardless of auto-detection.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **`install-hook` default** — without `--runtime`, detects which runtimes are installed and registers hooks for each. `--runtime claude-code` or `--runtime codex` scopes to one.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **Receipt footer** — restores the full relative path (`.hyperweave/receipts/{slug}.svg`); v0.3.3 had stripped the directory prefix.
|
|
24
|
+
|
|
25
|
+
### Notes
|
|
26
|
+
|
|
27
|
+
- Codex receipts refresh live as the session progresses, reflecting cumulative state after each turn.
|
|
28
|
+
|
|
29
|
+
## [0.3.3] - 2026-05-12
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- **Receipt filenames** — use consistent underscore separators; the footer displays the same human-readable filename.
|
|
34
|
+
- **Dark brutalist badge panels** — match the prototype: left panel reads `brand_panel_fill`, label reads `ink-primary`, seam-gap rect restored so the divider region renders the same in any markdown viewer.
|
|
35
|
+
- **Badge layout engine** — brutalist badges land every interior gap (accent→glyph, glyph→label, label→seam, seam→value, value→indicator, indicator→right border) on a single 5px rhythm. `measure_text` now consumes the paradigm's declared `value_letter_spacing_em` so the engine reserves the actual rendered width instead of under-counting by `(n-1) * font_size * em`.
|
|
36
|
+
- **Dark brutalist star charts** — header glyph fill routes through `var(--dna-signal)` (was an orphaned brand-text white). 6px solid left accent rail anchors the chart as a Y-axis spine; outer perimeter softens to a 1.5px hairline at 0.25 opacity so the rail dominates the read.
|
|
37
|
+
- **Light scholar star charts** — area gradient resolves through each variant's panel color across all 6 light variants instead of falling back to the seam color. Substrate-aware paper grain with multiply blend; perimeter inset and grain layer order match the prototype.
|
|
38
|
+
- **Activity graph bars** — light scholar stat cards use the correct accent color.
|
|
39
|
+
- **Divider tick marks** — resolve through the genome palette instead of a hardcoded green.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- **Star chart milestone callouts** — now include date context (e.g. `1K · JAN 24`) so the chart is self-documenting without cross-referencing external star history tools.
|
|
44
|
+
- **Star chart milestone markers** — data points use a filled square marker (■) to visually distinguish them from the regular interval crosshair (+) markers.
|
|
45
|
+
|
|
8
46
|
## [0.3.2] - 2026-05-11
|
|
9
47
|
|
|
10
48
|
Brutalist gets 12 variants split by substrate: 6 dark monochromes (celadon, carbon, alloy, temper, pigment, ember) and 6 light scholars (archive, signal, pulse, depth, afterimage, primer). Metadata pipeline wires 12 fields that were silently hardcoded. Per-frame reasoning populates `hw:reasoning` from per-genome YAML.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperweave
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
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
|
|
@@ -197,11 +197,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
197
197
|
<tr>
|
|
198
198
|
<th align="left">Dashboard<br/><sub>strip</sub></th>
|
|
199
199
|
<td>
|
|
200
|
-
<img src="https://hyperweave.app/v1/strip/
|
|
200
|
+
<img src="https://hyperweave.app/v1/strip/hyperweave/brutalist.static?data=gh:InnerAura/hyperweave.stars,pypi:hyperweave.version,gh:InnerAura/hyperweave.build&subtitle=InnerAura/hyperweave&glyph=github&variant=celadon" alt="strip"/>
|
|
201
201
|
<br/>
|
|
202
202
|
<ul>
|
|
203
203
|
<li><sub><code>/v1/strip/{title}/{genome}.static?data={tokens}&subtitle={text}&glyph={glyph}&variant={variant}</code></sub></li>
|
|
204
|
-
<li><sub><code>hyperweave.app/v1/strip/
|
|
204
|
+
<li><sub><code>hyperweave.app/v1/strip/hyperweave/brutalist.static?data=gh:InnerAura/hyperweave.stars,pypi:hyperweave.version,gh:InnerAura/hyperweave.build&subtitle=InnerAura/hyperweave&glyph=github&variant=celadon</code></sub></li>
|
|
205
205
|
</ul>
|
|
206
206
|
</td>
|
|
207
207
|
</tr>
|
|
@@ -165,11 +165,11 @@ Why genome and not theme? Because brand isn't a design problem, it's an infrastr
|
|
|
165
165
|
<tr>
|
|
166
166
|
<th align="left">Dashboard<br/><sub>strip</sub></th>
|
|
167
167
|
<td>
|
|
168
|
-
<img src="https://hyperweave.app/v1/strip/
|
|
168
|
+
<img src="https://hyperweave.app/v1/strip/hyperweave/brutalist.static?data=gh:InnerAura/hyperweave.stars,pypi:hyperweave.version,gh:InnerAura/hyperweave.build&subtitle=InnerAura/hyperweave&glyph=github&variant=celadon" alt="strip"/>
|
|
169
169
|
<br/>
|
|
170
170
|
<ul>
|
|
171
171
|
<li><sub><code>/v1/strip/{title}/{genome}.static?data={tokens}&subtitle={text}&glyph={glyph}&variant={variant}</code></sub></li>
|
|
172
|
-
<li><sub><code>hyperweave.app/v1/strip/
|
|
172
|
+
<li><sub><code>hyperweave.app/v1/strip/hyperweave/brutalist.static?data=gh:InnerAura/hyperweave.stars,pypi:hyperweave.version,gh:InnerAura/hyperweave.build&subtitle=InnerAura/hyperweave&glyph=github&variant=celadon</code></sub></li>
|
|
173
173
|
</ul>
|
|
174
174
|
</td>
|
|
175
175
|
</tr>
|
|
@@ -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.4'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 3, 4)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -361,39 +361,56 @@ def session(
|
|
|
361
361
|
|
|
362
362
|
frame_type = "receipt" if action == "receipt" else "rhythm-strip"
|
|
363
363
|
genome_slug = _normalize_genome_slug(genome) if genome else ""
|
|
364
|
+
|
|
365
|
+
# Pre-compute the receipt's on-disk filename (when applicable) so the
|
|
366
|
+
# footer can render the same path as the file the user sees. The compose
|
|
367
|
+
# pipeline reads receipt_filename_hint when set; an empty hint falls back
|
|
368
|
+
# to the legacy UUID-path footer (HTTP / MCP). Pass the FULL relative
|
|
369
|
+
# path (not just the basename) so the footer is self-documenting — a
|
|
370
|
+
# reader sees ".hyperweave/receipts/{slug}.svg" and knows where to find
|
|
371
|
+
# the file without prior context. Long footers trigger left-truncation
|
|
372
|
+
# of the constant prefix at resolver.py:_truncate_path_left.
|
|
373
|
+
filename_hint = ""
|
|
374
|
+
if action == "receipt" and not output:
|
|
375
|
+
from datetime import datetime as _dt
|
|
376
|
+
|
|
377
|
+
from hyperweave.telemetry.receipt_paths import receipt_filename
|
|
378
|
+
|
|
379
|
+
sess = contract.get("session", {})
|
|
380
|
+
sid = sess.get("id", "unknown")
|
|
381
|
+
session_name = sess.get("name", "")
|
|
382
|
+
start_iso = sess.get("start", "")
|
|
383
|
+
try:
|
|
384
|
+
ts = _dt.fromisoformat(start_iso)
|
|
385
|
+
except (TypeError, ValueError):
|
|
386
|
+
ts = _dt.now()
|
|
387
|
+
user_events = contract.get("user_events", []) or []
|
|
388
|
+
first_prompt = user_events[0].get("preview", "") if user_events else ""
|
|
389
|
+
hw_dir = Path(".hyperweave") / "receipts"
|
|
390
|
+
hw_dir.mkdir(parents=True, exist_ok=True)
|
|
391
|
+
output = hw_dir / receipt_filename(
|
|
392
|
+
timestamp=ts,
|
|
393
|
+
session_name=session_name,
|
|
394
|
+
session_id=sid,
|
|
395
|
+
prompt_text=first_prompt,
|
|
396
|
+
)
|
|
397
|
+
filename_hint = str(output)
|
|
398
|
+
elif action == "receipt" and output:
|
|
399
|
+
# Explicit --output: surface whatever path shape the user provided.
|
|
400
|
+
filename_hint = str(output)
|
|
401
|
+
|
|
364
402
|
spec = ComposeSpec(
|
|
365
403
|
type=frame_type,
|
|
366
404
|
genome_id=genome_slug,
|
|
367
405
|
telemetry_data=contract,
|
|
406
|
+
receipt_filename_hint=filename_hint,
|
|
368
407
|
)
|
|
369
408
|
result = do_compose(spec)
|
|
370
409
|
|
|
371
410
|
if action == "receipt":
|
|
372
|
-
#
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
from hyperweave.telemetry.receipt_paths import receipt_filename
|
|
377
|
-
|
|
378
|
-
sess = contract.get("session", {})
|
|
379
|
-
sid = sess.get("id", "unknown")
|
|
380
|
-
session_name = sess.get("name", "")
|
|
381
|
-
start_iso = sess.get("start", "")
|
|
382
|
-
try:
|
|
383
|
-
ts = _dt.fromisoformat(start_iso)
|
|
384
|
-
except (TypeError, ValueError):
|
|
385
|
-
ts = _dt.now()
|
|
386
|
-
user_events = contract.get("user_events", []) or []
|
|
387
|
-
first_prompt = user_events[0].get("preview", "") if user_events else ""
|
|
388
|
-
hw_dir = Path(".hyperweave") / "receipts"
|
|
389
|
-
hw_dir.mkdir(parents=True, exist_ok=True)
|
|
390
|
-
output = hw_dir / receipt_filename(
|
|
391
|
-
timestamp=ts,
|
|
392
|
-
session_name=session_name,
|
|
393
|
-
session_id=sid,
|
|
394
|
-
prompt_text=first_prompt,
|
|
395
|
-
)
|
|
396
|
-
|
|
411
|
+
# output is guaranteed non-None here: the receipt branch above either
|
|
412
|
+
# received an explicit --output or computed a default path.
|
|
413
|
+
assert output is not None
|
|
397
414
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
398
415
|
output.write_text(result.svg)
|
|
399
416
|
|
|
@@ -554,12 +571,13 @@ def _install_codex_hook(hook_command: str, full_slug: str) -> None:
|
|
|
554
571
|
"""Write a Stop hook to ``~/.codex/hooks.json`` + enable codex_hooks feature.
|
|
555
572
|
|
|
556
573
|
Per developers.openai.com/codex/hooks, Codex CLI fires Stop hooks
|
|
557
|
-
PER-TURN (
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
574
|
+
PER-TURN (after every assistant response). The receipt rewrites the
|
|
575
|
+
same deterministic filename each turn, so the on-disk file becomes a
|
|
576
|
+
live mid-session telemetry window — opening it during a long session
|
|
577
|
+
shows the current state, and the final write at session-end carries
|
|
578
|
+
the complete cumulative receipt. This is intentional; future versions
|
|
579
|
+
will lean into live-receipt consumers (file watchers, dashboards)
|
|
580
|
+
rather than collapse it back to a single session-end event.
|
|
563
581
|
|
|
564
582
|
Also writes ``[features] codex_hooks = true`` to ``~/.codex/config.toml``
|
|
565
583
|
(preserving any other keys); the feature flag is required for the
|
|
@@ -615,8 +633,8 @@ def _install_codex_hook(hook_command: str, full_slug: str) -> None:
|
|
|
615
633
|
typer.echo(f"Installed Stop hook in {hooks_path}{pinned}")
|
|
616
634
|
typer.echo(f"Set [features] codex_hooks = true in {config_path}")
|
|
617
635
|
typer.echo(
|
|
618
|
-
"Note: Codex Stop fires per-turn —
|
|
619
|
-
"
|
|
636
|
+
"Note: Codex Stop fires per-turn — the receipt file refreshes live as the "
|
|
637
|
+
"session progresses, always reflecting current cumulative state.",
|
|
620
638
|
err=True,
|
|
621
639
|
)
|
|
622
640
|
|
|
@@ -630,6 +648,37 @@ _HOOK_INSTALLERS = {
|
|
|
630
648
|
"codex": _install_codex_hook,
|
|
631
649
|
}
|
|
632
650
|
|
|
651
|
+
# Runtime → (config_dirname_under_home, cli_binary_name). Drives both the
|
|
652
|
+
# auto-detect path (config dir OR binary on PATH) and `hyperweave doctor`
|
|
653
|
+
# state reporting. Config-dir presence means "agent has been run at least
|
|
654
|
+
# once"; binary-on-PATH covers fresh installs where the dir hasn't been
|
|
655
|
+
# created yet. The installers create their dirs on demand, so installing
|
|
656
|
+
# for a binary-only runtime is safe.
|
|
657
|
+
_RUNTIME_DETECTION = {
|
|
658
|
+
"claude-code": (".claude", "claude"),
|
|
659
|
+
"codex": (".codex", "codex"),
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
def _detect_installed_runtimes() -> list[tuple[str, str]]:
|
|
664
|
+
"""Detect installed agent runtimes via config-dir-OR-binary-on-PATH.
|
|
665
|
+
|
|
666
|
+
Returns ``(runtime_key, signal)`` tuples in ``_RUNTIME_DETECTION`` order.
|
|
667
|
+
Signal is ``"initialized"`` when the runtime's config dir exists (agent
|
|
668
|
+
has been run at least once), ``"binary_only"`` when only the CLI is on
|
|
669
|
+
PATH (fresh install, config dir not created yet). Runtimes with
|
|
670
|
+
neither signal are omitted entirely.
|
|
671
|
+
"""
|
|
672
|
+
import shutil
|
|
673
|
+
|
|
674
|
+
detected: list[tuple[str, str]] = []
|
|
675
|
+
for runtime, (dirname, binname) in _RUNTIME_DETECTION.items():
|
|
676
|
+
if (Path.home() / dirname).exists():
|
|
677
|
+
detected.append((runtime, "initialized"))
|
|
678
|
+
elif shutil.which(binname):
|
|
679
|
+
detected.append((runtime, "binary_only"))
|
|
680
|
+
return detected
|
|
681
|
+
|
|
633
682
|
|
|
634
683
|
@app.command("install-hook")
|
|
635
684
|
def install_hook(
|
|
@@ -649,28 +698,55 @@ def install_hook(
|
|
|
649
698
|
typer.Option(
|
|
650
699
|
"--runtime",
|
|
651
700
|
help=(
|
|
652
|
-
"Agent runtime to install the receipt hook for.
|
|
653
|
-
"
|
|
654
|
-
"
|
|
655
|
-
"
|
|
656
|
-
"
|
|
701
|
+
"Agent runtime to install the receipt hook for. Empty (default) "
|
|
702
|
+
"auto-detects installed runtimes (~/.claude, ~/.codex, or 'claude'/"
|
|
703
|
+
"'codex' on PATH) and registers for each present. 'claude-code' "
|
|
704
|
+
"writes a SessionEnd hook to ~/.claude/settings.json. 'codex' writes "
|
|
705
|
+
"a Stop hook to ~/.codex/hooks.json plus [features] codex_hooks in "
|
|
706
|
+
"~/.codex/config.toml. 'all' forces both regardless of detection."
|
|
657
707
|
),
|
|
658
708
|
),
|
|
659
|
-
] = "
|
|
709
|
+
] = "",
|
|
660
710
|
) -> None:
|
|
661
|
-
"""Install
|
|
711
|
+
"""Install session-receipt hooks for installed agent runtimes.
|
|
712
|
+
|
|
713
|
+
Default behavior detects which agent CLIs are installed (Claude Code,
|
|
714
|
+
Codex) via config dir presence or binary on PATH, and registers receipt
|
|
715
|
+
hooks for each. Pass ``--runtime <name>`` to scope to a single runtime,
|
|
716
|
+
or ``--runtime all`` to force both regardless of detection.
|
|
717
|
+
"""
|
|
662
718
|
from hyperweave.compose.resolver import _genome_supports_receipts
|
|
663
719
|
|
|
664
|
-
|
|
720
|
+
# Resolve targets:
|
|
721
|
+
# "" (default) → auto-detect installed runtimes (config dir OR binary)
|
|
722
|
+
# "all" → both runtimes regardless of detection
|
|
723
|
+
# "<name>" → just that runtime (legacy explicit form)
|
|
724
|
+
if runtime == "":
|
|
725
|
+
detected = _detect_installed_runtimes()
|
|
726
|
+
if not detected:
|
|
727
|
+
typer.echo(
|
|
728
|
+
"Error: no agent runtime detected (~/.claude, ~/.codex, or "
|
|
729
|
+
"'claude'/'codex' on PATH). Install Claude Code or Codex CLI, "
|
|
730
|
+
"or pass --runtime <name> to force.",
|
|
731
|
+
err=True,
|
|
732
|
+
)
|
|
733
|
+
raise typer.Exit(1)
|
|
734
|
+
targets = [rt for rt, _signal in detected]
|
|
735
|
+
elif runtime == "all":
|
|
736
|
+
targets = list(_HOOK_INSTALLERS)
|
|
737
|
+
elif runtime in _HOOK_INSTALLERS:
|
|
738
|
+
targets = [runtime]
|
|
739
|
+
else:
|
|
665
740
|
typer.echo(
|
|
666
|
-
f"Error: unknown runtime '{runtime}'. Supported: {sorted(_HOOK_INSTALLERS)}",
|
|
741
|
+
f"Error: unknown runtime '{runtime}'. Supported: {sorted(_HOOK_INSTALLERS)} or 'all'.",
|
|
667
742
|
err=True,
|
|
668
743
|
)
|
|
669
744
|
raise typer.Exit(1)
|
|
670
745
|
|
|
671
|
-
# Validate --genome BEFORE writing
|
|
672
|
-
# the receipt CLI which silently falls through) because pinning
|
|
673
|
-
# would produce silent surprises every session-end until
|
|
746
|
+
# Validate --genome BEFORE writing any hook. install-hook fails loud
|
|
747
|
+
# (unlike the receipt CLI which silently falls through) because pinning
|
|
748
|
+
# a bad genome would produce silent surprises every session-end until
|
|
749
|
+
# someone notices. Validate once even when targeting multiple runtimes.
|
|
674
750
|
full_slug = ""
|
|
675
751
|
if genome:
|
|
676
752
|
full_slug = _normalize_genome_slug(genome)
|
|
@@ -685,7 +761,151 @@ def install_hook(
|
|
|
685
761
|
|
|
686
762
|
hook_command = f"hyperweave session receipt --genome {full_slug}" if full_slug else "hyperweave session receipt"
|
|
687
763
|
|
|
688
|
-
|
|
764
|
+
for target in targets:
|
|
765
|
+
_HOOK_INSTALLERS[target](hook_command, full_slug)
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
def _doctor_runtime_status(runtime: str, home_dir: Path) -> str:
|
|
769
|
+
"""Parse a runtime's hook config and return a one-line status string.
|
|
770
|
+
|
|
771
|
+
Returns ``✓`` when the hyperweave hook is wired correctly, ``✗`` when
|
|
772
|
+
the runtime is initialized but no hyperweave hook is registered, or
|
|
773
|
+
``⚠`` when the wiring is partial (malformed config; codex missing the
|
|
774
|
+
[features] codex_hooks flag). The string is rendered verbatim by
|
|
775
|
+
``doctor``.
|
|
776
|
+
"""
|
|
777
|
+
import json
|
|
778
|
+
|
|
779
|
+
if runtime == "claude-code":
|
|
780
|
+
settings_path = home_dir / "settings.json"
|
|
781
|
+
if not settings_path.exists():
|
|
782
|
+
return (
|
|
783
|
+
f"✗ {runtime}: ~/.claude/ exists but no settings.json — "
|
|
784
|
+
f"run 'hyperweave install-hook --runtime {runtime}'"
|
|
785
|
+
)
|
|
786
|
+
try:
|
|
787
|
+
settings = json.loads(settings_path.read_text())
|
|
788
|
+
except json.JSONDecodeError:
|
|
789
|
+
return f"⚠ {runtime}: ~/.claude/settings.json is malformed"
|
|
790
|
+
for entry in settings.get("hooks", {}).get("SessionEnd", []) or []:
|
|
791
|
+
if not isinstance(entry, dict):
|
|
792
|
+
continue
|
|
793
|
+
for hook in entry.get("hooks", []) or []:
|
|
794
|
+
if not isinstance(hook, dict):
|
|
795
|
+
continue
|
|
796
|
+
cmd = str(hook.get("command", ""))
|
|
797
|
+
if "hyperweave session" in cmd:
|
|
798
|
+
return f"✓ {runtime}: hook registered — {cmd}"
|
|
799
|
+
return f"✗ {runtime}: initialized but no hyperweave hook — run 'hyperweave install-hook --runtime {runtime}'"
|
|
800
|
+
|
|
801
|
+
if runtime == "codex":
|
|
802
|
+
hooks_path = home_dir / "hooks.json"
|
|
803
|
+
config_path = home_dir / "config.toml"
|
|
804
|
+
registered_cmd: str | None = None
|
|
805
|
+
if hooks_path.exists():
|
|
806
|
+
try:
|
|
807
|
+
hooks = json.loads(hooks_path.read_text())
|
|
808
|
+
except json.JSONDecodeError:
|
|
809
|
+
return f"⚠ {runtime}: ~/.codex/hooks.json is malformed"
|
|
810
|
+
for entry in hooks.get("Stop", []) or []:
|
|
811
|
+
if not isinstance(entry, dict):
|
|
812
|
+
continue
|
|
813
|
+
cmd = str(entry.get("command", ""))
|
|
814
|
+
if "hyperweave session" in cmd:
|
|
815
|
+
registered_cmd = cmd
|
|
816
|
+
break
|
|
817
|
+
if not registered_cmd:
|
|
818
|
+
return (
|
|
819
|
+
f"✗ {runtime}: initialized but no hyperweave hook — run 'hyperweave install-hook --runtime {runtime}'"
|
|
820
|
+
)
|
|
821
|
+
# [features] codex_hooks = true must be present for the hook to fire;
|
|
822
|
+
# the install command writes it, but a hand-edited config could miss it.
|
|
823
|
+
feature_ok = False
|
|
824
|
+
if config_path.exists():
|
|
825
|
+
in_features = False
|
|
826
|
+
for line in config_path.read_text().splitlines():
|
|
827
|
+
stripped = line.strip()
|
|
828
|
+
if stripped == "[features]":
|
|
829
|
+
in_features = True
|
|
830
|
+
continue
|
|
831
|
+
if in_features and stripped.startswith("["):
|
|
832
|
+
in_features = False
|
|
833
|
+
continue
|
|
834
|
+
if in_features and stripped.startswith("codex_hooks") and "true" in stripped:
|
|
835
|
+
feature_ok = True
|
|
836
|
+
break
|
|
837
|
+
if not feature_ok:
|
|
838
|
+
return (
|
|
839
|
+
f"⚠ {runtime}: hook registered but [features] codex_hooks = true "
|
|
840
|
+
f"is missing — re-run 'hyperweave install-hook --runtime {runtime}'"
|
|
841
|
+
)
|
|
842
|
+
return f"✓ {runtime}: hook registered — {registered_cmd}"
|
|
843
|
+
|
|
844
|
+
return f"? {runtime}: unknown runtime"
|
|
845
|
+
|
|
846
|
+
|
|
847
|
+
@app.command()
|
|
848
|
+
def doctor() -> None:
|
|
849
|
+
"""Diagnose hyperweave telemetry wiring across agent runtimes.
|
|
850
|
+
|
|
851
|
+
Reports per-runtime detection state (initialized / binary-only /
|
|
852
|
+
absent), hook registration status, transcript dir state, and recent
|
|
853
|
+
receipt activity in the current directory. Read-only — never
|
|
854
|
+
modifies any config. Always exits 0.
|
|
855
|
+
"""
|
|
856
|
+
import shutil
|
|
857
|
+
from datetime import datetime, timedelta
|
|
858
|
+
|
|
859
|
+
from hyperweave import __version__
|
|
860
|
+
|
|
861
|
+
typer.echo(f"hyperweave doctor — v{__version__}")
|
|
862
|
+
typer.echo("")
|
|
863
|
+
typer.echo("Runtimes:")
|
|
864
|
+
for runtime, (dirname, binname) in _RUNTIME_DETECTION.items():
|
|
865
|
+
home_dir = Path.home() / dirname
|
|
866
|
+
if home_dir.exists():
|
|
867
|
+
typer.echo(f" {_doctor_runtime_status(runtime, home_dir)}")
|
|
868
|
+
elif bin_path := shutil.which(binname):
|
|
869
|
+
typer.echo(
|
|
870
|
+
f" ⚠ {runtime}: CLI on PATH at {bin_path} but ~/{dirname}/ "
|
|
871
|
+
f"not initialized — run '{binname}' once, then "
|
|
872
|
+
f"'hyperweave install-hook --runtime {runtime}'"
|
|
873
|
+
)
|
|
874
|
+
else:
|
|
875
|
+
typer.echo(f" ✗ {runtime}: not detected")
|
|
876
|
+
|
|
877
|
+
typer.echo("")
|
|
878
|
+
typer.echo("Transcripts:")
|
|
879
|
+
for runtime, subdir in (("claude-code", "projects"), ("codex", "sessions")):
|
|
880
|
+
dirname = _RUNTIME_DETECTION[runtime][0]
|
|
881
|
+
root = Path.home() / dirname / subdir
|
|
882
|
+
display_root = f"~/{dirname}/{subdir}"
|
|
883
|
+
if not root.exists():
|
|
884
|
+
typer.echo(f" {runtime}: {display_root} (not found)")
|
|
885
|
+
continue
|
|
886
|
+
files = list(root.rglob("*.jsonl"))
|
|
887
|
+
if not files:
|
|
888
|
+
typer.echo(f" {runtime}: {display_root}/ (empty)")
|
|
889
|
+
continue
|
|
890
|
+
most_recent = max(files, key=lambda p: p.stat().st_mtime)
|
|
891
|
+
mtime = datetime.fromtimestamp(most_recent.stat().st_mtime)
|
|
892
|
+
typer.echo(f" {runtime}: {len(files)} transcript(s), most recent {mtime:%Y-%m-%d %H:%M}")
|
|
893
|
+
|
|
894
|
+
typer.echo("")
|
|
895
|
+
typer.echo("Receipts (./.hyperweave/receipts/):")
|
|
896
|
+
receipts_dir = Path(".hyperweave") / "receipts"
|
|
897
|
+
if not receipts_dir.exists():
|
|
898
|
+
typer.echo(" (no receipts directory in cwd)")
|
|
899
|
+
return
|
|
900
|
+
svgs = [p for p in receipts_dir.iterdir() if p.is_file() and p.suffix == ".svg"]
|
|
901
|
+
if not svgs:
|
|
902
|
+
typer.echo(" (no receipts)")
|
|
903
|
+
return
|
|
904
|
+
cutoff = datetime.now() - timedelta(days=7)
|
|
905
|
+
recent = [p for p in svgs if datetime.fromtimestamp(p.stat().st_mtime) > cutoff]
|
|
906
|
+
most_recent = max(svgs, key=lambda p: p.stat().st_mtime)
|
|
907
|
+
typer.echo(f" {len(recent)} receipt(s) in last 7 days, {len(svgs)} total")
|
|
908
|
+
typer.echo(f" most recent: {most_recent.name}")
|
|
689
909
|
|
|
690
910
|
|
|
691
911
|
@app.command("validate-genome")
|
|
@@ -110,6 +110,8 @@ def compute_badge_layout(
|
|
|
110
110
|
value_font_size: float,
|
|
111
111
|
right_canvas_inset: int = 0,
|
|
112
112
|
min_total_w: int = 60,
|
|
113
|
+
inner_bit_ratio: float = 0.5,
|
|
114
|
+
rhythm_gap: int = 0,
|
|
113
115
|
) -> BadgeLayout:
|
|
114
116
|
"""Compute every position the badge templates need from input measurements.
|
|
115
117
|
|
|
@@ -121,44 +123,83 @@ def compute_badge_layout(
|
|
|
121
123
|
|
|
122
124
|
The centering correctness is verified by ``tests/test_badge_layout``
|
|
123
125
|
against short / long / version / license / python_requires values.
|
|
126
|
+
|
|
127
|
+
When ``rhythm_gap > 0`` (brutalist v0.3.3 sets 8), the layout collapses
|
|
128
|
+
every interior gap to a single value: accent_right→glyph_left,
|
|
129
|
+
glyph_right→label_first, label_last→seam_left, seam_right→value_first,
|
|
130
|
+
value_last→indicator_left, indicator_right→right_border. Caller must
|
|
131
|
+
also set ``ind_pad_r=rhythm_gap`` so the indicator gaps land on the
|
|
132
|
+
same rhythm.
|
|
124
133
|
"""
|
|
125
134
|
# Glyph pixel position. Mirrors resolver.py logic: paradigms with a
|
|
126
135
|
# left-edge decoration zone (cellular pattern strip x=2..~20) reserve
|
|
127
136
|
# space via ``glyph_left_offset``; brutalist/chrome declare 0.
|
|
137
|
+
# When rhythm_gap is set, the glyph sits exactly ``rhythm_gap`` right
|
|
138
|
+
# of the accent bar so the accent→glyph gap matches the global rhythm.
|
|
128
139
|
if has_glyph:
|
|
129
|
-
|
|
130
|
-
|
|
140
|
+
if rhythm_gap > 0:
|
|
141
|
+
glyph_x = accent_w + rhythm_gap + glyph_left_offset
|
|
142
|
+
else:
|
|
143
|
+
glyph_x = (inset + accent_w + 4) if inset else (accent_w + 3)
|
|
144
|
+
glyph_x += glyph_left_offset
|
|
131
145
|
glyph_y = round((height - glyph_size) / 2, 1)
|
|
132
146
|
else:
|
|
133
147
|
glyph_x, glyph_y = 0, 0.0
|
|
134
148
|
|
|
135
149
|
# Label area starts after the glyph (or after the accent + paradigm
|
|
136
|
-
# left-edge decoration when there's no glyph).
|
|
137
|
-
#
|
|
138
|
-
#
|
|
139
|
-
|
|
150
|
+
# left-edge decoration when there's no glyph). When rhythm_gap > 0,
|
|
151
|
+
# the glyph→label gap (with-glyph) and accent→label gap (no-glyph)
|
|
152
|
+
# both equal rhythm_gap.
|
|
153
|
+
if rhythm_gap > 0:
|
|
154
|
+
label_start = (glyph_x + glyph_size + rhythm_gap) if has_glyph else (accent_w + rhythm_gap + glyph_left_offset)
|
|
155
|
+
else:
|
|
156
|
+
label_start = (glyph_x + glyph_size + glyph_gap) if has_glyph else (accent_w + 6 + glyph_left_offset)
|
|
140
157
|
|
|
141
158
|
# Left panel width — fits the label plus paradigm-driven right padding.
|
|
142
|
-
label_pad_r =
|
|
159
|
+
# rhythm_gap mode forces label_pad_r = rhythm_gap so label_last→seam_left
|
|
160
|
+
# equals the global rhythm. Legacy mode keeps the 9 (mono) / 8 (non-mono)
|
|
161
|
+
# default tuned for chrome/cellular's denser label kerning.
|
|
162
|
+
label_pad_r = rhythm_gap if rhythm_gap > 0 else (9 if use_mono else 8)
|
|
143
163
|
left_panel = round(label_start + measured_label_w + label_pad_r)
|
|
144
164
|
left_panel = max(left_panel, 30)
|
|
145
165
|
|
|
146
|
-
# Label text center
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
# Label text center. Legacy mode centers the label in [label_start,
|
|
167
|
+
# label_area_end] with a 6px shy-from-seam adjustment for uppercase
|
|
168
|
+
# labels. rhythm_gap mode aligns label_first with label_start exactly
|
|
169
|
+
# (label_x = label_start + w/2) so the accent_right→label_first gap
|
|
170
|
+
# lands at ``rhythm_gap`` regardless of label_w. The legacy area-center
|
|
171
|
+
# formula leaves a (panel_w - label_w)/2 interior gutter inside the
|
|
172
|
+
# label area, which collapses the structural gap to ~(rhythm_gap +
|
|
173
|
+
# interior_gutter)/2 — visible as 12.2/4.2 asymmetry on a 35.64px
|
|
174
|
+
# label in a 44px area when targeting an 8px rhythm.
|
|
175
|
+
if rhythm_gap > 0:
|
|
176
|
+
label_area_end = left_panel
|
|
177
|
+
label_x = round(label_start + measured_label_w / 2, 1)
|
|
178
|
+
else:
|
|
179
|
+
label_area_end = left_panel - (6 if label_uppercase else 0)
|
|
180
|
+
label_x = round((label_start + label_area_end) / 2, 1)
|
|
151
181
|
|
|
152
182
|
# Right-panel allocation. ``ls_extra`` accounts for non-mono letter-
|
|
153
183
|
# spacing overrun (each char carries 0.4 of trailing tracking).
|
|
154
184
|
indicator_alloc = (indicator_size + ind_pad_r) if show_indicator else 0
|
|
155
185
|
ls_extra = value_raw_len * 0.4 if (not use_mono and value_raw_len) else 0
|
|
156
|
-
#
|
|
157
|
-
#
|
|
158
|
-
#
|
|
159
|
-
#
|
|
160
|
-
#
|
|
161
|
-
|
|
186
|
+
# Gap between value text right edge and the indicator's left edge. For
|
|
187
|
+
# stateful badges this mirrors ``ind_pad_r`` (gap right of indicator) so
|
|
188
|
+
# the indicator sits with equal interior padding on both sides — the
|
|
189
|
+
# cohesive-balance contract the brutalist v16 prototype encodes. For
|
|
190
|
+
# stateless badges there's no indicator, so the trailing pad collapses
|
|
191
|
+
# to ``val_min_gap`` (3px tight right gutter; tighter than the stateful
|
|
192
|
+
# symmetric gap because there's no marker to balance against).
|
|
193
|
+
text_to_indicator_gap = ind_pad_r if show_indicator else val_min_gap
|
|
194
|
+
# rhythm_gap mode overrides ``val_pad_l`` (seam→value gap) to the
|
|
195
|
+
# global rhythm. Legacy mode keeps the resolver-supplied val_pad_l
|
|
196
|
+
# (3px) for chrome/cellular/default paradigms.
|
|
197
|
+
effective_val_pad_l = rhythm_gap if rhythm_gap > 0 else val_pad_l
|
|
198
|
+
# right_panel reserves: effective_val_pad_l (left interior gutter), the
|
|
199
|
+
# measured value text + letter-spacing overrun, text_to_indicator_gap
|
|
200
|
+
# (right interior gutter), and indicator_alloc when stateful. Symmetric
|
|
201
|
+
# stateful: text + ind_pad_r + indicator_size + ind_pad_r.
|
|
202
|
+
right_panel = effective_val_pad_l + measured_value_w + ls_extra + text_to_indicator_gap + indicator_alloc
|
|
162
203
|
total_w = round(left_panel + sep_w + seam_w + right_panel)
|
|
163
204
|
total_w = max(total_w, min_total_w)
|
|
164
205
|
|
|
@@ -176,13 +217,14 @@ def compute_badge_layout(
|
|
|
176
217
|
# which is the midpoint of [zone_left, indicator_left_edge], not
|
|
177
218
|
# [zone_left, zone_right]. Old formula skewed text by val_min_gap/2
|
|
178
219
|
# toward the indicator and was undefined when no indicator rendered.
|
|
179
|
-
value_zone_left = right_panel_x +
|
|
220
|
+
value_zone_left = right_panel_x + effective_val_pad_l
|
|
180
221
|
# When stateless (no indicator), the slab's right edge is total_w minus
|
|
181
|
-
# any paradigm-specific canvas inset (cellular: 2; brutalist/chrome: 0)
|
|
182
|
-
# val_min_gap
|
|
183
|
-
#
|
|
184
|
-
#
|
|
185
|
-
|
|
222
|
+
# any paradigm-specific canvas inset (cellular: 2; brutalist/chrome: 0)
|
|
223
|
+
# minus val_min_gap (tight 3px trailing pad). When stateful, the right
|
|
224
|
+
# edge sits ind_pad_r inside the indicator's left edge — mirroring the
|
|
225
|
+
# right-of-indicator gap so the indicator reads as equidistant from
|
|
226
|
+
# the value text and from the badge's right border.
|
|
227
|
+
value_zone_right = (indicator_x - ind_pad_r) if show_indicator else (total_w - right_canvas_inset - val_min_gap)
|
|
186
228
|
value_zone_width = value_zone_right - value_zone_left
|
|
187
229
|
value_x = round((value_zone_left + value_zone_right) / 2, 1)
|
|
188
230
|
|
|
@@ -196,9 +238,12 @@ def compute_badge_layout(
|
|
|
196
238
|
indicator_y = round(text_y - value_font_size * 0.3 - indicator_size / 2, 1)
|
|
197
239
|
|
|
198
240
|
# Indicator inner-bit geometry — moved from cellular/brutalist
|
|
199
|
-
# template-side arithmetic.
|
|
200
|
-
#
|
|
201
|
-
|
|
241
|
+
# template-side arithmetic. v0.3.3 generalizes the ratio so brutalist
|
|
242
|
+
# can render the prototype's 6/10 (0.6) bit instead of the cellular
|
|
243
|
+
# 4/8 (0.5) default — caller passes a paradigm-driven ratio. Rounded
|
|
244
|
+
# to the nearest integer so the bit lands on a pixel grid; offset is
|
|
245
|
+
# the half-difference, which can be a half-pixel for odd ratios.
|
|
246
|
+
inner_bit_w = round(indicator_size * inner_bit_ratio)
|
|
202
247
|
inner_bit_offset = (indicator_size - inner_bit_w) / 2
|
|
203
248
|
|
|
204
249
|
return BadgeLayout(
|