@silicaclaw/cli 1.0.0-beta.3 → 1.0.0-beta.31

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/INSTALL.md +41 -4
  3. package/README.md +80 -6
  4. package/apps/local-console/public/index.html +1283 -251
  5. package/apps/local-console/src/server.ts +108 -31
  6. package/docs/CLOUDFLARE_RELAY.md +61 -0
  7. package/docs/NEW_USER_INSTALL.md +166 -0
  8. package/docs/NEW_USER_OPERATIONS.md +265 -0
  9. package/package.json +6 -1
  10. package/packages/core/dist/crypto.d.ts +6 -0
  11. package/packages/core/dist/crypto.js +50 -0
  12. package/packages/core/dist/directory.d.ts +17 -0
  13. package/packages/core/dist/directory.js +145 -0
  14. package/packages/core/dist/identity.d.ts +2 -0
  15. package/packages/core/dist/identity.js +18 -0
  16. package/packages/core/dist/index.d.ts +11 -0
  17. package/packages/core/dist/index.js +27 -0
  18. package/packages/core/dist/indexing.d.ts +6 -0
  19. package/packages/core/dist/indexing.js +43 -0
  20. package/packages/core/dist/presence.d.ts +4 -0
  21. package/packages/core/dist/presence.js +23 -0
  22. package/packages/core/dist/profile.d.ts +4 -0
  23. package/packages/core/dist/profile.js +39 -0
  24. package/packages/core/dist/publicProfileSummary.d.ts +70 -0
  25. package/packages/core/dist/publicProfileSummary.js +103 -0
  26. package/packages/core/dist/socialConfig.d.ts +99 -0
  27. package/packages/core/dist/socialConfig.js +288 -0
  28. package/packages/core/dist/socialResolver.d.ts +46 -0
  29. package/packages/core/dist/socialResolver.js +237 -0
  30. package/packages/core/dist/socialTemplate.d.ts +2 -0
  31. package/packages/core/dist/socialTemplate.js +88 -0
  32. package/packages/core/dist/types.d.ts +37 -0
  33. package/packages/core/dist/types.js +2 -0
  34. package/packages/core/src/socialConfig.ts +8 -7
  35. package/packages/core/src/socialResolver.ts +17 -5
  36. package/packages/network/dist/abstractions/messageEnvelope.d.ts +28 -0
  37. package/packages/network/dist/abstractions/messageEnvelope.js +36 -0
  38. package/packages/network/dist/abstractions/peerDiscovery.d.ts +43 -0
  39. package/packages/network/dist/abstractions/peerDiscovery.js +2 -0
  40. package/packages/network/dist/abstractions/topicCodec.d.ts +4 -0
  41. package/packages/network/dist/abstractions/topicCodec.js +2 -0
  42. package/packages/network/dist/abstractions/transport.d.ts +36 -0
  43. package/packages/network/dist/abstractions/transport.js +2 -0
  44. package/packages/network/dist/codec/jsonMessageEnvelopeCodec.d.ts +5 -0
  45. package/packages/network/dist/codec/jsonMessageEnvelopeCodec.js +24 -0
  46. package/packages/network/dist/codec/jsonTopicCodec.d.ts +5 -0
  47. package/packages/network/dist/codec/jsonTopicCodec.js +12 -0
  48. package/packages/network/dist/discovery/heartbeatPeerDiscovery.d.ts +28 -0
  49. package/packages/network/dist/discovery/heartbeatPeerDiscovery.js +144 -0
  50. package/packages/network/dist/index.d.ts +14 -0
  51. package/packages/network/dist/index.js +30 -0
  52. package/packages/network/dist/localEventBus.d.ts +9 -0
  53. package/packages/network/dist/localEventBus.js +47 -0
  54. package/packages/network/dist/mock.d.ts +8 -0
  55. package/packages/network/dist/mock.js +24 -0
  56. package/packages/network/dist/realPreview.d.ts +105 -0
  57. package/packages/network/dist/realPreview.js +327 -0
  58. package/packages/network/dist/relayPreview.d.ts +166 -0
  59. package/packages/network/dist/relayPreview.js +430 -0
  60. package/packages/network/dist/transport/udpLanBroadcastTransport.d.ts +23 -0
  61. package/packages/network/dist/transport/udpLanBroadcastTransport.js +153 -0
  62. package/packages/network/dist/types.d.ts +6 -0
  63. package/packages/network/dist/types.js +2 -0
  64. package/packages/network/dist/webrtcPreview.d.ts +163 -0
  65. package/packages/network/dist/webrtcPreview.js +844 -0
  66. package/packages/network/src/index.ts +1 -0
  67. package/packages/network/src/relayPreview.ts +552 -0
  68. package/packages/storage/dist/index.d.ts +3 -0
  69. package/packages/storage/dist/index.js +19 -0
  70. package/packages/storage/dist/jsonRepo.d.ts +7 -0
  71. package/packages/storage/dist/jsonRepo.js +29 -0
  72. package/packages/storage/dist/repos.d.ts +21 -0
  73. package/packages/storage/dist/repos.js +41 -0
  74. package/packages/storage/dist/socialRuntimeRepo.d.ts +5 -0
  75. package/packages/storage/dist/socialRuntimeRepo.js +52 -0
  76. package/packages/storage/src/socialRuntimeRepo.ts +4 -4
  77. package/packages/storage/tsconfig.json +6 -1
  78. package/scripts/quickstart.sh +314 -36
  79. package/scripts/silicaclaw-cli.mjs +458 -24
  80. package/scripts/silicaclaw-gateway.mjs +467 -0
  81. package/scripts/webrtc-signaling-server.mjs +89 -5
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SocialRuntimeRepo = void 0;
4
+ const path_1 = require("path");
5
+ const jsonRepo_1 = require("./jsonRepo");
6
+ function emptyRuntime() {
7
+ return {
8
+ enabled: true,
9
+ public_enabled: false,
10
+ source_path: null,
11
+ last_loaded_at: 0,
12
+ social_found: false,
13
+ parse_error: null,
14
+ resolved_identity: null,
15
+ resolved_profile: null,
16
+ resolved_network: {
17
+ mode: "global-preview",
18
+ adapter: "relay-preview",
19
+ namespace: "silicaclaw.preview",
20
+ port: null,
21
+ signaling_url: "https://relay.silicaclaw.com",
22
+ signaling_urls: [],
23
+ room: "silicaclaw-global-preview",
24
+ seed_peers: [],
25
+ bootstrap_hints: [],
26
+ bootstrap_sources: [],
27
+ },
28
+ resolved_discovery: {
29
+ discoverable: true,
30
+ allow_profile_broadcast: true,
31
+ allow_presence_broadcast: true,
32
+ },
33
+ visibility: {
34
+ show_display_name: true,
35
+ show_bio: true,
36
+ show_tags: true,
37
+ show_agent_id: true,
38
+ show_last_seen: true,
39
+ show_capabilities_summary: true,
40
+ },
41
+ openclaw: {
42
+ bind_existing_identity: true,
43
+ use_openclaw_profile_if_available: true,
44
+ },
45
+ };
46
+ }
47
+ class SocialRuntimeRepo extends jsonRepo_1.JsonFileRepo {
48
+ constructor(rootDir = process.cwd()) {
49
+ super((0, path_1.resolve)(rootDir, ".silicaclaw", "social.runtime.json"), emptyRuntime);
50
+ }
51
+ }
52
+ exports.SocialRuntimeRepo = SocialRuntimeRepo;
@@ -13,13 +13,13 @@ function emptyRuntime(): SocialRuntimeConfig {
13
13
  resolved_identity: null,
14
14
  resolved_profile: null,
15
15
  resolved_network: {
16
- mode: "lan",
17
- adapter: "real-preview",
16
+ mode: "global-preview",
17
+ adapter: "relay-preview",
18
18
  namespace: "silicaclaw.preview",
19
19
  port: null,
20
- signaling_url: "http://localhost:4510",
20
+ signaling_url: "https://relay.silicaclaw.com",
21
21
  signaling_urls: [],
22
- room: "silicaclaw-room",
22
+ room: "silicaclaw-global-preview",
23
23
  seed_peers: [],
24
24
  bootstrap_hints: [],
25
25
  bootstrap_sources: [],
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "extends": "../../tsconfig.base.json",
3
3
  "compilerOptions": {
4
- "outDir": "./dist"
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "baseUrl": ".",
7
+ "paths": {
8
+ "@silicaclaw/core": ["../../node_modules/@silicaclaw/core/dist/index.d.ts"]
9
+ }
5
10
  },
6
11
  "include": ["src"]
7
12
  }
@@ -1,10 +1,17 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
- INVOKE_PWD="$PWD"
4
+ 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:-3}"
9
+ CONNECT_MODE="${QUICKSTART_CONNECT_MODE:-0}"
10
+
11
+ case "$DEFAULT_MODE_PICK" in
12
+ 1|2|3) ;;
13
+ *) DEFAULT_MODE_PICK="1" ;;
14
+ esac
8
15
 
