rterm-backend 2.7.4 → 2.7.6
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/bin/gybackend.js +95 -0
- package/package.json +1 -1
package/bin/gybackend.js
CHANGED
|
@@ -382209,6 +382209,87 @@ var EvidenceSealer = class {
|
|
|
382209
382209
|
}
|
|
382210
382210
|
};
|
|
382211
382211
|
|
|
382212
|
+
// ../../packages/backend/src/services/sre/monitorStatusService.ts
|
|
382213
|
+
var MonitorStatusService = class {
|
|
382214
|
+
constructor(monitor, terminalService, now = () => Date.now()) {
|
|
382215
|
+
this.monitor = monitor;
|
|
382216
|
+
this.terminalService = terminalService;
|
|
382217
|
+
this.now = now;
|
|
382218
|
+
}
|
|
382219
|
+
/** Build the full monitor status report. */
|
|
382220
|
+
report() {
|
|
382221
|
+
const publisherWired = this.monitor.publisher !== null;
|
|
382222
|
+
const entries = [];
|
|
382223
|
+
const issues = [];
|
|
382224
|
+
const terminals = this.terminalService.getDisplayTerminals();
|
|
382225
|
+
const now = this.now();
|
|
382226
|
+
for (const terminal of terminals) {
|
|
382227
|
+
const terminalId = terminal.id;
|
|
382228
|
+
const connected = terminal.runtimeState === "ready";
|
|
382229
|
+
const platform2 = terminal.remoteOs ?? terminal.type ?? "unknown";
|
|
382230
|
+
const sessions = this.monitor.sessions;
|
|
382231
|
+
const session = sessions?.get(terminalId);
|
|
382232
|
+
const hasSession = session !== void 0;
|
|
382233
|
+
const inFlight = session?.inFlight === true;
|
|
382234
|
+
const lastCollectAt = session?.lastCollectAt ?? 0;
|
|
382235
|
+
const lastCollectAgoMs = lastCollectAt > 0 ? now - lastCollectAt : -1;
|
|
382236
|
+
let diagnosis = "ok";
|
|
382237
|
+
if (!connected) {
|
|
382238
|
+
diagnosis = "terminal_not_connected";
|
|
382239
|
+
} else if (!hasSession) {
|
|
382240
|
+
diagnosis = "no_monitor_session";
|
|
382241
|
+
} else if (inFlight) {
|
|
382242
|
+
diagnosis = "collection_stuck_in_flight";
|
|
382243
|
+
} else if (lastCollectAt === 0) {
|
|
382244
|
+
diagnosis = "never_collected";
|
|
382245
|
+
} else if (lastCollectAgoMs > 3e4) {
|
|
382246
|
+
diagnosis = `stale_collection (${Math.round(lastCollectAgoMs / 1e3)}s ago)`;
|
|
382247
|
+
}
|
|
382248
|
+
entries.push({
|
|
382249
|
+
terminalId,
|
|
382250
|
+
connected,
|
|
382251
|
+
platform: platform2,
|
|
382252
|
+
hasSession,
|
|
382253
|
+
inFlight,
|
|
382254
|
+
lastCollectAt,
|
|
382255
|
+
lastCollectAgoMs,
|
|
382256
|
+
diagnosis
|
|
382257
|
+
});
|
|
382258
|
+
if (diagnosis !== "ok") {
|
|
382259
|
+
issues.push(`${terminalId}: ${diagnosis}`);
|
|
382260
|
+
}
|
|
382261
|
+
}
|
|
382262
|
+
if (!publisherWired) {
|
|
382263
|
+
issues.unshift("publisher_not_wired \u2014 createObservability may not have been called");
|
|
382264
|
+
}
|
|
382265
|
+
if (entries.length === 0) {
|
|
382266
|
+
issues.push("no_terminals \u2014 no terminals connected");
|
|
382267
|
+
}
|
|
382268
|
+
return {
|
|
382269
|
+
publisherWired,
|
|
382270
|
+
terminalCount: entries.length,
|
|
382271
|
+
entries,
|
|
382272
|
+
issues
|
|
382273
|
+
};
|
|
382274
|
+
}
|
|
382275
|
+
/** Build a compact summary string for the agent. */
|
|
382276
|
+
summary() {
|
|
382277
|
+
const r = this.report();
|
|
382278
|
+
const parts = [];
|
|
382279
|
+
parts.push(`publisher=${r.publisherWired ? "wired" : "NOT WIRED"}`);
|
|
382280
|
+
parts.push(`terminals=${r.terminalCount}`);
|
|
382281
|
+
if (r.issues.length > 0) {
|
|
382282
|
+
parts.push(`issues=${r.issues.length}:`);
|
|
382283
|
+
for (const issue2 of r.issues) {
|
|
382284
|
+
parts.push(` - ${issue2}`);
|
|
382285
|
+
}
|
|
382286
|
+
} else {
|
|
382287
|
+
parts.push("all terminals collecting normally");
|
|
382288
|
+
}
|
|
382289
|
+
return parts.join("\n");
|
|
382290
|
+
}
|
|
382291
|
+
};
|
|
382292
|
+
|
|
382212
382293
|
// ../../packages/backend/src/services/observability.ts
|
|
382213
382294
|
function createObservability(deps) {
|
|
382214
382295
|
const log = deps.onLog ?? (() => {
|
|
@@ -382287,6 +382368,7 @@ function createObservability(deps) {
|
|
|
382287
382368
|
});
|
|
382288
382369
|
const auditLedger = new AuditLedger({});
|
|
382289
382370
|
const evidenceSealer = new EvidenceSealer({});
|
|
382371
|
+
const monitorStatus = new MonitorStatusService(deps.resourceMonitorService, deps.terminalService);
|
|
382290
382372
|
const pluginScanRoot = (process.env.GYBACKEND_DATA_DIR ?? "./.gybackend-data") + "/plugins";
|
|
382291
382373
|
const bundlePluginRoot = new URL("../../plugins/", import.meta.url).pathname;
|
|
382292
382374
|
const scanRoots = [pluginScanRoot, "./plugins"];
|
|
@@ -382296,6 +382378,17 @@ function createObservability(deps) {
|
|
|
382296
382378
|
if (fs22.existsSync(bundlePluginRoot)) scanRoots.push(bundlePluginRoot);
|
|
382297
382379
|
} catch {
|
|
382298
382380
|
}
|
|
382381
|
+
try {
|
|
382382
|
+
const req = createRequire2(import.meta.url);
|
|
382383
|
+
const fs22 = req("node:fs");
|
|
382384
|
+
const path31 = req("node:path");
|
|
382385
|
+
const resourcesPath = process.resourcesPath;
|
|
382386
|
+
if (resourcesPath) {
|
|
382387
|
+
const resourcesPlugins = path31.join(resourcesPath, "plugins");
|
|
382388
|
+
if (fs22.existsSync(resourcesPlugins)) scanRoots.push(resourcesPlugins);
|
|
382389
|
+
}
|
|
382390
|
+
} catch {
|
|
382391
|
+
}
|
|
382299
382392
|
const pluginRegistry = new PluginRegistry({
|
|
382300
382393
|
scanRoots,
|
|
382301
382394
|
createContext: (record2) => PluginRegistry.defaultContext(
|
|
@@ -382348,6 +382441,7 @@ function createObservability(deps) {
|
|
|
382348
382441
|
notify: { slackChannel, teamsChannel, smtpChannel, telegramChannel },
|
|
382349
382442
|
aperf: { service: aperfService, toMetricPoint: aperfSummaryToMetricPoint },
|
|
382350
382443
|
audit: { ledger: auditLedger, sealer: evidenceSealer },
|
|
382444
|
+
monitorStatus,
|
|
382351
382445
|
pluginRegistry
|
|
382352
382446
|
};
|
|
382353
382447
|
}
|
|
@@ -384353,6 +384447,7 @@ async function startGyBackend() {
|
|
|
384353
384447
|
automationManager,
|
|
384354
384448
|
agentRunLedger,
|
|
384355
384449
|
gatewayService,
|
|
384450
|
+
resourceMonitorService,
|
|
384356
384451
|
setMonitorPublisher: (pub) => resourceMonitorService.setPublisher((channel, data) => {
|
|
384357
384452
|
pub(channel, data);
|
|
384358
384453
|
}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rterm-backend",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.6",
|
|
4
4
|
"description": "RTerm headless backend — run RTerm-as-a-service (AI agent, SSH/WinRM/Serial/local terminals, fleet orchestration, advanced automation with event-driven triggers + NATS event mesh, scheduled automation, SRE observability, Netdata integration, AWS APerf performance deep-dive, plugin system) and drive it over a WebSocket JSON-RPC gateway. No desktop UI required.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|