skillui 1.1.3 → 1.1.5

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 (3) hide show
  1. package/README.md +20 -15
  2. package/dist/cli.js +25 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,14 @@
1
- # skillui
2
-
3
- **Reverse-engineer any design system. Pure static analysis — no AI, no API keys.**
1
+ ```
2
+ ░██████╗██╗░░██╗██╗██╗░░░░░██╗░░░░░██╗░░░██╗██╗
3
+ ██╔════╝██║░██╔╝██║██║░░░░░██║░░░░░██║░░░██║██║
4
+ ╚█████╗░█████═╝░██║██║░░░░░██║░░░░░██║░░░██║██║
5
+ ░╚═══██╗██╔═██╗░██║██║░░░░░██║░░░░░██║░░░██║██║
6
+ ██████╔╝██║░╚██╗██║███████╗███████╗╚██████╔╝██║
7
+ ╚═════╝░╚═╝░░╚═╝╚═╝╚══════╝╚══════╝░╚═════╝░╚═╝
8
+ ```
9
+ > Reverse-engineer any design system. Pure static analysis. No AI, no API keys.
4
10
 
5
- Point `skillui` at any website, git repo, or local project and get exact colors, fonts, spacing, components, and animations packaged as a `.skill` file Claude can read.
11
+ Point skillui at any website, git repo, or local project and get exact colors, fonts, spacing, components, and animations packaged as a `.skill` file Claude can read.
6
12
 
7
13
  ```bash
8
14
  npm install -g skillui
@@ -16,7 +22,7 @@ skillui --url https://yoursite.com --mode ultra
16
22
  skillui crawls your target and extracts:
17
23
 
18
24
  | Output | Contents |
19
- |--------|----------|
25
+ |---|---|
20
26
  | `DESIGN.md` | Colors, typography, spacing, border radius, components |
21
27
  | `ANIMATIONS.md` | CSS keyframes, scroll triggers, GSAP/Lottie/Three.js detection |
22
28
  | `LAYOUT.md` | Flex/grid containers, page structure, spacing relationships |
@@ -63,6 +69,7 @@ skillui --url https://linear.app --mode ultra
63
69
  ```
64
70
 
65
71
  Ultra mode adds:
72
+
66
73
  - 7 scroll journey screenshots showing the page at each scroll depth
67
74
  - Hover/focus interaction state diffs
68
75
  - Full CSS keyframe extraction
@@ -83,9 +90,7 @@ skillui --dir ./my-app
83
90
  skillui --repo https://github.com/org/repo
84
91
  ```
85
92
 
86
- ---
87
-
88
- ## All flags
93
+ ### All flags
89
94
 
90
95
  ```
91
96
  skillui --url <url> Crawl a live website
@@ -114,7 +119,7 @@ Then ask Claude:
114
119
 
115
120
  > "Build me a dashboard that matches the Linear design system"
116
121
 
117
- Claude will read DESIGN.md, ANIMATIONS.md, LAYOUT.md, COMPONENTS.md, and all scroll journey screenshots to reconstruct the exact visual language of the site.
122
+ Claude will read `DESIGN.md`, `ANIMATIONS.md`, `LAYOUT.md`, `COMPONENTS.md`, and all scroll journey screenshots to reconstruct the exact visual language of the site.
118
123
 
119
124
  ---
120
125
 
@@ -174,12 +179,12 @@ skillui --url https://linear.app --out ./design-systems
174
179
 
175
180
  ## How it works
176
181
 
177
- skillui uses pure static analysis no AI, no API keys, no cloud.
182
+ skillui uses pure static analysis. No AI, no API keys, no cloud.
178
183
 
179
- 1. **URL mode** fetches HTML, crawls all linked CSS files, extracts computed styles via Playwright DOM inspection
180
- 2. **Dir mode** scans all `.css`, `.scss`, `.ts`, `.tsx`, `.js`, `.jsx` files for design tokens, Tailwind config, CSS variables, and component patterns
181
- 3. **Repo mode** clones the repo to a temp directory and runs dir mode
182
- 4. **Ultra mode** runs Playwright to capture scroll journey screenshots, detect animation libraries from `window.*` globals, extract `@keyframes` from `document.styleSheets`, capture hover/focus state diffs, and fingerprint DOM components
184
+ - **URL mode** fetches HTML, crawls all linked CSS files, extracts computed styles via Playwright DOM inspection
185
+ - **Dir mode** scans all `.css`, `.scss`, `.ts`, `.tsx`, `.js`, `.jsx` files for design tokens, Tailwind config, CSS variables, and component patterns
186
+ - **Repo mode** clones the repo to a temp directory and runs dir mode
187
+ - **Ultra mode** runs Playwright to capture scroll journey screenshots, detect animation libraries from `window.*` globals, extract `@keyframes` from `document.styleSheets`, capture hover/focus state diffs, and fingerprint DOM components
183
188
 
184
189
  ---
185
190
 
@@ -192,4 +197,4 @@ skillui uses pure static analysis — no AI, no API keys, no cloud.
192
197
 
193
198
  ## License
194
199
 
195
- MIT
200
+ MIT
package/dist/cli.js CHANGED
@@ -104561,7 +104561,7 @@ gradient.pastel = pastel;
104561
104561
  // src/ui.ts
