@silicaclaw/cli 2026.3.19-19 → 2026.3.19-21

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 (93) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/INSTALL.md +12 -8
  3. package/README.md +16 -12
  4. package/VERSION +1 -1
  5. package/apps/local-console/dist/apps/local-console/src/server.d.ts +2 -0
  6. package/apps/local-console/dist/apps/local-console/src/server.js +25 -1
  7. package/apps/local-console/public/app/social.js +17 -1
  8. package/apps/local-console/public/app/translations.js +8 -4
  9. package/apps/local-console/src/server.ts +32 -1
  10. package/dist/apps/local-console/src/server.d.ts +1 -0
  11. package/dist/apps/local-console/src/server.js +555 -0
  12. package/docs/NEW_USER_INSTALL.md +13 -10
  13. package/docs/NEW_USER_OPERATIONS.md +3 -3
  14. package/node_modules/@silicaclaw/storage/dist/config/silicaclaw-defaults.json +19 -0
  15. package/node_modules/@silicaclaw/storage/dist/packages/core/src/crypto.d.ts +6 -0
  16. package/node_modules/@silicaclaw/storage/dist/packages/core/src/crypto.js +50 -0
  17. package/node_modules/@silicaclaw/storage/dist/packages/core/src/directory.d.ts +17 -0
  18. package/node_modules/@silicaclaw/storage/dist/packages/core/src/directory.js +145 -0
  19. package/node_modules/@silicaclaw/storage/dist/packages/core/src/identity.d.ts +2 -0
  20. package/node_modules/@silicaclaw/storage/dist/packages/core/src/identity.js +18 -0
  21. package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.d.ts +12 -0
  22. package/node_modules/@silicaclaw/storage/dist/packages/core/src/index.js +28 -0
  23. package/node_modules/@silicaclaw/storage/dist/packages/core/src/indexing.d.ts +6 -0
  24. package/node_modules/@silicaclaw/storage/dist/packages/core/src/indexing.js +43 -0
  25. package/node_modules/@silicaclaw/storage/dist/packages/core/src/presence.d.ts +4 -0
  26. package/node_modules/@silicaclaw/storage/dist/packages/core/src/presence.js +23 -0
  27. package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.d.ts +4 -0
  28. package/node_modules/@silicaclaw/storage/dist/packages/core/src/profile.js +39 -0
  29. package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
  30. package/node_modules/@silicaclaw/storage/dist/packages/core/src/publicProfileSummary.js +103 -0
  31. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialConfig.d.ts +100 -0
  32. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialConfig.js +300 -0
  33. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialMessage.d.ts +19 -0
  34. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialMessage.js +69 -0
  35. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialResolver.d.ts +46 -0
  36. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialResolver.js +237 -0
  37. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialTemplate.d.ts +2 -0
  38. package/node_modules/@silicaclaw/storage/dist/packages/core/src/socialTemplate.js +90 -0
  39. package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.d.ts +59 -0
  40. package/node_modules/@silicaclaw/storage/dist/packages/core/src/types.js +2 -0
  41. package/node_modules/@silicaclaw/storage/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
  42. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/index.d.ts +3 -0
  43. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/index.js +19 -0
  44. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/jsonRepo.d.ts +7 -0
  45. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/jsonRepo.js +29 -0
  46. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.d.ts +61 -0
  47. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/repos.js +67 -0
  48. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/socialRuntimeRepo.d.ts +5 -0
  49. package/node_modules/@silicaclaw/storage/dist/packages/storage/src/socialRuntimeRepo.js +57 -0
  50. package/node_modules/@silicaclaw/storage/tsconfig.json +1 -6
  51. package/openclaw-skills/silicaclaw-broadcast/VERSION +1 -1
  52. package/openclaw-skills/silicaclaw-broadcast/manifest.json +1 -1
  53. package/package.json +3 -1
  54. package/packages/storage/dist/config/silicaclaw-defaults.json +19 -0
  55. package/packages/storage/dist/packages/core/src/crypto.d.ts +6 -0
  56. package/packages/storage/dist/packages/core/src/crypto.js +50 -0
  57. package/packages/storage/dist/packages/core/src/directory.d.ts +17 -0
  58. package/packages/storage/dist/packages/core/src/directory.js +145 -0
  59. package/packages/storage/dist/packages/core/src/identity.d.ts +2 -0
  60. package/packages/storage/dist/packages/core/src/identity.js +18 -0
  61. package/packages/storage/dist/packages/core/src/index.d.ts +12 -0
  62. package/packages/storage/dist/packages/core/src/index.js +28 -0
  63. package/packages/storage/dist/packages/core/src/indexing.d.ts +6 -0
  64. package/packages/storage/dist/packages/core/src/indexing.js +43 -0
  65. package/packages/storage/dist/packages/core/src/presence.d.ts +4 -0
  66. package/packages/storage/dist/packages/core/src/presence.js +23 -0
  67. package/packages/storage/dist/packages/core/src/profile.d.ts +4 -0
  68. package/packages/storage/dist/packages/core/src/profile.js +39 -0
  69. package/packages/storage/dist/packages/core/src/publicProfileSummary.d.ts +70 -0
  70. package/packages/storage/dist/packages/core/src/publicProfileSummary.js +103 -0
  71. package/packages/storage/dist/packages/core/src/socialConfig.d.ts +100 -0
  72. package/packages/storage/dist/packages/core/src/socialConfig.js +300 -0
  73. package/packages/storage/dist/packages/core/src/socialMessage.d.ts +19 -0
  74. package/packages/storage/dist/packages/core/src/socialMessage.js +69 -0
  75. package/packages/storage/dist/packages/core/src/socialResolver.d.ts +46 -0
  76. package/packages/storage/dist/packages/core/src/socialResolver.js +237 -0
  77. package/packages/storage/dist/packages/core/src/socialTemplate.d.ts +2 -0
  78. package/packages/storage/dist/packages/core/src/socialTemplate.js +90 -0
  79. package/packages/storage/dist/packages/core/src/types.d.ts +59 -0
  80. package/packages/storage/dist/packages/core/src/types.js +2 -0
  81. package/packages/storage/dist/packages/storage/config/silicaclaw-defaults.json +19 -0
  82. package/packages/storage/dist/packages/storage/src/index.d.ts +3 -0
  83. package/packages/storage/dist/packages/storage/src/index.js +19 -0
  84. package/packages/storage/dist/packages/storage/src/jsonRepo.d.ts +7 -0
  85. package/packages/storage/dist/packages/storage/src/jsonRepo.js +29 -0
  86. package/packages/storage/dist/packages/storage/src/repos.d.ts +61 -0
  87. package/packages/storage/dist/packages/storage/src/repos.js +67 -0
  88. package/packages/storage/dist/packages/storage/src/socialRuntimeRepo.d.ts +5 -0
  89. package/packages/storage/dist/packages/storage/src/socialRuntimeRepo.js +57 -0
  90. package/packages/storage/tsconfig.json +1 -6
  91. package/scripts/quickstart.sh +1 -1
  92. package/scripts/silicaclaw-cli.mjs +2 -1
  93. package/scripts/silicaclaw-gateway.mjs +209 -32
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawn, spawnSync } from "node:child_process";
4
- import { existsSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { cpSync, existsSync, mkdirSync, openSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
5
5
  import { homedir } from "node:os";
6
6
  import { dirname, join, resolve } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
@@ -54,7 +54,7 @@ function headline() {
54
54
  version = "unknown";
55
55
  }
56
56
  }
57
- console.log(`${paint("SilicaClaw", COLOR.bold, COLOR.orange)} ${paint(displayVersion(version), COLOR.dim)}`);
57
+ console.log(`${paint("🦀 SilicaClaw", COLOR.bold, COLOR.orange)} ${paint(displayVersion(version), COLOR.dim)}`);
58
58
  console.log(paint("Public identity and discovery for OpenClaw agents.", COLOR.dim));
59
59
  }
