feat!: sunset the review-panel webview — built-in preview + native diff are the review surfaces (D3/D17, spec §6.10); Keep/Reject lens copy (PUC-2)
Deletes the last bespoke UI surface (TrackChangesPreviewController + its sealed webview client assets); every entry point re-points at native VS Code chrome per spec §5: the #41 right-click entries become cowriting.openReviewPreview (enter coediting if needed -> "Open Preview to the Side"), Ctrl+Alt+R/Cmd+Alt+R moves to cowriting.reviewChanges (native diff), and the F12 CodeLens per-proposal titles read "Keep"/"Reject" with a top-of-file "Keep all (N)"/"Reject all" pair once >=2 proposals are pending. EditFlow drops its own askClaude/askEditInstruction (the webview's only caller) and its now-unused constructor params. Coverage that lived only in the webview's test seams (renderHtmlFor, receiveMessage, isOpen, ...) moves to direct calls against the surviving controllers/pure renderReview (test/e2e/suite/helpers.ts gains a shared renderHtmlFor probe); a genuine gap (pending-proposal + unchanged-block rendering) is backfilled in test/previewAnnotations.test.ts. README's "how it works" is rewritten as the native-surface map; the superseded F6/F7/F9/ F10/F11 sections are kept as a marked historical record rather than deleted outright. 292 unit + 91 E2E green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+43
-34
@@ -11,7 +11,6 @@ import { GlobalSidecarStore } from "./globalSidecarStore";
|
||||
import { SidecarRouter } from "./sidecarRouter";
|
||||
import { DiffViewController } from "./diffViewController";
|
||||
import { GitBaselineAdapter } from "./gitBaseline";
|
||||
import { TrackChangesPreviewController } from "./trackChangesPreview";
|
||||
import { EditFlow } from "./editFlow";
|
||||
import { LiveProgressUi } from "./liveProgressUi";
|
||||
import { EditorProposalController } from "./editorProposalController";
|
||||
@@ -29,7 +28,6 @@ export interface CowritingApi {
|
||||
proposalController: ProposalController;
|
||||
versionGuard: VersionGuard;
|
||||
diffViewController: DiffViewController;
|
||||
trackChangesPreviewController: TrackChangesPreviewController;
|
||||
editFlow: EditFlow;
|
||||
sidecarRouter: SidecarRouter;
|
||||
liveProgressUi: LiveProgressUi;
|
||||
@@ -160,8 +158,7 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
const attributionController = new AttributionController(sidecarRouter, root, versionGuard, coeditingRegistry);
|
||||
context.subscriptions.push(attributionController);
|
||||
|
||||
// --- F4: propose/accept (Feature #12) — constructed before the preview so F10
|
||||
// can route ✓/✗ through it ---
|
||||
// --- F4: propose/accept (Feature #12) ---
|
||||
const proposalController = new ProposalController(
|
||||
sidecarRouter,
|
||||
attributionController,
|
||||
@@ -174,10 +171,10 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
// --- F11/F12 (native-surfaces migration, spec §6.10): the edit flow — the
|
||||
// `cowriting.editDocument` command, the instruction-prompt/progress-wrapped
|
||||
// "ask Claude" gesture (INV-10 gate), and the turn→proposal(s) cut
|
||||
// (`runEditAndPropose`, INV-39/40). Constructed BEFORE the review preview (which
|
||||
// delegates to it) and BEFORE the thread controller, which now consumes it too
|
||||
// (Task 6: the comment-loop's "make this edit" offer calls runEditAndPropose). ---
|
||||
const editFlow = new EditFlow(proposalController, attributionController, liveProgressUi, coeditingRegistry);
|
||||
// (`runEditAndPropose`, INV-39/40). Constructed BEFORE the thread controller,
|
||||
// which consumes it too (Task 6: the comment-loop's "make this edit" offer
|
||||
// calls runEditAndPropose). ---
|
||||
const editFlow = new EditFlow(proposalController);
|
||||
context.subscriptions.push(editFlow);
|
||||
|
||||
// --- F2/F10 (Task 6, D19/D10/D8): comments-first ask + the comment→reply→
|
||||
@@ -186,20 +183,6 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
const threadController = new ThreadController(sidecarRouter, root, versionGuard, coeditingRegistry, editFlow, liveProgressUi);
|
||||
context.subscriptions.push(threadController);
|
||||
|
||||
// --- F7/F10: the review preview is the single interactive review surface ---
|
||||
// Workspace-INDEPENDENT (works on any markdown doc, reuses the F6 baseline,
|
||||
// INV-20). Constructed AFTER attribution (reads F3 spans), proposals (routes
|
||||
// F4 accept/reject from the webview ✓/✗), and editFlow (delegates the webview's
|
||||
// askClaude toolbar intent to it).
|
||||
const trackChangesPreviewController = new TrackChangesPreviewController(
|
||||
diffViewController,
|
||||
context.extensionUri,
|
||||
attributionController,
|
||||
proposalController,
|
||||
editFlow,
|
||||
);
|
||||
context.subscriptions.push(trackChangesPreviewController);
|
||||
|
||||
// --- F12 (#64): the editor surface — optimistic-apply proposals into the buffer,
|
||||
// decorate the diff, and provide Accept ▾/Reject ▾ CodeLens (INV-48/49/52/53). ---
|
||||
const editorProposalController = new EditorProposalController(
|
||||
@@ -211,10 +194,10 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
context.subscriptions.push(editorProposalController);
|
||||
|
||||
// #46 (INV-42): accept every pending proposal on the active doc in one gesture
|
||||
// (also reachable from the preview toolbar's "Accept all" button, which routes
|
||||
// through its own webview-facing acceptAll). Reuses the batched F4 seam +
|
||||
// reports applied-vs-skipped (native-surfaces migration: routes directly to
|
||||
// ProposalController, no preview-controller indirection).
|
||||
// (also reachable from the top-of-file "Keep all (N)" CodeLens, Task 8 PUC-2).
|
||||
// Reuses the batched F4 seam + reports applied-vs-skipped, routing directly to
|
||||
// ProposalController (native-surfaces migration: no preview-controller
|
||||
// indirection).
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("cowriting.acceptAllProposals", async () => {
|
||||
const doc = vscode.window.activeTextEditor?.document;
|
||||
@@ -223,7 +206,6 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
return;
|
||||
}
|
||||
const { applied, skipped } = await proposalController.acceptAllProposals(doc);
|
||||
trackChangesPreviewController.refresh(doc);
|
||||
if (applied === 0 && skipped === 0) return;
|
||||
const skipNote = skipped > 0 ? `, ${skipped} skipped (target text changed — undo or reject)` : "";
|
||||
void vscode.window.showInformationMessage(
|
||||
@@ -242,7 +224,6 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
return;
|
||||
}
|
||||
const { reverted } = await proposalController.rejectAll(doc);
|
||||
trackChangesPreviewController.refresh(doc);
|
||||
if (reverted > 0) {
|
||||
void vscode.window.showInformationMessage(
|
||||
`Cowriting: rejected ${reverted} proposal${reverted === 1 ? "" : "s"}.`,
|
||||
@@ -333,11 +314,13 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
);
|
||||
|
||||
// Code-review fix (Finding 1, session native-surfaces-exec): `cowriting.editDocument`
|
||||
// used to delegate to `EditFlow.askClaude(doc, {kind:"document"})`, which prompts via
|
||||
// `askEditInstruction` — a rejecting stub since Task 6 sunset the input webview
|
||||
// (spec §6.10). Reached with no selection (the common case for `cowriting.edit`),
|
||||
// that was a SILENT dead end: the reject fired before EditFlow.askClaude's own try/
|
||||
// catch and was `void`'d, so no toast, no thread, nothing. This command now resolves
|
||||
// used to delegate to `EditFlow.askClaude(doc, {kind:"document"})`, which prompted via
|
||||
// `askEditInstruction` — a rejecting stub after Task 6 sunset the input webview
|
||||
// (spec §6.10; both `askClaude`/`askEditInstruction` were deleted from EditFlow in
|
||||
// Task 8 once their only caller, the review webview, died too). Reached with no
|
||||
// selection (the common case for `cowriting.edit`), that was a SILENT dead end: the
|
||||
// reject fired before EditFlow.askClaude's own try/catch and was `void`'d, so no
|
||||
// toast, no thread, nothing. This command now resolves
|
||||
// its target document exactly as before (a tab's clicked URI, falling back to the
|
||||
// active editor), focuses it, and hands off to the SAME comments-first ask as
|
||||
// `cowriting.editSelection` — `ThreadController.askClaude()` top-anchors a
|
||||
@@ -386,6 +369,33 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
}),
|
||||
);
|
||||
|
||||
// Task 8 (native-surfaces migration, spec §6.10): the minimal gateway replacing
|
||||
// the sunset review-webview's #41 right-click entries. Resolves the clicked
|
||||
// doc (or falls back to the active editor, mirroring editDocument/#41), enters
|
||||
// coediting if not already (so a fresh doc gets a baseline to review against —
|
||||
// no-op if already entered or not authorable), then hands off to VS Code's
|
||||
// OWN "Open Preview to the Side" — the built-in preview IS the review surface
|
||||
// now (Task 7's annotations render inside it).
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("cowriting.openReviewPreview", async (uri?: vscode.Uri) => {
|
||||
const doc = uri
|
||||
? vscode.workspace.textDocuments.find((d) => d.uri.toString() === uri.toString()) ??
|
||||
(await vscode.workspace.openTextDocument(uri))
|
||||
: vscode.window.activeTextEditor?.document;
|
||||
if (!doc || doc.languageId !== "markdown") {
|
||||
void vscode.window.showWarningMessage("Cowriting: open a Markdown document to review it.");
|
||||
return;
|
||||
}
|
||||
if (vscode.window.activeTextEditor?.document.uri.toString() !== doc.uri.toString()) {
|
||||
await vscode.window.showTextDocument(doc);
|
||||
}
|
||||
if (!coeditingRegistry.isCoediting(doc.uri) && isAuthorable(doc.uri.scheme)) {
|
||||
await vscode.commands.executeCommand("cowriting.coeditDocument");
|
||||
}
|
||||
await vscode.commands.executeCommand("markdown.showPreviewToSide", doc.uri);
|
||||
}),
|
||||
);
|
||||
|
||||
// Render threads + attributions for already-open editors, and on future opens.
|
||||
// INV-10: gated on the registry too — belt-and-suspenders with the per-controller
|
||||
// gates (renderAll/loadAll already early-return), but keeps the intent explicit
|
||||
@@ -456,7 +466,6 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
proposalController,
|
||||
versionGuard,
|
||||
diffViewController,
|
||||
trackChangesPreviewController,
|
||||
editFlow,
|
||||
sidecarRouter,
|
||||
liveProgressUi,
|
||||
|
||||
Reference in New Issue
Block a user