skild 0.10.1 → 0.10.2

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 (2) hide show
  1. package/dist/index.js +123 -85
  2. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -1698,8 +1698,22 @@ import chalk5 from "chalk";
1698
1698
  import { PLATFORMS as PLATFORMS3, listAllSkills, listSkills as listSkills2 } from "@skild/core";
1699
1699
 
1700
1700
  // src/utils/table-utils.ts
1701
+ import stringWidth from "string-width";
1701
1702
  import chalk4 from "chalk";
1702
- var BOX_CHARS = {
1703
+ var BORDERS = {
1704
+ rounded: {
1705
+ topLeft: "\u256D",
1706
+ topRight: "\u256E",
1707
+ bottomLeft: "\u2570",
1708
+ bottomRight: "\u256F",
1709
+ horizontal: "\u2500",
1710
+ vertical: "\u2502",
1711
+ teeDown: "\u252C",
1712
+ teeUp: "\u2534",
1713
+ teeRight: "\u251C",
1714
+ teeLeft: "\u2524",
1715
+ cross: "\u253C"
1716
+ },
1703
1717
  single: {
1704
1718
  topLeft: "\u250C",
1705
1719
  topRight: "\u2510",
@@ -1707,11 +1721,11 @@ var BOX_CHARS = {
1707
1721
  bottomRight: "\u2518",
1708
1722
  horizontal: "\u2500",
1709
1723
  vertical: "\u2502",
1710
- cross: "\u253C",
1711
1724
  teeDown: "\u252C",
1712
1725
  teeUp: "\u2534",
1713
1726
  teeRight: "\u251C",
1714
- teeLeft: "\u2524"
1727
+ teeLeft: "\u2524",
1728
+ cross: "\u253C"
1715
1729
  },
1716
1730
  double: {
1717
1731
  topLeft: "\u2554",
@@ -1720,115 +1734,131 @@ var BOX_CHARS = {
1720
1734
  bottomRight: "\u255D",
1721
1735
  horizontal: "\u2550",
1722
1736
  vertical: "\u2551",
1723
- cross: "\u256C",
1724
1737
  teeDown: "\u2566",
1725
1738
  teeUp: "\u2569",
1726
1739
  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"
1740
+ teeLeft: "\u2563",
1741
+ cross: "\u256C"
1741
1742
  }
1742
1743
  };
1743
- function visibleLength(str) {
1744
- return str.replace(/\u001b\[\d+m/g, "").length;
1744
+ function getWidth(str) {
1745
+ return stringWidth(str);
1745
1746
  }
1746
- function padString(str, width, align = "left") {
1747
- const visible = visibleLength(str);
1748
- const padding = Math.max(0, width - visible);
1747
+ function pad(str, targetWidth, align = "left") {
1748
+ const currentWidth = getWidth(str);
1749
+ const padding = Math.max(0, targetWidth - currentWidth);
1750
+ if (padding === 0) return str;
1749
1751
  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") {
1752
+ const left = Math.floor(padding / 2);
1753
+ const right = padding - left;
1754
+ return " ".repeat(left) + str + " ".repeat(right);
1755
+ }
1756
+ if (align === "right") {
1754
1757
  return " ".repeat(padding) + str;
1755
- } else {
1756
- return str + " ".repeat(padding);
1757
1758
  }
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));
1759
+ return str + " ".repeat(padding);
1760
+ }
1761
+ function truncate(str, maxWidth) {
1762
+ if (getWidth(str) <= maxWidth) return str;
1763
+ const plain = str.replace(/\u001b\[[0-9;]*m/g, "");
1764
+ let result = "";
1765
+ let width = 0;
1766
+ for (const char of plain) {
1767
+ const charWidth = stringWidth(char);
1768
+ if (width + charWidth + 1 > maxWidth) break;
1769
+ result += char;
1770
+ width += charWidth;
1771
+ }
1772
+ return result + "\u2026";
1773
+ }
1774
+ function renderBorder(columns, chars, position, cellPadding) {
1775
+ const left = position === "top" ? chars.topLeft : position === "bottom" ? chars.bottomLeft : chars.teeRight;
1776
+ const right = position === "top" ? chars.topRight : position === "bottom" ? chars.bottomRight : chars.teeLeft;
1777
+ const junction = position === "top" ? chars.teeDown : position === "bottom" ? chars.teeUp : chars.cross;
1778
+ const segments = columns.map(
1779
+ (col) => chars.horizontal.repeat(col.width + cellPadding * 2)
1780
+ );
1770
1781
  return left + segments.join(junction) + right;
1771
1782
  }
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") + " ";
1783
+ function renderRow(cells, columns, chars, cellPadding) {
1784
+ const paddingStr = " ".repeat(cellPadding);
1785
+ const formattedCells = columns.map((col, i) => {
1786
+ const content = cells[i] ?? "";
1787
+ const truncated = getWidth(content) > col.width ? truncate(content, col.width) : content;
1788
+ const padded = pad(truncated, col.width, col.align);
1789
+ return paddingStr + padded + paddingStr;
1778
1790
  });
1779
- return chars.vertical + paddedCells.join(chars.vertical) + chars.vertical;
1791
+ return chars.vertical + formattedCells.join(chars.vertical) + chars.vertical;
1780
1792
  }
1781
- function renderTable(options) {
1782
- const { columns, rows, borderStyle = "rounded" } = options;
1783
- const chars = BOX_CHARS[borderStyle];
1793
+ function renderTable(config) {
1794
+ const { columns, rows, border = "rounded", cellPadding = 1 } = config;
1795
+ const chars = BORDERS[border];
1784
1796
  const lines = [];
1785
- lines.push(renderBorder(columns, chars, "top"));
1797
+ lines.push(renderBorder(columns, chars, "top", cellPadding));
1786
1798
  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];
1799
+ lines.push(renderRow(headerCells, columns, chars, cellPadding));
1800
+ lines.push(renderBorder(columns, chars, "middle", cellPadding));
1801
+ for (const row of rows) {
1791
1802
  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));
1803
+ lines.push(renderBorder(columns, chars, "middle", cellPadding));
1804
+ } else if (row.style === "section") {
1805
+ const sectionCells = row.cells.map(
1806
+ (cell, i) => i === 0 ? chalk4.bold(cell) : cell
1807
+ );
1808
+ lines.push(renderRow(sectionCells, columns, chars, cellPadding));
1796
1809
  } else {
1797
- lines.push(renderRow(row.cells, columns, chars));
1810
+ lines.push(renderRow(row.cells, columns, chars, cellPadding));
1798
1811
  }
1799
1812
  }
1800
- lines.push(renderBorder(columns, chars, "bottom"));
1813
+ lines.push(renderBorder(columns, chars, "bottom", cellPadding));
1801
1814
  return lines.join("\n");
1802
1815
  }
1803
- var TableBuilder = class {
1816
+ var Table = class {
1804
1817
  columns = [];
1805
1818
  rows = [];
1806
1819
  borderStyle = "rounded";
1807
- addColumn(header, width, align) {
1820
+ padding = 1;
1821
+ /** Add a column definition. */
1822
+ column(header, width, align = "left") {
1808
1823
  this.columns.push({ header, width, align });
1809
1824
  return this;
1810
1825
  }
1811
- addRow(cells, style) {
1812
- this.rows.push({ cells, style });
1826
+ /** Add a normal data row. */
1827
+ row(cells) {
1828
+ this.rows.push({ cells, style: "normal" });
1813
1829
  return this;
1814
1830
  }
1815
- addSeparator() {
1816
- this.rows.push({ cells: [], style: "separator" });
1831
+ /** Add a section header row (first cell is emphasized). */
1832
+ section(title, ...rest) {
1833
+ const cells = [title, ...rest];
1834
+ while (cells.length < this.columns.length) {
1835
+ cells.push("");
1836
+ }
1837
+ this.rows.push({ cells, style: "section" });
1817
1838
  return this;
1818
1839
  }
1819
- addHeaderRow(cells) {
1820
- this.rows.push({ cells, style: "header" });
1840
+ /** Add a horizontal separator line. */
1841
+ separator() {
1842
+ this.rows.push({ cells: [], style: "separator" });
1821
1843
  return this;
1822
1844
  }
1823
- setBorderStyle(style) {
1845
+ /** Set border style. */
1846
+ border(style) {
1824
1847
  this.borderStyle = style;
1825
1848
  return this;
1826
1849
  }
1850
+ /** Set cell padding. */
1851
+ cellPadding(padding) {
1852
+ this.padding = padding;
1853
+ return this;
1854
+ }
1855
+ /** Render the table to a string. */
1827
1856
  render() {
1828
1857
  return renderTable({
1829
1858
  columns: this.columns,
1830
1859
  rows: this.rows,
1831
- borderStyle: this.borderStyle
1860
+ border: this.borderStyle,
1861
+ cellPadding: this.padding
1832
1862
  });
1833
1863
  }
1834
1864
  };
@@ -1839,7 +1869,7 @@ var PLATFORM_ABBREV = {
1839
1869
  codex: "Codex",
1840
1870
  copilot: "Copilot",
1841
1871
  cursor: "Cursor",
1842
- antigravity: "Antigrav",
1872
+ antigravity: "Antigravity",
1843
1873
  opencode: "OpenCode",
1844
1874
  windsurf: "Windsurf"
1845
1875
  };
@@ -1903,21 +1933,19 @@ function renderTableView(allSkills, scope, options) {
1903
1933
  }
1904
1934
  const matrix = buildSkillMatrix(allSkills);
1905
1935
  const activePlatforms = PLATFORMS3.filter((p) => allSkills.some((s) => s.platform === p));
1906
- const table = new TableBuilder();
1907
- table.addColumn("Skill", 30, "left");
1936
+ const table = new Table();
1937
+ table.column("Skill", 30, "left");
1908
1938
  for (const platform of activePlatforms) {
1909
- table.addColumn(PLATFORM_ABBREV[platform] || platform, 9, "center");
1939
+ table.column(PLATFORM_ABBREV[platform] || platform, 11, "center");
1910
1940
  }
1911
1941
  const skillsets = matrix.filter((r) => r.isSkillset && r.indent === 0);
1912
- const skillsetDeps = matrix.filter((r) => r.indent > 0);
1913
1942
  const regular = matrix.filter((r) => !r.isSkillset && !r.isDependency && r.indent === 0);
1914
1943
  if (skillsets.length > 0) {
1915
- const sectionHeader = [`${chalk5.bold("\u{1F4E6} SKILLSETS")} ${chalk5.dim(`(${skillsets.length})`)}`, ...activePlatforms.map(() => "")];
1916
- table.addHeaderRow(sectionHeader);
1944
+ table.section(`\u{1F4E6} SKILLSETS ${chalk5.dim(`(${skillsets.length})`)}`);
1917
1945
  for (const row of skillsets) {
1918
1946
  const nameCell = chalk5.cyan(row.displayName);
1919
1947
  const statusCells = activePlatforms.map((p) => renderStatusIcon(row.platforms.get(p)));
1920
- table.addRow([nameCell, ...statusCells]);
1948
+ table.row([nameCell, ...statusCells]);
1921
1949
  if (options.verbose && row.dependencies) {
1922
1950
  const deps = matrix.filter((r) => r.indent > 0 && row.dependencies?.includes(r.name));
1923
1951
  for (const dep of deps) {
@@ -1926,19 +1954,18 @@ function renderTableView(allSkills, scope, options) {
1926
1954
  const status = dep.platforms.get(p);
1927
1955
  return status?.installed ? chalk5.dim("\u2022") : chalk5.dim("-");
1928
1956
  });
1929
- table.addRow([depName, ...depStatus]);
1957
+ table.row([depName, ...depStatus]);
1930
1958
  }
1931
1959
  }
1932
1960
  }
1933
1961
  }
1934
1962
  if (regular.length > 0) {
1935
- if (skillsets.length > 0) table.addSeparator();
1936
- const sectionHeader = [`${chalk5.bold("\u26A1 SKILLS")} ${chalk5.dim(`(${regular.length})`)}`, ...activePlatforms.map(() => "")];
1937
- table.addHeaderRow(sectionHeader);
1963
+ if (skillsets.length > 0) table.separator();
1964
+ table.section(`\u26A1 SKILLS ${chalk5.dim(`(${regular.length})`)}`);
1938
1965
  for (const row of regular) {
1939
1966
  const nameCell = chalk5.cyan(row.displayName);
1940
1967
  const statusCells = activePlatforms.map((p) => renderStatusIcon(row.platforms.get(p)));
1941
- table.addRow([nameCell, ...statusCells]);
1968
+ table.row([nameCell, ...statusCells]);
1942
1969
  }
1943
1970
  }
1944
1971
  console.log("");
@@ -1947,6 +1974,17 @@ function renderTableView(allSkills, scope, options) {
1947
1974
  const totalInstalls = allSkills.length;
1948
1975
  console.log("");
1949
1976
  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})`));
1977
+ if (activePlatforms.length > 1) {
1978
+ const unsyncedSkills = regular.filter((row) => {
1979
+ const installedCount = activePlatforms.filter((p) => row.platforms.get(p)?.installed).length;
1980
+ return installedCount > 0 && installedCount < activePlatforms.length;
1981
+ });
1982
+ if (unsyncedSkills.length > 0) {
1983
+ console.log("");
1984
+ console.log(chalk5.yellow(`\u{1F4A1} ${unsyncedSkills.length} skill${unsyncedSkills.length === 1 ? "" : "s"} not synced across all platforms.`));
1985
+ console.log(chalk5.dim(` Run ${chalk5.cyan("skild sync")} to sync skills across platforms.`));
1986
+ }
1987
+ }
1950
1988
  console.log("");
1951
1989
  }
1952
1990
  async function list(options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skild",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
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",
@@ -35,13 +35,15 @@
35
35
  "dependencies": {
36
36
  "@inquirer/prompts": "^8.2.0",
37
37
  "chalk": "^5.3.0",
38
+ "cli-table3": "^0.6.5",
38
39
  "commander": "^12.1.0",
39
40
  "mdast-util-to-string": "^4.0.0",
40
41
  "ora": "^8.0.1",
41
42
  "remark-parse": "^11.0.0",
43
+ "string-width": "^8.1.0",
42
44
  "tar": "^7.4.3",
43
45
  "unified": "^11.0.4",
44
- "@skild/core": "^0.10.1"
46
+ "@skild/core": "^0.10.2"
45
47
  },
46
48
  "devDependencies": {
47
49
  "@types/mdast": "^4.0.4",