skillops-cli 1.3.3 → 1.3.4
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 +98 -22
- package/dist/index.d.ts +13 -3
- package/dist/index.js +27 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SkillOps (`npx skillops-cli@latest`)
|
|
2
2
|
|
|
3
|
-
> **The Zero-API Framework & Benchmark-Verified Library for High-End AI Coding Skills & Context-Isolated Subagents (`v1.3.
|
|
3
|
+
> **The Zero-API Framework & Benchmark-Verified Library for High-End AI Coding Skills & Context-Isolated Subagents (`v1.3.4`)**
|
|
4
4
|
> *Explore, search, inspect, and install benchmark-verified AI Coding Skills and Context-Isolated Subagents in 10 seconds (`npx skillops-cli@latest quickstart`), scaffold and certify your own custom Skills & Subagents (`npx skillops-cli@latest create skill <name>`), enforce Startup Token Tax budgets (`npx skillops-cli@latest budget`), and transpile natively across the Top 20 AI coding agents & IDEs — 100% offline with zero API keys.*
|
|
5
5
|
|
|
6
6
|
[](./AGENTS.md)
|
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.4";
|
|
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]*)$/;
|
|
@@ -5189,6 +5189,9 @@ function renderCommandHelp(spec, version, colorEnabled) {
|
|
|
5189
5189
|
|
|
5190
5190
|
// src/ui/prompt.ts
|
|
5191
5191
|
function optionMatchesTab(opt, tab) {
|
|
5192
|
+
if (opt.tab) {
|
|
5193
|
+
return opt.tab === tab;
|
|
5194
|
+
}
|
|
5192
5195
|
if (opt.kind === "agent") {
|
|
5193
5196
|
return tab === "agent";
|
|
5194
5197
|
}
|
|
@@ -5224,7 +5227,7 @@ function createMultiSelectState(options) {
|
|
|
5224
5227
|
status: "active"
|
|
5225
5228
|
};
|
|
5226
5229
|
}
|
|
5227
|
-
function applyMultiSelectKey(state, key) {
|
|
5230
|
+
function applyMultiSelectKey(state, key, options = {}) {
|
|
5228
5231
|
if (state.status !== "active" || state.options.length === 0) {
|
|
5229
5232
|
return state;
|
|
5230
5233
|
}
|
|
@@ -5249,8 +5252,17 @@ function applyMultiSelectKey(state, key) {
|
|
|
5249
5252
|
};
|
|
5250
5253
|
}
|
|
5251
5254
|
if (key === "\r" || key === "\n") {
|
|
5255
|
+
let finalSelected = state.selected;
|
|
5256
|
+
if (options.selectCursorOnEmptySubmit && state.selected.size === 0) {
|
|
5257
|
+
const visibleOnSubmit = getFilteredTabOptions(state, state.activeTab);
|
|
5258
|
+
const currentOpt = visibleOnSubmit[state.cursor];
|
|
5259
|
+
if (currentOpt) {
|
|
5260
|
+
finalSelected = /* @__PURE__ */ new Set([currentOpt.value]);
|
|
5261
|
+
}
|
|
5262
|
+
}
|
|
5252
5263
|
return {
|
|
5253
5264
|
...state,
|
|
5265
|
+
selected: finalSelected,
|
|
5254
5266
|
searchMode: false,
|
|
5255
5267
|
status: "submitted"
|
|
5256
5268
|
};
|
|
@@ -5390,8 +5402,11 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5390
5402
|
const filteredAgents = getFilteredTabOptions(state, "agent");
|
|
5391
5403
|
const visible = state.activeTab === "skill" ? filteredSkills : filteredAgents;
|
|
5392
5404
|
const total = visible.length;
|
|
5405
|
+
const skillTabTitle = options.tabLabels?.skill ?? "Skills";
|
|
5406
|
+
const agentTabTitle = options.tabLabels?.agent ?? "Agents";
|
|
5407
|
+
const submitVerb = options.submitActionLabel ?? "import";
|
|
5393
5408
|
const header = `${style.bold(style.cyan(`\u25C6 ${title}`, c), c)}`;
|
|
5394
|
-
const instructions = state.searchMode ? `${bar} ${style.dim(
|
|
5409
|
+
const instructions = state.searchMode ? `${bar} ${style.dim(`\u2191/\u2193 move \xB7 \u2190/\u2192 tab \xB7 Space select \xB7 Esc clear \xB7 Enter ${submitVerb}`, c)}` : `${bar} ${style.dim(`\u2191/\u2193 move \xB7 \u2190/\u2192 tab \xB7 Space select \xB7 / search \xB7 a all \xB7 Enter ${submitVerb}`, c)}`;
|
|
5395
5410
|
const lines = [header];
|
|
5396
5411
|
if (options.subtitle) {
|
|
5397
5412
|
lines.push(`${bar} ${options.subtitle}`);
|
|
@@ -5400,8 +5415,8 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5400
5415
|
const hasQuery = state.searchQuery.length > 0;
|
|
5401
5416
|
const skillCountStr = hasQuery ? `${filteredSkills.length}/${totalSkills}` : `${totalSkills}`;
|
|
5402
5417
|
const agentCountStr = hasQuery ? `${filteredAgents.length}/${totalAgents}` : `${totalAgents}`;
|
|
5403
|
-
const skillTabLabel = state.activeTab === "skill" ? style.bold(style.cyan(`[ \u25C6
|
|
5404
|
-
const agentTabLabel = state.activeTab === "agent" ? style.bold(style.magenta(`[ \u25C6
|
|
5418
|
+
const skillTabLabel = state.activeTab === "skill" ? style.bold(style.cyan(`[ \u25C6 ${skillTabTitle} (${skillCountStr}) ]`, c), c) : style.dim(`\u25CB ${skillTabTitle} (${skillCountStr})`, c);
|
|
5419
|
+
const agentTabLabel = state.activeTab === "agent" ? style.bold(style.magenta(`[ \u25C6 ${agentTabTitle} (${agentCountStr}) ]`, c), c) : style.dim(`\u25CB ${agentTabTitle} (${agentCountStr})`, c);
|
|
5405
5420
|
const rawQuerySlice = state.searchQuery.length > 14 ? `\u2026${state.searchQuery.slice(-13)}` : state.searchQuery;
|
|
5406
5421
|
const searchSuffix = state.searchMode || hasQuery ? ` ${style.yellow(`/ Filter: ${rawQuerySlice}${state.searchMode ? "\u2588" : ""}`, c)}` : ` ${style.dim("(/ search)", c)}`;
|
|
5407
5422
|
lines.push(
|
|
@@ -5409,7 +5424,7 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5409
5424
|
bar
|
|
5410
5425
|
);
|
|
5411
5426
|
if (total === 0) {
|
|
5412
|
-
const tabName = state.activeTab === "skill" ?
|
|
5427
|
+
const tabName = state.activeTab === "skill" ? skillTabTitle : agentTabTitle;
|
|
5413
5428
|
lines.push(
|
|
5414
5429
|
`${bar} ${style.dim(`No ${tabName} match "${state.searchQuery}". Press Esc to clear filter.`, c)}`
|
|
5415
5430
|
);
|
|
@@ -5457,12 +5472,13 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5457
5472
|
const selectedAgentsCount = state.options.filter(
|
|
5458
5473
|
(o) => optionMatchesTab(o, "agent") && state.selected.has(o.value)
|
|
5459
5474
|
).length;
|
|
5460
|
-
const
|
|
5475
|
+
const currentOptLabel = visible[state.cursor]?.label ?? "";
|
|
5476
|
+
const summaryText = options.tabLabels ? state.selected.size > 0 ? `${state.selected.size} selected` : options.selectCursorOnEmptySubmit && currentOptLabel ? `Target: ${currentOptLabel}` : "0 selected" : `${state.selected.size} selected (${selectedSkillsCount} ${skillTabTitle}, ${selectedAgentsCount} ${agentTabTitle})`;
|
|
5461
5477
|
const rawTarget = options.targetHint ?? "";
|
|
5462
5478
|
const shortTarget = rawTarget.length > 18 ? `${rawTarget.slice(0, 17)}\u2026` : rawTarget;
|
|
5463
5479
|
const targetSuffix = shortTarget ? ` \xB7 IDE: ${shortTarget}` : "";
|
|
5464
5480
|
lines.push(
|
|
5465
|
-
`${style.dim("\u2570\u2500", c)} ${style.bold(summaryText, c)}${style.dim(`${targetSuffix} \u2014 Enter to
|
|
5481
|
+
`${style.dim("\u2570\u2500", c)} ${style.bold(summaryText, c)}${style.dim(`${targetSuffix} \u2014 Enter to ${submitVerb}`, c)}`
|
|
5466
5482
|
);
|
|
5467
5483
|
return lines.join("\n");
|
|
5468
5484
|
}
|
|
@@ -5499,7 +5515,9 @@ async function runMultiSelectPrompt(title, options, renderOpts = {}) {
|
|
|
5499
5515
|
};
|
|
5500
5516
|
const onData = (chunk) => {
|
|
5501
5517
|
const key = typeof chunk === "string" ? chunk : chunk.toString("utf-8");
|
|
5502
|
-
state = applyMultiSelectKey(state, key
|
|
5518
|
+
state = applyMultiSelectKey(state, key, {
|
|
5519
|
+
selectCursorOnEmptySubmit: renderOpts.selectCursorOnEmptySubmit
|
|
5520
|
+
});
|
|
5503
5521
|
if (state.status === "cancelled") {
|
|
5504
5522
|
if (renderedLineCount > 0) {
|
|
5505
5523
|
process.stdout.write(`\x1B[${renderedLineCount}A\x1B[J`);
|
|
@@ -6332,6 +6350,35 @@ function resolveCatalogDir(args, repoPath, loadedConfig) {
|
|
|
6332
6350
|
}
|
|
6333
6351
|
return path10.join(PACKAGE_ROOT, "catalog");
|
|
6334
6352
|
}
|
|
6353
|
+
var POPULAR_AI_ORDER = [
|
|
6354
|
+
"cursor",
|
|
6355
|
+
"claude",
|
|
6356
|
+
"antigravity",
|
|
6357
|
+
"copilot",
|
|
6358
|
+
"windsurf",
|
|
6359
|
+
"codex",
|
|
6360
|
+
"cline",
|
|
6361
|
+
"roocode",
|
|
6362
|
+
"kilocode",
|
|
6363
|
+
"zed"
|
|
6364
|
+
];
|
|
6365
|
+
function buildInteractiveTargetOptions() {
|
|
6366
|
+
const popularSet = new Set(POPULAR_AI_ORDER);
|
|
6367
|
+
const orderedTargets = [
|
|
6368
|
+
...POPULAR_AI_ORDER,
|
|
6369
|
+
...ALL_RUNTIME_TARGETS.filter((t) => !popularSet.has(t))
|
|
6370
|
+
];
|
|
6371
|
+
return orderedTargets.map((targetId, index) => {
|
|
6372
|
+
const spec = RUNTIME_HARNESS_SPECS[targetId];
|
|
6373
|
+
return {
|
|
6374
|
+
value: spec.id,
|
|
6375
|
+
label: spec.id,
|
|
6376
|
+
kind: "ide",
|
|
6377
|
+
tab: index < 10 ? "skill" : "agent",
|
|
6378
|
+
hint: `${spec.displayName} (${spec.skillsDir})`
|
|
6379
|
+
};
|
|
6380
|
+
});
|
|
6381
|
+
}
|
|
6335
6382
|
function buildInteractiveCatalogOptions(catalogDir) {
|
|
6336
6383
|
const options = [];
|
|
6337
6384
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -7055,7 +7102,7 @@ function runCli(argv) {
|
|
|
7055
7102
|
async function runCliInteractive(argv) {
|
|
7056
7103
|
const args = argv.slice(2);
|
|
7057
7104
|
const command = args[0];
|
|
7058
|
-
if (command === "add" && !args.includes("--help") && !args.includes("-h") &&
|
|
7105
|
+
if (command === "add" && !args.includes("--help") && !args.includes("-h") && process.stdin.isTTY && process.stdout.isTTY) {
|
|
7059
7106
|
const repoPath = getFlagValue(args, "--repo", "--project", "-p") ?? process.cwd();
|
|
7060
7107
|
const cfgRes = loadSkillOpsConfig(repoPath);
|
|
7061
7108
|
if (cfgRes.error) {
|
|
@@ -7066,29 +7113,57 @@ async function runCliInteractive(argv) {
|
|
|
7066
7113
|
return ExitCode.BUDGET_OR_CONTRACT_ERROR;
|
|
7067
7114
|
}
|
|
7068
7115
|
const catalogDir = resolveCatalogDir(args, repoPath, cfgRes.config);
|
|
7069
|
-
const
|
|
7116
|
+
const explicitTargetsArg = resolveTargetsArg(args);
|
|
7117
|
+
const positionals = getPositionalArgs(args);
|
|
7118
|
+
const needsCatalogPrompt = !args.includes("--all") && positionals.length === 0;
|
|
7119
|
+
let resolvedTargetsArg = explicitTargetsArg;
|
|
7120
|
+
if (!resolvedTargetsArg) {
|
|
7121
|
+
const targetOptions = buildInteractiveTargetOptions();
|
|
7122
|
+
const step1Title = needsCatalogPrompt ? "SkillOps \u2014 Step 1/2: Select Your AI IDE / Agent" : "SkillOps \u2014 Select Your AI IDE / Agent";
|
|
7123
|
+
const selectedTargets = await runMultiSelectPrompt(
|
|
7124
|
+
step1Title,
|
|
7125
|
+
targetOptions,
|
|
7126
|
+
{
|
|
7127
|
+
tabLabels: {
|
|
7128
|
+
skill: "Popular AIs",
|
|
7129
|
+
agent: "More AIs"
|
|
7130
|
+
},
|
|
7131
|
+
submitActionLabel: "continue",
|
|
7132
|
+
selectCursorOnEmptySubmit: true
|
|
7133
|
+
}
|
|
7134
|
+
);
|
|
7135
|
+
if (!selectedTargets || selectedTargets.length === 0) {
|
|
7136
|
+
process.stdout.write("No AI IDE selected.\n");
|
|
7137
|
+
return ExitCode.SUCCESS;
|
|
7138
|
+
}
|
|
7139
|
+
resolvedTargetsArg = selectedTargets.join(",");
|
|
7140
|
+
}
|
|
7070
7141
|
let targets;
|
|
7071
7142
|
try {
|
|
7072
|
-
targets =
|
|
7143
|
+
targets = resolveRuntimeTargets(resolvedTargetsArg, repoPath);
|
|
7073
7144
|
} catch (err) {
|
|
7074
7145
|
const msg = err instanceof Error ? err.message : String(err);
|
|
7075
7146
|
process.stderr.write(`Invalid --targets: ${msg}
|
|
7076
7147
|
`);
|
|
7077
7148
|
return ExitCode.BUDGET_OR_CONTRACT_ERROR;
|
|
7078
7149
|
}
|
|
7079
|
-
const
|
|
7080
|
-
|
|
7081
|
-
"
|
|
7082
|
-
|
|
7083
|
-
|
|
7150
|
+
const extraArgs = [];
|
|
7151
|
+
if (!explicitTargetsArg) {
|
|
7152
|
+
extraArgs.push("-t", targets.join(","));
|
|
7153
|
+
}
|
|
7154
|
+
if (needsCatalogPrompt) {
|
|
7155
|
+
const options = buildInteractiveCatalogOptions(catalogDir);
|
|
7156
|
+
const step2Title = !explicitTargetsArg ? "SkillOps \u2014 Step 2/2: Select Skills & Agents to Import" : "SkillOps \u2014 Select Skills & Agents to Import";
|
|
7157
|
+
const selected = await runMultiSelectPrompt(step2Title, options, {
|
|
7084
7158
|
targetHint: targets.join(", ")
|
|
7159
|
+
});
|
|
7160
|
+
if (!selected || selected.length === 0) {
|
|
7161
|
+
process.stdout.write("No Skills or Agents selected.\n");
|
|
7162
|
+
return ExitCode.SUCCESS;
|
|
7085
7163
|
}
|
|
7086
|
-
|
|
7087
|
-
if (!selected || selected.length === 0) {
|
|
7088
|
-
process.stdout.write("No Skills or Agents selected.\n");
|
|
7089
|
-
return ExitCode.SUCCESS;
|
|
7164
|
+
extraArgs.push(...selected);
|
|
7090
7165
|
}
|
|
7091
|
-
return runCli([...argv, ...
|
|
7166
|
+
return runCli([...argv, ...extraArgs]);
|
|
7092
7167
|
}
|
|
7093
7168
|
return runCli(argv);
|
|
7094
7169
|
}
|
|
@@ -7114,6 +7189,7 @@ if (isDirectCliInvocation()) {
|
|
|
7114
7189
|
}
|
|
7115
7190
|
export {
|
|
7116
7191
|
buildInteractiveCatalogOptions,
|
|
7192
|
+
buildInteractiveTargetOptions,
|
|
7117
7193
|
runCli,
|
|
7118
7194
|
runCliInteractive
|
|
7119
7195
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { z } from 'zod';
|
|
|
8
8
|
* telemetry and Multi-Runtime Transpilation lockfiles.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
declare const SKILLOPS_VERSION = "1.3.
|
|
11
|
+
declare const SKILLOPS_VERSION = "1.3.4";
|
|
12
12
|
/**
|
|
13
13
|
* Count whitespace-delimited words in text.
|
|
14
14
|
*/
|
|
@@ -2187,6 +2187,7 @@ interface MultiSelectOption {
|
|
|
2187
2187
|
readonly value: string;
|
|
2188
2188
|
readonly label: string;
|
|
2189
2189
|
readonly kind?: "skill" | "agent" | "ide";
|
|
2190
|
+
readonly tab?: MultiSelectTab;
|
|
2190
2191
|
readonly hint?: string;
|
|
2191
2192
|
readonly initialSelected?: boolean;
|
|
2192
2193
|
}
|
|
@@ -2199,9 +2200,18 @@ interface MultiSelectState {
|
|
|
2199
2200
|
readonly searchQuery: string;
|
|
2200
2201
|
readonly status: "active" | "submitted" | "cancelled";
|
|
2201
2202
|
}
|
|
2203
|
+
interface ApplyMultiSelectKeyOptions {
|
|
2204
|
+
readonly selectCursorOnEmptySubmit?: boolean;
|
|
2205
|
+
}
|
|
2202
2206
|
interface RenderMultiSelectOptions {
|
|
2203
2207
|
readonly subtitle?: string;
|
|
2204
2208
|
readonly targetHint?: string;
|
|
2209
|
+
readonly tabLabels?: {
|
|
2210
|
+
readonly skill: string;
|
|
2211
|
+
readonly agent: string;
|
|
2212
|
+
};
|
|
2213
|
+
readonly submitActionLabel?: string;
|
|
2214
|
+
readonly selectCursorOnEmptySubmit?: boolean;
|
|
2205
2215
|
readonly maxVisible?: number;
|
|
2206
2216
|
readonly colorEnabled?: boolean;
|
|
2207
2217
|
}
|
|
@@ -2216,7 +2226,7 @@ declare function createMultiSelectState(options: readonly MultiSelectOption[]):
|
|
|
2216
2226
|
/**
|
|
2217
2227
|
* Pure state reducer for keyboard input in the tabbed + searchable multi-select TUI.
|
|
2218
2228
|
*/
|
|
2219
|
-
declare function applyMultiSelectKey(state: MultiSelectState, key: string): MultiSelectState;
|
|
2229
|
+
declare function applyMultiSelectKey(state: MultiSelectState, key: string, options?: ApplyMultiSelectKeyOptions): MultiSelectState;
|
|
2220
2230
|
/**
|
|
2221
2231
|
* Render a single frame of the tabbed + searchable multi-select tree prompt (guaranteed <= 78 columns).
|
|
2222
2232
|
*/
|
|
@@ -2346,4 +2356,4 @@ declare const DEFAULT_VALID_COMMANDS: readonly string[];
|
|
|
2346
2356
|
*/
|
|
2347
2357
|
declare function suggestCommand(unknownCommand: string, validCommands?: readonly string[]): string | null;
|
|
2348
2358
|
|
|
2349
|
-
export { ALL_RUNTIME_TARGETS, type AddOptions, type AnalyzeTokenEconomyOptions, type AuditCatalogOptions, type BadgeType, type BenchmarkArm, BenchmarkArmSchema, type BenchmarkDelta, BenchmarkDeltaSchema, type BoxOptions, COMMAND_HELP_SPECS, CORE_RUNTIME_TARGETS, type CatalogEvalSummary, CatalogEvalSummarySchema, type CatalogItemInfo, type CatalogSearchMatch, type CatalogSearchReport, type CatalogTokenBudgetSummary, type CatalogTrack, CatalogTrackSchema, type CleanOptions, type CollisionPair, CollisionPairSchema, type CollisionReport, CollisionReportSchema, type CollisionSeverity, CollisionSeveritySchema, type ColorOverrideOptions, type CommandHelpSpec, type CommandOptionSpec, DEFAULT_VALID_COMMANDS, type DiagnoseRepositoryOptions, type DoctorCheckItem, type DoctorReport, type EvalAssertion, EvalAssertionSchema, type EvalCase, EvalCaseSchema, ExitCode, type ExitCodeValue, type HarnessCategory, type HarnessInspectionEntry, type HarnessInspectionReport, type HarnessSkillFormat, type JsonRpcRequest, type JsonRpcResponse, type LoadedSkillOpsConfigResult, type LockfileArtifactDiagnostic, type McpConfigAction, type McpServerContext, type McpSetupOptions, type McpSetupReport, type MultiSelectOption, type MultiSelectState, type MultiSelectTab, type NextStepHint, type ParseSkillOptions, type ParsedSkillDirectory, type ParsedSubagentFile, type QuickstartOptions, type QuickstartReport, RUNTIME_HARNESS_SPECS, type RemoveOptions, type RenderMultiSelectOptions, RepoFingerprinter, type RepoProfile, RepoProfileSchema, type RouteOptions, type RoutedBundle, RoutedBundleSchema, type RoutingSignals, RoutingSignalsSchema, type RuntimeHarnessSpec, type RuntimeTarget, RuntimeTargetSchema, SKILLOPS_VERSION, type ScaffoldOptions, type ScaffoldResult, type ScoredSkill, ScoredSkillSchema, type ScriptEntrypoint, ScriptEntrypointSchema, type SkillBenchmark, SkillBenchmarkSchema, type SkillEntrypoints, SkillEntrypointsSchema, type SkillEvalSuite, SkillEvalSuiteSchema, type SkillManifest, type SkillManifestInput, SkillManifestSchema, type SkillOpsConfig, SkillOpsConfigSchema, type SkillOpsDetectedStackConfig, SkillOpsDetectedStackConfigSchema, type SkillOpsTokenEconomyConfig, SkillOpsTokenEconomyConfigSchema, type SkillTokenBudgetAudit, type SkippedSkill, SkippedSkillSchema, type SubagentManifest, SubagentManifestSchema, type SubagentTokenBudgetAudit, type SyncLockEntry, SyncLockEntrySchema, type SyncLockfile, SyncLockfileSchema, type SyncOptions, type SyncReport, SyncReportSchema, type SyncedArtifact, SyncedArtifactSchema, type TableOptions, type TokenBarOptions, type TokenEconomyReport, TokenEconomyReportSchema, type TokenFileCategory, TokenFileCategorySchema, type TokenFileEntry, TokenFileEntrySchema, type TokenWasteHotspot, TokenWasteHotspotSchema, addSkillOrSubagent, analyzeRepoTokenEconomy, applyMultiSelectKey, auditCatalog, auditCatalogTokenBudgets, auditSkillTokenBudget, auditSubagentTokenBudget, classifyCollisionSeverity, cleanSyncedArtifacts, compileSkillBundle, computeCollisionMatrix, computeFeatureCosine, computeIdfWeights, computeSha256, countWords, createCollisionPair, createCollisionReport, createMultiSelectState, createSkillManifest, createSubagentManifest, detectInstalledHarnesses, diagnoseRepository, discoverSkillDirectories, discoverSubagentFiles, estimateTokenCount, evaluateCatalog, evaluateSkillDirectory, extractSkillFeatures, findCommandHelpSpec, fingerprintRepository, formatBadge, formatCatalogItemInfo, formatCatalogSearchReport, formatDoctorReport, formatEvalSummary, formatHarnessInspectionReport, formatMcpSetupReport, formatQuickstartReport, formatRoutedBundle, formatScaffoldReport, formatSyncReport, formatTokenEconomyReport, getFilteredTabOptions, handleMcpJsonRpcRequest, inspectCatalogItem, inspectHarnesses, isColorEnabled, levenshteinDistance, loadSkillOpsConfig, normalizePackageName, padVisible, parseSkillDirectory, parseSkillMdFile, parseSubagentFile, parseSubagentMdFile, removeSkillOrSubagent, renderAiUsageGuide, renderBox, renderCodexAgentsIndex, renderCommandHelp, renderGlobalHelp, renderHeaderBanner, renderMultiSelectFrame, renderNextSteps, renderProgressBar, renderSectionHeader, renderStep, renderTable, renderTokenBar, resolveRuntimeTargets, routeRepository, runMultiSelectPrompt, runQuickstart, scaffoldFrameworkItem, scoreSkillAgainstProfile, searchCatalog, setupMcpForHarnesses, splitFrontmatter, startMcpStdioServer, stripAnsi, stripCodexAgentsBlock, stripNegativeTriggerClauses, style, suggestCommand, syncRepository, tokenizeRoutingText, visibleLength };
|
|
2359
|
+
export { ALL_RUNTIME_TARGETS, type AddOptions, type AnalyzeTokenEconomyOptions, type ApplyMultiSelectKeyOptions, type AuditCatalogOptions, type BadgeType, type BenchmarkArm, BenchmarkArmSchema, type BenchmarkDelta, BenchmarkDeltaSchema, type BoxOptions, COMMAND_HELP_SPECS, CORE_RUNTIME_TARGETS, type CatalogEvalSummary, CatalogEvalSummarySchema, type CatalogItemInfo, type CatalogSearchMatch, type CatalogSearchReport, type CatalogTokenBudgetSummary, type CatalogTrack, CatalogTrackSchema, type CleanOptions, type CollisionPair, CollisionPairSchema, type CollisionReport, CollisionReportSchema, type CollisionSeverity, CollisionSeveritySchema, type ColorOverrideOptions, type CommandHelpSpec, type CommandOptionSpec, DEFAULT_VALID_COMMANDS, type DiagnoseRepositoryOptions, type DoctorCheckItem, type DoctorReport, type EvalAssertion, EvalAssertionSchema, type EvalCase, EvalCaseSchema, ExitCode, type ExitCodeValue, type HarnessCategory, type HarnessInspectionEntry, type HarnessInspectionReport, type HarnessSkillFormat, type JsonRpcRequest, type JsonRpcResponse, type LoadedSkillOpsConfigResult, type LockfileArtifactDiagnostic, type McpConfigAction, type McpServerContext, type McpSetupOptions, type McpSetupReport, type MultiSelectOption, type MultiSelectState, type MultiSelectTab, type NextStepHint, type ParseSkillOptions, type ParsedSkillDirectory, type ParsedSubagentFile, type QuickstartOptions, type QuickstartReport, RUNTIME_HARNESS_SPECS, type RemoveOptions, type RenderMultiSelectOptions, RepoFingerprinter, type RepoProfile, RepoProfileSchema, type RouteOptions, type RoutedBundle, RoutedBundleSchema, type RoutingSignals, RoutingSignalsSchema, type RuntimeHarnessSpec, type RuntimeTarget, RuntimeTargetSchema, SKILLOPS_VERSION, type ScaffoldOptions, type ScaffoldResult, type ScoredSkill, ScoredSkillSchema, type ScriptEntrypoint, ScriptEntrypointSchema, type SkillBenchmark, SkillBenchmarkSchema, type SkillEntrypoints, SkillEntrypointsSchema, type SkillEvalSuite, SkillEvalSuiteSchema, type SkillManifest, type SkillManifestInput, SkillManifestSchema, type SkillOpsConfig, SkillOpsConfigSchema, type SkillOpsDetectedStackConfig, SkillOpsDetectedStackConfigSchema, type SkillOpsTokenEconomyConfig, SkillOpsTokenEconomyConfigSchema, type SkillTokenBudgetAudit, type SkippedSkill, SkippedSkillSchema, type SubagentManifest, SubagentManifestSchema, type SubagentTokenBudgetAudit, type SyncLockEntry, SyncLockEntrySchema, type SyncLockfile, SyncLockfileSchema, type SyncOptions, type SyncReport, SyncReportSchema, type SyncedArtifact, SyncedArtifactSchema, type TableOptions, type TokenBarOptions, type TokenEconomyReport, TokenEconomyReportSchema, type TokenFileCategory, TokenFileCategorySchema, type TokenFileEntry, TokenFileEntrySchema, type TokenWasteHotspot, TokenWasteHotspotSchema, addSkillOrSubagent, analyzeRepoTokenEconomy, applyMultiSelectKey, auditCatalog, auditCatalogTokenBudgets, auditSkillTokenBudget, auditSubagentTokenBudget, classifyCollisionSeverity, cleanSyncedArtifacts, compileSkillBundle, computeCollisionMatrix, computeFeatureCosine, computeIdfWeights, computeSha256, countWords, createCollisionPair, createCollisionReport, createMultiSelectState, createSkillManifest, createSubagentManifest, detectInstalledHarnesses, diagnoseRepository, discoverSkillDirectories, discoverSubagentFiles, estimateTokenCount, evaluateCatalog, evaluateSkillDirectory, extractSkillFeatures, findCommandHelpSpec, fingerprintRepository, formatBadge, formatCatalogItemInfo, formatCatalogSearchReport, formatDoctorReport, formatEvalSummary, formatHarnessInspectionReport, formatMcpSetupReport, formatQuickstartReport, formatRoutedBundle, formatScaffoldReport, formatSyncReport, formatTokenEconomyReport, getFilteredTabOptions, handleMcpJsonRpcRequest, inspectCatalogItem, inspectHarnesses, isColorEnabled, levenshteinDistance, loadSkillOpsConfig, normalizePackageName, padVisible, parseSkillDirectory, parseSkillMdFile, parseSubagentFile, parseSubagentMdFile, removeSkillOrSubagent, renderAiUsageGuide, renderBox, renderCodexAgentsIndex, renderCommandHelp, renderGlobalHelp, renderHeaderBanner, renderMultiSelectFrame, renderNextSteps, renderProgressBar, renderSectionHeader, renderStep, renderTable, renderTokenBar, resolveRuntimeTargets, routeRepository, runMultiSelectPrompt, runQuickstart, scaffoldFrameworkItem, scoreSkillAgainstProfile, searchCatalog, setupMcpForHarnesses, splitFrontmatter, startMcpStdioServer, stripAnsi, stripCodexAgentsBlock, stripNegativeTriggerClauses, style, suggestCommand, syncRepository, tokenizeRoutingText, visibleLength };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import YAML from "yaml";
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
var SKILLOPS_VERSION = "1.3.
|
|
5
|
+
var SKILLOPS_VERSION = "1.3.4";
|
|
6
6
|
var SKILL_NAME_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
7
7
|
var SEMVER_REGEX = /^\d+\.\d+\.\d+$/;
|
|
8
8
|
var FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
@@ -5207,6 +5207,9 @@ function renderCommandHelp(spec, version, colorEnabled) {
|
|
|
5207
5207
|
|
|
5208
5208
|
// src/ui/prompt.ts
|
|
5209
5209
|
function optionMatchesTab(opt, tab) {
|
|
5210
|
+
if (opt.tab) {
|
|
5211
|
+
return opt.tab === tab;
|
|
5212
|
+
}
|
|
5210
5213
|
if (opt.kind === "agent") {
|
|
5211
5214
|
return tab === "agent";
|
|
5212
5215
|
}
|
|
@@ -5242,7 +5245,7 @@ function createMultiSelectState(options) {
|
|
|
5242
5245
|
status: "active"
|
|
5243
5246
|
};
|
|
5244
5247
|
}
|
|
5245
|
-
function applyMultiSelectKey(state, key) {
|
|
5248
|
+
function applyMultiSelectKey(state, key, options = {}) {
|
|
5246
5249
|
if (state.status !== "active" || state.options.length === 0) {
|
|
5247
5250
|
return state;
|
|
5248
5251
|
}
|
|
@@ -5267,8 +5270,17 @@ function applyMultiSelectKey(state, key) {
|
|
|
5267
5270
|
};
|
|
5268
5271
|
}
|
|
5269
5272
|
if (key === "\r" || key === "\n") {
|
|
5273
|
+
let finalSelected = state.selected;
|
|
5274
|
+
if (options.selectCursorOnEmptySubmit && state.selected.size === 0) {
|
|
5275
|
+
const visibleOnSubmit = getFilteredTabOptions(state, state.activeTab);
|
|
5276
|
+
const currentOpt = visibleOnSubmit[state.cursor];
|
|
5277
|
+
if (currentOpt) {
|
|
5278
|
+
finalSelected = /* @__PURE__ */ new Set([currentOpt.value]);
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
5270
5281
|
return {
|
|
5271
5282
|
...state,
|
|
5283
|
+
selected: finalSelected,
|
|
5272
5284
|
searchMode: false,
|
|
5273
5285
|
status: "submitted"
|
|
5274
5286
|
};
|
|
@@ -5408,8 +5420,11 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5408
5420
|
const filteredAgents = getFilteredTabOptions(state, "agent");
|
|
5409
5421
|
const visible = state.activeTab === "skill" ? filteredSkills : filteredAgents;
|
|
5410
5422
|
const total = visible.length;
|
|
5423
|
+
const skillTabTitle = options.tabLabels?.skill ?? "Skills";
|
|
5424
|
+
const agentTabTitle = options.tabLabels?.agent ?? "Agents";
|
|
5425
|
+
const submitVerb = options.submitActionLabel ?? "import";
|
|
5411
5426
|
const header = `${style.bold(style.cyan(`\u25C6 ${title}`, c), c)}`;
|
|
5412
|
-
const instructions = state.searchMode ? `${bar} ${style.dim(
|
|
5427
|
+
const instructions = state.searchMode ? `${bar} ${style.dim(`\u2191/\u2193 move \xB7 \u2190/\u2192 tab \xB7 Space select \xB7 Esc clear \xB7 Enter ${submitVerb}`, c)}` : `${bar} ${style.dim(`\u2191/\u2193 move \xB7 \u2190/\u2192 tab \xB7 Space select \xB7 / search \xB7 a all \xB7 Enter ${submitVerb}`, c)}`;
|
|
5413
5428
|
const lines = [header];
|
|
5414
5429
|
if (options.subtitle) {
|
|
5415
5430
|
lines.push(`${bar} ${options.subtitle}`);
|
|
@@ -5418,8 +5433,8 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5418
5433
|
const hasQuery = state.searchQuery.length > 0;
|
|
5419
5434
|
const skillCountStr = hasQuery ? `${filteredSkills.length}/${totalSkills}` : `${totalSkills}`;
|
|
5420
5435
|
const agentCountStr = hasQuery ? `${filteredAgents.length}/${totalAgents}` : `${totalAgents}`;
|
|
5421
|
-
const skillTabLabel = state.activeTab === "skill" ? style.bold(style.cyan(`[ \u25C6
|
|
5422
|
-
const agentTabLabel = state.activeTab === "agent" ? style.bold(style.magenta(`[ \u25C6
|
|
5436
|
+
const skillTabLabel = state.activeTab === "skill" ? style.bold(style.cyan(`[ \u25C6 ${skillTabTitle} (${skillCountStr}) ]`, c), c) : style.dim(`\u25CB ${skillTabTitle} (${skillCountStr})`, c);
|
|
5437
|
+
const agentTabLabel = state.activeTab === "agent" ? style.bold(style.magenta(`[ \u25C6 ${agentTabTitle} (${agentCountStr}) ]`, c), c) : style.dim(`\u25CB ${agentTabTitle} (${agentCountStr})`, c);
|
|
5423
5438
|
const rawQuerySlice = state.searchQuery.length > 14 ? `\u2026${state.searchQuery.slice(-13)}` : state.searchQuery;
|
|
5424
5439
|
const searchSuffix = state.searchMode || hasQuery ? ` ${style.yellow(`/ Filter: ${rawQuerySlice}${state.searchMode ? "\u2588" : ""}`, c)}` : ` ${style.dim("(/ search)", c)}`;
|
|
5425
5440
|
lines.push(
|
|
@@ -5427,7 +5442,7 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5427
5442
|
bar
|
|
5428
5443
|
);
|
|
5429
5444
|
if (total === 0) {
|
|
5430
|
-
const tabName = state.activeTab === "skill" ?
|
|
5445
|
+
const tabName = state.activeTab === "skill" ? skillTabTitle : agentTabTitle;
|
|
5431
5446
|
lines.push(
|
|
5432
5447
|
`${bar} ${style.dim(`No ${tabName} match "${state.searchQuery}". Press Esc to clear filter.`, c)}`
|
|
5433
5448
|
);
|
|
@@ -5475,12 +5490,13 @@ function renderMultiSelectFrame(title, state, options = {}) {
|
|
|
5475
5490
|
const selectedAgentsCount = state.options.filter(
|
|
5476
5491
|
(o) => optionMatchesTab(o, "agent") && state.selected.has(o.value)
|
|
5477
5492
|
).length;
|
|
5478
|
-
const
|
|
5493
|
+
const currentOptLabel = visible[state.cursor]?.label ?? "";
|
|
5494
|
+
const summaryText = options.tabLabels ? state.selected.size > 0 ? `${state.selected.size} selected` : options.selectCursorOnEmptySubmit && currentOptLabel ? `Target: ${currentOptLabel}` : "0 selected" : `${state.selected.size} selected (${selectedSkillsCount} ${skillTabTitle}, ${selectedAgentsCount} ${agentTabTitle})`;
|
|
5479
5495
|
const rawTarget = options.targetHint ?? "";
|
|
5480
5496
|
const shortTarget = rawTarget.length > 18 ? `${rawTarget.slice(0, 17)}\u2026` : rawTarget;
|
|
5481
5497
|
const targetSuffix = shortTarget ? ` \xB7 IDE: ${shortTarget}` : "";
|
|
5482
5498
|
lines.push(
|
|
5483
|
-
`${style.dim("\u2570\u2500", c)} ${style.bold(summaryText, c)}${style.dim(`${targetSuffix} \u2014 Enter to
|
|
5499
|
+
`${style.dim("\u2570\u2500", c)} ${style.bold(summaryText, c)}${style.dim(`${targetSuffix} \u2014 Enter to ${submitVerb}`, c)}`
|
|
5484
5500
|
);
|
|
5485
5501
|
return lines.join("\n");
|
|
5486
5502
|
}
|
|
@@ -5517,7 +5533,9 @@ async function runMultiSelectPrompt(title, options, renderOpts = {}) {
|
|
|
5517
5533
|
};
|
|
5518
5534
|
const onData = (chunk) => {
|
|
5519
5535
|
const key = typeof chunk === "string" ? chunk : chunk.toString("utf-8");
|
|
5520
|
-
state = applyMultiSelectKey(state, key
|
|
5536
|
+
state = applyMultiSelectKey(state, key, {
|
|
5537
|
+
selectCursorOnEmptySubmit: renderOpts.selectCursorOnEmptySubmit
|
|
5538
|
+
});
|
|
5521
5539
|
if (state.status === "cancelled") {
|
|
5522
5540
|
if (renderedLineCount > 0) {
|
|
5523
5541
|
process.stdout.write(`\x1B[${renderedLineCount}A\x1B[J`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillops-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "SkillOps — The Zero-API Framework & Benchmark-Verified Library for High-End AI Coding Skills & Context-Isolated Subagents with Universal Top-20 AI Agent Transpilation & Token Economy Auditing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|