Skill: tdavis009/clawhub-skill-guide (version 1.0.0)

--- name: clawhub-skill-guide description: > Create, structure, and publish OpenClaw skills to ClawHub that pass the security scanner with clean ratings. Covers frontmatter schema, env var declarations, script safety, config change patterns, and the full publish workflow. Use when: creating a new skill, publishing to ClawHub, fixing security scan warnings, structuring skill files, writing SKILL.md frontmatter, declaring environment variables, understanding scanner categories, preparing scripts for publication. --- # ClawHub Skill Guide Publish OpenClaw skills to ClawHub with clean security scanner ratings. This guide supplements the built-in `skill-creator` skill with ClawHub-specific publishing knowledge — especially frontmatter schema and scanner compliance. > **Note:** The built-in `skill-creator` says "Do not include any other fields > in YAML frontmatter." That guidance is outdated. ClawHub supports and the > scanner **requires** additional fields like `env`, `metadata`, `requires`, etc. > This guide documents the complete frontmatter schema. --- ## Quick Reference ### Skill Anatomy ``` my-skill/ ├── SKILL.md # Core instructions (required, under 500 lines) ├── scripts/ # Executable code (optional) ├── references/ # Docs loaded on demand (optional) └── assets/ # Templates, images, non-context files (optional) ``` ### Frontmatter Fields | Field | Required | Purpose | |-------|----------|---------| | `name` | ✅ | Lowercase, hyphens, under 64 chars | | `description` | ✅ | Trigger text with keywords | | `env` | When credentials needed | Array of env var declarations | | `metadata` | Alternative env format | OpenClaw-specific metadata | | `requires` | When dependencies exist | Human-readable requirement list | | `homepage` | Optional | Source/docs URL | | `category` | Optional | Skill category | | `emoji` | Optional | Display emoji | | `version` | Optional | Semver (can also set via CLI) | → Full schema: [references/frontmatter-schema.md](references/frontmatter-schema.md) ### Scanner Categories | # | Category | Key Requirement | |---|----------|-----------------| | 1 | PURPOSE & CAPABILITY | Description matches functionality; credentials declared | | 2 | INSTRUCTION SCOPE | Instructions on-topic; no auto-config language | | 3 | INSTALL MECHANISM | No external downloads; scripts write within workspace | | 4 | CREDENTIALS | All env vars declared in frontmatter; sensitive marked | | 5 | PERSISTENCE & PRIVILEGE | No always:true; config as templates for manual review | → Deep dive: [references/scanner-compliance.md](references/scanner-compliance.md) --- ## Creating a Skill ### Step 1: Plan Structure Decide what goes where: | Content Type | Location | |-------------|----------| | Core workflow, key instructions | SKILL.md body | | Detailed reference material | `references/` | | Executable automation | `scripts/` | | Templates, images, boilerplate | `assets/` | Keep SKILL.md under 500 lines. Move detailed docs to references. ### Step 2: Write Frontmatter This is where most scanner issues originate. Get frontmatter right first. **Important:** The local packager (`package_skill.py`) only allows these top-level frontmatter keys: `name`, `description`, `license`, `metadata`, `allowed-tools`. The `env:` key works on ClawHub's registry but fails local validation. Use the `metadata.openclaw` format for compatibility with both. **Minimal frontmatter (no credentials needed):** ```yaml --- name: my-skill description: > What this skill does. Include trigger keywords so the agent knows when to activate it. Use when: scenario1, scenario2. --- ``` **With credentials (packager-compatible format):** ```yaml --- name: my-api-skill description: > Integrates with Example API for data retrieval and analysis. Use when: querying example data, generating reports from Example API. metadata: openclaw: requires: env: - EXAMPLE_API_KEY bins: - curl primaryEnv: EXAMPLE_API_KEY env: - name: EXAMPLE_API_KEY description: "API key for Example service" required: true - name: EXAMPLE_BASE_URL description: "Base URL for Example API (default: https://api.example.com)" required: false --- ``` **Note:** If you skip the local packager and publish directly with `npx clawhub publish`, the direct `env:` top-level array also works (some published skills use this). But the `metadata.openclaw` format works everywhere. → All supported fields and formats: [references/frontmatter-schema.md](references/frontmatter-schema.md) ### Step 3: Write Body Structure the body for progressive disclosure: 1. **Quick Start** — Minimal steps to use the skill 2. **Prerequisites** — Table of requirements (if any) 3. **Security Notes** — Script safety, credential handling (if applicable) 4. **How It Works** — Core instructions 5. **File Reference** — List bundled resources with descriptions Keep instructions imperative. Challenge every paragraph: "Does the agent really need this?" ### Step 4: Add Scripts (If Needed) Follow safe patterns to pass the scanner: - Only write within the skill workspace - No network calls unless explicitly declared and justified - No obfuscated code - Document line count and purpose in SKILL.md - Include "inspect before running" warning → Full patterns: [references/script-safety.md](references/script-safety.md) ### Step 5: Validate and Package ```bash # Validate structure python3 ~/.npm-global/lib/node_modules/openclaw/skills/skill-creator/scripts/package_skill.py ./my-skill # Check manually: # - Frontmatter has name + description # - env declarations match actual credential usage # - No personal data or test artifacts # - SKILL.md under 500 lines ``` ### Step 6: Publish and Check Scanner ```bash # Verify auth npx clawhub whoami # Publish npx clawhub publish ./my-skill \ --slug my-skill \ --name "My Skill" \ --version 1.0.0 \ --changelog "Initial release" \ --tags latest # Check scanner results npx clawhub inspect my-skill ``` → Full workflow: [references/publish-workflow.md](references/publish-workflow.md) --- ## Frontmatter Quick Guide ### The Three Env Declaration Formats ClawHub supports three ways to declare environment variables. All are valid; the `metadata.openclaw` format is recommended for compatibility with both the local packager and the ClawHub scanner. **Format 1 — Direct `env:` array (richest data, but fails local packager):** ```yaml env: - name: MY_API_KEY description: "API key for the service" required: true sensitive: true ``` Works with `npx clawhub publish` but NOT with `package_skill.py` validation. **Format 2 — `metadata.openclaw.env` (recommended — works everywhere):** ```yaml metadata: openclaw: env: - name: MY_API_KEY description: "API key for the service" required: false ``` **Format 3 — `metadata.openclaw.requires`:** ```yaml metadata: openclaw: requires: env: - MY_API_KEY bins: - curl primaryEnv: MY_API_KEY ``` Format 1 gives the scanner the most information (including `sensitive` flag) and produces the cleanest scan results. ### Description Best Practices The description is the primary trigger mechanism. Include: - What the skill does (concrete actions) - Keywords matching user queries - "Use when:" clause listing activation scenarios **Bad:** `"Helps with APIs."` **Good:** ```yaml description: > Query and manage Example API resources including users, projects, and billing data. Generates reports, monitors usage, and handles authentication. Use when: querying Example API, generating usage reports, managing API resources, checking billing status. ``` --- ## Scanner Compliance Quick Guide ### 1. PURPOSE & CAPABILITY ✓ - Description accurately reflects what the skill does - All credentials declared in frontmatter `env` or `metadata` - No undeclared external service dependencies ### 2. INSTRUCTION SCOPE ✓ - Instructions stay on-topic for the skill's stated purpose - No language about automatically applying config changes - Privileged operations marked as "requires manual review" - If using `requireMention:false`, document data exposure implications ### 3. INSTALL MECHANISM ✓ - No `curl`, `wget`, or network downloads in scripts - Scripts only write within the skill workspace directory - Include "inspect before running" notes for all scripts - No obfuscated or minified executable code ### 4. CREDENTIALS ✓ - Every env var the skill uses is declared in frontmatter - Sensitive credentials marked `sensitive: true` - No requests for credentials unrelated to the skill's purpose - Prerequisites table lists all required accounts/keys ### 5. PERSISTENCE & PRIVILEGE ✓ - No `always:true` in config recommendations - Config changes presented as templates for manual review - Multi-user skills recommend agent isolation (separate OpenClaw agent) - No persistent background processes or daemons → Deep dive with case study: [references/scanner-compliance.md](references/scanner-compliance.md) --- ## Publishing ### Command Reference ```bash # Publish a skill npx clawhub publish ./skill-dir \ --slug my-skill \ --name "Display Name" \ --version 1.0.0 \ --changelog "What changed" \ --tags latest # Inspect published skill npx clawhub inspect my-skill npx clawhub inspect my-skill --files npx clawhub inspect my-skill --file SKILL.md # Browse and search npx clawhub explore npx clawhub search "keyword" # Auth npx clawhub whoami ``` ### Version Bumping When fixing scanner warnings, bump the version and republish: ```bash npx clawhub publish ./skill-dir \ --slug my-skill \ --version 1.1.0 \ --changelog "Fix: declared env vars in frontmatter for clean scan" \ --tags latest ``` --- ## Common Pitfalls | Mistake | Scanner Impact | Fix | |---------|---------------|-----| | No env declarations when skill uses credentials | ! CREDENTIALS | Add env vars via `metadata.openclaw.env` in frontmatter | | "Agent automatically applies config" language | ! INSTRUCTION SCOPE | Change to "manual review required" | | Scripts without inspection warning | ℹ INSTALL MECHANISM | Add "inspect before running" note | | No agent isolation for multi-user skills | ℹ PERSISTENCE | Add security model section | | `requireMention:false` without data exposure docs | ℹ INSTRUCTION SCOPE | Document what data the skill sees | | Description too short / missing keywords | Poor discoverability | Expand with trigger scenarios | | Shipping test DBs or generated files | Bloat | Clean before publishing | | Personal data in examples | Privacy risk | Use generic examples | --- ## Templates Ready-to-use SKILL.md templates: - [Basic skill](assets/templates/basic-skill.md) — Minimal SKILL.md - [Skill with scripts](assets/templates/skill-with-scripts.md) — Scripts + env vars - [Skill with config](assets/templates/skill-with-config.md) — Gateway config changes Copy, fill in the placeholders, publish. --- ## File Reference | File | Purpose | |------|---------| | `references/frontmatter-schema.md` | Complete YAML frontmatter field documentation | | `references/scanner-compliance.md` | Scanner categories deep dive with case study | | `references/script-safety.md` | Safe script patterns for publication | | `references/publish-workflow.md` | Step-by-step publish and iterate workflow | | `assets/templates/basic-skill.md` | Minimal SKILL.md template | | `assets/templates/skill-with-scripts.md` | Template with scripts and env vars | | `assets/templates/skill-with-config.md` | Template for config-changing skills |

