@axiomatic-labs/claudeflow 2.13.77 → 2.13.78

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 +54 -9
  2. package/package.json +1 -1
package/lib/panel.js CHANGED
@@ -886,6 +886,7 @@ let observerFilter = 'all';
886
886
  let observerShowResolved = false;
887
887
  let validatorsFilter = 'all';
888
888
  let validatorsStatusFilter = 'all';
889
+ let validatorsScopeFilter = 'all';
889
890
  let timer = null;
890
891
 
891
892
  // Preserve which <details> were open across re-renders (auto-refresh would
@@ -1667,6 +1668,7 @@ function renderValidators() {
1667
1668
  }
1668
1669
 
1669
1670
  const validators = [...new Set(v.runs.map((r) => r.validator))].sort();
1671
+ const scopes = [...new Set(v.runs.map((r) => r.scope))].sort();
1670
1672
  const validatorPill = (label, value, count) => {
1671
1673
  const a = (validatorsFilter === value);
1672
1674
  const cls = a ? 'pill pill-active' : 'pill';
@@ -1677,13 +1679,21 @@ function renderValidators() {
1677
1679
  const cls = a ? 'pill pill-active' : 'pill';
1678
1680
  return \`<button class="\${cls}" data-validators-status-filter="\${escapeHtml(value)}">\${escapeHtml(label)}<span class="muted" style="margin-left:6px;font-size:11px;">\${count}</span></button>\`;
1679
1681
  };
1682
+ const scopePill = (label, value, count) => {
1683
+ const a = (validatorsScopeFilter === value);
1684
+ const cls = a ? 'pill pill-active' : 'pill';
1685
+ return \`<button class="\${cls}" data-validators-scope-filter="\${escapeHtml(value)}">\${escapeHtml(label)}<span class="muted" style="margin-left:6px;font-size:11px;">\${count}</span></button>\`;
1686
+ };
1680
1687
 
1681
1688
  const filteredByValidator = validatorsFilter === 'all'
1682
1689
  ? v.runs
1683
1690
  : v.runs.filter((r) => r.validator === validatorsFilter);
1684
- const filtered = validatorsStatusFilter === 'all'
1691
+ const filteredByScope = validatorsScopeFilter === 'all'
1685
1692
  ? filteredByValidator
1686
- : filteredByValidator.filter((r) => r.status === validatorsStatusFilter);
1693
+ : filteredByValidator.filter((r) => r.scope === validatorsScopeFilter);
1694
+ const filtered = validatorsStatusFilter === 'all'
1695
+ ? filteredByScope
1696
+ : filteredByScope.filter((r) => r.status === validatorsStatusFilter);
1687
1697
 
1688
1698
  const STATUS_BADGE = {
1689
1699
  pass: '<span style="color:#3fb950;font-weight:600;">pass</span>',
@@ -1713,18 +1723,33 @@ function renderValidators() {
1713
1723
  validatorPill(vname, vname, v.runs.filter((r) => r.validator === vname).length)
1714
1724
  )].join(' ');
1715
1725
 
1726
+ const scopePills = [scopePill('all', 'all', v.runs.length), ...scopes.map((s) =>
1727
+ scopePill(s, s, v.runs.filter((r) => r.scope === s).length)
1728
+ )].join(' ');
1729
+
1716
1730
  const statusPills = ['all', 'pass', 'block', 'skip', 'error'].map((s) =>
1717
1731
  statusPill(s, s, s === 'all' ? v.runs.length : v.runs.filter((r) => r.status === s).length)
1718
1732
  ).join(' ');
1719
1733
 
1734
+ // Clear button label changes when a scope filter is active so the user
1735
+ // sees the action they're about to take. "Clear (Admin-Office)" is
1736
+ // unambiguous; "Clear history" wiped everything pre-v2.13.78.
1737
+ const clearLabel = validatorsScopeFilter === 'all'
1738
+ ? 'Clear all history'
1739
+ : \`Clear "\${escapeHtml(validatorsScopeFilter)}" history\`;
1740
+
1720
1741
  return \`<h2>Validators
1721
- <button id="clear-validators" class="btn btn-ghost" style="float:right;font-size:12px;">Clear history</button>
1742
+ <button id="clear-validators" class="btn btn-ghost" style="float:right;font-size:12px;" data-scope="\${escapeHtml(validatorsScopeFilter)}">\${clearLabel}</button>
1722
1743
  </h2>
1723
1744
  <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>
1724
1745
  <div style="margin:12px 0;">
1725
1746
  <div style="margin-bottom:6px;"><span class="muted" style="font-size:11px;text-transform:uppercase;">Validator</span></div>
1726
1747
  \${validatorPills}
1727
1748
  </div>
1749
+ <div style="margin:12px 0;">
1750
+ <div style="margin-bottom:6px;"><span class="muted" style="font-size:11px;text-transform:uppercase;">Scope</span></div>
1751
+ \${scopePills}
1752
+ </div>
1728
1753
  <div style="margin:12px 0;">
1729
1754
  <div style="margin-bottom:6px;"><span class="muted" style="font-size:11px;text-transform:uppercase;">Status</span></div>
1730
1755
  \${statusPills}
@@ -1901,21 +1926,38 @@ document.addEventListener('click', (e) => {
1901
1926
  renderContent();
1902
1927
  return;
1903
1928
  }
1929
+ if (t.dataset && t.dataset.validatorsScopeFilter) {
1930
+ validatorsScopeFilter = t.dataset.validatorsScopeFilter;
1931
+ renderContent();
1932
+ return;
1933
+ }
1904
1934
  if (t.id === 'clear-validators') {
1905
1935
  return clearValidatorsAction(t);
1906
1936
  }
1907
1937
  });
1908
1938
 
1909
1939
  async function clearValidatorsAction(btn) {
1910
- if (!confirm('Clear validator run history? This wipes the log shown in this tab. Validators continue running.')) return;
1940
+ const scope = (btn.dataset && btn.dataset.scope) || 'all';
1941
+ const isScoped = scope !== 'all';
1942
+ const message = isScoped
1943
+ ? \`Clear validator history for scope "\${scope}"? Runs from other scopes are preserved. Validators continue running.\`
1944
+ : 'Clear ALL validator run history? This wipes the entire log. Validators continue running.';
1945
+ if (!confirm(message)) return;
1911
1946
  const originalLabel = btn.textContent;
1912
1947
  btn.disabled = true;
1913
1948
  btn.textContent = 'Clearing…';
1914
1949
  try {
1915
- const r = await fetch('/api/validators/clear', { method: 'POST' });
1950
+ const url = isScoped
1951
+ ? '/api/validators/clear?scope=' + encodeURIComponent(scope)
1952
+ : '/api/validators/clear';
1953
+ const r = await fetch(url, { method: 'POST' });
1916
1954
  const result = await r.json();
1917
- if (r.ok && result.ok) showToast('Validator history cleared', 'ok');
1918
- else showToast('Clear failed: ' + (result.error || 'unknown'), 'err');
1955
+ if (r.ok && result.ok) {
1956
+ const removed = typeof result.removed === 'number' ? \` (removed \${result.removed})\` : '';
1957
+ showToast(isScoped ? \`Cleared "\${scope}"\${removed}\` : \`Cleared all history\${removed}\`, 'ok');
1958
+ } else {
1959
+ showToast('Clear failed: ' + (result.error || 'unknown'), 'err');
1960
+ }
1919
1961
  } catch (e) {
1920
1962
  showToast('Network error: ' + e.message, 'err');
1921
1963
  } finally {
@@ -2355,8 +2397,11 @@ function handler(cwd) {
2355
2397
  if (req.method === 'POST' && route === '/api/validators/clear') {
2356
2398
  try {
2357
2399
  const validatorState = require(path.join(cwd, '.claudeflow', 'runtime', 'validator-state.js'));
2358
- validatorState.clearState(cwd);
2359
- return send(200, JSON.stringify({ ok: true }), 'application/json');
2400
+ const scope = url.searchParams.get('scope');
2401
+ const removed = scope && scope !== 'all'
2402
+ ? validatorState.clearScope(cwd, scope)
2403
+ : (() => { const s = validatorState.readState(cwd); const n = s ? s.runs.length : 0; validatorState.clearState(cwd); return n; })();
2404
+ return send(200, JSON.stringify({ ok: true, removed, scope: scope || 'all' }), 'application/json');
2360
2405
  } catch (err) {
2361
2406
  return send(500, JSON.stringify({ ok: false, error: err.message }), 'application/json');
2362
2407
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.13.77",
3
+ "version": "2.13.78",
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"