@silicaclaw/cli 2026.3.20-8 → 2026.3.20-9

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/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## v1.0 beta - 2026-03-20
4
4
 
5
+ ### 2026.3.20-9
6
+
7
+ - release build:
8
+ - prepared another fresh latest-channel package build without publishing
9
+ - regenerated the npm tarball through the verified release packing workflow
10
+
5
11
  ### 2026.3.20-8
6
12
 
7
13
  - release build:
package/VERSION CHANGED
@@ -1 +1 @@
1
- v2026.3.20-8
1
+ v2026.3.20-9
@@ -245,6 +245,15 @@ export declare class LocalNodeService {
245
245
  can_enable_public_discovery: boolean;
246
246
  next_steps: string[];
247
247
  };
248
+ openclaw: {
249
+ detected: boolean;
250
+ running: boolean;
251
+ detection_mode: "gateway" | "gateway-probe+process+gateway" | "gateway-probe+gateway" | "gateway-probe+process" | "gateway-probe" | "process+gateway" | "process" | "not_running";
252
+ gateway_url: string;
253
+ gateway_probe_ok: boolean;
254
+ status_ok: boolean;
255
+ skill_installed: boolean;
256
+ };
248
257
  social: {
249
258
  found: boolean;
250
259
  enabled: boolean;
@@ -433,68 +433,17 @@ function resolveOpenClawGatewayProbeCommand(workspaceRoot) {
433
433
  function detectOpenClawRuntime(workspaceRoot) {
434
434
  const configuredGateway = readOpenClawConfiguredGateway(workspaceRoot);
435
435
  const statusCommand = resolveOpenClawStatusCommand(workspaceRoot);
436
- const gatewayProbeCommand = resolveOpenClawGatewayProbeCommand(workspaceRoot);
437
- const statusProbe = statusCommand
438
- ? (0, child_process_1.spawnSync)(statusCommand.cmd, statusCommand.args, {
439
- encoding: "utf8",
440
- env: process.env,
441
- })
442
- : null;
443
- const statusStdout = String(statusProbe?.stdout || "");
444
- const statusStderr = String(statusProbe?.stderr || "");
445
- const statusLooksConfigured = Boolean(statusCommand &&
446
- statusProbe &&
447
- statusProbe.status === 0 &&
448
- (/\bChannels\b/i.test(statusStdout) ||
449
- /\bSessions\b/i.test(statusStdout) ||
450
- /\bNext steps:\b/i.test(statusStdout)));
451
- const gatewayStatusProbe = gatewayProbeCommand
452
- ? (0, child_process_1.spawnSync)(gatewayProbeCommand.cmd, gatewayProbeCommand.args, {
453
- encoding: "utf8",
454
- env: process.env,
455
- })
456
- : null;
457
- const gatewayStatusStdout = String(gatewayStatusProbe?.stdout || "");
458
- const gatewayStatusStderr = String(gatewayStatusProbe?.stderr || "");
459
- const gatewayProbeOk = Boolean(gatewayProbeCommand &&
460
- gatewayStatusProbe &&
461
- gatewayStatusProbe.status === 0);
462
- const result = (0, child_process_1.spawnSync)("ps", ["-Ao", "pid=,ppid=,command="], {
463
- encoding: "utf8",
464
- });
465
- const stdout = String(result.stdout || "");
466
- const lines = stdout
467
- .split("\n")
468
- .map((line) => line.trim())
469
- .filter(Boolean);
470
- const processes = lines
471
- .map((line) => {
472
- const match = line.match(/^(\d+)\s+(\d+)\s+(.+)$/);
473
- if (!match)
474
- return null;
475
- const command = match[3] || "";
476
- const lower = command.toLowerCase();
477
- const isOpenClaw = lower.includes(" openclaw ") ||
478
- lower.endsWith(" openclaw") ||
479
- lower.includes("/openclaw ") ||
480
- lower.includes("openclaw.mjs") ||
481
- lower.includes("openclaw gateway") ||
482
- lower.includes("openclaw agent") ||
483
- lower.includes("openclaw message");
484
- if (!isOpenClaw)
485
- return null;
486
- return {
487
- pid: Number(match[1]),
488
- ppid: Number(match[2]),
489
- command,
490
- };
491
- })
492
- .filter((item) => Boolean(item));
493
- const openclawPids = new Set(processes.map((item) => item.pid));
494
- const gatewayProbe = (0, child_process_1.spawnSync)("lsof", ["-nP", "-iTCP", "-sTCP:LISTEN"], {
436
+ const statusLooksConfigured = Boolean(statusCommand ||
437
+ configuredGateway.config_path ||
438
+ detectOpenClawInstallation(workspaceRoot).detected);
439
+ const gatewayProbeCommand = ["lsof", "-nP", `-iTCP:${configuredGateway.gateway_port}`, "-sTCP:LISTEN"];
440
+ const gatewayProbe = (0, child_process_1.spawnSync)(gatewayProbeCommand[0], gatewayProbeCommand.slice(1), {
495
441
  encoding: "utf8",
442
+ timeout: 1200,
496
443
  });
497
- const gatewayLines = String(gatewayProbe.stdout || "")
444
+ const gatewayStatusStdout = String(gatewayProbe.stdout || "");
445
+ const gatewayStatusStderr = String(gatewayProbe.stderr || "");
446
+ const gatewayLines = gatewayStatusStdout
498
447
  .split("\n")
499
448
  .map((line) => line.trim())
500
449
  .filter(Boolean);
@@ -504,15 +453,10 @@ function detectOpenClawRuntime(workspaceRoot) {
504
453
  const parts = line.split(/\s+/);
505
454
  const pid = Number(parts[1] || 0);
506
455
  const command = parts[0] || "";
507
- const lowerCommand = command.toLowerCase();
508
456
  const endpoint = parts[8] || parts[parts.length - 1] || "";
509
457
  const portMatch = endpoint.match(/:(\d+)(?:\s*\(|$)/);
510
458
  if (!pid || !command || !portMatch)
511
459
  return null;
512
- const isOpenClawListener = openclawPids.has(pid) ||
513
- lowerCommand.includes("openclaw");
514
- if (!isOpenClawListener)
515
- return null;
516
460
  const port = Number(portMatch[1]);
517
461
  if (!Number.isFinite(port) || port <= 0)
518
462
  return null;
@@ -524,33 +468,58 @@ function detectOpenClawRuntime(workspaceRoot) {
524
468
  };
525
469
  })
526
470
  .filter((item) => Boolean(item));
471
+ const gatewayProbeOk = gatewayListeners.length > 0;
472
+ let processes = gatewayListeners.map((item) => ({
473
+ pid: item.pid,
474
+ ppid: item.ppid,
475
+ command: item.command,
476
+ }));
477
+ let processResult = null;
478
+ if (!gatewayProbeOk) {
479
+ processResult = (0, child_process_1.spawnSync)("ps", ["-Ao", "pid=,ppid=,command="], {
480
+ encoding: "utf8",
481
+ timeout: 1200,
482
+ });
483
+ const stdout = String(processResult.stdout || "");
484
+ const lines = stdout
485
+ .split("\n")
486
+ .map((line) => line.trim())
487
+ .filter(Boolean);
488
+ processes = lines
489
+ .map((line) => {
490
+ const match = line.match(/^(\d+)\s+(\d+)\s+(.+)$/);
491
+ if (!match)
492
+ return null;
493
+ const command = match[3] || "";
494
+ const lower = command.toLowerCase();
495
+ const isOpenClaw = lower.includes(" openclaw ") ||
496
+ lower.endsWith(" openclaw") ||
497
+ lower.includes("/openclaw ") ||
498
+ lower.includes("openclaw.mjs") ||
499
+ lower.includes("openclaw gateway") ||
500
+ lower.includes("openclaw agent") ||
501
+ lower.includes("openclaw message");
502
+ if (!isOpenClaw)
503
+ return null;
504
+ return {
505
+ pid: Number(match[1]),
506
+ ppid: Number(match[2]),
507
+ command,
508
+ };
509
+ })
510
+ .filter((item) => Boolean(item));
511
+ }
527
512
  const preferredListener = gatewayListeners.find((item) => item.port === configuredGateway.gateway_port) ||
528
513
  gatewayListeners[0] ||
529
514
  null;
530
- const combinedProcesses = new Map();
531
- for (const process of [...processes, ...gatewayListeners]) {
532
- if (!combinedProcesses.has(process.pid)) {
533
- combinedProcesses.set(process.pid, process);
534
- continue;
535
- }
536
- const current = combinedProcesses.get(process.pid);
537
- if (current && current.command.length < process.command.length) {
538
- combinedProcesses.set(process.pid, process);
539
- }
540
- }
541
- const allProcesses = Array.from(combinedProcesses.values());
542
- const gatewayReachable = gatewayListeners.length > 0;
515
+ const allProcesses = processes.slice(0, 10);
516
+ const gatewayReachable = gatewayProbeOk;
543
517
  const detectionNotes = [];
544
- if (statusProbe && statusProbe.status !== 0) {
545
- detectionNotes.push(String(statusStderr || "openclaw status failed").trim());
546
- }
547
- if (gatewayStatusProbe && gatewayStatusProbe.status !== 0) {
518
+ if (gatewayProbe.status !== 0 && gatewayLines.length === 0) {
548
519
  detectionNotes.push(String(gatewayStatusStderr || "openclaw gateway probe failed").trim());
549
520
  }
550
- if (result.status !== 0)
551
- detectionNotes.push(String(result.stderr || "ps failed").trim());
552
- if (gatewayProbe.status !== 0 && gatewayLines.length === 0) {
553
- detectionNotes.push(String(gatewayProbe.stderr || "lsof failed").trim());
521
+ if (processResult && processResult.status !== 0) {
522
+ detectionNotes.push(String(processResult.stderr || "ps failed").trim());
554
523
  }
555
524
  const gatewayPort = preferredListener?.port || configuredGateway.gateway_port;
556
525
  const gatewayUrl = `http://${OPENCLAW_GATEWAY_HOST}:${gatewayPort}/`;
@@ -565,14 +534,13 @@ function detectOpenClawRuntime(workspaceRoot) {
565
534
  status_command: statusCommand ? [statusCommand.cmd, ...statusCommand.args].join(" ") : null,
566
535
  status_ok: statusLooksConfigured,
567
536
  status_summary: statusLooksConfigured
568
- ? statusStdout
569
- .split("\n")
570
- .map((line) => line.trim())
571
- .filter(Boolean)
572
- .slice(0, 6)
573
- .join(" | ")
537
+ ? configuredGateway.config_path
538
+ ? `configured via ${configuredGateway.config_path}`
539
+ : statusCommand
540
+ ? `command available: ${[statusCommand.cmd, ...statusCommand.args].join(" ")}`
541
+ : "OpenClaw environment detected"
574
542
  : null,
575
- gateway_probe_command: gatewayProbeCommand ? [gatewayProbeCommand.cmd, ...gatewayProbeCommand.args].join(" ") : null,
543
+ gateway_probe_command: gatewayProbeCommand.join(" "),
576
544
  gateway_probe_ok: gatewayProbeOk,
577
545
  gateway_probe_summary: gatewayProbeOk
578
546
  ? gatewayStatusStdout
@@ -944,6 +912,9 @@ class LocalNodeService {
944
912
  getOverview() {
945
913
  const discovered = this.search("");
946
914
  const onlineCount = discovered.filter((profile) => profile.online).length;
915
+ const openclawInstallation = detectOpenClawInstallation(this.projectRoot);
916
+ const openclawRuntime = this.getCachedOpenClawRuntime();
917
+ const openclawSkillInstallation = detectOpenClawSkillInstallation();
947
918
  return {
948
919
  app_version: this.appVersion,
949
920
  agent_id: this.identity?.agent_id ?? "",
@@ -959,6 +930,15 @@ class LocalNodeService {
959
930
  init_state: this.initState,
960
931
  presence_ttl_ms: PRESENCE_TTL_MS,
961
932
  onboarding: this.getOnboardingSummary(),
933
+ openclaw: {
934
+ detected: openclawInstallation.detected,
935
+ running: openclawRuntime.running,
936
+ detection_mode: openclawRuntime.detection_mode,
937
+ gateway_url: openclawRuntime.gateway_url,
938
+ gateway_probe_ok: openclawRuntime.gateway_probe_ok,
939
+ status_ok: openclawRuntime.status_ok,
940
+ skill_installed: openclawSkillInstallation.installed,
941
+ },
962
942
  social: {
963
943
  found: this.socialFound,
964
944
  enabled: this.socialConfig.enabled,
@@ -66,12 +66,11 @@ export function createOverviewController({
66
66
  setOverviewMode,
67
67
  setVisibleRemotePublicCount,
68
68
  }) {
69
- const [overviewRes, discoveredRes, peerRes, profileRes, bridgeRes, networkCfgRes, networkStatsRes] = await Promise.allSettled([
69
+ const [overviewRes, discoveredRes, peerRes, profileRes, networkCfgRes, networkStatsRes] = await Promise.allSettled([
70
70
  api("/api/overview"),
71
71
  api("/api/search?q="),
72
72
  api("/api/peers"),
73
73
  api("/api/profile"),
74
- api("/api/openclaw/bridge"),
75
74
  api("/api/network/config"),
76
75
  api("/api/network/stats"),
77
76
  ]);
@@ -82,7 +81,6 @@ export function createOverviewController({
82
81
  const allProfiles = discoveredRes.status === "fulfilled" ? discoveredRes.value.data || [] : [];
83
82
  const peers = peerRes.status === "fulfilled" ? peerRes.value.data || {} : {};
84
83
  const currentProfile = profileRes.status === "fulfilled" ? profileRes.value.data || {} : {};
85
- const bridge = bridgeRes.status === "fulfilled" ? bridgeRes.value.data || {} : {};
86
84
  const networkCfg = networkCfgRes.status === "fulfilled" ? networkCfgRes.value.data || {} : {};
87
85
  const networkStats = networkStatsRes.status === "fulfilled" ? networkStatsRes.value.data || {} : {};
88
86
  const all = Array.isArray(allProfiles) ? allProfiles.slice() : [];
@@ -145,9 +143,10 @@ export function createOverviewController({
145
143
  document.getElementById("pillBroadcast").textContent = pillBroadcastText;
146
144
  document.getElementById("pillBroadcast").className = pillBroadcastClassName;
147
145
 
148
- const openclawRunning = !!bridge.openclaw_runtime?.running;
149
- const openclawDetected = !!bridge.openclaw_installation?.detected || openclawRunning || !!bridge.openclaw_runtime?.gateway_reachable;
150
- const skillInstalled = !!bridge.skill_learning?.installed;
146
+ const openclaw = o.openclaw || {};
147
+ const openclawRunning = !!openclaw.running;
148
+ const openclawDetected = !!openclaw.detected || openclawRunning;
149
+ const skillInstalled = !!openclaw.skill_installed;
151
150
  const globalMode = heroModeText === "global-preview";
152
151
  const lastNetworkError = String(networkDiag.last_error || o.last_broadcast_error || "").trim();
153
152
  const broadcastHealthy = o.broadcast_enabled && !lastNetworkError;
@@ -508,75 +508,19 @@ function resolveOpenClawGatewayProbeCommand(workspaceRoot: string) {
508
508
  function detectOpenClawRuntime(workspaceRoot: string) {
509
509
  const configuredGateway = readOpenClawConfiguredGateway(workspaceRoot);
510
510
  const statusCommand = resolveOpenClawStatusCommand(workspaceRoot);
511
- const gatewayProbeCommand = resolveOpenClawGatewayProbeCommand(workspaceRoot);
512
- const statusProbe = statusCommand
513
- ? spawnSync(statusCommand.cmd, statusCommand.args, {
514
- encoding: "utf8",
515
- env: process.env,
516
- })
517
- : null;
518
- const statusStdout = String(statusProbe?.stdout || "");
519
- const statusStderr = String(statusProbe?.stderr || "");
520
511
  const statusLooksConfigured = Boolean(
521
- statusCommand &&
522
- statusProbe &&
523
- statusProbe.status === 0 &&
524
- (
525
- /\bChannels\b/i.test(statusStdout) ||
526
- /\bSessions\b/i.test(statusStdout) ||
527
- /\bNext steps:\b/i.test(statusStdout)
528
- )
529
- );
530
- const gatewayStatusProbe = gatewayProbeCommand
531
- ? spawnSync(gatewayProbeCommand.cmd, gatewayProbeCommand.args, {
532
- encoding: "utf8",
533
- env: process.env,
534
- })
535
- : null;
536
- const gatewayStatusStdout = String(gatewayStatusProbe?.stdout || "");
537
- const gatewayStatusStderr = String(gatewayStatusProbe?.stderr || "");
538
- const gatewayProbeOk = Boolean(
539
- gatewayProbeCommand &&
540
- gatewayStatusProbe &&
541
- gatewayStatusProbe.status === 0
512
+ statusCommand ||
513
+ configuredGateway.config_path ||
514
+ detectOpenClawInstallation(workspaceRoot).detected
542
515
  );
543
- const result = spawnSync("ps", ["-Ao", "pid=,ppid=,command="], {
544
- encoding: "utf8",
545
- });
546
- const stdout = String(result.stdout || "");
547
- const lines = stdout
548
- .split("\n")
549
- .map((line) => line.trim())
550
- .filter(Boolean);
551
-
552
- const processes = lines
553
- .map((line) => {
554
- const match = line.match(/^(\d+)\s+(\d+)\s+(.+)$/);
555
- if (!match) return null;
556
- const command = match[3] || "";
557
- const lower = command.toLowerCase();
558
- const isOpenClaw =
559
- lower.includes(" openclaw ") ||
560
- lower.endsWith(" openclaw") ||
561
- lower.includes("/openclaw ") ||
562
- lower.includes("openclaw.mjs") ||
563
- lower.includes("openclaw gateway") ||
564
- lower.includes("openclaw agent") ||
565
- lower.includes("openclaw message");
566
- if (!isOpenClaw) return null;
567
- return {
568
- pid: Number(match[1]),
569
- ppid: Number(match[2]),
570
- command,
571
- };
572
- })
573
- .filter((item): item is { pid: number; ppid: number; command: string } => Boolean(item));
574
-
575
- const openclawPids = new Set(processes.map((item) => item.pid));
576
- const gatewayProbe = spawnSync("lsof", ["-nP", "-iTCP", "-sTCP:LISTEN"], {
516
+ const gatewayProbeCommand = ["lsof", "-nP", `-iTCP:${configuredGateway.gateway_port}`, "-sTCP:LISTEN"];
517
+ const gatewayProbe = spawnSync(gatewayProbeCommand[0], gatewayProbeCommand.slice(1), {
577
518
  encoding: "utf8",
519
+ timeout: 1200,
578
520
  });
579
- const gatewayLines = String(gatewayProbe.stdout || "")
521
+ const gatewayStatusStdout = String(gatewayProbe.stdout || "");
522
+ const gatewayStatusStderr = String(gatewayProbe.stderr || "");
523
+ const gatewayLines = gatewayStatusStdout
580
524
  .split("\n")
581
525
  .map((line) => line.trim())
582
526
  .filter(Boolean);
@@ -586,14 +530,9 @@ function detectOpenClawRuntime(workspaceRoot: string) {
586
530
  const parts = line.split(/\s+/);
587
531
  const pid = Number(parts[1] || 0);
588
532
  const command = parts[0] || "";
589
- const lowerCommand = command.toLowerCase();
590
533
  const endpoint = parts[8] || parts[parts.length - 1] || "";
591
534
  const portMatch = endpoint.match(/:(\d+)(?:\s*\(|$)/);
592
535
  if (!pid || !command || !portMatch) return null;
593
- const isOpenClawListener =
594
- openclawPids.has(pid) ||
595
- lowerCommand.includes("openclaw");
596
- if (!isOpenClawListener) return null;
597
536
  const port = Number(portMatch[1]);
598
537
  if (!Number.isFinite(port) || port <= 0) return null;
599
538
  return {
@@ -604,34 +543,59 @@ function detectOpenClawRuntime(workspaceRoot: string) {
604
543
  };
605
544
  })
606
545
  .filter((item): item is { pid: number; ppid: number; port: number; command: string } => Boolean(item));
546
+ const gatewayProbeOk = gatewayListeners.length > 0;
547
+ let processes: Array<{ pid: number; ppid: number; command: string }> = gatewayListeners.map((item) => ({
548
+ pid: item.pid,
549
+ ppid: item.ppid,
550
+ command: item.command,
551
+ }));
552
+ let processResult: ReturnType<typeof spawnSync> | null = null;
553
+ if (!gatewayProbeOk) {
554
+ processResult = spawnSync("ps", ["-Ao", "pid=,ppid=,command="], {
555
+ encoding: "utf8",
556
+ timeout: 1200,
557
+ });
558
+ const stdout = String(processResult.stdout || "");
559
+ const lines = stdout
560
+ .split("\n")
561
+ .map((line) => line.trim())
562
+ .filter(Boolean);
563
+ processes = lines
564
+ .map((line) => {
565
+ const match = line.match(/^(\d+)\s+(\d+)\s+(.+)$/);
566
+ if (!match) return null;
567
+ const command = match[3] || "";
568
+ const lower = command.toLowerCase();
569
+ const isOpenClaw =
570
+ lower.includes(" openclaw ") ||
571
+ lower.endsWith(" openclaw") ||
572
+ lower.includes("/openclaw ") ||
573
+ lower.includes("openclaw.mjs") ||
574
+ lower.includes("openclaw gateway") ||
575
+ lower.includes("openclaw agent") ||
576
+ lower.includes("openclaw message");
577
+ if (!isOpenClaw) return null;
578
+ return {
579
+ pid: Number(match[1]),
580
+ ppid: Number(match[2]),
581
+ command,
582
+ };
583
+ })
584
+ .filter((item): item is { pid: number; ppid: number; command: string } => Boolean(item));
585
+ }
586
+
607
587
  const preferredListener =
608
588
  gatewayListeners.find((item) => item.port === configuredGateway.gateway_port) ||
609
589
  gatewayListeners[0] ||
610
590
  null;
611
-
612
- const combinedProcesses = new Map<number, { pid: number; ppid: number; command: string }>();
613
- for (const process of [...processes, ...gatewayListeners]) {
614
- if (!combinedProcesses.has(process.pid)) {
615
- combinedProcesses.set(process.pid, process);
616
- continue;
617
- }
618
- const current = combinedProcesses.get(process.pid);
619
- if (current && current.command.length < process.command.length) {
620
- combinedProcesses.set(process.pid, process);
621
- }
622
- }
623
- const allProcesses = Array.from(combinedProcesses.values());
624
- const gatewayReachable = gatewayListeners.length > 0;
591
+ const allProcesses = processes.slice(0, 10);
592
+ const gatewayReachable = gatewayProbeOk;
625
593
  const detectionNotes = [];
626
- if (statusProbe && statusProbe.status !== 0) {
627
- detectionNotes.push(String(statusStderr || "openclaw status failed").trim());
628
- }
629
- if (gatewayStatusProbe && gatewayStatusProbe.status !== 0) {
594
+ if (gatewayProbe.status !== 0 && gatewayLines.length === 0) {
630
595
  detectionNotes.push(String(gatewayStatusStderr || "openclaw gateway probe failed").trim());
631
596
  }
632
- if (result.status !== 0) detectionNotes.push(String(result.stderr || "ps failed").trim());
633
- if (gatewayProbe.status !== 0 && gatewayLines.length === 0) {
634
- detectionNotes.push(String(gatewayProbe.stderr || "lsof failed").trim());
597
+ if (processResult && processResult.status !== 0) {
598
+ detectionNotes.push(String(processResult.stderr || "ps failed").trim());
635
599
  }
636
600
  const gatewayPort = preferredListener?.port || configuredGateway.gateway_port;
637
601
  const gatewayUrl = `http://${OPENCLAW_GATEWAY_HOST}:${gatewayPort}/`;
@@ -647,14 +611,13 @@ function detectOpenClawRuntime(workspaceRoot: string) {
647
611
  status_command: statusCommand ? [statusCommand.cmd, ...statusCommand.args].join(" ") : null,
648
612
  status_ok: statusLooksConfigured,
649
613
  status_summary: statusLooksConfigured
650
- ? statusStdout
651
- .split("\n")
652
- .map((line) => line.trim())
653
- .filter(Boolean)
654
- .slice(0, 6)
655
- .join(" | ")
614
+ ? configuredGateway.config_path
615
+ ? `configured via ${configuredGateway.config_path}`
616
+ : statusCommand
617
+ ? `command available: ${[statusCommand.cmd, ...statusCommand.args].join(" ")}`
618
+ : "OpenClaw environment detected"
656
619
  : null,
657
- gateway_probe_command: gatewayProbeCommand ? [gatewayProbeCommand.cmd, ...gatewayProbeCommand.args].join(" ") : null,
620
+ gateway_probe_command: gatewayProbeCommand.join(" "),
658
621
  gateway_probe_ok: gatewayProbeOk,
659
622
  gateway_probe_summary: gatewayProbeOk
660
623
  ? gatewayStatusStdout
@@ -1201,6 +1164,9 @@ export class LocalNodeService {
1201
1164
  getOverview() {
1202
1165
  const discovered = this.search("");
1203
1166
  const onlineCount = discovered.filter((profile) => profile.online).length;
1167
+ const openclawInstallation = detectOpenClawInstallation(this.projectRoot);
1168
+ const openclawRuntime = this.getCachedOpenClawRuntime();
1169
+ const openclawSkillInstallation = detectOpenClawSkillInstallation();
1204
1170
 
1205
1171
  return {
1206
1172
  app_version: this.appVersion,
@@ -1217,6 +1183,15 @@ export class LocalNodeService {
1217
1183
  init_state: this.initState,
1218
1184
  presence_ttl_ms: PRESENCE_TTL_MS,
1219
1185
  onboarding: this.getOnboardingSummary(),
1186
+ openclaw: {
1187
+ detected: openclawInstallation.detected,
1188
+ running: openclawRuntime.running,
1189
+ detection_mode: openclawRuntime.detection_mode,
1190
+ gateway_url: openclawRuntime.gateway_url,
1191
+ gateway_probe_ok: openclawRuntime.gateway_probe_ok,
1192
+ status_ok: openclawRuntime.status_ok,
1193
+ skill_installed: openclawSkillInstallation.installed,
1194
+ },
1220
1195
  social: {
1221
1196
  found: this.socialFound,
1222
1197
  enabled: this.socialConfig.enabled,
@@ -1 +1 @@
1
- 2026.3.20-beta.8
1
+ 2026.3.20-beta.9
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "silicaclaw-broadcast",
3
- "version": "2026.3.20-beta.8",
3
+ "version": "2026.3.20-beta.9",
4
4
  "display_name": "SilicaClaw Broadcast",
5
5
  "description": "Official OpenClaw skill for a bounded local SilicaClaw broadcast workflow: read public broadcasts, publish public broadcasts, and optionally forward owner-relevant summaries through OpenClaw's native channel.",
6
6
  "entrypoints": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@silicaclaw/cli",
3
- "version": "2026.3.20-8",
3
+ "version": "2026.3.20-9",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"