@nucleoicons/skills 0.1.7 → 0.1.9

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.
package/README.md CHANGED
@@ -5,7 +5,7 @@ CLI to install and update **Nucleo** MCP + icon skills on your machine.
5
5
  Once installed, your AI coding tool can help you **use Nucleo icons in code**. Typical uses:
6
6
 
7
7
  - Search icons by name or idea across your installed families (Pro and/or free)
8
- - Pick an icon and get the right React component or SVG for your project
8
+ - Pick an icon and get the right **React** component, **Vue** SFC, or **vanilla SVG** for your project
9
9
  - Customize icons when inserting them (color, secondary color, stroke width, duo opacity, corners)
10
10
 
11
11
  Ask your editor naturally, for example: “find a settings icon in Nucleo” or “insert the home icon as a React component.”
@@ -14,7 +14,7 @@ Requires **Node.js 20+**.
14
14
 
15
15
  ## Install
16
16
 
17
- **Pro** (Nucleo account — licensed families):
17
+ **Pro** (Nucleo account — licensed families **plus** free sets in the same install):
18
18
 
19
19
  ```bash
20
20
  npx @nucleoicons/skills setup --target react --tools cursor
@@ -26,13 +26,21 @@ npx @nucleoicons/skills setup --target react --tools cursor
26
26
  npx @nucleoicons/skills setup --free --target react --tools cursor
27
27
  ```
28
28
 
29
- **Required for setup:** `--target` (`react` or `vanilla`) and `--tools` (`cursor`, `claude`, `codex`).
29
+ **Required for setup:** `--target` (`react`, `vue`, or `vanilla`) and `--tools` (`cursor`, `claude`, `codex`).
30
30
 
31
31
  ```bash
32
32
  npx @nucleoicons/skills setup --target react --tools cursor
33
- npx @nucleoicons/skills setup --free --target vanilla --tools cursor,claude
33
+ npx @nucleoicons/skills setup --target vue --tools cursor
34
+ npx @nucleoicons/skills setup --target vanilla --tools cursor,claude
35
+ npx @nucleoicons/skills setup --free --target vue --tools cursor
34
36
  ```
35
37
 
38
+ | `--target` | What you get |
39
+ | ---------- | ------------------------- |
40
+ | `react` | React components (`.tsx`) |
41
+ | `vue` | Vue SFCs (`.vue`) |
42
+ | `vanilla` | SVG files |
43
+
36
44
  Setup installs the package under your user home (`~/.nucleo/skills`) and configures the editors you choose (skills + MCP, no manual config step).
37
45
 
38
46
  Reload MCP in your editor, then ask something like:
@@ -57,8 +65,8 @@ After updating, reload MCP in your editor again.
57
65
 
58
66
  ## Editors
59
67
 
60
- | Tool | `--tools` value | Auto-configured |
61
- | ----------- | --------------- | --------------- |
62
- | Cursor | `cursor` | `~/.cursor/mcp.json` + `~/.cursor/skills/` |
63
- | Claude Code | `claude` | `~/.claude.json` + `~/.claude/skills/` |
68
+ | Tool | `--tools` value | Auto-configured |
69
+ | ----------- | --------------- | -------------------------------------------- |
70
+ | Cursor | `cursor` | `~/.cursor/mcp.json` + `~/.cursor/skills/` |
71
+ | Claude Code | `claude` | `~/.claude.json` + `~/.claude/skills/` |
64
72
  | Codex | `codex` | `~/.codex/config.toml` + `~/.agents/skills/` |