path: assets/templates/basic-skill.md
content: ---
name: SKILL_NAME
description: >
  DESCRIPTION of what this skill does. Include specific trigger keywords
  and scenarios. Use when: scenario1, scenario2, scenario3.
env: []
---

# Skill Title

Brief overview of what this skill provides.

## Quick Start

Step-by-step instructions for the most common use case.

1. Step one
2. Step two
3. Step three

## How It Works

Core instructions and workflows. Keep under 500 lines total.

## File Reference

| File | Purpose |
|------|---------|
| `SKILL.md` | Core instructions (this file) |


path: assets/templates/skill-with-config.md
content: ---
name: SKILL_NAME
description: >
  DESCRIPTION of what this skill does. Include specific trigger keywords
  and scenarios. Use when: scenario1, scenario2, scenario3.
metadata:
  openclaw:
    env:
      - name: ENV_VAR_NAME
        description: "What this environment variable is for"
        required: false
---

# Skill Title

Brief overview of what this skill provides.

## Prerequisites

**All config changes require manual review. Nothing is applied automatically.**

| Requirement | Details |
|-------------|---------|
| Discord bot token | Configured in your OpenClaw gateway (not stored by this skill) |
| Guild (server) | You create or choose the server. You provide the guild ID. |
| Gateway admin access | You manually review and apply config changes |
| `ENV_VAR_NAME` | Optional. Description of this variable. |

