nextlevelbuilder/ui-ux-pro-max-skill
github.com/nextlevelbuilder/ui-ux-pro-max-skill ↗ · 616 files · 12.7 MB
UI UX Pro Max 🇮🇩 Bahasa Indonesia | 🇰🇷 한국어 | 🇻🇳 Tiếng Việt | 🇨🇳 简体中文 | 🇺🇸 English An AI skill that provides design intelligence for building professional UI/UX across multiple platforms and frameworks.
Overview
UI/UX Pro Max is a design-intelligence toolkit packaged three ways: a dependency-free Python search engine (BM25 + regex over canonical CSV datasets) under src/ui-ux-pro-max/, an npm CLI (ui-ux-pro-max-cli, bin `uipro`) that installs the skill into ~20 AI coding assistants via per-platform templates, and a Claude Code plugin rooted at .claude/skills/ with 6 sibling sub-skills. Its flagship feature is a --design-system generator that aggregates five domain searches plus a 192-row reasoning-rules CSV into a formatted design system with an optional Master+Overrides persistence layer. A Next.js style gallery, a separate 'website design stack' bundle (stack/), six GitHub Actions workflows, and a relevance-evaluation harness round out the repo.
System map
The repo is a content product, not a running service: the runtime is a stdlib-only Python 3 CLI (search.py over core.py/design_system.py) reading canonical CSVs under src/ui-ux-pro-max/data/. The TypeScript CLI under cli/ is purely an installer that renders platform templates and copies bundled assets; it never executes the Python. Distribution happens through three mirrored copies of the same data (src/ -> cli/assets/ -> .claude/skills/ui-ux-pro-max/) kept in sync by cli/scripts/sync-assets.mjs and enforced by CI. Supporting surfaces: a Next.js 14 style gallery, a stack/ sub-project that wraps the skill with Playwright/MCP tooling, and six GitHub Actions workflows covering tests, asset sync, catalog refresh, release, and version bumping.
- The runtime entrypoint is src/ui-ux-pro-max/scripts/search.py, an argparse CLI exposing --domain (12 keys of CSV_CONFIG), --stack (22 stacks), --design-system, --json, --persist/--page/--output-dir/--force, and three 1-10 dials --variance/--motion/--density.
- core.py implements a hand-rolled BM25 class (k1=1.5, b=0.75) with in-process caches _csv_cache and _bm25_cache keyed by file signature (st_mtime_ns, st_size), plus synonym normalization, per-domain score floors, and deterministic domain tie-breaking.
- design_system.py contains DesignSystemGenerator plus three output formatters (format_ascii_box, format_markdown, format_master_md) and the Master+Overrides persistence layer (persist_design_system, format_page_override_md).
- reasoning_contract.py is a closed, non-executable DSL: ui-reasoning.csv Decision_Rules cells are JSON objects whose conditions must come from ALLOWED_CONDITIONS (must_have + 38 if_* signals) and actions must carry a constraint:/style:/pattern:/mode: prefix.
- The npm CLI (cli/package.json name ui-ux-pro-max-cli v2.5.0, bin uipro -> dist/index.js) registers exactly four commander subcommands: init, versions, update, uninstall; it is ESM ('type': 'module') built by bun build with a tsc fallback in scripts/build.mjs.
- src/ui-ux-pro-max/ is the single source of truth; cli/scripts/sync-assets.mjs mirrors data/, scripts/, templates/ into cli/assets/, mirrors data/ and scripts/ into .claude/skills/ui-ux-pro-max/, and copies 6 sub-skills (banner-design, brand, design, design-system, slides, ui-styling) into cli/assets/skills/, normalizing CRLF->LF before hashing.
- The Claude plugin surface is .claude-plugin/plugin.json + marketplace.json (version 2.13.0) pointing 'skills' at ./.claude/skills/, where SKILL.md is hand-authored (not template-generated) while its data/ and scripts/ are mirrors of src/.
- The gallery is a Next.js 14 + Tailwind app (gallery/package.json name style-gallery) whose server component reads gallery/data/styles.csv — a symlink into ../../src/ui-ux-pro-max/data/styles.csv — and parses it with a hand-written CSV parser.
- stack/ is a separate private package (claude-website-design-stack) that wraps the skill with a design loop (plan -> commit aesthetic -> build -> Playwright visual check -> design-review subagent) installed by scripts/setup.sh via npx ui-ux-pro-max-cli init --ai claude.
- CI is six workflows: tests.yml (verify:data + pytest over .claude/skills + Playwright e2e + gallery build), check-asset-sync.yml (drift + skill-path contract greps), smoke-stacks.yml, refresh-catalogs.yml (weekly cron), release.yml (semantic-release to npm/GitHub), bump-versions.yml (post-release JSON version sync PR).
- Version numbers intentionally diverge: the skill/plugin manifests are at 2.13.0 while cli/package.json is 2.5.0; bump-versions.yml opens a PR to re-sync skill.json, marketplace.json, and plugin.json after each GitHub release.
- Python scripts are strictly stdlib-only (csv, json, re, difflib, math, pathlib) — no requirements.txt or pyproject exists; tests run under unittest/pytest with zero third-party runtime deps, matching the documented 'no external dependencies' prerequisite.
Feature catalog
User-facing surface splits into (a) the Python search CLI with 12 search domains, 22 stack datasets, domain auto-detection, identity exact-match, typo suggestions, and cross-domain redirects; (b) the --design-system generator with dials and persistence; (c) the uipro installer CLI supporting 20 AI platforms plus 'all', global installs, dry-run, update, and uninstall; and (d) the style gallery web app. Data products include 88 style rows (79 searchable / 50 active), 192 product+palette+reasoning triples, 74 font pairings, 25 charts, 105 curated icons, 17 GSAP presets, and 1271 stack guidelines.
- Domain search covers 12 CSV_CONFIG domains — style, color, chart, landing, product, ux, typography, icons, gsap, react, web, google-fonts — each with its own search_cols/output_cols projection in core.py.
- Stack search covers 22 framework CSVs under data/stacks/ (react, nextjs, vue, svelte, astro, swiftui, react-native, flutter, nuxtjs, nuxt-ui, html-tailwind, shadcn, jetpack-compose, threejs, angular, laravel, javafx, wpf, winui, avalonia, uno, uwp) sharing a common _STACK_COLS schema.
- Domain auto-detection (detect_domain) weights keyword matches by phrase specificity, adds +2 for hex-color literals, breaks ties via a fixed _DOMAIN_TIEBREAK_ORDER, and defaults to 'style' when nothing scores.
- Exact-identity routing resolves style queries directly against Style ID/Category/Aliases (_style_identity) and landing queries against Pattern ID/Name/Aliases (_exact_row_identity), bypassing BM25; deprecated styles redirect to a parent or cross-domain Replacement Domain/ID.
- Empty results return 'Closest known terms' suggestions via _suggest_terms (difflib >= 0.72 similarity, filtered through score thresholds) or _suggest_identities for landing patterns — a deliberate anti-fallback design to prevent silent fabrication.
- --design-system mode produces a structured recommendation: pattern+sections, style, 16-token semantic color palette, typography pair, key effects, anti-patterns, pre-delivery checklist, and optional GSAP motion snippet; rendered as ASCII box, markdown, or JSON.
- Three design dials tune generation: --variance biases style selection toward minimal or bold keywords, --motion attaches a tiered GSAP snippet from motion.csv, and --density swaps the spacing-scale tokens written into MASTER.md.
- Persistence (--persist --output-dir --page --force) writes design-system/<project-slug>/MASTER.md plus pages/<page>.md overrides, refusing to overwrite existing files unless --force, and generates page overrides via _generate_intelligent_overrides + _detect_page_type.
- uipro init installs for 20 AI platform types (claude, cursor, windsurf, antigravity, copilot, kiro, roocode, codex, qoder, gemini, trae, opencode, continue, codebuddy, droid, kilocode, warp, augment, codewhale, universal) or 'all', with --global targeting the home directory and --dry-run printing planned writes.
- uipro update compares the installed CLI version to the latest GitHub release and runs `npm install -g ui-ux-pro-max-cli@<version>` via execFileSync (shell:true only on Windows for npm.cmd), then instructs re-running init --force; uipro versions lists releases.
- uipro uninstall removes the orchestrator plus all bundled sub-skills, deriving the real install parent from each platform config's folderStructure (so copilot's .github/prompts/ and kiro's .kiro/steering/ are handled) and also cleaning legacy .shared/skills layouts.
- Each uipro init also installs 6 sibling sub-skills (banner-design, brand, design, design-system, slides, ui-styling) copied from cli/assets/skills/ next to the orchestrator's parent directory.
Data flow
Data flows one direction: canonical CSV/JSON datasets under src/ui-ux-pro-max/data/ are consumed in-process by the Python engine (csv.DictReader -> BM25 index -> projected row dicts -> formatted text/JSON), and physically mirrored by sync-assets.mjs into cli/assets/ and .claude/skills/. The CLI copies those bundled assets into the user's project at install time; at query time the skill instructs the agent to shell out to the installed scripts/search.py. Upstream catalog data (Google Fonts API, Phosphor npm packages, google/fonts repo metadata) enters only through the refresh-catalogs workflow as review-only candidates validated by refresh-*.py scripts.
- Input boundary is CSV_CONFIG/STACK_CONFIG: each domain maps to a file under DATA_DIR (Path(__file__).parent.parent / 'data') with declared search_cols and output_cols; rows are loaded via _load_csv_snapshot which re-stats the file before and after reading to reject mid-read mutations.
- Query pipeline: raw query -> _normalize (synonym table, e.g. 'e-commerce'->'ecommerce', 'colour'->'color') -> BM25.tokenize (punctuation strip, >=2 chars, stopword removal) -> optional _rewrite_query_for_domain routing rewrites -> BM25.score over joined search_cols.
- Calibrated abstention sits between scoring and output: _SEARCH_THRESHOLDS apply per-domain min_score/min_coverage (e.g. style 4.3, product 6.0, landing requires 0.5 token coverage), and _STACK_THRESHOLD requires min_score 3.6 + 1/3 coverage; abstained queries return empty results plus suggestions.
- Design-system generation is a fan-out/fan-in: search('product') -> category -> _apply_reasoning (ui-reasoning.csv row + decision rules) -> _multi_domain_search issues 5 searches with category/constraints/mood terms folded into the query -> _select_best_match resolves style_priority names through the style lookup before trusting BM25 order.
- Color-mode coherence is enforced in the transform layer: _resolve_color_mode (query markers or dark-primary style) -> _select_palette_for_mode -> _derive_dark_palette (WCAG luminance, contrast-checked ring) -> _filter_anti_patterns_for_mode strips 'avoid dark mode' advice once dark is chosen.
- Output boundary is stdout text formatted for agent consumption: format_output truncates cell values at 300 chars except UNTRUNCATED_COLS (code samples, checklists, CSS imports, GSAP snippets); --json emits the raw result dict including diagnostics when requested.
- Persistence writes only inside --output-dir (default cwd): safe_slug collapses project/page names to [a-z0-9_-] making traversal impossible, and _write_persisted_file publishes via temp-file + fsync + os.link/os.replace so a losing concurrent writer gets FileExistsError.
- Asset distribution flow: src/ui-ux-pro-max/{data,scripts,templates} -> syncDir() (delete target, rewrite LF-normalized) -> cli/assets/ and .claude/skills/ui-ux-pro-max/; install-time flow is ASSETS_DIR -> loadTemplate/renderSkillFile (placeholder substitution {{TITLE}}, {{SCRIPT_PATH}}, etc.) -> writeFile SKILL.md + cp data/ scripts/ -> copySubSkills.
- Platform-specific install paths are data-driven: templates/platforms/*.json declare folderStructure.root/skillPath/filename/dataPath and scriptPath; resolveInstallPaths derives skillDir, skillFilePath, dataDir, and skillsParentDir (e.g. copilot uses a separate dataPath under .github/).
- Catalog refresh flow is offline-review only: refresh-catalogs.yml fetches the Google Fonts Developer API (GOOGLE_FONTS_API_KEY, 25MB cap), sparse-clones google/fonts METADATA.pb files, and npm-installs pinned @phosphor-icons packages, then refresh-google-fonts.py/refresh-icon-catalog.py emit candidates+diffs uploaded as artifacts — nothing commits to main automatically.
- Provenance and freshness metadata travel with the data: data-provenance.json records per-entity verifiedAt/sla/confidence/source refs, catalog-summary.json pins sha256 snapshots + counts (88 styles, 1512 phosphor icons, 1271 stack guidelines), and .gitattributes forces LF on data files so hashes are platform-stable.
- The gallery reuses the canonical dataset through a symlink: page.tsx reads gallery/data/styles.csv -> src/ui-ux-pro-max/data/styles.csv at request/render time, then parseStylesCSV throws on any Status outside {active, supplemental, deprecated}.
Behavior traces
Three primary flows were traced end-to-end. (1) Domain search: argparse -> search() -> identity/auto-detect -> _search_csv_detailed -> BM25 -> calibrated abstention -> format_output. (2) Design system: generate_design_system -> DesignSystemGenerator.generate -> product search -> reasoning rules -> 5-domain fan-out -> mode-aware palette -> formatter -> optional atomic persist. (3) Install: uipro init -> detectAIType -> prompt -> templateInstall -> renderSkillFile + copyDataAndScripts + copySubSkills. A fourth maintenance flow (sync/check-assets and the relevance gate) is also traced.
- Domain search order: __main__ argparse -> search(query, domain, max_results) -> _valid_max_results -> if domain omitted, _load_rows_or_empty(styles.csv) + _style_identity(allow_contained=False), else detect_domain -> _search_csv_detailed -> _load_csv_snapshot -> _get_bm25 -> BM25.score -> threshold abstain -> _project_row -> format_output.
- Zero-result path: abstained search -> out['suggestions'] from _suggest_terms/_suggest_identities -> format_output prints 'No matches...' plus closest terms, instructing the agent to retry once and label fallbacks — matching SKILL.md's 'do not fabricate' contract.
- Deprecated-style redirect path: _style_identity exact match -> _style_search_destination -> Parent Style ID lookup or Replacement Domain/ID -> either the parent row is projected or a redirect object is emitted that format_output renders as 'modeled in the <domain> domain as <id>'.
- Design-system trace order: generate_design_system -> DesignSystemGenerator.__init__ (_load_reasoning, _load_styles, _build_style_lookup, _load_landing_patterns) -> generate -> search(query,'product',1) -> _apply_reasoning -> _find_reasoning_rule -> parse_decision_rules -> apply_decision_rules -> _multi_domain_search -> _select_best_match -> _resolve_color_mode/_select_palette_for_mode -> dict assembly.
- Persistence trace: persist_design_system -> safe_slug -> mkdir design-system/<slug>/pages -> format_master_md -> _write_persisted_file (NamedTemporaryFile + fsync + os.link) -> FileExistsError -> status 'skipped_exists' unless --force (os.replace); --page additionally runs format_page_override_md -> _generate_intelligent_overrides -> _detect_page_type.
- Install trace: uipro init -> initCommand -> detectAIType(cwd) probes ~20 marker dirs -> prompts select -> (dry-run: planPlatformInstallActions/planAllPlatformInstallActions, write nothing) -> templateInstall -> generatePlatformFiles -> loadPlatformConfig(AI_TO_PLATFORM) -> resolveInstallPaths -> renderSkillFile -> writeFile -> copyDataAndScripts -> copySubSkills.
- Asset-sync check trace: `npm run check:assets` -> sync-assets.mjs --check -> checkAssets -> diffDir over {data,scripts,templates} vs cli/assets, 6 sub-skills vs cli/assets/skills, and {data,scripts} vs .claude/skills/ui-ux-pro-max -> fileHash (LF-normalized sha256) -> any missing/extra/stale file exits 1.
- Relevance-gate trace: evaluate-relevance.py -> load_json(cases/thresholds/baseline) -> runtime_fingerprint + oracle_fingerprint (sha256 over code+data) -> validate_fixture/validate_identities -> per case: search/search_stack/DesignSystemGenerator.generate -> precision@k, MRR, nDCG, routing accuracy, negative abstention -> check_thresholds -> SystemExit with suspect-case diff on failure.
- Update trace: uipro update -> getLatestRelease (GitHub API with optional UI_PRO_MAX_GITHUB_TOKEN/GITHUB_TOKEN bearer) -> semver-gate the tag -> execFileSync npm install -g -> else fall through to initCommand(force:true) to refresh skill files in place.
- Skill-runtime trace (as installed): agent reads SKILL.md -> invokes `python <skill>/scripts/search.py` -> UTF-8 stdout wrapper -> search/design-system output -> agent synthesizes; references/quick-reference.md and pro-rules.md are read on demand, not loaded eagerly.
Testing signals
Testing is unusually heavy for a dataset repo: 13 stdlib unittest modules under src/ui-ux-pro-max/scripts/tests/ (mirrored into .claude/skills), a fixture-driven relevance evaluator with fingerprint-pinned thresholds, 5 Playwright e2e specs for the CLI (run as a Node test harness, not browser tests), node --test unit tests for the gallery, two bash smoke suites over all domains/stacks, and four validation scripts (CSV structure, semantic data contract, agent-guide claims, catalog summary). The aggregate `npm run verify:data` gate runs all of it and is wired into tests.yml, smoke-stacks.yml, release.yml, and prepublishOnly.
- Python tests live in src/ui-ux-pro-max/scripts/tests/ as 13 unittest modules (test_core, test_design_system_mode, test_data_contracts, test_style_taxonomy, test_catalog_refresh, test_relevance_evaluator, test_web_stack_freshness, etc.) deliberately stdlib-only so they add no dependencies; CI runs them via `python3 -m pytest .claude/skills -v`.
- test_core.py covers tokenizer synonym/stopword behavior, BM25 edge cases, and cache invalidation by file signature (re-writes a temp CSV and asserts the index rebuilds).
- The relevance harness uses fixtures (relevance-cases.json, relevance-thresholds.json, relevance-baseline.json) and graded judgments to compute routingAccuracy, precision@1/3, MRR@3, nDCG@3, negativeAbstention, typoRecoveryAt3, and designSystemCoherence, gated by check_thresholds with calibration vs held_out splits.
- Hard-negative cases tagged 'hard-negative' are run against every domain and every stack to measure false-positive abstention (globalNegativeApplicability), so retrieval regressions that over-match are caught by the gate.
- validate_data.py is a 1095-line semantic contract: it enforces exactly-192-row parity across products/colors/ui-reasoning, WCAG contrast floors per palette pair, style status/parent/redirect invariants, decision-rule validity against the closed grammar, icon import regexes, and per-stack official-doc host allowlists.
- validate-csv.py checks structural CSV hygiene (blank/duplicate headers, field-count mismatches, blank rows) across every data CSV; validate-agent-guide.py recomputes the advertised counts (styles, palettes, fonts, stacks) and asserts the SKILL.md/template descriptions and CLI examples stay accurate.
- smoke-domains.sh dynamically enumerates CSV_CONFIG domains (expected count 12 via EXPECTED_DOMAIN_COUNT) and asserts a focused probe returns >=1 result per domain, printing diagnostics on failure; smoke-stacks.sh does the same for stacks.
- CLI e2e specs (cli/tests/e2e/) use @playwright/test as a plain Node harness: dry-run.spec.ts asserts planPlatformInstallActions lists writes but touches nothing, template-script-paths.spec.ts and agent-query-contract.spec.ts pin the rendered skill content contract; playwright.config.ts targets chromium with CI retries.
- Gallery tests run via `tsc -p tsconfig.test.json && node --test` over compiled JS (lib/parseStyles.test.js, components/metadata-badges.test.js) — an unusual compile-then-test pipeline rather than jest/vitest.
- check-asset-sync.yml embeds two grep-based contract suites: skill-relative path enforcement (no ~/.claude/skills/, project-rooted, or CLAUDE_PLUGIN_ROOT paths outside the one allowed SKILL.md) and a bundled-skill allowlist scan over every shipped markdown file.
- Coverage gaps: no tests exercise the CLI's actual write path (generatePlatformFiles is only tested via the read-only planners), uninstall.ts has no spec, and format_ascii_box/markdown output is only implicitly covered through persistence tests. (inferred)
- release.yml runs the full gate (verify:data, bun build, Playwright, gallery build) before semantic-release publishes to npm with NPM_TOKEN and creates the GitHub release — so untested code cannot ship.
Risk map
The codebase is defensively written (closed decision-rule grammar, slug sanitization, atomic writes, calibrated abstention), but risk concentrates in (a) triple-mirrored data that must stay byte-identical, (b) dead/legacy install paths in the CLI, (c) a hand-rolled CSV parser in the gallery, (d) doc drift, and (e) CI-only network surfaces (GitHub API token, Google Fonts key, npm install of pinned packages). The symlinked gallery data file also contradicts the repo's stated no-symlink rule.
- Triple-mirror consistency is the biggest blast radius: a CSV edited in src/ but not re-synced silently ships stale data through both the npm CLI and the Claude plugin; mitigation is sync-assets.mjs --check in CI, but local edits still rely on the human running `npm run sync:assets`.
- Dead code: init.ts keeps a legacy ZIP-install path (tryGitHubInstall -> installFromZip -> extractZip shelling out to `unzip`/PowerShell Expand-Archive) gated on options.legacy, but index.ts never registers a --legacy flag, so the entire network-download + shell-out path is unreachable from the CLI.
- extractZip interpolates zipPath/destDir into a shell command string (`unzip -o "${zipPath}"`, powershell -Command) — a command-injection shape that is currently dead code but would be exploitable if the legacy flag were ever re-exposed. (inferred)
- update.ts shells out to npm install -g; it mitigates with execFileSync + explicit args + a semver regex gate on the tag, and shell:true only on Windows — but a compromised or malformed GitHub release feed remains the trust boundary.
- The gallery contains a second, hand-written CSV parser (parseCSVLine/splitCSVRecords) independent of Python's csv module; divergence in quoting/CRLF handling would surface only as a runtime throw ('Unterminated quoted CSV field') or misparsed styles.
- gallery/data/styles.csv is a symlink to ../../src/ui-ux-pro-max/data/styles.csv even though CLAUDE.md states the repo avoids symlinks because git-on-Windows checks them out as text pointer files — the gallery would read a path string instead of CSV on such a checkout. (inferred)
- Doc drift: CONTRIBUTING.md tells contributors to edit 'data/rules.csv' (the real file is ui-reasoning.csv) and references a .factory/ directory that does not exist at repo root; README install commands list platforms like 'antigravity' that map to an 'agent.json' template name via AI_TO_PLATFORM indirection.
- Search correctness is threshold-tuned by hand (_DOMAIN_SCORE_FLOORS like style 4.3, icons 5.8, _STACK_THRESHOLD 3.6 + coverage 1/3) and pinned by a calibration version string; a CSV content change can flip abstention behavior repo-wide, which is why the relevance fingerprint gate exists.
- The only network egress in shipped runtime code is cli/src/utils/github.ts (GitHub releases API, optional bearer token from --token/UI_PRO_MAX_GITHUB_TOKEN/GITHUB_TOKEN); refresh-catalogs.yml additionally uses GOOGLE_FONTS_API_KEY and `npm install` of pinned phosphor packages in a sandboxed weekly job.
- Persistence writes outside the repo by design (--output-dir defaults to cwd); safe_slug prevents traversal but nothing stops an agent from pointing --output-dir at an arbitrary directory — mitigated only by SKILL.md instruction text, not code. (inferred)
- bump-versions.yml auto-opens a PR editing three JSON manifests on release publish; skill/plugin manifests (2.13.0) and cli/package.json (2.5.0) are already out of step between releases, so version drift is normal rather than an error.
- Sub-skill directories (.claude/skills/{design,brand,banner-design,ui-styling,slides,design-system}) contain their own scripts/tests not covered by this report's read set; the bundled-skill CI contract treats them as shipped surface, so bugs there ship through every install. (inferred)
Extension points
Extension is deliberately data-driven: new search domains register in CSV_CONFIG, new stacks in STACK_CONFIG + STACK_CURRENT_* tables, new product categories as aligned rows across products/colors/ui-reasoning.csv, new decision-rule signals in CONDITION_SIGNALS, new dial tiers in DIAL_TIERS, new AI platforms via AI_TYPES + AI_TO_PLATFORM + a templates/platforms/*.json file, and new sub-skills via the subSkills array in sync-assets.mjs. Smoke tests and validators auto-enumerate these registries, so additions are picked up without wiring — but several guards (192-row parity, expected domain/stack counts, identity uniqueness) will fail CI if invariants are missed.
- New search domain = one CSV_CONFIG entry (file + search_cols + output_cols); --domain choices, smoke-domains.sh enumeration, and domain auto-detection all derive from it, though _DOMAIN_TIEBREAK_ORDER, _DOMAIN_QUERY_REWRITES, and _SEARCH_THRESHOLDS may need matching entries.
- New stack = a data/stacks/<name>.csv plus a STACK_CONFIG entry; STACK_CURRENT_VERSIONS, STACK_CURRENT_APPLICABILITY, _STACK_QUERY_NAMES, and STACK_OFFICIAL_HOSTS in validate_data.py form the freshness/identity contract the validator enforces.
- New product category requires exactly-aligned rows in products.csv, colors.csv, and ui-reasoning.csv — validate_data.py hard-fails unless each has exactly 192 rows with identical label sets.
- Decision-rule grammar extension points: add an if_* key to CONDITION_SIGNALS (regex-compiled signal phrases) or a prefix to ACTION_PREFIXES/TOKEN_ACTION_PREFIXES; apply_decision_rules produces only deterministic mutations (style_ids, constraints, pattern, mode) — data can never execute.
- Style taxonomy extension: new styles get a kebab-case Style ID, a Status in {active,supplemental,deprecated}, and optional Parent Style ID or Replacement Domain/ID redirect; _check_style_contract enforces identity uniqueness, parent cycles, and vocabulary vocabularies (Performance/Accessibility/mode fields).
- Design dials extend via DIAL_TIERS buckets — variance injects style_keywords ahead of reasoning priorities, motion maps to an Intensity Tier in motion.csv, density swaps the spacing dict written into MASTER.md.
- New AI platform = add the type to AI_TYPES + AI_FOLDERS + AI_TO_PLATFORM + getAITypeDescription, then drop a templates/platforms/<name>.json declaring folderStructure/scriptPath/frontmatter — the installer, dry-run planner, and uninstaller all derive paths from that JSON.
- Template rendering is placeholder substitution on templates/base/skill-content.md ({{TITLE}}, {{DESCRIPTION}}, {{SCRIPT_PATH}}, {{SKILL_OR_WORKFLOW}}, {{QUICK_REFERENCE}}); new platforms reuse the same base — per-platform divergence lives only in the JSON config.
- New bundled sub-skill = create .claude/skills/<name>/ and add the name to the subSkills array in sync-assets.mjs; the bundled-skill CI contract auto-derives its allowlist from the directory listing.
- Catalog refresh scripts are CLI-arg driven (--input, --package-json, --curated-csv, --output, --verified-at, --expected-count) so a new upstream catalog can be added by scripting the same validate->normalize->manifest-write pattern used for Phosphor icons.
- Gallery filter dimensions are computed from data via getUniqueValues over any StyleData key, so a new CSV column can become a filter facet with a small FilterBar change. (inferred)
Contributor handoff
Read CLAUDE.md first — it documents the src/ source-of-truth rule and the sync contract. Edit data/scripts/templates only under src/ui-ux-pro-max/, then run `cd cli && npm run sync:assets && npm run check:assets`. Never edit cli/assets/ or .claude/skills/ui-ux-pro-max/{data,scripts} directly (mirrored), but DO edit .claude/skills/ui-ux-pro-max/SKILL.md by hand (it is not generated). The Python layer is stdlib-only — no pip installs. Gate everything through `npm --prefix cli run verify:data` which runs both validators, unittest discovery, the relevance evaluator, both smoke suites, and the asset-sync check.
- Canonical edit boundary: modify CSVs under src/ui-ux-pro-max/data/, Python under src/ui-ux-pro-max/scripts/, templates under src/ui-ux-pro-max/templates/ — then `npm run sync:assets`; the two mirror trees (cli/assets/, .claude/skills/ui-ux-pro-max/{data,scripts}) are regenerated, never hand-edited.
- Exception to the mirror rule: .claude/skills/ui-ux-pro-max/SKILL.md is hand-authored and NOT synced — edit it directly; sync-assets.mjs only mirrors its data/ and scripts/ subdirs.
- Verify loop for any data/script change: `npm --prefix cli run verify:data` = validate:csv + validate:semantic + validate:agent-guide + validate:catalog-summary + unittest discovery + evaluate:relevance + smoke:domains + smoke:stacks + check:assets.
- When changing CSV row counts or advertised numbers (styles, palettes, fonts, stacks), regenerate catalog-summary.json via scripts/generate-catalog-summary.py and expect validate-agent-guide.py to recompute the SKILL.md/template description string — stale counts fail CI.
- Git workflow: never push to main; branch feat/... or fix/..., PR via gh; commits use Conventional Commits because release.yml runs semantic-release (conventionalcommits preset) that versions and publishes the CLI automatically.
- Known trap — path contract: skill docs must use skill-relative script paths ('scripts/search.py', '../<skill>/scripts/...'); ~/.claude/skills/, .claude/skills/, $HOME/, and ${CLAUDE_PLUGIN_ROOT} forms are grep-rejected by CI except in the core SKILL.md.
- Known trap — Windows/cp1252: search.py and design_system.py rewrap stdout/stderr to UTF-8 at import because emoji/box-drawing output crashes on the Windows default encoding; preserve that block when editing.
- Known trap — line endings: catalog-summary.json pins sha256 hashes of LF-normalized data and .gitattributes forces eol=lf on data files; committing CRLF data or bypassing .gitattributes breaks the hash check on other platforms.
- Known trap — abstention is intentional: a 0-result search is a feature (calibrated thresholds + suggestions), so don't 'fix' empty results by lowering thresholds without updating the relevance baseline and thresholds fixture.
- Files to read first for search changes: core.py (engine + registries), design_system.py (aggregator + persistence), reasoning_contract.py (rule grammar), then test_core.py + test_data_contracts.py to see the locked invariants; for installer changes: template.ts, types/index.ts, detect.ts, one platform JSON.
- cli/assets/ is .gitignore-adjacent generated output bundled into the npm package ('files': ['dist','assets']); the dry-run e2e specs import TS directly from src/, so CLI tests run without building dist first.
- CLI dev workflow: `npm run dev` runs via bun, `npm run build` prefers `bun build --target node` and falls back to node_modules tsc; `npm run typecheck` is tsc --noEmit; Playwright e2e needs `npx playwright install --with-deps chromium`.
Languages
| Language | Files | Share of source |
|---|---|---|
| Markdown | 145 | docs/config |
| Python | 103 | 61% |
| JSON | 102 | docs/config |
| TypeScript | 43 | 25% |
| JavaScript | 21 | 12% |
| YAML | 9 | docs/config |
| HTML | 4 | docs/config |
| Shell | 3 | 2% |
Start reading here
Probable source entrypoint: src/ — inferred from the directory tree and manifest, not the upstream docs.
Source roots
src/ (92 files)
Repository structure
| Top-level path | Files |
|---|---|
cli/ | 222 |
.claude/ | 206 |
src/ | 92 |
gallery/ | 34 |
stack/ | 18 |
scripts/ | 10 |
.github/ | 9 |
docs/ | 5 |
Docs found: CLAUDE.mdCONTRIBUTING.mdREADME.mddocs/journals/260812-1844-search-data-quality-planning.mddocs/journals/260813-0816-phase-6-accessibility-refresh.mddocs/journals/260813-1622-phase-7-web-stack-freshness.mddocs/journals/260813-1800-search-data-overhaul-completion.mddocs/三个 data-scripts-templates 的区别.md
Package
cli/package.json — ui-ux-pro-max-cli v2.5.0, 9 declared dependencies.
@playwright/test@types/bun@types/node@types/promptschalkcommanderorapromptstypescript
CI & config entrypoints
README.md— Repository readmeCLAUDE.md— Claude instructionscli/playwright.config.ts— Playwright e2e config.github/workflows/release.yml— GitHub Actions workflow.github/workflows/smoke-stacks.yml— GitHub Actions workflow.github/workflows/refresh-catalogs.yml— GitHub Actions workflow.github/workflows/tests.yml— GitHub Actions workflow.github/workflows/check-asset-sync.yml— GitHub Actions workflow.github/workflows/bump-versions.yml— GitHub Actions workflowcli/package.json— npm scripts: build, check:assets, dev, evaluate:relevance, evaluate:relevance:calibration, evaluate:relevance:held-out, prepublishOnly, smoke:domains
Structural health signals
Average score 7.6/10 across 92 analyzed source files; 24 hotspots surfaced.
gallery/components/UIControlsShowcase.tsx— 610 lines, score 5.5 (Large file, Deep nesting).claude/skills/ui-ux-pro-max/scripts/design_system.py— 1093 lines, score 5.7 (Large file, Deep nesting)cli/assets/scripts/design_system.py— 1093 lines, score 5.7 (Large file, Deep nesting)
These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.
Recent history
dcc40ff5133e2026-09-21 — docs: explain Claude Code output token limit (#503)0d2b646cb6f42026-09-21 — feat(nuxt-ui): refresh guidance for v4.11 (#502)f1c725fd2fda2026-09-21 — feat(react): add React 19 guidelines to stack data (#344)de5f12b400772026-09-19 — fix: protect existing Tailwind and token configurations (#501)15de38fb70bc2026-09-15 — fix(design): make workflows self-contained, add bundled-skill contract (#498)