package/dist/api.d.ts CHANGED
@@ -44,12 +44,12 @@ export interface DownloadProgress {
44
44
  */
45
45
  export declare function skillsLogin(email: string, password: string): Promise<SkillsLoginData>;
46
46
  /**
47
- * GET /skills/release?token=…&target=react|vanilla
47
+ * GET /skills/release?token=…&target=react|vanilla|vue
48
48
  * Response: { data: { version, families, files, downloadReady } }
49
49
  */
50
50
  export declare function fetchSkillsRelease(token: string, target: PackageTarget): Promise<SkillsReleaseData>;
51
51
  /**
52
- * GET /skills/release-free?target=react|vanilla (no auth)
52
+ * GET /skills/release-free?target=react|vanilla|vue (no auth)
53
53
  */
54
54
  export declare function fetchSkillsFreeRelease(target: PackageTarget): Promise<SkillsReleaseData>;
55
55
  declare function formatBytes(bytes: number): string;
package/dist/api.js CHANGED
@@ -65,7 +65,7 @@ export async function skillsLogin(email, password) {
65
65
  return json.data;
66
66
  }
67
67
  /**
68
- * GET /skills/release?token=…&target=react|vanilla
68
+ * GET /skills/release?token=…&target=react|vanilla|vue
69
69
  * Response: { data: { version, families, files, downloadReady } }
70
70
  */
71
71
  export async function fetchSkillsRelease(token, target) {
@@ -86,7 +86,7 @@ export async function fetchSkillsRelease(token, target) {
86
86
  return { ...json.data, tier: json.data.tier ?? "pro" };
87
87
  }
88
88
  /**
89
- * GET /skills/release-free?target=react|vanilla (no auth)
89
+ * GET /skills/release-free?target=react|vanilla|vue (no auth)
90
90
  */
91
91
  export async function fetchSkillsFreeRelease(target) {
92
92
  const url = new URL(`${getApiBaseUrl()}/skills/release-free`);
@@ -1,4 +1,4 @@
1
- import type { AgentTool, PackageTarget } from "../config.js";
1
+ import { type AgentTool, type PackageTarget } from "../config.js";
2
2
  export interface SetupOptions {
3
3
  /** Skip API; copy a local prepared package directory */
4
4
  from?: string;
@@ -1,8 +1,8 @@
1
1
  import { confirm, select, checkbox } from "@inquirer/prompts";
2
2
  import { mkdir } from "node:fs/promises";
3
3
  import { ApiError, fetchSkillsFreeRelease, fetchSkillsRelease } from "../api.js";
4
- import { installRoot, nucleoHomeDir } from "../config.js";
5
- import { buildMcp, ensureManifestTarget, installFromLocalDir, installFromRelease, readInstallManifest, } from "../install.js";
4
+ import { installRoot, isPackageTarget, nucleoHomeDir, } from "../config.js";
5
+ import { buildMcp, ensureManifestTarget, hasProFamilies, installFromLocalDir, installFromRelease, readInstallManifest, } from "../install.js";
6
6
  import { configureTool } from "../adapters/agents.js";
7
7
  import { ensureSkillsSession, isInvalidTokenError } from "../session.js";
8
8
  async function fetchProReleaseWithSession(target, emailHint) {
@@ -23,11 +23,15 @@ export async function runSetup(options = {}) {
23
23
  const free = Boolean(options.free);
24
24
  console.log(free ? "\nNucleo Skills setup (free)" : "\nNucleo Skills setup");
25
25
  console.log(free ? "─────────────────────────\n" : "───────────────────\n");
26
+ if (options.target && !isPackageTarget(options.target)) {
27
+ throw new Error(`Unknown target "${options.target}". Use react, vanilla, or vue.`);
28
+ }
26
29
  const target = options.target ??
27
30
  (await select({
28
31
  message: "Which package?",
29
32
  choices: [
30
33
  { name: "React components", value: "react" },
34
+ { name: "Vue components", value: "vue" },
31
35
  { name: "Vanilla SVG", value: "vanilla" },
32
36
  ],
33
37
  }));
@@ -64,6 +68,10 @@ export async function runSetup(options = {}) {
64
68
  });
65
69
  }
66
70
  else if (free) {
71
+ const mergingIntoPro = hasProFamilies();
72
+ if (mergingIntoPro) {
73
+ console.log("Existing Pro install detected — free icons will be added alongside Pro.\n");
74
+ }
67
75
  console.log(`Fetching free ${target} release…`);
68
76
  let release;
69
77
  try {
@@ -82,7 +90,7 @@ export async function runSetup(options = {}) {
82
90
  await installFromRelease(release, target);
83
91
  }
84
92
  else {
85
- console.log(`Fetching ${target} release…`);
93
+ console.log(`Fetching ${target} release (Pro + free)…`);
86
94
  let release;
87
95
  try {
88
96
  release = await fetchProReleaseWithSession(target, options.email);
@@ -111,5 +119,6 @@ export async function runSetup(options = {}) {
111
119
  console.log(` Target: ${manifest?.target ?? target}`);
112
120
  console.log(` Tier: ${manifest?.tier ?? (free ? "free" : "pro")}`);
113
121
  console.log(` Version: ${manifest?.version ?? "(none)"}`);
122
+ console.log(` Families: ${(manifest?.families ?? []).join(", ") || "(none)"}`);
114
123
  console.log("\nReload MCP in your editor, then try asking about Nucleo icons.\n");
115
124
  }
@@ -1,7 +1,7 @@
1
1
  import { confirm } from "@inquirer/prompts";
2
2
  import { ApiError, fetchSkillsFreeRelease, fetchSkillsRelease } from "../api.js";
3
3
  import { installRoot } from "../config.js";
4
- import { buildMcp, ensureManifestTarget, installFromLocalDir, installFromRelease, readInstallManifest, } from "../install.js";
4
+ import { buildMcp, ensureManifestTarget, installFromLocalDir, installFromRelease, isFreeOnlyInstall, readInstallManifest, } from "../install.js";
5
5
  import { configureTool } from "../adapters/agents.js";
6
6
  import { ensureSkillsSession, isInvalidTokenError } from "../session.js";
7
7
  async function fetchProReleaseWithSession(target) {
@@ -18,18 +18,6 @@ async function fetchProReleaseWithSession(target) {
18
18
  throw error;
19
19
  }
20
20
  }
21
- function isFreeInstall(manifest) {
22
- if (!manifest) {
23
- return false;
24
- }
25
- if (manifest.tier === "free") {
26
- return true;
27
- }
28
- if (typeof manifest.product === "string" && manifest.product.includes("free")) {
29
- return true;
30
- }
31
- return false;
32
- }
33
21
  export async function runUpdate(options = {}) {
34
22
  console.log("\nNucleo Skills update");
35
23
  console.log("────────────────────\n");
@@ -39,14 +27,11 @@ export async function runUpdate(options = {}) {
39
27
  }
40
28
  const target = manifest?.target ?? "react";
41
29
  const localVersion = manifest?.version ?? "0.0.0";
42
- const free = isFreeInstall(manifest);
30
+ const freeOnly = isFreeOnlyInstall(installRoot(), manifest);
43
31
  if (options.from) {
44
32
  console.log(`Updating from local folder:\n ${options.from}\n`);
45
33
  await installFromLocalDir(options.from);
46
- await ensureManifestTarget(target, {
47
- tier: free ? "free" : "pro",
48
- product: free ? "nucleo-skills-free" : "nucleo-skills",
49
- });
34
+ await ensureManifestTarget(target);
50
35
  console.log("Building MCP…");
51
36
  await buildMcp();
52
37
  await reconfigure(options.tools);
@@ -57,12 +42,12 @@ export async function runUpdate(options = {}) {
57
42
  }
58
43
  let release;
59
44
  try {
60
- if (free) {
45
+ if (freeOnly) {
61
46
  console.log("Channel: free");
62
47
  release = await fetchSkillsFreeRelease(target);
63
48
  }
64
49
  else {
65
- console.log("Channel: pro");
50
+ console.log("Channel: pro (+ free)");
66
51
  release = await fetchProReleaseWithSession(target);
67
52
  }
68
53
  }
package/dist/config.d.ts CHANGED
@@ -6,7 +6,9 @@ export declare function nucleoHomeDir(): string;
6
6
  export declare function credentialsPath(): string;
7
7
  /** Where the downloaded Pro package lives (MCP, skills, icons) */
8
8
  export declare function installRoot(): string;
9
- export type PackageTarget = "react" | "vanilla";
9
+ export declare const PACKAGE_TARGETS: readonly ["react", "vanilla", "vue"];
10
+ export type PackageTarget = (typeof PACKAGE_TARGETS)[number];
11
+ export declare function isPackageTarget(value: string): value is PackageTarget;
10
12
  export type AgentTool = "cursor" | "claude" | "codex";
11
13
  export interface NucleoCredentials {
12
14
  email: string;
@@ -15,8 +17,8 @@ export interface NucleoCredentials {
15
17
  }
16
18
  export interface InstallManifest {
17
19
  product?: string;
18
- /** free | pro — drives update channel without requiring --free again */
19
- tier?: "free" | "pro" | string;
20
+ /** free | pro | pro+free — drives update channel without requiring --free again */
21
+ tier?: "free" | "pro" | "pro+free" | string;
20
22
  target?: PackageTarget | string;
21
23
  version?: string;
22
24
  families?: string[];
package/dist/config.js CHANGED
@@ -19,3 +19,7 @@ export function credentialsPath() {
19
19
  export function installRoot() {
20
20
  return join(nucleoHomeDir(), "skills");
21
21
  }
22
+ export const PACKAGE_TARGETS = ["react", "vanilla", "vue"];
23
+ export function isPackageTarget(value) {
24
+ return PACKAGE_TARGETS.includes(value);
25
+ }
package/dist/index.js CHANGED
@@ -52,7 +52,7 @@ program
52
52
  program
53
53
  .command("setup")
54
54
  .description("Sign in, download your licensed package, configure your editor")
55
- .option("-t, --target <target>", "react | vanilla")
55
+ .option("-t, --target <target>", "react | vanilla | vue")
56
56
  .option("--tools <list>", "comma-separated: cursor,claude,codex (default: prompt, or cursor with --yes)")
57
57
  .option("--free", "Install free icon families (no Nucleo login)")
58
58
  .option("--from <dir>", "Install from a local prepared package (skip API download)")
package/dist/install.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { type SkillsReleaseData } from "./api.js";
2
2
  import { type InstallManifest, type PackageTarget } from "./config.js";
3
+ /** Licensed Pro families — never installed via the free (no-auth) channel. */
4
+ export declare const PRO_FAMILIES: readonly ["core", "ui", "sharp", "micro", "pixel"];
5
+ /** Free families from react-free.zip / vanilla-free.zip. */
6
+ export declare const FREE_FAMILIES: readonly ["flags", "cursors", "credit-cards", "social-media", "isometric", "arcade", "glass"];
3
7
  /**
4
8
  * Resolve a real npm binary. Prefer the one next to the running Node
5
9
  * (`process.execPath`) so we don't depend on PATH / shell aliases
@@ -8,12 +12,42 @@ import { type InstallManifest, type PackageTarget } from "./config.js";
8
12
  export declare function resolveNpmBin(): string;
9
13
  export declare function readInstallManifest(root?: string): Promise<InstallManifest | null>;
10
14
  export declare function cleanInstallRoot(root?: string): Promise<void>;
15
+ /** True if any Pro family catalog is present under the install root. */
16
+ export declare function hasProFamilies(root?: string): boolean;
17
+ /** True if any free family catalog is present under the install root. */
18
+ export declare function hasFreeFamilies(root?: string): boolean;
11
19
  /**
12
- * Download all release files (signed URLs) and merge into the install root.
13
- * Downloads complete first, then the install folder is replaced — so a failed
14
- * download does not wipe a previous working install.
20
+ * Detect installed icon families by looking for `{family}/icons.json`.
15
21
  */
16
- export declare function installFromRelease(release: SkillsReleaseData, target: PackageTarget, root?: string): Promise<void>;
22
+ export declare function detectInstalledFamilies(root?: string): string[];
23
+ export declare function resolveInstallTier(root?: string): {
24
+ hasPro: boolean;
25
+ hasFree: boolean;
26
+ tier: "free" | "pro" | "pro+free";
27
+ };
28
+ /**
29
+ * Free-only installs use the public free channel.
30
+ * Any Pro families on disk → Pro (authenticated) channel, which also ships free.
31
+ */
32
+ export declare function isFreeOnlyInstall(root?: string, manifest?: InstallManifest | null): boolean;
33
+ export interface InstallFromReleaseOptions {
34
+ /**
35
+ * When true, extract into the existing root without wiping.
36
+ * Used so `setup --free` can add free families beside Pro.
37
+ * Default: auto — merge free releases onto an existing Pro install.
38
+ */
39
+ merge?: boolean;
40
+ }
41
+ /**
42
+ * Download all release files (signed URLs) and install into the root.
43
+ *
44
+ * - Pro releases: replace the install root, then extract (Pro zips + free zip).
45
+ * - Free releases on top of Pro: merge (keep Pro families).
46
+ * - Free-only: replace the install root with free content.
47
+ *
48
+ * Downloads complete first — a failed download does not wipe a previous install.
49
+ */
50
+ export declare function installFromRelease(release: SkillsReleaseData, target: PackageTarget, root?: string, options?: InstallFromReleaseOptions): Promise<void>;
17
51
  /**
18
52
  * Copy a local prepared package (e.g. packages/react) into the install root.
19
53
  */
package/dist/install.js CHANGED
@@ -7,6 +7,18 @@ import extract from "extract-zip";
7
7
  import { downloadUrlToFile, formatBytes } from "./api.js";
8
8
  import { installRoot, nucleoHomeDir } from "./config.js";
9
9
  const execFileAsync = promisify(execFile);
10
+ /** Licensed Pro families — never installed via the free (no-auth) channel. */
11
+ export const PRO_FAMILIES = ["core", "ui", "sharp", "micro", "pixel"];
12
+ /** Free families from react-free.zip / vanilla-free.zip. */
13
+ export const FREE_FAMILIES = [
14
+ "flags",
15
+ "cursors",
16
+ "credit-cards",
17
+ "social-media",
18
+ "isometric",
19
+ "arcade",
20
+ "glass",
21
+ ];
10
22
  /**
11
23
  * Resolve a real npm binary. Prefer the one next to the running Node
12
24
  * (`process.execPath`) so we don't depend on PATH / shell aliases
@@ -58,6 +70,52 @@ export async function cleanInstallRoot(root = installRoot()) {
58
70
  await rm(root, { recursive: true, force: true });
59
71
  await mkdir(root, { recursive: true });
60
72
  }
73
+ /** True if any Pro family catalog is present under the install root. */
74
+ export function hasProFamilies(root = installRoot()) {
75
+ return PRO_FAMILIES.some((family) => existsSync(join(root, family, "icons.json")));
76
+ }
77
+ /** True if any free family catalog is present under the install root. */
78
+ export function hasFreeFamilies(root = installRoot()) {
79
+ return FREE_FAMILIES.some((family) => existsSync(join(root, family, "icons.json")));
80
+ }
81
+ /**
82
+ * Detect installed icon families by looking for `{family}/icons.json`.
83
+ */
84
+ export function detectInstalledFamilies(root = installRoot()) {
85
+ const known = [...PRO_FAMILIES, ...FREE_FAMILIES];
86
+ return known.filter((family) => existsSync(join(root, family, "icons.json")));
87
+ }
88
+ export function resolveInstallTier(root = installRoot()) {
89
+ const hasPro = hasProFamilies(root);
90
+ const hasFree = hasFreeFamilies(root);
91
+ if (hasPro && hasFree) {
92
+ return { hasPro, hasFree, tier: "pro+free" };
93
+ }
94
+ if (hasPro) {
95
+ return { hasPro, hasFree, tier: "pro" };
96
+ }
97
+ return { hasPro, hasFree, tier: "free" };
98
+ }
99
+ /**
100
+ * Free-only installs use the public free channel.
101
+ * Any Pro families on disk → Pro (authenticated) channel, which also ships free.
102
+ */
103
+ export function isFreeOnlyInstall(root = installRoot(), manifest) {
104
+ if (hasProFamilies(root)) {
105
+ return false;
106
+ }
107
+ if (manifest?.tier === "pro" || manifest?.tier === "pro+free") {
108
+ return false;
109
+ }
110
+ if (manifest?.tier === "free") {
111
+ return true;
112
+ }
113
+ if (typeof manifest?.product === "string" && manifest.product.includes("free")) {
114
+ return true;
115
+ }
116
+ // No Pro on disk and no explicit Pro tier → free-only channel.
117
+ return true;
118
+ }
61
119
  async function canRunUnzip() {
62
120
  try {
63
121
  await execFileAsync("unzip", ["-v"], { timeout: 5_000 });
@@ -104,11 +162,15 @@ async function assertInstallLooksComplete(root) {
104
162
  }
105
163
  }
106
164
  /**
107
- * Download all release files (signed URLs) and merge into the install root.
108
- * Downloads complete first, then the install folder is replaced — so a failed
109
- * download does not wipe a previous working install.
165
+ * Download all release files (signed URLs) and install into the root.
166
+ *
167
+ * - Pro releases: replace the install root, then extract (Pro zips + free zip).
168
+ * - Free releases on top of Pro: merge (keep Pro families).
169
+ * - Free-only: replace the install root with free content.
170
+ *
171
+ * Downloads complete first — a failed download does not wipe a previous install.
110
172
  */
111
- export async function installFromRelease(release, target, root = installRoot()) {
173
+ export async function installFromRelease(release, target, root = installRoot(), options = {}) {
112
174
  if (!release.downloadReady) {
113
175
  throw new Error(release.message ||
114
176
  "Downloads are not ready on the server yet. Please try again later.");
@@ -117,6 +179,15 @@ export async function installFromRelease(release, target, root = installRoot())
117
179
  if (missingUrl.length > 0) {
118
180
  throw new Error(`Release files missing download urls: ${missingUrl.map((f) => f.id).join(", ")}`);
119
181
  }
182
+ const isFreeRelease = release.tier === "free";
183
+ const merge = options.merge ?? (isFreeRelease && existsSync(root) && hasProFamilies(root));
184
+ // Safety: free channel must never claim Pro family modules.
185
+ if (isFreeRelease) {
186
+ const forbidden = release.files.filter((f) => PRO_FAMILIES.includes(f.id));
187
+ if (forbidden.length > 0) {
188
+ throw new Error(`Free release unexpectedly included Pro modules: ${forbidden.map((f) => f.id).join(", ")}`);
189
+ }
190
+ }
120
191
  const downloadsDir = join(nucleoHomeDir(), "downloads");
121
192
  await mkdir(downloadsDir, { recursive: true });
122
193
  const downloaded = [];
@@ -150,9 +221,14 @@ export async function installFromRelease(release, target, root = installRoot())
150
221
  }
151
222
  downloaded.push({ id: file.id, zipPath });
152
223
  }
153
- // 2) Only now replace the install root
154
- console.log(" Extracting…");
155
- await cleanInstallRoot(root);
224
+ // 2) Extract — wipe unless merging free into Pro
225
+ console.log(merge ? " Merging into existing install (Pro families kept)…" : " Extracting…");
226
+ if (!merge) {
227
+ await cleanInstallRoot(root);
228
+ }
229
+ else {
230
+ await mkdir(root, { recursive: true });
231
+ }
156
232
  for (const file of downloaded) {
157
233
  const zipInfo = await stat(file.zipPath);
158
234
  process.stdout.write(` ▸ ${file.id} (${formatBytes(zipInfo.size)}) `);
@@ -172,12 +248,14 @@ export async function installFromRelease(release, target, root = installRoot())
172
248
  finally {
173
249
  await rm(downloadsDir, { recursive: true, force: true }).catch(() => undefined);
174
250
  }
251
+ const families = detectInstalledFamilies(root);
252
+ const { tier } = resolveInstallTier(root);
175
253
  await writeInstallManifest({
176
- product: release.tier === "free" ? "nucleo-skills-free" : "nucleo-skills",
177
- tier: release.tier === "free" ? "free" : "pro",
254
+ product: tier === "free" ? "nucleo-skills-free" : "nucleo-skills",
255
+ tier,
178
256
  target,
179
257
  version: release.version,
180
- families: release.families,
258
+ families,
181
259
  }, root);
182
260
  }
183
261
  /**
@@ -205,15 +283,18 @@ export async function ensureManifestTarget(target, extras = {}, root = installRo
205
283
  manifest = {};
206
284
  }
207
285
  }
286
+ const families = extras.families ?? detectInstalledFamilies(root);
287
+ const { tier: detectedTier } = resolveInstallTier(root);
208
288
  manifest = {
209
289
  ...manifest,
210
290
  ...extras,
211
291
  target: extras.target ?? manifest.target ?? target,
212
292
  version: extras.version ?? manifest.version ?? "0.0.0-local",
293
+ families,
294
+ tier: extras.tier ?? detectedTier,
295
+ product: extras.product ??
296
+ (detectedTier === "free" ? "nucleo-skills-free" : "nucleo-skills"),
213
297
  };
214
- if (extras.families) {
215
- manifest.families = extras.families;
216
- }
217
298
  await writeInstallManifest(manifest, root);
218
299
  return manifest;
219
300
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nucleoicons/skills",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "CLI to install and update Nucleo MCP + icon skills (Pro and free)",
5
5
  "type": "module",
6
6
  "bin": {