Skip to content

Latest commit

 

History

History
153 lines (113 loc) · 9.98 KB

File metadata and controls

153 lines (113 loc) · 9.98 KB

acss-kit — Architecture (Contributor Guide)

This page is for maintainers editing the plugin: adding component references, updating a SKILL workflow, or extending the slash commands.

Prefer diagrams? See visual-guide.md §7 for the maintainer authoring loop as a flowchart.

Plugin layout

plugins/acss-kit/
  .claude-plugin/
    plugin.json                # Authoritative version source; read by Claude Code + /plugin update
  assets/
    foundation/
      ui.tsx                   # Polymorphic UI base — copied verbatim into user projects
  commands/
    kit-add.md                 # /kit-add; delegates to skills/kit-core/SKILL.md
    kit-list.md                # /kit-list; delegates to skills/kit-core/SKILL.md
    theme-create.md            # /theme-create; delegates to skills/styles/SKILL.md
    theme-brand.md             # /theme-brand; delegates to skills/styles/SKILL.md
    theme-update.md            # /theme-update; delegates to skills/styles/SKILL.md
    theme-extract.md           # /theme-extract; delegates to skills/styles/SKILL.md
  skills/
    kit-core/
      SKILL.md                 # Orchestrator for /kit-create, /kit-list, /kit-sync, /kit-update, Form/HTML/Style-Tune modes
      references/
        architecture.md        # UI polymorphic chain, compound pattern, data-attr selectors
        accessibility.md       # WCAG rationale, useDisabledState source, WCAG checklist
        composition.md         # Component categories, decision tree, inline-types pattern
        css-variables.md       # Naming convention, fallbacks, rem conversion
        inline-components.md   # Badge, Tag, Heading, Text/Paragraph, Details, Progress
        form.md                # Form composition (legacy; superseded by kit-core Form Mode)
        foundation.md          # UI polymorphic base documentation
    component-<name>/          # 15 per-component skills (alert, button, card, …)
      SKILL.md                 # Component skill (description, 5-step workflow)
      reference.md             # Nine-section reference doc (canonical 9-section example: component-button/)
    styles/
      SKILL.md                 # Theme generation workflow (4 flows)
      references/
        role-catalogue.md      # 15 required + 3 optional --color-* roles, contrast pairings
        palette-algorithm.md   # OKLCH lightness targets, state hue offsets
        theme-schema.md        # Internal JSON schema for the round-trip scripts

Command → SKILL delegation

Command files are intentionally thin. Each one:

  1. Documents the command signature and a brief description (for the Claude Code command palette).
  2. Points at the relevant SKILL.md section for the actual workflow.

The logic lives entirely in SKILL.md. Do not duplicate generation logic inside a command file — changes would need to be maintained in two places and would drift.

