start-vibing 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/package.json +1 -1
  2. package/template/.claude/CLAUDE.md +86 -20
  3. package/template/.claude/agents/sd-audit.md +197 -0
  4. package/template/.claude/agents/sd-fix-verify-semantic.md +112 -0
  5. package/template/.claude/agents/sd-fix-verify-technical.md +36 -0
  6. package/template/.claude/agents/sd-fix.md +194 -0
  7. package/template/.claude/agents/sd-research.md +61 -0
  8. package/template/.claude/agents/sd-synthesis.md +74 -0
  9. package/template/.claude/commands/super-design.md +15 -0
  10. package/template/.claude/hooks/super-design-session-start.sh +4 -0
  11. package/template/.claude/settings.json +14 -0
  12. package/template/.claude/skills/codebase-knowledge/SKILL.md +145 -0
  13. package/template/.claude/skills/codebase-knowledge/TEMPLATE.md +35 -0
  14. package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +93 -0
  15. package/template/.claude/skills/composition-patterns/SKILL.md +89 -0
  16. package/template/.claude/skills/docs-tracker/SKILL.md +239 -0
  17. package/template/.claude/skills/mcp-builder/SKILL.md +236 -0
  18. package/template/.claude/skills/quality-gate/scripts/check-all.sh +83 -0
  19. package/template/.claude/skills/react-best-practices/SKILL.md +146 -0
  20. package/template/.claude/skills/security-scan/reference/owasp-top-10.md +257 -0
  21. package/template/.claude/skills/security-scan/scripts/scan.py +190 -0
  22. package/template/.claude/skills/super-design/README.md +37 -0
  23. package/template/.claude/skills/super-design/SKILL.md +105 -0
  24. package/template/.claude/skills/super-design/hooks/guard-paths.py +35 -0
  25. package/template/.claude/skills/super-design/hooks/post-edit-lint.py +57 -0
  26. package/template/.claude/skills/super-design/references/audit-methodology.md +513 -0
  27. package/template/.claude/skills/super-design/references/change-detection-playbook.md +1432 -0
  28. package/template/.claude/skills/super-design/references/design-theory.md +706 -0
  29. package/template/.claude/skills/super-design/references/fix-agent-playbook.md +118 -0
  30. package/template/.claude/skills/super-design/references/market-research-playbook.md +773 -0
  31. package/template/.claude/skills/super-design/references/playwright-mcp-reference.md +1057 -0
  32. package/template/.claude/skills/super-design/references/skills-subagents-reference.md +784 -0
  33. package/template/.claude/skills/super-design/references/superpowers-and-distribution.md +136 -0
  34. package/template/.claude/skills/super-design/scripts/detect-changes.sh +61 -0
  35. package/template/.claude/skills/super-design/scripts/diff-tokens.sh +13 -0
  36. package/template/.claude/skills/super-design/scripts/discover-routes.sh +45 -0
  37. package/template/.claude/skills/super-design/scripts/extract-tokens.mjs +41 -0
  38. package/template/.claude/skills/super-design/scripts/hash-pages.sh +42 -0
  39. package/template/.claude/skills/super-design/scripts/validate-state.sh +15 -0
  40. package/template/.claude/skills/super-design/scripts/verify-audit.sh +19 -0
  41. package/template/.claude/skills/super-design/templates/audit-state.schema.json +57 -0
  42. package/template/.claude/skills/super-design/templates/findings.schema.json +57 -0
  43. package/template/.claude/skills/super-design/templates/fix-history.md.tpl +26 -0
  44. package/template/.claude/skills/super-design/templates/overview.md.tpl +52 -0
  45. package/template/.claude/skills/test-coverage/reference/playwright-patterns.md +260 -0
  46. package/template/.claude/skills/test-coverage/scripts/coverage-check.sh +52 -0
  47. package/template/.claude/skills/typeui-ant/SKILL.md +133 -0
  48. package/template/.claude/skills/typeui-application/SKILL.md +128 -0
  49. package/template/.claude/skills/typeui-artistic/SKILL.md +133 -0
  50. package/template/.claude/skills/typeui-bento/SKILL.md +127 -0
  51. package/template/.claude/skills/typeui-bold/SKILL.md +127 -0
  52. package/template/.claude/skills/typeui-clean/SKILL.md +128 -0
  53. package/template/.claude/skills/typeui-dashboard/SKILL.md +133 -0
  54. package/template/.claude/skills/typeui-doodle/SKILL.md +142 -0
  55. package/template/.claude/skills/typeui-dramatic/SKILL.md +127 -0
  56. package/template/.claude/skills/typeui-enterprise/SKILL.md +132 -0
  57. package/template/.claude/skills/typeui-neobrutalism/SKILL.md +127 -0
  58. package/template/.claude/skills/typeui-paper/SKILL.md +127 -0
  59. package/template/.claude/skills/ui-ux-audit/QUICK-START.md +450 -0
  60. package/template/.claude/skills/ui-ux-audit/README.md +470 -0
  61. package/template/.claude/skills/ui-ux-audit/templates/audit-report.md +591 -0
  62. package/template/.claude/skills/ui-ux-audit/templates/competitor-analysis.md +363 -0
  63. package/template/.claude/skills/ui-ux-audit/templates/component-spec.md +491 -0
  64. package/template/.claude/skills/ui-ux-audit/templates/improvement-recommendation.md +450 -0
  65. package/template/.claude/skills/web-design-guidelines/SKILL.md +39 -0
  66. package/template/.claude/skills/webapp-testing/SKILL.md +96 -0
  67. package/template/.claude/skills/workflow-state/workflow-state.json +77 -0