9
16
  case "$ROOT_DIR" in
10
17
  *"/.npm/_npx/"*)
@@ -14,22 +21,152 @@ esac
14
21
 
15
22
  STEP=1
16
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
+
17
40
  line() {
18
41
  printf '\n%s\n' "------------------------------------------------------------"
19
42
  }
20
43
 
21
44
  title() {
22
45
  line
23
- printf '[Step %s] %s\n' "$STEP" "$1"
46
+ printf '%s[Step %s]%s %s\n' "$BOLD" "$STEP" "$RESET" "$1"
24
47
  STEP=$((STEP + 1))
25
48
  }
26
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
+
27
67
  run_cmd() {
28
68
  local cmd="$1"
29
69
  printf '→ %s\n' "$cmd"
30
70
  eval "$cmd"
31
71
  }
32
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
+
33
170
  ask_yes_no() {
34
171
  local prompt="$1"
35
172
  local default="${2:-Y}"
@@ -66,9 +203,30 @@ detect_public_ip() {
66
203
  printf '%s' "$ip"
67
204
  }
68
205
 
206
+ url_host() {
207
+ local raw="${1:-}"
208
+ if [ -z "$raw" ]; then
209
+ printf ''
210
+ return 0
211
+ fi
212
+ node -e "try{const u=new URL(process.argv[1]); process.stdout.write(u.hostname||'');}catch{process.stdout.write('');}" "$raw"
213
+ }
214
+
215
+ url_port_or_default() {
216
+ local raw="${1:-}"
217
+ local fallback="${2:-4510}"
218
+ if [ -z "$raw" ]; then
219
+ printf '%s' "$fallback"
220
+ return 0
221
+ fi
222
+ node -e "try{const u=new URL(process.argv[1]); process.stdout.write(String(u.port || '$fallback'));}catch{process.stdout.write('$fallback');}" "$raw"
223
+ }
224
+
69
225
  title "SilicaClaw Quick Start 启动"
70
- echo "目录: $ROOT_DIR"
71
- echo "目标: 用终端一步步完成安装与启动(类似 OpenClaw Quick Start)"
226
+ headline
227
+ echo ""
228
+ kv "目录" "$ROOT_DIR"
229
+ kv "目标" "一步步完成安装、联网与启动"
72
230
  pause_continue
73
231
 
74
232
  if [ "$IS_NPX_MODE" -eq 1 ]; then
@@ -85,7 +243,8 @@ if [ "$IS_NPX_MODE" -eq 1 ]; then
85
243
  fi
86
244
 
87
245
  mkdir -p "$TARGET_DIR"
88
- echo "正在复制项目文件到: $TARGET_DIR"
246
+ kv "安装目录" "$TARGET_DIR"
247
+ echo "正在复制项目文件..."
89
248
  if command -v rsync >/dev/null 2>&1; then
90
249
  rsync -a --delete \
91
250
  --exclude '.git/' \
@@ -98,7 +257,8 @@ if [ "$IS_NPX_MODE" -eq 1 ]; then
98
257
  rm -rf "$TARGET_DIR/.git" "$TARGET_DIR/node_modules" "$TARGET_DIR/.npm-cache"
99
258
  fi
100
259
  WORK_DIR="$TARGET_DIR"
101
- echo "工作目录已切换到: $WORK_DIR"
260
+ success "工作目录已切换"
261
+ kv "目录" "$WORK_DIR"
102
262
  pause_continue
103
263
  fi
104
264
 
@@ -114,8 +274,8 @@ fi
114
274
 
115
275
  NODE_VER="$(node -p "process.versions.node")"
116
276
  NPM_VER="$(npm -v)"
117
- echo "node: $NODE_VER"
118
- echo "npm : $NPM_VER"
277
+ kv "node" "$NODE_VER"
278
+ kv "npm" "$NPM_VER"
119
279
 
120
280
  if ! node -e "const v=process.versions.node.split('.').map(Number); if (v[0] < 18) process.exit(1)"; then
121
281
  echo "Node.js 版本过低,请升级到 18+"
@@ -133,6 +293,70 @@ else
133
293
  fi
134
294
  fi
135
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
+
136
360
  title "准备 social.md"
137
361
  if [ -f "$WORK_DIR/social.md" ]; then
138
362
  echo "已存在 social.md,保留现有配置。"
@@ -148,16 +372,22 @@ fi
148
372
  title "选择网络模式"
149
373
  echo "1) local 单机预览(最快)"
150
374
  echo "2) lan 局域网预览(A/B 双机)"
151
- echo "3) global-preview 非局域网预览(WebRTC)"
152
- echo "提示: 不确定就直接回车(默认 local)。"
153
- echo "提示: 只有在你已有可达 signaling 地址时,才选择 3。"
154
- read -r -p "请输入模式编号 [1/2/3] (默认 1): " MODE_PICK || true
155
- MODE_PICK="${MODE_PICK:-1}"
375
+ echo "3) global-preview 互联网预览(Relay,推荐)"
376
+ note "不确定就直接回车,默认 global-preview。"
377
+ note "互联网模式需要所有节点都能访问同一个 relay。"
378
+ if [ "$CONNECT_MODE" = "1" ]; then
379
+ MODE_PICK="3"
380
+ echo "connect 模式:已自动选择 global-preview。"
381
+ else
382
+ read -r -p "请输入模式编号 [1/2/3] (默认 ${DEFAULT_MODE_PICK}): " MODE_PICK || true
383
+ MODE_PICK="${MODE_PICK:-$DEFAULT_MODE_PICK}"
384
+ fi
156
385
 
157
386
  NETWORK_MODE="local"
158
387
  NETWORK_ADAPTER="local-event-bus"
159
388
  WEBRTC_SIGNALING_URL_VALUE=""
160
- WEBRTC_ROOM_VALUE="silicaclaw-demo"
389
+ WEBRTC_ROOM_VALUE="silicaclaw-global-preview"
390
+ AUTO_START_SIGNALING=0
161
391
 
162
392
  case "$MODE_PICK" in
163
393
  2)
