Skip to content

Commit 0a77bf1

Browse files
jvdprngclaude
andauthored
feat: add Code Quality finding type with comment-on-issue workflow (#159)
* feat: add Code Quality finding type with comment-on-issue workflow Code Quality is a new value in the FindingType enum. When a finding has type "Code Quality", the details panel hides severity, difficulty, exploit scenario, and recommendation fields. The "Open Remote Issue" flow posts a comment on a single designated GitHub issue instead of creating a new issue per finding. The CQ issue number is stored per-workspace-root, shared across sibling roots with the same audit repo, and editable from both the command palette and the Repository Configuration panel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: fix biome formatting in codeMarker and messageHandlers test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address Code Quality PR review feedback - Add title and ignoreFocusOut to CQ QuickPick menus for consistency - Add "Open Settings" button to CQ confirmation dialog - Move CodeQuality from FindingType to FindingSeverity so selecting it in the first dropdown naturally hides subsequent fields Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: improve Code Quality UX — reorder dropdown and clarify settings prompt Move Code Quality before Informational in the severity dropdown and add explanatory text to the confirmation dialog so users understand why the Settings button is there. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: prevent double prompt in Code Quality issue setup and add GitLab support The "Create a new issue" path fell through into the "Enter existing issue number" input, causing two consecutive prompts. Wrapping the second path in an `else` clause fixes this. Also adds GitLab issue URL support (using /-/issues/ path format) alongside the existing GitHub URL handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b3e277e commit 0a77bf1

15 files changed

Lines changed: 565 additions & 27 deletions

esbuild.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ const watchPlugin = {
7979
console.log("build complete");
8080
}
8181
} catch (err) {
82-
process.stderr.write(err.stderr);
82+
if (err.stderr) {
83+
process.stderr.write(err.stderr);
84+
} else {
85+
console.error(err);
86+
}
8387
process.exit(1);
8488
}
8589
})();

package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@
272272
{
273273
"command": "weAudit.boundaryMoveDown",
274274
"title": "weAudit: Move Finding Down"
275+
},
276+
{
277+
"command": "weAudit.editCodeQualityIssueNumber",
278+
"title": "weAudit: Set Code Quality Issue Number"
275279
}
276280
],
277281
"keybindings": [
@@ -601,6 +605,11 @@
601605
"type": "boolean",
602606
"default": false,
603607
"description": "Sort findings and notes alphabetically by name in the tree view."
608+
},
609+
"weAudit.general.skipCodeQualityConfirmation": {
610+
"type": "boolean",
611+
"default": false,
612+
"description": "Skip the confirmation dialog when opening a Code Quality comment. The comment will be copied to clipboard and the issue opened immediately."
604613
}
605614
}
606615
},

src/codeMarker.ts

Lines changed: 306 additions & 21 deletions
Large diffs are not rendered by default.

src/panels/findingDetails.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<span class="detailSpan">Severity:</span>
99
<vscode-dropdown position="below" id="severity-dropdown">
1010
<vscode-option></vscode-option>
11+
<vscode-option>Code Quality</vscode-option>
1112
<vscode-option>Informational</vscode-option>
1213
<vscode-option>Undetermined</vscode-option>
1314
<vscode-option>Low</vscode-option>

src/panels/gitConfig.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@
1616
<span class="detailSpan">Commit Hash:</span>
1717
<vscode-text-field id="commit-hash"></vscode-text-field>
1818
</div>
19+
20+
<div class="detailsDiv">
21+
<span class="detailSpan">Code Quality Issue #:</span>
22+
<vscode-text-field id="cq-issue-number" placeholder="e.g. 42"></vscode-text-field>
23+
</div>
1924
</div>

