ClawHub CLI Reference: Commands, Flags, Config, and Lockfile Behavior

Complete reference for the ClawHub CLI, covering commands, global flags, environment variables, HTTP proxy support, and lockfile behavior. Essential for developers and DevOps engineers using ClawHub.

Read this when

  • Using the ClawHub CLI
  • Debugging install, update, or publish

CLI

The CLI package is clawhub, and its binary is clawhub.

Use npm or pnpm to install it globally:

npm i -g clawhub
# or
pnpm add -g clawhub

After installation, confirm it works:

clawhub --help
clawhub login
clawhub whoami

Global flags

  • --workdir <dir>: the directory the CLI operates in, defaulting to the current working directory, or the Clawdbot workspace when one is configured
  • --dir <dir>: where packages get installed under the working directory, defaulting to skills
  • --site <url>: the URL used for browser-based login, defaulting to https://clawhub.ai
  • --registry <url>: the base address for API calls, auto-detected unless https://clawhub.ai is used as the default
  • --no-input: turns off all interactive prompts

Corresponding environment variables:

  • CLAWHUB_SITE (older name: CLAWDHUB_SITE)
  • CLAWHUB_REGISTRY (older name: CLAWDHUB_REGISTRY)
  • CLAWHUB_WORKDIR (older name: CLAWDHUB_WORKDIR)

HTTP proxy

For setups behind corporate proxies or restricted networks, the CLI honors the standard HTTP proxy environment variables:

  • HTTPS_PROXY / https_proxy
  • HTTP_PROXY / http_proxy
  • NO_PROXY / no_proxy

Outbound traffic goes through the designated proxy whenever any of these variables is present. HTTPS requests rely on HTTPS_PROXY, while HTTP_PROXY handles plain HTTP. To exclude particular hosts or domains from proxying, NO_PROXY / no_proxy is respected.

This becomes necessary when direct outbound connections are unavailable, such as inside Docker containers, on Hetzner VPS instances with proxy-only internet, or behind corporate firewalls.

Example:

export HTTPS_PROXY=http://proxy.example.com:3128
export NO_PROXY=localhost,127.0.0.1
clawhub search "my query"

If no proxy variable is configured, the CLI behaves as usual, connecting directly.

Config file

Keeps your API token and the cached registry URL on disk.

  • macOS: ~/Library/Application Support/clawhub/config.json
  • Linux/XDG: $XDG_CONFIG_HOME/clawhub/config.json or ~/.config/clawhub/config.json
  • Windows: %APPDATA%\\clawhub\\config.json
  • Legacy fallback: when clawhub/config.json is absent but clawdhub/config.json exists, the older path is used instead
  • override: CLAWHUB_CONFIG_PATH (older name: CLAWDHUB_CONFIG_PATH)

Commands

login / auth login

  • Standard flow: opens the browser at <site>/cli/auth and finishes through a loopback callback.
  • Headless mode: clawhub login --token clh_...
  • Remote or headless interactive: clawhub login --device shows a code, then waits while you approve it at <site>/cli/device.

whoami

  • Checks the saved token by calling /api/v1/whoami.

token

  • Outputs the stored API token to stdout.
  • Handy for feeding a local login token into CI secret setup commands.

star <skill> / unstar <skill>

  • Toggles a skill in your Bookmarks. The commands stay named star and unstar for backward compatibility.
  • Invokes POST /api/v1/stars/<slug> and DELETE /api/v1/stars/<slug>.
  • Confirmation is bypassed with --yes.

search <query...>

  • Invokes /api/v1/search?q=....
  • The result includes the skill slug, owner handle, display name, and a relevance score.
  • Exact slug or name token matches rank ahead of download popularity. For instance, a standalone slug token like map aligns with personal-map more closely than the substring found within amap.
  • Popularity acts as a minor ranking prior, not a promise of top results.
  • --prefix: returns a deterministic page of matching slugs via /api/v1/skills; keep passing the printed --cursor until no cursor remains.
  • --exact: limits relevance search to exact slug matches.
  • --prefix and --exact cannot be used together.
  • --cursor works only when paired with --prefix.
  • If a skill is missing from results, run clawhub inspect @owner/slug while authenticated to review owner-visible moderation diagnostics before changing metadata.

