@silicaclaw/cli 1.0.0-beta.9 → 2026.3.18-3

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.
@@ -5,7 +5,7 @@ INVOKE_PWD="${INIT_CWD:-$PWD}"
5
5
  ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
6
6
  WORK_DIR="$ROOT_DIR"
7
7
  IS_NPX_MODE=0
8
- DEFAULT_MODE_PICK="${QUICKSTART_DEFAULT_MODE:-1}"
8
+ DEFAULT_MODE_PICK="${QUICKSTART_DEFAULT_MODE:-3}"
9
9
  CONNECT_MODE="${QUICKSTART_CONNECT_MODE:-0}"
10
10
 
11
11
  case "$DEFAULT_MODE_PICK" in
@@ -21,22 +21,152 @@ esac
21
21
 
22
22
  STEP=1
23
23
 
24
+ ORANGE=$'\033[38;5;208m'
25
+ BOLD=$'\033[1m'
26
+ DIM=$'\033[2m'
27
+ GREEN=$'\033[32m'
28
+ YELLOW=$'\033[33m'
29
+ RESET=$'\033[0m'
30
+
31
+ if [ ! -t 1 ] || [ -n "${NO_COLOR:-}" ]; then
32
+ ORANGE=""
33
+ BOLD=""
34
+ DIM=""
35
+ GREEN=""
36
+ YELLOW=""
37
+ RESET=""
38
+ fi
39
+
24
40
  line() {
25
41
  printf '\n%s\n' "------------------------------------------------------------"
26
42
  }
27
43
 
28
44
  title() {
29
45
  line
30
- printf '[Step %s] %s\n' "$STEP" "$1"
46
+ printf '%s[Step %s]%s %s\n' "$BOLD" "$STEP" "$RESET" "$1"
31
47
  STEP=$((STEP + 1))
32
48
  }
33
49
 
50
+ headline() {
51
+ printf '%sSilicaClaw%s %s%s%s\n' "$ORANGE$BOLD" "$RESET" "$DIM" "$(cat "$WORK_DIR/VERSION" 2>/dev/null || printf 'unknown')" "$RESET"
52
+ printf '%sPublic identity and discovery for OpenClaw agents.%s\n' "$DIM" "$RESET"
53
+ }
54
+
55
+ kv() {
56
+ printf '%s%-14s%s %s\n' "$DIM" "$1" "$RESET" "$2"
57
+ }
58
+
59
+ note() {
60
+ printf '%s%s%s\n' "$YELLOW" "$1" "$RESET"
61
+ }
62
+
63
+ success() {
64
+ printf '%s%s%s\n' "$GREEN" "$1" "$RESET"
65
+ }
66
+
34
67
  run_cmd() {
35
68
  local cmd="$1"
36
69
  printf '→ %s\n' "$cmd"
37
70
  eval "$cmd"
38
71
  }
39
72
 
