Skip to content
This repository was archived by the owner on Sep 23, 2025. It is now read-only.

Commit 61e9779

Browse files
committed
Fix VSCode Comments API reply button functionality
Key fixes: - Fixed CommentingRangeProvider to return single multi-line ranges instead of multiple single-line ranges - Added package.json menu contributions for comments/commentThread/context - Removed CommentController disposal that was breaking connections - Added comprehensive logging for debugging CommentingRangeProvider calls - Handle both regular file URIs and comment:// input URIs Reply buttons now work correctly on synthetic PR comment threads. Users can create comments via + icon and reply to existing threads. Next: Add 'Make Suggestion' button and LLM roundtrip functionality.
1 parent 1abd2b9 commit 61e9779

File tree

3 files changed

+460
-50
lines changed

3 files changed

+460
-50
lines changed

extension/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242
"title": "Show File Diff",
4343
"category": "Dialectic"
4444
},
45+
{
46+
"command": "dialectic.addComment",
47+
"title": "Add Comment",
48+
"category": "Dialectic"
49+
},
4550
{
4651
"command": "dialectic.addCommentReply",
4752
"title": "Add Comment Reply",
@@ -78,6 +83,13 @@
7883
"when": "view == dialectic.syntheticPR",
7984
"group": "navigation"
8085
}
86+
],
87+
"comments/commentThread/context": [
88+
{
89+
"command": "dialectic.addComment",
90+
"group": "inline@1",
91+
"when": "commentController == dialectic-synthetic-pr"
92+
}
8193
]
8294
}
8395
},

extension/src/syntheticPRProvider.ts

Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,45 @@ export class SyntheticPRProvider implements vscode.Disposable {
8282
'Synthetic PR Comments'
8383
);
8484

85+
// Configure comment controller options
86+
this.commentController.options = {
87+
prompt: 'Add a comment...',
88+
placeHolder: 'Type your comment here'
89+
};
90+
8591
this.commentController.commentingRangeProvider = {
8692
provideCommentingRanges: (document: vscode.TextDocument) => {
93+
console.log(`[COMMENTING] provideCommentingRanges called for: ${document.uri.toString()}`);
94+
8795
// Allow commenting on any line in files that are part of the current PR
88-
if (!this.currentPR) return [];
96+
if (!this.currentPR) {
97+
console.log(`[COMMENTING] No current PR - returning empty ranges`);
98+
return [];
99+
}
89100

101+
// Handle comment input URIs (comment://) - always allow commenting
102+
if (document.uri.scheme === 'comment') {
103+
console.log(`[COMMENTING] Comment input URI - allowing full document range`);
104+
const lineCount = document.lineCount;
105+
const range = new vscode.Range(0, 0, Math.max(0, lineCount - 1), 0);
106+
return [range];
107+
}
108+
109+
// Handle regular file URIs
90110
const filePath = vscode.workspace.asRelativePath(document.uri);
91111
const isInPR = this.currentPR.files_changed.some(f => f.path === filePath);
92112

113+
console.log(`[COMMENTING] File ${filePath} in PR: ${isInPR}`);
114+
93115
if (isInPR) {
94-
// Return ranges for every line to enable commenting anywhere
95-
const ranges: vscode.Range[] = [];
96-
for (let i = 0; i < document.lineCount; i++) {
97-
ranges.push(new vscode.Range(i, 0, i, document.lineAt(i).text.length));
98-
}
99-
return ranges;
116+
// Return a single range covering the entire document for multi-line support
117+
const lineCount = document.lineCount;
118+
const range = new vscode.Range(0, 0, Math.max(0, lineCount - 1), 0);
119+
console.log(`[COMMENTING] Returning range for ${lineCount} lines: ${range.start.line}-${range.end.line}`);
120+
return [range];
100121
}
122+
123+
console.log(`[COMMENTING] File not in PR - returning empty ranges`);
101124
return [];
102125
}
103126
};
@@ -132,12 +155,17 @@ export class SyntheticPRProvider implements vscode.Disposable {
132155
(thread: vscode.CommentThread, text: string) => this.addCommentReply(thread, text)
133156
);
134157

