skild 0.9.1 → 0.10.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 (3) hide show
  1. package/README.md +139 -26
  2. package/dist/index.js +367 -182
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -1,46 +1,159 @@
1
- # skild
1
+ # 🛡️ skild
2
2
 
3
- The npm for Agent Skills — discover, install, manage, and publish AI Agent Skills with ease.
3
+ [![npm version](https://img.shields.io/npm/v/skild.svg?style=flat-square)](https://www.npmjs.com/package/skild)
4
+ [![License: MIT](https://img.shields.io/npm/l/skild.svg?style=flat-square)](https://opensource.org/licenses/MIT)
4
5
 
5
- ## Install
6
+ > **The npm for AI Agent Skills** — Discover, install, manage, and publish skills for Claude, Codex, Windsurf, OpenCode, Copilot & Antigravity.
7
+
8
+ ## ⚡ Quick Start
9
+
10
+ ### 1. Install the CLI
6
11
 
7
12
  ```bash
8
- npm i -g skild
13
+ npm install -g skild
9
14
  ```
10
15
 
11
- ## Usage
16
+ ### 2. Equip any skill
12
17
 
13
18
  ```bash
14
- skild --help
19
+ # From GitHub
20
+ skild install [username]/[repo]
21
+
22
+ # From Registry
23
+ skild install @[publisher]/[skill]
24
+
25
+ # By Alias
26
+ skild install [alias]
27
+ ```
28
+
29
+ ### 3. Done
30
+
31
+ ```bash
32
+ # View installed skills
33
+ skild list
34
+ ```
35
+
36
+ Your agent is now equipped with new capabilities!
37
+
38
+ > 💡 **Tip**: Use `--all` to install to all platforms at once, or `-t windsurf` to target a specific platform.
39
+
40
+ ## ✨ Features
41
+
42
+ - **Multi-Platform** — Works with Claude, Codex, Windsurf, OpenCode, Copilot, and Antigravity
43
+ - **Multiple Sources** — Install from GitHub, the Skild Registry, or local directories
44
+ - **Skillsets** — Install bundles of related skills with one command
45
+ - **Sync** — Keep skills synchronized across all your platforms
46
+ - **Publish** — Share your skills with the community via the registry
47
+
48
+ ## 📦 Installation
49
+
50
+ ```bash
51
+ # npm
52
+ npm i -g skild
53
+
54
+ # pnpm
55
+ pnpm add -g skild
56
+
57
+ # yarn
58
+ yarn global add skild
59
+
60
+ # Or run without installing
61
+ npx skild@latest --help
62
+ ```
63
+
64
+ Requires **Node.js ≥18**.
65
+
66
+ ## 🚀 Commands
67
+
68
+ | Command | Description |
69
+ |---------|-------------|
70
+ | `skild install <source>` | Install from GitHub, Registry, or local path |
71
+ | `skild list` | Show installed skills |
72
+ | `skild info <skill>` | Display skill details |
73
+ | `skild update <skill>` | Update a skill |
74
+ | `skild uninstall <skill>` | Remove a skill |
75
+ | `skild sync` | Sync skills across platforms |
76
+ | `skild search <query>` | Search the registry |
77
+ | `skild init <name>` | Create a new skill |
78
+ | `skild publish` | Publish to the registry |
15
79
 
16
- # Install a skill (Git URL / degit shorthand / local dir)
80
+ ## 📥 Installing Skills
81
+
82
+ ### From GitHub
83
+
84
+ ```bash
85
+ # Full URL
17
86
  skild install https://github.com/anthropics/skills/tree/main/skills/pdf
18
- skild install anthropics/skills/skills/pdf#main
19
- skild install ./path/to/your-skill
20
87
 
21
- # Target platform + project-level install
22
- skild install https://github.com/anthropics/skills/tree/main/skills/pdf -t codex --local
88
+ # Shorthand (degit style)
89
+ skild install anthropics/skills/skills/pdf
90
+ ```
91
+
92
+ ### From Registry
93
+
94
+ ```bash
95
+ skild install @peiiii/pdf
96
+ skild install @peiiii/pdf@1.0.0
97
+ ```
98
+
99
+ ### From Local
100
+
101
+ ```bash
102
+ skild install ./path/to/my-skill
103
+ ```
104
+
105
+ ### Options
106
+
107
+ | Option | Description |
108
+ |--------|-------------|
109
+ | `-t, --target <platform>` | Target platform (default: interactive prompt) |
110
+ | `--all` | Install to all platforms |
111
+ | `--local` | Install to project directory instead of global |
112
+ | `--force` | Overwrite existing skill |
113
+ | `-y, --yes` | Skip confirmation prompts |
114
+
115
+ ## 🎯 Supported Platforms
23
116
 
24
- # List installed skills
25
- skild list --local
117
+ | Platform | Global Path |
118
+ |----------|-------------|
119
+ | Claude | `~/.claude/skills` |
120
+ | Codex | `~/.codex/skills` |
121
+ | Windsurf | `~/.windsurf/skills` |
122
+ | OpenCode | `~/.config/opencode/skill` |
123
+ | Copilot | `~/.github/skills` |
124
+ | Antigravity | `~/.gemini/antigravity/skills` |
26
125
 
27
- # Inspect / Validate / Update / Uninstall
28
- skild info pdf -t codex --local
29
- skild validate pdf -t codex --local
30
- skild update pdf -t codex --local
31
- skild uninstall pdf -t codex --local
126
+ ## 🔄 Syncing Skills
32
127
 
33
- # Sync installed skills across platforms (auto-detect missing, tree prompt)
128
+ Auto-detect missing skills across platforms and sync them:
129
+
130
+ ```bash
131
+ # Interactive mode
34
132
  skild sync
35
133
 
36
- # Create a new Skill
37
- skild init my-skill
134
+ # Sync specific skills to specific platforms
135
+ skild sync pdf web-scraper --to codex,windsurf
136
+ ```
137
+
138
+ ## 📤 Publishing
139
+
140
+ ```bash
141
+ # Create an account
142
+ skild signup
143
+
144
+ # Login
145
+ skild login
38
146
 
39
- # Extract GitHub skills
40
- skild extract-github-skills https://github.com/ComposioHQ/awesome-claude-skills
147
+ # Publish your skill
148
+ skild publish --dir ./my-skill
41
149
  ```
42
150
 
43
- Full user guide (CLI + registry + console):
151
+ ## 📚 Resources
152
+
153
+ - **[Skild Hub](https://hub.skild.sh)** — Browse and discover skills
154
+ - **[Full Documentation](https://github.com/Peiiii/skild/tree/main/docs)** — Complete usage guide
155
+ - **[GitHub](https://github.com/Peiiii/skild)** — Source code and issues
156
+
157
+ ## 📄 License
44
158
 
45
- - `docs/usage.md`
46
- - `docs/usage.zh-CN.md`
159
+ MIT © [Skild](https://skild.sh)
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import chalk18 from "chalk";
5
+ import chalk19 from "chalk";
6
6
  import { createRequire } from "module";
7
7
 
8
8
  // src/commands/install.ts
@@ -1694,103 +1694,263 @@ async function reportDownload(record, registryOverride) {
1694
1694
  }
1695
1695
 
1696
1696
  // src/commands/list.ts
1697
- import chalk4 from "chalk";
1697
+ import chalk5 from "chalk";
1698
1698
  import { PLATFORMS as PLATFORMS3, listAllSkills, listSkills as listSkills2 } from "@skild/core";
1699
+
1700
+ // src/utils/table-utils.ts
1701
+ import chalk4 from "chalk";
1702
+ var BOX_CHARS = {
1703
+ single: {
1704
+ topLeft: "\u250C",
1705
+ topRight: "\u2510",
1706
+ bottomLeft: "\u2514",
1707
+ bottomRight: "\u2518",
1708
+ horizontal: "\u2500",
1709
+ vertical: "\u2502",
1710
+ cross: "\u253C",
1711
+ teeDown: "\u252C",
1712
+ teeUp: "\u2534",
1713
+ teeRight: "\u251C",
1714
+ teeLeft: "\u2524"
1715
+ },
1716
+ double: {
1717
+ topLeft: "\u2554",
1718
+ topRight: "\u2557",
1719
+ bottomLeft: "\u255A",
1720
+ bottomRight: "\u255D",
1721
+ horizontal: "\u2550",
1722
+ vertical: "\u2551",
1723
+ cross: "\u256C",
1724
+ teeDown: "\u2566",
1725
+ teeUp: "\u2569",
1726
+ teeRight: "\u2560",
1727
+ teeLeft: "\u2563"
1728
+ },
1729
+ rounded: {
1730
+ topLeft: "\u256D",
1731
+ topRight: "\u256E",
1732
+ bottomLeft: "\u2570",
1733
+ bottomRight: "\u256F",
1734
+ horizontal: "\u2500",
1735
+ vertical: "\u2502",
1736
+ cross: "\u253C",
1737
+ teeDown: "\u252C",
1738
+ teeUp: "\u2534",
1739
+ teeRight: "\u251C",
1740
+ teeLeft: "\u2524"
1741
+ }
1742
+ };
1743
+ function visibleLength(str) {
1744
+ return str.replace(/\u001b\[\d+m/g, "").length;
1745
+ }
1746
+ function padString(str, width, align = "left") {
1747
+ const visible = visibleLength(str);
1748
+ const padding = Math.max(0, width - visible);
1749
+ if (align === "center") {
1750
+ const leftPad = Math.floor(padding / 2);
1751
+ const rightPad = padding - leftPad;
1752
+ return " ".repeat(leftPad) + str + " ".repeat(rightPad);
1753
+ } else if (align === "right") {
1754
+ return " ".repeat(padding) + str;
1755
+ } else {
1756
+ return str + " ".repeat(padding);
1757
+ }
1758
+ }
1759
+ function truncateString(str, maxWidth) {
1760
+ const visible = visibleLength(str);
1761
+ if (visible <= maxWidth) return str;
1762
+ const plain = str.replace(/\u001b\[\d+m/g, "");
1763
+ return plain.slice(0, maxWidth - 1) + "\u2026";
1764
+ }
1765
+ function renderBorder(columns, chars, type) {
1766
+ const left = type === "top" ? chars.topLeft : type === "bottom" ? chars.bottomLeft : chars.teeRight;
1767
+ const right = type === "top" ? chars.topRight : type === "bottom" ? chars.bottomRight : chars.teeLeft;
1768
+ const junction = type === "top" ? chars.teeDown : type === "bottom" ? chars.teeUp : chars.cross;
1769
+ const segments = columns.map((col) => chars.horizontal.repeat(col.width + 2));
1770
+ return left + segments.join(junction) + right;
1771
+ }
1772
+ function renderRow(cells, columns, chars) {
1773
+ const paddedCells = cells.map((cell, i) => {
1774
+ const col = columns[i];
1775
+ if (!col) return "";
1776
+ const truncated = truncateString(cell, col.width);
1777
+ return " " + padString(truncated, col.width, col.align || "left") + " ";
1778
+ });
1779
+ return chars.vertical + paddedCells.join(chars.vertical) + chars.vertical;
1780
+ }
1781
+ function renderTable(options) {
1782
+ const { columns, rows, borderStyle = "rounded" } = options;
1783
+ const chars = BOX_CHARS[borderStyle];
1784
+ const lines = [];
1785
+ lines.push(renderBorder(columns, chars, "top"));
1786
+ const headerCells = columns.map((col) => chalk4.bold(col.header));
1787
+ lines.push(renderRow(headerCells, columns, chars));
1788
+ lines.push(renderBorder(columns, chars, "middle"));
1789
+ for (let i = 0; i < rows.length; i++) {
1790
+ const row = rows[i];
1791
+ if (row.style === "separator") {
1792
+ lines.push(renderBorder(columns, chars, "middle"));
1793
+ } else if (row.style === "header") {
1794
+ const cells = row.cells.map((cell) => chalk4.bold(cell));
1795
+ lines.push(renderRow(cells, columns, chars));
1796
+ } else {
1797
+ lines.push(renderRow(row.cells, columns, chars));
1798
+ }
1799
+ }
1800
+ lines.push(renderBorder(columns, chars, "bottom"));
1801
+ return lines.join("\n");
1802
+ }
1803
+ var TableBuilder = class {
1804
+ columns = [];
1805
+ rows = [];
1806
+ borderStyle = "rounded";
1807
+ addColumn(header, width, align) {
1808
+ this.columns.push({ header, width, align });
1809
+ return this;
1810
+ }
1811
+ addRow(cells, style) {
1812
+ this.rows.push({ cells, style });
1813
+ return this;
1814
+ }
1815
+ addSeparator() {
1816
+ this.rows.push({ cells: [], style: "separator" });
1817
+ return this;
1818
+ }
1819
+ addHeaderRow(cells) {
1820
+ this.rows.push({ cells, style: "header" });
1821
+ return this;
1822
+ }
1823
+ setBorderStyle(style) {
1824
+ this.borderStyle = style;
1825
+ return this;
1826
+ }
1827
+ render() {
1828
+ return renderTable({
1829
+ columns: this.columns,
1830
+ rows: this.rows,
1831
+ borderStyle: this.borderStyle
1832
+ });
1833
+ }
1834
+ };
1835
+
1836
+ // src/commands/list.ts
1837
+ var PLATFORM_ABBREV = {
1838
+ claude: "Claude",
1839
+ codex: "Codex",
1840
+ copilot: "Copilot",
1841
+ cursor: "Cursor",
1842
+ antigravity: "Antigrav",
1843
+ opencode: "OpenCode",
1844
+ windsurf: "Windsurf"
1845
+ };
1699
1846
  function isSkillset(skill) {
1700
1847
  return Boolean(skill.record?.skillset || skill.record?.skill?.frontmatter?.skillset);
1701
1848
  }
1702
1849
  function getDisplayName(skill) {
1703
1850
  return skill.record?.canonicalName || skill.record?.skill?.frontmatter?.name || skill.name;
1704
1851
  }
1705
- function buildNameToDisplay(skills) {
1706
- const mapping = /* @__PURE__ */ new Map();
1707
- for (const skill of skills) {
1708
- mapping.set(skill.name, getDisplayName(skill));
1709
- }
1710
- return mapping;
1711
- }
1712
- function statusIcon(skill) {
1713
- return skill.hasSkillMd ? chalk4.green("\u2713") : chalk4.yellow("\u26A0");
1714
- }
1715
- function missingSkillMdLabel(skill) {
1716
- return skill.hasSkillMd ? "" : chalk4.yellow(" (missing SKILL.md)");
1717
- }
1718
- function formatDepName(dep, nameToDisplay) {
1719
- return dep.canonicalName || nameToDisplay.get(dep.name) || dep.name;
1720
- }
1721
- function printSkillsetSection(skills, nameToDisplay, options) {
1722
- console.log(chalk4.bold(` \u{1F4E6} Skillsets`) + chalk4.dim(` (${skills.length})`));
1723
- if (skills.length === 0) {
1724
- console.log(chalk4.dim(" No skillsets"));
1725
- return;
1852
+ function buildSkillMatrix(allSkills) {
1853
+ const skillMap = /* @__PURE__ */ new Map();
1854
+ for (const skill of allSkills) {
1855
+ const name = skill.name;
1856
+ if (!skillMap.has(name)) {
1857
+ skillMap.set(name, {
1858
+ name,
1859
+ displayName: getDisplayName(skill),
1860
+ isSkillset: isSkillset(skill),
1861
+ isDependency: Boolean(skill.record?.dependedBy?.length),
1862
+ platforms: /* @__PURE__ */ new Map(),
1863
+ dependencies: skill.record?.installedDependencies?.map((d) => d.name),
1864
+ dependedBy: skill.record?.dependedBy,
1865
+ indent: 0
1866
+ });
1867
+ }
1868
+ const row = skillMap.get(name);
1869
+ row.platforms.set(skill.platform, {
1870
+ installed: true,
1871
+ hasSkillMd: skill.hasSkillMd
1872
+ });
1726
1873
  }
1727
- for (const s of skills) {
1728
- const depsCount = s.record?.installedDependencies?.length || 0;
1729
- const depsSuffix = depsCount > 0 ? chalk4.dim(` \u2192 ${depsCount} deps`) : "";
1730
- console.log(` ${statusIcon(s)} ${chalk4.cyan(getDisplayName(s))}${depsSuffix}${missingSkillMdLabel(s)}`);
1731
- if (options.verbose) {
1732
- const deps = (s.record?.installedDependencies || []).slice().sort((a, b) => a.name.localeCompare(b.name));
1874
+ const rows = Array.from(skillMap.values());
1875
+ const skillsets = rows.filter((r) => r.isSkillset).sort((a, b) => a.displayName.localeCompare(b.displayName));
1876
+ const dependencies = rows.filter((r) => !r.isSkillset && r.isDependency).sort((a, b) => a.displayName.localeCompare(b.displayName));
1877
+ const regular = rows.filter((r) => !r.isSkillset && !r.isDependency).sort((a, b) => a.displayName.localeCompare(b.displayName));
1878
+ const result = [];
1879
+ for (const skillset of skillsets) {
1880
+ result.push(skillset);
1881
+ if (skillset.dependencies && skillset.dependencies.length > 0) {
1882
+ const deps = skillset.dependencies.map((depName) => skillMap.get(depName)).filter((dep) => dep !== void 0).sort((a, b) => a.displayName.localeCompare(b.displayName));
1733
1883
  for (const dep of deps) {
1734
- const depName = formatDepName(dep, nameToDisplay);
1735
- console.log(chalk4.dim(` \u2022 ${depName}`));
1884
+ result.push({ ...dep, indent: 1 });
1736
1885
  }
1737
1886
  }
1738
- if (options.paths || !s.hasSkillMd) console.log(chalk4.dim(` \u2514\u2500 ${s.installDir}`));
1739
1887
  }
1888
+ result.push(...regular);
1889
+ result.push(...dependencies);
1890
+ return result;
1740
1891
  }
1741
- function printSkillsSection(skills, options) {
1742
- console.log(chalk4.bold(` \u26A1 Skills`) + chalk4.dim(` (${skills.length})`));
1743
- if (skills.length === 0) {
1744
- console.log(chalk4.dim(" No skills"));
1745
- return;
1746
- }
1747
- for (const s of skills) {
1748
- console.log(` ${statusIcon(s)} ${chalk4.cyan(getDisplayName(s))}${missingSkillMdLabel(s)}`);
1749
- if (options.paths || !s.hasSkillMd) console.log(chalk4.dim(` \u2514\u2500 ${s.installDir}`));
1750
- }
1892
+ function renderStatusIcon(status) {
1893
+ if (!status || !status.installed) return chalk5.dim("-");
1894
+ if (!status.hasSkillMd) return chalk5.yellow("\u26A0");
1895
+ return chalk5.green("\u2713");
1751
1896
  }
1752
- function printDependenciesSection(skills, nameToDisplay, options) {
1753
- console.log(chalk4.bold(` \u{1F517} Dependencies`) + chalk4.dim(` (${skills.length})`));
1754
- if (skills.length === 0) {
1755
- console.log(chalk4.dim(" No dependencies"));
1897
+ function renderTableView(allSkills, scope, options) {
1898
+ if (allSkills.length === 0) {
1899
+ console.log(chalk5.dim("\nNo skills installed."));
1900
+ console.log(chalk5.dim(`\u{1F4A1} Use ${chalk5.cyan("skild install <source>")} to get started.
1901
+ `));
1756
1902
  return;
1757
1903
  }
1758
- for (const s of skills) {
1759
- const dependedBy = (s.record?.dependedBy || []).map((name) => nameToDisplay.get(name) || name).sort((a, b) => a.localeCompare(b));
1760
- const requiredBy = dependedBy.length ? chalk4.dim(` \u2190 ${dependedBy.join(", ")}`) : "";
1761
- console.log(` ${statusIcon(s)} ${chalk4.cyan(getDisplayName(s))}${requiredBy}${missingSkillMdLabel(s)}`);
1762
- if (options.paths || !s.hasSkillMd) console.log(chalk4.dim(` \u2514\u2500 ${s.installDir}`));
1763
- }
1764
- }
1765
- function printPlatform(skills, platform, scope, options) {
1766
- const platformLabel = platform.charAt(0).toUpperCase() + platform.slice(1);
1767
- console.log(chalk4.bold(`
1768
- ${platformLabel}`) + chalk4.dim(` (${scope}, ${skills.length} total)`));
1769
- if (skills.length === 0) {
1770
- console.log(chalk4.dim(" No skills installed."));
1771
- console.log(chalk4.dim(` \u{1F4A1} Use ${chalk4.cyan("skild install <source>")} to get started.`));
1772
- return;
1904
+ const matrix = buildSkillMatrix(allSkills);
1905
+ const activePlatforms = PLATFORMS3.filter((p) => allSkills.some((s) => s.platform === p));
1906
+ const table = new TableBuilder();
1907
+ table.addColumn("Skill", 30, "left");
1908
+ for (const platform of activePlatforms) {
1909
+ table.addColumn(PLATFORM_ABBREV[platform] || platform, 9, "center");
1773
1910
  }
1774
- const nameToDisplay = buildNameToDisplay(skills);
1775
- const skillsets = skills.filter(isSkillset).sort((a, b) => getDisplayName(a).localeCompare(getDisplayName(b)));
1776
- const dependencies = skills.filter((s) => !isSkillset(s) && Boolean(s.record?.dependedBy?.length)).sort((a, b) => getDisplayName(a).localeCompare(getDisplayName(b)));
1777
- const regular = skills.filter((s) => !isSkillset(s) && !Boolean(s.record?.dependedBy?.length)).sort((a, b) => getDisplayName(a).localeCompare(getDisplayName(b)));
1911
+ const skillsets = matrix.filter((r) => r.isSkillset && r.indent === 0);
1912
+ const skillsetDeps = matrix.filter((r) => r.indent > 0);
1913
+ const regular = matrix.filter((r) => !r.isSkillset && !r.isDependency && r.indent === 0);
1778
1914
  if (skillsets.length > 0) {
1779
- printSkillsetSection(skillsets, nameToDisplay, options);
1915
+ const sectionHeader = [`${chalk5.bold("\u{1F4E6} SKILLSETS")} ${chalk5.dim(`(${skillsets.length})`)}`, ...activePlatforms.map(() => "")];
1916
+ table.addHeaderRow(sectionHeader);
1917
+ for (const row of skillsets) {
1918
+ const nameCell = chalk5.cyan(row.displayName);
1919
+ const statusCells = activePlatforms.map((p) => renderStatusIcon(row.platforms.get(p)));
1920
+ table.addRow([nameCell, ...statusCells]);
1921
+ if (options.verbose && row.dependencies) {
1922
+ const deps = matrix.filter((r) => r.indent > 0 && row.dependencies?.includes(r.name));
1923
+ for (const dep of deps) {
1924
+ const depName = chalk5.dim(` \u251C\u2500 ${dep.displayName}`);
1925
+ const depStatus = activePlatforms.map((p) => {
1926
+ const status = dep.platforms.get(p);
1927
+ return status?.installed ? chalk5.dim("\u2022") : chalk5.dim("-");
1928
+ });
1929
+ table.addRow([depName, ...depStatus]);
1930
+ }
1931
+ }
1932
+ }
1780
1933
  }
1781
1934
  if (regular.length > 0) {
1782
- console.log("");
1783
- printSkillsSection(regular, options);
1784
- }
1785
- if (dependencies.length > 0) {
1786
- console.log("");
1787
- printDependenciesSection(dependencies, nameToDisplay, options);
1935
+ if (skillsets.length > 0) table.addSeparator();
1936
+ const sectionHeader = [`${chalk5.bold("\u26A1 SKILLS")} ${chalk5.dim(`(${regular.length})`)}`, ...activePlatforms.map(() => "")];
1937
+ table.addHeaderRow(sectionHeader);
1938
+ for (const row of regular) {
1939
+ const nameCell = chalk5.cyan(row.displayName);
1940
+ const statusCells = activePlatforms.map((p) => renderStatusIcon(row.platforms.get(p)));
1941
+ table.addRow([nameCell, ...statusCells]);
1942
+ }
1788
1943
  }
1789
1944
  console.log("");
1945
+ console.log(table.render());
1946
+ const totalSkills = new Set(matrix.map((r) => r.name)).size;
1947
+ const totalInstalls = allSkills.length;
1948
+ console.log("");
1949
+ console.log(chalk5.dim(`Summary: ${totalSkills} unique skill${totalSkills === 1 ? "" : "s"}, ${totalInstalls} total installation${totalInstalls === 1 ? "" : "s"} across ${activePlatforms.length} platform${activePlatforms.length === 1 ? "" : "s"} (${scope})`));
1950
+ console.log("");
1790
1951
  }
1791
1952
  async function list(options = {}) {
1792
1953
  const scope = options.local ? "project" : "global";
1793
- const paths = Boolean(options.paths);
1794
1954
  const verbose = Boolean(options.verbose);
1795
1955
  const platform = options.target;
1796
1956
  if (platform) {
@@ -1799,7 +1959,42 @@ async function list(options = {}) {
1799
1959
  console.log(JSON.stringify(skills, null, 2));
1800
1960
  return;
1801
1961
  }
1802
- printPlatform(skills, platform, scope, { paths, verbose });
1962
+ console.log(chalk5.bold(`
1963
+ ${PLATFORM_ABBREV[platform] || platform}`) + chalk5.dim(` (${scope}, ${skills.length} total)`));
1964
+ if (skills.length === 0) {
1965
+ console.log(chalk5.dim(" No skills installed."));
1966
+ console.log(chalk5.dim(` \u{1F4A1} Use ${chalk5.cyan("skild install <source>")} to get started.
1967
+ `));
1968
+ return;
1969
+ }
1970
+ const skillsets = skills.filter(isSkillset).sort((a, b) => getDisplayName(a).localeCompare(getDisplayName(b)));
1971
+ const regular = skills.filter((s) => !isSkillset(s) && !s.record?.dependedBy?.length).sort((a, b) => getDisplayName(a).localeCompare(getDisplayName(b)));
1972
+ const dependencies = skills.filter((s) => !isSkillset(s) && s.record?.dependedBy?.length).sort((a, b) => getDisplayName(a).localeCompare(getDisplayName(b)));
1973
+ if (skillsets.length > 0) {
1974
+ console.log(chalk5.bold(` \u{1F4E6} Skillsets`) + chalk5.dim(` (${skillsets.length})`));
1975
+ for (const s of skillsets) {
1976
+ const icon = s.hasSkillMd ? chalk5.green("\u2713") : chalk5.yellow("\u26A0");
1977
+ console.log(` ${icon} ${chalk5.cyan(getDisplayName(s))}`);
1978
+ }
1979
+ }
1980
+ if (regular.length > 0) {
1981
+ console.log("");
1982
+ console.log(chalk5.bold(` \u26A1 Skills`) + chalk5.dim(` (${regular.length})`));
1983
+ for (const s of regular) {
1984
+ const icon = s.hasSkillMd ? chalk5.green("\u2713") : chalk5.yellow("\u26A0");
1985
+ console.log(` ${icon} ${chalk5.cyan(getDisplayName(s))}`);
1986
+ }
1987
+ }
1988
+ if (dependencies.length > 0) {
1989
+ console.log("");
1990
+ console.log(chalk5.bold(` \u{1F517} Dependencies`) + chalk5.dim(` (${dependencies.length})`));
1991
+ for (const s of dependencies) {
1992
+ const icon = s.hasSkillMd ? chalk5.green("\u2713") : chalk5.yellow("\u26A0");
1993
+ const requiredBy = s.record?.dependedBy?.join(", ") || "";
1994
+ console.log(` ${icon} ${chalk5.cyan(getDisplayName(s))}${requiredBy ? chalk5.dim(` \u2190 ${requiredBy}`) : ""}`);
1995
+ }
1996
+ }
1997
+ console.log("");
1803
1998
  return;
1804
1999
  }
1805
2000
  const allSkills = listAllSkills({ scope });
@@ -1807,21 +2002,11 @@ async function list(options = {}) {
1807
2002
  console.log(JSON.stringify(allSkills, null, 2));
1808
2003
  return;
1809
2004
  }
1810
- if (allSkills.length === 0) {
1811
- console.log(chalk4.dim("\nNo skills installed."));
1812
- console.log(chalk4.dim(`\u{1F4A1} Use ${chalk4.cyan("skild install <source>")} to get started.
1813
- `));
1814
- return;
1815
- }
1816
- for (const p of PLATFORMS3) {
1817
- const platformSkills = allSkills.filter((s) => s.platform === p).sort((a, b) => a.name.localeCompare(b.name));
1818
- if (platformSkills.length === 0) continue;
1819
- printPlatform(platformSkills, p, scope, { paths, verbose });
1820
- }
2005
+ renderTableView(allSkills, scope, { verbose });
1821
2006
  }
1822
2007
 
1823
2008
  // src/commands/info.ts
1824
- import chalk5 from "chalk";
2009
+ import chalk6 from "chalk";
1825
2010
  import { canonicalNameToInstallDirName, getSkillInfo, SkildError as SkildError2 } from "@skild/core";
1826
2011
  async function info(skill, options = {}) {
1827
2012
  const platform = options.target || "claude";
@@ -1834,22 +2019,22 @@ async function info(skill, options = {}) {
1834
2019
  return;
1835
2020
  }
1836
2021
  const displayName = record.canonicalName || record.name;
1837
- console.log(chalk5.bold(`
1838
- ${chalk5.cyan(displayName)}
2022
+ console.log(chalk6.bold(`
2023
+ ${chalk6.cyan(displayName)}
1839
2024
  `));
1840
- console.log(` ${chalk5.dim("Path:")} ${record.installDir}`);
1841
- console.log(` ${chalk5.dim("Source:")} ${record.source}`);
1842
- console.log(` ${chalk5.dim("Target:")} ${record.platform} (${record.scope})`);
1843
- console.log(` ${chalk5.dim("Installed:")} ${record.installedAt}`);
1844
- if (record.updatedAt) console.log(` ${chalk5.dim("Updated:")} ${record.updatedAt}`);
1845
- console.log(` ${chalk5.dim("Hash:")} ${record.contentHash}`);
1846
- console.log(` ${chalk5.dim("SKILL.md:")} ${record.hasSkillMd ? chalk5.green("yes") : chalk5.yellow("no")}`);
2025
+ console.log(` ${chalk6.dim("Path:")} ${record.installDir}`);
2026
+ console.log(` ${chalk6.dim("Source:")} ${record.source}`);
2027
+ console.log(` ${chalk6.dim("Target:")} ${record.platform} (${record.scope})`);
2028
+ console.log(` ${chalk6.dim("Installed:")} ${record.installedAt}`);
2029
+ if (record.updatedAt) console.log(` ${chalk6.dim("Updated:")} ${record.updatedAt}`);
2030
+ console.log(` ${chalk6.dim("Hash:")} ${record.contentHash}`);
2031
+ console.log(` ${chalk6.dim("SKILL.md:")} ${record.hasSkillMd ? chalk6.green("yes") : chalk6.yellow("no")}`);
1847
2032
  const validation = record.skill?.validation;
1848
2033
  if (validation) {
1849
- console.log(` ${chalk5.dim("Validate:")} ${validation.ok ? chalk5.green("ok") : chalk5.red("failed")}`);
2034
+ console.log(` ${chalk6.dim("Validate:")} ${validation.ok ? chalk6.green("ok") : chalk6.red("failed")}`);
1850
2035
  if (!validation.ok) {
1851
2036
  for (const issue of validation.issues) {
1852
- const color = issue.level === "error" ? chalk5.red : chalk5.yellow;
2037
+ const color = issue.level === "error" ? chalk6.red : chalk6.yellow;
1853
2038
  console.log(` - ${color(issue.level)}: ${issue.message}`);
1854
2039
  }
1855
2040
  }
@@ -1857,20 +2042,20 @@ ${chalk5.cyan(displayName)}
1857
2042
  console.log("");
1858
2043
  } catch (error) {
1859
2044
  const message = error instanceof SkildError2 ? error.message : error instanceof Error ? error.message : String(error);
1860
- console.error(chalk5.red(message));
2045
+ console.error(chalk6.red(message));
1861
2046
  process.exitCode = 1;
1862
2047
  }
1863
2048
  }
1864
2049
 
1865
2050
  // src/commands/uninstall.ts
1866
- import chalk6 from "chalk";
2051
+ import chalk7 from "chalk";
1867
2052
  import { canonicalNameToInstallDirName as canonicalNameToInstallDirName2, uninstallSkill, SkildError as SkildError3 } from "@skild/core";
1868
2053
  async function uninstall(skill, options = {}) {
1869
2054
  const platform = options.target || "claude";
1870
2055
  const scope = options.local ? "project" : "global";
1871
2056
  const canonical = skill.trim();
1872
2057
  const resolvedName = canonical.startsWith("@") && canonical.includes("/") ? canonicalNameToInstallDirName2(canonical) : canonical;
1873
- const spinner = createSpinner(`Uninstalling ${chalk6.cyan(canonical)} from ${chalk6.dim(platform)} (${scope})...`);
2058
+ const spinner = createSpinner(`Uninstalling ${chalk7.cyan(canonical)} from ${chalk7.dim(platform)} (${scope})...`);
1874
2059
  try {
1875
2060
  uninstallSkill(resolvedName, {
1876
2061
  platform,
@@ -1878,40 +2063,40 @@ async function uninstall(skill, options = {}) {
1878
2063
  allowMissingMetadata: Boolean(options.force),
1879
2064
  withDeps: Boolean(options.withDeps)
1880
2065
  });
1881
- spinner.succeed(`Uninstalled ${chalk6.green(canonical)}`);
2066
+ spinner.succeed(`Uninstalled ${chalk7.green(canonical)}`);
1882
2067
  } catch (error) {
1883
- spinner.fail(`Failed to uninstall ${chalk6.red(canonical)}`);
2068
+ spinner.fail(`Failed to uninstall ${chalk7.red(canonical)}`);
1884
2069
  const message = error instanceof SkildError3 ? error.message : error instanceof Error ? error.message : String(error);
1885
- console.error(chalk6.red(message));
2070
+ console.error(chalk7.red(message));
1886
2071
  process.exitCode = 1;
1887
2072
  }
1888
2073
  }
1889
2074
 
1890
2075
  // src/commands/update.ts
1891
- import chalk7 from "chalk";
2076
+ import chalk8 from "chalk";
1892
2077
  import { canonicalNameToInstallDirName as canonicalNameToInstallDirName3, updateSkill, SkildError as SkildError4 } from "@skild/core";
1893
2078
  async function update(skill, options = {}) {
1894
2079
  const platform = options.target || "claude";
1895
2080
  const scope = options.local ? "project" : "global";
1896
2081
  const label = skill ? skill : "all skills";
1897
2082
  const resolvedName = skill && skill.trim().startsWith("@") && skill.includes("/") ? canonicalNameToInstallDirName3(skill.trim()) : skill;
1898
- const spinner = createSpinner(`Updating ${chalk7.cyan(label)} on ${chalk7.dim(platform)} (${scope})...`);
2083
+ const spinner = createSpinner(`Updating ${chalk8.cyan(label)} on ${chalk8.dim(platform)} (${scope})...`);
1899
2084
  try {
1900
2085
  const results = await updateSkill(resolvedName, { platform, scope });
1901
- spinner.succeed(`Updated ${chalk7.green(results.length.toString())} skill(s).`);
2086
+ spinner.succeed(`Updated ${chalk8.green(results.length.toString())} skill(s).`);
1902
2087
  if (options.json) {
1903
2088
  console.log(JSON.stringify(results, null, 2));
1904
2089
  }
1905
2090
  } catch (error) {
1906
- spinner.fail(`Failed to update ${chalk7.red(label)}`);
2091
+ spinner.fail(`Failed to update ${chalk8.red(label)}`);
1907
2092
  const message = error instanceof SkildError4 ? error.message : error instanceof Error ? error.message : String(error);
1908
- console.error(chalk7.red(message));
2093
+ console.error(chalk8.red(message));
1909
2094
  process.exitCode = 1;
1910
2095
  }
1911
2096
  }
1912
2097
 
1913
2098
  // src/commands/validate.ts
1914
- import chalk8 from "chalk";
2099
+ import chalk9 from "chalk";
1915
2100
  import { canonicalNameToInstallDirName as canonicalNameToInstallDirName4, validateSkill } from "@skild/core";
1916
2101
  async function validate(target, options = {}) {
1917
2102
  const platform = options.target || "claude";
@@ -1925,41 +2110,41 @@ async function validate(target, options = {}) {
1925
2110
  return;
1926
2111
  }
1927
2112
  if (result.ok) {
1928
- console.log(chalk8.green("\u2713"), "Valid skill");
1929
- if (result.frontmatter?.name) console.log(chalk8.dim(` name: ${result.frontmatter.name}`));
2113
+ console.log(chalk9.green("\u2713"), "Valid skill");
2114
+ if (result.frontmatter?.name) console.log(chalk9.dim(` name: ${result.frontmatter.name}`));
1930
2115
  return;
1931
2116
  }
1932
- console.error(chalk8.red("\u2717"), "Invalid skill");
2117
+ console.error(chalk9.red("\u2717"), "Invalid skill");
1933
2118
  for (const issue of result.issues) {
1934
- const color = issue.level === "error" ? chalk8.red : chalk8.yellow;
2119
+ const color = issue.level === "error" ? chalk9.red : chalk9.yellow;
1935
2120
  console.error(` - ${color(issue.level)}: ${issue.message}`);
1936
2121
  }
1937
2122
  process.exitCode = 1;
1938
2123
  }
1939
2124
 
1940
2125
  // src/commands/init.ts
1941
- import chalk9 from "chalk";
2126
+ import chalk10 from "chalk";
1942
2127
  import { initSkill, SkildError as SkildError5 } from "@skild/core";
1943
2128
  async function init(name, options = {}) {
1944
- const spinner = createSpinner(`Initializing ${chalk9.cyan(name)}...`);
2129
+ const spinner = createSpinner(`Initializing ${chalk10.cyan(name)}...`);
1945
2130
  try {
1946
2131
  const createdDir = initSkill(name, {
1947
2132
  dir: options.dir,
1948
2133
  description: options.description,
1949
2134
  force: Boolean(options.force)
1950
2135
  });
1951
- spinner.succeed(`Created ${chalk9.green(name)} at ${chalk9.dim(createdDir)}`);
1952
- console.log(chalk9.dim(`Next: cd ${createdDir} && skild validate .`));
2136
+ spinner.succeed(`Created ${chalk10.green(name)} at ${chalk10.dim(createdDir)}`);
2137
+ console.log(chalk10.dim(`Next: cd ${createdDir} && skild validate .`));
1953
2138
  } catch (error) {
1954
- spinner.fail(`Failed to init ${chalk9.red(name)}`);
2139
+ spinner.fail(`Failed to init ${chalk10.red(name)}`);
1955
2140
  const message = error instanceof SkildError5 ? error.message : error instanceof Error ? error.message : String(error);
1956
- console.error(chalk9.red(message));
2141
+ console.error(chalk10.red(message));
1957
2142
  process.exitCode = 1;
1958
2143
  }
1959
2144
  }
1960
2145
 
1961
2146
  // src/commands/signup.ts
1962
- import chalk10 from "chalk";
2147
+ import chalk11 from "chalk";
1963
2148
  import { fetchWithTimeout as fetchWithTimeout3, resolveRegistryUrl as resolveRegistryUrl2, SkildError as SkildError6 } from "@skild/core";
1964
2149
 
1965
2150
  // src/utils/prompt.ts
@@ -2028,7 +2213,7 @@ async function signup(options) {
2028
2213
  const handle = options.handle?.trim() || "";
2029
2214
  const password = options.password || "";
2030
2215
  if ((!email || !handle || !password) && (!interactive || options.json)) {
2031
- console.error(chalk10.red("Missing signup fields. Use --email/--handle/--password, or run `skild signup` interactively."));
2216
+ console.error(chalk11.red("Missing signup fields. Use --email/--handle/--password, or run `skild signup` interactively."));
2032
2217
  process.exitCode = 1;
2033
2218
  return;
2034
2219
  }
@@ -2063,13 +2248,13 @@ async function signup(options) {
2063
2248
  );
2064
2249
  text = await res.text();
2065
2250
  if (!res.ok) {
2066
- console.error(chalk10.red(`Signup failed (${res.status}): ${text}`));
2251
+ console.error(chalk11.red(`Signup failed (${res.status}): ${text}`));
2067
2252
  process.exitCode = 1;
2068
2253
  return;
2069
2254
  }
2070
2255
  } catch (error) {
2071
2256
  const message = error instanceof SkildError6 ? error.message : error instanceof Error ? error.message : String(error);
2072
- console.error(chalk10.red(`Signup failed: ${message}`));
2257
+ console.error(chalk11.red(`Signup failed: ${message}`));
2073
2258
  process.exitCode = 1;
2074
2259
  return;
2075
2260
  }
@@ -2077,29 +2262,29 @@ async function signup(options) {
2077
2262
  console.log(text || JSON.stringify({ ok: true }, null, 2));
2078
2263
  return;
2079
2264
  }
2080
- console.log(chalk10.green("Signup successful."));
2265
+ console.log(chalk11.green("Signup successful."));
2081
2266
  try {
2082
2267
  const parsed = JSON.parse(text);
2083
2268
  if (parsed.verification?.requiredForPublish) {
2084
2269
  if (parsed.verification.mode === "log") {
2085
- console.log(chalk10.dim("Dev mode: email sending is disabled. Check the registry dev logs for the verification link."));
2270
+ console.log(chalk11.dim("Dev mode: email sending is disabled. Check the registry dev logs for the verification link."));
2086
2271
  } else if (parsed.verification.sent) {
2087
- console.log(chalk10.dim("Verification email sent. Check your inbox (and spam)."));
2272
+ console.log(chalk11.dim("Verification email sent. Check your inbox (and spam)."));
2088
2273
  } else {
2089
- console.log(chalk10.yellow("Verification email was not sent. You may need to resend from the Skild Hub."));
2274
+ console.log(chalk11.yellow("Verification email was not sent. You may need to resend from the Skild Hub."));
2090
2275
  }
2091
- console.log(chalk10.dim(`Verify/resend in Skild Hub: ${(parsed.verification.consoleUrl || "https://hub.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
2276
+ console.log(chalk11.dim(`Verify/resend in Skild Hub: ${(parsed.verification.consoleUrl || "https://hub.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
2092
2277
  } else if (parsed.verification) {
2093
- console.log(chalk10.dim("Email verification is recommended. Publishing may be restricted in the future."));
2094
- console.log(chalk10.dim(`Verify/resend in Skild Hub: ${(parsed.verification.consoleUrl || "https://hub.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
2278
+ console.log(chalk11.dim("Email verification is recommended. Publishing may be restricted in the future."));
2279
+ console.log(chalk11.dim(`Verify/resend in Skild Hub: ${(parsed.verification.consoleUrl || "https://hub.skild.sh").replace(/\/+$/, "")}/verify-email/request`));
2095
2280
  }
2096
2281
  } catch {
2097
2282
  }
2098
- console.log(chalk10.dim("Next: run `skild login`"));
2283
+ console.log(chalk11.dim("Next: run `skild login`"));
2099
2284
  }
2100
2285
 
2101
2286
  // src/commands/login.ts
2102
- import chalk11 from "chalk";
2287
+ import chalk12 from "chalk";
2103
2288
  import { fetchWithTimeout as fetchWithTimeout4, resolveRegistryUrl as resolveRegistryUrl3, saveRegistryAuth, SkildError as SkildError7 } from "@skild/core";
2104
2289
  async function login(options) {
2105
2290
  const registry = resolveRegistryUrl3(options.registry);
@@ -2107,7 +2292,7 @@ async function login(options) {
2107
2292
  const handleOrEmail = options.handleOrEmail?.trim() || "";
2108
2293
  const password = options.password || "";
2109
2294
  if ((!handleOrEmail || !password) && (!interactive || options.json)) {
2110
- console.error(chalk11.red("Missing credentials. Use --handle-or-email and --password, or run `skild login` interactively."));
2295
+ console.error(chalk12.red("Missing credentials. Use --handle-or-email and --password, or run `skild login` interactively."));
2111
2296
  process.exitCode = 1;
2112
2297
  return;
2113
2298
  }
@@ -2142,13 +2327,13 @@ async function login(options) {
2142
2327
  );
2143
2328
  text = await res.text();
2144
2329
  if (!res.ok) {
2145
- console.error(chalk11.red(`Login failed (${res.status}): ${text}`));
2330
+ console.error(chalk12.red(`Login failed (${res.status}): ${text}`));
2146
2331
  process.exitCode = 1;
2147
2332
  return;
2148
2333
  }
2149
2334
  } catch (error) {
2150
2335
  const message = error instanceof SkildError7 ? error.message : error instanceof Error ? error.message : String(error);
2151
- console.error(chalk11.red(`Login failed: ${message}`));
2336
+ console.error(chalk12.red(`Login failed: ${message}`));
2152
2337
  process.exitCode = 1;
2153
2338
  return;
2154
2339
  }
@@ -2164,28 +2349,28 @@ async function login(options) {
2164
2349
  console.log(JSON.stringify({ ok: true, publisher: json.publisher }, null, 2));
2165
2350
  return;
2166
2351
  }
2167
- console.log(chalk11.green(`Logged in as ${chalk11.cyan(json.publisher.handle)}.`));
2352
+ console.log(chalk12.green(`Logged in as ${chalk12.cyan(json.publisher.handle)}.`));
2168
2353
  if (json.publisher.emailVerified === false) {
2169
- console.log(chalk11.yellow("Email not verified. Publishing may be restricted by server policy."));
2170
- console.log(chalk11.dim("Open the Skild Hub to verify: https://hub.skild.sh/verify-email/request"));
2354
+ console.log(chalk12.yellow("Email not verified. Publishing may be restricted by server policy."));
2355
+ console.log(chalk12.dim("Open the Skild Hub to verify: https://hub.skild.sh/verify-email/request"));
2171
2356
  }
2172
2357
  }
2173
2358
 
2174
2359
  // src/commands/logout.ts
2175
- import chalk12 from "chalk";
2360
+ import chalk13 from "chalk";
2176
2361
  import { clearRegistryAuth } from "@skild/core";
2177
2362
  async function logout() {
2178
2363
  clearRegistryAuth();
2179
- console.log(chalk12.green("Logged out."));
2364
+ console.log(chalk13.green("Logged out."));
2180
2365
  }
2181
2366
 
2182
2367
  // src/commands/whoami.ts
2183
- import chalk13 from "chalk";
2368
+ import chalk14 from "chalk";
2184
2369
  import { fetchWithTimeout as fetchWithTimeout5, loadRegistryAuth as loadRegistryAuth2, resolveRegistryUrl as resolveRegistryUrl4, SkildError as SkildError8 } from "@skild/core";
2185
2370
  async function whoami() {
2186
2371
  const auth = loadRegistryAuth2();
2187
2372
  if (!auth) {
2188
- console.error(chalk13.red("Not logged in. Run `skild login` first."));
2373
+ console.error(chalk14.red("Not logged in. Run `skild login` first."));
2189
2374
  process.exitCode = 1;
2190
2375
  return;
2191
2376
  }
@@ -2198,16 +2383,16 @@ async function whoami() {
2198
2383
  );
2199
2384
  const text = await res.text();
2200
2385
  if (!res.ok) {
2201
- console.error(chalk13.red(`whoami failed (${res.status}): ${text}`));
2386
+ console.error(chalk14.red(`whoami failed (${res.status}): ${text}`));
2202
2387
  process.exitCode = 1;
2203
2388
  return;
2204
2389
  }
2205
2390
  const json = JSON.parse(text);
2206
- console.log(chalk13.cyan(json.publisher.handle));
2391
+ console.log(chalk14.cyan(json.publisher.handle));
2207
2392
  } catch (error) {
2208
2393
  const message = error instanceof SkildError8 ? error.message : error instanceof Error ? error.message : String(error);
2209
- console.error(chalk13.red(`whoami failed: ${message}`));
2210
- console.error(chalk13.dim("Tip: if you previously logged into a local registry, run `skild logout` then `skild login`."));
2394
+ console.error(chalk14.red(`whoami failed: ${message}`));
2395
+ console.error(chalk14.dim("Tip: if you previously logged into a local registry, run `skild logout` then `skild login`."));
2211
2396
  process.exitCode = 1;
2212
2397
  }
2213
2398
  }
@@ -2218,7 +2403,7 @@ import os from "os";
2218
2403
  import path4 from "path";
2219
2404
  import crypto from "crypto";
2220
2405
  import * as tar from "tar";
2221
- import chalk14 from "chalk";
2406
+ import chalk15 from "chalk";
2222
2407
  import { assertValidAlias, fetchWithTimeout as fetchWithTimeout6, loadRegistryAuth as loadRegistryAuth3, normalizeAlias, resolveRegistryUrl as resolveRegistryUrl5, SkildError as SkildError9, splitCanonicalName, validateSkillDir } from "@skild/core";
2223
2408
  function sha256Hex(buf) {
2224
2409
  const h = crypto.createHash("sha256");
@@ -2234,15 +2419,15 @@ async function publish(options = {}) {
2234
2419
  const registry = resolveRegistryUrl5(options.registry || auth?.registryUrl);
2235
2420
  const token = auth?.token;
2236
2421
  if (!token) {
2237
- console.error(chalk14.red("Not logged in. Run `skild login` first."));
2422
+ console.error(chalk15.red("Not logged in. Run `skild login` first."));
2238
2423
  process.exitCode = 1;
2239
2424
  return;
2240
2425
  }
2241
2426
  const dir = path4.resolve(options.dir || process.cwd());
2242
2427
  const validation = validateSkillDir(dir);
2243
2428
  if (!validation.ok) {
2244
- console.error(chalk14.red("Skill validation failed:"));
2245
- for (const issue of validation.issues) console.error(chalk14.red(`- ${issue.message}`));
2429
+ console.error(chalk15.red("Skill validation failed:"));
2430
+ for (const issue of validation.issues) console.error(chalk15.red(`- ${issue.message}`));
2246
2431
  process.exitCode = 1;
2247
2432
  return;
2248
2433
  }
@@ -2256,14 +2441,14 @@ async function publish(options = {}) {
2256
2441
  const skillset = fm.skillset === true;
2257
2442
  const dependencies = Array.isArray(fm.dependencies) ? fm.dependencies : [];
2258
2443
  if (!name) {
2259
- console.error(chalk14.red("Missing name. Provide SKILL.md frontmatter.name or --name."));
2444
+ console.error(chalk15.red("Missing name. Provide SKILL.md frontmatter.name or --name."));
2260
2445
  process.exitCode = 1;
2261
2446
  return;
2262
2447
  }
2263
2448
  if (!name.startsWith("@")) {
2264
2449
  const seg = name.trim();
2265
2450
  if (!/^[a-z0-9][a-z0-9-]{1,63}$/.test(seg)) {
2266
- console.error(chalk14.red("Invalid name. Use @publisher/skill or a simple skill name (lowercase letters/digits/dashes)."));
2451
+ console.error(chalk15.red("Invalid name. Use @publisher/skill or a simple skill name (lowercase letters/digits/dashes)."));
2267
2452
  process.exitCode = 1;
2268
2453
  return;
2269
2454
  }
@@ -2274,26 +2459,26 @@ async function publish(options = {}) {
2274
2459
  );
2275
2460
  const meText = await meRes.text();
2276
2461
  if (!meRes.ok) {
2277
- console.error(chalk14.red(`Failed to infer publisher scope (${meRes.status}): ${meText}`));
2462
+ console.error(chalk15.red(`Failed to infer publisher scope (${meRes.status}): ${meText}`));
2278
2463
  process.exitCode = 1;
2279
2464
  return;
2280
2465
  }
2281
2466
  const meJson = JSON.parse(meText);
2282
2467
  const handle = String(meJson?.publisher?.handle || "").trim().toLowerCase();
2283
2468
  if (!handle) {
2284
- console.error(chalk14.red("Failed to infer publisher scope from registry response."));
2469
+ console.error(chalk15.red("Failed to infer publisher scope from registry response."));
2285
2470
  process.exitCode = 1;
2286
2471
  return;
2287
2472
  }
2288
2473
  name = `@${handle}/${seg}`;
2289
2474
  }
2290
2475
  if (!/^@[a-z0-9][a-z0-9-]{1,31}\/[a-z0-9][a-z0-9-]{1,63}$/.test(name)) {
2291
- console.error(chalk14.red("Invalid publish name. Expected @publisher/skill (lowercase letters/digits/dashes)."));
2476
+ console.error(chalk15.red("Invalid publish name. Expected @publisher/skill (lowercase letters/digits/dashes)."));
2292
2477
  process.exitCode = 1;
2293
2478
  return;
2294
2479
  }
2295
2480
  if (!version2) {
2296
- console.error(chalk14.red("Missing version. Provide semver like 1.2.3 via SKILL.md frontmatter or --skill-version."));
2481
+ console.error(chalk15.red("Missing version. Provide semver like 1.2.3 via SKILL.md frontmatter or --skill-version."));
2297
2482
  process.exitCode = 1;
2298
2483
  return;
2299
2484
  }
@@ -2302,12 +2487,12 @@ async function publish(options = {}) {
2302
2487
  assertValidAlias(alias);
2303
2488
  } catch (error) {
2304
2489
  const message = error instanceof SkildError9 ? error.message : error instanceof Error ? error.message : String(error);
2305
- console.error(chalk14.red(message));
2490
+ console.error(chalk15.red(message));
2306
2491
  process.exitCode = 1;
2307
2492
  return;
2308
2493
  }
2309
2494
  }
2310
- const spinner = createSpinner(`Publishing ${chalk14.cyan(`${name}@${version2}`)} to ${chalk14.dim(registry)}...`);
2495
+ const spinner = createSpinner(`Publishing ${chalk15.cyan(`${name}@${version2}`)} to ${chalk15.dim(registry)}...`);
2311
2496
  const tempDir = fs4.mkdtempSync(path4.join(os.tmpdir(), "skild-publish-"));
2312
2497
  const tarballPath = path4.join(tempDir, "skill.tgz");
2313
2498
  try {
@@ -2344,12 +2529,12 @@ async function publish(options = {}) {
2344
2529
  const text = await res.text();
2345
2530
  if (!res.ok) {
2346
2531
  spinner.fail(`Publish failed (${res.status})`);
2347
- console.error(chalk14.red(text));
2532
+ console.error(chalk15.red(text));
2348
2533
  process.exitCode = 1;
2349
2534
  return;
2350
2535
  }
2351
2536
  if (alias) {
2352
- spinner.text = `Publishing ${chalk14.cyan(`${name}@${version2}`)} \u2014 setting alias ${chalk14.cyan(alias)}...`;
2537
+ spinner.text = `Publishing ${chalk15.cyan(`${name}@${version2}`)} \u2014 setting alias ${chalk15.cyan(alias)}...`;
2353
2538
  const aliasRes = await fetchWithTimeout6(
2354
2539
  `${registry}/publisher/skills/${encodeURIComponent(scope)}/${encodeURIComponent(skillName)}/alias`,
2355
2540
  {
@@ -2365,7 +2550,7 @@ async function publish(options = {}) {
2365
2550
  const aliasText = await aliasRes.text();
2366
2551
  if (!aliasRes.ok) {
2367
2552
  spinner.fail(`Failed to set alias (${aliasRes.status})`);
2368
- console.error(chalk14.red(aliasText));
2553
+ console.error(chalk15.red(aliasText));
2369
2554
  process.exitCode = 1;
2370
2555
  return;
2371
2556
  }
@@ -2374,18 +2559,18 @@ async function publish(options = {}) {
2374
2559
  console.log(text);
2375
2560
  return;
2376
2561
  }
2377
- const suffix = alias ? ` (alias: ${chalk14.cyan(alias)})` : "";
2378
- spinner.succeed(`Published ${chalk14.green(`${name}@${version2}`)}${suffix} (sha256:${integrity.slice(0, 12)}\u2026)`);
2562
+ const suffix = alias ? ` (alias: ${chalk15.cyan(alias)})` : "";
2563
+ spinner.succeed(`Published ${chalk15.green(`${name}@${version2}`)}${suffix} (sha256:${integrity.slice(0, 12)}\u2026)`);
2379
2564
  try {
2380
2565
  const parsed = JSON.parse(text);
2381
2566
  const warnings = Array.isArray(parsed.warnings) ? parsed.warnings.map(String).filter(Boolean) : [];
2382
- for (const w of warnings) console.warn(chalk14.yellow(`Warning: ${w}`));
2567
+ for (const w of warnings) console.warn(chalk15.yellow(`Warning: ${w}`));
2383
2568
  } catch {
2384
2569
  }
2385
2570
  } catch (error) {
2386
2571
  spinner.fail("Publish failed");
2387
2572
  const message = error instanceof SkildError9 ? error.message : error instanceof Error ? error.message : String(error);
2388
- console.error(chalk14.red(message));
2573
+ console.error(chalk15.red(message));
2389
2574
  process.exitCode = 1;
2390
2575
  } finally {
2391
2576
  fs4.rmSync(tempDir, { recursive: true, force: true });
@@ -2393,7 +2578,7 @@ async function publish(options = {}) {
2393
2578
  }
2394
2579
 
2395
2580
  // src/commands/search.ts
2396
- import chalk15 from "chalk";
2581
+ import chalk16 from "chalk";
2397
2582
  import { resolveRegistryUrl as resolveRegistryUrl6, searchRegistrySkills, SkildError as SkildError10 } from "@skild/core";
2398
2583
  async function search(query, options = {}) {
2399
2584
  const registryUrl = resolveRegistryUrl6(options.registry);
@@ -2405,21 +2590,21 @@ async function search(query, options = {}) {
2405
2590
  return;
2406
2591
  }
2407
2592
  if (!skills.length) {
2408
- console.log(chalk15.dim("No results."));
2593
+ console.log(chalk16.dim("No results."));
2409
2594
  return;
2410
2595
  }
2411
- console.log(chalk15.bold(`
2412
- \u{1F50E} Results (${skills.length}) \u2014 ${chalk15.dim(registryUrl)}
2596
+ console.log(chalk16.bold(`
2597
+ \u{1F50E} Results (${skills.length}) \u2014 ${chalk16.dim(registryUrl)}
2413
2598
  `));
2414
2599
  for (const s of skills) {
2415
2600
  const name = String(s.name || "").trim();
2416
2601
  const desc = String(s.description || "").trim();
2417
2602
  if (!name) continue;
2418
- console.log(` ${chalk15.cyan(name)}${desc ? chalk15.dim(` \u2014 ${desc}`) : ""}`);
2603
+ console.log(` ${chalk16.cyan(name)}${desc ? chalk16.dim(` \u2014 ${desc}`) : ""}`);
2419
2604
  }
2420
2605
  } catch (error) {
2421
2606
  const message = error instanceof SkildError10 ? error.message : error instanceof Error ? error.message : String(error);
2422
- console.error(chalk15.red(message));
2607
+ console.error(chalk16.red(message));
2423
2608
  process.exitCode = 1;
2424
2609
  }
2425
2610
  }
@@ -2428,7 +2613,7 @@ async function search(query, options = {}) {
2428
2613
  import fs5 from "fs";
2429
2614
  import path5 from "path";
2430
2615
  import os2 from "os";
2431
- import chalk16 from "chalk";
2616
+ import chalk17 from "chalk";
2432
2617
  import {
2433
2618
  deriveChildSource as deriveChildSource3,
2434
2619
  materializeSourceToTemp as materializeSourceToTemp3,
@@ -2442,7 +2627,7 @@ async function extractGithubSkills(source, options) {
2442
2627
  if (jsonOnly) {
2443
2628
  process.stdout.write(JSON.stringify({ ok: false, error: message }, null, 2) + "\n");
2444
2629
  } else {
2445
- console.error(chalk16.red(message));
2630
+ console.error(chalk17.red(message));
2446
2631
  }
2447
2632
  process.exitCode = 1;
2448
2633
  return;
@@ -2459,12 +2644,12 @@ async function extractGithubSkills(source, options) {
2459
2644
  if (jsonOnly) {
2460
2645
  process.stdout.write(JSON.stringify({ ok: false, error: message }, null, 2) + "\n");
2461
2646
  } else {
2462
- console.error(chalk16.red(message));
2647
+ console.error(chalk17.red(message));
2463
2648
  }
2464
2649
  process.exitCode = 1;
2465
2650
  return;
2466
2651
  }
2467
- const spinner = createSpinner(`Parsing markdown at ${chalk16.cyan(resolvedSource)}...`);
2652
+ const spinner = createSpinner(`Parsing markdown at ${chalk17.cyan(resolvedSource)}...`);
2468
2653
  if (!jsonOnly) spinner.start();
2469
2654
  let skills = [];
2470
2655
  let tree = [];
@@ -2487,7 +2672,7 @@ async function extractGithubSkills(source, options) {
2487
2672
  tree = markdownResult.tree;
2488
2673
  cleanup = markdownResult.cleanup;
2489
2674
  } else {
2490
- if (!jsonOnly) spinner.text = `Scanning repository at ${chalk16.cyan(resolvedSource)}...`;
2675
+ if (!jsonOnly) spinner.text = `Scanning repository at ${chalk17.cyan(resolvedSource)}...`;
2491
2676
  const materialized = await materializeSourceToTemp3(resolvedSource);
2492
2677
  cleanup = materialized.cleanup;
2493
2678
  const discovered = discoverSkillDirsWithHeuristics(materialized.dir, { maxDepth: maxSkillDepth, maxSkills });
@@ -2552,7 +2737,7 @@ async function extractGithubSkills(source, options) {
2552
2737
  for (const entry of repoCache.values()) entry.cleanup();
2553
2738
  cleanup?.();
2554
2739
  if (!jsonOnly) {
2555
- spinner.succeed(`Exported ${skills.length} skill${skills.length > 1 ? "s" : ""} to ${chalk16.cyan(outDir)}`);
2740
+ spinner.succeed(`Exported ${skills.length} skill${skills.length > 1 ? "s" : ""} to ${chalk17.cyan(outDir)}`);
2556
2741
  } else {
2557
2742
  process.stdout.write(JSON.stringify({ ok: true, outDir, skills: catalogSkills }, null, 2) + "\n");
2558
2743
  }
@@ -2563,7 +2748,7 @@ async function extractGithubSkills(source, options) {
2563
2748
  if (jsonOnly) {
2564
2749
  process.stdout.write(JSON.stringify({ ok: false, error: message }, null, 2) + "\n");
2565
2750
  } else {
2566
- console.error(chalk16.red(message));
2751
+ console.error(chalk17.red(message));
2567
2752
  }
2568
2753
  process.exitCode = 1;
2569
2754
  }
@@ -2722,7 +2907,7 @@ function collapseNode2(node) {
2722
2907
  }
2723
2908
 
2724
2909
  // src/commands/sync.ts
2725
- import chalk17 from "chalk";
2910
+ import chalk18 from "chalk";
2726
2911
  import {
2727
2912
  PLATFORMS as PLATFORMS4,
2728
2913
  getSkillInfo as getSkillInfo2,
@@ -2941,7 +3126,7 @@ Cross-platform sync (scope: ${scope})`);
2941
3126
  const skipped = results.filter((r) => r.status === "skipped").length;
2942
3127
  const failed = results.filter((r) => r.status === "failed").length;
2943
3128
  logger.header(`
2944
- \u5B8C\u6210\uFF1A${chalk17.green(`${synced} \u6210\u529F`)} / ${chalk17.yellow(`${skipped} \u8DF3\u8FC7`)} / ${chalk17.red(`${failed} \u5931\u8D25`)}`);
3129
+ \u5B8C\u6210\uFF1A${chalk18.green(`${synced} \u6210\u529F`)} / ${chalk18.yellow(`${skipped} \u8DF3\u8FC7`)} / ${chalk18.red(`${failed} \u5931\u8D25`)}`);
2945
3130
  if (failed > 0) {
2946
3131
  process.exitCode = 1;
2947
3132
  }
@@ -2953,7 +3138,7 @@ var require2 = createRequire(import.meta.url);
2953
3138
  var { version } = require2("../package.json");
2954
3139
  var program = new Command();
2955
3140
  program.name("skild").description("The npm for Agent Skills \u2014 Discover, install, manage, and publish AI Agent Skills with ease.").version(version);
2956
- program.command("install <source>").alias("i").description("Install a Skill from a Git URL, degit shorthand, or local directory").option("-t, --target <platform>", `Target platform: ${PLATFORMS5.join(", ")}`).option("--all", `Install to all platforms: ${PLATFORMS5.join(", ")}`).option("--recursive", "If source is a multi-skill directory/repo, install all discovered skills").option("-y, --yes", "Skip confirmation prompts (assume yes)").option("--depth <n>", "Max markdown recursion depth (default: 0)", "0").option("--scan-depth <n>", "Max directory depth to scan for SKILL.md (default: 6)", "6").option("--max-skills <n>", "Max discovered skills to install (default: 200)", "200").option("-l, --local", "Install to project-level directory instead of global").option("-f, --force", "Overwrite existing installation").option("--registry <url>", "Registry base URL (default: https://registry.skild.sh)").option("--json", "Output JSON").action(async (source, options) => {
3141
+ program.command("install <source>").alias("i").alias("add").description("Install a Skill from a Git URL, degit shorthand, or local directory").option("-t, --target <platform>", `Target platform: ${PLATFORMS5.join(", ")}`).option("--all", `Install to all platforms: ${PLATFORMS5.join(", ")}`).option("--recursive", "If source is a multi-skill directory/repo, install all discovered skills").option("-y, --yes", "Skip confirmation prompts (assume yes)").option("--depth <n>", "Max markdown recursion depth (default: 0)", "0").option("--scan-depth <n>", "Max directory depth to scan for SKILL.md (default: 6)", "6").option("--max-skills <n>", "Max discovered skills to install (default: 200)", "200").option("-l, --local", "Install to project-level directory instead of global").option("-f, --force", "Overwrite existing installation").option("--registry <url>", "Registry base URL (default: https://registry.skild.sh)").option("--json", "Output JSON").action(async (source, options) => {
2957
3142
  await install(source, options);
2958
3143
  });
2959
3144
  program.command("list").alias("ls").description("List installed Skills").option("-t, --target <platform>", `Target platform: ${PLATFORMS5.join(", ")} (optional; omit to list all)`).option("-l, --local", "List project-level directory instead of global").option("--paths", "Show install paths").option("--verbose", "Show skillset dependency details").option("--json", "Output JSON").action(async (options) => list(options));
@@ -2975,7 +3160,7 @@ program.command("sync [skills...]").description("Sync missing skills across plat
2975
3160
  await sync(skills, options);
2976
3161
  });
2977
3162
  program.action(() => {
2978
- console.log(chalk18.bold("\n\u{1F6E1}\uFE0F skild \u2014 Get your agents skilled.\n"));
3163
+ console.log(chalk19.bold("\n\u{1F6E1}\uFE0F skild \u2014 Get your agents skilled.\n"));
2979
3164
  program.outputHelp();
2980
3165
  });
2981
3166
  var argv = process.argv.slice();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skild",
3
- "version": "0.9.1",
3
+ "version": "0.10.1",
4
4
  "description": "The npm for Agent Skills — Discover, install, manage, and publish AI Agent Skills with ease.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -41,7 +41,7 @@
41
41
  "remark-parse": "^11.0.0",
42
42
  "tar": "^7.4.3",
43
43
  "unified": "^11.0.4",
44
- "@skild/core": "^0.7.0"
44
+ "@skild/core": "^0.10.1"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/mdast": "^4.0.4",
@@ -55,7 +55,7 @@
55
55
  "scripts": {
56
56
  "build": "tsup src/index.ts --format esm --dts --clean --silent",
57
57
  "dev": "tsup src/index.ts --format esm --watch",
58
- "start": "node dist/index.js",
58
+ "start": "pnpm exec node dist/index.js",
59
59
  "typecheck": "pnpm -C ../core build && tsc -p tsconfig.json --noEmit"
60
60
  }
61
61
  }