73
+ run_cmd_may_fail() {
74
+ local cmd="$1"
75
+ printf '→ %s\n' "$cmd"
76
+ set +e
77
+ eval "$cmd"
78
+ local code=$?
79
+ set -e
80
+ return $code
81
+ }
82
+
83
+ first_writable_path_dir() {
84
+ local path_value="${PATH:-}"
85
+ local old_ifs="$IFS"
86
+ IFS=':'
87
+ for d in $path_value; do
88
+ if [ -n "$d" ] && [ -d "$d" ] && [ -w "$d" ] && [ -x "$d" ]; then
89
+ printf '%s' "$d"
90
+ IFS="$old_ifs"
91
+ return 0
92
+ fi
93
+ done
94
+ IFS="$old_ifs"
95
+ return 1
96
+ }
97
+
98
+ install_command_shim() {
99
+ local bindir="$1"
100
+ local script_path="$WORK_DIR/scripts/silicaclaw-cli.mjs"
101
+ local target="$bindir/silicaclaw"
102
+ if [ ! -f "$script_path" ]; then
103
+ echo "未找到 CLI 脚本: $script_path"
104
+ return 1
105
+ fi
106
+ cat >"$target" <<EOF
107
+ #!/usr/bin/env bash
108
+ set -euo pipefail
109
+ exec node "$script_path" "\$@"
110
+ EOF
111
+ chmod +x "$target"
112
+ return 0
113
+ }
114
+
115
+ default_system_bin_dir() {
116
+ if [ -d "/usr/local/bin" ]; then
117
+ printf '/usr/local/bin'
118
+ return 0
119
+ fi
120
+ if [ -d "/opt/homebrew/bin" ]; then
121
+ printf '/opt/homebrew/bin'
122
+ return 0
123
+ fi
124
+ printf '/usr/local/bin'
125
+ }
126
+
127
+ detect_shell_rc_file() {
128
+ local sh_name="${SHELL:-}"
129
+ case "$sh_name" in
130
+ */zsh) printf '%s' "$HOME/.zshrc" ;;
131
+ */bash) printf '%s' "$HOME/.bashrc" ;;
132
+ *)
133
+ if [ -n "${ZSH_VERSION:-}" ]; then
134
+ printf '%s' "$HOME/.zshrc"
135
+ else
136
+ printf '%s' "$HOME/.bashrc"
137
+ fi
138
+ ;;
139
+ esac
140
+ }
141
+
142
+ install_npx_alias() {
143
+ local rc_file
144
+ rc_file="$(detect_shell_rc_file)"
145
+ local begin_mark="# >>> silicaclaw npx alias >>>"
146
+ local end_mark="# <<< silicaclaw npx alias <<<"
147
+ local alias_line="alias silicaclaw='npx -y @silicaclaw/cli@beta'"
148
+
149
+ mkdir -p "$(dirname "$rc_file")"
150
+ touch "$rc_file"
151
+
152
+ if grep -Fq "$begin_mark" "$rc_file"; then
153
+ echo "已存在 silicaclaw alias 配置: $rc_file"
154
+ return 0
155
+ fi
156
+
157
+ {
158
+ echo ""
159
+ echo "$begin_mark"
160
+ echo "$alias_line"
161
+ echo "$end_mark"
162
+ } >>"$rc_file"
163
+
164
+ echo "已写入 alias 到: $rc_file"
165
+ echo "执行以下命令即可在当前 shell 立即生效:"
166
+ echo "source \"$rc_file\""
167
+ return 0
168
+ }
169
+
40
170
  ask_yes_no() {
41
171
  local prompt="$1"
42
172
  local default="${2:-Y}"
@@ -93,8 +223,10 @@ url_port_or_default() {
93
223
  }
94
224
 
95
225
  title "SilicaClaw Quick Start 启动"
96
- echo "目录: $ROOT_DIR"
97
- echo "目标: 用终端一步步完成安装与启动(类似 OpenClaw Quick Start)"
226
+ headline
227
+ echo ""
228
+ kv "目录" "$ROOT_DIR"
229
+ kv "目标" "一步步完成安装、联网与启动"
98
230
  pause_continue
99
231
 
100
232
  if [ "$IS_NPX_MODE" -eq 1 ]; then
@@ -111,7 +243,8 @@ if [ "$IS_NPX_MODE" -eq 1 ]; then
111
243
  fi
112
244
 
113
245
  mkdir -p "$TARGET_DIR"
114
- echo "正在复制项目文件到: $TARGET_DIR"
246
+ kv "安装目录" "$TARGET_DIR"
247
+ echo "正在复制项目文件..."
115
248
  if command -v rsync >/dev/null 2>&1; then
116
249
  rsync -a --delete \
117
250
  --exclude '.git/' \
@@ -124,7 +257,8 @@ if [ "$IS_NPX_MODE" -eq 1 ]; then
124
257
  rm -rf "$TARGET_DIR/.git" "$TARGET_DIR/node_modules" "$TARGET_DIR/.npm-cache"
125
258
  fi
126
259
  WORK_DIR="$TARGET_DIR"
127
- echo "工作目录已切换到: $WORK_DIR"
260
+ success "工作目录已切换"
261
+ kv "目录" "$WORK_DIR"
128
262
  pause_continue
129
263
  fi
130
264
 
@@ -140,8 +274,8 @@ fi
140
274
 
141
275
  NODE_VER="$(node -p "process.versions.node")"
142
276
  NPM_VER="$(npm -v)"
143
- echo "node: $NODE_VER"
144
- echo "npm : $NPM_VER"
277
+ kv "node" "$NODE_VER"
278
+ kv "npm" "$NPM_VER"
145
279
 
146
280
  if ! node -e "const v=process.versions.node.split('.').map(Number); if (v[0] < 18) process.exit(1)"; then
147
281
  echo "Node.js 版本过低,请升级到 18+"
@@ -159,6 +293,70 @@ else
159
293
  fi
160
294
  fi
161
295
 
296
+ title "安装系统命令(silicaclaw)"
297
+ if command -v silicaclaw >/dev/null 2>&1; then
298
+ success "已检测到 silicaclaw 命令"
299
+ kv "路径" "$(command -v silicaclaw)"
300
+ else
301
+ echo "将尝试安装可持久使用的 silicaclaw 命令。"
302
+ BIN_DIR="$(first_writable_path_dir || true)"
303
+ INSTALLED=0
304
+ if [ -n "${BIN_DIR:-}" ]; then
305
+ if install_command_shim "$BIN_DIR"; then
306
+ success "命令已写入"
307
+ kv "路径" "$BIN_DIR/silicaclaw"
308
+ hash -r || true
309
+ if command -v silicaclaw >/dev/null 2>&1; then
310
+ kv "验证" "$(command -v silicaclaw)"
311
+ INSTALLED=1
312
+ else
313
+ note "当前 shell 还未刷新。新开终端后即可直接运行 silicaclaw。"
314
+ fi
315
+ else
316
+ note "命令安装未完成,仍可继续使用 npx。"
317
+ fi
318
+ else
319
+ note "PATH 中没有可写目录,无法直接安装到现有 PATH。"
320
+ fi
321
+
322
+ if [ "$INSTALLED" != "1" ]; then
323
+ SYS_BIN_DIR="$(default_system_bin_dir)"
324
+ kv "建议路径" "$SYS_BIN_DIR/silicaclaw"
325
+ if ask_yes_no "是否使用 sudo 安装系统命令?" "Y"; then
326
+ run_cmd "sudo mkdir -p \"$SYS_BIN_DIR\""
327
+ run_cmd "sudo tee \"$SYS_BIN_DIR/silicaclaw\" >/dev/null <<'EOF'
328
+ #!/usr/bin/env bash
329
+ set -euo pipefail
330
+ exec node \"$WORK_DIR/scripts/silicaclaw-cli.mjs\" \"\$@\"
331
+ EOF"
332
+ run_cmd "sudo chmod +x \"$SYS_BIN_DIR/silicaclaw\""
333
+ hash -r || true
334
+ if command -v silicaclaw >/dev/null 2>&1; then
335
+ success "系统命令安装完成"
336
+ kv "验证" "$(command -v silicaclaw)"
337
+ INSTALLED=1
338
+ else
339
+ note "安装完成,但当前 shell 未刷新。新开终端后再试。"
340
+ fi
341
+ else
342
+ note "已跳过 sudo 安装。"
343
+ fi
344
+ fi
345
+
346
+ if [ "$INSTALLED" != "1" ]; then
347
+ echo "你也可以选择无需全局安装的命令别名模式。"
348
+ if ask_yes_no "是否自动写入 shell alias(silicaclaw -> npx @silicaclaw/cli@beta)?" "Y"; then
349
+ if install_npx_alias; then
350
+ success "alias 安装完成"
351
+ else
352
+ note "alias 安装失败。继续使用 npx 即可。"
353
+ fi
354
+ else
355
+ kv "临时用法" "npx @silicaclaw/cli@beta <command>"
356
+ fi
357
+ fi
358
+ fi
359
+
162
360
  title "准备 social.md"
163
361
  if [ -f "$WORK_DIR/social.md" ]; then
164
362
  echo "已存在 social.md,保留现有配置。"
@@ -174,9 +372,9 @@ fi
174
372
  title "选择网络模式"
175
373
  echo "1) local 单机预览(最快)"
176
374
  echo "2) lan 局域网预览(A/B 双机)"
177
- echo "3) global-preview 非局域网预览(WebRTC)"
178
- echo "提示: 不确定就直接回车(默认 local)。"
179
- echo "提示: 只有在你已有可达 signaling 地址时,才选择 3。"
375
+ echo "3) global-preview 互联网预览(Relay,推荐)"
376
+ note "不确定就直接回车,默认 global-preview。"
377
+ note "互联网模式需要所有节点都能访问同一个 relay。"
180
378
  if [ "$CONNECT_MODE" = "1" ]; then
181
379
  MODE_PICK="3"
182
380
  echo "connect 模式:已自动选择 global-preview。"
@@ -188,7 +386,7 @@ fi
188
386
  NETWORK_MODE="local"
189
387
  NETWORK_ADAPTER="local-event-bus"
190
388
  WEBRTC_SIGNALING_URL_VALUE=""
191
- WEBRTC_ROOM_VALUE="silicaclaw-demo"
389
+ WEBRTC_ROOM_VALUE="silicaclaw-global-preview"
192
390
  AUTO_START_SIGNALING=0
193
391
 
194
392
  case "$MODE_PICK" in
@@ -198,40 +396,40 @@ case "$MODE_PICK" in
198
396
  ;;
199
397
  3)
