@agentforge/skills 0.16.56 → 0.16.58

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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { z } from 'zod';
2
1
  import { Tool } from '@agentforge/core';
2
+ import { z } from 'zod';
3
3
 
4
4
  /**
5
5
  * Skill System Types
@@ -299,26 +299,6 @@ declare function scanSkillRoot(rootPath: string): SkillCandidate[];
299
299
  */
300
300
  declare function scanAllSkillRoots(skillRoots: string[]): SkillCandidate[];
301
301
 
302
- /**
303
- * Skill Activation Tools
304
- *
305
- * Provides `activate-skill` and `read-skill-resource` tools built with
306
- * the AgentForge tool builder API. These tools enable agents to load
307
- * skill instructions on demand and access skill resources at runtime.
308
- *
309
- * @see https://agentskills.io/specification
310
- *
311
- * @example
312
- * ```ts
313
- * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);
314
- * // activateSkill — load full SKILL.md body
315
- * // readSkillResource — load a resource file from a skill
316
- *
317
- * // Or use the convenience method:
318
- * const [activateSkill, readSkillResource] = registry.toActivationTools();
319
- * ```
320
- */
321
-
322
302
  declare const activateSkillSchema: z.ZodObject<{
323
303
  name: z.ZodString;
324
304
  }, "strip", z.ZodTypeAny, {
@@ -336,6 +316,18 @@ declare const readSkillResourceSchema: z.ZodObject<{
336
316
  name: string;
337
317
  path: string;
338
318
  }>;
319
+
320
+ /**
321
+ * Create the `activate-skill` tool bound to a registry instance.
322
+ *
323
+ * Resolves the skill by name, reads the full SKILL.md file, and returns
324
+ * the body content (below frontmatter).
325
+ *
326
+ * @param registry - The SkillRegistry to resolve skills from
327
+ * @returns An AgentForge Tool
328
+ */
329
+ declare function createActivateSkillTool(registry: SkillRegistry): Tool<z.infer<typeof activateSkillSchema>, string>;
330
+
339
331
  /**
340
332
  * Resolve a resource path within a skill root, blocking path traversal.
341
333
  *
@@ -350,16 +342,7 @@ declare function resolveResourcePath(skillPath: string, resourcePath: string): {
350
342
  success: false;
351
343
  error: string;
352
344
  };
353
- /**
354
- * Create the `activate-skill` tool bound to a registry instance.
355
- *
356
- * Resolves the skill by name, reads the full SKILL.md file, and returns
357
- * the body content (below frontmatter).
358
- *
359
- * @param registry - The SkillRegistry to resolve skills from
360
- * @returns An AgentForge Tool
361
- */
362
- declare function createActivateSkillTool(registry: SkillRegistry): Tool<z.infer<typeof activateSkillSchema>, string>;
345
+
363
346
  /**
364
347
  * Create the `read-skill-resource` tool bound to a registry instance.
365
348
  *
@@ -370,6 +353,27 @@ declare function createActivateSkillTool(registry: SkillRegistry): Tool<z.infer<
370
353
  * @returns An AgentForge Tool
371
354
  */
372
355
  declare function createReadSkillResourceTool(registry: SkillRegistry): Tool<z.infer<typeof readSkillResourceSchema>, string>;
356
+
357
+ /**
358
+ * Skill Activation Tools
359
+ *
360
+ * Provides `activate-skill` and `read-skill-resource` tools built with
361
+ * the AgentForge tool builder API. These tools enable agents to load
362
+ * skill instructions on demand and access skill resources at runtime.
363
+ *
364
+ * @see https://agentskills.io/specification
365
+ *
366
+ * @example
367
+ * ```ts
368
+ * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);
369
+ * // activateSkill — load full SKILL.md body
370
+ * // readSkillResource — load a resource file from a skill
371
+ *
372
+ * // Or use the convenience method:
373
+ * const [activateSkill, readSkillResource] = registry.toActivationTools();
374
+ * ```
375
+ */
376
+
373
377
  /**
374
378
  * Create both skill activation tools bound to a registry instance.
375
379
  *
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { z } from 'zod';
2
1
  import { Tool } from '@agentforge/core';
2
+ import { z } from 'zod';
3
3
 
4
4
  /**
5
5
  * Skill System Types
@@ -299,26 +299,6 @@ declare function scanSkillRoot(rootPath: string): SkillCandidate[];
299
299
  */
300
300
  declare function scanAllSkillRoots(skillRoots: string[]): SkillCandidate[];
301
301
 
302
- /**
303
- * Skill Activation Tools
304
- *
305
- * Provides `activate-skill` and `read-skill-resource` tools built with
306
- * the AgentForge tool builder API. These tools enable agents to load
307
- * skill instructions on demand and access skill resources at runtime.
308
- *
309
- * @see https://agentskills.io/specification
310
- *
311
- * @example
312
- * ```ts
313
- * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);
314
- * // activateSkill — load full SKILL.md body
315
- * // readSkillResource — load a resource file from a skill
316
- *
317
- * // Or use the convenience method:
318
- * const [activateSkill, readSkillResource] = registry.toActivationTools();
319
- * ```
320
- */
321
-
322
302
  declare const activateSkillSchema: z.ZodObject<{
323
303
  name: z.ZodString;
324
304
  }, "strip", z.ZodTypeAny, {
@@ -336,6 +316,18 @@ declare const readSkillResourceSchema: z.ZodObject<{
336
316
  name: string;
337
317
  path: string;
338
318
  }>;
319
+
320
+ /**
321
+ * Create the `activate-skill` tool bound to a registry instance.
322
+ *
323
+ * Resolves the skill by name, reads the full SKILL.md file, and returns
324
+ * the body content (below frontmatter).
325
+ *
326
+ * @param registry - The SkillRegistry to resolve skills from
327
+ * @returns An AgentForge Tool
328
+ */
329
+ declare function createActivateSkillTool(registry: SkillRegistry): Tool<z.infer<typeof activateSkillSchema>, string>;
330
+
339
331
  /**
340
332
  * Resolve a resource path within a skill root, blocking path traversal.
341
333
  *
@@ -350,16 +342,7 @@ declare function resolveResourcePath(skillPath: string, resourcePath: string): {
350
342
  success: false;
351
343
  error: string;
352
344
  };
353
- /**
354
- * Create the `activate-skill` tool bound to a registry instance.
355
- *
356
- * Resolves the skill by name, reads the full SKILL.md file, and returns
357
- * the body content (below frontmatter).
358
- *
359
- * @param registry - The SkillRegistry to resolve skills from
360
- * @returns An AgentForge Tool
361
- */
362
- declare function createActivateSkillTool(registry: SkillRegistry): Tool<z.infer<typeof activateSkillSchema>, string>;
345
+
363
346
  /**
364
347
  * Create the `read-skill-resource` tool bound to a registry instance.
365
348
  *
@@ -370,6 +353,27 @@ declare function createActivateSkillTool(registry: SkillRegistry): Tool<z.infer<
370
353
  * @returns An AgentForge Tool
371
354
  */
372
355
  declare function createReadSkillResourceTool(registry: SkillRegistry): Tool<z.infer<typeof readSkillResourceSchema>, string>;
356
+
357
+ /**
358
+ * Skill Activation Tools
359
+ *
360
+ * Provides `activate-skill` and `read-skill-resource` tools built with
361
+ * the AgentForge tool builder API. These tools enable agents to load
362
+ * skill instructions on demand and access skill resources at runtime.
363
+ *
364
+ * @see https://agentskills.io/specification
365
+ *
366
+ * @example
367
+ * ```ts
368
+ * const [activateSkill, readSkillResource] = createSkillActivationTools(registry);
369
+ * // activateSkill — load full SKILL.md body
370
+ * // readSkillResource — load a resource file from a skill
371
+ *
372
+ * // Or use the convenience method:
373
+ * const [activateSkill, readSkillResource] = registry.toActivationTools();
374
+ * ```
375
+ */
376
+
373
377
  /**
374
378
  * Create both skill activation tools bound to a registry instance.
375
379
  *
package/dist/index.js CHANGED
@@ -211,6 +211,65 @@ function scanAllSkillRoots(skillRoots) {
211
211
  });
212
212
  return allCandidates;
213
213
  }
214
+ function extractBody(content) {
215
+ return matter(content).content.trim();
216
+ }
217
+ var activateSkillSchema = z.object({
218
+ name: z.string().describe('The name of the skill to activate (e.g., "code-review")')
219
+ });
220
+ var readSkillResourceSchema = z.object({
221
+ name: z.string().describe("The name of the skill that owns the resource"),
222
+ path: z.string().describe('Relative path to the resource file within the skill directory (e.g., "references/GUIDE.md", "scripts/setup.sh")')
223
+ });
224
+ var activationLogger = createLogger("agentforge:skills:activation", {
225
+ level: LogLevel.INFO
226
+ });
227
+ function buildMissingSkillMessage(registry, name) {
228
+ const availableNames = registry.getNames();
229
+ const suggestion = availableNames.length > 0 ? ` Available skills: ${availableNames.join(", ")}` : " No skills are currently registered.";
230
+ return {
231
+ availableCount: availableNames.length,
232
+ errorMessage: `Skill "${name}" not found.${suggestion}`
233
+ };
234
+ }
235
+
236
+ // src/activation-activate-tool.ts
237
+ function createActivateSkillTool(registry) {
238
+ return new ToolBuilder().name("activate-skill").description(
239
+ "Activate an Agent Skill by name, loading its full instructions. Returns the complete SKILL.md body content for the named skill. Use this when you see a relevant skill in <available_skills> and want to follow its instructions."
240
+ ).category(ToolCategory.SKILLS).tags(["skill", "activation", "agent-skills"]).schema(activateSkillSchema).implement(async ({ name }) => {
241
+ const skill = registry.get(name);
242
+ if (!skill) {
243
+ const { availableCount, errorMessage } = buildMissingSkillMessage(registry, name);
244
+ activationLogger.warn("Skill activation failed \u2014 not found", { name, availableCount });
245
+ return errorMessage;
246
+ }
247
+ const skillMdPath = resolve(skill.skillPath, "SKILL.md");
248
+ try {
249
+ const content = readFileSync(skillMdPath, "utf-8");
250
+ const body = extractBody(content);
251
+ activationLogger.info("Skill activated", {
252
+ name: skill.metadata.name,
253
+ skillPath: skill.skillPath,
254
+ bodyLength: body.length
255
+ });
256
+ registry.emitEvent("skill:activated" /* SKILL_ACTIVATED */, {
257
+ name: skill.metadata.name,
258
+ skillPath: skill.skillPath,
259
+ bodyLength: body.length
260
+ });
261
+ return body;
262
+ } catch (error) {
263
+ const message = error instanceof Error ? error.message : String(error);
264
+ activationLogger.error("Skill activation failed \u2014 read error", {
265
+ name,
266
+ skillPath: skill.skillPath,
267
+ error: message
268
+ });
269
+ return `Failed to read skill "${name}" instructions: ${message}`;
270
+ }
271
+ }).build();
272
+ }
214
273
 
