Adds test/e2e/suite/f10Review.test.ts covering the F10 flow: open preview
(mode "on", fresh baseline all-unchanged), type → cw-by-human span, propose →
cw-proposal block with ✓/✗, accept → lands + baseline advances + block clears,
reject → vanishes + doc untouched, toggle off → renderPlain has no cw- marks,
status-bar PUC-6 (indicator with no panel, hidden once opened), and the
clean-editor INV-32 facts (retired toggleAttribution, F6 ctrl+alt+d hidden).
Rewrites the obsolete F9 authorship-mode test as an F10 review test
(cw-by-claude in the on-state render; getMode defaults to "on"). Updates
attribution.test.ts (drops the retired isVisible/toggleAttribution toggle,
asserts the toggle is gone) and noWorkspace.test.ts (toggleAttribution +
acceptProposal/rejectProposal are retired, preview-only — INV-32).
Honesty fix in the status-bar seam: hideStatus() clears statusItem.text so
statusText() reports undefined when the indicator is hidden (it previously
returned its stale last value after a panel opened).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code-quality polish: the webview panel title read 'Track changes: <name>' but
F10 makes the preview the single review surface. Match the 'Open Review Preview'
command rename.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Includes the PUC-6 status-bar indicator (updateStatus + show/dispose hooks)
since the constructor subscription references it (one file, no intermediate
broken build).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code-quality follow-up: with editor decorations gone (Task 1), the visibility
toggle was dead/misleading — nothing reads `visible`. Remove the field,
toggle()/isVisible(), the cowriting.toggleAttribution registration, and its
package.json command + palette declarations (spec §6.2 retires it). renderActive/
render stay — they refresh the orphan status bar on editor switch.
E2E toggle assertions (attribution.test.ts, noWorkspace.test.ts) are updated in SLICE-4.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per-panel mode (default changes); refresh branches to renderAuthorship reading
AttributionController.spansFor; webview setMode message; extension.ts reorders the
F7 controller after attribution. getMode/setMode test seams.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PUA sentinel injection through markdown-it; adjacent-span ordering handled;
code/mermaid fences atomic with a block-level author badge.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spec §6.4: construct GlobalSidecarStore + SidecarRouter (CoauthorStore when root);
remove the no-root early-return + command stubs so F2/F3/F4 are real folder-less;
renderIfOpen gated by isAuthorable; editor-context menus widened to untitled;
export sidecarRouter on CowritingApi. activate now always returns the API.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Spec §6.4: replace the scheme!=file / !isUnderRoot rejections with a single
!isAuthorable branch. isUnderRoot retained as a routing input. Per-condition
messaging (#24) kept for no-editor / empty-selection / non-{file,untitled}.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
F6 no longer requires a workspace file. It gets its own diffable predicate
(any file: or untitled:) decoupled from F2 isTracked, keys baselines by a
sha256 of the document URI, and stores them in VS Code GLOBAL storage
(context.globalStorageUri) — always present, never the repo (INV-19). Untitled
buffers have no durable identity → in-memory baseline only (lost on reload).
DiffViewController is now constructed before the workspace-root check and its
commands are always live (never stubbed) — the machine-landing advance wiring
stays in the with-root branch since the seam only fires on workspace files.
BaselineStore generalized to key-by-hash (Baseline.docPath → uri).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
F6 §6.2. BaselineStore from context.storageUri (in-memory fallback), advance
subscribed to the seam's onDidApplyAgentEdit, ensureBaseline on first sight in
renderIfOpen, diffViewController on the CowritingApi, commands stubbed in the
no-folder path (#8 precedent).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
F6 §6.5 PUC-1. Detects the baseline diff tab (original scheme cowriting-baseline,
modified == the doc) to close-and-reveal; else opens vscode.diff with an epoch
title. Live document on the right — editor state preserved by construction.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
F6 §6.2/§6.4, INV-18/INV-19. ensure/advance/pin capture buffer text, persist
via BaselineStore, refresh the open diff via onDidChange. Storage-unavailable
degrades to in-memory + one warning. toggle UX lands in SLICE-3.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
F6 §6.2/§6.4, INV-9/INV-18. Additive EventEmitter on the seam owner, fired
after a real (non-no-op) applyEdit succeeds. Seam signature/return unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
F6 §6.2/§6.3, INV-19. One JSON per docPath under VS Code workspace storage,
never the repo. Mirrors CoauthorStore; unit-tested round-trip/paths/overwrite.
Also lands the F6 implementation plan
(docs/superpowers/plans/2026-06-11-f6-diff-view-toggle.md).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Playing with F4, the operator hit VS Code's default "Reply…" box on a
proposal thread: no submit command is wired for cowriting.proposals, so
typed text had nowhere to go. Proposals are decide-only (accept/reject in
the title bar); discussion belongs in a coauthoring thread. Set
canReply=false so the dead input never renders, and expose canReply on the
test-facing RenderedProposal with an E2E assertion.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>