@hasna/skills 0.1.46 → 0.1.48
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 +486 -182
- package/bin/mcp.js +311 -94
- package/dist/index.js +122 -59
- package/dist/lib/compact-output.d.ts +32 -0
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/skill-aliases.d.ts +1 -0
- package/dist/storage.js +28 -7
- 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/mcp.js
CHANGED
|
@@ -6510,7 +6510,7 @@ var require_dist = __commonJS((exports, module) => {
|
|
|
6510
6510
|
});
|
|
6511
6511
|
|
|
6512
6512
|
// src/lib/config.ts
|
|
6513
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync } from "fs";
|
|
6513
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, readdirSync, statSync } from "fs";
|
|
6514
6514
|
import { join, dirname } from "path";
|
|
6515
6515
|
import { homedir } from "os";
|
|
6516
6516
|
function validKeys() {
|
|
@@ -6521,6 +6521,24 @@ function allowedValues(key) {
|
|
|
6521
6521
|
return MODE_VALUES;
|
|
6522
6522
|
return ENUM_KEYS[key];
|
|
6523
6523
|
}
|
|
6524
|
+
function mergeDirectoryContents(sourceDir, targetDir) {
|
|
6525
|
+
if (!existsSync(sourceDir))
|
|
6526
|
+
return;
|
|
6527
|
+
mkdirSync(targetDir, { recursive: true });
|
|
6528
|
+
for (const entry of readdirSync(sourceDir)) {
|
|
6529
|
+
const sourcePath = join(sourceDir, entry);
|
|
6530
|
+
const targetPath = join(targetDir, entry);
|
|
6531
|
+
try {
|
|
6532
|
+
const sourceStat = statSync(sourcePath);
|
|
6533
|
+
if (sourceStat.isDirectory()) {
|
|
6534
|
+
mergeDirectoryContents(sourcePath, targetPath);
|
|
6535
|
+
continue;
|
|
6536
|
+
}
|
|
6537
|
+
if (!existsSync(targetPath))
|
|
6538
|
+
copyFileSync(sourcePath, targetPath);
|
|
6539
|
+
} catch {}
|
|
6540
|
+
}
|
|
6541
|
+
}
|
|
6524
6542
|
function normalizeConfigValue(key, value) {
|
|
6525
6543
|
if (typeof value !== "string")
|
|
6526
6544
|
return;
|
|
@@ -6544,14 +6562,17 @@ function normalizeConfigValue(key, value) {
|
|
|
6544
6562
|
function getDataDir() {
|
|
6545
6563
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir();
|
|
6546
6564
|
const newDir = join(home, ".hasna", "skills");
|
|
6565
|
+
const oldDir = join(home, ".skills");
|
|
6547
6566
|
const oldConfigFile = join(home, ".skillsrc");
|
|
6567
|
+
mkdirSync(newDir, { recursive: true });
|
|
6568
|
+
try {
|
|
6569
|
+
mergeDirectoryContents(oldDir, newDir);
|
|
6570
|
+
} catch {}
|
|
6548
6571
|
if (existsSync(oldConfigFile) && !existsSync(join(newDir, "config.json"))) {
|
|
6549
|
-
mkdirSync(newDir, { recursive: true });
|
|
6550
6572
|
try {
|
|
6551
6573
|
copyFileSync(oldConfigFile, join(newDir, "config.json"));
|
|
6552
6574
|
} catch {}
|
|
6553
6575
|
}
|
|
6554
|
-
mkdirSync(newDir, { recursive: true });
|
|
6555
6576
|
return newDir;
|
|
6556
6577
|
}
|
|
6557
6578
|
function getConfigPath(scope) {
|
|
@@ -6625,7 +6646,8 @@ var init_skill_aliases = __esm(() => {
|
|
|
6625
6646
|
"pdf-reader": "read-pdf",
|
|
6626
6647
|
"generate-image": "image",
|
|
6627
6648
|
"image-generator": "image",
|
|
6628
|
-
"create-blog-article": "blog-article"
|
|
6649
|
+
"create-blog-article": "blog-article",
|
|
6650
|
+
"skill-diff": "diff-viewer"
|
|
6629
6651
|
};
|
|
6630
6652
|
});
|
|
6631
6653
|
|
|
@@ -7042,7 +7064,7 @@ var init_pricing = __esm(() => {
|
|
|
7042
7064
|
{ 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" },
|
|
7043
7065
|
{ slug: "generate-book-cover", displayName: "Book Cover", tier: "premium", costCents: 20, providers: ["gpt-image-2"], description: "Professional book cover design from title and genre" },
|
|
7044
7066
|
{ slug: "remove-background", displayName: "Remove Background", tier: "premium", costCents: 10, providers: ["gemini-3-pro"], description: "AI-powered background removal from images" },
|
|
7045
|
-
{ slug: "transcript", displayName: "Transcript", tier: "premium", costCents: 10, providers: ["
|
|
7067
|
+
{ slug: "transcript", displayName: "Transcript", tier: "premium", costCents: 10, providers: ["openai", "elevenlabs", "deepgram", "hosted"], description: "Audio/video transcription with timestamps, diarization, and URL support" },
|
|
7046
7068
|
{ slug: "webcrawling", displayName: "Web Crawling", tier: "premium", costCents: 5, providers: ["firecrawl"], description: "Structured web page crawling and extraction" },
|
|
7047
7069
|
{ slug: "browse", displayName: "Browse", tier: "premium", costCents: 5, providers: ["browser"], description: "Web browsing and page interaction" },
|
|
7048
7070
|
{ slug: "read-pdf", displayName: "Read PDF", tier: "premium", costCents: 5, providers: ["cerebras"], description: "Hosted PDF extraction and structured content analysis" },
|
|
@@ -18269,7 +18291,7 @@ function finalize(ctx, schema) {
|
|
|
18269
18291
|
result.$schema = "http://json-schema.org/draft-07/schema#";
|
|
18270
18292
|
} else if (ctx.target === "draft-04") {
|
|
18271
18293
|
result.$schema = "http://json-schema.org/draft-04/schema#";
|
|
18272
|
-
} else if (ctx.target === "openapi-3.0") {}
|
|
18294
|
+
} else if (ctx.target === "openapi-3.0") {} else {}
|
|
18273
18295
|
if (ctx.external?.uri) {
|
|
18274
18296
|
const id = ctx.external.registry.get(schema)?.id;
|
|
18275
18297
|
if (!id)
|
|
@@ -18517,7 +18539,7 @@ var literalProcessor = (schema, ctx, json, _params) => {
|
|
|
18517
18539
|
if (val === undefined) {
|
|
18518
18540
|
if (ctx.unrepresentable === "throw") {
|
|
18519
18541
|
throw new Error("Literal `undefined` cannot be represented in JSON Schema");
|
|
18520
|
-
}
|
|
18542
|
+
} else {}
|
|
18521
18543
|
} else if (typeof val === "bigint") {
|
|
18522
18544
|
if (ctx.unrepresentable === "throw") {
|
|
18523
18545
|
throw new Error("BigInt literals cannot be represented in JSON Schema");
|
|
@@ -21797,7 +21819,7 @@ class StdioServerTransport {
|
|
|
21797
21819
|
// package.json
|
|
21798
21820
|
var package_default = {
|
|
21799
21821
|
name: "@hasna/skills",
|
|
21800
|
-
version: "0.1.
|
|
21822
|
+
version: "0.1.48",
|
|
21801
21823
|
description: "Skills library for AI coding agents",
|
|
21802
21824
|
type: "module",
|
|
21803
21825
|
bin: {
|
|
@@ -21866,7 +21888,7 @@ var package_default = {
|
|
|
21866
21888
|
typescript: "^5"
|
|
21867
21889
|
},
|
|
21868
21890
|
dependencies: {
|
|
21869
|
-
"@hasna/events": "^0.1.
|
|
21891
|
+
"@hasna/events": "^0.1.7",
|
|
21870
21892
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
21871
21893
|
chalk: "^5.3.0",
|
|
21872
21894
|
commander: "^12.1.0",
|
|
@@ -29480,7 +29502,7 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
29480
29502
|
|
|
29481
29503
|
// src/lib/registry.ts
|
|
29482
29504
|
init_config();
|
|
29483
|
-
import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as
|
|
29505
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "fs";
|
|
29484
29506
|
import { join as join4 } from "path";
|
|
29485
29507
|
|
|
29486
29508
|
// src/lib/portable-skills.ts
|
|
@@ -29491,16 +29513,16 @@ import {
|
|
|
29491
29513
|
lstatSync as lstatSync2,
|
|
29492
29514
|
mkdirSync as mkdirSync2,
|
|
29493
29515
|
readFileSync as readFileSync3,
|
|
29494
|
-
readdirSync as
|
|
29516
|
+
readdirSync as readdirSync3,
|
|
29495
29517
|
rmSync,
|
|
29496
|
-
statSync as
|
|
29518
|
+
statSync as statSync3,
|
|
29497
29519
|
writeFileSync as writeFileSync2
|
|
29498
29520
|
} from "fs";
|
|
29499
29521
|
import { basename, dirname as dirname2, isAbsolute as isAbsolute2, join as join3, normalize as normalize2, relative } from "path";
|
|
29500
29522
|
|
|
29501
29523
|
// src/lib/skill-validation.ts
|
|
29502
29524
|
init_pricing();
|
|
29503
|
-
import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2, readdirSync, statSync } from "fs";
|
|
29525
|
+
import { existsSync as existsSync2, lstatSync, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
29504
29526
|
import { isAbsolute, join as join2, normalize } from "path";
|
|
29505
29527
|
var DOC_FILES = ["SKILL.md", "README.md", "CLAUDE.md"];
|
|
29506
29528
|
var RESERVED_SKILL_ENTRIES = new Set([
|
|
@@ -29656,7 +29678,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
29656
29678
|
if (!VALID_BIN_COMMAND.test(bareName)) {
|
|
29657
29679
|
add(issues, "skill.name_invalid", `Skill name '${bareName}' must use lowercase letters, numbers, dots, underscores, or hyphens`);
|
|
29658
29680
|
}
|
|
29659
|
-
for (const entry of
|
|
29681
|
+
for (const entry of readdirSync2(skillPath).sort()) {
|
|
29660
29682
|
const entryPath = join2(skillPath, entry);
|
|
29661
29683
|
if (RESERVED_SKILL_ENTRIES.has(entry)) {
|
|
29662
29684
|
add(issues, "skill.reserved_file", `Reserved file '${entry}' is not allowed in skill packages`);
|
|
@@ -29771,7 +29793,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
29771
29793
|
const targetPath = join2(skillPath, target);
|
|
29772
29794
|
if (!existsSync2(targetPath)) {
|
|
29773
29795
|
add(warnings, "package.bin_target_missing", `package.json bin '${command}' target '${target}' is not present before build`);
|
|
29774
|
-
} else if (
|
|
29796
|
+
} else if (statSync2(targetPath).isDirectory()) {
|
|
29775
29797
|
add(issues, "package.bin_target_directory", `package.json bin '${command}' target '${target}' must point to a file, not a directory`);
|
|
29776
29798
|
}
|
|
29777
29799
|
}
|
|
@@ -29794,7 +29816,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
29794
29816
|
add(issues, "skill.src_index_missing", "Missing src/index.ts or src/index.js");
|
|
29795
29817
|
} else {
|
|
29796
29818
|
const indexPath = existsSync2(join2(srcDir, "index.ts")) ? join2(srcDir, "index.ts") : join2(srcDir, "index.js");
|
|
29797
|
-
const size =
|
|
29819
|
+
const size = statSync2(indexPath).size;
|
|
29798
29820
|
if (size < 50)
|
|
29799
29821
|
add(warnings, "skill.src_index_minimal", `Source entry point is very small (${size}B)`);
|
|
29800
29822
|
}
|
|
@@ -29861,7 +29883,7 @@ function findPortableSkill(name, options = {}) {
|
|
|
29861
29883
|
return null;
|
|
29862
29884
|
}
|
|
29863
29885
|
const path = getPortableSkillPath(normalized, options);
|
|
29864
|
-
if (!existsSync3(path) || !
|
|
29886
|
+
if (!existsSync3(path) || !statSync3(path).isDirectory())
|
|
29865
29887
|
return null;
|
|
29866
29888
|
try {
|
|
29867
29889
|
return summarizePortableSkill(path, normalized);
|
|
@@ -29874,7 +29896,7 @@ function listPortableSkills(options = {}) {
|
|
|
29874
29896
|
if (!existsSync3(root))
|
|
29875
29897
|
return [];
|
|
29876
29898
|
const skills = [];
|
|
29877
|
-
for (const entry of
|
|
29899
|
+
for (const entry of readdirSync3(root).sort()) {
|
|
29878
29900
|
if (entry.startsWith(".") || DATA_DIR_NON_SKILL_ENTRIES.has(entry))
|
|
29879
29901
|
continue;
|
|
29880
29902
|
const path = join3(root, entry);
|
|
@@ -29950,7 +29972,7 @@ function scaffoldPortableSkill(name, options = {}) {
|
|
|
29950
29972
|
}
|
|
29951
29973
|
function portPortableSkill(sourcePath, options = {}) {
|
|
29952
29974
|
const absoluteSource = normalize2(sourcePath);
|
|
29953
|
-
if (!existsSync3(absoluteSource) || !
|
|
29975
|
+
if (!existsSync3(absoluteSource) || !statSync3(absoluteSource).isDirectory()) {
|
|
29954
29976
|
throw new Error(`Skill source directory not found: ${sourcePath}`);
|
|
29955
29977
|
}
|
|
29956
29978
|
const inferred = readPortableSkillManifest(absoluteSource, basename(absoluteSource));
|
|
@@ -30019,7 +30041,7 @@ function validatePortableSkillDirectory(name, skillPath) {
|
|
|
30019
30041
|
const entryPath = join3(skillPath, command.entry);
|
|
30020
30042
|
if (!existsSync3(entryPath))
|
|
30021
30043
|
add2(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
|
|
30022
|
-
else if (
|
|
30044
|
+
else if (statSync3(entryPath).isDirectory())
|
|
30023
30045
|
add2(issues, "portable.command_entry_directory", `Command '${command.name}' entry '${command.entry}' must be a file`);
|
|
30024
30046
|
}
|
|
30025
30047
|
}
|
|
@@ -30387,7 +30409,7 @@ function displayName(name) {
|
|
|
30387
30409
|
}
|
|
30388
30410
|
function safeIsDirectory(path) {
|
|
30389
30411
|
try {
|
|
30390
|
-
return
|
|
30412
|
+
return statSync3(path).isDirectory();
|
|
30391
30413
|
} catch {
|
|
30392
30414
|
return false;
|
|
30393
30415
|
}
|
|
@@ -31601,9 +31623,9 @@ var MEDIA_PROCESSING_SKILLS = [
|
|
|
31601
31623
|
{
|
|
31602
31624
|
name: "transcript",
|
|
31603
31625
|
displayName: "Transcript",
|
|
31604
|
-
description: "
|
|
31626
|
+
description: "Transcribe audio, video, and media URLs with OpenAI GPT-4o, ElevenLabs Scribe v2, DeepGram, or hosted runtime",
|
|
31605
31627
|
category: "Media Processing",
|
|
31606
|
-
tags: ["transcript", "audio", "video", "speech-to-text"]
|
|
31628
|
+
tags: ["transcript", "audio", "video", "speech-to-text", "diarization", "youtube"]
|
|
31607
31629
|
},
|
|
31608
31630
|
{
|
|
31609
31631
|
name: "video-cut-suggester",
|
|
@@ -32383,7 +32405,7 @@ function discoverSkillsInDir(dir) {
|
|
|
32383
32405
|
return [];
|
|
32384
32406
|
const result = [];
|
|
32385
32407
|
try {
|
|
32386
|
-
const entries =
|
|
32408
|
+
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
32387
32409
|
for (const entry of entries) {
|
|
32388
32410
|
if (!entry.isDirectory())
|
|
32389
32411
|
continue;
|
|
@@ -33047,18 +33069,29 @@ var runOutputSchema = objectSchema({
|
|
|
33047
33069
|
exitCode: { type: "number", description: "Process exit code for local runs." },
|
|
33048
33070
|
skill: stringSchema("Canonical skill slug."),
|
|
33049
33071
|
remote: { type: "boolean", description: "Whether the skill was submitted to the hosted runtime." },
|
|
33050
|
-
|
|
33051
|
-
|
|
33072
|
+
stdoutPreview: objectSchema({
|
|
33073
|
+
text: stringSchema("Truncated stdout preview."),
|
|
33074
|
+
length: { type: "number" },
|
|
33075
|
+
truncated: { type: "boolean" }
|
|
33076
|
+
}, [], "Default compact stdout preview."),
|
|
33077
|
+
stderrPreview: objectSchema({
|
|
33078
|
+
text: stringSchema("Truncated stderr preview."),
|
|
33079
|
+
length: { type: "number" },
|
|
33080
|
+
truncated: { type: "boolean" }
|
|
33081
|
+
}, [], "Default compact stderr preview."),
|
|
33082
|
+
stdout: stringSchema("Captured stdout for local runs when detail:true is requested."),
|
|
33083
|
+
stderr: stringSchema("Captured stderr for local runs when detail:true is requested."),
|
|
33052
33084
|
id: stringSchema("Remote run id when submitted remotely."),
|
|
33053
33085
|
localRunId: stringSchema("Local run metadata id."),
|
|
33054
33086
|
status: stringSchema("Run lifecycle status."),
|
|
33055
33087
|
pricing: pricingSchema,
|
|
33056
|
-
remoteRun: objectSchema({}, [], "
|
|
33057
|
-
run: objectSchema({}, [], "
|
|
33088
|
+
remoteRun: objectSchema({}, [], "Compact hosted remote run summary by default; full contract when detail:true is requested.", true),
|
|
33089
|
+
run: objectSchema({}, [], "Compact local run metadata by default; full metadata when detail:true is requested.", true),
|
|
33058
33090
|
nextActions: objectSchema({
|
|
33059
33091
|
poll: stringSchema("Command to poll run status."),
|
|
33060
33092
|
download: stringSchema("Command to download artifacts.")
|
|
33061
|
-
})
|
|
33093
|
+
}),
|
|
33094
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
33062
33095
|
}, [], "Skill run result.");
|
|
33063
33096
|
var toolContracts = [
|
|
33064
33097
|
{
|
|
@@ -33106,7 +33139,7 @@ var toolContracts = [
|
|
|
33106
33139
|
{
|
|
33107
33140
|
name: "list_skills",
|
|
33108
33141
|
title: "List Skills",
|
|
33109
|
-
description: "List skills from the basic or full registry profile.",
|
|
33142
|
+
description: "List skills from the basic or full registry profile. Returns a compact paged envelope by default.",
|
|
33110
33143
|
params: ["category?", "profile?", "detail?", "limit?", "offset?"],
|
|
33111
33144
|
category: "discovery",
|
|
33112
33145
|
sideEffects: "none",
|
|
@@ -33122,7 +33155,11 @@ var toolContracts = [
|
|
|
33122
33155
|
skills: arraySchema(skillSummarySchema),
|
|
33123
33156
|
total: { type: "number" },
|
|
33124
33157
|
offset: { type: "number" },
|
|
33125
|
-
limit: { type: "number" }
|
|
33158
|
+
limit: { type: "number" },
|
|
33159
|
+
nextOffset: { type: "number" },
|
|
33160
|
+
hasMore: { type: "boolean" },
|
|
33161
|
+
nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
|
|
33162
|
+
detailHint: stringSchema("How to request fuller skill objects.")
|
|
33126
33163
|
})
|
|
33127
33164
|
},
|
|
33128
33165
|
{
|
|
@@ -33143,7 +33180,7 @@ var toolContracts = [
|
|
|
33143
33180
|
{
|
|
33144
33181
|
name: "search_skills",
|
|
33145
33182
|
title: "Search Skills",
|
|
33146
|
-
description: "Search skills by name, description, or tags.",
|
|
33183
|
+
description: "Search skills by name, description, or tags. Returns a compact paged envelope by default.",
|
|
33147
33184
|
params: ["query", "profile?", "detail?", "limit?", "offset?"],
|
|
33148
33185
|
category: "discovery",
|
|
33149
33186
|
sideEffects: "none",
|
|
@@ -33155,7 +33192,16 @@ var toolContracts = [
|
|
|
33155
33192
|
limit: { type: "number", minimum: 0 },
|
|
33156
33193
|
offset: { type: "number", minimum: 0 }
|
|
33157
33194
|
}, ["query"]),
|
|
33158
|
-
outputSchema: objectSchema({
|
|
33195
|
+
outputSchema: objectSchema({
|
|
33196
|
+
skills: arraySchema(skillSummarySchema),
|
|
33197
|
+
total: { type: "number" },
|
|
33198
|
+
offset: { type: "number" },
|
|
33199
|
+
limit: { type: "number" },
|
|
33200
|
+
nextOffset: { type: "number" },
|
|
33201
|
+
hasMore: { type: "boolean" },
|
|
33202
|
+
nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
|
|
33203
|
+
detailHint: stringSchema("How to request fuller skill objects.")
|
|
33204
|
+
})
|
|
33159
33205
|
},
|
|
33160
33206
|
{
|
|
33161
33207
|
name: "get_skill_info",
|
|
@@ -33272,8 +33318,8 @@ var toolContracts = [
|
|
|
33272
33318
|
{
|
|
33273
33319
|
name: "run_skill",
|
|
33274
33320
|
title: "Run Skill",
|
|
33275
|
-
description: "Run a skill locally or through a configured remote runner.",
|
|
33276
|
-
params: ["name", "input?", "args?", "approved?"],
|
|
33321
|
+
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.",
|
|
33322
|
+
params: ["name", "input?", "args?", "approved?", "detail?"],
|
|
33277
33323
|
category: "execution",
|
|
33278
33324
|
sideEffects: "local-process-or-remote-run",
|
|
33279
33325
|
stable: true,
|
|
@@ -33281,28 +33327,33 @@ var toolContracts = [
|
|
|
33281
33327
|
name: skillNameInput,
|
|
33282
33328
|
input: runInputSchema,
|
|
33283
33329
|
args: runArgsSchema,
|
|
33284
|
-
approved: paidRunApprovalSchema
|
|
33330
|
+
approved: paidRunApprovalSchema,
|
|
33331
|
+
detail: { type: "boolean", default: false, description: "Return full stdout/stderr, remote run, and local run metadata." }
|
|
33285
33332
|
}, ["name"]),
|
|
33286
33333
|
outputSchema: runOutputSchema
|
|
33287
33334
|
},
|
|
33288
33335
|
{
|
|
33289
33336
|
name: "get_run_status",
|
|
33290
33337
|
title: "Get Run Status",
|
|
33291
|
-
description: "Fetch remote run status and next actions.",
|
|
33292
|
-
params: ["run_id"],
|
|
33338
|
+
description: "Fetch remote run status and next actions. Returns a compact status summary by default; pass detail:true for the complete remote run payload.",
|
|
33339
|
+
params: ["run_id", "detail?"],
|
|
33293
33340
|
category: "execution",
|
|
33294
33341
|
sideEffects: "none",
|
|
33295
33342
|
stable: true,
|
|
33296
|
-
inputSchema: objectSchema({
|
|
33343
|
+
inputSchema: objectSchema({
|
|
33344
|
+
run_id: stringSchema("Remote or local run id."),
|
|
33345
|
+
detail: { type: "boolean", default: false, description: "Return the complete remote run payload." }
|
|
33346
|
+
}, ["run_id"]),
|
|
33297
33347
|
outputSchema: objectSchema({
|
|
33298
33348
|
contractVersion: { type: "number", description: "Remote run payload contract version." },
|
|
33299
33349
|
runId: stringSchema("Remote run id."),
|
|
33300
33350
|
localRunId: stringSchema("Local run id."),
|
|
33301
|
-
run: objectSchema({}, [], "
|
|
33351
|
+
run: objectSchema({}, [], "Compact remote run status by default; full status when detail:true is requested.", true),
|
|
33302
33352
|
nextActions: objectSchema({
|
|
33303
33353
|
poll: stringSchema("Command to poll run status."),
|
|
33304
33354
|
download: stringSchema("Command to download artifacts.")
|
|
33305
|
-
})
|
|
33355
|
+
}),
|
|
33356
|
+
detailHint: stringSchema("How to request the complete payload.")
|
|
33306
33357
|
})
|
|
33307
33358
|
},
|
|
33308
33359
|
{
|
|
@@ -33397,13 +33448,25 @@ var toolContracts = [
|
|
|
33397
33448
|
{
|
|
33398
33449
|
name: "list_schedules",
|
|
33399
33450
|
title: "List Schedules",
|
|
33400
|
-
description: "List scheduled skill runs.",
|
|
33401
|
-
params: [],
|
|
33451
|
+
description: "List scheduled skill runs as a compact paged envelope.",
|
|
33452
|
+
params: ["limit?", "offset?"],
|
|
33402
33453
|
category: "scheduling",
|
|
33403
33454
|
sideEffects: "none",
|
|
33404
33455
|
stable: true,
|
|
33405
|
-
inputSchema: objectSchema(
|
|
33406
|
-
|
|
33456
|
+
inputSchema: objectSchema({
|
|
33457
|
+
limit: { type: "number", minimum: 0 },
|
|
33458
|
+
offset: { type: "number", minimum: 0 }
|
|
33459
|
+
}),
|
|
33460
|
+
outputSchema: objectSchema({
|
|
33461
|
+
schedules: arraySchema(objectSchema({}, [], "Compact schedule record.", true)),
|
|
33462
|
+
total: { type: "number" },
|
|
33463
|
+
offset: { type: "number" },
|
|
33464
|
+
limit: { type: "number" },
|
|
33465
|
+
nextOffset: { type: "number" },
|
|
33466
|
+
hasMore: { type: "boolean" },
|
|
33467
|
+
nextArguments: objectSchema({}, [], "Arguments for the next page.", true),
|
|
33468
|
+
detailHint: stringSchema("How to request complete schedule details.")
|
|
33469
|
+
})
|
|
33407
33470
|
},
|
|
33408
33471
|
{
|
|
33409
33472
|
name: "remove_schedule",
|
|
@@ -33810,6 +33873,90 @@ function resolveDiscoveryPricing(skill) {
|
|
|
33810
33873
|
return skill.pricing && typeof skill.pricing.formattedCost === "string" ? skill.pricing : getPublicSkillPricing(skill.name);
|
|
33811
33874
|
}
|
|
33812
33875
|
|
|
33876
|
+
// src/lib/compact-output.ts
|
|
33877
|
+
var DEFAULT_MCP_LIMIT = 25;
|
|
33878
|
+
var MAX_PAGE_LIMIT = 200;
|
|
33879
|
+
var DEFAULT_PREVIEW_CHARS = 600;
|
|
33880
|
+
function truncateText(value, maxChars = 96) {
|
|
33881
|
+
const text = String(value ?? "").replace(/\s+/g, " ").trim();
|
|
33882
|
+
if (text.length <= maxChars)
|
|
33883
|
+
return text;
|
|
33884
|
+
return `${text.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
|
|
33885
|
+
}
|
|
33886
|
+
function previewText(value, maxChars = DEFAULT_PREVIEW_CHARS) {
|
|
33887
|
+
const text = String(value ?? "");
|
|
33888
|
+
return {
|
|
33889
|
+
text: text.length > maxChars ? `${text.slice(0, Math.max(0, maxChars - 3))}...` : text,
|
|
33890
|
+
length: text.length,
|
|
33891
|
+
truncated: text.length > maxChars
|
|
33892
|
+
};
|
|
33893
|
+
}
|
|
33894
|
+
function parsePageLimit(value, fallback, options = {}) {
|
|
33895
|
+
const max = options.max ?? MAX_PAGE_LIMIT;
|
|
33896
|
+
if (typeof value === "string" && options.allowAll && value.trim().toLowerCase() === "all") {
|
|
33897
|
+
return Number.POSITIVE_INFINITY;
|
|
33898
|
+
}
|
|
33899
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(value ?? "", 10);
|
|
33900
|
+
if (!Number.isFinite(parsed))
|
|
33901
|
+
return fallback;
|
|
33902
|
+
if (options.allowAll && parsed === 0)
|
|
33903
|
+
return Number.POSITIVE_INFINITY;
|
|
33904
|
+
if (parsed <= 0)
|
|
33905
|
+
return fallback;
|
|
33906
|
+
return Math.min(parsed, max);
|
|
33907
|
+
}
|
|
33908
|
+
function parsePageOffset(value, fallback = 0) {
|
|
33909
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(value ?? "", 10);
|
|
33910
|
+
if (!Number.isFinite(parsed) || parsed < 0)
|
|
33911
|
+
return fallback;
|
|
33912
|
+
return parsed;
|
|
33913
|
+
}
|
|
33914
|
+
function paginate(items, options) {
|
|
33915
|
+
const offset = Math.min(parsePageOffset(options.offset), items.length);
|
|
33916
|
+
const effectiveLimit = Number.isFinite(options.limit) ? Math.max(0, Math.min(options.limit, MAX_PAGE_LIMIT)) : Math.max(0, items.length - offset);
|
|
33917
|
+
const pageItems = items.slice(offset, offset + effectiveLimit);
|
|
33918
|
+
const nextOffset = offset + pageItems.length < items.length ? offset + pageItems.length : null;
|
|
33919
|
+
return {
|
|
33920
|
+
items: pageItems,
|
|
33921
|
+
total: items.length,
|
|
33922
|
+
offset,
|
|
33923
|
+
limit: effectiveLimit,
|
|
33924
|
+
hasMore: nextOffset !== null,
|
|
33925
|
+
nextOffset
|
|
33926
|
+
};
|
|
33927
|
+
}
|
|
33928
|
+
function compactRunRecord(run) {
|
|
33929
|
+
if (!run || typeof run !== "object")
|
|
33930
|
+
return {};
|
|
33931
|
+
return {
|
|
33932
|
+
id: run.id,
|
|
33933
|
+
skill: run.skill,
|
|
33934
|
+
status: run.status,
|
|
33935
|
+
startedAt: run.startedAt,
|
|
33936
|
+
...run.completedAt ? { completedAt: run.completedAt } : {},
|
|
33937
|
+
...run.remoteRunId ? { remoteRunId: run.remoteRunId } : {},
|
|
33938
|
+
...run.costCents !== undefined ? { costCents: run.costCents } : {},
|
|
33939
|
+
...run.error ? { error: truncateText(run.error, 240) } : {},
|
|
33940
|
+
artifactCount: Array.isArray(run.artifacts) ? run.artifacts.length : 0,
|
|
33941
|
+
paths: run.paths
|
|
33942
|
+
};
|
|
33943
|
+
}
|
|
33944
|
+
function compactRemoteRun(run) {
|
|
33945
|
+
if (!run || typeof run !== "object")
|
|
33946
|
+
return {};
|
|
33947
|
+
return {
|
|
33948
|
+
...run.contractVersion !== undefined ? { contractVersion: run.contractVersion } : {},
|
|
33949
|
+
id: run.id,
|
|
33950
|
+
skill: run.skill ?? run.requestedSlug,
|
|
33951
|
+
status: run.status,
|
|
33952
|
+
...run.correlationId ? { correlationId: run.correlationId } : {},
|
|
33953
|
+
...run.createdAt ? { createdAt: run.createdAt } : {},
|
|
33954
|
+
...run.startedAt ? { startedAt: run.startedAt } : {},
|
|
33955
|
+
...run.completedAt ? { completedAt: run.completedAt } : {},
|
|
33956
|
+
...run.error || run.errorMessage ? { error: truncateText(run.error ?? run.errorMessage, 240) } : {}
|
|
33957
|
+
};
|
|
33958
|
+
}
|
|
33959
|
+
|
|
33813
33960
|
// src/mcp/helpers.ts
|
|
33814
33961
|
function stripNulls(obj) {
|
|
33815
33962
|
return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== null && v !== undefined && !(Array.isArray(v) && v.length === 0)));
|
|
@@ -33858,7 +34005,7 @@ var TOOL_DESCRIPTIONS = getMcpToolDescriptions();
|
|
|
33858
34005
|
function registerDiscoveryTools(server) {
|
|
33859
34006
|
server.registerTool("list_skills", {
|
|
33860
34007
|
title: "List Skills",
|
|
33861
|
-
description: "List skills with public pricing. Defaults to the
|
|
34008
|
+
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.",
|
|
33862
34009
|
inputSchema: {
|
|
33863
34010
|
category: exports_external.string().optional(),
|
|
33864
34011
|
profile: exports_external.enum(["basic", "all"]).optional(),
|
|
@@ -33870,16 +34017,20 @@ function registerDiscoveryTools(server) {
|
|
|
33870
34017
|
const selectedProfile = profile || "basic";
|
|
33871
34018
|
const skills = category ? loadRegistryProfile(selectedProfile).filter((s) => s.category === category) : loadRegistryProfile(selectedProfile);
|
|
33872
34019
|
const mapped = detail ? skills.map(getPublicSkillDiscovery) : skills.map(getCompactSkillDiscovery);
|
|
33873
|
-
|
|
33874
|
-
|
|
33875
|
-
|
|
33876
|
-
|
|
33877
|
-
|
|
33878
|
-
|
|
33879
|
-
|
|
33880
|
-
|
|
33881
|
-
|
|
33882
|
-
|
|
34020
|
+
const page = paginate(mapped, {
|
|
34021
|
+
limit: parsePageLimit(limit, DEFAULT_MCP_LIMIT, { max: 100 }),
|
|
34022
|
+
offset: parsePageOffset(offset)
|
|
34023
|
+
});
|
|
34024
|
+
return mcpJson({
|
|
34025
|
+
skills: page.items,
|
|
34026
|
+
total: page.total,
|
|
34027
|
+
offset: page.offset,
|
|
34028
|
+
limit: page.limit,
|
|
34029
|
+
nextOffset: page.nextOffset,
|
|
34030
|
+
hasMore: page.hasMore,
|
|
34031
|
+
nextArguments: page.hasMore ? { profile: selectedProfile, category, detail: Boolean(detail), limit: page.limit, offset: page.nextOffset } : null,
|
|
34032
|
+
detailHint: detail ? undefined : "Set detail:true for full public skill objects, or call get_skill_info for one skill."
|
|
34033
|
+
});
|
|
33883
34034
|
});
|
|
33884
34035
|
server.registerTool("list_pinned_skills", {
|
|
33885
34036
|
title: "List Pinned Skills",
|
|
@@ -33896,7 +34047,7 @@ function registerDiscoveryTools(server) {
|
|
|
33896
34047
|
});
|
|
33897
34048
|
server.registerTool("search_skills", {
|
|
33898
34049
|
title: "Search Skills",
|
|
33899
|
-
description: "Search skills by name, description, or tags. Defaults to the
|
|
34050
|
+
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.",
|
|
33900
34051
|
inputSchema: {
|
|
33901
34052
|
query: exports_external.string(),
|
|
33902
34053
|
profile: exports_external.enum(["basic", "all"]).optional(),
|
|
@@ -33912,16 +34063,20 @@ function registerDiscoveryTools(server) {
|
|
|
33912
34063
|
if (!cached2)
|
|
33913
34064
|
cacheSet(cacheKey, results);
|
|
33914
34065
|
const out = detail ? results.map(getPublicSkillDiscovery) : results.map(getCompactSkillDiscovery);
|
|
33915
|
-
|
|
33916
|
-
|
|
33917
|
-
|
|
33918
|
-
|
|
33919
|
-
|
|
33920
|
-
|
|
33921
|
-
|
|
33922
|
-
|
|
33923
|
-
|
|
33924
|
-
|
|
34066
|
+
const page = paginate(out, {
|
|
34067
|
+
limit: parsePageLimit(limit, DEFAULT_MCP_LIMIT, { max: 100 }),
|
|
34068
|
+
offset: parsePageOffset(offset)
|
|
34069
|
+
});
|
|
34070
|
+
return mcpJson({
|
|
34071
|
+
skills: page.items,
|
|
34072
|
+
total: page.total,
|
|
34073
|
+
offset: page.offset,
|
|
34074
|
+
limit: page.limit,
|
|
34075
|
+
nextOffset: page.nextOffset,
|
|
34076
|
+
hasMore: page.hasMore,
|
|
34077
|
+
nextArguments: page.hasMore ? { query, profile: selectedProfile, detail: Boolean(detail), limit: page.limit, offset: page.nextOffset } : null,
|
|
34078
|
+
detailHint: detail ? undefined : "Set detail:true for full public skill objects, or call get_skill_info for one skill."
|
|
34079
|
+
});
|
|
33925
34080
|
});
|
|
33926
34081
|
server.registerTool("get_skill_info", {
|
|
33927
34082
|
title: "Get Skill Info",
|
|
@@ -33966,12 +34121,12 @@ function registerDiscoveryTools(server) {
|
|
|
33966
34121
|
}
|
|
33967
34122
|
|
|
33968
34123
|
// src/mcp/operation-tools.ts
|
|
33969
|
-
import { existsSync as existsSync10, readdirSync as
|
|
34124
|
+
import { existsSync as existsSync10, readdirSync as readdirSync6, statSync as statSync5 } from "fs";
|
|
33970
34125
|
import { join as join10 } from "path";
|
|
33971
34126
|
|
|
33972
34127
|
// src/lib/run-state.ts
|
|
33973
34128
|
import { createHash, randomBytes } from "crypto";
|
|
33974
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as
|
|
34129
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4, readFileSync as readFileSync8, readdirSync as readdirSync5, statSync as statSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
33975
34130
|
import { extname, join as join8, relative as relative2 } from "path";
|
|
33976
34131
|
function createSkillRun(params, targetDir = process.cwd()) {
|
|
33977
34132
|
const now = new Date;
|
|
@@ -34045,7 +34200,7 @@ function findSkillRun(runId, targetDir = process.cwd()) {
|
|
|
34045
34200
|
const runsRoot = join8(getProjectStateDir(targetDir), "runs");
|
|
34046
34201
|
if (!existsSync8(runsRoot))
|
|
34047
34202
|
return null;
|
|
34048
|
-
for (const day of
|
|
34203
|
+
for (const day of readdirSync5(runsRoot)) {
|
|
34049
34204
|
const record3 = readRunRecord(join8(runsRoot, day, runId));
|
|
34050
34205
|
if (record3)
|
|
34051
34206
|
return record3;
|
|
@@ -34065,7 +34220,7 @@ function collectRunArtifacts(context) {
|
|
|
34065
34220
|
return [];
|
|
34066
34221
|
const artifacts = [];
|
|
34067
34222
|
for (const path of walkFiles(context.exportDir)) {
|
|
34068
|
-
const stat =
|
|
34223
|
+
const stat = statSync4(path);
|
|
34069
34224
|
const bytes = readFileSync8(path);
|
|
34070
34225
|
artifacts.push({
|
|
34071
34226
|
path: toProjectRelative(context.targetDir, path),
|
|
@@ -34088,9 +34243,9 @@ function readRunRecord(runDir) {
|
|
|
34088
34243
|
}
|
|
34089
34244
|
function walkFiles(dir) {
|
|
34090
34245
|
const files = [];
|
|
34091
|
-
for (const entry of
|
|
34246
|
+
for (const entry of readdirSync5(dir)) {
|
|
34092
34247
|
const full = join8(dir, entry);
|
|
34093
|
-
if (
|
|
34248
|
+
if (statSync4(full).isDirectory())
|
|
34094
34249
|
files.push(...walkFiles(full));
|
|
34095
34250
|
else
|
|
34096
34251
|
files.push(full);
|
|
@@ -34362,9 +34517,10 @@ function registerOperationTools(server) {
|
|
|
34362
34517
|
name: exports_external.string(),
|
|
34363
34518
|
input: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
|
|
34364
34519
|
args: exports_external.array(exports_external.string()).optional(),
|
|
34365
|
-
approved: exports_external.boolean().optional()
|
|
34520
|
+
approved: exports_external.boolean().optional(),
|
|
34521
|
+
detail: exports_external.boolean().optional()
|
|
34366
34522
|
}
|
|
34367
|
-
}, async ({ name, input, args, approved }) => {
|
|
34523
|
+
}, async ({ name, input, args, approved, detail }) => {
|
|
34368
34524
|
const skill = getSkill(name);
|
|
34369
34525
|
if (!skill) {
|
|
34370
34526
|
return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
|
|
@@ -34430,7 +34586,7 @@ function registerOperationTools(server) {
|
|
|
34430
34586
|
});
|
|
34431
34587
|
writeRunLogs(runContext, "", "");
|
|
34432
34588
|
const remoteRunId = typeof run.id === "string" ? run.id : undefined;
|
|
34433
|
-
|
|
34589
|
+
const payload2 = {
|
|
34434
34590
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
34435
34591
|
id: run.id,
|
|
34436
34592
|
localRunId: localRun2.id,
|
|
@@ -34441,7 +34597,8 @@ function registerOperationTools(server) {
|
|
|
34441
34597
|
remoteRun: run,
|
|
34442
34598
|
run: localRun2,
|
|
34443
34599
|
nextActions: remoteRunNextActions(remoteRunId)
|
|
34444
|
-
}
|
|
34600
|
+
};
|
|
34601
|
+
return mcpJson(detail ? payload2 : compactRunToolPayload(payload2, "Call run_skill again with detail:true for full remote/local run records."));
|
|
34445
34602
|
} catch (err) {
|
|
34446
34603
|
const error48 = `Hosted skill ${skillName} requires hosted access: ${err.message}`;
|
|
34447
34604
|
writeRunLogs(runContext, "", error48 + `
|
|
@@ -34463,23 +34620,23 @@ function registerOperationTools(server) {
|
|
|
34463
34620
|
status: result.exitCode === 0 ? "completed" : "failed",
|
|
34464
34621
|
error: result.error
|
|
34465
34622
|
});
|
|
34623
|
+
const payload = { exitCode: result.exitCode, skill: skillName, stdout: result.stdout, stderr: result.stderr, run: localRun };
|
|
34466
34624
|
if (result.error) {
|
|
34467
34625
|
return {
|
|
34468
|
-
content: [{ type: "text", text: JSON.stringify({
|
|
34626
|
+
content: [{ type: "text", text: JSON.stringify(detail ? { ...payload, error: result.error } : compactRunToolPayload({ ...payload, error: result.error }, "Call run_skill again with detail:true for full stdout/stderr and run metadata.")) }],
|
|
34469
34627
|
isError: true
|
|
34470
34628
|
};
|
|
34471
34629
|
}
|
|
34472
|
-
return
|
|
34473
|
-
content: [{ type: "text", text: JSON.stringify({ exitCode: result.exitCode, skill: skillName, stdout: result.stdout, stderr: result.stderr, run: localRun }, null, 2) }]
|
|
34474
|
-
};
|
|
34630
|
+
return mcpJson(detail ? payload : compactRunToolPayload(payload, "Call run_skill again with detail:true for full stdout/stderr and run metadata."));
|
|
34475
34631
|
});
|
|
34476
34632
|
server.registerTool("get_run_status", {
|
|
34477
34633
|
title: "Get Run Status",
|
|
34478
34634
|
description: "Fetch remote run status. Accepts a remote run id or a local run id linked to a remote run.",
|
|
34479
34635
|
inputSchema: {
|
|
34480
|
-
run_id: exports_external.string()
|
|
34636
|
+
run_id: exports_external.string(),
|
|
34637
|
+
detail: exports_external.boolean().optional()
|
|
34481
34638
|
}
|
|
34482
|
-
}, async ({ run_id }) => {
|
|
34639
|
+
}, async ({ run_id, detail }) => {
|
|
34483
34640
|
const { getApiKey: getApiKey2 } = await Promise.resolve().then(() => (init_auth_store(), exports_auth_store));
|
|
34484
34641
|
const apiKey = getApiKey2();
|
|
34485
34642
|
if (!apiKey) {
|
|
@@ -34496,12 +34653,20 @@ function registerOperationTools(server) {
|
|
|
34496
34653
|
const run = await client.getRun(remoteRunId);
|
|
34497
34654
|
if (!run)
|
|
34498
34655
|
return mcpError("RUN_NOT_FOUND", `Remote run '${remoteRunId}' not found`);
|
|
34499
|
-
|
|
34656
|
+
const payload = {
|
|
34500
34657
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
34501
34658
|
runId: remoteRunId,
|
|
34502
34659
|
...localRun ? { localRunId: localRun.id } : {},
|
|
34503
34660
|
run,
|
|
34504
34661
|
nextActions: remoteRunNextActions(remoteRunId)
|
|
34662
|
+
};
|
|
34663
|
+
return mcpJson(detail ? payload : {
|
|
34664
|
+
contractVersion: payload.contractVersion,
|
|
34665
|
+
runId: payload.runId,
|
|
34666
|
+
...localRun ? { localRunId: localRun.id } : {},
|
|
34667
|
+
run: compactRemoteRun(run),
|
|
34668
|
+
nextActions: payload.nextActions,
|
|
34669
|
+
detailHint: "Call get_run_status with detail:true for the complete remote run payload."
|
|
34505
34670
|
});
|
|
34506
34671
|
} catch (err) {
|
|
34507
34672
|
return mcpError("SKILLS_MD_ERROR", err.message);
|
|
@@ -34573,9 +34738,9 @@ function registerOperationTools(server) {
|
|
|
34573
34738
|
let skillCount = 0;
|
|
34574
34739
|
if (exists) {
|
|
34575
34740
|
try {
|
|
34576
|
-
skillCount =
|
|
34741
|
+
skillCount = readdirSync6(agentSkillsPath).filter((f) => {
|
|
34577
34742
|
const full = join10(agentSkillsPath, f);
|
|
34578
|
-
return !f.startsWith(".") &&
|
|
34743
|
+
return !f.startsWith(".") && statSync5(full).isDirectory();
|
|
34579
34744
|
}).length;
|
|
34580
34745
|
} catch {}
|
|
34581
34746
|
}
|
|
@@ -34593,6 +34758,32 @@ function registerOperationTools(server) {
|
|
|
34593
34758
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
34594
34759
|
});
|
|
34595
34760
|
}
|
|
34761
|
+
function compactRunToolPayload(payload, detailHint) {
|
|
34762
|
+
const stdout = previewText(payload.stdout ?? "");
|
|
34763
|
+
const stderr = previewText(payload.stderr ?? "");
|
|
34764
|
+
return {
|
|
34765
|
+
...payload.contractVersion !== undefined ? { contractVersion: payload.contractVersion } : {},
|
|
34766
|
+
...payload.id !== undefined ? { id: payload.id } : {},
|
|
34767
|
+
...payload.localRunId !== undefined ? { localRunId: payload.localRunId } : {},
|
|
34768
|
+
...payload.exitCode !== undefined ? { exitCode: payload.exitCode } : {},
|
|
34769
|
+
skill: payload.skill,
|
|
34770
|
+
...payload.status !== undefined ? { status: payload.status } : {},
|
|
34771
|
+
...payload.remote !== undefined ? { remote: payload.remote } : {},
|
|
34772
|
+
...payload.correlationId !== undefined ? { correlationId: payload.correlationId } : {},
|
|
34773
|
+
...payload.pricing !== undefined ? { pricing: payload.pricing } : {},
|
|
34774
|
+
...payload.error !== undefined ? { error: payload.error } : {},
|
|
34775
|
+
...payload.remoteRun !== undefined ? { remoteRun: compactRemoteRun(payload.remoteRun) } : {},
|
|
34776
|
+
run: compactRunRecord(payload.run),
|
|
34777
|
+
stdoutPreview: stdout,
|
|
34778
|
+
stderrPreview: stderr,
|
|
34779
|
+
stdoutChars: stdout.length,
|
|
34780
|
+
stderrChars: stderr.length,
|
|
34781
|
+
stdoutTruncated: stdout.truncated,
|
|
34782
|
+
stderrTruncated: stderr.truncated,
|
|
34783
|
+
...payload.nextActions !== undefined ? { nextActions: payload.nextActions } : {},
|
|
34784
|
+
detailHint
|
|
34785
|
+
};
|
|
34786
|
+
}
|
|
34596
34787
|
|
|
34597
34788
|
// src/lib/feedback.ts
|
|
34598
34789
|
import { existsSync as existsSync11, mkdirSync as mkdirSync6 } from "fs";
|
|
@@ -34951,11 +35142,37 @@ function registerScheduleTools(server) {
|
|
|
34951
35142
|
});
|
|
34952
35143
|
server.registerTool("list_schedules", {
|
|
34953
35144
|
title: "List Schedules",
|
|
34954
|
-
description: "List
|
|
34955
|
-
inputSchema: {
|
|
34956
|
-
|
|
35145
|
+
description: "List scheduled skill runs as a compact paged response. Use limit/offset for pagination.",
|
|
35146
|
+
inputSchema: {
|
|
35147
|
+
limit: exports_external.number().optional(),
|
|
35148
|
+
offset: exports_external.number().optional()
|
|
35149
|
+
}
|
|
35150
|
+
}, async ({ limit, offset }) => {
|
|
34957
35151
|
const schedules = listSchedules();
|
|
34958
|
-
|
|
35152
|
+
const page = paginate(schedules, {
|
|
35153
|
+
limit: parsePageLimit(limit, DEFAULT_MCP_LIMIT, { max: 100 }),
|
|
35154
|
+
offset: parsePageOffset(offset)
|
|
35155
|
+
});
|
|
35156
|
+
return mcpJson({
|
|
35157
|
+
schedules: page.items.map((schedule) => ({
|
|
35158
|
+
id: schedule.id,
|
|
35159
|
+
name: schedule.name,
|
|
35160
|
+
skill: schedule.skill,
|
|
35161
|
+
cron: schedule.cron,
|
|
35162
|
+
enabled: schedule.enabled,
|
|
35163
|
+
lastRun: schedule.lastRun,
|
|
35164
|
+
lastRunStatus: schedule.lastRunStatus,
|
|
35165
|
+
nextRun: schedule.nextRun,
|
|
35166
|
+
argCount: schedule.args?.length ?? 0
|
|
35167
|
+
})),
|
|
35168
|
+
total: page.total,
|
|
35169
|
+
offset: page.offset,
|
|
35170
|
+
limit: page.limit,
|
|
35171
|
+
nextOffset: page.nextOffset,
|
|
35172
|
+
hasMore: page.hasMore,
|
|
35173
|
+
nextArguments: page.hasMore ? { limit: page.limit, offset: page.nextOffset } : null,
|
|
35174
|
+
detailHint: "Use schedule state files or future schedule detail commands for complete schedule records."
|
|
35175
|
+
});
|
|
34959
35176
|
});
|
|
34960
35177
|
server.registerTool("remove_schedule", {
|
|
34961
35178
|
title: "Remove Schedule",
|
|
@@ -35011,8 +35228,8 @@ import {
|
|
|
35011
35228
|
existsSync as existsSync13,
|
|
35012
35229
|
mkdirSync as mkdirSync8,
|
|
35013
35230
|
readFileSync as readFileSync11,
|
|
35014
|
-
readdirSync as
|
|
35015
|
-
statSync as
|
|
35231
|
+
readdirSync as readdirSync7,
|
|
35232
|
+
statSync as statSync6,
|
|
35016
35233
|
writeFileSync as writeFileSync7
|
|
35017
35234
|
} from "fs";
|
|
35018
35235
|
import { dirname as dirname5, join as join13, normalize as normalize3, relative as relative3, sep } from "path";
|
|
@@ -35206,9 +35423,9 @@ function parsePositiveInteger(value) {
|
|
|
35206
35423
|
}
|
|
35207
35424
|
function walkFiles2(dir) {
|
|
35208
35425
|
const files = [];
|
|
35209
|
-
for (const entry of
|
|
35426
|
+
for (const entry of readdirSync7(dir)) {
|
|
35210
35427
|
const full = join13(dir, entry);
|
|
35211
|
-
const stats =
|
|
35428
|
+
const stats = statSync6(full);
|
|
35212
35429
|
if (stats.isDirectory())
|
|
35213
35430
|
files.push(...walkFiles2(full));
|
|
35214
35431
|
else
|