OpenClaw users need a central place to discover, publish, and manage reusable skills and plugins. Existing methods rely on ad‑hoc GitHub repos or manual installs, making it hard to version, moderate, or search skills. The lack of a curated catalog slows adoption and increases the risk of duplicate or insecure code.
What This Does
ClawHub supplies a web UI, CLI, and API that handle skill lifecycle operations.
Skill registry – packages/clawhub/src/cli.ts exposes skill publish, search, and merge commands that call Convex HTTP actions defined in convex/lib/skills/index.ts.
Vector search – embeddings are generated with text‑embedding‑3‑small and stored in Convex’s vector index; the UI queries them via the same Convex functions.
Package catalog – the packages/schema package exports TypeScript types for OpenClaw plugin metadata (openclaw.compat.pluginApi, openclaw.build.openclawVersion) and is imported by the CLI (packages/clawhub/src/schema/index.ts).
How It Is Wired
Entry point – convex/_generated/server.js boots the Convex backend.
Convex actions – convex/lib/skills/index.ts defines publishSkill, searchSkills, and moderation functions. These actions read/write the Convex database, store uploaded skill files, and invoke the OpenAI embedding endpoint.
CLI – packages/clawhub/src/cli.ts parses arguments, authenticates via Convex Auth (packages/clawhub/src/auth.ts), and calls the appropriate Convex action through the generated client (convex/_generated/client.js).
Web app – served by Convex; the UI components (React, TSX files in src/) call the same Convex actions through the client.
The control path is: CLI/UI → Convex client → Convex action → Convex DB / OpenAI → response. The widest blast radius is the publishSkill action; it writes skill metadata, files, and embeddings, and triggers moderation hooks.
How To Use It
Setup – clone the repo: ``bash git clone https://github.com/moses-y/clawhub cd clawhub npm install ``
Configuration – create a .env file at the repo root (see convex/.env.example) with CONVEX_DEPLOYMENT, OPENAI_API_KEY, and GITHUB_TOKEN.
Running the server – start Convex locally: ``bash npx convex dev ``
Using the CLI – publish a skill: ``bash npx ts-node packages/clawhub/src/cli.ts skill publish ./my-skill ` Search: `bash npx ts-node packages/clawhub/src/cli.ts search "image classification" ``
Real‑World Use
A data‑science team maintains a set of image‑processing skills. They use the CLI to publish new versions nightly, and the web UI to let teammates search by semantic intent. Moderators flag questionable code; the skill delete command soft‑deletes the entry, preserving the URL for audit.
Code Health & Issues
Low – Missing lockfile in fixtures/claws/hosted‑e2e/package/package.json → non‑reproducible builds.
Medium – No Dockerfile; container deployment instructions absent.
High – No license badge in the root LICENSE file (MIT is declared, but no badge).
Low – 675 test files, 69 docs – good test coverage but no CI fail‑fast strategy documented.
The Bottom Line
ClawHub offers a solid, Convex‑powered registry that covers skill publishing, moderation, and vector search. Its TypeScript codebase is well‑structured, and the CLI is straightforward to use. The main gaps are the missing lockfile and lack of containerization documentation, but for teams already using OpenClaw, ClawHub is a practical, minimal‑friction solution.
What the analyser found
Deployment readiness
5/7
✗Container image
✓CI pipeline
✗Lockfile committed
✓Test suite
✓README
✓License
✓No committed secrets
Composition
1,930 files
TypeScript1027
TSX253
Markdown242
YAML54
JSON43
JavaScript24
ReactExpressTransformersCUDA
Architecture
Top-level areas of the codebase, sized by module count. Arrows show how many imports cross from one area into another.
Ranked by severity × confidence × production reach. Reach is the honest discriminator across a collection that is mostly other people's code: the same finding matters more in something that ships.
critical2
high1
medium5
low1
Do not check out pull request code in a privileged workflowcritical
.github/workflows/deploy-test.yml
privileged trigger checks out the untrusted ref
This is the most reliably exploited Actions pattern: anyone opening a pull request gets code execution with your repository secrets.
Fix: Split into an unprivileged pull_request build and a workflow_run job that only consumes its artifact.
Keep secrets out of workflows a fork can triggercritical3 occurrences
.github/workflows/deploy-test.yml
CONVEX_DEPLOY_KEY, VERCEL_AUTOMATION_BYPASS_SECRET, VERCEL_TOKEN (publish or cloud scope)
Contributor-controlled input reaches a job holding a publish token or cloud credential, so a pull request becomes credential exfiltration.
Fix: Move secret-using steps into a workflow_run job that never checks out pull request code, or gate on an environment with required reviewers.
Stop discarding the exit code of steps whose failure mattershigh
.github/workflows/clawhub-cli-github-release.yml
lines 124 discard failure
The job reports green while the artifact it was supposed to produce was never produced, so a crash becomes a successful run built on stale data.
Fix: Let the step fail, or test the specific expected condition instead of discarding all exit codes.
Gate pull requests on a dependency vulnerability scanmedium
.github/workflows
no dependency scan in CI
This is the one gate that would catch a known-vulnerable package before it reaches a build, and no repository in the sample had it.
Fix: Add dependency-review-action on pull_request, or osv-scanner on push and a schedule.
Move large binaries to Git LFS or out of the repositorymedium
fixtures/public-corpus/corpus.jsonl
1 blobs over 5MB: corpus.jsonl 13.3MB
One repository here carries twenty blobs over 5MB including a 10.9MB spreadsheet, so every clone and every CI checkout pays for data nobody diffs.
Fix: Track those extensions with LFS, or move datasets to object storage and fetch them in a setup step.
Remove generated build output from version controlmedium60 occurrences
packages
60 generated files committed
The reviewer reads src, production runs dist, and a stale bundle means the fix that was reviewed is not the code that executes.
Fix: Gitignore the output directory and build in CI.
checkout keeps the token, then dependencies are installed
The token stays in .git/config for every later step, so a malicious postinstall script reads a pushable credential without one ever being passed to it.
Fix: Add with: persist-credentials: false, and pass an explicit token only to the step that pushes.
Review the install lifecycle script and disable scripts in CImedium
package.json
preinstall
Install scripts are the execution vector for every npm compromise from event-stream onward, and a postinstall that fetches a binary makes the build depend on a URL nobody reviews.
Fix: Move the work into an explicit build step, or set ignore-scripts in CI and run it by name.
Set timeout-minutes on the workflow jobslow2 occurrences
.github/workflows/clawhub-cli-github-release.yml
2 workflow(s) declare no job timeout
A wedged step runs to the six-hour platform default, which on a two-hourly schedule means three runs overlap behind it.
Fix: Add timeout-minutes with a realistic bound to each job.
Checked deterministically against the repository tree and a bounded set of its files: committed credentials, unpinned actions and base images, missing lockfiles and update bots, workflows that discard failures, published advisories against the declared dependencies, runtime configuration, licensing and notebook reproducibility. No language model is involved in this section.