Skip to main content

Skill Generation

The Skill Generator transforms detected workflow patterns into spec-compliant SKILL.md files that work across multiple coding agents (Claude Code, Cursor, Codex, Aider, Windsurf).

Generation Pipeline

1

Generate Candidate

Create a SkillCandidate from a DetectedPattern with frontmatter, steps, and metadata
2

Render SKILL.md

Convert candidate to Markdown with YAML frontmatter and rich content sections
3

Save to Disk

Write atomically to ~/.claude/skills/auto/ with path safety validation
4

Update Lock File

Register skill in lock file for version tracking (optional)
5

Create Symlinks

Link to other installed agents for cross-agent skill sharing (optional)

SKILL.md Format

Generated skills follow the agentskills.io specification with YAML frontmatter:
---
name: read-and-edit-abc123
description: Workflow pattern: Read, Edit
version: 1.0.0
auto-generated: true
confidence: 0.85
occurrence-count: 5
source-sessions:
  - session-123
  - session-456
first-seen: 2026-03-01T10:00:00Z
last-seen: 2026-03-03T15:30:00Z
pattern-id: a1b2c3d4e5f6
created-at: 2026-03-03T16:00:00Z
allowed-tools:
  - Read
  - Edit
tags:
  - read
  - edit
  - refactor
compatible-agents:
  - claude-code
  - opencode
  - codex
source: auto-generated
derived-from: local-patterns
---

# read-and-edit-abc123

Workflow pattern: Read, Edit

## Steps

1. Read the file to understand its contents
2. Edit the file to make the necessary changes

## Generated by Auto-Skill v2

This skill was automatically detected from your usage patterns.
Confidence reflects how frequently and successfully this pattern was used.

SkillCandidate Type

The intermediate representation before saving:
// From types/index.ts:180-192
export interface SkillCandidate {
  name: string;                    // Sanitized kebab-case name
  description: string;             // Human-readable description
  steps: string[];                 // Numbered procedural steps
  outputPath: string;              // Absolute path to SKILL.md
  yamlFrontmatter: Record<string, unknown>;  // Full frontmatter object
  useFork: boolean;                // Whether to run in isolated context
  agentType: string | null;        // Recommended agent type
  allowedTools: string[];          // Tools this skill can use
  pattern: DetectedPattern;        // Original detected pattern
  v2Content?: Record<string, unknown> | null;  // Enhanced sections
}

Frontmatter Generation

Frontmatter includes V1 metadata, V2 enhancements, and hybrid Phase 3 mental context:
// From skill-generator.ts:451-485
const fm: Record<string, unknown> = {
  name,
  description: description.slice(0, 1024),  // Spec max
  version: "1.0.0",
  "auto-generated": true,
  confidence: Math.round(pattern.confidence * 100) / 100,
  "occurrence-count": pattern.occurrenceCount,
  "source-sessions": pattern.sessionIds.slice(0, 5),
  "first-seen": pattern.firstSeen,
  "last-seen": pattern.lastSeen,
  "pattern-id": pattern.id,
  "created-at": new Date().toISOString()
};

Step Generation

Steps are generated from the tool sequence using templates:
// From skill-generator.ts:24-35
const TOOL_STEP_TEMPLATES: Record<string, string> = {
  Read: "Read the file to understand its contents",
  Write: "Create/update the file with the required content",
  Edit: "Edit the file to make the necessary changes",
  Bash: "Run the required command",
  Grep: "Search for patterns in the codebase",
  Glob: "Find files matching the pattern",
  WebFetch: "Fetch content from the URL",
  WebSearch: "Search the web for information",
  Task: "Delegate to a specialized agent",
};
Enhanced Steps: When V2 problem-solving approach is available, steps are enriched with domain knowledge:
// TDD workflow gets detailed steps
[
  "1. Write a failing test that defines desired behavior (Write)",
  "2. Run tests to confirm the failure (Red) (Bash)",
  "3. Write minimal code to make the test pass (Green) (Edit)",
  "4. Run tests to confirm they pass (Bash)"
]

V2 Content Sections

V2 skills include rich contextual sections beyond basic steps:

