@botcord/daemon 0.2.60 → 0.2.62

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.
@@ -346,6 +346,7 @@ export function mergeOpenclawGateways(
346
346
 
347
347
  function discoverFromConfigDir(root: string): DiscoveredOpenclawGateway[] {
348
348
  const dir = expandHome(root);
349
+ const rootIsQclaw = path.basename(dir) === ".qclaw";
349
350
  let names: string[];
350
351
  try {
351
352
  names = readdirSync(dir);
@@ -362,8 +363,9 @@ function discoverFromConfigDir(root: string): DiscoveredOpenclawGateway[] {
362
363
  const raw = readFileSync(file, "utf8");
363
364
  const parsed = name.endsWith(".json") ? parseJsonConfig(raw) : parseTomlConfig(raw);
364
365
  if (!parsed?.url) continue;
366
+ const namePrefix = rootIsQclaw || name.toLowerCase() === "qclaw.json" ? "qclaw" : "openclaw";
365
367
  const item: DiscoveredOpenclawGateway = {
366
- name: nameFromUrl(parsed.url),
368
+ name: nameFromUrl(parsed.url, namePrefix),
367
369
  url: parsed.url,
368
370
  source: "config-file",
369
371
  };
@@ -487,25 +489,34 @@ function dedupeDiscovered(items: DiscoveredOpenclawGateway[]): DiscoveredOpencla
487
489
  for (const item of items) {
488
490
  const key = normalizeUrlKey(item.url);
489
491
  const prev = byUrl.get(key);
490
- if (!prev || priority[item.source] > priority[prev.source] || hasMoreAuth(item, prev)) {
492
+ if (
493
+ !prev ||
494
+ priority[item.source] > priority[prev.source] ||
495
+ hasMoreAuth(item, prev) ||
496
+ prefersQclawName(item, prev)
497
+ ) {
491
498
  byUrl.set(key, item);
492
499
  }
493
500
  }
494
501
  return [...byUrl.values()];
495
502
  }
496
503
 
504
+ function prefersQclawName(a: DiscoveredOpenclawGateway, b: DiscoveredOpenclawGateway): boolean {
505
+ return a.name.startsWith("qclaw-") && !b.name.startsWith("qclaw-");
506
+ }
507
+
497
508
  function hasMoreAuth(a: DiscoveredOpenclawGateway, b: DiscoveredOpenclawGateway): boolean {
498
509
  const score = (x: DiscoveredOpenclawGateway): number => (x.token ? 2 : x.tokenFile ? 1 : 0);
499
510
  return score(a) > score(b);
500
511
  }
501
512
 
502
- function nameFromUrl(raw: string): string {
513
+ function nameFromUrl(raw: string, prefix = "openclaw"): string {
503
514
  try {
504
515
  const u = new URL(raw);
505
516
  const base = `${u.hostname}-${u.port || (u.protocol === "wss:" ? "443" : "80")}`;
506
- return `openclaw-${base.replace(/[^A-Za-z0-9_-]+/g, "-")}`;
517
+ return `${prefix}-${base.replace(/[^A-Za-z0-9_-]+/g, "-")}`;
507
518
  } catch {
508
- return "openclaw-local";
519
+ return `${prefix}-local`;
509
520
  }
510
521
  }
511
522
 
package/src/provision.ts CHANGED
@@ -48,6 +48,11 @@ import {
48
48
  buildManagedRoutes,
49
49
  prepareGatewayProfile,
50
50
  } from "./daemon-config-map.js";
51
+ import {
52
+ discoverLocalOpenclawGateways,
53
+ mergeOpenclawGateways,
54
+ openclawDiscoveryConfigEnabled,
55
+ } from "./openclaw-discovery.js";
51
56
  import {
52
57
  agentHomeDir,
53
58
  agentStateDir,
@@ -324,9 +329,10 @@ export function createProvisioner(opts: ProvisionerOptions): (
324
329
  case CONTROL_FRAME_TYPES.LIST_RUNTIMES: {
325
330
  // Async path so the openclaw-acp endpoints get probed inline; gateway
326
331
  // / WS errors are swallowed inside `collectRuntimeSnapshotAsync`.
327
- let cfgForProbe: { openclawGateways?: any[] } | undefined;
332
+ let cfgForProbe: DaemonConfig | undefined;
328
333
  try {
329
334
  cfgForProbe = loadConfig();
335
+ cfgForProbe = await refreshDiscoveredOpenclawGateways(cfgForProbe);
330
336
  } catch {
331
337
  cfgForProbe = undefined;
332
338
  }
@@ -428,6 +434,31 @@ export function createProvisioner(opts: ProvisionerOptions): (
428
434
  };
429
435
  }
430
436
 
437
+ async function refreshDiscoveredOpenclawGateways(cfg: DaemonConfig): Promise<DaemonConfig> {
438
+ if (!openclawDiscoveryConfigEnabled(cfg)) return cfg;
439
+ try {
440
+ const found = await discoverLocalOpenclawGateways({
441
+ searchPaths: cfg.openclawDiscovery?.searchPaths,
442
+ defaultPorts: cfg.openclawDiscovery?.defaultPorts,
443
+ timeoutMs: 500,
444
+ });
445
+ const merged = mergeOpenclawGateways(cfg, found);
446
+ if (!merged.changed) return cfg;
447
+ saveConfig(merged.cfg);
448
+ daemonLog.info("openclaw discovery: gateways merged", {
449
+ source: "list_runtimes",
450
+ added: merged.added.map((g) => ({ name: g.name, url: g.url })),
451
+ });
452
+ return merged.cfg;
453
+ } catch (err) {
454
+ daemonLog.warn("openclaw discovery failed; continuing", {
455
+ source: "list_runtimes",
456
+ error: err instanceof Error ? err.message : String(err),
457
+ });
458
+ return cfg;
459
+ }
460
+ }
461
+
431
462
  interface WakeAgentParams {
432
463
  agent_id?: string;
433
464
  agentId?: string;