How to add a new component reference

  1. Run /acss-kit-component-author <name> to scaffold skills/component-<name>/SKILL.md + skills/component-<name>/reference.md. Or create them manually following the shape of skills/component-button/.

  2. Add a Generation Contract block:

    ## Generation Contract
    
    \`\`\`
    export_name:  ComponentName
    file:         component-name/component-name.tsx
    scss:         component-name/component-name.scss
    imports:      [../ui]
    dependencies: [other-component-name]
    \`\`\`

    Every field is required. dependencies is an array of component names (lowercase, matching their reference doc names). An empty array [] means a leaf component.

  3. Add the props interface, CSS variables, and a usage snippet following the pattern in existing reference docs (see skills/component-button/reference.md for the most complete example).

  4. Cross-link the relevant shared references within the doc body:

    • Polymorphic UI type chain → references/architecture.md
    • useDisabledState hook → references/accessibility.md
    • Compound component pattern → references/composition.md
    • CSS variable naming / fallback strategy → references/css-variables.md
  5. All fpkit source references must use full GitHub URLs pinned to a tag or commit SHA — never repo-relative paths and never blob/main. For example:

    https://github.com/shawn-sandy/acss/blob/v6.5.0/packages/fpkit/src/components/button/btn.tsx
    

    See .claude/rules/fpkit-references.md for the full policy. The rule now auto-loads for both plugins/*/skills/*/references/** and plugins/*/skills/component-*/reference.md.

.acss-target.json — target directory contract

.acss-target.json at the project root tells the SKILL where to write generated components, and (since 0.5.0) what the user's build stack looks like so integration advice is correct for the framework. The full shape:

{
  "componentsDir": "src/components/fpkit",
  "utilitiesDir": "src/styles",
  "stack": {
    "framework": "vite",
    "frameworkVersion": "5.4.0",
    "bundler": "vite",
    "cssPipeline": ["sass"],
    "tsconfig": true,
    "entrypointFile": "src/main.tsx",
    "cssEntryFile": "src/styles/index.scss",
    "detectedAt": "2026-05-01T00:00:00Z"
  }
}

componentsDir and utilitiesDir are optional — the detectors fall back to src/components/fpkit and src/styles and refuse stale entries that point at deleted directories. The stack block is also optional; downstream scripts (verify_integration.py) emit a reason pointing back to detect_stack.py when it is absent.

stack.cssEntryFile is added by /setup Step 7.5 (scripts/detect_css_entry.py) when the user picks (or supplies) a CSS/SCSS entry to receive the generated light.css / dark.css @import lines. It is independent of entrypointFile: entrypointFile is the TSX root (typically src/main.tsx), while cssEntryFile is the stylesheet root (e.g. src/styles/index.scss). verify_integration.py accepts theme imports living in either file, so projects that route all styles through SCSS no longer trip the validator with an empty TSX entrypoint.

The SKILL reads the file during Step A3 and writes it if absent (scripts/detect_target.py), then refines it during Step A3.1 (scripts/detect_stack.py). Step G runs scripts/verify_integration.py to confirm the entrypoint actually imports the generated artifacts. Commit .acss-target.json to git so subsequent /kit-add and /theme-create runs reuse the same configuration.

Version bump checklist

Before committing any plugin change, per the repo-level pre-submit checklist:

  1. Bump the version in .claude-plugin/plugin.json using /release-plugin acss-kit (or manually).
  2. Confirm that all new references/ file links to fpkit source use full GitHub URLs.
  3. Update marketplace.json description if the change is user-facing. Do not add a version key to the marketplace.json entry — plugin.json is the authoritative version source.
  4. Update README.md if commands or behavior changed.

Docs-only additions (new docs/*.md files) do not require a version bump, as they do not change command behavior or generated output.

assets/foundation/ui.tsx

This file is copied verbatim into user projects. Changes to it are rare and high-impact: every project that has already run /kit-add keeps the old copy (skip-existing rule). Treat changes to ui.tsx like a breaking change — note them prominently in the CHANGELOG and consider bumping the minor version.

If you modify the polymorphic type chain (the PolymorphicRef<C>UIProps<C> ladder), verify that the generated component .tsx files in the reference docs still type-check against the new types. The reference docs contain inline TSX examples that must be kept consistent with ui.tsx.

Design notes (deferred work)

These are not implementation tickets — they capture decisions that surfaced during the v0.11 adoption review. None of these change behavior today; they are recorded so a future maintainer can pick up the work with full context instead of re-deriving the rationale.

Shared phrase-parser library for component-creator and component-form

The two creator-mode pilots both parse natural-language prompts: component-creator resolves prose against a component's ## Props Interface, and component-form derives a field list from a form description. Today each pilot carries its own parser plus colour/size synonym tables. The duplication is small per-pilot but grows linearly as either skill expands its vocabulary, and a fix to the synonym table for one skill silently leaves the other behind.

When both pilots reach their graduation criteria (see each SKILL.md description: front-matter), factor the shared logic into a single helper consumed by both:

  • Phrase tokeniser (split prose into intent / subject / modifier triples).
  • Synonym resolver (warm → friendly tone family, soft → reduced-weight family, etc.).
  • Prop-union matcher (resolve "primary" / "outline" / "small" against a TypeScript union literal).
  • Halt builder (generate the AskUserQuestion-shaped prompt for ambiguous inputs).

The helper should live alongside the pilots (e.g. skills/_shared/phrase-parser.md), not in assets/, so it stays markdown-as-source. Do not ship until both pilots are graduating — premature extraction would solidify a contract before either pilot's vocabulary has stabilised.

/kit-add --target=html (HTML output mode)

/kit-add shares most of its pipeline across React and HTML output: target detection, dependency resolution, manifest tracking, integration verification, and SCSS emission are byte-identical. The two modes diverge only at the final emit step (TSX vs HTML markup + vanilla JS).

The kit-core skill (skills/kit-core/SKILL.md) houses both modes: Steps A–G drive the shared React pipeline, and the ## HTML Target section (HT-A through HT-F) covers the static-HTML emit. Pass --target=html to /kit-add to switch modes; the default (--target=react) is unchanged. Components without a ## HTML Template block in their reference.md fall through to a "not yet" warning.