chore: import upstream snapshot with attribution
Check asset sync / cli/assets must match src/ui-ux-pro-max (push) Failing after 4s
Release / Semantic release (push) Has been skipped
Smoke test data / smoke (push) Failing after 0s

This commit is contained in:
wehub-resource-sync
2026-07-13 11:58:17 +08:00
commit a6e8bcde90
483 changed files with 67346 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Smoke test every registered non-stack search domain.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SCRIPTS_DIR="$REPO_ROOT/src/ui-ux-pro-max/scripts"
SEARCH="$SCRIPTS_DIR/search.py"
QUERY="${1:-dashboard performance button typography chart icon animation}"
EXPECTED_COUNT="${EXPECTED_DOMAIN_COUNT:-12}"
if [ ! -f "$SEARCH" ]; then
echo "FAIL: search.py not found at $SEARCH" >&2
exit 2
fi
DOMAINS=()
while IFS= read -r line; do
line="${line%$'\r'}"
[ -n "$line" ] && DOMAINS+=("$line")
done < <(PYTHONPATH="$SCRIPTS_DIR" python3 -c "
from core import CSV_CONFIG
for domain in CSV_CONFIG:
print(domain)
")
if [ "${#DOMAINS[@]}" -ne "$EXPECTED_COUNT" ]; then
echo "FAIL: CSV_CONFIG has ${#DOMAINS[@]} domains, expected $EXPECTED_COUNT" >&2
echo " Set EXPECTED_DOMAIN_COUNT after an intentional registry change." >&2
exit 2
fi
echo "Smoke-testing ${#DOMAINS[@]} domains with query '$QUERY':"
fail=0
for domain in "${DOMAINS[@]}"; do
payload=$(python3 "$SEARCH" "$QUERY" --domain "$domain" -n 1 --json 2>/dev/null || true)
count=$(printf '%s' "$payload" | python3 -c "import json,sys; data=json.load(sys.stdin); print(data.get('count',0) if not data.get('error') else 0)" 2>/dev/null || echo 0)
if [ "${count:-0}" -gt 0 ]; then
printf ' PASS %-14s %d\n' "$domain" "$count"
else
printf ' FAIL %-14s 0\n' "$domain"
fail=$((fail + 1))
fi
done
total=${#DOMAINS[@]}
echo
if [ "$fail" -gt 0 ]; then
echo "FAIL: $fail/$total domains returned 0 results for '$QUERY'" >&2
exit 1
fi
echo "OK: $total/$total domains returned ≥1 result"
+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/env bash
# Smoke test: every stack registered in STACK_CONFIG must return at least one
# search result for a neutral query. Catches registry/CSV regressions early
# (e.g. a stack added to STACK_CONFIG but missing its CSV, or a CSV emptied
# by a botched merge).
#
# Usage: scripts/smoke-stacks.sh [query]
# Env: EXPECTED_STACK_COUNT — default 22. Bump deliberately when adding
# or removing a stack so accidental drift still fails loudly.
#
# Exit codes:
# 0 — all stacks returned ≥1 result
# 1 — at least one stack returned 0 results
# 2 — environment problem (search.py missing, registry size mismatch)
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
SCRIPTS_DIR="$REPO_ROOT/src/ui-ux-pro-max/scripts"
SEARCH="$SCRIPTS_DIR/search.py"
QUERY="${1:-performance}"
EXPECTED_COUNT="${EXPECTED_STACK_COUNT:-22}"
if [ ! -f "$SEARCH" ]; then
echo "FAIL: search.py not found at $SEARCH" >&2
exit 2
fi
# Single source of truth: pull stacks from STACK_CONFIG so this script never
# goes stale relative to the registry.
STACKS=()
while IFS= read -r line; do
line="${line%$'\r'}" # strip CR on Windows where python's print emits CRLF
[ -n "$line" ] && STACKS+=("$line")
done < <(PYTHONPATH="$SCRIPTS_DIR" python3 -c "
from core import AVAILABLE_STACKS
for s in AVAILABLE_STACKS:
print(s)
")
if [ "${#STACKS[@]}" -ne "$EXPECTED_COUNT" ]; then
echo "FAIL: STACK_CONFIG has ${#STACKS[@]} stacks, expected $EXPECTED_COUNT" >&2
echo " Set EXPECTED_STACK_COUNT to override after an intentional change." >&2
exit 2
fi
echo "Smoke-testing ${#STACKS[@]} stacks with query '$QUERY':"
fail=0
for s in "${STACKS[@]}"; do
count=$(python3 "$SEARCH" "$QUERY" --stack "$s" -n 1 --json 2>/dev/null \
| python3 -c "import json,sys; print(json.load(sys.stdin).get('count',0))")
if [ "${count:-0}" -gt 0 ]; then
printf ' PASS %-18s %d\n' "$s" "$count"
else
printf ' FAIL %-18s 0\n' "$s"
fail=$((fail + 1))
fi
done
total=${#STACKS[@]}
echo
if [ "$fail" -gt 0 ]; then
echo "FAIL: $fail/$total stacks returned 0 results for '$QUERY'" >&2
exit 1
fi
echo "OK: $total/$total stacks returned ≥1 result"
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env node
import { readFileSync, writeFileSync } from 'node:fs';
import { resolve } from 'node:path';
const version = process.argv[2];
if (!version) {
console.error('Usage: node scripts/sync-release-version.mjs <version>');
process.exit(1);
}
function readJson(path) {
return JSON.parse(readFileSync(resolve(path), 'utf8'));
}
function replaceJsonVersion(path, updater) {
const fullPath = resolve(path);
const original = readFileSync(fullPath, 'utf8');
const data = JSON.parse(original);
updater(data);
let next = original;
const replacements = [];
function setTopLevelVersion(value) {
replacements.push([/(\"version\"\s*:\s*)\"[^\"]+\"/, `$1\"${value}\"`]);
}
function setMetadataVersion(value) {
replacements.push([/(\"metadata\"\s*:\s*\{[\s\S]*?\"version\"\s*:\s*)\"[^\"]+\"/, `$1\"${value}\"`]);
}
function setPluginVersions(value) {
replacements.push([/(\"plugins\"\s*:\s*\[[\s\S]*?\"version\"\s*:\s*)\"[^\"]+\"/, `$1\"${value}\"`]);
}
if (path === '.claude-plugin/marketplace.json') {
setMetadataVersion(data.metadata?.version);
if (data.plugins?.[0]?.version) setPluginVersions(data.plugins[0].version);
} else {
setTopLevelVersion(data.version);
if (data.packages?.['']?.version) {
replacements.push([/(\"packages\"\s*:\s*\{\s*\"\"\s*:\s*\{[\s\S]*?\"version\"\s*:\s*)\"[^\"]+\"/, `$1\"${data.packages[''].version}\"`]);
}
}
for (const [pattern, replacement] of replacements) next = next.replace(pattern, replacement);
writeFileSync(fullPath, next);
}
replaceJsonVersion('skill.json', (data) => {
data.version = version;
});
replaceJsonVersion('.claude-plugin/plugin.json', (data) => {
data.version = version;
});
replaceJsonVersion('.claude-plugin/marketplace.json', (data) => {
if (data.metadata) data.metadata.version = version;
if (Array.isArray(data.plugins)) {
for (const item of data.plugins) item.version = version;
}
});
replaceJsonVersion('cli/package.json', (data) => {
data.version = version;
});
try {
replaceJsonVersion('cli/package-lock.json', (data) => {
data.version = version;
if (data.packages?.['']) data.packages[''].version = version;
});
} catch (err) {
if (err.code !== 'ENOENT') throw err;
}
console.log(`Synced release version ${version} across skill, plugin, marketplace, and CLI manifests.`);
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""Validate UI/UX Pro Max CSV data files.
Checks every CSV under src/ui-ux-pro-max/data for structural issues that
csv.DictReader otherwise accepts silently:
- duplicate or blank header names
- rows with too many fields (unquoted commas)
- rows with too few fields (missing trailing columns)
- unexpected empty rows inside the dataset
"""
from __future__ import annotations
import csv
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
DATA_DIR = REPO_ROOT / "src" / "ui-ux-pro-max" / "data"
# Every CSV under data/ is a runtime dataset loaded by core.py.
# (Former reference-only notes design.csv/draft.csv were removed: they were
# unused by the runtime and contained prompt-shaped free-form text.)
REFERENCE_ONLY: set[Path] = set()
def validate_file(path: Path) -> list[str]:
errors: list[str] = []
rel = path.relative_to(REPO_ROOT)
with path.open("r", encoding="utf-8", newline="") as fh:
reader = csv.reader(fh)
try:
header = next(reader)
except StopIteration:
errors.append(f"{rel}: empty file")
return errors
if not header or all(not col.strip() for col in header):
errors.append(f"{rel}: missing header")
return errors
blank_headers = [idx + 1 for idx, col in enumerate(header) if not col.strip()]
if blank_headers:
errors.append(f"{rel}: blank header columns {blank_headers}")
duplicates = sorted({col for col in header if col and header.count(col) > 1})
if duplicates:
errors.append(f"{rel}: duplicate headers {duplicates}")
expected = len(header)
for line_no, row in enumerate(reader, start=2):
if not row or all(not cell.strip() for cell in row):
errors.append(f"{rel}:{line_no}: blank row")
continue
actual = len(row)
if actual != expected:
errors.append(
f"{rel}:{line_no}: expected {expected} fields, got {actual}"
)
return errors
def main() -> int:
if not DATA_DIR.exists():
print(f"CSV data directory not found: {DATA_DIR}", file=sys.stderr)
return 2
errors: list[str] = []
checked = 0
for path in sorted(DATA_DIR.rglob("*.csv")):
if path in REFERENCE_ONLY:
continue
checked += 1
errors.extend(validate_file(path))
if errors:
print("CSV validation failed:", file=sys.stderr)
for error in errors:
print(f" - {error}", file=sys.stderr)
print(f"\nChecked {checked} runtime CSV files.", file=sys.stderr)
return 1
print(f"CSV validation passed: {checked} runtime CSV files checked.")
return 0
if __name__ == "__main__":
raise SystemExit(main())