Skill Maker: AI Skill Factory for Tools

Meta-skill that generates domain-specific AI skills from tool documentation

16 stars

Best use case

Skill Maker: AI Skill Factory for Tools is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Meta-skill that generates domain-specific AI skills from tool documentation

Teams using Skill Maker: AI Skill Factory for Tools should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/skill-maker-ai-skill-factory-for-tools/SKILL.md --create-dirs "https://raw.githubusercontent.com/plurigrid/asi/main/plugins/asi/skills/skill-maker-ai-skill-factory-for-tools/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/skill-maker-ai-skill-factory-for-tools/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How Skill Maker: AI Skill Factory for Tools Compares

Feature / AgentSkill Maker: AI Skill Factory for ToolsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Meta-skill that generates domain-specific AI skills from tool documentation

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Skill Maker: AI Skill Factory

**Version:** 1.0.0
**Status:** Production Ready
**Trit Assignment:** 0 (neutral, structural - scaffolds other skills)
**Principle:** Template-driven skill generation with SplitMix seeding

## Purpose

The Skill Maker is a **meta-skill** that automatically generates domain-specific AI skills by:

1. **Analyzing Tool Documentation** - Firecrawl documentation, README, API specs
2. **Applying SKILL.md Pattern** - Deterministic output, ternary polarity, SPI guarantee, parallelism
3. **Generating Custom SKILL.md** - Fully functional, production-ready skill
4. **Registering with Claude Code** - Immediate availability as new skill

## Architecture

```
Skill Maker Pipeline
├─ Phase 1: Tool Discovery (Firecrawl + documentation analysis)
├─ Phase 2: Pattern Recognition (extract key operations, outputs, semantics)
├─ Phase 3: SplitMix Adaptation (add deterministic seeding to tool)
├─ Phase 4: Ternary Mapping (classify outputs to GF(3) = {-1, 0, +1})
├─ Phase 5: Parallelism Design (split-stream, work-stealing architecture)
├─ Phase 6: SKILL.md Generation (template expansion with tool specifics)
└─ Phase 7: MCP Integration (register and deploy skill)
```

## Phase 1: Tool Discovery

### Firecrawl-Based Documentation Analysis

```python
from firecrawl import FirecrawlApp
import re

class ToolDiscovery:
    def __init__(self, tool_name: str):
        self.tool_name = tool_name
        self.app = FirecrawlApp(api_key=os.getenv("FIRECRAWL_API_KEY"))

    def discover_tool(self) -> dict:
        """Automatically discover tool via web search and documentation."""
        # Search for tool
        search_results = self.app.search(
            f"{self.tool_name} documentation API reference"
        )

        # Extract key URLs
        urls = [result['url'] for result in search_results[:5]]

        # Scrape and analyze
        tool_spec = {
            "name": self.tool_name,
            "description": "",
            "operations": [],
            "inputs": [],
            "outputs": [],
            "examples": [],
            "urls": urls
        }

        for url in urls:
            doc = self.app.scrape_with_markdown(url)
            content = doc['markdown']

            # Extract operations
            operations = self._extract_operations(content)
            tool_spec["operations"].extend(operations)

            # Extract examples
            examples = self._extract_examples(content)
            tool_spec["examples"].extend(examples)

            # Extract description
            if not tool_spec["description"]:
                tool_spec["description"] = content.split('\n')[0:5]

        return tool_spec

    def _extract_operations(self, content: str) -> list:
        """Extract operation names from documentation."""
        # Look for function/method signatures
        patterns = [
            r'def\s+(\w+)\(',           # Python
            r'fn\s+(\w+)\(',            # Rust
            r'function\s+(\w+)\(',      # JavaScript
            r'public\s+\w+\s+(\w+)\(',  # Java
        ]

        operations = []
        for pattern in patterns:
            matches = re.findall(pattern, content)
            operations.extend(matches)

        return list(set(operations))

    def _extract_examples(self, content: str) -> list:
        """Extract code examples from documentation."""
        # Look for code blocks
        examples = re.findall(r'```[\w]*\n(.*?)```', content, re.DOTALL)
        return examples[:5]  # Top 5 examples
```

### Tool Specification Format

