npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@clawhive/openclaw-plugin

v0.2.2

Published

ClawHive channel plugin for OpenClaw

Downloads

325

Readme

ClawHive OpenClaw Plugin

Desktop-side OpenClaw channel plugin that bridges a local OpenClaw node to the ClawHive cloud so the ClawHive mobile app can send messages to and receive replies from the user's local agents.

For end-user setup and daily usage in Chinese, see INSTALLATION-GUIDE.zh-CN.md. For the latest stabilization summary, see RELEASE-NOTES-2026-04-24.md.

Architecture at a glance

ClawHive mobile app  ──►  Supabase (Postgres + Realtime + Edge Functions)  ──►  this plugin  ──►  OpenClaw core  ──►  local agent
                                                                         ◄──  writes agent reply  ◄──
  • Inbound: user messages are inserted by the mobile app into public.messages. This plugin subscribes to the messages Realtime publication and dispatches each role='user' row into the local agent via api.runtime.subagent.run({ sessionKey, message, deliver: true }).
  • Outbound: OpenClaw core routes the agent reply back through the channel's outbound.attachedResults.sendText, which calls the plugin-message-write edge function to persist the reply with role='agent'.
  • Heartbeat: a background loop calls plugin-heartbeat every heartbeat_interval seconds (default 30) to keep plugin_nodes.plugin_status='online'.
  • Market install orchestration: a separate background loop polls market-install-claim, keeps the approved releaseId/version/publishSourceRef/publishFingerprint pinned, and reports installing plus durable failed/cancelled outcomes through market-install-update.

Zero-config install

The install flow is intentionally self-provisioning. openclaw plugins install must not require a pre-created pluginToken or manual edits to ~/.openclaw/openclaw.json.

Install the published npm package:

openclaw plugins install @clawhive/openclaw-plugin

After plugin install, run:

openclaw clawhive authorize

The command prints the approval URL plus user_code, waits for approval, and persists the resulting pluginToken and userId into the OpenClaw config. Then restart the gateway.

On the next openclaw gateway run:

  1. Reads config — pluginToken is now present from the explicit authorization command.
  2. Calls plugin-register and receives {plugin_node_id, realtime_topic, user_session}.
  3. Persists any new pluginNodeId or updated userId into config.
  4. All subsequent calls (heartbeat, agent-reply writes, pair-code generation, agent sync) present the token via x-plugin-token, which the server validates against plugin_tokens.

No shared dev secret exists; each install owns its own credential and can be revoked independently.

Configuration

Minimum managed-cloud install: nothing. The plugin falls back to the baked DEFAULT_PROJECT_URL in src/defaults.ts, silently bootstraps, and writes everything else into config.

Self-hosted or local-dev setup overrides the URL:

openclaw channels add --channel clawhive --url https://my-clawhive.example.com

…or via env for one-shot dev:

export CLAWHIVE_SUPABASE_MODE=local
export CLAWHIVE_PROJECT_URL=http://127.0.0.1:54321
export CLAWHIVE_SUPABASE_ANON_KEY=your-local-anon-or-publishable-key

Runtime env vars

| Name | Required | Purpose | |---|---|---| | CLAWHIVE_SUPABASE_MODE | optional | cloud uses the baked-in managed Supabase project. local uses CLAWHIVE_PROJECT_URL and CLAWHIVE_SUPABASE_ANON_KEY. | | CLAWHIVE_PROJECT_URL | optional | Local Supabase project base URL used when CLAWHIVE_SUPABASE_MODE=local. Do not include /rest/v1. | | CLAWHIVE_PLUGIN_TOKEN | optional | Pre-seed the plugin token instead of letting the plugin bootstrap. Normally auto-populated after first run. | | CLAWHIVE_USER_ID | optional | Pre-seed the owner user id. Normally auto-populated after bootstrap. | | CLAWHIVE_SUPABASE_ANON_KEY | optional | Local Supabase anon/publishable key used when CLAWHIVE_SUPABASE_MODE=local and channels.clawhive.anonKey is not set in OpenClaw config. |

Build-time override (baked into dist/):

| Name | Purpose | |---|---| | CLAWHIVE_DEFAULT_PROJECT_URL | Replace the compiled-in default project URL. Set this before npm run build when producing a self-hosted plugin package. |

