plugins/acss-kit/skills/kit-sync/SKILL.md
Use when the user asks to bulk-install all acss-kit components and themes (/kit-sync) or re-copy unmodified components after a plugin update (/kit-update).
npx skillsauth add shawn-sandy/acss-plugins kit-syncInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Bulk install every shipped component + foundation + theme into a developer's project in one shot, then safely re-copy on subsequent plugin upgrades — without clobbering user customizations.
/kit-add is per-component. /setup is one-time bootstrap. Neither helps a developer who wants to:
skills/component-*/ plus the foundation and a starter theme in a single command.acss-kit upgrade without overwriting files they've edited.This skill closes both gaps via a manifest at <project>/.acss-kit/manifest.json that records the sha256 of every generated file at the moment it was written. Drift detection compares on-disk content to that recorded hash to classify each tracked file as clean, modified, or missing.
<project-root>/.acss-kit/manifest.json:
{
"schemaVersion": 1,
"pluginVersion": "0.9.0",
"targetDir": "src/components/fpkit",
"stylesDir": "src/styles",
"themeFile": "acss-kit.theme.json",
"generatedAt": "2026-05-03T14:22:11Z",
"files": {
"src/components/fpkit/ui.tsx": {
"source": "asset:foundation/ui.tsx",
"sha256": "<hex>",
"pluginVersion": "0.9.0",
"kind": "foundation"
},
"src/components/fpkit/button.tsx": {
"source": "ref:components/button.md#tsx-template",
"sha256": "<hex>",
"pluginVersion": "0.9.0",
"kind": "component",
"component": "button"
},
"src/styles/theme/light.css": {
"source": "generator:tokens_to_css.py",
"sha256": "<hex>",
"pluginVersion": "0.9.0",
"kind": "style"
}
}
}
kind is one of foundation (ui.tsx, foundation.css, and every file under foundation/sass/), component (a tracked TSX/SCSS pair), style (a generated theme CSS file), or theme (the user's seed theme.json).
Drift detection runs sha256 on normalized content, not raw bytes. Normalize both the freshly generated content (before recording the manifest hash) and the on-disk content (before comparing). The normalization is implemented in scripts/hash_file.py and duplicated in scripts/diff_status.py:
Without normalization a Prettier or editor save would flip every file to modified immediately.
Applies to both workflows below (/kit-sync bulk install and /kit-update safe re-copy). If the session is in plan mode, call ExitPlanMode before reaching Step S1 or U1 — both flows write component TSX/SCSS, theme CSS, and the manifest at .acss-kit/manifest.json, and they shell out to detect_target.py, detect_stack.py, manifest_read.py, manifest_write.py, diff_status.py, hash_file.py, generate_palette.py, tokens_to_css.py, validate_theme.py, and verify_integration.py. Plan mode blocks all of those.
--dry-run is not a reason to remain in plan mode. The flag suppresses writes inside the workflow, but the workflow still has to run detect_target.py, manifest_read.py, and diff_status.py via Bash to produce the plan tree — and plan mode would block those. Exit plan mode and pass --dry-run to skip the writes.
Stay in plan mode only when it is absolutely necessary — i.e. the user explicitly asked for a description of what /kit-sync or /kit-update would do without running any scripts at all. In that case, narrate the high-level workflow from the sections below without invoking Write/Edit/Bash, and wait for approval before re-entering this skill.
/kit-sync)Triggered by /kit-sync and by natural-language phrasing like "install all components", "bulk copy the kit", "sync the entire kit into my project".
--target=<dir> — override component directory (default: read .acss-target.json componentsDir, fallback src/components/fpkit).--styles-dir=<dir> — override styles directory (default: read .acss-target.json stylesDir, fallback src/styles).--seed=<hex> — seed color for theme generation (default: prompt the developer).--skip-styles — components-only sync; do not seed theme.--dry-run — print the plan tree, do not write any files or manifest.python3 ${CLAUDE_PLUGIN_ROOT}/scripts/detect_target.py <cwd>. If projectRoot is null, halt with the script's reasons[0].python3 ${CLAUDE_PLUGIN_ROOT}/scripts/detect_stack.py <projectRoot> and confirm cssPipeline includes sass. If not, surface the install command from detect_package_manager.py and stop.python3 ${CLAUDE_PLUGIN_ROOT}/scripts/manifest_read.py <projectRoot>. If the manifest already exists, treat this run as a re-sync — proceed to Step S2 but route every file through the diff/skip logic from the safe-update workflow before writing.Glob ${CLAUDE_PLUGIN_ROOT}/skills/component-*/SKILL.md. Every component with a per-component skill is in scope. Also read ${CLAUDE_PLUGIN_ROOT}/skills/kit-core/references/inline-components.md to include the inline-only entries (Badge, Tag, Heading, Text/Paragraph, Details, Progress) that have a Generation Contract.
Exclude Form (lives as a skill, not a reference doc) and UI (foundation) (handled separately as ui.tsx).
For each in-scope component, walk its Generation Contract dependencies: recursively (same logic as the components skill Step B3). Union all results into a single ordered list, leaves first.
Display the full plan to the developer:
/kit-sync plan — bulk install into <projectRoot>:
Foundation:
src/components/fpkit/ui.tsx
Components (15):
icon.tsx
button.tsx + button.scss
icon-button.tsx + icon-button.scss
...
Styles:
src/styles/theme/light.css (from seed #4f46e5)
src/styles/theme/dark.css
acss-kit.theme.json (seed record)
Manifest:
.acss-kit/manifest.json
Proceed? [Enter to continue, Ctrl+C to cancel]
Wait for confirmation. If --dry-run, print the plan and exit without writing.
For each entry in the dep tree (leaves first):
## TSX Template and ## SCSS Template content.{{IMPORT_SOURCE:...}} / {{NAME}} / {{FIELDS}} placeholders (same rules as /kit-add Step C).hash_file.py --stdin to capture the normalized sha256 before writing.files[] payload for manifest_write.py.Re-sync: if a tracked file already exists in the manifest and is modified (per Step S1's diff), skip it and add to the skipped[] summary instead of overwriting.
Apply the same three-case matrix as /kit-add Step A4:
ui.tsx, foundation.css, and every file under foundation/sass/ in the asset tree:
kind: "foundation".clean → overwrite + update hash.modified → skip (list in the skipped summary).foundation.css is absent from the project but ui.tsx is already present (regardless of manifest state — mirrors the "existing install" case in /kit-add Step A4) → print the backward-compat prompt before copying:
foundation.css not found. Adding it will apply a CSS reset, base typography,
and @layer ordering. To revert: delete foundation.css and remove its import.
Add foundation.css now?
Only copy on confirmation; skip silently otherwise.Manifest entry shape for foundation files:
"src/components/fpkit/foundation.css": {
"source": "asset:foundation/foundation.css",
"sha256": "<hex>",
"pluginVersion": "0.11.0",
"kind": "foundation"
},
"src/components/fpkit/foundation/sass/_index.scss": {
"source": "asset:foundation/sass/_index.scss",
"sha256": "<hex>",
"pluginVersion": "0.11.0",
"kind": "foundation"
}
Add one entry per file in the foundation/sass/ tree using the same pattern.
--skip-styles)--seed=<hex> flag, or the acss-kit.theme.json seed field if it exists, or prompt the developer.generate_palette.py → palette JSON.tokens_to_css.py → emit <stylesDir>/theme/light.css and <stylesDir>/theme/dark.css.<projectRoot>/acss-kit.theme.json with { "seed": "<hex>", "generatedAt": "<iso>" } for re-runs.kind: "style" (for the CSS files) and kind: "theme" (for acss-kit.theme.json).validate_theme.py against the new CSS files. Surface any WCAG failures, but do not block — the developer may want to tune.Pipe the assembled payload to manifest_write.py:
echo '<payload-json>' | python3 ${CLAUDE_PLUGIN_ROOT}/scripts/manifest_write.py
The payload includes projectRoot, pluginVersion (read from .claude-plugin/plugin.json), targetDir, stylesDir, themeFile, and the files[] array.
Run verify_integration.py. Surface any missing-import reasons as a numbered fix-up list.
/kit-sync complete:
Created: 18 files
Skipped: 2 files (modified — listed below)
Manifest: .acss-kit/manifest.json
Skipped (user-modified):
src/components/fpkit/button.tsx
src/styles/theme/light.css
Next:
/kit-update — re-sync clean files after future plugin upgrades
/kit-update --check — preview drift without writing
/kit-update)Triggered by /kit-update [<component>...] and by natural-language phrasing like "update unmodified components", "re-copy the kit safely", "refresh anything I haven't touched".
<component>... — restrict the update to a list of components (e.g. /kit-update button alert). Default: every entry in the manifest.--check — report only; do not write.--force — overwrite modified files too. Each modified file is backed up to <file>.bak before being overwritten.Run manifest_read.py <projectRoot>. Three terminating cases:
exists: false — manifest missing or malformed. Halt with:
No .acss-kit/manifest.json found. Run /kit-sync first to bulk-install
the kit and start tracking generated files.
schemaMismatch: true — manifest is on disk but written by a different schemaVersion. Halt with the reasons[] from the script — do not fall through to a fresh-install path, since that would bypass drift protection on every tracked file.
Otherwise — proceed to Step U2.
Run diff_status.py <projectRoot>. Capture clean[], modified[], and missing[].
If a positional component filter was passed, intersect each list with the requested set (matching on the component field of each entry).
/kit-update report — <projectRoot>:
Clean (will overwrite): 14 files
Modified (will skip): 2 files
Missing (will recreate): 1 file
Modified — your changes preserved:
src/components/fpkit/button.tsx
src/styles/theme/light.css
Missing — will be regenerated:
src/components/fpkit/icon.tsx
If --check, stop here.
For each entry in clean[] and missing[]:
kind and source.For each entry in modified[]:
--force: copy current content to <file>.bak, regenerate, write, hash, update manifest entry.Pipe the merged update payload to manifest_write.py. Existing entries that were not touched (because they were skipped) keep their previous sha — no spurious churn.
/kit-update complete:
Updated: 14 files
Skipped: 2 files (modified — pass --force to overwrite with .bak backup)
Recreated: 1 file
Manifest: .acss-kit/manifest.json
If a user phrase auto-triggers this skill (e.g. "copy every acss-kit component into my project"), pick the workflow that fits:
When ambiguous, ask once: "Bulk install (writes everything) or safe update (only re-copies unmodified files)?"
development
Internal orchestrator for /kit-create, /kit-list, /kit-sync, /kit-update and Form/HTML/Style-Tune modes. Per-component generation lives in component-<name> skills; do not auto-trigger for component requests.
data-ai
Use when the user asks to generate, create, or scaffold a Table — accessible data table with caption, scope headers, responsive scroll wrapper, and sortable column support.
tools
Use when the user asks to generate, create, or scaffold a Popover — accessible tooltip/popover using the Popover API with focus trap, aria-expanded, and light-dismiss.
tools
Use when the user asks to generate, create, or scaffold a Nav — accessible navigation landmark with aria-label, current-page link marking, and horizontal/vertical layout.