@openscout/scout 0.2.65 → 0.2.69

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.
@@ -63,6 +63,9 @@ function shouldFallbackFromUnixSocket(error) {
63
63
  const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
64
64
  return code === "ENOENT" || code === "ECONNREFUSED" || code === "ENOTSOCK" || code === "EACCES" || code === "FailedToOpenSocket";
65
65
  }
66
+ function errorMessage(error) {
67
+ return error instanceof Error ? error.message : String(error);
68
+ }
66
69
  function requestBrokerOverUnixSocket(socketPath, baseUrl, path, options) {
67
70
  return new Promise((resolve, reject) => {
68
71
  const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
@@ -116,17 +119,36 @@ async function requestBrokerWire(baseUrl, path, options) {
116
119
  const socketPath = options.socketPath?.trim();
117
120
  if (socketPath) {
118
121
  try {
119
- return await requestBrokerOverUnixSocket(socketPath, baseUrl, path, options);
122
+ return {
123
+ response: await requestBrokerOverUnixSocket(socketPath, baseUrl, path, options),
124
+ trace: {
125
+ transport: "unix_socket",
126
+ socketPath
127
+ }
128
+ };
120
129
  } catch (error) {
121
130
  if (!shouldFallbackFromUnixSocket(error)) {
122
131
  throw error;
123
132
  }
133
+ return {
134
+ response: await requestBrokerOverHttp(baseUrl, path, options),
135
+ trace: {
136
+ transport: "http",
137
+ socketPath,
138
+ socketFallbackError: `${socketPath}: ${errorMessage(error)}`
139
+ }
140
+ };
124
141
  }
125
142
  }
126
- return requestBrokerOverHttp(baseUrl, path, options);
143
+ return {
144
+ response: await requestBrokerOverHttp(baseUrl, path, options),
145
+ trace: {
146
+ transport: "http"
147
+ }
148
+ };
127
149
  }
128
- async function requestScoutBrokerJson(baseUrl, path, options = {}) {
129
- const response = await requestBrokerWire(baseUrl, path, options);
150
+ async function requestScoutBrokerJsonWithTrace(baseUrl, path, options = {}) {
151
+ const { response, trace } = await requestBrokerWire(baseUrl, path, options);
130
152
  let parsed;
131
153
  let parsedJson = false;
132
154
  if (response.text.length > 0) {
@@ -139,14 +161,14 @@ async function requestScoutBrokerJson(baseUrl, path, options = {}) {
139
161
  }
140
162
  if (!response.ok) {
141
163
  if (parsedJson && options.acceptErrorJson?.(parsed)) {
142
- return parsed;
164
+ return { value: parsed, trace };
143
165
  }
144
166
  throw new Error(`${path} returned ${response.status}: ${response.text}`);
145
167
  }
146
168
  if (parsedJson) {
147
- return parsed;
169
+ return { value: parsed, trace };
148
170
  }
149
- return;
171
+ return { value: undefined, trace };
150
172
  }
151
173
 
152
174
  // packages/runtime/src/support-paths.ts
@@ -476,11 +498,13 @@ function resolveBrokerServiceConfig() {
476
498
  brokerPort,
477
499
  brokerUrl,
478
500
  brokerSocketPath,
479
- advertiseScope
501
+ advertiseScope,
502
+ coreAgents: readCoreAgentsSync()
480
503
  };
481
504
  }
482
505
  function renderLaunchAgentPlist(config) {
483
506
  const launchPath = resolveLaunchAgentPATH();
507
+ const coreAgentsValue = (config.coreAgents ?? []).join(",");
484
508
  const envEntries = {
485
509
  OPENSCOUT_BROKER_HOST: config.brokerHost,
486
510
  OPENSCOUT_BROKER_PORT: String(config.brokerPort),
@@ -505,6 +529,9 @@ function renderLaunchAgentPlist(config) {
505
529
  "OPENSCOUT_SSE_KEEPALIVE_MS"
506
530
  ])
507
531
  };
532
+ if (coreAgentsValue) {
533
+ envEntries["OPENSCOUT_CORE_AGENTS"] = coreAgentsValue;
534
+ }
508
535
  const envBlock = Object.entries(envEntries).map(([key, value]) => `
509
536
  <key>${xmlEscape(key)}</key>
510
537
  <string>${xmlEscape(value)}</string>`).join("");
@@ -540,6 +567,18 @@ function renderLaunchAgentPlist(config) {
540
567
  </plist>
541
568
  `;
542
569
  }
570
+ function readCoreAgentsSync() {
571
+ try {
572
+ const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
573
+ const raw = readFileSync(settingsPath, "utf8");
574
+ const settings = JSON.parse(raw);
575
+ const raw_agents = settings?.agents?.coreAgents;
576
+ if (Array.isArray(raw_agents)) {
577
+ return raw_agents.filter((v) => typeof v === "string" && v.trim().length > 0);
578
+ }
579
+ } catch {}
580
+ return [];
581
+ }
543
582
  function collectOptionalEnvVars(keys) {
544
583
  const entries = {};
545
584
  for (const key of keys) {
@@ -684,22 +723,48 @@ function inspectLaunchctl(config) {
684
723
  async function fetchHealthSnapshot(config) {
685
724
  const controller = new AbortController;
686
725
  const timeout = setTimeout(() => controller.abort(), 1000);
726
+ const checkedAt = Date.now();
687
727
  try {
688
- const payload = await requestScoutBrokerJson(config.brokerUrl, "/health", {
728
+ const { value: payload, trace } = await requestScoutBrokerJsonWithTrace(config.brokerUrl, "/health", {
689
729
  signal: controller.signal,
690
730
  socketPath: config.brokerSocketPath
691
731
  });
692
732
  return {
693
733
  reachable: true,
694
734
  ok: Boolean(payload.ok),
735
+ checkedAt,
736
+ transport: trace.transport,
737
+ socketPath: trace.socketPath,
738
+ socketFallbackError: trace.socketFallbackError,
695
739
  nodeId: payload.nodeId,
696
740
  meshId: payload.meshId,
697
- counts: payload.counts
741
+ counts: payload.counts ? {
742
+ nodes: payload.counts.nodes ?? 0,
743
+ actors: payload.counts.actors ?? 0,
744
+ agents: payload.counts.agents ?? 0,
745
+ agentRecords: payload.counts.agentRecords,
746
+ rawAgentRecords: payload.counts.rawAgentRecords,
747
+ configuredAgents: payload.counts.configuredAgents,
748
+ scoutManagedAgents: payload.counts.scoutManagedAgents,
749
+ currentAgentRegistrations: payload.counts.currentAgentRegistrations,
750
+ localAgentRegistrations: payload.counts.localAgentRegistrations,
751
+ remoteAgentRegistrations: payload.counts.remoteAgentRegistrations,
752
+ staleAgentRegistrations: payload.counts.staleAgentRegistrations,
753
+ retiredAgentRegistrations: payload.counts.retiredAgentRegistrations,
754
+ oneTimeAgentCards: payload.counts.oneTimeAgentCards,
755
+ persistentAgentCards: payload.counts.persistentAgentCards,
756
+ conversations: payload.counts.conversations ?? 0,
757
+ messages: payload.counts.messages ?? 0,
758
+ flights: payload.counts.flights ?? 0,
759
+ collaborationRecords: payload.counts.collaborationRecords ?? 0
760
+ } : undefined
698
761
  };
699
762
  } catch (error) {
700
763
  return {
701
764
  reachable: false,
702
765
  ok: false,
766
+ checkedAt,
767
+ socketPath: config.brokerSocketPath,
703
768
  error: error instanceof Error ? error.message : String(error)
704
769
  };
705
770
  } finally {
@@ -834,8 +899,12 @@ function formatBrokerServiceStatus(status) {
834
899
  `broker socket: ${status.brokerSocketPath}`,
835
900
  `reachable: ${status.reachable ? "yes" : "no"}`,
836
901
  `health: ${status.health.ok ? "ok" : status.health.error ?? "unreachable"}`,
902
+ `health transport: ${status.health.transport ?? "unknown"}`,
837
903
  `logs: ${status.stdoutLogPath}`
838
904
  ];
905
+ if (status.health.socketFallbackError) {
906
+ lines.push(`socket fallback: ${status.health.socketFallbackError}`);
907
+ }
839
908
  if (status.lastLogLine) {
840
909
  lines.push(`last log: ${status.lastLogLine}`);
841
910
  }
@@ -960,7 +1029,7 @@ function resolveOpenScoutLocalEdgeConfig(input = {}) {
960
1029
  const portalHost = resolveScoutWebNamedHostname(input.portalHost ?? DEFAULT_SCOUT_WEB_PORTAL_HOST);
961
1030
  const nodeHost = resolveScoutWebNamedHostname(input.nodeHost ?? resolveConfiguredScoutWebHostname());
962
1031
  const wildcardHost = `*.${portalHost}`;
963
- const scheme = input.scheme ?? "both";
1032
+ const scheme = input.scheme ?? "http";
964
1033
  const upstream = `127.0.0.1:${input.webPort ?? resolveWebPort()}`;
965
1034
  const brokerUpstream = `127.0.0.1:${input.brokerPort ?? resolveBrokerPort()}`;
966
1035
  return {
@@ -1215,6 +1284,11 @@ var BROKER_HEALTH_TIMEOUT_MS = 30000;
1215
1284
  var BROKER_HEALTH_POLL_MS = 250;
1216
1285
  var MENU_BUNDLE_ID = "com.openscout.menu";
1217
1286
  var MENU_PROCESS_NAME = "OpenScoutMenu";
1287
+ var PROCESS_NAME = "scout-base";
1288
+ var BROKER_LAUNCHER_PROCESS_NAME = "scout-broker-run";
1289
+ var EDGE_PROCESS_NAME = "scout-edge";
1290
+ var MDNS_PROCESS_NAME = "scout-mdns";
1291
+ process.title = PROCESS_NAME;
1218
1292
  var shuttingDown = false;
1219
1293
  var brokerProcess = null;
1220
1294
  var caddyProcess = null;
@@ -1222,6 +1296,7 @@ var mdnsProcesses = [];
1222
1296
  var brokerRestartDelayMs = RESTART_MIN_DELAY_MS;
1223
1297
  var edgeRestartDelayMs = RESTART_MIN_DELAY_MS;
1224
1298
  var supervisedWebPid = null;
1299
+ var supervisorKeepAlive = null;
1225
1300
  var config = resolveBrokerServiceConfig();
1226
1301
  function log(message, details) {
1227
1302
  if (details === undefined) {
@@ -1259,6 +1334,7 @@ function spawnBroker() {
1259
1334
  runtimeEntrypoint(config),
1260
1335
  "broker"
1261
1336
  ], {
1337
+ argv0: BROKER_LAUNCHER_PROCESS_NAME,
1262
1338
  cwd: config.runtimePackageDir,
1263
1339
  env: {
1264
1340
  ...process.env,
@@ -1317,7 +1393,7 @@ function resolveEdgeScheme() {
1317
1393
  if (value === "http" || value === "https" || value === "both") {
1318
1394
  return value;
1319
1395
  }
1320
- return "both";
1396
+ return "http";
1321
1397
  }
1322
1398
  function resolveEdgeConfig() {
1323
1399
  const portalHost = process.env.OPENSCOUT_WEB_PORTAL_HOST?.trim() || DEFAULT_SCOUT_WEB_PORTAL_HOST;
@@ -1349,6 +1425,7 @@ function spawnMdnsProxy(input) {
1349
1425
  "127.0.0.1",
1350
1426
  "path=/"
1351
1427
  ], {
1428
+ argv0: MDNS_PROCESS_NAME,
1352
1429
  stdio: ["ignore", logFile("mdns.stdout.log"), logFile("mdns.stderr.log")]
1353
1430
  });
1354
1431
  }
@@ -1400,6 +1477,7 @@ function startLocalEdge() {
1400
1477
  "--adapter",
1401
1478
  "caddyfile"
1402
1479
  ], {
1480
+ argv0: EDGE_PROCESS_NAME,
1403
1481
  env: process.env,
1404
1482
  stdio: ["ignore", logFile("edge.stdout.log"), logFile("edge.stderr.log")]
1405
1483
  });
@@ -1523,6 +1601,10 @@ async function shutdown(exitCode = 0) {
1523
1601
  return;
1524
1602
  }
1525
1603
  shuttingDown = true;
1604
+ if (supervisorKeepAlive) {
1605
+ clearInterval(supervisorKeepAlive);
1606
+ supervisorKeepAlive = null;
1607
+ }
1526
1608
  stopSupervisedWeb();
1527
1609
  stopMenuBarApp();
1528
1610
  stopEdgeProcesses();
@@ -1535,6 +1617,14 @@ async function shutdown(exitCode = 0) {
1535
1617
  function sleep2(ms) {
1536
1618
  return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
1537
1619
  }
1620
+ function keepSupervisorAlive() {
1621
+ if (supervisorKeepAlive) {
1622
+ return;
1623
+ }
1624
+ supervisorKeepAlive = setInterval(() => {
1625
+ return;
1626
+ }, 60000);
1627
+ }
1538
1628
  for (const signal of ["SIGINT", "SIGTERM"]) {
1539
1629
  process.on(signal, () => {
1540
1630
  shutdown(0).catch((error) => {
@@ -1548,6 +1638,7 @@ log("starting Scout base service", {
1548
1638
  brokerUrl: config.brokerUrl,
1549
1639
  bootout: `launchctl bootout ${config.serviceTarget}`
1550
1640
  });
1641
+ keepSupervisorAlive();
1551
1642
  spawnBroker();
1552
1643
  startLocalEdge();
1553
1644
  startMenuBarApp();