openclaw-multi-auto 1.5.6 → 1.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{accounts-C_lW3Ag9.js → accounts-BOzyfwW4.js} +2 -2
- package/dist/{accounts-C9HcPI9h.js → accounts-L9ByEpnP.js} +2 -2
- package/dist/{accounts-Tgelvk0C.js → accounts-yfBeCZtS.js} +17 -17
- package/dist/{active-listener-BEdprTkn.js → active-listener-D1yqT1cw.js} +2 -2
- package/dist/{api-key-rotation-BJpKWXy0.js → api-key-rotation-DtsNS2Nb.js} +2 -2
- package/dist/{audio-preflight-BMvgEQ5j.js → audio-preflight-DpxQCpsA.js} +32 -32
- package/dist/{audio-transcription-runner-gLFfz8fr.js → audio-transcription-runner-28fcRNNi.js} +12 -12
- package/dist/{audit-membership-runtime-Dntemq07.js → audit-membership-runtime-DWyHWAHM.js} +4 -4
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +51 -51
- package/dist/bundled/bootstrap-extra-files/handler.js +6 -6
- package/dist/bundled/command-logger/handler.js +2 -2
- package/dist/bundled/session-memory/handler.js +51 -51
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{channel-activity-BDnjYF7B.js → channel-activity-xHOMiarp.js} +3 -3
- package/dist/{chrome-DxxEKrY7.js → chrome-DwizpzOC.js} +18 -18
- package/dist/{commands-registry-D5qXbFJn.js → commands-registry-V1zZ5pPC.js} +4 -4
- package/dist/{deliver-DbdywYJE.js → deliver-D4o6VIur.js} +21 -21
- package/dist/deliver-runtime-P-G3bPjW.js +36 -0
- package/dist/deps-send-discord.runtime-DnbhTFX9.js +26 -0
- package/dist/deps-send-imessage.runtime-BOiQ6mDx.js +25 -0
- package/dist/deps-send-signal.runtime-CTcl388M.js +24 -0
- package/dist/deps-send-slack.runtime-CCqBz4Kg.js +22 -0
- package/dist/deps-send-telegram.runtime-DGSKTCpH.js +27 -0
- package/dist/deps-send-whatsapp.runtime-CJkTHkah.js +60 -0
- package/dist/{diagnostic-Co6Kghr-.js → diagnostic-Bn4PZjMZ.js} +2 -2
- package/dist/{errors-xt401nuk.js → errors-CCLeFWAg.js} +1 -1
- package/dist/{fetch-DuraYswo.js → fetch-BlJWzEP6.js} +5 -5
- package/dist/{fetch-guard-DWr0d00H.js → fetch-guard-ChYBwfiy.js} +2 -2
- package/dist/{frontmatter-BkTfEZ93.js → frontmatter-CvaMP376.js} +3 -3
- package/dist/{fs-safe-CTYUrIgQ.js → fs-safe-0jAo_Whb.js} +4 -4
- package/dist/{github-copilot-token-BDioPmd6.js → github-copilot-token-D13V9YBz.js} +7 -7
- package/dist/{image-eT7Y-nP5.js → image-Bbn53mzj.js} +6 -6
- package/dist/{image-ops-BuUnEOE0.js → image-ops-CehkHxmW.js} +2 -2
- package/dist/image-runtime-CVv2ra9J.js +29 -0
- package/dist/{ir-B83looB-.js → ir-DAP-B-Xw.js} +8 -8
- package/dist/{legacy-names-DOC03BkU.js → legacy-names-TyzbVqa_.js} +1 -1
- package/dist/llm-slug-generator.js +51 -51
- package/dist/{logger-BfjWMCSD.js → logger-DMZQQtxK.js} +7 -7
- package/dist/{login-CrIwcrVI.js → login-DiCctRo1.js} +5 -5
- package/dist/{login-qr-BpPDZdl_.js → login-qr-MUbXgjtd.js} +10 -10
- package/dist/{manager-1bvuGrNR.js → manager-BW_NSIMl.js} +13 -13
- package/dist/manager-runtime-BN6VevdC.js +18 -0
- package/dist/{model-selection-Dna0Gz1k.js → model-selection-idoqPmw0.js} +43 -43
- package/dist/{outbound-ChDjtuD6.js → outbound-C2kanETZ.js} +6 -6
- package/dist/{outbound-attachment-DqHlD21U.js → outbound-attachment-DBrYWX8h.js} +2 -2
- package/dist/{path-alias-guards-BzvdLvTI.js → path-alias-guards-DqXRZmsL.js} +1 -1
- package/dist/{paths-Cvc9EM8Y.js → paths-C6TxBCvO.js} +5 -5
- package/dist/{paths-Bkr-BCxW.js → paths-CCxysrzL.js} +4 -4
- package/dist/{pi-embedded-BQQa91aA.js → pi-embedded-BaGj07T0.js} +158 -158
- package/dist/{pi-embedded-helpers-CLXm10bV.js → pi-embedded-helpers-wy0DZvx1.js} +52 -52
- package/dist/{pi-model-discovery-Dymwdjt0.js → pi-model-discovery-BGgOlX8N.js} +7 -7
- package/dist/pi-model-discovery-runtime-Bwmi4Ev8.js +11 -0
- package/dist/{pi-tools.before-tool-call.runtime-Cwab_5W1.js → pi-tools.before-tool-call.runtime-BuLxSyx9.js} +9 -9
- package/dist/plugin-sdk/mattermost.js +3 -3
- package/dist/{plugins-4Rj4OjLY.js → plugins-CWkRQYDj.js} +11 -11
- package/dist/{proxy-env-DlmzDx8x.js → proxy-env-Cq5gdrbj.js} +1 -1
- package/dist/{proxy-fetch-B2pEfjbR.js → proxy-fetch-CCjEYbFm.js} +1 -1
- package/dist/{pw-ai-DNMjFMqH.js → pw-ai-Cl1Lc7RC.js} +14 -14
- package/dist/{qmd-manager-BtIKUaO9.js → qmd-manager-BsYsO9Ii.js} +10 -10
- package/dist/{query-expansion-CX-1fS52.js → query-expansion-DtLc3wjL.js} +6 -6
- package/dist/{redact-COik8ET1.js → redact-ClbcYG1J.js} +1 -1
- package/dist/{run-with-concurrency-BgYfgkXT.js → run-with-concurrency-D_ZpbgEG.js} +4 -4
- package/dist/runtime-whatsapp-login.runtime-IeylZEl4.js +13 -0
- package/dist/runtime-whatsapp-outbound.runtime-ClBRuLsq.js +22 -0
- package/dist/{send-dfu6_rgf.js → send-BQERFNyo.js} +5 -5
- package/dist/{send-L7gRiwyd.js → send-Bj776ESJ.js} +7 -7
- package/dist/{send-PE6cwoTe.js → send-DcxmcFi_.js} +8 -8
- package/dist/{send-6lz6rNVP.js → send-Dx2RkUOZ.js} +6 -6
- package/dist/{send-BHTiZcH3.js → send-vmONuVgL.js} +26 -26
- package/dist/{session-D8ImowSs.js → session-A4QhBRvH.js} +8 -8
- package/dist/{skill-commands-DNqJ-kwn.js → skill-commands-CMzBZKG2.js} +9 -9
- package/dist/{skills-7ODkHQYp.js → skills-CE_iqvM5.js} +22 -22
- package/dist/slash-commands.runtime-Cpn2tYW4.js +16 -0
- package/dist/slash-dispatch.runtime-DoBAQBU5.js +56 -0
- package/dist/slash-skill-commands.runtime-DKMvvdDW.js +20 -0
- package/dist/{store-D89wDcz9.js → store--eR1R_UX.js} +2 -2
- package/dist/subagent-registry-runtime-ppWS3tVu.js +56 -0
- package/dist/{subsystem-B45WV3qB.js → subsystem-Di1z8l0Z.js} +14 -14
- package/dist/{tables-mE4cJBN2.js → tables-d739Y1xW.js} +1 -1
- package/dist/{target-errors-mnlwhAjP.js → target-errors-CBI2Ga0y.js} +2 -2
- package/dist/{thinking-BeGmb5k6.js → thinking-DXYisHiZ.js} +7 -7
- package/dist/{tokens-q32vI39c.js → tokens-DxnY9ui_.js} +1 -1
- package/dist/{tool-images-RZdHiZcG.js → tool-images-2cBx1W8h.js} +2 -2
- package/dist/{web-Btj-e8kN.js → web-CzWRVmFt.js} +55 -55
- package/dist/{whatsapp-actions-BHbJJyqw.js → whatsapp-actions-iEArE_Ez.js} +21 -21
- package/dist/{workspace-U-DyR64O.js → workspace-CUVC6GX1.js} +20 -20
- package/package.json +1 -1
- package/scripts/create-instance.sh +151 -418
- package/dist/deliver-runtime-BFs7iAZF.js +0 -36
- package/dist/deps-send-discord.runtime-DZUccI6Z.js +0 -26
- package/dist/deps-send-imessage.runtime-CF3OpoqY.js +0 -25
- package/dist/deps-send-signal.runtime-Cw4-ozeO.js +0 -24
- package/dist/deps-send-slack.runtime-BDsDhS1P.js +0 -22
- package/dist/deps-send-telegram.runtime-D_4xVasO.js +0 -27
- package/dist/deps-send-whatsapp.runtime-DK8jqd14.js +0 -60
- package/dist/image-runtime-BcAK3n8a.js +0 -29
- package/dist/manager-runtime-FO1Sx3W8.js +0 -18
- package/dist/pi-model-discovery-runtime-BeY4EUPp.js +0 -11
- package/dist/runtime-whatsapp-login.runtime-DUb55byQ.js +0 -13
- package/dist/runtime-whatsapp-outbound.runtime-Bii_xSfI.js +0 -22
- package/dist/slash-commands.runtime-CVw6566g.js +0 -16
- package/dist/slash-dispatch.runtime-B9Ygtzi4.js +0 -56
- package/dist/slash-skill-commands.runtime-DxZ4z5h6.js +0 -20
- package/dist/subagent-registry-runtime-DL1Wv7nA.js +0 -56
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# =================================================================
|
|
3
3
|
# OpenClaw 深度集成初始化工具 (create-instance.sh)
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# 增强:支持 --profile 命令行习惯,自动配置 profile 软链接
|
|
4
|
+
# 功能:安装全局运行时、安装扩展、创建实例目录、复制文件、配置模型、启动服务
|
|
5
|
+
# 正确顺序:安装全局 openclaw → 安装 page-action-cache → 创建实例
|
|
7
6
|
# =================================================================
|
|
8
7
|
|
|
9
8
|
set -e
|
|
@@ -15,75 +14,130 @@ YELLOW='\033[1;33m'
|
|
|
15
14
|
BLUE='\033[0;34m'
|
|
16
15
|
NC='\033[0m'
|
|
17
16
|
|
|
18
|
-
# --- 检查必要命令 ---
|
|
17
|
+
# --- 0. 检查必要命令 ---
|
|
18
|
+
echo -e "${BLUE}🔍 检查必要命令...${NC}"
|
|
19
19
|
for cmd in node pnpm; do
|
|
20
20
|
if ! command -v "$cmd" &> /dev/null; then
|
|
21
21
|
echo -e "${RED}❌ 错误: 未找到命令 '$cmd',请先安装${NC}"
|
|
22
22
|
exit 1
|
|
23
23
|
fi
|
|
24
24
|
done
|
|
25
|
+
echo -e "${GREEN}✅ 必要命令检查完成${NC}"
|
|
25
26
|
|
|
26
|
-
# --- 1.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
# --- 1. 设置全局目录 ---
|
|
28
|
+
GLOBAL_DIR="$HOME/openclaw-runtime"
|
|
29
|
+
echo -e "${BLUE}📂 全局运行时目录: $GLOBAL_DIR${NC}"
|
|
30
|
+
|
|
31
|
+
# 创建全局目录
|
|
32
|
+
if [ ! -d "$GLOBAL_DIR" ]; then
|
|
33
|
+
echo -e "${YELLOW}📁 创建全局目录...${NC}"
|
|
34
|
+
mkdir -p "$GLOBAL_DIR"
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
cd "$GLOBAL_DIR"
|
|
38
|
+
echo -e "${GREEN}✅ 切换到全局目录: $(pwd)${NC}"
|
|
39
|
+
|
|
40
|
+
# --- 2. 安装全局 openclaw-multi-auto ---
|
|
41
|
+
echo -e "${BLUE}🤖 正在检查/安装全局 openclaw-multi-auto...${NC}"
|
|
42
|
+
|
|
43
|
+
# 检查是否已安装 openclaw-multi-auto
|
|
44
|
+
if pnpm list openclaw-multi-auto 2>&1 | grep -q "openclaw-multi-auto"; then
|
|
45
|
+
echo -e "${YELLOW}⚠️ openclaw-multi-auto 已在全局安装${NC}"
|
|
46
|
+
echo -e "${YELLOW}💡 如需更新,请使用: pnpm install openclaw-multi-auto@latest${NC}"
|
|
30
47
|
else
|
|
31
|
-
|
|
32
|
-
if
|
|
33
|
-
|
|
34
|
-
echo -e "${
|
|
35
|
-
|
|
36
|
-
GLOBAL_PREFIX=$(npm config get prefix)
|
|
37
|
-
SOURCE_CODE="${GLOBAL_PREFIX}/lib/node_modules/openclaw-multi-auto"
|
|
38
|
-
echo -e "${YELLOW}⚠️ 未找到环境变量和本地路径,尝试使用全局安装路径: $SOURCE_CODE${NC}"
|
|
48
|
+
echo -e "${YELLOW}📦 正在安装 openclaw-multi-auto 到全局目录...${NC}"
|
|
49
|
+
if ! pnpm install openclaw-multi-auto --registry=https://registry.npmmirror.com 2>&1; then
|
|
50
|
+
echo -e "${RED}❌ openclaw-multi-auto 安装失败${NC}"
|
|
51
|
+
echo -e "${YELLOW}💡 提示: 请检查网络连接或包名是否正确${NC}"
|
|
52
|
+
exit 1
|
|
39
53
|
fi
|
|
54
|
+
echo -e "${GREEN}✅ openclaw-multi-auto 安装成功${NC}"
|
|
40
55
|
fi
|
|
41
56
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
echo -e "${
|
|
57
|
+
# 检查全局安装结果
|
|
58
|
+
if [ ! -d "node_modules/openclaw-multi-auto" ]; then
|
|
59
|
+
echo -e "${RED}❌ 严重错误: openclaw-multi-auto 未正确安装到 node_modules${NC}"
|
|
45
60
|
exit 1
|
|
46
61
|
fi
|
|
47
62
|
|
|
48
|
-
|
|
63
|
+
SOURCE_CODE="$GLOBAL_DIR/node_modules/openclaw-multi-auto"
|
|
64
|
+
echo -e "${GREEN}✅ 全局 openclaw-multi-auto 路径: $SOURCE_CODE${NC}"
|
|
65
|
+
|
|
66
|
+
# --- 3. 安装 page-action-cache 扩展到全局目录 ---
|
|
67
|
+
echo -e "${BLUE}🤖 正在安装 page-action-cache 扩展到全局目录...${NC}"
|
|
68
|
+
|
|
69
|
+
# 创建 extensions 目录
|
|
70
|
+
EXTENSIONS_DIR="$GLOBAL_DIR/extensions"
|
|
71
|
+
if [ ! -d "$EXTENSIONS_DIR" ]; then
|
|
72
|
+
echo -e "${YELLOW}📁 创建 extensions 目录...${NC}"
|
|
73
|
+
mkdir -p "$EXTENSIONS_DIR"
|
|
74
|
+
fi
|
|
49
75
|
|
|
50
|
-
#
|
|
76
|
+
# 检查 page-action-cache 是否已安装
|
|
77
|
+
if [ -d "$EXTENSIONS_DIR/page-action-cache" ]; then
|
|
78
|
+
echo -e "${YELLOW}⚠️ page-action-cache 已在全局安装${NC}"
|
|
79
|
+
echo -e "${YELLOW}💡 如需更新,请手动更新${NC}"
|
|
80
|
+
else
|
|
81
|
+
echo -e "${YELLOW}📦 正在安装 page-action-cache 到全局 extensions 目录...${NC}"
|
|
82
|
+
if ! pnpm add page-action-cache --registry=https://registry.npmmirror.com 2>&1; then
|
|
83
|
+
echo -e "${RED}❌ page-action-cache 安装失败${NC}"
|
|
84
|
+
echo -e "${YELLOW}💡 提示: 请检查网络连接或包名是否正确${NC}"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# 复制 page-action-cache 到 extensions 目录
|
|
89
|
+
if [ -d "node_modules/page-action-cache" ]; then
|
|
90
|
+
echo -e "${YELLOW}📁 复制 page-action-cache 到 extensions 目录...${NC}"
|
|
91
|
+
cp -r "node_modules/page-action-cache" "$EXTENSIONS_DIR/"
|
|
92
|
+
echo -e "${GREEN}✅ page-action-cache 安装并复制成功${NC}"
|
|
93
|
+
else
|
|
94
|
+
echo -e "${YELLOW}⚠️ page-action-cache 已安装但未在 node_modules 中找到${NC}"
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
echo -e "${GREEN}✅ 全局扩展安装完成${NC}"
|
|
99
|
+
echo -e "${BLUE}📝 全局运行时已就绪${NC}"
|
|
100
|
+
|
|
101
|
+
# --- 4. 获取实例名称 ---
|
|
51
102
|
INSTANCE_NAME="${1:-}"
|
|
52
103
|
if [ -z "$INSTANCE_NAME" ]; then
|
|
53
104
|
read -p "请输入实例名称 (默认: yunwei): " INPUT_NAME
|
|
54
105
|
INSTANCE_NAME="${INPUT_NAME:-yunwei}"
|
|
55
106
|
fi
|
|
56
107
|
|
|
57
|
-
# ---
|
|
108
|
+
# --- 5. 获取端口 ---
|
|
58
109
|
if [ -n "$2" ]; then
|
|
59
110
|
PORT="$2"
|
|
60
111
|
else
|
|
112
|
+
INSTANCES_BASE=$(eval echo "$HOME/openclaws")
|
|
61
113
|
EXISTING_COUNT=$(find "$INSTANCES_BASE" -maxdepth 1 -type d -name "*" ! -name ".*" 2>/dev/null | wc -l | tr -d ' ')
|
|
62
114
|
PORT=$((18789 + EXISTING_COUNT * 100))
|
|
63
115
|
fi
|
|
64
116
|
|
|
65
|
-
# ---
|
|
117
|
+
# --- 6. 定义实例目录并清理旧残留 ---
|
|
118
|
+
INSTANCES_BASE=$(eval echo "$HOME/openclaws")
|
|
66
119
|
INSTANCE_DIR="$INSTANCES_BASE/${INSTANCE_NAME}"
|
|
67
120
|
DIST_DIR="${INSTANCE_DIR}/dist"
|
|
68
121
|
|
|
69
122
|
echo -e "${BLUE}🏗️ 正在深度初始化实例: ${INSTANCE_NAME} (端口 ${PORT})${NC}"
|
|
70
123
|
echo "SOURCE_CODE = $SOURCE_CODE"
|
|
124
|
+
echo "GLOBAL_DIR = $GLOBAL_DIR"
|
|
71
125
|
|
|
72
126
|
if [ -d "$INSTANCE_DIR" ]; then
|
|
73
127
|
echo -e "${YELLOW}⚠️ 清理旧实例目录...${NC}"
|
|
74
128
|
rm -rf "$INSTANCE_DIR"
|
|
75
129
|
fi
|
|
76
|
-
[ -d "${INSTANCES_BASE}/node_modules" ] && rm -rf "${INSTANCES_BASE}/node_modules"
|
|
77
|
-
[ -f "${INSTANCES_BASE}/pnpm-workspace.yaml" ] && rm -f "${INSTANCES_BASE}/pnpm-workspace.yaml"
|
|
78
130
|
|
|
79
|
-
# ---
|
|
131
|
+
# --- 7. 完整目录结构创建 ---
|
|
132
|
+
echo -e "${YELLOW}📁 创建实例目录结构...${NC}"
|
|
80
133
|
mkdir -p "${INSTANCE_DIR}/config" "${INSTANCE_DIR}/tmp" "${INSTANCE_DIR}/workspace"
|
|
81
134
|
mkdir -p "${INSTANCE_DIR}/state"
|
|
82
135
|
mkdir -p "${INSTANCE_DIR}/workspace/memory"
|
|
83
136
|
mkdir -p "${INSTANCE_DIR}/agents/main/agent/sessions"
|
|
84
137
|
mkdir -p "${INSTANCE_DIR}/credentials" "${INSTANCE_DIR}/media"
|
|
138
|
+
echo -e "${GREEN}✅ 目录结构创建完成${NC}"
|
|
85
139
|
|
|
86
|
-
# ---
|
|
140
|
+
# --- 8. 动态提取母本版本号 ---
|
|
87
141
|
echo -e "${BLUE}🔍 正在提取母本版本信息...${NC}"
|
|
88
142
|
PKG_PATH="${SOURCE_CODE}/package.json"
|
|
89
143
|
if [ -f "$PKG_PATH" ]; then
|
|
@@ -94,13 +148,15 @@ else
|
|
|
94
148
|
echo -e "${YELLOW}⚠️ 未找到 package.json,使用兜底版本: ${CURRENT_VERSION}${NC}"
|
|
95
149
|
fi
|
|
96
150
|
|
|
97
|
-
# ---
|
|
98
|
-
echo -e "${BLUE}🔄
|
|
151
|
+
# --- 9. 从全局目录复制到实例目录 ---
|
|
152
|
+
echo -e "${BLUE}🔄 从全局运行时复制到实例目录...${NC}"
|
|
99
153
|
|
|
100
154
|
# 定义需要复制的目录和文件
|
|
101
155
|
DIRS_TO_COPY="dist extensions scripts skills docs ui assets"
|
|
102
156
|
FILES_TO_COPY="package.json openclaw.mjs"
|
|
103
157
|
|
|
158
|
+
cd "$SOURCE_CODE"
|
|
159
|
+
|
|
104
160
|
# 复制所有必要目录
|
|
105
161
|
for dir in $DIRS_TO_COPY; do
|
|
106
162
|
if [ -d "${SOURCE_CODE}/${dir}" ]; then
|
|
@@ -130,17 +186,13 @@ fi
|
|
|
130
186
|
|
|
131
187
|
echo -e "${GREEN}✅ 核心代码复制完成${NC}"
|
|
132
188
|
|
|
189
|
+
# --- 10. 安装实例依赖 ---
|
|
133
190
|
export SHARP_BINARY_HOST="https://npmmirror.com/mirrors/sharp"
|
|
134
191
|
export SHARP_LIBVIPS_BINARY_HOST="https://npmmirror.com/mirrors/sharp-libvips"
|
|
135
192
|
|
|
136
193
|
cd "${INSTANCE_DIR}"
|
|
137
194
|
echo -e "${YELLOW}📍 安装路径确认: $(pwd)${NC}"
|
|
138
195
|
|
|
139
|
-
if [ -f "${INSTANCES_BASE}/pnpm-workspace.yaml" ]; then
|
|
140
|
-
echo -e "${YELLOW}⚠️ 检测到 ${INSTANCES_BASE}/pnpm-workspace.yaml,临时重命名以避免干扰${NC}"
|
|
141
|
-
mv "${INSTANCES_BASE}/pnpm-workspace.yaml" "${INSTANCES_BASE}/pnpm-workspace.yaml.bak.$(date +%s)"
|
|
142
|
-
fi
|
|
143
|
-
|
|
144
196
|
echo -e "${BLUE}📦 安装依赖包...${NC}"
|
|
145
197
|
pnpm install --shamefully-hoist --ignore-workspace --registry=https://registry.npmmirror.com
|
|
146
198
|
|
|
@@ -150,70 +202,7 @@ if [ ! -d "node_modules" ]; then
|
|
|
150
202
|
fi
|
|
151
203
|
echo -e "${GREEN}✅ 依赖安装成功,node_modules 已生成在实例目录${NC}"
|
|
152
204
|
|
|
153
|
-
# ---
|
|
154
|
-
echo -e "${BLUE}🤖 正在安装 page-action-cache 扩展到全局目录...${NC}"
|
|
155
|
-
|
|
156
|
-
# 全局目录路径
|
|
157
|
-
GLOBAL_DIR="$HOME/openclaw-runtime"
|
|
158
|
-
echo -e "${BLUE}📂 全局目录: $GLOBAL_DIR${NC}"
|
|
159
|
-
|
|
160
|
-
# 检测可用的包管理器
|
|
161
|
-
if command -v pnpm &> /dev/null; then
|
|
162
|
-
PACKAGE_MANAGER="pnpm"
|
|
163
|
-
echo -e "${BLUE}📦 检测到包管理器: pnpm${NC}"
|
|
164
|
-
elif command -v npm &> /dev/null; then
|
|
165
|
-
PACKAGE_MANAGER="npm"
|
|
166
|
-
echo -e "${BLUE}📦 检测到包管理器: npm${NC}"
|
|
167
|
-
else
|
|
168
|
-
echo -e "${RED}❌ 未找到 npm 或 pnpm 命令${NC}"
|
|
169
|
-
echo -e "${YELLOW}💡 请先安装 Node.js 和包管理器${NC}"
|
|
170
|
-
exit 1
|
|
171
|
-
fi
|
|
172
|
-
|
|
173
|
-
# 确定包名
|
|
174
|
-
PACKAGE_NAME="page-action-cache"
|
|
175
|
-
|
|
176
|
-
# 安装 page-action-cache 到全局目录
|
|
177
|
-
echo -e "${YELLOW}📦 正在安装 $PACKAGE_NAME 到全局目录...${NC}"
|
|
178
|
-
cd "$GLOBAL_DIR"
|
|
179
|
-
|
|
180
|
-
# 检查全局安装状态
|
|
181
|
-
if $PACKAGE_MANAGER list $PACKAGE_NAME 2>&1 | grep -q "$PACKAGE_NAME"; then
|
|
182
|
-
echo -e "${YELLOW}⚠️ $PACKAGE_NAME 已在全局安装${NC}"
|
|
183
|
-
echo -e "${YELLOW}💡 如需更新,请使用: $PACKAGE_MANAGER install $PACKAGE_NAME@latest${NC}"
|
|
184
|
-
else
|
|
185
|
-
# 尝试从 npm 安装
|
|
186
|
-
echo -ne "${YELLOW}📦 尝试从 npm registry 安装 $PACKAGE_NAME...${NC}"
|
|
187
|
-
$PACKAGE_MANAGER install $PACKAGE_NAME --registry=https://registry.npmmirror.com --no-save 2>&1
|
|
188
|
-
|
|
189
|
-
if [ $? -eq 0 ]; then
|
|
190
|
-
echo -e "${GREEN}✅ $PACKAGE_NAME 安装成功到全局目录${NC}"
|
|
191
|
-
else
|
|
192
|
-
echo -e "${RED}❌ $PACKAGE_NAME 安装失败${NC}"
|
|
193
|
-
echo -e "${YELLOW}💡 提示: 请检查网络连接或包名是否正确${NC}"
|
|
194
|
-
fi
|
|
195
|
-
fi
|
|
196
|
-
|
|
197
|
-
# 检查全局安装结果
|
|
198
|
-
INSTALLED=$($PACKAGE_MANAGER list $PACKAGE_NAME 2>&1 | grep -q "$PACKAGE_NAME")
|
|
199
|
-
if [ $? -eq 0 ]; then
|
|
200
|
-
echo -e "${GREEN}✅ $PACKAGE_NAME 已安装到全局目录${NC}"
|
|
201
|
-
|
|
202
|
-
# 获取安装信息
|
|
203
|
-
PACKAGE_INFO=$($PACKAGE_MANAGER list $PACKAGE_NAME 2>&1)
|
|
204
|
-
echo -e "${BLUE}📦 $PACKAGE_NAME 全局安装信息:${NC}"
|
|
205
|
-
echo "$PACKAGE_INFO"
|
|
206
|
-
else
|
|
207
|
-
echo -e "${YELLOW}⚠️ $PACKAGE_NAME 安装状态不确定${NC}"
|
|
208
|
-
echo -e "${YELLOW}💡 提示: 请手动检查安装状态: $PACKAGE_MANAGER list $PACKAGE_NAME --global${NC}"
|
|
209
|
-
fi
|
|
210
|
-
|
|
211
|
-
echo -e "${GREEN}✅ page-action-cache 全局扩展安装完成${NC}"
|
|
212
|
-
echo -e "${BLUE}📝 yunwei 实例将从全局目录复制代码和依赖${NC}"
|
|
213
|
-
echo -e "${YELLOW}🔄 多实例架构:全局运行时 + 实例从运行时复制${NC}"
|
|
214
|
-
|
|
215
|
-
# 返回到实例目录
|
|
216
|
-
cd "${INSTANCE_DIR}"
|
|
205
|
+
# --- 11. 模型配置 ---
|
|
217
206
|
MODEL_PROVIDER="${3:-}"
|
|
218
207
|
if [ -z "$MODEL_PROVIDER" ]; then
|
|
219
208
|
echo -e "${BLUE}--- 请选择模型供应商 ---${NC}"
|
|
@@ -234,7 +223,7 @@ if [ -z "$API_KEY" ]; then
|
|
|
234
223
|
read -p "请输入您的 ${MODEL_PROVIDER} API Key: " API_KEY
|
|
235
224
|
fi
|
|
236
225
|
|
|
237
|
-
# ---
|
|
226
|
+
# --- 12. 生成深度配置文件 ---
|
|
238
227
|
DEFAULT_MODEL="zai/glm-5"
|
|
239
228
|
ZAI_KEY=""; DS_KEY=""; MX_KEY=""; KIMI_KEY=""; QWEN_KEY=""
|
|
240
229
|
|
|
@@ -244,344 +233,88 @@ case "$MODEL_PROVIDER" in
|
|
|
244
233
|
minimax) PRIMARY_MODEL="minimax-cn/MiniMax-M2.5-highspeed"; MX_KEY="$API_KEY" ;;
|
|
245
234
|
kimi) PRIMARY_MODEL="kimi/moonshot-v1-8k"; KIMI_KEY="$API_KEY" ;;
|
|
246
235
|
qwen) PRIMARY_MODEL="qwen/qwen-plus"; QWEN_KEY="$API_KEY" ;;
|
|
236
|
+
*) PRIMARY_MODEL="zai/glm-5"; ZAI_KEY="$API_KEY" ;;
|
|
247
237
|
esac
|
|
248
238
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
else
|
|
252
|
-
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
|
|
253
|
-
fi
|
|
254
|
-
|
|
255
|
-
cat > "${INSTANCE_DIR}/config/openclaw.json" << EOF
|
|
239
|
+
echo -e "${BLUE}⚙️ 生成配置文件...${NC}"
|
|
240
|
+
cat > "${INSTANCE_DIR}/config/deep.json" << EOF
|
|
256
241
|
{
|
|
257
|
-
"
|
|
258
|
-
"
|
|
259
|
-
"
|
|
242
|
+
"gateway": {
|
|
243
|
+
"mode": "local",
|
|
244
|
+
"port": ${PORT},
|
|
245
|
+
"bind": "127.0.0.1",
|
|
246
|
+
"autoStart": true
|
|
260
247
|
},
|
|
261
|
-
"
|
|
248
|
+
"plugins": {
|
|
249
|
+
"entries": {
|
|
250
|
+
"page-action-cache": {
|
|
251
|
+
"path": "${INSTANCE_DIR}/extensions/page-action-cache",
|
|
252
|
+
"enabled": true,
|
|
253
|
+
"config": {
|
|
254
|
+
"enabled": true,
|
|
255
|
+
"autoUseCache": true,
|
|
256
|
+
"scenarioRecognitionEnabled": true,
|
|
257
|
+
"llmClassificationThreshold": 0.8,
|
|
258
|
+
"cacheLevelStrategy": "auto",
|
|
259
|
+
"defaultCacheLevel": "L1",
|
|
260
|
+
"pageChangeDetectionEnabled": true,
|
|
261
|
+
"changeInvalidationThreshold": 0.5,
|
|
262
|
+
"invalidationStrategy": "soft",
|
|
263
|
+
"variableExtractionEnabled": true,
|
|
264
|
+
"allowUserConfirmVariables": true,
|
|
265
|
+
"allowUserForcedRefresh": true,
|
|
266
|
+
"enableUserCacheErrorReport": true,
|
|
267
|
+
"trackExecutionStats": true,
|
|
268
|
+
"statsUpdateInterval": 60000
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"model": {
|
|
274
|
+
"defaultProvider": "${MODEL_PROVIDER}",
|
|
262
275
|
"providers": {
|
|
263
276
|
"zai": {
|
|
264
|
-
"baseUrl": "https://open.bigmodel.cn/api/paas/v4",
|
|
265
277
|
"apiKey": "${ZAI_KEY}",
|
|
266
|
-
"
|
|
267
|
-
"models": [
|
|
268
|
-
{
|
|
269
|
-
"id": "glm-5",
|
|
270
|
-
"name": "GLM-5",
|
|
271
|
-
"input": ["text"],
|
|
272
|
-
"contextWindow": 32768,
|
|
273
|
-
"maxTokens": 4096
|
|
274
|
-
}
|
|
275
|
-
]
|
|
278
|
+
"baseURL": "https://open.bigmodel.cn/api/paas/v4",
|
|
279
|
+
"models": ["zai/glm-5"]
|
|
276
280
|
},
|
|
277
281
|
"deepseek": {
|
|
278
|
-
"baseUrl": "https://api.deepseek.com",
|
|
279
282
|
"apiKey": "${DS_KEY}",
|
|
280
|
-
"
|
|
281
|
-
"models": [
|
|
282
|
-
{
|
|
283
|
-
"id": "deepseek-chat",
|
|
284
|
-
"name": "DeepSeek-Chat",
|
|
285
|
-
"input": ["text"],
|
|
286
|
-
"contextWindow": 32768,
|
|
287
|
-
"maxTokens": 4096
|
|
288
|
-
}
|
|
289
|
-
]
|
|
283
|
+
"baseURL": "https://api.deepseek.com/v1",
|
|
284
|
+
"models": ["deepseek/deepseek-chat"]
|
|
290
285
|
},
|
|
291
286
|
"minimax-cn": {
|
|
292
|
-
"baseUrl": "https://api.minimax.chat/v1",
|
|
293
287
|
"apiKey": "${MX_KEY}",
|
|
294
|
-
"
|
|
295
|
-
"models": [
|
|
296
|
-
{
|
|
297
|
-
"id": "MiniMax-M2.5-highspeed",
|
|
298
|
-
"name": "MiniMax-M2.5-highspeed",
|
|
299
|
-
"input": ["text"],
|
|
300
|
-
"cost": { "input": 0.000002, "output": 0.000006 },
|
|
301
|
-
"contextWindow": 65536,
|
|
302
|
-
"maxTokens": 8192
|
|
303
|
-
}
|
|
304
|
-
]
|
|
305
|
-
},
|
|
306
|
-
"ollama": {
|
|
307
|
-
"baseUrl": "http://127.0.0.1:11434",
|
|
308
|
-
"api": "ollama",
|
|
309
|
-
"models": [
|
|
310
|
-
{
|
|
311
|
-
"id": "qwen3-vl:8b",
|
|
312
|
-
"name": "Qwen3-VL-8B",
|
|
313
|
-
"input": ["text", "image"],
|
|
314
|
-
"contextWindow": 32768,
|
|
315
|
-
"maxTokens": 4096
|
|
316
|
-
}
|
|
317
|
-
]
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
"agents": {
|
|
322
|
-
"defaults": {
|
|
323
|
-
"model": { "primary": "${PRIMARY_MODEL}" },
|
|
324
|
-
"imageModel": {
|
|
325
|
-
"primary": "ollama/qwen3-vl:8b",
|
|
326
|
-
"fallbacks": [
|
|
327
|
-
"ollama/qwen3-vl:8b"
|
|
328
|
-
]
|
|
288
|
+
"baseURL": "https://api.minimax.chat/v1",
|
|
289
|
+
"models": ["minimax-cn/MiniMax-M2.5-highspeed"]
|
|
329
290
|
},
|
|
330
|
-
"
|
|
331
|
-
"
|
|
291
|
+
"kimi": {
|
|
292
|
+
"apiKey": "${KIMI_KEY}",
|
|
293
|
+
"baseURL": "https://api.moonshot.cn/v1",
|
|
294
|
+
"models": ["kimi/moonshot-v1-8k"]
|
|
332
295
|
},
|
|
333
|
-
"
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
"gateway": { "port": ${PORT}, "mode": "local" },
|
|
339
|
-
"page-action-cache": {
|
|
340
|
-
"enabled": true,
|
|
341
|
-
"config": {
|
|
342
|
-
"cacheLevelStrategy": "l3-only",
|
|
343
|
-
"pageChangeDetectionEnabled": true,
|
|
344
|
-
"invalidationStrategy": "hard"
|
|
345
|
-
}
|
|
296
|
+
"qwen": {
|
|
297
|
+
"apiKey": "${QWEN_KEY}",
|
|
298
|
+
"baseURL": "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
299
|
+
"models": ["qwen/qwen-plus"]
|
|
300
|
+
}
|
|
346
301
|
}
|
|
302
|
+
}
|
|
347
303
|
}
|
|
348
304
|
EOF
|
|
349
305
|
|
|
350
|
-
|
|
351
|
-
echo -e "${BLUE}🤖 正在注入飞书运维机器人引导...${NC}"
|
|
352
|
-
SKILLS_DIR="${INSTANCE_DIR}/workspace/skills"
|
|
353
|
-
mkdir -p "$SKILLS_DIR"
|
|
306
|
+
echo -e "${GREEN}✅ 配置文件生成完成${NC}"
|
|
354
307
|
|
|
355
|
-
|
|
356
|
-
|
|
308
|
+
# --- 13. 完成 ---
|
|
309
|
+
echo -e "${GREEN}🎉 ${INSTANCE_NAME} 实例创建完成!${NC}"
|
|
310
|
+
echo -e "${BLUE}📂 实例路径: ${INSTANCE_DIR}${NC}"
|
|
311
|
+
echo -e "${BLUE}🔌 端口: ${PORT}${NC}"
|
|
312
|
+
echo -e "${BLUE}🤖 模型: ${PRIMARY_MODEL}${NC}"
|
|
313
|
+
echo -e "${BLUE}📦 全局运行时: ${GLOBAL_DIR}${NC}"
|
|
314
|
+
echo -e "${BLUE}📝 配置文件: ${INSTANCE_DIR}/config/deep.json${NC}"
|
|
357
315
|
|
|
358
|
-
|
|
359
|
-
|
|
316
|
+
echo -e "${YELLOW}--- 启动命令 ---${NC}"
|
|
317
|
+
echo -e "${BLUE}cd ${INSTANCE_DIR}${NC}"
|
|
318
|
+
echo -e "${BLUE}node openclaw.mjs gateway run --config config/deep.json${NC}"
|
|
360
319
|
|
|
361
|
-
|
|
362
|
-
TARBALL=$(ls *.tgz)
|
|
363
|
-
mkdir -p "$SKILLS_DIR/feishu-config"
|
|
364
|
-
tar -xzf "$TARBALL" -C "$SKILLS_DIR/feishu-config" --strip-components=1
|
|
365
|
-
echo -e "${GREEN}✅ 技能 feishu-config 安装成功${NC}"
|
|
366
|
-
else
|
|
367
|
-
echo -e "${YELLOW}⚠️ 技能 feishu-config 下载失败,跳过(可手动安装)${NC}"
|
|
368
|
-
fi
|
|
369
|
-
|
|
370
|
-
cd - > /dev/null
|
|
371
|
-
rm -rf "$TEMP_DIR"
|
|
372
|
-
|
|
373
|
-
# --- 如果实例是 yunwei,安装角色包并初始化 workspace ---
|
|
374
|
-
if [ "$INSTANCE_NAME" = "yunwei" ]; then
|
|
375
|
-
echo -e "${BLUE}🛠️ 检测到运维实例,正在安装角色包 role-openclaw-yunwei...${NC}"
|
|
376
|
-
TEMP_ROLE_DIR=$(mktemp -d)
|
|
377
|
-
cd "$TEMP_ROLE_DIR"
|
|
378
|
-
if npm pack role-openclaw-yunwei@latest --registry=https://registry.npmmirror.com --quiet > /dev/null; then
|
|
379
|
-
TARBALL=$(ls *.tgz)
|
|
380
|
-
tar -xzf "$TARBALL" --strip-components=1
|
|
381
|
-
rm "$TARBALL"
|
|
382
|
-
|
|
383
|
-
# 1. 将 memory、skills 等目录复制到 workspace 根目录(排除 .md 文件)
|
|
384
|
-
for item in *; do
|
|
385
|
-
if [ -d "$item" ]; then
|
|
386
|
-
# 目录(如 memory、skills)复制到 workspace
|
|
387
|
-
cp -r "$item" "$INSTANCE_DIR/workspace/"
|
|
388
|
-
elif [ -f "$item" ]; then
|
|
389
|
-
# 非 .md 文件(如 package.json)也复制到 workspace
|
|
390
|
-
cp "$item" "$INSTANCE_DIR/workspace/" 2>/dev/null || true
|
|
391
|
-
fi
|
|
392
|
-
done
|
|
393
|
-
|
|
394
|
-
# 2. 创建实例根目录下的 docs 目录,并将所有 .md 文件复制过去
|
|
395
|
-
mkdir -p "$INSTANCE_DIR/docs/reference/templates"
|
|
396
|
-
cp *.md "$INSTANCE_DIR/docs/reference/templates/" 2>/dev/null || true
|
|
397
|
-
|
|
398
|
-
echo -e "${GREEN}✅ 角色包安装完成,workspace 已初始化${NC}"
|
|
399
|
-
else
|
|
400
|
-
echo -e "${YELLOW}⚠️ 角色包下载失败,请检查网络或手动安装${NC}"
|
|
401
|
-
fi
|
|
402
|
-
cd - > /dev/null
|
|
403
|
-
rm -rf "$TEMP_ROLE_DIR"
|
|
404
|
-
fi
|
|
405
|
-
|
|
406
|
-
# --- 设置 profile 链接以便 openclaw --profile 使用 ---
|
|
407
|
-
echo -e "${BLUE}🔗 配置 profile 链接以支持 --profile 命令行...${NC}"
|
|
408
|
-
PROFILES_DIR="$HOME/.openclaw/profiles"
|
|
409
|
-
mkdir -p "$PROFILES_DIR"
|
|
410
|
-
|
|
411
|
-
# 配置文件软链接
|
|
412
|
-
ln -sf "$INSTANCE_DIR/config/openclaw.json" "$PROFILES_DIR/$INSTANCE_NAME.json"
|
|
413
|
-
|
|
414
|
-
# 状态目录软链接(profile 默认状态目录为 ~/.openclaw/profiles/<profile>/)
|
|
415
|
-
# 使用 -sfn 以确保目录链接正确
|
|
416
|
-
ln -sfn "$INSTANCE_DIR/state" "$PROFILES_DIR/$INSTANCE_NAME"
|
|
417
|
-
|
|
418
|
-
echo -e "${GREEN}✅ 现在可以使用 'openclaw --profile $INSTANCE_NAME ...' 管理此实例${NC}"
|
|
419
|
-
|
|
420
|
-
# --- 11. 生成增强型启动脚本 ---
|
|
421
|
-
cat > "${INSTANCE_DIR}/start.sh" << 'EOF'
|
|
422
|
-
#!/usr/bin/env bash
|
|
423
|
-
# =================================================================
|
|
424
|
-
# OpenClaw 实例启动脚本 (yunwei 优化版)
|
|
425
|
-
# 功能:启动网关、运行 TUI 或其他命令
|
|
426
|
-
# =================================================================
|
|
427
|
-
|
|
428
|
-
# 确保全局安装的 openclaw 命令可用
|
|
429
|
-
export PATH="$HOME/.npm-global/bin:$PATH"
|
|
430
|
-
|
|
431
|
-
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
432
|
-
cd "$SCRIPT_DIR"
|
|
433
|
-
INSTANCE_NAME=$(basename "$SCRIPT_DIR")
|
|
434
|
-
|
|
435
|
-
# 导出核心配置路径
|
|
436
|
-
export OPENCLAW_CONFIG_PATH="$SCRIPT_DIR/config/openclaw.json"
|
|
437
|
-
export OPENCLAW_TMP_DIR="$SCRIPT_DIR/tmp"
|
|
438
|
-
export OPENCLAW_STATE_DIR="$SCRIPT_DIR/state"
|
|
439
|
-
|
|
440
|
-
# 从配置中提取 workspace 路径并导出
|
|
441
|
-
if [ -f "$OPENCLAW_CONFIG_PATH" ]; then
|
|
442
|
-
export OPENCLAW_WORKSPACE=$(node -e "
|
|
443
|
-
const cfg = require('$OPENCLAW_CONFIG_PATH');
|
|
444
|
-
console.log(cfg.agents?.defaults?.workspace || '');
|
|
445
|
-
")
|
|
446
|
-
fi
|
|
447
|
-
|
|
448
|
-
# 从配置中导出 API Key(如果存在 env 字段)
|
|
449
|
-
if [ -f "$OPENCLAW_CONFIG_PATH" ]; then
|
|
450
|
-
eval $(node -e "
|
|
451
|
-
const env = require('$OPENCLAW_CONFIG_PATH').env || {};
|
|
452
|
-
Object.keys(env).forEach(k => {
|
|
453
|
-
if (env[k]) console.log('export ' + k + '=\"' + env[k] + '\"');
|
|
454
|
-
});
|
|
455
|
-
")
|
|
456
|
-
fi
|
|
457
|
-
|
|
458
|
-
# macOS launchd 守护配置(可选)
|
|
459
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
460
|
-
PLIST_LABEL="ai.openclaw.$INSTANCE_NAME"
|
|
461
|
-
PLIST_PATH="$HOME/Library/LaunchAgents/$PLIST_LABEL.plist"
|
|
462
|
-
if [ ! -f "$PLIST_PATH" ]; then
|
|
463
|
-
cat > "$PLIST_PATH" <<EOP
|
|
464
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
465
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
466
|
-
<plist version="1.0">
|
|
467
|
-
<dict>
|
|
468
|
-
<key>Label</key><string>$PLIST_LABEL</string>
|
|
469
|
-
<key>ProgramArguments</key><array><string>/bin/bash</string><string>$SCRIPT_DIR/start.sh</string></array>
|
|
470
|
-
<key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
|
|
471
|
-
<key>WorkingDirectory</key><string>$SCRIPT_DIR</string>
|
|
472
|
-
</dict>
|
|
473
|
-
</plist>
|
|
474
|
-
EOP
|
|
475
|
-
launchctl load "$PLIST_PATH" 2>/dev/null || true
|
|
476
|
-
fi
|
|
477
|
-
fi
|
|
478
|
-
|
|
479
|
-
# 定义可执行文件路径:优先使用全局 openclaw,否则用绝对路径 node
|
|
480
|
-
if command -v openclaw &> /dev/null; then
|
|
481
|
-
OPENCLAW_EXEC="openclaw"
|
|
482
|
-
else
|
|
483
|
-
# 使用完整复制的目录中的 openclaw.mjs 或 dist/index.js
|
|
484
|
-
if [ -f "$SCRIPT_DIR/openclaw.mjs" ]; then
|
|
485
|
-
OPENCLAW_EXEC="node $SCRIPT_DIR/openclaw.mjs"
|
|
486
|
-
elif [ -f "$SCRIPT_DIR/dist/index.js" ]; then
|
|
487
|
-
OPENCLAW_EXEC="node $SCRIPT_DIR/dist/index.js"
|
|
488
|
-
else
|
|
489
|
-
echo -e "${RED}❌ 错误: 未找到可执行文件${NC}"
|
|
490
|
-
exit 1
|
|
491
|
-
fi
|
|
492
|
-
fi
|
|
493
|
-
|
|
494
|
-
# 根据命令行参数执行对应操作
|
|
495
|
-
if [ $# -eq 0 ]; then
|
|
496
|
-
# 无参数:启动网关
|
|
497
|
-
GATEWAY_PORT=$(node -e "console.log(require('$OPENCLAW_CONFIG_PATH').gateway.port)")
|
|
498
|
-
echo "🚀 使用 $OPENCLAW_EXEC 启动 OpenClaw-$INSTANCE_NAME 网关..."
|
|
499
|
-
exec $OPENCLAW_EXEC gateway run --port "$GATEWAY_PORT"
|
|
500
|
-
else
|
|
501
|
-
if [ "$1" = "tui" ]; then
|
|
502
|
-
# TUI 必须在 workspace 目录下运行,以正确加载模板文件
|
|
503
|
-
echo "🚀 启动 OpenClaw-$INSTANCE_NAME TUI (workspace mode)..."
|
|
504
|
-
cd "$OPENCLAW_WORKSPACE"
|
|
505
|
-
# 使用绝对路径调用 node,避免相对路径问题
|
|
506
|
-
exec node "$SCRIPT_DIR/dist/index.js" tui
|
|
507
|
-
else
|
|
508
|
-
# 其他命令直接在实例目录执行
|
|
509
|
-
echo "🚀 使用 $OPENCLAW_EXEC 执行 OpenClaw-$INSTANCE_NAME 命令: $@"
|
|
510
|
-
exec $OPENCLAW_EXEC "$@"
|
|
511
|
-
fi
|
|
512
|
-
fi
|
|
513
|
-
EOF
|
|
514
|
-
|
|
515
|
-
chmod +x "${INSTANCE_DIR}/start.sh"
|
|
516
|
-
|
|
517
|
-
# --- 12. 执行拉起 ---
|
|
518
|
-
echo -e "${BLUE}⚡ 正在后台启动服务...${NC}"
|
|
519
|
-
nohup "${INSTANCE_DIR}/start.sh" > "${INSTANCE_DIR}/workspace/server.log" 2>&1 &
|
|
520
|
-
PID=$!
|
|
521
|
-
|
|
522
|
-
sleep 5
|
|
523
|
-
|
|
524
|
-
check_port() {
|
|
525
|
-
if command -v lsof &> /dev/null; then
|
|
526
|
-
lsof -i :$PORT -sTCP:LISTEN -t &> /dev/null
|
|
527
|
-
elif command -v nc &> /dev/null; then
|
|
528
|
-
nc -z localhost $PORT 2>/dev/null
|
|
529
|
-
elif command -v curl &> /dev/null; then
|
|
530
|
-
curl --head --connect-timeout 1 http://localhost:$PORT &> /dev/null
|
|
531
|
-
else
|
|
532
|
-
return 0
|
|
533
|
-
fi
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
if kill -0 $PID 2>/dev/null; then
|
|
537
|
-
if check_port; then
|
|
538
|
-
echo -e "${GREEN}================================================${NC}"
|
|
539
|
-
echo -e "${GREEN}🎉 实例 [${INSTANCE_NAME}] 初始化成功!${NC}"
|
|
540
|
-
echo -e "🌐 本地网关: http://localhost:${PORT}"
|
|
541
|
-
echo -e "📄 实时日志: tail -f ${INSTANCE_DIR}/workspace/server.log"
|
|
542
|
-
echo -e "${GREEN}================================================${NC}"
|
|
543
|
-
|
|
544
|
-
# --- 交互式菜单 ---
|
|
545
|
-
if [ -t 0 ]; then
|
|
546
|
-
echo
|
|
547
|
-
echo -e "${BLUE}请选择下一步操作:${NC}"
|
|
548
|
-
echo "1) 启动 TUI (终端交互界面)"
|
|
549
|
-
echo "2) 打开 Web UI (浏览器)"
|
|
550
|
-
echo "3) 退出"
|
|
551
|
-
read -p "请输入数字 [1-3]: " choice
|
|
552
|
-
case $choice in
|
|
553
|
-
1)
|
|
554
|
-
echo -e "${YELLOW}启动 TUI...${NC}"
|
|
555
|
-
cd "$INSTANCE_DIR"
|
|
556
|
-
./start.sh tui
|
|
557
|
-
;;
|
|
558
|
-
2)
|
|
559
|
-
TOKEN=$(node -e "console.log(require('$INSTANCE_DIR/config/openclaw.json').gateway?.auth?.token || '')")
|
|
560
|
-
if [ -n "$TOKEN" ]; then
|
|
561
|
-
URL="http://localhost:$PORT/?token=$TOKEN"
|
|
562
|
-
echo -e "${GREEN}请在浏览器中打开: ${BLUE}$URL${NC}"
|
|
563
|
-
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
564
|
-
open "$URL"
|
|
565
|
-
elif command -v xdg-open &> /dev/null; then
|
|
566
|
-
xdg-open "$URL"
|
|
567
|
-
fi
|
|
568
|
-
else
|
|
569
|
-
echo -e "${RED}未找到 token,请手动查看配置文件。${NC}"
|
|
570
|
-
fi
|
|
571
|
-
;;
|
|
572
|
-
3)
|
|
573
|
-
echo "退出"
|
|
574
|
-
exit 0
|
|
575
|
-
;;
|
|
576
|
-
*)
|
|
577
|
-
echo "无效选择"
|
|
578
|
-
;;
|
|
579
|
-
esac
|
|
580
|
-
fi
|
|
581
|
-
else
|
|
582
|
-
echo -e "${YELLOW}⚠️ 进程存在但端口 ${PORT} 未监听(可能启动较慢或检查工具问题),请查看日志: ${INSTANCE_DIR}/workspace/server.log${NC}"
|
|
583
|
-
fi
|
|
584
|
-
else
|
|
585
|
-
echo -e "${RED}❌ 启动失败,请查看日志: tail -n 20 ${INSTANCE_DIR}/workspace/server.log${NC}"
|
|
586
|
-
exit 1
|
|
587
|
-
fi
|
|
320
|
+
echo -e "${GREEN}🚀 已就绪,可以启动实例!${NC}"
|