explore

  • Shows the most recent skills through /api/v1/skills?limit=...&sort=createdAt, ordered by createdAt descending.
  • Options:
    • --limit <n> (1-200, defaults to 25)
    • --sort newest|updated|rating|downloads|trending (defaults to newest). Older install sort aliases remain functional for backward compatibility.
    • --json (output in machine-readable form)
  • Output: <slug> v<version> <age> <summary> (summary capped at 50 characters).

inspect @owner/slug

  • Retrieves skill metadata and version files without performing an install.
  • --version <version>: check a particular version (latest is the default).
  • --tag <tag>: check a version by tag (for example, latest).
  • --versions: show the version history (first page only).
  • --limit <n>: cap the number of versions listed (1-200).
  • --files: display files for the chosen version.
  • --file <path>: obtain raw file bytes, with a 10MB ceiling.
  • --json: machine-readable output; --file includes exact bytes as base64 and UTF-8 text when available.

install @owner/slug

  • Determines the latest version for the specified owner and skill.
  • Pulls the zip via /api/v1/download.
  • Unpacks into <workdir>/<dir>/<slug>.
  • Will not overwrite pinned skills; execute clawhub unpin <skill> beforehand.
  • Creates:
    • <workdir>/.clawhub/lock.json (previously .clawdhub)
    • <skill>/.clawhub/origin.json (previously .clawdhub)

uninstall <skill>

  • Deletes <workdir>/<dir>/<slug> and clears the lockfile entry.
  • Sends best-effort telemetry when logged in so current install counts can be deactivated.
  • Interactive mode asks for confirmation.
  • Non-interactive mode (--no-input) demands --yes.

list

  • Parses <workdir>/.clawhub/lock.json (formerly .clawdhub).
  • Displays pinned beside skills frozen with clawhub pin, including the optional reason.

pin <skill>

  • Flags an installed skill as pinned within the lockfile.
  • --reason <text> logs why the skill is frozen.
  • Pinned skills are ignored by update --all and blocked by direct update <skill>.
  • Pinned skills also reject install --force, preventing accidental replacement of local bytes.

unpin <skill>

  • Strips the lockfile pin from an installed skill, allowing future updates to alter it.

update [@owner/slug] / update --all

  • Derives a fingerprint from local files.
  • If the fingerprint matches a known version: no prompt appears.
  • If the fingerprint does not match:
    • refuses by default
    • overwrites with --force (or prompts, when interactive)
  • Pinned skills are never touched by --force.
  • update <skill> fails immediately for pinned skills and directs you to run clawhub unpin <skill> first.
  • update --all bypasses pinned slugs and reports which items stayed frozen.

skill publish <path>

  • The local bundle's fingerprint is checked against ClawHub, and the command exits with a success code when the content has already been published.
  • For new skills, the default version is 1.0.0; for modified skills, the next patch version becomes the default.
  • Publishing with an explicit version is handled by --version <version>, which proceeds even if the content matches an already existing version.
  • With --dry-run, the publish is resolved without any upload; --json outputs the result in a machine-readable format.
  • When the actor holds publisher access, --owner <handle> publishes using an org or user publisher handle.
  • While releasing a new version, --migrate-owner relocates an existing skill to --owner. Admin or owner rights are required on both publishers.
  • Comma-separated values are accepted by --categories <slugs> and --topics <topics>, which determine the browse filter placement for the skill. If a skill is first published without --categories, it is recorded as other; a subsequent publish that omits the flag preserves the stored value. The valid category slugs, limits, and reserved topic names appear in Skill catalog metadata.
  • Details on owner and review behavior are covered in docs/publishing.md.
  • Releasing a skill on ClawHub means it is published under MIT-0.
  • Published skills can be used, modified, and redistributed freely, with no attribution required.
  • Paid skills and per-skill pricing are not supported on ClawHub.
  • publish <path> serves as the legacy alias.
clawhub skill publish ./my-skill --dry-run
clawhub skill publish ./my-skill
clawhub skill publish ./my-skill --version 2.0.0

GitHub Actions

For a single skill_path, or for each immediate skill folder under root (default: skills), the reusable skill-publish.yml workflow on ClawHub invokes skill publish. Unchanged skills are skipped, and the same automatic patch-version behavior applies.

To preview without a token, set dry_run: true. The clawhub_token secret is mandatory for actual publishes.

