#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DIST_DIR="${SCRIPT_DIR}/dist"
echo "[install_to_image] 开始构建 subagent-coordinator..."
cd "${SCRIPT_DIR}"
if ! command -v pnpm &> /dev/null; then
echo "[install_to_image] 安装 pnpm..."
npm install -g pnpm
fi
OPENCLAW_VERSION="${OPENCLAW_VERSION:-2026.4.11}"
PLUGIN_SDK_DIR="/tmp/openclaw-src/packages/plugin-sdk"
if [[ ! -d "$PLUGIN_SDK_DIR" ]]; then
echo "[install_to_image] 克隆 openclaw v${OPENCLAW_VERSION} 获取 plugin-sdk..."
if git clone --depth 1 --branch "v${OPENCLAW_VERSION}" \
https://github.com/openclaw/openclaw.git /tmp/openclaw-src 2>&1; then
echo "[install_to_image] 克隆 openclaw 成功"
else
echo "[install_to_image] 克隆失败,尝试使用本地路径..."
rm -rf /tmp/openclaw-src
if [[ -n "$PLUGIN_SDK_SRC" && -d "$PLUGIN_SDK_SRC" ]]; then
echo "[install_to_image] 使用环境变量指定的 plugin-sdk: ${PLUGIN_SDK_SRC}"
mkdir -p node_modules/openclaw
ln -sfn "$PLUGIN_SDK_SRC" node_modules/openclaw/plugin-sdk
elif [[ -d "${SCRIPT_DIR}/../../docker/.openclaw-src-tmp/packages/plugin-sdk" ]]; then
LOCAL_PLUGIN_SDK="${SCRIPT_DIR}/../../docker/.openclaw-src-tmp/packages/plugin-sdk"
echo "[install_to_image] 使用本地 plugin-sdk: ${LOCAL_PLUGIN_SDK}"
mkdir -p node_modules/openclaw
ln -sfn "$LOCAL_PLUGIN_SDK" node_modules/openclaw/plugin-sdk
elif [[ -d "/tmp/.openclaw-src/packages/plugin-sdk" ]]; then
echo "[install_to_image] 使用缓存的 plugin-sdk"
mkdir -p node_modules/openclaw
ln -sfn "/tmp/.openclaw-src/packages/plugin-sdk" node_modules/openclaw/plugin-sdk
else
echo "[install_to_image] 错误: 无法获取 plugin-sdk(克隆失败,且无有效的本地路径)"
echo "[install_to_image] 可设置 PLUGIN_SDK_SRC 环境变量指定本地 plugin-sdk 路径"
exit 1
fi
fi
fi
if [[ -d "$PLUGIN_SDK_DIR" ]]; then
mkdir -p node_modules/openclaw
ln -sfn "$PLUGIN_SDK_DIR" node_modules/openclaw/plugin-sdk
echo "[install_to_image] plugin-sdk 准备完成"
fi
echo "[install_to_image] 安装依赖..."
pnpm install --config.minimum-release-age=0
echo "[install_to_image] 构建插件..."
pnpm build || true
echo "[install_to_image] 确保各插件 dist 产物存在..."
for plugin in plugins/*/; do
plugin_name=$(basename "$plugin")
expected_dist="${plugin}dist/plugins/${plugin_name}/src/index.js"
if [[ -f "$expected_dist" ]]; then
echo "[install_to_image] ${plugin_name} dist 已存在 (${expected_dist}),跳过"
else
echo "[install_to_image] 警告: ${plugin_name} 缺少产物 ${expected_dist},将依赖 pnpm build 产物"
fi
done
echo "[install_to_image] 准备产物目录: ${DIST_DIR}"
mkdir -p "${DIST_DIR}"
echo "[install_to_image] 复制插件产物..."
for plugin in plugins/*/; do
plugin_name=$(basename "$plugin")
if [[ -d "${plugin}dist" ]]; then
echo "[install_to_image] 复制 ${plugin_name}..."
mkdir -p "${DIST_DIR}/plugins/${plugin_name}"
src_dir="${plugin}dist/plugins/${plugin_name}/src"
if [[ -d "$src_dir" ]]; then
cp -r "$src_dir"/* "${DIST_DIR}/plugins/${plugin_name}/"
else
nested_dir="${plugin}dist/plugins/${plugin_name}"
if [[ -d "$nested_dir" ]]; then
cp -r "$nested_dir"/* "${DIST_DIR}/plugins/${plugin_name}/"
else
cp -r "${plugin}dist"/* "${DIST_DIR}/plugins/${plugin_name}/"
fi
fi
if [[ -f "${plugin}openclaw.plugin.json" ]]; then
cp "${plugin}openclaw.plugin.json" "${DIST_DIR}/plugins/${plugin_name}/"
fi
if [[ -f "${plugin}dist/package.json" ]]; then
cp "${plugin}dist/package.json" "${DIST_DIR}/plugins/${plugin_name}/"
fi
if [[ -d "packages/types/dist" ]]; then
mkdir -p "${DIST_DIR}/plugins/${plugin_name}/node_modules/@subagent-coordinator"
mkdir -p "${DIST_DIR}/plugins/${plugin_name}/node_modules/@subagent-coordinator/types"
if [[ -d "packages/types/dist/src" ]]; then
cp -r "packages/types/dist/src"/* "${DIST_DIR}/plugins/${plugin_name}/node_modules/@subagent-coordinator/types/"
else
cp -r "packages/types/dist"/* "${DIST_DIR}/plugins/${plugin_name}/node_modules/@subagent-coordinator/types/"
fi
cat > "${DIST_DIR}/plugins/${plugin_name}/node_modules/@subagent-coordinator/types/package.json" << 'PKGJSON'
{
"name": "@subagent-coordinator/types",
"version": "0.0.3",
"type": "commonjs",
"main": "./index.js",
"types": "./index.d.ts"
}
PKGJSON
fi
local typebox_source=""
typebox_source=$(compgen -G "node_modules/.pnpm/@sinclair+typebox@*/node_modules/@sinclair/typebox" | head -n 1 || true)
if [[ -n "$typebox_source" && -d "$typebox_source" ]]; then
mkdir -p "${DIST_DIR}/plugins/${plugin_name}/node_modules/@sinclair"
cp -RL "$typebox_source" "${DIST_DIR}/plugins/${plugin_name}/node_modules/@sinclair/typebox"
else
echo "[install_to_image] 警告: 未找到 @sinclair/typebox 源(node_modules/.pnpm/@sinclair+typebox@*/node_modules/@sinclair/typebox),镜像安装时可能需要补充"
fi
if [[ -d "${DIST_DIR}/plugins/${plugin_name}/node_modules" ]]; then
find "${DIST_DIR}/plugins/${plugin_name}/node_modules" -maxdepth 3 -type l -lname '*/.pnpm/*' -exec rm -f {} \; 2>/dev/null || true
fi
fi
done
if [[ -f "package.json" ]]; then
cp "package.json" "${DIST_DIR}/"
fi
echo "[install_to_image] 完成!产物目录: ${DIST_DIR}"
ls -la "${DIST_DIR}"