llmist 16.1.0 → 16.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +884 -61
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +486 -2
- package/dist/index.d.ts +486 -2
- package/dist/index.js +864 -51
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -2,6 +2,12 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
+
}) : x)(function(x) {
|
|
8
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
+
});
|
|
5
11
|
var __esm = (fn, res) => function __init() {
|
|
6
12
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
13
|
};
|
|
@@ -347,15 +353,15 @@ var init_execution_tree = __esm({
|
|
|
347
353
|
const parentId = params.parentId ?? this.parentNodeId;
|
|
348
354
|
const parent = parentId ? this.nodes.get(parentId) : null;
|
|
349
355
|
const depth = parent ? parent.depth + 1 : this.baseDepth;
|
|
350
|
-
const
|
|
356
|
+
const path3 = parent ? [...parent.path] : [];
|
|
351
357
|
const id = this.generateLLMCallId(params.iteration, parentId);
|
|
352
|
-
|
|
358
|
+
path3.push(id);
|
|
353
359
|
const node = {
|
|
354
360
|
id,
|
|
355
361
|
type: "llm_call",
|
|
356
362
|
parentId,
|
|
357
363
|
depth,
|
|
358
|
-
path,
|
|
364
|
+
path: path3,
|
|
359
365
|
createdAt: Date.now(),
|
|
360
366
|
completedAt: null,
|
|
361
367
|
iteration: params.iteration,
|
|
@@ -466,15 +472,15 @@ var init_execution_tree = __esm({
|
|
|
466
472
|
const parentId = params.parentId ?? this.getCurrentLLMCallId() ?? this.parentNodeId;
|
|
467
473
|
const parent = parentId ? this.nodes.get(parentId) : null;
|
|
468
474
|
const depth = parent ? parent.depth + 1 : this.baseDepth;
|
|
469
|
-
const
|
|
475
|
+
const path3 = parent ? [...parent.path] : [];
|
|
470
476
|
const id = this.generateGadgetId(params.invocationId);
|
|
471
|
-
|
|
477
|
+
path3.push(id);
|
|
472
478
|
const node = {
|
|
473
479
|
id,
|
|
474
480
|
type: "gadget",
|
|
475
481
|
parentId,
|
|
476
482
|
depth,
|
|
477
|
-
path,
|
|
483
|
+
path: path3,
|
|
478
484
|
createdAt: Date.now(),
|
|
479
485
|
completedAt: null,
|
|
480
486
|
invocationId: params.invocationId,
|
|
@@ -1413,8 +1419,8 @@ ${this.endPrefix}`
|
|
|
1413
1419
|
});
|
|
1414
1420
|
if (media && media.length > 0 && mediaIds && mediaIds.length > 0) {
|
|
1415
1421
|
const idRefs = media.map((m, i) => {
|
|
1416
|
-
const
|
|
1417
|
-
const pathInfo =
|
|
1422
|
+
const path3 = storedMedia?.[i]?.path;
|
|
1423
|
+
const pathInfo = path3 ? ` \u2192 saved to: ${path3}` : "";
|
|
1418
1424
|
return `[Media: ${mediaIds[i]} (${m.kind})${pathInfo}]`;
|
|
1419
1425
|
}).join("\n");
|
|
1420
1426
|
const textWithIds = `Result (${invocationId}): ${result}
|
|
@@ -4022,29 +4028,29 @@ function schemaToJSONSchema(schema, options) {
|
|
|
4022
4028
|
}
|
|
4023
4029
|
function detectDescriptionMismatch(schema, jsonSchema) {
|
|
4024
4030
|
const mismatches = [];
|
|
4025
|
-
function checkSchema(zodSchema, json,
|
|
4031
|
+
function checkSchema(zodSchema, json, path3) {
|
|
4026
4032
|
if (!zodSchema || typeof zodSchema !== "object") return;
|
|
4027
4033
|
const def = zodSchema._def;
|
|
4028
4034
|
const jsonObj = json;
|
|
4029
4035
|
if (def?.description && !jsonObj?.description) {
|
|
4030
|
-
mismatches.push(
|
|
4036
|
+
mismatches.push(path3 || "root");
|
|
4031
4037
|
}
|
|
4032
4038
|
if (def?.typeName === "ZodObject" && def?.shape) {
|
|
4033
4039
|
const shape = typeof def.shape === "function" ? def.shape() : def.shape;
|
|
4034
4040
|
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
4035
4041
|
const properties = jsonObj?.properties;
|
|
4036
4042
|
const jsonProp = properties?.[key];
|
|
4037
|
-
checkSchema(fieldSchema, jsonProp,
|
|
4043
|
+
checkSchema(fieldSchema, jsonProp, path3 ? `${path3}.${key}` : key);
|
|
4038
4044
|
}
|
|
4039
4045
|
}
|
|
4040
4046
|
if (def?.typeName === "ZodArray" && def?.type) {
|
|
4041
|
-
checkSchema(def.type, jsonObj?.items,
|
|
4047
|
+
checkSchema(def.type, jsonObj?.items, path3 ? `${path3}[]` : "[]");
|
|
4042
4048
|
}
|
|
4043
4049
|
if ((def?.typeName === "ZodOptional" || def?.typeName === "ZodNullable") && def?.innerType) {
|
|
4044
|
-
checkSchema(def.innerType, json,
|
|
4050
|
+
checkSchema(def.innerType, json, path3);
|
|
4045
4051
|
}
|
|
4046
4052
|
if (def?.typeName === "ZodDefault" && def?.innerType) {
|
|
4047
|
-
checkSchema(def.innerType, json,
|
|
4053
|
+
checkSchema(def.innerType, json, path3);
|
|
4048
4054
|
}
|
|
4049
4055
|
}
|
|
4050
4056
|
checkSchema(schema, jsonSchema, "");
|
|
@@ -4136,7 +4142,7 @@ Example fixes:
|
|
|
4136
4142
|
);
|
|
4137
4143
|
}
|
|
4138
4144
|
}
|
|
4139
|
-
function findUnknownTypes(schema,
|
|
4145
|
+
function findUnknownTypes(schema, path3 = []) {
|
|
4140
4146
|
const issues = [];
|
|
4141
4147
|
if (!schema || typeof schema !== "object") {
|
|
4142
4148
|
return issues;
|
|
@@ -4148,7 +4154,7 @@ function findUnknownTypes(schema, path = []) {
|
|
|
4148
4154
|
}
|
|
4149
4155
|
if (schema.properties) {
|
|
4150
4156
|
for (const [propName, propSchema] of Object.entries(schema.properties)) {
|
|
4151
|
-
const propPath = [...
|
|
4157
|
+
const propPath = [...path3, propName];
|
|
4152
4158
|
if (hasNoType(propSchema)) {
|
|
4153
4159
|
issues.push(propPath.join(".") || propName);
|
|
4154
4160
|
}
|
|
@@ -4156,7 +4162,7 @@ function findUnknownTypes(schema, path = []) {
|
|
|
4156
4162
|
}
|
|
4157
4163
|
}
|
|
4158
4164
|
if (schema.items) {
|
|
4159
|
-
const itemPath = [...
|
|
4165
|
+
const itemPath = [...path3, "[]"];
|
|
4160
4166
|
if (hasNoType(schema.items)) {
|
|
4161
4167
|
issues.push(itemPath.join("."));
|
|
4162
4168
|
}
|
|
@@ -4164,17 +4170,17 @@ function findUnknownTypes(schema, path = []) {
|
|
|
4164
4170
|
}
|
|
4165
4171
|
if (schema.anyOf) {
|
|
4166
4172
|
schema.anyOf.forEach((subSchema, index) => {
|
|
4167
|
-
issues.push(...findUnknownTypes(subSchema, [...
|
|
4173
|
+
issues.push(...findUnknownTypes(subSchema, [...path3, `anyOf[${index}]`]));
|
|
4168
4174
|
});
|
|
4169
4175
|
}
|
|
4170
4176
|
if (schema.oneOf) {
|
|
4171
4177
|
schema.oneOf.forEach((subSchema, index) => {
|
|
4172
|
-
issues.push(...findUnknownTypes(subSchema, [...
|
|
4178
|
+
issues.push(...findUnknownTypes(subSchema, [...path3, `oneOf[${index}]`]));
|
|
4173
4179
|
});
|
|
4174
4180
|
}
|
|
4175
4181
|
if (schema.allOf) {
|
|
4176
4182
|
schema.allOf.forEach((subSchema, index) => {
|
|
4177
|
-
issues.push(...findUnknownTypes(subSchema, [...
|
|
4183
|
+
issues.push(...findUnknownTypes(subSchema, [...path3, `allOf[${index}]`]));
|
|
4178
4184
|
});
|
|
4179
4185
|
}
|
|
4180
4186
|
return issues;
|
|
@@ -5190,6 +5196,625 @@ var init_registry = __esm({
|
|
|
5190
5196
|
}
|
|
5191
5197
|
});
|
|
5192
5198
|
|
|
5199
|
+
// src/skills/activation.ts
|
|
5200
|
+
import { execSync } from "child_process";
|
|
5201
|
+
function substituteArguments(instructions, args) {
|
|
5202
|
+
if (!args) {
|
|
5203
|
+
return instructions.replace(/\$ARGUMENTS\[\d+\]/g, "").replace(/\$ARGUMENTS/g, "").replace(/\$\d+/g, "");
|
|
5204
|
+
}
|
|
5205
|
+
const parts = splitArguments(args);
|
|
5206
|
+
let result = instructions.replace(/\$ARGUMENTS\[(\d+)\]/g, (_match, index) => {
|
|
5207
|
+
const i = Number.parseInt(index, 10);
|
|
5208
|
+
return parts[i] ?? "";
|
|
5209
|
+
});
|
|
5210
|
+
result = result.replace(/\$ARGUMENTS/g, args);
|
|
5211
|
+
result = result.replace(/\$(\d+)/g, (_match, index) => {
|
|
5212
|
+
const i = Number.parseInt(index, 10);
|
|
5213
|
+
return parts[i] ?? "";
|
|
5214
|
+
});
|
|
5215
|
+
return result;
|
|
5216
|
+
}
|
|
5217
|
+
function preprocessShellCommands(instructions, options) {
|
|
5218
|
+
const { cwd, shell = "bash", timeoutMs = 1e4 } = options ?? {};
|
|
5219
|
+
return instructions.replace(/!`([^`]+)`/g, (_match, command) => {
|
|
5220
|
+
try {
|
|
5221
|
+
const output = execSync(command, {
|
|
5222
|
+
cwd,
|
|
5223
|
+
shell: shell === "powershell" ? "powershell" : "/bin/bash",
|
|
5224
|
+
timeout: timeoutMs,
|
|
5225
|
+
encoding: "utf-8",
|
|
5226
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
5227
|
+
});
|
|
5228
|
+
return output.trim();
|
|
5229
|
+
} catch (error) {
|
|
5230
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
5231
|
+
return `[Error executing \`${command}\`: ${msg}]`;
|
|
5232
|
+
}
|
|
5233
|
+
});
|
|
5234
|
+
}
|
|
5235
|
+
function substituteVariables(instructions, variables) {
|
|
5236
|
+
return instructions.replace(/\$\{(\w+)\}/g, (_match, varName) => {
|
|
5237
|
+
return variables[varName] ?? "";
|
|
5238
|
+
});
|
|
5239
|
+
}
|
|
5240
|
+
function resolveInstructions(instructions, options) {
|
|
5241
|
+
let resolved = instructions;
|
|
5242
|
+
if (options?.variables) {
|
|
5243
|
+
resolved = substituteVariables(resolved, options.variables);
|
|
5244
|
+
}
|
|
5245
|
+
resolved = substituteArguments(resolved, options?.arguments);
|
|
5246
|
+
if (options?.enableShellPreprocessing !== false) {
|
|
5247
|
+
resolved = preprocessShellCommands(resolved, {
|
|
5248
|
+
cwd: options?.cwd,
|
|
5249
|
+
shell: options?.shell,
|
|
5250
|
+
timeoutMs: options?.shellTimeoutMs
|
|
5251
|
+
});
|
|
5252
|
+
}
|
|
5253
|
+
return resolved;
|
|
5254
|
+
}
|
|
5255
|
+
function splitArguments(args) {
|
|
5256
|
+
const parts = [];
|
|
5257
|
+
let current = "";
|
|
5258
|
+
let inQuote = null;
|
|
5259
|
+
for (const char of args) {
|
|
5260
|
+
if (inQuote) {
|
|
5261
|
+
if (char === inQuote) {
|
|
5262
|
+
inQuote = null;
|
|
5263
|
+
} else {
|
|
5264
|
+
current += char;
|
|
5265
|
+
}
|
|
5266
|
+
} else if (char === '"' || char === "'") {
|
|
5267
|
+
inQuote = char;
|
|
5268
|
+
} else if (char === " " || char === " ") {
|
|
5269
|
+
if (current) {
|
|
5270
|
+
parts.push(current);
|
|
5271
|
+
current = "";
|
|
5272
|
+
}
|
|
5273
|
+
} else {
|
|
5274
|
+
current += char;
|
|
5275
|
+
}
|
|
5276
|
+
}
|
|
5277
|
+
if (current) parts.push(current);
|
|
5278
|
+
return parts;
|
|
5279
|
+
}
|
|
5280
|
+
var init_activation = __esm({
|
|
5281
|
+
"src/skills/activation.ts"() {
|
|
5282
|
+
"use strict";
|
|
5283
|
+
}
|
|
5284
|
+
});
|
|
5285
|
+
|
|
5286
|
+
// src/skills/parser.ts
|
|
5287
|
+
import fs from "fs";
|
|
5288
|
+
import path from "path";
|
|
5289
|
+
import yaml from "js-yaml";
|
|
5290
|
+
function parseFrontmatter(content) {
|
|
5291
|
+
const trimmed = content.trimStart();
|
|
5292
|
+
if (!trimmed.startsWith("---")) {
|
|
5293
|
+
return { frontmatter: {}, body: content };
|
|
5294
|
+
}
|
|
5295
|
+
const endIndex = trimmed.indexOf("\n---", 3);
|
|
5296
|
+
if (endIndex === -1) {
|
|
5297
|
+
return { frontmatter: {}, body: content };
|
|
5298
|
+
}
|
|
5299
|
+
const yamlBlock = trimmed.slice(3, endIndex).trim();
|
|
5300
|
+
const body = trimmed.slice(endIndex + 4).trim();
|
|
5301
|
+
const parsed = yaml.load(yamlBlock);
|
|
5302
|
+
const frontmatter = typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
5303
|
+
return { frontmatter, body };
|
|
5304
|
+
}
|
|
5305
|
+
function parseMetadata(frontmatter, fallbackName) {
|
|
5306
|
+
const name = parseString(frontmatter.name) ?? fallbackName ?? "unnamed-skill";
|
|
5307
|
+
const description = parseString(frontmatter.description) ?? "";
|
|
5308
|
+
return {
|
|
5309
|
+
name,
|
|
5310
|
+
description,
|
|
5311
|
+
argumentHint: parseString(frontmatter["argument-hint"]),
|
|
5312
|
+
allowedTools: parseStringArray(frontmatter["allowed-tools"]),
|
|
5313
|
+
model: parseString(frontmatter.model),
|
|
5314
|
+
context: parseContext(frontmatter.context),
|
|
5315
|
+
agent: parseString(frontmatter.agent),
|
|
5316
|
+
paths: parseStringArray(frontmatter.paths),
|
|
5317
|
+
gadgets: parseStringArray(frontmatter.gadgets),
|
|
5318
|
+
disableModelInvocation: parseBool(frontmatter["disable-model-invocation"]),
|
|
5319
|
+
userInvocable: parseBool(frontmatter["user-invocable"]),
|
|
5320
|
+
shell: parseShell(frontmatter.shell),
|
|
5321
|
+
version: parseString(frontmatter.version)
|
|
5322
|
+
};
|
|
5323
|
+
}
|
|
5324
|
+
function scanResources(skillDir) {
|
|
5325
|
+
const resources = [];
|
|
5326
|
+
for (const category of RESOURCE_CATEGORIES) {
|
|
5327
|
+
const categoryDir = path.join(skillDir, category);
|
|
5328
|
+
if (!fs.existsSync(categoryDir)) continue;
|
|
5329
|
+
const stat = fs.statSync(categoryDir);
|
|
5330
|
+
if (!stat.isDirectory()) continue;
|
|
5331
|
+
for (const file of walkDirectory(categoryDir)) {
|
|
5332
|
+
resources.push({
|
|
5333
|
+
relativePath: path.relative(skillDir, file),
|
|
5334
|
+
absolutePath: file,
|
|
5335
|
+
category
|
|
5336
|
+
});
|
|
5337
|
+
}
|
|
5338
|
+
}
|
|
5339
|
+
return resources;
|
|
5340
|
+
}
|
|
5341
|
+
function parseSkillFile(skillMdPath, source, loadInstructions = false) {
|
|
5342
|
+
const content = fs.readFileSync(skillMdPath, "utf-8");
|
|
5343
|
+
return parseSkillContent(content, skillMdPath, source, loadInstructions);
|
|
5344
|
+
}
|
|
5345
|
+
function parseSkillContent(content, sourcePath, source, loadInstructions = false) {
|
|
5346
|
+
const sourceDir = path.dirname(sourcePath);
|
|
5347
|
+
const fallbackName = path.basename(sourceDir);
|
|
5348
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
5349
|
+
const metadata = parseMetadata(frontmatter, fallbackName);
|
|
5350
|
+
const resources = fs.existsSync(sourceDir) ? scanResources(sourceDir) : [];
|
|
5351
|
+
return {
|
|
5352
|
+
metadata,
|
|
5353
|
+
instructions: loadInstructions ? body : null,
|
|
5354
|
+
resources,
|
|
5355
|
+
sourcePath,
|
|
5356
|
+
sourceDir,
|
|
5357
|
+
source
|
|
5358
|
+
};
|
|
5359
|
+
}
|
|
5360
|
+
function validateMetadata(metadata) {
|
|
5361
|
+
const issues = [];
|
|
5362
|
+
if (!metadata.name) {
|
|
5363
|
+
issues.push("Skill name is required");
|
|
5364
|
+
} else {
|
|
5365
|
+
if (metadata.name.length > MAX_NAME_LENGTH) {
|
|
5366
|
+
issues.push(`Skill name exceeds ${MAX_NAME_LENGTH} characters`);
|
|
5367
|
+
}
|
|
5368
|
+
if (!NAME_PATTERN.test(metadata.name)) {
|
|
5369
|
+
issues.push(
|
|
5370
|
+
"Skill name must contain only lowercase letters, numbers, and hyphens, and must start with a letter or number"
|
|
5371
|
+
);
|
|
5372
|
+
}
|
|
5373
|
+
}
|
|
5374
|
+
if (!metadata.description) {
|
|
5375
|
+
issues.push("Skill description is required");
|
|
5376
|
+
} else if (metadata.description.length > MAX_DESCRIPTION_LENGTH) {
|
|
5377
|
+
issues.push(`Skill description exceeds ${MAX_DESCRIPTION_LENGTH} characters`);
|
|
5378
|
+
}
|
|
5379
|
+
if (metadata.context && metadata.context !== "fork" && metadata.context !== "inline") {
|
|
5380
|
+
issues.push('Skill context must be "fork" or "inline"');
|
|
5381
|
+
}
|
|
5382
|
+
return issues;
|
|
5383
|
+
}
|
|
5384
|
+
function parseString(value) {
|
|
5385
|
+
if (value == null) return void 0;
|
|
5386
|
+
if (typeof value === "string") return value;
|
|
5387
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
5388
|
+
return void 0;
|
|
5389
|
+
}
|
|
5390
|
+
function parseStringArray(value) {
|
|
5391
|
+
if (value == null) return void 0;
|
|
5392
|
+
if (Array.isArray(value)) {
|
|
5393
|
+
return value.filter((v) => typeof v === "string" || typeof v === "number").map(String);
|
|
5394
|
+
}
|
|
5395
|
+
if (typeof value === "string") return [value];
|
|
5396
|
+
return void 0;
|
|
5397
|
+
}
|
|
5398
|
+
function parseContext(value) {
|
|
5399
|
+
if (value === "fork" || value === "inline") return value;
|
|
5400
|
+
return void 0;
|
|
5401
|
+
}
|
|
5402
|
+
function parseShell(value) {
|
|
5403
|
+
if (value === "bash" || value === "powershell") return value;
|
|
5404
|
+
return void 0;
|
|
5405
|
+
}
|
|
5406
|
+
function parseBool(value) {
|
|
5407
|
+
if (value === true || value === false) return value;
|
|
5408
|
+
if (value === "true") return true;
|
|
5409
|
+
if (value === "false") return false;
|
|
5410
|
+
return void 0;
|
|
5411
|
+
}
|
|
5412
|
+
function* walkDirectory(dir) {
|
|
5413
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
5414
|
+
for (const entry of entries) {
|
|
5415
|
+
const fullPath = path.join(dir, entry.name);
|
|
5416
|
+
if (entry.isDirectory()) {
|
|
5417
|
+
yield* walkDirectory(fullPath);
|
|
5418
|
+
} else if (entry.isFile()) {
|
|
5419
|
+
yield fullPath;
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5422
|
+
}
|
|
5423
|
+
var RESOURCE_CATEGORIES, MAX_NAME_LENGTH, MAX_DESCRIPTION_LENGTH, NAME_PATTERN;
|
|
5424
|
+
var init_parser = __esm({
|
|
5425
|
+
"src/skills/parser.ts"() {
|
|
5426
|
+
"use strict";
|
|
5427
|
+
RESOURCE_CATEGORIES = ["scripts", "references", "assets"];
|
|
5428
|
+
MAX_NAME_LENGTH = 64;
|
|
5429
|
+
MAX_DESCRIPTION_LENGTH = 1024;
|
|
5430
|
+
NAME_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
|
|
5431
|
+
}
|
|
5432
|
+
});
|
|
5433
|
+
|
|
5434
|
+
// src/skills/registry.ts
|
|
5435
|
+
var registry_exports = {};
|
|
5436
|
+
__export(registry_exports, {
|
|
5437
|
+
SkillRegistry: () => SkillRegistry
|
|
5438
|
+
});
|
|
5439
|
+
import { minimatch } from "minimatch";
|
|
5440
|
+
var DEFAULT_CHAR_BUDGET, SUMMARY_DESCRIPTION_LIMIT, SkillRegistry;
|
|
5441
|
+
var init_registry2 = __esm({
|
|
5442
|
+
"src/skills/registry.ts"() {
|
|
5443
|
+
"use strict";
|
|
5444
|
+
DEFAULT_CHAR_BUDGET = 8e3;
|
|
5445
|
+
SUMMARY_DESCRIPTION_LIMIT = 250;
|
|
5446
|
+
SkillRegistry = class _SkillRegistry {
|
|
5447
|
+
skills = /* @__PURE__ */ new Map();
|
|
5448
|
+
/**
|
|
5449
|
+
* Register a skill. Overwrites any existing skill with the same name.
|
|
5450
|
+
*
|
|
5451
|
+
* Unlike GadgetRegistry (which throws on duplicates), SkillRegistry allows
|
|
5452
|
+
* overwriting because skills are loaded from multiple sources with intentional
|
|
5453
|
+
* priority ordering (project > user > default).
|
|
5454
|
+
*/
|
|
5455
|
+
register(skill) {
|
|
5456
|
+
this.skills.set(skill.name.toLowerCase(), skill);
|
|
5457
|
+
}
|
|
5458
|
+
/** Register multiple skills. */
|
|
5459
|
+
registerMany(skills) {
|
|
5460
|
+
for (const skill of skills) {
|
|
5461
|
+
this.register(skill);
|
|
5462
|
+
}
|
|
5463
|
+
}
|
|
5464
|
+
/** Remove a skill by name (case-insensitive). Returns true if removed. */
|
|
5465
|
+
remove(name) {
|
|
5466
|
+
return this.skills.delete(name.toLowerCase());
|
|
5467
|
+
}
|
|
5468
|
+
/** Remove all registered skills. */
|
|
5469
|
+
clear() {
|
|
5470
|
+
this.skills.clear();
|
|
5471
|
+
}
|
|
5472
|
+
/** Get a skill by name (case-insensitive). */
|
|
5473
|
+
get(name) {
|
|
5474
|
+
return this.skills.get(name.toLowerCase());
|
|
5475
|
+
}
|
|
5476
|
+
/** Check if a skill exists by name (case-insensitive). */
|
|
5477
|
+
has(name) {
|
|
5478
|
+
return this.skills.has(name.toLowerCase());
|
|
5479
|
+
}
|
|
5480
|
+
/** Get all registered skills. */
|
|
5481
|
+
getAll() {
|
|
5482
|
+
return [...this.skills.values()];
|
|
5483
|
+
}
|
|
5484
|
+
/** Get all skill names. */
|
|
5485
|
+
getNames() {
|
|
5486
|
+
return [...this.skills.keys()];
|
|
5487
|
+
}
|
|
5488
|
+
/** Number of registered skills. */
|
|
5489
|
+
get size() {
|
|
5490
|
+
return this.skills.size;
|
|
5491
|
+
}
|
|
5492
|
+
/**
|
|
5493
|
+
* Get skills that are visible to the LLM for auto-triggering.
|
|
5494
|
+
* Excludes skills with disableModelInvocation: true.
|
|
5495
|
+
*/
|
|
5496
|
+
getModelInvocable() {
|
|
5497
|
+
return this.getAll().filter((s) => s.isModelInvocable);
|
|
5498
|
+
}
|
|
5499
|
+
/**
|
|
5500
|
+
* Get skills that the user can invoke via /skill-name.
|
|
5501
|
+
* Excludes skills with userInvocable: false.
|
|
5502
|
+
*/
|
|
5503
|
+
getUserInvocable() {
|
|
5504
|
+
return this.getAll().filter((s) => s.isUserInvocable);
|
|
5505
|
+
}
|
|
5506
|
+
/**
|
|
5507
|
+
* Generate metadata summaries for system prompt injection (Tier 1).
|
|
5508
|
+
*
|
|
5509
|
+
* Each skill contributes a one-line summary: "name — description".
|
|
5510
|
+
* Output is truncated to fit the character budget.
|
|
5511
|
+
*
|
|
5512
|
+
* @param charBudget - Maximum characters for all summaries combined.
|
|
5513
|
+
*/
|
|
5514
|
+
getMetadataSummaries(charBudget = DEFAULT_CHAR_BUDGET) {
|
|
5515
|
+
const invocable = this.getModelInvocable();
|
|
5516
|
+
if (invocable.length === 0) return "";
|
|
5517
|
+
const lines = [];
|
|
5518
|
+
let totalChars = 0;
|
|
5519
|
+
for (const skill of invocable) {
|
|
5520
|
+
const desc = skill.description.length > SUMMARY_DESCRIPTION_LIMIT ? `${skill.description.slice(0, SUMMARY_DESCRIPTION_LIMIT - 3)}...` : skill.description;
|
|
5521
|
+
const line = `- ${skill.name}: ${desc}`;
|
|
5522
|
+
if (totalChars + line.length > charBudget) break;
|
|
5523
|
+
lines.push(line);
|
|
5524
|
+
totalChars += line.length + 1;
|
|
5525
|
+
}
|
|
5526
|
+
return lines.join("\n");
|
|
5527
|
+
}
|
|
5528
|
+
/**
|
|
5529
|
+
* Find skills whose `paths` patterns match a given file path.
|
|
5530
|
+
* Used for auto-activation when the user is working on specific files.
|
|
5531
|
+
*/
|
|
5532
|
+
findByFilePath(filePath) {
|
|
5533
|
+
return this.getModelInvocable().filter((skill) => {
|
|
5534
|
+
const patterns = skill.metadata.paths;
|
|
5535
|
+
if (!patterns || patterns.length === 0) return false;
|
|
5536
|
+
return patterns.some((pattern) => minimatch(filePath, pattern));
|
|
5537
|
+
});
|
|
5538
|
+
}
|
|
5539
|
+
/**
|
|
5540
|
+
* Merge another registry into this one.
|
|
5541
|
+
* Skills from the other registry overwrite existing skills with the same name.
|
|
5542
|
+
*/
|
|
5543
|
+
merge(other) {
|
|
5544
|
+
for (const skill of other.getAll()) {
|
|
5545
|
+
this.register(skill);
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
/** Create a registry from an array of skills. */
|
|
5549
|
+
static from(skills) {
|
|
5550
|
+
const registry = new _SkillRegistry();
|
|
5551
|
+
registry.registerMany(skills);
|
|
5552
|
+
return registry;
|
|
5553
|
+
}
|
|
5554
|
+
};
|
|
5555
|
+
}
|
|
5556
|
+
});
|
|
5557
|
+
|
|
5558
|
+
// src/skills/skill.ts
|
|
5559
|
+
import fs2 from "fs/promises";
|
|
5560
|
+
var Skill;
|
|
5561
|
+
var init_skill = __esm({
|
|
5562
|
+
"src/skills/skill.ts"() {
|
|
5563
|
+
"use strict";
|
|
5564
|
+
init_activation();
|
|
5565
|
+
init_parser();
|
|
5566
|
+
Skill = class _Skill {
|
|
5567
|
+
metadata;
|
|
5568
|
+
sourcePath;
|
|
5569
|
+
sourceDir;
|
|
5570
|
+
source;
|
|
5571
|
+
_instructions;
|
|
5572
|
+
_resources;
|
|
5573
|
+
_resourceCache = /* @__PURE__ */ new Map();
|
|
5574
|
+
_resourceLoading = /* @__PURE__ */ new Map();
|
|
5575
|
+
constructor(parsed) {
|
|
5576
|
+
this.metadata = parsed.metadata;
|
|
5577
|
+
this.sourcePath = parsed.sourcePath;
|
|
5578
|
+
this.sourceDir = parsed.sourceDir;
|
|
5579
|
+
this.source = parsed.source;
|
|
5580
|
+
this._instructions = parsed.instructions;
|
|
5581
|
+
this._resources = parsed.resources;
|
|
5582
|
+
}
|
|
5583
|
+
/** Skill name for registry lookup. */
|
|
5584
|
+
get name() {
|
|
5585
|
+
return this.metadata.name;
|
|
5586
|
+
}
|
|
5587
|
+
/** Skill description for LLM matching. */
|
|
5588
|
+
get description() {
|
|
5589
|
+
return this.metadata.description;
|
|
5590
|
+
}
|
|
5591
|
+
/** Whether the LLM can auto-trigger this skill. */
|
|
5592
|
+
get isModelInvocable() {
|
|
5593
|
+
return this.metadata.disableModelInvocation !== true;
|
|
5594
|
+
}
|
|
5595
|
+
/** Whether the user can invoke this skill via /skill-name. */
|
|
5596
|
+
get isUserInvocable() {
|
|
5597
|
+
return this.metadata.userInvocable !== false;
|
|
5598
|
+
}
|
|
5599
|
+
/**
|
|
5600
|
+
* Load and cache Tier 2 instructions.
|
|
5601
|
+
* If instructions were loaded during parsing, returns the cached value.
|
|
5602
|
+
*/
|
|
5603
|
+
async getInstructions() {
|
|
5604
|
+
if (this._instructions !== null) return this._instructions;
|
|
5605
|
+
const content = await fs2.readFile(this.sourcePath, "utf-8");
|
|
5606
|
+
const { body } = parseFrontmatter(content);
|
|
5607
|
+
this._instructions = body;
|
|
5608
|
+
return body;
|
|
5609
|
+
}
|
|
5610
|
+
/**
|
|
5611
|
+
* List Tier 3 resources.
|
|
5612
|
+
* Resources are discovered at parse time but content is loaded on demand.
|
|
5613
|
+
*/
|
|
5614
|
+
getResources() {
|
|
5615
|
+
return this._resources;
|
|
5616
|
+
}
|
|
5617
|
+
/**
|
|
5618
|
+
* Load a specific Tier 3 resource by relative path.
|
|
5619
|
+
* Results are cached for the lifetime of this Skill instance.
|
|
5620
|
+
* Concurrent calls for the same resource share a single read.
|
|
5621
|
+
*/
|
|
5622
|
+
async getResource(relativePath) {
|
|
5623
|
+
if (relativePath.includes("..")) {
|
|
5624
|
+
throw new Error(`Invalid resource path (path traversal): ${relativePath}`);
|
|
5625
|
+
}
|
|
5626
|
+
const cached = this._resourceCache.get(relativePath);
|
|
5627
|
+
if (cached !== void 0) return cached;
|
|
5628
|
+
const existing = this._resourceLoading.get(relativePath);
|
|
5629
|
+
if (existing) return existing;
|
|
5630
|
+
const resource = this._resources.find((r) => r.relativePath === relativePath);
|
|
5631
|
+
if (!resource) {
|
|
5632
|
+
throw new Error(`Resource not found: ${relativePath} in skill ${this.name}`);
|
|
5633
|
+
}
|
|
5634
|
+
const loadPromise = fs2.readFile(resource.absolutePath, "utf-8").then(
|
|
5635
|
+
(content) => {
|
|
5636
|
+
this._resourceCache.set(relativePath, content);
|
|
5637
|
+
this._resourceLoading.delete(relativePath);
|
|
5638
|
+
return content;
|
|
5639
|
+
},
|
|
5640
|
+
(error) => {
|
|
5641
|
+
this._resourceLoading.delete(relativePath);
|
|
5642
|
+
throw new Error(
|
|
5643
|
+
`Failed to load resource ${relativePath} in skill ${this.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
5644
|
+
);
|
|
5645
|
+
}
|
|
5646
|
+
);
|
|
5647
|
+
this._resourceLoading.set(relativePath, loadPromise);
|
|
5648
|
+
return loadPromise;
|
|
5649
|
+
}
|
|
5650
|
+
/**
|
|
5651
|
+
* Activate this skill with optional arguments.
|
|
5652
|
+
*
|
|
5653
|
+
* Performs:
|
|
5654
|
+
* 1. Variable substitution (${SKILL_DIR}, etc.)
|
|
5655
|
+
* 2. Argument substitution ($ARGUMENTS, $0, $1)
|
|
5656
|
+
* 3. Shell preprocessing (!`command`)
|
|
5657
|
+
* 4. Resource loading (if eagerResources is true)
|
|
5658
|
+
*/
|
|
5659
|
+
async activate(options) {
|
|
5660
|
+
const instructions = await this.getInstructions();
|
|
5661
|
+
const resolvedInstructions = resolveInstructions(instructions, {
|
|
5662
|
+
arguments: options?.arguments,
|
|
5663
|
+
variables: {
|
|
5664
|
+
SKILL_DIR: this.sourceDir,
|
|
5665
|
+
CLAUDE_SKILL_DIR: this.sourceDir
|
|
5666
|
+
},
|
|
5667
|
+
cwd: options?.cwd ?? this.sourceDir,
|
|
5668
|
+
shell: this.metadata.shell,
|
|
5669
|
+
enableShellPreprocessing: options?.enableShellPreprocessing,
|
|
5670
|
+
shellTimeoutMs: options?.shellTimeoutMs
|
|
5671
|
+
});
|
|
5672
|
+
const loadedResources = /* @__PURE__ */ new Map();
|
|
5673
|
+
if (options?.eagerResources) {
|
|
5674
|
+
for (const resource of this._resources) {
|
|
5675
|
+
const content = await this.getResource(resource.relativePath);
|
|
5676
|
+
loadedResources.set(resource.relativePath, content);
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
return {
|
|
5680
|
+
skillName: this.name,
|
|
5681
|
+
resolvedInstructions,
|
|
5682
|
+
gadgets: [],
|
|
5683
|
+
// Gadgets are resolved by the CLI layer
|
|
5684
|
+
loadedResources
|
|
5685
|
+
};
|
|
5686
|
+
}
|
|
5687
|
+
/**
|
|
5688
|
+
* Create a Skill from a SKILL.md content string.
|
|
5689
|
+
* Useful for testing or dynamic skill creation.
|
|
5690
|
+
*/
|
|
5691
|
+
static fromContent(content, sourcePath, source = { type: "directory", path: sourcePath }) {
|
|
5692
|
+
const parsed = parseSkillContent(content, sourcePath, source, true);
|
|
5693
|
+
return new _Skill(parsed);
|
|
5694
|
+
}
|
|
5695
|
+
};
|
|
5696
|
+
}
|
|
5697
|
+
});
|
|
5698
|
+
|
|
5699
|
+
// src/skills/loader.ts
|
|
5700
|
+
import fs3 from "fs";
|
|
5701
|
+
import os from "os";
|
|
5702
|
+
import path2 from "path";
|
|
5703
|
+
function loadSkillsFromDirectory(dir, source, onWarning) {
|
|
5704
|
+
if (!fs3.existsSync(dir)) return [];
|
|
5705
|
+
const stat = fs3.statSync(dir);
|
|
5706
|
+
if (!stat.isDirectory()) return [];
|
|
5707
|
+
const skills = [];
|
|
5708
|
+
scanForSkills(dir, source, skills, onWarning);
|
|
5709
|
+
return skills;
|
|
5710
|
+
}
|
|
5711
|
+
function discoverSkills(options) {
|
|
5712
|
+
const registry = new SkillRegistry();
|
|
5713
|
+
const userSkillsDir = options?.userDir ?? path2.join(os.homedir(), CONFIG_DIR_NAME, SKILLS_DIR_NAME);
|
|
5714
|
+
const userSkills = loadSkillsFromDirectory(userSkillsDir, {
|
|
5715
|
+
type: "user",
|
|
5716
|
+
path: userSkillsDir
|
|
5717
|
+
});
|
|
5718
|
+
registry.registerMany(userSkills);
|
|
5719
|
+
if (options?.projectDir) {
|
|
5720
|
+
const projectSkillsDir = path2.join(options.projectDir, CONFIG_DIR_NAME, SKILLS_DIR_NAME);
|
|
5721
|
+
const projectSkills = loadSkillsFromDirectory(projectSkillsDir, {
|
|
5722
|
+
type: "project",
|
|
5723
|
+
path: projectSkillsDir
|
|
5724
|
+
});
|
|
5725
|
+
registry.registerMany(projectSkills);
|
|
5726
|
+
}
|
|
5727
|
+
if (options?.additionalDirs) {
|
|
5728
|
+
for (const dir of options.additionalDirs) {
|
|
5729
|
+
const resolvedDir = dir.startsWith("~") ? path2.join(os.homedir(), dir.slice(1)) : dir;
|
|
5730
|
+
const skills = loadSkillsFromDirectory(resolvedDir, {
|
|
5731
|
+
type: "directory",
|
|
5732
|
+
path: resolvedDir
|
|
5733
|
+
});
|
|
5734
|
+
registry.registerMany(skills);
|
|
5735
|
+
}
|
|
5736
|
+
}
|
|
5737
|
+
return registry;
|
|
5738
|
+
}
|
|
5739
|
+
function scanForSkills(dir, source, results, onWarning) {
|
|
5740
|
+
let entries;
|
|
5741
|
+
try {
|
|
5742
|
+
entries = fs3.readdirSync(dir, { withFileTypes: true });
|
|
5743
|
+
} catch (error) {
|
|
5744
|
+
onWarning?.(
|
|
5745
|
+
`Cannot read skill directory ${dir}: ${error instanceof Error ? error.message : String(error)}`
|
|
5746
|
+
);
|
|
5747
|
+
return;
|
|
5748
|
+
}
|
|
5749
|
+
const skillMdPath = path2.join(dir, "SKILL.md");
|
|
5750
|
+
if (fs3.existsSync(skillMdPath)) {
|
|
5751
|
+
try {
|
|
5752
|
+
const parsed = parseSkillFile(skillMdPath, source, false);
|
|
5753
|
+
results.push(new Skill(parsed));
|
|
5754
|
+
} catch (error) {
|
|
5755
|
+
onWarning?.(
|
|
5756
|
+
`Failed to parse ${skillMdPath}: ${error instanceof Error ? error.message : String(error)}`
|
|
5757
|
+
);
|
|
5758
|
+
}
|
|
5759
|
+
return;
|
|
5760
|
+
}
|
|
5761
|
+
for (const entry of entries) {
|
|
5762
|
+
if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
5763
|
+
scanForSkills(path2.join(dir, entry.name), source, results, onWarning);
|
|
5764
|
+
}
|
|
5765
|
+
}
|
|
5766
|
+
}
|
|
5767
|
+
var SKILLS_DIR_NAME, CONFIG_DIR_NAME;
|
|
5768
|
+
var init_loader = __esm({
|
|
5769
|
+
"src/skills/loader.ts"() {
|
|
5770
|
+
"use strict";
|
|
5771
|
+
init_parser();
|
|
5772
|
+
init_registry2();
|
|
5773
|
+
init_skill();
|
|
5774
|
+
SKILLS_DIR_NAME = "skills";
|
|
5775
|
+
CONFIG_DIR_NAME = ".llmist";
|
|
5776
|
+
}
|
|
5777
|
+
});
|
|
5778
|
+
|
|
5779
|
+
// src/skills/use-skill-gadget.ts
|
|
5780
|
+
import { z as z4 } from "zod";
|
|
5781
|
+
function createUseSkillGadget(registry) {
|
|
5782
|
+
const summaries = registry.getMetadataSummaries();
|
|
5783
|
+
const skillNames = registry.getModelInvocable().map((s) => s.name);
|
|
5784
|
+
const description = [
|
|
5785
|
+
"Activate a skill to get specialized instructions for a task.",
|
|
5786
|
+
"Available skills:",
|
|
5787
|
+
summaries
|
|
5788
|
+
].join("\n");
|
|
5789
|
+
return createGadget({
|
|
5790
|
+
name: USE_SKILL_GADGET_NAME,
|
|
5791
|
+
description,
|
|
5792
|
+
schema: z4.object({
|
|
5793
|
+
skill: z4.enum(skillNames).describe("Name of the skill to activate"),
|
|
5794
|
+
arguments: z4.string().optional().describe("Arguments for the skill (e.g., a filename, issue number, or search query)")
|
|
5795
|
+
}),
|
|
5796
|
+
execute: async ({ skill: skillName, arguments: args }) => {
|
|
5797
|
+
const skill = registry.get(skillName);
|
|
5798
|
+
if (!skill) {
|
|
5799
|
+
return `Unknown skill: "${skillName}". Available skills: ${skillNames.join(", ")}`;
|
|
5800
|
+
}
|
|
5801
|
+
const activation = await skill.activate({
|
|
5802
|
+
arguments: args,
|
|
5803
|
+
cwd: process.cwd()
|
|
5804
|
+
});
|
|
5805
|
+
return activation.resolvedInstructions;
|
|
5806
|
+
}
|
|
5807
|
+
});
|
|
5808
|
+
}
|
|
5809
|
+
var USE_SKILL_GADGET_NAME;
|
|
5810
|
+
var init_use_skill_gadget = __esm({
|
|
5811
|
+
"src/skills/use-skill-gadget.ts"() {
|
|
5812
|
+
"use strict";
|
|
5813
|
+
init_create_gadget();
|
|
5814
|
+
USE_SKILL_GADGET_NAME = "UseSkill";
|
|
5815
|
+
}
|
|
5816
|
+
});
|
|
5817
|
+
|
|
5193
5818
|
// src/agent/builder-utils.ts
|
|
5194
5819
|
function formatGadgetCall(gadgetName, invocationId, parameters, prefixes) {
|
|
5195
5820
|
const startPrefix = prefixes?.start ?? GADGET_START_PREFIX;
|
|
@@ -12194,6 +12819,10 @@ var init_builder = __esm({
|
|
|
12194
12819
|
"use strict";
|
|
12195
12820
|
init_model_shortcuts();
|
|
12196
12821
|
init_registry();
|
|
12822
|
+
init_activation();
|
|
12823
|
+
init_loader();
|
|
12824
|
+
init_parser();
|
|
12825
|
+
init_use_skill_gadget();
|
|
12197
12826
|
init_agent();
|
|
12198
12827
|
init_agent_internal_key();
|
|
12199
12828
|
init_builder_utils();
|
|
@@ -12205,12 +12834,14 @@ var init_builder = __esm({
|
|
|
12205
12834
|
retry;
|
|
12206
12835
|
subagents;
|
|
12207
12836
|
policies;
|
|
12837
|
+
skills;
|
|
12208
12838
|
constructor(client) {
|
|
12209
12839
|
this.core = { client, initialMessages: [] };
|
|
12210
12840
|
this.gadgets = { gadgets: [] };
|
|
12211
12841
|
this.retry = {};
|
|
12212
12842
|
this.subagents = {};
|
|
12213
12843
|
this.policies = {};
|
|
12844
|
+
this.skills = { preActivated: [], skillDirs: [] };
|
|
12214
12845
|
}
|
|
12215
12846
|
/** Set the model to use. Supports aliases like "sonnet", "flash". */
|
|
12216
12847
|
withModel(model) {
|
|
@@ -12347,6 +12978,38 @@ var init_builder = __esm({
|
|
|
12347
12978
|
this.policies.compactionConfig = { enabled: false };
|
|
12348
12979
|
return this;
|
|
12349
12980
|
}
|
|
12981
|
+
// ─── Skills ──────────────────────────────────────────────────────────────────
|
|
12982
|
+
/** Register a skill registry for this agent. */
|
|
12983
|
+
withSkills(registry) {
|
|
12984
|
+
this.skills.registry = registry;
|
|
12985
|
+
return this;
|
|
12986
|
+
}
|
|
12987
|
+
/**
|
|
12988
|
+
* Pre-activate a specific skill before the agent starts.
|
|
12989
|
+
* Instructions are injected into the system prompt.
|
|
12990
|
+
*
|
|
12991
|
+
* Note: each call replaces (not appends) the pre-activated skill for that name.
|
|
12992
|
+
* This is safe for REPL loops where the same builder is reused.
|
|
12993
|
+
*/
|
|
12994
|
+
withSkill(name, args) {
|
|
12995
|
+
const existing = this.skills.preActivated.findIndex((s) => s.name === name);
|
|
12996
|
+
if (existing !== -1) {
|
|
12997
|
+
this.skills.preActivated[existing] = { name, args };
|
|
12998
|
+
} else {
|
|
12999
|
+
this.skills.preActivated.push({ name, args });
|
|
13000
|
+
}
|
|
13001
|
+
return this;
|
|
13002
|
+
}
|
|
13003
|
+
/** Clear all pre-activated skills. Call between REPL iterations. */
|
|
13004
|
+
clearPreActivatedSkills() {
|
|
13005
|
+
this.skills.preActivated = [];
|
|
13006
|
+
return this;
|
|
13007
|
+
}
|
|
13008
|
+
/** Add a directory to scan for skills. */
|
|
13009
|
+
withSkillsFrom(dir) {
|
|
13010
|
+
this.skills.skillDirs.push(dir);
|
|
13011
|
+
return this;
|
|
13012
|
+
}
|
|
12350
13013
|
/** Configure retry behavior for LLM API calls. */
|
|
12351
13014
|
withRetry(config) {
|
|
12352
13015
|
this.retry.retryConfig = { ...config, enabled: config.enabled ?? true };
|
|
@@ -12438,16 +13101,75 @@ var init_builder = __esm({
|
|
|
12438
13101
|
composeHooks() {
|
|
12439
13102
|
return HookComposer.compose(this.core.hooks, this.core.trailingMessage);
|
|
12440
13103
|
}
|
|
13104
|
+
resolveSkillRegistry() {
|
|
13105
|
+
if (this.skills.registry) {
|
|
13106
|
+
if (this.skills.skillDirs.length > 0) {
|
|
13107
|
+
for (const dir of this.skills.skillDirs) {
|
|
13108
|
+
const skills = loadSkillsFromDirectory(dir, { type: "directory", path: dir });
|
|
13109
|
+
this.skills.registry.registerMany(skills);
|
|
13110
|
+
}
|
|
13111
|
+
}
|
|
13112
|
+
return this.skills.registry;
|
|
13113
|
+
}
|
|
13114
|
+
if (this.skills.skillDirs.length > 0) {
|
|
13115
|
+
const { SkillRegistry: SR } = (init_registry2(), __toCommonJS(registry_exports));
|
|
13116
|
+
const reg = new SR();
|
|
13117
|
+
for (const dir of this.skills.skillDirs) {
|
|
13118
|
+
const skills = loadSkillsFromDirectory(dir, { type: "directory", path: dir });
|
|
13119
|
+
reg.registerMany(skills);
|
|
13120
|
+
}
|
|
13121
|
+
return reg;
|
|
13122
|
+
}
|
|
13123
|
+
return void 0;
|
|
13124
|
+
}
|
|
13125
|
+
/**
|
|
13126
|
+
* Resolve pre-activated skill instructions synchronously.
|
|
13127
|
+
* Reads SKILL.md from disk via readFileSync (skills are local files).
|
|
13128
|
+
*/
|
|
13129
|
+
resolvePreActivatedInstructions(skillRegistry) {
|
|
13130
|
+
if (this.skills.preActivated.length === 0) return void 0;
|
|
13131
|
+
const fs4 = __require("fs");
|
|
13132
|
+
const blocks = [];
|
|
13133
|
+
for (const { name, args } of this.skills.preActivated) {
|
|
13134
|
+
const skill = skillRegistry.get(name);
|
|
13135
|
+
if (!skill) continue;
|
|
13136
|
+
const content = fs4.readFileSync(skill.sourcePath, "utf-8");
|
|
13137
|
+
const { body } = parseFrontmatter(content);
|
|
13138
|
+
const resolved = resolveInstructions(body, {
|
|
13139
|
+
arguments: args,
|
|
13140
|
+
variables: { SKILL_DIR: skill.sourceDir, CLAUDE_SKILL_DIR: skill.sourceDir },
|
|
13141
|
+
cwd: skill.sourceDir,
|
|
13142
|
+
shell: skill.metadata.shell
|
|
13143
|
+
});
|
|
13144
|
+
blocks.push(`## Skill: ${name}
|
|
13145
|
+
|
|
13146
|
+
${resolved}`);
|
|
13147
|
+
}
|
|
13148
|
+
return blocks.length > 0 ? blocks.join("\n\n---\n\n") : void 0;
|
|
13149
|
+
}
|
|
12441
13150
|
buildAgentOptions(userPrompt) {
|
|
12442
13151
|
if (!this.core.client) {
|
|
12443
13152
|
const { LLMist: LLMistClass } = (init_client(), __toCommonJS(client_exports));
|
|
12444
13153
|
this.core.client = new LLMistClass();
|
|
12445
13154
|
}
|
|
12446
13155
|
const registry = GadgetRegistry.from(this.gadgets.gadgets);
|
|
13156
|
+
let systemPrompt = this.core.systemPrompt;
|
|
13157
|
+
const skillRegistry = this.resolveSkillRegistry();
|
|
13158
|
+
if (skillRegistry && skillRegistry.size > 0) {
|
|
13159
|
+
if (skillRegistry.getModelInvocable().length > 0) {
|
|
13160
|
+
registry.registerByClass(createUseSkillGadget(skillRegistry));
|
|
13161
|
+
}
|
|
13162
|
+
const preActivatedBlock = this.resolvePreActivatedInstructions(skillRegistry);
|
|
13163
|
+
if (preActivatedBlock) {
|
|
13164
|
+
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
13165
|
+
|
|
13166
|
+
${preActivatedBlock}` : preActivatedBlock;
|
|
13167
|
+
}
|
|
13168
|
+
}
|
|
12447
13169
|
return {
|
|
12448
13170
|
client: this.core.client,
|
|
12449
13171
|
model: this.core.model ?? "openai:gpt-5-nano",
|
|
12450
|
-
systemPrompt
|
|
13172
|
+
systemPrompt,
|
|
12451
13173
|
userPrompt,
|
|
12452
13174
|
registry,
|
|
12453
13175
|
maxIterations: this.core.maxIterations,
|
|
@@ -13132,8 +13854,8 @@ var init_error_formatter = __esm({
|
|
|
13132
13854
|
const parts = [];
|
|
13133
13855
|
parts.push(`Error: Invalid parameters for '${gadgetName}':`);
|
|
13134
13856
|
for (const issue of zodError.issues) {
|
|
13135
|
-
const
|
|
13136
|
-
parts.push(` - ${
|
|
13857
|
+
const path3 = issue.path.join(".") || "root";
|
|
13858
|
+
parts.push(` - ${path3}: ${issue.message}`);
|
|
13137
13859
|
}
|
|
13138
13860
|
parts.push("");
|
|
13139
13861
|
parts.push("Gadget Usage:");
|
|
@@ -13198,7 +13920,7 @@ function stripMarkdownFences(content) {
|
|
|
13198
13920
|
return cleaned.trim();
|
|
13199
13921
|
}
|
|
13200
13922
|
var globalInvocationCounter, GadgetCallParser;
|
|
13201
|
-
var
|
|
13923
|
+
var init_parser2 = __esm({
|
|
13202
13924
|
"src/gadgets/parser.ts"() {
|
|
13203
13925
|
"use strict";
|
|
13204
13926
|
init_constants();
|
|
@@ -13234,8 +13956,9 @@ var init_parser = __esm({
|
|
|
13234
13956
|
* - `GadgetName` - Auto-generate ID, no dependencies
|
|
13235
13957
|
* - `GadgetName:my_id` - Explicit ID, no dependencies
|
|
13236
13958
|
* - `GadgetName:my_id:dep1,dep2` - Explicit ID with dependencies
|
|
13959
|
+
* - `GadgetName:my_id:dep1:dep2:dep3` - Colons treated as dep separators (LLM resilience)
|
|
13237
13960
|
*
|
|
13238
|
-
* Dependencies
|
|
13961
|
+
* Dependencies can be comma-separated or colon-separated invocation IDs.
|
|
13239
13962
|
*/
|
|
13240
13963
|
parseInvocationMetadata(headerLine) {
|
|
13241
13964
|
const parts = headerLine.split(":");
|
|
@@ -13252,7 +13975,12 @@ var init_parser = __esm({
|
|
|
13252
13975
|
dependencies: []
|
|
13253
13976
|
};
|
|
13254
13977
|
} else {
|
|
13255
|
-
const
|
|
13978
|
+
const depsRaw = parts.slice(2).join(",");
|
|
13979
|
+
const deps = [
|
|
13980
|
+
...new Set(
|
|
13981
|
+
depsRaw.split(",").map((d) => d.trim()).filter((d) => d.length > 0)
|
|
13982
|
+
)
|
|
13983
|
+
];
|
|
13256
13984
|
return {
|
|
13257
13985
|
gadgetName: parts[0],
|
|
13258
13986
|
invocationId: parts[1].trim(),
|
|
@@ -13404,7 +14132,7 @@ var init_typed_gadget = __esm({
|
|
|
13404
14132
|
|
|
13405
14133
|
// src/gadgets/executor.ts
|
|
13406
14134
|
import equal from "fast-deep-equal";
|
|
13407
|
-
import { z as
|
|
14135
|
+
import { z as z5 } from "zod";
|
|
13408
14136
|
function getHostExportsInternal() {
|
|
13409
14137
|
return {
|
|
13410
14138
|
AgentBuilder,
|
|
@@ -13412,7 +14140,7 @@ function getHostExportsInternal() {
|
|
|
13412
14140
|
createGadget,
|
|
13413
14141
|
ExecutionTree,
|
|
13414
14142
|
LLMist,
|
|
13415
|
-
z:
|
|
14143
|
+
z: z5
|
|
13416
14144
|
};
|
|
13417
14145
|
}
|
|
13418
14146
|
var GadgetExecutor;
|
|
@@ -13430,7 +14158,7 @@ var init_executor = __esm({
|
|
|
13430
14158
|
init_create_gadget();
|
|
13431
14159
|
init_error_formatter();
|
|
13432
14160
|
init_exceptions();
|
|
13433
|
-
|
|
14161
|
+
init_parser2();
|
|
13434
14162
|
init_typed_gadget();
|
|
13435
14163
|
GadgetExecutor = class {
|
|
13436
14164
|
registry;
|
|
@@ -13825,6 +14553,8 @@ var init_gadget_concurrency_manager = __esm({
|
|
|
13825
14553
|
concurrencyQueue = /* @__PURE__ */ new Map();
|
|
13826
14554
|
/** All active gadget promises, keyed by invocationId */
|
|
13827
14555
|
inFlightExecutions = /* @__PURE__ */ new Map();
|
|
14556
|
+
/** Gadget name for each in-flight invocationId (for timeout event emission) */
|
|
14557
|
+
inFlightGadgetNames = /* @__PURE__ */ new Map();
|
|
13828
14558
|
/** Queue of exclusive gadgets deferred until in-flight gadgets complete */
|
|
13829
14559
|
exclusiveQueue = [];
|
|
13830
14560
|
constructor(options) {
|
|
@@ -13952,6 +14682,7 @@ var init_gadget_concurrency_manager = __esm({
|
|
|
13952
14682
|
const currentCount = this.activeCountByGadget.get(gadgetName) ?? 0;
|
|
13953
14683
|
this.activeCountByGadget.set(gadgetName, currentCount + 1);
|
|
13954
14684
|
this.inFlightExecutions.set(invocationId, promise);
|
|
14685
|
+
this.inFlightGadgetNames.set(invocationId, gadgetName);
|
|
13955
14686
|
}
|
|
13956
14687
|
/**
|
|
13957
14688
|
* Called when a gadget execution completes.
|
|
@@ -13995,11 +14726,25 @@ var init_gadget_concurrency_manager = __esm({
|
|
|
13995
14726
|
this.exclusiveQueue.push(call);
|
|
13996
14727
|
}
|
|
13997
14728
|
/**
|
|
13998
|
-
* Clear
|
|
13999
|
-
* Called after
|
|
14729
|
+
* Clear all in-flight tracking state.
|
|
14730
|
+
* Called after all promises have completed, or on force-timeout.
|
|
14731
|
+
* Also clears active gadget counts to prevent stale state when
|
|
14732
|
+
* hanging promises eventually resolve into the void.
|
|
14000
14733
|
*/
|
|
14001
14734
|
clearInFlight() {
|
|
14002
14735
|
this.inFlightExecutions.clear();
|
|
14736
|
+
this.inFlightGadgetNames.clear();
|
|
14737
|
+
this.activeCountByGadget.clear();
|
|
14738
|
+
}
|
|
14739
|
+
/**
|
|
14740
|
+
* Get metadata for all currently in-flight executions.
|
|
14741
|
+
* Used by the dispatcher to emit skip events when the in-flight timeout fires.
|
|
14742
|
+
*/
|
|
14743
|
+
getInFlightEntries() {
|
|
14744
|
+
return Array.from(this.inFlightGadgetNames.entries()).map(([invocationId, gadgetName]) => ({
|
|
14745
|
+
invocationId,
|
|
14746
|
+
gadgetName
|
|
14747
|
+
}));
|
|
14003
14748
|
}
|
|
14004
14749
|
// ==========================================================================
|
|
14005
14750
|
// Waiting
|
|
@@ -14324,6 +15069,7 @@ var init_gadget_dispatcher = __esm({
|
|
|
14324
15069
|
logger;
|
|
14325
15070
|
pushToQueue;
|
|
14326
15071
|
drainQueue;
|
|
15072
|
+
inFlightTimeoutMs;
|
|
14327
15073
|
constructor(options) {
|
|
14328
15074
|
this.iteration = options.iteration;
|
|
14329
15075
|
this.hookLifecycle = options.hookLifecycle;
|
|
@@ -14338,6 +15084,7 @@ var init_gadget_dispatcher = __esm({
|
|
|
14338
15084
|
this.logger = options.logger ?? createLogger({ name: "llmist:gadget-dispatcher" });
|
|
14339
15085
|
this.pushToQueue = options.pushToQueue;
|
|
14340
15086
|
this.drainQueue = options.drainQueue;
|
|
15087
|
+
this.inFlightTimeoutMs = options.inFlightTimeoutMs ?? 3e5;
|
|
14341
15088
|
}
|
|
14342
15089
|
// ==========================================================================
|
|
14343
15090
|
// Primary dispatch entry point
|
|
@@ -14369,39 +15116,54 @@ var init_gadget_dispatcher = __esm({
|
|
|
14369
15116
|
parentId: this.parentNodeId
|
|
14370
15117
|
});
|
|
14371
15118
|
}
|
|
15119
|
+
let effectiveCall = call;
|
|
14372
15120
|
if (call.dependencies.length > 0) {
|
|
14373
|
-
|
|
14374
|
-
|
|
15121
|
+
const selfRefs = [];
|
|
15122
|
+
const validDeps = [];
|
|
15123
|
+
for (const dep of call.dependencies) {
|
|
15124
|
+
(dep === call.invocationId ? selfRefs : validDeps).push(dep);
|
|
15125
|
+
}
|
|
15126
|
+
if (selfRefs.length > 0) {
|
|
15127
|
+
this.logger.warn("Filtering self-referential dependencies", {
|
|
14375
15128
|
gadgetName: call.gadgetName,
|
|
14376
|
-
invocationId: call.invocationId
|
|
15129
|
+
invocationId: call.invocationId,
|
|
15130
|
+
removedSelfRefs: selfRefs,
|
|
15131
|
+
remainingDeps: validDeps
|
|
14377
15132
|
});
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
15133
|
+
effectiveCall = { ...call, dependencies: validDeps };
|
|
15134
|
+
if (validDeps.length === 0) {
|
|
15135
|
+
const errorMessage = `Gadget "${call.invocationId}" cannot depend on itself (self-referential dependency)`;
|
|
15136
|
+
for await (const evt of this.emitGadgetSkipEvents(
|
|
15137
|
+
effectiveCall,
|
|
15138
|
+
call.invocationId,
|
|
15139
|
+
errorMessage
|
|
15140
|
+
)) {
|
|
15141
|
+
yield evt;
|
|
15142
|
+
}
|
|
15143
|
+
return;
|
|
14381
15144
|
}
|
|
14382
|
-
return;
|
|
14383
15145
|
}
|
|
14384
|
-
const failedDep = this.dependencyResolver.getFailedDependency(
|
|
15146
|
+
const failedDep = this.dependencyResolver.getFailedDependency(effectiveCall);
|
|
14385
15147
|
if (failedDep) {
|
|
14386
|
-
const skipEvents = await this.handleFailedDependency(
|
|
15148
|
+
const skipEvents = await this.handleFailedDependency(effectiveCall, failedDep);
|
|
14387
15149
|
for (const evt of skipEvents) {
|
|
14388
15150
|
yield evt;
|
|
14389
15151
|
}
|
|
14390
15152
|
return;
|
|
14391
15153
|
}
|
|
14392
|
-
if (!this.dependencyResolver.isAllSatisfied(
|
|
14393
|
-
const unsatisfied =
|
|
15154
|
+
if (!this.dependencyResolver.isAllSatisfied(effectiveCall)) {
|
|
15155
|
+
const unsatisfied = effectiveCall.dependencies.filter(
|
|
14394
15156
|
(dep) => !this.dependencyResolver.isCompleted(dep)
|
|
14395
15157
|
);
|
|
14396
15158
|
this.logger.debug("Queueing gadget for later - waiting on dependencies", {
|
|
14397
|
-
gadgetName:
|
|
14398
|
-
invocationId:
|
|
15159
|
+
gadgetName: effectiveCall.gadgetName,
|
|
15160
|
+
invocationId: effectiveCall.invocationId,
|
|
14399
15161
|
waitingOn: unsatisfied
|
|
14400
15162
|
});
|
|
14401
|
-
this.dependencyResolver.addPending(
|
|
15163
|
+
this.dependencyResolver.addPending(effectiveCall);
|
|
14402
15164
|
return;
|
|
14403
15165
|
}
|
|
14404
|
-
for await (const evt of this._checkLimitThenExecute(
|
|
15166
|
+
for await (const evt of this._checkLimitThenExecute(effectiveCall)) {
|
|
14405
15167
|
yield evt;
|
|
14406
15168
|
}
|
|
14407
15169
|
for await (const evt of this.processPendingGadgets()) {
|
|
@@ -14540,7 +15302,31 @@ var init_gadget_dispatcher = __esm({
|
|
|
14540
15302
|
queuedCount: this.concurrencyManager.getQueuedGadgetCount()
|
|
14541
15303
|
});
|
|
14542
15304
|
const POLL_INTERVAL_MS = 100;
|
|
15305
|
+
const startTime = Date.now();
|
|
14543
15306
|
while (this.concurrencyManager.inFlightCount > 0 || this.concurrencyManager.hasQueuedGadgets()) {
|
|
15307
|
+
if (Date.now() - startTime >= this.inFlightTimeoutMs) {
|
|
15308
|
+
const timedOutEntries = this.concurrencyManager.getInFlightEntries();
|
|
15309
|
+
this.logger.error("In-flight gadget timeout exceeded, force-clearing remaining gadgets", {
|
|
15310
|
+
timeoutMs: this.inFlightTimeoutMs,
|
|
15311
|
+
remainingInFlight: timedOutEntries.length,
|
|
15312
|
+
remainingQueued: this.concurrencyManager.getQueuedGadgetCount(),
|
|
15313
|
+
timedOutInvocations: timedOutEntries.map((e) => e.invocationId)
|
|
15314
|
+
});
|
|
15315
|
+
const timeoutError = `Gadget execution timed out after ${this.inFlightTimeoutMs}ms`;
|
|
15316
|
+
for (const { invocationId, gadgetName } of timedOutEntries) {
|
|
15317
|
+
this.dependencyResolver.markFailed(invocationId);
|
|
15318
|
+
yield {
|
|
15319
|
+
type: "gadget_skipped",
|
|
15320
|
+
gadgetName,
|
|
15321
|
+
invocationId,
|
|
15322
|
+
parameters: {},
|
|
15323
|
+
failedDependency: invocationId,
|
|
15324
|
+
failedDependencyError: timeoutError
|
|
15325
|
+
};
|
|
15326
|
+
}
|
|
15327
|
+
this.concurrencyManager.clearInFlight();
|
|
15328
|
+
break;
|
|
15329
|
+
}
|
|
14544
15330
|
const allDone = this.concurrencyManager.getAllDonePromise();
|
|
14545
15331
|
const result = await Promise.race([
|
|
14546
15332
|
allDone,
|
|
@@ -15031,7 +15817,7 @@ var init_stream_processor = __esm({
|
|
|
15031
15817
|
"src/agent/stream-processor.ts"() {
|
|
15032
15818
|
"use strict";
|
|
15033
15819
|
init_executor();
|
|
15034
|
-
|
|
15820
|
+
init_parser2();
|
|
15035
15821
|
init_logger();
|
|
15036
15822
|
init_gadget_concurrency_manager();
|
|
15037
15823
|
init_gadget_dependency_resolver();
|
|
@@ -15126,7 +15912,8 @@ var init_stream_processor = __esm({
|
|
|
15126
15912
|
const evts = [...this.completedResultsQueue];
|
|
15127
15913
|
this.completedResultsQueue = [];
|
|
15128
15914
|
return evts;
|
|
15129
|
-
}
|
|
15915
|
+
},
|
|
15916
|
+
inFlightTimeoutMs: options.inFlightTimeoutMs
|
|
15130
15917
|
});
|
|
15131
15918
|
}
|
|
15132
15919
|
/**
|
|
@@ -15350,6 +16137,7 @@ var init_stream_processor_factory = __esm({
|
|
|
15350
16137
|
logger;
|
|
15351
16138
|
requestHumanInput;
|
|
15352
16139
|
defaultGadgetTimeoutMs;
|
|
16140
|
+
inFlightTimeoutMs;
|
|
15353
16141
|
gadgetExecutionMode;
|
|
15354
16142
|
client;
|
|
15355
16143
|
mediaStore;
|
|
@@ -15368,6 +16156,7 @@ var init_stream_processor_factory = __esm({
|
|
|
15368
16156
|
this.logger = options.logger;
|
|
15369
16157
|
this.requestHumanInput = options.requestHumanInput;
|
|
15370
16158
|
this.defaultGadgetTimeoutMs = options.defaultGadgetTimeoutMs;
|
|
16159
|
+
this.inFlightTimeoutMs = options.inFlightTimeoutMs;
|
|
15371
16160
|
this.gadgetExecutionMode = options.gadgetExecutionMode;
|
|
15372
16161
|
this.client = options.client;
|
|
15373
16162
|
this.mediaStore = options.mediaStore;
|
|
@@ -15399,6 +16188,7 @@ var init_stream_processor_factory = __esm({
|
|
|
15399
16188
|
logger: this.logger.getSubLogger({ name: "stream-processor" }),
|
|
15400
16189
|
requestHumanInput: this.requestHumanInput,
|
|
15401
16190
|
defaultGadgetTimeoutMs: this.defaultGadgetTimeoutMs,
|
|
16191
|
+
inFlightTimeoutMs: this.inFlightTimeoutMs,
|
|
15402
16192
|
gadgetExecutionMode: this.gadgetExecutionMode,
|
|
15403
16193
|
client: this.client,
|
|
15404
16194
|
mediaStore: this.mediaStore,
|
|
@@ -16155,7 +16945,7 @@ init_builder();
|
|
|
16155
16945
|
init_event_handlers();
|
|
16156
16946
|
init_file_logging();
|
|
16157
16947
|
init_hook_presets();
|
|
16158
|
-
import { z as
|
|
16948
|
+
import { z as z6 } from "zod";
|
|
16159
16949
|
|
|
16160
16950
|
// src/agent/compaction/index.ts
|
|
16161
16951
|
init_config();
|
|
@@ -16464,7 +17254,7 @@ function resultWithFile(result, fileData, mimeType, options) {
|
|
|
16464
17254
|
|
|
16465
17255
|
// src/index.ts
|
|
16466
17256
|
init_output_viewer();
|
|
16467
|
-
|
|
17257
|
+
init_parser2();
|
|
16468
17258
|
init_registry();
|
|
16469
17259
|
init_typed_gadget();
|
|
16470
17260
|
init_constants2();
|
|
@@ -16731,6 +17521,14 @@ var SimpleSessionManager = class extends BaseSessionManager {
|
|
|
16731
17521
|
}
|
|
16732
17522
|
};
|
|
16733
17523
|
|
|
17524
|
+
// src/skills/index.ts
|
|
17525
|
+
init_activation();
|
|
17526
|
+
init_loader();
|
|
17527
|
+
init_parser();
|
|
17528
|
+
init_registry2();
|
|
17529
|
+
init_skill();
|
|
17530
|
+
init_use_skill_gadget();
|
|
17531
|
+
|
|
16734
17532
|
// src/utils/format.ts
|
|
16735
17533
|
function truncate(text3, maxLength, suffix = "...") {
|
|
16736
17534
|
if (text3.length <= maxLength) return text3;
|
|
@@ -16926,11 +17724,14 @@ export {
|
|
|
16926
17724
|
OpenRouterProvider,
|
|
16927
17725
|
RateLimitTracker,
|
|
16928
17726
|
SimpleSessionManager,
|
|
17727
|
+
Skill,
|
|
17728
|
+
SkillRegistry,
|
|
16929
17729
|
SlidingWindowStrategy,
|
|
16930
17730
|
StreamProcessor,
|
|
16931
17731
|
SummarizationStrategy,
|
|
16932
17732
|
TaskCompletionSignal,
|
|
16933
17733
|
TimeoutException,
|
|
17734
|
+
USE_SKILL_GADGET_NAME,
|
|
16934
17735
|
audioFromBase64,
|
|
16935
17736
|
audioFromBuffer,
|
|
16936
17737
|
collectEvents,
|
|
@@ -16948,10 +17749,12 @@ export {
|
|
|
16948
17749
|
createOpenAIProviderFromEnv,
|
|
16949
17750
|
createOpenRouterProviderFromEnv,
|
|
16950
17751
|
createSubagent,
|
|
17752
|
+
createUseSkillGadget,
|
|
16951
17753
|
defaultLogger,
|
|
16952
17754
|
detectAudioMimeType,
|
|
16953
17755
|
detectImageMimeType,
|
|
16954
17756
|
discoverProviderAdapters,
|
|
17757
|
+
discoverSkills,
|
|
16955
17758
|
extractMessageText,
|
|
16956
17759
|
extractRetryAfterMs,
|
|
16957
17760
|
filterByDepth,
|
|
@@ -16994,15 +17797,21 @@ export {
|
|
|
16994
17797
|
iterationProgressHint,
|
|
16995
17798
|
listPresets,
|
|
16996
17799
|
listSubagents,
|
|
17800
|
+
loadSkillsFromDirectory,
|
|
16997
17801
|
normalizeMessageContent,
|
|
16998
17802
|
parallelGadgetHint,
|
|
16999
17803
|
parseDataUrl,
|
|
17804
|
+
parseFrontmatter,
|
|
17000
17805
|
parseManifest,
|
|
17806
|
+
parseMetadata,
|
|
17001
17807
|
parseRetryAfterHeader,
|
|
17808
|
+
parseSkillContent,
|
|
17809
|
+
parseSkillFile,
|
|
17002
17810
|
randomDelay,
|
|
17003
17811
|
resetFileLoggingState,
|
|
17004
17812
|
resolveConfig,
|
|
17005
17813
|
resolveHintTemplate,
|
|
17814
|
+
resolveInstructions,
|
|
17006
17815
|
resolveModel,
|
|
17007
17816
|
resolvePromptTemplate,
|
|
17008
17817
|
resolveRateLimitConfig,
|
|
@@ -17017,9 +17826,12 @@ export {
|
|
|
17017
17826
|
resultWithImages,
|
|
17018
17827
|
resultWithMedia,
|
|
17019
17828
|
runWithHandlers,
|
|
17829
|
+
scanResources,
|
|
17020
17830
|
schemaToJSONSchema,
|
|
17021
17831
|
stream,
|
|
17022
17832
|
stripProviderPrefix,
|
|
17833
|
+
substituteArguments,
|
|
17834
|
+
substituteVariables,
|
|
17023
17835
|
text,
|
|
17024
17836
|
timing,
|
|
17025
17837
|
toBase64,
|
|
@@ -17027,9 +17839,10 @@ export {
|
|
|
17027
17839
|
validateAndApplyDefaults,
|
|
17028
17840
|
validateGadgetParams,
|
|
17029
17841
|
validateGadgetSchema,
|
|
17842
|
+
validateMetadata,
|
|
17030
17843
|
withErrorHandling,
|
|
17031
17844
|
withRetry,
|
|
17032
17845
|
withTimeout,
|
|
17033
|
-
|
|
17846
|
+
z6 as z
|
|
17034
17847
|
};
|
|
17035
17848
|
//# sourceMappingURL=index.js.map
|