The optional changelog, categories, and topics inputs correspond to the matching skill publish flags, while clear_categories and clear_topics strip metadata that a skill already has. When a skill is first published without categories, it is stored as other, identical to sync. Since catalog metadata applies to every skill in the run and disables the unchanged-skill skip mentioned earlier, review the notes under GitHub Actions before enabling it across the catalog.

sync

  • Local skill folders containing SKILL.md or skill.md are found by scanning the current workdir, the configured skills directory, and any --root <dir> folders.
  • Each local skill fingerprint is compared against ClawHub, and only new or modified skills are published.
  • New skills are published as 1.0.0; modified skills default to the next patch version. For update batches needing a larger semver step, use --bump minor|major.
  • The publish plan is displayed by --dry-run without uploading; --json provides a machine-readable version of the plan.
  • Without prompting, --all publishes every new or modified skill. If --all is absent, interactive terminals allow you to choose which skills to publish.
  • With publisher access, --owner <handle> publishes under an org or user publisher handle.
  • sync is strictly one-way publishing. It performs no installation, updates, downloads, or install/download telemetry reporting.
  • Neither --categories nor --topics exists in sync. Skills first published through sync are recorded as other until skill catalog metadata is set on them.
clawhub sync --all --dry-run
clawhub sync --all
clawhub sync --root ./skills --owner openclaw --bump minor

scan --slug <slug>

  • clawhub login is a prerequisite.
  • ClawHub ClawScan gets invoked through POST /api/v1/skills/-/scan, with polling continuing until the scan reaches a terminal state.
  • Because scans run asynchronously, completion can take a while. While a scan sits in the queue, the terminal spinner indicates its current priority position along with the count of scans ahead of it.
  • To publish a scan, you need ownership or publisher management privileges. Moderators and admins reach the same backend functionality via clawhub-admin.
  • --update only works in combination with --slug; it sends successful published scan results back to the chosen version.
  • Using --output <file.zip> pulls the complete report archive, which includes manifest.json, clawscan.json, skillspector.json, static-analysis.json, virustotal.json, and README.md.
  • --json outputs the entire poll response, which is handy for automation.
  • Local path scanning has been removed. Instead, upload a fresh version and then call scan download to fetch the stored scan results tied to that submitted version.
clawhub scan --slug gifgrep
clawhub scan --slug gifgrep --version 1.2.3
clawhub scan --slug gifgrep --update --output report.zip

scan download <name>

  • clawhub login is required.
  • Fetches the stored scan report ZIP for a submitted skill or plugin version, even if ClawHub security checks blocked or hid that version.
  • For skills, the download uses the skill slug and falls back to --kind skill.
  • For plugins, the package name drives the download, and --kind plugin is mandatory.
  • Authors must supply --version so they can inspect the exact submitted version that ClawHub rejected.
  • --output <file.zip> determines where the file gets saved.
clawhub scan download gifgrep --version 1.2.3
clawhub scan download @scope/demo --version 2.0.0 --kind plugin --output report.zip

GitHub Actions

ClawHub provides an official reusable workflow at /.github/workflows/skill-publish.yml that works for both skill repos and catalog repos.

A typical catalog setup looks like this:

name: Skill Publish

on:
  pull_request:
  workflow_dispatch:

jobs:
  dry-run:
    if: github.event_name == 'pull_request'
    uses: openclaw/clawhub/.github/workflows/skill-publish.yml@v1
    with:
      owner: nvidia
      dry_run: true

  publish:
    if: github.event_name == 'workflow_dispatch'
    uses: openclaw/clawhub/.github/workflows/skill-publish.yml@v1
    with:
      owner: nvidia
      dry_run: false
      changelog: "Describe the changes in this release."
      categories: "automation"
      topics: "code-review,linting"
    secrets:
      clawhub_token: ${{ secrets.CLAWHUB_TOKEN }}

