@jonathan0823/pi-sonarqube 0.6.0 → 0.7.0
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/api.d.ts +3 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +6 -6
- package/dist/api.js.map +1 -1
- package/dist/commands.d.ts +3 -2
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +34 -2
- package/dist/commands.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -4
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui.d.ts +13 -0
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +36 -8
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/src/api.ts +24 -24
- package/src/commands.ts +64 -9
- package/src/index.ts +33 -3
- package/src/types.ts +3 -1
- package/src/ui.ts +63 -10
package/src/ui.ts
CHANGED
|
@@ -3,7 +3,13 @@ import type {
|
|
|
3
3
|
ExtensionContext,
|
|
4
4
|
ExtensionCommandContext,
|
|
5
5
|
} from "@earendil-works/pi-coding-agent";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
Input,
|
|
8
|
+
Key,
|
|
9
|
+
matchesKey,
|
|
10
|
+
truncateToWidth,
|
|
11
|
+
type Focusable,
|
|
12
|
+
} from "@earendil-works/pi-tui";
|
|
7
13
|
import { readFile } from "node:fs/promises";
|
|
8
14
|
import { resolve } from "node:path";
|
|
9
15
|
import type {
|
|
@@ -162,11 +168,7 @@ export function startAnalysisUi(
|
|
|
162
168
|
// ── Searchable browser helpers ─────────────────────────────────────────────
|
|
163
169
|
|
|
164
170
|
function normalizeSearchQuery(query: string): string[] {
|
|
165
|
-
return query
|
|
166
|
-
.trim()
|
|
167
|
-
.toLowerCase()
|
|
168
|
-
.split(/\s+/)
|
|
169
|
-
.filter(Boolean);
|
|
171
|
+
return query.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
function matchesSearchQuery(haystack: string, query: string): boolean {
|
|
@@ -187,7 +189,11 @@ function filterSearchItems<T>(
|
|
|
187
189
|
|
|
188
190
|
interface SearchableBrowserConfig<T> {
|
|
189
191
|
title: string;
|
|
190
|
-
subtitle: (
|
|
192
|
+
subtitle: (
|
|
193
|
+
query: string,
|
|
194
|
+
totalCount: number,
|
|
195
|
+
filteredCount: number,
|
|
196
|
+
) => string;
|
|
191
197
|
searchHint: string;
|
|
192
198
|
emptyMessage: string;
|
|
193
199
|
footer: string;
|
|
@@ -295,7 +301,9 @@ export class IssueBrowser extends SearchableListBrowser<SonarIssue> {
|
|
|
295
301
|
theme: Theme,
|
|
296
302
|
done: (result: number | null) => void,
|
|
297
303
|
) {
|
|
298
|
-
const filterSuffix = state.filters
|
|
304
|
+
const filterSuffix = state.filters
|
|
305
|
+
? ` • ${issueFilterLabel(state.filters)}`
|
|
306
|
+
: "";
|
|
299
307
|
super(state.issues, theme, done, {
|
|
300
308
|
title: "SonarQube Issues",
|
|
301
309
|
subtitle: (_query, totalCount, filteredCount) =>
|
|
@@ -317,7 +325,9 @@ export class IssueBrowser extends SearchableListBrowser<SonarIssue> {
|
|
|
317
325
|
const marker = isSelected
|
|
318
326
|
? theme.fg("accent", ">")
|
|
319
327
|
: theme.fg("dim", " ");
|
|
320
|
-
const location = issue.line
|
|
328
|
+
const location = issue.line
|
|
329
|
+
? `${issue.filePath}:${issue.line}`
|
|
330
|
+
: issue.filePath;
|
|
321
331
|
const rule = issue.ruleName
|
|
322
332
|
? `${issue.rule} (${issue.ruleName})`
|
|
323
333
|
: issue.rule;
|
|
@@ -442,7 +452,8 @@ export class DuplicationBrowser extends SearchableListBrowser<FileDuplication> {
|
|
|
442
452
|
title: "SonarQube Duplications",
|
|
443
453
|
subtitle: (_query, totalCount, filteredCount) =>
|
|
444
454
|
`${totalCount} file(s) with duplicate code${scopeSuffix} • ${filteredCount} match(es)`,
|
|
445
|
-
searchHint:
|
|
455
|
+
searchHint:
|
|
456
|
+
"Search duplications by file path, duplicated lines, blocks, or density",
|
|
446
457
|
emptyMessage: "No matching duplicated files found.",
|
|
447
458
|
footer: "Up/Down to move, Enter for details, Esc to close",
|
|
448
459
|
pageSize: 15,
|
|
@@ -476,6 +487,48 @@ export async function showDuplicationBrowser(
|
|
|
476
487
|
);
|
|
477
488
|
}
|
|
478
489
|
|
|
490
|
+
// ── Workspace selector browser ────────────────────────────────────────────
|
|
491
|
+
|
|
492
|
+
export class WorkspaceBrowser extends SearchableListBrowser<{
|
|
493
|
+
alias: string;
|
|
494
|
+
path: string;
|
|
495
|
+
}> {
|
|
496
|
+
constructor(
|
|
497
|
+
workspaces: { alias: string; path: string }[],
|
|
498
|
+
theme: Theme,
|
|
499
|
+
done: (result: number | null) => void,
|
|
500
|
+
) {
|
|
501
|
+
super(workspaces, theme, done, {
|
|
502
|
+
title: "SonarQube Workspaces",
|
|
503
|
+
subtitle: (_query, totalCount, filteredCount) =>
|
|
504
|
+
`${totalCount} workspace(s) • ${filteredCount} match(es)`,
|
|
505
|
+
searchHint: "Search workspaces by alias or path",
|
|
506
|
+
emptyMessage: "No matching workspaces found.",
|
|
507
|
+
footer: "Up/Down to move, Enter to select, Esc to cancel",
|
|
508
|
+
pageSize: 15,
|
|
509
|
+
searchText: (ws) => `${ws.alias} ${ws.path}`,
|
|
510
|
+
renderItem: (ws, index, isSelected) => {
|
|
511
|
+
const marker = isSelected
|
|
512
|
+
? theme.fg("accent", ">")
|
|
513
|
+
: theme.fg("dim", " ");
|
|
514
|
+
return `${marker} ${String(index + 1).padStart(2, " ")}. ${theme.fg("accent", ws.alias.padEnd(20))} ${theme.fg("dim", ws.path)}`;
|
|
515
|
+
},
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export async function showWorkspaceBrowser(
|
|
521
|
+
ctx: ExtensionContext,
|
|
522
|
+
workspaces: { alias: string; path: string }[],
|
|
523
|
+
): Promise<string | null> {
|
|
524
|
+
if (ctx.mode !== "tui" || workspaces.length === 0) return null;
|
|
525
|
+
const choice = await ctx.ui.custom<number | null>(
|
|
526
|
+
(_tui, theme, _kb, done) => new WorkspaceBrowser(workspaces, theme, done),
|
|
527
|
+
);
|
|
528
|
+
if (choice == null) return null;
|
|
529
|
+
return workspaces[choice].alias;
|
|
530
|
+
}
|
|
531
|
+
|
|
479
532
|
// ── Issue browser / preview helpers (used by index.ts) ──────────────────────
|
|
480
533
|
|
|
481
534
|
export async function showIssueBrowser(
|