Context Section

Explains when the workflow is appropriate:
## Context

This workflow is most appropriate when:

- You are tracking down and fixing bugs
- Working in these areas: api, database, auth
- Following a Debug-Systematic approach

Success rate in previous usage: 85%

Detected Patterns Section

Lists design patterns incorporated in the workflow:
## Detected Patterns

This workflow incorporates these design patterns:

### TDD (workflow, confidence: 85%)
- **Description:** Test-Driven Development workflow
- **When to use:** When building new features or fixing bugs
- **Benefits:** Better coverage, Refactoring confidence
- **Detected from:** Tool sequence: Write -> Bash -> Edit -> Bash

Code Structure Awareness Section

Shows key classes and functions involved:
## Code Structure Awareness

**Key Classes:**
- `PatternDetector` (src/core/pattern-detector.ts:185)
- `SequenceMatcher` (src/core/sequence-matcher.ts:29)

**Key Functions:**
- `detectPatterns` (src/core/pattern-detector.ts:487)
- `calculateConfidence` (src/core/pattern-detector.ts:130)

**Dependencies:**
- pattern-detector → sequence-matcher (import)
- pattern-detector → session-analyzer (import)

Execution Context

Skills can specify their execution context:

Fork Context

Isolated execution for tools with side effects:
context: fork
agent: general-purpose
Tools that suggest fork: Bash, Task

Agent Type

Recommended agent type based on tool set:
  • Read + GrepExplore
  • Read + TaskPlan
  • Read-only tools → Explore
  • Has Taskgeneral-purpose
// From skill-generator.ts:119-160
function determineAgentType(tools: string[]): string | null {
  const toolSet = new Set(tools);
  
  // Exact match against heuristics
  if (toolSet equals {"Read", "Grep"}) return "Explore";
  
  // Subset match
  if (toolSetREAD_ONLY_TOOLS) return "Explore";
  if (toolSet.has("Task")) return "general-purpose";
  
  return null;
}

Tag Generation

Tags are generated from multiple sources (capped at 10):
// From skill-generator.ts:181-229
function generateTags(pattern: DetectedPattern): string[] {
  const tags: string[] = [];
  
  // 1. Tool-based tags
  for (const tool of pattern.toolSequence) {
    tags.push(tool.toLowerCase().replace(/_/g, "-"));
  }
  
  // 2. Intent-based tags from session context
  if (pattern.sessionContext?.primary_intent) {
    tags.push(String(ctx.primary_intent));
  }
  
  // 3. Mental domain tags
  if (pattern.mentalContext?.domains) {
    for (const domain of domains.slice(0, 3)) {
      tags.push(domain.name.toLowerCase().replace(/ /g, "-"));
    }
  }
  
  // 4. Design pattern tags
  if (pattern.designPatterns) {
    for (const dp of pattern.designPatterns.slice(0, 2)) {
      tags.push(dp.name.toLowerCase().replace(/ /g, "-"));
    }
  }
  
  return tags.slice(0, 10);
}

Name Sanitization

Skill names are sanitized to be spec-compliant kebab-case:
import { sanitizeName } from "./path-security";

function generateSkillName(pattern: DetectedPattern): string {
  let rawName: string;
  if (pattern.suggestedName) {
    rawName = pattern.suggestedName;
  } else {
    const tools = pattern.toolSequence;
    rawName = tools.length >= 2
      ? `${tools[0].toLowerCase()}-${tools[tools.length - 1].toLowerCase()}-workflow`
      : `${tools[0].toLowerCase()}-workflow`;
  }
  
  // Append first 6 chars of pattern ID for uniqueness
  rawName = `${rawName}-${pattern.id.slice(0, 6)}`;
  return sanitizeName(rawName);  // Ensures kebab-case, alphanumeric + hyphens
}

Path Safety

All output paths are validated to prevent directory traversal attacks:
// From skill-generator.ts:712-733
import { isPathSafe } from "./path-security";