Additional details:

  • root uses skills as its default for catalog repos.
  • To handle just one skill folder, pass skill_path: skills/review-helper.
  • The CLI flag --owner corresponds to owner; leave it out and publishing happens under the authenticated user's identity.
  • The optional changelog, categories, and topics each map to their respective skill publish flags. When you omit them, the metadata already published stays untouched.
  • Just like tags, all three of these affect every skill in the run. If the values describe a single skill rather than the whole catalog, pass skill_path instead.
  • Both categories and topics turn off the "skip unchanged skills" logic described earlier. The CLI treats any catalog metadata you supply as authoritative and skips its already-published short-circuit, meaning a catalog-wide run publishes a new patch version for each selected skill, even those with no file changes. The clear_categories and clear_topics flags count as supplied metadata and behave the same way. changelog does not: a run that only passes changelog still reports unchanged skills as alreadySynced. To stop a metadata edit from releasing an entire catalog, use skill_path.
  • changelog reaches the CLI exactly as written, the same way skill publish --changelog stores it, so Markdown indentation and trailing hard-break spaces survive the workflow; a value made up only of whitespace is treated as omitted. Being slug lists, categories and topics get trimmed instead.
  • Categories and topics arrive comma-separated and get validated on the server, so an unknown category slug or a topic exceeding the per-skill cap fails the publish after the run has already built and validated the skill.
  • To strip categories or topics already attached to a skill, set clear_categories: true or clear_topics: true. A workflow input cannot tell categories: "" apart from an omitted categories, so the empty string keeps its "leave them alone" meaning and the boolean is what sends the CLI's --categories "". Supplying a non-empty value together with its clear_ flag fails the run rather than silently choosing one. changelog has no such flag: the CLI already treats an omitted --changelog as empty.
  • The run logs echo the resolved skill publish command for each target, so any forwarded flag shows up in CI output. Keep the values non-sensitive.
  • V1 skill publishing relies on clawhub_token; GitHub OIDC trusted publishing is package-only at this time.

delete <skill>

  • To soft-delete a skill, use --version without it. Owners, moderators, and admins are the only roles permitted.
  • This invokes DELETE /api/v1/skills/{slug}.
  • When an owner starts a soft delete, the slug stays reserved for 30 days, and the command displays when that reservation ends.
  • With --version <version>, you can withdraw a single owned version that isn't the latest, through a route that fails closed and targets that version specifically. That version number stays reserved, so republishing it with altered content isn't possible. Before removing the current latest version, publish a replacement first. For this version-only operation, platform staff don't bypass ownership rules.
  • --reason <text> logs a moderation note and an audit entry when a whole-skill soft delete happens.
  • --note <text> serves as an alias for --reason.
  • Confirmation is bypassed with --yes.
  • The older POST /api/cli/skill/delete endpoint, when given a version, rejects it rather than treating it as a delete for the whole skill.

undelete <skill>

  • To restore a hidden skill, use this. Owners, moderators, and admins are the allowed roles.
  • It calls POST /api/v1/skills/{slug}/undelete.
  • --version <version> brings back only the exact retained artifact that the same owner actor previously withdrew. The restored version isn't set as latest, and removed tags aren't recreated.
  • Version restoration triggers POST /api/v1/skills/{slug}/versions/{version}/restore.
  • A moderation note and audit log entry are recorded via --reason <text>.
  • --note <text> is an alias for --reason.
  • Confirmation is skipped with --yes.

skill tag <skill> <version>

  • This moves a tag on an owned skill to an existing public version, with latest as the default choice.
  • It calls POST /api/v1/skills/{slug}/tags/{tag}.
  • For org publishers, owner or admin membership is required, matching the rules for version withdrawal.
  • Use this to roll latest back if you accidentally published a higher version; publishing a lower version by itself doesn't replace the latest version by highest semver.
  • Another tag can be selected with --tag <tag>.
  • Confirmation is skipped via --yes.

Example:

clawhub skill tag @owner/example 1.2.3 --yes

hide <skill>

  • Hide a skill. Owners, moderators, and admins can do this.
  • This is an alias for delete.

unhide <skill>

  • Unhide a skill. Owners, moderators, and admins can do this.
  • This is an alias for undelete.

skill rename <skill> <new-name>

  • Rename a skill you own, and the previous slug becomes a redirect alias.
  • It calls POST /api/v1/skills/{slug}/rename.
  • Confirmation is skipped with --yes.

skill merge <source> <target>

  • Merge one skill you own into another skill you own.
  • The source slug no longer appears in public listings and becomes a redirect alias pointing to the target.
  • It calls POST /api/v1/skills/{sourceSlug}/merge.
  • Confirmation is skipped via --yes.

