llmist 16.1.0 → 16.2.0

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 CHANGED
@@ -358,15 +358,15 @@ var init_execution_tree = __esm({
358
358
  const parentId = params.parentId ?? this.parentNodeId;
359
359
  const parent = parentId ? this.nodes.get(parentId) : null;
360
360
  const depth = parent ? parent.depth + 1 : this.baseDepth;
361
- const path = parent ? [...parent.path] : [];
361
+ const path3 = parent ? [...parent.path] : [];
362
362
  const id = this.generateLLMCallId(params.iteration, parentId);
363
- path.push(id);
363
+ path3.push(id);
364
364
  const node = {
365
365
  id,
366
366
  type: "llm_call",
367
367
  parentId,
368
368
  depth,
369
- path,
369
+ path: path3,
370
370
  createdAt: Date.now(),
371
371
  completedAt: null,
372
372
  iteration: params.iteration,
@@ -477,15 +477,15 @@ var init_execution_tree = __esm({
477
477
  const parentId = params.parentId ?? this.getCurrentLLMCallId() ?? this.parentNodeId;
478
478
  const parent = parentId ? this.nodes.get(parentId) : null;
479
479
  const depth = parent ? parent.depth + 1 : this.baseDepth;
480
- const path = parent ? [...parent.path] : [];
480
+ const path3 = parent ? [...parent.path] : [];
481
481
  const id = this.generateGadgetId(params.invocationId);
482
- path.push(id);
482
+ path3.push(id);
483
483
  const node = {
484
484
  id,
485
485
  type: "gadget",
486
486
  parentId,
487
487
  depth,
488
- path,
488
+ path: path3,
489
489
  createdAt: Date.now(),
490
490
  completedAt: null,
491
491
  invocationId: params.invocationId,
@@ -1424,8 +1424,8 @@ ${this.endPrefix}`
1424
1424
  });
1425
1425
  if (media && media.length > 0 && mediaIds && mediaIds.length > 0) {
1426
1426
  const idRefs = media.map((m, i) => {
1427
- const path = storedMedia?.[i]?.path;
1428
- const pathInfo = path ? ` \u2192 saved to: ${path}` : "";
1427
+ const path3 = storedMedia?.[i]?.path;
1428
+ const pathInfo = path3 ? ` \u2192 saved to: ${path3}` : "";
1429
1429
  return `[Media: ${mediaIds[i]} (${m.kind})${pathInfo}]`;
1430
1430
  }).join("\n");
1431
1431
  const textWithIds = `Result (${invocationId}): ${result}
@@ -4032,29 +4032,29 @@ function schemaToJSONSchema(schema, options) {
4032
4032
  }
4033
4033
  function detectDescriptionMismatch(schema, jsonSchema) {
4034
4034
  const mismatches = [];
4035
- function checkSchema(zodSchema, json, path) {
4035
+ function checkSchema(zodSchema, json, path3) {
4036
4036
  if (!zodSchema || typeof zodSchema !== "object") return;
4037
4037
  const def = zodSchema._def;
4038
4038
  const jsonObj = json;
4039
4039
  if (def?.description && !jsonObj?.description) {
4040
- mismatches.push(path || "root");
4040
+ mismatches.push(path3 || "root");
4041
4041
  }
4042
4042
  if (def?.typeName === "ZodObject" && def?.shape) {
4043
4043
  const shape = typeof def.shape === "function" ? def.shape() : def.shape;
4044
4044
  for (const [key, fieldSchema] of Object.entries(shape)) {
4045
4045
  const properties = jsonObj?.properties;
4046
4046
  const jsonProp = properties?.[key];
4047
- checkSchema(fieldSchema, jsonProp, path ? `${path}.${key}` : key);
4047
+ checkSchema(fieldSchema, jsonProp, path3 ? `${path3}.${key}` : key);
4048
4048
  }
4049
4049
  }
4050
4050
  if (def?.typeName === "ZodArray" && def?.type) {
4051
- checkSchema(def.type, jsonObj?.items, path ? `${path}[]` : "[]");
4051
+ checkSchema(def.type, jsonObj?.items, path3 ? `${path3}[]` : "[]");
4052
4052
  }
4053
4053
  if ((def?.typeName === "ZodOptional" || def?.typeName === "ZodNullable") && def?.innerType) {
4054
- checkSchema(def.innerType, json, path);
4054
+ checkSchema(def.innerType, json, path3);
4055
4055
  }
4056
4056
  if (def?.typeName === "ZodDefault" && def?.innerType) {
4057
- checkSchema(def.innerType, json, path);
4057
+ checkSchema(def.innerType, json, path3);
4058
4058
  }
4059
4059
  }
4060
4060
  checkSchema(schema, jsonSchema, "");
@@ -4147,7 +4147,7 @@ Example fixes:
4147
4147
  );
4148
4148
  }
4149
4149
  }
4150
- function findUnknownTypes(schema, path = []) {
4150
+ function findUnknownTypes(schema, path3 = []) {
4151
4151
  const issues = [];
4152
4152
  if (!schema || typeof schema !== "object") {
4153
4153
  return issues;
@@ -4159,7 +4159,7 @@ function findUnknownTypes(schema, path = []) {
4159
4159
  }
4160
4160
  if (schema.properties) {
4161
4161
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
4162
- const propPath = [...path, propName];
4162
+ const propPath = [...path3, propName];
4163
4163
  if (hasNoType(propSchema)) {
4164
4164
  issues.push(propPath.join(".") || propName);
4165
4165
  }
@@ -4167,7 +4167,7 @@ function findUnknownTypes(schema, path = []) {
4167
4167
  }
4168
4168
  }
4169
4169
  if (schema.items) {
4170
- const itemPath = [...path, "[]"];
4170
+ const itemPath = [...path3, "[]"];
4171
4171
  if (hasNoType(schema.items)) {
4172
4172
  issues.push(itemPath.join("."));
4173
4173
  }
@@ -4175,17 +4175,17 @@ function findUnknownTypes(schema, path = []) {
4175
4175
  }
4176
4176
  if (schema.anyOf) {
4177
4177
  schema.anyOf.forEach((subSchema, index) => {
4178
- issues.push(...findUnknownTypes(subSchema, [...path, `anyOf[${index}]`]));
4178
+ issues.push(...findUnknownTypes(subSchema, [...path3, `anyOf[${index}]`]));
4179
4179
  });
4180
4180
  }
4181
4181
  if (schema.oneOf) {
4182
4182
  schema.oneOf.forEach((subSchema, index) => {
4183
- issues.push(...findUnknownTypes(subSchema, [...path, `oneOf[${index}]`]));
4183
+ issues.push(...findUnknownTypes(subSchema, [...path3, `oneOf[${index}]`]));
4184
4184
  });
4185
4185
  }
4186
4186
  if (schema.allOf) {
4187
4187
  schema.allOf.forEach((subSchema, index) => {
4188
- issues.push(...findUnknownTypes(subSchema, [...path, `allOf[${index}]`]));
4188
+ issues.push(...findUnknownTypes(subSchema, [...path3, `allOf[${index}]`]));
4189
4189
  });
4190
4190
  }
4191
4191
  return issues;
@@ -5203,6 +5203,626 @@ var init_registry = __esm({
5203
5203
  }
5204
5204
  });
5205
5205
 
5206
+ // src/skills/activation.ts
5207
+ function substituteArguments(instructions, args) {
5208
+ if (!args) {
5209
+ return instructions.replace(/\$ARGUMENTS\[\d+\]/g, "").replace(/\$ARGUMENTS/g, "").replace(/\$\d+/g, "");
5210
+ }
5211
+ const parts = splitArguments(args);
5212
+ let result = instructions.replace(/\$ARGUMENTS\[(\d+)\]/g, (_match, index) => {
5213
+ const i = Number.parseInt(index, 10);
5214
+ return parts[i] ?? "";
5215
+ });
5216
+ result = result.replace(/\$ARGUMENTS/g, args);
5217
+ result = result.replace(/\$(\d+)/g, (_match, index) => {
5218
+ const i = Number.parseInt(index, 10);
5219
+ return parts[i] ?? "";
5220
+ });
5221
+ return result;
5222
+ }
5223
+ function preprocessShellCommands(instructions, options) {
5224
+ const { cwd, shell = "bash", timeoutMs = 1e4 } = options ?? {};
5225
+ return instructions.replace(/!`([^`]+)`/g, (_match, command) => {
5226
+ try {
5227
+ const output = (0, import_node_child_process.execSync)(command, {
5228
+ cwd,
5229
+ shell: shell === "powershell" ? "powershell" : "/bin/bash",
5230
+ timeout: timeoutMs,
5231
+ encoding: "utf-8",
5232
+ stdio: ["pipe", "pipe", "pipe"]
5233
+ });
5234
+ return output.trim();
5235
+ } catch (error) {
5236
+ const msg = error instanceof Error ? error.message : String(error);
5237
+ return `[Error executing \`${command}\`: ${msg}]`;
5238
+ }
5239
+ });
5240
+ }
5241
+ function substituteVariables(instructions, variables) {
5242
+ return instructions.replace(/\$\{(\w+)\}/g, (_match, varName) => {
5243
+ return variables[varName] ?? "";
5244
+ });
5245
+ }
5246
+ function resolveInstructions(instructions, options) {
5247
+ let resolved = instructions;
5248
+ if (options?.variables) {
5249
+ resolved = substituteVariables(resolved, options.variables);
5250
+ }
5251
+ resolved = substituteArguments(resolved, options?.arguments);
5252
+ if (options?.enableShellPreprocessing !== false) {
5253
+ resolved = preprocessShellCommands(resolved, {
5254
+ cwd: options?.cwd,
5255
+ shell: options?.shell,
5256
+ timeoutMs: options?.shellTimeoutMs
5257
+ });
5258
+ }
5259
+ return resolved;
5260
+ }
5261
+ function splitArguments(args) {
5262
+ const parts = [];
5263
+ let current = "";
5264
+ let inQuote = null;
5265
+ for (const char of args) {
5266
+ if (inQuote) {
5267
+ if (char === inQuote) {
5268
+ inQuote = null;
5269
+ } else {
5270
+ current += char;
5271
+ }
5272
+ } else if (char === '"' || char === "'") {
5273
+ inQuote = char;
5274
+ } else if (char === " " || char === " ") {
5275
+ if (current) {
5276
+ parts.push(current);
5277
+ current = "";
5278
+ }
5279
+ } else {
5280
+ current += char;
5281
+ }
5282
+ }
5283
+ if (current) parts.push(current);
5284
+ return parts;
5285
+ }
5286
+ var import_node_child_process;
5287
+ var init_activation = __esm({
5288
+ "src/skills/activation.ts"() {
5289
+ "use strict";
5290
+ import_node_child_process = require("child_process");
5291
+ }
5292
+ });
5293
+
5294
+ // src/skills/parser.ts
5295
+ function parseFrontmatter(content) {
5296
+ const trimmed = content.trimStart();
5297
+ if (!trimmed.startsWith("---")) {
5298
+ return { frontmatter: {}, body: content };
5299
+ }
5300
+ const endIndex = trimmed.indexOf("\n---", 3);
5301
+ if (endIndex === -1) {
5302
+ return { frontmatter: {}, body: content };
5303
+ }
5304
+ const yamlBlock = trimmed.slice(3, endIndex).trim();
5305
+ const body = trimmed.slice(endIndex + 4).trim();
5306
+ const parsed = import_js_yaml.default.load(yamlBlock);
5307
+ const frontmatter = typeof parsed === "object" && parsed !== null ? parsed : {};
5308
+ return { frontmatter, body };
5309
+ }
5310
+ function parseMetadata(frontmatter, fallbackName) {
5311
+ const name = parseString(frontmatter.name) ?? fallbackName ?? "unnamed-skill";
5312
+ const description = parseString(frontmatter.description) ?? "";
5313
+ return {
5314
+ name,
5315
+ description,
5316
+ argumentHint: parseString(frontmatter["argument-hint"]),
5317
+ allowedTools: parseStringArray(frontmatter["allowed-tools"]),
5318
+ model: parseString(frontmatter.model),
5319
+ context: parseContext(frontmatter.context),
5320
+ agent: parseString(frontmatter.agent),
5321
+ paths: parseStringArray(frontmatter.paths),
5322
+ gadgets: parseStringArray(frontmatter.gadgets),
5323
+ disableModelInvocation: parseBool(frontmatter["disable-model-invocation"]),
5324
+ userInvocable: parseBool(frontmatter["user-invocable"]),
5325
+ shell: parseShell(frontmatter.shell),
5326
+ version: parseString(frontmatter.version)
5327
+ };
5328
+ }
5329
+ function scanResources(skillDir) {
5330
+ const resources = [];
5331
+ for (const category of RESOURCE_CATEGORIES) {
5332
+ const categoryDir = import_node_path3.default.join(skillDir, category);
5333
+ if (!import_node_fs2.default.existsSync(categoryDir)) continue;
5334
+ const stat = import_node_fs2.default.statSync(categoryDir);
5335
+ if (!stat.isDirectory()) continue;
5336
+ for (const file of walkDirectory(categoryDir)) {
5337
+ resources.push({
5338
+ relativePath: import_node_path3.default.relative(skillDir, file),
5339
+ absolutePath: file,
5340
+ category
5341
+ });
5342
+ }
5343
+ }
5344
+ return resources;
5345
+ }
5346
+ function parseSkillFile(skillMdPath, source, loadInstructions = false) {
5347
+ const content = import_node_fs2.default.readFileSync(skillMdPath, "utf-8");
5348
+ return parseSkillContent(content, skillMdPath, source, loadInstructions);
5349
+ }
5350
+ function parseSkillContent(content, sourcePath, source, loadInstructions = false) {
5351
+ const sourceDir = import_node_path3.default.dirname(sourcePath);
5352
+ const fallbackName = import_node_path3.default.basename(sourceDir);
5353
+ const { frontmatter, body } = parseFrontmatter(content);
5354
+ const metadata = parseMetadata(frontmatter, fallbackName);
5355
+ const resources = import_node_fs2.default.existsSync(sourceDir) ? scanResources(sourceDir) : [];
5356
+ return {
5357
+ metadata,
5358
+ instructions: loadInstructions ? body : null,
5359
+ resources,
5360
+ sourcePath,
5361
+ sourceDir,
5362
+ source
5363
+ };
5364
+ }
5365
+ function validateMetadata(metadata) {
5366
+ const issues = [];
5367
+ if (!metadata.name) {
5368
+ issues.push("Skill name is required");
5369
+ } else {
5370
+ if (metadata.name.length > MAX_NAME_LENGTH) {
5371
+ issues.push(`Skill name exceeds ${MAX_NAME_LENGTH} characters`);
5372
+ }
5373
+ if (!NAME_PATTERN.test(metadata.name)) {
5374
+ issues.push(
5375
+ "Skill name must contain only lowercase letters, numbers, and hyphens, and must start with a letter or number"
5376
+ );
5377
+ }
5378
+ }
5379
+ if (!metadata.description) {
5380
+ issues.push("Skill description is required");
5381
+ } else if (metadata.description.length > MAX_DESCRIPTION_LENGTH) {
5382
+ issues.push(`Skill description exceeds ${MAX_DESCRIPTION_LENGTH} characters`);
5383
+ }
5384
+ if (metadata.context && metadata.context !== "fork" && metadata.context !== "inline") {
5385
+ issues.push('Skill context must be "fork" or "inline"');
5386
+ }
5387
+ return issues;
5388
+ }
5389
+ function parseString(value) {
5390
+ if (value == null) return void 0;
5391
+ if (typeof value === "string") return value;
5392
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
5393
+ return void 0;
5394
+ }
5395
+ function parseStringArray(value) {
5396
+ if (value == null) return void 0;
5397
+ if (Array.isArray(value)) {
5398
+ return value.filter((v) => typeof v === "string" || typeof v === "number").map(String);
5399
+ }
5400
+ if (typeof value === "string") return [value];
5401
+ return void 0;
5402
+ }
5403
+ function parseContext(value) {
5404
+ if (value === "fork" || value === "inline") return value;
5405
+ return void 0;
5406
+ }
5407
+ function parseShell(value) {
5408
+ if (value === "bash" || value === "powershell") return value;
5409
+ return void 0;
5410
+ }
5411
+ function parseBool(value) {
5412
+ if (value === true || value === false) return value;
5413
+ if (value === "true") return true;
5414
+ if (value === "false") return false;
5415
+ return void 0;
5416
+ }
5417
+ function* walkDirectory(dir) {
5418
+ const entries = import_node_fs2.default.readdirSync(dir, { withFileTypes: true });
5419
+ for (const entry of entries) {
5420
+ const fullPath = import_node_path3.default.join(dir, entry.name);
5421
+ if (entry.isDirectory()) {
5422
+ yield* walkDirectory(fullPath);
5423
+ } else if (entry.isFile()) {
5424
+ yield fullPath;
5425
+ }
5426
+ }
5427
+ }
5428
+ var import_node_fs2, import_node_path3, import_js_yaml, RESOURCE_CATEGORIES, MAX_NAME_LENGTH, MAX_DESCRIPTION_LENGTH, NAME_PATTERN;
5429
+ var init_parser = __esm({
5430
+ "src/skills/parser.ts"() {
5431
+ "use strict";
5432
+ import_node_fs2 = __toESM(require("fs"), 1);
5433
+ import_node_path3 = __toESM(require("path"), 1);
5434
+ import_js_yaml = __toESM(require("js-yaml"), 1);
5435
+ RESOURCE_CATEGORIES = ["scripts", "references", "assets"];
5436
+ MAX_NAME_LENGTH = 64;
5437
+ MAX_DESCRIPTION_LENGTH = 1024;
5438
+ NAME_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
5439
+ }
5440
+ });
5441
+
5442
+ // src/skills/registry.ts
5443
+ var registry_exports = {};
5444
+ __export(registry_exports, {
5445
+ SkillRegistry: () => SkillRegistry
5446
+ });
5447
+ var import_minimatch, DEFAULT_CHAR_BUDGET, SUMMARY_DESCRIPTION_LIMIT, SkillRegistry;
5448
+ var init_registry2 = __esm({
5449
+ "src/skills/registry.ts"() {
5450
+ "use strict";
5451
+ import_minimatch = require("minimatch");
5452
+ DEFAULT_CHAR_BUDGET = 8e3;
5453
+ SUMMARY_DESCRIPTION_LIMIT = 250;
5454
+ SkillRegistry = class _SkillRegistry {
5455
+ skills = /* @__PURE__ */ new Map();
5456
+ /**
5457
+ * Register a skill. Overwrites any existing skill with the same name.
5458
+ *
5459
+ * Unlike GadgetRegistry (which throws on duplicates), SkillRegistry allows
5460
+ * overwriting because skills are loaded from multiple sources with intentional
5461
+ * priority ordering (project > user > default).
5462
+ */
5463
+ register(skill) {
5464
+ this.skills.set(skill.name.toLowerCase(), skill);
5465
+ }
5466
+ /** Register multiple skills. */
5467
+ registerMany(skills) {
5468
+ for (const skill of skills) {
5469
+ this.register(skill);
5470
+ }
5471
+ }
5472
+ /** Remove a skill by name (case-insensitive). Returns true if removed. */
5473
+ remove(name) {
5474
+ return this.skills.delete(name.toLowerCase());
5475
+ }
5476
+ /** Remove all registered skills. */
5477
+ clear() {
5478
+ this.skills.clear();
5479
+ }
5480
+ /** Get a skill by name (case-insensitive). */
5481
+ get(name) {
5482
+ return this.skills.get(name.toLowerCase());
5483
+ }
5484
+ /** Check if a skill exists by name (case-insensitive). */
5485
+ has(name) {
5486
+ return this.skills.has(name.toLowerCase());
5487
+ }
5488
+ /** Get all registered skills. */
5489
+ getAll() {
5490
+ return [...this.skills.values()];
5491
+ }
5492
+ /** Get all skill names. */
5493
+ getNames() {
5494
+ return [...this.skills.keys()];
5495
+ }
5496
+ /** Number of registered skills. */
5497
+ get size() {
5498
+ return this.skills.size;
5499
+ }
5500
+ /**
5501
+ * Get skills that are visible to the LLM for auto-triggering.
5502
+ * Excludes skills with disableModelInvocation: true.
5503
+ */
5504
+ getModelInvocable() {
5505
+ return this.getAll().filter((s) => s.isModelInvocable);
5506
+ }
5507
+ /**
5508
+ * Get skills that the user can invoke via /skill-name.
5509
+ * Excludes skills with userInvocable: false.
5510
+ */
5511
+ getUserInvocable() {
5512
+ return this.getAll().filter((s) => s.isUserInvocable);
5513
+ }
5514
+ /**
5515
+ * Generate metadata summaries for system prompt injection (Tier 1).
5516
+ *
5517
+ * Each skill contributes a one-line summary: "name — description".
5518
+ * Output is truncated to fit the character budget.
5519
+ *
5520
+ * @param charBudget - Maximum characters for all summaries combined.
5521
+ */
5522
+ getMetadataSummaries(charBudget = DEFAULT_CHAR_BUDGET) {
5523
+ const invocable = this.getModelInvocable();
5524
+ if (invocable.length === 0) return "";
5525
+ const lines = [];
5526
+ let totalChars = 0;
5527
+ for (const skill of invocable) {
5528
+ const desc = skill.description.length > SUMMARY_DESCRIPTION_LIMIT ? `${skill.description.slice(0, SUMMARY_DESCRIPTION_LIMIT - 3)}...` : skill.description;
5529
+ const line = `- ${skill.name}: ${desc}`;
5530
+ if (totalChars + line.length > charBudget) break;
5531
+ lines.push(line);
5532
+ totalChars += line.length + 1;
5533
+ }
5534
+ return lines.join("\n");
5535
+ }
5536
+ /**
5537
+ * Find skills whose `paths` patterns match a given file path.
5538
+ * Used for auto-activation when the user is working on specific files.
5539
+ */
5540
+ findByFilePath(filePath) {
5541
+ return this.getModelInvocable().filter((skill) => {
5542
+ const patterns = skill.metadata.paths;
5543
+ if (!patterns || patterns.length === 0) return false;
5544
+ return patterns.some((pattern) => (0, import_minimatch.minimatch)(filePath, pattern));
5545
+ });
5546
+ }
5547
+ /**
5548
+ * Merge another registry into this one.
5549
+ * Skills from the other registry overwrite existing skills with the same name.
5550
+ */
5551
+ merge(other) {
5552
+ for (const skill of other.getAll()) {
5553
+ this.register(skill);
5554
+ }
5555
+ }
5556
+ /** Create a registry from an array of skills. */
5557
+ static from(skills) {
5558
+ const registry = new _SkillRegistry();
5559
+ registry.registerMany(skills);
5560
+ return registry;
5561
+ }
5562
+ };
5563
+ }
5564
+ });
5565
+
5566
+ // src/skills/skill.ts
5567
+ var import_promises2, Skill;
5568
+ var init_skill = __esm({
5569
+ "src/skills/skill.ts"() {
5570
+ "use strict";
5571
+ import_promises2 = __toESM(require("fs/promises"), 1);
5572
+ init_activation();
5573
+ init_parser();
5574
+ Skill = class _Skill {
5575
+ metadata;
5576
+ sourcePath;
5577
+ sourceDir;
5578
+ source;
5579
+ _instructions;
5580
+ _resources;
5581
+ _resourceCache = /* @__PURE__ */ new Map();
5582
+ _resourceLoading = /* @__PURE__ */ new Map();
5583
+ constructor(parsed) {
5584
+ this.metadata = parsed.metadata;
5585
+ this.sourcePath = parsed.sourcePath;
5586
+ this.sourceDir = parsed.sourceDir;
5587
+ this.source = parsed.source;
5588
+ this._instructions = parsed.instructions;
5589
+ this._resources = parsed.resources;
5590
+ }
5591
+ /** Skill name for registry lookup. */
5592
+ get name() {
5593
+ return this.metadata.name;
5594
+ }
5595
+ /** Skill description for LLM matching. */
5596
+ get description() {
5597
+ return this.metadata.description;
5598
+ }
5599
+ /** Whether the LLM can auto-trigger this skill. */
5600
+ get isModelInvocable() {
5601
+ return this.metadata.disableModelInvocation !== true;
5602
+ }
5603
+ /** Whether the user can invoke this skill via /skill-name. */
5604
+ get isUserInvocable() {
5605
+ return this.metadata.userInvocable !== false;
5606
+ }
5607
+ /**
5608
+ * Load and cache Tier 2 instructions.
5609
+ * If instructions were loaded during parsing, returns the cached value.
5610
+ */
5611
+ async getInstructions() {
5612
+ if (this._instructions !== null) return this._instructions;
5613
+ const content = await import_promises2.default.readFile(this.sourcePath, "utf-8");
5614
+ const { body } = parseFrontmatter(content);
5615
+ this._instructions = body;
5616
+ return body;
5617
+ }
5618
+ /**
5619
+ * List Tier 3 resources.
5620
+ * Resources are discovered at parse time but content is loaded on demand.
5621
+ */
5622
+ getResources() {
5623
+ return this._resources;
5624
+ }
5625
+ /**
5626
+ * Load a specific Tier 3 resource by relative path.
5627
+ * Results are cached for the lifetime of this Skill instance.
5628
+ * Concurrent calls for the same resource share a single read.
5629
+ */
5630
+ async getResource(relativePath) {
5631
+ if (relativePath.includes("..")) {
5632
+ throw new Error(`Invalid resource path (path traversal): ${relativePath}`);
5633
+ }
5634
+ const cached = this._resourceCache.get(relativePath);
5635
+ if (cached !== void 0) return cached;
5636
+ const existing = this._resourceLoading.get(relativePath);
5637
+ if (existing) return existing;
5638
+ const resource = this._resources.find((r) => r.relativePath === relativePath);
5639
+ if (!resource) {
5640
+ throw new Error(`Resource not found: ${relativePath} in skill ${this.name}`);
5641
+ }
5642
+ const loadPromise = import_promises2.default.readFile(resource.absolutePath, "utf-8").then(
5643
+ (content) => {
5644
+ this._resourceCache.set(relativePath, content);
5645
+ this._resourceLoading.delete(relativePath);
5646
+ return content;
5647
+ },
5648
+ (error) => {
5649
+ this._resourceLoading.delete(relativePath);
5650
+ throw new Error(
5651
+ `Failed to load resource ${relativePath} in skill ${this.name}: ${error instanceof Error ? error.message : String(error)}`
5652
+ );
5653
+ }
5654
+ );
5655
+ this._resourceLoading.set(relativePath, loadPromise);
5656
+ return loadPromise;
5657
+ }
5658
+ /**
5659
+ * Activate this skill with optional arguments.
5660
+ *
5661
+ * Performs:
5662
+ * 1. Variable substitution (${SKILL_DIR}, etc.)
5663
+ * 2. Argument substitution ($ARGUMENTS, $0, $1)
5664
+ * 3. Shell preprocessing (!`command`)
5665
+ * 4. Resource loading (if eagerResources is true)
5666
+ */
5667
+ async activate(options) {
5668
+ const instructions = await this.getInstructions();
5669
+ const resolvedInstructions = resolveInstructions(instructions, {
5670
+ arguments: options?.arguments,
5671
+ variables: {
5672
+ SKILL_DIR: this.sourceDir,
5673
+ CLAUDE_SKILL_DIR: this.sourceDir
5674
+ },
5675
+ cwd: options?.cwd ?? this.sourceDir,
5676
+ shell: this.metadata.shell,
5677
+ enableShellPreprocessing: options?.enableShellPreprocessing,
5678
+ shellTimeoutMs: options?.shellTimeoutMs
5679
+ });
5680
+ const loadedResources = /* @__PURE__ */ new Map();
5681
+ if (options?.eagerResources) {
5682
+ for (const resource of this._resources) {
5683
+ const content = await this.getResource(resource.relativePath);
5684
+ loadedResources.set(resource.relativePath, content);
5685
+ }
5686
+ }
5687
+ return {
5688
+ skillName: this.name,
5689
+ resolvedInstructions,
5690
+ gadgets: [],
5691
+ // Gadgets are resolved by the CLI layer
5692
+ loadedResources
5693
+ };
5694
+ }
5695
+ /**
5696
+ * Create a Skill from a SKILL.md content string.
5697
+ * Useful for testing or dynamic skill creation.
5698
+ */
5699
+ static fromContent(content, sourcePath, source = { type: "directory", path: sourcePath }) {
5700
+ const parsed = parseSkillContent(content, sourcePath, source, true);
5701
+ return new _Skill(parsed);
5702
+ }
5703
+ };
5704
+ }
5705
+ });
5706
+
5707
+ // src/skills/loader.ts
5708
+ function loadSkillsFromDirectory(dir, source, onWarning) {
5709
+ if (!import_node_fs3.default.existsSync(dir)) return [];
5710
+ const stat = import_node_fs3.default.statSync(dir);
5711
+ if (!stat.isDirectory()) return [];
5712
+ const skills = [];
5713
+ scanForSkills(dir, source, skills, onWarning);
5714
+ return skills;
5715
+ }
5716
+ function discoverSkills(options) {
5717
+ const registry = new SkillRegistry();
5718
+ const userSkillsDir = options?.userDir ?? import_node_path4.default.join(import_node_os2.default.homedir(), CONFIG_DIR_NAME, SKILLS_DIR_NAME);
5719
+ const userSkills = loadSkillsFromDirectory(userSkillsDir, {
5720
+ type: "user",
5721
+ path: userSkillsDir
5722
+ });
5723
+ registry.registerMany(userSkills);
5724
+ if (options?.projectDir) {
5725
+ const projectSkillsDir = import_node_path4.default.join(options.projectDir, CONFIG_DIR_NAME, SKILLS_DIR_NAME);
5726
+ const projectSkills = loadSkillsFromDirectory(projectSkillsDir, {
5727
+ type: "project",
5728
+ path: projectSkillsDir
5729
+ });
5730
+ registry.registerMany(projectSkills);
5731
+ }
5732
+ if (options?.additionalDirs) {
5733
+ for (const dir of options.additionalDirs) {
5734
+ const resolvedDir = dir.startsWith("~") ? import_node_path4.default.join(import_node_os2.default.homedir(), dir.slice(1)) : dir;
5735
+ const skills = loadSkillsFromDirectory(resolvedDir, {
5736
+ type: "directory",
5737
+ path: resolvedDir
5738
+ });
5739
+ registry.registerMany(skills);
5740
+ }
5741
+ }
5742
+ return registry;
5743
+ }
5744
+ function scanForSkills(dir, source, results, onWarning) {
5745
+ let entries;
5746
+ try {
5747
+ entries = import_node_fs3.default.readdirSync(dir, { withFileTypes: true });
5748
+ } catch (error) {
5749
+ onWarning?.(
5750
+ `Cannot read skill directory ${dir}: ${error instanceof Error ? error.message : String(error)}`
5751
+ );
5752
+ return;
5753
+ }
5754
+ const skillMdPath = import_node_path4.default.join(dir, "SKILL.md");
5755
+ if (import_node_fs3.default.existsSync(skillMdPath)) {
5756
+ try {
5757
+ const parsed = parseSkillFile(skillMdPath, source, false);
5758
+ results.push(new Skill(parsed));
5759
+ } catch (error) {
5760
+ onWarning?.(
5761
+ `Failed to parse ${skillMdPath}: ${error instanceof Error ? error.message : String(error)}`
5762
+ );
5763
+ }
5764
+ return;
5765
+ }
5766
+ for (const entry of entries) {
5767
+ if (entry.isDirectory() && !entry.name.startsWith(".")) {
5768
+ scanForSkills(import_node_path4.default.join(dir, entry.name), source, results, onWarning);
5769
+ }
5770
+ }
5771
+ }
5772
+ var import_node_fs3, import_node_os2, import_node_path4, SKILLS_DIR_NAME, CONFIG_DIR_NAME;
5773
+ var init_loader = __esm({
5774
+ "src/skills/loader.ts"() {
5775
+ "use strict";
5776
+ import_node_fs3 = __toESM(require("fs"), 1);
5777
+ import_node_os2 = __toESM(require("os"), 1);
5778
+ import_node_path4 = __toESM(require("path"), 1);
5779
+ init_parser();
5780
+ init_registry2();
5781
+ init_skill();
5782
+ SKILLS_DIR_NAME = "skills";
5783
+ CONFIG_DIR_NAME = ".llmist";
5784
+ }
5785
+ });
5786
+
5787
+ // src/skills/use-skill-gadget.ts
5788
+ function createUseSkillGadget(registry) {
5789
+ const summaries = registry.getMetadataSummaries();
5790
+ const skillNames = registry.getModelInvocable().map((s) => s.name);
5791
+ const description = [
5792
+ "Activate a skill to get specialized instructions for a task.",
5793
+ "Available skills:",
5794
+ summaries
5795
+ ].join("\n");
5796
+ return createGadget({
5797
+ name: USE_SKILL_GADGET_NAME,
5798
+ description,
5799
+ schema: import_zod2.z.object({
5800
+ skill: import_zod2.z.enum(skillNames).describe("Name of the skill to activate"),
5801
+ arguments: import_zod2.z.string().optional().describe("Arguments for the skill (e.g., a filename, issue number, or search query)")
5802
+ }),
5803
+ execute: async ({ skill: skillName, arguments: args }) => {
5804
+ const skill = registry.get(skillName);
5805
+ if (!skill) {
5806
+ return `Unknown skill: "${skillName}". Available skills: ${skillNames.join(", ")}`;
5807
+ }
5808
+ const activation = await skill.activate({
5809
+ arguments: args,
5810
+ cwd: process.cwd()
5811
+ });
5812
+ return activation.resolvedInstructions;
5813
+ }
5814
+ });
5815
+ }
5816
+ var import_zod2, USE_SKILL_GADGET_NAME;
5817
+ var init_use_skill_gadget = __esm({
5818
+ "src/skills/use-skill-gadget.ts"() {
5819
+ "use strict";
5820
+ import_zod2 = require("zod");
5821
+ init_create_gadget();
5822
+ USE_SKILL_GADGET_NAME = "UseSkill";
5823
+ }
5824
+ });
5825
+
5206
5826
  // src/agent/builder-utils.ts
5207
5827
  function formatGadgetCall(gadgetName, invocationId, parameters, prefixes) {
5208
5828
  const startPrefix = prefixes?.start ?? GADGET_START_PREFIX;
@@ -5336,7 +5956,7 @@ function resolveLoggingDirectory(state, baseDirectory, counterPadding, subagentC
5336
5956
  if (!fullPath) {
5337
5957
  const chronoNumber = getNextCounter(state, parentDir);
5338
5958
  const subdirName = `${formatCallNumber(chronoNumber, counterPadding)}-${parentGadgetInvocationId}`;
5339
- fullPath = (0, import_node_path3.join)(parentDir, subdirName);
5959
+ fullPath = (0, import_node_path5.join)(parentDir, subdirName);
5340
5960
  state.subagentDirectories.set(subagentKey, fullPath);
5341
5961
  }
5342
5962
  state.activeDirectoryByContext.set(contextKey, fullPath);
@@ -5355,8 +5975,8 @@ function formatCallNumber(n, padding = 4) {
5355
5975
  return n.toString().padStart(padding, "0");
5356
5976
  }
5357
5977
  async function writeLogFile(dir, filename, content) {
5358
- await (0, import_promises2.mkdir)(dir, { recursive: true });
5359
- await (0, import_promises2.writeFile)((0, import_node_path3.join)(dir, filename), content, "utf-8");
5978
+ await (0, import_promises3.mkdir)(dir, { recursive: true });
5979
+ await (0, import_promises3.writeFile)((0, import_node_path5.join)(dir, filename), content, "utf-8");
5360
5980
  }
5361
5981
  function createFileLoggingHooks(options, state = getDefaultState()) {
5362
5982
  const {
@@ -5366,7 +5986,7 @@ function createFileLoggingHooks(options, state = getDefaultState()) {
5366
5986
  formatRequest = formatLlmRequest,
5367
5987
  onFileWritten
5368
5988
  } = options;
5369
- const baseDirectory = (0, import_node_path3.resolve)(options.directory);
5989
+ const baseDirectory = (0, import_node_path5.resolve)(options.directory);
5370
5990
  if (!state.counters.has(baseDirectory)) {
5371
5991
  state.counters.set(baseDirectory, startingCounter - 1);
5372
5992
  }
@@ -5394,7 +6014,7 @@ function createFileLoggingHooks(options, state = getDefaultState()) {
5394
6014
  await writeLogFile(currentDirectory, filename, content);
5395
6015
  if (onFileWritten) {
5396
6016
  onFileWritten({
5397
- filePath: (0, import_node_path3.join)(currentDirectory, filename),
6017
+ filePath: (0, import_node_path5.join)(currentDirectory, filename),
5398
6018
  type: "request",
5399
6019
  callNumber: currentCallNumber,
5400
6020
  contentLength: content.length,
@@ -5423,7 +6043,7 @@ function createFileLoggingHooks(options, state = getDefaultState()) {
5423
6043
  await writeLogFile(currentDirectory, filename, content);
5424
6044
  if (onFileWritten) {
5425
6045
  onFileWritten({
5426
- filePath: (0, import_node_path3.join)(currentDirectory, filename),
6046
+ filePath: (0, import_node_path5.join)(currentDirectory, filename),
5427
6047
  type: "response",
5428
6048
  callNumber: currentCallNumber,
5429
6049
  contentLength: content.length,
@@ -5445,12 +6065,12 @@ function getEnvFileLoggingHooks() {
5445
6065
  }
5446
6066
  return createFileLoggingHooks({ directory });
5447
6067
  }
5448
- var import_promises2, import_node_path3, defaultState, ENV_LOG_RAW_DIRECTORY;
6068
+ var import_promises3, import_node_path5, defaultState, ENV_LOG_RAW_DIRECTORY;
5449
6069
  var init_file_logging = __esm({
5450
6070
  "src/agent/file-logging.ts"() {
5451
6071
  "use strict";
5452
- import_promises2 = require("fs/promises");
5453
- import_node_path3 = require("path");
6072
+ import_promises3 = require("fs/promises");
6073
+ import_node_path5 = require("path");
5454
6074
  init_messages();
5455
6075
  ENV_LOG_RAW_DIRECTORY = "LLMIST_LOG_RAW_DIRECTORY";
5456
6076
  }
@@ -12207,6 +12827,10 @@ var init_builder = __esm({
12207
12827
  "use strict";
12208
12828
  init_model_shortcuts();
12209
12829
  init_registry();
12830
+ init_activation();
12831
+ init_loader();
12832
+ init_parser();
12833
+ init_use_skill_gadget();
12210
12834
  init_agent();
12211
12835
  init_agent_internal_key();
12212
12836
  init_builder_utils();
@@ -12218,12 +12842,14 @@ var init_builder = __esm({
12218
12842
  retry;
12219
12843
  subagents;
12220
12844
  policies;
12845
+ skills;
12221
12846
  constructor(client) {
12222
12847
  this.core = { client, initialMessages: [] };
12223
12848
  this.gadgets = { gadgets: [] };
12224
12849
  this.retry = {};
12225
12850
  this.subagents = {};
12226
12851
  this.policies = {};
12852
+ this.skills = { preActivated: [], skillDirs: [] };
12227
12853
  }
12228
12854
  /** Set the model to use. Supports aliases like "sonnet", "flash". */
12229
12855
  withModel(model) {
@@ -12360,6 +12986,38 @@ var init_builder = __esm({
12360
12986
  this.policies.compactionConfig = { enabled: false };
12361
12987
  return this;
12362
12988
  }
12989
+ // ─── Skills ──────────────────────────────────────────────────────────────────
12990
+ /** Register a skill registry for this agent. */
12991
+ withSkills(registry) {
12992
+ this.skills.registry = registry;
12993
+ return this;
12994
+ }
12995
+ /**
12996
+ * Pre-activate a specific skill before the agent starts.
12997
+ * Instructions are injected into the system prompt.
12998
+ *
12999
+ * Note: each call replaces (not appends) the pre-activated skill for that name.
13000
+ * This is safe for REPL loops where the same builder is reused.
13001
+ */
13002
+ withSkill(name, args) {
13003
+ const existing = this.skills.preActivated.findIndex((s) => s.name === name);
13004
+ if (existing !== -1) {
13005
+ this.skills.preActivated[existing] = { name, args };
13006
+ } else {
13007
+ this.skills.preActivated.push({ name, args });
13008
+ }
13009
+ return this;
13010
+ }
13011
+ /** Clear all pre-activated skills. Call between REPL iterations. */
13012
+ clearPreActivatedSkills() {
13013
+ this.skills.preActivated = [];
13014
+ return this;
13015
+ }
13016
+ /** Add a directory to scan for skills. */
13017
+ withSkillsFrom(dir) {
13018
+ this.skills.skillDirs.push(dir);
13019
+ return this;
13020
+ }
12363
13021
  /** Configure retry behavior for LLM API calls. */
12364
13022
  withRetry(config) {
12365
13023
  this.retry.retryConfig = { ...config, enabled: config.enabled ?? true };
@@ -12451,16 +13109,75 @@ var init_builder = __esm({
12451
13109
  composeHooks() {
12452
13110
  return HookComposer.compose(this.core.hooks, this.core.trailingMessage);
12453
13111
  }
13112
+ resolveSkillRegistry() {
13113
+ if (this.skills.registry) {
13114
+ if (this.skills.skillDirs.length > 0) {
13115
+ for (const dir of this.skills.skillDirs) {
13116
+ const skills = loadSkillsFromDirectory(dir, { type: "directory", path: dir });
13117
+ this.skills.registry.registerMany(skills);
13118
+ }
13119
+ }
13120
+ return this.skills.registry;
13121
+ }
13122
+ if (this.skills.skillDirs.length > 0) {
13123
+ const { SkillRegistry: SR } = (init_registry2(), __toCommonJS(registry_exports));
13124
+ const reg = new SR();
13125
+ for (const dir of this.skills.skillDirs) {
13126
+ const skills = loadSkillsFromDirectory(dir, { type: "directory", path: dir });
13127
+ reg.registerMany(skills);
13128
+ }
13129
+ return reg;
13130
+ }
13131
+ return void 0;
13132
+ }
13133
+ /**
13134
+ * Resolve pre-activated skill instructions synchronously.
13135
+ * Reads SKILL.md from disk via readFileSync (skills are local files).
13136
+ */
13137
+ resolvePreActivatedInstructions(skillRegistry) {
13138
+ if (this.skills.preActivated.length === 0) return void 0;
13139
+ const fs4 = require("fs");
13140
+ const blocks = [];
13141
+ for (const { name, args } of this.skills.preActivated) {
13142
+ const skill = skillRegistry.get(name);
13143
+ if (!skill) continue;
13144
+ const content = fs4.readFileSync(skill.sourcePath, "utf-8");
13145
+ const { body } = parseFrontmatter(content);
13146
+ const resolved = resolveInstructions(body, {
13147
+ arguments: args,
13148
+ variables: { SKILL_DIR: skill.sourceDir, CLAUDE_SKILL_DIR: skill.sourceDir },
13149
+ cwd: skill.sourceDir,
13150
+ shell: skill.metadata.shell
13151
+ });
13152
+ blocks.push(`## Skill: ${name}
13153
+
13154
+ ${resolved}`);
13155
+ }
13156
+ return blocks.length > 0 ? blocks.join("\n\n---\n\n") : void 0;
13157
+ }
12454
13158
  buildAgentOptions(userPrompt) {
12455
13159
  if (!this.core.client) {
12456
13160
  const { LLMist: LLMistClass } = (init_client(), __toCommonJS(client_exports));
12457
13161
  this.core.client = new LLMistClass();
12458
13162
  }
12459
13163
  const registry = GadgetRegistry.from(this.gadgets.gadgets);
13164
+ let systemPrompt = this.core.systemPrompt;
13165
+ const skillRegistry = this.resolveSkillRegistry();
13166
+ if (skillRegistry && skillRegistry.size > 0) {
13167
+ if (skillRegistry.getModelInvocable().length > 0) {
13168
+ registry.registerByClass(createUseSkillGadget(skillRegistry));
13169
+ }
13170
+ const preActivatedBlock = this.resolvePreActivatedInstructions(skillRegistry);
13171
+ if (preActivatedBlock) {
13172
+ systemPrompt = systemPrompt ? `${systemPrompt}
13173
+
13174
+ ${preActivatedBlock}` : preActivatedBlock;
13175
+ }
13176
+ }
12460
13177
  return {
12461
13178
  client: this.core.client,
12462
13179
  model: this.core.model ?? "openai:gpt-5-nano",
12463
- systemPrompt: this.core.systemPrompt,
13180
+ systemPrompt,
12464
13181
  userPrompt,
12465
13182
  registry,
12466
13183
  maxIterations: this.core.maxIterations,
@@ -13145,8 +13862,8 @@ var init_error_formatter = __esm({
13145
13862
  const parts = [];
13146
13863
  parts.push(`Error: Invalid parameters for '${gadgetName}':`);
13147
13864
  for (const issue of zodError.issues) {
13148
- const path = issue.path.join(".") || "root";
13149
- parts.push(` - ${path}: ${issue.message}`);
13865
+ const path3 = issue.path.join(".") || "root";
13866
+ parts.push(` - ${path3}: ${issue.message}`);
13150
13867
  }
13151
13868
  parts.push("");
13152
13869
  parts.push("Gadget Usage:");
@@ -13211,7 +13928,7 @@ function stripMarkdownFences(content) {
13211
13928
  return cleaned.trim();
13212
13929
  }
13213
13930
  var globalInvocationCounter, GadgetCallParser;
13214
- var init_parser = __esm({
13931
+ var init_parser2 = __esm({
13215
13932
  "src/gadgets/parser.ts"() {
13216
13933
  "use strict";
13217
13934
  init_constants();
@@ -13423,15 +14140,15 @@ function getHostExportsInternal() {
13423
14140
  createGadget,
13424
14141
  ExecutionTree,
13425
14142
  LLMist,
13426
- z: import_zod2.z
14143
+ z: import_zod3.z
13427
14144
  };
13428
14145
  }
13429
- var import_fast_deep_equal, import_zod2, GadgetExecutor;
14146
+ var import_fast_deep_equal, import_zod3, GadgetExecutor;
13430
14147
  var init_executor = __esm({
13431
14148
  "src/gadgets/executor.ts"() {
13432
14149
  "use strict";
13433
14150
  import_fast_deep_equal = __toESM(require("fast-deep-equal"), 1);
13434
- import_zod2 = require("zod");
14151
+ import_zod3 = require("zod");
13435
14152
  init_builder();
13436
14153
  init_hook_utils();
13437
14154
  init_client();
@@ -13443,7 +14160,7 @@ var init_executor = __esm({
13443
14160
  init_create_gadget();
13444
14161
  init_error_formatter();
13445
14162
  init_exceptions();
13446
- init_parser();
14163
+ init_parser2();
13447
14164
  init_typed_gadget();
13448
14165
  GadgetExecutor = class {
13449
14166
  registry;
@@ -15044,7 +15761,7 @@ var init_stream_processor = __esm({
15044
15761
  "src/agent/stream-processor.ts"() {
15045
15762
  "use strict";
15046
15763
  init_executor();
15047
- init_parser();
15764
+ init_parser2();
15048
15765
  init_logger();
15049
15766
  init_gadget_concurrency_manager();
15050
15767
  init_gadget_dependency_resolver();
@@ -16206,11 +16923,14 @@ __export(index_exports, {
16206
16923
  OpenRouterProvider: () => OpenRouterProvider,
16207
16924
  RateLimitTracker: () => RateLimitTracker,
16208
16925
  SimpleSessionManager: () => SimpleSessionManager,
16926
+ Skill: () => Skill,
16927
+ SkillRegistry: () => SkillRegistry,
16209
16928
  SlidingWindowStrategy: () => SlidingWindowStrategy,
16210
16929
  StreamProcessor: () => StreamProcessor,
16211
16930
  SummarizationStrategy: () => SummarizationStrategy,
16212
16931
  TaskCompletionSignal: () => TaskCompletionSignal,
16213
16932
  TimeoutException: () => TimeoutException,
16933
+ USE_SKILL_GADGET_NAME: () => USE_SKILL_GADGET_NAME,
16214
16934
  audioFromBase64: () => audioFromBase64,
16215
16935
  audioFromBuffer: () => audioFromBuffer,
16216
16936
  collectEvents: () => collectEvents,
@@ -16228,10 +16948,12 @@ __export(index_exports, {
16228
16948
  createOpenAIProviderFromEnv: () => createOpenAIProviderFromEnv,
16229
16949
  createOpenRouterProviderFromEnv: () => createOpenRouterProviderFromEnv,
16230
16950
  createSubagent: () => createSubagent,
16951
+ createUseSkillGadget: () => createUseSkillGadget,
16231
16952
  defaultLogger: () => defaultLogger,
16232
16953
  detectAudioMimeType: () => detectAudioMimeType,
16233
16954
  detectImageMimeType: () => detectImageMimeType,
16234
16955
  discoverProviderAdapters: () => discoverProviderAdapters,
16956
+ discoverSkills: () => discoverSkills,
16235
16957
  extractMessageText: () => extractMessageText,
16236
16958
  extractRetryAfterMs: () => extractRetryAfterMs,
16237
16959
  filterByDepth: () => filterByDepth,
@@ -16274,15 +16996,21 @@ __export(index_exports, {
16274
16996
  iterationProgressHint: () => iterationProgressHint,
16275
16997
  listPresets: () => listPresets,
16276
16998
  listSubagents: () => listSubagents,
16999
+ loadSkillsFromDirectory: () => loadSkillsFromDirectory,
16277
17000
  normalizeMessageContent: () => normalizeMessageContent,
16278
17001
  parallelGadgetHint: () => parallelGadgetHint,
16279
17002
  parseDataUrl: () => parseDataUrl,
17003
+ parseFrontmatter: () => parseFrontmatter,
16280
17004
  parseManifest: () => parseManifest,
17005
+ parseMetadata: () => parseMetadata,
16281
17006
  parseRetryAfterHeader: () => parseRetryAfterHeader,
17007
+ parseSkillContent: () => parseSkillContent,
17008
+ parseSkillFile: () => parseSkillFile,
16282
17009
  randomDelay: () => randomDelay,
16283
17010
  resetFileLoggingState: () => resetFileLoggingState,
16284
17011
  resolveConfig: () => resolveConfig,
16285
17012
  resolveHintTemplate: () => resolveHintTemplate,
17013
+ resolveInstructions: () => resolveInstructions,
16286
17014
  resolveModel: () => resolveModel,
16287
17015
  resolvePromptTemplate: () => resolvePromptTemplate,
16288
17016
  resolveRateLimitConfig: () => resolveRateLimitConfig,
@@ -16297,9 +17025,12 @@ __export(index_exports, {
16297
17025
  resultWithImages: () => resultWithImages,
16298
17026
  resultWithMedia: () => resultWithMedia,
16299
17027
  runWithHandlers: () => runWithHandlers,
17028
+ scanResources: () => scanResources,
16300
17029
  schemaToJSONSchema: () => schemaToJSONSchema,
16301
17030
  stream: () => stream,
16302
17031
  stripProviderPrefix: () => stripProviderPrefix,
17032
+ substituteArguments: () => substituteArguments,
17033
+ substituteVariables: () => substituteVariables,
16303
17034
  text: () => text,
16304
17035
  timing: () => timing,
16305
17036
  toBase64: () => toBase64,
@@ -16307,13 +17038,14 @@ __export(index_exports, {
16307
17038
  validateAndApplyDefaults: () => validateAndApplyDefaults,
16308
17039
  validateGadgetParams: () => validateGadgetParams,
16309
17040
  validateGadgetSchema: () => validateGadgetSchema,
17041
+ validateMetadata: () => validateMetadata,
16310
17042
  withErrorHandling: () => withErrorHandling,
16311
17043
  withRetry: () => withRetry,
16312
17044
  withTimeout: () => withTimeout,
16313
- z: () => import_zod3.z
17045
+ z: () => import_zod4.z
16314
17046
  });
16315
17047
  module.exports = __toCommonJS(index_exports);
16316
- var import_zod3 = require("zod");
17048
+ var import_zod4 = require("zod");
16317
17049
  init_agent();
16318
17050
  init_builder();
16319
17051
  init_event_handlers();
@@ -16627,7 +17359,7 @@ function resultWithFile(result, fileData, mimeType, options) {
16627
17359
 
16628
17360
  // src/index.ts
16629
17361
  init_output_viewer();
16630
- init_parser();
17362
+ init_parser2();
16631
17363
  init_registry();
16632
17364
  init_typed_gadget();
16633
17365
  init_constants2();
@@ -16894,6 +17626,14 @@ var SimpleSessionManager = class extends BaseSessionManager {
16894
17626
  }
16895
17627
  };
16896
17628
 
17629
+ // src/skills/index.ts
17630
+ init_activation();
17631
+ init_loader();
17632
+ init_parser();
17633
+ init_registry2();
17634
+ init_skill();
17635
+ init_use_skill_gadget();
17636
+
16897
17637
  // src/utils/format.ts
16898
17638
  function truncate(text3, maxLength, suffix = "...") {
16899
17639
  if (text3.length <= maxLength) return text3;
@@ -17090,11 +17830,14 @@ function getHostExports2(ctx) {
17090
17830
  OpenRouterProvider,
17091
17831
  RateLimitTracker,
17092
17832
  SimpleSessionManager,
17833
+ Skill,
17834
+ SkillRegistry,
17093
17835
  SlidingWindowStrategy,
17094
17836
  StreamProcessor,
17095
17837
  SummarizationStrategy,
17096
17838
  TaskCompletionSignal,
17097
17839
  TimeoutException,
17840
+ USE_SKILL_GADGET_NAME,
17098
17841
  audioFromBase64,
17099
17842
  audioFromBuffer,
17100
17843
  collectEvents,
@@ -17112,10 +17855,12 @@ function getHostExports2(ctx) {
17112
17855
  createOpenAIProviderFromEnv,
17113
17856
  createOpenRouterProviderFromEnv,
17114
17857
  createSubagent,
17858
+ createUseSkillGadget,
17115
17859
  defaultLogger,
17116
17860
  detectAudioMimeType,
17117
17861
  detectImageMimeType,
17118
17862
  discoverProviderAdapters,
17863
+ discoverSkills,
17119
17864
  extractMessageText,
17120
17865
  extractRetryAfterMs,
17121
17866
  filterByDepth,
@@ -17158,15 +17903,21 @@ function getHostExports2(ctx) {
17158
17903
  iterationProgressHint,
17159
17904
  listPresets,
17160
17905
  listSubagents,
17906
+ loadSkillsFromDirectory,
17161
17907
  normalizeMessageContent,
17162
17908
  parallelGadgetHint,
17163
17909
  parseDataUrl,
17910
+ parseFrontmatter,
17164
17911
  parseManifest,
17912
+ parseMetadata,
17165
17913
  parseRetryAfterHeader,
17914
+ parseSkillContent,
17915
+ parseSkillFile,
17166
17916
  randomDelay,
17167
17917
  resetFileLoggingState,
17168
17918
  resolveConfig,
17169
17919
  resolveHintTemplate,
17920
+ resolveInstructions,
17170
17921
  resolveModel,
17171
17922
  resolvePromptTemplate,
17172
17923
  resolveRateLimitConfig,
@@ -17181,9 +17932,12 @@ function getHostExports2(ctx) {
17181
17932
  resultWithImages,
17182
17933
  resultWithMedia,
17183
17934
  runWithHandlers,
17935
+ scanResources,
17184
17936
  schemaToJSONSchema,
17185
17937
  stream,
17186
17938
  stripProviderPrefix,
17939
+ substituteArguments,
17940
+ substituteVariables,
17187
17941
  text,
17188
17942
  timing,
17189
17943
  toBase64,
@@ -17191,6 +17945,7 @@ function getHostExports2(ctx) {
17191
17945
  validateAndApplyDefaults,
17192
17946
  validateGadgetParams,
17193
17947
  validateGadgetSchema,
17948
+ validateMetadata,
17194
17949
  withErrorHandling,
17195
17950
  withRetry,
17196
17951
  withTimeout,