F3 SLICE-3: applyAgentEdit seam + live tracking + decorations/toggle (INV-7/INV-9) (#6)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+7
-18
@@ -1,9 +1,11 @@
|
||||
/**
|
||||
* ThreadController — the thin editor-facing layer (spec §6.4). Wires
|
||||
* CoauthorStore + Anchorer + threadModel to vscode.comments: create-on-
|
||||
* selection, reply, resolve, render, live-range tracking, reload, and
|
||||
* FileSystemWatcher-driven external re-anchoring (SLICE-4). Threads are NEVER
|
||||
* silently moved — an unresolvable anchor renders as an orphaned thread (INV-1).
|
||||
* selection, reply, resolve, render, live-range tracking, reload, and external
|
||||
* re-anchoring (SLICE-4) — driven by the SHARED sidecar watcher in extension.ts
|
||||
* via handleExternalSidecarChange (self-writes are suppressed in CoauthorStore).
|
||||
* Threads are NEVER silently moved — an unresolvable anchor renders as an
|
||||
* orphaned thread (INV-1).
|
||||
*/
|
||||
import * as vscode from "vscode";
|
||||
import { CoauthorStore } from "./store";
|
||||
@@ -35,8 +37,6 @@ export class ThreadController implements vscode.Disposable {
|
||||
private readonly controller: vscode.CommentController;
|
||||
private readonly disposables: vscode.Disposable[] = [];
|
||||
private readonly docs = new Map<string, DocState>(); // keyed by docPath
|
||||
/** sidecar paths we just wrote, to ignore our own watcher events. */
|
||||
private readonly selfWrites = new Set<string>();
|
||||
|
||||
constructor(private readonly store: CoauthorStore, private readonly rootDir: string) {
|
||||
this.controller = vscode.comments.createCommentController("cowriting.threads", "Coauthoring Threads");
|
||||
@@ -60,13 +60,6 @@ export class ThreadController implements vscode.Disposable {
|
||||
vscode.workspace.onDidChangeTextDocument((e) => this.onDidChange(e)),
|
||||
vscode.workspace.onDidSaveTextDocument((d) => this.onDidSave(d)),
|
||||
);
|
||||
|
||||
// Re-anchor on external change to any sidecar (a git pull, a manual edit).
|
||||
const watcher = vscode.workspace.createFileSystemWatcher("**/.threads/**/*.json");
|
||||
const onSidecar = (uri: vscode.Uri) => this.onExternalSidecarChange(uri);
|
||||
watcher.onDidChange(onSidecar);
|
||||
watcher.onDidCreate(onSidecar);
|
||||
this.disposables.push(watcher);
|
||||
}
|
||||
|
||||
private isInRoot(uri: vscode.Uri): boolean {
|
||||
@@ -83,7 +76,6 @@ export class ThreadController implements vscode.Disposable {
|
||||
}
|
||||
|
||||
private persist(state: DocState): void {
|
||||
this.selfWrites.add(this.store.sidecarPath(state.docPath));
|
||||
this.store.update(state.docPath, (a) => {
|
||||
a.threads = state.artifact.threads;
|
||||
for (const t of state.artifact.threads) {
|
||||
@@ -174,12 +166,9 @@ export class ThreadController implements vscode.Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private onExternalSidecarChange(uri: vscode.Uri): void {
|
||||
/** Shared-watcher entry point (extension.ts): a sidecar changed externally. */
|
||||
handleExternalSidecarChange(uri: vscode.Uri): void {
|
||||
const p = uri.fsPath;
|
||||
if (this.selfWrites.has(p)) {
|
||||
this.selfWrites.delete(p);
|
||||
return; // our own write
|
||||
}
|
||||
for (const state of this.docs.values()) {
|
||||
if (this.store.sidecarPath(state.docPath) === p) {
|
||||
const doc = vscode.workspace.textDocuments.find((d) => this.docPathOf(d.uri) === state.docPath);
|
||||
|
||||
Reference in New Issue
Block a user