transfer

  • Workflow for transferring ownership.
  • When transferring to a user handle, a pending request is created, and the recipient must accept it.
  • Transfers to org or publisher handles apply right away only if the actor has admin access to both the current owner and the destination publisher.
  • Subcommands:
    • transfer request <skill> <handle> [--message "..."] [--yes]
    • transfer list [--outgoing]
    • transfer accept <skill> [--yes]
    • transfer reject <skill> [--yes]
    • transfer cancel <skill> [--yes]
  • Endpoints:
    • POST /api/v1/skills/{slug}/transfer
    • POST /api/v1/skills/{slug}/transfer/accept
    • POST /api/v1/skills/{slug}/transfer/reject
    • POST /api/v1/skills/{slug}/transfer/cancel
    • GET /api/v1/transfers/incoming
    • GET /api/v1/transfers/outgoing

package explore [query...]

  • Lets you browse or search the combined package index with GET /api/v1/packages and GET /api/v1/packages/search.
  • Intended for plugins and other package-family items; search at the top level still handles skill searches.
  • Available flags:
    • --family skill|code-plugin|bundle-plugin
    • --official
    • --executes-code
    • --target <target>, --os <os>, --arch <arch>, --libc <libc>
    • --requires-browser, --requires-desktop, --requires-native-deps
    • --requires-external-service, --external-service <name>
    • --binary <name>, --os-permission <name>
    • --artifact-kind legacy-zip|npm-pack
    • --npm-mirror
    • --limit <n> (1-100, default: 25)
    • --json

Sample usage:

clawhub package explore --family code-plugin
clawhub package explore --family code-plugin --os darwin --requires-desktop
clawhub package explore --family code-plugin --artifact-kind npm-pack
clawhub package explore --npm-mirror
clawhub package explore episodic-claw --family code-plugin

package inspect <name>

  • Pulls package metadata without performing an installation.
  • Suitable for plugin metadata, compatibility checks, verification, source inspection, and version/file review.
  • --version <version>: examine a particular version (default: latest).
  • --tag <tag>: examine a version by tag (for instance, latest).
  • --versions: show the first page of the version list.
  • --limit <n>: maximum number of versions displayed (1-100).
  • --files: show files for the version you selected.
  • --file <path>: retrieve a limited UTF-8 text preview (capped at 200KB).
  • --json: output in a machine-readable format.

package download <name>

  • Determines a package version via GET /api/v1/packages/{name}/versions/{version}/artifact.
  • Pulls the artifact from the resolver's downloadUrl.
  • Confirms the ClawHub SHA-256 for every artifact.
  • For ClawPack npm-pack artifacts, additionally confirms npm sha512 integrity, the npm shasum, and the tarball's package.json name/version.
  • Legacy ZIP versions follow the legacy ZIP download path.
  • Flags:
    • --version <version>: download a chosen version.
    • --tag <tag>: download a version by tag (default: latest).
    • -o, --output <path>: destination file or directory.
    • --force: replace an existing output file.
    • --json: output in a machine-readable format.

Sample usage:

clawhub package download @openclaw/example-plugin --tag latest
clawhub package download @openclaw/example-plugin --version 1.2.3 -o artifacts/

package verify <file>

  • Calculates ClawHub SHA-256, npm sha512 integrity, and npm shasum for a local artifact.
  • With --package, pulls expected metadata from ClawHub and checks the local file against the published artifact metadata.
  • Using direct digest flags, verification happens without a network call.
  • Flags:
    • --package <name>: package name for resolving expected artifact metadata.
    • --version <version> or --tag <tag>: expected package version.
    • --sha256 <hex>: expected ClawHub SHA-256.
    • --npm-integrity <sri>: expected npm integrity.
    • --npm-shasum <sha1>: expected npm shasum.
    • --json: output in a machine-readable format.

Sample usage:

clawhub package verify ./example-plugin-1.2.3.tgz --package @openclaw/example-plugin --version 1.2.3
clawhub package verify ./example-plugin-1.2.3.tgz --sha256 <hex>

package validate <source>

  • Executes the Plugin Inspector bundled with the ClawHub CLI on a local plugin package directory.
  • By default, validation is offline and static, with no attempt to locate or import a local OpenClaw checkout.
  • Hard compatibility errors cause a non-zero exit. Warning-level findings are printed, yet the exit code remains zero.
  • Flags:
    • --out <dir>: output Plugin Inspector reports to the specified directory.
    • --openclaw <path>: validate against a designated local OpenClaw checkout.
    • --runtime: turn on runtime capture, which imports plugin code.
    • --allow-execute: permit runtime capture within an isolated workspace.
    • --no-mock-sdk: turn off the mocked OpenClaw SDK during runtime capture.
    • --json: produce output in a machine-readable format.