## Security Notes

- All gateway config changes are **generated as templates for your review**
- No config is applied automatically by this skill
- Scripts only write within the skill workspace directory
- Scripts make no network calls and contain no obfuscation
- **Inspect scripts before running**

## Security Model

The agent using this skill MUST run as a **separate OpenClaw agent** with
restricted permissions:

- `tools.fs.workspaceOnly: true` — can only read/write within skill workspace
- `tools.exec.security: "deny"` — cannot execute shell commands
- `tools.deny` list blocking all unnecessary tools
- `tools.profile: "messaging"` — only messaging + web search

This ensures:
- No access to the owner's personal files, messages, or other agents
- No ability to send emails, read calendars, or access other services
- Even if a user attempts prompt injection, there is nothing to exfiltrate

## Config Template

**Review and apply manually** via your gateway configuration.

**Agent entry** (add to `agents.list` array):
```json
{
  "id": "skill-agent",
  "name": "Skill Agent",
  "workspace": "/path/to/skill/workspace",
  "model": { "primary": "anthropic/claude-sonnet-4-6" },
  "tools": {
    "profile": "messaging",
    "deny": ["exec", "process", "nodes", "cron", "gateway", "browser",
             "canvas", "sessions_spawn", "sessions_send", "memory_search"],
    "exec": { "security": "deny" },
    "fs": { "workspaceOnly": true }
  }
}
```

**Binding entry** (add to `bindings` BEFORE catch-all):
```json
{ "agentId": "skill-agent", "match": { "channel": "discord", "guildId": "YOUR_GUILD_ID" } }
```

**Guild entry** (safe to merge via `config.patch`):
```json
{ "channels": { "discord": { "guilds": { "YOUR_GUILD_ID": { "requireMention": true, "channels": { "*": { "allow": true } } } } } } }
```

**Important:** `agents.list` and `bindings` are arrays — `config.patch` replaces
them entirely. Include ALL existing agents/bindings plus the new entries.

## Quick Start

1. Review prerequisites and set environment variables
2. Review and apply the config template above (manual review required)
3. Start using the skill in the configured channel

## How It Works

Core instructions and workflows.

## File Reference

| File | Purpose |
|------|---------|
| `SKILL.md` | Core instructions (this file) |


path: assets/templates/skill-with-scripts.md
content: ---
name: SKILL_NAME
description: >
  DESCRIPTION of what this skill does. Include specific trigger keywords
  and scenarios. Use when: scenario1, scenario2, scenario3.
metadata:
  openclaw:
    requires:
      env:
        - ENV_VAR_NAME
      bins: []
    primaryEnv: ENV_VAR_NAME
    env:
      - name: ENV_VAR_NAME
        description: "What this environment variable is for"
        required: true
      - name: OPTIONAL_CONFIG_VAR
        description: "Optional configuration value (default: some-default)"
        required: false
---

# Skill Title

Brief overview of what this skill provides.

## Prerequisites

| Requirement | Details |
|-------------|---------|
| `ENV_VAR_NAME` | Required. Obtain from Example service dashboard. |
| `OPTIONAL_CONFIG_VAR` | Optional. Defaults to `some-default` if not set. |

## Security Notes

The included scripts (`scripts/setup.sh`, `scripts/run.py`) only create files
within the skill workspace. They make no network calls and write no files
outside the skill directory. **Inspect them before running** — both are plain
code with no obfuscation.

## Bundled Scripts

| Script | Purpose | Lines |
|--------|---------|-------|
| `scripts/setup.sh` | Creates workspace directory structure | ~25 |
| `scripts/run.py` | Core processing logic | ~80 |

## Quick Start

1. Set required environment variable: `export ENV_VAR_NAME="your-value"`
2. Run setup: `bash scripts/setup.sh`
3. Execute: `python3 scripts/run.py`

## How It Works

Core instructions and workflows.

## File Reference

| File | Purpose |
|------|---------|
| `SKILL.md` | Core instructions (this file) |
| `scripts/setup.sh` | Workspace initialization |
| `scripts/run.py` | Core processing logic |


path: references/frontmatter-schema.md
content: # Frontmatter Schema Reference

Complete documentation of every YAML frontmatter field supported by ClawHub.

> **Important:** The built-in `skill-creator` skill says "Do not include any
> other fields in YAML frontmatter." This is outdated. ClawHub supports all
> fields documented here, and the scanner checks several of them.

---

## Required Fields

### `name`