@@ -166,28 +396,40 @@ case "$MODE_PICK" in
166
396
  ;;
167
397
  3)
168
398
  NETWORK_MODE="global-preview"
169
- NETWORK_ADAPTER="webrtc-preview"
399
+ NETWORK_ADAPTER="relay-preview"
170
400
  PUBLIC_IP="$(detect_public_ip)"
171
- SIGNALING_DEFAULT="http://localhost:4510"
401
+ SIGNALING_DEFAULT="${WEBRTC_SIGNALING_URL:-https://relay.silicaclaw.com}"
172
402
  if [ -n "$PUBLIC_IP" ]; then
173
- SIGNALING_DEFAULT="http://$PUBLIC_IP:4510"
403
+ SIGNALING_DEFAULT="https://relay.silicaclaw.com"
174
404
  fi
175
- echo "提示: signaling 地址需要“所有节点可访问”。"
405
+ note "signaling 地址需要所有节点都可访问。"
176
406
  if [ -n "$PUBLIC_IP" ]; then
177
- echo "已检测到本机公网 IP: $PUBLIC_IP"
178
- echo "如果你这台机器就是 signaling 服务器,可直接回车使用默认值。"
407
+ kv "公网 IP" "$PUBLIC_IP"
408
+ note "如果这台机器就是 relay 所在主机,可直接使用默认值。"
179
409
  else
