# Skill Hub (ClawHub) Compatibility

## Overview

PyClaw is fully compatible with OpenClaw's [ClawHub](https://clawhub.ai) skill ecosystem. Skills installed by either tool are available to both.

## What Is a Skill?

A skill is a directory containing `SKILL.md` — a Markdown file with YAML frontmatter:

```yaml
---
name: my-skill
description: "What this skill does and when to use it"
metadata:
  openclaw:
    emoji: "🔧"
    requires:
      bins: ["some-binary"]     # ALL must exist on PATH
      anyBins: ["alt1", "alt2"] # ANY must exist
      env: ["SOME_API_KEY"]     # Required env vars
    install:
      - kind: brew
        formula: "package-name"
      - kind: node
        package: "@scope/pkg"
      - kind: uv
        package: "httpie"
---

# Skill Instructions (Markdown)

These instructions are injected into the agent's system prompt...
```

Skills are NOT code — they are prompts (instructions for the AI agent). Language-agnostic.

## ClawHub API

Base URL: `https://clawhub.ai`

| Endpoint | Purpose |
|----------|---------|
| GET /api/v1/search?q=... | Search skills |
| GET /api/v1/skills/{slug} | Skill detail |
| GET /api/v1/download?slug=...&version=... | Download ZIP |
| GET /api/v1/skills | List all skills |

Auth: `Authorization: Bearer {token}` (from `CLAWHUB_TOKEN` env or `~/.config/clawhub/config.json`)

## Install Flow

1. GET `/api/v1/skills/{slug}` → get metadata + latest version
2. GET `/api/v1/download?slug={slug}&version={version}` → download ZIP
3. Extract ZIP, verify SKILL.md exists
4. Install to `{workspace}/skills/{slug}/`
5. Write `.clawhub/origin.json` (registry, slug, version, installedAt)
6. Update `.clawhub/lock.json` (workspace-level version tracking)

## Shared Directory

PyClaw reads from `~/.openclaw/skills/` — the same directory OpenClaw uses for managed skills. Skills installed by OpenClaw's `clawhub install` command are immediately available to PyClaw.

## Discovery Order (high → low priority)

PyClaw scans seven layered sources in priority order. When the same skill `name`
appears in multiple sources, the highest-priority source wins. The "closer to
user / project" → "further from user / vendor" axis is preserved at every
layer.

| # | Source | Default path | Tier |
|---|---|---|---|
| 1 | workspace | `{workspace}/skills/` | project |
| 2 | project-agents | `{workspace}/.agents/skills/` | project |
| 3 | project-claude | `{workspace}/.claude/skills/` | project |
| 4 | managed | `~/.openclaw/skills/` | user / team |
| 5 | personal-agents | `~/.agents/skills/` | personal |
| 6 | personal-claude | `~/.claude/skills/` | personal |
| 7 | bundled | `<package>/skills/` (none by default) | vendor |

Within each tier (project / personal), `.agents/skills/` wins over
`.claude/skills/`. The reasoning: `.claude/skills/` is the de facto cross-
ecosystem default — it's where Claude Code, Cursor 2.4+, OpenCode, Crush, and
DeepSeek-TUI place skills out of the box. `.agents/skills/` is the explicit
opt-in cross-ecosystem normalization, so when a user has both, treating their
explicit move as authoritative matches intent.

### Cross-ecosystem compatibility (Sprint 4')

PyClaw reads `~/.claude/skills/` and `{workspace}/.claude/skills/` natively.
Anything written for the [Anthropic Agent Skills v1.0](https://docs.anthropic.com/en/docs/agents-and-tools/agent-skills/overview)
SKILL.md spec works without modification — including the
[superpowers](https://github.com/obra/superpowers) skill library and any
project-local `.claude/skills/` directory checked into git.

Operators in regulated environments who do not want PyClaw reading
`.claude/skills/` paths can opt out via env var (no JSON edit required):

```bash
export PYCLAW_DISABLE_CLAUDE_SKILLS=1
```

When set, both `personal-claude` and `project-claude` sources are skipped
entirely. The other five sources continue to scan normally.

### Configuration

All seven path roots are configurable in `pyclaw.json`:

```jsonc
{
  "skills": {
    "workspace_skills_dir": "skills",
    "project_agents_skills_dir": ".agents/skills",
    "project_claude_skills_dir": ".claude/skills",
    "managed_skills_dir": "~/.openclaw/skills",
    "personal_agents_skills_dir": "~/.agents/skills",
    "personal_claude_skills_dir": "~/.claude/skills",
    "bundled_skills_dir": null
  }
}
```

## Prompt Injection Format

Skills are injected into the system prompt as XML:
```xml
<available_skills>
  <skill>
    <name>github</name>
    <description>GitHub CLI operations...</description>
    <location>~/.openclaw/skills/github/SKILL.md</location>
  </skill>
</available_skills>
```

The agent uses its `read` tool to load a skill's full content when it decides to use it.

## Compatibility Scope

| Compatible | Not Compatible |
|------------|---------------|
| family="skill" (Markdown) | family="code-plugin" (TypeScript) |
| SKILL.md format | bundle-plugin (TypeScript) |
| ClawHub REST API | OpenClaw extension system |
| Install specs (brew, node, uv, go, download) | TypeScript-specific tools |
| .clawhub/lock.json + origin.json | |
| Auth token sharing | |

## Lockfile Format

`.clawhub/lock.json`:
```json
{
  "version": 1,
  "skills": {
    "weather": { "version": "1.2.3", "installedAt": 1714500000000 }
  }
}
```

Per-skill `.clawhub/origin.json`:
```json
{
  "version": 1,
  "registry": "https://clawhub.ai",
  "slug": "weather",
  "installedVersion": "1.2.3",
  "installedAt": 1714500000000
}
```