- **Type:** string
- **Required:** Yes
- **Rules:** Lowercase letters, digits, hyphens only. Under 64 characters.
- **Scanner check:** Must be present and valid.

```yaml
# Good
name: my-api-skill

# Bad — uppercase, spaces
name: My API Skill
```

### `description`

- **Type:** string (multi-line recommended)
- **Required:** Yes
- **Scanner check:** Must be present and substantive. Short or vague descriptions
  may trigger ℹ on PURPOSE & CAPABILITY.

The description serves as the primary trigger mechanism. Include:
- Concrete actions the skill performs
- Keywords users would use when they need this skill
- "Use when:" clause listing activation scenarios

```yaml
# Good
description: >
  Query and manage EVE Online market data, character skills, and
  corporation assets via the ESI API. Supports real-time price lookups,
  skill queue management, and asset inventory. Use when: checking EVE
  market prices, managing character skills, querying corporation data,
  working with EVE ESI endpoints.

# Bad — too vague, no trigger keywords
description: "Helps with EVE stuff."
```

---

## Environment Variable Fields

Three formats exist. All are recognized by the ClawHub registry scanner.

**Compatibility note:** The local packager (`package_skill.py`) only allows
these top-level keys: `name`, `description`, `license`, `metadata`, `allowed-tools`.
The direct `env:` key works when publishing directly with `npx clawhub publish`
but fails local `package_skill.py` validation. Use Format 2 or 3 (under `metadata`)
for full compatibility with both the local packager and the registry scanner.

### Format 1: `env` (Recommended)

- **Type:** array of objects
- **Required:** When the skill uses any credentials or configurable values
- **Scanner check:** PURPOSE & CAPABILITY and CREDENTIALS categories both verify
  that referenced env vars are declared here.

Each object supports:

| Property | Type | Default | Purpose |
|----------|------|---------|---------|
| `name` | string | — | Env var name (UPPER_SNAKE_CASE) |
| `description` | string | — | What this variable is for |
| `required` | boolean | false | Whether the skill fails without it |
| `sensitive` | boolean | false | Whether this is a secret/credential |

```yaml
# Real example: eve-esi skill pattern
env:
  - name: EVE_CLIENT_ID
    description: "EVE Developer Application Client ID"
    required: false
    sensitive: false
  - name: EVE_CLIENT_SECRET
    description: "EVE Developer Application Client Secret"
    required: false
    sensitive: true
  - name: EVE_TOKEN_MAIN
    description: "ESI OAuth2 access token for main character"
    required: false
    sensitive: true
```

**Tradeoffs:**
- Gives the scanner the `sensitive` flag (Format 2 and 3 lack this)
- Most explicit and readable
- **BUT** fails `package_skill.py` local validation (top-level `env:` not allowed)
- Works fine when publishing directly with `npx clawhub publish` (bypasses local packager)

### Format 2: `metadata.openclaw.env`

- **Type:** nested object → array
- **Scanner check:** Recognized as env declaration.

```yaml
# Real example: raon-os skill pattern
metadata:
  openclaw:
    env:
      - name: GEMINI_API_KEY
        description: "Google Gemini API key"
        required: false
```

Missing the `sensitive` field compared to Format 1. Use when you need to group
env declarations with other openclaw metadata.

### Format 3: `metadata.openclaw.requires`

- **Type:** nested object with `env` (string array), `bins` (string array), `primaryEnv` (string)
- **Scanner check:** Recognized, but provides least detail.

```yaml
# Real example: zen-founder-agent skill pattern
metadata:
  openclaw:
    requires:
      env:
        - ZEN_FOUNDER_AGENT_API_KEY
      bins:
        - curl
    primaryEnv: ZEN_FOUNDER_AGENT_API_KEY
```

This format only lists env var **names** — no descriptions or sensitivity flags.
Use when you also need to declare binary dependencies (`bins`).

### Combining Formats

You can use `env:` for detailed declarations and `metadata.openclaw.requires.bins`
for binary dependencies:

```yaml
env:
  - name: MY_API_KEY
    description: "API key for the service"
    required: true
    sensitive: true
metadata:
  openclaw:
    requires:
      bins:
        - curl
        - jq
    primaryEnv: MY_API_KEY
```

---

## Optional Fields

### `requires`

- **Type:** array of strings
- **Purpose:** Human-readable list of requirements, displayed to users.
- **Scanner check:** Checked against actual skill content for consistency.

```yaml
requires:
  - "Active account on Example service with API access"
  - "curl CLI tool installed"
  - "Node.js 18+ for script execution"
```

### `homepage`

- **Type:** string (URL)
- **Purpose:** Link to source code or documentation.

```yaml
homepage: "https://github.com/user/my-skill"
```

### `category`

- **Type:** string
- **Purpose:** Categorize the skill in ClawHub listings.

```yaml
category: "developer-tools"
```

### `emoji`

- **Type:** string (single emoji)
- **Purpose:** Display icon in ClawHub listings.

```yaml
emoji: "🔧"
```

### `version`

- **Type:** string (semver)
- **Purpose:** Version in frontmatter. Can also be set via `--version` flag on publish.
- **Note:** The CLI `--version` flag takes precedence if both are set.

```yaml
version: "1.2.0"
```

---

## Scanner Impact by Field

| Field | Scanner Category | Impact |
|-------|-----------------|--------|
| `name` | All | Must be present |
| `description` | PURPOSE & CAPABILITY | Must match actual functionality |
| `env` | CREDENTIALS, PURPOSE | All used credentials must be declared |
| `env[].sensitive` | CREDENTIALS | Secrets must be flagged |
| `metadata.openclaw.requires.bins` | INSTALL MECHANISM | Declared tools validated |
| `requires` | PURPOSE & CAPABILITY | Checked against skill content |

