skillops-cli 1.3.0 → 1.3.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.
- package/README.md +1 -1
- package/dist/cli.js +505 -528
- package/dist/index.d.ts +137 -137
- package/dist/index.js +492 -494
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
// src/auditor/parser.ts
|
|
2
|
-
import fs2 from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
|
|
5
1
|
// src/models.ts
|
|
6
2
|
import fs from "fs";
|
|
7
3
|
import YAML from "yaml";
|
|
8
4
|
import { z } from "zod";
|
|
9
|
-
var SKILLOPS_VERSION = "1.3.
|
|
5
|
+
var SKILLOPS_VERSION = "1.3.1";
|
|
10
6
|
var SKILL_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
11
7
|
var SEMVER_REGEX = /^\d+\.\d+\.\d+$/;
|
|
12
8
|
var FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
@@ -22,7 +18,9 @@ function estimateTokenCount(text) {
|
|
|
22
18
|
return 0;
|
|
23
19
|
}
|
|
24
20
|
const words = countWords(stripped);
|
|
25
|
-
const punctBonus = Math.floor(
|
|
21
|
+
const punctBonus = Math.floor(
|
|
22
|
+
(stripped.match(PUNCT_CODE_REGEX)?.length ?? 0) / 4
|
|
23
|
+
);
|
|
26
24
|
return Math.max(1, Math.ceil(words * 1.33) + punctBonus);
|
|
27
25
|
}
|
|
28
26
|
function splitFrontmatter(rawText, sourceLabel) {
|
|
@@ -36,7 +34,9 @@ function splitFrontmatter(rawText, sourceLabel) {
|
|
|
36
34
|
const body = match[2] ?? "";
|
|
37
35
|
const parsed = YAML.parse(yamlText);
|
|
38
36
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
39
|
-
throw new Error(
|
|
37
|
+
throw new Error(
|
|
38
|
+
`YAML frontmatter in '${sourceLabel}' must evaluate to a key-value mapping.`
|
|
39
|
+
);
|
|
40
40
|
}
|
|
41
41
|
return [parsed, body];
|
|
42
42
|
}
|
|
@@ -535,7 +535,9 @@ var SubagentManifestSchema = z.object({
|
|
|
535
535
|
});
|
|
536
536
|
}
|
|
537
537
|
}),
|
|
538
|
-
tools: z.array(z.string().min(1)).min(1, {
|
|
538
|
+
tools: z.array(z.string().min(1)).min(1, {
|
|
539
|
+
message: "Subagent must declare an explicit non-empty tool allowlist per INV-SKILL-04."
|
|
540
|
+
}).superRefine((tools, ctx) => {
|
|
539
541
|
for (const tool of tools) {
|
|
540
542
|
if (FORBIDDEN_WILDCARD_TOOLS.has(tool.trim().toLowerCase())) {
|
|
541
543
|
ctx.addIssue({
|
|
@@ -726,7 +728,14 @@ var SyncedArtifactSchema = z.object({
|
|
|
726
728
|
skill_name: z.string().min(1),
|
|
727
729
|
relative_path: z.string().min(1),
|
|
728
730
|
sha256: z.string().regex(/^[0-9a-f]{64}$/),
|
|
729
|
-
action: z.enum([
|
|
731
|
+
action: z.enum([
|
|
732
|
+
"created",
|
|
733
|
+
"updated",
|
|
734
|
+
"unchanged",
|
|
735
|
+
"removed",
|
|
736
|
+
"planned",
|
|
737
|
+
"conflict"
|
|
738
|
+
])
|
|
730
739
|
}).strict();
|
|
731
740
|
var SyncLockEntrySchema = z.object({
|
|
732
741
|
target: RuntimeTargetSchema,
|
|
@@ -812,6 +821,8 @@ function loadSkillOpsConfig(repoPath) {
|
|
|
812
821
|
}
|
|
813
822
|
|
|
814
823
|
// src/auditor/parser.ts
|
|
824
|
+
import fs2 from "fs";
|
|
825
|
+
import path from "path";
|
|
815
826
|
function walkForFilesNamed(rootDir, targetFilename) {
|
|
816
827
|
if (!fs2.existsSync(rootDir)) {
|
|
817
828
|
return [];
|
|
@@ -844,7 +855,10 @@ function parseSkillDirectory(skillDir, options = {}) {
|
|
|
844
855
|
const rawText = fs2.readFileSync(skillMdPath, "utf-8");
|
|
845
856
|
const lines = rawText.split(/\r?\n/);
|
|
846
857
|
const totalLines = rawText.endsWith("\n") ? lines.length - 1 : lines.length;
|
|
847
|
-
const [, markdownBody] = splitFrontmatter(
|
|
858
|
+
const [, markdownBody] = splitFrontmatter(
|
|
859
|
+
rawText,
|
|
860
|
+
skillMdPath.replace(/\\/g, "/")
|
|
861
|
+
);
|
|
848
862
|
const manifest = parseSkillMdFile(skillMdPath);
|
|
849
863
|
const declaredScripts = [];
|
|
850
864
|
const missingDeclaredScripts = [];
|
|
@@ -878,7 +892,9 @@ function parseSkillDirectory(skillDir, options = {}) {
|
|
|
878
892
|
const referencesDir = path.join(skillDir, "references");
|
|
879
893
|
const referenceFiles = [];
|
|
880
894
|
if (fs2.existsSync(referencesDir) && fs2.statSync(referencesDir).isDirectory()) {
|
|
881
|
-
for (const entry of fs2.readdirSync(referencesDir, {
|
|
895
|
+
for (const entry of fs2.readdirSync(referencesDir, {
|
|
896
|
+
withFileTypes: true
|
|
897
|
+
})) {
|
|
882
898
|
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
883
899
|
referenceFiles.push(path.join(referencesDir, entry.name));
|
|
884
900
|
}
|
|
@@ -943,112 +959,6 @@ function parseSubagentFile(filePath) {
|
|
|
943
959
|
};
|
|
944
960
|
}
|
|
945
961
|
|
|
946
|
-
// src/auditor/token_budget.ts
|
|
947
|
-
function auditSkillTokenBudget(skillDir, options = {}) {
|
|
948
|
-
const requireLayout = options.requireLayout ?? false;
|
|
949
|
-
try {
|
|
950
|
-
const parsed = parseSkillDirectory(skillDir, { requireLayout });
|
|
951
|
-
const warnings = [];
|
|
952
|
-
const errors = [];
|
|
953
|
-
if (parsed.manifest.routing_signals.negative_triggers.length === 0 && !parsed.manifest.description.toLowerCase().includes("do not trigger")) {
|
|
954
|
-
warnings.push(
|
|
955
|
-
`Skill '${parsed.manifest.name}' has no explicit negative triggers ('Do not trigger for...' or routing_signals.negative_triggers).`
|
|
956
|
-
);
|
|
957
|
-
}
|
|
958
|
-
if (requireLayout && parsed.missingDeclaredScripts.length > 0) {
|
|
959
|
-
errors.push(
|
|
960
|
-
`Skill '${parsed.manifest.name}' is missing declared script(s): ${parsed.missingDeclaredScripts.join(", ")}`
|
|
961
|
-
);
|
|
962
|
-
}
|
|
963
|
-
return {
|
|
964
|
-
skillName: parsed.manifest.name,
|
|
965
|
-
skillDir: skillDir.replace(/\\/g, "/"),
|
|
966
|
-
l1Words: parsed.manifest.description_words,
|
|
967
|
-
l1Tokens: parsed.manifest.description_tokens,
|
|
968
|
-
l2Lines: parsed.manifest.body_lines,
|
|
969
|
-
l2Tokens: parsed.manifest.body_tokens,
|
|
970
|
-
totalLines: parsed.totalLines,
|
|
971
|
-
scriptsCount: parsed.declaredScripts.length,
|
|
972
|
-
passed: errors.length === 0,
|
|
973
|
-
errors,
|
|
974
|
-
warnings
|
|
975
|
-
};
|
|
976
|
-
} catch (err) {
|
|
977
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
978
|
-
return {
|
|
979
|
-
skillName: skillDir.split(/[\\/]/).pop() ?? "unknown",
|
|
980
|
-
skillDir: skillDir.replace(/\\/g, "/"),
|
|
981
|
-
l1Words: 0,
|
|
982
|
-
l1Tokens: 0,
|
|
983
|
-
l2Lines: 0,
|
|
984
|
-
l2Tokens: 0,
|
|
985
|
-
totalLines: 0,
|
|
986
|
-
scriptsCount: 0,
|
|
987
|
-
passed: false,
|
|
988
|
-
errors: [message],
|
|
989
|
-
warnings: []
|
|
990
|
-
};
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
function auditSubagentTokenBudget(filePath) {
|
|
994
|
-
try {
|
|
995
|
-
const parsed = parseSubagentFile(filePath);
|
|
996
|
-
return {
|
|
997
|
-
subagentName: parsed.manifest.name,
|
|
998
|
-
filePath: filePath.replace(/\\/g, "/"),
|
|
999
|
-
descriptionTokens: parsed.manifest.description_tokens,
|
|
1000
|
-
systemPromptLines: parsed.manifest.system_prompt_lines,
|
|
1001
|
-
systemPromptTokens: parsed.manifest.system_prompt_tokens,
|
|
1002
|
-
maxOutputTokens: parsed.manifest.max_output_tokens,
|
|
1003
|
-
tools: parsed.manifest.tools,
|
|
1004
|
-
passed: true,
|
|
1005
|
-
errors: []
|
|
1006
|
-
};
|
|
1007
|
-
} catch (err) {
|
|
1008
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1009
|
-
return {
|
|
1010
|
-
subagentName: filePath.split(/[\\/]/).pop() ?? "unknown",
|
|
1011
|
-
filePath: filePath.replace(/\\/g, "/"),
|
|
1012
|
-
descriptionTokens: 0,
|
|
1013
|
-
systemPromptLines: 0,
|
|
1014
|
-
systemPromptTokens: 0,
|
|
1015
|
-
maxOutputTokens: 0,
|
|
1016
|
-
tools: [],
|
|
1017
|
-
passed: false,
|
|
1018
|
-
errors: [message]
|
|
1019
|
-
};
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
function auditCatalogTokenBudgets(catalogDir, options = {}) {
|
|
1023
|
-
const skillDirs = discoverSkillDirectories(catalogDir);
|
|
1024
|
-
const subagentFiles = discoverSubagentFiles(catalogDir);
|
|
1025
|
-
const skills = skillDirs.map((dir) => auditSkillTokenBudget(dir, options));
|
|
1026
|
-
const subagents = subagentFiles.map((file) => auditSubagentTokenBudget(file));
|
|
1027
|
-
const errors = [];
|
|
1028
|
-
const warnings = [];
|
|
1029
|
-
let totalL1Tokens = 0;
|
|
1030
|
-
let totalSubagentPromptTokens = 0;
|
|
1031
|
-
for (const s of skills) {
|
|
1032
|
-
totalL1Tokens += s.l1Tokens;
|
|
1033
|
-
errors.push(...s.errors);
|
|
1034
|
-
warnings.push(...s.warnings);
|
|
1035
|
-
}
|
|
1036
|
-
for (const sa of subagents) {
|
|
1037
|
-
totalSubagentPromptTokens += sa.systemPromptTokens;
|
|
1038
|
-
errors.push(...sa.errors);
|
|
1039
|
-
}
|
|
1040
|
-
return {
|
|
1041
|
-
catalogPath: catalogDir.replace(/\\/g, "/"),
|
|
1042
|
-
skills,
|
|
1043
|
-
subagents,
|
|
1044
|
-
totalL1Tokens,
|
|
1045
|
-
totalSubagentPromptTokens,
|
|
1046
|
-
errors,
|
|
1047
|
-
warnings,
|
|
1048
|
-
passed: errors.length === 0
|
|
1049
|
-
};
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
962
|
// src/auditor/collision.ts
|
|
1053
963
|
var ROUTING_STOPWORDS = /* @__PURE__ */ new Set([
|
|
1054
964
|
"a",
|
|
@@ -1377,6 +1287,12 @@ function auditCatalog(catalogDir, options = {}) {
|
|
|
1377
1287
|
});
|
|
1378
1288
|
}
|
|
1379
1289
|
|
|
1290
|
+
// src/auditor/doctor.ts
|
|
1291
|
+
import { spawnSync } from "child_process";
|
|
1292
|
+
import crypto from "crypto";
|
|
1293
|
+
import fs4 from "fs";
|
|
1294
|
+
import path3 from "path";
|
|
1295
|
+
|
|
1380
1296
|
// src/auditor/token_economy.ts
|
|
1381
1297
|
import fs3 from "fs";
|
|
1382
1298
|
import path2 from "path";
|
|
@@ -1450,7 +1366,7 @@ function padVisible(text, width, align = "left") {
|
|
|
1450
1366
|
}
|
|
1451
1367
|
function renderBox(lines, options) {
|
|
1452
1368
|
const paddingX = options?.paddingX ?? 2;
|
|
1453
|
-
const minWidth = options?.minWidth ??
|
|
1369
|
+
const minWidth = options?.minWidth ?? 36;
|
|
1454
1370
|
const colorEnabled = options?.colorEnabled;
|
|
1455
1371
|
const borderFn = options?.borderColor ?? style.cyan;
|
|
1456
1372
|
const titleText = options?.title ? ` ${options.title.trim()} ` : "";
|
|
@@ -1474,16 +1390,10 @@ function renderBox(lines, options) {
|
|
|
1474
1390
|
const bottomBorder = borderFn(`\u2570${"\u2500".repeat(innerWidth)}\u256F`, colorEnabled);
|
|
1475
1391
|
return [topBorder, ...bodyLines, bottomBorder].join("\n");
|
|
1476
1392
|
}
|
|
1477
|
-
function renderHeaderBanner(subtitle = "Framework & Library for
|
|
1393
|
+
function renderHeaderBanner(subtitle = "Framework & Library for AI Skills & Subagents", options) {
|
|
1478
1394
|
const ver = options?.version ?? SKILLOPS_VERSION;
|
|
1479
1395
|
const c = options?.colorEnabled;
|
|
1480
|
-
|
|
1481
|
-
return renderBox([headline], {
|
|
1482
|
-
borderColor: style.cyan,
|
|
1483
|
-
paddingX: 2,
|
|
1484
|
-
minWidth: 72,
|
|
1485
|
-
colorEnabled: c
|
|
1486
|
-
});
|
|
1396
|
+
return `${style.bold(style.cyan(`\u25C6 SkillOps v${ver}`, c), c)} ${style.dim("\u2014", c)} ${subtitle}`;
|
|
1487
1397
|
}
|
|
1488
1398
|
function renderTable(headers, rows, options) {
|
|
1489
1399
|
const indent = " ".repeat(options?.indent ?? 2);
|
|
@@ -1516,7 +1426,7 @@ function renderTable(headers, rows, options) {
|
|
|
1516
1426
|
].join("\n");
|
|
1517
1427
|
}
|
|
1518
1428
|
function renderTokenBar(current, max, options) {
|
|
1519
|
-
const width = options?.width ??
|
|
1429
|
+
const width = options?.width ?? 10;
|
|
1520
1430
|
const unit = options?.unit ?? "tokens";
|
|
1521
1431
|
const c = options?.colorEnabled;
|
|
1522
1432
|
const safeMax = max > 0 ? max : 1;
|
|
@@ -1534,9 +1444,8 @@ function renderTokenBar(current, max, options) {
|
|
|
1534
1444
|
var renderProgressBar = renderTokenBar;
|
|
1535
1445
|
function renderSectionHeader(title, colorEnabled) {
|
|
1536
1446
|
const c = colorEnabled;
|
|
1537
|
-
return
|
|
1538
|
-
|
|
1539
|
-
${style.dim("\u2500".repeat(Math.max(24, visibleLength(title))), c)}`;
|
|
1447
|
+
return `${style.dim("\u2502", c)}
|
|
1448
|
+
${style.dim("\u251C\u2500", c)} ${style.bold(style.cyan(title, c), c)}`;
|
|
1540
1449
|
}
|
|
1541
1450
|
function formatBadge(type, customLabel, colorEnabled) {
|
|
1542
1451
|
switch (type) {
|
|
@@ -1575,73 +1484,72 @@ function formatBadge(type, customLabel, colorEnabled) {
|
|
|
1575
1484
|
function renderStep(step, total, title, detail, status = "done", colorEnabled) {
|
|
1576
1485
|
const icon = status === "done" ? style.green("\u2714", colorEnabled) : status === "warn" ? style.yellow("\u26A0", colorEnabled) : style.dim("\u25CB", colorEnabled);
|
|
1577
1486
|
const stepBadge = style.dim(`[${step}/${total}]`, colorEnabled);
|
|
1578
|
-
const titleStyled = style.bold(padVisible(title,
|
|
1579
|
-
const detailStyled = detail ? ` ${style.dim("\
|
|
1580
|
-
return
|
|
1487
|
+
const titleStyled = style.bold(padVisible(title, 20, "left"), colorEnabled);
|
|
1488
|
+
const detailStyled = detail ? ` ${style.dim("\xB7", colorEnabled)} ${detail}` : "";
|
|
1489
|
+
return `${style.dim("\u2502", colorEnabled)} ${icon} ${stepBadge} ${titleStyled}${detailStyled}`;
|
|
1581
1490
|
}
|
|
1582
1491
|
function renderNextSteps(hints, colorEnabled) {
|
|
1583
1492
|
if (hints.length === 0) {
|
|
1584
1493
|
return "";
|
|
1585
1494
|
}
|
|
1586
1495
|
const c = colorEnabled;
|
|
1587
|
-
const maxCmdLen =
|
|
1588
|
-
|
|
1589
|
-
0
|
|
1496
|
+
const maxCmdLen = Math.min(
|
|
1497
|
+
44,
|
|
1498
|
+
hints.reduce((m, h) => Math.max(m, visibleLength(h.command)), 0)
|
|
1590
1499
|
);
|
|
1591
1500
|
const lines = [
|
|
1592
|
-
"",
|
|
1593
|
-
|
|
1594
|
-
...hints.map(
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1501
|
+
style.dim("\u2502", c),
|
|
1502
|
+
`${style.dim("\u2570\u2500", c)} ${style.bold(style.cyan("Next Steps:", c), c)}`,
|
|
1503
|
+
...hints.map((h) => {
|
|
1504
|
+
const cmdPadded = padVisible(h.command, maxCmdLen, "left");
|
|
1505
|
+
const prefixCols = 5 + visibleLength(cmdPadded) + 3;
|
|
1506
|
+
const maxDescCols = Math.max(10, 76 - prefixCols);
|
|
1507
|
+
const desc = h.description.length > maxDescCols ? `${h.description.slice(0, maxDescCols - 1)}\u2026` : h.description;
|
|
1508
|
+
return ` ${style.dim("$", c)} ${style.green(cmdPadded, c)} ${style.dim(`\u2014 ${desc}`, c)}`;
|
|
1509
|
+
})
|
|
1598
1510
|
];
|
|
1599
|
-
return lines.join("\n")
|
|
1511
|
+
return `${lines.join("\n")}
|
|
1512
|
+
`;
|
|
1600
1513
|
}
|
|
1601
1514
|
function renderAiUsageGuide(targets, skills, subagents, colorEnabled) {
|
|
1602
1515
|
const c = colorEnabled;
|
|
1603
1516
|
const sampleSkill = skills[0] ?? "systematic-debugging";
|
|
1604
1517
|
const sampleAgent = subagents[0] ?? "context-scout";
|
|
1518
|
+
const bar = style.dim("\u2502", c);
|
|
1605
1519
|
const lines = [
|
|
1606
|
-
|
|
1607
|
-
""
|
|
1520
|
+
bar,
|
|
1521
|
+
`${style.dim("\u251C\u2500", c)} ${style.bold(style.cyan("Using Your Skills & Subagents", c), c)}`
|
|
1608
1522
|
];
|
|
1609
1523
|
const targetSet = new Set(targets);
|
|
1610
1524
|
if (targetSet.has("claude") || targetSet.size === 0) {
|
|
1611
1525
|
lines.push(
|
|
1612
|
-
|
|
1526
|
+
`${bar} \u2022 ${style.bold("Claude Code:", c)} Auto-routed (${sampleSkill}) or @${sampleAgent}`
|
|
1613
1527
|
);
|
|
1614
1528
|
}
|
|
1615
1529
|
if (targetSet.has("cursor")) {
|
|
1616
1530
|
lines.push(
|
|
1617
|
-
|
|
1531
|
+
`${bar} \u2022 ${style.bold("Cursor IDE:", c)} Type ${style.cyan(`@${sampleSkill}`, c)} in Chat (.cursor/rules/)`
|
|
1618
1532
|
);
|
|
1619
1533
|
}
|
|
1620
1534
|
if (targetSet.has("antigravity")) {
|
|
1621
1535
|
lines.push(
|
|
1622
|
-
|
|
1536
|
+
`${bar} \u2022 ${style.bold("Antigravity:", c)} Auto-activated (.agent/skills/${sampleSkill})`
|
|
1623
1537
|
);
|
|
1624
1538
|
}
|
|
1625
1539
|
if (targetSet.has("copilot")) {
|
|
1626
1540
|
lines.push(
|
|
1627
|
-
|
|
1541
|
+
`${bar} \u2022 ${style.bold("Copilot:", c)} Use ${style.cyan(`/${sampleSkill}`, c)} in Chat (.github/instructions/)`
|
|
1628
1542
|
);
|
|
1629
1543
|
}
|
|
1630
1544
|
if (targetSet.has("windsurf") || targetSet.has("cline") || targetSet.has("roocode") || targetSet.has("kilocode")) {
|
|
1631
1545
|
lines.push(
|
|
1632
|
-
|
|
1546
|
+
`${bar} \u2022 ${style.bold("Windsurf/Cline/Roo/Kilo:", c)} Workspace rules load automatically`
|
|
1633
1547
|
);
|
|
1634
1548
|
}
|
|
1635
1549
|
lines.push(
|
|
1636
|
-
|
|
1550
|
+
`${bar} \u2022 ${style.bold("Inspect:", c)} ${style.green(`npx skillops-cli info ${sampleSkill}`, c)}`
|
|
1637
1551
|
);
|
|
1638
|
-
return
|
|
1639
|
-
title: "\u{1F680} Using Your Skills & Subagents",
|
|
1640
|
-
borderColor: style.green,
|
|
1641
|
-
paddingX: 2,
|
|
1642
|
-
minWidth: 72,
|
|
1643
|
-
colorEnabled: c
|
|
1644
|
-
});
|
|
1552
|
+
return lines.join("\n");
|
|
1645
1553
|
}
|
|
1646
1554
|
function levenshteinDistance(a, b) {
|
|
1647
1555
|
const s1 = a.toLowerCase();
|
|
@@ -2079,7 +1987,7 @@ function formatTokenEconomyReport(report, format = "table") {
|
|
|
2079
1987
|
const startupBar = renderProgressBar(
|
|
2080
1988
|
report.startup_token_tax,
|
|
2081
1989
|
report.startup_tax_budget,
|
|
2082
|
-
{ width:
|
|
1990
|
+
{ width: 10, unit: "tokens" }
|
|
2083
1991
|
);
|
|
2084
1992
|
const lines = [
|
|
2085
1993
|
"=== SkillOps Token Economy & Startup Context Tax Analyzer ===",
|
|
@@ -2104,11 +2012,11 @@ function formatTokenEconomyReport(report, format = "table") {
|
|
|
2104
2012
|
renderNextSteps([
|
|
2105
2013
|
{
|
|
2106
2014
|
command: "npx skillops-cli quickstart",
|
|
2107
|
-
description: "Sync Progressive Disclosure Skills &
|
|
2015
|
+
description: "Sync Progressive Disclosure Skills & Subagents"
|
|
2108
2016
|
},
|
|
2109
2017
|
{
|
|
2110
2018
|
command: "npx skillops-cli doctor",
|
|
2111
|
-
description: "Inspect
|
|
2019
|
+
description: "Inspect lockfile & startup tax diagnostics"
|
|
2112
2020
|
}
|
|
2113
2021
|
]).trimEnd()
|
|
2114
2022
|
);
|
|
@@ -2117,10 +2025,6 @@ function formatTokenEconomyReport(report, format = "table") {
|
|
|
2117
2025
|
}
|
|
2118
2026
|
|
|
2119
2027
|
// src/auditor/doctor.ts
|
|
2120
|
-
import { spawnSync } from "child_process";
|
|
2121
|
-
import crypto from "crypto";
|
|
2122
|
-
import fs4 from "fs";
|
|
2123
|
-
import path3 from "path";
|
|
2124
2028
|
function computeFileSha256(content) {
|
|
2125
2029
|
return crypto.createHash("sha256").update(content, "utf-8").digest("hex");
|
|
2126
2030
|
}
|
|
@@ -2352,10 +2256,12 @@ function inspectHarnesses(repoPath) {
|
|
|
2352
2256
|
const repoLabel = path3.basename(resolvedRepo) || ".";
|
|
2353
2257
|
const detectedHarnesses = detectInstalledHarnesses(resolvedRepo);
|
|
2354
2258
|
const detectedSet = new Set(detectedHarnesses);
|
|
2355
|
-
const harnesses = ALL_RUNTIME_TARGETS.map(
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2259
|
+
const harnesses = ALL_RUNTIME_TARGETS.map(
|
|
2260
|
+
(target) => ({
|
|
2261
|
+
...RUNTIME_HARNESS_SPECS[target],
|
|
2262
|
+
detected: detectedSet.has(target)
|
|
2263
|
+
})
|
|
2264
|
+
);
|
|
2359
2265
|
return {
|
|
2360
2266
|
repo_path: repoLabel,
|
|
2361
2267
|
total_supported: harnesses.length,
|
|
@@ -2412,9 +2318,13 @@ function formatDoctorReport(report, format = "table") {
|
|
|
2412
2318
|
}
|
|
2413
2319
|
for (const check of report.checks) {
|
|
2414
2320
|
if (check.status === "fail") {
|
|
2415
|
-
lines2.push(
|
|
2321
|
+
lines2.push(
|
|
2322
|
+
`::error title=SkillOps Doctor (${check.title})::${check.summary}`
|
|
2323
|
+
);
|
|
2416
2324
|
} else if (check.status === "warn") {
|
|
2417
|
-
lines2.push(
|
|
2325
|
+
lines2.push(
|
|
2326
|
+
`::warning title=SkillOps Doctor (${check.title})::${check.summary}`
|
|
2327
|
+
);
|
|
2418
2328
|
}
|
|
2419
2329
|
}
|
|
2420
2330
|
lines2.push(
|
|
@@ -2484,7 +2394,9 @@ function formatDoctorReport(report, format = "table") {
|
|
|
2484
2394
|
lines.push("-".repeat(64), "Tracked Lockfile Artifacts:");
|
|
2485
2395
|
for (const art of report.artifacts) {
|
|
2486
2396
|
const badge = art.status === "healthy" ? "[HEALTHY]" : art.status === "drifted" ? "[DRIFTED]" : "[MISSING]";
|
|
2487
|
-
lines.push(
|
|
2397
|
+
lines.push(
|
|
2398
|
+
` ${badge} ${art.relative_path} (${art.target} :: ${art.item_name})`
|
|
2399
|
+
);
|
|
2488
2400
|
}
|
|
2489
2401
|
}
|
|
2490
2402
|
if (report.remediation.length > 0) {
|
|
@@ -2496,6 +2408,112 @@ function formatDoctorReport(report, format = "table") {
|
|
|
2496
2408
|
return lines.join("\n");
|
|
2497
2409
|
}
|
|
2498
2410
|
|
|
2411
|
+
// src/auditor/token_budget.ts
|
|
2412
|
+
function auditSkillTokenBudget(skillDir, options = {}) {
|
|
2413
|
+
const requireLayout = options.requireLayout ?? false;
|
|
2414
|
+
try {
|
|
2415
|
+
const parsed = parseSkillDirectory(skillDir, { requireLayout });
|
|
2416
|
+
const warnings = [];
|
|
2417
|
+
const errors = [];
|
|
2418
|
+
if (parsed.manifest.routing_signals.negative_triggers.length === 0 && !parsed.manifest.description.toLowerCase().includes("do not trigger")) {
|
|
2419
|
+
warnings.push(
|
|
2420
|
+
`Skill '${parsed.manifest.name}' has no explicit negative triggers ('Do not trigger for...' or routing_signals.negative_triggers).`
|
|
2421
|
+
);
|
|
2422
|
+
}
|
|
2423
|
+
if (requireLayout && parsed.missingDeclaredScripts.length > 0) {
|
|
2424
|
+
errors.push(
|
|
2425
|
+
`Skill '${parsed.manifest.name}' is missing declared script(s): ${parsed.missingDeclaredScripts.join(", ")}`
|
|
2426
|
+
);
|
|
2427
|
+
}
|
|
2428
|
+
return {
|
|
2429
|
+
skillName: parsed.manifest.name,
|
|
2430
|
+
skillDir: skillDir.replace(/\\/g, "/"),
|
|
2431
|
+
l1Words: parsed.manifest.description_words,
|
|
2432
|
+
l1Tokens: parsed.manifest.description_tokens,
|
|
2433
|
+
l2Lines: parsed.manifest.body_lines,
|
|
2434
|
+
l2Tokens: parsed.manifest.body_tokens,
|
|
2435
|
+
totalLines: parsed.totalLines,
|
|
2436
|
+
scriptsCount: parsed.declaredScripts.length,
|
|
2437
|
+
passed: errors.length === 0,
|
|
2438
|
+
errors,
|
|
2439
|
+
warnings
|
|
2440
|
+
};
|
|
2441
|
+
} catch (err) {
|
|
2442
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2443
|
+
return {
|
|
2444
|
+
skillName: skillDir.split(/[\\/]/).pop() ?? "unknown",
|
|
2445
|
+
skillDir: skillDir.replace(/\\/g, "/"),
|
|
2446
|
+
l1Words: 0,
|
|
2447
|
+
l1Tokens: 0,
|
|
2448
|
+
l2Lines: 0,
|
|
2449
|
+
l2Tokens: 0,
|
|
2450
|
+
totalLines: 0,
|
|
2451
|
+
scriptsCount: 0,
|
|
2452
|
+
passed: false,
|
|
2453
|
+
errors: [message],
|
|
2454
|
+
warnings: []
|
|
2455
|
+
};
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
function auditSubagentTokenBudget(filePath) {
|
|
2459
|
+
try {
|
|
2460
|
+
const parsed = parseSubagentFile(filePath);
|
|
2461
|
+
return {
|
|
2462
|
+
subagentName: parsed.manifest.name,
|
|
2463
|
+
filePath: filePath.replace(/\\/g, "/"),
|
|
2464
|
+
descriptionTokens: parsed.manifest.description_tokens,
|
|
2465
|
+
systemPromptLines: parsed.manifest.system_prompt_lines,
|
|
2466
|
+
systemPromptTokens: parsed.manifest.system_prompt_tokens,
|
|
2467
|
+
maxOutputTokens: parsed.manifest.max_output_tokens,
|
|
2468
|
+
tools: parsed.manifest.tools,
|
|
2469
|
+
passed: true,
|
|
2470
|
+
errors: []
|
|
2471
|
+
};
|
|
2472
|
+
} catch (err) {
|
|
2473
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2474
|
+
return {
|
|
2475
|
+
subagentName: filePath.split(/[\\/]/).pop() ?? "unknown",
|
|
2476
|
+
filePath: filePath.replace(/\\/g, "/"),
|
|
2477
|
+
descriptionTokens: 0,
|
|
2478
|
+
systemPromptLines: 0,
|
|
2479
|
+
systemPromptTokens: 0,
|
|
2480
|
+
maxOutputTokens: 0,
|
|
2481
|
+
tools: [],
|
|
2482
|
+
passed: false,
|
|
2483
|
+
errors: [message]
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
function auditCatalogTokenBudgets(catalogDir, options = {}) {
|
|
2488
|
+
const skillDirs = discoverSkillDirectories(catalogDir);
|
|
2489
|
+
const subagentFiles = discoverSubagentFiles(catalogDir);
|
|
2490
|
+
const skills = skillDirs.map((dir) => auditSkillTokenBudget(dir, options));
|
|
2491
|
+
const subagents = subagentFiles.map((file) => auditSubagentTokenBudget(file));
|
|
2492
|
+
const errors = [];
|
|
2493
|
+
const warnings = [];
|
|
2494
|
+
let totalL1Tokens = 0;
|
|
2495
|
+
let totalSubagentPromptTokens = 0;
|
|
2496
|
+
for (const s of skills) {
|
|
2497
|
+
totalL1Tokens += s.l1Tokens;
|
|
2498
|
+
errors.push(...s.errors);
|
|
2499
|
+
warnings.push(...s.warnings);
|
|
2500
|
+
}
|
|
2501
|
+
for (const sa of subagents) {
|
|
2502
|
+
totalSubagentPromptTokens += sa.systemPromptTokens;
|
|
2503
|
+
errors.push(...sa.errors);
|
|
2504
|
+
}
|
|
2505
|
+
return {
|
|
2506
|
+
catalogPath: catalogDir.replace(/\\/g, "/"),
|
|
2507
|
+
skills,
|
|
2508
|
+
subagents,
|
|
2509
|
+
totalL1Tokens,
|
|
2510
|
+
totalSubagentPromptTokens,
|
|
2511
|
+
errors,
|
|
2512
|
+
warnings,
|
|
2513
|
+
passed: errors.length === 0
|
|
2514
|
+
};
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2499
2517
|
// src/eval/index.ts
|
|
2500
2518
|
import fs5 from "fs";
|
|
2501
2519
|
import path4 from "path";
|
|
@@ -2555,10 +2573,15 @@ function evaluateSkillDirectory(skillDir) {
|
|
|
2555
2573
|
const evalsPath = path4.join(skillDir, "evals", "evals.json");
|
|
2556
2574
|
const rawSuite = JSON.parse(fs5.readFileSync(evalsPath, "utf-8"));
|
|
2557
2575
|
const suite = SkillEvalSuiteSchema.parse(rawSuite);
|
|
2558
|
-
const assertionsCount = suite.evals.reduce(
|
|
2576
|
+
const assertionsCount = suite.evals.reduce(
|
|
2577
|
+
(acc, c) => acc + c.assertions.length,
|
|
2578
|
+
0
|
|
2579
|
+
);
|
|
2559
2580
|
const benchmarkPath = path4.join(skillDir, "evals", "benchmark.json");
|
|
2560
2581
|
if (fs5.existsSync(benchmarkPath) && fs5.statSync(benchmarkPath).isFile()) {
|
|
2561
|
-
const rawBench = JSON.parse(
|
|
2582
|
+
const rawBench = JSON.parse(
|
|
2583
|
+
fs5.readFileSync(benchmarkPath, "utf-8")
|
|
2584
|
+
);
|
|
2562
2585
|
const bench = SkillBenchmarkSchema.parse({
|
|
2563
2586
|
...rawBench,
|
|
2564
2587
|
eval_cases_count: suite.evals.length,
|
|
@@ -2614,18 +2637,25 @@ function evaluateCatalog(catalogDir, options = {}) {
|
|
|
2614
2637
|
}
|
|
2615
2638
|
const count = benchmarks.length;
|
|
2616
2639
|
const meanWith = count > 0 ? Number(
|
|
2617
|
-
(benchmarks.reduce(
|
|
2640
|
+
(benchmarks.reduce(
|
|
2641
|
+
(acc, b) => acc + b.with_skill.pass_rate_mean,
|
|
2642
|
+
0
|
|
2643
|
+
) / count).toFixed(4)
|
|
2618
2644
|
) : 0;
|
|
2619
2645
|
const meanWithout = count > 0 ? Number(
|
|
2620
|
-
(benchmarks.reduce(
|
|
2621
|
-
|
|
2622
|
-
|
|
2646
|
+
(benchmarks.reduce(
|
|
2647
|
+
(acc, b) => acc + b.without_skill.pass_rate_mean,
|
|
2648
|
+
0
|
|
2649
|
+
) / count).toFixed(4)
|
|
2623
2650
|
) : 0;
|
|
2624
2651
|
const meanGain = count > 0 ? Number(
|
|
2625
2652
|
(benchmarks.reduce((acc, b) => acc + b.delta.pass_rate_gain, 0) / count).toFixed(4)
|
|
2626
2653
|
) : 0;
|
|
2627
2654
|
const meanTokRed = count > 0 ? Number(
|
|
2628
|
-
(benchmarks.reduce(
|
|
2655
|
+
(benchmarks.reduce(
|
|
2656
|
+
(acc, b) => acc + b.delta.token_reduction_pct,
|
|
2657
|
+
0
|
|
2658
|
+
) / count).toFixed(2)
|
|
2629
2659
|
) : 0;
|
|
2630
2660
|
return CatalogEvalSummarySchema.parse({
|
|
2631
2661
|
catalog_path: resolvedCatalog.replace(/\\/g, "/"),
|
|
@@ -2731,6 +2761,9 @@ import path7 from "path";
|
|
|
2731
2761
|
import readline from "readline";
|
|
2732
2762
|
import YAML3 from "yaml";
|
|
2733
2763
|
|
|
2764
|
+
// src/router/bundle_compiler.ts
|
|
2765
|
+
import path6 from "path";
|
|
2766
|
+
|
|
2734
2767
|
// src/router/fingerprinter.ts
|
|
2735
2768
|
import fs6 from "fs";
|
|
2736
2769
|
import path5 from "path";
|
|
@@ -2830,13 +2863,17 @@ var RepoFingerprinter = class {
|
|
|
2830
2863
|
python312Plus = true;
|
|
2831
2864
|
signals.add("python3.12");
|
|
2832
2865
|
}
|
|
2833
|
-
const quotedSpecs = content.match(
|
|
2866
|
+
const quotedSpecs = content.match(
|
|
2867
|
+
/["']([a-zA-Z0-9._-]+(?:\[[a-zA-Z0-9,_-]+\])?\s*(?:[><=~!][^"']+)?)["']/g
|
|
2868
|
+
) ?? [];
|
|
2834
2869
|
for (const spec of quotedSpecs) {
|
|
2835
2870
|
recordDep(spec);
|
|
2836
2871
|
}
|
|
2837
2872
|
}
|
|
2838
2873
|
if (fs6.existsSync(this.repoPath)) {
|
|
2839
|
-
for (const entry of fs6.readdirSync(this.repoPath, {
|
|
2874
|
+
for (const entry of fs6.readdirSync(this.repoPath, {
|
|
2875
|
+
withFileTypes: true
|
|
2876
|
+
})) {
|
|
2840
2877
|
if (entry.isFile() && /^requirements.*\.txt$/i.test(entry.name)) {
|
|
2841
2878
|
detectedFiles.add(entry.name);
|
|
2842
2879
|
languages.add("python");
|
|
@@ -2856,8 +2893,14 @@ var RepoFingerprinter = class {
|
|
|
2856
2893
|
signals.add("nodejs");
|
|
2857
2894
|
signals.add("package.json");
|
|
2858
2895
|
try {
|
|
2859
|
-
const pkgJson = JSON.parse(
|
|
2860
|
-
|
|
2896
|
+
const pkgJson = JSON.parse(
|
|
2897
|
+
fs6.readFileSync(pkgJsonPath, "utf-8")
|
|
2898
|
+
);
|
|
2899
|
+
const depSections = [
|
|
2900
|
+
"dependencies",
|
|
2901
|
+
"devDependencies",
|
|
2902
|
+
"peerDependencies"
|
|
2903
|
+
];
|
|
2861
2904
|
for (const section of depSections) {
|
|
2862
2905
|
const obj = pkgJson[section];
|
|
2863
2906
|
if (obj && typeof obj === "object") {
|
|
@@ -2961,7 +3004,6 @@ function fingerprintRepository(repoPath) {
|
|
|
2961
3004
|
}
|
|
2962
3005
|
|
|
2963
3006
|
// src/router/bundle_compiler.ts
|
|
2964
|
-
import path6 from "path";
|
|
2965
3007
|
function scoreSkillAgainstProfile(parsedSkill, profile, taskPrompt = "") {
|
|
2966
3008
|
const manifest = parsedSkill.manifest;
|
|
2967
3009
|
const repoSignalSet = new Set(
|
|
@@ -3182,7 +3224,7 @@ function formatRoutedBundle(bundle, format = "table", colorEnabled) {
|
|
|
3182
3224
|
bundle.total_l1_tokens,
|
|
3183
3225
|
bundle.max_l1_tokens,
|
|
3184
3226
|
{
|
|
3185
|
-
width:
|
|
3227
|
+
width: 10,
|
|
3186
3228
|
unit: "tokens",
|
|
3187
3229
|
colorEnabled
|
|
3188
3230
|
}
|
|
@@ -3191,11 +3233,11 @@ function formatRoutedBundle(bundle, format = "table", colorEnabled) {
|
|
|
3191
3233
|
[
|
|
3192
3234
|
{
|
|
3193
3235
|
command: "npx skillops-cli quickstart",
|
|
3194
|
-
description: "Install
|
|
3236
|
+
description: "Install recommended bundle & wire MCP"
|
|
3195
3237
|
},
|
|
3196
3238
|
{
|
|
3197
3239
|
command: `npx skillops-cli info ${topSkill}`,
|
|
3198
|
-
description: `Inspect ${topSkill} triggers
|
|
3240
|
+
description: `Inspect ${topSkill} triggers & L3 scripts`
|
|
3199
3241
|
}
|
|
3200
3242
|
],
|
|
3201
3243
|
colorEnabled
|
|
@@ -3222,7 +3264,10 @@ var MCP_TOOLS = [
|
|
|
3222
3264
|
inputSchema: {
|
|
3223
3265
|
type: "object",
|
|
3224
3266
|
properties: {
|
|
3225
|
-
catalog_dir: {
|
|
3267
|
+
catalog_dir: {
|
|
3268
|
+
type: "string",
|
|
3269
|
+
description: "Optional path to catalog directory."
|
|
3270
|
+
}
|
|
3226
3271
|
},
|
|
3227
3272
|
additionalProperties: false
|
|
3228
3273
|
}
|
|
@@ -3233,8 +3278,14 @@ var MCP_TOOLS = [
|
|
|
3233
3278
|
inputSchema: {
|
|
3234
3279
|
type: "object",
|
|
3235
3280
|
properties: {
|
|
3236
|
-
repo_path: {
|
|
3237
|
-
|
|
3281
|
+
repo_path: {
|
|
3282
|
+
type: "string",
|
|
3283
|
+
description: "Target repository root path."
|
|
3284
|
+
},
|
|
3285
|
+
startup_tax_budget: {
|
|
3286
|
+
type: "number",
|
|
3287
|
+
description: "Max startup token budget."
|
|
3288
|
+
}
|
|
3238
3289
|
},
|
|
3239
3290
|
additionalProperties: false
|
|
3240
3291
|
}
|
|
@@ -3245,8 +3296,14 @@ var MCP_TOOLS = [
|
|
|
3245
3296
|
inputSchema: {
|
|
3246
3297
|
type: "object",
|
|
3247
3298
|
properties: {
|
|
3248
|
-
repo_path: {
|
|
3249
|
-
|
|
3299
|
+
repo_path: {
|
|
3300
|
+
type: "string",
|
|
3301
|
+
description: "Target repository root path."
|
|
3302
|
+
},
|
|
3303
|
+
task_prompt: {
|
|
3304
|
+
type: "string",
|
|
3305
|
+
description: "Optional developer task description."
|
|
3306
|
+
}
|
|
3250
3307
|
},
|
|
3251
3308
|
additionalProperties: false
|
|
3252
3309
|
}
|
|
@@ -3269,7 +3326,10 @@ var MCP_TOOLS = [
|
|
|
3269
3326
|
inputSchema: {
|
|
3270
3327
|
type: "object",
|
|
3271
3328
|
properties: {
|
|
3272
|
-
skill_name: {
|
|
3329
|
+
skill_name: {
|
|
3330
|
+
type: "string",
|
|
3331
|
+
description: "Optional skill name filter."
|
|
3332
|
+
}
|
|
3273
3333
|
},
|
|
3274
3334
|
additionalProperties: false
|
|
3275
3335
|
}
|
|
@@ -3289,8 +3349,14 @@ var MCP_TOOLS = [
|
|
|
3289
3349
|
inputSchema: {
|
|
3290
3350
|
type: "object",
|
|
3291
3351
|
properties: {
|
|
3292
|
-
repo_path: {
|
|
3293
|
-
|
|
3352
|
+
repo_path: {
|
|
3353
|
+
type: "string",
|
|
3354
|
+
description: "Target repository root path."
|
|
3355
|
+
},
|
|
3356
|
+
startup_tax_budget: {
|
|
3357
|
+
type: "number",
|
|
3358
|
+
description: "Optional startup token budget override."
|
|
3359
|
+
}
|
|
3294
3360
|
},
|
|
3295
3361
|
additionalProperties: false
|
|
3296
3362
|
}
|
|
@@ -3301,7 +3367,10 @@ var MCP_TOOLS = [
|
|
|
3301
3367
|
inputSchema: {
|
|
3302
3368
|
type: "object",
|
|
3303
3369
|
properties: {
|
|
3304
|
-
repo_path: {
|
|
3370
|
+
repo_path: {
|
|
3371
|
+
type: "string",
|
|
3372
|
+
description: "Target repository root path."
|
|
3373
|
+
}
|
|
3305
3374
|
},
|
|
3306
3375
|
additionalProperties: false
|
|
3307
3376
|
}
|
|
@@ -3383,7 +3452,9 @@ function handleMcpJsonRpcRequest(request, context) {
|
|
|
3383
3452
|
const skillFilter = typeof args.skill_name === "string" ? args.skill_name : void 0;
|
|
3384
3453
|
payload = evaluateCatalog(context.catalogDir, { skillFilter });
|
|
3385
3454
|
} else if (toolName === "list_catalog_items") {
|
|
3386
|
-
payload = auditCatalogTokenBudgets(context.catalogDir, {
|
|
3455
|
+
payload = auditCatalogTokenBudgets(context.catalogDir, {
|
|
3456
|
+
requireLayout: false
|
|
3457
|
+
});
|
|
3387
3458
|
} else if (toolName === "diagnose_repo") {
|
|
3388
3459
|
const repoPath = typeof args.repo_path === "string" ? args.repo_path : context.repoPath;
|
|
3389
3460
|
const budget = typeof args.startup_tax_budget === "number" ? args.startup_tax_budget : void 0;
|
|
@@ -3588,7 +3659,11 @@ function setupMcpForHarnesses(repoPath, options = {}) {
|
|
|
3588
3659
|
const absPath = path7.join(resolvedRepo, spec.mcpConfigPath);
|
|
3589
3660
|
const exists = fs7.existsSync(absPath) && fs7.statSync(absPath).isFile();
|
|
3590
3661
|
const existingRaw = exists ? fs7.readFileSync(absPath, "utf-8") : null;
|
|
3591
|
-
const updatedRaw = buildUpdatedMcpConfigContent(
|
|
3662
|
+
const updatedRaw = buildUpdatedMcpConfigContent(
|
|
3663
|
+
target,
|
|
3664
|
+
existingRaw,
|
|
3665
|
+
serverName
|
|
3666
|
+
);
|
|
3592
3667
|
let status;
|
|
3593
3668
|
if (!exists) {
|
|
3594
3669
|
status = "created";
|
|
@@ -3608,7 +3683,9 @@ function setupMcpForHarnesses(repoPath, options = {}) {
|
|
|
3608
3683
|
status
|
|
3609
3684
|
});
|
|
3610
3685
|
}
|
|
3611
|
-
const configuredCount = actions.filter(
|
|
3686
|
+
const configuredCount = actions.filter(
|
|
3687
|
+
(a) => a.status !== "unsupported"
|
|
3688
|
+
).length;
|
|
3612
3689
|
return {
|
|
3613
3690
|
repo_path: path7.basename(resolvedRepo) || ".",
|
|
3614
3691
|
dry_run: dryRun,
|
|
@@ -4452,29 +4529,21 @@ function formatSyncReport(report, format = "table", colorEnabled) {
|
|
|
4452
4529
|
(a) => a.action === "created" || a.action === "updated" || a.action === "unchanged"
|
|
4453
4530
|
);
|
|
4454
4531
|
const firstSkill = activeArtifacts.find((a) => a.skill_name !== "codex-agents-index")?.skill_name ?? report.routed_bundle.selected_skills[0]?.name ?? "security-sast-gate";
|
|
4455
|
-
const usageBox = activeArtifacts.length > 0 ?
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
` \u2022 ${style.cyan("Deep-Inspect:", c)} Run ${style.green(`npx skillops-cli info ${firstSkill}`, c)} to view triggers & Level 3 scripts`
|
|
4461
|
-
],
|
|
4462
|
-
{
|
|
4463
|
-
title: "\u{1F680} Using Your Skills & Subagents",
|
|
4464
|
-
borderColor: style.cyan,
|
|
4465
|
-
minWidth: 74,
|
|
4466
|
-
colorEnabled: c
|
|
4467
|
-
}
|
|
4532
|
+
const usageBox = activeArtifacts.length > 0 ? renderAiUsageGuide(
|
|
4533
|
+
report.targets,
|
|
4534
|
+
[firstSkill],
|
|
4535
|
+
report.routed_bundle.recommended_subagents,
|
|
4536
|
+
c
|
|
4468
4537
|
) : "";
|
|
4469
4538
|
const nextSteps = renderNextSteps(
|
|
4470
4539
|
[
|
|
4471
4540
|
{
|
|
4472
4541
|
command: `npx skillops-cli info ${firstSkill}`,
|
|
4473
|
-
description: "Inspect triggers, token budget &
|
|
4542
|
+
description: "Inspect triggers, token budget & L3 scripts"
|
|
4474
4543
|
},
|
|
4475
4544
|
{
|
|
4476
4545
|
command: "npx skillops-cli doctor",
|
|
4477
|
-
description: "Verify lockfile SHA-256
|
|
4546
|
+
description: "Verify lockfile SHA-256 & Startup Token Tax"
|
|
4478
4547
|
}
|
|
4479
4548
|
],
|
|
4480
4549
|
c
|
|
@@ -4501,20 +4570,20 @@ var COMMAND_HELP_SPECS = [
|
|
|
4501
4570
|
name: "quickstart",
|
|
4502
4571
|
aliases: ["setup"],
|
|
4503
4572
|
pillar: "library",
|
|
4504
|
-
summary: "1-step onboarding: detect
|
|
4573
|
+
summary: "1-step onboarding: detect, route & sync",
|
|
4505
4574
|
usage: "npx skillops-cli quickstart [options]",
|
|
4506
4575
|
options: [
|
|
4507
4576
|
{
|
|
4508
|
-
flags: "
|
|
4509
|
-
description: "Target repository directory (default:
|
|
4577
|
+
flags: "-p, --project <dir>",
|
|
4578
|
+
description: "Target repository directory (default: cwd)"
|
|
4510
4579
|
},
|
|
4511
4580
|
{
|
|
4512
|
-
flags: "
|
|
4513
|
-
description: "Target AI coding harnesses (
|
|
4581
|
+
flags: "-t, --harness <list|auto|all>",
|
|
4582
|
+
description: "Target AI coding harnesses (claude,cursor...)"
|
|
4514
4583
|
},
|
|
4515
4584
|
{
|
|
4516
4585
|
flags: "--top, --max-skills <n>",
|
|
4517
|
-
description: "
|
|
4586
|
+
description: "Max Skills to activate in bundle (default: 12)"
|
|
4518
4587
|
},
|
|
4519
4588
|
{
|
|
4520
4589
|
flags: "--skip-mcp, --no-mcp",
|
|
@@ -4522,25 +4591,25 @@ var COMMAND_HELP_SPECS = [
|
|
|
4522
4591
|
},
|
|
4523
4592
|
{
|
|
4524
4593
|
flags: "--dry-run",
|
|
4525
|
-
description: "Preview planned changes without writing files
|
|
4594
|
+
description: "Preview planned changes without writing files"
|
|
4526
4595
|
},
|
|
4527
4596
|
{
|
|
4528
4597
|
flags: "--force",
|
|
4529
|
-
description: "Overwrite locally modified artifacts
|
|
4598
|
+
description: "Overwrite locally modified artifacts"
|
|
4530
4599
|
},
|
|
4531
4600
|
{
|
|
4532
|
-
flags: "--format
|
|
4601
|
+
flags: "-f, --format <table|json|md>",
|
|
4533
4602
|
description: "Output report format (default: table)"
|
|
4534
4603
|
}
|
|
4535
4604
|
],
|
|
4536
4605
|
examples: [
|
|
4537
4606
|
{
|
|
4538
4607
|
command: "npx skillops-cli quickstart",
|
|
4539
|
-
description: "Auto-detect stack
|
|
4608
|
+
description: "Auto-detect stack, sync Skills & wire MCP"
|
|
4540
4609
|
},
|
|
4541
4610
|
{
|
|
4542
|
-
command: "npx skillops-cli quickstart
|
|
4543
|
-
description: "
|
|
4611
|
+
command: "npx skillops-cli quickstart -t cursor,claude --top 6",
|
|
4612
|
+
description: "Sync top 6 Skills to Cursor & Claude Code"
|
|
4544
4613
|
}
|
|
4545
4614
|
]
|
|
4546
4615
|
},
|
|
@@ -4548,7 +4617,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4548
4617
|
name: "list",
|
|
4549
4618
|
aliases: [],
|
|
4550
4619
|
pillar: "library",
|
|
4551
|
-
summary: "Browse all
|
|
4620
|
+
summary: "Browse all 10 Skills & 9 Subagents",
|
|
4552
4621
|
usage: "npx skillops-cli list [options]",
|
|
4553
4622
|
options: [
|
|
4554
4623
|
{
|
|
@@ -4556,18 +4625,18 @@ var COMMAND_HELP_SPECS = [
|
|
|
4556
4625
|
description: "Custom catalog directory to list"
|
|
4557
4626
|
},
|
|
4558
4627
|
{
|
|
4559
|
-
flags: "--format
|
|
4628
|
+
flags: "-f, --format <table|json|md>",
|
|
4560
4629
|
description: "Output format (default: table)"
|
|
4561
4630
|
}
|
|
4562
4631
|
],
|
|
4563
4632
|
examples: [
|
|
4564
4633
|
{
|
|
4565
4634
|
command: "npx skillops-cli list",
|
|
4566
|
-
description: "Display all 10 Skills
|
|
4635
|
+
description: "Display all 10 Skills & 9 Subagents"
|
|
4567
4636
|
},
|
|
4568
4637
|
{
|
|
4569
4638
|
command: "npx skillops-cli info security-sast-gate",
|
|
4570
|
-
description: "
|
|
4639
|
+
description: "Inspect a specific Skill from the Library"
|
|
4571
4640
|
}
|
|
4572
4641
|
]
|
|
4573
4642
|
},
|
|
@@ -4575,7 +4644,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4575
4644
|
name: "search",
|
|
4576
4645
|
aliases: ["find"],
|
|
4577
4646
|
pillar: "library",
|
|
4578
|
-
summary: "Search
|
|
4647
|
+
summary: "Search catalog by keyword, stack or domain",
|
|
4579
4648
|
usage: "npx skillops-cli search <query> [options]",
|
|
4580
4649
|
options: [
|
|
4581
4650
|
{
|
|
@@ -4583,18 +4652,18 @@ var COMMAND_HELP_SPECS = [
|
|
|
4583
4652
|
description: "Custom catalog directory to search"
|
|
4584
4653
|
},
|
|
4585
4654
|
{
|
|
4586
|
-
flags: "--format
|
|
4655
|
+
flags: "-f, --format <table|json|md>",
|
|
4587
4656
|
description: "Output format (default: table)"
|
|
4588
4657
|
}
|
|
4589
4658
|
],
|
|
4590
4659
|
examples: [
|
|
4591
4660
|
{
|
|
4592
4661
|
command: "npx skillops-cli search security",
|
|
4593
|
-
description: "Find Skills
|
|
4662
|
+
description: "Find Skills/Subagents matching security/SAST"
|
|
4594
4663
|
},
|
|
4595
4664
|
{
|
|
4596
4665
|
command: "npx skillops-cli find postgres",
|
|
4597
|
-
description: "Find database & PostgreSQL optimization Skills
|
|
4666
|
+
description: "Find database & PostgreSQL optimization Skills"
|
|
4598
4667
|
}
|
|
4599
4668
|
]
|
|
4600
4669
|
},
|
|
@@ -4602,65 +4671,65 @@ var COMMAND_HELP_SPECS = [
|
|
|
4602
4671
|
name: "info",
|
|
4603
4672
|
aliases: ["show", "inspect"],
|
|
4604
4673
|
pillar: "library",
|
|
4605
|
-
summary: "Inspect
|
|
4606
|
-
usage: "npx skillops-cli info <
|
|
4674
|
+
summary: "Inspect triggers, L2 budget & AI usage",
|
|
4675
|
+
usage: "npx skillops-cli info <name> [options]",
|
|
4607
4676
|
options: [
|
|
4608
4677
|
{
|
|
4609
4678
|
flags: "--catalog <dir>",
|
|
4610
4679
|
description: "Custom catalog directory"
|
|
4611
4680
|
},
|
|
4612
4681
|
{
|
|
4613
|
-
flags: "--format
|
|
4682
|
+
flags: "-f, --format <table|json|md>",
|
|
4614
4683
|
description: "Output format (default: table)"
|
|
4615
4684
|
}
|
|
4616
4685
|
],
|
|
4617
4686
|
examples: [
|
|
4618
4687
|
{
|
|
4619
4688
|
command: "npx skillops-cli info bug-reproducer-tdd",
|
|
4620
|
-
description: "Inspect
|
|
4689
|
+
description: "Inspect triggers, L3 scripts & IDE invocation"
|
|
4621
4690
|
},
|
|
4622
4691
|
{
|
|
4623
4692
|
command: "npx skillops-cli show red-team-breaker",
|
|
4624
|
-
description: "Inspect the red-team-breaker
|
|
4693
|
+
description: "Inspect the red-team-breaker Subagent card"
|
|
4625
4694
|
}
|
|
4626
4695
|
]
|
|
4627
4696
|
},
|
|
4628
4697
|
{
|
|
4629
4698
|
name: "add",
|
|
4630
|
-
aliases: ["install"
|
|
4699
|
+
aliases: ["install"],
|
|
4631
4700
|
pillar: "library",
|
|
4632
|
-
summary: "Install
|
|
4701
|
+
summary: "Install Skills/Subagents into AI harnesses",
|
|
4633
4702
|
usage: "npx skillops-cli add <name...> [options]",
|
|
4634
4703
|
options: [
|
|
4635
4704
|
{
|
|
4636
|
-
flags: "
|
|
4705
|
+
flags: "-p, --project <dir>",
|
|
4637
4706
|
description: "Target repository directory"
|
|
4638
4707
|
},
|
|
4639
4708
|
{
|
|
4640
|
-
flags: "
|
|
4641
|
-
description: "Target AI
|
|
4709
|
+
flags: "-t, --harness <list|auto|all>",
|
|
4710
|
+
description: "Target AI harnesses (claude,cursor,all...)"
|
|
4642
4711
|
},
|
|
4643
4712
|
{
|
|
4644
4713
|
flags: "--dry-run",
|
|
4645
|
-
description: "Preview planned
|
|
4714
|
+
description: "Preview planned writes without modifying disk"
|
|
4646
4715
|
},
|
|
4647
4716
|
{
|
|
4648
4717
|
flags: "--force",
|
|
4649
4718
|
description: "Overwrite locally drifted files"
|
|
4650
4719
|
},
|
|
4651
4720
|
{
|
|
4652
|
-
flags: "--format
|
|
4721
|
+
flags: "-f, --format <table|json|md>",
|
|
4653
4722
|
description: "Output format (default: table)"
|
|
4654
4723
|
}
|
|
4655
4724
|
],
|
|
4656
4725
|
examples: [
|
|
4657
4726
|
{
|
|
4658
4727
|
command: "npx skillops-cli install security-sast-gate",
|
|
4659
|
-
description: "Install
|
|
4728
|
+
description: "Install security-sast-gate into harnesses"
|
|
4660
4729
|
},
|
|
4661
4730
|
{
|
|
4662
|
-
command: "npx skillops-cli add mcp-architect
|
|
4663
|
-
description: "Install
|
|
4731
|
+
command: "npx skillops-cli add mcp-architect -t claude,cursor",
|
|
4732
|
+
description: "Install mcp-architect into Claude & Cursor"
|
|
4664
4733
|
}
|
|
4665
4734
|
]
|
|
4666
4735
|
},
|
|
@@ -4668,26 +4737,26 @@ var COMMAND_HELP_SPECS = [
|
|
|
4668
4737
|
name: "remove",
|
|
4669
4738
|
aliases: ["uninstall", "rm"],
|
|
4670
4739
|
pillar: "library",
|
|
4671
|
-
summary: "
|
|
4740
|
+
summary: "Remove a Skill/Subagent from harnesses",
|
|
4672
4741
|
usage: "npx skillops-cli remove <name...> [options]",
|
|
4673
4742
|
options: [
|
|
4674
4743
|
{
|
|
4675
|
-
flags: "
|
|
4744
|
+
flags: "-p, --project <dir>",
|
|
4676
4745
|
description: "Target repository directory"
|
|
4677
4746
|
},
|
|
4678
4747
|
{
|
|
4679
|
-
flags: "
|
|
4748
|
+
flags: "-t, --harness <list>",
|
|
4680
4749
|
description: "Restrict removal to specific harnesses"
|
|
4681
4750
|
},
|
|
4682
4751
|
{
|
|
4683
4752
|
flags: "--force",
|
|
4684
|
-
description: "Remove even if
|
|
4753
|
+
description: "Remove even if SHA-256 drift is detected"
|
|
4685
4754
|
}
|
|
4686
4755
|
],
|
|
4687
4756
|
examples: [
|
|
4688
4757
|
{
|
|
4689
4758
|
command: "npx skillops-cli uninstall mcp-architect",
|
|
4690
|
-
description: "Remove
|
|
4759
|
+
description: "Remove runtime files & update lockfile"
|
|
4691
4760
|
}
|
|
4692
4761
|
]
|
|
4693
4762
|
},
|
|
@@ -4695,16 +4764,16 @@ var COMMAND_HELP_SPECS = [
|
|
|
4695
4764
|
name: "route",
|
|
4696
4765
|
aliases: ["recommend"],
|
|
4697
4766
|
pillar: "library",
|
|
4698
|
-
summary: "
|
|
4767
|
+
summary: "Recommend optimal <=12 Skill bundle",
|
|
4699
4768
|
usage: "npx skillops-cli recommend [options]",
|
|
4700
4769
|
options: [
|
|
4701
4770
|
{
|
|
4702
|
-
flags: "
|
|
4771
|
+
flags: "-p, --project <dir>",
|
|
4703
4772
|
description: "Repository directory to fingerprint"
|
|
4704
4773
|
},
|
|
4705
4774
|
{
|
|
4706
4775
|
flags: "--task <prompt>",
|
|
4707
|
-
description: "
|
|
4776
|
+
description: "Task prompt to boost task-specific Skills"
|
|
4708
4777
|
},
|
|
4709
4778
|
{
|
|
4710
4779
|
flags: "--top, --max-skills <n>",
|
|
@@ -4712,21 +4781,21 @@ var COMMAND_HELP_SPECS = [
|
|
|
4712
4781
|
},
|
|
4713
4782
|
{
|
|
4714
4783
|
flags: "--max-l1-tokens <n>",
|
|
4715
|
-
description: "Maximum
|
|
4784
|
+
description: "Maximum L1 routing token budget (default: 1500)"
|
|
4716
4785
|
},
|
|
4717
4786
|
{
|
|
4718
|
-
flags: "--format
|
|
4787
|
+
flags: "-f, --format <table|json|md>",
|
|
4719
4788
|
description: "Output format (default: table)"
|
|
4720
4789
|
}
|
|
4721
4790
|
],
|
|
4722
4791
|
examples: [
|
|
4723
4792
|
{
|
|
4724
4793
|
command: "npx skillops-cli recommend",
|
|
4725
|
-
description: "Recommend
|
|
4794
|
+
description: "Recommend best Skills for current repo stack"
|
|
4726
4795
|
},
|
|
4727
4796
|
{
|
|
4728
|
-
command: 'npx skillops-cli route --task "
|
|
4729
|
-
description: "Route top 4 Skills
|
|
4797
|
+
command: 'npx skillops-cli route --task "slow postgres" --top 4',
|
|
4798
|
+
description: "Route top 4 Skills for a specific task"
|
|
4730
4799
|
}
|
|
4731
4800
|
]
|
|
4732
4801
|
},
|
|
@@ -4734,12 +4803,12 @@ var COMMAND_HELP_SPECS = [
|
|
|
4734
4803
|
name: "create",
|
|
4735
4804
|
aliases: ["new"],
|
|
4736
4805
|
pillar: "framework",
|
|
4737
|
-
summary: "Scaffold
|
|
4738
|
-
usage: "npx skillops-cli create <skill|subagent> <
|
|
4806
|
+
summary: "Scaffold custom Skill or Subagent template",
|
|
4807
|
+
usage: "npx skillops-cli create <skill|subagent> <name> [options]",
|
|
4739
4808
|
options: [
|
|
4740
4809
|
{
|
|
4741
|
-
flags: "--description
|
|
4742
|
-
description: "Custom trigger description (
|
|
4810
|
+
flags: "-d, --description <text>",
|
|
4811
|
+
description: "Custom trigger description (INV-SKILL-01..04)"
|
|
4743
4812
|
},
|
|
4744
4813
|
{
|
|
4745
4814
|
flags: "--catalog <dir>",
|
|
@@ -4750,18 +4819,18 @@ var COMMAND_HELP_SPECS = [
|
|
|
4750
4819
|
description: "Overwrite existing Skill or Subagent template"
|
|
4751
4820
|
},
|
|
4752
4821
|
{
|
|
4753
|
-
flags: "--format
|
|
4822
|
+
flags: "-f, --format <table|json|md>",
|
|
4754
4823
|
description: "Output format (default: table)"
|
|
4755
4824
|
}
|
|
4756
4825
|
],
|
|
4757
4826
|
examples: [
|
|
4758
4827
|
{
|
|
4759
4828
|
command: "npx skillops-cli create skill graphql-schema-guard",
|
|
4760
|
-
description: "Scaffold a new
|
|
4829
|
+
description: "Scaffold a new Skill with L3 script & evals"
|
|
4761
4830
|
},
|
|
4762
4831
|
{
|
|
4763
4832
|
command: "npx skillops-cli create subagent migration-reviewer",
|
|
4764
|
-
description: "Scaffold a new
|
|
4833
|
+
description: "Scaffold a new Context-Isolated Subagent"
|
|
4765
4834
|
}
|
|
4766
4835
|
]
|
|
4767
4836
|
},
|
|
@@ -4769,7 +4838,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4769
4838
|
name: "audit",
|
|
4770
4839
|
aliases: [],
|
|
4771
4840
|
pillar: "framework",
|
|
4772
|
-
summary: "
|
|
4841
|
+
summary: "Verify L1/L2 budgets & TF-IDF collisions",
|
|
4773
4842
|
usage: "npx skillops-cli audit [options]",
|
|
4774
4843
|
options: [
|
|
4775
4844
|
{
|
|
@@ -4778,21 +4847,21 @@ var COMMAND_HELP_SPECS = [
|
|
|
4778
4847
|
},
|
|
4779
4848
|
{
|
|
4780
4849
|
flags: "--require-layout",
|
|
4781
|
-
description: "Enforce
|
|
4850
|
+
description: "Enforce evals/evals.json and L3 scripts"
|
|
4782
4851
|
},
|
|
4783
4852
|
{
|
|
4784
4853
|
flags: "--strict",
|
|
4785
|
-
description: "Fail
|
|
4854
|
+
description: "Fail on HIGH_RISK as well as BLOCKING collisions"
|
|
4786
4855
|
},
|
|
4787
4856
|
{
|
|
4788
|
-
flags: "--format
|
|
4857
|
+
flags: "-f, --format <table|json|gh>",
|
|
4789
4858
|
description: "Output format (default: table)"
|
|
4790
4859
|
}
|
|
4791
4860
|
],
|
|
4792
4861
|
examples: [
|
|
4793
4862
|
{
|
|
4794
4863
|
command: "npx skillops-cli audit --require-layout --strict",
|
|
4795
|
-
description: "Certify
|
|
4864
|
+
description: "Certify token budgets & zero collisions"
|
|
4796
4865
|
}
|
|
4797
4866
|
]
|
|
4798
4867
|
},
|
|
@@ -4800,7 +4869,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4800
4869
|
name: "eval",
|
|
4801
4870
|
aliases: [],
|
|
4802
4871
|
pillar: "framework",
|
|
4803
|
-
summary: "
|
|
4872
|
+
summary: "Run deterministic A/B TDD benchmarks",
|
|
4804
4873
|
usage: "npx skillops-cli eval [options]",
|
|
4805
4874
|
options: [
|
|
4806
4875
|
{
|
|
@@ -4813,25 +4882,25 @@ var COMMAND_HELP_SPECS = [
|
|
|
4813
4882
|
},
|
|
4814
4883
|
{
|
|
4815
4884
|
flags: "--out <file>",
|
|
4816
|
-
description: "Write
|
|
4885
|
+
description: "Write benchmark report (HTML/Markdown) to disk"
|
|
4817
4886
|
},
|
|
4818
4887
|
{
|
|
4819
4888
|
flags: "--strict",
|
|
4820
|
-
description: "Exit
|
|
4889
|
+
description: "Exit 4 if any Skill fails CERTIFIED_IMPROVEMENT"
|
|
4821
4890
|
},
|
|
4822
4891
|
{
|
|
4823
|
-
flags: "--format
|
|
4892
|
+
flags: "-f, --format <table|json|html>",
|
|
4824
4893
|
description: "Output format (default: table)"
|
|
4825
4894
|
}
|
|
4826
4895
|
],
|
|
4827
4896
|
examples: [
|
|
4828
4897
|
{
|
|
4829
4898
|
command: "npx skillops-cli eval --strict",
|
|
4830
|
-
description: "Run deterministic A/B evals across
|
|
4899
|
+
description: "Run deterministic A/B evals across catalog"
|
|
4831
4900
|
},
|
|
4832
4901
|
{
|
|
4833
|
-
command: "npx skillops-cli eval
|
|
4834
|
-
description: "Export
|
|
4902
|
+
command: "npx skillops-cli eval -f html --out benchmark.html",
|
|
4903
|
+
description: "Export standalone HTML benchmark dashboard"
|
|
4835
4904
|
}
|
|
4836
4905
|
]
|
|
4837
4906
|
},
|
|
@@ -4839,22 +4908,22 @@ var COMMAND_HELP_SPECS = [
|
|
|
4839
4908
|
name: "init",
|
|
4840
4909
|
aliases: [],
|
|
4841
4910
|
pillar: "runtime",
|
|
4842
|
-
summary: "
|
|
4911
|
+
summary: "Create .skillops.yml and detect harnesses",
|
|
4843
4912
|
usage: "npx skillops-cli init [options]",
|
|
4844
4913
|
options: [
|
|
4845
4914
|
{
|
|
4846
|
-
flags: "
|
|
4915
|
+
flags: "-p, --project <dir>",
|
|
4847
4916
|
description: "Target repository directory"
|
|
4848
4917
|
},
|
|
4849
4918
|
{
|
|
4850
|
-
flags: "
|
|
4851
|
-
description: "Initial target harnesses
|
|
4919
|
+
flags: "-t, --harness <list|auto|all>",
|
|
4920
|
+
description: "Initial target harnesses for .skillops.yml"
|
|
4852
4921
|
}
|
|
4853
4922
|
],
|
|
4854
4923
|
examples: [
|
|
4855
4924
|
{
|
|
4856
4925
|
command: "npx skillops-cli init",
|
|
4857
|
-
description: "Create .skillops.yml with
|
|
4926
|
+
description: "Create .skillops.yml with detected harnesses"
|
|
4858
4927
|
}
|
|
4859
4928
|
]
|
|
4860
4929
|
},
|
|
@@ -4862,16 +4931,16 @@ var COMMAND_HELP_SPECS = [
|
|
|
4862
4931
|
name: "sync",
|
|
4863
4932
|
aliases: [],
|
|
4864
4933
|
pillar: "runtime",
|
|
4865
|
-
summary: "Transpile
|
|
4934
|
+
summary: "Transpile bundle across 20 AI agents",
|
|
4866
4935
|
usage: "npx skillops-cli sync [options]",
|
|
4867
4936
|
options: [
|
|
4868
4937
|
{
|
|
4869
|
-
flags: "
|
|
4938
|
+
flags: "-p, --project <dir>",
|
|
4870
4939
|
description: "Target repository directory"
|
|
4871
4940
|
},
|
|
4872
4941
|
{
|
|
4873
|
-
flags: "
|
|
4874
|
-
description: "Target AI
|
|
4942
|
+
flags: "-t, --harness <list|auto|all>",
|
|
4943
|
+
description: "Target AI harnesses (default: .skillops.yml)"
|
|
4875
4944
|
},
|
|
4876
4945
|
{
|
|
4877
4946
|
flags: "--top, --max-skills <n>",
|
|
@@ -4879,7 +4948,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4879
4948
|
},
|
|
4880
4949
|
{
|
|
4881
4950
|
flags: "--dry-run",
|
|
4882
|
-
description: "Preview planned artifacts without writing
|
|
4951
|
+
description: "Preview planned artifacts without writing"
|
|
4883
4952
|
},
|
|
4884
4953
|
{
|
|
4885
4954
|
flags: "--force",
|
|
@@ -4889,11 +4958,11 @@ var COMMAND_HELP_SPECS = [
|
|
|
4889
4958
|
examples: [
|
|
4890
4959
|
{
|
|
4891
4960
|
command: "npx skillops-cli sync --auto",
|
|
4892
|
-
description: "Sync
|
|
4961
|
+
description: "Sync bundle into all detected AI harnesses"
|
|
4893
4962
|
},
|
|
4894
4963
|
{
|
|
4895
4964
|
command: "npx skillops-cli sync --harness all",
|
|
4896
|
-
description: "Transpile across all 20 supported AI
|
|
4965
|
+
description: "Transpile across all 20 supported AI agents"
|
|
4897
4966
|
}
|
|
4898
4967
|
]
|
|
4899
4968
|
},
|
|
@@ -4901,11 +4970,11 @@ var COMMAND_HELP_SPECS = [
|
|
|
4901
4970
|
name: "clean",
|
|
4902
4971
|
aliases: [],
|
|
4903
4972
|
pillar: "runtime",
|
|
4904
|
-
summary: "Remove all
|
|
4973
|
+
summary: "Remove all tracked runtime artifacts",
|
|
4905
4974
|
usage: "npx skillops-cli clean [options]",
|
|
4906
4975
|
options: [
|
|
4907
4976
|
{
|
|
4908
|
-
flags: "
|
|
4977
|
+
flags: "-p, --project <dir>",
|
|
4909
4978
|
description: "Target repository directory"
|
|
4910
4979
|
},
|
|
4911
4980
|
{
|
|
@@ -4920,7 +4989,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4920
4989
|
examples: [
|
|
4921
4990
|
{
|
|
4922
4991
|
command: "npx skillops-cli clean",
|
|
4923
|
-
description: "
|
|
4992
|
+
description: "Remove all synced artifacts & lockfile"
|
|
4924
4993
|
}
|
|
4925
4994
|
]
|
|
4926
4995
|
},
|
|
@@ -4928,11 +4997,11 @@ var COMMAND_HELP_SPECS = [
|
|
|
4928
4997
|
name: "tokens",
|
|
4929
4998
|
aliases: ["budget"],
|
|
4930
4999
|
pillar: "runtime",
|
|
4931
|
-
summary: "Analyze
|
|
5000
|
+
summary: "Analyze Startup Token Tax & context bloat",
|
|
4932
5001
|
usage: "npx skillops-cli budget [options]",
|
|
4933
5002
|
options: [
|
|
4934
5003
|
{
|
|
4935
|
-
flags: "
|
|
5004
|
+
flags: "-p, --project <dir>",
|
|
4936
5005
|
description: "Repository directory to inspect"
|
|
4937
5006
|
},
|
|
4938
5007
|
{
|
|
@@ -4941,17 +5010,17 @@ var COMMAND_HELP_SPECS = [
|
|
|
4941
5010
|
},
|
|
4942
5011
|
{
|
|
4943
5012
|
flags: "--strict",
|
|
4944
|
-
description: "
|
|
5013
|
+
description: "Exit 3 if Startup Token Tax exceeds budget"
|
|
4945
5014
|
},
|
|
4946
5015
|
{
|
|
4947
|
-
flags: "--format
|
|
5016
|
+
flags: "-f, --format <table|json|md>",
|
|
4948
5017
|
description: "Output format (default: table)"
|
|
4949
5018
|
}
|
|
4950
5019
|
],
|
|
4951
5020
|
examples: [
|
|
4952
5021
|
{
|
|
4953
5022
|
command: "npx skillops-cli budget",
|
|
4954
|
-
description: "Inspect repository Startup Token Tax
|
|
5023
|
+
description: "Inspect repository Startup Token Tax & savings"
|
|
4955
5024
|
}
|
|
4956
5025
|
]
|
|
4957
5026
|
},
|
|
@@ -4959,11 +5028,11 @@ var COMMAND_HELP_SPECS = [
|
|
|
4959
5028
|
name: "doctor",
|
|
4960
5029
|
aliases: ["status"],
|
|
4961
5030
|
pillar: "runtime",
|
|
4962
|
-
summary: "Diagnose
|
|
5031
|
+
summary: "Diagnose environment, drift & token budget",
|
|
4963
5032
|
usage: "npx skillops-cli doctor [options]",
|
|
4964
5033
|
options: [
|
|
4965
5034
|
{
|
|
4966
|
-
flags: "
|
|
5035
|
+
flags: "-p, --project <dir>",
|
|
4967
5036
|
description: "Repository directory to diagnose"
|
|
4968
5037
|
},
|
|
4969
5038
|
{
|
|
@@ -4971,7 +5040,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4971
5040
|
description: "Fail on warnings as well as errors"
|
|
4972
5041
|
},
|
|
4973
5042
|
{
|
|
4974
|
-
flags: "--format
|
|
5043
|
+
flags: "-f, --format <table|json|md>",
|
|
4975
5044
|
description: "Output format (default: table)"
|
|
4976
5045
|
}
|
|
4977
5046
|
],
|
|
@@ -4986,22 +5055,22 @@ var COMMAND_HELP_SPECS = [
|
|
|
4986
5055
|
name: "harnesses",
|
|
4987
5056
|
aliases: [],
|
|
4988
5057
|
pillar: "runtime",
|
|
4989
|
-
summary: "List
|
|
5058
|
+
summary: "List 20 supported AI agents & repo status",
|
|
4990
5059
|
usage: "npx skillops-cli harnesses [options]",
|
|
4991
5060
|
options: [
|
|
4992
5061
|
{
|
|
4993
|
-
flags: "
|
|
5062
|
+
flags: "-p, --project <dir>",
|
|
4994
5063
|
description: "Repository directory to scan for AI harnesses"
|
|
4995
5064
|
},
|
|
4996
5065
|
{
|
|
4997
|
-
flags: "--format
|
|
5066
|
+
flags: "-f, --format <table|json|md>",
|
|
4998
5067
|
description: "Output format (default: table)"
|
|
4999
5068
|
}
|
|
5000
5069
|
],
|
|
5001
5070
|
examples: [
|
|
5002
5071
|
{
|
|
5003
5072
|
command: "npx skillops-cli harnesses",
|
|
5004
|
-
description: "View all 20 supported AI
|
|
5073
|
+
description: "View all 20 supported AI IDEs/CLI agents"
|
|
5005
5074
|
}
|
|
5006
5075
|
]
|
|
5007
5076
|
},
|
|
@@ -5009,15 +5078,15 @@ var COMMAND_HELP_SPECS = [
|
|
|
5009
5078
|
name: "mcp-setup",
|
|
5010
5079
|
aliases: [],
|
|
5011
5080
|
pillar: "runtime",
|
|
5012
|
-
summary: "
|
|
5081
|
+
summary: "Wire MCP server across 13 AI IDEs & agents",
|
|
5013
5082
|
usage: "npx skillops-cli mcp-setup [options]",
|
|
5014
5083
|
options: [
|
|
5015
5084
|
{
|
|
5016
|
-
flags: "
|
|
5085
|
+
flags: "-p, --project <dir>",
|
|
5017
5086
|
description: "Target repository directory"
|
|
5018
5087
|
},
|
|
5019
5088
|
{
|
|
5020
|
-
flags: "
|
|
5089
|
+
flags: "-t, --harness <list|auto|all>",
|
|
5021
5090
|
description: "Target harnesses to configure MCP for"
|
|
5022
5091
|
},
|
|
5023
5092
|
{
|
|
@@ -5028,7 +5097,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
5028
5097
|
examples: [
|
|
5029
5098
|
{
|
|
5030
5099
|
command: "npx skillops-cli mcp-setup --auto",
|
|
5031
|
-
description: "
|
|
5100
|
+
description: "Wire SkillOps MCP into detected IDEs"
|
|
5032
5101
|
}
|
|
5033
5102
|
]
|
|
5034
5103
|
},
|
|
@@ -5036,18 +5105,18 @@ var COMMAND_HELP_SPECS = [
|
|
|
5036
5105
|
name: "mcp",
|
|
5037
5106
|
aliases: [],
|
|
5038
5107
|
pillar: "runtime",
|
|
5039
|
-
summary: "Start
|
|
5108
|
+
summary: "Start stdio JSON-RPC 2.0 MCP server",
|
|
5040
5109
|
usage: "npx skillops-cli mcp [options]",
|
|
5041
5110
|
options: [
|
|
5042
5111
|
{
|
|
5043
|
-
flags: "
|
|
5112
|
+
flags: "-p, --project <dir>",
|
|
5044
5113
|
description: "Repository root served over MCP"
|
|
5045
5114
|
}
|
|
5046
5115
|
],
|
|
5047
5116
|
examples: [
|
|
5048
5117
|
{
|
|
5049
5118
|
command: "npx skillops-cli mcp",
|
|
5050
|
-
description: "Start stdio MCP server
|
|
5119
|
+
description: "Start stdio MCP server for AI IDEs"
|
|
5051
5120
|
}
|
|
5052
5121
|
]
|
|
5053
5122
|
}
|
|
@@ -5060,117 +5129,69 @@ function findCommandHelpSpec(commandOrAlias) {
|
|
|
5060
5129
|
}
|
|
5061
5130
|
function renderGlobalHelp(version, colorEnabled) {
|
|
5062
5131
|
const c = colorEnabled;
|
|
5132
|
+
const bar = style.dim("\u2502", c);
|
|
5063
5133
|
const banner = renderHeaderBanner(
|
|
5064
|
-
"
|
|
5134
|
+
"Framework & Library for AI Skills & Subagents",
|
|
5065
5135
|
{
|
|
5066
5136
|
version,
|
|
5067
5137
|
colorEnabled: c
|
|
5068
5138
|
}
|
|
5069
5139
|
);
|
|
5070
|
-
const quickstartBox = renderBox(
|
|
5071
|
-
[
|
|
5072
|
-
`${style.bold(style.green("npx skillops-cli quickstart", c), c)} ${style.dim("# 1-step setup: detect stack, install Skills/Subagents & wire MCP", c)}`,
|
|
5073
|
-
`${style.bold(style.cyan("npx skillops-cli info <name>", c), c)} ${style.dim("# Inspect any Skill/Subagent & see how to invoke it in your AI", c)}`,
|
|
5074
|
-
`${style.bold(style.magenta("npx skillops-cli create skill <name>", c), c)} ${style.dim("# Scaffold your own custom Skill using the SkillOps Framework", c)}`
|
|
5075
|
-
],
|
|
5076
|
-
{
|
|
5077
|
-
title: "\u{1F680} 10-Second Quickstart (Library + Framework)",
|
|
5078
|
-
borderColor: style.cyan,
|
|
5079
|
-
minWidth: 88,
|
|
5080
|
-
colorEnabled: c
|
|
5081
|
-
}
|
|
5082
|
-
);
|
|
5083
5140
|
const formatCmdSection = (pillar) => {
|
|
5084
5141
|
const specs = COMMAND_HELP_SPECS.filter((s) => s.pillar === pillar);
|
|
5085
|
-
return
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
style.bold(style.cyan(s.name, c), c)
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
{
|
|
5093
|
-
);
|
|
5142
|
+
return specs.map((s) => {
|
|
5143
|
+
const aliasPart = s.aliases.length > 0 ? style.dim(` (${s.aliases.join(", ")})`, c) : "";
|
|
5144
|
+
const cmdCol = padVisible(
|
|
5145
|
+
`${style.bold(style.cyan(s.name, c), c)}${aliasPart}`,
|
|
5146
|
+
23,
|
|
5147
|
+
"left"
|
|
5148
|
+
);
|
|
5149
|
+
return `${bar} ${cmdCol}${s.summary}`;
|
|
5150
|
+
}).join("\n");
|
|
5094
5151
|
};
|
|
5095
|
-
const globalFlagsTable = renderTable(
|
|
5096
|
-
["Global Flag", "Description"],
|
|
5097
|
-
[
|
|
5098
|
-
[
|
|
5099
|
-
style.cyan("--project, --repo, -p <dir>", c),
|
|
5100
|
-
"Target project/repository directory (default: current working directory)"
|
|
5101
|
-
],
|
|
5102
|
-
[
|
|
5103
|
-
style.cyan("--harness, --targets, -t <list|auto|all>", c),
|
|
5104
|
-
"Target AI coding harnesses (e.g. claude,cursor,windsurf,copilot or auto/all)"
|
|
5105
|
-
],
|
|
5106
|
-
[
|
|
5107
|
-
style.cyan("--format, -f <table|json|markdown|github>", c),
|
|
5108
|
-
"Output format for reports and CI pipelines (default: table)"
|
|
5109
|
-
],
|
|
5110
|
-
[
|
|
5111
|
-
style.cyan("--help, -h / --version, -V", c),
|
|
5112
|
-
"Show global or per-command help (`npx skillops-cli <cmd> --help`) / CLI version"
|
|
5113
|
-
]
|
|
5114
|
-
],
|
|
5115
|
-
{ colorEnabled: c, indent: 2 }
|
|
5116
|
-
);
|
|
5117
5152
|
return [
|
|
5118
|
-
`SkillOps v${version} \u2014 The Zero-API NPX Engine for High-End AI Skills & Subagents`,
|
|
5119
|
-
"Usage: npx skillops-cli <command> [options]",
|
|
5120
|
-
"",
|
|
5121
5153
|
banner,
|
|
5122
|
-
|
|
5123
|
-
renderSectionHeader(
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
),
|
|
5154
|
+
`${bar} Usage: npx skillops-cli <command> [options]`,
|
|
5155
|
+
renderSectionHeader("Quickstart (Library + Framework)", c),
|
|
5156
|
+
`${bar} ${style.dim("$", c)} ${style.bold(style.green("npx skillops-cli quickstart", c), c)} ${style.dim("\u2014 Detect stack, sync Skills & MCP", c)}`,
|
|
5157
|
+
`${bar} ${style.dim("$", c)} ${style.bold(style.cyan("npx skillops-cli info <name>", c), c)} ${style.dim("\u2014 Inspect Skill/Subagent & usage", c)}`,
|
|
5158
|
+
`${bar} ${style.dim("$", c)} ${style.bold(style.magenta("npx skillops-cli create skill <name>", c), c)} ${style.dim("\u2014 Scaffold a custom Skill", c)}`,
|
|
5159
|
+
renderSectionHeader("1. Library of High-End Skills & Subagents", c),
|
|
5127
5160
|
formatCmdSection("library"),
|
|
5128
5161
|
renderSectionHeader(
|
|
5129
|
-
"
|
|
5162
|
+
"2. Framework for Building Custom Skills & Subagents",
|
|
5130
5163
|
c
|
|
5131
5164
|
),
|
|
5132
5165
|
formatCmdSection("framework"),
|
|
5133
5166
|
renderSectionHeader(
|
|
5134
|
-
"
|
|
5167
|
+
"3. Universal Runtime Sync, Token Economy & Diagnostics",
|
|
5135
5168
|
c
|
|
5136
5169
|
),
|
|
5137
5170
|
formatCmdSection("runtime"),
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
"",
|
|
5141
|
-
` ${style.dim("\u{1F4A1} Tip: Run", c)} ${style.bold(style.cyan("npx skillops-cli <command> --help", c), c)} ${style.dim("for detailed flags and copy-paste examples.", c)}`,
|
|
5142
|
-
""
|
|
5171
|
+
bar,
|
|
5172
|
+
`${style.dim("\u2570\u2500", c)} ${style.bold("Global Flags:", c)} ${style.cyan("-p <dir>", c)} \xB7 ${style.cyan("-t <harnesses>", c)} \xB7 ${style.cyan("-f <table|json|md>", c)} \xB7 ${style.cyan("-h <cmd>", c)}`
|
|
5143
5173
|
].join("\n");
|
|
5144
5174
|
}
|
|
5145
5175
|
function renderCommandHelp(spec, version, colorEnabled) {
|
|
5146
5176
|
const c = colorEnabled;
|
|
5177
|
+
const bar = style.dim("\u2502", c);
|
|
5147
5178
|
const pillarBadge = spec.pillar === "library" ? formatBadge("info", "LIBRARY", c) : spec.pillar === "framework" ? formatBadge("pass", "FRAMEWORK", c) : formatBadge("subagent", "RUNTIME", c);
|
|
5148
5179
|
const aliasText = spec.aliases.length > 0 ? ` (aliases: ${spec.aliases.map((a) => style.cyan(a, c)).join(", ")})` : "";
|
|
5149
|
-
const
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
"",
|
|
5155
|
-
`${style.bold("Usage:", c)} ${style.green(spec.usage, c)}`
|
|
5156
|
-
],
|
|
5157
|
-
{
|
|
5158
|
-
title: `SkillOps v${version} \u2014 Command Reference`,
|
|
5159
|
-
borderColor: style.cyan,
|
|
5160
|
-
minWidth: 78,
|
|
5161
|
-
colorEnabled: c
|
|
5162
|
-
}
|
|
5163
|
-
);
|
|
5180
|
+
const headerLines = [
|
|
5181
|
+
`${style.bold(style.cyan(`\u25C6 SkillOps v${version}`, c), c)} ${style.dim("\u2014", c)} ${style.bold(`skillops ${spec.name}`, c)}${aliasText} ${pillarBadge}`,
|
|
5182
|
+
`${bar} ${spec.summary}`,
|
|
5183
|
+
`${bar} ${style.bold("Usage:", c)} ${style.green(spec.usage, c)}`
|
|
5184
|
+
].join("\n");
|
|
5164
5185
|
const optionsSection = spec.options.length > 0 ? [
|
|
5165
5186
|
renderSectionHeader("Options & Flags", c),
|
|
5166
5187
|
renderTable(
|
|
5167
5188
|
["Flag", "Description"],
|
|
5168
5189
|
spec.options.map((o) => [style.cyan(o.flags, c), o.description]),
|
|
5169
|
-
{ colorEnabled: c, indent:
|
|
5190
|
+
{ colorEnabled: c, indent: 3 }
|
|
5170
5191
|
)
|
|
5171
5192
|
].join("\n") : "";
|
|
5172
5193
|
const examplesSection = renderNextSteps(spec.examples, c);
|
|
5173
|
-
return [
|
|
5194
|
+
return [headerLines, optionsSection, examplesSection].filter(Boolean).join("\n");
|
|
5174
5195
|
}
|
|
5175
5196
|
|
|
5176
5197
|
// src/framework/index.ts
|
|
@@ -5272,71 +5293,66 @@ function formatCatalogItemInfo(info, format = "table", colorEnabled) {
|
|
|
5272
5293
|
return lines.join("\n");
|
|
5273
5294
|
}
|
|
5274
5295
|
const c = colorEnabled;
|
|
5296
|
+
const bar = style.dim("\u2502", c);
|
|
5275
5297
|
const badge = info.kind === "skill" ? formatBadge("skill", "HYBRID EXECUTABLE SKILL", c) : formatBadge("subagent", "CONTEXT-ISOLATED SUBAGENT", c);
|
|
5298
|
+
const shortDesc = info.description.length > 68 ? `${info.description.slice(0, 65)}...` : info.description;
|
|
5276
5299
|
const cardLines = [
|
|
5277
|
-
`${
|
|
5278
|
-
|
|
5279
|
-
`${
|
|
5280
|
-
|
|
5281
|
-
""
|
|
5300
|
+
`${style.bold(style.cyan(`\u25C6 SkillOps Library Inspector \u2014 ${info.name}`, c), c)}`,
|
|
5301
|
+
`${bar} ${badge}`,
|
|
5302
|
+
`${bar} ${shortDesc}`,
|
|
5303
|
+
bar
|
|
5282
5304
|
];
|
|
5283
5305
|
if (info.kind === "skill") {
|
|
5284
5306
|
cardLines.push(
|
|
5285
|
-
`${style.bold("Token Economy (INV-SKILL-01..03)
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5307
|
+
`${style.dim("\u251C\u2500", c)} ${style.bold(style.cyan("Token Economy (INV-SKILL-01..03)", c), c)}`,
|
|
5308
|
+
`${bar} \u2022 L1 Routing : ${style.green(`${info.l1Tokens} tokens`, c)} (<= 160 budget)`,
|
|
5309
|
+
`${bar} \u2022 L2 Playbook : ${info.l2Lines} lines (${info.l2Tokens}t, <= 250 lines)`,
|
|
5310
|
+
`${bar} \u2022 Token Savings : ${style.bold(style.green(`${info.savingsPct}%`, c), c)} Startup Tax saved`,
|
|
5311
|
+
`${bar} \u2022 L3 Scripts (${info.scripts.length}) : ${info.scripts.length > 0 ? style.cyan(info.scripts.join(", "), c) : "none"}`,
|
|
5312
|
+
`${bar} \u2022 TDD Evals : ${info.evalCasesCount} deterministic cases`
|
|
5291
5313
|
);
|
|
5292
5314
|
} else {
|
|
5293
5315
|
cardLines.push(
|
|
5294
|
-
`${style.bold("Context Isolation Contract (INV-SKILL-04)
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5316
|
+
`${style.dim("\u251C\u2500", c)} ${style.bold(style.cyan("Context Isolation Contract (INV-SKILL-04)", c), c)}`,
|
|
5317
|
+
`${bar} \u2022 System Prompt : ${style.green(`${info.l1Tokens} tokens`, c)}`,
|
|
5318
|
+
`${bar} \u2022 Max Output Cap : <= ${style.bold(`${info.maxOutputTokens} tokens`, c)}`,
|
|
5319
|
+
`${bar} \u2022 Isolation Mode : ${style.cyan(info.isolation ?? "context-isolated", c)}`,
|
|
5320
|
+
`${bar} \u2022 Allowed Tools : ${info.tools.join(", ")}`
|
|
5299
5321
|
);
|
|
5300
5322
|
}
|
|
5301
5323
|
if (info.headings.length > 0) {
|
|
5302
5324
|
cardLines.push(
|
|
5303
|
-
|
|
5304
|
-
`${style.bold("
|
|
5305
|
-
...info.headings.slice(0,
|
|
5325
|
+
bar,
|
|
5326
|
+
`${style.dim("\u251C\u2500", c)} ${style.bold(style.cyan("Playbook Sections", c), c)}`,
|
|
5327
|
+
...info.headings.slice(0, 5).map((h) => `${bar} \u2022 ${h}`)
|
|
5306
5328
|
);
|
|
5307
5329
|
}
|
|
5308
5330
|
cardLines.push(
|
|
5309
|
-
|
|
5310
|
-
`${style.bold("How to Invoke in Your AI Agent
|
|
5311
|
-
|
|
5312
|
-
info.kind === "skill" ?
|
|
5331
|
+
bar,
|
|
5332
|
+
`${style.dim("\u251C\u2500", c)} ${style.bold(style.cyan("How to Invoke in Your AI Agent", c), c)}`,
|
|
5333
|
+
`${bar} \u2022 ${style.bold("Install:", c)} ${style.green(`npx skillops-cli add ${info.name}`, c)}`,
|
|
5334
|
+
info.kind === "skill" ? `${bar} \u2022 ${style.bold("IDE Chat:", c)} Reference ${style.cyan(`@${info.name}`, c)} or ${style.cyan(`/${info.name}`, c)}` : `${bar} \u2022 ${style.bold("Delegate:", c)} Ask main agent to run ${style.magenta(`@${info.name}`, c)}`
|
|
5313
5335
|
);
|
|
5314
|
-
const box = renderBox(cardLines, {
|
|
5315
|
-
title: `\u{1F4E6} SkillOps Library Inspector \u2014 ${info.name}`,
|
|
5316
|
-
borderColor: info.kind === "skill" ? style.cyan : style.magenta,
|
|
5317
|
-
minWidth: 74,
|
|
5318
|
-
colorEnabled: c
|
|
5319
|
-
});
|
|
5320
5336
|
const nextSteps = renderNextSteps(
|
|
5321
5337
|
[
|
|
5322
5338
|
{
|
|
5323
5339
|
command: `npx skillops-cli add ${info.name}`,
|
|
5324
|
-
description:
|
|
5340
|
+
description: "Install into AI agents"
|
|
5325
5341
|
},
|
|
5326
5342
|
...info.kind === "skill" ? [
|
|
5327
5343
|
{
|
|
5328
5344
|
command: `npx skillops-cli eval --skill ${info.name}`,
|
|
5329
|
-
description:
|
|
5345
|
+
description: "Run TDD benchmark"
|
|
5330
5346
|
}
|
|
5331
5347
|
] : [],
|
|
5332
5348
|
{
|
|
5333
5349
|
command: "npx skillops-cli list",
|
|
5334
|
-
description: "Browse
|
|
5350
|
+
description: "Browse 10 Skills & 9 Subagents"
|
|
5335
5351
|
}
|
|
5336
5352
|
],
|
|
5337
5353
|
c
|
|
5338
5354
|
);
|
|
5339
|
-
return `${
|
|
5355
|
+
return `${cardLines.join("\n")}
|
|
5340
5356
|
${nextSteps}`;
|
|
5341
5357
|
}
|
|
5342
5358
|
function searchCatalog(catalogDir, query) {
|
|
@@ -5365,7 +5381,7 @@ function searchCatalog(catalogDir, query) {
|
|
|
5365
5381
|
name: parsed.manifest.name,
|
|
5366
5382
|
score,
|
|
5367
5383
|
tokens: parsed.manifest.description_tokens,
|
|
5368
|
-
summary: parsed.manifest.description.length >
|
|
5384
|
+
summary: parsed.manifest.description.length > 30 ? `${parsed.manifest.description.slice(0, 27)}...` : parsed.manifest.description
|
|
5369
5385
|
});
|
|
5370
5386
|
}
|
|
5371
5387
|
}
|
|
@@ -5392,7 +5408,7 @@ function searchCatalog(catalogDir, query) {
|
|
|
5392
5408
|
name: parsed.manifest.name,
|
|
5393
5409
|
score,
|
|
5394
5410
|
tokens: parsed.manifest.system_prompt_tokens,
|
|
5395
|
-
summary: parsed.manifest.description.length >
|
|
5411
|
+
summary: parsed.manifest.description.length > 30 ? `${parsed.manifest.description.slice(0, 27)}...` : parsed.manifest.description
|
|
5396
5412
|
});
|
|
5397
5413
|
}
|
|
5398
5414
|
}
|
|
@@ -5422,43 +5438,39 @@ function formatCatalogSearchReport(report, format = "table", colorEnabled) {
|
|
|
5422
5438
|
return lines.join("\n");
|
|
5423
5439
|
}
|
|
5424
5440
|
const c = colorEnabled;
|
|
5425
|
-
const
|
|
5426
|
-
|
|
5427
|
-
`${style.bold(style.cyan("\u{1F50D} SkillOps Library Search", c), c)} \u2014 Query: ${style.bold(`"${report.query || "*"}"`, c)} (${report.total_matches} matches)`
|
|
5428
|
-
],
|
|
5429
|
-
{ minWidth: 74, colorEnabled: c }
|
|
5430
|
-
);
|
|
5441
|
+
const bar = style.dim("\u2502", c);
|
|
5442
|
+
const header = `${style.bold(style.cyan("\u25C6 SkillOps Library Search", c), c)} ${style.dim("\u2014", c)} Query: ${style.bold(`"${report.query || "*"}"`, c)} (${report.total_matches} matches)`;
|
|
5431
5443
|
if (report.matches.length === 0) {
|
|
5432
5444
|
return `${header}
|
|
5433
|
-
${formatBadge("warn", "No matching Skills or Subagents found.", c)}
|
|
5434
|
-
${renderNextSteps([{ command: "npx skillops-cli list", description: "View all 10 Skills & 9 Subagents
|
|
5445
|
+
${bar} ${formatBadge("warn", "No matching Skills or Subagents found.", c)}
|
|
5446
|
+
${renderNextSteps([{ command: "npx skillops-cli list", description: "View all 10 Skills & 9 Subagents" }], c)}`;
|
|
5435
5447
|
}
|
|
5436
5448
|
const table = renderTable(
|
|
5437
|
-
["Type", "Name", "Tokens", "
|
|
5449
|
+
["Type", "Name", "Tokens", "Summary"],
|
|
5438
5450
|
report.matches.map((m) => [
|
|
5439
5451
|
m.kind === "skill" ? formatBadge("skill", "SKILL", c) : formatBadge("subagent", "SUBAGENT", c),
|
|
5440
5452
|
style.bold(m.name, c),
|
|
5441
5453
|
`${m.tokens}t`,
|
|
5442
5454
|
m.summary
|
|
5443
5455
|
]),
|
|
5444
|
-
{ align: ["left", "left", "right", "left"], colorEnabled: c }
|
|
5456
|
+
{ align: ["left", "left", "right", "left"], colorEnabled: c, indent: 3 }
|
|
5445
5457
|
);
|
|
5446
5458
|
const topItem = report.matches[0]?.name ?? "bug-reproducer-tdd";
|
|
5447
5459
|
const nextSteps = renderNextSteps(
|
|
5448
5460
|
[
|
|
5449
5461
|
{
|
|
5450
5462
|
command: `npx skillops-cli info ${topItem}`,
|
|
5451
|
-
description:
|
|
5463
|
+
description: "Inspect triggers & usage"
|
|
5452
5464
|
},
|
|
5453
5465
|
{
|
|
5454
5466
|
command: `npx skillops-cli add ${topItem}`,
|
|
5455
|
-
description:
|
|
5467
|
+
description: "Install into AI agents"
|
|
5456
5468
|
}
|
|
5457
5469
|
],
|
|
5458
5470
|
c
|
|
5459
5471
|
);
|
|
5460
5472
|
return `${header}
|
|
5461
|
-
|
|
5473
|
+
${bar}
|
|
5462
5474
|
${table}
|
|
5463
5475
|
${nextSteps}`;
|
|
5464
5476
|
}
|
|
@@ -5676,38 +5688,31 @@ function formatScaffoldReport(result, format = "table", colorEnabled) {
|
|
|
5676
5688
|
].join("\n");
|
|
5677
5689
|
}
|
|
5678
5690
|
const c = colorEnabled;
|
|
5679
|
-
const
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
{
|
|
5687
|
-
title: "\u{1F6E0}\uFE0F SkillOps Framework Scaffolder",
|
|
5688
|
-
borderColor: style.green,
|
|
5689
|
-
minWidth: 74,
|
|
5690
|
-
colorEnabled: c
|
|
5691
|
-
}
|
|
5692
|
-
);
|
|
5691
|
+
const bar = style.dim("\u2502", c);
|
|
5692
|
+
const treeHeader = [
|
|
5693
|
+
`${style.bold(style.cyan("\u25C6 SkillOps Framework Scaffolder", c), c)} ${style.dim("\u2014", c)} ${formatBadge("pass", "CREATED", c)} ${style.bold(result.kind.toUpperCase(), c)} ${style.bold(style.cyan(result.name, c), c)}`,
|
|
5694
|
+
bar,
|
|
5695
|
+
`${style.dim("\u251C\u2500", c)} ${style.bold("Generated Files:", c)}`,
|
|
5696
|
+
...result.created_files.map((f) => `${bar} \u2022 ${style.green(f, c)}`)
|
|
5697
|
+
].join("\n");
|
|
5693
5698
|
const nextSteps = renderNextSteps(
|
|
5694
5699
|
[
|
|
5695
5700
|
{
|
|
5696
5701
|
command: `npx skillops-cli info ${result.name}`,
|
|
5697
|
-
description: `Inspect
|
|
5702
|
+
description: `Inspect new ${result.kind} metadata & budget`
|
|
5698
5703
|
},
|
|
5699
5704
|
{
|
|
5700
5705
|
command: "npx skillops-cli audit --require-layout",
|
|
5701
|
-
description: "Verify INV-SKILL-01..04
|
|
5706
|
+
description: "Verify INV-SKILL-01..04 & collisions"
|
|
5702
5707
|
},
|
|
5703
5708
|
{
|
|
5704
5709
|
command: `npx skillops-cli add ${result.name}`,
|
|
5705
|
-
description: `
|
|
5710
|
+
description: `Install '${result.name}' into AI agents`
|
|
5706
5711
|
}
|
|
5707
5712
|
],
|
|
5708
5713
|
c
|
|
5709
5714
|
);
|
|
5710
|
-
return `${
|
|
5715
|
+
return `${treeHeader}
|
|
5711
5716
|
${nextSteps}`;
|
|
5712
5717
|
}
|
|
5713
5718
|
function runQuickstart(repoPath, catalogDir, options = {}) {
|
|
@@ -5806,34 +5811,35 @@ function formatQuickstartReport(report, format = "table", colorEnabled) {
|
|
|
5806
5811
|
].join("\n");
|
|
5807
5812
|
}
|
|
5808
5813
|
const c = colorEnabled;
|
|
5809
|
-
const
|
|
5810
|
-
const
|
|
5814
|
+
const bar = style.dim("\u2502", c);
|
|
5815
|
+
const stackLabel = [...report.detected_languages, ...report.detected_frameworks].join(", ") || "general";
|
|
5816
|
+
const targetsLabel = report.active_targets.length > 4 ? `${report.active_targets.slice(0, 4).join(", ")} (+${report.active_targets.length - 4})` : report.active_targets.join(", ");
|
|
5811
5817
|
const banner = renderHeaderBanner(
|
|
5812
|
-
`
|
|
5818
|
+
`Quickstart Setup ${report.dry_run ? "[DRY-RUN]" : "[READY]"}`,
|
|
5813
5819
|
{ colorEnabled: c }
|
|
5814
5820
|
);
|
|
5815
5821
|
const stepsBlock = [
|
|
5816
5822
|
renderStep(
|
|
5817
5823
|
1,
|
|
5818
5824
|
4,
|
|
5819
|
-
"Detect Stack &
|
|
5820
|
-
|
|
5825
|
+
"Detect Stack & Agents",
|
|
5826
|
+
`${style.cyan(stackLabel, c)} \xB7 ${style.bold(targetsLabel, c)}`,
|
|
5821
5827
|
"done",
|
|
5822
5828
|
c
|
|
5823
5829
|
),
|
|
5824
5830
|
renderStep(
|
|
5825
5831
|
2,
|
|
5826
5832
|
4,
|
|
5827
|
-
"Route
|
|
5828
|
-
`${style.green(`${report.selected_skills.length} Skills`, c)} + ${style.magenta(`${report.selected_subagents.length} Subagents`, c)}
|
|
5833
|
+
"Route Library Bundle",
|
|
5834
|
+
`${style.green(`${report.selected_skills.length} Skills`, c)} + ${style.magenta(`${report.selected_subagents.length} Subagents`, c)}`,
|
|
5829
5835
|
"done",
|
|
5830
5836
|
c
|
|
5831
5837
|
),
|
|
5832
5838
|
renderStep(
|
|
5833
5839
|
3,
|
|
5834
5840
|
4,
|
|
5835
|
-
"Transpile & Sync
|
|
5836
|
-
`${report.synced_files_count} files
|
|
5841
|
+
"Transpile & Sync",
|
|
5842
|
+
`${report.synced_files_count} files (${report.dry_run ? "dry-run" : ".skillops.yml + lockfile"})`,
|
|
5837
5843
|
"done",
|
|
5838
5844
|
c
|
|
5839
5845
|
),
|
|
@@ -5841,12 +5847,12 @@ function formatQuickstartReport(report, format = "table", colorEnabled) {
|
|
|
5841
5847
|
4,
|
|
5842
5848
|
4,
|
|
5843
5849
|
"Register MCP Server",
|
|
5844
|
-
`${report.mcp_configured_count} MCP
|
|
5850
|
+
`${report.mcp_configured_count} MCP agent config(s) wired`,
|
|
5845
5851
|
"done",
|
|
5846
5852
|
c
|
|
5847
5853
|
)
|
|
5848
5854
|
].join("\n");
|
|
5849
|
-
const tokenBar =
|
|
5855
|
+
const tokenBar = `${bar} ${renderTokenBar(
|
|
5850
5856
|
report.total_l1_tokens,
|
|
5851
5857
|
report.max_l1_budget,
|
|
5852
5858
|
{
|
|
@@ -5854,21 +5860,16 @@ function formatQuickstartReport(report, format = "table", colorEnabled) {
|
|
|
5854
5860
|
colorEnabled: c
|
|
5855
5861
|
}
|
|
5856
5862
|
)}`;
|
|
5857
|
-
const
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
""
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
{
|
|
5866
|
-
|
|
5867
|
-
borderColor: style.cyan,
|
|
5868
|
-
minWidth: 72,
|
|
5869
|
-
colorEnabled: c
|
|
5870
|
-
}
|
|
5871
|
-
);
|
|
5863
|
+
const bundleTree = [
|
|
5864
|
+
bar,
|
|
5865
|
+
`${style.dim("\u251C\u2500", c)} ${style.bold(style.cyan(`Active Bundle (${report.selected_skills.length} Skills \xB7 ${report.selected_subagents.length} Subagents)`, c), c)}`,
|
|
5866
|
+
`${bar} \u2022 ${style.bold("Skills:", c)} ${report.selected_skills.slice(0, 2).map((s) => style.cyan(s, c)).join(
|
|
5867
|
+
", "
|
|
5868
|
+
)}${report.selected_skills.length > 2 ? ` (+${report.selected_skills.length - 2} more)` : ""}`,
|
|
5869
|
+
`${bar} \u2022 ${style.bold("Subagents:", c)} ${report.selected_subagents.slice(0, 2).map((a) => style.magenta(a, c)).join(
|
|
5870
|
+
", "
|
|
5871
|
+
)}${report.selected_subagents.length > 2 ? ` (+${report.selected_subagents.length - 2} more)` : ""}`
|
|
5872
|
+
].join("\n");
|
|
5872
5873
|
const usageGuide = renderAiUsageGuide(
|
|
5873
5874
|
report.active_targets,
|
|
5874
5875
|
report.selected_skills,
|
|
@@ -5879,32 +5880,29 @@ function formatQuickstartReport(report, format = "table", colorEnabled) {
|
|
|
5879
5880
|
[
|
|
5880
5881
|
{
|
|
5881
5882
|
command: `npx skillops-cli info ${report.selected_skills[0] ?? "bug-reproducer-tdd"}`,
|
|
5882
|
-
description: "Inspect
|
|
5883
|
+
description: "Inspect Skill triggers & L3 scripts"
|
|
5883
5884
|
},
|
|
5884
5885
|
{
|
|
5885
5886
|
command: "npx skillops-cli list",
|
|
5886
|
-
description: "Browse all 10 Skills & 9 Subagents
|
|
5887
|
+
description: "Browse all 10 Skills & 9 Subagents"
|
|
5887
5888
|
},
|
|
5888
5889
|
{
|
|
5889
|
-
command: "npx skillops-cli create skill my-
|
|
5890
|
-
description: "Create
|
|
5890
|
+
command: "npx skillops-cli create skill my-skill",
|
|
5891
|
+
description: "Create a custom Skill"
|
|
5891
5892
|
},
|
|
5892
5893
|
{
|
|
5893
5894
|
command: "npx skillops-cli doctor",
|
|
5894
|
-
description: "Verify lockfile
|
|
5895
|
+
description: "Verify lockfile & Startup Token Tax"
|
|
5895
5896
|
}
|
|
5896
5897
|
],
|
|
5897
5898
|
c
|
|
5898
5899
|
);
|
|
5899
5900
|
return [
|
|
5900
5901
|
banner,
|
|
5901
|
-
|
|
5902
|
+
bar,
|
|
5902
5903
|
stepsBlock,
|
|
5903
|
-
"",
|
|
5904
5904
|
tokenBar,
|
|
5905
|
-
|
|
5906
|
-
bundleBox,
|
|
5907
|
-
"",
|
|
5905
|
+
bundleTree,
|
|
5908
5906
|
usageGuide,
|
|
5909
5907
|
nextSteps
|
|
5910
5908
|
].join("\n");
|