Example:

clawhub package validate ./example-plugin

Should validation surface any package, manifest, SDK import, or artifact issue, consult Plugin validation fixes and then run the command again.

package delete <name>

  • In the absence of --version, a package along with all its releases is soft-deleted.
  • With --version <version>, a single non-latest release that you own is withdrawn through a fail-closed, version-specific path. That version stays reserved and cannot be republished with altered contents. Before deleting the current latest version, publish a replacement. This version-only operation demands the package owner or an org publisher admin; platform staff do not override package ownership.
  • Soft-deleting an entire package requires the package owner, an org publisher owner/admin, platform moderator, or platform admin.
  • Flags:
    • --version <version>: withdraw one non-latest version.
    • --yes: bypass the confirmation prompt.
    • --json: machine-readable output.

Example:

clawhub package delete @openclaw/example-plugin --yes
clawhub package delete @openclaw/example-plugin --version 1.2.3 --yes

package undelete <name>

  • Brings back a soft-deleted package and its releases.
  • Requires the package owner, an org publisher owner/admin, platform moderator, or platform admin.
  • Invokes POST /api/v1/packages/{name}/undelete.
  • --version <version> restores only the specific retained release that the same owner actor previously withdrew. It neither marks the release as latest nor recreates removed package tags or dist-tags.
  • Restoring a version calls POST /api/v1/packages/{name}/versions/{version}/restore.
  • Flags:
    • --version <version>: restore a single owner-withdrawn release.
    • --yes: skip the confirmation prompt.
    • --json: machine-readable output.

Example:

clawhub package undelete @openclaw/example-plugin --yes

package transfer <name>

  • Moves a package to a different publisher.
  • Requires admin access to both the current package owner and the destination publisher, unless a platform admin performs the transfer.
  • Scoped package names must move to the owner of the matching scope.
  • Calls POST /api/v1/packages/{name}/transfer.
  • Flags:
    • --to <owner>: handle of the destination publisher.
    • --reason <text>: optional audit reason.
    • --json: machine-readable output.

Example:

clawhub package transfer @openclaw/example-plugin --to openclaw

package report

  • Authenticated command used to flag a package for moderator review.
  • Calls POST /api/v1/packages/{name}/report.
  • Reports apply at the package level, can optionally reference a version, and are visible to moderators for assessment.
  • Reports alone do not hide packages or prevent downloads.
  • Flags:
    • --version <version>: optional package version to include with the report.
    • --reason <text>: required reason for the report.
    • --json: machine-readable output.

Example:

clawhub package report @openclaw/example-plugin --version 1.2.3 --reason "suspicious native payload"

package moderation-status

  • Owner command that checks a package's moderation visibility.
  • Calls GET /api/v1/packages/{name}/moderation.
  • Displays the current package scan state, count of open reports, manual moderation state of the latest release, download block state, and moderation reasons.
  • Flags:
    • --json: machine-readable output.

Example:

clawhub package moderation-status @openclaw/example-plugin

package readiness <name>

  • Verifies whether a package is prepared for future OpenClaw use.
  • Calls GET /api/v1/packages/{name}/readiness.
  • Reports blockers related to official status, ClawPack availability, artifact digest, source provenance, OpenClaw compatibility, host targets, environment metadata, and scan state.
  • Flags:
    • --json: machine-readable output.

Example:

clawhub package readiness @openclaw/example-plugin

package migration-status <name>

  • Shows operator-focused migration status for a package that could replace a bundled OpenClaw plugin.
  • Uses the same computed readiness endpoint as package readiness, but outputs migration-specific status, latest version, official-package state, checks, and blockers.
  • Flags:
    • --json: machine-readable output.

Example:

clawhub package migration-status @openclaw/example-plugin

publisher create <handle>

  • Establishes an org publisher owned by the authenticated user.
  • The handle is lowercased and can be supplied with or without @.
  • Fresh org publishers are not trusted or official by default.
  • The operation fails if the handle already belongs to an existing publisher, user, or reserved route.
clawhub publisher create opik --display-name "Opik"

