mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 08:52:21 +00:00
feat: add skill metadata docs, suspicious appeal banner for owners
- Document full frontmatter metadata reference in docs/skill-format.md - Add metadata section + quick example to README - Show appeal message on suspicious skills (owner-only) linking to GitHub issues - Accept metadata.openclaw alias in README docs - Re-evaluate all skills with full file content reading (backfill in progress)
This commit is contained in:
@@ -138,7 +138,30 @@ metadata: {"clawdbot":{"cliHelp":"padel --help\\nUsage: padel [command]\\n"}}
|
||||
---
|
||||
```
|
||||
|
||||
`metadata.clawdbot` is preferred, but `metadata.clawdis` is accepted as an alias for compatibility.
|
||||
`metadata.clawdbot` is preferred, but `metadata.clawdis` and `metadata.openclaw` are accepted as aliases.
|
||||
|
||||
## Skill metadata
|
||||
|
||||
Skills declare their runtime requirements (env vars, binaries, install specs) in the `SKILL.md` frontmatter. ClawHub's security analysis checks these declarations against actual skill behavior.
|
||||
|
||||
Full reference: [`docs/skill-format.md`](docs/skill-format.md#frontmatter-metadata)
|
||||
|
||||
Quick example:
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: my-skill
|
||||
description: Does a thing with an API.
|
||||
metadata:
|
||||
openclaw:
|
||||
requires:
|
||||
env:
|
||||
- MY_API_KEY
|
||||
bins:
|
||||
- curl
|
||||
primaryEnv: MY_API_KEY
|
||||
---
|
||||
```
|
||||
|
||||
## Scripts
|
||||
|
||||
|
||||
+2
-2
@@ -344,12 +344,12 @@ export const backfillLlmEval = internalAction({
|
||||
)
|
||||
|
||||
for (const { versionId, slug } of batch.skills) {
|
||||
// The query already filters out versions with llmAnalysis, but double-check
|
||||
// Re-evaluate all (full file content reading upgrade)
|
||||
const version = (await ctx.runQuery(internal.skills.getVersionByIdInternal, {
|
||||
versionId,
|
||||
})) as Doc<'skillVersions'> | null
|
||||
|
||||
if (!version || (version.llmAnalysis && version.llmAnalysis.status !== 'error')) {
|
||||
if (!version) {
|
||||
accSkipped++
|
||||
continue
|
||||
}
|
||||
|
||||
+2
-2
@@ -1678,8 +1678,8 @@ export const getActiveSkillBatchForLlmBackfillInternal = internalQuery({
|
||||
|
||||
const version = await ctx.db.get(skill.latestVersionId)
|
||||
if (!version) continue
|
||||
// Skip versions that already have a successful llmAnalysis (retry errors)
|
||||
if (version.llmAnalysis && version.llmAnalysis.status !== 'error') continue
|
||||
// Re-evaluate all skills (full file content reading upgrade)
|
||||
// if (version.llmAnalysis && version.llmAnalysis.status !== 'error') continue
|
||||
|
||||
results.push({
|
||||
skillId: skill._id,
|
||||
|
||||
@@ -35,6 +35,99 @@ Workdir install state (written by the CLI):
|
||||
- The server extracts metadata from frontmatter during publish.
|
||||
- `description` is used as the skill summary in the UI/search.
|
||||
|
||||
## Frontmatter metadata
|
||||
|
||||
Skill metadata is declared in the YAML frontmatter at the top of your `SKILL.md`. This tells the registry (and security analysis) what your skill needs to run.
|
||||
|
||||
### Basic frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: my-skill
|
||||
description: Short summary of what this skill does.
|
||||
version: 1.0.0
|
||||
---
|
||||
```
|
||||
|
||||
### Runtime metadata (`metadata.openclaw`)
|
||||
|
||||
Declare your skill's runtime requirements under `metadata.openclaw` (aliases: `metadata.clawdbot`, `metadata.clawdis`).
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: my-skill
|
||||
description: Manage tasks via the Todoist API.
|
||||
metadata:
|
||||
openclaw:
|
||||
requires:
|
||||
env:
|
||||
- TODOIST_API_KEY
|
||||
bins:
|
||||
- curl
|
||||
primaryEnv: TODOIST_API_KEY
|
||||
---
|
||||
```
|
||||
|
||||
### Full field reference
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `requires.env` | `string[]` | Environment variables your skill expects. |
|
||||
| `requires.bins` | `string[]` | CLI binaries that must all be installed. |
|
||||
| `requires.anyBins` | `string[]` | CLI binaries where at least one must exist. |
|
||||
| `requires.config` | `string[]` | Config file paths your skill reads. |
|
||||
| `primaryEnv` | `string` | The main credential env var for your skill. |
|
||||
| `always` | `boolean` | If `true`, skill is always active (no explicit install needed). |
|
||||
| `skillKey` | `string` | Override the skill's invocation key. |
|
||||
| `emoji` | `string` | Display emoji for the skill. |
|
||||
| `homepage` | `string` | URL to the skill's homepage or docs. |
|
||||
| `os` | `string[]` | OS restrictions (e.g. `["macos"]`, `["linux"]`). |
|
||||
| `install` | `array` | Install specs for dependencies (see below). |
|
||||
| `nix` | `object` | Nix plugin spec (see README). |
|
||||
| `config` | `object` | Clawdbot config spec (see README). |
|
||||
|
||||
### Install specs
|
||||
|
||||
If your skill needs dependencies installed, declare them in the `install` array:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
openclaw:
|
||||
install:
|
||||
- kind: brew
|
||||
formula: jq
|
||||
bins: [jq]
|
||||
- kind: node
|
||||
package: typescript
|
||||
bins: [tsc]
|
||||
```
|
||||
|
||||
Supported install kinds: `brew`, `node`, `go`, `uv`.
|
||||
|
||||
### Why this matters
|
||||
|
||||
ClawHub's security analysis checks that what your skill declares matches what it actually does. If your code references `TODOIST_API_KEY` but your frontmatter doesn't declare it under `requires.env`, the analysis will flag a metadata mismatch. Keeping declarations accurate helps your skill pass review and helps users understand what they're installing.
|
||||
|
||||
### Example: complete frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: todoist-cli
|
||||
description: Manage Todoist tasks, projects, and labels from the command line.
|
||||
version: 1.2.0
|
||||
metadata:
|
||||
openclaw:
|
||||
requires:
|
||||
env:
|
||||
- TODOIST_API_KEY
|
||||
bins:
|
||||
- curl
|
||||
primaryEnv: TODOIST_API_KEY
|
||||
emoji: "\u2705"
|
||||
homepage: https://github.com/example/todoist-cli
|
||||
---
|
||||
```
|
||||
|
||||
## Allowed files
|
||||
|
||||
Only “text-based” files are accepted by publish.
|
||||
|
||||
@@ -577,6 +577,15 @@ export function SkillDetailPage({
|
||||
ClawHub Security flagged this skill as suspicious. Review the scan results before
|
||||
using.
|
||||
</p>
|
||||
{canManage ? (
|
||||
<p className="pending-banner-appeal">
|
||||
If you believe this skill has been incorrectly flagged, please{' '}
|
||||
<a href="https://github.com/openclaw/clawhub/issues" target="_blank" rel="noopener noreferrer">
|
||||
submit an issue on GitHub
|
||||
</a>{' '}
|
||||
and we'll break down why it was flagged and what you can do.
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : modInfo?.isRemoved ? (
|
||||
|
||||
@@ -3206,6 +3206,17 @@ html.theme-transition::view-transition-new(theme) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.pending-banner-appeal {
|
||||
margin-top: 6px !important;
|
||||
font-size: 0.8rem !important;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.pending-banner-appeal a {
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* Blocked/removed banner variant */
|
||||
.pending-banner-blocked {
|
||||
background: rgba(239, 68, 68, 0.12);
|
||||
|
||||
Reference in New Issue
Block a user