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:
+46
-3
@@ -2,11 +2,13 @@ import * as vscode from "vscode";
|
||||
import { fetchSdkSummary } from "./cline";
|
||||
import { CoauthorStore } from "./store";
|
||||
import { ThreadController } from "./threadController";
|
||||
import { AttributionController } from "./attributionController";
|
||||
|
||||
const CHANNEL_NAME = "Cowriting (Cline SDK)";
|
||||
|
||||
export interface CowritingApi {
|
||||
threadController: ThreadController;
|
||||
attributionController: AttributionController;
|
||||
}
|
||||
|
||||
export function activate(context: vscode.ExtensionContext): CowritingApi | undefined {
|
||||
@@ -41,14 +43,55 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
const threadController = new ThreadController(store, root);
|
||||
context.subscriptions.push(threadController);
|
||||
|
||||
// Render threads for already-open editors, and on future opens.
|
||||
// --- F3: live attribution (Feature #6) ---
|
||||
const attributionController = new AttributionController(store, root);
|
||||
context.subscriptions.push(attributionController);
|
||||
|
||||
// One SHARED sidecar watcher for both controllers; self-writes are
|
||||
// suppressed centrally in the store (the sidecar is co-owned).
|
||||
const watcher = vscode.workspace.createFileSystemWatcher("**/.threads/**/*.json");
|
||||
const onSidecar = (uri: vscode.Uri) => {
|
||||
if (store.consumeSelfWrite(uri.fsPath)) return;
|
||||
threadController.handleExternalSidecarChange(uri);
|
||||
attributionController.handleExternalSidecarChange(uri);
|
||||
};
|
||||
watcher.onDidChange(onSidecar);
|
||||
watcher.onDidCreate(onSidecar);
|
||||
context.subscriptions.push(watcher);
|
||||
|
||||
// The seam as a command (INV-9): the only machine-edit ingress, hidden from
|
||||
// the palette — for the host E2E harness and future SDK turn plumbing.
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand(
|
||||
"cowriting.applyAgentEdit",
|
||||
(args: {
|
||||
uri: string; start: number; end: number; newText: string;
|
||||
model?: string; sessionId?: string; turnId?: string;
|
||||
}) => {
|
||||
const doc = vscode.workspace.textDocuments.find((d) => d.uri.toString() === args.uri);
|
||||
if (!doc) return Promise.resolve(false);
|
||||
const range = new vscode.Range(doc.positionAt(args.start), doc.positionAt(args.end));
|
||||
const provenance = {
|
||||
kind: "agent" as const,
|
||||
id: "claude",
|
||||
agent: { sdk: "@cline/sdk", model: args.model ?? "sonnet", sessionId: args.sessionId ?? "" },
|
||||
};
|
||||
return attributionController.applyAgentEdit(doc, range, args.newText, provenance, { turnId: args.turnId });
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// Render threads + attributions for already-open editors, and on future opens.
|
||||
const renderIfOpen = (doc: vscode.TextDocument) => {
|
||||
if (doc.uri.scheme === "file" && doc.uri.fsPath.startsWith(root)) threadController.renderAll(doc);
|
||||
if (doc.uri.scheme === "file" && doc.uri.fsPath.startsWith(root)) {
|
||||
threadController.renderAll(doc);
|
||||
attributionController.loadAll(doc);
|
||||
}
|
||||
};
|
||||
vscode.workspace.textDocuments.forEach(renderIfOpen);
|
||||
context.subscriptions.push(vscode.workspace.onDidOpenTextDocument(renderIfOpen));
|
||||
|
||||
return { threadController };
|
||||
return { threadController, attributionController };
|
||||
}
|
||||
|
||||
export function deactivate(): void {
|
||||
|
||||
Reference in New Issue
Block a user