F4 SLICE-3: wire ProposalController — contributes, watcher fan-out, propose command, stubs, API (#12)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+38
-1
@@ -3,12 +3,15 @@ import { fetchSdkSummary } from "./cline";
|
||||
import { CoauthorStore } from "./store";
|
||||
import { ThreadController } from "./threadController";
|
||||
import { AttributionController } from "./attributionController";
|
||||
import { ProposalController } from "./proposalController";
|
||||
import { buildFingerprint } from "./anchorer";
|
||||
|
||||
const CHANNEL_NAME = "Cowriting (Cline SDK)";
|
||||
|
||||
export interface CowritingApi {
|
||||
threadController: ThreadController;
|
||||
attributionController: AttributionController;
|
||||
proposalController: ProposalController;
|
||||
}
|
||||
|
||||
export function activate(context: vscode.ExtensionContext): CowritingApi | undefined {
|
||||
@@ -55,6 +58,9 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
"cowriting.editSelection",
|
||||
"cowriting.toggleAttribution",
|
||||
"cowriting.applyAgentEdit",
|
||||
"cowriting.acceptProposal",
|
||||
"cowriting.rejectProposal",
|
||||
"cowriting.proposeAgentEdit",
|
||||
]) {
|
||||
context.subscriptions.push(vscode.commands.registerCommand(command, stub));
|
||||
}
|
||||
@@ -68,6 +74,10 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
const attributionController = new AttributionController(store, root);
|
||||
context.subscriptions.push(attributionController);
|
||||
|
||||
// --- F4: propose/accept (Feature #12) ---
|
||||
const proposalController = new ProposalController(store, attributionController, root);
|
||||
context.subscriptions.push(proposalController);
|
||||
|
||||
// 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");
|
||||
@@ -75,6 +85,7 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
if (store.consumeSelfWrite(uri.fsPath)) return;
|
||||
threadController.handleExternalSidecarChange(uri);
|
||||
attributionController.handleExternalSidecarChange(uri);
|
||||
proposalController.handleExternalSidecarChange(uri);
|
||||
};
|
||||
watcher.onDidChange(onSidecar);
|
||||
watcher.onDidCreate(onSidecar);
|
||||
@@ -102,6 +113,31 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
),
|
||||
);
|
||||
|
||||
// The propose ingress as a command (spec §6.4): records a pending proposal,
|
||||
// NEVER touches the document (INV-10) — for the host E2E harness.
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand(
|
||||
"cowriting.proposeAgentEdit",
|
||||
(args: {
|
||||
uri: string; start: number; end: number; newText: string;
|
||||
model?: string; sessionId?: string; turnId?: string; instruction?: string;
|
||||
}) => {
|
||||
const doc = vscode.workspace.textDocuments.find((d) => d.uri.toString() === args.uri);
|
||||
if (!doc) return Promise.resolve(undefined);
|
||||
const fp = buildFingerprint(doc.getText(), { start: args.start, end: args.end });
|
||||
const provenance = {
|
||||
kind: "agent" as const,
|
||||
id: "claude",
|
||||
agent: { sdk: "@cline/sdk", model: args.model ?? "sonnet", sessionId: args.sessionId ?? "" },
|
||||
};
|
||||
return proposalController.propose(doc, fp, args.newText, provenance, {
|
||||
turnId: args.turnId,
|
||||
instruction: args.instruction,
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// F3 SLICE-5: the live turn (PUC-2) — selection + instruction → one
|
||||
// claude-code SDK turn (liveTurn.ts, INV-8) → the applyAgentEdit seam (INV-9).
|
||||
context.subscriptions.push(
|
||||
@@ -172,12 +208,13 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
if (doc.uri.scheme === "file" && doc.uri.fsPath.startsWith(root)) {
|
||||
threadController.renderAll(doc);
|
||||
attributionController.loadAll(doc);
|
||||
proposalController.renderAll(doc);
|
||||
}
|
||||
};
|
||||
vscode.workspace.textDocuments.forEach(renderIfOpen);
|
||||
context.subscriptions.push(vscode.workspace.onDidOpenTextDocument(renderIfOpen));
|
||||
|
||||
return { threadController, attributionController };
|
||||
return { threadController, attributionController, proposalController };
|
||||
}
|
||||
|
||||
export function deactivate(): void {
|
||||
|
||||
Reference in New Issue
Block a user