@vibecodeqa/cli 0.37.2 → 0.37.4
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.
- package/dist/monitor.js +24 -18
- package/package.json +1 -1
package/dist/monitor.js
CHANGED
|
@@ -164,7 +164,7 @@ function ActivityPanel({ log, height }) {
|
|
|
164
164
|
improve: "green", regress: "red", error: "red", alert: "magenta",
|
|
165
165
|
};
|
|
166
166
|
const visibleLines = Math.max(1, height - 3);
|
|
167
|
-
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, height: height, overflowY: "hidden", children: [_jsx(Text, { bold: true, color: "magenta", children: " \u25C8 Activity" }), log.slice(-visibleLines).map((entry, i) => (_jsxs(Text, { wrap: "truncate", children: [_jsxs(Text, { dimColor: true, children: [entry.time, " "] }), _jsx(Text, { color: colors[entry.type], children: entry.text })] }, i)))] }));
|
|
167
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, height: height, overflowY: "hidden", children: [_jsx(Text, { bold: true, color: "magenta", children: " \u25C8 Activity" }), log.slice(-visibleLines).map((entry, i) => (_jsxs(Text, { wrap: "truncate", children: [_jsxs(Text, { dimColor: true, children: [entry.time, " "] }), _jsx(Text, { color: colors[entry.type], children: entry.text })] }, `${entry.time}-${i}`)))] }));
|
|
168
168
|
}
|
|
169
169
|
function ConfigScreen({ cursor, options }) {
|
|
170
170
|
return (_jsxs(Box, { flexDirection: "column", borderStyle: "double", borderColor: "magenta", paddingX: 2, paddingY: 1, children: [_jsx(Text, { bold: true, color: "magenta", children: " \u2699 Settings" }), _jsx(Text, { dimColor: true, children: " " }), options.map((opt, i) => {
|
|
@@ -346,11 +346,10 @@ function IssueDetail({ issue, checkName, cwd, height, copied }) {
|
|
|
346
346
|
const srcHeight = ctx ? Math.min(ctx.lines.length + 2, Math.floor((height - 8) * 0.6)) : 0;
|
|
347
347
|
const promptHeight = height - 8 - srcHeight;
|
|
348
348
|
const promptLines = prompt.split("\n");
|
|
349
|
-
return (_jsxs(Box, { flexDirection: "column", height: height, paddingX: 1, overflowY: "hidden", children: [_jsx(Text, { bold: true, color: "magenta", children: " \u25C8 Issue Detail" }), _jsxs(Text, { children: [_jsxs(Text, { color: sc(issue.severity), bold: true, children: [" ", issue.severity.toUpperCase(), " "] }), _jsx(Text, { dimColor: true, children: checkName }), issue.rule && _jsxs(Text, { dimColor: true, children: [" \u00B7 ", issue.rule] }), copied && _jsx(Text, { color: "green", bold: true, children: " \u2713 Copied!" })] }), _jsxs(Text, { wrap: "wrap", children: [" ", issue.message] }), issue.file && (_jsxs(Text, { color: "cyan", children: [" ", issue.file, issue.line ? `:${issue.line}` : ""] })), ctx && (_jsxs(Box, { flexDirection: "column", height: srcHeight, overflowY: "hidden", children: [_jsxs(Text, { dimColor: true, children: [" \u2500\u2500\u2500 ", ctx.filePath, " \u2500\u2500\u2500"] }), ctx.lines.slice(0, srcHeight - 2).map((l) => (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: l.highlight ? "yellow" : "gray", children: l.highlight ? "▸" : " " }), _jsxs(Text, { dimColor: true, children: [String(l.num).padStart(4), "\u2502"] }), _jsx(Text, { color: l.highlight ? "white" : undefined, children: l.text })] }, l.num))), _jsx(Text, { dimColor: true, children: " \u2500\u2500\u2500" })] })), _jsxs(Box, { flexDirection: "column", height: Math.max(3, promptHeight), overflowY: "hidden", marginTop: ctx ? 0 : 1, children: [_jsxs(Text, { bold: true, color: "green", children: [" Fix prompt ", _jsx(Text, { dimColor: true, children: "(y to copy)" })] }), promptLines.slice(0, Math.max(1, promptHeight - 1)).map((line, i) => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [" ", line] }, i)))] })] }));
|
|
349
|
+
return (_jsxs(Box, { flexDirection: "column", height: height, paddingX: 1, overflowY: "hidden", children: [_jsx(Text, { bold: true, color: "magenta", children: " \u25C8 Issue Detail" }), _jsxs(Text, { children: [_jsxs(Text, { color: sc(issue.severity), bold: true, children: [" ", issue.severity.toUpperCase(), " "] }), _jsx(Text, { dimColor: true, children: checkName }), issue.rule && _jsxs(Text, { dimColor: true, children: [" \u00B7 ", issue.rule] }), copied && _jsx(Text, { color: "green", bold: true, children: " \u2713 Copied!" })] }), _jsxs(Text, { wrap: "wrap", children: [" ", issue.message] }), issue.file && (_jsxs(Text, { color: "cyan", children: [" ", issue.file, issue.line ? `:${issue.line}` : ""] })), ctx && (_jsxs(Box, { flexDirection: "column", height: srcHeight, overflowY: "hidden", children: [_jsxs(Text, { dimColor: true, children: [" \u2500\u2500\u2500 ", ctx.filePath, " \u2500\u2500\u2500"] }), ctx.lines.slice(0, srcHeight - 2).map((l) => (_jsxs(Text, { wrap: "truncate", children: [_jsx(Text, { color: l.highlight ? "yellow" : "gray", children: l.highlight ? "▸" : " " }), _jsxs(Text, { dimColor: true, children: [String(l.num).padStart(4), "\u2502"] }), _jsx(Text, { color: l.highlight ? "white" : undefined, children: l.text })] }, l.num))), _jsx(Text, { dimColor: true, children: " \u2500\u2500\u2500" })] })), _jsxs(Box, { flexDirection: "column", height: Math.max(3, promptHeight), overflowY: "hidden", marginTop: ctx ? 0 : 1, children: [_jsxs(Text, { bold: true, color: "green", children: [" Fix prompt ", _jsx(Text, { dimColor: true, children: "(y to copy)" })] }), promptLines.slice(0, Math.max(1, promptHeight - 1)).map((line, i) => (_jsxs(Text, { dimColor: true, wrap: "truncate", children: [" ", line] }, `p-${i}`)))] })] }));
|
|
350
350
|
}
|
|
351
351
|
// ── Git Changes View ──
|
|
352
|
-
function GitChangesView({
|
|
353
|
-
const changes = useMemo(() => getGitChanges(cwd), [cwd]);
|
|
352
|
+
function GitChangesView({ changes, checks, height, cursor }) {
|
|
354
353
|
// Cross-reference with issues
|
|
355
354
|
const issuesByFile = useMemo(() => {
|
|
356
355
|
const map = new Map();
|
|
@@ -440,6 +439,18 @@ function MonitorApp({ cwd }) {
|
|
|
440
439
|
return (o[a.severity] ?? 2) - (o[b.severity] ?? 2);
|
|
441
440
|
}), [state.checks]);
|
|
442
441
|
const currentList = panel === "checks" ? activeChecks : allIssues;
|
|
442
|
+
// Derived data for file views (memoized, used by both render + keyboard)
|
|
443
|
+
const filesWithIssues = useMemo(() => {
|
|
444
|
+
const map = new Map();
|
|
445
|
+
for (const c of state.checks) {
|
|
446
|
+
for (const iss of c.issues) {
|
|
447
|
+
if (iss.file && typeof iss.file === "string")
|
|
448
|
+
map.set(iss.file, (map.get(iss.file) || 0) + 1);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return [...map.keys()].sort((a, b) => (map.get(b) || 0) - (map.get(a) || 0));
|
|
452
|
+
}, [state.checks]);
|
|
453
|
+
const gitChanges = useMemo(() => getGitChanges(cwd), [cwd, state.scanCount]);
|
|
443
454
|
// Clamp cursor when data changes
|
|
444
455
|
useEffect(() => {
|
|
445
456
|
setCursor((c) => Math.min(c, Math.max(0, currentList.length - 1)));
|
|
@@ -679,28 +690,23 @@ function MonitorApp({ cwd }) {
|
|
|
679
690
|
}
|
|
680
691
|
// ── All files: ↑↓ navigate, Enter drill into file issues ──
|
|
681
692
|
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
693
|
if (key.upArrow)
|
|
687
694
|
setCursor((c) => Math.max(0, c - 1));
|
|
688
695
|
if (key.downArrow)
|
|
689
|
-
setCursor((c) => Math.min(
|
|
690
|
-
if (key.return &&
|
|
691
|
-
setMode({ view: "file-issues", file:
|
|
696
|
+
setCursor((c) => Math.min(filesWithIssues.length - 1, c + 1));
|
|
697
|
+
if (key.return && filesWithIssues[cursor]) {
|
|
698
|
+
setMode({ view: "file-issues", file: filesWithIssues[cursor] });
|
|
692
699
|
setCursor(0);
|
|
693
700
|
}
|
|
694
701
|
}
|
|
695
702
|
// ── Git changes: ↑↓ navigate, Enter drill into file issues ──
|
|
696
703
|
if (mode.view === "git-changes") {
|
|
697
|
-
const changes = getGitChanges(cwd);
|
|
698
704
|
if (key.upArrow)
|
|
699
705
|
setCursor((c) => Math.max(0, c - 1));
|
|
700
706
|
if (key.downArrow)
|
|
701
|
-
setCursor((c) => Math.min(
|
|
702
|
-
if (key.return &&
|
|
703
|
-
setMode({ view: "file-issues", file:
|
|
707
|
+
setCursor((c) => Math.min(gitChanges.length - 1, c + 1));
|
|
708
|
+
if (key.return && gitChanges[cursor]) {
|
|
709
|
+
setMode({ view: "file-issues", file: gitChanges[cursor].file });
|
|
704
710
|
setCursor(0);
|
|
705
711
|
}
|
|
706
712
|
}
|
|
@@ -738,13 +744,13 @@ function MonitorApp({ cwd }) {
|
|
|
738
744
|
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
745
|
}
|
|
740
746
|
if (mode.view === "git-changes") {
|
|
741
|
-
return (_jsxs(Box, { flexDirection: "column", height: rows, children: [_jsx(Header, { proj: proj, stack: stack, workspace: workspace, state: state }), _jsx(GitChangesView, {
|
|
747
|
+
return (_jsxs(Box, { flexDirection: "column", height: rows, children: [_jsx(Header, { proj: proj, stack: stack, workspace: workspace, state: state }), _jsx(GitChangesView, { changes: gitChanges, 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" }) })] }));
|
|
742
748
|
}
|
|
743
749
|
if (mode.view === "file-issues") {
|
|
744
750
|
const fileIssues = state.checks.flatMap((c) => c.issues.filter((i) => i.file === mode.file).map((i) => ({ check: c.name, ...i })));
|
|
745
751
|
return (_jsxs(Box, { flexDirection: "column", height: rows, children: [_jsx(Header, { proj: proj, stack: stack, workspace: workspace, state: state }), _jsxs(Box, { flexDirection: "column", height: rows - 3, paddingX: 1, overflowY: "hidden", children: [_jsxs(Text, { bold: true, color: "magenta", children: [" \u25C8 ", mode.file] }), _jsxs(Text, { dimColor: true, children: [" ", fileIssues.length, " issue", fileIssues.length !== 1 ? "s" : "", copied && _jsx(Text, { color: "green", bold: true, children: " \u2713 Copied!" })] }), _jsx(Text, { children: " " }), fileIssues.length === 0 ? (_jsx(Text, { color: "green", children: " No issues in this file." })) : (fileIssues.slice(0, rows - 8).map((iss, i) => {
|
|
746
752
|
const sel = i === cursor;
|
|
747
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: sel ? "white" : "gray", children: sel ? "▸" : " " }), _jsxs(Text, { color: sc(iss.severity), bold: true, children: [iss.severity[0].toUpperCase(), " "] }), iss.line && _jsx(Text, { color: "cyan", children: String(iss.line).padEnd(5) }), _jsx(Text, { dimColor: true, children: iss.check.padEnd(14) }), iss.rule && _jsxs(Text, { dimColor: true, children: ["(", iss.rule, ") "] })] }), _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: sel ? "white" : "gray", children: " " }), _jsx(Text, { color: sel ? "white" : undefined, children: iss.message })] })] }, i));
|
|
753
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsx(Text, { color: sel ? "white" : "gray", children: sel ? "▸" : " " }), _jsxs(Text, { color: sc(iss.severity), bold: true, children: [iss.severity[0].toUpperCase(), " "] }), iss.line && _jsx(Text, { color: "cyan", children: String(iss.line).padEnd(5) }), _jsx(Text, { dimColor: true, children: iss.check.padEnd(14) }), iss.rule && _jsxs(Text, { dimColor: true, children: ["(", iss.rule, ") "] })] }), _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: sel ? "white" : "gray", children: " " }), _jsx(Text, { color: sel ? "white" : undefined, children: iss.message })] })] }, `${iss.check}-${iss.line || i}`));
|
|
748
754
|
}))] }), _jsx(Box, { paddingX: 1, children: _jsx(Text, { dimColor: true, children: "Esc back \u00B7 \u2191\u2193 select \u00B7 Enter source \u00B7 y copy prompt \u00B7 q quit" }) })] }));
|
|
749
755
|
}
|
|
750
756
|
if (mode.view === "issue-detail") {
|
|
@@ -777,7 +783,7 @@ function MonitorApp({ cwd }) {
|
|
|
777
783
|
return (_jsxs(Text, { children: [_jsxs(Text, { color: sel ? "white" : gc(c.grade), children: [sel ? "▸" : " ", c.grade === "A" ? "●" : c.grade === "B" ? "◐" : "○", " "] }), _jsx(Text, { bold: sel, children: c.name.slice(0, 13).padEnd(13) }), _jsx(Text, { color: gc(c.grade), children: String(c.score).padStart(3) })] }, c.name));
|
|
778
784
|
})] }))] })), 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) => {
|
|
779
785
|
const sel = panel === "issues" && i === cursor;
|
|
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));
|
|
786
|
+
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) })] }, `${iss.check}-${iss.file || ""}-${iss.line || i}`));
|
|
781
787
|
}), 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" }) })] }));
|
|
782
788
|
}
|
|
783
789
|
function Header({ proj, stack, workspace, state }) {
|