package publish <source>

  • Sends a code plugin or bundle plugin to the registry with POST /api/v1/packages.
  • The following inputs are accepted by <source>:
    • A directory on disk: ./my-plugin
    • A ClawPack tarball produced by npm-pack locally: ./my-plugin-1.2.3.tgz
    • A GitHub repository: owner/repo or owner/repo@ref
    • A GitHub web address: https://github.com/owner/repo
  • Metadata gets pulled automatically from package.json, openclaw.plugin.json, and genuine OpenClaw bundle indicators like .codex-plugin/plugin.json, .claude-plugin/plugin.json, and .cursor-plugin/plugin.json.
  • Any source coming from .tgz is handled as ClawPack. The exact npm-pack byte stream is what the CLI uploads, and the extracted package/ data serves only to validate and prefill metadata.
  • Publishing an experimental Claw requires an already-compiled .tgz. Sources from Claw folders or GitHub are not allowed; run openclaw claws build beforehand. The request records the local SHA-256, and after the precise bytes are accepted, ClawHub responds with that digest.
  • Before upload, code-plugin directories get converted into a ClawPack npm tarball so OpenClaw installs can confirm the exact artifact. Bundle-plugin directories continue down the extracted-file publish route instead.
  • When the source is GitHub, attribution comes from the repository, the resolved commit, the ref, and the subpath automatically.
  • For local directories, attribution is inferred from local git when the origin remote points to GitHub.
  • Code plugins from outside must spell out openclaw.compat.pluginApi and openclaw.build.openclawVersion. The top-level package.json.version is never consulted as a fallback during publish validation.
  • With --dry-run, you can see the resolved publish payload ahead of time without sending anything.
  • --json produces output that machines can parse, meant for CI pipelines.
  • --wait blocks until pre-publication security scans finish, and only returns once the release is out or a terminal error state is hit.
  • The --wait timeout is set by --wait-timeout <seconds>, which defaults to 1800.
  • --owner <handle> releases under a user or org publisher handle provided the actor holds publisher rights.
  • --categories <slugs> and --topics <topics> follow the same behavior as they do for skill publish, except code-plugin and bundle-plugin categories are checked against the plugin list rather than the skill one: channels, models, memory, context, voice, media, web, tools, runtime, gateway, security, other. Experimental --family claw publishes bypass that category check and keep the provided slugs unchanged. The topic constraints in Skill catalog metadata, limits, reserved names, republish behavior, hold across every family, claw included.
  • The selected owner must match the scoped package name. Refer to docs/publishing.md.
  • Overrides from existing flags (--family, --name, --version, --source-repo, --source-commit, --source-ref, --source-path) remain functional.
  • Accessing private GitHub repositories needs GITHUB_TOKEN.
clawhub package publish ./plugin.tgz --owner openclaw

Start with --dry-run so you can verify the resolved package metadata and source attribution before going live with an actual release:

npm pack
clawhub package publish ./my-plugin-1.2.3.tgz --family code-plugin --dry-run
clawhub package publish ./my-plugin-1.2.3.tgz --family code-plugin --wait

Local folder flow

When publishing code plugins, folder publish compiles and sends a ClawPack artifact built from the package directory. This shortcut does not extend to Claws:

clawhub package publish ./my-plugin --family code-plugin --dry-run
clawhub package publish ./my-plugin --family code-plugin

Minimal package.json for --family code-plugin

External code plugins require a small set of OpenClaw metadata in package.json. This minimal manifest suffices for a valid publish:

{
  "name": "@myorg/openclaw-my-plugin",
  "version": "1.0.0",
  "type": "module",
  "openclaw": {
    "extensions": ["./index.ts"],
    "compat": {
      "pluginApi": ">=2026.3.24-beta.2"
    },
    "build": {
      "openclawVersion": "2026.3.24-beta.2"
    }
  }
}

Mandatory fields:

  • openclaw.compat.pluginApi
  • openclaw.build.openclawVersion

Remarks:

  • package.json.version indicates your package release version, yet it is not employed as a fallback for OpenClaw compatibility or build validation.
  • openclaw.hostTargets and openclaw.environment are optional metadata. ClawHub may display them if available, but they are not necessary for publishing.
  • openclaw.compat.minGatewayVersion and openclaw.build.pluginSdkVersion are optional additions for those wanting to include richer compatibility details.
  • When using an older clawhub CLI version, update it prior to publishing so the local preflight checks execute before the upload.
  • Should validation return a remediation code, refer to Plugin validation fixes.

GitHub Actions

ClawHub also provides an official reusable workflow at /.github/workflows/package-publish.yml for plugin repositories.

