@lifeaitools/clauth 0.7.4 → 0.7.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.
@@ -154,6 +154,16 @@ function dashboardHtml(port, whitelist) {
154
154
  .btn-tunnel-stop{background:#1e293b;color:#f87171;border:1px solid #334155;padding:6px 12px;font-size:.8rem;border-radius:6px;cursor:pointer;font-weight:500}
155
155
  .btn-tunnel-stop:hover{background:#2d1f1f;border-color:#f87171}
156
156
  .tunnel-err{font-size:.78rem;color:#f87171;width:100%;margin-top:4px}
157
+ .build-panel{background:#0f1a2d;border:1px solid #1e3a5f;border-radius:8px;padding:1rem 1.25rem;margin-bottom:1.25rem;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
158
+ .build-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
159
+ .build-dot.idle{background:#64748b}
160
+ .build-dot.building{background:#3b82f6;animation:pulse 1s infinite}
161
+ .build-dot.succeeded{background:#22c55e}
162
+ .build-dot.failed{background:#ef4444}
163
+ .build-dot.timeout{background:#f59e0b}
164
+ .build-label{font-size:.85rem;color:#94a3b8;flex:1}
165
+ .build-label strong{color:#e2e8f0}
166
+ .build-meta{font-family:'Courier New',monospace;font-size:.75rem;color:#64748b}
157
167
  .mcp-setup{background:#0f1d2d;border:1px solid #1e3a5f;border-radius:8px;padding:1rem 1.25rem;margin-bottom:1.25rem;display:none}
158
168
  .mcp-setup.open{display:block}
159
169
  .mcp-setup-title{font-size:.85rem;font-weight:600;color:#e2e8f0;margin-bottom:.75rem}
@@ -216,6 +226,15 @@ function dashboardHtml(port, whitelist) {
216
226
  <div>Services: <span id="s-services">${whitelist ? whitelist.join(", ") : "all"}</span></div>
217
227
  <div>Failures: <span id="s-fails">—</span></div>
218
228
  </div>
229
+ <div class="build-panel" id="build-panel">
230
+ <div class="build-dot idle" id="build-dot"></div>
231
+ <div class="build-label" id="build-label">
232
+ <strong>Deploy</strong> — idle
233
+ </div>
234
+ <span id="build-sha" style="font-family:'Courier New',monospace;font-size:.72rem;color:#60a5fa;background:#0a0f1a;border:1px solid #1e3a5f;border-radius:4px;padding:2px 8px;letter-spacing:.3px"></span>
235
+ <div class="build-meta" id="build-meta" style="width:100%;margin-top:4px"></div>
236
+ </div>
237
+
219
238
  <div class="toolbar">
220
239
  <button class="btn-refresh" onclick="loadServices()">↻ Refresh</button>
221
240
  <button class="btn-add" onclick="toggleAddService()">+ Add Service</button>
@@ -413,6 +432,7 @@ function showMain(ping) {
413
432
  ping.failures + "/" + (ping.failures + ping.failures_remaining);
414
433
  }
415
434
  pollTunnel();
435
+ updateBuildStatus();
416
436
  }
417
437
 
418
438
  // ── Unlock ──────────────────────────────────
@@ -1001,6 +1021,42 @@ function copyMcp(elId) {
1001
1021
  }).catch(() => {});
1002
1022
  }
1003
1023
 
1024
+ // ── Build Status ──────────────────────────────────
1025
+ async function updateBuildStatus() {
1026
+ try {
1027
+ const data = await fetch(BASE + "/builds").then(r => r.json());
1028
+ const dot = document.getElementById("build-dot");
1029
+ const label = document.getElementById("build-label");
1030
+ const meta = document.getElementById("build-meta");
1031
+ const sha = document.getElementById("build-sha");
1032
+
1033
+ // Update dot class
1034
+ dot.className = "build-dot " + (data.status || "idle");
1035
+
1036
+ // Update label
1037
+ const statusText = {
1038
+ idle: "idle", building: "building…", succeeded: "deployed", failed: "FAILED", timeout: "timeout"
1039
+ }[data.status] || data.status || "idle";
1040
+ label.innerHTML = "<strong>Deploy</strong> — " + statusText;
1041
+
1042
+ // Update SHA badge
1043
+ sha.textContent = data.commit ? data.commit.slice(0, 7) : "";
1044
+
1045
+ // Update meta
1046
+ const parts = [];
1047
+ if (data.message) parts.push(data.message.slice(0, 60));
1048
+ if (data.finished_at) {
1049
+ const ago = Math.floor((Date.now() - new Date(data.finished_at).getTime()) / 60000);
1050
+ parts.push(ago < 1 ? "just now" : ago < 60 ? ago + "m ago" : Math.floor(ago/60) + "h ago");
1051
+ } else if (data.started_at) {
1052
+ const ago = Math.floor((Date.now() - new Date(data.started_at).getTime()) / 60000);
1053
+ parts.push(ago < 1 ? "just started" : ago + "m");
1054
+ }
1055
+ meta.textContent = parts.join(" · ");
1056
+ } catch {}
1057
+ }
1058
+ setInterval(updateBuildStatus, 10000);
1059
+
1004
1060
  boot();
1005
1061
  </script>
1006
1062
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {