@enigmax/dashboard 0.1.100 → 0.1.101
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/assets/index.html +94 -6
- package/package.json +1 -1
package/assets/index.html
CHANGED
|
@@ -720,6 +720,10 @@
|
|
|
720
720
|
.modal-ok.danger { background: var(--accent2); border-color: var(--accent2); color: #2a0f08; }
|
|
721
721
|
.modal-ok:disabled { opacity: .45; cursor: not-allowed; }
|
|
722
722
|
.modal-err { color: var(--bad); font-size: 12px; margin-top: 8px; }
|
|
723
|
+
/* The default value printed beside a setting hint: quiet, so it reads as an annotation
|
|
724
|
+
rather than a second label competing with the name. */
|
|
725
|
+
.set-def{opacity:.72;font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
726
|
+
.set-ctl .gate-reset{flex:none}
|
|
723
727
|
</style>
|
|
724
728
|
</head>
|
|
725
729
|
<body>
|
|
@@ -1118,7 +1122,7 @@
|
|
|
1118
1122
|
<div class="set-grid">
|
|
1119
1123
|
<div class="set-row">
|
|
1120
1124
|
<div class="set-meta"><div class="set-name">Agent</div><div class="set-hint" id="gateAgentHint">which coding agent the pipeline drives</div></div>
|
|
1121
|
-
<div class="set-ctl"><select id="gateAgent" class="linput"><option value="auto">auto</option><option value="claude">claude</option><option value="codex">codex</option><option value="opencode">opencode</option><option value="rovodev">rovodev</option><option value="pi">pi</option></select></div>
|
|
1125
|
+
<div class="set-ctl ladd" style="align-items:center"><select id="gateAgent" class="linput"><option value="auto">auto</option><option value="claude">claude</option><option value="codex">codex</option><option value="opencode">opencode</option><option value="rovodev">rovodev</option><option value="pi">pi</option></select></div>
|
|
1122
1126
|
</div>
|
|
1123
1127
|
<div class="set-row" id="gateModelRow">
|
|
1124
1128
|
<div class="set-meta"><div class="set-name">Model</div><div class="set-hint" id="gateModelHint">the model every step runs on; a smaller one cuts run time and tokens</div></div>
|
|
@@ -1130,11 +1134,11 @@
|
|
|
1130
1134
|
</div>
|
|
1131
1135
|
<div class="set-row">
|
|
1132
1136
|
<div class="set-meta"><div class="set-name">Log level</div><div class="set-hint">daemon output verbosity</div></div>
|
|
1133
|
-
<div class="set-ctl"><select id="gateLogLevel" class="linput"><option value="debug">debug</option><option value="info">info</option><option value="warn">warn</option><option value="error">error</option></select></div>
|
|
1137
|
+
<div class="set-ctl ladd" style="align-items:center"><select id="gateLogLevel" class="linput"><option value="debug">debug</option><option value="info">info</option><option value="warn">warn</option><option value="error">error</option></select></div>
|
|
1134
1138
|
</div>
|
|
1135
1139
|
<div class="set-row">
|
|
1136
1140
|
<div class="set-meta"><div class="set-name">Read intent from transcripts</div><div class="set-hint">feeds what you were trying to do to every step; off makes the agents work from the diff alone</div></div>
|
|
1137
|
-
<div class="set-ctl"><button id="gateIntent" type="button" class="toggle" data-kind="bool" role="switch" aria-checked="false" aria-label="Read intent from transcripts"></button></div>
|
|
1141
|
+
<div class="set-ctl ladd" style="align-items:center"><button id="gateIntent" type="button" class="toggle" data-kind="bool" role="switch" aria-checked="false" aria-label="Read intent from transcripts"></button></div>
|
|
1138
1142
|
</div>
|
|
1139
1143
|
</div>
|
|
1140
1144
|
<div class="set-cat-h" style="margin-top:18px">Auto-fix attempts</div>
|
|
@@ -4467,6 +4471,57 @@ export {
|
|
|
4467
4471
|
btn.dataset.on = on ? "1" : "0";
|
|
4468
4472
|
btn.setAttribute("aria-checked", on ? "true" : "false");
|
|
4469
4473
|
}
|
|
4474
|
+
// Defaults for every gate setting, straight from the gate's own config loader (the
|
|
4475
|
+
// server resolves an empty config rather than keeping a second copy of the numbers).
|
|
4476
|
+
// They drive the "default N" hint and the per-row reset below.
|
|
4477
|
+
let gateDefaults = null;
|
|
4478
|
+
// A per-setting reset. These values are mostly small integers that get nudged once and
|
|
4479
|
+
// then forgotten, and nothing on screen said what they started as - so the default is
|
|
4480
|
+
// printed in the hint AND made one click away. Icon-only with a name, per the icon
|
|
4481
|
+
// action rules; the title carries the value so a disabled reset still answers "what
|
|
4482
|
+
// was it?" without the user opening the YAML.
|
|
4483
|
+
function resetBtn(key, def, label) {
|
|
4484
|
+
if (def === null || def === undefined) return "";
|
|
4485
|
+
return '<button type="button" class="iconbtn gate-reset" data-gate-reset="' + esc(key) + '" data-gate-def="' + esc(String(def)) + '" data-gate-label="' + esc(label) + '"'
|
|
4486
|
+
+ ' title="Reset to the default (' + esc(String(def)) + ')" aria-label="Reset ' + esc(label) + ' to the default (' + esc(String(def)) + ')">'
|
|
4487
|
+
+ '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 2v6h6"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L3 8"/></svg></button>';
|
|
4488
|
+
}
|
|
4489
|
+
/** Put (or refresh) a reset button in the cell of a control rendered by the static markup. */
|
|
4490
|
+
function mountGateReset(key, label, def) {
|
|
4491
|
+
const el = gateCtlFor(key);
|
|
4492
|
+
if (!el || def === null || def === undefined || def === "") return;
|
|
4493
|
+
const cell = el.parentElement;
|
|
4494
|
+
if (!cell) return;
|
|
4495
|
+
const old = cell.querySelector("[data-gate-reset]");
|
|
4496
|
+
if (old) old.remove();
|
|
4497
|
+
cell.insertAdjacentHTML("beforeend", resetBtn(key, def, label));
|
|
4498
|
+
}
|
|
4499
|
+
/** The control a reset key writes, so the button can compare against what is on screen. */
|
|
4500
|
+
function gateCtlFor(key) {
|
|
4501
|
+
if (key.indexOf("auto_fix.") === 0) return document.querySelector('[data-gate-af="' + key.slice("auto_fix.".length) + '"]');
|
|
4502
|
+
if (key === "agent") return $("gateAgent");
|
|
4503
|
+
if (key === "log_level") return $("gateLogLevel");
|
|
4504
|
+
if (key === "ci_timeout") return $("gateCiTimeout");
|
|
4505
|
+
if (key === "intent.enabled") return $("gateIntent");
|
|
4506
|
+
return null;
|
|
4507
|
+
}
|
|
4508
|
+
/** Current value of a reset-able control, as the string its default is compared against. */
|
|
4509
|
+
function gateCtlValue(key, el) {
|
|
4510
|
+
if (!el) return null;
|
|
4511
|
+
if (key === "intent.enabled") return el.dataset.on === "1" ? "true" : "false";
|
|
4512
|
+
return String(el.value).trim();
|
|
4513
|
+
}
|
|
4514
|
+
// Nothing to reset is not the same as nothing to say: the button stays visible and
|
|
4515
|
+
// disabled (never hidden), because its title is where the default value is written.
|
|
4516
|
+
function syncGateResets() {
|
|
4517
|
+
for (const b of document.querySelectorAll("[data-gate-reset]")) {
|
|
4518
|
+
const key = b.dataset.gateReset;
|
|
4519
|
+
const cur = gateCtlValue(key, gateCtlFor(key));
|
|
4520
|
+
const isDefault = cur !== null && cur === b.dataset.gateDef;
|
|
4521
|
+
b.disabled = isDefault || !gateWritable;
|
|
4522
|
+
b.title = isDefault ? "Already the default (" + b.dataset.gateDef + ")" : "Reset to the default (" + b.dataset.gateDef + ")";
|
|
4523
|
+
}
|
|
4524
|
+
}
|
|
4470
4525
|
const GATE_AUTOFIX = [
|
|
4471
4526
|
["rebase", "conflicts and stale-base failures"],
|
|
4472
4527
|
["review", "0 by default: review findings are yours to approve"],
|
|
@@ -4556,12 +4611,26 @@ export {
|
|
|
4556
4611
|
$("gateLogLevel").value = s.logLevel;
|
|
4557
4612
|
syncDD($("gateLogLevel"));
|
|
4558
4613
|
gateBool($("gateIntent"), s.intentEnabled);
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4614
|
+
gateDefaults = s.defaults || null;
|
|
4615
|
+
$("gateAutoFix").innerHTML = GATE_AUTOFIX.map(([step, hint]) => {
|
|
4616
|
+
const def = gateDefaults && gateDefaults.autoFix ? Number(gateDefaults.autoFix[step] || 0) : null;
|
|
4617
|
+
return '<div class="set-row"><div class="set-meta"><div class="set-name">' + esc(step) + '</div><div class="set-hint">' + esc(hint)
|
|
4618
|
+
+ (def === null ? "" : ' <span class="set-def">default ' + def + "</span>") + "</div></div>"
|
|
4619
|
+
+ '<div class="set-ctl ladd" style="align-items:center"><input type="number" min="0" max="20" step="1" inputmode="numeric" class="linput" style="flex:none;width:80px" data-gate-af="' + esc(step) + '" value="' + Number(s.autoFix[step] || 0) + '">'
|
|
4620
|
+
+ resetBtn("auto_fix." + step, def, "the " + step + " limit") + "</div></div>";
|
|
4621
|
+
}).join("");
|
|
4622
|
+
// The fixed rows get their reset mounted here rather than in the static markup,
|
|
4623
|
+
// because only the payload knows what each default actually is.
|
|
4624
|
+
if (gateDefaults) {
|
|
4625
|
+
mountGateReset("agent", "the agent", gateDefaults.agent);
|
|
4626
|
+
mountGateReset("log_level", "the log level", gateDefaults.logLevel);
|
|
4627
|
+
mountGateReset("ci_timeout", "the CI timeout", gateDefaults.ciTimeout);
|
|
4628
|
+
mountGateReset("intent.enabled", "intent extraction", String(gateDefaults.intentEnabled));
|
|
4629
|
+
}
|
|
4562
4630
|
const ctls = panel.querySelectorAll("input, select, button");
|
|
4563
4631
|
for (const c of ctls) c.disabled = !gateWritable;
|
|
4564
4632
|
syncGateModelSave(); // after the sweep, which would otherwise re-enable a clean Save
|
|
4633
|
+
syncGateResets(); // likewise: the sweep would re-enable a reset with nothing to reset
|
|
4565
4634
|
}
|
|
4566
4635
|
// `live` marks a poll refresh: it repaints the run strip and the two switches, and leaves
|
|
4567
4636
|
// every editor alone so a poll can never overwrite what is being typed.
|
|
@@ -4719,6 +4788,25 @@ export {
|
|
|
4719
4788
|
const step = e.target.dataset && e.target.dataset.gateAf;
|
|
4720
4789
|
if (step) saveGateSetting("auto_fix." + step, Number(e.target.value), "the " + step + " limit");
|
|
4721
4790
|
});
|
|
4791
|
+
// Live feedback while typing: the reset greys out the moment the value is back to the
|
|
4792
|
+
// default, so the row answers "am I still overriding this?" without a save.
|
|
4793
|
+
$("gateAutoFix").addEventListener("input", syncGateResets);
|
|
4794
|
+
$("gateCiTimeout").addEventListener("input", syncGateResets);
|
|
4795
|
+
// One delegated handler for every reset in the panel. The write goes through the same
|
|
4796
|
+
// saveGateSetting as the control itself, so it reloads the gate afterwards - which is
|
|
4797
|
+
// what reconciles the optimistic paint and rolls it back if the save did not land.
|
|
4798
|
+
$("gateSetPanel").addEventListener("click", (e) => {
|
|
4799
|
+
const b = e.target.closest && e.target.closest("[data-gate-reset]");
|
|
4800
|
+
if (!b || b.disabled) return;
|
|
4801
|
+
const key = b.dataset.gateReset, def = b.dataset.gateDef, el = gateCtlFor(key);
|
|
4802
|
+
if (el) {
|
|
4803
|
+
if (key === "intent.enabled") gateBool(el, def === "true");
|
|
4804
|
+
else { el.value = def; if (el.tagName === "SELECT") syncDD(el); }
|
|
4805
|
+
syncGateResets();
|
|
4806
|
+
}
|
|
4807
|
+
const value = key.indexOf("auto_fix.") === 0 ? Number(def) : (key === "intent.enabled" ? def === "true" : def);
|
|
4808
|
+
saveGateSetting(key, value, b.dataset.gateLabel);
|
|
4809
|
+
});
|
|
4722
4810
|
|
|
4723
4811
|
// --- section rail (a full-screen drawer below 900px) ---
|
|
4724
4812
|
const sidebarEl = $("sidebar"), navScrimEl = $("navScrim"), navOpenBtn = $("navOpen");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enigmax/dashboard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.101",
|
|
4
4
|
"description": "Local browser dashboard UI for enigma: the static page and chart assets enigma serves on its loopback dashboard (savings, real tool usage, in-browser settings). Installed on demand by enigma-cli; not a runtime dependency.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|