@axiomatic-labs/claudeflow 2.13.33 → 2.13.34

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 +56 -0
  2. package/package.json +1 -1
package/lib/panel.js CHANGED
@@ -422,6 +422,29 @@ function readLogEvent(cwd, id) {
422
422
  }
423
423
  }
424
424
 
425
+ // Destructive: removes every sidecar in .claude/tmp/log-events/ and truncates
426
+ // .claude/tmp/hooks.log. Returns counts so the UI can confirm the wipe.
427
+ function clearLogs(cwd) {
428
+ const dir = logEventsDir(cwd);
429
+ let removed = 0;
430
+ try {
431
+ const files = fs.readdirSync(dir).filter((f) => f.endsWith('.json'));
432
+ for (const f of files) {
433
+ try { fs.unlinkSync(path.join(dir, f)); removed++; } catch {}
434
+ }
435
+ } catch {}
436
+ // Truncate the human-readable log too so the user sees a fresh tail -f.
437
+ let logTruncated = false;
438
+ const logPath = path.join(cwd, '.claude', 'tmp', 'hooks.log');
439
+ try {
440
+ if (fs.existsSync(logPath)) {
441
+ fs.writeFileSync(logPath, '');
442
+ logTruncated = true;
443
+ }
444
+ } catch {}
445
+ return { removed, logTruncated };
446
+ }
447
+
425
448
  function getLogsInfo(cwd) {
426
449
  const dir = logEventsDir(cwd);
427
450
  const thresholds = tokenThresholds();
@@ -593,6 +616,10 @@ details[open] summary { padding-bottom: 8px; border-bottom: 1px solid var(--bord
593
616
  .logs-controls { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; }
594
617
  .logs-controls select, .logs-controls button { background: var(--panel); border: 1px solid var(--border); color: var(--fg); padding: 6px 10px; border-radius: 6px; font: inherit; }
595
618
  .logs-controls button:hover { border-color: var(--accent); cursor: pointer; }
619
+ .logs-clear-btn { margin-left: auto; color: var(--err); border-color: rgba(248,81,73,0.4); }
620
+ .logs-clear-btn:hover { border-color: var(--err); background: rgba(248,81,73,0.08); }
621
+ .logs-clear-btn:disabled { opacity: 0.4; cursor: not-allowed; color: var(--muted); border-color: var(--border); }
622
+ .logs-clear-btn:disabled:hover { border-color: var(--border); background: var(--panel); }
596
623
  .logs-table { width: 100%; border-collapse: collapse; font-size: 13px; }
597
624
  .logs-table th, .logs-table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); vertical-align: top; }
598
625
  .logs-table th { font-weight: 500; color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.5px; }
@@ -1113,6 +1140,7 @@ function renderLogs() {
1113
1140
  </select>
1114
1141
  </label>
1115
1142
  <button id="logs-reload">Reload</button>
1143
+ <button id="logs-clear" class="logs-clear-btn" \${state.logs && state.logs.total ? '' : 'disabled'} title="Delete every sidecar in .claude/tmp/log-events/ and truncate .claude/tmp/hooks.log. Cannot be undone.">Clear all</button>
1116
1144
  </div>
1117
1145
  \${empty || \`<table class="logs-table">
1118
1146
  <thead><tr><th>Time</th><th>Type</th><th title="Did the hook actually run? ✓ injected = hook ran and emitted to Claude Code · ✗ SILENCED = master Enforcement OFF blocked the hook from running.">Status</th><th>Handler</th><th title="Approximate token count (chars/4 heuristic, ±10–15% vs Claude's real tokenizer). Heavy ≥\${thresholds.heavy.toLocaleString()} → yellow border. High ≥\${thresholds.high.toLocaleString()} → red border. Anthropic does not publish official thresholds for per-turn additionalContext.">≈ Tokens</th><th></th></tr></thead>
@@ -1237,8 +1265,31 @@ document.addEventListener('click', (e) => {
1237
1265
  if (t.id === 'logs-load-more') {
1238
1266
  return loadLogsPage({ append: true });
1239
1267
  }
1268
+ if (t.id === 'logs-clear') {
1269
+ const total = (state.logs && state.logs.total) || 0;
1270
+ if (!total) return;
1271
+ if (!confirm('Delete ' + total + ' captured log event(s) and truncate .claude/tmp/hooks.log?\\n\\nThis cannot be undone. (Future events will be captured normally.)')) return;
1272
+ return clearLogsAction();
1273
+ }
1240
1274
  });
1241
1275
 
1276
+ async function clearLogsAction() {
1277
+ try {
1278
+ const r = await fetch('/api/logs', { method: 'DELETE' });
1279
+ const result = await r.json();
1280
+ if (!r.ok) {
1281
+ showToast('Clear failed: ' + (result.error || r.status), 'err');
1282
+ return;
1283
+ }
1284
+ showToast('Cleared ' + result.removed + ' event(s)' + (result.logTruncated ? ' + truncated hooks.log' : ''), 'ok');
1285
+ logsState.entries = [];
1286
+ logsState.allLoaded = false;
1287
+ await refresh();
1288
+ } catch (e) {
1289
+ showToast('Network error: ' + e.message, 'err');
1290
+ }
1291
+ }
1292
+
1242
1293
  document.addEventListener('change', (e) => {
1243
1294
  const t = e.target;
1244
1295
  if (!t || !t.classList) return;
@@ -1380,6 +1431,11 @@ function handler(cwd) {
1380
1431
  return send(status, JSON.stringify(result), 'application/json');
1381
1432
  }
1382
1433
 
1434
+ if (req.method === 'DELETE' && route === '/api/logs') {
1435
+ const result = clearLogs(cwd);
1436
+ return send(200, JSON.stringify(result), 'application/json');
1437
+ }
1438
+
1383
1439
  if (req.method === 'POST' && route === '/api/enforcement/toggle') {
1384
1440
  const raw = await readRequestBody(req);
1385
1441
  let payload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.13.33",
3
+ "version": "2.13.34",
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"