Skip to content

Latest commit

 

History

History
204 lines (160 loc) · 10.8 KB

File metadata and controls

204 lines (160 loc) · 10.8 KB

Astryx repository guidance

Astryx is a public design-system repository. Never commit internal links, identifiers, service names, private operational instructions, or other Meta-only context.

Instruction surface

This AGENTS.md is the canonical, tool-agnostic instruction surface for the repository. Add or change shared agent guidance here rather than duplicating it in tool-specific instruction files. Put genuinely path-specific guidance in a nested AGENTS.md.

Start here

  • Product builders: use astryx docs, component {Name}.doc.mjs files, and packages/cli/assets/docs/.
  • Contributors: read CONTRIBUTING.md and the relevant guidance linked from docs/README.md.
  • Component work: read the component's {Name}.spec.md when one exists, then any module:* records it lists for the public module being changed, followed by consumer docs, tests, and implementation.
  • Cross-component work: read the relevant contract under docs/families/, applicable design spec under docs/design/, and current architecture under docs/architecture/.
  • Consequential shared-system changes: use a record under docs/specs/.

Authority

Knowledge records declare authority:

  • draft: not authoritative; may still need evidence or owner review;
  • current: explicitly approved and authoritative;
  • archived: context only, with a reason such as superseded, withdrawn, or historical and a replacement link when one exists.

Only current records govern implementation and review. Never infer approval from merged code, silence, an old review, or an existing wiki page.

Judgment boundary

Resolve checkable behavior from code, tests, and browser evidence. Ask a human only when a stable public API, theme contract, ownership boundary, compatibility policy, or genuinely subjective visual direction remains undecided. Ask one question at a time.

Before drafting, reviewing, or implementing a proposed outcome, search current records and open pull requests using the proposed canonical owner/id, affected paths and exported symbols, and the behavior's semantic terms. Extend or project the existing canonical owner by default. Create a new record only for a distinct fact boundary, and state why the existing owner cannot contain it. Do not create new policy for work that is already complete, owned, or superseded.

Validation

Run pnpm check:knowledge after editing knowledge records or templates. A material template-shape change requires a schema-version bump and migration of active records; changing template guidance alone does not rewrite accepted history.

Custom Commands

/vibe-test [count] - Run vibeability tests

Tests how well AGENTS.md helps LLMs generate correct Astryx component code.

Usage:

/vibe-test 5                    # Run 5 stratified sample tests (one-shot)
/vibe-test                      # Run all 21 tests (one-shot)
/vibe-test 5 --degradation      # Run 5 tests with degradation curve (10-turn)

How to execute:

  1. Run pnpm -F @astryxdesign/vibe-tests interactive --sample <count> to set up iteration
  2. Spawn parallel subagents (one per test prompt) to:
    • Read the task file from results/<iteration>/tasks/{promptId}.json
    • Generate code for the prompt using Astryx components (AGENTS.md auto-injected)
    • Self-evaluate for success/escape hatches
    • Write .tsx result to results/<iteration>/results/{promptId}.tsx
    • Write .json metadata to results/<iteration>/results/{promptId}.json
  3. Trigger gh workflow run vibe-screenshots.yml to build previews and capture screenshots
  4. Run pnpm -F @astryxdesign/vibe-tests aggregate --iteration <id> to see results

Degradation mode (--degradation): Tests context retention across 10-turn conversations with filler, distractor, and recovery turns. Probes at turns 0, 6, 8, 10 to measure quality degradation. Results show a line graph of each test's progression.

Result format:

{
  "id": "<iter>-<promptId>",
  "timestamp": "...",
  "model": "claude-code-interactive",
  "persona": "naive",
  "promptCategory": "...",
  "trajectoryDepth": 0,
  "prompt": "...",
  "response": "<code>",
  "evaluation": {"success": true, "componentsUsed": [...], "escapeHatches": [...]}
}

Runners 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.

AI Context

For architectural context, decisions, and research, see the GitHub Wiki:

  • Decisions — API Conventions, Why StyleX, StyleX Distribution
  • Architecture — System Architecture, Component Authoring Guide
  • Research — AI + Design Systems, AI Model Trajectory, Swizzle Ergonomics
  • Future — Animation System, RSC Utilities, Distribution Strategy

For 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).

Documentation Standard

Documentation lives in two places:

  1. File Headers — Each source file has a structured JSDoc header with @input, @output, @position
  2. Component Docs{Name}.doc.mjs files in each component directory (props, features, examples)

Update Protocol: When modifying code, update the file's header comment. Look for SYNC: comments as reminders.

