@openscout/scout 0.2.65 → 0.2.68

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.
@@ -56,6 +56,9 @@ function shouldFallbackFromUnixSocket(error) {
56
56
  const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
57
57
  return code === "ENOENT" || code === "ECONNREFUSED" || code === "ENOTSOCK" || code === "EACCES" || code === "FailedToOpenSocket";
58
58
  }
59
+ function errorMessage(error) {
60
+ return error instanceof Error ? error.message : String(error);
61
+ }
59
62
  function requestBrokerOverUnixSocket(socketPath, baseUrl, path, options) {
60
63
  return new Promise((resolve, reject) => {
61
64
  const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
@@ -109,17 +112,36 @@ async function requestBrokerWire(baseUrl, path, options) {
109
112
  const socketPath = options.socketPath?.trim();
110
113
  if (socketPath) {
111
114
  try {
112
- return await requestBrokerOverUnixSocket(socketPath, baseUrl, path, options);
115
+ return {
116
+ response: await requestBrokerOverUnixSocket(socketPath, baseUrl, path, options),
117
+ trace: {
118
+ transport: "unix_socket",
119
+ socketPath
120
+ }
121
+ };
113
122
  } catch (error) {
114
123
  if (!shouldFallbackFromUnixSocket(error)) {
115
124
  throw error;
116
125
  }
126
+ return {
127
+ response: await requestBrokerOverHttp(baseUrl, path, options),
128
+ trace: {
129
+ transport: "http",
130
+ socketPath,
131
+ socketFallbackError: `${socketPath}: ${errorMessage(error)}`
132
+ }
133
+ };
117
134
  }
118
135
  }
119
- return requestBrokerOverHttp(baseUrl, path, options);
136
+ return {
137
+ response: await requestBrokerOverHttp(baseUrl, path, options),
138
+ trace: {
139
+ transport: "http"
140
+ }
141
+ };
120
142
  }
121
- async function requestScoutBrokerJson(baseUrl, path, options = {}) {
122
- const response = await requestBrokerWire(baseUrl, path, options);
143
+ async function requestScoutBrokerJsonWithTrace(baseUrl, path, options = {}) {
144
+ const { response, trace } = await requestBrokerWire(baseUrl, path, options);
123
145
  let parsed;
124
146
  let parsedJson = false;
125
147
  if (response.text.length > 0) {
@@ -132,14 +154,14 @@ async function requestScoutBrokerJson(baseUrl, path, options = {}) {
132
154
  }
133
155
  if (!response.ok) {
134
156
  if (parsedJson && options.acceptErrorJson?.(parsed)) {
135
- return parsed;
157
+ return { value: parsed, trace };
136
158
  }
137
159
  throw new Error(`${path} returned ${response.status}: ${response.text}`);
138
160
  }
139
161
  if (parsedJson) {
140
- return parsed;
162
+ return { value: parsed, trace };
141
163
  }
142
- return;
164
+ return { value: undefined, trace };
143
165
  }
144
166
 
145
167
  // packages/runtime/src/support-paths.ts
@@ -483,11 +505,13 @@ function resolveBrokerServiceConfig() {
483
505
  brokerPort,
484
506
  brokerUrl,
485
507
  brokerSocketPath,
486
- advertiseScope
508
+ advertiseScope,
509
+ coreAgents: readCoreAgentsSync()
487
510
  };
488
511
  }
489
512
  function renderLaunchAgentPlist(config) {
490
513
  const launchPath = resolveLaunchAgentPATH();
514
+ const coreAgentsValue = (config.coreAgents ?? []).join(",");
491
515
  const envEntries = {
492
516
  OPENSCOUT_BROKER_HOST: config.brokerHost,
493
517
  OPENSCOUT_BROKER_PORT: String(config.brokerPort),
@@ -512,6 +536,9 @@ function renderLaunchAgentPlist(config) {
512
536
  "OPENSCOUT_SSE_KEEPALIVE_MS"
513
537
  ])
514
538
  };
539
+ if (coreAgentsValue) {
540
+ envEntries["OPENSCOUT_CORE_AGENTS"] = coreAgentsValue;
541
+ }
515
542
  const envBlock = Object.entries(envEntries).map(([key, value]) => `
516
543
  <key>${xmlEscape(key)}</key>
517
544
  <string>${xmlEscape(value)}</string>`).join("");
@@ -547,6 +574,18 @@ function renderLaunchAgentPlist(config) {
547
574
  </plist>
548
575
  `;
549
576
  }
577
+ function readCoreAgentsSync() {
578
+ try {
579
+ const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
580
+ const raw = readFileSync(settingsPath, "utf8");
581
+ const settings = JSON.parse(raw);
582
+ const raw_agents = settings?.agents?.coreAgents;
583
+ if (Array.isArray(raw_agents)) {
584
+ return raw_agents.filter((v) => typeof v === "string" && v.trim().length > 0);
585
+ }
586
+ } catch {}
587
+ return [];
588
+ }
550
589
  function collectOptionalEnvVars(keys) {
551
590
  const entries = {};
552
591
  for (const key of keys) {
@@ -691,22 +730,37 @@ function inspectLaunchctl(config) {
691
730
  async function fetchHealthSnapshot(config) {
692
731
  const controller = new AbortController;
693
732
  const timeout = setTimeout(() => controller.abort(), 1000);
733
+ const checkedAt = Date.now();
694
734
  try {
695
- const payload = await requestScoutBrokerJson(config.brokerUrl, "/health", {
735
+ const { value: payload, trace } = await requestScoutBrokerJsonWithTrace(config.brokerUrl, "/health", {
696
736
  signal: controller.signal,
697
737
  socketPath: config.brokerSocketPath
698
738
  });
699
739
  return {
700
740
  reachable: true,
701
741
  ok: Boolean(payload.ok),
742
+ checkedAt,
743
+ transport: trace.transport,
744
+ socketPath: trace.socketPath,
745
+ socketFallbackError: trace.socketFallbackError,
702
746
  nodeId: payload.nodeId,
703
747
  meshId: payload.meshId,
704
- counts: payload.counts
748
+ counts: payload.counts ? {
749
+ nodes: payload.counts.nodes ?? 0,
750
+ actors: payload.counts.actors ?? 0,
751
+ agents: payload.counts.agents ?? 0,
752
+ conversations: payload.counts.conversations ?? 0,
753
+ messages: payload.counts.messages ?? 0,
754
+ flights: payload.counts.flights ?? 0,
755
+ collaborationRecords: payload.counts.collaborationRecords ?? 0
756
+ } : undefined
705
757
  };
706
758
  } catch (error) {
707
759
  return {
708
760
  reachable: false,
709
761
  ok: false,
762
+ checkedAt,
763
+ socketPath: config.brokerSocketPath,
710
764
  error: error instanceof Error ? error.message : String(error)
711
765
  };
712
766
  } finally {
@@ -841,8 +895,12 @@ function formatBrokerServiceStatus(status) {
841
895
  `broker socket: ${status.brokerSocketPath}`,
842
896
  `reachable: ${status.reachable ? "yes" : "no"}`,
843
897
  `health: ${status.health.ok ? "ok" : status.health.error ?? "unreachable"}`,
898
+ `health transport: ${status.health.transport ?? "unknown"}`,
844
899
  `logs: ${status.stdoutLogPath}`
845
900
  ];
901
+ if (status.health.socketFallbackError) {
902
+ lines.push(`socket fallback: ${status.health.socketFallbackError}`);
903
+ }
846
904
  if (status.lastLogLine) {
847
905
  lines.push(`last log: ${status.lastLogLine}`);
848
906
  }
@@ -56,6 +56,9 @@ function shouldFallbackFromUnixSocket(error) {
56
56
  const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
57
57
  return code === "ENOENT" || code === "ECONNREFUSED" || code === "ENOTSOCK" || code === "EACCES" || code === "FailedToOpenSocket";
58
58
  }
59
+ function errorMessage(error) {
60
+ return error instanceof Error ? error.message : String(error);
61
+ }
59
62
  function requestBrokerOverUnixSocket(socketPath, baseUrl, path, options) {
60
63
  return new Promise((resolve, reject) => {
61
64
  const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
@@ -109,17 +112,36 @@ async function requestBrokerWire(baseUrl, path, options) {
109
112
  const socketPath = options.socketPath?.trim();
110
113
  if (socketPath) {
111
114
  try {
112
- return await requestBrokerOverUnixSocket(socketPath, baseUrl, path, options);
115
+ return {
116
+ response: await requestBrokerOverUnixSocket(socketPath, baseUrl, path, options),
117
+ trace: {
118
+ transport: "unix_socket",
119
+ socketPath
120
+ }
121
+ };
113
122
  } catch (error) {
114
123
  if (!shouldFallbackFromUnixSocket(error)) {
115
124
  throw error;
116
125
  }
126
+ return {
127
+ response: await requestBrokerOverHttp(baseUrl, path, options),
128
+ trace: {
129
+ transport: "http",
130
+ socketPath,
131
+ socketFallbackError: `${socketPath}: ${errorMessage(error)}`
132
+ }
133
+ };
117
134
  }
118
135
  }
119
- return requestBrokerOverHttp(baseUrl, path, options);
136
+ return {
137
+ response: await requestBrokerOverHttp(baseUrl, path, options),
138
+ trace: {
139
+ transport: "http"
140
+ }
141
+ };
120
142
  }
121
- async function requestScoutBrokerJson(baseUrl, path, options = {}) {
122
- const response = await requestBrokerWire(baseUrl, path, options);
143
+ async function requestScoutBrokerJsonWithTrace(baseUrl, path, options = {}) {
144
+ const { response, trace } = await requestBrokerWire(baseUrl, path, options);
123
145
  let parsed;
124
146
  let parsedJson = false;
125
147
  if (response.text.length > 0) {
@@ -132,14 +154,14 @@ async function requestScoutBrokerJson(baseUrl, path, options = {}) {
132
154
  }
133
155
  if (!response.ok) {
134
156
  if (parsedJson && options.acceptErrorJson?.(parsed)) {
135
- return parsed;
157
+ return { value: parsed, trace };
136
158
  }
137
159
  throw new Error(`${path} returned ${response.status}: ${response.text}`);
138
160
  }
139
161
  if (parsedJson) {
140
- return parsed;
162
+ return { value: parsed, trace };
141
163
  }
142
- return;
164
+ return { value: undefined, trace };
143
165
  }
144
166
 
145
167
  // packages/runtime/src/support-paths.ts
@@ -469,11 +491,13 @@ function resolveBrokerServiceConfig() {
469
491
  brokerPort,
470
492
  brokerUrl,
471
493
  brokerSocketPath,
472
- advertiseScope
494
+ advertiseScope,
495
+ coreAgents: readCoreAgentsSync()
473
496
  };
474
497
  }
475
498
  function renderLaunchAgentPlist(config) {
476
499
  const launchPath = resolveLaunchAgentPATH();
500
+ const coreAgentsValue = (config.coreAgents ?? []).join(",");
477
501
  const envEntries = {
478
502
  OPENSCOUT_BROKER_HOST: config.brokerHost,
479
503
  OPENSCOUT_BROKER_PORT: String(config.brokerPort),
@@ -498,6 +522,9 @@ function renderLaunchAgentPlist(config) {
498
522
  "OPENSCOUT_SSE_KEEPALIVE_MS"
499
523
  ])
500
524
  };
525
+ if (coreAgentsValue) {
526
+ envEntries["OPENSCOUT_CORE_AGENTS"] = coreAgentsValue;
527
+ }
501
528
  const envBlock = Object.entries(envEntries).map(([key, value]) => `
502
529
  <key>${xmlEscape(key)}</key>
503
530
  <string>${xmlEscape(value)}</string>`).join("");
@@ -533,6 +560,18 @@ function renderLaunchAgentPlist(config) {
533
560
  </plist>
534
561
  `;
535
562
  }
563
+ function readCoreAgentsSync() {
564
+ try {
565
+ const settingsPath = resolveOpenScoutSupportPaths().settingsPath;
566
+ const raw = readFileSync(settingsPath, "utf8");
567
+ const settings = JSON.parse(raw);
568
+ const raw_agents = settings?.agents?.coreAgents;
569
+ if (Array.isArray(raw_agents)) {
570
+ return raw_agents.filter((v) => typeof v === "string" && v.trim().length > 0);
571
+ }
572
+ } catch {}
573
+ return [];
574
+ }
536
575
  function collectOptionalEnvVars(keys) {
537
576
  const entries = {};
538
577
  for (const key of keys) {
@@ -677,22 +716,37 @@ function inspectLaunchctl(config) {
677
716
  async function fetchHealthSnapshot(config) {
678
717
  const controller = new AbortController;
679
718
  const timeout = setTimeout(() => controller.abort(), 1000);
719
+ const checkedAt = Date.now();
680
720
  try {
681
- const payload = await requestScoutBrokerJson(config.brokerUrl, "/health", {
721
+ const { value: payload, trace } = await requestScoutBrokerJsonWithTrace(config.brokerUrl, "/health", {
682
722
  signal: controller.signal,
683
723
  socketPath: config.brokerSocketPath
684
724
  });
685
725
  return {
686
726
  reachable: true,
687
727
  ok: Boolean(payload.ok),
728
+ checkedAt,
729
+ transport: trace.transport,
730
+ socketPath: trace.socketPath,
731
+ socketFallbackError: trace.socketFallbackError,
688
732
  nodeId: payload.nodeId,
689
733
  meshId: payload.meshId,
690
- counts: payload.counts
734
+ counts: payload.counts ? {
735
+ nodes: payload.counts.nodes ?? 0,
736
+ actors: payload.counts.actors ?? 0,
737
+ agents: payload.counts.agents ?? 0,
738
+ conversations: payload.counts.conversations ?? 0,
739
+ messages: payload.counts.messages ?? 0,
740
+ flights: payload.counts.flights ?? 0,
741
+ collaborationRecords: payload.counts.collaborationRecords ?? 0
742
+ } : undefined
691
743
  };
692
744
  } catch (error) {
693
745
  return {
694
746
  reachable: false,
695
747
  ok: false,
748
+ checkedAt,
749
+ socketPath: config.brokerSocketPath,
696
750
  error: error instanceof Error ? error.message : String(error)
697
751
  };
698
752
  } finally {
@@ -827,8 +881,12 @@ function formatBrokerServiceStatus(status) {
827
881
  `broker socket: ${status.brokerSocketPath}`,
828
882
  `reachable: ${status.reachable ? "yes" : "no"}`,
829
883
  `health: ${status.health.ok ? "ok" : status.health.error ?? "unreachable"}`,
884
+ `health transport: ${status.health.transport ?? "unknown"}`,
830
885
  `logs: ${status.stdoutLogPath}`
831
886
  ];
887
+ if (status.health.socketFallbackError) {
888
+ lines.push(`socket fallback: ${status.health.socketFallbackError}`);
889
+ }
832
890
  if (status.lastLogLine) {
833
891
  lines.push(`last log: ${status.lastLogLine}`);
834
892
  }