---

## Complete Example

A well-structured frontmatter covering all common fields:

```yaml
---
name: example-api-manager
description: >
  Manage Example API resources including users, projects, and billing.
  Query data, generate reports, and monitor usage with full CRUD support.
  Use when: querying Example API, generating usage reports, managing
  API projects, checking billing, creating API resources, monitoring
  service health.
env:
  - name: EXAMPLE_API_KEY
    description: "API key from Example dashboard (Settings → API Keys)"
    required: true
    sensitive: true
  - name: EXAMPLE_ORG_ID
    description: "Organization ID (visible in account settings)"
    required: false
    sensitive: false
requires:
  - "Example API account with admin access"
  - "curl CLI tool"
homepage: "https://github.com/example/example-api-manager"
category: "api-integrations"
emoji: "🔌"
---
```

---

## Anti-Patterns

### Missing env declarations

```yaml
# BAD — skill body references OPENAI_API_KEY but frontmatter doesn't declare it
---
name: my-skill
description: "Uses AI to analyze text."
---
# Result: ! on CREDENTIALS
```

### Overly broad description

```yaml
# BAD — description doesn't match actual narrow functionality
---
name: pdf-rotate
description: >
  Complete PDF suite for all document operations including editing,
  signing, encrypting, converting, and managing PDFs.
---
# Result: ℹ on PURPOSE & CAPABILITY (description overpromises)
```

### Inline JSON metadata

```yaml
# WORKS but hard to read and maintain
metadata: {"openclaw":{"requires":{"env":["MY_KEY"],"bins":["curl"]},"primaryEnv":"MY_KEY"}}
```

Prefer expanded YAML:

```yaml
metadata:
  openclaw:
    requires:
      env:
        - MY_KEY
      bins:
        - curl
    primaryEnv: MY_KEY
```


path: references/publish-workflow.md
content: # Publish Workflow

Step-by-step process for publishing a skill to ClawHub and iterating
until the security scanner gives all ✓ ratings.

---

## Step 1: Pre-Flight Checklist

Before publishing, verify:

| Check | How |
|-------|-----|
| Frontmatter has `name` | Lowercase, hyphens, under 64 chars |
| Frontmatter has `description` | Multi-line with trigger keywords |
| `env:` declares all credentials | Search body for env var names |
| Sensitive vars flagged | `sensitive: true` on keys/tokens |
| `requires:` lists dependencies | External services, CLI tools |
| SKILL.md under 500 lines | `wc -l SKILL.md` |
| No personal data | No names, emails, real credentials |
| No test artifacts | No `.db`, `.log`, `node_modules`, `__pycache__` |
| Scripts are safe | No network calls, workspace-scoped writes |
| Scripts documented | Line counts, purposes, inspection warning |
| References linked | SKILL.md points to all reference files |

---

## Step 2: Package Validation

Run the built-in skill validator to check structure:

```bash
python3 ~/.npm-global/lib/node_modules/openclaw/skills/skill-creator/scripts/package_skill.py ./my-skill
```

This checks:
- YAML frontmatter format and required fields
- Skill naming conventions
- Directory structure
- Description quality

Fix any reported errors before proceeding.

---

## Step 3: Publish

### First publish

```bash
npx clawhub publish ./my-skill \
  --slug my-skill \
  --name "My Skill Display Name" \
  --version 1.0.0 \
  --changelog "Initial release" \
  --tags latest
```

### Parameter reference

| Flag | Required | Purpose |
|------|----------|---------|
| `--slug` | Yes (first publish) | URL-safe identifier (lowercase, hyphens) |
| `--name` | Yes (first publish) | Human-readable display name |
| `--version` | Recommended | Semver version string |
| `--changelog` | Recommended | What changed in this version |
| `--tags` | Recommended | Tag names (use `latest` for default install) |

### Subsequent publishes (version bumps)

```bash
npx clawhub publish ./my-skill \
  --slug my-skill \
  --version 1.1.0 \
  --changelog "Fix: added env declarations for clean scanner results" \
  --tags latest
```

---

## Step 4: Check Scanner Results

After publishing, the scanner runs automatically. Check results:

```bash
# View metadata including scan results
npx clawhub inspect my-skill

# List published files
npx clawhub inspect my-skill --files

# View specific file content
npx clawhub inspect my-skill --file SKILL.md
```

Review each of the 5 scanner categories:

1. **PURPOSE & CAPABILITY** — Description matches functionality?
2. **INSTRUCTION SCOPE** — No auto-config language?
3. **INSTALL MECHANISM** — Scripts safe and documented?
4. **CREDENTIALS** — All env vars in frontmatter?
5. **PERSISTENCE & PRIVILEGE** — No always:true, isolation recommended?

---

## Step 5: Fix Warnings and Republish

If any category shows ℹ or !:

1. Identify the specific trigger (see [scanner-compliance.md](scanner-compliance.md))
2. Make the fix in your local skill directory
3. Bump the version
4. Republish

```bash
# After fixing issues
npx clawhub publish ./my-skill \
  --slug my-skill \
  --version 1.1.0 \
  --changelog "Fix: [describe what was fixed]" \
  --tags latest
```

### Common fixes by category

