Files
ajarbot/docs/SKILLS_INTEGRATION.md
Jordan Ramos a99799bf3d Initial commit: Ajarbot with optimizations
Features:
- Multi-platform bot (Slack, Telegram)
- Memory system with SQLite FTS
- Tool use capabilities (file ops, commands)
- Scheduled tasks system
- Dynamic model switching (/sonnet, /haiku)
- Prompt caching for cost optimization

Optimizations:
- Default to Haiku 4.5 (12x cheaper)
- Reduced context: 3 messages, 2 memory results
- Optimized SOUL.md (48% smaller)
- Automatic caching when using Sonnet (90% savings)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-13 19:06:28 -07:00

8.7 KiB

Skills Integration Guide for Ajarbot

This guide explains how to integrate local Claude Code skills into your ajarbot runtime, allowing users to invoke them from messaging platforms (Slack, Telegram, etc.).

🎯 Architecture

User (Slack/Telegram)
  ↓
  "Hey bot, /adapter-dev create Discord adapter"
  ↓
Runtime Preprocessor
  ↓
Skill Invoker → Load .claude/skills/adapter-dev/SKILL.md
  ↓
Agent (processes skill instructions + message)
  ↓
Response sent back to user

📁 File Structure

ajarbot/
├── .claude/
│   ├── skills/                    # Local skills (version controlled)
│   │   ├── adapter-dev/          # Example skill
│   │   │   ├── SKILL.md          # Main skill definition
│   │   │   └── examples/
│   │   │       └── usage.md
│   │   └── my-custom-skill/      # Your skills here
│   │       └── SKILL.md
│   └── SKILLS_README.md          # Skills documentation
├── adapters/
│   └── skill_integration.py      # Skill system integration
└── example_bot_with_skills.py    # Example with skills enabled

🚀 Quick Start

1. Skills are Already Set Up

Your project now has:

  • Skill directory: .claude/skills/adapter-dev/
  • Skill invoker: adapters/skill_integration.py
  • Example bot: example_bot_with_skills.py

2. Test Skills Locally (in Claude Code)

From the command line or in Claude Code:

/adapter-dev create a WhatsApp adapter

This will invoke the skill and Claude will help build the adapter.

3. Enable Skills in Your Bot

Option A: Use the example bot

python example_bot_with_skills.py

Option B: Add to your existing bot_runner.py

from adapters.skill_integration import SkillInvoker

# In BotRunner.setup(), after creating runtime:
skill_invoker = SkillInvoker()

def skill_preprocessor(message):
    if message.text.startswith("/"):
        parts = message.text.split(maxsplit=1)
        skill_name = parts[0][1:]
        args = parts[1] if len(parts) > 1 else ""

        if skill_name in skill_invoker.list_available_skills():
            skill_info = skill_invoker.get_skill_info(skill_name)
            skill_body = skill_info.get("body", "")
            message.text = skill_body.replace("$ARGUMENTS", args)

    return message

self.runtime.add_preprocessor(skill_preprocessor)

4. Use Skills from Messaging Platforms

From Slack:

@yourbot /adapter-dev create Discord adapter

@yourbot /skills

From Telegram:

/adapter-dev create Discord adapter

/skills

🛠️ Creating Your Own Skills

Example: Code Review Skill

mkdir -p .claude/skills/code-review

Create .claude/skills/code-review/SKILL.md:

---
name: code-review
description: Review code changes for quality and security
user-invocable: true
disable-model-invocation: true
allowed-tools: Read, Grep, Glob
context: fork
agent: Explore
---

# Code Review Skill

Review the following code changes: $ARGUMENTS

## Review checklist

1. **Security**: Check for vulnerabilities (SQL injection, XSS, etc.)
2. **Performance**: Identify potential bottlenecks
3. **Code Quality**: Review patterns and best practices
4. **Documentation**: Verify docstrings and comments
5. **Testing**: Suggest test cases

## Output format

Provide:
- Security findings (if any)
- Performance concerns
- Code quality issues
- Recommendations

Focus on actionable feedback.

Invoke from bot:

@bot /code-review adapters/slack/adapter.py

Example: Deploy Skill

---
name: deploy
description: Deploy the bot to production
user-invocable: true
disable-model-invocation: true
allowed-tools: Bash(git:*), Bash(docker:*)
---

# Deploy Skill

Deploy ajarbot to production environment: $ARGUMENTS

## Steps