Typical caller configuration:

name: Package Publish

on:
  pull_request:
  workflow_dispatch:
  push:
    tags:
      - "v*"

jobs:
  dry-run:
    if: github.event_name == 'pull_request'
    uses: openclaw/clawhub/.github/workflows/package-publish.yml@v0.12.0
    with:
      dry_run: true

  publish:
    if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/')
    permissions:
      contents: read
      id-token: write
    uses: openclaw/clawhub/.github/workflows/package-publish.yml@v0.12.0
    with:
      dry_run: false
    secrets:
      clawhub_token: ${{ secrets.CLAWHUB_TOKEN }}

To include release and catalog metadata, add the matching CLI values to the job's current with block. Keep dry_run: true for pull-request jobs; use dry_run: false only on the trusted publish job shown above.

with:
  changelog: "Describe the changes in this release."
  categories: "tools"
  topics: "automation,productivity"

Remarks:

  • The reusable workflow sets source to the caller repository by default.
  • For monorepos, pass source_path so the workflow publishes the plugin package directory, such as source_path: extensions/codex.
  • changelog, categories, and topics are optional. When supplied, the workflow passes them to the corresponding package publish CLI flags. Categories and topics accept comma-separated values; leaving them out preserves the existing workflow behavior.
  • To clear previously declared metadata, set clear_categories: true or clear_topics: true. A clear input cannot be used together with its matching value input.
  • Anchor the reusable workflow to a stable tag or full commit SHA. Do not run release publishing from @main.
  • pull_request should rely on dry_run: true to keep CI non-polluting.
  • Actual publishes should be restricted to trusted events like workflow_dispatch or tag pushes.
  • Trusted publishing without a secret functions only on workflow_dispatch; tag pushes still demand clawhub_token.
  • Keep clawhub_token available for the first publish, untrusted packages, or break-glass scenarios.
  • Real publishes wait for definitive publication by default. Set wait_for_publication: false only when a caller intentionally wants the legacy submit-and-return mode.
  • publication_timeout_minutes manages the publication wait timeout and defaults to 30 minutes (maximum: 40).
  • The workflow uploads the JSON result as an artifact and reveals it as workflow outputs.

package trusted-publisher get <name>

  • Displays the GitHub Actions trusted publisher configuration for a package.
  • Run this after setting config to verify the repository, workflow filename, and any environment pin.
  • Flags:
    • --json: machine-readable output.

Example:

clawhub package trusted-publisher get @openclaw/example-plugin

package trusted-publisher set <name>

  • Adds or replaces GitHub Actions trusted publisher config for an existing package.
  • The package must be created beforehand through normal manual or token-authenticated clawhub package publish.
  • Once config is set, future supported GitHub Actions publishes can use OIDC/trusted publishing without a long-lived ClawHub token.
  • --repository <repo> must be owner/repo.
  • --workflow-filename <file> must align with the workflow file name in .github/workflows/.
  • --environment <name> is optional. When set, the GitHub Actions environment in the OIDC claim must match exactly.
  • ClawHub checks the configured GitHub repository when this command runs. Public repositories can be verified via public GitHub metadata. Private repositories require ClawHub to have GitHub access to that repository, for example through a future ClawHub GitHub App installation or another authorized GitHub integration.
  • Flags:
    • --repository <repo>: GitHub repository, such as openclaw/example-plugin.
    • --workflow-filename <file>: workflow file name, such as package-publish.yml.
    • --environment <name>: optional exact-match GitHub Actions environment.
    • --json: machine-readable output.

Example:

clawhub package trusted-publisher set @openclaw/example-plugin \
  --repository openclaw/example-plugin \
  --workflow-filename package-publish.yml \
  --environment release

package trusted-publisher delete <name>

  • Deletes trusted publisher config from a package.
  • Use this as rollback when the workflow, repository, or environment pin needs to be disabled or re-created.
  • Future real publishes must use normal authenticated publishing until config is set again.
  • Flags:
    • --json: machine-readable output.

Example:

clawhub package trusted-publisher delete @openclaw/example-plugin

Install telemetry

  • Transmitted after clawhub install <slug> when logged in, unless CLAWHUB_DISABLE_TELEMETRY=1 is set.
  • Reporting is best-effort. Install commands do not fail if telemetry is unavailable.
  • Details: docs/telemetry.md.
5,326 words · updated Sep 1, 2026