| Category | Common Fix |
|----------|-----------|
| PURPOSE & CAPABILITY | Expand description, add `requires:` |
| INSTRUCTION SCOPE | Replace "apply" with "review and manually apply" |
| INSTALL MECHANISM | Add script documentation + inspection warning |
| CREDENTIALS | Add `env:` array to frontmatter |
| PERSISTENCE & PRIVILEGE | Add agent isolation recommendation |

---

## Step 6: Iterate Until All ✓

Repeat Steps 4-5 until every category shows ✓.

**Typical progression:**
- v1.0.0 → Publish, get scanner feedback
- v1.1.0 → Fix obvious issues (env declarations, config language)
- v1.2.0 → Address remaining ℹ items (isolation, script docs)
- v1.3.0 → All ✓

Each publish gets a fresh scan. The scanner evaluates the latest version only.

---

## ClawHub CLI Reference

### Authentication

```bash
# Verify you're logged in
npx clawhub whoami
```

### Publishing

```bash
# Publish a skill directory
npx clawhub publish ./skill-dir \
  --slug SLUG \
  --name "Display Name" \
  --version X.Y.Z \
  --changelog "Description of changes" \
  --tags latest
```

### Inspection

```bash
# View skill metadata and scan results
npx clawhub inspect SLUG

# List all published files
npx clawhub inspect SLUG --files

# View a specific file
npx clawhub inspect SLUG --file SKILL.md
npx clawhub inspect SLUG --file references/schema.md
```

### Discovery

```bash
# Browse latest published skills
npx clawhub explore

# Search for skills by keyword
npx clawhub search "api integration"
npx clawhub search "pdf"
```

---

## Troubleshooting

### "Not authenticated"

```bash
# Re-authenticate
npx clawhub whoami
# If expired, the CLI will prompt for re-auth
```

### "Slug already taken"

Slugs are globally unique. Choose a different slug or check if you own the
existing one (`npx clawhub inspect SLUG`).

### "Invalid version"

Version must be valid semver (e.g., `1.0.0`, `2.1.3`). Leading `v` is not
required.

### Scanner results not showing

The scanner runs asynchronously. Wait a minute after publishing, then
`npx clawhub inspect SLUG` again.

### Publish succeeds but skill not found

Make sure you included `--tags latest`. Without a tag, the skill may be
published but not discoverable via default search/explore.


path: references/scanner-compliance.md
content: # Scanner Compliance Deep Dive

After publishing a skill to ClawHub, an automated security scanner evaluates it
across 5 categories. Each category receives a rating:

| Rating | Meaning |
|--------|---------|
| ✓ | Pass — no concerns |
| ℹ | Informational — minor observations, not blocking |
| ! | Warning — significant concerns that reduce trust |

The goal is **all ✓ marks**. This guide covers what triggers each rating and
how to fix issues.

---

## Category 1: PURPOSE & CAPABILITY

**What the scanner checks:**
- Does the description accurately reflect what the skill does?
- Are all external services and credentials declared?
- Are there undeclared capabilities or requirements?

### ✓ Pass

- Description clearly states what the skill does
- All referenced APIs, services, and credentials appear in frontmatter
- `requires` list matches actual dependencies
- No hidden functionality beyond what's described

### ℹ Informational

- Description is vague or overly broad relative to actual functionality
- Minor mismatch between described and actual capabilities

### ! Warning

- Skill accesses services not mentioned in description
- Credentials referenced in body but not declared in frontmatter
- Significant functionality not reflected in description

### Fix Pattern

1. Audit SKILL.md body for every external service, API, or credential mentioned
2. Ensure each appears in the description and `env` / `requires` frontmatter
3. Make description specific — match actual functionality, not aspirational scope

---

## Category 2: INSTRUCTION SCOPE

**What the scanner checks:**
- Do instructions stay within the skill's stated purpose?
- Does the skill instruct the agent to modify system config automatically?
- Are privileged operations properly gated?

### ✓ Pass

- All instructions relate to the skill's declared purpose
- Config changes presented as templates for **manual review**
- Privileged operations documented as requiring explicit user approval
- `requireMention:false` usage documented with data exposure implications

### ℹ Informational

- Instructions slightly broader than description suggests
- Config recommendations exist but aren't clearly marked as manual-review
- `requireMention:false` present without clear documentation

### ! Warning

- Language like "automatically apply," "agent patches config," or "auto-configure"
- Instructions directing the agent to modify gateway config without user review
- Scope creep — instructions for actions beyond the skill's stated purpose

### Fix Pattern

1. Replace all "automatic" config language with "manual review required"
2. Present config changes as templates or examples, not directives
3. Add explicit: "**All config changes require manual review. Nothing is applied automatically.**"
4. If `requireMention:false` is recommended, explain what data the agent will see

---

## Category 3: INSTALL MECHANISM

**What the scanner checks:**
- Do scripts download external code (curl, wget, npm install, pip install)?
- Do scripts write outside the skill workspace?
- Is code obfuscated or minified?
- Are scripts documented and inspectable?

### ✓ Pass

- Scripts only write within the skill workspace directory
- No network calls in scripts (no curl, wget, nc, etc.)
- Code is plain, readable, and documented
- SKILL.md includes "inspect before running" warning
- Script line counts and purposes documented

### ℹ Informational

- Scripts exist but without explicit inspection warning
- Scripts are mostly safe but documentation could be clearer

### ! Warning

- Scripts download external code or resources
- Scripts write to locations outside the skill directory
- Obfuscated or minified executable code
- No documentation of what scripts do

### Fix Pattern

1. Add to SKILL.md:
   ```
   The included scripts only create files within the skill workspace.
   They make no network calls and write no files outside the skill
   directory. **Inspect them before running.**
   ```