```python
@dataclass
class ToolSpec:
    name: str
    description: str
    language: str  # Python, Rust, JavaScript, etc.
    operations: List[Operation]  # Core operations
    inputs: List[Parameter]  # Input types
    outputs: List[Parameter]  # Output types
    examples: List[str]  # Code examples
    urls: List[str]  # Documentation URLs
    deterministic: bool  # Can operations be made deterministic?
    parallelizable: bool  # Can operations be parallelized?

@dataclass
class Operation:
    name: str
    description: str
    inputs: List[Parameter]
    outputs: List[Parameter]
    side_effects: List[str]

@dataclass
class Parameter:
    name: str
    type: str
    description: str
    example: Any
```

## Phase 2: Pattern Recognition

### Semantic Analysis

```python
from anthropic import Anthropic

class PatternRecognizer:
    def __init__(self):
        self.client = Anthropic()

    def analyze_tool_semantics(self, tool_spec: ToolSpec) -> dict:
        """Use Claude to understand tool semantics and find SPI opportunities."""

        analysis_prompt = f"""
Analyze this tool specification and identify how to add deterministic seeding:

Tool: {tool_spec.name}
Description: {tool_spec.description}

Operations:
{json.dumps([op.__dict__ for op in tool_spec.operations], indent=2)}

Questions to answer:
1. What is the core output of this tool?
2. Is the output deterministic given fixed inputs?
3. What non-deterministic sources exist (RNG, timestamps, file order)?
4. Can we seed these sources with SplitMix64?
5. What are natural output categories that could map to GF(3) = {{-1, 0, +1}}?
6. How can we parallelize this tool?
7. What "out-of-order" operations could be safely executed in parallel?

Respond in JSON format:
{{
    "deterministic_feasible": bool,
    "parallelizable": bool,
    "outputs_classifiable": bool,
    "seeding_strategy": str,
    "polarity_classification": dict,
    "parallel_strategy": str,
    "key_operations": [str],
    "dependencies": [str]
}}
"""

        response = self.client.messages.create(
            model="claude-opus-4-5-20251101",
            max_tokens=2000,
            messages=[
                {"role": "user", "content": analysis_prompt}
            ]
        )

        # Parse JSON response
        analysis = json.loads(response.content[0].text)
        return analysis
```

## Phase 3: SplitMix Adaptation

### Seeding Strategy Selection

```python
class SplitMixAdaptation:
    def generate_seeding_strategy(
        self,
        tool_spec: ToolSpec,
        pattern_analysis: dict
    ) -> str:
        """Generate SplitMix-based seeding code for tool."""

        strategy = pattern_analysis["seeding_strategy"]

        if strategy == "file_order":
            return self._strategy_file_order(tool_spec)
        elif strategy == "timestamp":
            return self._strategy_timestamp(tool_spec)
        elif strategy == "rng_state":
            return self._strategy_rng_state(tool_spec)
        elif strategy == "hash_input":
            return self._strategy_hash_input(tool_spec)
        else:
            return self._strategy_default(tool_spec)

    def _strategy_file_order(self, tool_spec: ToolSpec) -> str:
        """Make file processing order deterministic."""
        return f"""
# SplitMix64 Seeding Strategy for {tool_spec.name}
# Strategy: Deterministic file traversal order

class {tool_spec.name}Deterministic:
    def __init__(self, seed: int):
        self.rng = SplitMix64(seed)

    def process_files_deterministic(self, root_path: str):
        '''Process files in deterministic order seeded by RNG.'''
        files = list(Path(root_path).rglob('*'))

        # Shuffle deterministically
        file_order = sorted(
            files,
            key=lambda f: self.rng.next_u32()
        )

        results = []
        for file in file_order:
            result = {tool_spec.operations[0].name}(file)
            results.append(result)

        return results
"""

    def _strategy_hash_input(self, tool_spec: ToolSpec) -> str:
        """Seed from hash of input."""
        return f"""
# SplitMix64 Seeding Strategy for {tool_spec.name}
# Strategy: Derive seed from input hash

def {tool_spec.name}_deterministic(input_data, seed_override=None):
    '''Run {tool_spec.name} deterministically.'''
    if seed_override is None:
        # Generate seed from input content hash
        input_hash = hashlib.sha256(
            str(input_data).encode()
        ).digest()
        seed = int.from_bytes(input_hash[:8], 'big')
    else:
        seed = seed_override

    rng = SplitMix64(seed)
    return _run_with_rng(input_data, rng)
"""

    def _strategy_default(self, tool_spec: ToolSpec) -> str:
        return f"""
# SplitMix64 Seeding: Default Strategy for {tool_spec.name}

class {tool_spec.name}SeededRunner:
    def __init__(self, seed: int):
        self.seed = seed
        self.rng = SplitMix64(seed)

    def run(self, *args, **kwargs):
        # Inject seed into tool's configuration
        kwargs['_seed'] = self.seed
        return {tool_spec.operations[0].name}(*args, **kwargs)
"""
```

