@lifeaitools/clauth 1.30.20 → 1.30.21

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.
@@ -933,7 +933,7 @@ function dashboardHtml(port, whitelist, isStaged = false, initWriteToken = null)
933
933
  .supervisor-name{font-size:.82rem;color:#e2e8f0;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
934
934
  .supervisor-row-actions{display:flex;gap:5px;flex-wrap:wrap;margin-top:7px}
935
935
  .supervisor-log{font-family:'Courier New',monospace;font-size:.7rem;color:#94a3b8;white-space:pre-wrap;word-break:break-word;max-height:280px;overflow:auto}
936
- .supervisor-feedback{margin-top:8px;padding:7px 9px;border-radius:6px;font-family:'Courier New',monospace;font-size:.72rem;color:#86efac;background:rgba(34,197,94,.08);border:1px solid rgba(74,222,128,.22);display:none}
936
+ .supervisor-feedback{margin-top:8px;padding:9px 12px;border-radius:6px;font-family:'Courier New',monospace;font-size:.88rem;font-weight:600;color:#86efac;background:rgba(34,197,94,.12);border:1px solid rgba(74,222,128,.35);border-left:4px solid #4ade80;display:none}
937
937
  .supervisor-feedback.bad{color:#fecaca;background:rgba(248,113,113,.08);border-color:rgba(248,113,113,.25)}
938
938
  </style>
939
939
  </head>
@@ -1187,12 +1187,6 @@ function dashboardHtml(port, whitelist, isStaged = false, initWriteToken = null)
1187
1187
  <div id="supervisor-status" class="supervisor-sub">Loading supervisor state…</div>
1188
1188
  <div id="supervisor-feedback" class="supervisor-feedback" role="status"></div>
1189
1189
  <div class="supervisor-grid" style="margin-top:10px">
1190
- <div class="supervisor-card">
1191
- <h4>Plugins</h4>
1192
- <div class="supervisor-kpi" id="supervisor-plugin-count">—</div>
1193
- <div class="supervisor-meta" id="supervisor-plugin-meta">awaiting data</div>
1194
- <div class="supervisor-list" id="supervisor-plugins" style="margin-top:8px"></div>
1195
- </div>
1196
1190
  <div class="supervisor-card">
1197
1191
  <h4>Surfaces</h4>
1198
1192
  <div class="supervisor-kpi" id="supervisor-surface-count">—</div>
@@ -1515,21 +1509,16 @@ async function loadSupervisorCockpit() {
1515
1509
  const status = document.getElementById("supervisor-status");
1516
1510
  if (status) status.textContent = "Loading supervisor state…";
1517
1511
  try {
1518
- const [health, plugins, surfaces, logs] = await Promise.all([
1512
+ const [health, surfaces, logs] = await Promise.all([
1519
1513
  supervisorJson("/health"),
1520
- supervisorJson("/v1/plugins"),
1521
1514
  supervisorJson("/v1/surfaces"),
1522
1515
  supervisorJson("/v1/logs?limit=40"),
1523
1516
  ]);
1524
- const pluginRows = plugins.plugins || [];
1525
1517
  const surfaceRows = surfaces.surfaces || [];
1526
- document.getElementById("supervisor-plugin-count").textContent = String(pluginRows.length);
1527
1518
  document.getElementById("supervisor-surface-count").textContent = String(surfaceRows.length);
1528
1519
  document.getElementById("supervisor-operation-count").textContent = String((logs.operations || []).length);
1529
- document.getElementById("supervisor-plugin-meta").textContent = "current " + (pluginRows.filter(p => p.state === "current").length) + " · awaiting " + (pluginRows.filter(p => p.state === "awaiting_enable").length);
1530
1520
  document.getElementById("supervisor-surface-meta").textContent = "pm2 home: " + (health.pm2_home || "—");
1531
1521
  document.getElementById("supervisor-log-path").textContent = logs.log_path || "events.jsonl";
1532
- document.getElementById("supervisor-plugins").innerHTML = pluginRows.length ? pluginRows.map(renderSupervisorPlugin).join("") : '<div class="supervisor-sub">No plugins discovered.</div>';
1533
1522
  document.getElementById("supervisor-surfaces").innerHTML = surfaceRows.length ? surfaceRows.map(renderSupervisorSurface).join("") : '<div class="supervisor-sub">No surfaces declared.</div>';
1534
1523
  document.getElementById("supervisor-events").textContent = (logs.events || []).slice(-20).reverse().map(e => {
1535
1524
  const label = e.kind === "operation" ? (e.action + " " + JSON.stringify(e.target || {})) : (e.kind + " " + (e.plugin_id || ""));
@@ -1542,21 +1531,13 @@ async function loadSupervisorCockpit() {
1542
1531
  }
1543
1532
  }
1544
1533
 
1545
- function renderSupervisorPlugin(plugin) {
1546
- const stateKind = plugin.state === "current" ? "ok" : (plugin.state === "manifest_invalid" || plugin.state === "missing" ? "bad" : "warn");
1547
- return '<div class="supervisor-row"><div class="supervisor-row-top"><span class="supervisor-name">' + htmlEscape(plugin.id) + '</span>' + supervisorBadge(plugin.state || "unknown", stateKind) + '</div>' +
1548
- '<div class="supervisor-meta">' + htmlEscape(plugin.publisher || "unknown") + ' · ' + htmlEscape(plugin.version || "—") + ' · ' + htmlEscape(plugin.source || "—") + '</div>' +
1549
- '<div class="supervisor-meta">' + htmlEscape((plugin.manifest_hash || "").slice(0, 12)) + '</div>' +
1550
- '<div class="supervisor-row-actions"><button class="supervisor-action" onclick="runSupervisorPlugin(' + jsArg(plugin.id) + ',' + jsArg(plugin.enabled ? "disable" : "enable") + ')">' + (plugin.enabled ? "Disable" : "Enable") + '</button><button class="supervisor-action" onclick="runSupervisorPlugin(' + jsArg(plugin.id) + ',' + jsArg("test") + ')">Test</button><button class="supervisor-action" onclick="runSupervisorPlugin(' + jsArg(plugin.id) + ',' + jsArg("promote") + ')">Promote</button></div></div>';
1551
- }
1552
-
1553
1534
  function renderSupervisorSurface(surface) {
1554
1535
  const ownerKind = surface.lifecycle_owner === "clauth" ? "ok" : (surface.lifecycle_owner === "plugin" ? "warn" : "");
1555
1536
  const stateKind = surface.state === "current" || surface.status === "healthy" ? "ok" : (surface.state === "unavailable" ? "bad" : "warn");
1556
1537
  return '<div class="supervisor-row"><div class="supervisor-row-top"><span class="supervisor-name">' + htmlEscape(surface.plugin_id + ":" + surface.id) + '</span>' + supervisorBadge(surface.lifecycle_owner || "unknown", ownerKind) + supervisorBadge(surface.state || surface.status || "unknown", stateKind) + '</div>' +
1557
1538
  '<div class="supervisor-meta">' + htmlEscape(surface.destination || "—") + ' · port ' + htmlEscape(surface.port || "—") + '</div>' +
1558
1539
  '<div class="supervisor-meta">' + htmlEscape(surface.health || surface.health_url || "no health") + '</div>' +
1559
- '<div class="supervisor-row-actions">' + ["start","stop","restart","reconcile","test","promote","rollback"].map(a => '<button class="supervisor-action" data-supervisor-action="' + a + '" onclick="runSupervisorSurface(' + jsArg(surface.plugin_id + ":" + surface.id) + ',' + jsArg(a) + ')">' + a + '</button>').join("") + '</div></div>';
1540
+ '<div class="supervisor-row-actions">' + ["start","stop","restart","reconcile","test","promote","rollback"].map(a => '<button class="supervisor-action" data-supervisor-action="' + a + '" onclick="runSupervisorSurface(' + jsArg(surface.plugin_id + ":" + surface.id) + ',' + jsArg(a) + ',this)">' + a + '</button>').join("") + '</div></div>';
1560
1541
  }
1561
1542
 
1562
1543
  async function rescanSupervisorPlugins() {
@@ -1567,21 +1548,23 @@ async function rescanSupervisorPlugins() {
1567
1548
  } catch (err) { supervisorFeedback("Plugin rescan failed: " + (err.message || err), true); }
1568
1549
  }
1569
1550
 
1570
- async function runSupervisorPlugin(id, action) {
1571
- try {
1572
- const receipt = await supervisorJson("/v1/plugins/" + encodeURIComponent(id) + "/" + encodeURIComponent(action), { method: "POST", headers: writeHeaders() });
1573
- supervisorFeedback("Plugin " + action + " receipt " + (receipt.operationId || "recorded") + " · " + ((receipt.resulting_state && receipt.resulting_state.state) || "completed"), false);
1574
- await loadSupervisorCockpit();
1575
- } catch (err) { supervisorFeedback("Plugin " + action + " failed: " + (err.message || err), true); }
1576
- }
1577
-
1578
- async function runSupervisorSurface(id, action) {
1551
+ async function runSupervisorSurface(id, action, btn) {
1552
+ const originalLabel = btn ? btn.textContent : null;
1553
+ if (btn) { btn.disabled = true; btn.textContent = "..."; btn.style.opacity = "0.6"; }
1554
+ supervisorFeedback(action + " " + id + ": sending...", false);
1579
1555
  try {
1580
1556
  const receipt = await supervisorJson("/v1/surfaces/" + encodeURIComponent(id) + "/actions", { method: "POST", headers: writeHeaders({ "Content-Type": "application/json" }), body: JSON.stringify({ action }) });
1581
1557
  const result = receipt.resulting_state || {};
1582
- supervisorFeedback("Surface " + action + " receipt " + (receipt.operationId || "recorded") + " · " + (result.state || "completed"), result.ok === false);
1558
+ const ok = result.ok !== false;
1559
+ if (btn) { btn.textContent = ok ? "done" : "failed"; btn.style.background = ok ? "#14532d" : "#7f1d1d"; }
1560
+ supervisorFeedback(id + " " + action + " " + (ok ? "succeeded" : "failed") + " " + [char]0x2192 + " " + (result.state || result.reason || "completed"), !ok);
1561
+ await new Promise((resolve) => setTimeout(resolve, 700));
1583
1562
  await loadSupervisorCockpit();
1584
- } catch (err) { supervisorFeedback("Surface " + action + " failed: " + (err.message || err), true); }
1563
+ } catch (err) {
1564
+ if (btn) { btn.textContent = "failed"; btn.style.background = "#7f1d1d"; }
1565
+ supervisorFeedback(id + " " + action + " failed: " + (err.message || err), true);
1566
+ if (btn) { setTimeout(() => { btn.disabled = false; btn.textContent = originalLabel; btn.style.opacity = ""; btn.style.background = ""; }, 2500); }
1567
+ }
1585
1568
  }
1586
1569
 
1587
1570
  // ── Unlock ──────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.30.20",
3
+ "version": "1.30.21",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {
Binary file
Binary file
Binary file