{"owner":"facebook","repo":"astryx","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":4291,"categories":["claude-rule","root-instruction","mcp-config","marketplace","plugin-manifest"],"hasMcp":true,"mcpConfig":{"mcpServers":{"astryx":{"command":"npx","args":["-y","@modelcontextprotocol/server-astryx"]}}},"found":["CLAUDE.md","AGENTS.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json"],"skills":{"CLAUDE.md":"# Claude Code guidance\n\nRead and follow [`AGENTS.md`](AGENTS.md). It is the canonical repository instruction surface.\n\nAlso read the nearest nested `AGENTS.md` for any path you modify. Do not duplicate shared guidance in this file.\n","AGENTS.md":"# Astryx repository guidance\n\nAstryx is a public design-system repository. Never commit internal links,\nidentifiers, service names, private operational instructions, or other\nMeta-only context.\n\n## Instruction surface\n\nThis `AGENTS.md` is the canonical, tool-agnostic instruction surface for the\nrepository. Add or change shared agent guidance here rather than duplicating it\nin tool-specific instruction files. Put genuinely path-specific guidance in a\nnested `AGENTS.md`.\n\n## Start here\n\n- Product builders: use `astryx docs`, component `{Name}.doc.mjs` files, and\n  `packages/cli/assets/docs/`.\n- Contributors: read `CONTRIBUTING.md` and the relevant guidance linked from\n  `docs/README.md`.\n- Pull requests: choose one primary intent and use its template under\n  `.github/PULL_REQUEST_TEMPLATE/`; read `docs/contributing/pull-requests.md`\n  before opening or reviewing a mixed change.\n- Component work: derive the review's semantic triggers, load matching `current`\n  global baseline claims with `node scripts/review-global-baselines.mjs\n--authority-commit <base-sha> --review-head <head-sha> --triggers\n<comma-separated-triggers>`, then read\n  the component's `{Name}.spec.md` when one exists and any `module:*` records it\n  lists. Load global records before narrower owners, but resolve the direct\n  component or family owner first when it governs the exact delta. A global\n  route exposes only the listed claim; it never makes the whole record govern\n  the component or change. Preserve each matched record, claim, trigger, and\n  match reason in the review receipt.\n- Any path: `pnpm specs:for <path>` lists the current records linked to it,\n  the specs that decided them, and the global claims its component's triggers\n  route. It reads the working tree, so on a pull-request branch it shows that\n  branch's proposed records; it is a lookup, not review authority. It adds to\n  the component-review steps above; it does not replace them.\n- Component-local visual intent: reuse or amend the optional `Design decisions`\n  table in the current component/module spec only when durable local intent must\n  survive future redesigns. Keep exact tuning in code/evidence and shared rules\n  in `docs/design/`. DESIGNOWNER authors may include that local intent with the\n  pixels and evidence in one atomic appearance-only PR. External contributors\n  follow the normal contribution flow and are never asked to author specs;\n  maintainers own missing authority.\n- Cross-component work: read the relevant contract under `docs/families/`,\n  applicable design spec under `docs/design/`, and current architecture under\n  `docs/architecture/`.\n- Consequential shared-system changes: use a record under `docs/specs/`.\n- Writing or reviewing any knowledge record: run the rubric in\n  `docs/contributing/spec-writing.md` over the record and put its results in\n  the pull request description under `## Writing rubric results`. A record\n  describes the system in the present tense; proposals, history, pull\n  requests, and research stay out of it. When reviewing, read the record\n  against the reported results; a record pull request without them is\n  incomplete, so ask for them before reviewing the content.\n- Integration contribution work: read `docs/specs/AST-039/spec.md`. Every new\n  discoverable item owns a strongly typed, same-stem `.doc.mjs`; root manifests\n  locate directories and never catalog their items. No catalog file (like\n  `themes/manifest.json`) and no per-item map in the manifest, ever.\n\n## Authority\n\nKnowledge records declare `authority`:\n\n- `draft`: not authoritative; may still need evidence or owner review;\n- `current`: explicitly approved and authoritative;\n- `archived`: context only, with a reason such as `superseded`, `withdrawn`,\n  or `historical` and a replacement link when one exists.\n\nOnly `current` records govern implementation and review. Never infer approval\nfrom merged code, silence, an old review, or an existing wiki page.\n\n## Judgment boundary\n\nResolve checkable behavior from code, tests, and browser evidence. Ask a human\nonly when a stable public API, theme contract, ownership boundary, compatibility\npolicy, or genuinely subjective visual direction remains undecided. Ask one\nquestion at a time.\n\nBefore drafting, reviewing, or implementing a proposed outcome, search current\nrecords and open pull requests using the proposed canonical owner/id, affected\npaths and exported symbols, and the behavior's semantic terms. Extend or project\nthe existing canonical owner by default. Create a new record only for a distinct\nfact boundary, and state why the existing owner cannot contain it. Do not create\nnew policy for work that is already complete, owned, or superseded.\n\n## Validation\n\nRun `pnpm check:knowledge` after editing knowledge records or templates. A\nmaterial template-shape change requires a schema-version bump and migration of\nactive records; changing template guidance alone does not rewrite accepted\nhistory.\n\n## Custom Commands\n\n### `/vibe-test [count]` - Run vibeability tests\n\nTests how well AGENTS.md helps LLMs generate correct Astryx component code.\n\n**Usage:**\n\n```\n/vibe-test 5                    # Run 5 stratified sample tests (one-shot)\n/vibe-test                      # Run all 21 tests (one-shot)\n/vibe-test 5 --degradation      # Run 5 tests with degradation curve (10-turn)\n```\n\n**How to execute:**\n\n1. Run `pnpm -F @astryxdesign/vibe-tests interactive --sample <count>` to set up iteration\n2. Spawn parallel subagents (one per test prompt) to:\n   - Read the task file from `results/<iteration>/tasks/{promptId}.json`\n   - Generate code for the prompt using Astryx components (AGENTS.md auto-injected)\n   - Self-evaluate for success/escape hatches\n   - Write `.tsx` result to `results/<iteration>/results/{promptId}.tsx`\n   - Write `.json` metadata to `results/<iteration>/results/{promptId}.json`\n3. Trigger `gh workflow run vibe-screenshots.yml` to build previews and capture screenshots\n4. Run `pnpm -F @astryxdesign/vibe-tests aggregate --iteration <id>` to see results\n\n**Degradation mode (--degradation):**\nTests context retention across 10-turn conversations with filler, distractor, and recovery turns.\nProbes at turns 0, 6, 8, 10 to measure quality degradation. Results show a line graph of each test's progression.\n\n**Result format:**\n\n```json\n{\n  \"id\": \"<iter>-<promptId>\",\n  \"timestamp\": \"...\",\n  \"model\": \"claude-code-interactive\",\n  \"persona\": \"naive\",\n  \"promptCategory\": \"...\",\n  \"trajectoryDepth\": 0,\n  \"prompt\": \"...\",\n  \"response\": \"<code>\",\n  \"evaluation\": {\"success\": true, \"componentsUsed\": [...], \"escapeHatches\": [...]}\n}\n```\n\nRunners may also write an optional `<promptId>.provenance.json` sidecar beside the result metadata. The versioned, executor-neutral contract and fallback behavior are documented in `internal/vibe-tests/docs/execution-provenance.md`.\n\n## AI Context\n\nFor architectural context, decisions, and research, see the **[GitHub Wiki](https://github.com/facebook/astryx/wiki)**:\n\n- **Decisions** — API Conventions, Why StyleX, StyleX Distribution\n- **Architecture** — System Architecture, Component Authoring Guide\n- **Research** — AI + Design Systems, AI Model Trajectory, Swizzle Ergonomics\n- **Future** — Animation System, RSC Utilities, Distribution Strategy\n\nFor component-specific documentation, see the `{Name}.doc.mjs` file in each component directory under `packages/core/src/` (e.g. `Button/Button.doc.mjs`). These are plain JS files with JSDoc type annotations exporting a `ComponentDoc` object (typed via `@astryxdesign/cli/authoring`).\n\n## Documentation Standard\n\nDocumentation lives in two places:\n\n1. **File Headers** — Each source file has a structured JSDoc header with `@input`, `@output`, `@position`\n2. **Component Docs** — `{Name}.doc.mjs` files in each component directory (props, features, examples)\n\n**Update Protocol**: When modifying code, update the file's header comment. Look for `SYNC:` comments as reminders.\n\n**Audience**: every `.doc.mjs`, and everything under `packages/cli/assets/docs/`, is written for people **building with** Astryx — not for people building Astryx. Internal review rubrics, readiness gates, audit checklists and lab→core criteria belong in the wiki. A public authoring-quality rubric belongs in shipped docs when callers use it to evaluate an artifact they create through Astryx and a current system spec assigns that ownership. [`packages/cli/assets/docs/README.md`](packages/cli/assets/docs/README.md) has the test and the page each kind of material goes to.\n\n## Quick Reference\n\n- **Package manager**: pnpm 11, pinned by the `packageManager` field (see\n  CONTRIBUTING.md for install options — Corepack is one of several, and Node\n  25+ no longer bundles it)\n- **Testing**: Vitest (colocated tests)\n- **Components**: `packages/core/`\n- **Storybook**: `apps/storybook/`\n\n## JSDoc Conventions\n\n- **`@example` code fences must use plain ` ``` `, not ` ```tsx `.**\n  Storybook's autodocs parser doesn't handle language-tagged fences in JSDoc correctly — the code block won't render as a proper code block. Always use untagged fences in `@example` blocks.\n\n<!-- STYLEX-CAPS:START -->\n\n[StyleX v0.19.0 CSS Support]|Use CSS-native solutions. Don't build JS workarounds for supported features.\n|AT-RULES: @media, @supports, @container (+named), @starting-style, @scope — YES\n|AT-RULES: @layer, @property (explicit) — NO (compiles but invalid CSS output)\n|PSEUDO-CLS: :hover, :focus, :focus-visible, :focus-within, :active, :disabled — YES\n|PSEUDO-CLS: :first-child, :last-child, :nth-child(), :where(), :is(), :has(), :not() — YES\n|PSEUDO-CLS: :placeholder-shown, :checked, :empty, :modal, :user-valid, :user-invalid — YES\n|PSEUDO-EL: ::before, ::after, ::placeholder, ::selection, ::backdrop, ::marker, ::view-transition-_ — YES\n|COMPOUND: ::backdrop+condition, RTL :is([dir=\"rtl\"] _), nested @media+pseudo — YES\n|VALUES: var(), calc(), clamp(), light-dark(), color-mix(), container-type/name — YES\n|ANIM: transition (shorthand+individual), transitionBehavior:allow-discrete, animation longhands, stylex.keyframes — YES\n|ANIM: animation shorthand — NO (use animationName/duration/timingFunction/etc.)\n|WHEN: stylex.when.ancestor(':hover'/':focus-within'/':active'/':disabled') — YES\n|WHEN: stylex.when.descendant(':hover'), siblingBefore(':checked'), siblingAfter(':checked'), anySibling(':hover') — YES\n|WHEN: stylex.when.ancestor('[data-attr]') — YES\n|NESTING: CSS nesting with & — NO (use stylex.when.ancestor/descendant/sibling for parent-child state)\n|API: stylex.firstThatWorks() for CSS fallbacks (e.g. display: grid with flex fallback) — YES\n|API: stylex.positionTry() for anchor positioning @position-try — YES\n|API: stylex.types.color/length/etc for typed CSS variables in defineVars — YES\n|API: stylex.defineConsts() for compile-time constants — YES\n|DYNAMIC: Functions in stylex.create for runtime values — YES\n|VARS: stylex.defineVars, stylex.createTheme (require .stylex.ts files) — YES\n|LAYOUT: grid, flex+gap, aspect-ratio, overscrollBehavior, scrollbar-gutter/width — YES\n|PATTERN: dialog entry animation -> @starting-style (not useState+rAF)\n|PATTERN: parent hover child style -> stylex.when.ancestor(':hover', marker) (not CSS nesting). Use stylex.defineMarker() in a .stylex.ts file for scoped markers. Ancestor element MUST have marker.marker in its stylex.props() call. NEVER use stylex.defaultMarker() for form controls (CheckboxInput, RadioList, Switch) — it leaks hover/focus-within from outer containers like Popovers. Always use a component-scoped defineMarker() instead.\n|PATTERN: hover on touch -> @media (hover: hover) guard\n|PATTERN: zebra striping -> :nth-child(even) (not index%2 JS)\n|PATTERN: container responsive -> @container (not ResizeObserver)\n|PATTERN: CSS fallback values -> stylex.firstThatWorks() (not manual fallback)\n|PATTERN: dynamic/runtime values -> stylex.create({ s: (val) => ({ prop: val }) }) (not inline styles)\n|PATTERN: conditional styles -> stylex.props(condition && styles.x) (not className toggling)\n|PATTERN: link elements -> useLinkComponent() (not hardcoded <a>). Consumers swap via LinkProvider for framework routers (Next.js, React Router)\n|VERIFY: node internal/stylex-capabilities/scan.mjs\n\n<!-- STYLEX-CAPS:END -->\n\n<!-- ASTRYX-CLI:START -->\n\nAstryx CLI|Run from repo root. Load agent docs before any component work.\nastryx() { node packages/cli/clients/cli/bin/astryx.mjs \"$@\"; }\nBOOTSTRAP (run every branch, <500ms):\nastryx help # discover all commands and options\nastryx docs # list available doc topics\nastryx docs principles --dense # design rules, anti-patterns, xstyle, tokens\nastryx docs tokens --dense # spacing, color, radius, typography, shadow\nastryx docs theme --dense # theme provider, light/dark, overrides\nastryx component --list # all components grouped by category\nastryx template --list # available page templates\nON DEMAND:\nastryx docs <topic> --index # section index: one line per section, with its key\nastryx docs <topic> <section> # one section, by key or title\nastryx component <Name> --dense # props, variants, usage, anatomy for one component\nastryx template <name> # emit full page source\nastryx template <name> --skeleton # layout skeleton with spatial annotations\nastryx swizzle <Name> # eject component source for deep customization\nastryx upgrade --from <old version> --apply # run version migration codemods\nOPTIONS: --detail compact|brief less output | --dense token-efficient | --zh Chinese\nRULE: always run bootstrap on each branch — docs reflect the branch's actual API\nRULE: always run astryx component <Name> --dense before modifying a component\nRULE: after @astryxdesign/core bump, always run astryx upgrade --from <old version> --apply\n\n<!-- ASTRYX-CLI:END -->\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/plugin.json)"},"files":{"CLAUDE.md":"# Claude Code guidance\n\nRead and follow [`AGENTS.md`](AGENTS.md). It is the canonical repository instruction surface.\n\nAlso read the nearest nested `AGENTS.md` for any path you modify. Do not duplicate shared guidance in this file.\n","AGENTS.md":"# Astryx repository guidance\n\nAstryx is a public design-system repository. Never commit internal links,\nidentifiers, service names, private operational instructions, or other\nMeta-only context.\n\n## Instruction surface\n\nThis `AGENTS.md` is the canonical, tool-agnostic instruction surface for the\nrepository. Add or change shared agent guidance here rather than duplicating it\nin tool-specific instruction files. Put genuinely path-specific guidance in a\nnested `AGENTS.md`.\n\n## Start here\n\n- Product builders: use `astryx docs`, component `{Name}.doc.mjs` files, and\n  `packages/cli/assets/docs/`.\n- Contributors: read `CONTRIBUTING.md` and the relevant guidance linked from\n  `docs/README.md`.\n- Pull requests: choose one primary intent and use its template under\n  `.github/PULL_REQUEST_TEMPLATE/`; read `docs/contributing/pull-requests.md`\n  before opening or reviewing a mixed change.\n- Component work: derive the review's semantic triggers, load matching `current`\n  global baseline claims with `node scripts/review-global-baselines.mjs\n--authority-commit <base-sha> --review-head <head-sha> --triggers\n<comma-separated-triggers>`, then read\n  the component's `{Name}.spec.md` when one exists and any `module:*` records it\n  lists. Load global records before narrower owners, but resolve the direct\n  component or family owner first when it governs the exact delta. A global\n  route exposes only the listed claim; it never makes the whole record govern\n  the component or change. Preserve each matched record, claim, trigger, and\n  match reason in the review receipt.\n- Any path: `pnpm specs:for <path>` lists the current records linked to it,\n  the specs that decided them, and the global claims its component's triggers\n  route. It reads the working tree, so on a pull-request branch it shows that\n  branch's proposed records; it is a lookup, not review authority. It adds to\n  the component-review steps above; it does not replace them.\n- Component-local visual intent: reuse or amend the optional `Design decisions`\n  table in the current component/module spec only when durable local intent must\n  survive future redesigns. Keep exact tuning in code/evidence and shared rules\n  in `docs/design/`. DESIGNOWNER authors may include that local intent with the\n  pixels and evidence in one atomic appearance-only PR. External contributors\n  follow the normal contribution flow and are never asked to author specs;\n  maintainers own missing authority.\n- Cross-component work: read the relevant contract under `docs/families/`,\n  applicable design spec under `docs/design/`, and current architecture under\n  `docs/architecture/`.\n- Consequential shared-system changes: use a record under `docs/specs/`.\n- Writing or reviewing any knowledge record: run the rubric in\n  `docs/contributing/spec-writing.md` over the record and put its results in\n  the pull request description under `## Writing rubric results`. A record\n  describes the system in the present tense; proposals, history, pull\n  requests, and research stay out of it. When reviewing, read the record\n  against the reported results; a record pull request without them is\n  incomplete, so ask for them before reviewing the content.\n- Integration contribution work: read `docs/specs/AST-039/spec.md`. Every new\n  discoverable item owns a strongly typed, same-stem `.doc.mjs`; root manifests\n  locate directories and never catalog their items. No catalog file (like\n  `themes/manifest.json`) and no per-item map in the manifest, ever.\n\n## Authority\n\nKnowledge records declare `authority`:\n\n- `draft`: not authoritative; may still need evidence or owner review;\n- `current`: explicitly approved and authoritative;\n- `archived`: context only, with a reason such as `superseded`, `withdrawn`,\n  or `historical` and a replacement link when one exists.\n\nOnly `current` records govern implementation and review. Never infer approval\nfrom merged code, silence, an old review, or an existing wiki page.\n\n## Judgment boundary\n\nResolve checkable behavior from code, tests, and browser evidence. Ask a human\nonly when a stable public API, theme contract, ownership boundary, compatibility\npolicy, or genuinely subjective visual direction remains undecided. Ask one\nquestion at a time.\n\nBefore drafting, reviewing, or implementing a proposed outcome, search current\nrecords and open pull requests using the proposed canonical owner/id, affected\npaths and exported symbols, and the behavior's semantic terms. Extend or project\nthe existing canonical owner by default. Create a new record only for a distinct\nfact boundary, and state why the existing owner cannot contain it. Do not create\nnew policy for work that is already complete, owned, or superseded.\n\n## Validation\n\nRun `pnpm check:knowledge` after editing knowledge records or templates. A\nmaterial template-shape change requires a schema-version bump and migration of\nactive records; changing template guidance alone does not rewrite accepted\nhistory.\n\n## Custom Commands\n\n### `/vibe-test [count]` - Run vibeability tests\n\nTests how well AGENTS.md helps LLMs generate correct Astryx component code.\n\n**Usage:**\n\n```\n/vibe-test 5                    # Run 5 stratified sample tests (one-shot)\n/vibe-test                      # Run all 21 tests (one-shot)\n/vibe-test 5 --degradation      # Run 5 tests with degradation curve (10-turn)\n```\n\n**How to execute:**\n\n1. Run `pnpm -F @astryxdesign/vibe-tests interactive --sample <count>` to set up iteration\n2. Spawn parallel subagents (one per test prompt) to:\n   - Read the task file from `results/<iteration>/tasks/{promptId}.json`\n   - Generate code for the prompt using Astryx components (AGENTS.md auto-injected)\n   - Self-evaluate for success/escape hatches\n   - Write `.tsx` result to `results/<iteration>/results/{promptId}.tsx`\n   - Write `.json` metadata to `results/<iteration>/results/{promptId}.json`\n3. Trigger `gh workflow run vibe-screenshots.yml` to build previews and capture screenshots\n4. Run `pnpm -F @astryxdesign/vibe-tests aggregate --iteration <id>` to see results\n\n**Degradation mode (--degradation):**\nTests context retention across 10-turn conversations with filler, distractor, and recovery turns.\nProbes at turns 0, 6, 8, 10 to measure quality degradation. Results show a line graph of each test's progression.\n\n**Result format:**\n\n```json\n{\n  \"id\": \"<iter>-<promptId>\",\n  \"timestamp\": \"...\",\n  \"model\": \"claude-code-interactive\",\n  \"persona\": \"naive\",\n  \"promptCategory\": \"...\",\n  \"trajectoryDepth\": 0,\n  \"prompt\": \"...\",\n  \"response\": \"<code>\",\n  \"evaluation\": {\"success\": true, \"componentsUsed\": [...], \"escapeHatches\": [...]}\n}\n```\n\nRunners may also write an optional `<promptId>.provenance.json` sidecar beside the result metadata. The versioned, executor-neutral contract and fallback behavior are documented in `internal/vibe-tests/docs/execution-provenance.md`.\n\n## AI Context\n\nFor architectural context, decisions, and research, see the **[GitHub Wiki](https://github.com/facebook/astryx/wiki)**:\n\n- **Decisions** — API Conventions, Why StyleX, StyleX Distribution\n- **Architecture** — System Architecture, Component Authoring Guide\n- **Research** — AI + Design Systems, AI Model Trajectory, Swizzle Ergonomics\n- **Future** — Animation System, RSC Utilities, Distribution Strategy\n\nFor component-specific documentation, see the `{Name}.doc.mjs` file in each component directory under `packages/core/src/` (e.g. `Button/Button.doc.mjs`). These are plain JS files with JSDoc type annotations exporting a `ComponentDoc` object (typed via `@astryxdesign/cli/authoring`).\n\n## Documentation Standard\n\nDocumentation lives in two places:\n\n1. **File Headers** — Each source file has a structured JSDoc header with `@input`, `@output`, `@position`\n2. **Component Docs** — `{Name}.doc.mjs` files in each component directory (props, features, examples)\n\n**Update Protocol**: When modifying code, update the file's header comment. Look for `SYNC:` comments as reminders.\n\n**Audience**: every `.doc.mjs`, and everything under `packages/cli/assets/docs/`, is written for people **building with** Astryx — not for people building Astryx. Internal review rubrics, readiness gates, audit checklists and lab→core criteria belong in the wiki. A public authoring-quality rubric belongs in shipped docs when callers use it to evaluate an artifact they create through Astryx and a current system spec assigns that ownership. [`packages/cli/assets/docs/README.md`](packages/cli/assets/docs/README.md) has the test and the page each kind of material goes to.\n\n## Quick Reference\n\n- **Package manager**: pnpm 11, pinned by the `packageManager` field (see\n  CONTRIBUTING.md for install options — Corepack is one of several, and Node\n  25+ no longer bundles it)\n- **Testing**: Vitest (colocated tests)\n- **Components**: `packages/core/`\n- **Storybook**: `apps/storybook/`\n\n## JSDoc Conventions\n\n- **`@example` code fences must use plain ` ``` `, not ` ```tsx `.**\n  Storybook's autodocs parser doesn't handle language-tagged fences in JSDoc correctly — the code block won't render as a proper code block. Always use untagged fences in `@example` blocks.\n\n<!-- STYLEX-CAPS:START -->\n\n[StyleX v0.19.0 CSS Support]|Use CSS-native solutions. Don't build JS workarounds for supported features.\n|AT-RULES: @media, @supports, @container (+named), @starting-style, @scope — YES\n|AT-RULES: @layer, @property (explicit) — NO (compiles but invalid CSS output)\n|PSEUDO-CLS: :hover, :focus, :focus-visible, :focus-within, :active, :disabled — YES\n|PSEUDO-CLS: :first-child, :last-child, :nth-child(), :where(), :is(), :has(), :not() — YES\n|PSEUDO-CLS: :placeholder-shown, :checked, :empty, :modal, :user-valid, :user-invalid — YES\n|PSEUDO-EL: ::before, ::after, ::placeholder, ::selection, ::backdrop, ::marker, ::view-transition-_ — YES\n|COMPOUND: ::backdrop+condition, RTL :is([dir=\"rtl\"] _), nested @media+pseudo — YES\n|VALUES: var(), calc(), clamp(), light-dark(), color-mix(), container-type/name — YES\n|ANIM: transition (shorthand+individual), transitionBehavior:allow-discrete, animation longhands, stylex.keyframes — YES\n|ANIM: animation shorthand — NO (use animationName/duration/timingFunction/etc.)\n|WHEN: stylex.when.ancestor(':hover'/':focus-within'/':active'/':disabled') — YES\n|WHEN: stylex.when.descendant(':hover'), siblingBefore(':checked'), siblingAfter(':checked'), anySibling(':hover') — YES\n|WHEN: stylex.when.ancestor('[data-attr]') — YES\n|NESTING: CSS nesting with & — NO (use stylex.when.ancestor/descendant/sibling for parent-child state)\n|API: stylex.firstThatWorks() for CSS fallbacks (e.g. display: grid with flex fallback) — YES\n|API: stylex.positionTry() for anchor positioning @position-try — YES\n|API: stylex.types.color/length/etc for typed CSS variables in defineVars — YES\n|API: stylex.defineConsts() for compile-time constants — YES\n|DYNAMIC: Functions in stylex.create for runtime values — YES\n|VARS: stylex.defineVars, stylex.createTheme (require .stylex.ts files) — YES\n|LAYOUT: grid, flex+gap, aspect-ratio, overscrollBehavior, scrollbar-gutter/width — YES\n|PATTERN: dialog entry animation -> @starting-style (not useState+rAF)\n|PATTERN: parent hover child style -> stylex.when.ancestor(':hover', marker) (not CSS nesting). Use stylex.defineMarker() in a .stylex.ts file for scoped markers. Ancestor element MUST have marker.marker in its stylex.props() call. NEVER use stylex.defaultMarker() for form controls (CheckboxInput, RadioList, Switch) — it leaks hover/focus-within from outer containers like Popovers. Always use a component-scoped defineMarker() instead.\n|PATTERN: hover on touch -> @media (hover: hover) guard\n|PATTERN: zebra striping -> :nth-child(even) (not index%2 JS)\n|PATTERN: container responsive -> @container (not ResizeObserver)\n|PATTERN: CSS fallback values -> stylex.firstThatWorks() (not manual fallback)\n|PATTERN: dynamic/runtime values -> stylex.create({ s: (val) => ({ prop: val }) }) (not inline styles)\n|PATTERN: conditional styles -> stylex.props(condition && styles.x) (not className toggling)\n|PATTERN: link elements -> useLinkComponent() (not hardcoded <a>). Consumers swap via LinkProvider for framework routers (Next.js, React Router)\n|VERIFY: node internal/stylex-capabilities/scan.mjs\n\n<!-- STYLEX-CAPS:END -->\n\n<!-- ASTRYX-CLI:START -->\n\nAstryx CLI|Run from repo root. Load agent docs before any component work.\nastryx() { node packages/cli/clients/cli/bin/astryx.mjs \"$@\"; }\nBOOTSTRAP (run every branch, <500ms):\nastryx help # discover all commands and options\nastryx docs # list available doc topics\nastryx docs principles --dense # design rules, anti-patterns, xstyle, tokens\nastryx docs tokens --dense # spacing, color, radius, typography, shadow\nastryx docs theme --dense # theme provider, light/dark, overrides\nastryx component --list # all components grouped by category\nastryx template --list # available page templates\nON DEMAND:\nastryx docs <topic> --index # section index: one line per section, with its key\nastryx docs <topic> <section> # one section, by key or title\nastryx component <Name> --dense # props, variants, usage, anatomy for one component\nastryx template <name> # emit full page source\nastryx template <name> --skeleton # layout skeleton with spatial annotations\nastryx swizzle <Name> # eject component source for deep customization\nastryx upgrade --from <old version> --apply # run version migration codemods\nOPTIONS: --detail compact|brief less output | --dense token-efficient | --zh Chinese\nRULE: always run bootstrap on each branch — docs reflect the branch's actual API\nRULE: always run astryx component <Name> --dense before modifying a component\nRULE: after @astryxdesign/core bump, always run astryx upgrade --from <old version> --apply\n\n<!-- ASTRYX-CLI:END -->\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/plugin.json)"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/facebook/astryx/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# Astryx repository guidance\n\nAstryx is a public design-system repository. Never commit internal links,\nidentifiers, service names, private operational instructions, or other\nMeta-only context.\n\n## Instruction surface\n\nThis `AGENTS.md` is the canonical, tool-agnostic instruction surface for the\nrepository. Add or change shared agent guidance here rather than duplicating it\nin tool-specific instruction files. Put genuinely path-specific guidance in a\nnested `AGENTS.md`.\n\n## Start here\n\n- Product builders: use `astryx docs`, component `{Name}.doc.mjs` files, and\n  `packages/cli/assets/docs/`.\n- Contributors: read `CONTRIBUTING.md` and the relevant guidance linked from\n  `docs/README.md`.\n- Pull requests: choose one primary intent and use its template under\n  `.github/PULL_REQUEST_TEMPLATE/`; read `docs/contributing/pull-requests.md`\n  before opening or reviewing a mixed change.\n- Component work: derive the review's semantic triggers, load matching `current`\n  global baseline claims with `node scripts/review-global-baselines.mjs\n--authority-commit <base-sha> --review-head <head-sha> --triggers\n<comma-separated-triggers>`, then read\n  the component's `{Name}.spec.md` when one exists and any `module:*` records it\n  lists. Load global records before narrower owners, but resolve the direct\n  component or family owner first when it governs the exact delta. A global\n  route exposes only the listed claim; it never makes the whole record govern\n  the component or change. Preserve each matched record, claim, trigger, and\n  match reason in the review receipt.\n- Any path: `pnpm specs:for <path>` lists the current records linked to it,\n  the specs that decided them, and the global claims its component's triggers\n  route. It reads the working tree, so on a pull-request branch it shows that\n  branch's proposed records; it is a lookup, not review authority. It adds to\n  the component-review steps above; it does not replace them.\n- Component-local visual intent: reuse or amend the optional `Design decisions`\n  table in the current component/module spec only when durable local intent must\n  survive future redesigns. Keep exact tuning in code/evidence and shared rules\n  in `docs/design/`. DESIGNOWNER authors may include that local intent with the\n  pixels and evidence in one atomic appearance-only PR. External contributors\n  follow the normal contribution flow and are never asked to author specs;\n  maintainers own missing authority.\n- Cross-component work: read the relevant contract under `docs/families/`,\n  applicable design spec under `docs/design/`, and current architecture under\n  `docs/architecture/`.\n- Consequential shared-system changes: use a record under `docs/specs/`.\n- Writing or reviewing any knowledge record: run the rubric in\n  `docs/contributing/spec-writing.md` over the record and put its results in\n  the pull request description under `## Writing rubric results`. A record\n  describes the system in the present tense; proposals, history, pull\n  requests, and research stay out of it. When reviewing, read the record\n  against the reported results; a record pull request without them is\n  incomplete, so ask for them before reviewing the content.\n- Integration contribution work: read `docs/specs/AST-039/spec.md`. Every new\n  discoverable item owns a strongly typed, same-stem `.doc.mjs`; root manifests\n  locate directories and never catalog their items. No catalog file (like\n  `themes/manifest.json`) and no per-item map in the manifest, ever.\n\n## Authority\n\nKnowledge records declare `authority`:\n\n- `draft`: not authoritative; may still need evidence or owner review;\n- `current`: explicitly approved and authoritative;\n- `archived`: context only, with a reason such as `superseded`, `withdrawn`,\n  or `historical` and a replacement link when one exists.\n\nOnly `current` records govern implementation and review. Never infer approval\nfrom merged code, silence, an old review, or an existing wiki page.\n\n## Judgment boundary\n\nResolve checkable behavior from code, tests, and browser evidence. Ask a human\nonly when a stable public API, theme contract, ownership boundary, compatibility\npolicy, or genuinely subjective visual direction remains undecided. Ask one\nquestion at a time.\n\nBefore drafting, reviewing, or implementing a proposed outcome, search current\nrecords and open pull requests using the proposed canonical owner/id, affected\npaths and exported symbols, and the behavior's semantic terms. Extend or project\nthe existing canonical owner by default. Create a new record only for a distinct\nfact boundary, and state why the existing owner cannot contain it. Do not create\nnew policy for work that is already complete, owned, or superseded.\n\n## Validation\n\nRun `pnpm check:knowledge` after editing knowledge records or templates. A\nmaterial template-shape change requires a schema-version bump and migration of\nactive records; changing template guidance alone does not rewrite accepted\nhistory.\n\n## Custom Commands\n\n### `/vibe-test [count]` - Run vibeability tests\n\nTests how well AGENTS.md helps LLMs generate correct Astryx component code.\n\n**Usage:**\n\n```\n/vibe-test 5                    # Run 5 stratified sample tests (one-shot)\n/vibe-test                      # Run all 21 tests (one-shot)\n/vibe-test 5 --degradation      # Run 5 tests with degradation curve (10-turn)\n```\n\n**How to execute:**\n\n1. Run `pnpm -F @astryxdesign/vibe-tests interactive --sample <count>` to set up iteration\n2. Spawn parallel subagents (one per test prompt) to:\n   - Read the task file from `results/<iteration>/tasks/{promptId}.json`\n   - Generate code for the prompt using Astryx components (AGENTS.md auto-injected)\n   - Self-evaluate for success/escape hatches\n   - Write `.tsx` result to `results/<iteration>/results/{promptId}.tsx`\n   - Write `.json` metadata to `results/<iteration>/results/{promptId}.json`\n3. Trigger `gh workflow run vibe-screenshots.yml` to build previews and capture screenshots\n4. Run `pnpm -F @astryxdesign/vibe-tests aggregate --iteration <id>` to see results\n\n**Degradation mode (--degradation):**\nTests context retention across 10-turn conversations with filler, distractor, and recovery turns.\nProbes at turns 0, 6, 8, 10 to measure quality degradation. Results show a line graph of each test's progression.\n\n**Result format:**\n\n```json\n{\n  \"id\": \"<iter>-<promptId>\",\n  \"timestamp\": \"...\",\n  \"model\": \"claude-code-interactive\",\n  \"persona\": \"naive\",\n  \"promptCategory\": \"...\",\n  \"trajectoryDepth\": 0,\n  \"prompt\": \"...\",\n  \"response\": \"<code>\",\n  \"evaluation\": {\"success\": true, \"componentsUsed\": [...], \"escapeHatches\": [...]}\n}\n```\n\nRunners may also write an optional `<promptId>.provenance.json` sidecar beside the result metadata. The versioned, executor-neutral contract and fallback behavior are documented in `internal/vibe-tests/docs/execution-provenance.md`.\n\n## AI Context\n\nFor architectural context, decisions, and research, see the **[GitHub Wiki](https://github.com/facebook/astryx/wiki)**:\n\n- **Decisions** — API Conventions, Why StyleX, StyleX Distribution\n- **Architecture** — System Architecture, Component Authoring Guide\n- **Research** — AI + Design Systems, AI Model Trajectory, Swizzle Ergonomics\n- **Future** — Animation System, RSC Utilities, Distribution Strategy\n\nFor component-specific documentation, see the `{Name}.doc.mjs` file in each component directory under `packages/core/src/` (e.g. `Button/Button.doc.mjs`). These are plain JS files with JSDoc type annotations exporting a `ComponentDoc` object (typed via `@astryxdesign/cli/authoring`).\n\n## Documentation Standard\n\nDocumentation lives in two places:\n\n1. **File Headers** — Each source file has a structured JSDoc header with `@input`, `@output`, `@position`\n2. **Component Docs** — `{Name}.doc.mjs` files in each component directory (props, features, examples)\n\n**Update Protocol**: When modifying code, update the file's header comment. Look for `SYNC:` comments as reminders.\n\n**Audience**: every `.doc.mjs`, and everything under `packages/cli/assets/docs/`, is written for people **building with** Astryx — not for people building Astryx. Internal review rubrics, readiness gates, audit checklists and lab→core criteria belong in the wiki. A public authoring-quality rubric belongs in shipped docs when callers use it to evaluate an artifact they create through Astryx and a current system spec assigns that ownership. [`packages/cli/assets/docs/README.md`](packages/cli/assets/docs/README.md) has the test and the page each kind of material goes to.\n\n## Quick Reference\n\n- **Package manager**: pnpm 11, pinned by the `packageManager` field (see\n  CONTRIBUTING.md for install options — Corepack is one of several, and Node\n  25+ no longer bundles it)\n- **Testing**: Vitest (colocated tests)\n- **Components**: `packages/core/`\n- **Storybook**: `apps/storybook/`\n\n## JSDoc Conventions\n\n- **`@example` code fences must use plain ` ``` `, not ` ```tsx `.**\n  Storybook's autodocs parser doesn't handle language-tagged fences in JSDoc correctly — the code block won't render as a proper code block. Always use untagged fences in `@example` blocks.\n\n<!-- STYLEX-CAPS:START -->\n\n[StyleX v0.19.0 CSS Support]|Use CSS-native solutions. Don't build JS workarounds for supported features.\n|AT-RULES: @media, @supports, @container (+named), @starting-style, @scope — YES\n|AT-RULES: @layer, @property (explicit) — NO (compiles but invalid CSS output)\n|PSEUDO-CLS: :hover, :focus, :focus-visible, :focus-within, :active, :disabled — YES\n|PSEUDO-CLS: :first-child, :last-child, :nth-child(), :where(), :is(), :has(), :not() — YES\n|PSEUDO-CLS: :placeholder-shown, :checked, :empty, :modal, :user-valid, :user-invalid — YES\n|PSEUDO-EL: ::before, ::after, ::placeholder, ::selection, ::backdrop, ::marker, ::view-transition-_ — YES\n|COMPOUND: ::backdrop+condition, RTL :is([dir=\"rtl\"] _), nested @media+pseudo — YES\n|VALUES: var(), calc(), clamp(), light-dark(), color-mix(), container-type/name — YES\n|ANIM: transition (shorthand+individual), transitionBehavior:allow-discrete, animation longhands, stylex.keyframes — YES\n|ANIM: animation shorthand — NO (use animationName/duration/timingFunction/etc.)\n|WHEN: stylex.when.ancestor(':hover'/':focus-within'/':active'/':disabled') — YES\n|WHEN: stylex.when.descendant(':hover'), siblingBefore(':checked'), siblingAfter(':checked'), anySibling(':hover') — YES\n|WHEN: stylex.when.ancestor('[data-attr]') — YES\n|NESTING: CSS nesting with & — NO (use stylex.when.ancestor/descendant/sibling for parent-child state)\n|API: stylex.firstThatWorks() for CSS fallbacks (e.g. display: grid with flex fallback) — YES\n|API: stylex.positionTry() for anchor positioning @position-try — YES\n|API: stylex.types.color/length/etc for typed CSS variables in defineVars — YES\n|API: stylex.defineConsts() for compile-time constants — YES\n|DYNAMIC: Functions in stylex.create for runtime values — YES\n|VARS: stylex.defineVars, stylex.createTheme (require .stylex.ts files) — YES\n|LAYOUT: grid, flex+gap, aspect-ratio, overscrollBehavior, scrollbar-gutter/width — YES\n|PATTERN: dialog entry animation -> @starting-style (not useState+rAF)\n|PATTERN: parent hover child style -> stylex.when.ancestor(':hover', marker) (not CSS nesting). Use stylex.defineMarker() in a .stylex.ts file for scoped markers. Ancestor element MUST have marker.marker in its stylex.props() call. NEVER use stylex.defaultMarker() for form controls (CheckboxInput, RadioList, Switch) — it leaks hover/focus-within from outer containers like Popovers. Always use a component-scoped defineMarker() instead.\n|PATTERN: hover on touch -> @media (hover: hover) guard\n|PATTERN: zebra striping -> :nth-child(even) (not index%2 JS)\n|PATTERN: container responsive -> @container (not ResizeObserver)\n|PATTERN: CSS fallback values -> stylex.firstThatWorks() (not manual fallback)\n|PATTERN: dynamic/runtime values -> stylex.create({ s: (val) => ({ prop: val }) }) (not inline styles)\n|PATTERN: conditional styles -> stylex.props(condition && styles.x) (not className toggling)\n|PATTERN: link elements -> useLinkComponent() (not hardcoded <a>). Consumers swap via LinkProvider for framework routers (Next.js, React Router)\n|VERIFY: node internal/stylex-capabilities/scan.mjs\n\n<!-- STYLEX-CAPS:END -->\n\n<!-- ASTRYX-CLI:START -->\n\nAstryx CLI|Run from repo root. Load agent docs before any component work.\nastryx() { node packages/cli/clients/cli/bin/astryx.mjs \"$@\"; }\nBOOTSTRAP (run every branch, <500ms):\nastryx help # discover all commands and options\nastryx docs # list available doc topics\nastryx docs principles --dense # design rules, anti-patterns, xstyle, tokens\nastryx docs tokens --dense # spacing, color, radius, typography, shadow\nastryx docs theme --dense # theme provider, light/dark, overrides\nastryx component --list # all components grouped by category\nastryx template --list # available page templates\nON DEMAND:\nastryx docs <topic> --index # section index: one line per section, with its key\nastryx docs <topic> <section> # one section, by key or title\nastryx component <Name> --dense # props, variants, usage, anatomy for one component\nastryx template <name> # emit full page source\nastryx template <name> --skeleton # layout skeleton with spatial annotations\nastryx swizzle <Name> # eject component source for deep customization\nastryx upgrade --from <old version> --apply # run version migration codemods\nOPTIONS: --detail compact|brief less output | --dense token-efficient | --zh Chinese\nRULE: always run bootstrap on each branch — docs reflect the branch's actual API\nRULE: always run astryx component <Name> --dense before modifying a component\nRULE: after @astryxdesign/core bump, always run astryx upgrade --from <old version> --apply\n\n<!-- ASTRYX-CLI:END -->\n","isInternal":false,"tokens":3341,"sizeBytes":13788},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/facebook/astryx/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# Claude Code guidance\n\nRead and follow [`AGENTS.md`](AGENTS.md). It is the canonical repository instruction surface.\n\nAlso read the nearest nested `AGENTS.md` for any path you modify. Do not duplicate shared guidance in this file.\n","isInternal":false,"tokens":50,"sizeBytes":232},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":194},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":180},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/facebook/astryx/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":173}],"systemPromptSnippet":"<yakaai_skills repo=\"facebook/astryx\">\n<!-- File: AGENTS.md (Tokens: ~3341 | Category: root-instruction) -->\n# Astryx repository guidance\n\nAstryx is a public design-system repository. Never commit internal links,\nidentifiers, service names, private operational instructions, or other\nMeta-only context.\n\n## Instruction surface\n\nThis `AGENTS.md` is the canonical, tool-agnostic instruction surface for the\nrepository. Add or change shared agent guidance here rather than duplicating it\nin tool-specific instruction files. Put genuinely path-specific guidance in a\nnested `AGENTS.md`.\n\n## Start here\n\n- Product builders: use `astryx docs`, component `{Name}.doc.mjs` files, and\n  `packages/cli/assets/docs/`.\n- Contributors: read `CONTRIBUTING.md` and the relevant guidance linked from\n  `docs/README.md`.\n- Pull requests: choose one primary intent and use its template under\n  `.github/PULL_REQUEST_TEMPLATE/`; read `docs/contributing/pull-requests.md`\n  before opening or reviewing a mixed change.\n- Component work: derive the review's semantic triggers, load matching `current`\n  global baseline claims with `node scripts/review-global-baselines.mjs\n--authority-commit <base-sha> --review-head <head-sha> --triggers\n<comma-separated-triggers>`, then read\n  the component's `{Name}.spec.md` when one exists and any `module:*` records it\n  lists. Load global records before narrower owners, but resolve the direct\n  component or family owner first when it governs the exact delta. A global\n  route exposes only the listed claim; it never makes the whole record govern\n  the component or change. Preserve each matched record, claim, trigger, and\n  match reason in the review receipt.\n- Any path: `pnpm specs:for <path>` lists the current records linked to it,\n  the specs that decided them, and the global claims its component's triggers\n  route. It reads the working tree, so on a pull-request branch it shows that\n  branch's proposed records; it is a lookup, not review authority. It adds to\n  the component-review steps above; it does not replace them.\n- Component-local visual intent: reuse or amend the optional `Design decisions`\n  table in the current component/module spec only when durable local intent must\n  survive future redesigns. Keep exact tuning in code/evidence and shared rules\n  in `docs/design/`. DESIGNOWNER authors may include that local intent with the\n  pixels and evidence in one atomic appearance-only PR. External contributors\n  follow the normal contribution flow and are never asked to author specs;\n  maintainers own missing authority.\n- Cross-component work: read the relevant contract under `docs/families/`,\n  applicable design spec under `docs/design/`, and current architecture under\n  `docs/architecture/`.\n- Consequential shared-system changes: use a record under `docs/specs/`.\n- Writing or reviewing any knowledge record: run the rubric in\n  `docs/contributing/spec-writing.md` over the record and put its results in\n  the pull request description under `## Writing rubric results`. A record\n  describes the system in the present tense; proposals, history, pull\n  requests, and research stay out of it. When reviewing, read the record\n  against the reported results; a record pull request without them is\n  incomplete, so ask for them before reviewing the content.\n- Integration contribution work: read `docs/specs/AST-039/spec.md`. Every new\n  discoverable item owns a strongly typed, same-stem `.doc.mjs`; root manifests\n  locate directories and never catalog their items. No catalog file (like\n  `themes/manifest.json`) and no per-item map in the manifest, ever.\n\n## Authority\n\nKnowledge records declare `authority`:\n\n- `draft`: not authoritative; may still need evidence or owner review;\n- `current`: explicitly approved and authoritative;\n- `archived`: context only, with a reason such as `superseded`, `withdrawn`,\n  or `historical` and a replacement link when one exists.\n\nOnly `current` records govern implementation and review. Never infer approval\nfrom merged code, silence, an old review, or an existing wiki page.\n\n## Judgment boundary\n\nResolve checkable behavior from code, tests, and browser evidence. Ask a human\nonly when a stable public API, theme contract, ownership boundary, compatibility\npolicy, or genuinely subjective visual direction remains undecided. Ask one\nquestion at a time.\n\nBefore drafting, reviewing, or implementing a proposed outcome, search current\nrecords and open pull requests using the proposed canonical owner/id, affected\npaths and exported symbols, and the behavior's semantic terms. Extend or project\nthe existing canonical owner by default. Create a new record only for a distinct\nfact boundary, and state why the existing owner cannot contain it. Do not create\nnew policy for work that is already complete, owned, or superseded.\n\n## Validation\n\nRun `pnpm check:knowledge` after editing knowledge records or templates. A\nmaterial template-shape change requires a schema-version bump and migration of\nactive records; changing template guidance alone does not rewrite accepted\nhistory.\n\n## Custom Commands\n\n### `/vibe-test [count]` - Run vibeability tests\n\nTests how well AGENTS.md helps LLMs generate correct Astryx component code.\n\n**Usage:**\n\n```\n/vibe-test 5                    # Run 5 stratified sample tests (one-shot)\n/vibe-test                      # Run all 21 tests (one-shot)\n/vibe-test 5 --degradation      # Run 5 tests with degradation curve (10-turn)\n```\n\n**How to execute:**\n\n1. Run `pnpm -F @astryxdesign/vibe-tests interactive --sample <count>` to set up iteration\n2. Spawn parallel subagents (one per test prompt) to:\n   - Read the task file from `results/<iteration>/tasks/{promptId}.json`\n   - Generate code for the prompt using Astryx components (AGENTS.md auto-injected)\n   - Self-evaluate for success/escape hatches\n   - Write `.tsx` result to `results/<iteration>/results/{promptId}.tsx`\n   - Write `.json` metadata to `results/<iteration>/results/{promptId}.json`\n3. Trigger `gh workflow run vibe-screenshots.yml` to build previews and capture screenshots\n4. Run `pnpm -F @astryxdesign/vibe-tests aggregate --iteration <id>` to see results\n\n**Degradation mode (--degradation):**\nTests context retention across 10-turn conversations with filler, distractor, and recovery turns.\nProbes at turns 0, 6, 8, 10 to measure quality degradation. Results show a line graph of each test's progression.\n\n**Result format:**\n\n```json\n{\n  \"id\": \"<iter>-<promptId>\",\n  \"timestamp\": \"...\",\n  \"model\": \"claude-code-interactive\",\n  \"persona\": \"naive\",\n  \"promptCategory\": \"...\",\n  \"trajectoryDepth\": 0,\n  \"prompt\": \"...\",\n  \"response\": \"<code>\",\n  \"evaluation\": {\"success\": true, \"componentsUsed\": [...], \"escapeHatches\": [...]}\n}\n```\n\nRunners may also write an optional `<promptId>.provenance.json` sidecar beside the result metadata. The versioned, executor-neutral contract and fallback behavior are documented in `internal/vibe-tests/docs/execution-provenance.md`.\n\n## AI Context\n\nFor architectural context, decisions, and research, see the **[GitHub Wiki](https://github.com/facebook/astryx/wiki)**:\n\n- **Decisions** — API Conventions, Why StyleX, StyleX Distribution\n- **Architecture** — System Architecture, Component Authoring Guide\n- **Research** — AI + Design Systems, AI Model Trajectory, Swizzle Ergonomics\n- **Future** — Animation System, RSC Utilities, Distribution Strategy\n\nFor component-specific documentation, see the `{Name}.doc.mjs` file in each component directory under `packages/core/src/` (e.g. `Button/Button.doc.mjs`). These are plain JS files with JSDoc type annotations exporting a `ComponentDoc` object (typed via `@astryxdesign/cli/authoring`).\n\n## Documentation Standard\n\nDocumentation lives in two places:\n\n1. **File Headers** — Each source file has a structured JSDoc header with `@input`, `@output`, `@position`\n2. **Component Docs** — `{Name}.doc.mjs` files in each component directory (props, features, examples)\n\n**Update Protocol**: When modifying code, update the file's header comment. Look for `SYNC:` comments as reminders.\n\n**Audience**: every `.doc.mjs`, and everything under `packages/cli/assets/docs/`, is written for people **building with** Astryx — not for people building Astryx. Internal review rubrics, readiness gates, audit checklists and lab→core criteria belong in the wiki. A public authoring-quality rubric belongs in shipped docs when callers use it to evaluate an artifact they create through Astryx and a current system spec assigns that ownership. [`packages/cli/assets/docs/README.md`](packages/cli/assets/docs/README.md) has the test and the page each kind of material goes to.\n\n## Quick Reference\n\n- **Package manager**: pnpm 11, pinned by the `packageManager` field (see\n  CONTRIBUTING.md for install options — Corepack is one of several, and Node\n  25+ no longer bundles it)\n- **Testing**: Vitest (colocated tests)\n- **Components**: `packages/core/`\n- **Storybook**: `apps/storybook/`\n\n## JSDoc Conventions\n\n- **`@example` code fences must use plain ` ``` `, not ` ```tsx `.**\n  Storybook's autodocs parser doesn't handle language-tagged fences in JSDoc correctly — the code block won't render as a proper code block. Always use untagged fences in `@example` blocks.\n\n<!-- STYLEX-CAPS:START -->\n\n[StyleX v0.19.0 CSS Support]|Use CSS-native solutions. Don't build JS workarounds for supported features.\n|AT-RULES: @media, @supports, @container (+named), @starting-style, @scope — YES\n|AT-RULES: @layer, @property (explicit) — NO (compiles but invalid CSS output)\n|PSEUDO-CLS: :hover, :focus, :focus-visible, :focus-within, :active, :disabled — YES\n|PSEUDO-CLS: :first-child, :last-child, :nth-child(), :where(), :is(), :has(), :not() — YES\n|PSEUDO-CLS: :placeholder-shown, :checked, :empty, :modal, :user-valid, :user-invalid — YES\n|PSEUDO-EL: ::before, ::after, ::placeholder, ::selection, ::backdrop, ::marker, ::view-transition-_ — YES\n|COMPOUND: ::backdrop+condition, RTL :is([dir=\"rtl\"] _), nested @media+pseudo — YES\n|VALUES: var(), calc(), clamp(), light-dark(), color-mix(), container-type/name — YES\n|ANIM: transition (shorthand+individual), transitionBehavior:allow-discrete, animation longhands, stylex.keyframes — YES\n|ANIM: animation shorthand — NO (use animationName/duration/timingFunction/etc.)\n|WHEN: stylex.when.ancestor(':hover'/':focus-within'/':active'/':disabled') — YES\n|WHEN: stylex.when.descendant(':hover'), siblingBefore(':checked'), siblingAfter(':checked'), anySibling(':hover') — YES\n|WHEN: stylex.when.ancestor('[data-attr]') — YES\n|NESTING: CSS nesting with & — NO (use stylex.when.ancestor/descendant/sibling for parent-child state)\n|API: stylex.firstThatWorks() for CSS fallbacks (e.g. display: grid with flex fallback) — YES\n|API: stylex.positionTry() for anchor positioning @position-try — YES\n|API: stylex.types.color/length/etc for typed CSS variables in defineVars — YES\n|API: stylex.defineConsts() for compile-time constants — YES\n|DYNAMIC: Functions in stylex.create for runtime values — YES\n|VARS: stylex.defineVars, stylex.createTheme (require .stylex.ts files) — YES\n|LAYOUT: grid, flex+gap, aspect-ratio, overscrollBehavior, scrollbar-gutter/width — YES\n|PATTERN: dialog entry animation -> @starting-style (not useState+rAF)\n|PATTERN: parent hover child style -> stylex.when.ancestor(':hover', marker) (not CSS nesting). Use stylex.defineMarker() in a .stylex.ts file for scoped markers. Ancestor element MUST have marker.marker in its stylex.props() call. NEVER use stylex.defaultMarker() for form controls (CheckboxInput, RadioList, Switch) — it leaks hover/focus-within from outer containers like Popovers. Always use a component-scoped defineMarker() instead.\n|PATTERN: hover on touch -> @media (hover: hover) guard\n|PATTERN: zebra striping -> :nth-child(even) (not index%2 JS)\n|PATTERN: container responsive -> @container (not ResizeObserver)\n|PATTERN: CSS fallback values -> stylex.firstThatWorks() (not manual fallback)\n|PATTERN: dynamic/runtime values -> stylex.create({ s: (val) => ({ prop: val }) }) (not inline styles)\n|PATTERN: conditional styles -> stylex.props(condition && styles.x) (not className toggling)\n|PATTERN: link elements -> useLinkComponent() (not hardcoded <a>). Consumers swap via LinkProvider for framework routers (Next.js, React Router)\n|VERIFY: node internal/stylex-capabilities/scan.mjs\n\n<!-- STYLEX-CAPS:END -->\n\n<!-- ASTRYX-CLI:START -->\n\nAstryx CLI|Run from repo root. Load agent docs before any component work.\nastryx() { node packages/cli/clients/cli/bin/astryx.mjs \"$@\"; }\nBOOTSTRAP (run every branch, <500ms):\nastryx help # discover all commands and options\nastryx docs # list available doc topics\nastryx docs principles --dense # design rules, anti-patterns, xstyle, tokens\nastryx docs tokens --dense # spacing, color, radius, typography, shadow\nastryx docs theme --dense # theme provider, light/dark, overrides\nastryx component --list # all components grouped by category\nastryx template --list # available page templates\nON DEMAND:\nastryx docs <topic> --index # section index: one line per section, with its key\nastryx docs <topic> <section> # one section, by key or title\nastryx component <Name> --dense # props, variants, usage, anatomy for one component\nastryx template <name> # emit full page source\nastryx template <name> --skeleton # layout skeleton with spatial annotations\nastryx swizzle <Name> # eject component source for deep customization\nastryx upgrade --from <old version> --apply # run version migration codemods\nOPTIONS: --detail compact|brief less output | --dense token-efficient | --zh Chinese\nRULE: always run bootstrap on each branch — docs reflect the branch's actual API\nRULE: always run astryx component <Name> --dense before modifying a component\nRULE: after @astryxdesign/core bump, always run astryx upgrade --from <old version> --apply\n\n<!-- ASTRYX-CLI:END -->\n\n<!-- File: CLAUDE.md (Tokens: ~50 | Category: claude-rule) -->\n# Claude Code guidance\n\nRead and follow [`AGENTS.md`](AGENTS.md). It is the canonical repository instruction surface.\n\nAlso read the nearest nested `AGENTS.md` for any path you modify. Do not duplicate shared guidance in this file.\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/facebook/astryx/HEAD/.cursor/mcp.json)\n</yakaai_skills>"}