@@ -0,0 +1,136 @@
1
+ # Superpowers framework + private distribution reference — PLACEHOLDER
2
+
3
+ > **This file is a placeholder.** The complete content was delivered as the
4
+ > "Superpowers and Private Claude Skill Distribution: 2026 Playbook" artifact
5
+ > in the conversation history. Paste it here (~25KB).
6
+
7
+ ## What the content covers
8
+
9
+ ### Part 1 — Jesse Vincent's Superpowers framework
10
+ - What Superpowers actually is (Claude Code plugin, ~14 skills + session-start hook)
11
+ - Distribution via github.com/obra/superpowers + Anthropic marketplace
12
+ - Four stated principles: TDD, systematic over ad-hoc, complexity reduction,
13
+ evidence over claims
14
+ - The pipeline: brainstorming → writing-plans → subagent-driven-development →
15
+ two-stage review → verification-before-completion → finishing-a-development-branch
16
+ - Jesse Vincent's background (Request Tracker, Perl pumpking, K-9 Mail,
17
+ Keyboardio, VaccinateCA, Prime Radiant)
18
+ - Release cadence: v5.0.7 (Mar 31, 2026), last commit Apr 16, 2026
19
+ - Install: `/plugin install superpowers@claude-plugins-official`
20
+ - 355,657 installs shown on claude.com/plugins/superpowers
21
+ - Cross-platform: Cursor, Codex, OpenCode, Gemini CLI, GitHub Copilot CLI
22
+ - Reception: Simon Willison endorsement, benchmark skepticism, 94% PR rejection rate
23
+ - Relationship to Anthropic Agent Skills (complementary, not competing)
24
+
25
+ ### Part 2 — Publishing Claude skills privately in 2026
26
+
27
+ #### Anthropic's official distribution layer
28
+ - Skills Directory (Dec 18, 2025) at claude.com/connectors
29
+ - Only partner-gated, no open submission
30
+ - Claude Code plugin marketplace anthropics/claude-plugins-official
31
+ - Reserved marketplace names list
32
+ - Mahesh Murag (PM) quote: "no revenue-sharing arrangements at this time"
33
+ - 3,000+ community upvotes requesting monetization, zero response from Anthropic
34
+ - Claude Marketplace at claude.com/platform/marketplace is procurement, NOT a skill store
35
+
36
+ #### Private marketplace mechanism (code.claude.com/docs/en/plugin-marketplaces)
37
+ Six channels that work today:
38
+ 1. Private GitHub repo (GITHUB_TOKEN env)
39
+ 2. Private GitLab/Bitbucket/self-hosted git (SSH key pre-loaded)
40
+ 3. Self-hosted HTTP JSON (LiteLLM Enterprise reference)
41
+ 4. Private npm registry (.npmrc auth)
42
+ 5. Container seed (CLAUDE_CODE_PLUGIN_SEED_DIR env)
43
+ 6. Managed settings allowlist (strictKnownMarketplaces)
44
+
45
+ Example marketplace.json:
46
+ ```json
47
+ {
48
+ "name": "super-design-private",
49
+ "owner": { "name": "Your Agency", "email": "dev@agency.com" },
50
+ "plugins": [
51
+ { "source": "github", "repo": "your-org/super-design-skill", "ref": "v1.0.0" }
52
+ ]
53
+ }
54
+ ```
55
+
56
+ Install flow:
57
+ ```
58
+ /plugin marketplace add your-org/super-design-marketplace
59
+ /plugin install super-design@super-design-marketplace
60
+ ```
61
+
62
+ #### Team/Enterprise org-wide skill sharing (Dec 18, 2025)
63
+ - Admin-provisioned org-wide (default-on)
64
+ - Peer-to-peer sharing (off by default)
65
+ - Peer-to-org sharing (off by default)
66
+ - Skills don't sync across surfaces (Claude.ai / API / Claude Code separate)
67
+ - Collision order: enterprise > personal > project > plugin
68
+
69
+ #### Monetization platform comparison
70
+
71
+ | Platform | Fee | Strengths | Weaknesses |
72
+ |---|---|---|---|
73
+ | **Polar.sh** | 4% + $0.40 | MoR; license keys + GitHub benefits auto; best for super-design | Newer platform |
74
+ | **Lemon Squeezy** | 5% + $0.50 | Strong license API | Higher fees; onboarding rejections |
75
+ | **Gumroad** | 10% + $0.50 | Dominant for existing paid skills | 10% painful at scale |
76
+ | **Stripe** | 2.9% + $0.30 | Lowest fees | NOT merchant-of-record; build your own license server |
77
+ | **Paddle** | varies | MoR | Avoid post-2025 FTC settlement friction |
78
+ | **GitHub Sponsors** | 0% | Auto-invite sponsors to private repo | Monthly tiers only, not one-time |
79
+
80
+ #### License-key mechanics in Claude Code
81
+ - Phone-home validation (24h cached)
82
+ - Ed25519-signed offline files (~50 lines using cryptography.hazmat)
83
+ - Encrypted assets (AES-256-GCM)
84
+ - Watermarking via invisible unicode
85
+ - Telemetry keyed on sha256(license_key)
86
+
87
+ #### Existing paid Claude skills (all Gumroad, zero enforcement)
88
+ - Brian Wagner: $9-$49 bundles
89
+ - Aakash Gupta Job Search OS: $49 one-time / $250/year
90
+ - Usama Akram: 300+ skill bundle
91
+ - RAXXO Studios: €5 single, 8-skill bundle
92
+ - Alex McFarland: Plugin Marketplace Builder (Substack)
93
+ - Sahil Lavingia (Gumroad founder): free as visibility play
94
+
95
+ Price anchors: $9-$19 single, $29-$49 bundles, $49-$99 15+ skill systems, $250+/year subscription.
96
+
97
+ #### Legal: license choices for paid distribution
98
+ - **Elastic License 2.0 (RECOMMENDED for super-design)**: 3 short restrictions —
99
+ no hosted reselling, no circumventing license-key, no removing copyright
100
+ - **PolyForm Shield 1.0.0**: source-available on GitHub, no competitor use
101
+ - **PolyForm Internal Use 1.0.0**: read-only eval version
102
+ - **Custom proprietary EULA**: per-organization seat license, no ML training clause
103
+
104
+ Trademark: CLAUDE registered USPTO, use nominative fair-use, include
105
+ "not affiliated with Anthropic" disclaimer.
106
+
107
+ #### Recommended stack for super-design
108
+ Phase 1 (internal-only): private GitHub repo + PolyForm Internal Use +
109
+ `/plugin marketplace add` with GITHUB_TOKEN.
110
+
111
+ Phase 2 (selling to agencies): Polar.sh as merchant-of-record. Product with:
112
+ - License Keys benefit (3-activation limit)
113
+ - GitHub Repository benefit pointing at private repo
114
+ - Optional file-download of super-design.skill ZIP
115
+
116
+ Pricing: $149 one-time per seat OR $29/month.
117
+
118
+ scripts/verify_license.py: 24-hour cached Polar validation pattern (~40 lines Python).
119
+
120
+ Files: LICENSE (Elastic 2.0 verbatim), EULA.md (plain-English addendum),
121
+ README.md with buy → GitHub invite → export SUPER_DESIGN_LICENSE_KEY → use.
122
+
123
+ Telemetry abuse detection via sha256(license_key) pings.
124
+
125
+ #### Deeper moat (if super-design becomes real business)
126
+ Hosted execution: Stripe-billed service running audits on your infrastructure.
127
+ Heuristics and prompts never touch customer's machine. Tabnine/Wallaby
128
+ precedent. Agent37.com positioning as "Gumroad for Claude skills" with
129
+ hosted-runtime + Stripe billing is worth evaluating.
130
+
131
+ ## Where super-design uses this
132
+
133
+ - **LICENSE** (Elastic 2.0 verbatim) — see top-level file
134
+ - **EULA.md** (per-organization seat license) — see top-level file
135
+ - **README.md** install instructions use the private-marketplace pattern
136
+ - **Future scripts/verify_license.py** would follow Polar.sh 24h-cache pattern
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: detect-changes.sh <last_sha> [<last_iso>]
3
+ # Emits JSON: { mode, range_start, commits, files, classified }
4
+ set -euo pipefail
5
+
6
+ LAST_SHA="${1:-}"
7
+ LAST_ISO="${2:-}"
8
+
9
+ if [[ -z "$LAST_SHA" ]]; then echo '{"error":"missing last_sha"}'; exit 2; fi
10
+ if ! git rev-parse --git-dir >/dev/null 2>&1; then echo '{"error":"not-a-git-repo"}'; exit 3; fi
11
+
12
+ if git rev-parse --verify --quiet "${LAST_SHA}^{commit}" >/dev/null; then
13
+ if git merge-base --is-ancestor "$LAST_SHA" HEAD; then RANGE_START="$LAST_SHA"
14
+ else RANGE_START="$(git merge-base HEAD "$LAST_SHA" 2>/dev/null || echo "")"; fi
15
+ else RANGE_START=""; fi
16
+
17
+ if [[ -z "$RANGE_START" ]]; then
18
+ if [[ -n "$LAST_ISO" ]]; then
19
+ FILES="$(git log --since="$LAST_ISO" --name-only --pretty=format: 2>/dev/null | sort -u | sed '/^$/d' || true)"
20
+ COMMITS="$(git log --since="$LAST_ISO" --pretty=format:'%H|%s|%an|%aI' 2>/dev/null || true)"
21
+ MODE="since-time"
22
+ else echo '{"error":"lost-anchor-no-fallback-time"}'; exit 4; fi
23
+ else
24
+ FILES="$(git diff --name-only "${RANGE_START}..HEAD" \
25
+ -- ':!*.lock' ':!package-lock.json' ':!pnpm-lock.yaml' ':!yarn.lock' \
26
+ ':!.github/**' ':!**/*.test.*' ':!**/*.spec.*' ':!**/*.stories.*' | sort -u)"
27
+ COMMITS="$(git log --no-merges --pretty=format:'%H|%s|%an|%aI' "${RANGE_START}..HEAD" 2>/dev/null || true)"
28
+ MODE="sha-range"
29
+ fi
30
+
31
+ declare -A CLASSIFIED
32
+ while IFS= read -r p; do
33
+ [[ -z "$p" ]] && continue
34
+ case "$p" in
35
+ tailwind.config.*|*.tokens.json|styles/tokens.css|styles/theme.css) CLASSIFIED[tokens]+="$p,";;
36
+ components/*|src/components/*|app/_components/*) CLASSIFIED[components]+="$p,";;
37
+ app/*/page.*|app/page.*|app/*/route.*|app/route.*|pages/*|src/pages/*|app/routes/*|src/routes/*) CLASSIFIED[routes]+="$p,";;
38
+ public/*|src/assets/*|assets/*) CLASSIFIED[imagery]+="$p,";;
39
+ package.json) CLASSIFIED[deps]+="$p,";;
40
+ references/design-theory.md|references/market-analysis.md) CLASSIFIED[theory]+="$p,";;
41
+ *.md|*.mdx) CLASSIFIED[content]+="$p,";;
42
+ *) CLASSIFIED[other]+="$p,";;
43
+ esac
44
+ done <<< "$FILES"
45
+
46
+ jq -Rn --arg mode "$MODE" --arg range_start "$RANGE_START" --arg last_iso "$LAST_ISO" \
47
+ --arg tokens "${CLASSIFIED[tokens]:-}" --arg components "${CLASSIFIED[components]:-}" \
48
+ --arg routes "${CLASSIFIED[routes]:-}" --arg imagery "${CLASSIFIED[imagery]:-}" \
49
+ --arg deps "${CLASSIFIED[deps]:-}" --arg theory "${CLASSIFIED[theory]:-}" \
50
+ --arg content "${CLASSIFIED[content]:-}" \
51
+ --argjson files "$(printf '%s\n' "$FILES" | jq -R . | jq -s .)" \
52
+ --argjson commits "$(printf '%s\n' "$COMMITS" | jq -R . | jq -s .)" '
53
+ def tolist(s): s | split(",") | map(select(length>0));
54
+ {mode:$mode, range_start:$range_start, since_iso:$last_iso,
55
+ commits:$commits, files:$files,
56
+ classified: {
57
+ tokens: tolist($tokens), components: tolist($components),
58
+ routes: tolist($routes), imagery: tolist($imagery),
59
+ deps: tolist($deps), theory: tolist($theory), content: tolist($content)
60
+ }
61
+ }'
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ PREV="${1:?usage: diff-tokens.sh <prev> <curr>}"
4
+ CURR="${2:?usage: diff-tokens.sh <prev> <curr>}"
5
+ jq -n --slurpfile a "$PREV" --slurpfile b "$CURR" '
6
+ ($a[0] // {}) as $before | ($b[0] // {}) as $after |
7
+ {
8
+ added: [$after | to_entries[] | select(.key as $k | ($before | has($k)) | not) | .key],
9
+ removed: [$before | to_entries[] | select(.key as $k | ($after | has($k)) | not) | .key],
10
+ modified: [$after | to_entries[] |
11
+ select(.key as $k | ($before | has($k)) and (.value != $before[$k])) |
12
+ { key: .key, before: $before[.key], after: .value }]
13
+ }'
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ detect_framework() {
5
+ if [[ -f next.config.js || -f next.config.ts || -f next.config.mjs ]]; then echo "next"
6
+ elif [[ -f remix.config.js || -d app/routes ]]; then echo "remix"
7
+ elif [[ -f svelte.config.js && -d src/routes ]]; then echo "sveltekit"
8
+ elif [[ -f astro.config.mjs || -f astro.config.ts ]]; then echo "astro"
9
+ elif [[ -f nuxt.config.ts || -f nuxt.config.js ]]; then echo "nuxt"
10
+ elif [[ -f app.config.ts && -d src/routes ]]; then echo "solid-start"
11
+ elif [[ -f gatsby-config.js || -f gatsby-config.ts ]]; then echo "gatsby"
12
+ elif [[ -f angular.json ]]; then echo "angular"
13
+ else echo "unknown"; fi
14
+ }
15
+
16
+ FW="$(detect_framework)"
17
+ case "$FW" in
18
+ next)
19
+ APP="$(find app src/app -type f \( -name 'page.tsx' -o -name 'page.ts' -o -name 'page.jsx' -o -name 'page.js' -o -name 'page.md' -o -name 'page.mdx' -o -name 'route.ts' -o -name 'route.js' \) 2>/dev/null \
20
+ | sed -E 's|(^|/)(app|src/app)/||; s|/page\.[a-z]+$||; s|/route\.[a-z]+$||; s|^$|/|' \
21
+ | sed -E 's|\([^)]+\)/||g; /(^|\/)_/d' | sort -u || true)"
22
+ PG="$(find pages src/pages -type f \( -name '*.tsx' -o -name '*.ts' -o -name '*.jsx' -o -name '*.js' -o -name '*.md' -o -name '*.mdx' \) 2>/dev/null \
23
+ | grep -vE '(^|/)(pages|src/pages)/(_app|_document|_error|404|500|api/)' \
24
+ | sed -E 's|(^|/)(pages|src/pages)/||; s|\.(tsx|ts|jsx|js|md|mdx)$||; s|index$||' | sort -u || true)"
25
+ printf '%s\n%s\n' "$APP" "$PG" | awk 'NF' | sed -E 's|^|/|; s|//|/|g' | sort -u | jq -Rn '[inputs]';;
26
+ sveltekit)
27
+ find src/routes -type f -name '+page.svelte' 2>/dev/null \
28
+ | sed -E 's|^src/routes||; s|/\+page\.svelte$||; s|\([^)]+\)/||g' \
29
+ | awk 'NF==0 {print "/"; next} {print}' | sort -u | jq -Rn '[inputs]';;
30
+ astro)
31
+ find src/pages -type f \( -name '*.astro' -o -name '*.md' -o -name '*.mdx' \) 2>/dev/null \
32
+ | sed -E 's|^src/pages||; s|\.(astro|md|mdx)$||; s|/index$||' | sort -u | jq -Rn '[inputs]';;
33
+ nuxt)
34
+ find pages app/pages -type f -name '*.vue' 2>/dev/null \
35
+ | sed -E 's|^(app/)?pages||; s|\.vue$||; s|/index$||' | sort -u | jq -Rn '[inputs]';;
36
+ remix)
37
+ find app/routes -type f \( -name '*.tsx' -o -name '*.ts' -o -name '*.jsx' -o -name '*.js' -o -name '*.md' -o -name '*.mdx' \) 2>/dev/null \
38
+ | sed -E 's|^app/routes/||; s|\.(tsx|ts|jsx|js|md|mdx)$||; s|\.|/|g; s|_index$||; s|^|/|' \
39
+ | sort -u | jq -Rn '[inputs]';;
40
+ solid-start)
41
+ find src/routes -type f \( -name '*.tsx' -o -name '*.ts' -o -name '*.jsx' -o -name '*.js' \) 2>/dev/null \
42
+ | sed -E 's|^src/routes||; s|\.(tsx|ts|jsx|js)$||; s|/index$||; s|\([^)]+\)/||g' \
43
+ | sort -u | jq -Rn '[inputs]';;
44
+ *) echo '[]';;
45
+ esac
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+
6
+ const out = {};
7
+ const tailwindConfigs = ["tailwind.config.ts", "tailwind.config.js", "tailwind.config.mjs", "tailwind.config.cjs"];
8
+ for (const candidate of tailwindConfigs) {
9
+ if (fs.existsSync(candidate)) {
10
+ try {
11
+ const { default: resolveConfig } = await import("tailwindcss/resolveConfig");
12
+ const cfg = (await import(pathToFileURL(path.resolve(candidate)).href)).default;
13
+ const resolved = resolveConfig(cfg);
14
+ flatten(resolved.theme, "tw", out);
15
+ } catch (e) { out[`_error_${candidate}`] = String(e.message || e); }
16
+ break;
17
+ }
18
+ }
19
+ try {
20
+ const postcss = (await import("postcss")).default;
21
+ const cssCandidates = ["styles/globals.css","src/styles/globals.css","app/globals.css","styles/theme.css","src/app/globals.css"];
22
+ for (const css of cssCandidates) {
23
+ if (!fs.existsSync(css)) continue;
24
+ const source = fs.readFileSync(css, "utf8");
25
+ const root = postcss.parse(source);
26
+ root.walkAtRules("theme", at => { at.walkDecls(/^--/, d => { out[`css:${d.prop}`] = d.value.trim(); }); });
27
+ root.walkRules(":root", rule => { rule.walkDecls(/^--/, d => { out[`css:${d.prop}`] = d.value.trim(); }); });
28
+ }
29
+ } catch (e) { out._postcss_error = String(e.message || e); }
30
+
31
+ console.log(JSON.stringify(out, null, 2));
32
+
33
+ function flatten(obj, prefix, acc) {
34
+ if (obj == null) return;
35
+ if (typeof obj !== "object") { acc[prefix] = String(obj); return; }
36
+ for (const [k, v] of Object.entries(obj)) {
37
+ const key = `${prefix}.${k}`;
38
+ if (v && typeof v === "object" && !Array.isArray(v)) flatten(v, key, acc);
39
+ else acc[key] = Array.isArray(v) ? v.join(",") : String(v);
40
+ }
41
+ }
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: hash-pages.sh <urls_file>
3
+ set -euo pipefail
4
+ URLS="${1:?usage: hash-pages.sh <urls_file>}"
5
+ OUT_DIR="${OUT_DIR:-docs/super-design/.cache/hashes}"
6
+ mkdir -p "$OUT_DIR"
7
+
8
+ URLS="$URLS" OUT_DIR="$OUT_DIR" node --experimental-vm-modules <<'JS'
9
+ import { chromium } from "playwright";
10
+ import { createHash } from "node:crypto";
11
+ import { readFileSync, writeFileSync } from "node:fs";
12
+
13
+ const urlsFile = process.env.URLS;
14
+ const outDir = process.env.OUT_DIR;
15
+ const urls = readFileSync(urlsFile, "utf8").split("\n").map(s => s.trim()).filter(Boolean);
16
+ const browser = await chromium.launch();
17
+ const ctx = await browser.newContext({
18
+ viewport: { width: 1280, height: 800 }, reducedMotion: "reduce", deviceScaleFactor: 1,
19
+ });
20
+ const page = await ctx.newPage();
21
+ const sha = s => createHash("sha256").update(s).digest("hex");
22
+ const results = [];
23
+ for (const url of urls) {
24
+ try {
25
+ await page.goto(url, { waitUntil: "networkidle", timeout: 30000 });
26
+ const html = (await page.content()).replace(/\s+/g, " ").trim();
27
+ const dom = await page.evaluate(() => {
28
+ const V = new Set(["nonce","data-timestamp","data-reactid","data-next-hydrate"]);
29
+ const walk = n => n.nodeType !== 1 ? "" :
30
+ `<${n.tagName.toLowerCase()}[${[...n.attributes].filter(a=>!V.has(a.name))
31
+ .map(a=>`${a.name}=${a.value}`).sort().join(",")}]${[...n.childNodes].map(walk).join("")}>`;
32
+ return walk(document.documentElement);
33
+ });
34
+ const buf = await page.screenshot({ fullPage: true, animations: "disabled", caret: "hide" });
35
+ results.push({ url, html_hash: "sha256:" + sha(html),
36
+ dom_structure_hash: "sha256:" + sha(dom), screenshot_hash: "sha256:" + sha(buf) });
37
+ } catch (e) { results.push({ url, error: String(e.message || e) }); }
38
+ }
39
+ writeFileSync(outDir + "/hashes.json", JSON.stringify(results, null, 2));
40
+ await browser.close();
41
+ console.log(JSON.stringify({ count: results.length, path: outDir + "/hashes.json" }));
42
+ JS
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ STATE="${1:-docs/super-design/.audit-state.json}"
4
+ if [[ ! -f "$STATE" ]]; then echo '{"status":"missing"}'; exit 2; fi
5
+ jq -e '
6
+ (.schema_version | type == "string") and
7
+ (.last_audit_at | fromdateiso8601 | . > 0) and
8
+ (.git_sha_at_audit | test("^[0-9a-f]{7,64}$")) and
9
+ (.skill_version | type == "string") and
10
+ (.tools | type == "object")
11
+ ' "$STATE" >/dev/null 2>&1 || { echo '{"status":"corrupt"}'; exit 2; }
12
+ AGE_DAYS=$(( ( $(date -u +%s) - $(jq -r '.last_audit_at | fromdateiso8601' "$STATE") ) / 86400 ))
13
+ if (( AGE_DAYS > 180 )); then echo "{\"status\":\"stale-force-full\",\"age_days\":$AGE_DAYS}"; exit 1
14
+ elif (( AGE_DAYS > 90 )); then echo "{\"status\":\"stale-refresh-research\",\"age_days\":$AGE_DAYS}"; exit 1
15
+ else echo "{\"status\":\"fresh\",\"age_days\":$AGE_DAYS}"; exit 0; fi
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ SESSION_DIR="${1:?usage: verify-audit.sh <session_dir>}"
4
+ FINDINGS="$SESSION_DIR/findings.json"
5
+ if [[ ! -f "$FINDINGS" ]]; then echo "FATAL: no findings.json at $FINDINGS" >&2; exit 2; fi
6
+
7
+ jq -r '.[] | [.id, .screenshot_path, .snapshot_path] | @tsv' "$FINDINGS" | while IFS=$'\t' read -r id shot snap; do
8
+ if [[ ! -s "$shot" ]]; then echo "FAIL $id: missing/empty screenshot $shot" >&2; exit 1; fi
9
+ if [[ ! -s "$snap" ]]; then echo "FAIL $id: missing/empty snapshot $snap" >&2; exit 1; fi
10
+ done
11
+
12
+ jq -c '.[]' "$FINDINGS" | while read -r f; do
13
+ id=$(echo "$f" | jq -r .id)
14
+ q=$(echo "$f" | jq -r .snapshot_quote)
15
+ s=$(echo "$f" | jq -r .snapshot_path)
16
+ if ! grep -qF "$q" "$s"; then echo "FAIL $id: quote not found verbatim in $s" >&2; exit 1; fi
17
+ done
18
+
19
+ echo "OK: $(jq 'length' "$FINDINGS") findings verified"
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "super-design/audit-state.schema.json",
4
+ "type": "object",
5
+ "required": ["schema_version","skill_version","last_audit_at","git_sha_at_audit","theory_doc_sha","tools","pages_audited","findings_counts"],
6
+ "properties": {
7
+ "schema_version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$" },
8
+ "skill_version": { "type": "string" },
9
+ "last_audit_at": { "type": "string", "format": "date-time" },
10
+ "git_sha_at_audit": { "type": "string", "pattern": "^[0-9a-f]{7,64}$" },
11
+ "git_branch": { "type": "string" },
12
+ "is_shallow_clone": { "type": "boolean" },
13
+ "theory_doc_sha": { "type": "string" },
14
+ "market_analysis_sha": { "type": "string" },
15
+ "tools": { "type": "object", "additionalProperties": { "type": "string" } },
16
+ "framework": {
17
+ "type": "object",
18
+ "properties": {
19
+ "name": { "type": "string" },
20
+ "router": { "type": "string" },
21
+ "version": { "type": "string" }
22
+ }
23
+ },
24
+ "route_map": { "type": "array", "items": { "type": "string" } },
25
+ "pages_audited": {
26
+ "type": "array",
27
+ "items": {
28
+ "type": "object",
29
+ "required": ["url","last_audited"],
30
+ "properties": {
31
+ "url": { "type": "string" },
32
+ "route_file": { "type": "string" },
33
+ "html_hash": { "type": "string" },
34
+ "dom_structure_hash": { "type": "string" },
35
+ "viewport_hashes": { "type": "object" },
36
+ "last_audited": { "type": "string", "format": "date-time" },
37
+ "findings_ids": { "type": "array", "items": { "type": "string" } }
38
+ }
39
+ }
40
+ },
41
+ "components": { "type": "object", "additionalProperties": { "type": "string" } },
42
+ "token_hash": { "type": "string" },
43
+ "import_graph_sha": { "type": "string" },
44
+ "findings_counts": {
45
+ "type": "object",
46
+ "required": ["blockers","high","medium","nitpicks"],
47
+ "properties": {
48
+ "blockers": { "type": "integer" },
49
+ "high": { "type": "integer" },
50
+ "medium": { "type": "integer" },
51
+ "nitpicks": { "type": "integer" }
52
+ }
53
+ },
54
+ "research_at": { "type": "string", "format": "date-time" },
55
+ "ignored_paths": { "type": "array", "items": { "type": "string" } }
56
+ }
57
+ }
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "super-design/findings.schema.json",
4
+ "type": "object",
5
+ "required": ["session_id", "findings"],
6
+ "properties": {
7
+ "session_id": { "type": "string" },
8
+ "findings": {
9
+ "type": "array",
10
+ "items": {
11
+ "type": "object",
12
+ "required": ["id","category","rule","impact","risk_for_fix","files_affected","dom_selector","page_url","viewport","screenshot_path","snapshot_path","snapshot_quote","computed_style_excerpt","severity","finding"],
13
+ "properties": {
14
+ "id": { "type": "string", "pattern": "^F-\\d{4,}$" },
15
+ "category": { "enum": ["a11y","design","ux","perf","baymard","heuristic"] },
16
+ "rule": { "type": "string" },
17
+ "wcag_criterion": { "type": "string" },
18
+ "nielsen_heuristic": { "type": "string" },
19
+ "impact": { "enum": ["minor","moderate","serious","critical"] },
20
+ "severity": { "type": "integer", "minimum": 0, "maximum": 4 },
21
+ "risk_for_fix": { "enum": ["TRIVIAL","LOW","MEDIUM","HIGH"] },
22
+ "files_affected": { "type": "array", "items": { "type": "string" } },
23
+ "page_url": { "type": "string" },
24
+ "viewport": {
25
+ "type": "object",
26
+ "required": ["name","w","h"],
27
+ "properties": {
28
+ "name": { "type": "string" },
29
+ "w": { "type": "integer" },
30
+ "h": { "type": "integer" }
31
+ }
32
+ },
33
+ "screenshot_path": { "type": "string" },
34
+ "snapshot_path": { "type": "string" },
35
+ "snapshot_quote": { "type": "string" },
36
+ "dom_selector": { "type": "string" },
37
+ "computed_style_excerpt": { "type": "object" },
38
+ "evidence_hex_fg": { "type": "string" },
39
+ "evidence_hex_bg": { "type": "string" },
40
+ "evidence_contrast_ratio": { "type": "number" },
41
+ "evidence_px": { "type": "object" },
42
+ "suggested_fix": {
43
+ "type": "object",
44
+ "properties": {
45
+ "strategy": { "type": "string" },
46
+ "template_id": { "type": "string" },
47
+ "value_hint": { "type": "string" }
48
+ }
49
+ },
50
+ "finding": { "type": "string" },
51
+ "first_seen_at": { "type": "string", "format": "date-time" },
52
+ "status": { "enum": ["new","persisted","resolved"] }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,26 @@
1
+ ## {{session_date}} · `{{session_id}}` · branch `{{branch}}`
2
+
3
+ **Counts:** Applied {{applied}} · Proposed {{proposed}} · Skipped {{skipped}} · Failed {{failed}}
4
+ **Base:** `{{base_sha}}` · **Tip:** `{{tip_sha}}`
5
+
6
+ ### Applied
7
+ | Finding | Category | Files | Commit |
8
+ |---|---|---|---|
9
+ {{applied_table}}
10
+
11
+ ### Proposed (awaiting approval)
12
+ | Finding | Category | Files | Patch |
13
+ |---|---|---|---|
14
+ {{proposed_table}}
15
+
16
+ ### Skipped (HIGH risk — tracked as issues)
17
+ | Finding | Issue | Reason |
18
+ |---|---|---|
19
+ {{skipped_table}}
20
+
21
+ ### Failed (rolled back)
22
+ | Finding | Gate | Reason |
23
+ |---|---|---|
24
+ {{failed_table}}
25
+
26
+ ---
@@ -0,0 +1,52 @@
1
+ # Design audit overview — {{project_name}}
2
+
3
+ > **{{mode_banner}}**
4
+ > {{changelog_body}}
5
+
6
+ ## Executive summary
7
+
8
+ {{executive_summary}}
9
+
10
+ ## Scorecard
11
+
12
+ | Category | Score | Blockers | High | Medium | Nitpicks |
13
+ |---|---|---|---|---|---|
14
+ | Nielsen heuristics | {{nielsen_score}}/40 | {{n_blockers_nielsen}} | {{n_high_nielsen}} | {{n_medium_nielsen}} | {{n_nits_nielsen}} |
15
+ | WCAG 2.2 AA | {{wcag_score}}% | {{n_blockers_wcag}} | {{n_high_wcag}} | {{n_medium_wcag}} | {{n_nits_wcag}} |
16
+ | Core Web Vitals | {{cwv_badge}} | {{n_blockers_cwv}} | {{n_high_cwv}} | — | — |
17
+ | Baymard (if applicable) | {{baymard_score}} | {{n_blockers_baymard}} | {{n_high_baymard}} | {{n_medium_baymard}} | — |
18
+
19
+ ## Top findings
20
+
21
+ ### 🚨 Blockers
22
+ {{blockers_table}}
23
+
24
+ ### High priority
25
+ {{high_table}}
26
+
27
+ ### Medium priority
28
+ {{medium_table}}
29
+
30
+ ### Nitpicks
31
+ {{nitpicks_table}}
32
+
33
+ ### ✅ Resolved since last audit
34
+ {{resolved_table}}
35
+
36
+ ## Market positioning snapshot
37
+ {{market_snapshot}}
38
+
39
+ Full market analysis: `docs/super-design/market-analysis.md`.
40
+
41
+ ## Remediation roadmap
42
+ {{roadmap_body}}
43
+
44
+ ## Appendix — evidence
45
+ - Per-finding details: `docs/super-design/findings/F-*.md`
46
+ - Screenshots: `docs/super-design/.cache/screenshots/`
47
+ - axe-core outputs: `docs/super-design/.cache/axe/`
48
+ - Web Vitals: `docs/super-design/.cache/vitals/`
49
+ - Audit history: `docs/super-design/audit-history.md`
50
+
51
+ ---
52
+ *Generated by super-design v{{version}} on {{timestamp}}. Session: `{{session_id}}`.*