1. Check git status - ensure working tree is clean
2. Run tests to verify everything passes
3. Build Docker image
4. Tag with version
5. Push to container registry
6. Update deployment manifest
7. Apply to production cluster

Confirm each step before proceeding.

🔐 Security Best Practices

1. Restrict Tool Access

In SKILL.md frontmatter:

allowed-tools: Read, Grep, Glob

This prevents the skill from:

  • Running arbitrary bash commands
  • Editing files
  • Making network requests

2. Disable Auto-Invocation

disable-model-invocation: true

This ensures only you (not Claude autonomously) can invoke the skill.

3. Run in Isolated Context

context: fork

Skill runs in a forked subagent, isolated from your main session.

4. Permission Allowlist

In .claude/settings.json:

{
  "permissions": {
    "allow": [
      "Skill(adapter-dev)",
      "Skill(code-review)",
      "Skill(deploy)"
    ],
    "deny": [
      "Skill(*)"  // Deny all other skills
    ]
  }
}

5. Version Control All Skills

git add .claude/skills/
git commit -m "Add code-review skill"

This allows team review before skills are used.

📊 Skill Arguments

Skills can receive arguments in multiple ways:

Positional Arguments

Invoke:

/my-skill arg1 arg2 arg3

Access in SKILL.md:

First arg: $0
Second arg: $1
All args: $ARGUMENTS

Named Arguments Pattern

Create a skill that parses flags:

---
name: smart-deploy
---

Parse deployment arguments: $ARGUMENTS

Expected format: --env <env> --version <ver>

Extract:
- Environment (--env): prod, staging, dev
- Version (--version): semver tag
- Optional flags: --dry-run, --rollback

Then execute deployment with extracted parameters.

Invoke:

/smart-deploy --env prod --version v1.2.3 --dry-run

🔧 Advanced Integration

Auto-Generate Skills from Code

from adapters.skill_integration import SkillInvoker
from pathlib import Path

def generate_adapter_skill(platform_name: str):
    """Auto-generate a skill for creating adapters."""
    skill_dir = Path(f".claude/skills/create-{platform_name}-adapter")
    skill_dir.mkdir(parents=True, exist_ok=True)

    skill_content = f"""---
name: create-{platform_name}-adapter
description: Create a new {platform_name} adapter
user-invocable: true
allowed-tools: Read, Write, Edit
---

Create a new {platform_name} messaging adapter for ajarbot.

1. Read existing adapters (Slack, Telegram) as templates
2. Create adapters/{platform_name}/adapter.py
3. Implement BaseAdapter interface
4. Add configuration template
5. Update bot_runner.py
"""

    (skill_dir / "SKILL.md").write_text(skill_content)
    print(f"✓ Generated skill: /create-{platform_name}-adapter")

# Usage
generate_adapter_skill("discord")
generate_adapter_skill("whatsapp")

Dynamic Skill Loading

def reload_skills(skill_invoker: SkillInvoker):
    """Hot-reload skills without restarting bot."""
    available = skill_invoker.list_available_skills()
    print(f"Reloaded {len(available)} skills: {', '.join(available)}")
    return available

Skill Metrics

from collections import Counter

skill_usage = Counter()

def tracked_skill_preprocessor(message):
    if message.text.startswith("/"):
        skill_name = message.text.split()[0][1:]
        skill_usage[skill_name] += 1
        print(f"[Metrics] Skill usage: {skill_usage}")
    return message

📝 Skill Best Practices

  1. Clear descriptions - User-facing help text
  2. Argument documentation - Explain expected format
  3. Error handling - Graceful failures
  4. Output format - Consistent structure
  5. Examples - Provide usage examples in examples/

🔍 Debugging Skills

Test skill locally

# In project root
python -c "from adapters.skill_integration import SkillInvoker; \
           si = SkillInvoker(); \
           print(si.get_skill_info('adapter-dev'))"

Validate skill syntax

# Check YAML frontmatter is valid
python -c "import yaml; \
           f = open('.claude/skills/adapter-dev/SKILL.md'); \
           content = f.read(); \
           parts = content.split('---'); \
           print(yaml.safe_load(parts[1]))"

📚 Resources

🎉 Summary

You now have:

Local skills stored in .claude/skills/ No registry dependencies - fully offline Version controlled - reviewed in PRs Invokable from bots - Slack, Telegram, etc. Secure by default - restricted tool access Team-shareable - consistent across developers

Next steps:

  1. Try /adapter-dev in Claude Code
  2. Test example_bot_with_skills.py
  3. Create your own custom skills
  4. Share skills with your team via git