200
398
  NETWORK_MODE="global-preview"
201
- NETWORK_ADAPTER="webrtc-preview"
399
+ NETWORK_ADAPTER="relay-preview"
202
400
  PUBLIC_IP="$(detect_public_ip)"
203
- SIGNALING_DEFAULT="${WEBRTC_SIGNALING_URL:-http://localhost:4510}"
401
+ SIGNALING_DEFAULT="${WEBRTC_SIGNALING_URL:-https://relay.silicaclaw.com}"
204
402
  if [ -n "$PUBLIC_IP" ]; then
205
- SIGNALING_DEFAULT="http://$PUBLIC_IP:4510"
403
+ SIGNALING_DEFAULT="https://relay.silicaclaw.com"
206
404
  fi
207
- echo "提示: signaling 地址需要“所有节点可访问”。"
405
+ note "signaling 地址需要所有节点都可访问。"
208
406
  if [ -n "$PUBLIC_IP" ]; then
209
- echo "已检测到本机公网 IP: $PUBLIC_IP"
210
- echo "如果你这台机器就是 signaling 服务器,可直接回车使用默认值。"
407
+ kv "公网 IP" "$PUBLIC_IP"
408
+ note "如果这台机器就是 relay 所在主机,可直接使用默认值。"
211
409
  else