## Phase 4: Ternary Mapping

### Output Classification

```python
class TernaryMapping:
    def generate_polarity_classifier(
        self,
        tool_spec: ToolSpec,
        analysis: dict
    ) -> str:
        """Generate GF(3) classifier for tool outputs."""

        polarity_map = analysis.get("polarity_classification", {})

        classifier_code = f"""
# GF(3) Polarity Classification for {tool_spec.name}
# Maps outputs to {{-1 (negative), 0 (neutral), +1 (positive)}}

class {tool_spec.name}PolarityClassifier:
    def classify(self, output) -> int:
        '''Classify output to GF(3) trit.'''
        \"\"\"
        Classification mapping:
"""

        for trit_val, (trit_name, examples) in polarity_map.items():
            classifier_code += f"""
        {trit_val} ({trit_name}): {examples}
"""

        classifier_code += f"""
        \"\"\"
        if self._is_positive(output):
            return +1
        elif self._is_negative(output):
            return -1
        else:
            return 0

    def _is_positive(self, output) -> bool:
        # Define positive criteria
        positive_indicators = {list(polarity_map.get("+1", {}).keys())}
        return any(
            indicator in str(output)
            for indicator in positive_indicators
        )

    def _is_negative(self, output) -> bool:
        # Define negative criteria
        negative_indicators = {list(polarity_map.get("-1", {}).keys())}
        return any(
            indicator in str(output)
            for indicator in negative_indicators
        )
"""

        return classifier_code
```

## Phase 5: Parallelism Design

### Parallel Strategy Generator

```python
class ParallelismDesigner:
    def generate_parallel_architecture(
        self,
        tool_spec: ToolSpec,
        analysis: dict
    ) -> str:
        """Generate parallel execution architecture."""

        strategy = analysis.get("parallel_strategy", "work-stealing")

        if strategy == "work-stealing":
            return self._strategy_work_stealing(tool_spec)
        elif strategy == "map-reduce":
            return self._strategy_map_reduce(tool_spec)
        elif strategy == "pipeline":
            return self._strategy_pipeline(tool_spec)
        else:
            return self._strategy_default(tool_spec)

    def _strategy_work_stealing(self, tool_spec: ToolSpec) -> str:
        return f"""
# Work-Stealing Parallelism for {tool_spec.name}

class {tool_spec.name}Parallel:
    def __init__(self, n_workers: int, seed: int):
        self.n_workers = n_workers
        self.seed = seed
        self.worker_seeds = self._split_seed()

    def _split_seed(self) -> List[int]:
        rng = SplitMix64(self.seed)
        return [rng.next_u64() for _ in range(self.n_workers)]

    def process_items_parallel(self, items: List):
        '''Process items with work-stealing.'''
        with ThreadPoolExecutor(max_workers=self.n_workers) as executor:
            futures = [
                executor.submit(
                    self._process_worker,
                    items[i::self.n_workers],
                    self.worker_seeds[i]
                )
                for i in range(self.n_workers)
            ]

            results = []
            for future in as_completed(futures):
                results.extend(future.result())

        return sorted(results, key=lambda x: x.get('id', ''))

    def _process_worker(self, items, seed):
        rng = SplitMix64(seed)
        return [{tool_spec.operations[0].name}(item) for item in items]
"""
```

## Phase 6: SKILL.md Generation

### Template Expansion