Runtime lifecycle

  1. gateway_start fires. Resolve account from config + env + baked default.
  2. If no pluginToken, print a hint telling the user to run openclaw clawhive authorize, then stay idle.
  3. Once authorized, call plugin-register → receive plugin_node_id, realtime_topic, and a user-session JWT`.
  4. Persist any config drift (pluginNodeId, updated userId).
  5. Push local agents (cfg.agents.list) to the cloud via plugin-agents-sync.
  6. Open the Supabase Realtime channel on public.messages filtered by user_id.
  7. Start the heartbeat loop.
  8. Start the market install claim loop. It runs independently from messaging and heartbeat so long-running install work cannot block inbound chat.
  9. Always print an ANSI QR (via qrcode-terminal) with a 5-minute TTL pair_token so first-time installs, additional phones, and reinstalled apps can pair without manual cleanup. The banner changes when phones are already paired.
  10. On each inbound role='user' row, call api.runtime.subagent.run({ sessionKey, message, deliver: true }). Reconnects fetch missed messages via messages-sync.
  11. On gateway_stop, tear down the install loop, transport, and heartbeat, then mark plugin_status='offline'.

Marketplace install runner

The plugin now claims durable install jobs from the market backend. The current execution contract is intentionally strict:

  1. Claim only jobs targeted at this plugin_node_id.
  2. Keep the approved releaseId, version, publishSourceRef, and publishFingerprint pinned for the whole execution attempt.
  3. Reject incompatible releases if minPluginVersion or minOpenClawVersion is not satisfied.
  4. Mark the durable job as installing once preflight passes.
  5. Always write a final durable failed or cancelled state with a machine-readable reasonKind and a plain-language errorMessage if local apply cannot complete.

Failure mapping

The install runner currently emits these durable failure kinds:

| reasonKind | Meaning | |---|---| | claim_rejected | The claimed job does not match the current node or is missing pinned release identity. | | artifact_fetch_failed | The approved release is missing publishSourceRef or publishFingerprint, so the plugin cannot verify the exact artifact. | | compatibility_rejected | minPluginVersion or minOpenClawVersion rejects the current desktop runtime. | | install_apply_failed | The job passed preflight but the local host still has no stable marketplace install API to apply the artifact. | | cancelled | Reserved for future explicit cancellation flows. |

Release metadata relevance

  • publishSourceRef: stable source locator the plugin keeps pinned after the user confirms a release on mobile.
  • publishFingerprint: immutable checksum/fingerprint the plugin expects before local apply.
  • minPluginVersion: minimum ClawHive plugin runtime required by the release.
  • minOpenClawVersion: minimum OpenClaw host version required by the release.

The current OpenClaw SDK surface does not yet expose a stable local marketplace install API, so the runner stops after durable preflight and reports a visible failure instead of silently dropping the job or guessing how to install it.

Manual Commands

  • openclaw clawhive authorize Prints the browser approval URL and device user code, then waits for authorization.
  • openclaw clawhive pair Prints a fresh mobile pairing QR plus short code on demand so you can re-pair a phone after reinstall, add another phone, or recover if you missed the startup banner.
  • openclaw clawhive pair --ttl-seconds 600 Optional override for the pairing-code TTL when you need a longer window.

Manual smoke-testing

Everything below runs against a local supabase start:

# 1. Start the stack
cd /path/to/openclaw-assistant
supabase start
source <(supabase status -o env)
export PROJECT_URL=http://127.0.0.1:54321

# 2. Mint a real plugin token (no shared dev secret)
BOOT=$(curl -s -X POST "$PROJECT_URL/functions/v1/plugin-bootstrap" \
  -H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" \
  -H "Content-Type: application/json" -d '{"description":"manual-test"}')
PLUGIN_TOKEN=$(echo "$BOOT" | python3 -c 'import sys,json;print(json.load(sys.stdin)["plugin_token"])')

# 3. Exercise the plugin-authed endpoints with the real token
curl -s -X POST "$PROJECT_URL/functions/v1/plugin-register" \
  -H "apikey: $ANON_KEY" -H "Authorization: Bearer $ANON_KEY" \
  -H "x-plugin-token: $PLUGIN_TOKEN" -H "Content-Type: application/json" \
  -d '{"node_name":"smoke"}'

To run the plugin itself against the local stack:

cd openclaw-plugin && npm install && npm run build && cd ..
openclaw plugins install "$PWD/openclaw-plugin" --force

export CLAWHIVE_PROJECT_URL="$PROJECT_URL"
export CLAWHIVE_SUPABASE_ANON_KEY="$ANON_KEY"
export CLAWHIVE_SUPABASE_MODE=local
openclaw clawhive authorize
openclaw gateway run --dev --verbose

The local dev flow above should not require hand-editing ~/.openclaw/openclaw.json. The explicit authorization command persists the token, user id, and anon key before the gateway starts the runtime.

Marketplace install smoke flow

Use this flow when validating Phase 9 install orchestration end to end:

  1. Start the plugin and confirm the desktop node registers successfully.
  2. Publish a market release whose metadata includes publishSourceRef, publishFingerprint, minPluginVersion, and minOpenClawVersion as needed.
  3. In the mobile app, discover the listing, open the detail screen, confirm a compatible node, and create the durable install job.
  4. Watch the plugin claim the job and report installing, then either:
    • a durable success once a stable host install API exists, or
    • a durable failure with reasonKind and plain-language errorMessage.
  5. Confirm the app shows the latest install status and My installs history, and confirm operator evidence exists via install events / health summary.

Expert Panel Sessions

When ClawHive creates an expert panel session, the cloud stores the turn and contribution state. The plugin claims panel turns, runs local OpenClaw agents in two rounds, updates each contribution as it completes or times out, and writes only the moderator's final answer back to the normal message stream.

The first version assumes all selected agents are available on the same OpenClaw node. Multi-node distributed execution is not supported yet.

MVP non-goals

  • Successful local apply of a marketplace artifact before OpenClaw exposes a stable native install API.
  • Outbound media / file attachments — sendMedia throws unsupported_media.
  • Plugin token rotation / expiry (tokens are currently long-lived; revoke manually via update public.plugin_tokens set revoked_at = now() where id = '...' until a rotation endpoint ships).

Development

npm install
npm run check      # tsc --noEmit
npm run build      # emits dist/

Publishing to npm

The package is published from this directory:

npm login
npm publish --access public

prepublishOnly runs TypeScript checking, builds dist/, and prints the exact npm tarball contents with npm pack --dry-run before publishing.

The required cloud deltas live under supabase/ — migrations add plugin_tokens and enable Realtime on messages, and edge functions cover bootstrap, register, heartbeat, message-write, agents-sync, pair-code-create. Apply with supabase db reset in local dev.