212
- echo "未检测到公网 IP,将使用默认值: $SIGNALING_DEFAULT"
213
- echo "如果 signaling 在其他机器,请输入该机器公网地址。"
410
+ kv "默认 relay" "$SIGNALING_DEFAULT"
411
+ note "如需私有 relay,可改成你自己的公网地址。"
214
412
  fi
215
413
  read -r -p "请输入 signaling URL(默认 ${SIGNALING_DEFAULT}): " WEBRTC_SIGNALING_URL_INPUT || true
216
414
  WEBRTC_SIGNALING_URL_VALUE="${WEBRTC_SIGNALING_URL_INPUT:-$SIGNALING_DEFAULT}"
217
415
  if [ -z "${WEBRTC_SIGNALING_URL_VALUE:-}" ]; then
218
- echo "global-preview 必须提供 signaling URL"
416
+ echo "global-preview 必须提供公网可达的 signaling URL"
219
417
  exit 1
220
418
  fi
221
419
 
222
420
  SIGNALING_HOST="$(url_host "$WEBRTC_SIGNALING_URL_VALUE")"
223
421
  if [ "$SIGNALING_HOST" = "localhost" ] || [ "$SIGNALING_HOST" = "127.0.0.1" ]; then
224
- echo "提示: 当前 signaling URL 是本机地址,仅本机可用,不适合跨网络双机演示。"
422
+ note "当前 signaling URL 是本机地址,仅本机可用,不适合异地双机。"
225
423
  fi
226
424
 
227
425
  if ask_yes_no "是否在当前机器自动后台启动 signaling server(用于演示)?" "Y"; then
228
426
  AUTO_START_SIGNALING=1
229
427
  SIGNALING_PORT_VALUE="$(url_port_or_default "$WEBRTC_SIGNALING_URL_VALUE" "4510")"
230
- echo "将尝试以 PORT=$SIGNALING_PORT_VALUE 后台启动 signaling server"
428
+ kv "本地 relay" "PORT=$SIGNALING_PORT_VALUE"
231
429
  fi
232
430
 
233
- read -r -p "请输入 room(默认 silicaclaw-demo): " WEBRTC_ROOM_VALUE_INPUT || true
234
- WEBRTC_ROOM_VALUE="${WEBRTC_ROOM_VALUE_INPUT:-silicaclaw-demo}"
431
+ read -r -p "请输入 room(默认 silicaclaw-global-preview): " WEBRTC_ROOM_VALUE_INPUT || true
432
+ WEBRTC_ROOM_VALUE="${WEBRTC_ROOM_VALUE_INPUT:-silicaclaw-global-preview}"
235
433
  ;;