Audience: every .doc.mjs, and everything under packages/cli/assets/docs/, is written for people building with Astryx — not for people building Astryx. Rubrics, readiness gates, audit checklists and lab→core criteria belong in the wiki. packages/cli/assets/docs/README.md has the test and the page each kind of material goes to.

Quick Reference

  • Package manager: pnpm 11, pinned by the packageManager field (see CONTRIBUTING.md for install options — Corepack is one of several, and Node 25+ no longer bundles it)
  • Testing: Vitest (colocated tests)
  • Components: packages/core/
  • Storybook: apps/storybook/

JSDoc Conventions

  • @example code fences must use plain ```, not ```tsx. 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.

[StyleX v0.17.5 CSS Support]|Use CSS-native solutions. Don't build JS workarounds for supported features. |AT-RULES: @media, @supports, @container (+named), @starting-style, @scope — YES |AT-RULES: @layer, @property (explicit) — NO (compiles but invalid CSS output) |PSEUDO-CLS: :hover, :focus, :focus-visible, :focus-within, :active, :disabled — YES |PSEUDO-CLS: :first-child, :last-child, :nth-child(), :where(), :is(), :has(), :not() — YES |PSEUDO-CLS: :placeholder-shown, :checked, :empty, :modal, :user-valid, :user-invalid — YES |PSEUDO-EL: ::before, ::after, ::placeholder, ::selection, ::backdrop, ::marker, ::view-transition-_ — YES |COMPOUND: ::backdrop+condition, RTL :is([dir="rtl"] _), nested @media+pseudo — YES |VALUES: var(), calc(), clamp(), light-dark(), color-mix(), container-type/name — YES |ANIM: transition (shorthand+individual), transitionBehavior:allow-discrete, animation, stylex.keyframes — YES |WHEN: stylex.when.ancestor(':hover'/':focus-within'/':active'/':disabled') — YES |WHEN: stylex.when.descendant(':hover'), siblingBefore(':checked'), siblingAfter(':checked'), anySibling(':hover') — YES |WHEN: stylex.when.ancestor('[data-attr]') — NO (pseudo selectors only, must start with ":") |NESTING: CSS nesting with & — NO (use stylex.when.ancestor/descendant/sibling for parent-child state) |API: stylex.firstThatWorks() for CSS fallbacks (e.g. display: grid with flex fallback) — YES |API: stylex.positionTry() for anchor positioning @position-try — YES |API: stylex.types.color/length/etc for typed CSS variables in defineVars — YES |API: stylex.defineConsts() for compile-time constants — YES |DYNAMIC: Functions in stylex.create for runtime values — YES |VARS: stylex.defineVars, stylex.createTheme (require .stylex.ts files) — YES |LAYOUT: grid, flex+gap, aspect-ratio, overscrollBehavior, scrollbar-gutter/width — YES |PATTERN: dialog entry animation -> @starting-style (not useState+rAF) |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. |PATTERN: hover on touch -> @media (hover: hover) guard |PATTERN: zebra striping -> :nth-child(even) (not index%2 JS) |PATTERN: container responsive -> @container (not ResizeObserver) |PATTERN: CSS fallback values -> stylex.firstThatWorks() (not manual fallback) |PATTERN: dynamic/runtime values -> stylex.create({ s: (val) => ({ prop: val }) }) (not inline styles) |PATTERN: conditional styles -> stylex.props(condition && styles.x) (not className toggling) |PATTERN: link elements -> useLinkComponent() (not hardcoded ). Consumers swap via LinkProvider for framework routers (Next.js, React Router) |VERIFY: node internal/stylex-capabilities/scan.mjs

Astryx CLI|Run from repo root. Load agent docs before any component work. astryx() { node packages/cli/clients/cli/bin/astryx.mjs "$@"; } BOOTSTRAP (run every branch, <500ms): astryx help # discover all commands and options astryx docs # list available doc topics astryx docs principles --dense # design rules, anti-patterns, xstyle, tokens astryx docs tokens --dense # spacing, color, radius, typography, shadow astryx docs theme --dense # theme provider, light/dark, overrides astryx component --list # all components grouped by category astryx template --list # available page templates ON DEMAND: astryx component --dense # props, variants, usage, anatomy for one component astryx template # emit full page source astryx template --skeleton # layout skeleton with spatial annotations astryx swizzle # eject component source for deep customization astryx upgrade --apply # run version migration codemods OPTIONS: --detail compact|brief less output | --dense token-efficient | --zh Chinese RULE: always run bootstrap on each branch — docs reflect the branch's actual API RULE: always run astryx component --dense before modifying a component RULE: after @astryxdesign/core bump, always run astryx upgrade --apply