@vibecodeqa/cli 0.37.1 → 0.37.2

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/dist/monitor.js +58 -2
  2. package/package.json +1 -1
package/dist/monitor.js CHANGED
@@ -371,6 +371,39 @@ function GitChangesView({ cwd, checks, height, cursor }) {
371
371
  return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: sel ? "white" : "gray", children: sel ? "▸" : " " }), _jsxs(Text, { color: statusColor[ch.status] || "gray", bold: true, children: [" ", ch.status, " "] }), _jsxs(Text, { color: sel ? "white" : undefined, children: [ch.file, " "] }), count > 0 ? (_jsxs(Text, { color: "yellow", children: [count, " issue", count !== 1 ? "s" : ""] })) : (_jsx(Text, { color: "green", children: "clean" }))] }, ch.file));
372
372
  }), changes.length > visibleLines && _jsxs(Text, { dimColor: true, children: [" +", changes.length - visibleLines, " more"] })] }))] }));
373
373
  }
374
+ // ── All Files View ──
375
+ function AllFilesView({ checks, height, cursor }) {
376
+ // Build file list from all issues, sorted by issue count descending
377
+ const fileMap = useMemo(() => {
378
+ const map = new Map();
379
+ for (const c of checks) {
380
+ for (const iss of c.issues) {
381
+ if (!iss.file || typeof iss.file !== "string")
382
+ continue;
383
+ const entry = map.get(iss.file) || { errors: 0, warnings: 0, infos: 0 };
384
+ if (iss.severity === "error")
385
+ entry.errors++;
386
+ else if (iss.severity === "warning")
387
+ entry.warnings++;
388
+ else
389
+ entry.infos++;
390
+ map.set(iss.file, entry);
391
+ }
392
+ }
393
+ return [...map.entries()]
394
+ .map(([file, counts]) => ({ file, total: counts.errors + counts.warnings + counts.infos, ...counts }))
395
+ .sort((a, b) => b.total - a.total);
396
+ }, [checks]);
397
+ const visibleLines = Math.max(1, height - 5);
398
+ // Scroll window
399
+ const scrollStart = Math.max(0, Math.min(cursor - Math.floor(visibleLines / 2), fileMap.length - visibleLines));
400
+ const visible = fileMap.slice(scrollStart, scrollStart + visibleLines);
401
+ return (_jsxs(Box, { flexDirection: "column", height: height, paddingX: 1, overflowY: "hidden", children: [_jsxs(Text, { bold: true, color: "magenta", children: [" \u25C8 Files with Issues (", fileMap.length, ")"] }), _jsx(Text, { dimColor: true, children: " sorted by issue count \u00B7 Enter to drill in" }), _jsx(Text, { children: " " }), fileMap.length === 0 ? (_jsx(Text, { color: "green", children: " No issues in any file." })) : (_jsxs(_Fragment, { children: [visible.map((f, i) => {
402
+ const idx = scrollStart + i;
403
+ const sel = idx === cursor;
404
+ return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: sel ? "white" : "gray", children: sel ? "▸" : " " }), f.errors > 0 ? _jsxs(Text, { color: "red", bold: true, children: [String(f.errors).padStart(2), "E "] }) : _jsx(Text, { dimColor: true, children: " " }), f.warnings > 0 ? _jsxs(Text, { color: "yellow", children: [String(f.warnings).padStart(2), "W "] }) : _jsx(Text, { dimColor: true, children: " " }), f.infos > 0 ? _jsxs(Text, { dimColor: true, children: [String(f.infos).padStart(2), "I "] }) : _jsx(Text, { dimColor: true, children: " " }), _jsx(Text, { color: sel ? "white" : "cyan", children: f.file })] }, f.file));
405
+ }), fileMap.length > scrollStart + visibleLines && _jsxs(Text, { dimColor: true, children: [" +", fileMap.length - scrollStart - visibleLines, " more (\u2193)"] })] }))] }));
406
+ }
374
407
  function MonitorApp({ cwd }) {
375
408
  const { exit } = useApp();
376
409
  const { stdout } = useStdout();
@@ -504,7 +537,7 @@ function MonitorApp({ cwd }) {
504
537
  return;
505
538
  }
506
539
  if (mode.view === "file-issues") {
507
- setMode({ view: "git-changes" });
540
+ setMode({ view: "dashboard" });
508
541
  setCursor(0);
509
542
  return;
510
543
  }
@@ -577,6 +610,11 @@ function MonitorApp({ cwd }) {
577
610
  setCursor(0);
578
611
  return;
579
612
  }
613
+ if (input === "f") {
614
+ setMode({ view: "all-files" });
615
+ setCursor(0);
616
+ return;
617
+ }
580
618
  if (input === "c") {
581
619
  setMode({ view: "config" });
582
620
  setConfigCursor(0);
@@ -639,6 +677,21 @@ function MonitorApp({ cwd }) {
639
677
  }
640
678
  }
641
679
  }
680
+ // ── All files: ↑↓ navigate, Enter drill into file issues ──
681
+ if (mode.view === "all-files") {
682
+ const fileMap = state.checks
683
+ .flatMap((c) => c.issues.filter((i) => i.file && typeof i.file === "string").map((i) => i.file))
684
+ .reduce((map, f) => { map.set(f, (map.get(f) || 0) + 1); return map; }, new Map());
685
+ const files = [...fileMap.keys()].sort((a, b) => (fileMap.get(b) || 0) - (fileMap.get(a) || 0));
686
+ if (key.upArrow)
687
+ setCursor((c) => Math.max(0, c - 1));
688
+ if (key.downArrow)
689
+ setCursor((c) => Math.min(files.length - 1, c + 1));
690
+ if (key.return && files[cursor]) {
691
+ setMode({ view: "file-issues", file: files[cursor] });
692
+ setCursor(0);
693
+ }
694
+ }
642
695
  // ── Git changes: ↑↓ navigate, Enter drill into file issues ──