180
- echo "未检测到公网 IP,将使用默认值: $SIGNALING_DEFAULT"
181
- echo "如果 signaling 在其他机器,请输入该机器公网地址。"
410
+ kv "默认 relay" "$SIGNALING_DEFAULT"
411
+ note "如需私有 relay,可改成你自己的公网地址。"
182
412
  fi
183
413
  read -r -p "请输入 signaling URL(默认 ${SIGNALING_DEFAULT}): " WEBRTC_SIGNALING_URL_INPUT || true
184
414
  WEBRTC_SIGNALING_URL_VALUE="${WEBRTC_SIGNALING_URL_INPUT:-$SIGNALING_DEFAULT}"
185
415
  if [ -z "${WEBRTC_SIGNALING_URL_VALUE:-}" ]; then
186
- echo "global-preview 必须提供 signaling URL"
416
+ echo "global-preview 必须提供公网可达的 signaling URL"
187
417
  exit 1
188
418
  fi
189
- read -r -p "请输入 room(默认 silicaclaw-demo): " WEBRTC_ROOM_VALUE_INPUT || true
190
- WEBRTC_ROOM_VALUE="${WEBRTC_ROOM_VALUE_INPUT:-silicaclaw-demo}"
419
+
420
+ SIGNALING_HOST="$(url_host "$WEBRTC_SIGNALING_URL_VALUE")"
421
+ if [ "$SIGNALING_HOST" = "localhost" ] || [ "$SIGNALING_HOST" = "127.0.0.1" ]; then
422
+ note "当前 signaling URL 是本机地址,仅本机可用,不适合异地双机。"
423
+ fi
424
+
425
+ if ask_yes_no "是否在当前机器自动后台启动 signaling server(用于演示)?" "Y"; then
426
+ AUTO_START_SIGNALING=1
427
+ SIGNALING_PORT_VALUE="$(url_port_or_default "$WEBRTC_SIGNALING_URL_VALUE" "4510")"
428
+ kv "本地 relay" "PORT=$SIGNALING_PORT_VALUE"
429
+ fi
430
+
431
+ read -r -p "请输入 room(默认 silicaclaw-global-preview): " WEBRTC_ROOM_VALUE_INPUT || true
432
+ WEBRTC_ROOM_VALUE="${WEBRTC_ROOM_VALUE_INPUT:-silicaclaw-global-preview}"
191
433
  ;;