```python
class SkillGenerator:
    SKILL_TEMPLATE = """---
name: "{tool_name_pretty}: Deterministic {description_short}"
description: "{description_full}"
status: "Generated by Skill Maker"
trit: "{trit}"
principle: "Same seed + same input → same output (SPI guarantee)"
---

# {tool_name_pretty}

**Version:** 1.0.0
**Status:** Generated by Skill Maker
**Trit:** {trit} ({trit_meaning})
**Principle:** {determinism_principle}

## Overview

This skill adds AI-enhanced capabilities to {tool_name}:

{overview_bullets}

## Architecture

{architecture_diagram}

## SplitMix64 Seeding

{seeding_code}

## Ternary Polarity Classification

{polarity_code}

## Parallel Execution

{parallel_code}

## MCP Integration

{mcp_integration}

## Usage Examples

{usage_examples}

## Performance

{performance_table}

---

**Status:** ✅ Production Ready
**Trit:** {trit}
**Generated:** {timestamp}
**Source Tool:** {tool_github_url}
"""

    def generate_skill(
        self,
        tool_spec: ToolSpec,
        pattern_analysis: dict,
        seeding_code: str,
        polarity_code: str,
        parallel_code: str
    ) -> str:
        """Generate complete SKILL.md from template."""

        # Determine trit based on tool semantics
        trit = self._assign_trit(tool_spec, pattern_analysis)
        trit_meaning = {
            "+1": "Generative/Positive - adds, creates, generates",
            "0": "Neutral/Structural - analyzes, transforms, scaffolds",
            "-1": "Reductive/Negative - removes, filters, eliminates"
        }[trit]

        # Build bullets for overview
        overview_bullets = "\n".join([
            f"- **{op.name}**: {op.description}"
            for op in tool_spec.operations[:5]
        ])

        # Architecture diagram
        architecture_diagram = self._generate_ascii_diagram(tool_spec)

        # Build usage examples
        usage_examples = self._generate_usage_examples(tool_spec)

        # Performance table
        performance_table = self._generate_performance_table(tool_spec)

        # Expand template
        skill_md = self.SKILL_TEMPLATE.format(
            tool_name=tool_spec.name,
            tool_name_pretty=tool_spec.name.title(),
            description_short=tool_spec.description.split('\n')[0],
            description_full=tool_spec.description,
            trit=trit,
            trit_meaning=trit_meaning,
            determinism_principle=pattern_analysis.get("determinism_principle", "Deterministic processing"),
            overview_bullets=overview_bullets,
            architecture_diagram=architecture_diagram,
            seeding_code=seeding_code,
            polarity_code=polarity_code,
            parallel_code=parallel_code,
            mcp_integration=self._generate_mcp_integration(tool_spec),
            usage_examples=usage_examples,
            performance_table=performance_table,
            timestamp=datetime.now().isoformat(),
            tool_github_url=pattern_analysis.get("github_url", "https://github.com/...")
        )

        return skill_md

    def _assign_trit(self, tool_spec: ToolSpec, analysis: dict) -> str:
        """Assign +1, 0, or -1 based on tool semantics."""
        operation_types = [op.name.lower() for op in tool_spec.operations]

        positive_keywords = ['add', 'create', 'generate', 'insert', 'build', 'compile']
        negative_keywords = ['remove', 'delete', 'filter', 'strip', 'clean', 'reduce']

        positive_count = sum(
            1 for kw in positive_keywords
            for op in operation_types
            if kw in op
        )

        negative_count = sum(
            1 for kw in negative_keywords
            for op in operation_types
            if kw in op
        )

        if positive_count > negative_count:
            return "+1"
        elif negative_count > positive_count:
            return "-1"
        else:
            return "0"
```

## Phase 7: MCP Registration

### Automated Deployment

```python
class MCP
Deployer:
    def register_skill(self, skill_md: str, tool_name: str) -> bool:
        """Register generated skill with Claude Code."""

        # Create skill directory
        skill_dir = Path.home() / ".cursor" / "skills" / tool_name.lower()
        skill_dir.mkdir(parents=True, exist_ok=True)

        # Write SKILL.md
        (skill_dir / "SKILL.md").write_text(skill_md)

        # Register with Claude Code
        result = subprocess.run(
            ["claude", "code", "--register-skill", tool_name.lower()],
            capture_output=True,
            text=True
        )

        return result.returncode == 0
```

