skillops-cli 1.3.4 → 1.3.6
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 +440 -65
- package/dist/index.d.ts +42 -42
- package/dist/index.js +266 -41
- package/package.json +10 -2
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.6";
|
|
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]*)$/;
|
|
@@ -87,7 +87,15 @@ var RuntimeTargetSchema = z.enum([
|
|
|
87
87
|
"kiro",
|
|
88
88
|
"trae",
|
|
89
89
|
"amazonq",
|
|
90
|
-
"junie"
|
|
90
|
+
"junie",
|
|
91
|
+
"gemini",
|
|
92
|
+
"factory",
|
|
93
|
+
"qwen",
|
|
94
|
+
"augment",
|
|
95
|
+
"vibe",
|
|
96
|
+
"warp",
|
|
97
|
+
"crush",
|
|
98
|
+
"idx"
|
|
91
99
|
]);
|
|
92
100
|
var CORE_RUNTIME_TARGETS = [
|
|
93
101
|
"claude",
|
|
@@ -116,7 +124,15 @@ var ALL_RUNTIME_TARGETS = [
|
|
|
116
124
|
"kiro",
|
|
117
125
|
"trae",
|
|
118
126
|
"amazonq",
|
|
119
|
-
"junie"
|
|
127
|
+
"junie",
|
|
128
|
+
"gemini",
|
|
129
|
+
"factory",
|
|
130
|
+
"qwen",
|
|
131
|
+
"augment",
|
|
132
|
+
"vibe",
|
|
133
|
+
"warp",
|
|
134
|
+
"crush",
|
|
135
|
+
"idx"
|
|
120
136
|
];
|
|
121
137
|
var RUNTIME_HARNESS_SPECS = {
|
|
122
138
|
claude: {
|
|
@@ -134,15 +150,15 @@ var RUNTIME_HARNESS_SPECS = {
|
|
|
134
150
|
},
|
|
135
151
|
antigravity: {
|
|
136
152
|
id: "antigravity",
|
|
137
|
-
displayName: "Google Antigravity
|
|
153
|
+
displayName: "Google Antigravity IDE",
|
|
138
154
|
vendor: "Google DeepMind",
|
|
139
155
|
category: "ai-ide",
|
|
140
156
|
skillFormat: "progressive-skill-dir",
|
|
141
157
|
skillsDir: ".agent/skills",
|
|
142
158
|
subagentsDir: ".agent/agents",
|
|
143
|
-
detectionPaths: [".agent", "
|
|
144
|
-
alwaysOnFiles: ["GEMINI.md"
|
|
145
|
-
mcpConfigPath: ".
|
|
159
|
+
detectionPaths: [".agent", "GEMINI.md"],
|
|
160
|
+
alwaysOnFiles: ["GEMINI.md"],
|
|
161
|
+
mcpConfigPath: ".agent/mcp_config.json",
|
|
146
162
|
supportsMcp: true
|
|
147
163
|
},
|
|
148
164
|
cursor: {
|
|
@@ -387,6 +403,110 @@ var RUNTIME_HARNESS_SPECS = {
|
|
|
387
403
|
alwaysOnFiles: [".junie/guidelines.md"],
|
|
388
404
|
mcpConfigPath: null,
|
|
389
405
|
supportsMcp: false
|
|
406
|
+
},
|
|
407
|
+
gemini: {
|
|
408
|
+
id: "gemini",
|
|
409
|
+
displayName: "Google Gemini CLI",
|
|
410
|
+
vendor: "Google",
|
|
411
|
+
category: "cli-agent",
|
|
412
|
+
skillFormat: "progressive-skill-dir",
|
|
413
|
+
skillsDir: ".gemini/skills",
|
|
414
|
+
subagentsDir: ".gemini/agents",
|
|
415
|
+
detectionPaths: [".gemini", "GEMINI.md"],
|
|
416
|
+
alwaysOnFiles: ["GEMINI.md", ".gemini/GEMINI.md", ".gemini/STYLEGUIDE.md"],
|
|
417
|
+
mcpConfigPath: ".gemini/settings.json",
|
|
418
|
+
supportsMcp: true
|
|
419
|
+
},
|
|
420
|
+
factory: {
|
|
421
|
+
id: "factory",
|
|
422
|
+
displayName: "Factory AI Droid",
|
|
423
|
+
vendor: "Factory AI",
|
|
424
|
+
category: "cli-agent",
|
|
425
|
+
skillFormat: "progressive-skill-dir",
|
|
426
|
+
skillsDir: ".factory/skills",
|
|
427
|
+
subagentsDir: ".factory/droids",
|
|
428
|
+
detectionPaths: [".factory"],
|
|
429
|
+
alwaysOnFiles: ["AGENTS.md", ".factory/instructions.md"],
|
|
430
|
+
mcpConfigPath: ".factory/mcp.json",
|
|
431
|
+
supportsMcp: true
|
|
432
|
+
},
|
|
433
|
+
qwen: {
|
|
434
|
+
id: "qwen",
|
|
435
|
+
displayName: "Qwen Code CLI",
|
|
436
|
+
vendor: "Alibaba Cloud / Qwen",
|
|
437
|
+
category: "cli-agent",
|
|
438
|
+
skillFormat: "progressive-skill-dir",
|
|
439
|
+
skillsDir: ".qwen/skills",
|
|
440
|
+
subagentsDir: ".qwen/agents",
|
|
441
|
+
detectionPaths: [".qwen", "QWEN.md"],
|
|
442
|
+
alwaysOnFiles: ["QWEN.md", "AGENTS.md"],
|
|
443
|
+
mcpConfigPath: ".qwen/settings.json",
|
|
444
|
+
supportsMcp: true
|
|
445
|
+
},
|
|
446
|
+
augment: {
|
|
447
|
+
id: "augment",
|
|
448
|
+
displayName: "Augment Code",
|
|
449
|
+
vendor: "Augment",
|
|
450
|
+
category: "ide-extension",
|
|
451
|
+
skillFormat: "markdown-rule",
|
|
452
|
+
skillsDir: ".augment/rules",
|
|
453
|
+
subagentsDir: ".augment/agents",
|
|
454
|
+
detectionPaths: [".augment", ".augment-guidelines"],
|
|
455
|
+
alwaysOnFiles: [".augment-guidelines", "AGENTS.md"],
|
|
456
|
+
mcpConfigPath: ".augment/settings.json",
|
|
457
|
+
supportsMcp: true
|
|
458
|
+
},
|
|
459
|
+
vibe: {
|
|
460
|
+
id: "vibe",
|
|
461
|
+
displayName: "Mistral Vibe CLI",
|
|
462
|
+
vendor: "Mistral AI",
|
|
463
|
+
category: "cli-agent",
|
|
464
|
+
skillFormat: "progressive-skill-dir",
|
|
465
|
+
skillsDir: ".vibe/skills",
|
|
466
|
+
subagentsDir: ".vibe/agents",
|
|
467
|
+
detectionPaths: [".vibe"],
|
|
468
|
+
alwaysOnFiles: [".vibe/config.toml", "AGENTS.md"],
|
|
469
|
+
mcpConfigPath: ".vibe/config.toml",
|
|
470
|
+
supportsMcp: true
|
|
471
|
+
},
|
|
472
|
+
warp: {
|
|
473
|
+
id: "warp",
|
|
474
|
+
displayName: "Warp AI Terminal",
|
|
475
|
+
vendor: "Warp",
|
|
476
|
+
category: "cli-agent",
|
|
477
|
+
skillFormat: "progressive-skill-dir",
|
|
478
|
+
skillsDir: ".warp/skills",
|
|
479
|
+
subagentsDir: ".warp/agents",
|
|
480
|
+
detectionPaths: [".warp", "WARP.md"],
|
|
481
|
+
alwaysOnFiles: ["WARP.md", "AGENTS.md"],
|
|
482
|
+
mcpConfigPath: null,
|
|
483
|
+
supportsMcp: false
|
|
484
|
+
},
|
|
485
|
+
crush: {
|
|
486
|
+
id: "crush",
|
|
487
|
+
displayName: "Charmbracelet Crush",
|
|
488
|
+
vendor: "Charmbracelet",
|
|
489
|
+
category: "cli-agent",
|
|
490
|
+
skillFormat: "progressive-skill-dir",
|
|
491
|
+
skillsDir: ".crush/skills",
|
|
492
|
+
subagentsDir: ".crush/agents",
|
|
493
|
+
detectionPaths: [".crush", ".crush.json", "CRUSH.md"],
|
|
494
|
+
alwaysOnFiles: ["CRUSH.md", "AGENTS.md"],
|
|
495
|
+
mcpConfigPath: ".crush.json",
|
|
496
|
+
supportsMcp: true
|
|
497
|
+
},
|
|
498
|
+
idx: {
|
|
499
|
+
id: "idx",
|
|
500
|
+
displayName: "Firebase Studio (Project IDX)",
|
|
501
|
+
vendor: "Google",
|
|
502
|
+
category: "ai-ide",
|
|
503
|
+
skillFormat: "markdown-rule",
|
|
504
|
+
skillsDir: ".idx/rules",
|
|
505
|
+
subagentsDir: ".idx/agents",
|
|
506
|
+
detectionPaths: [".idx"],
|
|
507
|
+
alwaysOnFiles: [".idx/airules.md", "GEMINI.md"],
|
|
508
|
+
mcpConfigPath: ".idx/mcp.json",
|
|
509
|
+
supportsMcp: true
|
|
390
510
|
}
|
|
391
511
|
};
|
|
392
512
|
function detectInstalledHarnesses(repoPath) {
|
|
@@ -418,7 +538,7 @@ function resolveRuntimeTargets(rawSpec, repoPath, fallbackTargets = CORE_RUNTIME
|
|
|
418
538
|
}
|
|
419
539
|
};
|
|
420
540
|
for (const token of tokens) {
|
|
421
|
-
if (token === "all" || token === "*" || token === "top20") {
|
|
541
|
+
if (token === "all" || token === "*" || token === "top20" || token === "top28") {
|
|
422
542
|
for (const t of ALL_RUNTIME_TARGETS) {
|
|
423
543
|
pushUnique(t);
|
|
424
544
|
}
|
|
@@ -1613,6 +1733,10 @@ var ALWAYS_ON_INSTRUCTION_CANDIDATES = [
|
|
|
1613
1733
|
"AGENTS.md",
|
|
1614
1734
|
"GEMINI.md",
|
|
1615
1735
|
".gemini/GEMINI.md",
|
|
1736
|
+
".gemini/STYLEGUIDE.md",
|
|
1737
|
+
"QWEN.md",
|
|
1738
|
+
"WARP.md",
|
|
1739
|
+
"CRUSH.md",
|
|
1616
1740
|
"AGENT.md",
|
|
1617
1741
|
"CONVENTIONS.md",
|
|
1618
1742
|
".github/copilot-instructions.md",
|
|
@@ -1622,17 +1746,22 @@ var ALWAYS_ON_INSTRUCTION_CANDIDATES = [
|
|
|
1622
1746
|
".roorules",
|
|
1623
1747
|
".kilocoderules",
|
|
1624
1748
|
".continuerules",
|
|
1749
|
+
".augment-guidelines",
|
|
1625
1750
|
".rules",
|
|
1626
1751
|
".goosehints",
|
|
1627
1752
|
".junie/guidelines.md",
|
|
1628
1753
|
".openhands/microagents/repo.md",
|
|
1629
1754
|
".trae/rules/project_rules.md",
|
|
1755
|
+
".factory/instructions.md",
|
|
1756
|
+
".idx/airules.md",
|
|
1757
|
+
".vibe/config.toml",
|
|
1630
1758
|
".kiro/steering/product.md",
|
|
1631
1759
|
".kiro/steering/tech.md",
|
|
1632
1760
|
".kiro/steering/structure.md"
|
|
1633
1761
|
];
|
|
1634
1762
|
var MCP_CONFIG_CANDIDATES = [
|
|
1635
1763
|
".mcp.json",
|
|
1764
|
+
".agent/mcp_config.json",
|
|
1636
1765
|
".cursor/mcp.json",
|
|
1637
1766
|
".vscode/mcp.json",
|
|
1638
1767
|
".gemini/settings.json",
|
|
@@ -1644,7 +1773,13 @@ var MCP_CONFIG_CANDIDATES = [
|
|
|
1644
1773
|
".amp/settings.json",
|
|
1645
1774
|
"opencode.json",
|
|
1646
1775
|
".kiro/settings/mcp.json",
|
|
1647
|
-
".amazonq/mcp.json"
|
|
1776
|
+
".amazonq/mcp.json",
|
|
1777
|
+
".factory/mcp.json",
|
|
1778
|
+
".qwen/settings.json",
|
|
1779
|
+
".augment/settings.json",
|
|
1780
|
+
".vibe/config.toml",
|
|
1781
|
+
".crush.json",
|
|
1782
|
+
".idx/mcp.json"
|
|
1648
1783
|
];
|
|
1649
1784
|
function countMcpServersInConfig(rawText, relPath) {
|
|
1650
1785
|
if (relPath.endsWith(".toml")) {
|
|
@@ -2074,9 +2209,9 @@ function diagnoseRepository(repoPath, options = {}) {
|
|
|
2074
2209
|
const detectedHarnesses = detectInstalledHarnesses(resolvedRepo);
|
|
2075
2210
|
checks.push({
|
|
2076
2211
|
id: "detected_harnesses",
|
|
2077
|
-
title: "Detected AI Coding Harnesses (Top
|
|
2212
|
+
title: "Detected AI Coding Harnesses (Top 28)",
|
|
2078
2213
|
status: "pass",
|
|
2079
|
-
summary: detectedHarnesses.length > 0 ? `Detected ${detectedHarnesses.length} AI coding harness(es): ${detectedHarnesses.join(", ")}.` : "No repo-local AI harness folders detected yet (ready to sync all
|
|
2214
|
+
summary: detectedHarnesses.length > 0 ? `Detected ${detectedHarnesses.length} AI coding harness(es): ${detectedHarnesses.join(", ")}.` : "No repo-local AI harness folders detected yet (ready to sync all 28 agents)."
|
|
2080
2215
|
});
|
|
2081
2216
|
const loadedCfg = loadSkillOpsConfig(resolvedRepo);
|
|
2082
2217
|
const configPresent = loadedCfg.exists;
|
|
@@ -2259,7 +2394,7 @@ function formatHarnessInspectionReport(report, format = "table") {
|
|
|
2259
2394
|
}
|
|
2260
2395
|
if (format === "markdown") {
|
|
2261
2396
|
const lines2 = [
|
|
2262
|
-
`## SkillOps Universal Top-
|
|
2397
|
+
`## SkillOps Universal Top-28 AI Coding Agent Harnesses (\`${report.repo_path}\`)`,
|
|
2263
2398
|
"",
|
|
2264
2399
|
`- **Supported AI Coding Harnesses:** \`${report.total_supported}\``,
|
|
2265
2400
|
`- **Detected in Repository:** \`${report.detected_count}\` (${report.detected_harnesses.length > 0 ? report.detected_harnesses.join(", ") : "none"})`,
|
|
@@ -2274,7 +2409,7 @@ function formatHarnessInspectionReport(report, format = "table") {
|
|
|
2274
2409
|
return lines2.join("\n");
|
|
2275
2410
|
}
|
|
2276
2411
|
const lines = [
|
|
2277
|
-
`=== SkillOps Universal Top-
|
|
2412
|
+
`=== SkillOps Universal Top-28 AI Coding Harnesses (${report.repo_path}) ===`,
|
|
2278
2413
|
`Supported Harnesses : ${report.total_supported}`,
|
|
2279
2414
|
`Detected in Repo : ${report.detected_count} (${report.detected_harnesses.length > 0 ? report.detected_harnesses.join(", ") : "none"})`,
|
|
2280
2415
|
"-".repeat(92),
|
|
@@ -3345,7 +3480,7 @@ var MCP_TOOLS = [
|
|
|
3345
3480
|
},
|
|
3346
3481
|
{
|
|
3347
3482
|
name: "list_supported_harnesses",
|
|
3348
|
-
description: "Inspect all
|
|
3483
|
+
description: "Inspect all 28 supported AI coding agents, IDEs, and CLI harnesses (target paths, MCP support, and repository auto-detection).",
|
|
3349
3484
|
inputSchema: {
|
|
3350
3485
|
type: "object",
|
|
3351
3486
|
properties: {
|
|
@@ -3517,7 +3652,7 @@ function startMcpStdioServer(context) {
|
|
|
3517
3652
|
}
|
|
3518
3653
|
function buildUpdatedMcpConfigContent(target, existingRaw, serverName) {
|
|
3519
3654
|
const mcpArgs = ["-y", "skillops-cli@latest", "mcp"];
|
|
3520
|
-
if (target === "codex") {
|
|
3655
|
+
if (target === "codex" || target === "vibe") {
|
|
3521
3656
|
const tomlBlock = [
|
|
3522
3657
|
`[mcp_servers.${serverName}]`,
|
|
3523
3658
|
'command = "npx"',
|
|
@@ -3610,6 +3745,20 @@ ${tomlBlock}
|
|
|
3610
3745
|
};
|
|
3611
3746
|
parsedObj.mcp = mcpMap;
|
|
3612
3747
|
return `${JSON.stringify(parsedObj, null, 2)}
|
|
3748
|
+
`;
|
|
3749
|
+
}
|
|
3750
|
+
if (target === "crush") {
|
|
3751
|
+
if (!("$schema" in parsedObj)) {
|
|
3752
|
+
parsedObj.$schema = "https://charm.land/crush.json";
|
|
3753
|
+
}
|
|
3754
|
+
const mcpMap = parsedObj.mcp && typeof parsedObj.mcp === "object" && !Array.isArray(parsedObj.mcp) ? { ...parsedObj.mcp } : {};
|
|
3755
|
+
mcpMap[serverName] = {
|
|
3756
|
+
type: "stdio",
|
|
3757
|
+
command: "npx",
|
|
3758
|
+
args: mcpArgs
|
|
3759
|
+
};
|
|
3760
|
+
parsedObj.mcp = mcpMap;
|
|
3761
|
+
return `${JSON.stringify(parsedObj, null, 2)}
|
|
3613
3762
|
`;
|
|
3614
3763
|
}
|
|
3615
3764
|
const mcpServers = parsedObj.mcpServers && typeof parsedObj.mcpServers === "object" && !Array.isArray(parsedObj.mcpServers) ? { ...parsedObj.mcpServers } : {};
|
|
@@ -3860,6 +4009,24 @@ ${body}
|
|
|
3860
4009
|
${kiroFrontmatter}
|
|
3861
4010
|
---
|
|
3862
4011
|
|
|
4012
|
+
${body}
|
|
4013
|
+
`
|
|
4014
|
+
});
|
|
4015
|
+
return files;
|
|
4016
|
+
}
|
|
4017
|
+
if (target === "augment") {
|
|
4018
|
+
const augFrontmatter = YAML4.stringify({
|
|
4019
|
+
type: "agent_requested",
|
|
4020
|
+
description: parsed.manifest.description
|
|
4021
|
+
}).trim();
|
|
4022
|
+
files.push({
|
|
4023
|
+
target,
|
|
4024
|
+
itemName: name,
|
|
4025
|
+
relativePath: `.augment/rules/skillops-${name}.md`,
|
|
4026
|
+
content: `---
|
|
4027
|
+
${augFrontmatter}
|
|
4028
|
+
---
|
|
4029
|
+
|
|
3863
4030
|
${body}
|
|
3864
4031
|
`
|
|
3865
4032
|
});
|
|
@@ -3893,6 +4060,7 @@ function renderSubagentFilesForRuntime(subagent, target) {
|
|
|
3893
4060
|
const fm = YAML4.stringify({
|
|
3894
4061
|
name: subagent.manifest.name,
|
|
3895
4062
|
description: subagent.manifest.description,
|
|
4063
|
+
model: "inherit",
|
|
3896
4064
|
model_tier: subagent.manifest.model_tier,
|
|
3897
4065
|
tools: subagent.manifest.tools,
|
|
3898
4066
|
max_output_tokens: subagent.manifest.max_output_tokens
|
|
@@ -3903,7 +4071,7 @@ ${fm}
|
|
|
3903
4071
|
|
|
3904
4072
|
${promptBody}
|
|
3905
4073
|
`;
|
|
3906
|
-
if (target === "claude" || target === "antigravity" || target === "codex" || target === "amp" || target === "goose" || target === "opencode") {
|
|
4074
|
+
if (target === "claude" || target === "antigravity" || target === "gemini" || target === "codex" || target === "amp" || target === "goose" || target === "opencode" || target === "qwen" || target === "warp" || target === "crush") {
|
|
3907
4075
|
return [
|
|
3908
4076
|
{
|
|
3909
4077
|
target,
|
|
@@ -3913,6 +4081,44 @@ ${promptBody}
|
|
|
3913
4081
|
}
|
|
3914
4082
|
];
|
|
3915
4083
|
}
|
|
4084
|
+
if (target === "factory") {
|
|
4085
|
+
const droidFm = YAML4.stringify({
|
|
4086
|
+
name,
|
|
4087
|
+
description: subagent.manifest.description,
|
|
4088
|
+
model: "inherit"
|
|
4089
|
+
}).trim();
|
|
4090
|
+
return [
|
|
4091
|
+
{
|
|
4092
|
+
target,
|
|
4093
|
+
itemName: name,
|
|
4094
|
+
relativePath: `.factory/droids/skillops-agent-${name}.md`,
|
|
4095
|
+
content: `---
|
|
4096
|
+
${droidFm}
|
|
4097
|
+
---
|
|
4098
|
+
|
|
4099
|
+
${promptBody}
|
|
4100
|
+
`
|
|
4101
|
+
}
|
|
4102
|
+
];
|
|
4103
|
+
}
|
|
4104
|
+
if (target === "vibe") {
|
|
4105
|
+
const escapedDesc = JSON.stringify(subagent.manifest.description);
|
|
4106
|
+
const escapedPrompt = JSON.stringify(promptBody);
|
|
4107
|
+
const tomlDoc = [
|
|
4108
|
+
`name = "${name}"`,
|
|
4109
|
+
`description = ${escapedDesc}`,
|
|
4110
|
+
`system_prompt = ${escapedPrompt}`,
|
|
4111
|
+
""
|
|
4112
|
+
].join("\n");
|
|
4113
|
+
return [
|
|
4114
|
+
{
|
|
4115
|
+
target,
|
|
4116
|
+
itemName: name,
|
|
4117
|
+
relativePath: `.vibe/agents/skillops-agent-${name}.toml`,
|
|
4118
|
+
content: tomlDoc
|
|
4119
|
+
}
|
|
4120
|
+
];
|
|
4121
|
+
}
|
|
3916
4122
|
if (target === "copilot") {
|
|
3917
4123
|
return [
|
|
3918
4124
|
{
|
|
@@ -4719,8 +4925,8 @@ var COMMAND_HELP_SPECS = [
|
|
|
4719
4925
|
name: "remove",
|
|
4720
4926
|
aliases: ["uninstall", "rm"],
|
|
4721
4927
|
pillar: "library",
|
|
4722
|
-
summary: "Remove
|
|
4723
|
-
usage: "npx skillops-cli remove
|
|
4928
|
+
summary: "Remove imported Skills/Subagents from harnesses",
|
|
4929
|
+
usage: "npx skillops-cli remove [name...] [options]",
|
|
4724
4930
|
options: [
|
|
4725
4931
|
{
|
|
4726
4932
|
flags: "-p, --project <dir>",
|
|
@@ -4730,12 +4936,20 @@ var COMMAND_HELP_SPECS = [
|
|
|
4730
4936
|
flags: "-t, --harness <list>",
|
|
4731
4937
|
description: "Restrict removal to specific harnesses"
|
|
4732
4938
|
},
|
|
4939
|
+
{
|
|
4940
|
+
flags: "--all",
|
|
4941
|
+
description: "Remove all imported Skills & Agents from project"
|
|
4942
|
+
},
|
|
4733
4943
|
{
|
|
4734
4944
|
flags: "--force",
|
|
4735
4945
|
description: "Remove even if SHA-256 drift is detected"
|
|
4736
4946
|
}
|
|
4737
4947
|
],
|
|
4738
4948
|
examples: [
|
|
4949
|
+
{
|
|
4950
|
+
command: "npx skillops-cli remove",
|
|
4951
|
+
description: "Interactive selector of installed Skills & Agents"
|
|
4952
|
+
},
|
|
4739
4953
|
{
|
|
4740
4954
|
command: "npx skillops-cli uninstall mcp-architect",
|
|
4741
4955
|
description: "Remove runtime files & update lockfile"
|
|
@@ -4913,7 +5127,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4913
5127
|
name: "sync",
|
|
4914
5128
|
aliases: [],
|
|
4915
5129
|
pillar: "runtime",
|
|
4916
|
-
summary: "Transpile bundle across
|
|
5130
|
+
summary: "Transpile bundle across 28 AI agents",
|
|
4917
5131
|
usage: "npx skillops-cli sync [options]",
|
|
4918
5132
|
options: [
|
|
4919
5133
|
{
|
|
@@ -4944,7 +5158,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
4944
5158
|
},
|
|
4945
5159
|
{
|
|
4946
5160
|
command: "npx skillops-cli sync --harness all",
|
|
4947
|
-
description: "Transpile across all
|
|
5161
|
+
description: "Transpile across all 28 supported AI agents"
|
|
4948
5162
|
}
|
|
4949
5163
|
]
|
|
4950
5164
|
},
|
|
@@ -5037,7 +5251,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
5037
5251
|
name: "harnesses",
|
|
5038
5252
|
aliases: [],
|
|
5039
5253
|
pillar: "runtime",
|
|
5040
|
-
summary: "List
|
|
5254
|
+
summary: "List 28 supported AI agents & repo status",
|
|
5041
5255
|
usage: "npx skillops-cli harnesses [options]",
|
|
5042
5256
|
options: [
|
|
5043
5257
|
{
|
|
@@ -5052,7 +5266,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
5052
5266
|
examples: [
|
|
5053
5267
|
{
|
|
5054
5268
|
command: "npx skillops-cli harnesses",
|
|
5055
|
-
description: "View all
|
|
5269
|
+
description: "View all 28 supported AI IDEs/CLI agents"
|
|
5056
5270
|
}
|
|
5057
5271
|
]
|
|
5058
5272
|
},
|
|
@@ -5060,7 +5274,7 @@ var COMMAND_HELP_SPECS = [
|
|
|
5060
5274
|
name: "mcp-setup",
|
|
5061
5275
|
aliases: [],
|
|
5062
5276
|
pillar: "runtime",
|
|
5063
|
-
summary: "Wire MCP server across
|
|
5277
|
+
summary: "Wire MCP server across 20 AI IDEs & agents",
|
|
5064
5278
|
usage: "npx skillops-cli mcp-setup [options]",
|
|
5065
5279
|
options: [
|
|
5066
5280
|
{
|
|
@@ -5125,24 +5339,20 @@ function renderGlobalHelp(version, colorEnabled) {
|
|
|
5125
5339
|
desc: "Import Skills or Agents (interactive if no name given)"
|
|
5126
5340
|
},
|
|
5127
5341
|
{
|
|
5128
|
-
cmd: "
|
|
5129
|
-
desc: "
|
|
5342
|
+
cmd: "remove [name...]",
|
|
5343
|
+
desc: "Remove Skills or Agents (interactive if no name given)"
|
|
5130
5344
|
},
|
|
5131
5345
|
{
|
|
5132
5346
|
cmd: "list [query]",
|
|
5133
5347
|
desc: "List or filter available Skills & Agents in catalog"
|
|
5134
5348
|
},
|
|
5135
5349
|
{
|
|
5136
|
-
cmd: "
|
|
5137
|
-
desc: "
|
|
5138
|
-
},
|
|
5139
|
-
{
|
|
5140
|
-
cmd: "remove <name>",
|
|
5141
|
-
desc: "Remove an imported Skill or Agent from your project"
|
|
5350
|
+
cmd: "search <query>",
|
|
5351
|
+
desc: "Search Skills & Agents by keyword, stack, or domain"
|
|
5142
5352
|
},
|
|
5143
5353
|
{
|
|
5144
|
-
cmd: "
|
|
5145
|
-
desc: "
|
|
5354
|
+
cmd: "info <name>",
|
|
5355
|
+
desc: "View details and how to use a Skill or Agent"
|
|
5146
5356
|
}
|
|
5147
5357
|
];
|
|
5148
5358
|
const cmdRows = coreCmds.map(
|
|
@@ -5154,12 +5364,12 @@ function renderGlobalHelp(version, colorEnabled) {
|
|
|
5154
5364
|
renderSectionHeader("Commands", c),
|
|
5155
5365
|
cmdRows,
|
|
5156
5366
|
renderSectionHeader("Options", c),
|
|
5157
|
-
`${bar} ${padVisible(style.cyan("-t, --target <ide>", c), 22, "left")}AI IDE (cursor, claude, copilot,
|
|
5367
|
+
`${bar} ${padVisible(style.cyan("-t, --target <ide>", c), 22, "left")}AI IDE (cursor, claude, copilot, antigravity...)`,
|
|
5158
5368
|
`${bar} ${padVisible(style.cyan("-p, --project <dir>", c), 22, "left")}Project folder (default: current directory)`,
|
|
5159
|
-
`${bar} ${padVisible(style.cyan("--all", c), 22, "left")}Import all
|
|
5369
|
+
`${bar} ${padVisible(style.cyan("--all", c), 22, "left")}Import or remove all Skills & Agents`,
|
|
5160
5370
|
renderSectionHeader("Examples", c),
|
|
5161
|
-
`${bar} ${style.dim("$", c)} ${style.green("skillops add", c)} ${style.dim("\u2014 Interactive
|
|
5162
|
-
`${bar} ${style.dim("$", c)} ${style.green("skillops
|
|
5371
|
+
`${bar} ${style.dim("$", c)} ${style.green("skillops add", c)} ${style.dim("\u2014 Interactive import", c)}`,
|
|
5372
|
+
`${bar} ${style.dim("$", c)} ${style.green("skillops remove", c)} ${style.dim("\u2014 Interactive removal", c)}`,
|
|
5163
5373
|
`${bar} ${style.dim("$", c)} ${style.green("skillops list", c)} ${style.dim("\u2014 Browse catalog", c)}`,
|
|
5164
5374
|
bar,
|
|
5165
5375
|
`${style.dim("\u2570\u2500", c)} ${style.dim("Run", c)} ${style.cyan("skillops <cmd> -h", c)} ${style.dim("for command options.", c)}`
|
|
@@ -5269,6 +5479,12 @@ function applyMultiSelectKey(state, key, options = {}) {
|
|
|
5269
5479
|
}
|
|
5270
5480
|
if (key === "\x1B[D" || key === "\x1BOD" || key === "\x1B[C" || key === "\x1BOC" || key === " " || !state.searchMode && (key === "h" || key === "H" || key === "l" || key === "L")) {
|
|
5271
5481
|
const nextTab = state.activeTab === "skill" ? "agent" : "skill";
|
|
5482
|
+
const hasNextTabOptions = state.options.some(
|
|
5483
|
+
(opt) => optionMatchesTab(opt, nextTab)
|
|
5484
|
+
);
|
|
5485
|
+
if (!hasNextTabOptions) {
|
|
5486
|
+
return state;
|
|
5487
|
+
}
|
|
5272
5488
|
return {
|
|
5273
5489
|
...state,
|
|
5274
5490
|
activeTab: nextTab,
|
|
@@ -5405,8 +5621,10 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5405
5621
|
const skillTabTitle = options.tabLabels?.skill ?? "Skills";
|
|
5406
5622
|
const agentTabTitle = options.tabLabels?.agent ?? "Agents";
|
|
5407
5623
|
const submitVerb = options.submitActionLabel ?? "import";
|
|
5624
|
+
const isSinglePage = totalAgents === 0 || totalSkills === 0;
|
|
5408
5625
|
const header = `${style.bold(style.cyan(`\u25C6 ${title}`, c), c)}`;
|
|
5409
|
-
const
|
|
5626
|
+
const tabHint = isSinglePage ? "" : " \xB7 \u2190/\u2192 tab";
|
|
5627
|
+
const instructions = state.searchMode ? `${bar} ${style.dim(`\u2191/\u2193 move${tabHint} \xB7 Space select \xB7 Esc clear \xB7 Enter ${submitVerb}`, c)}` : `${bar} ${style.dim(`\u2191/\u2193 move${tabHint} \xB7 Space select \xB7 / search \xB7 a all \xB7 Enter ${submitVerb}`, c)}`;
|
|
5410
5628
|
const lines = [header];
|
|
5411
5629
|
if (options.subtitle) {
|
|
5412
5630
|
lines.push(`${bar} ${options.subtitle}`);
|
|
@@ -5415,12 +5633,19 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5415
5633
|
const hasQuery = state.searchQuery.length > 0;
|
|
5416
5634
|
const skillCountStr = hasQuery ? `${filteredSkills.length}/${totalSkills}` : `${totalSkills}`;
|
|
5417
5635
|
const agentCountStr = hasQuery ? `${filteredAgents.length}/${totalAgents}` : `${totalAgents}`;
|
|
5418
|
-
const skillTabLabel = state.activeTab === "skill" ? style.bold(
|
|
5419
|
-
|
|
5636
|
+
const skillTabLabel = state.activeTab === "skill" ? style.bold(
|
|
5637
|
+
style.cyan(`[ \u25C6 ${skillTabTitle} (${skillCountStr}) ]`, c),
|
|
5638
|
+
c
|
|
5639
|
+
) : style.dim(`\u25CB ${skillTabTitle} (${skillCountStr})`, c);
|
|
5640
|
+
const agentTabLabel = state.activeTab === "agent" ? style.bold(
|
|
5641
|
+
style.magenta(`[ \u25C6 ${agentTabTitle} (${agentCountStr}) ]`, c),
|
|
5642
|
+
c
|
|
5643
|
+
) : style.dim(`\u25CB ${agentTabTitle} (${agentCountStr})`, c);
|
|
5420
5644
|
const rawQuerySlice = state.searchQuery.length > 14 ? `\u2026${state.searchQuery.slice(-13)}` : state.searchQuery;
|
|
5421
5645
|
const searchSuffix = state.searchMode || hasQuery ? ` ${style.yellow(`/ Filter: ${rawQuerySlice}${state.searchMode ? "\u2588" : ""}`, c)}` : ` ${style.dim("(/ search)", c)}`;
|
|
5646
|
+
const singleTabLabel = totalSkills > 0 ? skillTabLabel : agentTabLabel;
|
|
5422
5647
|
lines.push(
|
|
5423
|
-
`${style.dim("\u251C\u2500", c)} ${skillTabLabel} ${agentTabLabel}${searchSuffix}`,
|
|
5648
|
+
isSinglePage ? `${style.dim("\u251C\u2500", c)} ${singleTabLabel}${searchSuffix}` : `${style.dim("\u251C\u2500", c)} ${skillTabLabel} ${agentTabLabel}${searchSuffix}`,
|
|
5424
5649
|
bar
|
|
5425
5650
|
);
|
|
5426
5651
|
if (total === 0) {
|
|
@@ -6353,14 +6578,32 @@ function resolveCatalogDir(args, repoPath, loadedConfig) {
|
|
|
6353
6578
|
var POPULAR_AI_ORDER = [
|
|
6354
6579
|
"cursor",
|
|
6355
6580
|
"claude",
|
|
6356
|
-
"antigravity",
|
|
6357
6581
|
"copilot",
|
|
6582
|
+
"antigravity",
|
|
6358
6583
|
"windsurf",
|
|
6359
6584
|
"codex",
|
|
6585
|
+
"gemini",
|
|
6360
6586
|
"cline",
|
|
6361
6587
|
"roocode",
|
|
6362
6588
|
"kilocode",
|
|
6363
|
-
"zed"
|
|
6589
|
+
"zed",
|
|
6590
|
+
"continue",
|
|
6591
|
+
"aider",
|
|
6592
|
+
"kiro",
|
|
6593
|
+
"trae",
|
|
6594
|
+
"augment",
|
|
6595
|
+
"factory",
|
|
6596
|
+
"qwen",
|
|
6597
|
+
"opencode",
|
|
6598
|
+
"openhands",
|
|
6599
|
+
"amp",
|
|
6600
|
+
"goose",
|
|
6601
|
+
"warp",
|
|
6602
|
+
"crush",
|
|
6603
|
+
"vibe",
|
|
6604
|
+
"junie",
|
|
6605
|
+
"amazonq",
|
|
6606
|
+
"idx"
|
|
6364
6607
|
];
|
|
6365
6608
|
function buildInteractiveTargetOptions() {
|
|
6366
6609
|
const popularSet = new Set(POPULAR_AI_ORDER);
|
|
@@ -6368,13 +6611,13 @@ function buildInteractiveTargetOptions() {
|
|
|
6368
6611
|
...POPULAR_AI_ORDER,
|
|
6369
6612
|
...ALL_RUNTIME_TARGETS.filter((t) => !popularSet.has(t))
|
|
6370
6613
|
];
|
|
6371
|
-
return orderedTargets.map((targetId
|
|
6614
|
+
return orderedTargets.map((targetId) => {
|
|
6372
6615
|
const spec = RUNTIME_HARNESS_SPECS[targetId];
|
|
6373
6616
|
return {
|
|
6374
6617
|
value: spec.id,
|
|
6375
6618
|
label: spec.id,
|
|
6376
6619
|
kind: "ide",
|
|
6377
|
-
tab:
|
|
6620
|
+
tab: "skill",
|
|
6378
6621
|
hint: `${spec.displayName} (${spec.skillsDir})`
|
|
6379
6622
|
};
|
|
6380
6623
|
});
|
|
@@ -6414,6 +6657,66 @@ function buildInteractiveCatalogOptions(catalogDir) {
|
|
|
6414
6657
|
}
|
|
6415
6658
|
return options;
|
|
6416
6659
|
}
|
|
6660
|
+
function buildInteractiveInstalledOptions(repoPath, catalogDir, targetFilter) {
|
|
6661
|
+
const lockfilePath = path10.join(path10.resolve(repoPath), ".skillops-lock.json");
|
|
6662
|
+
if (!fs10.existsSync(lockfilePath)) {
|
|
6663
|
+
return [];
|
|
6664
|
+
}
|
|
6665
|
+
let parsedLock;
|
|
6666
|
+
try {
|
|
6667
|
+
const raw = JSON.parse(fs10.readFileSync(lockfilePath, "utf-8"));
|
|
6668
|
+
parsedLock = SyncLockfileSchema.safeParse(raw);
|
|
6669
|
+
} catch {
|
|
6670
|
+
return [];
|
|
6671
|
+
}
|
|
6672
|
+
if (!parsedLock.success) {
|
|
6673
|
+
return [];
|
|
6674
|
+
}
|
|
6675
|
+
const lock = parsedLock.data;
|
|
6676
|
+
const targetSet = targetFilter && targetFilter.length > 0 ? new Set(targetFilter) : null;
|
|
6677
|
+
const targetsByItem = /* @__PURE__ */ new Map();
|
|
6678
|
+
for (const entry of Object.values(lock.artifacts)) {
|
|
6679
|
+
if (entry.skill_name === "codex-agents-index") {
|
|
6680
|
+
continue;
|
|
6681
|
+
}
|
|
6682
|
+
if (targetSet && !targetSet.has(entry.target)) {
|
|
6683
|
+
continue;
|
|
6684
|
+
}
|
|
6685
|
+
let itemTargets = targetsByItem.get(entry.skill_name);
|
|
6686
|
+
if (!itemTargets) {
|
|
6687
|
+
itemTargets = /* @__PURE__ */ new Set();
|
|
6688
|
+
targetsByItem.set(entry.skill_name, itemTargets);
|
|
6689
|
+
}
|
|
6690
|
+
itemTargets.add(entry.target);
|
|
6691
|
+
}
|
|
6692
|
+
if (targetsByItem.size === 0) {
|
|
6693
|
+
return [];
|
|
6694
|
+
}
|
|
6695
|
+
const catalogOptions = buildInteractiveCatalogOptions(catalogDir);
|
|
6696
|
+
const catalogMap = new Map(catalogOptions.map((o) => [o.value, o]));
|
|
6697
|
+
const subagentSet = new Set(lock.selected_subagents);
|
|
6698
|
+
const skills = [];
|
|
6699
|
+
const agents = [];
|
|
6700
|
+
for (const [itemName, itemTargets] of targetsByItem.entries()) {
|
|
6701
|
+
const catalogOpt = catalogMap.get(itemName);
|
|
6702
|
+
const isAgent = catalogOpt ? catalogOpt.kind === "agent" : subagentSet.has(itemName);
|
|
6703
|
+
const targetsLabel = [...itemTargets].join(", ");
|
|
6704
|
+
const baseHint = catalogOpt?.hint ?? "Installed in project";
|
|
6705
|
+
const option = {
|
|
6706
|
+
value: itemName,
|
|
6707
|
+
label: itemName,
|
|
6708
|
+
kind: isAgent ? "agent" : "skill",
|
|
6709
|
+
tab: isAgent ? "agent" : "skill",
|
|
6710
|
+
hint: `[${targetsLabel}] \xB7 ${baseHint}`
|
|
6711
|
+
};
|
|
6712
|
+
if (isAgent) {
|
|
6713
|
+
agents.push(option);
|
|
6714
|
+
} else {
|
|
6715
|
+
skills.push(option);
|
|
6716
|
+
}
|
|
6717
|
+
}
|
|
6718
|
+
return [...skills, ...agents];
|
|
6719
|
+
}
|
|
6417
6720
|
function runCli(argv) {
|
|
6418
6721
|
const args = argv.slice(2);
|
|
6419
6722
|
if (args.includes("--version") || args.includes("-V") || args[0] === "version") {
|
|
@@ -6681,6 +6984,10 @@ function runCli(argv) {
|
|
|
6681
6984
|
(a) => ` [SUBAGENT] ${a.subagentName} (prompt=${a.systemPromptTokens}t, max_out<=${a.maxOutputTokens}t, tools=${a.tools.length})`
|
|
6682
6985
|
),
|
|
6683
6986
|
renderNextSteps([
|
|
6987
|
+
{
|
|
6988
|
+
command: "npx skillops-cli add",
|
|
6989
|
+
description: "Interactive import into your AI IDE"
|
|
6990
|
+
},
|
|
6684
6991
|
{
|
|
6685
6992
|
command: `npx skillops-cli info ${firstSkill}`,
|
|
6686
6993
|
description: "Inspect triggers & usage"
|
|
@@ -6688,10 +6995,6 @@ function runCli(argv) {
|
|
|
6688
6995
|
{
|
|
6689
6996
|
command: "npx skillops-cli search <keyword>",
|
|
6690
6997
|
description: "Search Skills & Subagents"
|
|
6691
|
-
},
|
|
6692
|
-
{
|
|
6693
|
-
command: "npx skillops-cli quickstart",
|
|
6694
|
-
description: "Auto-detect & install"
|
|
6695
6998
|
}
|
|
6696
6999
|
])
|
|
6697
7000
|
];
|
|
@@ -6932,12 +7235,7 @@ function runCli(argv) {
|
|
|
6932
7235
|
}
|
|
6933
7236
|
if (command === "remove" || command === "uninstall" || command === "rm") {
|
|
6934
7237
|
const positionals = getPositionalArgs(args);
|
|
6935
|
-
|
|
6936
|
-
process.stderr.write(
|
|
6937
|
-
"Usage: npx skillops-cli remove <skill-or-subagent-name> [options]\n"
|
|
6938
|
-
);
|
|
6939
|
-
return ExitCode.ERROR;
|
|
6940
|
-
}
|
|
7238
|
+
const removeAll = args.includes("--all");
|
|
6941
7239
|
const repoPath = getFlagValue(args, "--repo", "--project", "-p") ?? process.cwd();
|
|
6942
7240
|
const cfgRes = loadSkillOpsConfig(repoPath);
|
|
6943
7241
|
if (cfgRes.error) {
|
|
@@ -6955,19 +7253,44 @@ function runCli(argv) {
|
|
|
6955
7253
|
const format = rawFormat === "json" || rawFormat === "markdown" ? rawFormat : "table";
|
|
6956
7254
|
try {
|
|
6957
7255
|
const targets = rawTargetsArg ? resolveRuntimeTargets(rawTargetsArg, repoPath) : void 0;
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
const report = removeSkillOrSubagent(repoPath, catalogDir, itemName, {
|
|
6961
|
-
targets,
|
|
7256
|
+
if (removeAll && positionals.length === 0 && !targets) {
|
|
7257
|
+
const report = cleanSyncedArtifacts(repoPath, catalogDir, {
|
|
6962
7258
|
dryRun,
|
|
6963
7259
|
force
|
|
6964
7260
|
});
|
|
6965
7261
|
process.stdout.write(formatSyncReport(report, format));
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
7262
|
+
return report.passed ? ExitCode.SUCCESS : ExitCode.ERROR;
|
|
7263
|
+
}
|
|
7264
|
+
const itemsToRemove = removeAll && positionals.length === 0 ? buildInteractiveInstalledOptions(repoPath, catalogDir, targets).map(
|
|
7265
|
+
(o) => o.value
|
|
7266
|
+
) : positionals;
|
|
7267
|
+
if (itemsToRemove.length === 0) {
|
|
7268
|
+
process.stderr.write(
|
|
7269
|
+
"Usage: npx skillops-cli remove <skill-or-subagent-name> [options]\n"
|
|
7270
|
+
);
|
|
7271
|
+
return ExitCode.ERROR;
|
|
7272
|
+
}
|
|
7273
|
+
const reports = itemsToRemove.map(
|
|
7274
|
+
(itemName) => removeSkillOrSubagent(repoPath, catalogDir, itemName, {
|
|
7275
|
+
targets,
|
|
7276
|
+
dryRun,
|
|
7277
|
+
force
|
|
7278
|
+
})
|
|
7279
|
+
);
|
|
7280
|
+
const firstReport = reports[0];
|
|
7281
|
+
if (!firstReport) {
|
|
7282
|
+
return ExitCode.ERROR;
|
|
6969
7283
|
}
|
|
6970
|
-
|
|
7284
|
+
const finalReport = reports.length === 1 ? firstReport : {
|
|
7285
|
+
...firstReport,
|
|
7286
|
+
artifacts: reports.flatMap((r) => r.artifacts),
|
|
7287
|
+
drift_conflicts: [
|
|
7288
|
+
...new Set(reports.flatMap((r) => r.drift_conflicts))
|
|
7289
|
+
],
|
|
7290
|
+
passed: reports.every((r) => r.passed)
|
|
7291
|
+
};
|
|
7292
|
+
process.stdout.write(formatSyncReport(finalReport, format));
|
|
7293
|
+
return finalReport.passed ? ExitCode.SUCCESS : ExitCode.ERROR;
|
|
6971
7294
|
} catch (err) {
|
|
6972
7295
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6973
7296
|
process.stderr.write(`Error: ${msg}
|
|
@@ -7125,8 +7448,8 @@ async function runCliInteractive(argv) {
|
|
|
7125
7448
|
targetOptions,
|
|
7126
7449
|
{
|
|
7127
7450
|
tabLabels: {
|
|
7128
|
-
skill: "
|
|
7129
|
-
agent: "
|
|
7451
|
+
skill: "AI IDEs & Agents",
|
|
7452
|
+
agent: ""
|
|
7130
7453
|
},
|
|
7131
7454
|
submitActionLabel: "continue",
|
|
7132
7455
|
selectCursorOnEmptySubmit: true
|
|
@@ -7165,6 +7488,57 @@ async function runCliInteractive(argv) {
|
|
|
7165
7488
|
}
|
|
7166
7489
|
return runCli([...argv, ...extraArgs]);
|
|
7167
7490
|
}
|
|
7491
|
+
if ((command === "remove" || command === "uninstall" || command === "rm") && !args.includes("--help") && !args.includes("-h") && !args.includes("--all") && process.stdin.isTTY && process.stdout.isTTY) {
|
|
7492
|
+
const positionals = getPositionalArgs(args);
|
|
7493
|
+
if (positionals.length === 0) {
|
|
7494
|
+
const repoPath = getFlagValue(args, "--repo", "--project", "-p") ?? process.cwd();
|
|
7495
|
+
const cfgRes = loadSkillOpsConfig(repoPath);
|
|
7496
|
+
if (cfgRes.error) {
|
|
7497
|
+
process.stderr.write(
|
|
7498
|
+
`Invalid .skillops.yml at ${cfgRes.configPath}: ${cfgRes.error}
|
|
7499
|
+
`
|
|
7500
|
+
);
|
|
7501
|
+
return ExitCode.BUDGET_OR_CONTRACT_ERROR;
|
|
7502
|
+
}
|
|
7503
|
+
const catalogDir = resolveCatalogDir(args, repoPath, cfgRes.config);
|
|
7504
|
+
const explicitTargetsArg = resolveTargetsArg(args);
|
|
7505
|
+
let targets;
|
|
7506
|
+
if (explicitTargetsArg) {
|
|
7507
|
+
try {
|
|
7508
|
+
targets = resolveRuntimeTargets(explicitTargetsArg, repoPath);
|
|
7509
|
+
} catch (err) {
|
|
7510
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7511
|
+
process.stderr.write(`Invalid --targets: ${msg}
|
|
7512
|
+
`);
|
|
7513
|
+
return ExitCode.BUDGET_OR_CONTRACT_ERROR;
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
const installedOptions = buildInteractiveInstalledOptions(
|
|
7517
|
+
repoPath,
|
|
7518
|
+
catalogDir,
|
|
7519
|
+
targets
|
|
7520
|
+
);
|
|
7521
|
+
if (installedOptions.length === 0) {
|
|
7522
|
+
process.stdout.write(
|
|
7523
|
+
"No imported Skills or Agents found in this project.\n"
|
|
7524
|
+
);
|
|
7525
|
+
return ExitCode.SUCCESS;
|
|
7526
|
+
}
|
|
7527
|
+
const selected = await runMultiSelectPrompt(
|
|
7528
|
+
"SkillOps \u2014 Select Installed Skills & Agents to Remove",
|
|
7529
|
+
installedOptions,
|
|
7530
|
+
{
|
|
7531
|
+
submitActionLabel: "remove",
|
|
7532
|
+
targetHint: targets ? targets.join(", ") : void 0
|
|
7533
|
+
}
|
|
7534
|
+
);
|
|
7535
|
+
if (!selected || selected.length === 0) {
|
|
7536
|
+
process.stdout.write("No Skills or Agents selected for removal.\n");
|
|
7537
|
+
return ExitCode.SUCCESS;
|
|
7538
|
+
}
|
|
7539
|
+
return runCli([...argv, ...selected]);
|
|
7540
|
+
}
|
|
7541
|
+
}
|
|
7168
7542
|
return runCli(argv);
|
|
7169
7543
|
}
|
|
7170
7544
|
function isDirectCliInvocation() {
|
|
@@ -7189,6 +7563,7 @@ if (isDirectCliInvocation()) {
|
|
|
7189
7563
|
}
|
|
7190
7564
|
export {
|
|
7191
7565
|
buildInteractiveCatalogOptions,
|
|
7566
|
+
buildInteractiveInstalledOptions,
|
|
7192
7567
|
buildInteractiveTargetOptions,
|
|
7193
7568
|
runCli,
|
|
7194
7569
|
runCliInteractive
|