192
434
  *)
193
435
  NETWORK_MODE="local"
@@ -195,19 +437,55 @@ case "$MODE_PICK" in
195
437
  ;;
196
438
  esac
197
439
 
198
- echo "已选择: $NETWORK_MODE ($NETWORK_ADAPTER)"
440
+ success "网络模式已选择"
441
+ kv "Mode" "$NETWORK_MODE"
442
+ kv "Adapter" "$NETWORK_ADAPTER"
199
443
 
200
444
  title "启动 local-console"
201
- if [ "$NETWORK_MODE" = "global-preview" ]; then
202
- echo "将使用以下参数启动:"
203
- echo "NETWORK_ADAPTER=$NETWORK_ADAPTER"
204
- echo "WEBRTC_SIGNALING_URL=$WEBRTC_SIGNALING_URL_VALUE"
205
- echo "WEBRTC_ROOM=$WEBRTC_ROOM_VALUE"
206
- pause_continue
207
- 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"
445
+ echo "1) gateway(推荐) 后台服务模式,可用 start/stop/restart/status 管理"
446
+ echo "2) dev watch 前台开发模式(tsx watch)"
447
+ read -r -p "请选择启动方式 [1/2] (默认 1): " START_MODE_PICK || true
448
+ START_MODE_PICK="${START_MODE_PICK:-1}"
449
+
450
+ if [ "$START_MODE_PICK" = "2" ]; then
451
+ if [ "$NETWORK_MODE" = "global-preview" ]; then
452
+ if [ "$AUTO_START_SIGNALING" -eq 1 ]; then
453
+ mkdir -p "$WORK_DIR/.silicaclaw"
454
+ SIGNALING_LOG="$WORK_DIR/.silicaclaw/signaling.log"
455
+ SIGNALING_PID_FILE="$WORK_DIR/.silicaclaw/signaling.pid"
456
+ run_cmd "cd \"$WORK_DIR\" && PORT=${SIGNALING_PORT_VALUE:-4510} nohup npm run webrtc-signaling > \"$SIGNALING_LOG\" 2>&1 & echo \$! > \"$SIGNALING_PID_FILE\""
457
+ success "已后台启动 signaling server"
458
+ kv "日志" "$SIGNALING_LOG"
459
+ kv "停止" "kill \$(cat \"$SIGNALING_PID_FILE\")"
460
+ fi
461
+ echo "将使用以下参数启动(dev watch):"
462
+ kv "Adapter" "$NETWORK_ADAPTER"
463
+ kv "Relay" "$WEBRTC_SIGNALING_URL_VALUE"
464
+ kv "Room" "$WEBRTC_ROOM_VALUE"
465
+ pause_continue
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"
467
+ else
468
+ echo "将使用以下参数启动(dev watch):"
469
+ kv "Adapter" "$NETWORK_ADAPTER"
470
+ pause_continue
471
+ run_cmd "cd \"$WORK_DIR\" && NETWORK_ADAPTER=$NETWORK_ADAPTER npm run local-console"
472
+ fi
208
473
  else
209
- echo "将使用以下参数启动:"
210
- echo "NETWORK_ADAPTER=$NETWORK_ADAPTER"
474
+ GATEWAY_CMD="cd \"$WORK_DIR\" && npm run gateway -- start --mode=$NETWORK_MODE"
475
+ if [ "$NETWORK_MODE" = "global-preview" ]; then
476
+ GATEWAY_CMD="$GATEWAY_CMD --signaling-url=$WEBRTC_SIGNALING_URL_VALUE --room=$WEBRTC_ROOM_VALUE"
477
+ fi
478
+ echo "将使用 gateway 后台启动:"
479
+ kv "Command" "$GATEWAY_CMD"
211
480
  pause_continue
212
- run_cmd "cd \"$WORK_DIR\" && NETWORK_ADAPTER=$NETWORK_ADAPTER npm run local-console"
481
+ run_cmd "$GATEWAY_CMD"
482
+ echo ""
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"
490
+ echo ""
213
491
  fi