feat(ux): unify Ask-Claude-to-Edit on a split-below multi-line webview
Operator feedback iteration on the Ask-Claude input. Replaces the inline comment-thread box (and the top-center QuickInput before it) with ONE input for both scopes: a multi-line webview in a split pane below the document. - New `editInstructionInput.ts` (`promptEditInstruction`): a tall, resizable textarea + Send, opened via `newGroupBelow` so it sits under the document, not over it. Auto-focused; ⌘↵/Ctrl↵ sends; Esc cancels. Cancel/Esc confirms ONLY when there's text to lose (a webview can read its own textarea); closing the tab is an explicit dismiss. On submit/cancel the split collapses AND focus is handed back to the document, so the bottom panel (Output/Debug Console) no longer pops. - Selection edits use the same box; the document above keeps the selection highlighted (inactive-selection style) so the user sees what Claude will edit — the selection is captured before the prompt, never touched. - Removes the whole inline-comment mechanism: deletes `inlineAsk.ts` (InlineAskController), the `cowriting.askClaude.submit`/`.cancel` commands, their comment-thread menus, and the Escape keybinding — net deletion. One overridable seam `TrackChangesPreviewController.askEditInstruction` (used by editSelection and the preview), stubbed by the host E2E. Sealed webview (INV-8/35): collects text only, no SDK/secret surface, no network. 242 unit + typecheck (src + e2e) + build green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -76,9 +76,9 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => {
|
||||
await vscode.window.showTextDocument(a.doc);
|
||||
await settle();
|
||||
|
||||
// Stub the instruction prompt (sealed input box can't run in CI) + the LLM turn.
|
||||
const origPrompt = api.inlineAsk.prompt;
|
||||
(api.inlineAsk as any).prompt = async () => "rewrite it";
|
||||
// Stub the document instruction prompt (the webview can't run in CI) + the LLM turn.
|
||||
const origPrompt = ctl.askEditInstruction;
|
||||
ctl.askEditInstruction = async () => "rewrite it";
|
||||
ctl.setEditTurnForTest(async () => ({
|
||||
replacement: "# Tab\n\nThe REWRITTEN tab paragraph.\n",
|
||||
model: "sonnet",
|
||||
@@ -88,7 +88,7 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => {
|
||||
await vscode.commands.executeCommand("cowriting.editDocument", b.doc.uri);
|
||||
await settle();
|
||||
} finally {
|
||||
(api.inlineAsk as any).prompt = origPrompt;
|
||||
ctl.askEditInstruction = origPrompt;
|
||||
}
|
||||
|
||||
// The proposal(s) landed on the TAB doc (B), and the ACTIVE doc (A) has none.
|
||||
@@ -110,8 +110,8 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => {
|
||||
await vscode.window.showTextDocument(a.doc);
|
||||
await settle();
|
||||
|
||||
const origPrompt = api.inlineAsk.prompt;
|
||||
(api.inlineAsk as any).prompt = async () => "rewrite it";
|
||||
const origPrompt = ctl.askEditInstruction;
|
||||
ctl.askEditInstruction = async () => "rewrite it";
|
||||
ctl.setEditTurnForTest(async () => ({
|
||||
replacement: "# No arg\n\nThe REWRITTEN active doc paragraph.\n",
|
||||
model: "sonnet",
|
||||
@@ -121,7 +121,7 @@ suite("F12 SLICE-1 — Ask-Claude reach (#42, INV-38)", () => {
|
||||
await vscode.commands.executeCommand("cowriting.editDocument");
|
||||
await settle();
|
||||
} finally {
|
||||
(api.inlineAsk as any).prompt = origPrompt;
|
||||
ctl.askEditInstruction = origPrompt;
|
||||
}
|
||||
assert.ok(api.proposalController.listProposals(a.doc).length >= 1, "active doc received the proposal(s) on no-arg");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user