60
60
 
@@ -130,6 +130,7 @@ const APP_DIR = detectAppDir();
130
130
  const WORKSPACE_DIR = detectWorkspaceDir();
131
131
  const LOCAL_CONSOLE_DIR = join(APP_DIR, "apps", "local-console");
132
132
  const STATE_DIR = join(homedir(), ".silicaclaw", "gateway");
133
+ const MANAGED_RUNTIME_DIR = join(homedir(), ".silicaclaw", "runtime", "silicaclaw");
133
134
  const CONSOLE_PID_FILE = join(STATE_DIR, "local-console.pid");
134
135
  const CONSOLE_LOG_FILE = join(STATE_DIR, "local-console.log");
135
136
  const SIGNALING_PID_FILE = join(STATE_DIR, "signaling.pid");
@@ -147,6 +148,10 @@ function ensureLaunchAgentsDir() {
147
148
  mkdirSync(LAUNCH_AGENTS_DIR, { recursive: true });
148
149
  }
149
150
 
151
+ function ensureManagedRuntimeDir() {
152
+ mkdirSync(MANAGED_RUNTIME_DIR, { recursive: true });
153
+ }
154
+
150
155
  function readPid(file) {
151
156
  if (!existsSync(file)) return null;
152
157
  const text = String(readFileSync(file, "utf8")).trim();
@@ -168,6 +173,46 @@ function removeFileIfExists(path) {
168
173
  if (existsSync(path)) rmSync(path, { force: true });
169
174
  }
170
175
 
176
+ function syncManagedRuntime() {
177
+ if (resolve(APP_DIR) === resolve(MANAGED_RUNTIME_DIR)) return MANAGED_RUNTIME_DIR;
178
+
179
+ ensureManagedRuntimeDir();
180
+ const entries = [
181
+ "config",
182
+ "dist",
183
+ "scripts",
184
+ "apps/local-console/public",
185
+ "apps/public-explorer/public",
186
+ "package.json",
187
+ "package-lock.json",
188
+ "VERSION",
189
+ "node_modules",
190
+ ];
191
+
192
+ for (const rel of entries) {
193
+ const src = resolve(APP_DIR, rel);
194
+ if (!existsSync(src)) continue;
195
+ const dst = resolve(MANAGED_RUNTIME_DIR, rel);
196
+ rmSync(dst, { recursive: true, force: true });
197
+ cpSync(src, dst, {
198
+ recursive: true,
199
+ force: true,
200
+ dereference: rel === "node_modules",
201
+ });
202
+ }
203
+
204
+ const manifest = {
205
+ source_app_dir: APP_DIR,
206
+ synced_at: Date.now(),
207
+ version: readJson(resolve(APP_DIR, "package.json"))?.version || null,
208
+ dist_server_mtime: existsSync(resolve(APP_DIR, "dist", "apps", "local-console", "src", "server.js"))
209
+ ? statSync(resolve(APP_DIR, "dist", "apps", "local-console", "src", "server.js")).mtimeMs
210
+ : null,
211
+ };
212
+ writeFileSync(resolve(MANAGED_RUNTIME_DIR, ".silicaclaw-runtime.json"), JSON.stringify(manifest, null, 2));
213
+ return MANAGED_RUNTIME_DIR;
214
+ }
215
+
171
216
  async function stopPid(pid, name) {
172
217
  if (!pid || !isRunning(pid)) return;
173
218
  try {
@@ -256,25 +301,34 @@ function runLaunchctl(args) {
256
301
  });
257
302
  }
258
303
 
259
- function resolveCommandPath(command) {
260
- const result = spawnSync("which", [command], {
261
- encoding: "utf8",
262
- stdio: ["ignore", "pipe", "ignore"],
263
- });
264
- if ((result.status ?? 1) === 0) {
265
- const value = String(result.stdout || "").trim();
266
- if (value) return value;
267
- }
268
- return command;
304
+ function launchServiceTarget(label) {
305
+ return `${launchdDomain()}/${label}`;
306
+ }
307
+
308
+ function isLaunchctlNotLoadedResult(result) {
309
+ const text = `${result?.stdout || ""}\n${result?.stderr || ""}`.toLowerCase();
310
+ return (
311
+ text.includes("could not find service") ||
312
+ text.includes("service not found") ||
313
+ text.includes("bad request") ||
314
+ text.includes("not loaded")
315
+ );
316
+ }
317
+
318
+ function localConsoleProgramArguments(appDir = APP_DIR) {
319
+ return [
320
+ process.execPath,
321
+ resolve(appDir, "dist", "apps", "local-console", "src", "server.js"),
322
+ ];
269
323
  }
270
324
 
271
325
  function isLaunchAgentLoaded(label) {
272
- const result = runLaunchctl(["print", `${launchdDomain()}/${label}`]);
326
+ const result = runLaunchctl(["print", launchServiceTarget(label)]);
273
327
  return (result.status ?? 1) === 0;
274
328
  }
275
329
 
276
330
  function readLaunchAgentRuntime(label) {
277
- const result = runLaunchctl(["print", `${launchdDomain()}/${label}`]);
331
+ const result = runLaunchctl(["print", launchServiceTarget(label)]);
278
332
  if ((result.status ?? 1) !== 0) return { loaded: false, pid: null };
279
333
  const text = `${result.stdout || ""}\n${result.stderr || ""}`;
280
334
  const pidMatch = text.match(/pid = (\d+)/);
@@ -284,7 +338,47 @@ function readLaunchAgentRuntime(label) {
284
338
  };
285
339
  }
286
340
 
287
- function installLaunchAgent({ label, programArguments, workingDirectory, logFile, environment }) {
341
+ function writeLaunchAgentPlistIfChanged(plistPath, plist) {
342
+ const current = existsSync(plistPath) ? String(readFileSync(plistPath, "utf8")) : null;
343
+ if (current === plist) return false;
344
+ writeFileSync(plistPath, plist, "utf8");
345
+ return true;
346
+ }
347
+
348
+ function bootstrapLaunchAgent(label, plistPath) {
349
+ const result = runLaunchctl(["bootstrap", launchdDomain(), plistPath]);
350
+ if ((result.status ?? 1) !== 0) {
351
+ const detail = String(result.stderr || result.stdout || "launchctl bootstrap failed").trim();
352
+ throw new Error(detail);
353
+ }
354
+ }
355
+
356
+ function startLaunchAgent(label, plistPath) {
357
+ const result = runLaunchctl(["start", launchServiceTarget(label)]);
358
+ if ((result.status ?? 1) === 0) return;
359
+ if (!isLaunchctlNotLoadedResult(result)) {
360
+ const detail = String(result.stderr || result.stdout || "launchctl start failed").trim();
361
+ throw new Error(detail);
362
+ }
363
+ bootstrapLaunchAgent(label, plistPath);
364
+ }
365
+
366
+ function restartLaunchAgent(label, plistPath) {
367
+ const result = runLaunchctl(["kickstart", "-k", launchServiceTarget(label)]);
368
+ if ((result.status ?? 1) === 0) return;
369
+ if (!isLaunchctlNotLoadedResult(result)) {
370
+ const detail = String(result.stderr || result.stdout || "launchctl kickstart failed").trim();
371
+ throw new Error(detail);
372
+ }
373
+ bootstrapLaunchAgent(label, plistPath);
374
+ const retry = runLaunchctl(["kickstart", "-k", launchServiceTarget(label)]);
375
+ if ((retry.status ?? 1) !== 0) {
376
+ const detail = String(retry.stderr || retry.stdout || "launchctl kickstart failed").trim();
377
+ throw new Error(detail);
378
+ }
379
+ }
380
+
381
+ function ensureLaunchAgent({ label, programArguments, workingDirectory, logFile, environment }) {
288
382
  ensureLaunchAgentsDir();
289
383
  ensureStateDir();
290
384
  const plistPath = launchAgentPlistPath(label);
@@ -296,17 +390,23 @@ function installLaunchAgent({ label, programArguments, workingDirectory, logFile
296
390
  stderrPath: logFile,
297
391
  environment,
298
392
  });
299
- writeFileSync(plistPath, plist, "utf8");
300
-
301
- if (isLaunchAgentLoaded(label)) {
302
- runLaunchctl(["bootout", launchdDomain(), plistPath]);
393
+ const changed = writeLaunchAgentPlistIfChanged(plistPath, plist);
394
+ const loaded = isLaunchAgentLoaded(label);
395
+
396
+ if (changed && loaded) {
397
+ const bootout = runLaunchctl(["bootout", launchdDomain(), plistPath]);
398
+ if ((bootout.status ?? 1) !== 0 && !isLaunchctlNotLoadedResult(bootout)) {
399
+ const detail = String(bootout.stderr || bootout.stdout || "launchctl bootout failed").trim();
400
+ throw new Error(detail);
401
+ }
402
+ bootstrapLaunchAgent(label, plistPath);
403
+ return { changed: true, loaded: true, plistPath };
303
404
  }
304
405
 
305
- const result = runLaunchctl(["bootstrap", launchdDomain(), plistPath]);
306
- if ((result.status ?? 1) !== 0) {
307
- const detail = String(result.stderr || result.stdout || "launchctl bootstrap failed").trim();
308
- throw new Error(detail);
406
+ if (!loaded) {
407
+ bootstrapLaunchAgent(label, plistPath);
309
408
  }
409
+ return { changed, loaded, plistPath };
310
410
  }
311
411
 
312
412
  function stopLaunchAgent(label) {
@@ -409,6 +509,7 @@ function buildStatusPayload() {
409
509
  const signalingListener = listeningProcessOnPort(4510);
410
510
  return {
411
511
  app_dir: APP_DIR,
512
+ managed_app_dir: state?.managed_app_dir || null,
412
513
  workspace_dir: state?.workspace_dir || WORKSPACE_DIR,
413
514
  mode: state?.mode || "unknown",
414
515
  adapter: state?.adapter || "unknown",
@@ -691,8 +792,8 @@ async function startAll() {
691
792
  (host === "localhost" || host === "127.0.0.1");
692
793
 
693
794
  if (isLaunchdPlatform()) {
694
- const npmPath = resolveCommandPath("npm");
695
- const signalingEntry = resolve(APP_DIR, "scripts", "webrtc-signaling-server.mjs");
795
+ const managedAppDir = syncManagedRuntime();
796
+ const signalingEntry = resolve(managedAppDir, "scripts", "webrtc-signaling-server.mjs");
696
797
  await drainOwnedListener(LOCAL_CONSOLE_PORT, "local-console", 8000);
697
798
  await drainOwnedListener(4510, "signaling", 5000);
698
799
  const baseEnv = {
@@ -700,24 +801,25 @@ async function startAll() {
700
801
  NETWORK_MODE: mode,
701
802
  WEBRTC_SIGNALING_URL: signalingUrl,
702
803
  WEBRTC_ROOM: room,
804
+ SILICACLAW_APP_DIR: managedAppDir,
703
805
  SILICACLAW_WORKSPACE_DIR: WORKSPACE_DIR,
704
806
  PATH: process.env.PATH || "/usr/bin:/bin:/usr/sbin:/sbin",
705
807
  HOME: process.env.HOME || homedir(),
706
808
  };
707
809
 
708
- installLaunchAgent({
810
+ ensureLaunchAgent({
709
811
  label: LOCAL_CONSOLE_LABEL,
710
- programArguments: [npmPath, "run", "--workspace", "@silicaclaw/local-console", "start"],
711
- workingDirectory: APP_DIR,
812
+ programArguments: localConsoleProgramArguments(managedAppDir),
813
+ workingDirectory: managedAppDir,
712
814
  logFile: CONSOLE_LOG_FILE,
713
815
  environment: baseEnv,
714
816
  });
715
817
 
716
818
  if (shouldAutoStartSignaling) {
717
- installLaunchAgent({
819
+ ensureLaunchAgent({
718
820
  label: SIGNALING_LABEL,
719
821
  programArguments: [process.execPath, signalingEntry],
720
- workingDirectory: APP_DIR,
822
+ workingDirectory: managedAppDir,
721
823
  logFile: SIGNALING_LOG_FILE,
722
824
  environment: {
723
825
  PATH: baseEnv.PATH,
@@ -731,6 +833,7 @@ async function startAll() {
731
833
 
732
834
  writeState({
733
835
  app_dir: APP_DIR,
836
+ managed_app_dir: managedAppDir,
734
837
  workspace_dir: WORKSPACE_DIR,
735
838
  mode,
736
839
  adapter,
@@ -799,6 +902,81 @@ async function startAll() {
799
902
  return { localPid, signalingPid: shouldAutoStartSignaling ? signalingPid : null };
800
903
  }
801
904
 
905
+ async function restartAll() {
906
+ if (!isLaunchdPlatform()) {
907
+ await stopAll();
908
+ await startAll();
909
+ return;
910
+ }
911
+
912
+ ensureStateDir();
913
+
914
+ const mode = parseMode(parseFlag("mode", process.env.NETWORK_MODE || DEFAULT_NETWORK_MODE));
915
+ const adapter = adapterForMode(mode);
916
+ const signalingUrl = parseFlag("signaling-url", process.env.WEBRTC_SIGNALING_URL || DEFAULT_SIGNALING_URL);
917
+ const room = parseFlag("room", process.env.WEBRTC_ROOM || DEFAULT_ROOM);
918
+ const shouldDisableSignaling = hasFlag("no-signaling");
919
+ const { host, port } = parseUrlHostPort(signalingUrl);
920
+ const shouldAutoStartSignaling =
921
+ mode === "global-preview" &&
922
+ !shouldDisableSignaling &&
923
+ (host === "localhost" || host === "127.0.0.1");
924
+
925
+ const managedAppDir = syncManagedRuntime();
926
+ const signalingEntry = resolve(managedAppDir, "scripts", "webrtc-signaling-server.mjs");
927
+ const baseEnv = {
928
+ NETWORK_ADAPTER: adapter,
929
+ NETWORK_MODE: mode,
930
+ WEBRTC_SIGNALING_URL: signalingUrl,
931
+ WEBRTC_ROOM: room,
932
+ SILICACLAW_APP_DIR: managedAppDir,
933
+ SILICACLAW_WORKSPACE_DIR: WORKSPACE_DIR,
934
+ PATH: process.env.PATH || "/usr/bin:/bin:/usr/sbin:/sbin",
935
+ HOME: process.env.HOME || homedir(),
936
+ };
937
+
938
+ const localConsoleService = ensureLaunchAgent({
939
+ label: LOCAL_CONSOLE_LABEL,
940
+ programArguments: localConsoleProgramArguments(managedAppDir),
941
+ workingDirectory: managedAppDir,
942
+ logFile: CONSOLE_LOG_FILE,
943
+ environment: baseEnv,
944
+ });
945
+ if (!localConsoleService.changed) {
946
+ restartLaunchAgent(LOCAL_CONSOLE_LABEL, localConsoleService.plistPath);
947
+ }
948
+
949
+ if (shouldAutoStartSignaling) {
950
+ const signalingService = ensureLaunchAgent({
951
+ label: SIGNALING_LABEL,
952
+ programArguments: [process.execPath, signalingEntry],
953
+ workingDirectory: managedAppDir,
954
+ logFile: SIGNALING_LOG_FILE,
955
+ environment: {
956
+ PATH: baseEnv.PATH,
957
+ HOME: baseEnv.HOME,
958
+ PORT: String(port),
959
+ },
960
+ });
961
+ if (!signalingService.changed) {
962
+ restartLaunchAgent(SIGNALING_LABEL, signalingService.plistPath);
963
+ }
964
+ } else {
965
+ uninstallLaunchAgent(SIGNALING_LABEL);
966
+ }
967
+
968
+ writeState({
969
+ app_dir: APP_DIR,
970
+ managed_app_dir: managedAppDir,
971
+ workspace_dir: WORKSPACE_DIR,
972
+ mode,
973
+ adapter,
974
+ signaling_url: signalingUrl,
975
+ room,
976
+ updated_at: Date.now(),
977
+ });
978
+ }
979
+
802
980
  async function main() {
803
981
  if (cmd === "help" || cmd === "-h" || cmd === "--help") {
804
982
  printHelp();
@@ -841,8 +1019,7 @@ async function main() {
841
1019
  return;
842
1020
  }
843
1021
  if (cmd === "restart") {
844
- await stopAll();
845
- await startAll();
1022
+ await restartAll();
846
1023
  const listener = await waitForCurrentAppListener(LOCAL_CONSOLE_PORT, "local-console", 15000);
847
1024
  if (!listener || !isCurrentAppListener(listener, "local-console")) {
848
1025
  headline();