@hasna/skills 0.1.45 → 0.1.47
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 +32 -1
- package/bin/index.js +469 -151
- package/bin/mcp.js +299 -68
- package/dist/index.js +108 -31
- package/dist/lib/compact-output.d.ts +32 -0
- package/dist/lib/skill-aliases.d.ts +1 -0
- package/package.json +2 -2
- package/skills/transcript/SKILL.md +53 -73
- package/skills/transcript/package.json +1 -1
- package/skills/apidocs/.claude/settings.json +0 -5
- package/skills/hook/bunfig.toml +0 -5
- package/skills/implementation/bunfig.toml +0 -5
package/bin/index.js
CHANGED
|
@@ -9553,7 +9553,7 @@ Learn more about this warning here: https://reactjs.org/link/legacy-context`, so
|
|
|
9553
9553
|
|
|
9554
9554
|
` + ("" + errorBoundaryMessage);
|
|
9555
9555
|
console["error"](combinedMessage);
|
|
9556
|
-
}
|
|
9556
|
+
} else {}
|
|
9557
9557
|
} catch (e) {
|
|
9558
9558
|
setTimeout(function() {
|
|
9559
9559
|
throw e;
|
|
@@ -18037,7 +18037,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
18037
18037
|
987: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
18038
18038
|
if (true) {
|
|
18039
18039
|
module2.exports = __webpack_require__2(786);
|
|
18040
|
-
}
|
|
18040
|
+
} else {}
|
|
18041
18041
|
},
|
|
18042
18042
|
126: (__unused_webpack_module, exports2, __webpack_require__2) => {
|
|
18043
18043
|
var process3 = __webpack_require__2(169);
|
|
@@ -18487,7 +18487,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
18487
18487
|
189: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
18488
18488
|
if (true) {
|
|
18489
18489
|
module2.exports = __webpack_require__2(126);
|
|
18490
|
-
}
|
|
18490
|
+
} else {}
|
|
18491
18491
|
},
|
|
18492
18492
|
206: function(module2, exports2, __webpack_require__2) {
|
|
18493
18493
|
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
|
|
@@ -18502,7 +18502,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
18502
18502
|
(function(root, factory) {
|
|
18503
18503
|
if (true) {
|
|
18504
18504
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__2(430)], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
18505
|
-
}
|
|
18505
|
+
} else {}
|
|
18506
18506
|
})(this, function ErrorStackParser(StackFrame) {
|
|
18507
18507
|
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
|
|
18508
18508
|
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
|
|
@@ -19198,7 +19198,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
19198
19198
|
(function(root, factory) {
|
|
19199
19199
|
if (true) {
|
|
19200
19200
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
19201
|
-
}
|
|
19201
|
+
} else {}
|
|
19202
19202
|
})(this, function() {
|
|
19203
19203
|
function _isNumber(n) {
|
|
19204
19204
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
@@ -24572,7 +24572,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
24572
24572
|
var suffix = "";
|
|
24573
24573
|
if (true) {
|
|
24574
24574
|
suffix = " (<anonymous>)";
|
|
24575
|
-
}
|
|
24575
|
+
} else {}
|
|
24576
24576
|
return `
|
|
24577
24577
|
` + prefix + name + suffix;
|
|
24578
24578
|
}
|
|
@@ -27301,7 +27301,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
27301
27301
|
hasChanges = true;
|
|
27302
27302
|
updateMostRecentlyInspectedElementIfNecessary(devtoolsInstance.id);
|
|
27303
27303
|
}
|
|
27304
|
-
}
|
|
27304
|
+
} else {}
|
|
27305
27305
|
}
|
|
27306
27306
|
} catch (err) {
|
|
27307
27307
|
_iterator2.e(err);
|
|
@@ -29080,7 +29080,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29080
29080
|
if (contentFiber === null) {
|
|
29081
29081
|
throw new Error("There should always be an Offscreen Fiber child in a hydrated Suspense boundary.");
|
|
29082
29082
|
}
|
|
29083
|
-
}
|
|
29083
|
+
} else {}
|
|
29084
29084
|
var _isTimedOut = fiber.memoizedState !== null;
|
|
29085
29085
|
if (!_isTimedOut) {
|
|
29086
29086
|
newSuspenseNode.rects = measureInstance(newInstance);
|
|
@@ -29114,7 +29114,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29114
29114
|
if (_contentFiber === null) {
|
|
29115
29115
|
throw new Error("There should always be an Offscreen Fiber child in a hydrated Suspense boundary.");
|
|
29116
29116
|
}
|
|
29117
|
-
}
|
|
29117
|
+
} else {}
|
|
29118
29118
|
var suspenseState = fiber.memoizedState;
|
|
29119
29119
|
var _isTimedOut3 = suspenseState !== null;
|
|
29120
29120
|
if (!_isTimedOut3) {
|
|
@@ -29214,7 +29214,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29214
29214
|
trackThrownPromisesFromRetryCache(newSuspenseNode, fiber.stateNode);
|
|
29215
29215
|
mountSuspenseChildrenRecursively(_contentFiber2, traceNearestHostComponentUpdate, stashedSuspenseParent, stashedSuspensePrevious, stashedSuspenseRemaining);
|
|
29216
29216
|
shouldPopSuspenseNode = false;
|
|
29217
|
-
}
|
|
29217
|
+
} else {}
|
|
29218
29218
|
} else {
|
|
29219
29219
|
if (fiber.child !== null) {
|
|
29220
29220
|
mountChildrenRecursively(fiber.child, traceNearestHostComponentUpdate);
|
|
@@ -29800,7 +29800,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29800
29800
|
shouldPopSuspenseNode = false;
|
|
29801
29801
|
} else if (previousHydrated && !nextHydrated) {
|
|
29802
29802
|
throw new Error("Encountered a dehydrated Suspense boundary that was previously hydrated.");
|
|
29803
|
-
}
|
|
29803
|
+
} else {}
|
|
29804
29804
|
} else {
|
|
29805
29805
|
if (nextFiber.child !== prevFiber.child) {
|
|
29806
29806
|
updateFlags |= updateChildrenRecursively(nextFiber.child, prevFiber.child, traceNearestHostComponentUpdate);
|
|
@@ -29846,8 +29846,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29846
29846
|
recordResetChildren(fiberInstance);
|
|
29847
29847
|
}
|
|
29848
29848
|
updateFlags &= ~ShouldResetChildren;
|
|
29849
|
-
}
|
|
29850
|
-
}
|
|
29849
|
+
} else {}
|
|
29850
|
+
} else {}
|
|
29851
29851
|
if ((updateFlags & ShouldResetSuspenseChildren) !== NoUpdate) {
|
|
29852
29852
|
if (fiberInstance !== null && fiberInstance.kind === FIBER_INSTANCE) {
|
|
29853
29853
|
var _suspenseNode3 = fiberInstance.suspenseNode;
|
|
@@ -29855,7 +29855,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29855
29855
|
recordResetSuspenseChildren(_suspenseNode3);
|
|
29856
29856
|
updateFlags &= ~ShouldResetSuspenseChildren;
|
|
29857
29857
|
}
|
|
29858
|
-
}
|
|
29858
|
+
} else {}
|
|
29859
29859
|
}
|
|
29860
29860
|
if ((updateFlags & ShouldResetParentSuspenseChildren) !== NoUpdate) {
|
|
29861
29861
|
if (fiberInstance !== null && fiberInstance.kind === FIBER_INSTANCE) {
|
|
@@ -29864,7 +29864,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29864
29864
|
updateFlags &= ~ShouldResetParentSuspenseChildren;
|
|
29865
29865
|
updateFlags |= ShouldResetSuspenseChildren;
|
|
29866
29866
|
}
|
|
29867
|
-
}
|
|
29867
|
+
} else {}
|
|
29868
29868
|
}
|
|
29869
29869
|
return updateFlags;
|
|
29870
29870
|
} finally {
|
|
@@ -32928,7 +32928,7 @@ The error thrown in the component is:
|
|
|
32928
32928
|
rendererInterface = renderer_attach(hook, id, renderer, global2, shouldStartProfilingNow, profilingSettings);
|
|
32929
32929
|
} else if (renderer.ComponentTree) {
|
|
32930
32930
|
rendererInterface = legacy_renderer_attach(hook, id, renderer, global2);
|
|
32931
|
-
}
|
|
32931
|
+
} else {}
|
|
32932
32932
|
}
|
|
32933
32933
|
return rendererInterface;
|
|
32934
32934
|
}
|
|
@@ -35811,7 +35811,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
35811
35811
|
this._exitCallback = (err) => {
|
|
35812
35812
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
35813
35813
|
throw err;
|
|
35814
|
-
}
|
|
35814
|
+
} else {}
|
|
35815
35815
|
};
|
|
35816
35816
|
}
|
|
35817
35817
|
return this;
|
|
@@ -36860,7 +36860,7 @@ var package_default;
|
|
|
36860
36860
|
var init_package = __esm(() => {
|
|
36861
36861
|
package_default = {
|
|
36862
36862
|
name: "@hasna/skills",
|
|
36863
|
-
version: "0.1.
|
|
36863
|
+
version: "0.1.47",
|
|
36864
36864
|
description: "Skills library for AI coding agents",
|
|
36865
36865
|
type: "module",
|
|
36866
36866
|
bin: {
|
|
@@ -36929,7 +36929,7 @@ var init_package = __esm(() => {
|
|
|
36929
36929
|
typescript: "^5"
|
|
36930
36930
|
},
|
|
36931
36931
|
dependencies: {
|
|
36932
|
-
"@hasna/events": "^0.1.
|
|
36932
|
+
"@hasna/events": "^0.1.7",
|
|
36933
36933
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
36934
36934
|
chalk: "^5.3.0",
|
|
36935
36935
|
commander: "^12.1.0",
|
|
@@ -37993,7 +37993,8 @@ var init_skill_aliases = __esm(() => {
|
|
|
37993
37993
|
"pdf-reader": "read-pdf",
|
|
37994
37994
|
"generate-image": "image",
|
|
37995
37995
|
"image-generator": "image",
|
|
37996
|
-
"create-blog-article": "blog-article"
|
|
37996
|
+
"create-blog-article": "blog-article",
|
|
37997
|
+
"skill-diff": "diff-viewer"
|
|
37997
37998
|
};
|
|
37998
37999
|
});
|
|
37999
38000
|
|
|
@@ -38410,7 +38411,7 @@ var init_pricing = __esm(() => {
|
|
|
38410
38411
|
{ slug: "brand-kit", displayName: "Brand Kit", tier: "premium", costCents: 400, providers: ["hosted"], description: "Hosted brand kit with logo usage, palette, typography, brand voice, sample applications, Markdown guide, PDF guide, and SVG assets" },
|
|
38411
38412
|
{ slug: "generate-book-cover", displayName: "Book Cover", tier: "premium", costCents: 20, providers: ["gpt-image-2"], description: "Professional book cover design from title and genre" },
|
|
38412
38413
|
{ slug: "remove-background", displayName: "Remove Background", tier: "premium", costCents: 10, providers: ["gemini-3-pro"], description: "AI-powered background removal from images" },
|
|
38413
|
-
{ slug: "transcript", displayName: "Transcript", tier: "premium", costCents: 10, providers: ["
|
|
38414
|
+
{ slug: "transcript", displayName: "Transcript", tier: "premium", costCents: 10, providers: ["openai", "elevenlabs", "deepgram", "hosted"], description: "Audio/video transcription with timestamps, diarization, and URL support" },
|
|
38414
38415
|
{ slug: "webcrawling", displayName: "Web Crawling", tier: "premium", costCents: 5, providers: ["firecrawl"], description: "Structured web page crawling and extraction" },
|
|
38415
38416
|
{ slug: "browse", displayName: "Browse", tier: "premium", costCents: 5, providers: ["browser"], description: "Web browsing and page interaction" },
|
|
38416
38417
|
{ slug: "read-pdf", displayName: "Read PDF", tier: "premium", costCents: 5, providers: ["cerebras"], description: "Hosted PDF extraction and structured content analysis" },
|
|
@@ -39089,12 +39090,47 @@ function ensurePortableSkillFiles(skillPath, manifest) {
|
|
|
39089
39090
|
writeFileSync2(join5(skillPath, "skill.json"), renderSkillJson(next));
|
|
39090
39091
|
if (!existsSync5(join5(skillPath, "AGENTS.md")))
|
|
39091
39092
|
writeFileSync2(join5(skillPath, "AGENTS.md"), renderAgentsMd(next));
|
|
39092
|
-
|
|
39093
|
-
writeFileSync2(join5(skillPath, "package.json"), renderPackageJson(next));
|
|
39093
|
+
ensurePackageJson(skillPath, next);
|
|
39094
39094
|
if (!existsSync5(join5(skillPath, "tsconfig.json")))
|
|
39095
39095
|
writeFileSync2(join5(skillPath, "tsconfig.json"), renderTsconfig());
|
|
39096
39096
|
return readPortableSkillManifest(skillPath, next.name);
|
|
39097
39097
|
}
|
|
39098
|
+
function ensurePackageJson(skillPath, manifest) {
|
|
39099
|
+
const pkgPath = join5(skillPath, "package.json");
|
|
39100
|
+
const first = manifest.commands[0] ?? { name: manifest.name, entry: "src/index.ts" };
|
|
39101
|
+
const commandName = normalizePortableSkillName(first.name || manifest.name);
|
|
39102
|
+
const entry = (first.entry ?? "src/index.ts").replace(/^\.\//, "");
|
|
39103
|
+
if (!existsSync5(pkgPath)) {
|
|
39104
|
+
writeFileSync2(pkgPath, renderPackageJson(manifest));
|
|
39105
|
+
return;
|
|
39106
|
+
}
|
|
39107
|
+
const existing = readJsonObject(pkgPath);
|
|
39108
|
+
const bin = {};
|
|
39109
|
+
if (isRecord(existing.bin)) {
|
|
39110
|
+
for (const [name, value] of Object.entries(existing.bin)) {
|
|
39111
|
+
if (typeof value === "string" && value.trim())
|
|
39112
|
+
bin[normalizePortableSkillName(name)] = value.replace(/^\.\//, "");
|
|
39113
|
+
}
|
|
39114
|
+
} else {
|
|
39115
|
+
const binEntry = stringValue(existing.bin);
|
|
39116
|
+
if (binEntry)
|
|
39117
|
+
bin[manifest.name] = binEntry.replace(/^\.\//, "");
|
|
39118
|
+
}
|
|
39119
|
+
bin[commandName] = entry;
|
|
39120
|
+
const scripts = isRecord(existing.scripts) ? { ...existing.scripts } : {};
|
|
39121
|
+
if (!stringValue(scripts.dev))
|
|
39122
|
+
scripts.dev = `bun run ${entry}`;
|
|
39123
|
+
writeFileSync2(pkgPath, `${JSON.stringify({
|
|
39124
|
+
...existing,
|
|
39125
|
+
name: manifest.name,
|
|
39126
|
+
version: manifest.version,
|
|
39127
|
+
description: manifest.description,
|
|
39128
|
+
type: stringValue(existing.type) ?? "module",
|
|
39129
|
+
bin,
|
|
39130
|
+
scripts
|
|
39131
|
+
}, null, 2)}
|
|
39132
|
+
`);
|
|
39133
|
+
}
|
|
39098
39134
|
function copySkillDirectory(source, destination) {
|
|
39099
39135
|
mkdirSync2(destination, { recursive: true });
|
|
39100
39136
|
cpSync(source, destination, {
|
|
@@ -40581,9 +40617,9 @@ var init_media_processing = __esm(() => {
|
|
|
40581
40617
|
{
|
|
40582
40618
|
name: "transcript",
|
|
40583
40619
|
displayName: "Transcript",
|
|
40584
|
-
description: "
|
|
40620
|
+
description: "Transcribe audio, video, and media URLs with OpenAI GPT-4o, ElevenLabs Scribe v2, DeepGram, or hosted runtime",
|
|
40585
40621
|
category: "Media Processing",
|
|
40586
|
-
tags: ["transcript", "audio", "video", "speech-to-text"]
|
|
40622
|
+
tags: ["transcript", "audio", "video", "speech-to-text", "diarization", "youtube"]
|
|
40587
40623
|
},
|
|
40588
40624
|
{
|
|
40589
40625
|
name: "video-cut-suggester",
|
|
@@ -54456,7 +54492,7 @@ function finalize(ctx, schema) {
|
|
|
54456
54492
|
result2.$schema = "http://json-schema.org/draft-07/schema#";
|
|
54457
54493
|
} else if (ctx.target === "draft-04") {
|
|
54458
54494
|
result2.$schema = "http://json-schema.org/draft-04/schema#";
|
|
54459
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
54495
|
+
} else if (ctx.target === "openapi-3.0") {} else {}
|
|
54460
54496
|
if (ctx.external?.uri) {
|
|
54461
54497
|
const id = ctx.external.registry.get(schema)?.id;
|
|
54462
54498
|
if (!id)
|
|
@@ -54721,7 +54757,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
|
|
|
54721
54757
|
if (val === undefined) {
|
|
54722
54758
|
if (ctx.unrepresentable === "throw") {
|
|
54723
54759
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
54724
|
-
}
|
|
54760
|
+
} else {}
|
|
54725
54761
|
} else if (typeof val === "bigint") {
|
|
54726
54762
|
if (ctx.unrepresentable === "throw") {
|
|
54727
54763
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -58051,30 +58087,119 @@ var init_install = __esm(() => {
|
|
|
58051
58087
|
init_installer();
|
|
58052
58088
|
});
|
|
58053
58089
|
|
|
58090
|
+
// src/lib/compact-output.ts
|
|
58091
|
+
function truncateText(value, maxChars = 96) {
|
|
58092
|
+
const text = String(value ?? "").replace(/\s+/g, " ").trim();
|
|
58093
|
+
if (text.length <= maxChars)
|
|
58094
|
+
return text;
|
|
58095
|
+
return `${text.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
|
|
58096
|
+
}
|
|
58097
|
+
function previewText(value, maxChars = DEFAULT_PREVIEW_CHARS) {
|
|
58098
|
+
const text = String(value ?? "");
|
|
58099
|
+
return {
|
|
58100
|
+
text: text.length > maxChars ? `${text.slice(0, Math.max(0, maxChars - 3))}...` : text,
|
|
58101
|
+
length: text.length,
|
|
58102
|
+
truncated: text.length > maxChars
|
|
58103
|
+
};
|
|
58104
|
+
}
|
|
58105
|
+
function parsePageLimit(value, fallback, options = {}) {
|
|
58106
|
+
const max2 = options.max ?? MAX_PAGE_LIMIT;
|
|
58107
|
+
if (typeof value === "string" && options.allowAll && value.trim().toLowerCase() === "all") {
|
|
58108
|
+
return Number.POSITIVE_INFINITY;
|
|
58109
|
+
}
|
|
58110
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(value ?? "", 10);
|
|
58111
|
+
if (!Number.isFinite(parsed))
|
|
58112
|
+
return fallback;
|
|
58113
|
+
if (options.allowAll && parsed === 0)
|
|
58114
|
+
return Number.POSITIVE_INFINITY;
|
|
58115
|
+
if (parsed <= 0)
|
|
58116
|
+
return fallback;
|
|
58117
|
+
return Math.min(parsed, max2);
|
|
58118
|
+
}
|
|
58119
|
+
function parsePageOffset(value, fallback = 0) {
|
|
58120
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(value ?? "", 10);
|
|
58121
|
+
if (!Number.isFinite(parsed) || parsed < 0)
|
|
58122
|
+
return fallback;
|
|
58123
|
+
return parsed;
|
|
58124
|
+
}
|
|
58125
|
+
function paginate(items, options) {
|
|
58126
|
+
const offset = Math.min(parsePageOffset(options.offset), items.length);
|
|
58127
|
+
const effectiveLimit = Number.isFinite(options.limit) ? Math.max(0, Math.min(options.limit, MAX_PAGE_LIMIT)) : Math.max(0, items.length - offset);
|
|
58128
|
+
const pageItems = items.slice(offset, offset + effectiveLimit);
|
|
58129
|
+
const nextOffset = offset + pageItems.length < items.length ? offset + pageItems.length : null;
|
|
58130
|
+
return {
|
|
58131
|
+
items: pageItems,
|
|
58132
|
+
total: items.length,
|
|
58133
|
+
offset,
|
|
58134
|
+
limit: effectiveLimit,
|
|
58135
|
+
hasMore: nextOffset !== null,
|
|
58136
|
+
nextOffset
|
|
58137
|
+
};
|
|
58138
|
+
}
|
|
58139
|
+
function showingLabel(total, shown, offset) {
|
|
58140
|
+
if (offset > 0 || shown < total)
|
|
58141
|
+
return `showing ${shown} of ${total}, cursor ${offset}`;
|
|
58142
|
+
return String(total);
|
|
58143
|
+
}
|
|
58144
|
+
function compactRunRecord(run) {
|
|
58145
|
+
if (!run || typeof run !== "object")
|
|
58146
|
+
return {};
|
|
58147
|
+
return {
|
|
58148
|
+
id: run.id,
|
|
58149
|
+
skill: run.skill,
|
|
58150
|
+
status: run.status,
|
|
58151
|
+
startedAt: run.startedAt,
|
|
58152
|
+
...run.completedAt ? { completedAt: run.completedAt } : {},
|
|
58153
|
+
...run.remoteRunId ? { remoteRunId: run.remoteRunId } : {},
|
|
58154
|
+
...run.costCents !== undefined ? { costCents: run.costCents } : {},
|
|
58155
|
+
...run.error ? { error: truncateText(run.error, 240) } : {},
|
|
58156
|
+
artifactCount: Array.isArray(run.artifacts) ? run.artifacts.length : 0,
|
|
58157
|
+
paths: run.paths
|
|
58158
|
+
};
|
|
58159
|
+
}
|
|
58160
|
+
function compactRemoteRun(run) {
|
|
58161
|
+
if (!run || typeof run !== "object")
|
|
58162
|
+
return {};
|
|
58163
|
+
return {
|
|
58164
|
+
...run.contractVersion !== undefined ? { contractVersion: run.contractVersion } : {},
|
|
58165
|
+
id: run.id,
|
|
58166
|
+
skill: run.skill ?? run.requestedSlug,
|
|
58167
|
+
status: run.status,
|
|
58168
|
+
...run.correlationId ? { correlationId: run.correlationId } : {},
|
|
58169
|
+
...run.createdAt ? { createdAt: run.createdAt } : {},
|
|
58170
|
+
...run.startedAt ? { startedAt: run.startedAt } : {},
|
|
58171
|
+
...run.completedAt ? { completedAt: run.completedAt } : {},
|
|
58172
|
+
...run.error || run.errorMessage ? { error: truncateText(run.error ?? run.errorMessage, 240) } : {}
|
|
58173
|
+
};
|
|
58174
|
+
}
|
|
58175
|
+
var DEFAULT_LIST_LIMIT = 30, DEFAULT_SEARCH_LIMIT = 20, DEFAULT_TAG_LIMIT = 80, DEFAULT_MCP_LIMIT = 25, MAX_PAGE_LIMIT = 200, DEFAULT_PREVIEW_CHARS = 600;
|
|
58176
|
+
|
|
58054
58177
|
// src/cli/commands/list.ts
|
|
58055
58178
|
var exports_list = {};
|
|
58056
58179
|
__export(exports_list, {
|
|
58057
58180
|
registerBrowse: () => registerBrowse
|
|
58058
58181
|
});
|
|
58059
58182
|
function registerBrowse(parent) {
|
|
58060
|
-
parent.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-p, --pinned", "Show only pinned skills", false).option("-t, --tags <tags>", "Filter by comma-separated tags (OR logic, case-insensitive)").option("--all", "Show the full skill registry instead of the default basic set", false).option("--remote", "Use remote registry from SKILLS_API_URL or config apiUrl", false).option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).option("--format <format>", "Output format: compact (names only) or csv (name,category,price,description)").action((options) => {
|
|
58183
|
+
parent.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-p, --pinned", "Show only pinned skills", false).option("-t, --tags <tags>", "Filter by comma-separated tags (OR logic, case-insensitive)").option("--all", "Show the full skill registry instead of the default basic set", false).option("--remote", "Use remote registry from SKILLS_API_URL or config apiUrl", false).option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).option("--format <format>", "Output format: compact (names only) or csv (name,category,price,description)").option("--limit <n>", "Maximum rows to print for human output (default: 30, use 0 or all for every row)").option("--cursor <n>", "Numeric offset for human-output pagination", "0").option("--verbose", "Show longer descriptions and tags in human output", false).action((options) => {
|
|
58061
58184
|
return handleList(options).catch(handleBrowseError);
|
|
58062
58185
|
});
|
|
58063
|
-
parent.command("search").alias("s").argument("<query>", "Search term").option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).option("--format <format>", "Output format: compact (names only) or csv (name,category,price,description)").option("-c, --category <category>", "Filter results by category").option("-t, --tags <tags>", "Filter results by comma-separated tags (OR logic, case-insensitive)").option("--all", "Search the full skill registry instead of the default basic set", false).option("--remote", "Use remote registry from SKILLS_API_URL or config apiUrl", false).description("Search for skills").action((query, options) => {
|
|
58186
|
+
parent.command("search").alias("s").argument("<query>", "Search term").option("--json", "Output as JSON", false).option("--brief", "One line per skill: name \u2014 description [category]", false).option("--format <format>", "Output format: compact (names only) or csv (name,category,price,description)").option("-c, --category <category>", "Filter results by category").option("-t, --tags <tags>", "Filter results by comma-separated tags (OR logic, case-insensitive)").option("--all", "Search the full skill registry instead of the default basic set", false).option("--remote", "Use remote registry from SKILLS_API_URL or config apiUrl", false).option("--limit <n>", "Maximum rows to print for human output (default: 20, use 0 or all for every row)").option("--cursor <n>", "Numeric offset for human-output pagination", "0").option("--verbose", "Show longer descriptions and tags in human output", false).description("Search for skills").action((query, options) => {
|
|
58064
58187
|
return handleSearch(query, options).catch(handleBrowseError);
|
|
58065
58188
|
});
|
|
58066
58189
|
parent.command("categories").option("--json", "Output as JSON", false).option("--remote", "Use remote registry from SKILLS_API_URL or config apiUrl", false).description("List all categories").action((options) => {
|
|
58067
58190
|
return handleCategories(options).catch(handleBrowseError);
|
|
58068
58191
|
});
|
|
58069
|
-
parent.command("tags").option("--json", "Output as JSON", false).option("--remote", "Use remote registry from SKILLS_API_URL or config apiUrl", false).description("List all unique tags with counts").action((options) => {
|
|
58192
|
+
parent.command("tags").option("--json", "Output as JSON", false).option("--remote", "Use remote registry from SKILLS_API_URL or config apiUrl", false).option("--limit <n>", "Maximum rows to print for human output (default: 80, use 0 or all for every row)").option("--cursor <n>", "Numeric offset for human-output pagination", "0").description("List all unique tags with counts").action((options) => {
|
|
58070
58193
|
return handleTags(options).catch(handleBrowseError);
|
|
58071
58194
|
});
|
|
58072
58195
|
}
|
|
58073
58196
|
function formatBrief(skill) {
|
|
58074
|
-
return `${skill.name} \u2014 ${skill.description} (${publicDiscoveryPriceLabel(skill)}) [${skill.category}]`;
|
|
58197
|
+
return `${skill.name} \u2014 ${truncateText(skill.description, 110)} (${publicDiscoveryPriceLabel(skill)}) [${skill.category}]`;
|
|
58075
58198
|
}
|
|
58076
|
-
function formatSkillLine(skill) {
|
|
58077
|
-
|
|
58199
|
+
function formatSkillLine(skill, options = {}) {
|
|
58200
|
+
const description = truncateText(skill.description, options.verbose ? 180 : 88);
|
|
58201
|
+
const tags = options.verbose && skill.tags.length ? source_default.dim(` tags: ${skill.tags.join(", ")}`) : "";
|
|
58202
|
+
return ` ${source_default.cyan(skill.name)}${skill.source === "custom" ? source_default.yellow(" [custom]") : ""} ${source_default.dim(`[${skill.category}]`)} ${source_default.dim(`(${publicDiscoveryPriceLabel(skill)})`)} - ${description}${tags}`;
|
|
58078
58203
|
}
|
|
58079
58204
|
function enrichDiscovery(skills) {
|
|
58080
58205
|
return skills.map(getPublicSkillDiscovery);
|
|
@@ -58114,6 +58239,8 @@ async function handleList(options) {
|
|
|
58114
58239
|
const fmt = !options.json ? options.format : undefined;
|
|
58115
58240
|
const profile = options.all ? "all" : "basic";
|
|
58116
58241
|
const registry2 = await getBrowseRegistry(options);
|
|
58242
|
+
const limit = parsePageLimit(options.limit, DEFAULT_LIST_LIMIT, { allowAll: true });
|
|
58243
|
+
const offset = parsePageOffset(options.cursor);
|
|
58117
58244
|
if (options.pinned) {
|
|
58118
58245
|
const installed = getInstalledSkills();
|
|
58119
58246
|
if (options.json) {
|
|
@@ -58137,14 +58264,16 @@ async function handleList(options) {
|
|
|
58137
58264
|
}
|
|
58138
58265
|
const meta3 = getInstallMeta();
|
|
58139
58266
|
const registry3 = loadRegistry();
|
|
58267
|
+
const page2 = paginate(installed, { limit, offset });
|
|
58140
58268
|
console.log(source_default.bold(`
|
|
58141
|
-
Pinned skills (${installed.length}):
|
|
58269
|
+
Pinned skills (${showingLabel(installed.length, page2.items.length, page2.offset)}):
|
|
58142
58270
|
`));
|
|
58143
|
-
for (const name of
|
|
58271
|
+
for (const name of page2.items) {
|
|
58144
58272
|
const m = meta3.skills[name];
|
|
58145
58273
|
const s = registry3.find((r) => r.name === name);
|
|
58146
58274
|
console.log(` ${source_default.cyan(name)}${s?.source === "custom" ? source_default.yellow(" [custom]") : ""} ${m?.version ? source_default.dim(`v${m.version}`) : ""} ${m?.installedAt ? source_default.dim(new Date(m.installedAt).toLocaleDateString()) : ""}`);
|
|
58147
58275
|
}
|
|
58276
|
+
printPageHint(page2, "skills list --pinned");
|
|
58148
58277
|
return;
|
|
58149
58278
|
}
|
|
58150
58279
|
const tagFilter = options.tags ? options.tags.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean) : null;
|
|
@@ -58165,16 +58294,19 @@ Available: ${categories.join(", ")}`);
|
|
|
58165
58294
|
await writeJson(output, 2);
|
|
58166
58295
|
return;
|
|
58167
58296
|
}
|
|
58297
|
+
const page2 = paginate(output, { limit, offset });
|
|
58168
58298
|
if (brief) {
|
|
58169
|
-
for (const s of
|
|
58299
|
+
for (const s of page2.items)
|
|
58170
58300
|
console.log(formatBrief(s));
|
|
58301
|
+
printPageHint(page2, listCommand(options));
|
|
58171
58302
|
return;
|
|
58172
58303
|
}
|
|
58173
58304
|
console.log(source_default.bold(`
|
|
58174
|
-
${category} (${
|
|
58305
|
+
${category} (${showingLabel(output.length, page2.items.length, page2.offset)}):
|
|
58175
58306
|
`));
|
|
58176
|
-
for (const s of
|
|
58177
|
-
console.log(formatSkillLine(s));
|
|
58307
|
+
for (const s of page2.items)
|
|
58308
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58309
|
+
printSkillHint(page2, listCommand(options));
|
|
58178
58310
|
return;
|
|
58179
58311
|
}
|
|
58180
58312
|
if (tagFilter) {
|
|
@@ -58184,16 +58316,19 @@ ${category} (${skills.length}):
|
|
|
58184
58316
|
await writeJson(output, 2);
|
|
58185
58317
|
return;
|
|
58186
58318
|
}
|
|
58319
|
+
const page2 = paginate(output, { limit, offset });
|
|
58187
58320
|
if (brief) {
|
|
58188
|
-
for (const s of
|
|
58321
|
+
for (const s of page2.items)
|
|
58189
58322
|
console.log(formatBrief(s));
|
|
58323
|
+
printPageHint(page2, listCommand(options));
|
|
58190
58324
|
return;
|
|
58191
58325
|
}
|
|
58192
58326
|
console.log(source_default.bold(`
|
|
58193
|
-
Skills matching tags [${tagFilter.join(", ")}] (${
|
|
58327
|
+
Skills matching tags [${tagFilter.join(", ")}] (${showingLabel(output.length, page2.items.length, page2.offset)}):
|
|
58194
58328
|
`));
|
|
58195
|
-
for (const s of
|
|
58196
|
-
console.log(
|
|
58329
|
+
for (const s of page2.items)
|
|
58330
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58331
|
+
printSkillHint(page2, listCommand(options));
|
|
58197
58332
|
return;
|
|
58198
58333
|
}
|
|
58199
58334
|
const allSkills = enrichDiscovery(registry2);
|
|
@@ -58215,28 +58350,21 @@ Skills matching tags [${tagFilter.join(", ")}] (${skills.length}):
|
|
|
58215
58350
|
return;
|
|
58216
58351
|
}
|
|
58217
58352
|
if (brief) {
|
|
58218
|
-
|
|
58353
|
+
const sorted2 = [...allSkills].sort((a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name));
|
|
58354
|
+
const page2 = paginate(sorted2, { limit, offset });
|
|
58355
|
+
for (const s of page2.items)
|
|
58219
58356
|
console.log(formatBrief(s));
|
|
58357
|
+
printPageHint(page2, listCommand(options));
|
|
58220
58358
|
return;
|
|
58221
58359
|
}
|
|
58360
|
+
const sorted = [...allSkills].sort((a, b) => a.category.localeCompare(b.category) || a.name.localeCompare(b.name));
|
|
58361
|
+
const page = paginate(sorted, { limit, offset });
|
|
58222
58362
|
console.log(source_default.bold(`
|
|
58223
|
-
Available ${profile === "basic" ? "default " : ""}skills (${allSkills.length}):
|
|
58363
|
+
Available ${profile === "basic" ? "default " : ""}skills (${showingLabel(allSkills.length, page.items.length, page.offset)}):
|
|
58224
58364
|
`));
|
|
58225
|
-
for (const
|
|
58226
|
-
|
|
58227
|
-
|
|
58228
|
-
continue;
|
|
58229
|
-
console.log(source_default.bold(`${category} (${skills.length}):`));
|
|
58230
|
-
for (const s of skills)
|
|
58231
|
-
console.log(formatSkillLine(s));
|
|
58232
|
-
console.log();
|
|
58233
|
-
}
|
|
58234
|
-
const customUncategorized = allSkills.filter((s) => s.source === "custom" && !CATEGORIES.includes(s.category));
|
|
58235
|
-
if (customUncategorized.length > 0) {
|
|
58236
|
-
console.log(source_default.bold(`Custom (${customUncategorized.length}):`));
|
|
58237
|
-
for (const s of customUncategorized)
|
|
58238
|
-
console.log(` ${source_default.yellow(s.name)} ${source_default.dim(`(${publicDiscoveryPriceLabel(s)})`)} - ${s.description}`);
|
|
58239
|
-
}
|
|
58365
|
+
for (const s of page.items)
|
|
58366
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58367
|
+
printSkillHint(page, listCommand(options));
|
|
58240
58368
|
}
|
|
58241
58369
|
async function handleSearch(query, options) {
|
|
58242
58370
|
const registry2 = await getBrowseRegistry(options);
|
|
@@ -58283,19 +58411,22 @@ Available: ${categories.join(", ")}`);
|
|
|
58283
58411
|
}
|
|
58284
58412
|
return;
|
|
58285
58413
|
}
|
|
58414
|
+
const limit = parsePageLimit(options.limit, DEFAULT_SEARCH_LIMIT, { allowAll: true });
|
|
58415
|
+
const offset = parsePageOffset(options.cursor);
|
|
58416
|
+
const page = paginate(output, { limit, offset });
|
|
58286
58417
|
if (brief) {
|
|
58287
|
-
for (const s of
|
|
58418
|
+
for (const s of page.items)
|
|
58288
58419
|
console.log(formatBrief(s));
|
|
58420
|
+
printPageHint(page, searchCommand(query, options));
|
|
58289
58421
|
return;
|
|
58290
58422
|
}
|
|
58291
58423
|
console.log(source_default.bold(`
|
|
58292
|
-
Found ${output.length}
|
|
58424
|
+
Found ${skillCountLabel(output.length, page.items.length, page.offset)} for "${query}":
|
|
58293
58425
|
`));
|
|
58294
|
-
for (const s of
|
|
58295
|
-
console.log(
|
|
58296
|
-
console.log(` ${source_default.dim("Price:")} ${publicDiscoveryPriceLabel(s)}`);
|
|
58297
|
-
console.log(` ${s.description}`);
|
|
58426
|
+
for (const s of page.items) {
|
|
58427
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58298
58428
|
}
|
|
58429
|
+
printSkillHint(page, searchCommand(query, options));
|
|
58299
58430
|
}
|
|
58300
58431
|
async function handleCategories(options) {
|
|
58301
58432
|
const registry2 = await getBrowseRegistry({ all: true, remote: options.remote });
|
|
@@ -58324,11 +58455,60 @@ async function handleTags(options) {
|
|
|
58324
58455
|
await writeJson(sorted, 2);
|
|
58325
58456
|
return;
|
|
58326
58457
|
}
|
|
58458
|
+
const page = paginate(sorted, {
|
|
58459
|
+
limit: parsePageLimit(options.limit, DEFAULT_TAG_LIMIT, { allowAll: true }),
|
|
58460
|
+
offset: parsePageOffset(options.cursor)
|
|
58461
|
+
});
|
|
58327
58462
|
console.log(source_default.bold(`
|
|
58328
|
-
Tags:
|
|
58463
|
+
Tags: ${showingLabel(sorted.length, page.items.length, page.offset)}
|
|
58329
58464
|
`));
|
|
58330
|
-
for (const { name, count } of
|
|
58465
|
+
for (const { name, count } of page.items)
|
|
58331
58466
|
console.log(` ${source_default.cyan(name)} (${count})`);
|
|
58467
|
+
printPageHint(page, `skills tags${options.remote ? " --remote" : ""}`);
|
|
58468
|
+
}
|
|
58469
|
+
function printSkillHint(page, command) {
|
|
58470
|
+
printPageHint(page, command);
|
|
58471
|
+
console.log(source_default.dim(`Details: skills show <name> or rerun with --verbose. Use --json for the full machine-readable payload.`));
|
|
58472
|
+
}
|
|
58473
|
+
function printPageHint(page, command) {
|
|
58474
|
+
if (!page.hasMore || page.nextOffset === null)
|
|
58475
|
+
return;
|
|
58476
|
+
console.log(source_default.dim(`
|
|
58477
|
+
Next: ${command} --cursor ${page.nextOffset} --limit ${page.limit}`));
|
|
58478
|
+
}
|
|
58479
|
+
function listCommand(options) {
|
|
58480
|
+
const parts = ["skills list"];
|
|
58481
|
+
if (options.all)
|
|
58482
|
+
parts.push("--all");
|
|
58483
|
+
if (options.remote)
|
|
58484
|
+
parts.push("--remote");
|
|
58485
|
+
if (options.category)
|
|
58486
|
+
parts.push("--category", quoteArg(options.category));
|
|
58487
|
+
if (options.tags)
|
|
58488
|
+
parts.push("--tags", quoteArg(options.tags));
|
|
58489
|
+
if (options.pinned)
|
|
58490
|
+
parts.push("--pinned");
|
|
58491
|
+
return parts.join(" ");
|
|
58492
|
+
}
|
|
58493
|
+
function searchCommand(query, options) {
|
|
58494
|
+
const parts = ["skills search", quoteArg(query)];
|
|
58495
|
+
if (options.all)
|
|
58496
|
+
parts.push("--all");
|
|
58497
|
+
if (options.remote)
|
|
58498
|
+
parts.push("--remote");
|
|
58499
|
+
if (options.category)
|
|
58500
|
+
parts.push("--category", quoteArg(options.category));
|
|
58501
|
+
if (options.tags)
|
|
58502
|
+
parts.push("--tags", quoteArg(options.tags));
|
|
58503
|
+
return parts.join(" ");
|
|
58504
|
+
}
|
|
58505
|
+
function quoteArg(value) {
|
|
58506
|
+
return value.includes(" ") ? JSON.stringify(value) : value;
|
|
58507
|
+
}
|
|
58508
|
+
function skillCountLabel(total, shown, offset) {
|
|
58509
|
+
if (offset > 0 || shown < total)
|
|
58510
|
+
return `${shown} of ${total} skill(s), cursor ${offset}`;
|
|
58511
|
+
return `${total} skill(s)`;
|
|
58332
58512
|
}
|
|
58333
58513
|
var init_list = __esm(() => {
|
|
58334
58514
|
init_source();
|
|
@@ -75142,18 +75322,29 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75142
75322
|
exitCode: { type: "number", description: "Process exit code for local runs." },
|
|
75143
75323
|
skill: stringSchema("Canonical skill slug."),
|
|
75144
75324
|
remote: { type: "boolean", description: "Whether the skill was submitted to the hosted runtime." },
|
|
75145
|
-
|
|
75146
|
-
|
|
75325
|
+
stdoutPreview: objectSchema({
|
|
75326
|
+
text: stringSchema("Truncated stdout preview."),
|
|
75327
|
+
length: { type: "number" },
|
|
75328
|
+
truncated: { type: "boolean" }
|
|
75329
|
+
}, [], "Default compact stdout preview."),
|
|
75330
|
+
stderrPreview: objectSchema({
|
|
75331
|
+
text: stringSchema("Truncated stderr preview."),
|
|
75332
|
+
length: { type: "number" },
|
|
75333
|
+
truncated: { type: "boolean" }
|
|
75334
|
+
}, [], "Default compact stderr preview."),
|
|
75335
|
+
stdout: stringSchema("Captured stdout for local runs when detail:true is requested."),
|
|
75336
|
+
stderr: stringSchema("Captured stderr for local runs when detail:true is requested."),
|
|
75147
75337
|
id: stringSchema("Remote run id when submitted remotely."),
|
|
75148
75338
|
localRunId: stringSchema("Local run metadata id."),
|
|
75149
75339
|
status: stringSchema("Run lifecycle status."),
|
|
75150
75340
|
pricing: pricingSchema,
|
|
75151
|
-
remoteRun: objectSchema({}, [], "
|
|
75152
|
-
run: objectSchema({}, [], "
|
|
75341
|
+
remoteRun: objectSchema({}, [], "Compact hosted remote run summary by default; full contract when detail:true is requested.", true),
|
|
75342
|
+
run: objectSchema({}, [], "Compact local run metadata by default; full metadata when detail:true is requested.", true),
|
|
75153
75343
|
nextActions: objectSchema({
|
|
75154
75344
|
poll: stringSchema("Command to poll run status."),
|
|
75155
75345
|
download: stringSchema("Command to download artifacts.")
|
|
75156
|
-
})
|
|
75346
|
+
}),
|
|
75347
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
75157
75348
|
}, [], "Skill run result.");
|
|
75158
75349
|
toolContracts = [
|
|
75159
75350
|
{
|
|
@@ -75201,7 +75392,7 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75201
75392
|
{
|
|
75202
75393
|
name: "list_skills",
|
|
75203
75394
|
title: "List Skills",
|
|
75204
|
-
description: "List skills from the basic or full registry profile.",
|
|
75395
|
+
description: "List skills from the basic or full registry profile. Returns a compact paged envelope by default.",
|
|
75205
75396
|
params: ["category?", "profile?", "detail?", "limit?", "offset?"],
|
|
75206
75397
|
category: "discovery",
|
|
75207
75398
|
sideEffects: "none",
|
|
@@ -75217,7 +75408,11 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75217
75408
|
skills: arraySchema(skillSummarySchema),
|
|
75218
75409
|
total: { type: "number" },
|
|
75219
75410
|
offset: { type: "number" },
|
|
75220
|
-
limit: { type: "number" }
|
|
75411
|
+
limit: { type: "number" },
|
|
75412
|
+
nextOffset: { type: "number" },
|
|
75413
|
+
hasMore: { type: "boolean" },
|
|
75414
|
+
nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
|
|
75415
|
+
detailHint: stringSchema("How to request fuller skill objects.")
|
|
75221
75416
|
})
|
|
75222
75417
|
},
|
|
75223
75418
|
{
|
|
@@ -75238,7 +75433,7 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75238
75433
|
{
|
|
75239
75434
|
name: "search_skills",
|
|
75240
75435
|
title: "Search Skills",
|
|
75241
|
-
description: "Search skills by name, description, or tags.",
|
|
75436
|
+
description: "Search skills by name, description, or tags. Returns a compact paged envelope by default.",
|
|
75242
75437
|
params: ["query", "profile?", "detail?", "limit?", "offset?"],
|
|
75243
75438
|
category: "discovery",
|
|
75244
75439
|
sideEffects: "none",
|
|
@@ -75250,7 +75445,16 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75250
75445
|
limit: { type: "number", minimum: 0 },
|
|
75251
75446
|
offset: { type: "number", minimum: 0 }
|
|
75252
75447
|
}, ["query"]),
|
|
75253
|
-
outputSchema: objectSchema({
|
|
75448
|
+
outputSchema: objectSchema({
|
|
75449
|
+
skills: arraySchema(skillSummarySchema),
|
|
75450
|
+
total: { type: "number" },
|
|
75451
|
+
offset: { type: "number" },
|
|
75452
|
+
limit: { type: "number" },
|
|
75453
|
+
nextOffset: { type: "number" },
|
|
75454
|
+
hasMore: { type: "boolean" },
|
|
75455
|
+
nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
|
|
75456
|
+
detailHint: stringSchema("How to request fuller skill objects.")
|
|
75457
|
+
})
|
|
75254
75458
|
},
|
|
75255
75459
|
{
|
|
75256
75460
|
name: "get_skill_info",
|
|
@@ -75367,8 +75571,8 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75367
75571
|
{
|
|
75368
75572
|
name: "run_skill",
|
|
75369
75573
|
title: "Run Skill",
|
|
75370
|
-
description: "Run a skill locally or through a configured remote runner.",
|
|
75371
|
-
params: ["name", "input?", "args?", "approved?"],
|
|
75574
|
+
description: "Run a skill locally or through a configured remote runner. Returns compact stdout/stderr previews and run summaries by default; pass detail:true for full records.",
|
|
75575
|
+
params: ["name", "input?", "args?", "approved?", "detail?"],
|
|
75372
75576
|
category: "execution",
|
|
75373
75577
|
sideEffects: "local-process-or-remote-run",
|
|
75374
75578
|
stable: true,
|
|
@@ -75376,28 +75580,33 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75376
75580
|
name: skillNameInput,
|
|
75377
75581
|
input: runInputSchema,
|
|
75378
75582
|
args: runArgsSchema,
|
|
75379
|
-
approved: paidRunApprovalSchema
|
|
75583
|
+
approved: paidRunApprovalSchema,
|
|
75584
|
+
detail: { type: "boolean", default: false, description: "Return full stdout/stderr, remote run, and local run metadata." }
|
|
75380
75585
|
}, ["name"]),
|
|
75381
75586
|
outputSchema: runOutputSchema
|
|
75382
75587
|
},
|
|
75383
75588
|
{
|
|
75384
75589
|
name: "get_run_status",
|
|
75385
75590
|
title: "Get Run Status",
|
|
75386
|
-
description: "Fetch remote run status and next actions.",
|
|
75387
|
-
params: ["run_id"],
|
|
75591
|
+
description: "Fetch remote run status and next actions. Returns a compact status summary by default; pass detail:true for the complete remote run payload.",
|
|
75592
|
+
params: ["run_id", "detail?"],
|
|
75388
75593
|
category: "execution",
|
|
75389
75594
|
sideEffects: "none",
|
|
75390
75595
|
stable: true,
|
|
75391
|
-
inputSchema: objectSchema({
|
|
75596
|
+
inputSchema: objectSchema({
|
|
75597
|
+
run_id: stringSchema("Remote or local run id."),
|
|
75598
|
+
detail: { type: "boolean", default: false, description: "Return the complete remote run payload." }
|
|
75599
|
+
}, ["run_id"]),
|
|
75392
75600
|
outputSchema: objectSchema({
|
|
75393
75601
|
contractVersion: { type: "number", description: "Remote run payload contract version." },
|
|
75394
75602
|
runId: stringSchema("Remote run id."),
|
|
75395
75603
|
localRunId: stringSchema("Local run id."),
|
|
75396
|
-
run: objectSchema({}, [], "
|
|
75604
|
+
run: objectSchema({}, [], "Compact remote run status by default; full status when detail:true is requested.", true),
|
|
75397
75605
|
nextActions: objectSchema({
|
|
75398
75606
|
poll: stringSchema("Command to poll run status."),
|
|
75399
75607
|
download: stringSchema("Command to download artifacts.")
|
|
75400
|
-
})
|
|
75608
|
+
}),
|
|
75609
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
75401
75610
|
})
|
|
75402
75611
|
},
|
|
75403
75612
|
{
|
|
@@ -75492,13 +75701,25 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75492
75701
|
{
|
|
75493
75702
|
name: "list_schedules",
|
|
75494
75703
|
title: "List Schedules",
|
|
75495
|
-
description: "List scheduled skill runs.",
|
|
75496
|
-
params: [],
|
|
75704
|
+
description: "List scheduled skill runs as a compact paged envelope.",
|
|
75705
|
+
params: ["limit?", "offset?"],
|
|
75497
75706
|
category: "scheduling",
|
|
75498
75707
|
sideEffects: "none",
|
|
75499
75708
|
stable: true,
|
|
75500
|
-
inputSchema: objectSchema(
|
|
75501
|
-
|
|
75709
|
+
inputSchema: objectSchema({
|
|
75710
|
+
limit: { type: "number", minimum: 0 },
|
|
75711
|
+
offset: { type: "number", minimum: 0 }
|
|
75712
|
+
}),
|
|
75713
|
+
outputSchema: objectSchema({
|
|
75714
|
+
schedules: arraySchema(objectSchema({}, [], "Compact schedule record.", true)),
|
|
75715
|
+
total: { type: "number" },
|
|
75716
|
+
offset: { type: "number" },
|
|
75717
|
+
limit: { type: "number" },
|
|
75718
|
+
nextOffset: { type: "number" },
|
|
75719
|
+
hasMore: { type: "boolean" },
|
|
75720
|
+
nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
|
|
75721
|
+
detailHint: stringSchema("How to request complete schedule details.")
|
|
75722
|
+
})
|
|
75502
75723
|
},
|
|
75503
75724
|
{
|
|
75504
75725
|
name: "remove_schedule",
|
|
@@ -75710,7 +75931,7 @@ var init_helpers = __esm(() => {
|
|
|
75710
75931
|
function registerDiscoveryTools(server) {
|
|
75711
75932
|
server.registerTool("list_skills", {
|
|
75712
75933
|
title: "List Skills",
|
|
75713
|
-
description: "List skills with public pricing. Defaults to the
|
|
75934
|
+
description: "List skills with public pricing. Defaults to a compact paged response from the basic profile to avoid context overflow. Set profile:'all' for the full registry, detail:true for full public objects, and use limit/offset to page.",
|
|
75714
75935
|
inputSchema: {
|
|
75715
75936
|
category: exports_external.string().optional(),
|
|
75716
75937
|
profile: exports_external.enum(["basic", "all"]).optional(),
|
|
@@ -75722,16 +75943,20 @@ function registerDiscoveryTools(server) {
|
|
|
75722
75943
|
const selectedProfile = profile || "basic";
|
|
75723
75944
|
const skills = category ? loadRegistryProfile(selectedProfile).filter((s) => s.category === category) : loadRegistryProfile(selectedProfile);
|
|
75724
75945
|
const mapped = detail ? skills.map(getPublicSkillDiscovery) : skills.map(getCompactSkillDiscovery);
|
|
75725
|
-
|
|
75726
|
-
|
|
75727
|
-
|
|
75728
|
-
|
|
75729
|
-
|
|
75730
|
-
|
|
75731
|
-
|
|
75732
|
-
|
|
75733
|
-
|
|
75734
|
-
|
|
75946
|
+
const page = paginate(mapped, {
|
|
75947
|
+
limit: parsePageLimit(limit, DEFAULT_MCP_LIMIT, { max: 100 }),
|
|
75948
|
+
offset: parsePageOffset(offset)
|
|
75949
|
+
});
|
|
75950
|
+
return mcpJson({
|
|
75951
|
+
skills: page.items,
|
|
75952
|
+
total: page.total,
|
|
75953
|
+
offset: page.offset,
|
|
75954
|
+
limit: page.limit,
|
|
75955
|
+
nextOffset: page.nextOffset,
|
|
75956
|
+
hasMore: page.hasMore,
|
|
75957
|
+
nextArguments: page.hasMore ? { profile: selectedProfile, category, detail: Boolean(detail), limit: page.limit, offset: page.nextOffset } : null,
|
|
75958
|
+
detailHint: detail ? undefined : "Set detail:true for full public skill objects, or call get_skill_info for one skill."
|
|
75959
|
+
});
|
|
75735
75960
|
});
|
|
75736
75961
|
server.registerTool("list_pinned_skills", {
|
|
75737
75962
|
title: "List Pinned Skills",
|
|
@@ -75748,7 +75973,7 @@ function registerDiscoveryTools(server) {
|
|
|
75748
75973
|
});
|
|
75749
75974
|
server.registerTool("search_skills", {
|
|
75750
75975
|
title: "Search Skills",
|
|
75751
|
-
description: "Search skills by name, description, or tags. Defaults to the
|
|
75976
|
+
description: "Search skills by name, description, or tags. Defaults to a compact paged response from the basic profile; set profile:'all' for the full registry and detail:true for full public objects.",
|
|
75752
75977
|
inputSchema: {
|
|
75753
75978
|
query: exports_external.string(),
|
|
75754
75979
|
profile: exports_external.enum(["basic", "all"]).optional(),
|
|
@@ -75764,16 +75989,20 @@ function registerDiscoveryTools(server) {
|
|
|
75764
75989
|
if (!cached2)
|
|
75765
75990
|
cacheSet(cacheKey, results);
|
|
75766
75991
|
const out = detail ? results.map(getPublicSkillDiscovery) : results.map(getCompactSkillDiscovery);
|
|
75767
|
-
|
|
75768
|
-
|
|
75769
|
-
|
|
75770
|
-
|
|
75771
|
-
|
|
75772
|
-
|
|
75773
|
-
|
|
75774
|
-
|
|
75775
|
-
|
|
75776
|
-
|
|
75992
|
+
const page = paginate(out, {
|
|
75993
|
+
limit: parsePageLimit(limit, DEFAULT_MCP_LIMIT, { max: 100 }),
|
|
75994
|
+
offset: parsePageOffset(offset)
|
|
75995
|
+
});
|
|
75996
|
+
return mcpJson({
|
|
75997
|
+
skills: page.items,
|
|
75998
|
+
total: page.total,
|
|
75999
|
+
offset: page.offset,
|
|
76000
|
+
limit: page.limit,
|
|
76001
|
+
nextOffset: page.nextOffset,
|
|
76002
|
+
hasMore: page.hasMore,
|
|
76003
|
+
nextArguments: page.hasMore ? { query, profile: selectedProfile, detail: Boolean(detail), limit: page.limit, offset: page.nextOffset } : null,
|
|
76004
|
+
detailHint: detail ? undefined : "Set detail:true for full public skill objects, or call get_skill_info for one skill."
|
|
76005
|
+
});
|
|
75777
76006
|
});
|
|
75778
76007
|
server.registerTool("get_skill_info", {
|
|
75779
76008
|
title: "Get Skill Info",
|
|
@@ -76146,9 +76375,10 @@ function registerOperationTools(server) {
|
|
|
76146
76375
|
name: exports_external.string(),
|
|
76147
76376
|
input: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
|
|
76148
76377
|
args: exports_external.array(exports_external.string()).optional(),
|
|
76149
|
-
approved: exports_external.boolean().optional()
|
|
76378
|
+
approved: exports_external.boolean().optional(),
|
|
76379
|
+
detail: exports_external.boolean().optional()
|
|
76150
76380
|
}
|
|
76151
|
-
}, async ({ name, input, args, approved }) => {
|
|
76381
|
+
}, async ({ name, input, args, approved, detail }) => {
|
|
76152
76382
|
const skill = getSkill(name);
|
|
76153
76383
|
if (!skill) {
|
|
76154
76384
|
return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
|
|
@@ -76214,7 +76444,7 @@ function registerOperationTools(server) {
|
|
|
76214
76444
|
});
|
|
76215
76445
|
writeRunLogs(runContext, "", "");
|
|
76216
76446
|
const remoteRunId = typeof run.id === "string" ? run.id : undefined;
|
|
76217
|
-
|
|
76447
|
+
const payload2 = {
|
|
76218
76448
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
76219
76449
|
id: run.id,
|
|
76220
76450
|
localRunId: localRun2.id,
|
|
@@ -76225,7 +76455,8 @@ function registerOperationTools(server) {
|
|
|
76225
76455
|
remoteRun: run,
|
|
76226
76456
|
run: localRun2,
|
|
76227
76457
|
nextActions: remoteRunNextActions(remoteRunId)
|
|
76228
|
-
}
|
|
76458
|
+
};
|
|
76459
|
+
return mcpJson(detail ? payload2 : compactRunToolPayload(payload2, "Call run_skill again with detail:true for full remote/local run records."));
|
|
76229
76460
|
} catch (err) {
|
|
76230
76461
|
const error48 = `Hosted skill ${skillName} requires hosted access: ${err.message}`;
|
|
76231
76462
|
writeRunLogs(runContext, "", error48 + `
|
|
@@ -76247,23 +76478,23 @@ function registerOperationTools(server) {
|
|
|
76247
76478
|
status: result2.exitCode === 0 ? "completed" : "failed",
|
|
76248
76479
|
error: result2.error
|
|
76249
76480
|
});
|
|
76481
|
+
const payload = { exitCode: result2.exitCode, skill: skillName, stdout: result2.stdout, stderr: result2.stderr, run: localRun };
|
|
76250
76482
|
if (result2.error) {
|
|
76251
76483
|
return {
|
|
76252
|
-
content: [{ type: "text", text: JSON.stringify({
|
|
76484
|
+
content: [{ type: "text", text: JSON.stringify(detail ? { ...payload, error: result2.error } : compactRunToolPayload({ ...payload, error: result2.error }, "Call run_skill again with detail:true for full stdout/stderr and run metadata.")) }],
|
|
76253
76485
|
isError: true
|
|
76254
76486
|
};
|
|
76255
76487
|
}
|
|
76256
|
-
return
|
|
76257
|
-
content: [{ type: "text", text: JSON.stringify({ exitCode: result2.exitCode, skill: skillName, stdout: result2.stdout, stderr: result2.stderr, run: localRun }, null, 2) }]
|
|
76258
|
-
};
|
|
76488
|
+
return mcpJson(detail ? payload : compactRunToolPayload(payload, "Call run_skill again with detail:true for full stdout/stderr and run metadata."));
|
|
76259
76489
|
});
|
|
76260
76490
|
server.registerTool("get_run_status", {
|
|
76261
76491
|
title: "Get Run Status",
|
|
76262
76492
|
description: "Fetch remote run status. Accepts a remote run id or a local run id linked to a remote run.",
|
|
76263
76493
|
inputSchema: {
|
|
76264
|
-
run_id: exports_external.string()
|
|
76494
|
+
run_id: exports_external.string(),
|
|
76495
|
+
detail: exports_external.boolean().optional()
|
|
76265
76496
|
}
|
|
76266
|
-
}, async ({ run_id }) => {
|
|
76497
|
+
}, async ({ run_id, detail }) => {
|
|
76267
76498
|
const { getApiKey: getApiKey2 } = await Promise.resolve().then(() => (init_auth_store(), exports_auth_store));
|
|
76268
76499
|
const apiKey = getApiKey2();
|
|
76269
76500
|
if (!apiKey) {
|
|
@@ -76280,12 +76511,20 @@ function registerOperationTools(server) {
|
|
|
76280
76511
|
const run = await client.getRun(remoteRunId);
|
|
76281
76512
|
if (!run)
|
|
76282
76513
|
return mcpError("RUN_NOT_FOUND", `Remote run '${remoteRunId}' not found`);
|
|
76283
|
-
|
|
76514
|
+
const payload = {
|
|
76284
76515
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
76285
76516
|
runId: remoteRunId,
|
|
76286
76517
|
...localRun ? { localRunId: localRun.id } : {},
|
|
76287
76518
|
run,
|
|
76288
76519
|
nextActions: remoteRunNextActions(remoteRunId)
|
|
76520
|
+
};
|
|
76521
|
+
return mcpJson(detail ? payload : {
|
|
76522
|
+
contractVersion: payload.contractVersion,
|
|
76523
|
+
runId: payload.runId,
|
|
76524
|
+
...localRun ? { localRunId: localRun.id } : {},
|
|
76525
|
+
run: compactRemoteRun(run),
|
|
76526
|
+
nextActions: payload.nextActions,
|
|
76527
|
+
detailHint: "Call get_run_status with detail:true for the complete remote run payload."
|
|
76289
76528
|
});
|
|
76290
76529
|
} catch (err) {
|
|
76291
76530
|
return mcpError("SKILLS_MD_ERROR", err.message);
|
|
@@ -76377,6 +76616,32 @@ function registerOperationTools(server) {
|
|
|
76377
76616
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
76378
76617
|
});
|
|
76379
76618
|
}
|
|
76619
|
+
function compactRunToolPayload(payload, detailHint) {
|
|
76620
|
+
const stdout = previewText(payload.stdout ?? "");
|
|
76621
|
+
const stderr = previewText(payload.stderr ?? "");
|
|
76622
|
+
return {
|
|
76623
|
+
...payload.contractVersion !== undefined ? { contractVersion: payload.contractVersion } : {},
|
|
76624
|
+
...payload.id !== undefined ? { id: payload.id } : {},
|
|
76625
|
+
...payload.localRunId !== undefined ? { localRunId: payload.localRunId } : {},
|
|
76626
|
+
...payload.exitCode !== undefined ? { exitCode: payload.exitCode } : {},
|
|
76627
|
+
skill: payload.skill,
|
|
76628
|
+
...payload.status !== undefined ? { status: payload.status } : {},
|
|
76629
|
+
...payload.remote !== undefined ? { remote: payload.remote } : {},
|
|
76630
|
+
...payload.correlationId !== undefined ? { correlationId: payload.correlationId } : {},
|
|
76631
|
+
...payload.pricing !== undefined ? { pricing: payload.pricing } : {},
|
|
76632
|
+
...payload.error !== undefined ? { error: payload.error } : {},
|
|
76633
|
+
...payload.remoteRun !== undefined ? { remoteRun: compactRemoteRun(payload.remoteRun) } : {},
|
|
76634
|
+
run: compactRunRecord(payload.run),
|
|
76635
|
+
stdoutPreview: stdout,
|
|
76636
|
+
stderrPreview: stderr,
|
|
76637
|
+
stdoutChars: stdout.length,
|
|
76638
|
+
stderrChars: stderr.length,
|
|
76639
|
+
stdoutTruncated: stdout.truncated,
|
|
76640
|
+
stderrTruncated: stderr.truncated,
|
|
76641
|
+
...payload.nextActions !== undefined ? { nextActions: payload.nextActions } : {},
|
|
76642
|
+
detailHint
|
|
76643
|
+
};
|
|
76644
|
+
}
|
|
76380
76645
|
var init_operation_tools = __esm(() => {
|
|
76381
76646
|
init_zod();
|
|
76382
76647
|
init_package();
|
|
@@ -76785,11 +77050,37 @@ function registerScheduleTools(server) {
|
|
|
76785
77050
|
});
|
|
76786
77051
|
server.registerTool("list_schedules", {
|
|
76787
77052
|
title: "List Schedules",
|
|
76788
|
-
description: "List
|
|
76789
|
-
inputSchema: {
|
|
76790
|
-
|
|
77053
|
+
description: "List scheduled skill runs as a compact paged response. Use limit/offset for pagination.",
|
|
77054
|
+
inputSchema: {
|
|
77055
|
+
limit: exports_external.number().optional(),
|
|
77056
|
+
offset: exports_external.number().optional()
|
|
77057
|
+
}
|
|
77058
|
+
}, async ({ limit, offset }) => {
|
|
76791
77059
|
const schedules = listSchedules();
|
|
76792
|
-
|
|
77060
|
+
const page = paginate(schedules, {
|
|
77061
|
+
limit: parsePageLimit(limit, DEFAULT_MCP_LIMIT, { max: 100 }),
|
|
77062
|
+
offset: parsePageOffset(offset)
|
|
77063
|
+
});
|
|
77064
|
+
return mcpJson({
|
|
77065
|
+
schedules: page.items.map((schedule) => ({
|
|
77066
|
+
id: schedule.id,
|
|
77067
|
+
name: schedule.name,
|
|
77068
|
+
skill: schedule.skill,
|
|
77069
|
+
cron: schedule.cron,
|
|
77070
|
+
enabled: schedule.enabled,
|
|
77071
|
+
lastRun: schedule.lastRun,
|
|
77072
|
+
lastRunStatus: schedule.lastRunStatus,
|
|
77073
|
+
nextRun: schedule.nextRun,
|
|
77074
|
+
argCount: schedule.args?.length ?? 0
|
|
77075
|
+
})),
|
|
77076
|
+
total: page.total,
|
|
77077
|
+
offset: page.offset,
|
|
77078
|
+
limit: page.limit,
|
|
77079
|
+
nextOffset: page.nextOffset,
|
|
77080
|
+
hasMore: page.hasMore,
|
|
77081
|
+
nextArguments: page.hasMore ? { limit: page.limit, offset: page.nextOffset } : null,
|
|
77082
|
+
detailHint: "Use schedule state files or future schedule detail commands for complete schedule records."
|
|
77083
|
+
});
|
|
76793
77084
|
});
|
|
76794
77085
|
server.registerTool("remove_schedule", {
|
|
76795
77086
|
title: "Remove Schedule",
|
|
@@ -76845,6 +77136,7 @@ var init_schedule_tools = __esm(() => {
|
|
|
76845
77136
|
init_portable_skills();
|
|
76846
77137
|
init_scheduler();
|
|
76847
77138
|
init_skill_validation();
|
|
77139
|
+
init_helpers();
|
|
76848
77140
|
});
|
|
76849
77141
|
|
|
76850
77142
|
// src/lib/native-storage.ts
|
|
@@ -77627,7 +77919,7 @@ function registerRuntime(parent) {
|
|
|
77627
77919
|
parent.command("quote").argument("<skill>", "Skill name").argument("[args...]", "Arguments that affect pricing, such as --count 8").allowUnknownOption(true).passThroughOptions(true).option("--json", "Output quote as JSON", false).description("Quote a skill run before spending account balance").action((name, args2, options) => handleQuote(name, args2, options));
|
|
77628
77920
|
parent.command("run").argument("<skill>", "Skill name").argument("[args...]", "Arguments to pass to the skill").allowUnknownOption(true).passThroughOptions(true).option("--json", "Output result as JSON", false).option("-y, --yes", "Approve paid hosted execution without an interactive prompt", false).option("--wait", "Poll remote runs until a terminal status", false).option("--poll-interval-ms <ms>", "Remote polling interval in milliseconds", "1000").option("--poll-timeout-ms <ms>", "Maximum time to wait for a remote run", "300000").description("Run a skill directly").action(async (name, args2, options) => handleRun(name, args2, options));
|
|
77629
77921
|
const runs = parent.command("runs").description("Inspect local skill run records");
|
|
77630
|
-
runs.command("list").option("--json", "Output as JSON", false).option("--limit <n>", "Maximum number of runs", "20").description("List recent skill runs").action((options) => handleRunsList(options));
|
|
77922
|
+
runs.command("list").option("--json", "Output as JSON", false).option("--limit <n>", "Maximum number of runs", "20").option("--cursor <n>", "Numeric offset for human-output pagination", "0").description("List recent skill runs").action((options) => handleRunsList(options));
|
|
77631
77923
|
runs.command("show").argument("<run-id>", "Run id").option("--json", "Output as JSON", false).description("Show a skill run record").action((runId, options) => handleRunsShow(runId, options));
|
|
77632
77924
|
runs.command("status").argument("<run-id>", "Remote run id, or local run id linked to a remote run").option("--json", "Output as JSON", false).description("Fetch remote run status").action((runId, options) => handleRunsStatus(runId, options));
|
|
77633
77925
|
const exportsCommand = parent.command("exports").description("Inspect or open skill run exports");
|
|
@@ -77986,22 +78278,32 @@ function writeBlogArticleValidationError(errors4, json2) {
|
|
|
77986
78278
|
process.exitCode = 1;
|
|
77987
78279
|
}
|
|
77988
78280
|
function handleRunsList(options) {
|
|
77989
|
-
const limit = Number.parseInt(options.limit, 10);
|
|
77990
|
-
const runs = listSkillRuns(process.cwd(), Number.isFinite(limit) ? limit : 20);
|
|
77991
78281
|
if (options.json) {
|
|
77992
|
-
|
|
78282
|
+
const jsonLimit = Number.parseInt(options.limit, 10);
|
|
78283
|
+
const runs2 = listSkillRuns(process.cwd(), Number.isFinite(jsonLimit) ? jsonLimit : 20);
|
|
78284
|
+
console.log(JSON.stringify(runs2, null, 2));
|
|
77993
78285
|
return;
|
|
77994
78286
|
}
|
|
78287
|
+
const limit = parsePageLimit(options.limit, DEFAULT_LIST_LIMIT, { allowAll: true });
|
|
78288
|
+
const offset = parsePageOffset(options.cursor);
|
|
78289
|
+
const fetchLimit = Number.isFinite(limit) ? limit + offset + 1 : Number.POSITIVE_INFINITY;
|
|
78290
|
+
const runs = listSkillRuns(process.cwd(), Number.isFinite(fetchLimit) ? fetchLimit : 1e4);
|
|
77995
78291
|
if (!runs.length) {
|
|
77996
78292
|
console.log(source_default.dim("No skill runs found"));
|
|
77997
78293
|
return;
|
|
77998
78294
|
}
|
|
78295
|
+
const hasMoreThanFetched = Number.isFinite(limit) && runs.length > offset + limit;
|
|
78296
|
+
const page = paginate(hasMoreThanFetched ? runs.slice(0, offset + limit) : runs, { limit, offset });
|
|
77999
78297
|
console.log(source_default.bold(`
|
|
78000
|
-
Recent skill runs (${runs.length}):
|
|
78298
|
+
Recent skill runs (${showingLabel(hasMoreThanFetched ? offset + limit + 1 : runs.length, page.items.length, page.offset)}):
|
|
78001
78299
|
`));
|
|
78002
|
-
for (const run of
|
|
78003
|
-
console.log(` ${source_default.cyan(run.id)} ${run.skill} ${statusColor(run.status)} ${source_default.dim(run.startedAt)}`);
|
|
78300
|
+
for (const run of page.items) {
|
|
78301
|
+
console.log(` ${source_default.cyan(run.id)} ${run.skill} ${statusColor(run.status)} ${source_default.dim(run.startedAt)} artifacts:${run.artifacts.length}`);
|
|
78004
78302
|
}
|
|
78303
|
+
if (hasMoreThanFetched)
|
|
78304
|
+
console.log(source_default.dim(`
|
|
78305
|
+
Next: skills runs list --cursor ${offset + page.items.length} --limit ${page.limit}`));
|
|
78306
|
+
console.log(source_default.dim("Details: skills runs show <run-id> or use --json for full run records."));
|
|
78005
78307
|
}
|
|
78006
78308
|
function handleRunsShow(runId, options) {
|
|
78007
78309
|
const run = findSkillRun(runId);
|
|
@@ -78793,7 +79095,7 @@ function registerSchedule(parent) {
|
|
|
78793
79095
|
console.log(source_default.dim(` Next run: ${new Date(schedule.nextRun).toLocaleString()}`));
|
|
78794
79096
|
console.log(source_default.dim(` ID: ${schedule.id}`));
|
|
78795
79097
|
});
|
|
78796
|
-
scheduleCmd.command("list").option("--json", "Output as JSON", false).description("List all scheduled skills").action((options) => {
|
|
79098
|
+
scheduleCmd.command("list").option("--json", "Output as JSON", false).option("--limit <n>", "Maximum rows to print for human output (default: 30, use 0 or all for every row)").option("--cursor <n>", "Numeric offset for human-output pagination", "0").description("List all scheduled skills").action((options) => {
|
|
78797
79099
|
const schedules = listSchedules();
|
|
78798
79100
|
if (options.json) {
|
|
78799
79101
|
console.log(JSON.stringify(schedules));
|
|
@@ -78803,15 +79105,25 @@ function registerSchedule(parent) {
|
|
|
78803
79105
|
console.log(source_default.dim("No schedules. Run: skills schedule add <skill> <cron>"));
|
|
78804
79106
|
return;
|
|
78805
79107
|
}
|
|
79108
|
+
const page = paginate(schedules, {
|
|
79109
|
+
limit: parsePageLimit(options.limit, DEFAULT_LIST_LIMIT, { allowAll: true }),
|
|
79110
|
+
offset: parsePageOffset(options.cursor)
|
|
79111
|
+
});
|
|
78806
79112
|
console.log(source_default.bold(`
|
|
78807
|
-
Scheduled skills (${schedules.length}):
|
|
79113
|
+
Scheduled skills (${showingLabel(schedules.length, page.items.length, page.offset)}):
|
|
78808
79114
|
`));
|
|
78809
|
-
for (const s of
|
|
79115
|
+
for (const s of page.items) {
|
|
78810
79116
|
console.log(` ${source_default.cyan(s.name)} [${s.enabled ? source_default.green("enabled") : source_default.dim("disabled")}]`);
|
|
78811
79117
|
const last2 = s.lastRun ? `last: ${new Date(s.lastRun).toLocaleString()} [${s.lastRunStatus ?? "?"}]` : "never run";
|
|
78812
79118
|
const next = s.nextRun ? `next: ${new Date(s.nextRun).toLocaleString()}` : "";
|
|
78813
|
-
|
|
79119
|
+
const args2 = s.args?.length ? ` args: ${truncateText(s.args.join(" "), 80)}` : "";
|
|
79120
|
+
console.log(source_default.dim(` ${s.id} skill: ${s.skill} cron: ${s.cron} ${last2} ${next}${args2}`));
|
|
78814
79121
|
}
|
|
79122
|
+
if (page.hasMore && page.nextOffset !== null) {
|
|
79123
|
+
console.log(source_default.dim(`
|
|
79124
|
+
Next: skills schedule list --cursor ${page.nextOffset} --limit ${page.limit}`));
|
|
79125
|
+
}
|
|
79126
|
+
console.log(source_default.dim("Details: use --json for complete schedule records."));
|
|
78815
79127
|
});
|
|
78816
79128
|
scheduleCmd.command("remove").argument("<id-or-name>", "Schedule ID or name to remove").option("--json", "Output as JSON", false).description("Remove a schedule").action((idOrName, options) => {
|
|
78817
79129
|
const removed = removeSchedule(idOrName);
|
|
@@ -85280,9 +85592,15 @@ function print(value, json, text) {
|
|
|
85280
85592
|
else
|
|
85281
85593
|
console.log(text);
|
|
85282
85594
|
}
|
|
85595
|
+
function hasJsonOption(options) {
|
|
85596
|
+
return Boolean(options?.json || options?.opts?.().json || options?.optsWithGlobals?.().json || options?.parent?.opts?.().json || options?.parent?.optsWithGlobals?.().json);
|
|
85597
|
+
}
|
|
85598
|
+
function wantsJson(actionOptions, command) {
|
|
85599
|
+
return hasJsonOption(actionOptions) || hasJsonOption(command);
|
|
85600
|
+
}
|
|
85283
85601
|
function registerWebhookCommands(program2, options) {
|
|
85284
85602
|
const webhooks = program2.command(options.webhooksCommandName ?? "webhooks").description("Manage Hasna event webhook subscriptions");
|
|
85285
|
-
webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions) => {
|
|
85603
|
+
webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions, command) => {
|
|
85286
85604
|
const timestamp = new Date().toISOString();
|
|
85287
85605
|
const channel = {
|
|
85288
85606
|
id: actionOptions.id,
|
|
@@ -85303,11 +85621,11 @@ function registerWebhookCommands(program2, options) {
|
|
|
85303
85621
|
throw new Error(`Transport ${actionOptions.transport} is reserved for future use and cannot be added yet`);
|
|
85304
85622
|
}
|
|
85305
85623
|
const saved = await createClient(options).addChannel(channel);
|
|
85306
|
-
print(sanitizeChannelForOutput(saved),
|
|
85624
|
+
print(sanitizeChannelForOutput(saved), wantsJson(actionOptions, command), `Added ${saved.transport} channel ${saved.id}`);
|
|
85307
85625
|
});
|
|
85308
|
-
webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
85626
|
+
webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
85309
85627
|
const channels = await createClient(options).listChannels();
|
|
85310
|
-
if (actionOptions
|
|
85628
|
+
if (wantsJson(actionOptions, command)) {
|
|
85311
85629
|
console.log(JSON.stringify(sanitizeChannelsForOutput(channels), null, 2));
|
|
85312
85630
|
return;
|
|
85313
85631
|
}
|
|
@@ -85319,11 +85637,11 @@ function registerWebhookCommands(program2, options) {
|
|
|
85319
85637
|
console.log(`${channel.id} ${channel.enabled ? "enabled" : "disabled"} ${channel.transport} ${channel.webhook?.url ?? channel.command?.command ?? channel.transport}`);
|
|
85320
85638
|
}
|
|
85321
85639
|
});
|
|
85322
|
-
webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
|
|
85640
|
+
webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
|
|
85323
85641
|
const removed = await createClient(options).removeChannel(id);
|
|
85324
|
-
print({ removed },
|
|
85642
|
+
print({ removed }, wantsJson(actionOptions, command), removed ? `Removed ${id}` : `Channel not found: ${id}`);
|
|
85325
85643
|
});
|
|
85326
|
-
webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
|
|
85644
|
+
webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
|
|
85327
85645
|
const result2 = await createClient(options).testChannel(id, {
|
|
85328
85646
|
source: options.source,
|
|
85329
85647
|
type: actionOptions.type,
|
|
@@ -85331,13 +85649,13 @@ function registerWebhookCommands(program2, options) {
|
|
|
85331
85649
|
message: actionOptions.message,
|
|
85332
85650
|
data: parseJsonObject(actionOptions.data, { test: true })
|
|
85333
85651
|
});
|
|
85334
|
-
print(result2,
|
|
85652
|
+
print(result2, wantsJson(actionOptions, command), `${result2.status}: ${result2.channelId}`);
|
|
85335
85653
|
});
|
|
85336
85654
|
return webhooks;
|
|
85337
85655
|
}
|
|
85338
85656
|
function registerEventCommands(program2, options) {
|
|
85339
85657
|
const events = program2.command(options.eventsCommandName ?? "events").description("Emit, list, and replay Hasna events");
|
|
85340
|
-
events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions) => {
|
|
85658
|
+
events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions, command) => {
|
|
85341
85659
|
const result2 = await createClient(options).emit({
|
|
85342
85660
|
source: actionOptions.source ?? options.source,
|
|
85343
85661
|
type,
|
|
@@ -85348,9 +85666,9 @@ function registerEventCommands(program2, options) {
|
|
|
85348
85666
|
data: parseJsonObject(actionOptions.data, {}),
|
|
85349
85667
|
metadata: parseJsonObject(actionOptions.metadata, {})
|
|
85350
85668
|
}, { deliver: actionOptions.deliver, dedupe: actionOptions.dedupe });
|
|
85351
|
-
print(result2,
|
|
85669
|
+
print(result2, wantsJson(actionOptions, command), `${result2.deduped ? "Deduped" : "Emitted"} ${result2.event.id} to ${result2.deliveries.length} channel(s)`);
|
|
85352
85670
|
});
|
|
85353
|
-
events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
85671
|
+
events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
85354
85672
|
let rows = await createClient(options).listEvents();
|
|
85355
85673
|
if (actionOptions.source)
|
|
85356
85674
|
rows = rows.filter((event) => event.source === actionOptions.source);
|
|
@@ -85358,7 +85676,7 @@ function registerEventCommands(program2, options) {
|
|
|
85358
85676
|
rows = rows.filter((event) => event.type === actionOptions.type);
|
|
85359
85677
|
if (actionOptions.limit)
|
|
85360
85678
|
rows = rows.slice(-actionOptions.limit);
|
|
85361
|
-
if (actionOptions
|
|
85679
|
+
if (wantsJson(actionOptions, command)) {
|
|
85362
85680
|
console.log(JSON.stringify(rows, null, 2));
|
|
85363
85681
|
return;
|
|
85364
85682
|
}
|
|
@@ -85369,14 +85687,14 @@ function registerEventCommands(program2, options) {
|
|
|
85369
85687
|
for (const event of rows)
|
|
85370
85688
|
console.log(`${event.time} ${event.id} ${event.source} ${event.type} ${event.severity}`);
|
|
85371
85689
|
});
|
|
85372
|
-
events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
85690
|
+
events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
85373
85691
|
const result2 = await createClient(options).replay({
|
|
85374
85692
|
eventId: actionOptions.id,
|
|
85375
85693
|
source: actionOptions.source,
|
|
85376
85694
|
type: actionOptions.type,
|
|
85377
85695
|
dryRun: actionOptions.dryRun
|
|
85378
85696
|
});
|
|
85379
|
-
print(result2,
|
|
85697
|
+
print(result2, wantsJson(actionOptions, command), `Replayed ${result2.events.length} event(s), ${result2.deliveries.length} delivery result(s)`);
|
|
85380
85698
|
});
|
|
85381
85699
|
return events;
|
|
85382
85700
|
}
|