feat: add rule dispatch, cross-plugin API, and Docker integration test

Wire rule registry and authenticated callbacks into both client and server
runtimes; expose __yonexusClient / __yonexusServer on globalThis for
cross-plugin communication. Add Docker-based integration test with
server-test-plugin (test_ping echo) and client-test-plugin (test_pong
receiver), plus docker-compose setup. Fix transport race condition where
a stale _connections entry caused promoteToAuthenticated to silently fail.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
h z
2026-04-10 20:15:09 +01:00
parent 17b9cc83f4
commit a8b2f5d9ed
12 changed files with 365 additions and 2 deletions

View File

@@ -0,0 +1,40 @@
# Build context: repo root (Yonexus/)
# ── Stage 1: compile ──────────────────────────────────────────────────────────
FROM node:22-alpine AS builder
WORKDIR /build
# Server imports Yonexus.Protocol and Yonexus.Client/crypto — all needed for tsc
COPY Yonexus.Protocol/src ./Yonexus.Protocol/src
COPY Yonexus.Client/plugin/crypto ./Yonexus.Client/plugin/crypto
COPY Yonexus.Server/package.json ./Yonexus.Server/
COPY Yonexus.Server/package-lock.json ./Yonexus.Server/
COPY Yonexus.Server/tsconfig.json ./Yonexus.Server/
COPY Yonexus.Server/plugin ./Yonexus.Server/plugin
WORKDIR /build/Yonexus.Server
RUN npm ci
RUN npm run build
# ── Stage 2: runtime ─────────────────────────────────────────────────────────
FROM node:22-alpine AS runtime
RUN npm install -g openclaw@2026.4.9
WORKDIR /app
# Layout expected by install.mjs: repoRoot = /app, sourceDist = /app/dist
COPY --from=builder /build/Yonexus.Server/dist ./dist
COPY --from=builder /build/Yonexus.Server/node_modules ./node_modules
COPY Yonexus.Server/package.json ./package.json
COPY Yonexus.Server/plugin/openclaw.plugin.json ./plugin/openclaw.plugin.json
COPY Yonexus.Server/scripts/install.mjs ./scripts/install.mjs
COPY tests/docker/server-test-plugin /app/server-test-plugin
COPY tests/docker/server/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 8787
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -0,0 +1,71 @@
#!/bin/sh
set -e
: "${CLIENT_IDENTIFIER:?CLIENT_IDENTIFIER is required}"
: "${NOTIFY_BOT_TOKEN:?NOTIFY_BOT_TOKEN is required}"
: "${ADMIN_USER_ID:?ADMIN_USER_ID is required}"
STATE_DIR=/app/.openclaw-state
PLUGIN_DIR="$STATE_DIR/plugins/Yonexus.Server"
TEST_PLUGIN_DIR="$STATE_DIR/plugins/yonexus-server-test"
SERVER_WS_URL="${PUBLIC_WS_URL:-ws://yonexus-server:8787}"
# Install plugin dist + manifest into isolated state directory
node /app/scripts/install.mjs --install --openclaw-profile-path "$STATE_DIR"
# Symlink node_modules so bare-module imports (e.g. ws) resolve from plugin dir
ln -sf /app/node_modules "$PLUGIN_DIR/node_modules"
# Install test plugin (plain .mjs, no compilation needed)
mkdir -p "$TEST_PLUGIN_DIR"
cp /app/server-test-plugin/index.mjs "$TEST_PLUGIN_DIR/"
cp /app/server-test-plugin/openclaw.plugin.json "$TEST_PLUGIN_DIR/"
# Write openclaw config — plugin id is "yonexus-server" per openclaw.plugin.json
mkdir -p "$STATE_DIR"
cat > "$STATE_DIR/openclaw.json" << EOF
{
"meta": { "lastTouchedVersion": "2026.4.9" },
"gateway": { "bind": "loopback" },
"agents": { "defaults": { "workspace": "$STATE_DIR/workspace" } },
"plugins": {
"allow": ["yonexus-server", "yonexus-server-test"],
"load": { "paths": ["$PLUGIN_DIR", "$TEST_PLUGIN_DIR"] },
"installs": {
"yonexus-server": {
"source": "path",
"sourcePath": "$PLUGIN_DIR",
"installPath": "$PLUGIN_DIR",
"version": "0.1.0",
"installedAt": "2026-04-10T00:00:00.000Z"
},
"yonexus-server-test": {
"source": "path",
"sourcePath": "$TEST_PLUGIN_DIR",
"installPath": "$TEST_PLUGIN_DIR",
"version": "0.1.0",
"installedAt": "2026-04-10T00:00:00.000Z"
}
},
"entries": {
"yonexus-server": {
"enabled": true,
"config": {
"followerIdentifiers": ["$CLIENT_IDENTIFIER"],
"notifyBotToken": "$NOTIFY_BOT_TOKEN",
"adminUserId": "$ADMIN_USER_ID",
"listenHost": "0.0.0.0",
"listenPort": 8787,
"publicWsUrl": "$SERVER_WS_URL"
}
},
"yonexus-server-test": {
"enabled": true,
"config": {}
}
}
}
}
EOF
export OPENCLAW_STATE_DIR="$STATE_DIR"
exec openclaw gateway run --allow-unconfigured