function saveSkill(candidate: SkillCandidate): string {
  const resolvedOut = path.resolve(outDir);
  
  // Ensure output directory exists
  fs.mkdirSync(resolvedOut, { recursive: true });
  
  // Ensure skill sub-directory exists
  const skillDir = path.dirname(candidate.outputPath);
  fs.mkdirSync(skillDir, { recursive: true });
  
  // Validate path is within allowed output directory
  if (!isPathSafe(candidate.outputPath, resolvedOut)) {
    throw new Error(
      `Unsafe skill path: ${candidate.outputPath} is not within ${resolvedOut}`
    );
  }
  
  // Write atomically
  writeFileAtomic(candidate.outputPath, content);
}

Atomic Writes

Skills are written using atomic file operations to prevent corruption:
import { writeFileAtomic } from "../util/atomic-write";

// Writes to temporary file first, then renames
// Prevents partial writes if process is interrupted
writeFileAtomic(candidatePath, content);

Usage Example

Complete workflow from detection to saved skill:
import { createPatternDetector } from "./core/pattern-detector";
import { createSkillGenerator } from "./core/skill-generator";
import { createEventStore } from "./core/event-store";

// 1. Detect patterns
const eventStore = createEventStore();
const eventSessions = eventStore.getEventsWithInputs();
const detector = createPatternDetector();
const patterns = detector.detectPatterns(eventSessions);

// 2. Generate skill candidates
const generator = createSkillGenerator();
const candidates = patterns
  .filter(p => p.confidence >= 0.7)
  .map(p => generator.generateCandidate(p));

// 3. Save skills to disk
for (const candidate of candidates) {
  const savedPath = generator.saveSkill(candidate, {
    updateLockFile: true,      // Update lock file
    createSymlinks: true       // Symlink to other agents
  });
  console.log(`Saved skill: ${savedPath}`);
}

// 4. List all generated skills
const allSkills = generator.listGeneratedSkills();
console.log(`Total skills: ${allSkills.length}`);
Generated skills can be symlinked to other installed agents:
import { createAgentRegistry } from "./agent-registry";

const registry = createAgentRegistry();
const current = registry.detectCurrentAgent();

// Creates symlinks to other agents' skill directories
registry.createSkillSymlinks(
  candidatePath,
  candidate.name,
  current?.id
);

// Example:
// ~/.claude/skills/auto/debug-systematic/ (original)
// ~/.cursor/skills/auto/debug-systematic/ (symlink)
// ~/.aider/skills/auto/debug-systematic/ (symlink)
Symlinks enable cross-agent skill sharing — a skill generated by Claude Code can be used by Cursor, Aider, or any other compatible agent.

Lock File Integration

Skills are registered in the lock file for version tracking:
import { createLockFile } from "./lock-file";

const lock = createLockFile();
lock.load();
lock.addSkill({
  name: candidate.name,
  path: candidatePath,
  content,
  source: "auto"  // auto | graduated | manual
});
lock.save();

API Reference

generateCandidate
function
Generate a skill candidate from a detected patternParameters:
  • pattern: DetectedPattern — The detected workflow pattern
  • options?: { forceFork?, forceAgent?, customAllowedTools? } — Optional overrides
Returns: SkillCandidate
saveSkill
function
Save a skill candidate to diskParameters:
  • candidate: SkillCandidate — The skill to save
  • options?: { updateLockFile?, createSymlinks? } — Optional flags
Returns: string — Absolute path to saved SKILL.md
renderSkillMd
function
Render a complete SKILL.md stringParameters:
  • name: string
  • description: string
  • steps: string[]
  • frontmatter: Record<string, unknown>
  • v2Content?: Record<string, unknown> | null
Returns: string — Formatted SKILL.md content
listGeneratedSkills
function
List all auto-generated skill file pathsReturns: string[] — Sorted array of absolute paths
deleteSkill
function
Delete an auto-generated skill by nameParameters:
  • name: string — Skill directory name
Returns: boolean — True if deleted

Next Steps

Pattern Detection

Learn how patterns are detected from tool usage

Session Analysis

Understand session context enrichment

Design Patterns

Explore recognized design patterns

CLI Overview

Learn about CLI commands

Build docs developers (and LLMs) love