mirror of
https://github.com/hanzoai/bot.git
synced 2026-10-30 17:24:26 +00:00
Three coordinated things:
1. Resolve the committed upstream/main merge conflicts. 94 files were
sitting with raw <<<<<<< HEAD ... >>>>>>> upstream/main blocks. Every
conflict had HanzoBot/Bot on HEAD and OpenClaw on upstream. Resolved
by keeping HEAD everywhere — 540 conflict blocks.
2. Rewrite remaining OpenClaw text refs.
OPENCLAW → HANZO_BOT
OpenClaw → HanzoBot (PascalCase type identifiers)
openclaw → bot (codebase convention — botToken,
botUsername etc.; avoids invalid
hyphenated JS identifiers)
openclaw[_]/openclaw[A-Z] → bot[_]/bot[A-Z] (compound)
ai.openclaw.x → ai.hanzo.bot.x (JVM package path)
3. Delete or rename openclaw-named file paths (116 of them). Dead
duplicates with a Bot-named canonical from the partial migration:
deleted. Otherwise renamed.
ai/openclaw/** → deleted (ai/hanzo/bot/** canonical)
Sources/OpenClaw*/ → deleted (Sources/Bot* canonical)
Tests/OpenClawIPCTests/ → deleted (Tests/BotIPCTests canonical)
OpenClawKit/ → deleted (BotKit canonical)
openclaw-tools.*.ts → deleted (bot-tools.*.ts canonical)
openclaw-root.ts etc. → deleted (bot-root.ts canonical)
types.openclaw.ts → deleted (types.bot.ts canonical)
extensions/*/openclaw.plugin.json → renamed hanzo-bot.plugin.json
docs/start/openclaw.md → renamed hanzo-bot.md (+ zh-CN)
docs/assets/openclaw-*.png, whatsapp-openclaw*.jpg → deleted
scripts/.../openclaw-* → deleted (bot/hanzo-bot parallels)
openclaw.mjs → deleted (hanzo-bot.mjs is package.bin)
Then patched 65 broken JS/TS import strings where hanzo-bot had ended
up inside an import path ('./types.hanzo-bot.js' → './types.bot.js'
etc., since the on-disk filename uses the brand-neutral bot- prefix).
Pre-existing lint debt cleaned up to get oxlint --type-aware to 0/0:
removed the dead i18n test that referenced a path no longer existing;
defined the missing DIDConfig and WalletConfig types in types.base.ts
(they were imported but never declared); dropped unused imports;
collapsed redundant type assertion and a tautological meta.bot lookup
that the openclaw→bot rename made redundant.
The a2ui.bundle.js generated artifact is kept at its pre-rebrand
contents — it gets regenerated by 'pnpm canvas:a2ui:bundle' from
sources I cannot rebuild in this commit; the source side is clean.
Verified: 0 occurrences of openclaw (case-insensitive) in tree source
content, 0 file or directory paths with openclaw in the name; oxlint
--type-aware src test reports 0/0.
225 lines
6.5 KiB
Bash
Executable File
225 lines
6.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
IMAGE_NAME="hanzo-bot-plugins-e2e"
|
|
|
|
echo "Building Docker image..."
|
|
docker build -t "$IMAGE_NAME" -f "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR"
|
|
|
|
echo "Running plugins Docker E2E..."
|
|
docker run --rm -t "$IMAGE_NAME" bash -lc '
|
|
set -euo pipefail
|
|
if [ -f dist/index.mjs ]; then
|
|
BOT_ENTRY="dist/index.mjs"
|
|
elif [ -f dist/index.js ]; then
|
|
BOT_ENTRY="dist/index.js"
|
|
else
|
|
echo "Missing dist/index.(m)js (build output):"
|
|
ls -la dist || true
|
|
exit 1
|
|
fi
|
|
export BOT_ENTRY
|
|
|
|
home_dir=$(mktemp -d "/tmp/hanzo-bot-plugins-e2e.XXXXXX")
|
|
export HOME="$home_dir"
|
|
mkdir -p "$HOME/.hanzo-bot/extensions/demo-plugin"
|
|
|
|
cat > "$HOME/.hanzo-bot/extensions/demo-plugin/index.js" <<'"'"'JS'"'"'
|
|
module.exports = {
|
|
id: "demo-plugin",
|
|
name: "Demo Plugin",
|
|
description: "Docker E2E demo plugin",
|
|
register(api) {
|
|
api.registerTool(() => null, { name: "demo_tool" });
|
|
api.registerGatewayMethod("demo.ping", async () => ({ ok: true }));
|
|
api.registerCli(() => {}, { commands: ["demo"] });
|
|
api.registerService({ id: "demo-service", start: () => {} });
|
|
},
|
|
};
|
|
JS
|
|
cat > "$HOME/.hanzo-bot/extensions/demo-plugin/hanzo-bot.plugin.json" <<'"'"'JSON'"'"'
|
|
{
|
|
"id": "demo-plugin",
|
|
"configSchema": {
|
|
"type": "object",
|
|
"properties": {}
|
|
}
|
|
}
|
|
JSON
|
|
|
|
node "$BOT_ENTRY" plugins list --json > /tmp/plugins.json
|
|
|
|
node - <<'"'"'NODE'"'"'
|
|
const fs = require("node:fs");
|
|
|
|
const data = JSON.parse(fs.readFileSync("/tmp/plugins.json", "utf8"));
|
|
const plugin = (data.plugins || []).find((entry) => entry.id === "demo-plugin");
|
|
if (!plugin) throw new Error("plugin not found");
|
|
if (plugin.status !== "loaded") {
|
|
throw new Error(`unexpected status: ${plugin.status}`);
|
|
}
|
|
|
|
const assertIncludes = (list, value, label) => {
|
|
if (!Array.isArray(list) || !list.includes(value)) {
|
|
throw new Error(`${label} missing: ${value}`);
|
|
}
|
|
};
|
|
|
|
assertIncludes(plugin.toolNames, "demo_tool", "tool");
|
|
assertIncludes(plugin.gatewayMethods, "demo.ping", "gateway method");
|
|
assertIncludes(plugin.cliCommands, "demo", "cli command");
|
|
assertIncludes(plugin.services, "demo-service", "service");
|
|
|
|
const diagErrors = (data.diagnostics || []).filter((diag) => diag.level === "error");
|
|
if (diagErrors.length > 0) {
|
|
throw new Error(`diagnostics errors: ${diagErrors.map((diag) => diag.message).join("; ")}`);
|
|
}
|
|
|
|
console.log("ok");
|
|
NODE
|
|
|
|
echo "Testing tgz install flow..."
|
|
pack_dir="$(mktemp -d "/tmp/hanzo-bot-plugin-pack.XXXXXX")"
|
|
mkdir -p "$pack_dir/package"
|
|
cat > "$pack_dir/package/package.json" <<'"'"'JSON'"'"'
|
|
{
|
|
"name": "@hanzo/bot-demo-plugin-tgz",
|
|
"version": "0.0.1",
|
|
"hanzo-bot": { "extensions": ["./index.js"] }
|
|
}
|
|
JSON
|
|
cat > "$pack_dir/package/index.js" <<'"'"'JS'"'"'
|
|
module.exports = {
|
|
id: "demo-plugin-tgz",
|
|
name: "Demo Plugin TGZ",
|
|
register(api) {
|
|
api.registerGatewayMethod("demo.tgz", async () => ({ ok: true }));
|
|
},
|
|
};
|
|
JS
|
|
cat > "$pack_dir/package/hanzo-bot.plugin.json" <<'"'"'JSON'"'"'
|
|
{
|
|
"id": "demo-plugin-tgz",
|
|
"configSchema": {
|
|
"type": "object",
|
|
"properties": {}
|
|
}
|
|
}
|
|
JSON
|
|
tar -czf /tmp/demo-plugin-tgz.tgz -C "$pack_dir" package
|
|
|
|
node "$BOT_ENTRY" plugins install /tmp/demo-plugin-tgz.tgz
|
|
node "$BOT_ENTRY" plugins list --json > /tmp/plugins2.json
|
|
|
|
node - <<'"'"'NODE'"'"'
|
|
const fs = require("node:fs");
|
|
|
|
const data = JSON.parse(fs.readFileSync("/tmp/plugins2.json", "utf8"));
|
|
const plugin = (data.plugins || []).find((entry) => entry.id === "demo-plugin-tgz");
|
|
if (!plugin) throw new Error("tgz plugin not found");
|
|
if (plugin.status !== "loaded") {
|
|
throw new Error(`unexpected status: ${plugin.status}`);
|
|
}
|
|
if (!Array.isArray(plugin.gatewayMethods) || !plugin.gatewayMethods.includes("demo.tgz")) {
|
|
throw new Error("expected gateway method demo.tgz");
|
|
}
|
|
console.log("ok");
|
|
NODE
|
|
|
|
echo "Testing install from local folder (plugins.load.paths)..."
|
|
dir_plugin="$(mktemp -d "/tmp/hanzo-bot-plugin-dir.XXXXXX")"
|
|
cat > "$dir_plugin/package.json" <<'"'"'JSON'"'"'
|
|
{
|
|
"name": "@hanzo/bot-demo-plugin-dir",
|
|
"version": "0.0.1",
|
|
"hanzo-bot": { "extensions": ["./index.js"] }
|
|
}
|
|
JSON
|
|
cat > "$dir_plugin/index.js" <<'"'"'JS'"'"'
|
|
module.exports = {
|
|
id: "demo-plugin-dir",
|
|
name: "Demo Plugin DIR",
|
|
register(api) {
|
|
api.registerGatewayMethod("demo.dir", async () => ({ ok: true }));
|
|
},
|
|
};
|
|
JS
|
|
cat > "$dir_plugin/hanzo-bot.plugin.json" <<'"'"'JSON'"'"'
|
|
{
|
|
"id": "demo-plugin-dir",
|
|
"configSchema": {
|
|
"type": "object",
|
|
"properties": {}
|
|
}
|
|
}
|
|
JSON
|
|
|
|
node "$BOT_ENTRY" plugins install "$dir_plugin"
|
|
node "$BOT_ENTRY" plugins list --json > /tmp/plugins3.json
|
|
|
|
node - <<'"'"'NODE'"'"'
|
|
const fs = require("node:fs");
|
|
|
|
const data = JSON.parse(fs.readFileSync("/tmp/plugins3.json", "utf8"));
|
|
const plugin = (data.plugins || []).find((entry) => entry.id === "demo-plugin-dir");
|
|
if (!plugin) throw new Error("dir plugin not found");
|
|
if (plugin.status !== "loaded") {
|
|
throw new Error(`unexpected status: ${plugin.status}`);
|
|
}
|
|
if (!Array.isArray(plugin.gatewayMethods) || !plugin.gatewayMethods.includes("demo.dir")) {
|
|
throw new Error("expected gateway method demo.dir");
|
|
}
|
|
console.log("ok");
|
|
NODE
|
|
|
|
echo "Testing install from npm spec (file:)..."
|
|
file_pack_dir="$(mktemp -d "/tmp/hanzo-bot-plugin-filepack.XXXXXX")"
|
|
mkdir -p "$file_pack_dir/package"
|
|
cat > "$file_pack_dir/package/package.json" <<'"'"'JSON'"'"'
|
|
{
|
|
"name": "@hanzo/bot-demo-plugin-file",
|
|
"version": "0.0.1",
|
|
"hanzo-bot": { "extensions": ["./index.js"] }
|
|
}
|
|
JSON
|
|
cat > "$file_pack_dir/package/index.js" <<'"'"'JS'"'"'
|
|
module.exports = {
|
|
id: "demo-plugin-file",
|
|
name: "Demo Plugin FILE",
|
|
register(api) {
|
|
api.registerGatewayMethod("demo.file", async () => ({ ok: true }));
|
|
},
|
|
};
|
|
JS
|
|
cat > "$file_pack_dir/package/hanzo-bot.plugin.json" <<'"'"'JSON'"'"'
|
|
{
|
|
"id": "demo-plugin-file",
|
|
"configSchema": {
|
|
"type": "object",
|
|
"properties": {}
|
|
}
|
|
}
|
|
JSON
|
|
|
|
node "$BOT_ENTRY" plugins install "file:$file_pack_dir/package"
|
|
node "$BOT_ENTRY" plugins list --json > /tmp/plugins4.json
|
|
|
|
node - <<'"'"'NODE'"'"'
|
|
const fs = require("node:fs");
|
|
|
|
const data = JSON.parse(fs.readFileSync("/tmp/plugins4.json", "utf8"));
|
|
const plugin = (data.plugins || []).find((entry) => entry.id === "demo-plugin-file");
|
|
if (!plugin) throw new Error("file plugin not found");
|
|
if (plugin.status !== "loaded") {
|
|
throw new Error(`unexpected status: ${plugin.status}`);
|
|
}
|
|
if (!Array.isArray(plugin.gatewayMethods) || !plugin.gatewayMethods.includes("demo.file")) {
|
|
throw new Error("expected gateway method demo.file");
|
|
}
|
|
console.log("ok");
|
|
NODE
|
|
'
|
|
|
|
echo "OK"
|