2. Remove any curl/wget/network calls from scripts
3. Use relative paths or `$SKILL_DIR` — never absolute system paths
4. Document each script's purpose and line count

→ Full patterns: [script-safety.md](script-safety.md)

---

## Category 4: CREDENTIALS

**What the scanner checks:**
- Are all env vars / credentials declared in frontmatter?
- Are sensitive values marked `sensitive: true`?
- Does the skill request credentials unrelated to its purpose?

### ✓ Pass

- Every env var referenced in the body appears in frontmatter `env:` array
- Sensitive credentials (API keys, tokens, passwords) marked `sensitive: true`
- No requests for credentials outside the skill's scope
- Prerequisites table lists all required accounts/services

### ℹ Informational

- Env vars declared but `sensitive` flag missing on what appears to be a secret
- Minor mismatch between body references and frontmatter

### ! Warning

- Body references credentials not declared in frontmatter at all
- Skill requests credentials unrelated to its stated purpose
- Sensitive credentials without any `sensitive` flag

### Fix Pattern

1. Search SKILL.md body for every env var name, API key reference, token mention
2. Add each to the `env:` array with `name`, `description`, `required`, `sensitive`
3. Mark all keys, tokens, passwords, and secrets as `sensitive: true`
4. Add a Prerequisites table mapping each credential to its source

---

## Category 5: PERSISTENCE & PRIVILEGE

**What the scanner checks:**
- Does the skill recommend `always:true` (always-on activation)?
- Are config changes automatic or gated behind manual review?
- For multi-user skills, is agent isolation recommended?
- Does the skill create persistent background processes?

### ✓ Pass

- No `always:true` recommendations
- Config changes explicitly presented as templates for manual review
- Multi-user or shared skills recommend a separate OpenClaw agent
- No persistent daemons or background processes
- Skill operates within its own workspace boundary

### ℹ Informational

- Multi-user patterns exist but isolation not explicitly recommended
- Config changes mentioned without clear manual-review gating

### ! Warning

- `always:true` recommended without justification
- Config changes presented as automatic directives
- No isolation recommendation for skills that process multi-user data
- Background processes or system-level modifications

### Fix Pattern

1. Never recommend `always:true` unless truly necessary — and justify it
2. Frame all config changes as: "Review this template and apply manually"
3. For multi-user skills, add a Security Model section recommending a dedicated agent
4. Ensure all operations are stateless and workspace-scoped

---

## Case Study: A Debate Moderator Skill

This traces the real progression of a multi-user skill through scanner iterations.

### v1.0.0 — Initial Publish

**Scanner results:**
- PURPOSE & CAPABILITY: ✓
- INSTRUCTION SCOPE: **!** — Instructions told agent to "apply config changes" automatically
- INSTALL MECHANISM: ℹ — Scripts existed but no inspection warning
- CREDENTIALS: **!** — Skill used env vars for API keys but none declared in frontmatter
- PERSISTENCE & PRIVILEGE: ℹ — Multi-user skill without agent isolation recommendation

**Issues identified:**
1. SKILL.md said "add this to your gateway config" as a directive, not a suggestion
2. Env vars referenced in body (`DEBATE_API_KEY`) not in frontmatter
3. Setup scripts had no "inspect before running" documentation
4. No recommendation to run as a separate agent

### v1.1.0 — First Fix Round

**Changes:**
- Added Prerequisites section with requirements table
- Changed all config language from "apply this config" to "review this template"
- Added "inspect before running" note for scripts
- Added basic security notes

**Scanner results:**
- PURPOSE & CAPABILITY: ✓
- INSTRUCTION SCOPE: ℹ — Better but some residual automatic-sounding language
- INSTALL MECHANISM: ✓ — Inspection warning resolved this
- CREDENTIALS: **!** — Body mentioned env vars still not in frontmatter YAML
- PERSISTENCE & PRIVILEGE: ℹ — Still missing explicit isolation recommendation

**Lesson:** Adding a Prerequisites *section in the body* is not enough. The scanner
checks **frontmatter** for credential declarations. Body-only documentation of
env vars does not satisfy the CREDENTIALS check.

### v1.2.0 — Second Fix Round

**Changes:**
- Added `env:` array to frontmatter with all env vars, including `sensitive: true`
- Added `requires:` array listing external dependencies
- Replaced remaining "configure your agent" with "review and manually apply"
- Added explicit: "**All config changes require manual review.**"
- Added Security Model section recommending dedicated agent with restricted permissions
- Documented script line counts and purposes

**Scanner results:**
- PURPOSE & CAPABILITY: ✓
- INSTRUCTION SCOPE: ✓
- INSTALL MECHANISM: ✓
- CREDENTIALS: ✓
- PERSISTENCE & PRIVILEGE: ✓

### Key Takeaways

1. **Frontmatter is king for CREDENTIALS.** Body documentation is for humans;
   the scanner reads frontmatter for credential declarations.
2. **Language matters for INSTRUCTION SCOPE.** "Apply this" → warning.
   "Review and manually apply" → pass.
3. **Script inspection warnings are cheap wins.** One sentence resolves
   INSTALL MECHANISM concerns.
4. **Agent isolation is required for multi-user skills.** A Security Model
   section with "run as a separate agent" satisfies PERSISTENCE & PRIVILEGE.
5. **Iterate with version bumps.** Each publish gets a fresh scan. Bump
   version, fix issues, republish, check again.

---

## Quick Compliance Checklist

Before publishing, verify:

