hyperweave 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hyperweave-0.2.1 → hyperweave-0.2.2}/.gitignore +2 -2
- {hyperweave-0.2.1 → hyperweave-0.2.2}/CHANGELOG.md +6 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/PKG-INFO +1 -1
- hyperweave-0.2.2/scripts/extract_glyphs.py +276 -0
- hyperweave-0.2.2/scripts/generate_hw_compliant.py +327 -0
- hyperweave-0.2.2/scripts/generate_proofset.py +613 -0
- hyperweave-0.2.2/scripts/stress_test.py +521 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/_version.py +2 -2
- {hyperweave-0.2.1 → hyperweave-0.2.2}/.dockerignore +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/.github/workflows/ci.yml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/.github/workflows/deploy.yml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/.github/workflows/publish.yml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/Dockerfile +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/LICENSE +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/README.md +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/buttons/button-liquid.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/cards/card-butterfly.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/cards/card-python.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/cards/card-sunflower.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/cards/card-waves.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/badge_critical.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/badge_passing.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/badge_warning.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/banner.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/icons/discord.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/icons/notion.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/icons/reddit.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/icons/spotify.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/icons/youtube.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/marquee_counter.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/marquee_horizontal.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/marquee_vertical.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/profile-cards/stats.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/brutalist-emerald/strip.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/badge_critical.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/badge_passing.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/badge_warning.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/banner.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/icons/bluesky.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/icons/github.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/icons/instagram.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/icons/mastodon.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/icons/x.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/marquee_counter.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/marquee_horizontal.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/marquee_vertical.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/profile-cards/chart_stars_full.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/profile-cards/stats.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/chrome-horizon/strip.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/telemetry/master_card.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/telemetry/receipt.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/examples/telemetry/rhythm_strip.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/footers/inneraura-footer-liquid.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/footers/inneraura-footer-purple.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/footers/inneraura-footer.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-discord.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-docs.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-github.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-instagram.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-linkedin.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-tiktok.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-x.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/icons/cobalt-sapphire-youtube.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/marquees/badge-showcase-triple.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/marquees/genome-marquee-triple.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/marquees/sample-badges.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/404.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/callout-icons.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/divider.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/favicon.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/hero-banner.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/hyperweave-banner-v2.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/loader.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/mintlify-assets/og-image.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/assets/timelines/hyperweave-roadmap.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/assets/favicon.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/assets/hyperweave-banner.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/assets/hyperweave-navbar-logo.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/assets/og-image.svg +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/explanation/architecture.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/explanation/camo-compatibility.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/explanation/cim-compliance.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/explanation/genome-profile-system.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/explanation/metadata-tiers.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/how-to/add-motion-to-badges.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/how-to/create-session-receipts.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/how-to/set-up-claude-code-hooks.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/how-to/use-live-data-badges.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/introduction.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/mint.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/quickstart.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/reference/cli.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/reference/compose-spec.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/reference/genomes.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/reference/http-api.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/reference/mcp-tools.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/reference/motions.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/reference/telemetry-contract.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/spec/hyperweave-protocol.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/tutorials/build-an-artifact-kit.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/tutorials/compose-your-first-badge.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/docs/tutorials/install-session-telemetry.mdx +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/fly.toml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/hooks/install.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/hooks/session_end.sh +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/justfile +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/pyproject.toml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/__main__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/cli.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/assembler.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/context.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/engine.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/lanes.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/resolver.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/resolvers/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/resolvers/chart.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/resolvers/stats.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/compose/resolvers/timeline.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/config/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/config/genome_validator.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/config/loader.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/config/registry.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/config/settings.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/connectors/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/connectors/arxiv.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/connectors/base.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/connectors/cache.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/connectors/github.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/connectors/rest.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/color.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/contracts.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/enums.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/models.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/schema.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/text.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/core/thresholds.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/css/accessibility.css +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/css/bridge.css +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/css/expression.css +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/css/phase-colors.css +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/css/status.css +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/css/telemetry.css +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/font-metrics/inter.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/fonts/jetbrains-mono.b64 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/fonts/jetbrains-mono.meta.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/fonts/orbitron.b64 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/fonts/orbitron.meta.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/genomes/brutalist-emerald.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/genomes/chrome-horizon.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/genomes/telemetry-void.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/glyphs.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/border/chromatic-pulse.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/border/corner-trace.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/border/dual-orbit.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/border/entanglement.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/border/rimrun.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/bars.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/breach.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/broadcast.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/cascade.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/collapse.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/converge.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/crash.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/drop.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/kinetic/pulse.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/motions/static.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/policies/normal.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/policies/permissive.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/policies/ungoverned.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/profiles/brutalist.contract.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/profiles/brutalist.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/profiles/chrome.contract.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/profiles/chrome.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/specimens.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/telemetry/model-pricing.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/telemetry/stage-config.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/telemetry/stage-labels.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/telemetry/tool-classes.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/telemetry/tool-colors.yaml +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/arrow.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/aurora.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/beacon.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/bracket3d.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/chevron.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/crosshair.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/diamond.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/rocket.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/rules/bar.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/rules/dashed.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/rules/five-wave.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/rules/spectral.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/rules/straight.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/rules/wave.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/data/terminals/stijl.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/kit.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/mcp/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/mcp/__main__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/mcp/server.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/py.typed +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/render/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/render/chart_engine.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/render/fonts.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/render/glyphs.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/render/motion.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/render/templates.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/serve/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/serve/app.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/capture.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/contract.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/corrections.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/cost.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/models.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/parser.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/telemetry/stages.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/filter.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/glyph-inline.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/glyph.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/gradient.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/metadata.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/metric.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/phase-segment.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/rule.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/status.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/terminal.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/components/treemap.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/document.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/error-badge.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/badge/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/badge/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/badge/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/badge/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/badge/default-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/badge/default-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/badge.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/banner/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/banner/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/banner/default-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/banner.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/catalog.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/chart/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/chart/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/chart/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/chart/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/chart.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/divider.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/icon/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/icon/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/icon/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/icon/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/icon/default-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/icon/default-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/icon.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-counter/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-counter/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-counter/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-counter/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-counter.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-horizontal/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-horizontal/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-horizontal/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-horizontal.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-vertical/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-vertical/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-vertical/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-vertical/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/marquee-vertical.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/master-card.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/receipt.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/rhythm-strip.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/stats/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/stats/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/stats/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/stats/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/stats.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/brutalist-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/brutalist-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/brutalist-status.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/chrome-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/chrome-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/chrome-status.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/default-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/default-defs.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip/default-status.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/strip.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/timeline/default-content.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/frames/timeline.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/border/chromatic-pulse.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/border/corner-trace.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/border/dual-orbit.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/border/entanglement.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/border/rimrun.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/bars.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/breach.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/broadcast.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/cascade.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/collapse.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/converge.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/crash.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/drop.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/src/hyperweave/templates/motions/kinetic/pulse.svg.j2 +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/__init__.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/conftest.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/fixtures/github_contributions/synthetic.html +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/fixtures/session.json +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/fixtures/session.jsonl +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_assembler.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_chart_engine.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_chart_frame.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_connectors.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_core.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_github_scrape.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_kit.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_mcp.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_paradigm_dispatch.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_proofset.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_render.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_serve.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_stats_card.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_telemetry.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_telemetry_integration.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/tests/test_timeline.py +0 -0
- {hyperweave-0.2.1 → hyperweave-0.2.2}/uv.lock +0 -0
|
@@ -27,10 +27,10 @@ htmlcov/
|
|
|
27
27
|
archive/
|
|
28
28
|
.claude/
|
|
29
29
|
# CLAUDE.md
|
|
30
|
-
docs/_notes/
|
|
30
|
+
docs/_notes/
|
|
31
31
|
outputs/
|
|
32
|
-
scripts/
|
|
33
32
|
specs/
|
|
33
|
+
# scripts/ is version-controlled (tests/test_proofset.py imports generate_proofset.py)
|
|
34
34
|
|
|
35
35
|
assets/cards/butterfly-mcp.svg
|
|
36
36
|
assets/cards/card-moon.svg
|
|
@@ -5,6 +5,12 @@ All notable changes to HyperWeave are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.2] - 2026-04-13
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **CI test job** was red on the v0.2.1 push because `tests/test_proofset.py` imports `scripts/generate_proofset.py`, but `scripts/` was excluded from version control by `.gitignore`. The three test runners saw `FileNotFoundError: No such file or directory: scripts/generate_proofset.py`. `scripts/` is now tracked (it is a dev-tools directory, not a runtime dependency, and remains excluded from the PyPI wheel by `[tool.hatch.build.targets.wheel].packages`).
|
|
13
|
+
|
|
8
14
|
## [0.2.1] - 2026-04-13
|
|
9
15
|
|
|
10
16
|
Post-v0.2.0 stabilization: typography alignment, mobile rendering fix, and a streak computation correction.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hyperweave
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
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
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Extract curated glyphs from Simple Icons and output data/glyphs.json.
|
|
3
|
+
|
|
4
|
+
Build-time only. Requires: npm install simple-icons (temp dev dependency).
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
npm install simple-icons # one-time
|
|
8
|
+
python scripts/extract_glyphs.py
|
|
9
|
+
|
|
10
|
+
Output:
|
|
11
|
+
src/hyperweave/data/glyphs.json
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import json
|
|
17
|
+
import subprocess
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
# Curated icon set per PRD SS10
|
|
22
|
+
# Keys = Simple Icons export names (camelCase with 'si' prefix)
|
|
23
|
+
# Values = (our slug, category)
|
|
24
|
+
CURATED_ICONS: dict[str, tuple[str, str]] = {
|
|
25
|
+
# Social (LinkedIn/Slack removed from SI v16 — trademark)
|
|
26
|
+
"siGithub": ("github", "social"),
|
|
27
|
+
"siX": ("x", "social"),
|
|
28
|
+
"siDiscord": ("discord", "social"),
|
|
29
|
+
"siYoutube": ("youtube", "social"),
|
|
30
|
+
"siSpotify": ("spotify", "social"),
|
|
31
|
+
"siInstagram": ("instagram", "social"),
|
|
32
|
+
"siTiktok": ("tiktok", "social"),
|
|
33
|
+
"siReddit": ("reddit", "social"),
|
|
34
|
+
"siMastodon": ("mastodon", "social"),
|
|
35
|
+
"siBluesky": ("bluesky", "social"),
|
|
36
|
+
# Dev
|
|
37
|
+
"siPython": ("python", "dev"),
|
|
38
|
+
"siNpm": ("npm", "dev"),
|
|
39
|
+
"siDocker": ("docker", "dev"),
|
|
40
|
+
"siRust": ("rust", "dev"),
|
|
41
|
+
"siGo": ("go", "dev"),
|
|
42
|
+
"siTypescript": ("typescript", "dev"),
|
|
43
|
+
"siJavascript": ("javascript", "dev"),
|
|
44
|
+
"siReact": ("react", "dev"),
|
|
45
|
+
"siVuedotjs": ("vue", "dev"),
|
|
46
|
+
"siSvelte": ("svelte", "dev"),
|
|
47
|
+
"siNextdotjs": ("nextjs", "dev"),
|
|
48
|
+
"siNodedotjs": ("nodejs", "dev"),
|
|
49
|
+
"siDeno": ("deno", "dev"),
|
|
50
|
+
"siSwift": ("swift", "dev"),
|
|
51
|
+
"siKotlin": ("kotlin", "dev"),
|
|
52
|
+
"siCplusplus": ("cplusplus", "dev"),
|
|
53
|
+
"siRuby": ("ruby", "dev"),
|
|
54
|
+
"siPhp": ("php", "dev"),
|
|
55
|
+
"siElixir": ("elixir", "dev"),
|
|
56
|
+
"siZig": ("zig", "dev"),
|
|
57
|
+
# Platforms (AWS/Azure/Heroku removed from SI v16 — trademark)
|
|
58
|
+
"siPypi": ("pypi", "platforms"),
|
|
59
|
+
"siHuggingface": ("huggingface", "platforms"),
|
|
60
|
+
"siArxiv": ("arxiv", "platforms"),
|
|
61
|
+
"siKaggle": ("kaggle", "platforms"),
|
|
62
|
+
"siVercel": ("vercel", "platforms"),
|
|
63
|
+
"siNetlify": ("netlify", "platforms"),
|
|
64
|
+
"siCloudflare": ("cloudflare", "platforms"),
|
|
65
|
+
"siGooglecloud": ("googlecloud", "platforms"),
|
|
66
|
+
"siDigitalocean": ("digitalocean", "platforms"),
|
|
67
|
+
"siSupabase": ("supabase", "platforms"),
|
|
68
|
+
"siFirebase": ("firebase", "platforms"),
|
|
69
|
+
"siGithubactions": ("githubactions", "platforms"),
|
|
70
|
+
"siGitlab": ("gitlab", "platforms"),
|
|
71
|
+
"siBitbucket": ("bitbucket", "platforms"),
|
|
72
|
+
# Tools (VS Code removed from SI v16 — trademark)
|
|
73
|
+
"siNeovim": ("neovim", "tools"),
|
|
74
|
+
"siFigma": ("figma", "tools"),
|
|
75
|
+
"siNotion": ("notion", "tools"),
|
|
76
|
+
"siObsidian": ("obsidian", "tools"),
|
|
77
|
+
"siLinear": ("linear", "tools"),
|
|
78
|
+
"siPostman": ("postman", "tools"),
|
|
79
|
+
"siGrafana": ("grafana", "tools"),
|
|
80
|
+
"siPrometheus": ("prometheus", "tools"),
|
|
81
|
+
"siJetbrains": ("jetbrains", "tools"),
|
|
82
|
+
"siSublimetext": ("sublimetext", "tools"),
|
|
83
|
+
"siStorybook": ("storybook", "tools"),
|
|
84
|
+
"siEslint": ("eslint", "tools"),
|
|
85
|
+
"siPrettier": ("prettier", "tools"),
|
|
86
|
+
# AI / ML (OpenAI removed from SI v16 — trademark)
|
|
87
|
+
"siAnthropic": ("anthropic", "ai"),
|
|
88
|
+
"siTensorflow": ("tensorflow", "ai"),
|
|
89
|
+
"siPytorch": ("pytorch", "ai"),
|
|
90
|
+
"siJupyter": ("jupyter", "ai"),
|
|
91
|
+
"siApachespark": ("spark", "ai"),
|
|
92
|
+
"siGithubcopilot": ("githubcopilot", "ai"),
|
|
93
|
+
# Infrastructure (AWS/Azure/Heroku removed from SI v16 — trademark)
|
|
94
|
+
"siKubernetes": ("kubernetes", "infra"),
|
|
95
|
+
"siTerraform": ("terraform", "infra"),
|
|
96
|
+
"siNginx": ("nginx", "infra"),
|
|
97
|
+
"siRedis": ("redis", "infra"),
|
|
98
|
+
"siPostgresql": ("postgresql", "infra"),
|
|
99
|
+
"siMongodb": ("mongodb", "infra"),
|
|
100
|
+
"siElasticsearch": ("elasticsearch", "infra"),
|
|
101
|
+
"siApachekafka": ("kafka", "infra"),
|
|
102
|
+
"siRabbitmq": ("rabbitmq", "infra"),
|
|
103
|
+
"siGnubash": ("bash", "infra"),
|
|
104
|
+
"siGit": ("git", "infra"),
|
|
105
|
+
# Web / Frameworks
|
|
106
|
+
"siTailwindcss": ("tailwindcss", "dev"),
|
|
107
|
+
"siVite": ("vite", "dev"),
|
|
108
|
+
"siBun": ("bun", "dev"),
|
|
109
|
+
"siPnpm": ("pnpm", "dev"),
|
|
110
|
+
"siAstro": ("astro", "dev"),
|
|
111
|
+
"siRemix": ("remix", "dev"),
|
|
112
|
+
"siFlutter": ("flutter", "dev"),
|
|
113
|
+
"siDart": ("dart", "dev"),
|
|
114
|
+
"siHtml5": ("html5", "dev"),
|
|
115
|
+
"siSass": ("sass", "dev"),
|
|
116
|
+
"siMarkdown": ("markdown", "dev"),
|
|
117
|
+
# Mobile / OS
|
|
118
|
+
"siAndroid": ("android", "platforms"),
|
|
119
|
+
"siApple": ("apple", "platforms"),
|
|
120
|
+
"siLinux": ("linux", "platforms"),
|
|
121
|
+
# Commerce / Services
|
|
122
|
+
"siStripe": ("stripe", "platforms"),
|
|
123
|
+
"siShopify": ("shopify", "platforms"),
|
|
124
|
+
"siAuth0": ("auth0", "platforms"),
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
# Geometric shapes (hand-authored, not from Simple Icons)
|
|
128
|
+
# Defined in 640x640 viewBox per PRD SS10
|
|
129
|
+
GEOMETRIC_SHAPES: dict[str, dict[str, str | None]] = {
|
|
130
|
+
"triangle": {
|
|
131
|
+
"path": "M320 53.3 586.6 533.3H53.4Z",
|
|
132
|
+
"viewBox": "0 0 640 640",
|
|
133
|
+
"brand_color": None,
|
|
134
|
+
"category": "geometric",
|
|
135
|
+
},
|
|
136
|
+
"diamond": {
|
|
137
|
+
"path": "M320 53.3 506.7 320 320 586.7 133.3 320Z",
|
|
138
|
+
"viewBox": "0 0 640 640",
|
|
139
|
+
"brand_color": None,
|
|
140
|
+
"category": "geometric",
|
|
141
|
+
},
|
|
142
|
+
"hexagon": {
|
|
143
|
+
"path": "M320 53.3 566.4 186.7V453.3L320 586.7 73.6 453.3V186.7Z",
|
|
144
|
+
"viewBox": "0 0 640 640",
|
|
145
|
+
"brand_color": None,
|
|
146
|
+
"category": "geometric",
|
|
147
|
+
},
|
|
148
|
+
"shield": {
|
|
149
|
+
"path": "M320 53.3 533.3 186.7V373.3C533.3 480 320 586.7 320 586.7S106.7 480 106.7 373.3V186.7Z",
|
|
150
|
+
"viewBox": "0 0 640 640",
|
|
151
|
+
"brand_color": None,
|
|
152
|
+
"category": "geometric",
|
|
153
|
+
},
|
|
154
|
+
"circle": {
|
|
155
|
+
"path": "M320 106.7A213.3 213.3 0 11106.7 320 213.3 213.3 0 01320 106.7Z",
|
|
156
|
+
"viewBox": "0 0 640 640",
|
|
157
|
+
"brand_color": None,
|
|
158
|
+
"category": "geometric",
|
|
159
|
+
},
|
|
160
|
+
"star": {
|
|
161
|
+
"path": (
|
|
162
|
+
"M320 53.3 396.4 237.8 586.7 253.3 440 381.5 483.3 566.7"
|
|
163
|
+
" 320 471.1 156.7 566.7 200 381.5 53.3 253.3 243.6 237.8Z"
|
|
164
|
+
),
|
|
165
|
+
"viewBox": "0 0 640 640",
|
|
166
|
+
"brand_color": None,
|
|
167
|
+
"category": "geometric",
|
|
168
|
+
},
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def extract_from_npm() -> dict[str, dict[str, object]]:
|
|
173
|
+
"""Extract icons from the simple-icons npm package via Node.js subprocess.
|
|
174
|
+
|
|
175
|
+
Uses `node -e` to require simple-icons, extract all curated paths,
|
|
176
|
+
and return JSON to stdout. This avoids parsing JS manually.
|
|
177
|
+
"""
|
|
178
|
+
# Build the Node.js extraction script
|
|
179
|
+
icon_keys = list(CURATED_ICONS.keys())
|
|
180
|
+
icon_keys_json = json.dumps(icon_keys)
|
|
181
|
+
slugs_json = json.dumps({k: v[0] for k, v in CURATED_ICONS.items()})
|
|
182
|
+
cats_json = json.dumps({k: v[1] for k, v in CURATED_ICONS.items()})
|
|
183
|
+
|
|
184
|
+
node_script = f"""
|
|
185
|
+
const si = require('simple-icons');
|
|
186
|
+
const keys = {icon_keys_json};
|
|
187
|
+
const slugs = {slugs_json};
|
|
188
|
+
const cats = {cats_json};
|
|
189
|
+
const result = {{}};
|
|
190
|
+
for (const key of keys) {{
|
|
191
|
+
const icon = si[key];
|
|
192
|
+
if (!icon) {{
|
|
193
|
+
process.stderr.write('WARN: ' + key + ' not found in simple-icons\\n');
|
|
194
|
+
continue;
|
|
195
|
+
}}
|
|
196
|
+
result[slugs[key]] = {{
|
|
197
|
+
path: icon.path,
|
|
198
|
+
viewBox: '0 0 24 24',
|
|
199
|
+
brand_color: '#' + icon.hex,
|
|
200
|
+
category: cats[key],
|
|
201
|
+
}};
|
|
202
|
+
}}
|
|
203
|
+
process.stdout.write(JSON.stringify(result));
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
proc = subprocess.run(
|
|
208
|
+
["node", "-e", node_script],
|
|
209
|
+
capture_output=True,
|
|
210
|
+
text=True,
|
|
211
|
+
timeout=30,
|
|
212
|
+
)
|
|
213
|
+
if proc.returncode != 0:
|
|
214
|
+
print(f"Node.js extraction failed: {proc.stderr}", file=sys.stderr)
|
|
215
|
+
return {}
|
|
216
|
+
if proc.stderr:
|
|
217
|
+
# Print warnings (missing icons)
|
|
218
|
+
for line in proc.stderr.strip().splitlines():
|
|
219
|
+
print(line, file=sys.stderr)
|
|
220
|
+
|
|
221
|
+
return json.loads(proc.stdout)
|
|
222
|
+
|
|
223
|
+
except FileNotFoundError:
|
|
224
|
+
print("Node.js not found. Install Node.js to extract Simple Icons.", file=sys.stderr)
|
|
225
|
+
return {}
|
|
226
|
+
except subprocess.TimeoutExpired:
|
|
227
|
+
print("Node.js extraction timed out.", file=sys.stderr)
|
|
228
|
+
return {}
|
|
229
|
+
except json.JSONDecodeError as e:
|
|
230
|
+
print(f"Invalid JSON from Node.js: {e}", file=sys.stderr)
|
|
231
|
+
return {}
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def main() -> None:
|
|
235
|
+
"""Run glyph extraction and write data/glyphs.json."""
|
|
236
|
+
output_path = Path(__file__).resolve().parent.parent / "src" / "hyperweave" / "data" / "glyphs.json"
|
|
237
|
+
|
|
238
|
+
# Extract from npm (via Node subprocess)
|
|
239
|
+
glyphs = extract_from_npm()
|
|
240
|
+
|
|
241
|
+
if not glyphs:
|
|
242
|
+
print("No SI icons extracted. Check that simple-icons is installed.", file=sys.stderr)
|
|
243
|
+
print("Run: npm install simple-icons", file=sys.stderr)
|
|
244
|
+
sys.exit(1)
|
|
245
|
+
|
|
246
|
+
# Add geometric shapes (always)
|
|
247
|
+
for glyph_id, definition in GEOMETRIC_SHAPES.items():
|
|
248
|
+
glyphs[glyph_id] = definition # type: ignore[assignment]
|
|
249
|
+
|
|
250
|
+
# Sort by category then name for readability
|
|
251
|
+
sorted_glyphs = dict(
|
|
252
|
+
sorted(
|
|
253
|
+
glyphs.items(),
|
|
254
|
+
key=lambda x: (x[1].get("category", "zzz"), x[0]),
|
|
255
|
+
)
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
# Write output
|
|
259
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
260
|
+
with output_path.open("w", encoding="utf-8") as f:
|
|
261
|
+
json.dump(sorted_glyphs, f, indent=2)
|
|
262
|
+
f.write("\n")
|
|
263
|
+
|
|
264
|
+
# Summary
|
|
265
|
+
by_cat: dict[str, int] = {}
|
|
266
|
+
for v in sorted_glyphs.values():
|
|
267
|
+
cat = v.get("category", "unknown")
|
|
268
|
+
by_cat[cat] = by_cat.get(cat, 0) + 1
|
|
269
|
+
|
|
270
|
+
print(f"Wrote {len(sorted_glyphs)} glyphs to {output_path}")
|
|
271
|
+
for cat, count in sorted(by_cat.items()):
|
|
272
|
+
print(f" {cat}: {count}")
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
if __name__ == "__main__":
|
|
276
|
+
main()
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generate HW-compliant versions of all specimen SVGs.
|
|
3
|
+
|
|
4
|
+
For each specimen SVG in specs/components/ and specs/motion/:
|
|
5
|
+
1. Do NOT modify originals
|
|
6
|
+
2. Create hw-compliant/ subfolder within each specimen's directory
|
|
7
|
+
3. Regenerate with full HyperWeave v8.0 protocol scaffolding
|
|
8
|
+
4. ZERO visual changes
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
python3 scripts/generate_hw_compliant.py
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import re
|
|
17
|
+
import uuid
|
|
18
|
+
from datetime import UTC, datetime
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
ROOT = Path(__file__).resolve().parent.parent
|
|
22
|
+
SPECS = ROOT / "specs"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _has_hw_metadata(svg: str) -> bool:
|
|
26
|
+
"""Check if SVG already has HW protocol metadata."""
|
|
27
|
+
return "hw:artifact" in svg and "xmlns:hw" in svg and 'role="img"' in svg
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _has_reduced_motion(svg: str) -> bool:
|
|
31
|
+
return "prefers-reduced-motion" in svg
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _has_color_scheme(svg: str) -> bool:
|
|
35
|
+
return "prefers-color-scheme" in svg
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _extract_viewbox(svg: str) -> str:
|
|
39
|
+
m = re.search(r'viewBox="([^"]+)"', svg, re.IGNORECASE)
|
|
40
|
+
return m.group(1) if m else "0 0 800 220"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _extract_dims(svg: str) -> tuple[str, str]:
|
|
44
|
+
"""Extract width/height from SVG, preserving original values exactly."""
|
|
45
|
+
w = re.search(r'width="([^"]+)"', svg)
|
|
46
|
+
h = re.search(r'height="([^"]+)"', svg)
|
|
47
|
+
return (w.group(1) if w else "800", h.group(1) if h else "220")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _extract_svg_tag(svg: str) -> tuple[str, str]:
|
|
51
|
+
"""Split into the opening <svg ...> tag and everything after."""
|
|
52
|
+
m = re.match(r"(<svg[^>]*>)(.*)", svg, re.DOTALL)
|
|
53
|
+
if m:
|
|
54
|
+
return m.group(1), m.group(2)
|
|
55
|
+
return "<svg>", svg
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _augment_svg_tag(tag: str, attrs: dict[str, str]) -> str:
|
|
59
|
+
"""Add attributes to an existing <svg ...> tag without replacing originals.
|
|
60
|
+
|
|
61
|
+
Preserves ALL original attributes (xmlns, viewBox, width, height, etc.).
|
|
62
|
+
Only ADDS attributes that don't already exist in the tag.
|
|
63
|
+
"""
|
|
64
|
+
for key, val in attrs.items():
|
|
65
|
+
# Skip if attribute already exists
|
|
66
|
+
if f"{key}=" in tag or f"{key} =" in tag:
|
|
67
|
+
continue
|
|
68
|
+
# Insert before the closing >
|
|
69
|
+
tag = tag.rstrip(">").rstrip() + f'\n {key}="{val}">'
|
|
70
|
+
# Fix: ensure single closing >
|
|
71
|
+
tag = tag.replace(">>", ">")
|
|
72
|
+
return tag
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _infer_type(path: Path) -> str:
|
|
76
|
+
"""Infer artifact type from directory structure."""
|
|
77
|
+
parts = str(path).lower()
|
|
78
|
+
if "divider" in parts:
|
|
79
|
+
return "divider"
|
|
80
|
+
if "icon" in parts:
|
|
81
|
+
return "icon"
|
|
82
|
+
if "banner" in parts or "holofoil" in parts:
|
|
83
|
+
return "banner"
|
|
84
|
+
if "marquee" in parts:
|
|
85
|
+
return "marquee"
|
|
86
|
+
if "border-frame" in parts:
|
|
87
|
+
return "motion-primitive"
|
|
88
|
+
if "kinetic-typography" in parts:
|
|
89
|
+
return "kinetic-typography"
|
|
90
|
+
return "specimen"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _infer_motion_id(path: Path) -> str:
|
|
94
|
+
"""Infer motion ID from filename."""
|
|
95
|
+
name = path.stem.lower()
|
|
96
|
+
mapping = {
|
|
97
|
+
"002-chromatic-pulse": "chromatic-pulse",
|
|
98
|
+
"003-corner-trace": "corner-trace",
|
|
99
|
+
"004-dual-orbit": "dual-orbit",
|
|
100
|
+
"020-quantum-entanglement": "entanglement",
|
|
101
|
+
"rim-runners": "rimrun",
|
|
102
|
+
"banner_bars": "bars",
|
|
103
|
+
"banner_broadcast": "broadcast",
|
|
104
|
+
"banner_cascade": "cascade",
|
|
105
|
+
"banner_convergence": "converge",
|
|
106
|
+
"banner_drop": "drop",
|
|
107
|
+
"crash": "crash",
|
|
108
|
+
"chromatic_impact_physics": "impact",
|
|
109
|
+
"quantum_tunneling_breach": "breach",
|
|
110
|
+
"pulse": "pulse",
|
|
111
|
+
"z_axis_illusion_via_exponential_scale_blur_convergence": "collapse",
|
|
112
|
+
}
|
|
113
|
+
return mapping.get(name, name)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _slug(path: Path) -> str:
|
|
117
|
+
return path.stem.lower().replace(" ", "-").replace("_", "-")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _check_cim(svg: str) -> tuple[bool, str]:
|
|
121
|
+
"""Check CIM compliance and return waiver if needed."""
|
|
122
|
+
non_cim_indicators = []
|
|
123
|
+
if "stop-color" in svg and "animate" in svg.lower():
|
|
124
|
+
non_cim_indicators.append("stop-color animation")
|
|
125
|
+
if "stroke-dashoffset" in svg and "animate" in svg.lower():
|
|
126
|
+
non_cim_indicators.append("stroke-dashoffset animation")
|
|
127
|
+
if "stroke-width" in svg and "<animate" in svg.lower() and "stroke-width" in svg.split("<animate")[1][:200]:
|
|
128
|
+
non_cim_indicators.append("stroke-width animation")
|
|
129
|
+
if "letter-spacing" in svg and "animate" in svg.lower():
|
|
130
|
+
non_cim_indicators.append("letter-spacing animation")
|
|
131
|
+
if "stdDeviation" in svg and "animate" in svg.lower():
|
|
132
|
+
non_cim_indicators.append("filter blur animation")
|
|
133
|
+
if "baseFrequency" in svg and "animate" in svg.lower():
|
|
134
|
+
non_cim_indicators.append("turbulence animation")
|
|
135
|
+
if "clip-path" in svg and "@keyframes" in svg:
|
|
136
|
+
non_cim_indicators.append("clip-path animation")
|
|
137
|
+
# Check for animated gradients
|
|
138
|
+
if re.search(r'<animate[^>]*attributeName="x[12]"', svg, re.IGNORECASE):
|
|
139
|
+
non_cim_indicators.append("gradient coordinate animation")
|
|
140
|
+
|
|
141
|
+
if non_cim_indicators:
|
|
142
|
+
return False, f"Non-CIM: {', '.join(non_cim_indicators)}"
|
|
143
|
+
return True, ""
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def wrap_specimen(src: Path) -> str:
|
|
147
|
+
"""Wrap a raw specimen SVG with HW v8.0 protocol scaffolding.
|
|
148
|
+
|
|
149
|
+
CRITICAL: The original <svg> tag's xmlns, viewBox, width, height are
|
|
150
|
+
preserved EXACTLY. We only ADD new attributes (xmlns:hw, role,
|
|
151
|
+
aria-labelledby, data-hw-*). Never replace existing ones.
|
|
152
|
+
"""
|
|
153
|
+
svg = src.read_text(encoding="utf-8").strip()
|
|
154
|
+
|
|
155
|
+
# Already compliant — add only missing layers
|
|
156
|
+
if _has_hw_metadata(svg):
|
|
157
|
+
if not _has_reduced_motion(svg):
|
|
158
|
+
svg = _inject_reduced_motion(svg)
|
|
159
|
+
if not _has_color_scheme(svg):
|
|
160
|
+
svg = _inject_color_scheme(svg)
|
|
161
|
+
return svg
|
|
162
|
+
|
|
163
|
+
# Raw specimen — full protocol wrap
|
|
164
|
+
artifact_id = str(uuid.uuid4())
|
|
165
|
+
uid = f"hw-{artifact_id[:8]}"
|
|
166
|
+
now = datetime.now(UTC).isoformat()
|
|
167
|
+
w, h = _extract_dims(svg)
|
|
168
|
+
art_type = _infer_type(src)
|
|
169
|
+
slug = _slug(src)
|
|
170
|
+
motion_id = _infer_motion_id(src) if "motion" in str(src) else "static"
|
|
171
|
+
cim_ok, cim_waiver = _check_cim(svg)
|
|
172
|
+
|
|
173
|
+
# Extract the original <svg ...> tag and inner content
|
|
174
|
+
svg_tag, inner = _extract_svg_tag(svg)
|
|
175
|
+
if inner.rstrip().endswith("</svg>"):
|
|
176
|
+
inner = inner.rstrip()[:-6]
|
|
177
|
+
|
|
178
|
+
# Augment the ORIGINAL tag — preserve xmlns, viewBox, width, height
|
|
179
|
+
augmented = _augment_svg_tag(
|
|
180
|
+
svg_tag,
|
|
181
|
+
{
|
|
182
|
+
"xmlns:hw": "https://hyperweave.dev/hw/v8.0",
|
|
183
|
+
"role": "img",
|
|
184
|
+
"aria-labelledby": f"{uid}-title {uid}-desc",
|
|
185
|
+
"data-hw-id": artifact_id,
|
|
186
|
+
"data-hw-frame": art_type,
|
|
187
|
+
"data-hw-chromatic": "adaptive",
|
|
188
|
+
"data-hw-motion": motion_id,
|
|
189
|
+
},
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
perf = "composite-only" if cim_ok else "paint-ok"
|
|
193
|
+
cim_str = "true" if cim_ok else "false"
|
|
194
|
+
tradeoffs = "CIM-compliant: uses only compositor-friendly properties." if cim_ok else f"CIM waiver: {cim_waiver}"
|
|
195
|
+
|
|
196
|
+
return f'''{augmented}
|
|
197
|
+
|
|
198
|
+
<title id="{uid}-title">{slug} -- HyperWeave Specimen</title>
|
|
199
|
+
<desc id="{uid}-desc">HW-compliant version of {src.name}. Type: {art_type}. Zero visual changes from original.</desc>
|
|
200
|
+
|
|
201
|
+
<metadata>
|
|
202
|
+
<hw:artifact id="{artifact_id}" type="{art_type}" series="specimens" version="1.0.0"
|
|
203
|
+
xmlns:hw="https://hyperweave.dev/hw/v8.0">
|
|
204
|
+
<hw:provenance>
|
|
205
|
+
<hw:generator>HyperWeave Specimen Wrapper v0.1 (InnerAura Labs)</hw:generator>
|
|
206
|
+
<hw:created>{now}</hw:created>
|
|
207
|
+
<hw:human-directed>true</hw:human-directed>
|
|
208
|
+
<hw:source-file>{src.relative_to(ROOT)}</hw:source-file>
|
|
209
|
+
</hw:provenance>
|
|
210
|
+
<hw:spec size="{w}x{h}" performance="{perf}"
|
|
211
|
+
theme="adaptive" a11y="WCAG-AA"/>
|
|
212
|
+
<hw:composition>
|
|
213
|
+
<hw:frame>{art_type}</hw:frame>
|
|
214
|
+
<hw:environment motion="{motion_id}" status="active"/>
|
|
215
|
+
</hw:composition>
|
|
216
|
+
<hw:aesthetic>
|
|
217
|
+
<hw:motion vocabulary="{motion_id}" cim-compliant="{cim_str}"/>
|
|
218
|
+
</hw:aesthetic>
|
|
219
|
+
<hw:reasoning>
|
|
220
|
+
<hw:intent>Specimen artifact wrapped with HW v8.0 protocol for Layer 1 editorial publishing.</hw:intent>
|
|
221
|
+
<hw:approach>Zero-visual-change wrapping: original SVG preserved, HW metadata injected around it.</hw:approach>
|
|
222
|
+
<hw:tradeoffs>{tradeoffs}</hw:tradeoffs>
|
|
223
|
+
</hw:reasoning>
|
|
224
|
+
</hw:artifact>
|
|
225
|
+
</metadata>
|
|
226
|
+
|
|
227
|
+
<style>
|
|
228
|
+
@media (prefers-reduced-motion: reduce) {{
|
|
229
|
+
*, *::before, *::after {{
|
|
230
|
+
animation-duration: 0.01ms !important;
|
|
231
|
+
animation-iteration-count: 1 !important;
|
|
232
|
+
transition-duration: 0.01ms !important;
|
|
233
|
+
}}
|
|
234
|
+
animate, animateTransform, animateMotion, set {{
|
|
235
|
+
display: none !important;
|
|
236
|
+
}}
|
|
237
|
+
}}
|
|
238
|
+
@media (prefers-color-scheme: light) {{
|
|
239
|
+
svg {{ --hw-scheme: light; }}
|
|
240
|
+
}}
|
|
241
|
+
@media (prefers-color-scheme: dark) {{
|
|
242
|
+
svg {{ --hw-scheme: dark; }}
|
|
243
|
+
}}
|
|
244
|
+
</style>
|
|
245
|
+
|
|
246
|
+
<!-- Original specimen content (zero visual changes) -->
|
|
247
|
+
<g data-hw-zone="specimen-content">
|
|
248
|
+
{_indent(inner, 4)}
|
|
249
|
+
</g>
|
|
250
|
+
|
|
251
|
+
</svg>'''
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def _inject_reduced_motion(svg: str) -> str:
|
|
255
|
+
"""Inject prefers-reduced-motion into existing compliant SVG."""
|
|
256
|
+
rm_block = """
|
|
257
|
+
@media (prefers-reduced-motion: reduce) {
|
|
258
|
+
*, *::before, *::after {
|
|
259
|
+
animation-duration: 0.01ms !important;
|
|
260
|
+
animation-iteration-count: 1 !important;
|
|
261
|
+
transition-duration: 0.01ms !important;
|
|
262
|
+
}
|
|
263
|
+
animate, animateTransform, animateMotion, set {
|
|
264
|
+
display: none !important;
|
|
265
|
+
}
|
|
266
|
+
}"""
|
|
267
|
+
# Try to inject into existing <style> block
|
|
268
|
+
if "<style>" in svg:
|
|
269
|
+
return svg.replace("<style>", f"<style>{rm_block}", 1)
|
|
270
|
+
# Or add before </svg>
|
|
271
|
+
return svg.replace("</svg>", f"<style>{rm_block}</style>\n</svg>")
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def _inject_color_scheme(svg: str) -> str:
|
|
275
|
+
"""Inject prefers-color-scheme into existing compliant SVG."""
|
|
276
|
+
cs_block = """
|
|
277
|
+
@media (prefers-color-scheme: light) { svg { --hw-scheme: light; } }
|
|
278
|
+
@media (prefers-color-scheme: dark) { svg { --hw-scheme: dark; } }"""
|
|
279
|
+
if "</style>" in svg:
|
|
280
|
+
return svg.replace("</style>", f"{cs_block}\n</style>", 1)
|
|
281
|
+
return svg
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def _indent(text: str, spaces: int) -> str:
|
|
285
|
+
"""Indent every line by N spaces."""
|
|
286
|
+
pad = " " * spaces
|
|
287
|
+
return "\n".join(f"{pad}{line}" if line.strip() else line for line in text.splitlines())
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def generate() -> None:
|
|
291
|
+
total = 0
|
|
292
|
+
dirs = [
|
|
293
|
+
SPECS / "components" / "dividers",
|
|
294
|
+
SPECS / "components" / "icons",
|
|
295
|
+
SPECS / "components" / "banners",
|
|
296
|
+
SPECS / "components" / "marquees",
|
|
297
|
+
SPECS / "motion" / "motion-border-frames",
|
|
298
|
+
SPECS / "motion" / "motion-kinetic-typography",
|
|
299
|
+
]
|
|
300
|
+
|
|
301
|
+
for d in dirs:
|
|
302
|
+
if not d.exists():
|
|
303
|
+
continue
|
|
304
|
+
svgs = sorted(d.glob("*.svg"))
|
|
305
|
+
if not svgs:
|
|
306
|
+
continue
|
|
307
|
+
|
|
308
|
+
out_dir = d / "hw-compliant"
|
|
309
|
+
out_dir.mkdir(exist_ok=True)
|
|
310
|
+
|
|
311
|
+
for src in svgs:
|
|
312
|
+
wrapped = wrap_specimen(src)
|
|
313
|
+
out = out_dir / src.name
|
|
314
|
+
out.write_text(wrapped, encoding="utf-8")
|
|
315
|
+
total += 1
|
|
316
|
+
|
|
317
|
+
cim_ok, _ = _check_cim(wrapped)
|
|
318
|
+
already = _has_hw_metadata(src.read_text())
|
|
319
|
+
status = "copy" if already else "wrap"
|
|
320
|
+
cim_tag = "CIM" if cim_ok else "NON-CIM"
|
|
321
|
+
print(f" [{status:4s}] [{cim_tag:7s}] {src.relative_to(ROOT)}")
|
|
322
|
+
|
|
323
|
+
print(f"\nWrote {total} hw-compliant specimens.")
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
if __name__ == "__main__":
|
|
327
|
+
generate()
|