@hasna/skills 0.1.46 → 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 +432 -149
- package/bin/mcp.js +262 -66
- package/dist/index.js +71 -29
- 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" },
|
|
@@ -40616,9 +40617,9 @@ var init_media_processing = __esm(() => {
|
|
|
40616
40617
|
{
|
|
40617
40618
|
name: "transcript",
|
|
40618
40619
|
displayName: "Transcript",
|
|
40619
|
-
description: "
|
|
40620
|
+
description: "Transcribe audio, video, and media URLs with OpenAI GPT-4o, ElevenLabs Scribe v2, DeepGram, or hosted runtime",
|
|
40620
40621
|
category: "Media Processing",
|
|
40621
|
-
tags: ["transcript", "audio", "video", "speech-to-text"]
|
|
40622
|
+
tags: ["transcript", "audio", "video", "speech-to-text", "diarization", "youtube"]
|
|
40622
40623
|
},
|
|
40623
40624
|
{
|
|
40624
40625
|
name: "video-cut-suggester",
|
|
@@ -54491,7 +54492,7 @@ function finalize(ctx, schema) {
|
|
|
54491
54492
|
result2.$schema = "http://json-schema.org/draft-07/schema#";
|
|
54492
54493
|
} else if (ctx.target === "draft-04") {
|
|
54493
54494
|
result2.$schema = "http://json-schema.org/draft-04/schema#";
|
|
54494
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
54495
|
+
} else if (ctx.target === "openapi-3.0") {} else {}
|
|
54495
54496
|
if (ctx.external?.uri) {
|
|
54496
54497
|
const id = ctx.external.registry.get(schema)?.id;
|
|
54497
54498
|
if (!id)
|
|
@@ -54756,7 +54757,7 @@ var formatMap, stringProcessor = (schema, ctx, _json, _params) => {
|
|
|
54756
54757
|
if (val === undefined) {
|
|
54757
54758
|
if (ctx.unrepresentable === "throw") {
|
|
54758
54759
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
54759
|
-
}
|
|
54760
|
+
} else {}
|
|
54760
54761
|
} else if (typeof val === "bigint") {
|
|
54761
54762
|
if (ctx.unrepresentable === "throw") {
|
|
54762
54763
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -58086,30 +58087,119 @@ var init_install = __esm(() => {
|
|
|
58086
58087
|
init_installer();
|
|
58087
58088
|
});
|
|
58088
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
|
+
|
|
58089
58177
|
// src/cli/commands/list.ts
|
|
58090
58178
|
var exports_list = {};
|
|
58091
58179
|
__export(exports_list, {
|
|
58092
58180
|
registerBrowse: () => registerBrowse
|
|
58093
58181
|
});
|
|
58094
58182
|
function registerBrowse(parent) {
|
|
58095
|
-
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) => {
|
|
58096
58184
|
return handleList(options).catch(handleBrowseError);
|
|
58097
58185
|
});
|
|
58098
|
-
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) => {
|
|
58099
58187
|
return handleSearch(query, options).catch(handleBrowseError);
|
|
58100
58188
|
});
|
|
58101
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) => {
|
|
58102
58190
|
return handleCategories(options).catch(handleBrowseError);
|
|
58103
58191
|
});
|
|
58104
|
-
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) => {
|
|
58105
58193
|
return handleTags(options).catch(handleBrowseError);
|
|
58106
58194
|
});
|
|
58107
58195
|
}
|
|
58108
58196
|
function formatBrief(skill) {
|
|
58109
|
-
return `${skill.name} \u2014 ${skill.description} (${publicDiscoveryPriceLabel(skill)}) [${skill.category}]`;
|
|
58197
|
+
return `${skill.name} \u2014 ${truncateText(skill.description, 110)} (${publicDiscoveryPriceLabel(skill)}) [${skill.category}]`;
|
|
58110
58198
|
}
|
|
58111
|
-
function formatSkillLine(skill) {
|
|
58112
|
-
|
|
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}`;
|
|
58113
58203
|
}
|
|
58114
58204
|
function enrichDiscovery(skills) {
|
|
58115
58205
|
return skills.map(getPublicSkillDiscovery);
|
|
@@ -58149,6 +58239,8 @@ async function handleList(options) {
|
|
|
58149
58239
|
const fmt = !options.json ? options.format : undefined;
|
|
58150
58240
|
const profile = options.all ? "all" : "basic";
|
|
58151
58241
|
const registry2 = await getBrowseRegistry(options);
|
|
58242
|
+
const limit = parsePageLimit(options.limit, DEFAULT_LIST_LIMIT, { allowAll: true });
|
|
58243
|
+
const offset = parsePageOffset(options.cursor);
|
|
58152
58244
|
if (options.pinned) {
|
|
58153
58245
|
const installed = getInstalledSkills();
|
|
58154
58246
|
if (options.json) {
|
|
@@ -58172,14 +58264,16 @@ async function handleList(options) {
|
|
|
58172
58264
|
}
|
|
58173
58265
|
const meta3 = getInstallMeta();
|
|
58174
58266
|
const registry3 = loadRegistry();
|
|
58267
|
+
const page2 = paginate(installed, { limit, offset });
|
|
58175
58268
|
console.log(source_default.bold(`
|
|
58176
|
-
Pinned skills (${installed.length}):
|
|
58269
|
+
Pinned skills (${showingLabel(installed.length, page2.items.length, page2.offset)}):
|
|
58177
58270
|
`));
|
|
58178
|
-
for (const name of
|
|
58271
|
+
for (const name of page2.items) {
|
|
58179
58272
|
const m = meta3.skills[name];
|
|
58180
58273
|
const s = registry3.find((r) => r.name === name);
|
|
58181
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()) : ""}`);
|
|
58182
58275
|
}
|
|
58276
|
+
printPageHint(page2, "skills list --pinned");
|
|
58183
58277
|
return;
|
|
58184
58278
|
}
|
|
58185
58279
|
const tagFilter = options.tags ? options.tags.split(",").map((t) => t.trim().toLowerCase()).filter(Boolean) : null;
|
|
@@ -58200,16 +58294,19 @@ Available: ${categories.join(", ")}`);
|
|
|
58200
58294
|
await writeJson(output, 2);
|
|
58201
58295
|
return;
|
|
58202
58296
|
}
|
|
58297
|
+
const page2 = paginate(output, { limit, offset });
|
|
58203
58298
|
if (brief) {
|
|
58204
|
-
for (const s of
|
|
58299
|
+
for (const s of page2.items)
|
|
58205
58300
|
console.log(formatBrief(s));
|
|
58301
|
+
printPageHint(page2, listCommand(options));
|
|
58206
58302
|
return;
|
|
58207
58303
|
}
|
|
58208
58304
|
console.log(source_default.bold(`
|
|
58209
|
-
${category} (${
|
|
58305
|
+
${category} (${showingLabel(output.length, page2.items.length, page2.offset)}):
|
|
58210
58306
|
`));
|
|
58211
|
-
for (const s of
|
|
58212
|
-
console.log(formatSkillLine(s));
|
|
58307
|
+
for (const s of page2.items)
|
|
58308
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58309
|
+
printSkillHint(page2, listCommand(options));
|
|
58213
58310
|
return;
|
|
58214
58311
|
}
|
|
58215
58312
|
if (tagFilter) {
|
|
@@ -58219,16 +58316,19 @@ ${category} (${skills.length}):
|
|
|
58219
58316
|
await writeJson(output, 2);
|
|
58220
58317
|
return;
|
|
58221
58318
|
}
|
|
58319
|
+
const page2 = paginate(output, { limit, offset });
|
|
58222
58320
|
if (brief) {
|
|
58223
|
-
for (const s of
|
|
58321
|
+
for (const s of page2.items)
|
|
58224
58322
|
console.log(formatBrief(s));
|
|
58323
|
+
printPageHint(page2, listCommand(options));
|
|
58225
58324
|
return;
|
|
58226
58325
|
}
|
|
58227
58326
|
console.log(source_default.bold(`
|
|
58228
|
-
Skills matching tags [${tagFilter.join(", ")}] (${
|
|
58327
|
+
Skills matching tags [${tagFilter.join(", ")}] (${showingLabel(output.length, page2.items.length, page2.offset)}):
|
|
58229
58328
|
`));
|
|
58230
|
-
for (const s of
|
|
58231
|
-
console.log(
|
|
58329
|
+
for (const s of page2.items)
|
|
58330
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58331
|
+
printSkillHint(page2, listCommand(options));
|
|
58232
58332
|
return;
|
|
58233
58333
|
}
|
|
58234
58334
|
const allSkills = enrichDiscovery(registry2);
|
|
@@ -58250,28 +58350,21 @@ Skills matching tags [${tagFilter.join(", ")}] (${skills.length}):
|
|
|
58250
58350
|
return;
|
|
58251
58351
|
}
|
|
58252
58352
|
if (brief) {
|
|
58253
|
-
|
|
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)
|
|
58254
58356
|
console.log(formatBrief(s));
|
|
58357
|
+
printPageHint(page2, listCommand(options));
|
|
58255
58358
|
return;
|
|
58256
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 });
|
|
58257
58362
|
console.log(source_default.bold(`
|
|
58258
|
-
Available ${profile === "basic" ? "default " : ""}skills (${allSkills.length}):
|
|
58363
|
+
Available ${profile === "basic" ? "default " : ""}skills (${showingLabel(allSkills.length, page.items.length, page.offset)}):
|
|
58259
58364
|
`));
|
|
58260
|
-
for (const
|
|
58261
|
-
|
|
58262
|
-
|
|
58263
|
-
continue;
|
|
58264
|
-
console.log(source_default.bold(`${category} (${skills.length}):`));
|
|
58265
|
-
for (const s of skills)
|
|
58266
|
-
console.log(formatSkillLine(s));
|
|
58267
|
-
console.log();
|
|
58268
|
-
}
|
|
58269
|
-
const customUncategorized = allSkills.filter((s) => s.source === "custom" && !CATEGORIES.includes(s.category));
|
|
58270
|
-
if (customUncategorized.length > 0) {
|
|
58271
|
-
console.log(source_default.bold(`Custom (${customUncategorized.length}):`));
|
|
58272
|
-
for (const s of customUncategorized)
|
|
58273
|
-
console.log(` ${source_default.yellow(s.name)} ${source_default.dim(`(${publicDiscoveryPriceLabel(s)})`)} - ${s.description}`);
|
|
58274
|
-
}
|
|
58365
|
+
for (const s of page.items)
|
|
58366
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58367
|
+
printSkillHint(page, listCommand(options));
|
|
58275
58368
|
}
|
|
58276
58369
|
async function handleSearch(query, options) {
|
|
58277
58370
|
const registry2 = await getBrowseRegistry(options);
|
|
@@ -58318,19 +58411,22 @@ Available: ${categories.join(", ")}`);
|
|
|
58318
58411
|
}
|
|
58319
58412
|
return;
|
|
58320
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 });
|
|
58321
58417
|
if (brief) {
|
|
58322
|
-
for (const s of
|
|
58418
|
+
for (const s of page.items)
|
|
58323
58419
|
console.log(formatBrief(s));
|
|
58420
|
+
printPageHint(page, searchCommand(query, options));
|
|
58324
58421
|
return;
|
|
58325
58422
|
}
|
|
58326
58423
|
console.log(source_default.bold(`
|
|
58327
|
-
Found ${output.length}
|
|
58424
|
+
Found ${skillCountLabel(output.length, page.items.length, page.offset)} for "${query}":
|
|
58328
58425
|
`));
|
|
58329
|
-
for (const s of
|
|
58330
|
-
console.log(
|
|
58331
|
-
console.log(` ${source_default.dim("Price:")} ${publicDiscoveryPriceLabel(s)}`);
|
|
58332
|
-
console.log(` ${s.description}`);
|
|
58426
|
+
for (const s of page.items) {
|
|
58427
|
+
console.log(formatSkillLine(s, { verbose: options.verbose }));
|
|
58333
58428
|
}
|
|
58429
|
+
printSkillHint(page, searchCommand(query, options));
|
|
58334
58430
|
}
|
|
58335
58431
|
async function handleCategories(options) {
|
|
58336
58432
|
const registry2 = await getBrowseRegistry({ all: true, remote: options.remote });
|
|
@@ -58359,11 +58455,60 @@ async function handleTags(options) {
|
|
|
58359
58455
|
await writeJson(sorted, 2);
|
|
58360
58456
|
return;
|
|
58361
58457
|
}
|
|
58458
|
+
const page = paginate(sorted, {
|
|
58459
|
+
limit: parsePageLimit(options.limit, DEFAULT_TAG_LIMIT, { allowAll: true }),
|
|
58460
|
+
offset: parsePageOffset(options.cursor)
|
|
58461
|
+
});
|
|
58362
58462
|
console.log(source_default.bold(`
|
|
58363
|
-
Tags:
|
|
58463
|
+
Tags: ${showingLabel(sorted.length, page.items.length, page.offset)}
|
|
58364
58464
|
`));
|
|
58365
|
-
for (const { name, count } of
|
|
58465
|
+
for (const { name, count } of page.items)
|
|
58366
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)`;
|
|
58367
58512
|
}
|
|
58368
58513
|
var init_list = __esm(() => {
|
|
58369
58514
|
init_source();
|
|
@@ -75177,18 +75322,29 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75177
75322
|
exitCode: { type: "number", description: "Process exit code for local runs." },
|
|
75178
75323
|
skill: stringSchema("Canonical skill slug."),
|
|
75179
75324
|
remote: { type: "boolean", description: "Whether the skill was submitted to the hosted runtime." },
|
|
75180
|
-
|
|
75181
|
-
|
|
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."),
|
|
75182
75337
|
id: stringSchema("Remote run id when submitted remotely."),
|
|
75183
75338
|
localRunId: stringSchema("Local run metadata id."),
|
|
75184
75339
|
status: stringSchema("Run lifecycle status."),
|
|
75185
75340
|
pricing: pricingSchema,
|
|
75186
|
-
remoteRun: objectSchema({}, [], "
|
|
75187
|
-
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),
|
|
75188
75343
|
nextActions: objectSchema({
|
|
75189
75344
|
poll: stringSchema("Command to poll run status."),
|
|
75190
75345
|
download: stringSchema("Command to download artifacts.")
|
|
75191
|
-
})
|
|
75346
|
+
}),
|
|
75347
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
75192
75348
|
}, [], "Skill run result.");
|
|
75193
75349
|
toolContracts = [
|
|
75194
75350
|
{
|
|
@@ -75236,7 +75392,7 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75236
75392
|
{
|
|
75237
75393
|
name: "list_skills",
|
|
75238
75394
|
title: "List Skills",
|
|
75239
|
-
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.",
|
|
75240
75396
|
params: ["category?", "profile?", "detail?", "limit?", "offset?"],
|
|
75241
75397
|
category: "discovery",
|
|
75242
75398
|
sideEffects: "none",
|
|
@@ -75252,7 +75408,11 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75252
75408
|
skills: arraySchema(skillSummarySchema),
|
|
75253
75409
|
total: { type: "number" },
|
|
75254
75410
|
offset: { type: "number" },
|
|
75255
|
-
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.")
|
|
75256
75416
|
})
|
|
75257
75417
|
},
|
|
75258
75418
|
{
|
|
@@ -75273,7 +75433,7 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75273
75433
|
{
|
|
75274
75434
|
name: "search_skills",
|
|
75275
75435
|
title: "Search Skills",
|
|
75276
|
-
description: "Search skills by name, description, or tags.",
|
|
75436
|
+
description: "Search skills by name, description, or tags. Returns a compact paged envelope by default.",
|
|
75277
75437
|
params: ["query", "profile?", "detail?", "limit?", "offset?"],
|
|
75278
75438
|
category: "discovery",
|
|
75279
75439
|
sideEffects: "none",
|
|
@@ -75285,7 +75445,16 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75285
75445
|
limit: { type: "number", minimum: 0 },
|
|
75286
75446
|
offset: { type: "number", minimum: 0 }
|
|
75287
75447
|
}, ["query"]),
|
|
75288
|
-
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
|
+
})
|
|
75289
75458
|
},
|
|
75290
75459
|
{
|
|
75291
75460
|
name: "get_skill_info",
|
|
@@ -75402,8 +75571,8 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75402
75571
|
{
|
|
75403
75572
|
name: "run_skill",
|
|
75404
75573
|
title: "Run Skill",
|
|
75405
|
-
description: "Run a skill locally or through a configured remote runner.",
|
|
75406
|
-
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?"],
|
|
75407
75576
|
category: "execution",
|
|
75408
75577
|
sideEffects: "local-process-or-remote-run",
|
|
75409
75578
|
stable: true,
|
|
@@ -75411,28 +75580,33 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75411
75580
|
name: skillNameInput,
|
|
75412
75581
|
input: runInputSchema,
|
|
75413
75582
|
args: runArgsSchema,
|
|
75414
|
-
approved: paidRunApprovalSchema
|
|
75583
|
+
approved: paidRunApprovalSchema,
|
|
75584
|
+
detail: { type: "boolean", default: false, description: "Return full stdout/stderr, remote run, and local run metadata." }
|
|
75415
75585
|
}, ["name"]),
|
|
75416
75586
|
outputSchema: runOutputSchema
|
|
75417
75587
|
},
|
|
75418
75588
|
{
|
|
75419
75589
|
name: "get_run_status",
|
|
75420
75590
|
title: "Get Run Status",
|
|
75421
|
-
description: "Fetch remote run status and next actions.",
|
|
75422
|
-
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?"],
|
|
75423
75593
|
category: "execution",
|
|
75424
75594
|
sideEffects: "none",
|
|
75425
75595
|
stable: true,
|
|
75426
|
-
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"]),
|
|
75427
75600
|
outputSchema: objectSchema({
|
|
75428
75601
|
contractVersion: { type: "number", description: "Remote run payload contract version." },
|
|
75429
75602
|
runId: stringSchema("Remote run id."),
|
|
75430
75603
|
localRunId: stringSchema("Local run id."),
|
|
75431
|
-
run: objectSchema({}, [], "
|
|
75604
|
+
run: objectSchema({}, [], "Compact remote run status by default; full status when detail:true is requested.", true),
|
|
75432
75605
|
nextActions: objectSchema({
|
|
75433
75606
|
poll: stringSchema("Command to poll run status."),
|
|
75434
75607
|
download: stringSchema("Command to download artifacts.")
|
|
75435
|
-
})
|
|
75608
|
+
}),
|
|
75609
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
75436
75610
|
})
|
|
75437
75611
|
},
|
|
75438
75612
|
{
|
|
@@ -75527,13 +75701,25 @@ var init_mcp_contracts = __esm(() => {
|
|
|
75527
75701
|
{
|
|
75528
75702
|
name: "list_schedules",
|
|
75529
75703
|
title: "List Schedules",
|
|
75530
|
-
description: "List scheduled skill runs.",
|
|
75531
|
-
params: [],
|
|
75704
|
+
description: "List scheduled skill runs as a compact paged envelope.",
|
|
75705
|
+
params: ["limit?", "offset?"],
|
|
75532
75706
|
category: "scheduling",
|
|
75533
75707
|
sideEffects: "none",
|
|
75534
75708
|
stable: true,
|
|
75535
|
-
inputSchema: objectSchema(
|
|
75536
|
-
|
|
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
|
+
})
|
|
75537
75723
|
},
|
|
75538
75724
|
{
|
|
75539
75725
|
name: "remove_schedule",
|
|
@@ -75745,7 +75931,7 @@ var init_helpers = __esm(() => {
|
|
|
75745
75931
|
function registerDiscoveryTools(server) {
|
|
75746
75932
|
server.registerTool("list_skills", {
|
|
75747
75933
|
title: "List Skills",
|
|
75748
|
-
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.",
|
|
75749
75935
|
inputSchema: {
|
|
75750
75936
|
category: exports_external.string().optional(),
|
|
75751
75937
|
profile: exports_external.enum(["basic", "all"]).optional(),
|
|
@@ -75757,16 +75943,20 @@ function registerDiscoveryTools(server) {
|
|
|
75757
75943
|
const selectedProfile = profile || "basic";
|
|
75758
75944
|
const skills = category ? loadRegistryProfile(selectedProfile).filter((s) => s.category === category) : loadRegistryProfile(selectedProfile);
|
|
75759
75945
|
const mapped = detail ? skills.map(getPublicSkillDiscovery) : skills.map(getCompactSkillDiscovery);
|
|
75760
|
-
|
|
75761
|
-
|
|
75762
|
-
|
|
75763
|
-
|
|
75764
|
-
|
|
75765
|
-
|
|
75766
|
-
|
|
75767
|
-
|
|
75768
|
-
|
|
75769
|
-
|
|
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
|
+
});
|
|
75770
75960
|
});
|
|
75771
75961
|
server.registerTool("list_pinned_skills", {
|
|
75772
75962
|
title: "List Pinned Skills",
|
|
@@ -75783,7 +75973,7 @@ function registerDiscoveryTools(server) {
|
|
|
75783
75973
|
});
|
|
75784
75974
|
server.registerTool("search_skills", {
|
|
75785
75975
|
title: "Search Skills",
|
|
75786
|
-
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.",
|
|
75787
75977
|
inputSchema: {
|
|
75788
75978
|
query: exports_external.string(),
|
|
75789
75979
|
profile: exports_external.enum(["basic", "all"]).optional(),
|
|
@@ -75799,16 +75989,20 @@ function registerDiscoveryTools(server) {
|
|
|
75799
75989
|
if (!cached2)
|
|
75800
75990
|
cacheSet(cacheKey, results);
|
|
75801
75991
|
const out = detail ? results.map(getPublicSkillDiscovery) : results.map(getCompactSkillDiscovery);
|
|
75802
|
-
|
|
75803
|
-
|
|
75804
|
-
|
|
75805
|
-
|
|
75806
|
-
|
|
75807
|
-
|
|
75808
|
-
|
|
75809
|
-
|
|
75810
|
-
|
|
75811
|
-
|
|
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
|
+
});
|
|
75812
76006
|
});
|
|
75813
76007
|
server.registerTool("get_skill_info", {
|
|
75814
76008
|
title: "Get Skill Info",
|
|
@@ -76181,9 +76375,10 @@ function registerOperationTools(server) {
|
|
|
76181
76375
|
name: exports_external.string(),
|
|
76182
76376
|
input: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
|
|
76183
76377
|
args: exports_external.array(exports_external.string()).optional(),
|
|
76184
|
-
approved: exports_external.boolean().optional()
|
|
76378
|
+
approved: exports_external.boolean().optional(),
|
|
76379
|
+
detail: exports_external.boolean().optional()
|
|
76185
76380
|
}
|
|
76186
|
-
}, async ({ name, input, args, approved }) => {
|
|
76381
|
+
}, async ({ name, input, args, approved, detail }) => {
|
|
76187
76382
|
const skill = getSkill(name);
|
|
76188
76383
|
if (!skill) {
|
|
76189
76384
|
return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
|
|
@@ -76249,7 +76444,7 @@ function registerOperationTools(server) {
|
|
|
76249
76444
|
});
|
|
76250
76445
|
writeRunLogs(runContext, "", "");
|
|
76251
76446
|
const remoteRunId = typeof run.id === "string" ? run.id : undefined;
|
|
76252
|
-
|
|
76447
|
+
const payload2 = {
|
|
76253
76448
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
76254
76449
|
id: run.id,
|
|
76255
76450
|
localRunId: localRun2.id,
|
|
@@ -76260,7 +76455,8 @@ function registerOperationTools(server) {
|
|
|
76260
76455
|
remoteRun: run,
|
|
76261
76456
|
run: localRun2,
|
|
76262
76457
|
nextActions: remoteRunNextActions(remoteRunId)
|
|
76263
|
-
}
|
|
76458
|
+
};
|
|
76459
|
+
return mcpJson(detail ? payload2 : compactRunToolPayload(payload2, "Call run_skill again with detail:true for full remote/local run records."));
|
|
76264
76460
|
} catch (err) {
|
|
76265
76461
|
const error48 = `Hosted skill ${skillName} requires hosted access: ${err.message}`;
|
|
76266
76462
|
writeRunLogs(runContext, "", error48 + `
|
|
@@ -76282,23 +76478,23 @@ function registerOperationTools(server) {
|
|
|
76282
76478
|
status: result2.exitCode === 0 ? "completed" : "failed",
|
|
76283
76479
|
error: result2.error
|
|
76284
76480
|
});
|
|
76481
|
+
const payload = { exitCode: result2.exitCode, skill: skillName, stdout: result2.stdout, stderr: result2.stderr, run: localRun };
|
|
76285
76482
|
if (result2.error) {
|
|
76286
76483
|
return {
|
|
76287
|
-
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.")) }],
|
|
76288
76485
|
isError: true
|
|
76289
76486
|
};
|
|
76290
76487
|
}
|
|
76291
|
-
return
|
|
76292
|
-
content: [{ type: "text", text: JSON.stringify({ exitCode: result2.exitCode, skill: skillName, stdout: result2.stdout, stderr: result2.stderr, run: localRun }, null, 2) }]
|
|
76293
|
-
};
|
|
76488
|
+
return mcpJson(detail ? payload : compactRunToolPayload(payload, "Call run_skill again with detail:true for full stdout/stderr and run metadata."));
|
|
76294
76489
|
});
|
|
76295
76490
|
server.registerTool("get_run_status", {
|
|
76296
76491
|
title: "Get Run Status",
|
|
76297
76492
|
description: "Fetch remote run status. Accepts a remote run id or a local run id linked to a remote run.",
|
|
76298
76493
|
inputSchema: {
|
|
76299
|
-
run_id: exports_external.string()
|
|
76494
|
+
run_id: exports_external.string(),
|
|
76495
|
+
detail: exports_external.boolean().optional()
|
|
76300
76496
|
}
|
|
76301
|
-
}, async ({ run_id }) => {
|
|
76497
|
+
}, async ({ run_id, detail }) => {
|
|
76302
76498
|
const { getApiKey: getApiKey2 } = await Promise.resolve().then(() => (init_auth_store(), exports_auth_store));
|
|
76303
76499
|
const apiKey = getApiKey2();
|
|
76304
76500
|
if (!apiKey) {
|
|
@@ -76315,12 +76511,20 @@ function registerOperationTools(server) {
|
|
|
76315
76511
|
const run = await client.getRun(remoteRunId);
|
|
76316
76512
|
if (!run)
|
|
76317
76513
|
return mcpError("RUN_NOT_FOUND", `Remote run '${remoteRunId}' not found`);
|
|
76318
|
-
|
|
76514
|
+
const payload = {
|
|
76319
76515
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
76320
76516
|
runId: remoteRunId,
|
|
76321
76517
|
...localRun ? { localRunId: localRun.id } : {},
|
|
76322
76518
|
run,
|
|
76323
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."
|
|
76324
76528
|
});
|
|
76325
76529
|
} catch (err) {
|
|
76326
76530
|
return mcpError("SKILLS_MD_ERROR", err.message);
|
|
@@ -76412,6 +76616,32 @@ function registerOperationTools(server) {
|
|
|
76412
76616
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
76413
76617
|
});
|
|
76414
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
|
+
}
|
|
76415
76645
|
var init_operation_tools = __esm(() => {
|
|
76416
76646
|
init_zod();
|
|
76417
76647
|
init_package();
|
|
@@ -76820,11 +77050,37 @@ function registerScheduleTools(server) {
|
|
|
76820
77050
|
});
|
|
76821
77051
|
server.registerTool("list_schedules", {
|
|
76822
77052
|
title: "List Schedules",
|
|
76823
|
-
description: "List
|
|
76824
|
-
inputSchema: {
|
|
76825
|
-
|
|
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 }) => {
|
|
76826
77059
|
const schedules = listSchedules();
|
|
76827
|
-
|
|
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
|
+
});
|
|
76828
77084
|
});
|
|
76829
77085
|
server.registerTool("remove_schedule", {
|
|
76830
77086
|
title: "Remove Schedule",
|
|
@@ -76880,6 +77136,7 @@ var init_schedule_tools = __esm(() => {
|
|
|
76880
77136
|
init_portable_skills();
|
|
76881
77137
|
init_scheduler();
|
|
76882
77138
|
init_skill_validation();
|
|
77139
|
+
init_helpers();
|
|
76883
77140
|
});
|
|
76884
77141
|
|
|
76885
77142
|
// src/lib/native-storage.ts
|
|
@@ -77662,7 +77919,7 @@ function registerRuntime(parent) {
|
|
|
77662
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));
|
|
77663
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));
|
|
77664
77921
|
const runs = parent.command("runs").description("Inspect local skill run records");
|
|
77665
|
-
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));
|
|
77666
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));
|
|
77667
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));
|
|
77668
77925
|
const exportsCommand = parent.command("exports").description("Inspect or open skill run exports");
|
|
@@ -78021,22 +78278,32 @@ function writeBlogArticleValidationError(errors4, json2) {
|
|
|
78021
78278
|
process.exitCode = 1;
|
|
78022
78279
|
}
|
|
78023
78280
|
function handleRunsList(options) {
|
|
78024
|
-
const limit = Number.parseInt(options.limit, 10);
|
|
78025
|
-
const runs = listSkillRuns(process.cwd(), Number.isFinite(limit) ? limit : 20);
|
|
78026
78281
|
if (options.json) {
|
|
78027
|
-
|
|
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));
|
|
78028
78285
|
return;
|
|
78029
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);
|
|
78030
78291
|
if (!runs.length) {
|
|
78031
78292
|
console.log(source_default.dim("No skill runs found"));
|
|
78032
78293
|
return;
|
|
78033
78294
|
}
|
|
78295
|
+
const hasMoreThanFetched = Number.isFinite(limit) && runs.length > offset + limit;
|
|
78296
|
+
const page = paginate(hasMoreThanFetched ? runs.slice(0, offset + limit) : runs, { limit, offset });
|
|
78034
78297
|
console.log(source_default.bold(`
|
|
78035
|
-
Recent skill runs (${runs.length}):
|
|
78298
|
+
Recent skill runs (${showingLabel(hasMoreThanFetched ? offset + limit + 1 : runs.length, page.items.length, page.offset)}):
|
|
78036
78299
|
`));
|
|
78037
|
-
for (const run of
|
|
78038
|
-
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}`);
|
|
78039
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."));
|
|
78040
78307
|
}
|
|
78041
78308
|
function handleRunsShow(runId, options) {
|
|
78042
78309
|
const run = findSkillRun(runId);
|
|
@@ -78828,7 +79095,7 @@ function registerSchedule(parent) {
|
|
|
78828
79095
|
console.log(source_default.dim(` Next run: ${new Date(schedule.nextRun).toLocaleString()}`));
|
|
78829
79096
|
console.log(source_default.dim(` ID: ${schedule.id}`));
|
|
78830
79097
|
});
|
|
78831
|
-
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) => {
|
|
78832
79099
|
const schedules = listSchedules();
|
|
78833
79100
|
if (options.json) {
|
|
78834
79101
|
console.log(JSON.stringify(schedules));
|
|
@@ -78838,15 +79105,25 @@ function registerSchedule(parent) {
|
|
|
78838
79105
|
console.log(source_default.dim("No schedules. Run: skills schedule add <skill> <cron>"));
|
|
78839
79106
|
return;
|
|
78840
79107
|
}
|
|
79108
|
+
const page = paginate(schedules, {
|
|
79109
|
+
limit: parsePageLimit(options.limit, DEFAULT_LIST_LIMIT, { allowAll: true }),
|
|
79110
|
+
offset: parsePageOffset(options.cursor)
|
|
79111
|
+
});
|
|
78841
79112
|
console.log(source_default.bold(`
|
|
78842
|
-
Scheduled skills (${schedules.length}):
|
|
79113
|
+
Scheduled skills (${showingLabel(schedules.length, page.items.length, page.offset)}):
|
|
78843
79114
|
`));
|
|
78844
|
-
for (const s of
|
|
79115
|
+
for (const s of page.items) {
|
|
78845
79116
|
console.log(` ${source_default.cyan(s.name)} [${s.enabled ? source_default.green("enabled") : source_default.dim("disabled")}]`);
|
|
78846
79117
|
const last2 = s.lastRun ? `last: ${new Date(s.lastRun).toLocaleString()} [${s.lastRunStatus ?? "?"}]` : "never run";
|
|
78847
79118
|
const next = s.nextRun ? `next: ${new Date(s.nextRun).toLocaleString()}` : "";
|
|
78848
|
-
|
|
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}`));
|
|
78849
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."));
|
|
78850
79127
|
});
|
|
78851
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) => {
|
|
78852
79129
|
const removed = removeSchedule(idOrName);
|
|
@@ -85315,9 +85592,15 @@ function print(value, json, text) {
|
|
|
85315
85592
|
else
|
|
85316
85593
|
console.log(text);
|
|
85317
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
|
+
}
|
|
85318
85601
|
function registerWebhookCommands(program2, options) {
|
|
85319
85602
|
const webhooks = program2.command(options.webhooksCommandName ?? "webhooks").description("Manage Hasna event webhook subscriptions");
|
|
85320
|
-
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) => {
|
|
85321
85604
|
const timestamp = new Date().toISOString();
|
|
85322
85605
|
const channel = {
|
|
85323
85606
|
id: actionOptions.id,
|
|
@@ -85338,11 +85621,11 @@ function registerWebhookCommands(program2, options) {
|
|
|
85338
85621
|
throw new Error(`Transport ${actionOptions.transport} is reserved for future use and cannot be added yet`);
|
|
85339
85622
|
}
|
|
85340
85623
|
const saved = await createClient(options).addChannel(channel);
|
|
85341
|
-
print(sanitizeChannelForOutput(saved),
|
|
85624
|
+
print(sanitizeChannelForOutput(saved), wantsJson(actionOptions, command), `Added ${saved.transport} channel ${saved.id}`);
|
|
85342
85625
|
});
|
|
85343
|
-
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) => {
|
|
85344
85627
|
const channels = await createClient(options).listChannels();
|
|
85345
|
-
if (actionOptions
|
|
85628
|
+
if (wantsJson(actionOptions, command)) {
|
|
85346
85629
|
console.log(JSON.stringify(sanitizeChannelsForOutput(channels), null, 2));
|
|
85347
85630
|
return;
|
|
85348
85631
|
}
|
|
@@ -85354,11 +85637,11 @@ function registerWebhookCommands(program2, options) {
|
|
|
85354
85637
|
console.log(`${channel.id} ${channel.enabled ? "enabled" : "disabled"} ${channel.transport} ${channel.webhook?.url ?? channel.command?.command ?? channel.transport}`);
|
|
85355
85638
|
}
|
|
85356
85639
|
});
|
|
85357
|
-
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) => {
|
|
85358
85641
|
const removed = await createClient(options).removeChannel(id);
|
|
85359
|
-
print({ removed },
|
|
85642
|
+
print({ removed }, wantsJson(actionOptions, command), removed ? `Removed ${id}` : `Channel not found: ${id}`);
|
|
85360
85643
|
});
|
|
85361
|
-
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) => {
|
|
85362
85645
|
const result2 = await createClient(options).testChannel(id, {
|
|
85363
85646
|
source: options.source,
|
|
85364
85647
|
type: actionOptions.type,
|
|
@@ -85366,13 +85649,13 @@ function registerWebhookCommands(program2, options) {
|
|
|
85366
85649
|
message: actionOptions.message,
|
|
85367
85650
|
data: parseJsonObject(actionOptions.data, { test: true })
|
|
85368
85651
|
});
|
|
85369
|
-
print(result2,
|
|
85652
|
+
print(result2, wantsJson(actionOptions, command), `${result2.status}: ${result2.channelId}`);
|
|
85370
85653
|
});
|
|
85371
85654
|
return webhooks;
|
|
85372
85655
|
}
|
|
85373
85656
|
function registerEventCommands(program2, options) {
|
|
85374
85657
|
const events = program2.command(options.eventsCommandName ?? "events").description("Emit, list, and replay Hasna events");
|
|
85375
|
-
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) => {
|
|
85376
85659
|
const result2 = await createClient(options).emit({
|
|
85377
85660
|
source: actionOptions.source ?? options.source,
|
|
85378
85661
|
type,
|
|
@@ -85383,9 +85666,9 @@ function registerEventCommands(program2, options) {
|
|
|
85383
85666
|
data: parseJsonObject(actionOptions.data, {}),
|
|
85384
85667
|
metadata: parseJsonObject(actionOptions.metadata, {})
|
|
85385
85668
|
}, { deliver: actionOptions.deliver, dedupe: actionOptions.dedupe });
|
|
85386
|
-
print(result2,
|
|
85669
|
+
print(result2, wantsJson(actionOptions, command), `${result2.deduped ? "Deduped" : "Emitted"} ${result2.event.id} to ${result2.deliveries.length} channel(s)`);
|
|
85387
85670
|
});
|
|
85388
|
-
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) => {
|
|
85389
85672
|
let rows = await createClient(options).listEvents();
|
|
85390
85673
|
if (actionOptions.source)
|
|
85391
85674
|
rows = rows.filter((event) => event.source === actionOptions.source);
|
|
@@ -85393,7 +85676,7 @@ function registerEventCommands(program2, options) {
|
|
|
85393
85676
|
rows = rows.filter((event) => event.type === actionOptions.type);
|
|
85394
85677
|
if (actionOptions.limit)
|
|
85395
85678
|
rows = rows.slice(-actionOptions.limit);
|
|
85396
|
-
if (actionOptions
|
|
85679
|
+
if (wantsJson(actionOptions, command)) {
|
|
85397
85680
|
console.log(JSON.stringify(rows, null, 2));
|
|
85398
85681
|
return;
|
|
85399
85682
|
}
|
|
@@ -85404,14 +85687,14 @@ function registerEventCommands(program2, options) {
|
|
|
85404
85687
|
for (const event of rows)
|
|
85405
85688
|
console.log(`${event.time} ${event.id} ${event.source} ${event.type} ${event.severity}`);
|
|
85406
85689
|
});
|
|
85407
|
-
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) => {
|
|
85408
85691
|
const result2 = await createClient(options).replay({
|
|
85409
85692
|
eventId: actionOptions.id,
|
|
85410
85693
|
source: actionOptions.source,
|
|
85411
85694
|
type: actionOptions.type,
|
|
85412
85695
|
dryRun: actionOptions.dryRun
|
|
85413
85696
|
});
|
|
85414
|
-
print(result2,
|
|
85697
|
+
print(result2, wantsJson(actionOptions, command), `Replayed ${result2.events.length} event(s), ${result2.deliveries.length} delivery result(s)`);
|
|
85415
85698
|
});
|
|
85416
85699
|
return events;
|
|
85417
85700
|
}
|