Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,14 @@ ENV NPM_CONFIG_OFFLINE=true \
NPM_CONFIG_FUND=false

# Install NemoClaw plugin into OpenClaw (local /opt/nemoclaw, no network).
# Re-apply WeChat account seeding after OpenClaw doctor/plugin-install touches
# openclaw.json; the seed script no-ops unless WeChat is actively configured.
# Prune non-runtime metadata from staged bundled plugin dependencies before
# this layer is committed; deleting it in a later layer would not reduce the
# OCI image imported by k3s.
# hadolint ignore=DL3059,DL4006
RUN (openclaw plugins install /opt/nemoclaw > /dev/null 2>&1 || true) \
&& python3 /usr/local/lib/nemoclaw/seed-wechat-accounts.py \
&& if [ -d /sandbox/.openclaw/plugin-runtime-deps ]; then \
find /sandbox/.openclaw/plugin-runtime-deps -type f \( \
-name '*.d.ts' -o -name '*.d.mts' -o -name '*.d.cts' -o \
Expand Down
36 changes: 34 additions & 2 deletions scripts/seed-wechat-accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
# is registered. Without channels.openclaw-weixin.accounts.<id>.enabled=true
# in openclaw.json, the plugin's auth/accounts.ts considers the account
# disabled and the bridge won't start, even if the per-account state files
# above exist. generate-openclaw-config.py invokes this only after
# plugins.installs.openclaw-weixin has been preserved from the base image.
# above exist. The patch also restores the openclaw-weixin plugin registry
# entry because later OpenClaw config rewrites can drop it while leaving the
# pre-installed extension files in place.
#
# State dir resolution mirrors the upstream's resolveStateDir():
# $OPENCLAW_STATE_DIR || $CLAWDBOT_STATE_DIR || ~/.openclaw
Expand Down Expand Up @@ -53,6 +54,12 @@
import sys


WECHAT_PLUGIN_ID = "openclaw-weixin"
WECHAT_PLUGIN_SPEC = "@tencent-weixin/openclaw-weixin@2.4.2"
WECHAT_PLUGIN_INSTALL = {
"source": "npm",
"spec": WECHAT_PLUGIN_SPEC,
}
WECHAT_TOKEN_PLACEHOLDER = "openshell:resolve:env:WECHAT_BOT_TOKEN"


Expand Down Expand Up @@ -141,6 +148,31 @@ def _patch_openclaw_config(account_id: str) -> None:
)
return

plugins = cfg.setdefault("plugins", {})
if not isinstance(plugins, dict):
plugins = {}
cfg["plugins"] = plugins
installs = plugins.setdefault("installs", {})
if not isinstance(installs, dict):
installs = {}
plugins["installs"] = installs
wechat_install = installs.get(WECHAT_PLUGIN_ID)
if (
not isinstance(wechat_install, dict)
or wechat_install.get("source") != WECHAT_PLUGIN_INSTALL["source"]
or not wechat_install.get("spec")
):
installs[WECHAT_PLUGIN_ID] = dict(WECHAT_PLUGIN_INSTALL)
entries = plugins.setdefault("entries", {})
if not isinstance(entries, dict):
entries = {}
plugins["entries"] = entries
wechat_entry = entries.setdefault(WECHAT_PLUGIN_ID, {})
if not isinstance(wechat_entry, dict):
wechat_entry = {}
entries[WECHAT_PLUGIN_ID] = wechat_entry
wechat_entry["enabled"] = True

channels = cfg.setdefault("channels", {})
weixin = channels.setdefault("openclaw-weixin", {})
weixin["channelConfigUpdatedAt"] = _js_iso_utc()
Expand Down
Loading