feat: baseline router — git HEAD + snapshot per INV-7/D13/D14; retire machine-landing advance (spec §6.4)
Task 2 of the native-surfaces migration plan. GitBaselineAdapter resolves a
document's HEAD blob via the built-in vscode.git extension (hardened with a
.git/logs/HEAD watch that nudges repo.status(), since the git extension's own
watcher doesn't reliably notice out-of-band commits on non-workspace-folder
repos in the E2E host). DiffViewController is reworked into a baseline router:
head mode (git-tracked, never persisted, re-read on commit) vs snapshot mode
(captured on CoeditingRegistry entry, re-pinned by "Mark Changes as Reviewed"
— renamed from cowriting.pinDiffBaseline, D14). The shipped machine-landing
baseline advance (#48/INV-18) is retired: a landed Claude edit now stays a
visible change-since-baseline until commit or review (INV-7/D21). Legacy
on-disk reasons ("opened"/"machine-landing") migrate to "entered" via
BaselineStore.normalizeReason on load.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,7 +15,9 @@ async function getApi(): Promise<CowritingApi> {
|
||||
return api;
|
||||
}
|
||||
|
||||
/** Create + open a fresh markdown doc under WS, returning the doc + its uri key. */
|
||||
/** Create + open a fresh markdown doc under WS, returning the doc + its uri key.
|
||||
* Also enters coediting (INV-10/Task 2): the baseline is established only on
|
||||
* entry, not merely on open. */
|
||||
async function freshDoc(rel: string, body: string): Promise<{ doc: vscode.TextDocument; key: string }> {
|
||||
const abs = path.join(WS, rel);
|
||||
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
||||
@@ -23,6 +25,7 @@ async function freshDoc(rel: string, body: string): Promise<{ doc: vscode.TextDo
|
||||
const uri = vscode.Uri.file(abs);
|
||||
const doc = await vscode.workspace.openTextDocument(uri);
|
||||
await vscode.window.showTextDocument(doc);
|
||||
await vscode.commands.executeCommand("cowriting.coeditDocument");
|
||||
await settle();
|
||||
return { doc, key: uri.toString() };
|
||||
}
|
||||
@@ -114,7 +117,7 @@ suite("F10 interactive review (host E2E — preview is the single review surface
|
||||
assert.ok(doc.getText().includes("A FIRST claude REPLACEMENT sentence."), "F12 optimistic-apply: replacement in buffer");
|
||||
});
|
||||
|
||||
test("accept → the proposal lands, clears from the preview, and the baseline advances (PUC-4)", async () => {
|
||||
test("accept → the proposal lands, clears from the preview, and stays a visible change-since-baseline (PUC-4, INV-7/D21)", async () => {
|
||||
const { doc, key } = await reopen(DOC_REL);
|
||||
const api = await getApi();
|
||||
const id = api.proposalController.listProposals(doc).find((v) => v.replaced === T1)!.id;
|
||||
@@ -126,10 +129,12 @@ suite("F10 interactive review (host E2E — preview is the single review surface
|
||||
assert.ok(!api.proposalController.listProposals(doc).some((v) => v.id === id), "proposal cleared from listProposals");
|
||||
const html = api.trackChangesPreviewController.renderHtmlFor(key);
|
||||
assert.ok(!html.includes(`data-proposal-id="${id}"`), "the accepted proposal block is gone from the preview");
|
||||
// The baseline advanced on the landing (INV-18): the landed text is not marked.
|
||||
// Native-surfaces migration (INV-7/D21): the shipped machine-landing baseline
|
||||
// advance (#48/INV-18) is retired — the landed text stays a visible change
|
||||
// until "Mark Changes as Reviewed".
|
||||
const model = api.trackChangesPreviewController.getLastModel(key) ?? [];
|
||||
const marked = model.some((o) => o.kind !== "unchanged" && o.block.raw.includes("FIRST claude REPLACEMENT"));
|
||||
assert.ok(!marked, "the just-landed Claude text renders unmarked (baseline advanced)");
|
||||
assert.ok(marked, "the just-landed Claude text still renders as a change (baseline does not auto-advance)");
|
||||
});
|
||||
|
||||
test("reject → the proposal vanishes and the document is reverted (PUC-5)", async () => {
|
||||
@@ -228,8 +233,8 @@ suite("F10 interactive review (host E2E — preview is the single review surface
|
||||
(k) => k.command === "cowriting.toggleDiffView",
|
||||
);
|
||||
assert.ok(!dKb, "the toggleDiffView keybinding is gone from package.json (#34)");
|
||||
// …but the F6 baseline data layer survives: pinDiffBaseline stays a real command.
|
||||
assert.ok(all.includes("cowriting.pinDiffBaseline"), "pinDiffBaseline (baseline data layer) is kept");
|
||||
// …but the F6 baseline data layer survives: markReviewed stays a real command.
|
||||
assert.ok(all.includes("cowriting.markReviewed"), "markReviewed (baseline data layer) is kept");
|
||||
void key;
|
||||
});
|
||||
|
||||
@@ -297,6 +302,9 @@ async function reopen(rel: string): Promise<{ doc: vscode.TextDocument; key: str
|
||||
const uri = vscode.Uri.file(path.join(WS, rel));
|
||||
const doc = await vscode.workspace.openTextDocument(uri);
|
||||
await vscode.window.showTextDocument(doc);
|
||||
// Idempotent (INV-10): the doc entered coediting in freshDoc(); re-entering
|
||||
// is a no-op that leaves the once-captured baseline untouched.
|
||||
await vscode.commands.executeCommand("cowriting.coeditDocument");
|
||||
await settle();
|
||||
return { doc, key: uri.toString() };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user