158+
// Register add comment command (for new comments)
159+
const addCommentCommand = vscode.commands.registerCommand('dialectic.addComment',
160+
(reply: vscode.CommentReply) => this.handleCommentSubmission(reply)
161+
);
162+
135163
// Register toggle comments command
136164
const toggleCommentsCommand = vscode.commands.registerCommand('dialectic.toggleComments',
137165
() => this.treeProvider.toggleCommentsExpansion()
138166
);
139167

140-
context.subscriptions.push(this.commentController, treeView, diffCommand, commentReplyCommand, toggleCommentsCommand);
168+
context.subscriptions.push(this.commentController, treeView, diffCommand, commentReplyCommand, addCommentCommand, toggleCommentsCommand);
141169
}
142170

143171
/**
@@ -153,48 +181,6 @@ export class SyntheticPRProvider implements vscode.Disposable {
153181
this.treeProvider.updatePR(prData);
154182
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: treeProvider.updatePR completed`);
155183

156-
// Clear existing comment threads asynchronously
157-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: Starting commentController.dispose()`);
158-
await new Promise(resolve => {
159-
this.commentController.dispose();
160-
setImmediate(resolve);
161-
});
162-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: commentController.dispose() completed`);
163-
164-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: Creating new commentController`);
165-
this.commentController = vscode.comments.createCommentController(
166-
'dialectic-synthetic-pr',
167-
`PR: ${prData.title}`
168-
);
169-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: New commentController created`);
170-
171-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: Setting up commentingRangeProvider`);
172-
this.commentController.commentingRangeProvider = {
173-
provideCommentingRanges: (document: vscode.TextDocument) => {
174-
// Allow commenting on any line in files that are part of the current PR
175-
if (!this.currentPR) return [];
176-
177-
const filePath = vscode.workspace.asRelativePath(document.uri);
178-
const isInPR = this.currentPR.files_changed.some(f => f.path === filePath);
179-
180-
if (isInPR) {
181-
// Return ranges for every line to enable commenting anywhere
182-
const ranges: vscode.Range[] = [];
183-
for (let i = 0; i < document.lineCount; i++) {
184-
ranges.push(new vscode.Range(i, 0, i, document.lineAt(i).text.length));
185-
}
186-
return ranges;
187-
}
188-
return [];
189-
}
190-
};
191-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: commentingRangeProvider setup completed`);
192-
193-
// Handle comment thread creation and replies
194-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: Setting up comment handlers`);
195-
this.setupCommentHandlers();
196-
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: Comment handlers setup completed`);
197-
198184
// Create comment threads for each AI insight
199185
console.log(`[SYNTHETIC PR] ${Date.now() - startTime}ms: Creating ${prData.comment_threads.length} comment threads`);
200186
for (const thread of prData.comment_threads) {
@@ -453,6 +439,24 @@ export class SyntheticPRProvider implements vscode.Disposable {
453439
thread.comments = [...thread.comments, newComment];
454440
}
455441

442+
/**
443+
* Handle comment submission from VSCode (both new comments and replies)
444+
*/
445+
private handleCommentSubmission(reply: vscode.CommentReply): void {
446+
const newComment: vscode.Comment = {
447+
body: new vscode.MarkdownString(reply.text),
448+
mode: vscode.CommentMode.Preview,
449+
author: {
450+
name: vscode.env.uriScheme === 'vscode' ? 'User' : 'Developer'
451+
}
452+
};
453+
454+
reply.thread.comments = [...reply.thread.comments, newComment];
455+
456+
// Ensure the thread can accept more replies
457+
reply.thread.canReply = true;
458+
}
459+
456460
dispose(): void {
457461
this.commentController.dispose();
458462
this.treeProvider.clearPR();

0 commit comments

Comments
 (0)