fix(edit-selection): accurate per-condition warnings + path-boundary workspace check
cowriting.editSelection collapsed four distinct failures (no editor / no selection / unsaved / outside the workspace folder) into one misleading "select some text in a workspace document first" warning — so editing a selection in a file OUTSIDE the EDH workspace root (e.g. a content-repo file while the EDH opens sandbox/) was rejected as if no text were selected. - New pure, vscode-free src/workspacePath.ts: isUnderRoot() (separator-bounded membership, fixing a latent startsWith() prefix collision where a sibling whose name prefixes the root — e.g. vscode-cowriting-plugin-content vs vscode-cowriting-plugin — falsely matched) + selectionRejection() (one message per condition). Unit-tested (8 cases), incl. the reported bug. - Wire isUnderRoot into all five membership checks: extension.ts (editSelection guard + renderIfOpen) and the thread/attribution/proposal controllers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+16
-9
@@ -9,6 +9,7 @@ import { VersionGuard } from "./versionGuard";
|
||||
import { BaselineStore } from "./baselineStore";
|
||||
import { DiffViewController } from "./diffViewController";
|
||||
import { TrackChangesPreviewController } from "./trackChangesPreview";
|
||||
import { isUnderRoot, selectionRejection } from "./workspacePath";
|
||||
|
||||
const CHANNEL_NAME = "Cowriting (Cline SDK)";
|
||||
|
||||
@@ -187,22 +188,28 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand("cowriting.editSelection", async () => {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (
|
||||
!editor ||
|
||||
editor.selection.isEmpty ||
|
||||
editor.document.uri.scheme !== "file" ||
|
||||
!editor.document.uri.fsPath.startsWith(root)
|
||||
) {
|
||||
void vscode.window.showWarningMessage("Cowriting: select some text in a workspace document first.");
|
||||
// Each failure names its real reason (no editor / no selection / unsaved /
|
||||
// outside the workspace folder) — not always "select some text" (#bug:
|
||||
// an out-of-workspace file was rejected with the no-selection message).
|
||||
const reason = selectionRejection({
|
||||
hasEditor: !!editor,
|
||||
selectionEmpty: editor?.selection.isEmpty ?? true,
|
||||
scheme: editor?.document.uri.scheme ?? "",
|
||||
fsPath: editor?.document.uri.fsPath ?? "",
|
||||
root,
|
||||
});
|
||||
if (reason) {
|
||||
void vscode.window.showWarningMessage(reason);
|
||||
return;
|
||||
}
|
||||
if (!editor) return; // unreachable once reason is null, but narrows the type
|
||||
const instruction = await vscode.window.showInputBox({
|
||||
prompt: "What should Claude do with the selection?",
|
||||
placeHolder: "e.g. tighten this paragraph",
|
||||
});
|
||||
if (!instruction) return;
|
||||
if (editor.selection.isEmpty) {
|
||||
void vscode.window.showWarningMessage("Cowriting: select some text in a workspace document first.");
|
||||
void vscode.window.showWarningMessage("Cowriting: select some text to send to Claude first.");
|
||||
return;
|
||||
}
|
||||
const document = editor.document;
|
||||
@@ -262,7 +269,7 @@ export function activate(context: vscode.ExtensionContext): CowritingApi | undef
|
||||
|
||||
// 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)) {
|
||||
if (doc.uri.scheme === "file" && isUnderRoot(doc.uri.fsPath, root)) {
|
||||
threadController.renderAll(doc);
|
||||
attributionController.loadAll(doc);
|
||||
proposalController.renderAll(doc);
|
||||
|
||||
Reference in New Issue
Block a user