215
274
  // src/trust.ts
216
275
  var SCRIPT_PATH_PREFIX = "scripts/";
@@ -272,16 +331,6 @@ function evaluateTrustPolicy(resourcePath, trustLevel, allowUntrustedScripts = f
272
331
  };
273
332
  }
274
333
  }
275
-
276
- // src/activation.ts
277
- var logger2 = createLogger("agentforge:skills:activation", { level: LogLevel.INFO });
278
- var activateSkillSchema = z.object({
279
- name: z.string().describe('The name of the skill to activate (e.g., "code-review")')
280
- });
281
- var readSkillResourceSchema = z.object({
282
- name: z.string().describe("The name of the skill that owns the resource"),
283
- path: z.string().describe('Relative path to the resource file within the skill directory (e.g., "references/GUIDE.md", "scripts/setup.sh")')
284
- });
285
334
  function resolveResourcePath(skillPath, resourcePath) {
286
335
  if (isAbsolute(resourcePath)) {
287
336
  return { success: false, error: "Absolute resource paths are not allowed" };
@@ -307,59 +356,21 @@ function resolveResourcePath(skillPath, resourcePath) {
307
356
  }
308
357
  return { success: true, resolvedPath };
309
358
  }
310
- function createActivateSkillTool(registry) {
311
- return new ToolBuilder().name("activate-skill").description(
312
- "Activate an Agent Skill by name, loading its full instructions. Returns the complete SKILL.md body content for the named skill. Use this when you see a relevant skill in <available_skills> and want to follow its instructions."
313
- ).category(ToolCategory.SKILLS).tags(["skill", "activation", "agent-skills"]).schema(activateSkillSchema).implement(async ({ name }) => {
314
- const skill = registry.get(name);
315
- if (!skill) {
316
- const availableNames = registry.getNames();
317
- const suggestion = availableNames.length > 0 ? ` Available skills: ${availableNames.join(", ")}` : " No skills are currently registered.";
318
- const errorMsg = `Skill "${name}" not found.${suggestion}`;
319
- logger2.warn("Skill activation failed \u2014 not found", { name, availableCount: availableNames.length });
320
- return errorMsg;
321
- }
322
- const skillMdPath = resolve(skill.skillPath, "SKILL.md");
323
- try {
324
- const content = readFileSync(skillMdPath, "utf-8");
325
- const body = extractBody(content);
326
- logger2.info("Skill activated", {
327
- name: skill.metadata.name,
328
- skillPath: skill.skillPath,
329
- bodyLength: body.length
330
- });
331
- registry.emitEvent("skill:activated" /* SKILL_ACTIVATED */, {
332
- name: skill.metadata.name,
333
- skillPath: skill.skillPath,
334
- bodyLength: body.length
335
- });
336
- return body;
337
- } catch (error) {
338
- const errorMsg = `Failed to read skill "${name}" instructions: ${error instanceof Error ? error.message : String(error)}`;
339
- logger2.error("Skill activation failed \u2014 read error", {
340
- name,
341
- skillPath: skill.skillPath,
342
- error: error instanceof Error ? error.message : String(error)
343
- });
344
- return errorMsg;
345
- }
346
- }).build();
347
- }
359
+
360
+ // src/activation-resource-tool.ts
348
361
  function createReadSkillResourceTool(registry) {
349
362
  return new ToolBuilder().name("read-skill-resource").description(
350
363
  "Read a resource file from an activated Agent Skill. Returns the content of a file within the skill directory (e.g., references/, scripts/, assets/). The path must be relative to the skill root and cannot traverse outside it."
351
364
  ).category(ToolCategory.SKILLS).tags(["skill", "resource", "agent-skills"]).schema(readSkillResourceSchema).implement(async ({ name, path: resourcePath }) => {
352
365
  const skill = registry.get(name);
353
366
  if (!skill) {
354
- const availableNames = registry.getNames();
355
- const suggestion = availableNames.length > 0 ? ` Available skills: ${availableNames.join(", ")}` : " No skills are currently registered.";
356
- const errorMsg = `Skill "${name}" not found.${suggestion}`;
357
- logger2.warn("Skill resource load failed \u2014 skill not found", { name, resourcePath });
358
- return errorMsg;
367
+ const { errorMessage } = buildMissingSkillMessage(registry, name);
368
+ activationLogger.warn("Skill resource load failed \u2014 skill not found", { name, resourcePath });
369
+ return errorMessage;
359
370
  }
360
371
  const pathResult = resolveResourcePath(skill.skillPath, resourcePath);
361
372
  if (!pathResult.success) {
362
- logger2.warn("Skill resource load blocked \u2014 path traversal", {
373
+ activationLogger.warn("Skill resource load blocked \u2014 path traversal", {
363
374
  name,
364
375
  resourcePath,
365
376
  error: pathResult.error
@@ -372,7 +383,7 @@ function createReadSkillResourceTool(registry) {
372
383
  registry.getAllowUntrustedScripts()
373
384
  );
374
385
  if (!policyDecision.allowed) {
375
- logger2.warn("Skill resource load blocked \u2014 trust policy", {
386
+ activationLogger.warn("Skill resource load blocked \u2014 trust policy", {
376
387
  name,
377
388
  resourcePath,
378
389
  trustLevel: skill.trustLevel,
@@ -389,7 +400,7 @@ function createReadSkillResourceTool(registry) {
389
400
  return policyDecision.message;
390
401
  }
391
402
  if (policyDecision.reason !== "not-script" /* NOT_SCRIPT */) {
392
- logger2.info("Skill resource trust policy \u2014 allowed", {
403
+ activationLogger.info("Skill resource trust policy \u2014 allowed", {
393
404
  name,
394
405
  resourcePath,
395
406
  trustLevel: skill.trustLevel,
@@ -404,7 +415,7 @@ function createReadSkillResourceTool(registry) {
404
415
  }
405
416
  try {
406
417
  const content = readFileSync(pathResult.resolvedPath, "utf-8");
407
- logger2.info("Skill resource loaded", {
418
+ activationLogger.info("Skill resource loaded", {
408
419
  name: skill.metadata.name,
409
420
  resourcePath,
410
421
  resolvedPath: pathResult.resolvedPath,
@@ -418,26 +429,25 @@ function createReadSkillResourceTool(registry) {
418
429
  });
419
430
  return content;
420
431
  } catch (error) {
421
- const errorMsg = `Failed to read resource "${resourcePath}" from skill "${name}": ${error instanceof Error ? error.message : String(error)}`;
422
- logger2.warn("Skill resource load failed \u2014 file not found or unreadable", {
432
+ const message = error instanceof Error ? error.message : String(error);
433
+ activationLogger.warn("Skill resource load failed \u2014 file not found or unreadable", {
423
434
  name,
424
435
  resourcePath,
425
- error: error instanceof Error ? error.message : String(error)
436
+ error: message
426
437
  });
427
- return errorMsg;
438
+ return `Failed to read resource "${resourcePath}" from skill "${name}": ${message}`;
428
439
  }
429
440
  }).build();
430
441
  }
442
+
443
+ // src/activation.ts
431
444
  function createSkillActivationTools(registry) {
432
445
  return [
433
446
  createActivateSkillTool(registry),
434
447
  createReadSkillResourceTool(registry)
435
448
  ];
436
449
  }
437
- function extractBody(content) {
438
- return matter(content).content.trim();
439
- }
440
- var logger3 = createLogger("agentforge:skills:registry", { level: LogLevel.INFO });
450
+ var logger2 = createLogger("agentforge:skills:registry", { level: LogLevel.INFO });
441
451
  function discoverSkills(config, skills, rootTrustMap, emit) {
442
452
  skills.clear();
443
453
  rootTrustMap.clear();
@@ -461,7 +471,7 @@ function discoverSkills(config, skills, rootTrustMap, emit) {
461
471
  rootPath: candidate.rootPath,
462
472
  error: result.error
463
473
  });
464
- logger3.warn("Skipping invalid skill", {
474
+ logger2.warn("Skipping invalid skill", {
465
475
  skillPath: candidate.skillPath,
466
476
  ...result.error ? { error: result.error } : {}
467
477
  });
@@ -484,7 +494,7 @@ function discoverSkills(config, skills, rootTrustMap, emit) {
484
494
  duplicateOf: existing.skillPath,
485
495
  error: warningMessage
486
496
  });
487
- logger3.warn("Duplicate skill name, keeping first", {
497
+ logger2.warn("Duplicate skill name, keeping first", {
488
498
  name: skill.metadata.name,
489
499
  kept: existing.skillPath,
490
500
  skipped: candidate.skillPath
@@ -494,13 +504,13 @@ function discoverSkills(config, skills, rootTrustMap, emit) {
494
504
  skills.set(skill.metadata.name, skill);
495
505
  successCount++;
496
506
  emit("skill:discovered" /* SKILL_DISCOVERED */, skill);
497
- logger3.debug("Skill discovered", {
507
+ logger2.debug("Skill discovered", {
498
508
  name: skill.metadata.name,
499
509
  description: skill.metadata.description.slice(0, 80),
500
510
  skillPath: skill.skillPath
501
511
  });
502
512
  }
503
- logger3.info("Skill registry populated", {
513
+ logger2.info("Skill registry populated", {
504
514
  rootsScanned: config.skillRoots.length,
505
515
  skillsDiscovered: successCount,
506
516
  warnings: warningCount
@@ -510,7 +520,7 @@ function discoverSkills(config, skills, rootTrustMap, emit) {
510
520
  function recordScanError(scanErrors, path, error) {
511
521
  scanErrors.push({ path, error });
512
522
  }
513
- var logger4 = createLogger("agentforge:skills:registry", { level: LogLevel.INFO });
523
+ var logger3 = createLogger("agentforge:skills:registry", { level: LogLevel.INFO });
514
524
  function addRegistryEventHandler(eventHandlers, event, handler) {
515
525
  if (!eventHandlers.has(event)) {
516
526
  eventHandlers.set(event, /* @__PURE__ */ new Set());
@@ -532,7 +542,7 @@ function emitRegistryEvent(eventHandlers, event, data) {
532
542
  try {
533
543
  handler(data);
534
544
  } catch (error) {
535
- logger4.error("Skill event handler error", {
545
+ logger3.error("Skill event handler error", {
536
546
  event,
537
547
  error: error instanceof Error ? error.message : String(error),
538
548
  ...error instanceof Error && error.stack ? { stack: error.stack } : {}
@@ -540,10 +550,10 @@ function emitRegistryEvent(eventHandlers, event, data) {
540
550
  }
541
551
  });
542
552
  }
543
- var logger5 = createLogger("agentforge:skills:registry", { level: LogLevel.INFO });
553
+ var logger4 = createLogger("agentforge:skills:registry", { level: LogLevel.INFO });
544
554
  function generateSkillPrompt(config, allSkills, totalDiscovered, options) {
545
555
  if (!config.enabled) {
546
- logger5.debug("Skill prompt generation skipped (disabled)", {
556
+ logger4.debug("Skill prompt generation skipped (disabled)", {
547
557
  enabled: config.enabled ?? false
548
558
  });
549
559
  return "";
@@ -557,7 +567,7 @@ function generateSkillPrompt(config, allSkills, totalDiscovered, options) {
557
567
  skills = skills.slice(0, config.maxDiscoveredSkills);
558
568
  }
559
569
  if (skills.length === 0) {
560
- logger5.debug("Skill prompt generation produced empty result", {
570
+ logger4.debug("Skill prompt generation produced empty result", {
561
571
  totalDiscovered,
562
572
  filterApplied: !!(options?.skills && options.skills.length > 0),
563
573
  ...config.maxDiscoveredSkills !== void 0 ? { maxCap: config.maxDiscoveredSkills } : {}
@@ -568,7 +578,7 @@ function generateSkillPrompt(config, allSkills, totalDiscovered, options) {
568
578
  ${skills.map(renderSkillEntry).join("\n")}
569
579
  </available_skills>`;
570
580
  const estimatedTokens = Math.ceil(xml.length / 4);
571
- logger5.info("Skill prompt generated", {
581
+ logger4.info("Skill prompt generated", {
572
582
  skillCount: skills.length,
573
583
  totalDiscovered,
574
584
  filterApplied: !!(options?.skills && options.skills.length > 0),