fix: route document asks to comment-first askClaude (plan T6 Step 4); machine-author guard + offer cleanup

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-07-02 09:04:32 -07:00
parent 75f4a3cc20
commit c9975ba9e6
5 changed files with 177 additions and 70 deletions
+43
View File
@@ -44,4 +44,47 @@ suite("comment → reply → offer → proposal (PUC-8, D10/D19)", () => {
const id = await api.threadController.createThreadOnSelection("hello");
assert.strictEqual(id, undefined); // gate refuses thread creation entirely
});
// Finding 1 (code review, session native-surfaces-exec): `cowriting.edit` with NO
// selection used to route through `cowriting.editDocument` → the removed
// `askEditInstruction` webview prompt — a rejecting stub `void`'d before any
// try/catch, i.e. a completely silent dead end (no toast, no thread). It must now
// reach ThreadController.askClaude()'s top-anchored whole-document path (D19) —
// the same comments-first ask the selection route already used. There is no API to
// drive VS Code's native comment-widget submission from a host E2E test (the actual
// comment→reply→offer→proposal round trip is exercised above via the
// createThreadOnSelection seam), so this asserts the routing itself: the gesture
// reaches ThreadController.askClaude (never the old broken stub) and does not throw.
test("cowriting.edit with no selection on a coedited doc reaches the top-anchored ask path, not a silent dead end", async () => {
const api = await activateApi();
const doc = await vscode.workspace.openTextDocument({
language: "markdown",
content: "# T\n\nA document-level ask with no selection.\n",
});
const ed = await vscode.window.showTextDocument(doc);
await vscode.commands.executeCommand("cowriting.coeditDocument");
// Defensive stubs, mirroring the suite's other test — no real turn should fire
// from this gesture alone (no comment text is ever submitted), but guard against
// a real @cline/sdk call if the routing regresses.
api.threadController.setTurnRunnerForTest(async () => ({ replacement: "stub", model: "stub", sessionId: "s1" }));
api.editFlow.setEditTurnForTest(async () => ({ replacement: "stub", model: "stub", sessionId: "s1" }));
ed.selection = new vscode.Selection(0, 0, 0, 0); // no selection
let askClaudeCalls = 0;
const origAskClaude = api.threadController.askClaude.bind(api.threadController);
api.threadController.askClaude = async () => {
askClaudeCalls++;
return origAskClaude();
};
try {
await vscode.commands.executeCommand("cowriting.edit");
} finally {
api.threadController.askClaude = origAskClaude;
}
assert.strictEqual(
askClaudeCalls,
1,
"cowriting.edit (no selection) reached ThreadController.askClaude — not the removed editDocument prompt stub",
);
});
});