@axiomatic-labs/claudeflow 2.13.84 → 2.13.86

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 +38 -9
  2. package/package.json +1 -1
package/lib/panel.js CHANGED
@@ -1038,14 +1038,28 @@ function severityFor(id) {
1038
1038
  return 'ok';
1039
1039
  }
1040
1040
  case 'validators': {
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';
1041
+ if (!s.validators) 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
+ // No failing combos — green. Includes "no runs yet" (cleared history
1058
+ // or hooks haven't fired) which is conceptually a passing state, not
1059
+ // a broken-system state. Pre-v2.13.86 this returned info (gray) when
1060
+ // there were 0 runs, which made an empty Validators look "unknown"
1061
+ // when it really meant "nothing to worry about".
1062
+ return 'ok';
1049
1063
  }
1050
1064
  case 'setupContext': return !s.setupContext.exists ? 'err' : (s.setupContext.toolingComplete ? 'ok' : 'warn');
1051
1065
  case 'activeRun': return s.activeRun.active ? 'info' : 'info';
@@ -1757,10 +1771,25 @@ function renderValidators() {
1757
1771
  <div style="display:flex;gap:6px;flex-wrap:wrap;">\${pillsHtml}</div>
1758
1772
  </div>\`;
1759
1773
 
1774
+ // Compute "current state" per (validator, scope) — newest run wins, so
1775
+ // the user sees what's failing RIGHT NOW vs what once failed and has
1776
+ // since been fixed. The historical totals remain available below.
1777
+ const currentBy = new Map();
1778
+ for (const r of v.runs) {
1779
+ const key = r.validator + '|' + r.scope;
1780
+ if (!currentBy.has(key)) currentBy.set(key, r);
1781
+ }
1782
+ const currentRuns = [...currentBy.values()];
1783
+ const currentFailing = currentRuns.filter((r) => r.status === 'block' || r.status === 'error');
1784
+ const currentStateLine = currentFailing.length === 0
1785
+ ? \`<span style="color:var(--ok,#3fb950);">✓ All \${currentRuns.length} (validator, scope) combo(s) currently passing</span>\`
1786
+ : \`<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(', ')}\`;
1787
+
1760
1788
  return \`<h2>Validators
1761
1789
  <button id="clear-validators" class="logs-clear-btn" style="float:right;" data-scope="\${escapeHtml(validatorsScopeFilter)}">\${clearLabel}</button>
1762
1790
  </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>
1791
+ <p style="margin-top:0;">\${currentStateLine}</p>
1792
+ <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
1793
  <div class="card" style="padding:10px 14px;margin:12px 0;">
1765
1794
  \${filterRow('Validator', validatorPills)}
1766
1795
  \${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.86",
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"