Skip to content

@agentforge/skills

The skills package provides SKILL.md-driven capability loading for agents. Skills are discovered from configurable directories and activated at runtime through tool calls.

Installation

bash
pnpm add @agentforge/core @agentforge/skills

@agentforge/core is a peer dependency of @agentforge/skills and must be installed alongside it.

TIP

For a step-by-step tutorial, see Building a Skill-Powered Agent. For usage patterns, see Agent Skills Examples.

SkillRegistry

Central registry that discovers, indexes, and provides access to SKILL.md-based skills.

typescript
import { SkillRegistry } from '@agentforge/skills';

const registry = new SkillRegistry({
  skillRoots: [
    { path: './.agentskills', trust: 'workspace' },
  ],
  enabled: true,
});

Constructor Options — SkillRegistryConfig

PropertyTypeDefaultDescription
skillRootsArray<string | SkillRootConfig>requiredDirectories to scan for skills
enabledbooleanfalseGates generatePrompt() output
maxDiscoveredSkillsnumberundefinedCap on skills included in prompt
allowUntrustedScriptsbooleanfalseAllow script access from untrusted roots

SkillRootConfig

PropertyTypeDescription
pathstringDirectory path to scan
trustTrustLevel'workspace' | 'trusted' | 'untrusted'

Plain string roots default to { path: value, trust: 'untrusted' }.

Query Methods

MethodReturnsDescription
get(name)Skill | undefinedGet a skill by name
getAll()Skill[]Get all discovered skills
has(name)booleanCheck if a skill exists
size()numberNumber of discovered skills
getNames()string[]Array of all skill names
getScanErrors()ReadonlyArray<{ path: string; error: string }>Errors from last scan
getAllowedTools(name)string[] | undefinedGet allowed-tools list for a skill
getAllowUntrustedScripts()booleanWhether untrusted script override is set

generatePrompt(options?)

Generates an <available_skills> XML block for the LLM system prompt.

typescript
// All skills
const prompt = registry.generatePrompt();

// Filtered subset
const prompt = registry.generatePrompt({ skills: ['code-review'] });

SkillPromptOptions:

PropertyTypeDescription
skillsstring[]Optional subset of skill names to include

Returns an empty string when enabled is false or no skills match.

toActivationTools()

Returns a tuple of two tools pre-wired to the registry instance:

typescript
const [activateSkill, readSkillResource] = registry.toActivationTools();
ToolSchemaDescription
activate-skill{ name: string }Loads the full SKILL.md body content for a skill
read-skill-resource{ name: string, path: string }Reads a resource file from a skill directory

Both tools are in the ToolCategory.SKILLS category.

discover()

Re-scans all configured roots and rebuilds the registry. Called automatically during construction.

typescript
registry.discover(); // Rescan after installing new skills

Event Methods

MethodSignatureDescription
on(event, handler)(SkillRegistryEvent, (data: unknown) => void) => voidSubscribe to event
off(event, handler)(SkillRegistryEvent, (data: unknown) => void) => voidUnsubscribe
emitEvent(event, data)(SkillRegistryEvent, unknown) => voidEmit an event (used by activation tools)

SkillRegistryEvent

Enum of events emitted by the registry and activation tools.

EventString ValuePayload Shape
SKILL_DISCOVERED'skill:discovered'Skill object
SKILL_WARNING'skill:warning'{ skillPath, rootPath, error, duplicateOf? }
SKILL_ACTIVATED'skill:activated'{ name, skillPath, bodyLength }
SKILL_RESOURCE_LOADED'skill:resource-loaded'{ name, resourcePath, resolvedPath, contentLength }
TRUST_POLICY_DENIED'trust:policy-denied'{ name, resourcePath, trustLevel, reason, message }
TRUST_POLICY_ALLOWED'trust:policy-allowed'{ name, resourcePath, trustLevel, reason }

TrustLevel

typescript
type TrustLevel = 'workspace' | 'trusted' | 'untrusted';
LevelReference FilesScript FilesUse Case
workspaceFirst-party project skills
trustedVetted community/team skills
untrustedUnknown or unreviewed sources

TrustPolicyReason

Enum returned in trust policy decisions for audit logging.

ReasonWhen
NOT_SCRIPTResource is not in scripts/ — always allowed
WORKSPACE_TRUSTRoot has workspace trust — scripts allowed
TRUSTED_ROOTRoot has trusted trust — scripts allowed
UNTRUSTED_SCRIPT_DENIEDUntrusted root, no override — scripts blocked
UNTRUSTED_SCRIPT_ALLOWEDUntrusted root but allowUntrustedScripts: true
UNKNOWN_TRUST_LEVELUnknown trust level — treated as denied

Skill Type

typescript
interface Skill {
  metadata: SkillMetadata;
  skillPath: string;      // Absolute path to skill directory
  rootPath: string;       // Which configured root this was discovered from
  trustLevel: TrustLevel;
}

SkillMetadata

typescript
interface SkillMetadata {
  name: string;                       // 1-64 chars, kebab-case, matches directory name
  description: string;                // 1-1024 chars
  license?: string;                   // SPDX identifier
  compatibility?: string[];           // Compatible frameworks
  metadata?: Record<string, unknown>; // Arbitrary key-value pairs
  allowedTools?: string[];            // Tools the skill is designed to use
}

Utility Functions

FunctionSignatureDescription
createActivateSkillTool(registry)(SkillRegistry) => ToolCreate standalone activate-skill tool
createReadSkillResourceTool(registry)(SkillRegistry) => ToolCreate standalone read-skill-resource tool
createSkillActivationTools(registry)(SkillRegistry) => [Tool, Tool]Create both tools as a tuple
resolveResourcePath(skillDir, resourcePath)(string, string) => { success: true; resolvedPath: string } | { success: false; error: string }Validate and resolve a resource path (returns discriminated union)
evaluateTrustPolicy(resourcePath, trustLevel, allowUntrustedScripts?)(...) => TrustPolicyDecisionEvaluate whether a resource access is allowed
isScriptResource(resourcePath)(string) => booleanCheck if path targets scripts/ directory
normalizeRootConfig(root)(string | SkillRootConfig) => SkillRootConfigNormalize string to root config
parseSkillContent(content, dirName)(string, string) => SkillParseResultParse SKILL.md content and validate
validateSkillName(name)(string) => SkillValidationError[]Validate skill name format
scanSkillRoot(rootPath)(string) => SkillCandidate[]Scan a directory for skill candidates
scanAllSkillRoots(roots)(string[]) => SkillCandidate[]Scan multiple root directories

Type Definitions

All exports include full TypeScript definitions. See the source code for complete type information.

Released under the MIT License.