643
696
  if (mode.view === "git-changes") {
644
697
  const changes = getGitChanges(cwd);
@@ -681,6 +734,9 @@ function MonitorApp({ cwd }) {
681
734
  const proj = basename(cwd);
682
735
  const p = monCfg.panels;
683
736
  // ── Render views ──
737
+ if (mode.view === "all-files") {
738
+ return (_jsxs(Box, { flexDirection: "column", height: rows, children: [_jsx(Header, { proj: proj, stack: stack, workspace: workspace, state: state }), _jsx(AllFilesView, { checks: state.checks, height: rows - 3, cursor: cursor }), _jsx(Box, { paddingX: 1, children: _jsx(Text, { dimColor: true, children: "Esc back \u00B7 \u2191\u2193 select \u00B7 Enter view file issues \u00B7 q quit" }) })] }));
739
+ }
684
740
  if (mode.view === "git-changes") {
685
741
  return (_jsxs(Box, { flexDirection: "column", height: rows, children: [_jsx(Header, { proj: proj, stack: stack, workspace: workspace, state: state }), _jsx(GitChangesView, { cwd: cwd, checks: state.checks, height: rows - 3, cursor: cursor }), _jsx(Box, { paddingX: 1, children: _jsx(Text, { dimColor: true, children: "Esc back \u00B7 \u2191\u2193 select \u00B7 Enter view file issues \u00B7 q quit" }) })] }));
686
742
  }
@@ -722,7 +778,7 @@ function MonitorApp({ cwd }) {
722
778
  })] }))] })), mainVisible && (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [p.activity && _jsx(ActivityPanel, { log: log, height: activityH }), p.issues && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: panel === "issues" ? "magenta" : "gray", paddingX: 1, height: issuesH, overflowY: "hidden", children: [_jsxs(Text, { bold: true, color: "magenta", children: [" ", "\u25C8 Issues (", allIssues.length, ") ", panel === "issues" && _jsx(Text, { dimColor: true, children: "\u25C4" })] }), allIssues.slice(0, issuesH - 3).map((iss, i) => {
723
779
  const sel = panel === "issues" && i === cursor;
724
780
  return (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: sel ? "white" : "gray", children: sel ? "▸" : " " }), _jsxs(Text, { color: sc(iss.severity), bold: true, children: [iss.severity[0].toUpperCase(), " "] }), _jsxs(Text, { dimColor: true, children: [(iss.check || "").slice(0, 11).padEnd(11), " "] }), iss.file && _jsxs(Text, { color: "cyan", children: [basename(String(iss.file)).slice(0, 18).padEnd(18), " "] }), _jsx(Text, { children: iss.message.slice(0, 40) })] }, i));
725
- }), allIssues.length > issuesH - 3 && _jsxs(Text, { dimColor: true, children: [" +", allIssues.length - (issuesH - 3), " more"] })] }))] })), !sidebarVisible && !mainVisible && (_jsx(Box, { height: bodyRows, justifyContent: "center", alignItems: "center", children: _jsx(Text, { dimColor: true, children: "All panels hidden. Press c to configure." }) }))] }), _jsx(Box, { paddingX: 1, justifyContent: "space-between", children: _jsx(Text, { dimColor: true, children: "Tab panel \u00B7 \u2191\u2193 Enter Esc \u00B7 r scan \u00B7 g git \u00B7 t trends \u00B7 c config \u00B7 q quit" }) })] }));
781
+ }), allIssues.length > issuesH - 3 && _jsxs(Text, { dimColor: true, children: [" +", allIssues.length - (issuesH - 3), " more"] })] }))] })), !sidebarVisible && !mainVisible && (_jsx(Box, { height: bodyRows, justifyContent: "center", alignItems: "center", children: _jsx(Text, { dimColor: true, children: "All panels hidden. Press c to configure." }) }))] }), _jsx(Box, { paddingX: 1, justifyContent: "space-between", children: _jsx(Text, { dimColor: true, children: "Tab panel \u00B7 \u2191\u2193 Enter Esc \u00B7 r scan \u00B7 f files \u00B7 g git \u00B7 t trends \u00B7 c config \u00B7 q" }) })] }));
726
782
  }
727
783
  function Header({ proj, stack, workspace, state }) {
728
784
  return (_jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [_jsxs(Text, { children: [_jsx(Text, { color: "magenta", bold: true, children: "vcqa monitor" }), _jsxs(Text, { dimColor: true, children: [" v", VERSION] })] }), _jsxs(Text, { children: [_jsx(Text, { bold: true, children: proj }), _jsxs(Text, { dimColor: true, children: [" ", stack.language, "/", stack.framework, workspace.isMonorepo ? ` · ${workspace.tool}` : ""] })] }), _jsxs(Text, { children: [state.score > 0 && _jsxs(Text, { color: gc(state.grade), bold: true, children: [state.grade, " ", state.score, " "] }), _jsx(Text, { dimColor: true, children: state.scanning ? "⟳ scanning" : "● watching" })] })] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecodeqa/cli",
3
- "version": "0.37.1",
3
+ "version": "0.37.2",
4
4
  "description": "Code health scanner for the AI coding era. 25 checks, zero config, full report.",
5
5
  "type": "module",
6
6
  "bin": {