@axiomatic-labs/claudeflow 2.13.84 → 2.13.85

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.
Files changed (2) hide show
  1. package/lib/panel.js +32 -8
  2. package/package.json +1 -1
package/lib/panel.js CHANGED
@@ -1039,13 +1039,22 @@ function severityFor(id) {
1039
1039
  }
1040
1040
  case 'validators': {
1041
1041
  if (!s.validators || !s.validators.available) return 'info';
1042
- // Block > error > pass > skip. Block is the actionable state — the
1043
- // hook actually halted the agent. Surface it the same way Observer
1044
- // surfaces unresolved incidents (warn = amber dot in the nav).
1045
- if (s.validators.stats && s.validators.stats.block > 0) return 'warn';
1046
- if (s.validators.stats && s.validators.stats.error > 0) return 'warn';
1047
- if (s.validators.stats && s.validators.stats.pass > 0) return 'ok';
1048
- return 'info';
1042
+ // Compute the CURRENT state per (validator, scope) instead of the
1043
+ // all-time tally. Runs are stored newest-first, so the first
1044
+ // encounter of a given key is the latest run for that combo.
1045
+ // Pre-v2.13.85 we used stats.block > 0, which kept the badge amber
1046
+ // forever once anything had ever blocked — even after the LLM fixed
1047
+ // the underlying bug and subsequent runs passed.
1048
+ const seen = new Set();
1049
+ let currentlyFailing = 0;
1050
+ for (const r of s.validators.runs || []) {
1051
+ const key = (r.validator || '') + '|' + (r.scope || '');
1052
+ if (seen.has(key)) continue;
1053
+ seen.add(key);
1054
+ if (r.status === 'block' || r.status === 'error') currentlyFailing += 1;
1055
+ }
1056
+ if (currentlyFailing > 0) return 'warn';
1057
+ return seen.size > 0 ? 'ok' : 'info';
1049
1058
  }
1050
1059
  case 'setupContext': return !s.setupContext.exists ? 'err' : (s.setupContext.toolingComplete ? 'ok' : 'warn');
1051
1060
  case 'activeRun': return s.activeRun.active ? 'info' : 'info';
@@ -1757,10 +1766,25 @@ function renderValidators() {
1757
1766
  <div style="display:flex;gap:6px;flex-wrap:wrap;">\${pillsHtml}</div>
1758
1767
  </div>\`;
1759
1768
 
1769
+ // Compute "current state" per (validator, scope) — newest run wins, so
1770
+ // the user sees what's failing RIGHT NOW vs what once failed and has
1771
+ // since been fixed. The historical totals remain available below.
1772
+ const currentBy = new Map();
1773
+ for (const r of v.runs) {
1774
+ const key = r.validator + '|' + r.scope;
1775
+ if (!currentBy.has(key)) currentBy.set(key, r);
1776
+ }
1777
+ const currentRuns = [...currentBy.values()];
1778
+ const currentFailing = currentRuns.filter((r) => r.status === 'block' || r.status === 'error');
1779
+ const currentStateLine = currentFailing.length === 0
1780
+ ? \`<span style="color:var(--ok,#3fb950);">✓ All \${currentRuns.length} (validator, scope) combo(s) currently passing</span>\`
1781
+ : \`<span style="color:var(--err,#f85149);">✗ \${currentFailing.length} of \${currentRuns.length} (validator, scope) combo(s) currently failing:</span> \${currentFailing.map((r) => escapeHtml(r.validator + ' @ ' + r.scope)).join(', ')}\`;
1782
+
1760
1783
  return \`<h2>Validators
1761
1784
  <button id="clear-validators" class="logs-clear-btn" style="float:right;" data-scope="\${escapeHtml(validatorsScopeFilter)}">\${clearLabel}</button>
1762
1785
  </h2>
1763
- <p class="muted" style="margin-top:0;">Last updated \${formatRelativeTime(v.updated_at)} · \${v.stats.total} total run(s): \${v.stats.pass} pass, \${v.stats.block} block, \${v.stats.skip} skip, \${v.stats.error} error.</p>
1786
+ <p style="margin-top:0;">\${currentStateLine}</p>
1787
+ <p class="muted" style="margin-top:4px;font-size:12px;">History: last updated \${formatRelativeTime(v.updated_at)} · \${v.stats.total} total run(s): \${v.stats.pass} pass, \${v.stats.block} block, \${v.stats.skip} skip, \${v.stats.error} error.</p>
1764
1788
  <div class="card" style="padding:10px 14px;margin:12px 0;">
1765
1789
  \${filterRow('Validator', validatorPills)}
1766
1790
  \${filterRow('Scope', scopePills)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.13.84",
3
+ "version": "2.13.85",
4
4
  "description": "Claudeflow — AI-powered development toolkit for Claude Code. Skills, agents, hooks, and quality gates that ship production apps.",
5
5
  "bin": {
6
6
  "claudeflow": "./bin/cli.js"