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

Commit 0a47ece

Browse files
committed
Complete tree view button implementation - eliminate QuickPick
**No More Interrupting QuickPick! 🎉** **Implementation:** - Registered 'dialectic.reviewAction' command for tree view buttons - Added promise-based feedback collection that waits for button clicks - Added handleReviewAction() method to process button clicks - Replaced QuickPick modal with persistent tree view actions **Flow:** 1. Review created → Shows info message with 'Show Tree View' button 2. User clicks tree view action button → Triggers command with action type 3. Command calls handleReviewAction() → Resolves pending promise 4. Feedback flows back to LLM as before **Benefits:** - **No workflow interruption** - No modal blocking the interface - **Persistent actions** - Buttons always visible in tree view - **Better discoverability** - Actions integrated into review context - **Cleaner UX** - User stays in review interface throughout **Result:** Users can review code and take actions without any disruptive modals!
1 parent 307a8e9 commit 0a47ece

File tree

1 file changed

+68
-57
lines changed

1 file changed

+68
-57
lines changed

extension/src/extension.ts

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ class DaemonClient implements vscode.Disposable {
147147
// Terminal registry: track active shell PIDs with MCP servers
148148
private activeTerminals: Set<number> = new Set();
149149

150+
// Review feedback handling
151+
private pendingFeedbackResolvers: Map<string, (feedback: UserFeedback) => void> = new Map();
152+
private currentReviewId?: string;
153+
150154
constructor(
151155
private context: vscode.ExtensionContext,
152156
private reviewProvider: ReviewWebviewProvider,
@@ -472,80 +476,82 @@ class DaemonClient implements vscode.Disposable {
472476
}
473477

474478
/**
475-
* Collect user feedback for a review
476-
* This method blocks until the user provides feedback via UI
479+
* Handle review action from tree view button click
477480
*/
478-
private async collectUserFeedback(reviewId: string): Promise<UserFeedback> {
479-
// Show quick pick for user action
480-
const action = await vscode.window.showQuickPick([
481-
{
482-
label: '💬 Add Comment',
483-
description: 'Leave a comment on the review',
484-
action: 'comment'
485-
},
486-
{
487-
label: '✅ Request Changes',
488-
description: 'Ask the agent to make changes',
489-
action: 'request_changes'
490-
},
491-
{
492-
label: '📝 Checkpoint Work',
493-
description: 'Ask the agent to commit and document progress',
494-
action: 'checkpoint'
495-
},
496-
{
497-
label: '↩️ Return to Agent',
498-
description: 'Return control without specific request',
499-
action: 'return'
500-
}
501-
], {
502-
placeHolder: 'What would you like to do with this review?',
503-
ignoreFocusOut: true
504-
});
481+
public handleReviewAction(action: string): void {
482+
const reviewId = this.currentReviewId;
483+
if (!reviewId) {
484+
vscode.window.showErrorMessage('No active review found');
485+
return;
486+
}
505487

506-
if (!action) {
507-
// User cancelled - return default feedback
508-
return {
509-
feedback_type: 'complete_review',
510-
review_id: reviewId,
511-
completion_action: 'return'
512-
};
488+
const resolver = this.pendingFeedbackResolvers.get(reviewId);
489+
if (!resolver) {
490+
vscode.window.showErrorMessage('No pending feedback request found');
491+
return;
513492
}
514493

515-
if (action.action === 'comment') {
516-
// Collect comment from user
494+
this.handleSpecificAction(action, reviewId, resolver);
495+
}
496+
497+
private async handleSpecificAction(action: string, reviewId: string, resolver: (feedback: UserFeedback) => void): Promise<void> {
498+
if (action === 'comment') {
517499
const commentText = await vscode.window.showInputBox({
518500
prompt: 'Enter your comment',
519501
placeHolder: 'Type your comment here...',
520502
ignoreFocusOut: true
521503
});
522504

523-
return {
505+
resolver({
524506
feedback_type: 'comment',
525507
review_id: reviewId,
526508
comment_text: commentText || '',
527-
file_path: 'review', // TODO: Get actual file if commenting on specific file
528-
line_number: 1 // TODO: Get actual line number
529-
};
530-
} else {
531-
// Completion action
532-
let additionalNotes: string | undefined;
533-
534-
if (action.action === 'request_changes' || action.action === 'checkpoint') {
535-
additionalNotes = await vscode.window.showInputBox({
536-
prompt: 'Any additional notes? (optional)',
537-
placeHolder: 'Additional instructions or context...',
538-
ignoreFocusOut: true
539-
});
540-
}
509+
file_path: 'review',
510+
line_number: 1
511+
});
512+
} else if (action === 'request_changes' || action === 'checkpoint') {
513+
const additionalNotes = await vscode.window.showInputBox({
514+
prompt: 'Any additional notes? (optional)',
515+
placeHolder: 'Additional instructions or context...',
516+
ignoreFocusOut: true
517+
});
541518

542-
return {
519+
resolver({
543520
feedback_type: 'complete_review',
544521
review_id: reviewId,
545-
completion_action: action.action as 'request_changes' | 'checkpoint' | 'return',
522+
completion_action: action as 'request_changes' | 'checkpoint',
546523
additional_notes: additionalNotes
547-
};
524+
});
525+
} else {
526+
resolver({
527+
feedback_type: 'complete_review',
528+
review_id: reviewId,
529+
completion_action: 'return'
530+
});
548531
}
532+
533+
this.pendingFeedbackResolvers.delete(reviewId);
534+
}
535+
536+
/**
537+
* Collect user feedback for a review
538+
* This method blocks until the user provides feedback via tree view buttons
539+
*/
540+
private async collectUserFeedback(reviewId: string): Promise<UserFeedback> {
541+
this.currentReviewId = reviewId;
542+
543+
return new Promise<UserFeedback>((resolve) => {
544+
this.pendingFeedbackResolvers.set(reviewId, resolve);
545+
546+
vscode.window.showInformationMessage(
547+
'Review ready! Use the action buttons in the Dialectic tree view to provide feedback.',
548+
'Show Tree View'
549+
).then((selection) => {
550+
if (selection === 'Show Tree View') {
551+
vscode.commands.executeCommand('dialectic.showReview');
552+
}
553+
});
554+
});
549555
}
550556

551557
private sendResponse(messageId: string, response: ResponsePayload): void {
@@ -775,6 +781,11 @@ export function activate(context: vscode.ExtensionContext) {
775781
reviewProvider.showReview();
776782
});
777783

784+
// Register review action command for tree view buttons
785+
const reviewActionCommand = vscode.commands.registerCommand('dialectic.reviewAction', (action: string) => {
786+
daemonClient.handleReviewAction(action);
787+
});
788+
778789
// 💡: Copy review command is now handled via webview postMessage
779790
const copyReviewCommand = vscode.commands.registerCommand('dialectic.copyReview', () => {
780791
vscode.window.showInformationMessage('Use the Copy Review button in the review panel');
@@ -787,7 +798,7 @@ export function activate(context: vscode.ExtensionContext) {
787798
vscode.window.showInformationMessage('PID information logged to Dialectic output channel');
788799
});
789800

790-
context.subscriptions.push(showReviewCommand, copyReviewCommand, logPIDsCommand, reviewProvider, syntheticPRProvider, daemonClient);
801+
context.subscriptions.push(showReviewCommand, reviewActionCommand, copyReviewCommand, logPIDsCommand, reviewProvider, syntheticPRProvider, daemonClient);
791802

792803
// Return API for Ask Socratic Shell integration
793804
return {

0 commit comments

Comments
 (0)