- [ ] `name` and `description` in frontmatter
- [ ] `env:` array declares every credential/env var used in the body
- [ ] Sensitive values marked `sensitive: true`
- [ ] `requires:` lists external dependencies
- [ ] No "automatic" config language — all changes are "manual review"
- [ ] Scripts documented with line counts, purposes, and "inspect before running"
- [ ] No curl/wget/network calls in scripts (or explicitly declared if necessary)
- [ ] Multi-user skills include agent isolation recommendation
- [ ] No `always:true` without clear justification
- [ ] Description matches actual functionality — not broader, not narrower
- [ ] No personal data, test databases, or generated artifacts


path: references/script-safety.md
content: # Script Safety Patterns

Patterns for including scripts in ClawHub skills that pass the security scanner.

The scanner evaluates scripts under **INSTALL MECHANISM** and checks for:
- External downloads or network calls
- Writes outside the skill workspace
- Obfuscated or unreadable code
- Missing documentation and inspection warnings

---

## Safe Script Checklist

Before publishing scripts, verify:

- [ ] Scripts only write within the skill workspace (relative paths or `$SKILL_DIR`)
- [ ] No network calls (`curl`, `wget`, `nc`, `fetch`, `requests.get`, etc.)
- [ ] No obfuscated, minified, or encoded code
- [ ] Each script's purpose and line count documented in SKILL.md
- [ ] "Inspect before running" warning in SKILL.md
- [ ] Plain bash/python/node — no compiled binaries

---

## Safe Patterns

### Workspace-scoped writes

```bash
#!/usr/bin/env bash
# Only write within the skill directory
SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
OUTPUT_DIR="$SKILL_DIR/output"
mkdir -p "$OUTPUT_DIR"
echo "result" > "$OUTPUT_DIR/result.txt"
```

### Relative path operations

```bash
#!/usr/bin/env bash
# Use relative paths from script location
cd "$(dirname "$0")"
mkdir -p ../data
cp ../assets/template.json ../data/config.json
```

### Read-only analysis

```python
#!/usr/bin/env python3
"""Analyze a file and print results. No writes, no network."""
import sys
import json

with open(sys.argv[1]) as f:
    data = json.load(f)
print(f"Records: {len(data)}")
```

### Environment variable usage

```bash
#!/usr/bin/env bash
# Use declared env vars — never hardcode credentials
if [ -z "$MY_API_KEY" ]; then
    echo "Error: MY_API_KEY not set. See Prerequisites in SKILL.md."
    exit 1
fi
# Use $MY_API_KEY in operations...
```

---

## Unsafe Patterns (Trigger Scanner Warnings)

### Network downloads

```bash
# BAD — downloads external code
curl -sL https://example.com/installer.sh | bash
wget https://example.com/tool.tar.gz
pip install some-package
npm install some-module
```

### Writing outside workspace

```bash
# BAD — writes to system locations
cp config.json /etc/myapp/config.json
echo "alias myskill='...'" >> ~/.bashrc
sudo mv binary /usr/local/bin/
```

### Obfuscated code

```bash
# BAD — base64 encoded execution
eval "$(echo 'c29tZSBjb2Rl' | base64 -d)"
```

### Hardcoded credentials

```python
# BAD — credentials in source
[REDACTED_SECRET]"
```

---

## Documentation Template

Add this to SKILL.md for any skill with scripts:

```markdown
## Bundled Scripts

| Script | Purpose | Lines |
|--------|---------|-------|
| `scripts/setup.sh` | Creates workspace directory structure | 25 |
| `scripts/analyze.py` | Parses input data and generates report | 80 |

The included scripts only create files within the skill workspace. They make
no network calls and write no files outside the skill directory. **Inspect
them before running** — all scripts are plain, readable code with no
obfuscation.
```

Adapt the table to list your actual scripts with accurate line counts.

---

## When Scripts Must Make Network Calls

Some skills legitimately need network access (API integrations, data fetching).
If scripts must make network calls:

### 1. Declare endpoints explicitly

In SKILL.md, document exactly which endpoints are contacted:

```markdown
## Network Access

The `scripts/fetch-data.sh` script contacts the following endpoints:
- `https://api.example.com/v2/data` — retrieves user data
- `https://api.example.com/v2/status` — checks service health

No other network calls are made.
```

### 2. Declare env vars for credentials

```yaml
env:
  - name: EXAMPLE_API_KEY
    description: "API key for Example service (used by fetch-data.sh)"
    required: true
    sensitive: true
```

### 3. Explain why network access is needed

```markdown
## Why Network Access

This skill integrates with the Example API to retrieve live data.
The `fetch-data.sh` script makes authenticated HTTPS requests to the
Example API. No data is sent to any other endpoint.
```

### 4. Recommend sandboxed execution

```markdown
## Security Notes

For production use, run this skill's scripts in a sandboxed environment
or review each network call before execution. The scripts use only the
declared API endpoints and transmit only the data described above.
```

---

## Script Testing Before Publish

Before publishing, run each script and verify:

1. **No files created outside the skill directory**
   ```bash
   # Watch filesystem writes during script execution
   find /tmp -newer /tmp/timestamp-file  # check for temp files
   ```

2. **No unexpected network connections**
   ```bash
   # Run with network monitoring (macOS)
   nettop -p $(pgrep -f your_script)
   ```

3. **Exit codes are correct**
   ```bash
   ./scripts/your-script.sh; echo "Exit: $?"
   ```

4. **Output matches documentation**
   - Verify files are created where documented
   - Verify no side effects beyond documented behavior


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)