hyperweave 0.3.5__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.5 → hyperweave-0.3.7}/CHANGELOG.md +44 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/PKG-INFO +33 -18
- {hyperweave-0.3.5 → hyperweave-0.3.7}/README.md +30 -17
- {hyperweave-0.3.5 → hyperweave-0.3.7}/justfile +10 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/pyproject.toml +7 -2
- {hyperweave-0.3.5 → hyperweave-0.3.7}/scripts/generate_proofset.py +12 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/_version.py +2 -2
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/cli.py +178 -44
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/assembler.py +39 -53
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/context.py +178 -25
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/resolver.py +47 -19
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/validate_paradigms.py +99 -0
- {hyperweave-0.3.5 → 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.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/codex_parser.py +5 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/contract.py +5 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/models.py +12 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/parser.py +6 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_chart_frame.py +5 -3
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_doctor.py +53 -4
- {hyperweave-0.3.5 → 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.5 → hyperweave-0.3.7}/tests/test_install_hook.py +122 -7
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_paradigm_cellular.py +43 -14
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_telemetry_integration.py +70 -1
- hyperweave-0.3.5/src/hyperweave/render/fonts.py +0 -48
- {hyperweave-0.3.5 → hyperweave-0.3.7}/.dockerignore +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/.github/workflows/ci.yml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/.github/workflows/deploy.yml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/.github/workflows/publish.yml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/.gitignore +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/.pre-commit-config.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/Dockerfile +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/LICENSE +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/buttons/button-liquid.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/cards/card-butterfly.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/cards/card-python.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/cards/card-sunflower.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/cards/card-waves.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/badge_critical.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/badge_passing.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/badge_warning.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/banner.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/discord.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/notion.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/reddit.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/spotify.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/icons/youtube.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/marquee_counter.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/marquee_horizontal.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/marquee_vertical.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/profile-cards/stats.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/brutalist-emerald/strip.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/badge_critical.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/badge_passing.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/badge_warning.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/banner.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/bluesky.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/github.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/instagram.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/mastodon.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/icons/x.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/marquee_counter.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/marquee_horizontal.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/marquee_vertical.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/profile-cards/stats.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/chrome-horizon/strip.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/telemetry/master_card.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/telemetry/receipt.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/telemetry/receipt_claude-code_medium.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/telemetry/receipt_codex_large.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/telemetry/receipt_voltage_xlarge.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/telemetry/rhythm_strip.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/examples/telemetry/rhythm_strip_voltage_xlarge.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/footers/inneraura-footer-liquid.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/footers/inneraura-footer-purple.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/footers/inneraura-footer.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-discord.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-docs.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-github.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-instagram.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-linkedin.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-tiktok.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-x.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/icons/cobalt-sapphire-youtube.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/marquees/badge-showcase-triple.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/marquees/genome-marquee-triple.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/marquees/sample-badges.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/404.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/callout-icons.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/divider.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/favicon.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/hero-banner.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/hyperweave-banner-v2.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/loader.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/mintlify-assets/og-image.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/assets/timelines/hyperweave-roadmap.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/assets/favicon.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/assets/og-image.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/explanation/architecture.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/explanation/camo-compatibility.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/explanation/cim-compliance.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/explanation/genome-profile-system.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/explanation/metadata-tiers.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/how-to/add-motion-to-badges.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/how-to/create-session-receipts.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/how-to/set-up-claude-code-hooks.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/how-to/use-live-data-badges.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/introduction.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/mint.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/quickstart.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/reference/cli.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/reference/compose-spec.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/reference/genomes.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/reference/http-api.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/reference/mcp-tools.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/reference/motions.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/reference/telemetry-contract.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/spec/hyperweave-protocol.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/tutorials/build-an-artifact-kit.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/tutorials/compose-your-first-badge.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/docs/tutorials/install-session-telemetry.mdx +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/fly.toml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/hooks/install.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/hooks/session_end.sh +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/scripts/extract_font_metrics.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/scripts/extract_glyphs.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/scripts/probe_live_stats.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/scripts/probe_star_history.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/scripts/stress_test.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/__main__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/bar_chart.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/engine.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/lanes.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/layout.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/palette.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/reasoning.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/resolvers/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/resolvers/chart.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/resolvers/stats.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/rhythm.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/rhythm_strip.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/compose/treemap.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/config/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/config/genome_validator.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/config/registry.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/config/settings.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/connectors/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/connectors/arxiv.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/connectors/base.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/connectors/cache.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/connectors/github.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/connectors/rest.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/cell_layout.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/color.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/contracts.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/enums.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/font_metrics.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/models.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/paradigm.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/schema.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/state.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/text.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/core/thresholds.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/badge_modes.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/css/accessibility.css +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/css/bridge.css +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/css/expression.css +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/css/status.css +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/chakra-petch.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/inter.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/jetbrains-mono.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/font-metrics/orbitron.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-700.b64 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-700.meta.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-900.b64 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/barlow-condensed-900.meta.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/chakra-petch.b64 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/chakra-petch.meta.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/jetbrains-mono.b64 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/jetbrains-mono.meta.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/orbitron.b64 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/fonts/orbitron.meta.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/genomes/automata.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/genomes/brutalist.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/genomes/chrome.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-claude-code.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-codex.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-cream.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/genomes/telemetry-voltage.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/glyphs.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/chromatic-pulse.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/corner-trace.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/dual-orbit.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/entanglement.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/motions/border/rimrun.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/motions/static.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/brutalist.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/cellular.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/chrome.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/paradigms/default.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/policies/normal.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/policies/permissive.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/policies/ungoverned.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/profiles/brutalist.contract.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/profiles/brutalist.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/profiles/chrome.contract.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/profiles/chrome.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/reasoning/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/reasoning/brutalist.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/specimens.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/model-pricing.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/runtimes/claude-code.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/runtimes/codex.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/stage-config.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/stage-labels.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/telemetry/tool-colors.yaml +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/arrow.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/aurora.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/beacon.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/bracket3d.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/chevron.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/crosshair.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/diamond.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rocket.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/bar.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/dashed.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/five-wave.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/spectral.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/straight.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/rules/wave.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/data/terminals/stijl.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/kit.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/mcp/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/mcp/__main__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/mcp/server.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/py.typed +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/render/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/render/chart_engine.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/render/glyphs.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/render/motion.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/render/templates.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/serve/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/serve/app.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/serve/data_tokens.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/capture.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/corrections.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/cost.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/receipt_paths.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/runtimes.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/telemetry/stages.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-area.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-axes.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-empty-state.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-gridlines.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/circle.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/diamond.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/endpoint-diamond.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/endpoint-rect.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-markers/rect.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-milestone-brutalist.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-milestone.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/chart-polyline.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/filter.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/glyph-inline.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/glyph.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/gradient.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/metadata.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/metric.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/phase-segment.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/rule.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/status.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/components/terminal.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/document.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/error-badge.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/cellular-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/cellular-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/chrome-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/chrome-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/default-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge/default-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/badge.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/catalog.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/cellular-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/cellular-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/chrome-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart/chrome-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/chart.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/divider/brutalist-seam.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/divider/chrome-band.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/divider.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/brutalist-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/cellular-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/cellular-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/chrome-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/chrome-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/default-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon/default-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/icon.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-overlay.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/cellular-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/cellular-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/cellular-overlay.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/chrome-overlay.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/default-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal/default-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/marquee-horizontal.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/master-card.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/receipt.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/rhythm-strip.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/cellular-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/cellular-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/chrome-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats/chrome-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/stats.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-dark-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-light-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/brutalist-status.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/cellular-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/cellular-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/cellular-status.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/chrome-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/chrome-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/chrome-status.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/default-content.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/default-defs.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip/default-status.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/frames/strip.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/chromatic-pulse.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/corner-trace.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/dual-orbit.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/entanglement.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/motions/border/rimrun.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/partials/provider-glyphs.svg.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/src/hyperweave/templates/partials/state-signal-cascade.j2 +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/__init__.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/conftest.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/fixtures/codex_session.jsonl +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/fixtures/codex_session_patches.jsonl +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/fixtures/github_contributions/synthetic.html +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/fixtures/session.json +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/fixtures/session.jsonl +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/fixtures/synthetic_session.jsonl +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/helpers.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/snapshots/url_stability/divider_band_chrome_static.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/snapshots/url_stability/icon_github_chrome_static.svg +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_assembler.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_badge_brutalist_dark.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_badge_cellular.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_badge_layout.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_badge_mode.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_chart_engine.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_chromatic_coverage_validator.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_chrome_variants.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_codex_parser.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_compose_bar_chart.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_compose_rhythm_strip.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_compose_treemap.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_compose_variant_field.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_connectors.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_core.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_data_tokens.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_divider_cellular.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_divider_genome_specific.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_font_metrics_chakra.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_genome_automata.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_github_scrape.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_kit.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_marquee_v0_2_16.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_mcp.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_paradigm_dispatch.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_paradigm_extensibility.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_parse_transcript_auto.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_proofset.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_receipt_paths.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_receipt_token_compliance.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_render.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_resolver_rhythm.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_runtime_registries.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_serve.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_serve_live_state.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_slot_metric_state.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_state_inference.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_stats_brutalist.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_stats_card.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_strip_brutalist_grammar.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_strip_cellular.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_strip_status_toggle.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_telemetry.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_telemetry_contract_per_stage.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_telemetry_skin_dispatch.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_tool_class_completeness.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_url_stability.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/tests/test_variant_default_resolution.py +0 -0
- {hyperweave-0.3.5 → hyperweave-0.3.7}/uv.lock +4 -4
|
@@ -5,6 +5,50 @@ 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
|
+
|
|
29
|
+
## [0.3.6] - 2026-05-18
|
|
30
|
+
|
|
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.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- **`just tag VERSION MESSAGE`** — annotated tag plus automatic `_version.py` refresh so the `doctor` banner and metadata version stay in sync after release.
|
|
36
|
+
- **`just version-refresh`** — standalone recipe to rebuild `_version.py` from the current git tag.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **Receipt active-duration** — Claude Code sessions source from `system.turn_duration` events; Codex and mocked fixtures fall back to the prior `min(stage-span sum, wall-clock span)` formula.
|
|
41
|
+
- **Session contract** — new `turn_duration_minutes` field surfaces the parser's per-turn compute sum; null when the runtime emits no per-turn signal.
|
|
42
|
+
- **Codex hooks file** — `install-hook` writes the wrapped-matcher GA format (Codex CLI v0.129+). Existing flat installs are migrated on next install.
|
|
43
|
+
- **Hooks feature flag** — `codex_hooks` renames to `hooks` to match Codex's GA terminology; the legacy name continues to work for one release.
|
|
44
|
+
- **`hyperweave doctor`** — traverses both the new wrapped format and the legacy flat layout, surfacing a migration prompt when a flat config is detected.
|
|
45
|
+
- **Genome root attribute** — `data-hw-genome` reflects the resolved genome ID instead of raw spec input, so variants and auto-resolved genomes never emit empty.
|
|
46
|
+
|
|
47
|
+
### Notes
|
|
48
|
+
|
|
49
|
+
- Codex sessions hit the active-duration fallback because the runtime emits no per-turn duration signal.
|
|
50
|
+
- `_version.py` refreshes automatically when tagging through `just tag`.
|
|
51
|
+
|
|
8
52
|
## [0.3.5] - 2026-05-17
|
|
9
53
|
|
|
10
54
|
Receipt hero reads `token volume · $cost` with a four-cell decomposition strip below (IN / OUT / CACHED / WRITTEN), making the asymmetric cache-token math legible at a glance. Codex receipts now price tokens against the OpenAI rate card; figures previously inflated ~2× drop to actual GPT rates.
|
|
@@ -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>
|
|
@@ -48,3 +48,13 @@ docs:
|
|
|
48
48
|
|
|
49
49
|
build:
|
|
50
50
|
uv build
|
|
51
|
+
|
|
52
|
+
version-refresh:
|
|
53
|
+
uv pip install -e . --force-reinstall --no-deps --quiet
|
|
54
|
+
@uv run python -c "import hyperweave; print(f'_version.py refreshed to {hyperweave.__version__}')"
|
|
55
|
+
|
|
56
|
+
tag VERSION MESSAGE:
|
|
57
|
+
git tag -a {{VERSION}} -m "{{MESSAGE}}"
|
|
58
|
+
just version-refresh
|
|
59
|
+
@echo ""
|
|
60
|
+
@echo "Tagged {{VERSION}}. Push with: git push --follow-tags"
|
|
@@ -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
|
|
@@ -567,8 +567,45 @@ def _install_claude_code_hook(hook_command: str, full_slug: str) -> None:
|
|
|
567
567
|
typer.echo(f"Installed SessionEnd hook in {settings_path}{pinned}")
|
|
568
568
|
|
|
569
569
|
|
|
570
|
+
# Codex hook event names (v0.129.0 GA). Used by ``_install_codex_hook`` and
|
|
571
|
+
# ``_doctor_runtime_status`` to detect pre-GA flat-format event keys sitting
|
|
572
|
+
# at the top of ``hooks.json`` and lift them under the canonical ``hooks``
|
|
573
|
+
# wrapper introduced when hooks went GA.
|
|
574
|
+
_CODEX_HOOK_EVENTS = frozenset(
|
|
575
|
+
{
|
|
576
|
+
"SessionStart",
|
|
577
|
+
"PreToolUse",
|
|
578
|
+
"PermissionRequest",
|
|
579
|
+
"PostToolUse",
|
|
580
|
+
"UserPromptSubmit",
|
|
581
|
+
"Stop",
|
|
582
|
+
}
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
def _wrap_legacy_codex_hook_entry(entry: object) -> object:
|
|
587
|
+
"""Lift a pre-GA bare-command hook entry into the GA matcher+hooks group.
|
|
588
|
+
|
|
589
|
+
Codex v0.129 (hooks GA) changed each event-array entry from a bare
|
|
590
|
+
``{type, command, timeout}`` to a matcher group
|
|
591
|
+
``{matcher, hooks: [{type, command, timeout}]}``. Idempotent: an entry
|
|
592
|
+
already carrying a list-valued ``hooks`` key is returned unchanged so
|
|
593
|
+
repeated migrations stay stable. Bare-command entries are wrapped under
|
|
594
|
+
a universal ``"*"`` matcher; the matcher is parsed-but-ignored for Stop
|
|
595
|
+
today per the spec, but we use ``"*"`` for forward-compat against any
|
|
596
|
+
future Codex release that begins to honor it on Stop.
|
|
597
|
+
"""
|
|
598
|
+
if not isinstance(entry, dict):
|
|
599
|
+
return entry
|
|
600
|
+
if isinstance(entry.get("hooks"), list):
|
|
601
|
+
return entry # already in GA shape
|
|
602
|
+
if entry.get("type") == "command":
|
|
603
|
+
return {"matcher": "*", "hooks": [entry]}
|
|
604
|
+
return entry # unknown shape — preserve as-is
|
|
605
|
+
|
|
606
|
+
|
|
570
607
|
def _install_codex_hook(hook_command: str, full_slug: str) -> None:
|
|
571
|
-
"""Write a Stop hook to ``~/.codex/hooks.json`` + enable
|
|
608
|
+
"""Write a Stop hook to ``~/.codex/hooks.json`` + enable hooks feature.
|
|
572
609
|
|
|
573
610
|
Per developers.openai.com/codex/hooks, Codex CLI fires Stop hooks
|
|
574
611
|
PER-TURN (after every assistant response). The receipt rewrites the
|
|
@@ -579,9 +616,21 @@ def _install_codex_hook(hook_command: str, full_slug: str) -> None:
|
|
|
579
616
|
will lean into live-receipt consumers (file watchers, dashboards)
|
|
580
617
|
rather than collapse it back to a single session-end event.
|
|
581
618
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
619
|
+
Codex v0.129.0 (2026-05-07) took hooks GA with two shape changes the
|
|
620
|
+
installer handles via migration-on-write:
|
|
621
|
+
|
|
622
|
+
* ``hooks.json`` moved from flat ``{Stop: [{type, command, timeout}]}``
|
|
623
|
+
to wrapped ``{hooks: {Stop: [{matcher, hooks: [{type, command,
|
|
624
|
+
timeout}]}]}}``. Any pre-GA event keys at the top level are lifted
|
|
625
|
+
under the new wrapper; each bare-command entry is wrapped under a
|
|
626
|
+
universal ``"*"`` matcher group.
|
|
627
|
+
* ``[features].codex_hooks`` was aliased as ``[features].hooks``. The
|
|
628
|
+
installer strips any legacy ``codex_hooks`` entry and writes the
|
|
629
|
+
canonical ``hooks = true``.
|
|
630
|
+
|
|
631
|
+
Both migrations are idempotent — re-running install-hook over any
|
|
632
|
+
combination of pre-GA, partially-migrated, or GA configs converges to
|
|
633
|
+
the canonical GA shape with exactly one hyperweave entry.
|
|
585
634
|
"""
|
|
586
635
|
import json
|
|
587
636
|
|
|
@@ -590,48 +639,99 @@ def _install_codex_hook(hook_command: str, full_slug: str) -> None:
|
|
|
590
639
|
config_path = codex_dir / "config.toml"
|
|
591
640
|
codex_dir.mkdir(parents=True, exist_ok=True)
|
|
592
641
|
|
|
593
|
-
# ── Update hooks.json:
|
|
642
|
+
# ── Update hooks.json: lift any pre-GA flat keys into the wrapper, then
|
|
643
|
+
# operate on hooks.Stop as the canonical GA structure ──
|
|
594
644
|
config: dict[str, object] = {}
|
|
595
645
|
if hooks_path.exists():
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
646
|
+
loaded = json.loads(hooks_path.read_text())
|
|
647
|
+
if isinstance(loaded, dict):
|
|
648
|
+
config = loaded
|
|
649
|
+
|
|
650
|
+
# GA wrapper: hooks lives under config["hooks"]. Pre-GA configs may not
|
|
651
|
+
# have it yet; create it (or reset if it's the wrong shape).
|
|
652
|
+
wrapper_raw = config.setdefault("hooks", {})
|
|
653
|
+
hooks_wrapper: dict[str, object]
|
|
654
|
+
if isinstance(wrapper_raw, dict):
|
|
655
|
+
hooks_wrapper = wrapper_raw
|
|
656
|
+
else:
|
|
657
|
+
hooks_wrapper = {}
|
|
658
|
+
config["hooks"] = hooks_wrapper
|
|
659
|
+
|
|
660
|
+
# Lift any pre-GA top-level event keys (Stop, PreToolUse, etc.) into the
|
|
661
|
+
# wrapper, wrapping bare-command entries with a universal matcher group.
|
|
662
|
+
# Iterate over a snapshot of keys since we mutate during traversal.
|
|
663
|
+
for legacy_event in list(config.keys()):
|
|
664
|
+
if legacy_event == "hooks" or legacy_event not in _CODEX_HOOK_EVENTS:
|
|
665
|
+
continue
|
|
666
|
+
legacy_value = config.pop(legacy_event)
|
|
667
|
+
if not isinstance(legacy_value, list):
|
|
668
|
+
continue
|
|
669
|
+
target_raw = hooks_wrapper.setdefault(legacy_event, [])
|
|
670
|
+
target: list[object]
|
|
671
|
+
if isinstance(target_raw, list):
|
|
672
|
+
target = target_raw
|
|
673
|
+
else:
|
|
674
|
+
target = []
|
|
675
|
+
hooks_wrapper[legacy_event] = target
|
|
676
|
+
for entry in legacy_value:
|
|
677
|
+
target.append(_wrap_legacy_codex_hook_entry(entry))
|
|
678
|
+
|
|
679
|
+
# Now drop any prior hyperweave matcher groups under hooks.Stop and
|
|
680
|
+
# append the fresh one. A hyperweave group is identified by ANY inner
|
|
681
|
+
# handler whose command mentions "hyperweave session".
|
|
682
|
+
raw_stop = hooks_wrapper.setdefault("Stop", [])
|
|
683
|
+
stop_groups: list[object]
|
|
684
|
+
if isinstance(raw_stop, list):
|
|
685
|
+
stop_groups = raw_stop
|
|
686
|
+
else:
|
|
687
|
+
stop_groups = []
|
|
688
|
+
hooks_wrapper["Stop"] = stop_groups
|
|
602
689
|
|
|
603
|
-
cleaned = []
|
|
604
|
-
for
|
|
605
|
-
if not isinstance(
|
|
606
|
-
cleaned.append(
|
|
690
|
+
cleaned: list[object] = []
|
|
691
|
+
for group in stop_groups:
|
|
692
|
+
if not isinstance(group, dict):
|
|
693
|
+
cleaned.append(group)
|
|
607
694
|
continue
|
|
608
|
-
|
|
609
|
-
if
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
695
|
+
inner_hooks = group.get("hooks", [])
|
|
696
|
+
if isinstance(inner_hooks, list) and any(
|
|
697
|
+
isinstance(h, dict) and "hyperweave session" in str(h.get("command", "")) for h in inner_hooks
|
|
698
|
+
):
|
|
699
|
+
continue # drop the whole matcher group — owned by hyperweave
|
|
700
|
+
cleaned.append(group)
|
|
701
|
+
cleaned.append(
|
|
702
|
+
{
|
|
703
|
+
"matcher": "*",
|
|
704
|
+
"hooks": [{"type": "command", "command": hook_command, "timeout": 10}],
|
|
705
|
+
}
|
|
706
|
+
)
|
|
707
|
+
hooks_wrapper["Stop"] = cleaned
|
|
614
708
|
hooks_path.write_text(json.dumps(config, indent=2) + "\n")
|
|
615
709
|
|
|
616
|
-
# ── Update config.toml: ensure [features]
|
|
710
|
+
# ── Update config.toml: ensure [features] hooks = true (preserve other keys) ──
|
|
711
|
+
# Codex v0.130.0 renamed the gate from `codex_hooks` to `hooks`; strip any
|
|
712
|
+
# legacy key on the way in so re-running install-hook over an older config
|
|
713
|
+
# upgrades cleanly instead of leaving a dead key. Key detection is exact-
|
|
714
|
+
# match (split-on-=, strip), not prefix, so `hooks_*` lookalikes can't
|
|
715
|
+
# spoof a hit.
|
|
617
716
|
config_lines: list[str] = []
|
|
618
717
|
if config_path.exists():
|
|
619
718
|
config_lines = config_path.read_text().splitlines()
|
|
719
|
+
config_lines = [line for line in config_lines if line.split("=", 1)[0].strip() != "codex_hooks"]
|
|
620
720
|
has_features_section = any(line.strip() == "[features]" for line in config_lines)
|
|
621
|
-
|
|
721
|
+
has_hooks_key = any("=" in line and line.split("=", 1)[0].strip() == "hooks" for line in config_lines)
|
|
622
722
|
if not has_features_section:
|
|
623
|
-
config_lines.extend(["", "[features]", "
|
|
624
|
-
elif not
|
|
625
|
-
# Insert
|
|
723
|
+
config_lines.extend(["", "[features]", "hooks = true"])
|
|
724
|
+
elif not has_hooks_key:
|
|
725
|
+
# Insert hooks = true right after [features] header
|
|
626
726
|
for i, line in enumerate(config_lines):
|
|
627
727
|
if line.strip() == "[features]":
|
|
628
|
-
config_lines.insert(i + 1, "
|
|
728
|
+
config_lines.insert(i + 1, "hooks = true")
|
|
629
729
|
break
|
|
630
730
|
config_path.write_text("\n".join(config_lines) + "\n")
|
|
631
731
|
|
|
632
732
|
pinned = f" (pinned to {full_slug})" if full_slug else " (auto-detect skin)"
|
|
633
733
|
typer.echo(f"Installed Stop hook in {hooks_path}{pinned}")
|
|
634
|
-
typer.echo(f"Set [features]
|
|
734
|
+
typer.echo(f"Set [features] hooks = true in {config_path}")
|
|
635
735
|
typer.echo(
|
|
636
736
|
"Note: Codex Stop fires per-turn — the receipt file refreshes live as the "
|
|
637
737
|
"session progresses, always reflecting current cumulative state.",
|
|
@@ -702,7 +802,7 @@ def install_hook(
|
|
|
702
802
|
"auto-detects installed runtimes (~/.claude, ~/.codex, or 'claude'/"
|
|
703
803
|
"'codex' on PATH) and registers for each present. 'claude-code' "
|
|
704
804
|
"writes a SessionEnd hook to ~/.claude/settings.json. 'codex' writes "
|
|
705
|
-
"a Stop hook to ~/.codex/hooks.json plus [features]
|
|
805
|
+
"a Stop hook to ~/.codex/hooks.json plus [features] hooks in "
|
|
706
806
|
"~/.codex/config.toml. 'all' forces both regardless of detection."
|
|
707
807
|
),
|
|
708
808
|
),
|
|
@@ -771,8 +871,8 @@ def _doctor_runtime_status(runtime: str, home_dir: Path) -> str:
|
|
|
771
871
|
Returns ``✓`` when the hyperweave hook is wired correctly, ``✗`` when
|
|
772
872
|
the runtime is initialized but no hyperweave hook is registered, or
|
|
773
873
|
``⚠`` when the wiring is partial (malformed config; codex missing the
|
|
774
|
-
[features]
|
|
775
|
-
``doctor``.
|
|
874
|
+
[features] hooks flag — renamed from ``codex_hooks`` in Codex v0.130.0).
|
|
875
|
+
The string is rendered verbatim by ``doctor``.
|
|
776
876
|
"""
|
|
777
877
|
import json
|
|
778
878
|
|
|
@@ -802,24 +902,56 @@ def _doctor_runtime_status(runtime: str, home_dir: Path) -> str:
|
|
|
802
902
|
hooks_path = home_dir / "hooks.json"
|
|
803
903
|
config_path = home_dir / "config.toml"
|
|
804
904
|
registered_cmd: str | None = None
|
|
905
|
+
legacy_flat_cmd: str | None = None
|
|
805
906
|
if hooks_path.exists():
|
|
806
907
|
try:
|
|
807
908
|
hooks = json.loads(hooks_path.read_text())
|
|
808
909
|
except json.JSONDecodeError:
|
|
809
910
|
return f"⚠ {runtime}: ~/.codex/hooks.json is malformed"
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
911
|
+
# GA traversal (Codex v0.129+):
|
|
912
|
+
# hooks["hooks"]["Stop"][group].hooks[handler].command
|
|
913
|
+
wrapper = hooks.get("hooks") if isinstance(hooks, dict) else None
|
|
914
|
+
if isinstance(wrapper, dict):
|
|
915
|
+
for group in wrapper.get("Stop") or []:
|
|
916
|
+
if not isinstance(group, dict):
|
|
917
|
+
continue
|
|
918
|
+
for handler in group.get("hooks") or []:
|
|
919
|
+
if not isinstance(handler, dict):
|
|
920
|
+
continue
|
|
921
|
+
cmd = str(handler.get("command", ""))
|
|
922
|
+
if "hyperweave session" in cmd:
|
|
923
|
+
registered_cmd = cmd
|
|
924
|
+
break
|
|
925
|
+
if registered_cmd:
|
|
926
|
+
break
|
|
927
|
+
# Pre-GA flat fallback (kept for one release): hooks["Stop"][entry]
|
|
928
|
+
# with command directly on the entry. Detected separately so a
|
|
929
|
+
# legacy install surfaces as ⚠ with an upgrade pointer instead of
|
|
930
|
+
# silently misreporting the hook as missing.
|
|
931
|
+
if not registered_cmd and isinstance(hooks, dict):
|
|
932
|
+
for entry in hooks.get("Stop") or []:
|
|
933
|
+
if not isinstance(entry, dict):
|
|
934
|
+
continue
|
|
935
|
+
cmd = str(entry.get("command", ""))
|
|
936
|
+
if "hyperweave session" in cmd:
|
|
937
|
+
legacy_flat_cmd = cmd
|
|
938
|
+
break
|
|
939
|
+
if legacy_flat_cmd and not registered_cmd:
|
|
940
|
+
return (
|
|
941
|
+
f"⚠ {runtime}: hook registered in legacy pre-GA flat format — "
|
|
942
|
+
f"re-run 'hyperweave install-hook --runtime {runtime}' to lift "
|
|
943
|
+
f"it to the GA wrapped structure (Codex v0.129+)"
|
|
944
|
+
)
|
|
817
945
|
if not registered_cmd:
|
|
818
946
|
return (
|
|
819
947
|
f"✗ {runtime}: initialized but no hyperweave hook — run 'hyperweave install-hook --runtime {runtime}'"
|
|
820
948
|
)
|
|
821
|
-
# [features]
|
|
822
|
-
#
|
|
949
|
+
# [features] hooks = true must be present for the hook to fire; the
|
|
950
|
+
# install command writes it, but a hand-edited config could miss it.
|
|
951
|
+
# Codex v0.130.0 renamed the gate from `codex_hooks` to `hooks`; key
|
|
952
|
+
# detection is exact-match within the [features] section so a stale
|
|
953
|
+
# `codex_hooks = true` left over from older installs is not mistaken
|
|
954
|
+
# for the live gate (and so `hooks_*` lookalikes can't spoof a hit).
|
|
823
955
|
feature_ok = False
|
|
824
956
|
if config_path.exists():
|
|
825
957
|
in_features = False
|
|
@@ -831,12 +963,14 @@ def _doctor_runtime_status(runtime: str, home_dir: Path) -> str:
|
|
|
831
963
|
if in_features and stripped.startswith("["):
|
|
832
964
|
in_features = False
|
|
833
965
|
continue
|
|
834
|
-
if in_features and
|
|
835
|
-
|
|
836
|
-
|
|
966
|
+
if in_features and "=" in stripped:
|
|
967
|
+
key, _, value = stripped.partition("=")
|
|
968
|
+
if key.strip() == "hooks" and "true" in value:
|
|
969
|
+
feature_ok = True
|
|
970
|
+
break
|
|
837
971
|
if not feature_ok:
|
|
838
972
|
return (
|
|
839
|
-
f"⚠ {runtime}: hook registered but [features]
|
|
973
|
+
f"⚠ {runtime}: hook registered but [features] hooks = true "
|
|
840
974
|
f"is missing — re-run 'hyperweave install-hook --runtime {runtime}'"
|
|
841
975
|
)
|
|
842
976
|
return f"✓ {runtime}: hook registered — {registered_cmd}"
|