feat(21st): replace the magic MCP with the @21st-dev CLI + skill pack
Upstream supersedes `@21st-dev/magic` with `@21st-dev/cli` (bin `21st`): same endpoint, `21st login` in place of an API key, no MCP process loaded into every session. - install-plugins.sh Step 8.7: `npm i -g @21st-dev/cli` (pinned in plugins.lock.json), staged `21st skills install`, TTY-only login offer, pack disabled by default. update-all.sh 7.4 refreshes both. - The documented `21st install-skill` cannot be used: the installer refuses to follow a symlink on the target path and `~/.claude/skills` is one. The install runs under a throwaway HOME and the result moves into skills-external/21st-* (gitignored), symlinked on demand. - toggle-external.sh manages `21st` as a pack (names globbed from skills-external/21st-*, parked under plain names). `magic` is gone. - The 5 design skills join design/web/web-full/full and MANAGED_EXTERNALS; 21st-registry and 21st-design-sync stay parked. MANAGED_MCPS is now empty and profile.sh's dead magic branches are removed. - Design gate: GATE-BLOCK gains `21st` (required-manual, magic's old slot) and `21st-ui-build`; PATH repair extended to the npm global bin. - settings.json: the 4 mcp__magic__* ask entries go; the outward-facing 21st verbs land in autoMode.soft_deny, the tier that holds under auto mode (LRN-153). - Docs: README, CLAUDE.global.md, design-gate.md, profile SKILL.md, .env.example, .gitleaks.toml, link.sh. BDR-093, LRN-158. Tests: profile-set-managed 17/17, make test green except 2 pre-existing gitflow FAILs (gitleaks binary absent on this host), shellcheck clean.
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
# lib/tests/profile-set-managed.test.sh — `set` symmetry on managed
|
||||
# externals + MCPs, gstack on-demand, external from-source (BDR-079).
|
||||
# externals, gstack on-demand, external from-source (BDR-079). The MCP
|
||||
# assertions went with `magic` (2026-09-22): MANAGED_MCPS is empty now, the
|
||||
# 21st skills that replaced it are managed as externals, so the pack's
|
||||
# park/restore round-trip is what this covers on that side.
|
||||
# Hermetic: fixture repo via *_REPO_OVERRIDE + fake `claude` on PATH.
|
||||
set -u
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
@@ -10,13 +13,13 @@ check() { if [ "$2" = "$3" ]; then pass=$((pass+1)); else fail=$((fail+1));
|
||||
|
||||
FX="$(mktemp -d)"; trap 'rm -rf "$FX"' EXIT
|
||||
mkdir -p "$FX/skills" "$FX/skills-disabled" "$FX/lib/profiles" "$FX/bin" \
|
||||
"$FX/skills-external/emil-design-eng" "$FX/skills-external/other-ext"
|
||||
"$FX/skills-external/emil-design-eng" "$FX/skills-external/other-ext" \
|
||||
"$FX/skills-external/21st-ui-build"
|
||||
for g in gs-a gs-b gs-c; do
|
||||
mkdir -p "$FX/skills-external/gstack/$g"
|
||||
touch "$FX/skills-external/gstack/$g/SKILL.md"
|
||||
done
|
||||
cp "$ROOT/lib/profile.sh" "$ROOT/lib/toggle-external.sh" "$FX/lib/"
|
||||
printf 'MAGIC_API_KEY=test-secret-000\n' > "$FX/.env"
|
||||
|
||||
# Non-managed external, enabled from the start — must never be touched.
|
||||
ln -s "$FX/skills-external/other-ext" "$FX/skills/other-ext"
|
||||
@@ -25,22 +28,18 @@ cat > "$FX/lib/profiles/designish.profile" <<'EOF'
|
||||
gs-a
|
||||
gs-b
|
||||
emil-design-eng external
|
||||
magic mcp
|
||||
21st-ui-build external
|
||||
EOF
|
||||
cat > "$FX/lib/profiles/backendish.profile" <<'EOF'
|
||||
gs-c
|
||||
EOF
|
||||
|
||||
# Fake claude: logs every call; keeps MCP registry state in a flat file.
|
||||
# Fake claude: logs every call. No MCP state to keep — MANAGED_MCPS is empty,
|
||||
# so `set` must never reach for `claude mcp` at all (asserted below).
|
||||
cat > "$FX/bin/claude" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
FX="$FX"
|
||||
echo "\$*" >> "\$FX/claude-calls.log"
|
||||
case "\$1 \${2:-}" in
|
||||
"mcp list") cat "\$FX/mcp-state" 2>/dev/null ;;
|
||||
"mcp add") echo "magic: stub" > "\$FX/mcp-state" ;;
|
||||
"mcp remove") : > "\$FX/mcp-state" ;;
|
||||
esac
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$FX/bin/claude"
|
||||
@@ -48,14 +47,14 @@ chmod +x "$FX/bin/claude"
|
||||
run() { PATH="$FX/bin:$PATH" PROFILE_REPO_OVERRIDE="$FX" \
|
||||
TOGGLE_EXTERNAL_REPO_OVERRIDE="$FX" bash "$FX/lib/profile.sh" "$@"; }
|
||||
|
||||
# --- set designish: gstack on-demand + external from-source + magic on ---
|
||||
# --- set designish: gstack on-demand + externals from-source (21st + emil) ---
|
||||
run set designish >/dev/null 2>&1
|
||||
check T1-gsa-on "$([ -e "$FX/skills/gs-a" ] && echo on || echo off)" on
|
||||
check T2-gsb-on "$([ -e "$FX/skills/gs-b" ] && echo on || echo off)" on
|
||||
check T3-gsc-off "$([ -e "$FX/skills/gs-c" ] && echo on || echo off)" off
|
||||
check T4-emil-src "$([ -L "$FX/skills/emil-design-eng" ] && echo on || echo off)" on
|
||||
check T5-magic-on "$(grep -c '^magic:' "$FX/mcp-state" 2>/dev/null)" 1
|
||||
check T6-add-call "$(grep -c '^mcp add magic' "$FX/claude-calls.log")" 1
|
||||
check T5-21st-src "$([ -L "$FX/skills/21st-ui-build" ] && echo on || echo off)" on
|
||||
check T6-no-mcp "$(grep -c '^mcp ' "$FX/claude-calls.log" || true)" 0
|
||||
|
||||
# --- set backendish: managed leftovers parked/unregistered ---
|
||||
run set backendish >/dev/null 2>&1
|
||||
@@ -63,14 +62,15 @@ check T7-gsc-on "$([ -e "$FX/skills/gs-c" ] && echo on || echo off)" on
|
||||
check T8-gsa-park "$([ -e "$FX/skills-disabled/gstack__gs-a" ] && echo p || echo n)" p
|
||||
check T9-emil-off "$([ -e "$FX/skills/emil-design-eng" ] && echo on || echo off)" off
|
||||
check T10-emil-park "$([ -e "$FX/skills-disabled/emil-design-eng" ] && echo p || echo n)" p
|
||||
check T11-magic-off "$(grep -c '^magic:' "$FX/mcp-state" 2>/dev/null || true)" 0
|
||||
check T12-rm-call "$(grep -c '^mcp remove magic' "$FX/claude-calls.log")" 1
|
||||
check T11-21st-off "$([ -e "$FX/skills/21st-ui-build" ] && echo on || echo off)" off
|
||||
check T12-21st-park "$([ -e "$FX/skills-disabled/21st-ui-build" ] && echo p || echo n)" p
|
||||
check T13-other-untouched "$([ -e "$FX/skills/other-ext" ] && echo on || echo off)" on
|
||||
|
||||
# --- back to designish: parked external restored (not re-sourced) ---
|
||||
run set designish >/dev/null 2>&1
|
||||
check T14-emil-back "$([ -e "$FX/skills/emil-design-eng" ] && echo on || echo off)" on
|
||||
check T15-park-gone "$([ -e "$FX/skills-disabled/emil-design-eng" ] && echo p || echo n)" n
|
||||
check T16-magic-back "$(grep -c '^magic:' "$FX/mcp-state" 2>/dev/null)" 1
|
||||
check T16-21st-back "$([ -e "$FX/skills/21st-ui-build" ] && echo on || echo off)" on
|
||||
check T17-no-mcp-ever "$(grep -c '^mcp ' "$FX/claude-calls.log" || true)" 0
|
||||
|
||||
printf 'PASS=%s FAIL=%s\n' "$pass" "$fail"; [ "$fail" -eq 0 ]
|
||||
|
||||
Reference in New Issue
Block a user