src/panels/gitConfigPanel.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ class GitConfigProvider implements vscode.WebviewViewProvider {
2626

2727
vscode.commands.registerCommand(
2828
"weAudit.setGitConfigView",
29-
(rootPathAndLabel: RootPathAndLabel, clientRepo: string, auditRepo: string, commitHash: string) => {
29+
(rootPathAndLabel: RootPathAndLabel, clientRepo: string, auditRepo: string, commitHash: string, cqIssueNumber?: string) => {
3030
this.currentRootPathAndLabel = rootPathAndLabel;
3131
const msg: UpdateRepositoryMessage = {
3232
command: "update-repository-config",
3333
rootLabel: rootPathAndLabel.rootLabel,
3434
clientURL: clientRepo,
3535
auditURL: auditRepo,
3636
commitHash,
37+
cqIssueNumber: cqIssueNumber ?? "",
3738
};
3839
this._view?.webview.postMessage(msg);
3940
},
@@ -142,7 +143,14 @@ class GitConfigProvider implements vscode.WebviewViewProvider {
142143
);
143144
return;
144145
}
145-
vscode.commands.executeCommand("weAudit.updateGitConfig", rootPath, message.clientURL, message.auditURL, message.commitHash);
146+
vscode.commands.executeCommand(
147+
"weAudit.updateGitConfig",
148+
rootPath,
149+
message.clientURL,
150+
message.auditURL,
151+
message.commitHash,
152+
message.cqIssueNumber,
153+
);
146154
return;
147155
case "choose-workspace-root":
148156
rootPath = this.dirToPathMap.get(message.rootLabel);

src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export enum FindingSeverity {
3131
Low = "Low",
3232
Medium = "Medium",
3333
High = "High",
34+
CodeQuality = "Code Quality",
3435
Undefined = "",
3536
}
3637

@@ -89,6 +90,8 @@ export interface SerializedData {
8990
// older versions do not have partiallyAuditedFiles
9091
partiallyAuditedFiles?: PartiallyAuditedFile[];
9192
resolvedEntries: Entry[];
93+
// optional code quality issue number for the workspace root
94+
codeQualityIssueNumber?: number;
9295
}
9396

9497
/**
@@ -104,6 +107,8 @@ export interface FullSerializedData {
104107
// older versions do not have partiallyAuditedFiles
105108
partiallyAuditedFiles?: PartiallyAuditedFile[];
106109
resolvedEntries: FullEntry[];
110+
// optional code quality issue number for the workspace root
111+
codeQualityIssueNumber?: number;
107112
}
108113

109114
/**

src/webview/findingDetailsMain.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ function main(): void {
2525
titleField?.addEventListener("change", handlePersistentFieldChange);
2626

2727
const severityDropdown = document.getElementById("severity-dropdown") as Dropdown;
28-
severityDropdown?.addEventListener("change", handlePersistentFieldChange);
28+
severityDropdown?.addEventListener("change", (e: Event) => {
29+
handlePersistentFieldChange(e);
30+
updateFieldVisibility(severityDropdown.value);
31+
});
2932

3033
const difficultyDropdown = document.getElementById("difficulty-dropdown") as Dropdown;
3134
difficultyDropdown?.addEventListener("change", handlePersistentFieldChange);
@@ -71,6 +74,7 @@ function main(): void {
7174
descriptionArea.value = message.description;
7275
exploitArea.value = message.exploit;
7376
recommendationArea.value = message.recommendation;
77+
updateFieldVisibility(message.severity as string);
7478
break;
7579

7680
case "hide-finding-details":
@@ -101,3 +105,21 @@ function handleFieldChange(e: Event, isPersistent: boolean): void {
101105
};
102106
vscode.postMessage(message);
103107
}
108+
109+
const CODE_QUALITY_SEVERITY = "Code Quality";
110+
111+
/**
112+
* Shows or hides detail fields based on whether the finding severity is "Code Quality".
113+
* Code Quality findings only show title, severity, and description.
114+
*/
115+
function updateFieldVisibility(severity: string): void {
116+
const isCodeQuality = severity === CODE_QUALITY_SEVERITY;
117+
const hiddenIds = ["difficulty-dropdown", "type-dropdown", "exploit-area", "recommendation-area"];
118+
for (const id of hiddenIds) {
119+
const element = document.getElementById(id);
120+
const parentDiv = element?.parentElement;
121+
if (parentDiv) {
122+
parentDiv.style.display = isCodeQuality ? "none" : "";
123+
}
124+
}
125+
}

src/webview/gitConfigMain.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ function main(): void {
2828
const commitHash = document.getElementById("commit-hash") as TextField;
2929
commitHash?.addEventListener("change", handleFieldChange);
3030

31+
const cqIssueNumber = document.getElementById("cq-issue-number") as TextField;
32+
cqIssueNumber?.addEventListener("change", handleFieldChange);
33+
3134
// handle the message inside the webview
3235
window.addEventListener("message", (event) => {
3336
const message = event.data;
@@ -39,6 +42,7 @@ function main(): void {
3942
clientURL.value = message.clientURL;
4043
auditURL.value = message.auditURL;
4144
commitHash.value = message.commitHash;
45+
cqIssueNumber.value = message.cqIssueNumber ?? "";
4246
break;
4347

4448
case "set-workspace-roots":
@@ -67,6 +71,7 @@ function handleFieldChange(_e: Event): void {
6771
const clientURL = document.getElementById("client-url") as TextField;
6872
const auditURL = document.getElementById("audit-url") as TextField;
6973
const commitHash = document.getElementById("commit-hash") as TextField;
74+
const cqIssueNumber = document.getElementById("cq-issue-number") as TextField;
7075
const rootDropdown = document.getElementById("workspace-root-list-dropdown") as Dropdown;
7176

7277
const message: UpdateRepositoryMessage = {
@@ -75,6 +80,7 @@ function handleFieldChange(_e: Event): void {
7580
clientURL: clientURL.value,
7681
auditURL: auditURL.value,
7782
commitHash: commitHash.value,
83+
cqIssueNumber: cqIssueNumber.value,
7884
};
7985
vscode.postMessage(message);
8086
}

src/webview/webviewMessageTypes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface UpdateRepositoryMessage {
1313
clientURL: string;
1414
auditURL: string;
1515
commitHash: string;
16+
cqIssueNumber: string;
1617
}
1718

1819
export interface ChooseWorkspaceRootMessage {

0 commit comments

Comments
 (0)