File AI-detected Varaverk defects as deduped reports, surfaced on the AI tab and counted in the coffee report
This commit is contained in:
@@ -187,6 +187,18 @@ if (is_dir('/var/log/varaverk')) {
|
||||
.vv-ai-tok-foot { margin-top:9px; padding-top:7px; border-top:1px solid #1a1a1a; font-size:10px;
|
||||
color:#4a4a4a; display:flex; gap:14px; flex-wrap:wrap; }
|
||||
|
||||
/* ── Assistant-filed bug reports ─────────────────────────────────────────── */
|
||||
.vv-ai-bug { border-left:2px solid #5a3a2a; background:#140f0c; border-radius:0 3px 3px 0;
|
||||
padding:8px 10px; margin-bottom:8px; }
|
||||
.vv-ai-bug-h { display:flex; align-items:center; gap:9px; margin-bottom:4px; }
|
||||
.vv-ai-bug-c { font-family:monospace; font-size:11px; color:#c8a87a; }
|
||||
.vv-ai-bug-m { font-size:10px; color:#4a4a4a; font-family:monospace; margin-left:auto; }
|
||||
.vv-ai-bug-s { font-size:12px; color:#b8b8b8; line-height:1.5; margin-bottom:5px; }
|
||||
.vv-ai-bug-e { margin:0; padding:6px 8px; background:#0b0b0b; border:1px solid #1e1e1e;
|
||||
border-radius:3px; font-size:10px; line-height:1.5; color:#8a8a8a;
|
||||
white-space:pre-wrap; overflow-x:auto; max-height:110px; overflow-y:auto; }
|
||||
.vv-ai-bug-q { font-size:10px; color:#4a4a4a; margin-top:5px; font-style:italic; }
|
||||
|
||||
.vv-ai-pending { font-size:12px; color:#5a5a5a; display:flex; align-items:center; gap:8px; }
|
||||
.vv-ai-dot { width:6px; height:6px; border-radius:50%; background:#6fcf97; animation:vvAiPulse 1.1s infinite; }
|
||||
@keyframes vvAiPulse { 0%,100%{opacity:.25;} 50%{opacity:1;} }
|
||||
@@ -256,6 +268,19 @@ if (is_dir('/var/log/varaverk')) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bug reports the scheduler's troubleshooter filed. Hidden entirely when there are none:
|
||||
an empty card here would be a permanent reminder of nothing, and this row already
|
||||
competes for the space above the transcript. -->
|
||||
<div class="vv-ai-tok" id="vv-ai-bugs-wrap" style="display:none">
|
||||
<div class="vv-ai-diag-col" style="grid-column:1/-1">
|
||||
<div class="vv-ai-diag-h">
|
||||
<span id="vv-ai-bugs-sum"></span> Reported by the assistant
|
||||
<span class="vv-ai-set-sum" style="margin-left:auto">filed from the Scheduler troubleshooter</span>
|
||||
</div>
|
||||
<div id="vv-ai-bugs"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="vv-ai-diag">
|
||||
<div class="vv-ai-diag-col">
|
||||
<div class="vv-ai-diag-h"><span id="vv-ai-health-sum"></span> System checks</div>
|
||||
@@ -499,6 +524,47 @@ if (is_dir('/var/log/varaverk')) {
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
// ── Bug reports ─────────────────────────────────────────────────────────
|
||||
// Read-only here plus dismissal. These are filed by the troubleshooter on the Scheduler tab;
|
||||
// this card is where they are actually seen, since a chat window closes and a finding that
|
||||
// only ever existed in one is a finding you do not have.
|
||||
function loadBugs() {
|
||||
fetch(API + '?action=bugs').then(r => r.json())
|
||||
.then(d => { if (d.ok) renderBugs(d.bugs || []); })
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
function renderBugs(bugs) {
|
||||
const wrap = $('vv-ai-bugs-wrap');
|
||||
if (!bugs.length) { wrap.style.display = 'none'; return; }
|
||||
wrap.style.display = '';
|
||||
$('vv-ai-bugs-sum').innerHTML =
|
||||
`<span class="vv-ai-warn">${bugs.length} open</span>`;
|
||||
$('vv-ai-bugs').innerHTML = bugs.map(b => {
|
||||
const when = ago(b.last);
|
||||
// The seen count is the triage signal — once is a curiosity, forty times is a pattern.
|
||||
const seen = b.seen > 1 ? ` · seen ${b.seen}×` : '';
|
||||
return `<div class="vv-ai-bug">
|
||||
<div class="vv-ai-bug-h">
|
||||
<span class="vv-ai-bug-c">${esc(b.component)}</span>
|
||||
<span class="vv-ai-bug-m">${esc(b.id)}${esc(seen)} · ${esc(when)}</span>
|
||||
<button class="vv-ai-btn ghost" onclick="vvAiBugClose('${esc(b.id)}')">Dismiss</button>
|
||||
</div>
|
||||
<div class="vv-ai-bug-s">${esc(b.summary)}</div>
|
||||
<pre class="vv-ai-bug-e">${esc(b.evidence)}</pre>
|
||||
${b.context && b.context.asked
|
||||
? `<div class="vv-ai-bug-q">asked: ${esc(b.context.asked)}</div>` : ''}
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
window.vvAiBugClose = function (id) {
|
||||
fetch(API, { method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
|
||||
body: new URLSearchParams({ action: 'bug_close', id, open: '0' }) })
|
||||
.then(() => loadBugs()).catch(() => {});
|
||||
};
|
||||
|
||||
// ── Token accounting ────────────────────────────────────────────────────
|
||||
// Fetched on load and after each completed turn, never on the 30s banner tick: the totals
|
||||
// only move when a turn finishes, and the page is the thing that knows when that was.
|
||||
@@ -919,5 +985,6 @@ if (is_dir('/var/log/varaverk')) {
|
||||
|
||||
loadBanner();
|
||||
loadTokens();
|
||||
loadBugs();
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user