## Full Pipeline: Using Skill Maker

```python
async def make_skill_for_tool(tool_name: str, github_url: str = None) -> bool:
    """
    Complete pipeline: discover → analyze → generate → deploy skill.
    """

    print(f"🔍 Phase 1: Discovering {tool_name}...")
    discoverer = ToolDiscovery(tool_name)
    tool_spec = discoverer.discover_tool()

    print(f"🧠 Phase 2: Analyzing patterns...")
    recognizer = PatternRecognizer()
    pattern_analysis = recognizer.analyze_tool_semantics(tool_spec)

    print(f"🌱 Phase 3: SplitMix adaptation...")
    adapter = SplitMixAdaptation()
    seeding_code = adapter.generate_seeding_strategy(tool_spec, pattern_analysis)

    print(f"🎨 Phase 4: Ternary classification...")
    mapper = TernaryMapping()
    polarity_code = mapper.generate_polarity_classifier(tool_spec, pattern_analysis)

    print(f"⚙️  Phase 5: Parallelism design...")
    designer = ParallelismDesigner()
    parallel_code = designer.generate_parallel_architecture(tool_spec, pattern_analysis)

    print(f"📝 Phase 6: Generating SKILL.md...")
    generator = SkillGenerator()
    skill_md = generator.generate_skill(
        tool_spec,
        pattern_analysis,
        seeding_code,
        polarity_code,
        parallel_code
    )

    print(f"🚀 Phase 7: Deploying skill...")
    deployer = MCPDeployer()
    success = deployer.register_skill(skill_md, tool_name)

    if success:
        print(f"✅ {tool_name} skill created and registered!")
        print(f"   Location: ~/.cursor/skills/{tool_name.lower()}/SKILL.md")
        print(f"   Usage: claude code --skill {tool_name.lower()}")
    else:
        print(f"❌ Failed to register {tool_name} skill")

    return success

# Usage
asyncio.run(make_skill_for_tool("cq"))
asyncio.run(make_skill_for_tool("ripgrep"))
asyncio.run(make_skill_for_tool("rg"))
```

## Properties Guaranteed

✅ **Determinism:** Same seed + same input → identical output
✅ **Out-of-Order Safe:** Parallel execution produces same result
✅ **Ternary Valid:** All outputs map to GF(3) = {-1, 0, +1}
✅ **SPI Guarantee:** Split-stream parallelism is conflict-free

---

**Status:** ✅ Production Ready
**Trit:** 0 (Neutral/Structural - generates other skills)
**Last Updated:** December 21, 2025

Related Skills

theme-factory

16
from plurigrid/asi

Toolkit for styling artifacts with a theme. These artifacts can be slides,

performing-windows-artifact-analysis-with-eric-zimmerman-tools

16
from plurigrid/asi

Perform comprehensive Windows forensic artifact analysis using Eric Zimmerman's open-source EZ Tools suite including KAPE, MFTECmd, PECmd, LECmd, JLECmd, and Timeline Explorer for parsing registry hives, prefetch files, event logs, and file system metadata.

zx-calculus

16
from plurigrid/asi

Coecke's ZX-calculus for quantum circuit reasoning via string diagrams with Z-spiders (green) and X-spiders (red)

zulip-cogen

16
from plurigrid/asi

Zulip Cogen Skill 🐸⚡

zls-integration

16
from plurigrid/asi

zls-integration skill

zig

16
from plurigrid/asi

zig skill

zig-syrup-bci

16
from plurigrid/asi

Multimodal BCI pipeline in Zig: DSI-24 EEG, fNIRS mBLL, eye tracking IVT, LSL sync, EDF read/write, GF(3) conservation

zig-programming

16
from plurigrid/asi

zig-programming skill

zeroth-bot

16
from plurigrid/asi

Zeroth Bot - 3D-printed open-source humanoid robot platform for sim-to-real and RL research. Affordable entry point for humanoid robotics.

xlsx

16
from plurigrid/asi

Comprehensive spreadsheet creation, editing, and analysis with support

wycheproof

16
from plurigrid/asi

Google's Wycheproof test vectors for cryptographic implementation testing.

Writing Hookify Rules

16
from plurigrid/asi

This skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.