neuralos 3.3.4 → 3.3.5
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.cjs +330 -12
- package/neuralos-3.3.5.tgz +0 -0
- package/package.json +1 -1
- package/neuralos-3.3.4.tgz +0 -0
package/bin/gybackend.cjs
CHANGED
|
@@ -389282,6 +389282,233 @@ var RumLedger = class {
|
|
|
389282
389282
|
init_infraMonitor();
|
|
389283
389283
|
init_etwService();
|
|
389284
389284
|
|
|
389285
|
+
// ../../packages/backend/src/services/dashboard/dashboardPresentation.ts
|
|
389286
|
+
var WORK_LIMIT = 8;
|
|
389287
|
+
var SITUATION_LIMIT = 8;
|
|
389288
|
+
function emptyHint(section, hasRows, message) {
|
|
389289
|
+
if (hasRows) return null;
|
|
389290
|
+
return { section, message };
|
|
389291
|
+
}
|
|
389292
|
+
function dashboardEmptyHints(state) {
|
|
389293
|
+
const hints = [];
|
|
389294
|
+
const push2 = (section, hasRows, message) => {
|
|
389295
|
+
const h = emptyHint(section, hasRows, message);
|
|
389296
|
+
if (h) hints.push(h);
|
|
389297
|
+
};
|
|
389298
|
+
push2(
|
|
389299
|
+
"hosts",
|
|
389300
|
+
(state.hosts?.length ?? 0) > 0,
|
|
389301
|
+
"No hosts reporting yet. Open a terminal so Monitor can collect CPU/mem/disk, or add a watchdog target."
|
|
389302
|
+
);
|
|
389303
|
+
push2(
|
|
389304
|
+
"slos",
|
|
389305
|
+
(state.slos?.length ?? 0) > 0,
|
|
389306
|
+
"No SLOs defined yet. Define an SLO to track error budget and burn rate."
|
|
389307
|
+
);
|
|
389308
|
+
push2(
|
|
389309
|
+
"uptime",
|
|
389310
|
+
(state.uptime?.length ?? 0) > 0,
|
|
389311
|
+
"No watchdog targets yet. Uptime probes appear here once a host is watched."
|
|
389312
|
+
);
|
|
389313
|
+
push2("incidents", (state.incidents?.length ?? 0) > 0, "No open incidents.");
|
|
389314
|
+
push2(
|
|
389315
|
+
"apm",
|
|
389316
|
+
(state.apm?.bottleneckServices?.length ?? 0) > 0 || (state.apm?.slowestTraces?.length ?? 0) > 0,
|
|
389317
|
+
"No APM spans ingested yet. Model calls and OTLP spans appear here when tracing is on."
|
|
389318
|
+
);
|
|
389319
|
+
push2(
|
|
389320
|
+
"dem",
|
|
389321
|
+
(state.dem?.slowestPages?.length ?? 0) > 0,
|
|
389322
|
+
"No RUM sessions yet. Core Web Vitals appear after DEM beacons are ingested."
|
|
389323
|
+
);
|
|
389324
|
+
push2(
|
|
389325
|
+
"clusters",
|
|
389326
|
+
(state.clusters?.length ?? 0) > 0,
|
|
389327
|
+
"No Kubernetes clusters reporting yet. Run collect_infra / kubectl ingest to populate."
|
|
389328
|
+
);
|
|
389329
|
+
push2(
|
|
389330
|
+
"capacity",
|
|
389331
|
+
(state.capacity?.length ?? 0) > 0,
|
|
389332
|
+
"No capacity forecast yet. Disk-days-to-full needs Monitor disk samples."
|
|
389333
|
+
);
|
|
389334
|
+
return hints;
|
|
389335
|
+
}
|
|
389336
|
+
function rankSituation(state, extras = {}) {
|
|
389337
|
+
const items = [];
|
|
389338
|
+
for (const u of state.uptime ?? []) {
|
|
389339
|
+
const name = u.target?.name;
|
|
389340
|
+
if (!name) continue;
|
|
389341
|
+
if (u.state === "down") {
|
|
389342
|
+
items.push({
|
|
389343
|
+
id: `down:${name}`,
|
|
389344
|
+
severity: "critical",
|
|
389345
|
+
kind: "host-down",
|
|
389346
|
+
title: `${name} is down`,
|
|
389347
|
+
detail: u.lastError || `${u.consecutiveFailures ?? 0} consecutive probe failure(s)`,
|
|
389348
|
+
action: { type: "open-host", target: name, label: "Open host" }
|
|
389349
|
+
});
|
|
389350
|
+
} else if (u.state === "degraded") {
|
|
389351
|
+
items.push({
|
|
389352
|
+
id: `deg:${name}`,
|
|
389353
|
+
severity: "warning",
|
|
389354
|
+
kind: "host-degraded",
|
|
389355
|
+
title: `${name} is degraded`,
|
|
389356
|
+
detail: u.lastError || "Watchdog reports degraded",
|
|
389357
|
+
action: { type: "open-host", target: name, label: "Open host" }
|
|
389358
|
+
});
|
|
389359
|
+
}
|
|
389360
|
+
}
|
|
389361
|
+
for (const i of state.incidents ?? []) {
|
|
389362
|
+
const sev = String(i.severity || "sev3");
|
|
389363
|
+
const critical = sev === "sev1" || sev === "sev2";
|
|
389364
|
+
items.push({
|
|
389365
|
+
id: `inc:${i.id || i.title || "unknown"}`,
|
|
389366
|
+
severity: critical ? "critical" : "warning",
|
|
389367
|
+
kind: "incident",
|
|
389368
|
+
title: String(i.title || "Open incident"),
|
|
389369
|
+
detail: `${sev} \xB7 ${(i.affected || []).join(", ") || "no affected hosts"}`,
|
|
389370
|
+
action: { type: "open-chat", label: "Ask agent" }
|
|
389371
|
+
});
|
|
389372
|
+
}
|
|
389373
|
+
for (const s of state.slos ?? []) {
|
|
389374
|
+
if (!s.fastBurning) continue;
|
|
389375
|
+
items.push({
|
|
389376
|
+
id: `slo:${s.sloId}`,
|
|
389377
|
+
severity: "critical",
|
|
389378
|
+
kind: "slo-burn",
|
|
389379
|
+
title: `SLO ${s.sloId} is fast-burning`,
|
|
389380
|
+
detail: `burn ${s.burnRate != null ? s.burnRate.toFixed(2) : "\u2014"}x \xB7 budget ${s.errorBudgetRemaining != null ? Math.round(s.errorBudgetRemaining * 100) : "\u2014"}%`,
|
|
389381
|
+
action: { type: "open-connections", target: "playbooks", label: "Playbooks" }
|
|
389382
|
+
});
|
|
389383
|
+
}
|
|
389384
|
+
for (const c of state.capacity ?? []) {
|
|
389385
|
+
if (c.daysToFull != null && c.daysToFull < 7) {
|
|
389386
|
+
items.push({
|
|
389387
|
+
id: `disk:${c.host}`,
|
|
389388
|
+
severity: c.daysToFull < 2 ? "critical" : "warning",
|
|
389389
|
+
kind: "disk-full",
|
|
389390
|
+
title: `${c.host} disk full in ${c.daysToFull.toFixed(1)}d`,
|
|
389391
|
+
detail: `disk ${c.diskPercent != null ? c.diskPercent.toFixed(1) : "\u2014"}%`,
|
|
389392
|
+
action: { type: "open-host", target: c.host, label: "Open host" }
|
|
389393
|
+
});
|
|
389394
|
+
}
|
|
389395
|
+
}
|
|
389396
|
+
for (const cl of state.clusters ?? []) {
|
|
389397
|
+
const crash = cl.crashLoopPods ?? 0;
|
|
389398
|
+
const notReady = cl.notReadyPods ?? 0;
|
|
389399
|
+
if (crash > 0 || notReady > 0) {
|
|
389400
|
+
items.push({
|
|
389401
|
+
id: `k8s:${cl.context || "cluster"}`,
|
|
389402
|
+
severity: crash > 0 ? "critical" : "warning",
|
|
389403
|
+
kind: "cluster-unhealthy",
|
|
389404
|
+
title: `${cl.context || "cluster"} unhealthy`,
|
|
389405
|
+
detail: `${crash} crashloop \xB7 ${notReady} not ready \xB7 ${cl.totalPods ?? 0} pods`
|
|
389406
|
+
});
|
|
389407
|
+
}
|
|
389408
|
+
}
|
|
389409
|
+
for (const p of extras.playbooks ?? []) {
|
|
389410
|
+
if (p.lastRunOk === false) {
|
|
389411
|
+
items.push({
|
|
389412
|
+
id: `pb:${p.id}`,
|
|
389413
|
+
severity: "warning",
|
|
389414
|
+
kind: "playbook-failed",
|
|
389415
|
+
title: `Playbook "${p.name}" last run failed`,
|
|
389416
|
+
detail: p.lastRunAt ? `last run ${p.lastRunAt}` : "last run failed",
|
|
389417
|
+
action: { type: "open-connections", target: "playbooks", label: "Open playbooks" }
|
|
389418
|
+
});
|
|
389419
|
+
}
|
|
389420
|
+
}
|
|
389421
|
+
for (const r of extras.agentRuns ?? []) {
|
|
389422
|
+
if (r.status === "failed" || r.status === "aborted") {
|
|
389423
|
+
items.push({
|
|
389424
|
+
id: `run:${r.runId}`,
|
|
389425
|
+
severity: r.status === "failed" ? "warning" : "info",
|
|
389426
|
+
kind: "agent-failed",
|
|
389427
|
+
title: `Agent run ${r.status}`,
|
|
389428
|
+
detail: r.error || r.inputPreview || r.sessionId,
|
|
389429
|
+
action: { type: "open-chat", target: r.sessionId, label: "Open chat" }
|
|
389430
|
+
});
|
|
389431
|
+
}
|
|
389432
|
+
}
|
|
389433
|
+
const order = { critical: 0, warning: 1, info: 2 };
|
|
389434
|
+
items.sort((a, b) => order[a.severity] - order[b.severity]);
|
|
389435
|
+
const sliced = items.slice(0, SITUATION_LIMIT);
|
|
389436
|
+
if (sliced.length === 0) {
|
|
389437
|
+
const n2 = state.hosts?.length ?? 0;
|
|
389438
|
+
return [
|
|
389439
|
+
{
|
|
389440
|
+
id: "clear",
|
|
389441
|
+
severity: "info",
|
|
389442
|
+
kind: "all-clear",
|
|
389443
|
+
title: n2 > 0 ? `All clear \xB7 ${n2} host${n2 === 1 ? "" : "s"} reporting` : "All clear \xB7 nothing to act on",
|
|
389444
|
+
detail: "No down hosts, fast-burning SLOs, or failed runs."
|
|
389445
|
+
}
|
|
389446
|
+
];
|
|
389447
|
+
}
|
|
389448
|
+
return sliced;
|
|
389449
|
+
}
|
|
389450
|
+
function collectWork(extras = {}) {
|
|
389451
|
+
const playbooks = (extras.playbooks ?? []).filter((p) => p.lastRunAt).sort((a, b) => String(b.lastRunAt).localeCompare(String(a.lastRunAt))).slice(0, WORK_LIMIT).map((p) => ({
|
|
389452
|
+
id: p.id,
|
|
389453
|
+
kind: "playbook",
|
|
389454
|
+
name: p.name,
|
|
389455
|
+
ok: p.lastRunOk ?? null,
|
|
389456
|
+
at: p.lastRunAt,
|
|
389457
|
+
detail: p.lastRunOk === false ? "failed" : p.lastRunOk === true ? "ok" : "ran",
|
|
389458
|
+
action: { type: "open-connections", target: "playbooks", label: "Open" }
|
|
389459
|
+
}));
|
|
389460
|
+
const triggers = (extras.triggers ?? []).filter((t) => t.lastFiredAt || (t.fireCount ?? 0) > 0).sort((a, b) => (b.lastFiredAt ?? 0) - (a.lastFiredAt ?? 0)).slice(0, WORK_LIMIT).map((t) => ({
|
|
389461
|
+
id: t.id,
|
|
389462
|
+
kind: "trigger",
|
|
389463
|
+
name: t.name,
|
|
389464
|
+
ok: true,
|
|
389465
|
+
at: t.lastFiredAt,
|
|
389466
|
+
detail: `${t.kind || "trigger"} \xB7 fired ${t.fireCount ?? 0}\xD7`,
|
|
389467
|
+
action: { type: "open-connections", target: "triggers", label: "Open" }
|
|
389468
|
+
}));
|
|
389469
|
+
const scheduledTasks = (extras.scheduledTasks ?? []).filter((t) => t.lastRunAt).sort((a, b) => String(b.lastRunAt).localeCompare(String(a.lastRunAt))).slice(0, WORK_LIMIT).map((t) => ({
|
|
389470
|
+
id: t.id,
|
|
389471
|
+
kind: "scheduled-task",
|
|
389472
|
+
name: t.name,
|
|
389473
|
+
ok: t.enabled === false ? null : true,
|
|
389474
|
+
at: t.lastRunAt,
|
|
389475
|
+
detail: t.enabled === false ? "disabled" : "last run",
|
|
389476
|
+
action: { type: "open-connections", target: "scheduledTasks", label: "Open" }
|
|
389477
|
+
}));
|
|
389478
|
+
const agentRuns = (extras.agentRuns ?? []).slice().sort((a, b) => (b.startedAt || 0) - (a.startedAt || 0)).slice(0, WORK_LIMIT).map((r) => ({
|
|
389479
|
+
id: r.runId,
|
|
389480
|
+
kind: "agent-run",
|
|
389481
|
+
name: r.inputPreview?.slice(0, 60) || r.runId,
|
|
389482
|
+
ok: r.status === "completed" ? true : r.status === "failed" || r.status === "aborted" ? false : null,
|
|
389483
|
+
at: r.endedAt || r.startedAt,
|
|
389484
|
+
detail: r.status + (r.error ? ` \xB7 ${r.error}` : ""),
|
|
389485
|
+
action: { type: "open-chat", target: r.sessionId, label: "Open chat" }
|
|
389486
|
+
}));
|
|
389487
|
+
return { playbooks, triggers, scheduledTasks, agentRuns };
|
|
389488
|
+
}
|
|
389489
|
+
function situationHeadline(items) {
|
|
389490
|
+
const crit = items.filter((i) => i.severity === "critical" && i.kind !== "all-clear").length;
|
|
389491
|
+
const warn = items.filter((i) => i.severity === "warning").length;
|
|
389492
|
+
if (items.length === 1 && items[0].kind === "all-clear") return items[0].title;
|
|
389493
|
+
const parts = [];
|
|
389494
|
+
if (crit) parts.push(`${crit} critical`);
|
|
389495
|
+
if (warn) parts.push(`${warn} warning`);
|
|
389496
|
+
const top = items[0];
|
|
389497
|
+
return `${parts.join(" \xB7 ") || "attention"} \xB7 ${top.title}`;
|
|
389498
|
+
}
|
|
389499
|
+
function presentDashboard(state, extras = {}) {
|
|
389500
|
+
const situation = rankSituation(state, extras);
|
|
389501
|
+
return {
|
|
389502
|
+
situation,
|
|
389503
|
+
headline: situationHeadline(situation),
|
|
389504
|
+
work: collectWork(extras),
|
|
389505
|
+
empty: dashboardEmptyHints(state),
|
|
389506
|
+
hostCount: state.hosts?.length ?? 0,
|
|
389507
|
+
downCount: (state.uptime ?? []).filter((u) => u.state === "down").length,
|
|
389508
|
+
degradedCount: (state.uptime ?? []).filter((u) => u.state === "degraded").length
|
|
389509
|
+
};
|
|
389510
|
+
}
|
|
389511
|
+
|
|
389285
389512
|
// ../../packages/backend/src/services/dashboard/dashboardService.ts
|
|
389286
389513
|
var DEFAULT_LIMIT6 = 10;
|
|
389287
389514
|
var DashboardService = class {
|
|
@@ -389317,7 +389544,7 @@ var DashboardService = class {
|
|
|
389317
389544
|
} : { slowestPages: [], poorPages: [] };
|
|
389318
389545
|
const clusters = d.infraMonitor ? d.infraMonitor.clusters_().slice(0, this.limit) : [];
|
|
389319
389546
|
const capacity = d.goldenSignals.capacityForecast();
|
|
389320
|
-
|
|
389547
|
+
const fleet = {
|
|
389321
389548
|
at: this.now(),
|
|
389322
389549
|
hosts,
|
|
389323
389550
|
slos,
|
|
@@ -389328,6 +389555,20 @@ var DashboardService = class {
|
|
|
389328
389555
|
clusters,
|
|
389329
389556
|
capacity
|
|
389330
389557
|
};
|
|
389558
|
+
let extras = {};
|
|
389559
|
+
try {
|
|
389560
|
+
extras = this.deps.getExtras?.() ?? {};
|
|
389561
|
+
} catch {
|
|
389562
|
+
extras = {};
|
|
389563
|
+
}
|
|
389564
|
+
const presented = presentDashboard(fleet, extras);
|
|
389565
|
+
return {
|
|
389566
|
+
...fleet,
|
|
389567
|
+
situation: presented.situation,
|
|
389568
|
+
headline: presented.headline,
|
|
389569
|
+
work: presented.work,
|
|
389570
|
+
empty: presented.empty
|
|
389571
|
+
};
|
|
389331
389572
|
}
|
|
389332
389573
|
/** A compact summary line for the gateway/agent (e.g. "3 hosts, 1 degraded, 2 open incidents, 1 SLO fast-burning"). */
|
|
389333
389574
|
async summary() {
|
|
@@ -394742,7 +394983,40 @@ function createObservability(deps) {
|
|
|
394742
394983
|
incidentLedger,
|
|
394743
394984
|
spanLedger,
|
|
394744
394985
|
rumLedger,
|
|
394745
|
-
infraMonitor
|
|
394986
|
+
infraMonitor,
|
|
394987
|
+
getExtras: () => {
|
|
394988
|
+
const am = deps.automationManager;
|
|
394989
|
+
const playbooks = am.listPlaybooks().map((p) => ({
|
|
394990
|
+
id: p.id,
|
|
394991
|
+
name: p.name,
|
|
394992
|
+
lastRunAt: p.lastRunAt,
|
|
394993
|
+
lastRunOk: p.lastRunOk
|
|
394994
|
+
}));
|
|
394995
|
+
const scheduledTasks = am.listScheduledTasks().map((t) => ({
|
|
394996
|
+
id: t.id,
|
|
394997
|
+
name: t.name,
|
|
394998
|
+
enabled: t.enabled,
|
|
394999
|
+
lastRunAt: t.lastRunAt
|
|
395000
|
+
}));
|
|
395001
|
+
const triggers = am.listTriggers().map((t) => ({
|
|
395002
|
+
id: t.id,
|
|
395003
|
+
name: t.name,
|
|
395004
|
+
enabled: t.enabled,
|
|
395005
|
+
kind: t.kind,
|
|
395006
|
+
lastFiredAt: t.lastFiredAt,
|
|
395007
|
+
fireCount: t.fireCount
|
|
395008
|
+
}));
|
|
395009
|
+
const agentRuns = deps.agentRunLedger.listRuns({ limit: 12 }).map((r) => ({
|
|
395010
|
+
runId: r.runId,
|
|
395011
|
+
sessionId: r.sessionId,
|
|
395012
|
+
status: r.status,
|
|
395013
|
+
error: r.error,
|
|
395014
|
+
startedAt: r.startedAt,
|
|
395015
|
+
endedAt: r.endedAt,
|
|
395016
|
+
inputPreview: r.inputPreview
|
|
395017
|
+
}));
|
|
395018
|
+
return { playbooks, scheduledTasks, triggers, agentRuns };
|
|
395019
|
+
}
|
|
394746
395020
|
});
|
|
394747
395021
|
const anomalyDetector = new AnomalyDetector(metricsLedger);
|
|
394748
395022
|
const earlyWarning = new EarlyWarningService({
|
|
@@ -395411,7 +395685,30 @@ function renderDashboardHtml(state, opts = {}) {
|
|
|
395411
395685
|
<td>${pct(c.diskPercent)}</td>
|
|
395412
395686
|
<td>${c.daysToFull !== void 0 ? num2(c.daysToFull, 1) + " days" : "\u2014"}</td>
|
|
395413
395687
|
</tr>`).join("\n");
|
|
395414
|
-
const
|
|
395688
|
+
const emptyMsg = (sectionId, fallback) => state.empty?.find((e) => e.section === sectionId)?.message ?? fallback;
|
|
395689
|
+
const sitItems = state.situation ?? [];
|
|
395690
|
+
const sitHtml = sitItems.map((s) => {
|
|
395691
|
+
const cls = s.severity === "critical" ? "bad" : s.severity === "warning" ? "warn" : "ok";
|
|
395692
|
+
const act = s.action ? `<button class="act" data-action="${esc2(s.action.type)}" data-target="${esc2(s.action.target ?? "")}">${esc2(s.action.label)}</button>` : "";
|
|
395693
|
+
return `<div class="sit ${cls}"><span class="badge ${cls}">${esc2(s.severity)}</span><div><strong>${esc2(s.title)}</strong><div class="dim">${esc2(s.detail)}</div></div>${act}</div>`;
|
|
395694
|
+
}).join("");
|
|
395695
|
+
const workBlock = (title2, items) => {
|
|
395696
|
+
if (!items.length) return "";
|
|
395697
|
+
const rows = items.map((w) => {
|
|
395698
|
+
const badge = w.ok === false ? "bad" : w.ok === true ? "ok" : "mute";
|
|
395699
|
+
const act = w.action ? `<button class="act" data-action="${esc2(w.action.type)}" data-target="${esc2(w.action.target ?? "")}">${esc2(w.action.label)}</button>` : "";
|
|
395700
|
+
return `<tr><td class="host">${esc2(w.name)}</td><td><span class="badge ${badge}">${esc2(w.detail)}</span></td><td>${act}</td></tr>`;
|
|
395701
|
+
}).join("");
|
|
395702
|
+
return `<h3>${esc2(title2)}</h3><table>${rows}</table>`;
|
|
395703
|
+
};
|
|
395704
|
+
const work = state.work;
|
|
395705
|
+
const workHtml = work ? [
|
|
395706
|
+
workBlock("Playbooks", work.playbooks),
|
|
395707
|
+
workBlock("Triggers", work.triggers),
|
|
395708
|
+
workBlock("Scheduled tasks", work.scheduledTasks),
|
|
395709
|
+
workBlock("Agent runs", work.agentRuns)
|
|
395710
|
+
].join("") : "";
|
|
395711
|
+
const section = (id, label, rows, emptyMsgText) => live ? `<section><h2>${label}</h2><div id="${id}">${rows ? `<table>${rows}</table>` : `<p class="empty">${esc2(emptyMsgText)}</p>`}</div></section>` : rows ? `<section id="${id}"><h2>${label}</h2><table>${rows}</table></section>` : `<section id="${id}"><h2>${label}</h2><p class="empty">${esc2(emptyMsgText)}</p></section>`;
|
|
395415
395712
|
return `<!DOCTYPE html>
|
|
395416
395713
|
<html lang="en">
|
|
395417
395714
|
<head>
|
|
@@ -395451,6 +395748,16 @@ ${refresh > 0 && !live ? `<meta http-equiv="refresh" content="${refresh}">` : ""
|
|
|
395451
395748
|
.row-bad td { background: rgba(255,93,126,0.05); }
|
|
395452
395749
|
.empty { color: var(--muted); font-size: 12px; padding: 8px 0; }
|
|
395453
395750
|
.span2 { grid-column: span 2; }
|
|
395751
|
+
.sit-strip { display: flex; flex-direction: column; gap: 8px; }
|
|
395752
|
+
.sit { display: flex; align-items: flex-start; gap: 10px; padding: 8px 10px; border-radius: 8px; border: 1px solid var(--border); }
|
|
395753
|
+
.sit.bad { border-color: rgba(255,93,126,0.35); background: rgba(255,93,126,0.06); }
|
|
395754
|
+
.sit.warn { border-color: rgba(255,196,77,0.3); background: rgba(255,196,77,0.05); }
|
|
395755
|
+
.sit.ok { border-color: rgba(61,220,151,0.25); }
|
|
395756
|
+
.sit strong { display: block; font-size: 13px; }
|
|
395757
|
+
.act { margin-left: auto; background: transparent; color: var(--accent); border: 1px solid rgba(79,216,232,0.35); border-radius: 6px; padding: 3px 8px; font-size: 11px; cursor: pointer; white-space: nowrap; }
|
|
395758
|
+
.act:hover { background: rgba(79,216,232,0.12); }
|
|
395759
|
+
section h3 { font-size: 11px; color: var(--muted); margin: 10px 0 6px; text-transform: uppercase; letter-spacing: 0.06em; }
|
|
395760
|
+
.filter { margin: 0 0 10px; padding: 6px 10px; width: 100%; max-width: 320px; background: var(--panel2); color: var(--fg); border: 1px solid var(--border); border-radius: 8px; }
|
|
395454
395761
|
footer { color: var(--muted); font-size: 11px; padding: 14px 26px 30px; }
|
|
395455
395762
|
@media (max-width: 900px) { .grid { grid-template-columns: 1fr; } .span2 { grid-column: span 1; } }
|
|
395456
395763
|
</style>
|
|
@@ -395462,25 +395769,36 @@ ${refresh > 0 && !live ? `<meta http-equiv="refresh" content="${refresh}">` : ""
|
|
|
395462
395769
|
<span class="live" id="live-indicator">LIVE \xB7 updated ${esc2(new Date(state.at).toISOString().slice(11, 19))} UTC</span>
|
|
395463
395770
|
</header>
|
|
395464
395771
|
<main>
|
|
395772
|
+
<section class="span2" id="situation-wrap">
|
|
395773
|
+
<h2>Situation</h2>
|
|
395774
|
+
<div class="sub dim" id="headline">${esc2(state.headline || "")}</div>
|
|
395775
|
+
<div class="sit-strip" id="situation">${sitHtml || '<p class="empty">All clear.</p>'}</div>
|
|
395776
|
+
</section>
|
|
395465
395777
|
<div class="grid">
|
|
395466
395778
|
<section class="span2">
|
|
395467
395779
|
<h2>Fleet health</h2>
|
|
395780
|
+
<input class="filter" id="host-filter" type="search" placeholder="Filter hosts\u2026" />
|
|
395468
395781
|
<div id="fleet">
|
|
395469
395782
|
<table>
|
|
395470
395783
|
<tr><th>host</th><th>state</th><th>cpu</th><th>mem</th><th>disk</th><th>cpu trend</th><th>disk full in</th></tr>
|
|
395471
|
-
${hostRows ||
|
|
395784
|
+
${hostRows || `<tr><td class="empty">${esc2(emptyMsg("hosts", "No hosts reporting yet. Open a terminal so Monitor can collect CPU/mem/disk, or add a watchdog target."))}</td></tr>`}
|
|
395472
395785
|
</table>
|
|
395473
395786
|
</div>
|
|
395474
395787
|
</section>
|
|
395475
395788
|
|
|
395476
|
-
|
|
395477
|
-
|
|
395478
|
-
|
|
395479
|
-
|
|
395480
|
-
|
|
395481
|
-
${section("
|
|
395482
|
-
${section("
|
|
395483
|
-
${section("
|
|
395789
|
+
<section class="span2" id="work-wrap">
|
|
395790
|
+
<h2>RTerm work</h2>
|
|
395791
|
+
<div id="work">${workHtml || '<p class="empty">No playbook runs, trigger fires, scheduled tasks, or agent runs yet.</p>'}</div>
|
|
395792
|
+
</section>
|
|
395793
|
+
|
|
395794
|
+
${section("slo", "SLO board", sloRows ? `<tr><th>slo</th><th>sli</th><th>burn rate</th><th>budget</th><th>status</th></tr>${sloRows}` : "", emptyMsg("slos", "No SLOs defined yet. Define an SLO to track error budget and burn rate."))}
|
|
395795
|
+
${section("uptime", "Uptime", upRows ? `<tr><th>host</th><th>state</th><th>failures</th><th>latency</th><th>error</th></tr>${upRows}` : "", emptyMsg("uptime", "No watchdog targets yet. Uptime probes appear here once a host is watched."))}
|
|
395796
|
+
${section("incidents", "Open incidents", incRows ? `<tr><th>incident</th><th>sev</th><th>status</th><th>affected</th><th>rca</th></tr>${incRows}` : "", emptyMsg("incidents", "No open incidents."))}
|
|
395797
|
+
${section("apm-svc", "APM \xB7 bottleneck services", apmSvcRows ? `<tr><th>service</th><th>spans</th><th>errors</th><th>error rate</th><th>p95</th></tr>${apmSvcRows}` : "", emptyMsg("apm", "No APM spans ingested yet. Model calls and OTLP spans appear here when tracing is on."))}
|
|
395798
|
+
${section("apm-trace", "APM \xB7 slowest traces", apmTraceRows ? `<tr><th>trace</th><th>root</th><th>spans</th><th>duration</th><th>status</th></tr>${apmTraceRows}` : "", emptyMsg("apm", "No traces yet."))}
|
|
395799
|
+
${section("dem", "DEM \xB7 slowest pages (Core Web Vitals)", demRows ? `<tr><th>page</th><th>sessions</th><th>p75 lcp</th><th>p75 inp</th><th>error rate</th></tr>${demRows}` : "", emptyMsg("dem", "No RUM sessions yet. Core Web Vitals appear after DEM beacons are ingested."))}
|
|
395800
|
+
${section("clusters", "Kubernetes / cloud clusters", clusterRows ? `<tr><th>context</th><th>pods</th><th>not ready</th><th>crashloop</th><th>restarts</th><th>nodes</th></tr>${clusterRows}` : "", emptyMsg("clusters", "No Kubernetes clusters reporting yet. Run collect_infra / kubectl ingest to populate."))}
|
|
395801
|
+
${section("capacity", "Capacity forecast", capRows ? `<tr><th>host</th><th>disk</th><th>full in</th></tr>${capRows}` : "", emptyMsg("capacity", "No capacity forecast yet. Disk-days-to-full needs Monitor disk samples."))}
|
|
395484
395802
|
</div>
|
|
395485
395803
|
</main>
|
|
395486
395804
|
<footer>
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neuralos",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.5",
|
|
4
4
|
"description": "AI-native terminal & agentic-AI operations platform for Forward Deployed Engineers & SREs: AIOps closed-loop remediation, AI SRE, self-healing infrastructure, runbook automation, ChatOps; executes over SSH/WinRM/serial under policy with tamper-evident audit.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"forward-deployed-engineer",
|
package/neuralos-3.3.4.tgz
DELETED
|
Binary file
|