fix(edit-selection): accurate warnings + path-boundary workspace check #24

Merged
benstull merged 1 commits from fix-editselection-guard into main 2026-06-11 19:13:12 +00:00
Owner

Summary

Reported during F7 manual testing: "Ask Claude to Edit Selection" warned "I need to highlight text" even though text was selected. Root cause — cowriting.editSelection's guard collapsed four distinct failures (no editor / no selection / unsaved / file outside the workspace folder) into one misleading "select some text in a workspace document first" message. The file (vscode-cowriting-plugin-content/issues/diff-view-toggle.md) was outside the EDH workspace root (.../vscode-cowriting-plugin/sandbox), so the membership check rejected it — but blamed the selection.

Changes

  • New pure, vscode-free src/workspacePath.ts:
    • isUnderRoot(fsPath, root) — separator-bounded membership, fixing a latent startsWith() prefix-collision (a sibling whose name prefixes the root — vscode-cowriting-plugin-content vs vscode-cowriting-plugin — falsely matched).
    • selectionRejection(ctx) — one accurate message per condition (the out-of-workspace case now says so explicitly, not "select some text").
  • Wired isUnderRoot into all five membership checks: extension.ts (editSelection guard + renderIfOpen) and the thread / attribution / proposal controllers.

Test Plan

  • New unit suite test/workspacePath.test.ts (8 cases) incl. the reported bug (out-of-workspace file → outside-workspace message, NOT the no-selection message) and the prefix-collision case.
  • npm test130 passing (122 + 8).
  • npm run test:e2e33 + 4 passing (existing F2–F7 suites exercise the membership checks through real workspace fixtures = regression guard for isUnderRoot).
  • npm run typecheck clean.

Not an F7 regression — editSelection was last touched by F6 (#19). Session 0022.

Co-authored with Claude.

## Summary Reported during F7 manual testing: **"Ask Claude to Edit Selection" warned "I need to highlight text" even though text was selected.** Root cause — `cowriting.editSelection`'s guard collapsed four distinct failures (no editor / no selection / unsaved / **file outside the workspace folder**) into one misleading "select some text in a workspace document first" message. The file (`vscode-cowriting-plugin-content/issues/diff-view-toggle.md`) was outside the EDH workspace root (`.../vscode-cowriting-plugin/sandbox`), so the membership check rejected it — but blamed the selection. ## Changes - New pure, vscode-free `src/workspacePath.ts`: - `isUnderRoot(fsPath, root)` — separator-bounded membership, fixing a **latent `startsWith()` prefix-collision** (a sibling whose name prefixes the root — `vscode-cowriting-plugin-content` vs `vscode-cowriting-plugin` — falsely matched). - `selectionRejection(ctx)` — one accurate message per condition (the out-of-workspace case now says so explicitly, not "select some text"). - Wired `isUnderRoot` into **all five** membership checks: `extension.ts` (editSelection guard + `renderIfOpen`) and the thread / attribution / proposal controllers. ## Test Plan - [x] New unit suite `test/workspacePath.test.ts` (8 cases) incl. the reported bug (out-of-workspace file → outside-workspace message, NOT the no-selection message) and the prefix-collision case. - [x] `npm test` — **130 passing** (122 + 8). - [x] `npm run test:e2e` — **33 + 4 passing** (existing F2–F7 suites exercise the membership checks through real workspace fixtures = regression guard for `isUnderRoot`). - [x] `npm run typecheck` clean. Not an F7 regression — `editSelection` was last touched by F6 (#19). Session 0022. Co-authored with Claude.
benstull added 1 commit 2026-06-11 19:12:54 +00:00
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>
benstull merged commit 0525c40eed into main 2026-06-11 19:13:12 +00:00
Sign in to join this conversation.