236
434
  *)
237
435
  NETWORK_MODE="local"
@@ -239,7 +437,9 @@ case "$MODE_PICK" in
239
437
  ;;
240
438
  esac
241
439
 
242
- echo "已选择: $NETWORK_MODE ($NETWORK_ADAPTER)"
440
+ success "网络模式已选择"
441
+ kv "Mode" "$NETWORK_MODE"
442
+ kv "Adapter" "$NETWORK_ADAPTER"
243
443
 
244
444
  title "启动 local-console"
245
445
  echo "1) gateway(推荐) 后台服务模式,可用 start/stop/restart/status 管理"
@@ -254,18 +454,19 @@ if [ "$START_MODE_PICK" = "2" ]; then
254
454
  SIGNALING_LOG="$WORK_DIR/.silicaclaw/signaling.log"
255
455
  SIGNALING_PID_FILE="$WORK_DIR/.silicaclaw/signaling.pid"
256
456
  run_cmd "cd \"$WORK_DIR\" && PORT=${SIGNALING_PORT_VALUE:-4510} nohup npm run webrtc-signaling > \"$SIGNALING_LOG\" 2>&1 & echo \$! > \"$SIGNALING_PID_FILE\""
257
- echo "已后台启动 signaling server,日志: $SIGNALING_LOG"
258
- echo "停止 signaling: kill \$(cat \"$SIGNALING_PID_FILE\")"
457
+ success "已后台启动 signaling server"
458
+ kv "日志" "$SIGNALING_LOG"
459
+ kv "停止" "kill \$(cat \"$SIGNALING_PID_FILE\")"
259
460
  fi
260
461
  echo "将使用以下参数启动(dev watch):"
261
- echo "NETWORK_ADAPTER=$NETWORK_ADAPTER"
262
- echo "WEBRTC_SIGNALING_URL=$WEBRTC_SIGNALING_URL_VALUE"
263
- echo "WEBRTC_ROOM=$WEBRTC_ROOM_VALUE"
462
+ kv "Adapter" "$NETWORK_ADAPTER"
463
+ kv "Relay" "$WEBRTC_SIGNALING_URL_VALUE"
464
+ kv "Room" "$WEBRTC_ROOM_VALUE"
264
465
  pause_continue
265
466
  run_cmd "cd \"$WORK_DIR\" && NETWORK_ADAPTER=$NETWORK_ADAPTER WEBRTC_SIGNALING_URL=$WEBRTC_SIGNALING_URL_VALUE WEBRTC_ROOM=$WEBRTC_ROOM_VALUE npm run local-console"
266
467
  else
267
468
  echo "将使用以下参数启动(dev watch):"
268
- echo "NETWORK_ADAPTER=$NETWORK_ADAPTER"
469
+ kv "Adapter" "$NETWORK_ADAPTER"
269
470
  pause_continue
270
471
  run_cmd "cd \"$WORK_DIR\" && NETWORK_ADAPTER=$NETWORK_ADAPTER npm run local-console"
271
472
  fi
@@ -275,14 +476,16 @@ else
275
476
  GATEWAY_CMD="$GATEWAY_CMD --signaling-url=$WEBRTC_SIGNALING_URL_VALUE --room=$WEBRTC_ROOM_VALUE"
276
477
  fi
277
478
  echo "将使用 gateway 后台启动:"
278
- echo "$GATEWAY_CMD"
479
+ kv "Command" "$GATEWAY_CMD"
279
480
  pause_continue
280
481
  run_cmd "$GATEWAY_CMD"
281
482
  echo ""
282
- echo "已启动完成。常用命令:"
283
- echo "cd \"$WORK_DIR\" && npm run gateway -- status"
284
- echo "cd \"$WORK_DIR\" && npm run gateway -- logs local-console"
285
- echo "cd \"$WORK_DIR\" && npm run gateway -- stop"
483
+ success "已启动完成"
484
+ kv "打开" "http://localhost:4310"
485
+ echo ""
486
+ echo "常用命令:"
487
+ kv "Status" "silicaclaw status"
488
+ kv "Logs" "silicaclaw logs local-console"
489
+ kv "Stop" "silicaclaw stop"
286
490
  echo ""
287
- echo "打开: http://localhost:4310"
288
491
  fi