Skill hub query
Skill Songhonglei/build-better-skills/skills/skill-hub-query
A suite of skills to build better skills — from creation through install, audit, release, regression testing, and sediment.
npx -y skills add Songhonglei/build-better-skills --skill skill-hub-queryAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Query, install, update, and edit AI agent skills on any compatible Skill Hub (self-hosted, or any Hub implementing the documented API contract). Dual-channel: with a token it uses the authenticated API (full features including private skills); without a token it falls back to the unauthenticated channel (public skills only). Covers: list newly published skills, search by keyword / author / time / source, inspect version history, install or upgrade a specific version, and edit a skill's card metadata (display name, summary, tags, visibility, applicable position, etc.) via a safety-first GET -> diff -> backup -> PUT -> dual-channel verify -> auto-rollback flow. Trigger phrases include "what's new on the hub", "search for X skill", "install X", "update Y skill", "edit hub card info", "show skill version history", "skill-hub-query".
SKILL.md
21.1 KB, as published. Nobody here has run it
skill-hub-query
- Version: 1.1.5
- License: MIT
- Author: Evan Song (https://github.com/Songhonglei)
- Repository: https://github.com/Songhonglei/build-better-skills/tree/main/skills/skill-hub-query
- Part of:
build-better-skillssuite — see Stages for the lifecycle map.
Drive any compatible Skill Hub from the command line with a single, predictable interface. Works with self-hosted Hubs that implement the documented API contract.
Heads-up: this tool talks to Hubs that implement the API contract below. It does NOT target clawhub.ai — that Hub has its own API surface and an official CLI named
clawhub. Use this tool when you have a private or compatible Hub to drive.
Agent workflow
Dual-channel auto-selection
When the user asks a Hub-related question ("what's on the hub", "install X",
"search for Y"), run sync.sh / query.sh / install.sh directly — the
scripts pick the right channel:
| User state | Channel | Capability |
|---|---|---|
| Token set (env or credentials file) | OpenAPI (<HUB_API_PREFIX>/* with auth header) | Full features incl. private skills |
| No token | Legacy fallback (<HUB_LEGACY_API_PREFIX>/* without auth) | Search & install public skills |
When falling back the first time, the script emits a one-shot notice suggesting the user request a token for long-term stability. After that it stays silent.
When to actively suggest the user configure a token
Only when the user explicitly needs to:
- install a private skill (search finds it, but download requires auth)
- get contract-stable, long-term behavior (legacy fallback may be removed)
- when
doctor.shexplicitly recommends it
Setting up the token (after the user provides one)
# Option A: env var (CI / temporary)
export SKILL_HUB_URL="https://hub.your-company.com"
export SKILL_HUB_TOKEN="<your-token>"
# Option B: credentials file (recommended, cross-skill reusable)
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query"
cat > "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query/credentials.json" <<EOF
{
"endpoint": "https://hub.your-company.com",
"token": "<your-token>",
"authHeader": "Authorization",
"authScheme": "Bearer "
}
EOF
chmod 600 "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query/credentials.json"
Then verify with bash scripts/doctor.sh.
Never echo a full token back to the user, write it outside the credentials directory, or commit it to git.
"What's on the hub for X?"
- Silently
bash sync.sh(incremental; zero HTTP if nothing changed) bash query.sh keyword X- Reply with a user-readable table (name / author / version / updated / summary), not raw IDs
- If ≤5 hits include the summary; if many, list top 10 + total count
"Install X"
bash sync.shthenbash query.sh slug Xto get the latest version and summary- Confirm first: "Will install {displayName} v{latest} (author X). Proceed?"
- After user approves, run:
bash install.sh X --yes - Without
--yes, install.sh blocks on stdin for already-installed skills; in non-interactive mode it refuses outright — preventing silent overwrite - Show: "installed; will be loaded on the next agent session"
"Install a batch"
- Query each slug for version + permission info
- Show one combined manifest + estimated download size, wait for approval
- After approval, install serially with
install.sh <slug> --yes(avoid rate limiting); report failures separately
Configuration
⚠️ You MUST configure
SKILL_HUB_URL(or.endpointin the credentials file) before any network call. There is no baked-in default, because no single public Hub is guaranteed to implement this contract. Runbash scripts/doctor.shfirst — it will tell you exactly what's missing.
| Env variable | Default | Purpose |
|---|---|---|
SKILL_HUB_PROVIDER | (unset) | Select a built-in adapter for a known public Hub instead of the generic contract. Currently supports skillhub_cn (see Built-in provider: skillhub.cn). When unset, the generic-contract behavior below applies. |
SKILL_HUB_URL | (must be set) | Hub base URL, e.g. https://hub.your-company.com (ignored when SKILL_HUB_PROVIDER is set) |
SKILL_HUB_API_PREFIX | /api/v1/skill | Primary API path |
SKILL_HUB_LEGACY_API_PREFIX | /api/skill | Fallback API path |
SKILL_HUB_AUTH_HEADER | Authorization | HTTP header name for auth |
SKILL_HUB_AUTH_SCHEME | Bearer | Header value prefix (note trailing space; set to "" for API-key auth) |
SKILL_HUB_TOKEN | (unset) | API token (takes precedence over credentials file) |
SKILL_HUB_TOKEN_FILE | ${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json | Credentials file |
SKILL_HUB_SKILLS_DIR | (auto-detect) | Where installed skills land |
SKILL_HUB_CACHE_DIR | ${XDG_CACHE_HOME:-~/.cache}/skill-hub-query | Where the local cache lives |
SKILL_HUB_EDIT_PREFIX | same as SKILL_HUB_LEGACY_API_PREFIX | Path prefix for /edit and /detail (edit.sh only) |
SKILL_HUB_DISABLE_EDIT | 0 | Set to 1 to disable edit.sh when your Hub does not implement /edit |
SKILL_HUB_BACKUP_RETENTION | 20 | How many recent edit.sh backups to keep per slug (older are pruned) |
SKILL_HUB_DOWNLOAD_TIMEOUT | 120 | curl --max-time (seconds) for skill ZIP download in install.sh |
SKILL_HUB_OWNER_EMAIL | (auto: git config user.email) | Email used by edit.sh owner pre-check; override if your git identity differs from your Hub identity |
Skills install directory
Resolved in order: SKILL_HUB_SKILLS_DIR -> ~/.claude/skills/ ->
~/.openclaw/workspace/skills/ -> ~/.config/skills/ (first existing wins).
Setting up Hub URL + token (one-time)
echo 'export SKILL_HUB_URL="https://hub.your-company.com"' >> ~/.bashrc
echo 'export SKILL_HUB_TOKEN="<your-token>"' >> ~/.bashrc
source ~/.bashrc
Or — for richer per-Hub profiles — use the credentials file:
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query"
cat > "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query/credentials.json" <<EOF
{
"endpoint": "https://hub.your-company.com",
"token": "<your-token>",
"authHeader": "Authorization",
"authScheme": "Bearer "
}
EOF
chmod 600 "${XDG_CONFIG_HOME:-$HOME/.config}/skill-hub-query/credentials.json"
Never commit tokens to git, never hardcode them in scripts, and never echo the full token to the user.
Built-in provider: skillhub.cn
skillhub.cn is a China-optimized public skills hub. Because its API shape differs from the generic contract above, this skill ships a built-in adapter for it. Activate it with:
export SKILL_HUB_PROVIDER=skillhub_cn # one-off
# or persist it:
echo 'export SKILL_HUB_PROVIDER=skillhub_cn' >> ~/.bashrc
When the provider is active, SKILL_HUB_URL / token / API-prefix env vars are
ignored — the adapter targets https://api.skillhub.cn directly. No token
is needed (all supported operations are public, read-only).
Capability matrix (skillhub.cn)
| Operation | Command | Supported? |
|---|---|---|
| Search / browse | query.sh keyword <kw> · query.sh today · query.sh combo --keyword= --category= --source= | ✅ live (no local cache) |
| Skill detail | query.sh slug <slug> | ✅ |
| Version history | query.sh versions <slug> | ✅ |
| Install | install.sh <slug> [--yes] | ✅ |
sync.sh | — | ⚪ no-op (live search needs no cache; informational, exit 0) |
query.sh author <handle> | — | ❌ no author-filter param on skillhub.cn (use keyword) |
edit.sh (edit card metadata) | — | ❌ not available — see below |
Why edit is not supported on skillhub.cn
skillhub.cn card metadata (displayName / summary / tags / category) is a
one-way mirror synced from the upstream source (clawhub / GitHub). The only
write endpoints the platform exposes are publish / unlist / relist / delete /
claim — none of which edit card fields. To change a card, update the
upstream source and re-publish/let it re-sync. (This differs from a
generic Hub that implements a PUT /edit contract, which edit.sh drives.)
Examples (skillhub.cn)
export SKILL_HUB_PROVIDER=skillhub_cn
bash scripts/query.sh keyword code # search
bash scripts/query.sh today # browse newest
bash scripts/query.sh slug skill-creator # detail
bash scripts/query.sh versions skill-creator # versions
bash scripts/install.sh skill-creator --yes # install
bash scripts/doctor.sh # shows the capability matrix
Self-check / diagnosis
bash scripts/doctor.sh
doctor.sh probes both channels (OpenAPI with token, legacy without) plus
optionally the /edit endpoint. If at least one channel works, the skill is
usable.
Cache & performance
All list queries hit a local JSON cache (${SKILL_HUB_CACHE_DIR}/skill-cache.json),
parsed with jq (sub-ms).
| Trigger | Sync action |
|---|---|
| Cache missing or corrupt | Full sync |
| User asks "refresh cache" | Forced full sync |
| Routine query | Incremental (records with updatedAt newer than cursor) |
| Incremental page 1 entirely new (= 100 records) | Upgrade to full sync |
Incremental sync does NOT prune removed/withdrawn skills (it only unions new records). If you hit a "found in cache but install 404s" case, run
bash sync.sh --full. The full sync log will report "pruned N removed".
Multi-user / shared-host caveat
The legacy channel (no token) identifies callers by source IP. On shared
hosts (containers, CI runners), all agents/users share one identity.
scope=mine returns the list for that shared identity.
For per-user isolation on shared hosts, configure a per-user SKILL_HUB_TOKEN.
Quick reference: scenarios
Scenario 1: search
| User request | Action |
|---|---|
| "Search for calendar-related skills" | bash sync.sh && bash query.sh keyword calendar |
| "What was published this week?" | bash sync.sh && bash query.sh time this_week |
| "Anything on 2026-05-20?" | bash query.sh time 2026-05-20 (single day: 00:00 - 23:59) |
| "Between 5/18 and 5/22?" | bash query.sh time 2026-05-18:2026-05-22 |
| "Last week by user X?" | bash sync.sh && bash query.sh combo --since=last_week --author=X |
| "Only this account (avoid prefix collisions)" | bash query.sh author [email protected] --exact |
| "Official skills today?" | bash sync.sh && bash query.sh combo --since=today --source=official |
| "Show details of skill XX" | bash query.sh slug XX |
Scenario 2: install / update
| User request | Action |
|---|---|
| "Install calendar" | 1) Check cached version 2) Confirm with user 3) After approval: bash install.sh calendar --yes |
| "Update html-go-live to latest" | First query.sh slug html-go-live for new version + confirm with user -> after approval bash install.sh html-go-live --yes (--yes must be user-authorized) |
| "Install html-go-live 2.4.0" | Same confirmation flow -> after approval bash install.sh html-go-live 2.4.0 --yes |
| "Search skillhub.cn for X" | SKILL_HUB_PROVIDER=skillhub_cn bash query.sh keyword X (no token; see Built-in provider: skillhub.cn) |
| "Install X from skillhub.cn" | SKILL_HUB_PROVIDER=skillhub_cn bash install.sh X --yes |
--yesis a user-authorization flag; an LLM/agent caller must not add it on its own. The user must explicitly say "yes" / "go ahead" / "install" first; SKILL.md examples in automated paths intentionally omit--yes.
Scenario 3: version history
| User request | Action |
|---|---|
| "Version history of html-go-live" | source scripts/_lib.sh && api_get "${HUB_API_PREFIX}/versions/html-go-live?limit=20" | jq |
| "What changed in 2.4.0?" | api_get "${HUB_API_PREFIX}/versions/html-go-live/2.4.0" | jq .data.version.changelog |
Scenario 4: diagnose / refresh
| User request | Action |
|---|---|
| "skill-hub-query is broken / I can't find anything" | bash doctor.sh (probes all channels and reports the precise issue) |
| "Refresh cache / rebuild cache / prune removed skills" | bash sync.sh --full |
Scenario 5: edit a skill's card metadata
Use edit.sh to modify the Hub card for a skill you own. You can only edit
skills you own; non-owners get 403 from the Hub.
Hub compatibility: This requires your Hub to implement
PUT /edit/<slug>andGET /detail/<slug>. If your Hub does not implement them, run:export SKILL_HUB_DISABLE_EDIT=1and edit.sh will refuse to run with an informative message instead of producing confusing errors.
| User request | Action |
|---|---|
| "Show current card info for my-skill" | bash edit.sh <slug> --show |
| "Change summary of my-skill to xxx" | First --show or --dry-run to confirm -> after approval: bash edit.sh <slug> --summary "xxx" --yes |
| "Add tags Demo / Test to my-skill" | First --show to grab current tags, build the merged list -> after approval bash edit.sh <slug> --tags "old1,old2,Demo,Test" --yes |
| "Change visibility of my-skill to public" | High-risk: surface the prompt to the user explicitly (including any Hub-side policy that may silently downgrade) -> after explicit approval add --yes |
Agent caller rule (same as install.sh):
--yesis a user-authorization flag. An agent must NOT add it on its own; the human user must explicitly approve. Without--yes,edit.shblocks on stdin in a TTY and refuses to proceed in non-interactive mode.
Array fields (tags / scene / business / ...) are full overwrites, not additive. To append, first
--showto read the current list, then submit the merged list.
Supported fields: see
bash edit.sh --helpfor the full list of CLI flags.
Safety guarantees (five-stage flow):
- GET the authoritative current value
- Owner pre-check (server-side 403 is the ultimate safety net)
- Build patch + show diff (skip PUT if no actual diff)
- Backup to disk + user confirm (backups in
${SKILL_HUB_CACHE_DIR}/edit-backups/, latest 20 per slug)- PUT + dual-channel verify with retry + auto-rollback on mismatch (visibility silent-downgrade is a documented partial-success edge case)
Self-hosted Hub: API contract
Your Hub must implement these endpoints (response envelope
{code: 200, message: "", data: {...}}):
GET <endpoint><SKILL_HUB_API_PREFIX>/search?page=N&size=N&orderBy=updatedAt&order=desc
-> data: {records: [<skill>...], total: <number>}
GET <endpoint><SKILL_HUB_API_PREFIX>/versions/<slug>?limit=N
-> data: {items: [{version, changelog, ...}, ...]}
GET <endpoint><SKILL_HUB_API_PREFIX>/versions/<slug>/<version>
-> data: {version: {...}}
GET <endpoint><SKILL_HUB_LEGACY_API_PREFIX>/download/<slug>?version=<v>&track=true
-> body: zip bytes (Content-Type may be application/octet-stream)
Each <skill> record minimally contains:
{
"slug": "string",
"displayName": "string",
"summary": "string",
"owner": {"displayName": "...", "handle": "...", "email": "..."},
"source": "official|personal|external",
"updatedAt": <epoch_ms>,
"latestVersion": {"version": "x.y.z"}
}
For edit.sh (optional), additionally:
PUT <endpoint><SKILL_HUB_EDIT_PREFIX>/edit/<slug>
body = JSON patch (any subset of editable fields)
empty body returns the current snapshot
-> data: <full skill metadata>
GET <endpoint><SKILL_HUB_EDIT_PREFIX>/detail/<slug>
-> data: {skill: <full metadata>}
If your Hub uses a different auth scheme, override SKILL_HUB_AUTH_HEADER and
SKILL_HUB_AUTH_SCHEME (e.g. SKILL_HUB_AUTH_HEADER=X-API-Key
SKILL_HUB_AUTH_SCHEME="").
📖 Need the full request/response field reference? When implementing or debugging a self-hosted Hub, read
references/api.md— it documents every endpoint's exact parameters, response envelope, and field semantics in detail.
File layout
skill-hub-query/
├── SKILL.md # this file
├── credentials.example.json # template for the credentials file
├── references/
│ └── api.md # detailed API contract reference
└── scripts/
├── _lib.sh # path discovery + token + curl wrapper (sourced)
├── _edit_lib.sh # edit.sh internals (sourced)
├── doctor.sh # one-shot self-check
├── sync.sh # full / incremental cache sync
├── query.sh # query the local cache
├── install.sh # download + safe extract + atomic dir replace
└── edit.sh # five-stage safe metadata editor (optional Hub features)
Cache & credentials (NOT in skill directory, NOT git-tracked):
${SKILL_HUB_CACHE_DIR:-~/.cache/skill-hub-query}/
├── skill-cache.json # full skill index (key = slug)
├── skill-cache-meta.json # sync cursor + metadata
├── skill-versions.json # locally installed skill versions
└── edit-backups/ # snapshots before each edit (latest 20 per slug)
${XDG_CONFIG_HOME:-~/.config}/skill-hub-query/credentials.json (chmod 600)
Direct API call pattern (advanced)
# 1) source the lib (loads token / paths / curl wrapper)
source ./scripts/_lib.sh
# 2) call any API path (api_get auto-routes: token -> OpenAPI; none -> legacy)
api_get "${HUB_API_PREFIX}/search?keyword=calendar&size=20"
api_get "${HUB_API_PREFIX}/versions/html-go-live?limit=10"
api_get "${HUB_API_PREFIX}/versions/html-go-live/2.4.0"
# 3) download a zip (public skills don't need auth; private skills do)
api_download "html-go-live" "2.4.0" "/tmp/x.zip"
For direct curl calls, pass the auth header when you have a token:
-H "$(load_auth_header): $(load_auth_scheme)$SKILL_HUB_TOKEN".
Error reference
| Error | What to do |
|---|---|
[info] No SKILL_HUB_TOKEN configured, falling back to legacy channel | Normal; consider setting a token for long-term stability |
[error] No SKILL_HUB_TOKEN found, and the legacy fallback channel is unavailable | Both channels are down; run doctor.sh to pinpoint |
HTTP 401 / token invalid | Token expired or revoked; refresh it or remove it to fall back to legacy |
[error] Skill 'X' access denied (HTTP 403, private skill) | Private skill; configure a token with permission, or ask the owner |
[error] Skill 'X' is private (response code=403) | Same as above (some Hubs return 200 + JSON error) |
[error] Skill 'X' not found (HTTP 404) | Wrong slug / removed; try query.sh slug X and possibly sync.sh --full |
[error] Download failed: X (network error) | curl-layer failure (network/DNS); check connectivity |
zip contains unsafe paths | Defense against directory traversal; report to Hub maintainer |
Extracted content is missing SKILL.md | Malformed zip; aborted without touching existing install |
install failed; rolling back | Atomic dir replace failed (rare; usually disk full) |
X exists and --yes not given | Agent didn't get user authorization; have the user say "yes" first |
| Cache corruption (jq parse failure) | sync.sh rebuilds automatically |
edit.sh is disabled because SKILL_HUB_DISABLE_EDIT=1 | Your Hub does not expose /edit; unset the var only if it does |
Known limitations
- The ZIP download endpoint is not part of the formal OpenAPI spec on all Hubs;
install.shuses the legacy/download/<slug>path (public skills: no auth needed; private: token required). - Some legacy fields (
starredAt,starred,litToday, etc.) are deprecated and may be missing depending on Hub version. - Incremental sync does not prune removed skills (see "Cache" section).
- The legacy channel is a transition path; for production / long-term use, configure a token.
edit.shrequires optional/editand/detailendpoints; not all Hubs expose them.
版本
当前 v1.1.4。完整版本历史见 CHANGELOG.md。