skillops-cli 1.3.7 → 1.3.8
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/dist/cli.js +186 -45
- package/dist/index.d.ts +63 -2
- package/dist/index.js +224 -40
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ import YAML6 from "yaml";
|
|
|
10
10
|
import fs from "fs";
|
|
11
11
|
import YAML from "yaml";
|
|
12
12
|
import { z } from "zod";
|
|
13
|
-
var SKILLOPS_VERSION = "1.3.
|
|
13
|
+
var SKILLOPS_VERSION = "1.3.8";
|
|
14
14
|
var SKILL_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
15
15
|
var SEMVER_REGEX = /^\d+\.\d+\.\d+$/;
|
|
16
16
|
var FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
@@ -1426,9 +1426,104 @@ import fs3 from "fs";
|
|
|
1426
1426
|
import path2 from "path";
|
|
1427
1427
|
import YAML2 from "yaml";
|
|
1428
1428
|
|
|
1429
|
-
// src/ui/
|
|
1429
|
+
// src/ui/lipgloss.ts
|
|
1430
1430
|
var ESC = String.fromCharCode(27);
|
|
1431
|
-
var
|
|
1431
|
+
var CHARM_PALETTE = {
|
|
1432
|
+
indigo: "#7D56F4",
|
|
1433
|
+
fuchsia: "#EE6FF8",
|
|
1434
|
+
hotPink: "#F25D94",
|
|
1435
|
+
mint: "#04B575",
|
|
1436
|
+
amber: "#FFBD2E",
|
|
1437
|
+
coral: "#FF5F56",
|
|
1438
|
+
cyan: "#00D7FF",
|
|
1439
|
+
lavender: "#B4A7D6",
|
|
1440
|
+
white: "#FAFAFA",
|
|
1441
|
+
muted: "#6C6C6C",
|
|
1442
|
+
subtle: "#4A4A4A",
|
|
1443
|
+
surface: "#2A2438",
|
|
1444
|
+
keycapBg: "#302B3F"
|
|
1445
|
+
};
|
|
1446
|
+
function hexToRgb(hex) {
|
|
1447
|
+
const cleaned = hex.trim().replace(/^#/, "");
|
|
1448
|
+
if (cleaned.length === 3) {
|
|
1449
|
+
const r2 = Number.parseInt(`${cleaned[0]}${cleaned[0]}`, 16);
|
|
1450
|
+
const g2 = Number.parseInt(`${cleaned[1]}${cleaned[1]}`, 16);
|
|
1451
|
+
const b2 = Number.parseInt(`${cleaned[2]}${cleaned[2]}`, 16);
|
|
1452
|
+
return [
|
|
1453
|
+
Number.isNaN(r2) ? 255 : r2,
|
|
1454
|
+
Number.isNaN(g2) ? 255 : g2,
|
|
1455
|
+
Number.isNaN(b2) ? 255 : b2
|
|
1456
|
+
];
|
|
1457
|
+
}
|
|
1458
|
+
const r = Number.parseInt(cleaned.slice(0, 2), 16);
|
|
1459
|
+
const g = Number.parseInt(cleaned.slice(2, 4), 16);
|
|
1460
|
+
const b = Number.parseInt(cleaned.slice(4, 6), 16);
|
|
1461
|
+
return [
|
|
1462
|
+
Number.isNaN(r) ? 255 : r,
|
|
1463
|
+
Number.isNaN(g) ? 255 : g,
|
|
1464
|
+
Number.isNaN(b) ? 255 : b
|
|
1465
|
+
];
|
|
1466
|
+
}
|
|
1467
|
+
function fgHex(hex, text, enabled) {
|
|
1468
|
+
const useColor = enabled ?? isColorEnabled();
|
|
1469
|
+
if (!useColor || text.length === 0) {
|
|
1470
|
+
return text;
|
|
1471
|
+
}
|
|
1472
|
+
const [r, g, b] = hexToRgb(hex);
|
|
1473
|
+
return `${ESC}[38;2;${r};${g};${b}m${text}${ESC}[39m`;
|
|
1474
|
+
}
|
|
1475
|
+
function bgHex(hex, text, enabled) {
|
|
1476
|
+
const useColor = enabled ?? isColorEnabled();
|
|
1477
|
+
if (!useColor || text.length === 0) {
|
|
1478
|
+
return text;
|
|
1479
|
+
}
|
|
1480
|
+
const [r, g, b] = hexToRgb(hex);
|
|
1481
|
+
return `${ESC}[48;2;${r};${g};${b}m${text}${ESC}[49m`;
|
|
1482
|
+
}
|
|
1483
|
+
function renderPill(text, options) {
|
|
1484
|
+
const useColor = options?.colorEnabled ?? isColorEnabled();
|
|
1485
|
+
if (!useColor || text.length === 0) {
|
|
1486
|
+
return text;
|
|
1487
|
+
}
|
|
1488
|
+
const fg = options?.fg ?? CHARM_PALETTE.white;
|
|
1489
|
+
const bg = options?.bg ?? CHARM_PALETTE.indigo;
|
|
1490
|
+
const bold = options?.bold ?? true;
|
|
1491
|
+
let styled = fgHex(fg, text, true);
|
|
1492
|
+
styled = bgHex(bg, styled, true);
|
|
1493
|
+
if (bold) {
|
|
1494
|
+
styled = `${ESC}[1m${styled}${ESC}[22m`;
|
|
1495
|
+
}
|
|
1496
|
+
return styled;
|
|
1497
|
+
}
|
|
1498
|
+
function renderKeycap(keyLabel, actionLabel, colorEnabled) {
|
|
1499
|
+
const useColor = colorEnabled ?? isColorEnabled();
|
|
1500
|
+
if (!useColor) {
|
|
1501
|
+
return `${keyLabel} ${actionLabel}`;
|
|
1502
|
+
}
|
|
1503
|
+
const keyStyled = `${ESC}[1m${fgHex(CHARM_PALETTE.lavender, keyLabel, true)}${ESC}[22m`;
|
|
1504
|
+
const actionStyled = fgHex(CHARM_PALETTE.muted, actionLabel, true);
|
|
1505
|
+
return `${keyStyled} ${actionStyled}`;
|
|
1506
|
+
}
|
|
1507
|
+
function renderPaginationDots(currentPage, totalPages, colorEnabled) {
|
|
1508
|
+
const safeTotal = Math.max(1, Math.min(12, totalPages));
|
|
1509
|
+
const safeCurrent = Math.max(0, Math.min(safeTotal - 1, currentPage));
|
|
1510
|
+
const useColor = colorEnabled ?? isColorEnabled();
|
|
1511
|
+
const dots = [];
|
|
1512
|
+
for (let i = 0; i < safeTotal; i++) {
|
|
1513
|
+
if (i === safeCurrent) {
|
|
1514
|
+
dots.push(
|
|
1515
|
+
useColor ? `${ESC}[1m${fgHex(CHARM_PALETTE.hotPink, "\u2022", true)}${ESC}[22m` : "\u2022"
|
|
1516
|
+
);
|
|
1517
|
+
} else {
|
|
1518
|
+
dots.push(useColor ? fgHex(CHARM_PALETTE.muted, "\u25E6", true) : "\u25E6");
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
return dots.join(" ");
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
// src/ui/terminal.ts
|
|
1525
|
+
var ESC2 = String.fromCharCode(27);
|
|
1526
|
+
var ANSI_ESCAPE_REGEX = new RegExp(`${ESC2}\\[[0-9;]*m`, "g");
|
|
1432
1527
|
function isColorEnabled(options) {
|
|
1433
1528
|
const env = options?.env ?? process.env;
|
|
1434
1529
|
const isTTY = options?.isTTY ?? Boolean(process.stdout?.isTTY);
|
|
@@ -1454,21 +1549,21 @@ function wrapAnsi(openCode, closeCode, text, enabled) {
|
|
|
1454
1549
|
if (!useColor || text.length === 0) {
|
|
1455
1550
|
return text;
|
|
1456
1551
|
}
|
|
1457
|
-
return `${
|
|
1552
|
+
return `${ESC2}[${openCode}m${text}${ESC2}[${closeCode}m`;
|
|
1458
1553
|
}
|
|
1459
1554
|
var style = {
|
|
1460
1555
|
bold: (text, enabled) => wrapAnsi("1", "22", text, enabled),
|
|
1461
1556
|
dim: (text, enabled) => wrapAnsi("2", "22", text, enabled),
|
|
1462
1557
|
italic: (text, enabled) => wrapAnsi("3", "23", text, enabled),
|
|
1463
1558
|
underline: (text, enabled) => wrapAnsi("4", "24", text, enabled),
|
|
1464
|
-
cyan: (text, enabled) =>
|
|
1465
|
-
green: (text, enabled) =>
|
|
1466
|
-
yellow: (text, enabled) =>
|
|
1467
|
-
red: (text, enabled) =>
|
|
1468
|
-
magenta: (text, enabled) =>
|
|
1469
|
-
blue: (text, enabled) =>
|
|
1470
|
-
gray: (text, enabled) =>
|
|
1471
|
-
white: (text, enabled) =>
|
|
1559
|
+
cyan: (text, enabled) => fgHex(CHARM_PALETTE.cyan, text, enabled),
|
|
1560
|
+
green: (text, enabled) => fgHex(CHARM_PALETTE.mint, text, enabled),
|
|
1561
|
+
yellow: (text, enabled) => fgHex(CHARM_PALETTE.amber, text, enabled),
|
|
1562
|
+
red: (text, enabled) => fgHex(CHARM_PALETTE.coral, text, enabled),
|
|
1563
|
+
magenta: (text, enabled) => fgHex(CHARM_PALETTE.fuchsia, text, enabled),
|
|
1564
|
+
blue: (text, enabled) => fgHex(CHARM_PALETTE.indigo, text, enabled),
|
|
1565
|
+
gray: (text, enabled) => fgHex(CHARM_PALETTE.muted, text, enabled),
|
|
1566
|
+
white: (text, enabled) => fgHex(CHARM_PALETTE.white, text, enabled)
|
|
1472
1567
|
};
|
|
1473
1568
|
function stripAnsi(text) {
|
|
1474
1569
|
return text.replace(ANSI_ESCAPE_REGEX, "");
|
|
@@ -1495,7 +1590,13 @@ function padVisible(text, width, align = "left") {
|
|
|
1495
1590
|
function renderHeaderBanner(subtitle = "Framework & Library for AI Skills & Subagents", options) {
|
|
1496
1591
|
const ver = options?.version ?? SKILLOPS_VERSION;
|
|
1497
1592
|
const c = options?.colorEnabled;
|
|
1498
|
-
|
|
1593
|
+
const brandPill = renderPill(`\u25C6 SkillOps v${ver}`, {
|
|
1594
|
+
fg: CHARM_PALETTE.white,
|
|
1595
|
+
bg: CHARM_PALETTE.indigo,
|
|
1596
|
+
bold: true,
|
|
1597
|
+
colorEnabled: c
|
|
1598
|
+
});
|
|
1599
|
+
return `${brandPill} ${style.dim("\u2014", c)} ${fgHex(CHARM_PALETTE.lavender, subtitle, c)}`;
|
|
1499
1600
|
}
|
|
1500
1601
|
function renderTable(headers, rows, options) {
|
|
1501
1602
|
const indent = " ".repeat(options?.indent ?? 2);
|
|
@@ -1572,15 +1673,19 @@ function formatBadge(type, customLabel, colorEnabled) {
|
|
|
1572
1673
|
colorEnabled
|
|
1573
1674
|
);
|
|
1574
1675
|
case "skill":
|
|
1575
|
-
return
|
|
1576
|
-
|
|
1676
|
+
return renderPill(`[${customLabel ?? "SKILL"}]`, {
|
|
1677
|
+
fg: CHARM_PALETTE.white,
|
|
1678
|
+
bg: CHARM_PALETTE.indigo,
|
|
1679
|
+
bold: true,
|
|
1577
1680
|
colorEnabled
|
|
1578
|
-
);
|
|
1681
|
+
});
|
|
1579
1682
|
case "subagent":
|
|
1580
|
-
return
|
|
1581
|
-
|
|
1683
|
+
return renderPill(`[${customLabel ?? "SUBAGENT"}]`, {
|
|
1684
|
+
fg: CHARM_PALETTE.white,
|
|
1685
|
+
bg: CHARM_PALETTE.hotPink,
|
|
1686
|
+
bold: true,
|
|
1582
1687
|
colorEnabled
|
|
1583
|
-
);
|
|
1688
|
+
});
|
|
1584
1689
|
}
|
|
1585
1690
|
}
|
|
1586
1691
|
function renderStep(step, total, title, detail, status = "done", colorEnabled) {
|
|
@@ -5684,27 +5789,51 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5684
5789
|
const agentTabTitle = options.tabLabels?.agent ?? "Agents";
|
|
5685
5790
|
const submitVerb = options.submitActionLabel ?? "import";
|
|
5686
5791
|
const isSinglePage = totalAgents === 0 || totalSkills === 0;
|
|
5687
|
-
const header =
|
|
5688
|
-
|
|
5689
|
-
|
|
5792
|
+
const header = renderPill(`\u25C6 ${title}`, {
|
|
5793
|
+
fg: CHARM_PALETTE.white,
|
|
5794
|
+
bg: CHARM_PALETTE.indigo,
|
|
5795
|
+
bold: true,
|
|
5796
|
+
colorEnabled: c
|
|
5797
|
+
});
|
|
5798
|
+
const sep = style.dim(" \xB7 ", c);
|
|
5799
|
+
const keyItems = [
|
|
5800
|
+
renderKeycap("\u2191/\u2193", "move", c),
|
|
5801
|
+
...isSinglePage ? [] : [renderKeycap("\u2190/\u2192", "tab", c)],
|
|
5802
|
+
renderKeycap("Space", "select", c),
|
|
5803
|
+
...state.searchMode ? [renderKeycap("Esc", "clear", c)] : [renderKeycap("/", "search", c), renderKeycap("a", "all", c)],
|
|
5804
|
+
renderKeycap("Enter", submitVerb, c)
|
|
5805
|
+
];
|
|
5806
|
+
const instructions = `${bar} ${keyItems.join(sep)}`;
|
|
5690
5807
|
const lines = [header];
|
|
5691
5808
|
if (options.subtitle) {
|
|
5692
|
-
lines.push(`${bar} ${options.subtitle}`);
|
|
5809
|
+
lines.push(`${bar} ${fgHex(CHARM_PALETTE.lavender, options.subtitle, c)}`);
|
|
5693
5810
|
}
|
|
5694
5811
|
lines.push(instructions, bar);
|
|
5695
5812
|
const hasQuery = state.searchQuery.length > 0;
|
|
5696
5813
|
const skillCountStr = hasQuery ? `${realFilteredSkills.length}/${totalSkills}` : `${totalSkills}`;
|
|
5697
5814
|
const agentCountStr = hasQuery ? `${realFilteredAgents.length}/${totalAgents}` : `${totalAgents}`;
|
|
5698
|
-
const skillTabLabel = state.activeTab === "skill" ?
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5815
|
+
const skillTabLabel = state.activeTab === "skill" ? renderPill(`[ \u25C6 ${skillTabTitle} (${skillCountStr}) ]`, {
|
|
5816
|
+
fg: CHARM_PALETTE.white,
|
|
5817
|
+
bg: CHARM_PALETTE.indigo,
|
|
5818
|
+
bold: true,
|
|
5819
|
+
colorEnabled: c
|
|
5820
|
+
}) : style.dim(`\u25CB ${skillTabTitle} (${skillCountStr})`, c);
|
|
5821
|
+
const agentTabLabel = state.activeTab === "agent" ? renderPill(`[ \u25C6 ${agentTabTitle} (${agentCountStr}) ]`, {
|
|
5822
|
+
fg: CHARM_PALETTE.white,
|
|
5823
|
+
bg: CHARM_PALETTE.hotPink,
|
|
5824
|
+
bold: true,
|
|
5825
|
+
colorEnabled: c
|
|
5826
|
+
}) : style.dim(`\u25CB ${agentTabTitle} (${agentCountStr})`, c);
|
|
5706
5827
|
const rawQuerySlice = state.searchQuery.length > 14 ? `\u2026${state.searchQuery.slice(-13)}` : state.searchQuery;
|
|
5707
|
-
const searchSuffix = state.searchMode || hasQuery ? ` ${
|
|
5828
|
+
const searchSuffix = state.searchMode || hasQuery ? ` ${renderPill(
|
|
5829
|
+
`/ Filter: ${rawQuerySlice}${state.searchMode ? "\u2588" : ""}`,
|
|
5830
|
+
{
|
|
5831
|
+
fg: CHARM_PALETTE.amber,
|
|
5832
|
+
bg: CHARM_PALETTE.surface,
|
|
5833
|
+
bold: true,
|
|
5834
|
+
colorEnabled: c
|
|
5835
|
+
}
|
|
5836
|
+
)}` : ` ${style.dim("(/ search)", c)}`;
|
|
5708
5837
|
const singleTabLabel = totalSkills > 0 ? skillTabLabel : agentTabLabel;
|
|
5709
5838
|
lines.push(
|
|
5710
5839
|
isSinglePage ? `${style.dim("\u251C\u2500", c)} ${singleTabLabel}${searchSuffix}` : `${style.dim("\u251C\u2500", c)} ${skillTabLabel} ${agentTabLabel}${searchSuffix}`,
|
|
@@ -5722,8 +5851,16 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5722
5851
|
startIdx = Math.max(0, Math.min(state.cursor - half, total - maxVisible));
|
|
5723
5852
|
}
|
|
5724
5853
|
const endIdx = Math.min(total, startIdx + maxVisible);
|
|
5854
|
+
const totalPages = Math.max(1, Math.ceil(total / maxVisible));
|
|
5855
|
+
const currentPage = Math.min(
|
|
5856
|
+
totalPages - 1,
|
|
5857
|
+
Math.floor(state.cursor / maxVisible)
|
|
5858
|
+
);
|
|
5859
|
+
const pageDots = totalPages > 1 ? ` ${renderPaginationDots(currentPage, totalPages, c)}` : "";
|
|
5725
5860
|
if (startIdx > 0) {
|
|
5726
|
-
lines.push(
|
|
5861
|
+
lines.push(
|
|
5862
|
+
`${bar} ${style.dim(`\u2191 ${startIdx} more above...`, c)}${endIdx >= total ? pageDots : ""}`
|
|
5863
|
+
);
|
|
5727
5864
|
}
|
|
5728
5865
|
const maxLabelCols = Math.min(
|
|
5729
5866
|
26,
|
|
@@ -5736,21 +5873,21 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5736
5873
|
const allRealSelected = realVisible.length > 0 && realVisible.every((o) => state.selected.has(o.value));
|
|
5737
5874
|
const someRealSelected = realVisible.some((o) => state.selected.has(o.value)) && !allRealSelected;
|
|
5738
5875
|
const isChecked = opt.isSelectAll ? allRealSelected : state.selected.has(opt.value);
|
|
5739
|
-
const pointer = isCurrent ? style.
|
|
5740
|
-
const checkbox = isChecked ? style.green("\u25C9", c) : opt.isSelectAll && someRealSelected ?
|
|
5876
|
+
const pointer = isCurrent ? fgHex(CHARM_PALETTE.hotPink, style.bold("\u276F", c), c) : " ";
|
|
5877
|
+
const checkbox = isChecked ? style.green("\u25C9", c) : opt.isSelectAll && someRealSelected ? fgHex(CHARM_PALETTE.fuchsia, "\u25D0", c) : style.dim("\u25EF", c);
|
|
5741
5878
|
const labelRaw = opt.label.length > maxLabelCols ? `${opt.label.slice(0, maxLabelCols - 1)}\u2026` : opt.label;
|
|
5742
5879
|
const labelPadded = padVisible(labelRaw, maxLabelCols + 1, "left");
|
|
5743
|
-
const styledLabel = isCurrent ? style.bold(labelPadded, c) : isChecked ? style.green(labelPadded, c) : labelPadded;
|
|
5880
|
+
const styledLabel = isCurrent ? fgHex(CHARM_PALETTE.fuchsia, style.bold(labelPadded, c), c) : isChecked ? style.green(labelPadded, c) : labelPadded;
|
|
5744
5881
|
const prefixWidth = 7 + maxLabelCols + 1;
|
|
5745
5882
|
const maxHintCols = Math.max(10, 76 - prefixWidth);
|
|
5746
5883
|
const rawHint = opt.hint ?? "";
|
|
5747
5884
|
const shortHint = rawHint.length > maxHintCols ? `${rawHint.slice(0, maxHintCols - 1)}\u2026` : rawHint;
|
|
5748
|
-
const hintPart = shortHint ? ` ${style.dim(shortHint, c)}` : "";
|
|
5885
|
+
const hintPart = shortHint ? ` ${isCurrent ? fgHex(CHARM_PALETTE.lavender, shortHint, c) : style.dim(shortHint, c)}` : "";
|
|
5749
5886
|
lines.push(`${bar} ${pointer} ${checkbox} ${styledLabel}${hintPart}`);
|
|
5750
5887
|
}
|
|
5751
5888
|
if (endIdx < total) {
|
|
5752
5889
|
lines.push(
|
|
5753
|
-
`${bar} ${style.dim(`\u2193 ${total - endIdx} more below...`, c)}`
|
|
5890
|
+
`${bar} ${style.dim(`\u2193 ${total - endIdx} more below...`, c)}${pageDots}`
|
|
5754
5891
|
);
|
|
5755
5892
|
}
|
|
5756
5893
|
}
|
|
@@ -5766,8 +5903,9 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5766
5903
|
const rawTarget = options.targetHint ?? "";
|
|
5767
5904
|
const shortTarget = rawTarget.length > 18 ? `${rawTarget.slice(0, 17)}\u2026` : rawTarget;
|
|
5768
5905
|
const targetSuffix = shortTarget ? ` \xB7 IDE: ${shortTarget}` : "";
|
|
5906
|
+
const styledSummary = state.selected.size > 0 ? fgHex(CHARM_PALETTE.mint, style.bold(summaryText, c), c) : fgHex(CHARM_PALETTE.lavender, style.bold(summaryText, c), c);
|
|
5769
5907
|
lines.push(
|
|
5770
|
-
`${style.dim("\u2570\u2500", c)} ${
|
|
5908
|
+
`${style.dim("\u2570\u2500", c)} ${styledSummary}${style.dim(`${targetSuffix} \u2014 Enter to ${submitVerb}`, c)}`
|
|
5771
5909
|
);
|
|
5772
5910
|
return lines.join("\n");
|
|
5773
5911
|
}
|
|
@@ -7038,16 +7176,19 @@ function runCli(argv) {
|
|
|
7038
7176
|
unit: "tokens"
|
|
7039
7177
|
});
|
|
7040
7178
|
const firstSkill = summary.skills[0]?.skillName ?? "security-sast-gate";
|
|
7179
|
+
const skillBadge = formatBadge("skill", "SKILL");
|
|
7180
|
+
const subagentBadge = formatBadge("subagent", "SUBAGENT");
|
|
7041
7181
|
const lines = [
|
|
7042
|
-
|
|
7043
|
-
`Skills (${summary.skills.length}) \u2014 Total L1 Routing Tax: ${summary.totalL1Tokens} tokens`,
|
|
7044
|
-
|
|
7182
|
+
renderHeaderBanner("Catalog \u2014 Hybrid Skills & Context-Isolated Agents"),
|
|
7183
|
+
`${style.dim("\u251C\u2500")} ${style.bold(`Skills (${summary.skills.length})`)} \u2014 Total L1 Routing Tax: ${style.green(`${summary.totalL1Tokens} tokens`)}`,
|
|
7184
|
+
`${style.dim("\u2502")} L1 Budget Meter: ${l1Bar}`,
|
|
7045
7185
|
...summary.skills.map(
|
|
7046
|
-
(s) =>
|
|
7186
|
+
(s) => `${style.dim("\u2502")} ${skillBadge} ${style.bold(s.skillName)} \u2014 L1: ${s.l1Tokens}t | L2: ${s.l2Lines} lines (${s.l2Tokens}t) | L3 Scripts: ${s.scriptsCount}`
|
|
7047
7187
|
),
|
|
7048
|
-
|
|
7188
|
+
style.dim("\u2502"),
|
|
7189
|
+
`${style.dim("\u251C\u2500")} ${style.bold(`Subagents (${summary.subagents.length})`)} \u2014 Context-Isolated Specialist Agents:`,
|
|
7049
7190
|
...summary.subagents.map(
|
|
7050
|
-
(a) =>
|
|
7191
|
+
(a) => `${style.dim("\u2502")} ${subagentBadge} ${style.bold(a.subagentName)} (prompt=${a.systemPromptTokens}t, max_out<=${a.maxOutputTokens}t, tools=${a.tools.length})`
|
|
7051
7192
|
),
|
|
7052
7193
|
renderNextSteps([
|
|
7053
7194
|
{
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { z } from 'zod';
|
|
|
8
8
|
* telemetry and Multi-Runtime Transpilation lockfiles.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
declare const SKILLOPS_VERSION = "1.3.
|
|
11
|
+
declare const SKILLOPS_VERSION = "1.3.8";
|
|
12
12
|
/**
|
|
13
13
|
* Count whitespace-delimited words in text.
|
|
14
14
|
*/
|
|
@@ -2173,6 +2173,67 @@ declare function renderGlobalHelp(version: string, colorEnabled?: boolean): stri
|
|
|
2173
2173
|
*/
|
|
2174
2174
|
declare function renderCommandHelp(spec: CommandHelpSpec, version: string, colorEnabled?: boolean): string;
|
|
2175
2175
|
|
|
2176
|
+
/**
|
|
2177
|
+
* Charmbracelet Lip Gloss & Bubbles Inspired Terminal Styling Engine (`src/ui/lipgloss.ts`).
|
|
2178
|
+
*
|
|
2179
|
+
* Zero-dependency TypeScript implementation of Lip Gloss TrueColor (24-bit RGB)
|
|
2180
|
+
* palettes, background pills, Bubbles paginator dots, keycap status bars, and
|
|
2181
|
+
* ANSI-aware horizontal block composition (`joinHorizontal`).
|
|
2182
|
+
*/
|
|
2183
|
+
/**
|
|
2184
|
+
* Official Charmbracelet Lip Gloss / Huh / Bubbles inspired TrueColor palette.
|
|
2185
|
+
*/
|
|
2186
|
+
declare const CHARM_PALETTE: {
|
|
2187
|
+
readonly indigo: "#7D56F4";
|
|
2188
|
+
readonly fuchsia: "#EE6FF8";
|
|
2189
|
+
readonly hotPink: "#F25D94";
|
|
2190
|
+
readonly mint: "#04B575";
|
|
2191
|
+
readonly amber: "#FFBD2E";
|
|
2192
|
+
readonly coral: "#FF5F56";
|
|
2193
|
+
readonly cyan: "#00D7FF";
|
|
2194
|
+
readonly lavender: "#B4A7D6";
|
|
2195
|
+
readonly white: "#FAFAFA";
|
|
2196
|
+
readonly muted: "#6C6C6C";
|
|
2197
|
+
readonly subtle: "#4A4A4A";
|
|
2198
|
+
readonly surface: "#2A2438";
|
|
2199
|
+
readonly keycapBg: "#302B3F";
|
|
2200
|
+
};
|
|
2201
|
+
type CharmColorKey = keyof typeof CHARM_PALETTE;
|
|
2202
|
+
/**
|
|
2203
|
+
* Parse a `#RRGGBB` or `#RGB` hex color string into an `[r, g, b]` tuple.
|
|
2204
|
+
*/
|
|
2205
|
+
declare function hexToRgb(hex: string): readonly [number, number, number];
|
|
2206
|
+
/**
|
|
2207
|
+
* Apply 24-bit TrueColor foreground (`\x1b[38;2;R;G;Bm`) when color is enabled.
|
|
2208
|
+
*/
|
|
2209
|
+
declare function fgHex(hex: string, text: string, enabled?: boolean): string;
|
|
2210
|
+
/**
|
|
2211
|
+
* Apply 24-bit TrueColor background (`\x1b[48;2;R;G;Bm`) when color is enabled.
|
|
2212
|
+
*/
|
|
2213
|
+
declare function bgHex(hex: string, text: string, enabled?: boolean): string;
|
|
2214
|
+
interface PillOptions {
|
|
2215
|
+
readonly fg?: string;
|
|
2216
|
+
readonly bg?: string;
|
|
2217
|
+
readonly bold?: boolean;
|
|
2218
|
+
readonly colorEnabled?: boolean;
|
|
2219
|
+
}
|
|
2220
|
+
/**
|
|
2221
|
+
* Render a Lip Gloss background pill badge without altering visible character length.
|
|
2222
|
+
*/
|
|
2223
|
+
declare function renderPill(text: string, options?: PillOptions): string;
|
|
2224
|
+
/**
|
|
2225
|
+
* Render a Charm `bubbles/help` style keybinding hint (`key action`).
|
|
2226
|
+
*/
|
|
2227
|
+
declare function renderKeycap(keyLabel: string, actionLabel: string, colorEnabled?: boolean): string;
|
|
2228
|
+
/**
|
|
2229
|
+
* Render Charm `bubbles/paginator` style pagination dots (`• ◦ ◦`).
|
|
2230
|
+
*/
|
|
2231
|
+
declare function renderPaginationDots(currentPage: number, totalPages: number, colorEnabled?: boolean): string;
|
|
2232
|
+
/**
|
|
2233
|
+
* Compose two multi-line blocks horizontally (`lipgloss.JoinHorizontal`).
|
|
2234
|
+
*/
|
|
2235
|
+
declare function joinHorizontal(align: "top" | "center" | "bottom", leftBlock: string, rightBlock: string, gap?: number): string;
|
|
2236
|
+
|
|
2176
2237
|
/**
|
|
2177
2238
|
* Zero-dependency interactive terminal multi-select prompt (`src/ui/prompt.ts`).
|
|
2178
2239
|
*
|
|
@@ -2361,4 +2422,4 @@ declare const DEFAULT_VALID_COMMANDS: readonly string[];
|
|
|
2361
2422
|
*/
|
|
2362
2423
|
declare function suggestCommand(unknownCommand: string, validCommands?: readonly string[]): string | null;
|
|
2363
2424
|
|
|
2364
|
-
export { ALL_RUNTIME_TARGETS, type AddOptions, type AnalyzeTokenEconomyOptions, type ApplyMultiSelectKeyOptions, type AuditCatalogOptions, type BadgeType, type BenchmarkArm, BenchmarkArmSchema, type BenchmarkDelta, BenchmarkDeltaSchema, type BoxOptions, COMMAND_HELP_SPECS, CORE_RUNTIME_TARGETS, type CatalogEvalSummary, CatalogEvalSummarySchema, type CatalogItemInfo, type CatalogSearchMatch, type CatalogSearchReport, type CatalogTokenBudgetSummary, type CatalogTrack, CatalogTrackSchema, type CleanOptions, type CollisionPair, CollisionPairSchema, type CollisionReport, CollisionReportSchema, type CollisionSeverity, CollisionSeveritySchema, type ColorOverrideOptions, type CommandHelpSpec, type CommandOptionSpec, type CreateMultiSelectStateOptions, DEFAULT_VALID_COMMANDS, type DiagnoseRepositoryOptions, type DoctorCheckItem, type DoctorReport, type EvalAssertion, EvalAssertionSchema, type EvalCase, EvalCaseSchema, ExitCode, type ExitCodeValue, type HarnessCategory, type HarnessInspectionEntry, type HarnessInspectionReport, type HarnessSkillFormat, type JsonRpcRequest, type JsonRpcResponse, type LoadedSkillOpsConfigResult, type LockfileArtifactDiagnostic, type McpConfigAction, type McpServerContext, type McpSetupOptions, type McpSetupReport, type MultiSelectOption, type MultiSelectState, type MultiSelectTab, type NextStepHint, type ParseSkillOptions, type ParsedSkillDirectory, type ParsedSubagentFile, type QuickstartOptions, type QuickstartReport, RUNTIME_HARNESS_SPECS, type RemoveOptions, type RenderMultiSelectOptions, RepoFingerprinter, type RepoProfile, RepoProfileSchema, type RouteOptions, type RoutedBundle, RoutedBundleSchema, type RoutingSignals, RoutingSignalsSchema, type RuntimeHarnessSpec, type RuntimeTarget, RuntimeTargetSchema, SKILLOPS_VERSION, type ScaffoldOptions, type ScaffoldResult, type ScoredSkill, ScoredSkillSchema, type ScriptEntrypoint, ScriptEntrypointSchema, type SkillBenchmark, SkillBenchmarkSchema, type SkillEntrypoints, SkillEntrypointsSchema, type SkillEvalSuite, SkillEvalSuiteSchema, type SkillManifest, type SkillManifestInput, SkillManifestSchema, type SkillOpsConfig, SkillOpsConfigSchema, type SkillOpsDetectedStackConfig, SkillOpsDetectedStackConfigSchema, type SkillOpsTokenEconomyConfig, SkillOpsTokenEconomyConfigSchema, type SkillTokenBudgetAudit, type SkippedSkill, SkippedSkillSchema, type SubagentManifest, SubagentManifestSchema, type SubagentTokenBudgetAudit, type SyncLockEntry, SyncLockEntrySchema, type SyncLockfile, SyncLockfileSchema, type SyncOptions, type SyncReport, SyncReportSchema, type SyncedArtifact, SyncedArtifactSchema, type TableOptions, type TokenBarOptions, type TokenEconomyReport, TokenEconomyReportSchema, type TokenFileCategory, TokenFileCategorySchema, type TokenFileEntry, TokenFileEntrySchema, type TokenWasteHotspot, TokenWasteHotspotSchema, addSkillOrSubagent, analyzeRepoTokenEconomy, applyMultiSelectKey, auditCatalog, auditCatalogTokenBudgets, auditSkillTokenBudget, auditSubagentTokenBudget, classifyCollisionSeverity, cleanSyncedArtifacts, compileSkillBundle, computeCollisionMatrix, computeFeatureCosine, computeIdfWeights, computeSha256, countWords, createCollisionPair, createCollisionReport, createMultiSelectState, createSkillManifest, createSubagentManifest, detectInstalledHarnesses, diagnoseRepository, discoverSkillDirectories, discoverSubagentFiles, estimateTokenCount, evaluateCatalog, evaluateSkillDirectory, extractSkillFeatures, findCommandHelpSpec, fingerprintRepository, formatBadge, formatCatalogItemInfo, formatCatalogSearchReport, formatDoctorReport, formatEvalSummary, formatHarnessInspectionReport, formatMcpSetupReport, formatQuickstartReport, formatRoutedBundle, formatScaffoldReport, formatSyncReport, formatTokenEconomyReport, getFilteredTabOptions, handleMcpJsonRpcRequest, inspectCatalogItem, inspectHarnesses, isColorEnabled, levenshteinDistance, loadSkillOpsConfig, normalizePackageName, padVisible, parseSkillDirectory, parseSkillMdFile, parseSubagentFile, parseSubagentMdFile, removeSkillOrSubagent, renderAiUsageGuide, renderBox, renderCodexAgentsIndex, renderCommandHelp, renderGlobalHelp, renderHeaderBanner, renderMultiSelectFrame, renderNextSteps, renderProgressBar, renderSectionHeader, renderStep, renderTable, renderTokenBar, resolveRuntimeTargets, routeRepository, runMultiSelectPrompt, runQuickstart, scaffoldFrameworkItem, scoreSkillAgainstProfile, searchCatalog, setupMcpForHarnesses, splitFrontmatter, startMcpStdioServer, stripAnsi, stripCodexAgentsBlock, stripNegativeTriggerClauses, style, suggestCommand, syncRepository, tokenizeRoutingText, visibleLength };
|
|
2425
|
+
export { ALL_RUNTIME_TARGETS, type AddOptions, type AnalyzeTokenEconomyOptions, type ApplyMultiSelectKeyOptions, type AuditCatalogOptions, type BadgeType, type BenchmarkArm, BenchmarkArmSchema, type BenchmarkDelta, BenchmarkDeltaSchema, type BoxOptions, CHARM_PALETTE, COMMAND_HELP_SPECS, CORE_RUNTIME_TARGETS, type CatalogEvalSummary, CatalogEvalSummarySchema, type CatalogItemInfo, type CatalogSearchMatch, type CatalogSearchReport, type CatalogTokenBudgetSummary, type CatalogTrack, CatalogTrackSchema, type CharmColorKey, type CleanOptions, type CollisionPair, CollisionPairSchema, type CollisionReport, CollisionReportSchema, type CollisionSeverity, CollisionSeveritySchema, type ColorOverrideOptions, type CommandHelpSpec, type CommandOptionSpec, type CreateMultiSelectStateOptions, DEFAULT_VALID_COMMANDS, type DiagnoseRepositoryOptions, type DoctorCheckItem, type DoctorReport, type EvalAssertion, EvalAssertionSchema, type EvalCase, EvalCaseSchema, ExitCode, type ExitCodeValue, type HarnessCategory, type HarnessInspectionEntry, type HarnessInspectionReport, type HarnessSkillFormat, type JsonRpcRequest, type JsonRpcResponse, type LoadedSkillOpsConfigResult, type LockfileArtifactDiagnostic, type McpConfigAction, type McpServerContext, type McpSetupOptions, type McpSetupReport, type MultiSelectOption, type MultiSelectState, type MultiSelectTab, type NextStepHint, type ParseSkillOptions, type ParsedSkillDirectory, type ParsedSubagentFile, type PillOptions, type QuickstartOptions, type QuickstartReport, RUNTIME_HARNESS_SPECS, type RemoveOptions, type RenderMultiSelectOptions, RepoFingerprinter, type RepoProfile, RepoProfileSchema, type RouteOptions, type RoutedBundle, RoutedBundleSchema, type RoutingSignals, RoutingSignalsSchema, type RuntimeHarnessSpec, type RuntimeTarget, RuntimeTargetSchema, SKILLOPS_VERSION, type ScaffoldOptions, type ScaffoldResult, type ScoredSkill, ScoredSkillSchema, type ScriptEntrypoint, ScriptEntrypointSchema, type SkillBenchmark, SkillBenchmarkSchema, type SkillEntrypoints, SkillEntrypointsSchema, type SkillEvalSuite, SkillEvalSuiteSchema, type SkillManifest, type SkillManifestInput, SkillManifestSchema, type SkillOpsConfig, SkillOpsConfigSchema, type SkillOpsDetectedStackConfig, SkillOpsDetectedStackConfigSchema, type SkillOpsTokenEconomyConfig, SkillOpsTokenEconomyConfigSchema, type SkillTokenBudgetAudit, type SkippedSkill, SkippedSkillSchema, type SubagentManifest, SubagentManifestSchema, type SubagentTokenBudgetAudit, type SyncLockEntry, SyncLockEntrySchema, type SyncLockfile, SyncLockfileSchema, type SyncOptions, type SyncReport, SyncReportSchema, type SyncedArtifact, SyncedArtifactSchema, type TableOptions, type TokenBarOptions, type TokenEconomyReport, TokenEconomyReportSchema, type TokenFileCategory, TokenFileCategorySchema, type TokenFileEntry, TokenFileEntrySchema, type TokenWasteHotspot, TokenWasteHotspotSchema, addSkillOrSubagent, analyzeRepoTokenEconomy, applyMultiSelectKey, auditCatalog, auditCatalogTokenBudgets, auditSkillTokenBudget, auditSubagentTokenBudget, bgHex, classifyCollisionSeverity, cleanSyncedArtifacts, compileSkillBundle, computeCollisionMatrix, computeFeatureCosine, computeIdfWeights, computeSha256, countWords, createCollisionPair, createCollisionReport, createMultiSelectState, createSkillManifest, createSubagentManifest, detectInstalledHarnesses, diagnoseRepository, discoverSkillDirectories, discoverSubagentFiles, estimateTokenCount, evaluateCatalog, evaluateSkillDirectory, extractSkillFeatures, fgHex, findCommandHelpSpec, fingerprintRepository, formatBadge, formatCatalogItemInfo, formatCatalogSearchReport, formatDoctorReport, formatEvalSummary, formatHarnessInspectionReport, formatMcpSetupReport, formatQuickstartReport, formatRoutedBundle, formatScaffoldReport, formatSyncReport, formatTokenEconomyReport, getFilteredTabOptions, handleMcpJsonRpcRequest, hexToRgb, inspectCatalogItem, inspectHarnesses, isColorEnabled, joinHorizontal, levenshteinDistance, loadSkillOpsConfig, normalizePackageName, padVisible, parseSkillDirectory, parseSkillMdFile, parseSubagentFile, parseSubagentMdFile, removeSkillOrSubagent, renderAiUsageGuide, renderBox, renderCodexAgentsIndex, renderCommandHelp, renderGlobalHelp, renderHeaderBanner, renderKeycap, renderMultiSelectFrame, renderNextSteps, renderPaginationDots, renderPill, renderProgressBar, renderSectionHeader, renderStep, renderTable, renderTokenBar, resolveRuntimeTargets, routeRepository, runMultiSelectPrompt, runQuickstart, scaffoldFrameworkItem, scoreSkillAgainstProfile, searchCatalog, setupMcpForHarnesses, splitFrontmatter, startMcpStdioServer, stripAnsi, stripCodexAgentsBlock, stripNegativeTriggerClauses, style, suggestCommand, syncRepository, tokenizeRoutingText, visibleLength };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import YAML from "yaml";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
var SKILLOPS_VERSION = "1.3.
|
|
5
|
+
var SKILLOPS_VERSION = "1.3.8";
|
|
6
6
|
var SKILL_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
7
7
|
var SEMVER_REGEX = /^\d+\.\d+\.\d+$/;
|
|
8
8
|
var FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
@@ -1418,9 +1418,142 @@ import fs3 from "fs";
|
|
|
1418
1418
|
import path2 from "path";
|
|
1419
1419
|
import YAML2 from "yaml";
|
|
1420
1420
|
|
|
1421
|
-
// src/ui/
|
|
1421
|
+
// src/ui/lipgloss.ts
|
|
1422
1422
|
var ESC = String.fromCharCode(27);
|
|
1423
|
-
var
|
|
1423
|
+
var CHARM_PALETTE = {
|
|
1424
|
+
indigo: "#7D56F4",
|
|
1425
|
+
fuchsia: "#EE6FF8",
|
|
1426
|
+
hotPink: "#F25D94",
|
|
1427
|
+
mint: "#04B575",
|
|
1428
|
+
amber: "#FFBD2E",
|
|
1429
|
+
coral: "#FF5F56",
|
|
1430
|
+
cyan: "#00D7FF",
|
|
1431
|
+
lavender: "#B4A7D6",
|
|
1432
|
+
white: "#FAFAFA",
|
|
1433
|
+
muted: "#6C6C6C",
|
|
1434
|
+
subtle: "#4A4A4A",
|
|
1435
|
+
surface: "#2A2438",
|
|
1436
|
+
keycapBg: "#302B3F"
|
|
1437
|
+
};
|
|
1438
|
+
function hexToRgb(hex) {
|
|
1439
|
+
const cleaned = hex.trim().replace(/^#/, "");
|
|
1440
|
+
if (cleaned.length === 3) {
|
|
1441
|
+
const r2 = Number.parseInt(`${cleaned[0]}${cleaned[0]}`, 16);
|
|
1442
|
+
const g2 = Number.parseInt(`${cleaned[1]}${cleaned[1]}`, 16);
|
|
1443
|
+
const b2 = Number.parseInt(`${cleaned[2]}${cleaned[2]}`, 16);
|
|
1444
|
+
return [
|
|
1445
|
+
Number.isNaN(r2) ? 255 : r2,
|
|
1446
|
+
Number.isNaN(g2) ? 255 : g2,
|
|
1447
|
+
Number.isNaN(b2) ? 255 : b2
|
|
1448
|
+
];
|
|
1449
|
+
}
|
|
1450
|
+
const r = Number.parseInt(cleaned.slice(0, 2), 16);
|
|
1451
|
+
const g = Number.parseInt(cleaned.slice(2, 4), 16);
|
|
1452
|
+
const b = Number.parseInt(cleaned.slice(4, 6), 16);
|
|
1453
|
+
return [
|
|
1454
|
+
Number.isNaN(r) ? 255 : r,
|
|
1455
|
+
Number.isNaN(g) ? 255 : g,
|
|
1456
|
+
Number.isNaN(b) ? 255 : b
|
|
1457
|
+
];
|
|
1458
|
+
}
|
|
1459
|
+
function fgHex(hex, text, enabled) {
|
|
1460
|
+
const useColor = enabled ?? isColorEnabled();
|
|
1461
|
+
if (!useColor || text.length === 0) {
|
|
1462
|
+
return text;
|
|
1463
|
+
}
|
|
1464
|
+
const [r, g, b] = hexToRgb(hex);
|
|
1465
|
+
return `${ESC}[38;2;${r};${g};${b}m${text}${ESC}[39m`;
|
|
1466
|
+
}
|
|
1467
|
+
function bgHex(hex, text, enabled) {
|
|
1468
|
+
const useColor = enabled ?? isColorEnabled();
|
|
1469
|
+
if (!useColor || text.length === 0) {
|
|
1470
|
+
return text;
|
|
1471
|
+
}
|
|
1472
|
+
const [r, g, b] = hexToRgb(hex);
|
|
1473
|
+
return `${ESC}[48;2;${r};${g};${b}m${text}${ESC}[49m`;
|
|
1474
|
+
}
|
|
1475
|
+
function renderPill(text, options) {
|
|
1476
|
+
const useColor = options?.colorEnabled ?? isColorEnabled();
|
|
1477
|
+
if (!useColor || text.length === 0) {
|
|
1478
|
+
return text;
|
|
1479
|
+
}
|
|
1480
|
+
const fg = options?.fg ?? CHARM_PALETTE.white;
|
|
1481
|
+
const bg = options?.bg ?? CHARM_PALETTE.indigo;
|
|
1482
|
+
const bold = options?.bold ?? true;
|
|
1483
|
+
let styled = fgHex(fg, text, true);
|
|
1484
|
+
styled = bgHex(bg, styled, true);
|
|
1485
|
+
if (bold) {
|
|
1486
|
+
styled = `${ESC}[1m${styled}${ESC}[22m`;
|
|
1487
|
+
}
|
|
1488
|
+
return styled;
|
|
1489
|
+
}
|
|
1490
|
+
function renderKeycap(keyLabel, actionLabel, colorEnabled) {
|
|
1491
|
+
const useColor = colorEnabled ?? isColorEnabled();
|
|
1492
|
+
if (!useColor) {
|
|
1493
|
+
return `${keyLabel} ${actionLabel}`;
|
|
1494
|
+
}
|
|
1495
|
+
const keyStyled = `${ESC}[1m${fgHex(CHARM_PALETTE.lavender, keyLabel, true)}${ESC}[22m`;
|
|
1496
|
+
const actionStyled = fgHex(CHARM_PALETTE.muted, actionLabel, true);
|
|
1497
|
+
return `${keyStyled} ${actionStyled}`;
|
|
1498
|
+
}
|
|
1499
|
+
function renderPaginationDots(currentPage, totalPages, colorEnabled) {
|
|
1500
|
+
const safeTotal = Math.max(1, Math.min(12, totalPages));
|
|
1501
|
+
const safeCurrent = Math.max(0, Math.min(safeTotal - 1, currentPage));
|
|
1502
|
+
const useColor = colorEnabled ?? isColorEnabled();
|
|
1503
|
+
const dots = [];
|
|
1504
|
+
for (let i = 0; i < safeTotal; i++) {
|
|
1505
|
+
if (i === safeCurrent) {
|
|
1506
|
+
dots.push(
|
|
1507
|
+
useColor ? `${ESC}[1m${fgHex(CHARM_PALETTE.hotPink, "\u2022", true)}${ESC}[22m` : "\u2022"
|
|
1508
|
+
);
|
|
1509
|
+
} else {
|
|
1510
|
+
dots.push(useColor ? fgHex(CHARM_PALETTE.muted, "\u25E6", true) : "\u25E6");
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
return dots.join(" ");
|
|
1514
|
+
}
|
|
1515
|
+
function joinHorizontal(align, leftBlock, rightBlock, gap = 2) {
|
|
1516
|
+
const leftLines = leftBlock.split("\n");
|
|
1517
|
+
const rightLines = rightBlock.split("\n");
|
|
1518
|
+
const totalRows = Math.max(leftLines.length, rightLines.length);
|
|
1519
|
+
const leftWidth = leftLines.reduce(
|
|
1520
|
+
(max, line) => Math.max(max, visibleLength(line)),
|
|
1521
|
+
0
|
|
1522
|
+
);
|
|
1523
|
+
const gapStr = " ".repeat(Math.max(0, gap));
|
|
1524
|
+
const padBlockLines = (lines) => {
|
|
1525
|
+
const diff = totalRows - lines.length;
|
|
1526
|
+
if (diff <= 0) {
|
|
1527
|
+
return lines;
|
|
1528
|
+
}
|
|
1529
|
+
if (align === "bottom") {
|
|
1530
|
+
return [...Array.from({ length: diff }, () => ""), ...lines];
|
|
1531
|
+
}
|
|
1532
|
+
if (align === "center") {
|
|
1533
|
+
const top = Math.floor(diff / 2);
|
|
1534
|
+
const bottom = diff - top;
|
|
1535
|
+
return [
|
|
1536
|
+
...Array.from({ length: top }, () => ""),
|
|
1537
|
+
...lines,
|
|
1538
|
+
...Array.from({ length: bottom }, () => "")
|
|
1539
|
+
];
|
|
1540
|
+
}
|
|
1541
|
+
return [...lines, ...Array.from({ length: diff }, () => "")];
|
|
1542
|
+
};
|
|
1543
|
+
const paddedLeft = padBlockLines(leftLines);
|
|
1544
|
+
const paddedRight = padBlockLines(rightLines);
|
|
1545
|
+
const out = [];
|
|
1546
|
+
for (let i = 0; i < totalRows; i++) {
|
|
1547
|
+
const l = padVisible(paddedLeft[i] ?? "", leftWidth, "left");
|
|
1548
|
+
const r = paddedRight[i] ?? "";
|
|
1549
|
+
out.push(r.length > 0 ? `${l}${gapStr}${r}` : l.trimEnd());
|
|
1550
|
+
}
|
|
1551
|
+
return out.join("\n");
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
// src/ui/terminal.ts
|
|
1555
|
+
var ESC2 = String.fromCharCode(27);
|
|
1556
|
+
var ANSI_ESCAPE_REGEX = new RegExp(`${ESC2}\\[[0-9;]*m`, "g");
|
|
1424
1557
|
function isColorEnabled(options) {
|
|
1425
1558
|
const env = options?.env ?? process.env;
|
|
1426
1559
|
const isTTY = options?.isTTY ?? Boolean(process.stdout?.isTTY);
|
|
@@ -1446,21 +1579,21 @@ function wrapAnsi(openCode, closeCode, text, enabled) {
|
|
|
1446
1579
|
if (!useColor || text.length === 0) {
|
|
1447
1580
|
return text;
|
|
1448
1581
|
}
|
|
1449
|
-
return `${
|
|
1582
|
+
return `${ESC2}[${openCode}m${text}${ESC2}[${closeCode}m`;
|
|
1450
1583
|
}
|
|
1451
1584
|
var style = {
|
|
1452
1585
|
bold: (text, enabled) => wrapAnsi("1", "22", text, enabled),
|
|
1453
1586
|
dim: (text, enabled) => wrapAnsi("2", "22", text, enabled),
|
|
1454
1587
|
italic: (text, enabled) => wrapAnsi("3", "23", text, enabled),
|
|
1455
1588
|
underline: (text, enabled) => wrapAnsi("4", "24", text, enabled),
|
|
1456
|
-
cyan: (text, enabled) =>
|
|
1457
|
-
green: (text, enabled) =>
|
|
1458
|
-
yellow: (text, enabled) =>
|
|
1459
|
-
red: (text, enabled) =>
|
|
1460
|
-
magenta: (text, enabled) =>
|
|
1461
|
-
blue: (text, enabled) =>
|
|
1462
|
-
gray: (text, enabled) =>
|
|
1463
|
-
white: (text, enabled) =>
|
|
1589
|
+
cyan: (text, enabled) => fgHex(CHARM_PALETTE.cyan, text, enabled),
|
|
1590
|
+
green: (text, enabled) => fgHex(CHARM_PALETTE.mint, text, enabled),
|
|
1591
|
+
yellow: (text, enabled) => fgHex(CHARM_PALETTE.amber, text, enabled),
|
|
1592
|
+
red: (text, enabled) => fgHex(CHARM_PALETTE.coral, text, enabled),
|
|
1593
|
+
magenta: (text, enabled) => fgHex(CHARM_PALETTE.fuchsia, text, enabled),
|
|
1594
|
+
blue: (text, enabled) => fgHex(CHARM_PALETTE.indigo, text, enabled),
|
|
1595
|
+
gray: (text, enabled) => fgHex(CHARM_PALETTE.muted, text, enabled),
|
|
1596
|
+
white: (text, enabled) => fgHex(CHARM_PALETTE.white, text, enabled)
|
|
1464
1597
|
};
|
|
1465
1598
|
function stripAnsi(text) {
|
|
1466
1599
|
return text.replace(ANSI_ESCAPE_REGEX, "");
|
|
@@ -1488,7 +1621,7 @@ function renderBox(lines, options) {
|
|
|
1488
1621
|
const paddingX = options?.paddingX ?? 2;
|
|
1489
1622
|
const minWidth = options?.minWidth ?? 36;
|
|
1490
1623
|
const colorEnabled = options?.colorEnabled;
|
|
1491
|
-
const borderFn = options?.borderColor ?? style.
|
|
1624
|
+
const borderFn = options?.borderColor ?? style.blue;
|
|
1492
1625
|
const titleText = options?.title ? ` ${options.title.trim()} ` : "";
|
|
1493
1626
|
const titleVisibleLen = visibleLength(titleText);
|
|
1494
1627
|
const maxLineLen = lines.reduce(
|
|
@@ -1513,7 +1646,13 @@ function renderBox(lines, options) {
|
|
|
1513
1646
|
function renderHeaderBanner(subtitle = "Framework & Library for AI Skills & Subagents", options) {
|
|
1514
1647
|
const ver = options?.version ?? SKILLOPS_VERSION;
|
|
1515
1648
|
const c = options?.colorEnabled;
|
|
1516
|
-
|
|
1649
|
+
const brandPill = renderPill(`\u25C6 SkillOps v${ver}`, {
|
|
1650
|
+
fg: CHARM_PALETTE.white,
|
|
1651
|
+
bg: CHARM_PALETTE.indigo,
|
|
1652
|
+
bold: true,
|
|
1653
|
+
colorEnabled: c
|
|
1654
|
+
});
|
|
1655
|
+
return `${brandPill} ${style.dim("\u2014", c)} ${fgHex(CHARM_PALETTE.lavender, subtitle, c)}`;
|
|
1517
1656
|
}
|
|
1518
1657
|
function renderTable(headers, rows, options) {
|
|
1519
1658
|
const indent = " ".repeat(options?.indent ?? 2);
|
|
@@ -1590,15 +1729,19 @@ function formatBadge(type, customLabel, colorEnabled) {
|
|
|
1590
1729
|
colorEnabled
|
|
1591
1730
|
);
|
|
1592
1731
|
case "skill":
|
|
1593
|
-
return
|
|
1594
|
-
|
|
1732
|
+
return renderPill(`[${customLabel ?? "SKILL"}]`, {
|
|
1733
|
+
fg: CHARM_PALETTE.white,
|
|
1734
|
+
bg: CHARM_PALETTE.indigo,
|
|
1735
|
+
bold: true,
|
|
1595
1736
|
colorEnabled
|
|
1596
|
-
);
|
|
1737
|
+
});
|
|
1597
1738
|
case "subagent":
|
|
1598
|
-
return
|
|
1599
|
-
|
|
1739
|
+
return renderPill(`[${customLabel ?? "SUBAGENT"}]`, {
|
|
1740
|
+
fg: CHARM_PALETTE.white,
|
|
1741
|
+
bg: CHARM_PALETTE.hotPink,
|
|
1742
|
+
bold: true,
|
|
1600
1743
|
colorEnabled
|
|
1601
|
-
);
|
|
1744
|
+
});
|
|
1602
1745
|
}
|
|
1603
1746
|
}
|
|
1604
1747
|
function renderStep(step, total, title, detail, status = "done", colorEnabled) {
|
|
@@ -5702,27 +5845,51 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5702
5845
|
const agentTabTitle = options.tabLabels?.agent ?? "Agents";
|
|
5703
5846
|
const submitVerb = options.submitActionLabel ?? "import";
|
|
5704
5847
|
const isSinglePage = totalAgents === 0 || totalSkills === 0;
|
|
5705
|
-
const header =
|
|
5706
|
-
|
|
5707
|
-
|
|
5848
|
+
const header = renderPill(`\u25C6 ${title}`, {
|
|
5849
|
+
fg: CHARM_PALETTE.white,
|
|
5850
|
+
bg: CHARM_PALETTE.indigo,
|
|
5851
|
+
bold: true,
|
|
5852
|
+
colorEnabled: c
|
|
5853
|
+
});
|
|
5854
|
+
const sep = style.dim(" \xB7 ", c);
|
|
5855
|
+
const keyItems = [
|
|
5856
|
+
renderKeycap("\u2191/\u2193", "move", c),
|
|
5857
|
+
...isSinglePage ? [] : [renderKeycap("\u2190/\u2192", "tab", c)],
|
|
5858
|
+
renderKeycap("Space", "select", c),
|
|
5859
|
+
...state.searchMode ? [renderKeycap("Esc", "clear", c)] : [renderKeycap("/", "search", c), renderKeycap("a", "all", c)],
|
|
5860
|
+
renderKeycap("Enter", submitVerb, c)
|
|
5861
|
+
];
|
|
5862
|
+
const instructions = `${bar} ${keyItems.join(sep)}`;
|
|
5708
5863
|
const lines = [header];
|
|
5709
5864
|
if (options.subtitle) {
|
|
5710
|
-
lines.push(`${bar} ${options.subtitle}`);
|
|
5865
|
+
lines.push(`${bar} ${fgHex(CHARM_PALETTE.lavender, options.subtitle, c)}`);
|
|
5711
5866
|
}
|
|
5712
5867
|
lines.push(instructions, bar);
|
|
5713
5868
|
const hasQuery = state.searchQuery.length > 0;
|
|
5714
5869
|
const skillCountStr = hasQuery ? `${realFilteredSkills.length}/${totalSkills}` : `${totalSkills}`;
|
|
5715
5870
|
const agentCountStr = hasQuery ? `${realFilteredAgents.length}/${totalAgents}` : `${totalAgents}`;
|
|
5716
|
-
const skillTabLabel = state.activeTab === "skill" ?
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5871
|
+
const skillTabLabel = state.activeTab === "skill" ? renderPill(`[ \u25C6 ${skillTabTitle} (${skillCountStr}) ]`, {
|
|
5872
|
+
fg: CHARM_PALETTE.white,
|
|
5873
|
+
bg: CHARM_PALETTE.indigo,
|
|
5874
|
+
bold: true,
|
|
5875
|
+
colorEnabled: c
|
|
5876
|
+
}) : style.dim(`\u25CB ${skillTabTitle} (${skillCountStr})`, c);
|
|
5877
|
+
const agentTabLabel = state.activeTab === "agent" ? renderPill(`[ \u25C6 ${agentTabTitle} (${agentCountStr}) ]`, {
|
|
5878
|
+
fg: CHARM_PALETTE.white,
|
|
5879
|
+
bg: CHARM_PALETTE.hotPink,
|
|
5880
|
+
bold: true,
|
|
5881
|
+
colorEnabled: c
|
|
5882
|
+
}) : style.dim(`\u25CB ${agentTabTitle} (${agentCountStr})`, c);
|
|
5724
5883
|
const rawQuerySlice = state.searchQuery.length > 14 ? `\u2026${state.searchQuery.slice(-13)}` : state.searchQuery;
|
|
5725
|
-
const searchSuffix = state.searchMode || hasQuery ? ` ${
|
|
5884
|
+
const searchSuffix = state.searchMode || hasQuery ? ` ${renderPill(
|
|
5885
|
+
`/ Filter: ${rawQuerySlice}${state.searchMode ? "\u2588" : ""}`,
|
|
5886
|
+
{
|
|
5887
|
+
fg: CHARM_PALETTE.amber,
|
|
5888
|
+
bg: CHARM_PALETTE.surface,
|
|
5889
|
+
bold: true,
|
|
5890
|
+
colorEnabled: c
|
|
5891
|
+
}
|
|
5892
|
+
)}` : ` ${style.dim("(/ search)", c)}`;
|
|
5726
5893
|
const singleTabLabel = totalSkills > 0 ? skillTabLabel : agentTabLabel;
|
|
5727
5894
|
lines.push(
|
|
5728
5895
|
isSinglePage ? `${style.dim("\u251C\u2500", c)} ${singleTabLabel}${searchSuffix}` : `${style.dim("\u251C\u2500", c)} ${skillTabLabel} ${agentTabLabel}${searchSuffix}`,
|
|
@@ -5740,8 +5907,16 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5740
5907
|
startIdx = Math.max(0, Math.min(state.cursor - half, total - maxVisible));
|
|
5741
5908
|
}
|
|
5742
5909
|
const endIdx = Math.min(total, startIdx + maxVisible);
|
|
5910
|
+
const totalPages = Math.max(1, Math.ceil(total / maxVisible));
|
|
5911
|
+
const currentPage = Math.min(
|
|
5912
|
+
totalPages - 1,
|
|
5913
|
+
Math.floor(state.cursor / maxVisible)
|
|
5914
|
+
);
|
|
5915
|
+
const pageDots = totalPages > 1 ? ` ${renderPaginationDots(currentPage, totalPages, c)}` : "";
|
|
5743
5916
|
if (startIdx > 0) {
|
|
5744
|
-
lines.push(
|
|
5917
|
+
lines.push(
|
|
5918
|
+
`${bar} ${style.dim(`\u2191 ${startIdx} more above...`, c)}${endIdx >= total ? pageDots : ""}`
|
|
5919
|
+
);
|
|
5745
5920
|
}
|
|
5746
5921
|
const maxLabelCols = Math.min(
|
|
5747
5922
|
26,
|
|
@@ -5754,21 +5929,21 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5754
5929
|
const allRealSelected = realVisible.length > 0 && realVisible.every((o) => state.selected.has(o.value));
|
|
5755
5930
|
const someRealSelected = realVisible.some((o) => state.selected.has(o.value)) && !allRealSelected;
|
|
5756
5931
|
const isChecked = opt.isSelectAll ? allRealSelected : state.selected.has(opt.value);
|
|
5757
|
-
const pointer = isCurrent ? style.
|
|
5758
|
-
const checkbox = isChecked ? style.green("\u25C9", c) : opt.isSelectAll && someRealSelected ?
|
|
5932
|
+
const pointer = isCurrent ? fgHex(CHARM_PALETTE.hotPink, style.bold("\u276F", c), c) : " ";
|
|
5933
|
+
const checkbox = isChecked ? style.green("\u25C9", c) : opt.isSelectAll && someRealSelected ? fgHex(CHARM_PALETTE.fuchsia, "\u25D0", c) : style.dim("\u25EF", c);
|
|
5759
5934
|
const labelRaw = opt.label.length > maxLabelCols ? `${opt.label.slice(0, maxLabelCols - 1)}\u2026` : opt.label;
|
|
5760
5935
|
const labelPadded = padVisible(labelRaw, maxLabelCols + 1, "left");
|
|
5761
|
-
const styledLabel = isCurrent ? style.bold(labelPadded, c) : isChecked ? style.green(labelPadded, c) : labelPadded;
|
|
5936
|
+
const styledLabel = isCurrent ? fgHex(CHARM_PALETTE.fuchsia, style.bold(labelPadded, c), c) : isChecked ? style.green(labelPadded, c) : labelPadded;
|
|
5762
5937
|
const prefixWidth = 7 + maxLabelCols + 1;
|
|
5763
5938
|
const maxHintCols = Math.max(10, 76 - prefixWidth);
|
|
5764
5939
|
const rawHint = opt.hint ?? "";
|
|
5765
5940
|
const shortHint = rawHint.length > maxHintCols ? `${rawHint.slice(0, maxHintCols - 1)}\u2026` : rawHint;
|
|
5766
|
-
const hintPart = shortHint ? ` ${style.dim(shortHint, c)}` : "";
|
|
5941
|
+
const hintPart = shortHint ? ` ${isCurrent ? fgHex(CHARM_PALETTE.lavender, shortHint, c) : style.dim(shortHint, c)}` : "";
|
|
5767
5942
|
lines.push(`${bar} ${pointer} ${checkbox} ${styledLabel}${hintPart}`);
|
|
5768
5943
|
}
|
|
5769
5944
|
if (endIdx < total) {
|
|
5770
5945
|
lines.push(
|
|
5771
|
-
`${bar} ${style.dim(`\u2193 ${total - endIdx} more below...`, c)}`
|
|
5946
|
+
`${bar} ${style.dim(`\u2193 ${total - endIdx} more below...`, c)}${pageDots}`
|
|
5772
5947
|
);
|
|
5773
5948
|
}
|
|
5774
5949
|
}
|
|
@@ -5784,8 +5959,9 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5784
5959
|
const rawTarget = options.targetHint ?? "";
|
|
5785
5960
|
const shortTarget = rawTarget.length > 18 ? `${rawTarget.slice(0, 17)}\u2026` : rawTarget;
|
|
5786
5961
|
const targetSuffix = shortTarget ? ` \xB7 IDE: ${shortTarget}` : "";
|
|
5962
|
+
const styledSummary = state.selected.size > 0 ? fgHex(CHARM_PALETTE.mint, style.bold(summaryText, c), c) : fgHex(CHARM_PALETTE.lavender, style.bold(summaryText, c), c);
|
|
5787
5963
|
lines.push(
|
|
5788
|
-
`${style.dim("\u2570\u2500", c)} ${
|
|
5964
|
+
`${style.dim("\u2570\u2500", c)} ${styledSummary}${style.dim(`${targetSuffix} \u2014 Enter to ${submitVerb}`, c)}`
|
|
5789
5965
|
);
|
|
5790
5966
|
return lines.join("\n");
|
|
5791
5967
|
}
|
|
@@ -6566,6 +6742,7 @@ export {
|
|
|
6566
6742
|
ALL_RUNTIME_TARGETS,
|
|
6567
6743
|
BenchmarkArmSchema,
|
|
6568
6744
|
BenchmarkDeltaSchema,
|
|
6745
|
+
CHARM_PALETTE,
|
|
6569
6746
|
COMMAND_HELP_SPECS,
|
|
6570
6747
|
CORE_RUNTIME_TARGETS,
|
|
6571
6748
|
CatalogEvalSummarySchema,
|
|
@@ -6610,6 +6787,7 @@ export {
|
|
|
6610
6787
|
auditCatalogTokenBudgets,
|
|
6611
6788
|
auditSkillTokenBudget,
|
|
6612
6789
|
auditSubagentTokenBudget,
|
|
6790
|
+
bgHex,
|
|
6613
6791
|
classifyCollisionSeverity,
|
|
6614
6792
|
cleanSyncedArtifacts,
|
|
6615
6793
|
compileSkillBundle,
|
|
@@ -6631,6 +6809,7 @@ export {
|
|
|
6631
6809
|
evaluateCatalog,
|
|
6632
6810
|
evaluateSkillDirectory,
|
|
6633
6811
|
extractSkillFeatures,
|
|
6812
|
+
fgHex,
|
|
6634
6813
|
findCommandHelpSpec,
|
|
6635
6814
|
fingerprintRepository,
|
|
6636
6815
|
formatBadge,
|
|
@@ -6647,9 +6826,11 @@ export {
|
|
|
6647
6826
|
formatTokenEconomyReport,
|
|
6648
6827
|
getFilteredTabOptions,
|
|
6649
6828
|
handleMcpJsonRpcRequest,
|
|
6829
|
+
hexToRgb,
|
|
6650
6830
|
inspectCatalogItem,
|
|
6651
6831
|
inspectHarnesses,
|
|
6652
6832
|
isColorEnabled,
|
|
6833
|
+
joinHorizontal,
|
|
6653
6834
|
levenshteinDistance,
|
|
6654
6835
|
loadSkillOpsConfig,
|
|
6655
6836
|
normalizePackageName,
|
|
@@ -6665,8 +6846,11 @@ export {
|
|
|
6665
6846
|
renderCommandHelp,
|
|
6666
6847
|
renderGlobalHelp,
|
|
6667
6848
|
renderHeaderBanner,
|
|
6849
|
+
renderKeycap,
|
|
6668
6850
|
renderMultiSelectFrame,
|
|
6669
6851
|
renderNextSteps,
|
|
6852
|
+
renderPaginationDots,
|
|
6853
|
+
renderPill,
|
|
6670
6854
|
renderProgressBar,
|
|
6671
6855
|
renderSectionHeader,
|
|
6672
6856
|
renderStep,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillops-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.8",
|
|
4
4
|
"description": "SkillOps — The Zero-API Framework & Benchmark-Verified Library for High-End AI Coding Skills & Context-Isolated Subagents with Universal Top-28 AI Agent Transpilation & Token Economy Auditing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|