104562
104562
  var import_cli_progress = __toESM(require_cli_progress());
104563
104563
  var path15 = __toESM(require("path"));
104564
- var VERSION = "1.1.3";
104564
+ var VERSION = "1.1.5";
104565
104565
  function padAnsi(str, width) {
104566
104566
  const raw = stripAnsi(str);
104567
104567
  return str + " ".repeat(Math.max(0, width - raw.length));
@@ -104755,7 +104755,7 @@ function showUltraPlaywrightError() {
104755
104755
  console.log("");
104756
104756
  }
104757
104757
  function showResults(data) {
104758
- const { profile, animations, skillFilePath, designMdPath, projectName } = data;
104758
+ const { profile, animations, skillFilePath, designMdPath, projectName, skillInstalled } = data;
104759
104759
  const fontCount = new Set(profile.typography.map((t) => t.fontFamily)).size;
104760
104760
  const framework = profile.frameworks.map((f) => f.name).join(", ") || "none detected";
104761
104761
  const darkMode = profile.designTraits.hasDarkMode ? "detected" : "not detected";
@@ -104806,17 +104806,17 @@ function showResults(data) {
104806
104806
  }));
104807
104807
  console.log("");
104808
104808
  }
104809
+ const skillLine = skillInstalled ? source_default.hex("#4ade80")(" \u2713 Skill auto-installed") + source_default.dim(" \u2014 type ") + source_default.hex("#38bdf8")("/skills") + source_default.dim(" in Claude Code to see it") : source_default.dim(" Copy SKILL.md to ") + source_default.hex("#38bdf8")("~/.claude/skills/" + projectName + ".md");
104809
104810
  const nextSteps = [
104810
- source_default.dim(" Install skill in Claude Code:"),
104811
- " " + source_default.hex("#38bdf8")("claude skill install ./" + projectName + ".skill"),
104811
+ skillLine,
104812
104812
  "",
104813
- source_default.dim(" Or drop DESIGN.md into your project and ask Claude:"),
104814
- " " + source_default.dim('"Build me a UI that matches this design system"')
104813
+ source_default.dim(" Then ask Claude:"),
104814
+ " " + source_default.dim('"Build me a UI that matches the ' + projectName + ' design system"')
104815
104815
  ].join("\n");
104816
104816
  console.log(boxen(nextSteps, {
104817
104817
  title: source_default.bold(" Next steps "),
104818
104818
  borderStyle: "round",
104819
- borderColor: "yellow",
104819
+ borderColor: skillInstalled ? "green" : "yellow",
104820
104820
  width: 76,
104821
104821
  padding: { top: 0, bottom: 0, left: 0, right: 1 }
104822
104822
  }));
@@ -104973,12 +104973,14 @@ program2.name("skillui").description("Reverse-engineer design systems from any p
104973
104973
  succeedSpinner(spWrite, "DESIGN.md", designMdPath);
104974
104974
  }
104975
104975
  let skillFilePath;
104976
+ let skillInstalled = false;
104976
104977
  if (shouldWriteSkill) {
104977
104978
  const spSkill = startSpinner("Bundling .skill package...");
104978
104979
  try {
104979
104980
  const result = await generateSkill(profile, designMdContent, path16.resolve(opts.out), screenshotPath, ultraAnimations);
104980
104981
  skillFilePath = result.skillFile;
104981
104982
  succeedSpinner(spSkill, ".skill package", skillFilePath);
104983
+ skillInstalled = installSkillForClaude(result.skillDir, safeName);
104982
104984
  } catch (e) {
104983
104985
  failSpinner(spSkill, ".skill package", e.message);
104984
104986
  throw e;
@@ -104989,7 +104991,8 @@ program2.name("skillui").description("Reverse-engineer design systems from any p
104989
104991
  animations: ultraAnimations ?? void 0,
104990
104992
  skillFilePath,
104991
104993
  designMdPath,
104992
- projectName: safeName
104994
+ projectName: safeName,
104995
+ skillInstalled
104993
104996
  });
104994
104997
  } catch (err) {
104995
104998
  console.error(`
@@ -104999,6 +105002,20 @@ program2.name("skillui").description("Reverse-engineer design systems from any p
104999
105002
  }
105000
105003
  });
105001
105004
  program2.parse();
105005
+ function installSkillForClaude(skillDir, safeName) {
105006
+ try {
105007
+ const skillMdSrc = path16.join(skillDir, "SKILL.md");
105008
+ if (!fs14.existsSync(skillMdSrc)) return false;
105009
+ const homeDir = process.env.HOME || process.env.USERPROFILE || "";
105010
+ const claudeSkillsDir = path16.join(homeDir, ".claude", "skills");
105011
+ fs14.mkdirSync(claudeSkillsDir, { recursive: true });
105012
+ const dest = path16.join(claudeSkillsDir, `${safeName}.md`);
105013
+ fs14.copyFileSync(skillMdSrc, dest);
105014
+ return true;
105015
+ } catch {
105016
+ return false;
105017
+ }
105018
+ }
105002
105019
  /*! Bundled license information:
105003
105020
 
105004
105021
  tmp/lib/tmp.js:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillui",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Reverse-engineer design systems from any website, repo, or project. Extracts colors, fonts, spacing, animations, and components — packaged as a .skill file for Claude. Pure static analysis, zero AI, zero API keys.",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {