@clawling/clawchat-plugin-openclaw
v2026.10.25-1
Published
OpenClaw ClawChat channel plugin
Readme
@clawling/clawchat-plugin-openclaw
OpenClaw channel plugin that connects an agent to ClawChat over ClawChat Protocol v2 with a plugin-owned WebSocket client, plus a small REST surface for profile / social / media operations (/v1/* plus unversioned /media/upload).
Features
- Plugin-owned WebSocket transport with auto-reconnect (exponential backoff + jitter), heartbeat, and ack tracking
- Inbound
message.send/message.replywith reply context - Outbound text replies as complete
message.send/message.replyframes by default; experimentalstreamReplies: truestreams direct-chat replies (see Reply Streaming) - Typing indicators and filtered forwarding for thinking / tool-call content
- Media fragments (image / file / audio / video) in either direction
- Invite-code onboarding (no raw credentials) via
/clawchat-activateor supportedopenclaw channels add, plus always-registeredclawchat_*account/media tools
Install
# Add as an OpenClaw extension
npm i @clawling/clawchat-plugin-openclawRequires openclaw >= 2026.8.1 as a peer host.
Example LLM prompt:
Install and activate the ClawChat plugin from npm package @clawling/clawchat-plugin-openclaw. The invite code is XXXXXX.Current activation paths
Pick one of these invite-code activation paths after the plugin is loaded into OpenClaw:
Runtime slash command (recommended). Send
/clawchat-activate K7RM4TQPin the chat where OpenClaw is running. Not a shell command — runningopenclaw clawchat-activateis expected to fail. This is the reliable first-time activation path on supported hosts (OpenClaw 2026.8.1 and newer).CLI
channels addwhen the host exposesclawchat-plugin-openclawin its channel catalog:openclaw channels add --channel clawchat-plugin-openclaw --token "$CLAWCHAT_INVITE_CODE" openclaw channels status --probeCLI
channels loginto refresh credentials later, once the channel already exists on the host.openclaw channels login --channel clawchat-plugin-openclaw
If channels add reports Unknown channel: clawchat-plugin-openclaw, use the
runtime slash command after the plugin is loaded.
Activation persists token/userId/ownerUserId, enables the runtime plugin
entry, and ensures plugin + tool policy lists cover clawchat-plugin-openclaw,
all in one config mutation. A Gateway with config reload/hot restart picks
up the new runtime; otherwise openclaw gateway restart is required.
See activation for persisted fields, stale-catalog recovery and bootstrap; runtime registration covers the config mutation and host reload boundary.
Standalone web chat (dev)
A minimal browser test harness is bundled under tools/:
node tools/standalone-webchat-server.mjs
# Options: --host (default 127.0.0.1), --port (default 4318), --default-ws-urlThen open the printed URL (default http://127.0.0.1:4318) to exercise the plugin end to end against a WebSocket relay.
Layout
src/
channel.ts full-runtime plugin adapter (auth.login, gateway,
agentPrompt, messaging, reload). Extends:
channel.setup.ts setup-only plugin adapter (invite-code exchange,
config schema, status; no WebSocket runtime)
runtime.ts inbound dispatch + reply dispatcher
ws-client.ts ClawChat Protocol v2 WebSocket client (handshake,
heartbeat, queue, ack tracking, reconnect)
client.ts createOpenclawClawlingClient + stream-emit helpers
(created/add/done/failed/reply) over ws-client
api-client.ts REST client for /v1/* + /media/upload
api-types.ts /v1/* request/response type definitions
inbound.ts envelope → agent turn
outbound.ts agent reply → envelope
message-mapper.ts fragment ↔ text/media mapping
group-message-coalescer.ts
per-group idle/max batching for non-mention turns
group-settings.ts per-group agent settings cache (GET /v1/agents/me/
group-settings)
reply-dispatcher.ts outbound reply routing (optional direct-chat streaming)
no-reply.ts clawchat:no-reply / :silent suppression token guard
login.runtime.ts invite-code exchange flow
refresh-manager.ts ClawChat token refresh + auto-logout orchestration
skill-update.ts conversational, adapter-driven skill hot-update
media-runtime.ts media download/upload pipeline
liveware-cli.ts liveware asset download helper (custom CDN User-Agent)
tools.ts clawchat_* agent tools (account / media / memory /
metadata / moments / mention)
tools-schema.ts JSON schemas for the clawchat_* tools
protocol.ts inbound payload type guards
protocol-types.ts v2 envelope, fragment, transport shapes
config.ts defaults + typebox schema
config-compat.ts migration for the plugin rename (openclaw-clawchat →
clawchat-plugin-openclaw id/channel key)
storage.ts plugin-owned SQLite (activations, connections,
clawchat_messages, tool_calls)
clawchat-memory.ts file-backed memory tools (see docs/clawchat-memory.md)
clawchat-metadata.ts metadata pull/push + invalidation handling
profile-sync.ts profile/metadata pull + sync into file-backed memory
profile-prompt.ts dynamic ClawChat prompt composition
prompt-injection.ts register-time wiring of the prompt injector
plugin-prompts.ts loads prompts/platform.md and default-* prompts
ws-alignment.ts handshake capabilities + hello-ok diagnostics
ws-log.ts clawchat.ws single-line log formatting
llm-context-debug.ts opt-in LLM input/output snapshot capture for debugging
plugin-report.ts best-effort read of this plugin's package version
commands.ts /clawchat-activate runtime slash command
terminal-send.ts terminal-send suppression for clawchat_mention_message
mock-transport.ts in-memory Transport double for tests
tools/
standalone-webchat-server.mjs
standalone-webchat.html
docs/
README.md typed index of the docs/ tree
clawchat-plugin-openclaw.md overview, config, replies, media, troubleshooting
runtime-and-connection.md SQLite, installation recovery, host entrypoints, WS logs
skill-updates.md bundled skills, consent, updates and tombstones
liveware-sample.md sample auto-boot, relaunch and process lifecycle
tools.md registered tools and argument/server constraints
tool-grants.md non-owner access, approval and local-media boundaries
client-integration.md Protocol v2 plugin delta and upstream pointers
activation.md activation entry points, persistence, and recovery
token-refresh.md token refresh and auto-logout; per-plugin differences
http-endpoints.md HTTP request inventory mapped to client methods
cc-memory.md legacy redirect to clawchat-memory.md
clawchat-memory.md file-backed memory contract (shared with Hermes)
mention-message.md clawchat_mention_message tool reference
per-group-mode.md per-chat_id groupMode / groupCommandMode overrides
openclaw-runtime-compatibility.md
host runtime API compatibility notes
openclaw-source-lookup.md
when/how to inspect the OpenClaw host checkoutDocumentation
Start at docs/README.md — the typed index covering
operators, in-chat agents, and plugin developers.
docs/clawchat-plugin-openclaw.md is the
configuration, replies/media and troubleshooting overview. Detailed contracts:
- Runtime and connection: SQLite, installation conflicts, reclaim, host registration, WebSocket delivery and log templates.
- Skill updates: six bundled skills, consent, integrity checks and managed-skill cleanup.
- Liveware Sample: bootstrap/relaunch, isolated CLI homes, persistence, restart budgets and recovery.
- Tools and tool grants: registered operations and non-owner access boundaries.
- Activation, memory and prompts, HTTP inventory and Protocol v2 cover their respective interfaces; the server implementation wins for wire formats.
Development
# Tests
npm test -- --run
# Typecheck
npm run typecheckTests live next to the source they cover (*.test.ts). The development entrypoint stays in TypeScript for the OpenClaw extension loader, while npm installs use the compiled runtime entrypoint generated by npm run build / prepack under dist/.
Functional E2E test cases are documented in the aggregator repo's e2e/
docs; keep that guide updated when adding or changing E2E flows.
For OpenClaw host SDK/source lookup while developing this plugin, optionally
clone OpenClaw into tmp/openclaw:
npm run dev:openclaw-source
# equivalent: git clone --depth=1 https://github.com/openclaw/openclaw.git tmp/openclawThis checkout is local-only. It is ignored by git and is not required to run the plugin tests or publish the package.
Branches and releasing
Everything reaches main through a GitHub PR; nothing is pushed to main
directly.
- Day-to-day, non-urgent changes are merged into the
pre-releasebranch, notmain, also through a GitHub PR (--base pre-release) that is squash-merged.mainonly moves when a release is cut, so it always equals the newest published version. - An urgent fix (security, widespread connection failure) may target
maindirectly with a squash-merged PR that includes the version bump; afterwards mergemainback intopre-release.
A release runs in this fixed order — never publish first and merge later, and
never tag a commit that is not on main:
Bump the version on
pre-release. Setpackage.jsonversionto the newYYYY.M.D-N(no zero padding, e.g.2026.10.7-1;-Ncounts releases on the same day) in a commit titledchore(release): openclaw <old> -> <new>, and runnpm test -- --runandnpm run typecheck.Merge
pre-releaseintomainthrough a PR, with a merge commit:( set -e gh pr create --base main --head pre-release --title "release: <version>" gh pr merge <n> --merge # merge commit, not squash test "$(gh pr view <n> --json state --jq .state)" = MERGED git fetch origin git push origin origin/main:pre-release # fast-forward pre-release to main (not a force push) )Tag the merge commit on
mainand push the tag. The tag name equals thepackage.jsonversion, without av;<n>is the release PR from step 2, whose merge commit is tagged (not whatevermainpoints to now):Use the PR's merge commit because the floating
origin/mainmay already contain a later merge.( set -e git fetch origin --tags release_commit=$(gh pr view <n> --json mergeCommit --jq .mergeCommit.oid) git merge-base --is-ancestor "$release_commit" origin/main git tag -a <version> "$release_commit" -m "<version>: <one-line summary>" git push origin <version> )Publish to npm from a clean checkout of the tag:
( set -e git worktree add --detach .worktrees/release-<version> <version> cd .worktrees/release-<version> test -z "$(git status --porcelain)" # must be clean npm install # no lockfile is committed (package-lock.json is gitignored) npm test -- --run npm run release # npm publish --tag latest; guard, typecheck, then prepack builds dist/ )The subshell stops at the first failing command, so a failed install or test never reaches
npm run release.Every
npm publishruns the release guard throughprepublishOnly, before typecheck and beforeprepackchanges the manifest. The guard requires a local annotated tag named exactly afterpackage.json's version, HEAD at that tag's commit, and a clean working tree (including non-ignored untracked files). It checks thatoriginhas the same tag object, fetchesorigin/main, and requires the tag commit to be an ancestor of that refreshed branch. Any Git error blocks publishing; there is no npm dist-tag exemption. Runnpm publish --dry-runfrom the tag checkout to exercise the guard. Never skip the guard; fix the checkout instead.Record the release. Use the commit SHA tagged in step 3 as
<sha>:gh release create <version> --verify-tag --title <version> --notes "commit: <sha> npm: @clawling/clawchat-plugin-openclaw@<version>"Add later results with
gh release edit <version> --notes "<updated notes>", keeping the commit and npm version in the notes; never move the tag.
Tag messages, PR titles, PR bodies and release notes are public like commit messages.
License
MIT — see LICENSE.
