F8: out-of-workspace authoring — hybrid sidecar persistence (#25) #26

Merged
benstull merged 8 commits from f8-out-of-workspace into main 2026-06-11 20:18:55 +00:00

8 Commits

Author SHA1 Message Date
Ben Stull bfd951552c docs(f8): manual smoke runbook + README hybrid-model/non-shareability note + plan
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:15:54 -07:00
Ben Stull 5030cad612 test(f8): host E2E — out-of-folder file + untitled + in-workspace regression; folder-less suite
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:14:45 -07:00
Ben Stull 7892e2fe87 feat(f8): wire SidecarRouter; authoring commands live folder-less (#19 precedent)
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>
2026-06-11 13:13:26 -07:00
Ben Stull 7387366e28 refactor(f8): controllers depend on SidecarRouter + isAuthorable (key via keyOf)
Spec §6.4: constructor store CoauthorStore→SidecarRouter, rootDir→string|undefined;
isInRoot/isTracked gate → isAuthorable(scheme); per-doc key via store.keyOf(docIdentity).
Seam + artifact logic unchanged. currentAuthor omits git email when no root (fail-open).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:11:39 -07:00
Ben Stull 94aaff71e9 refactor(f8): VersionGuard depends on SidecarStore not CoauthorStore
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:08:27 -07:00
Ben Stull dca12f4f50 feat(f8): SidecarRouter — keyOf + per-document routing (spec §6.2)
Routes by #24's isUnderRoot: in-workspace file: → CoauthorStore (repo-relative key,
.threads/), out-of-folder file: + untitled: → GlobalSidecarStore (URI-string key).
keyOf is the single document identity. vscode-free; CoauthorStore conforms
structurally (unmodified, INV-2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:08:01 -07:00
Ben Stull bc77cee0bd feat(f8): isAuthorable + widened selectionRejection (file|untitled)
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>
2026-06-11 13:06:58 -07:00
Ben Stull 515acb4868 feat(f8): SidecarStore interface + GlobalSidecarStore (sha256 key, untitled in-memory)
Spec §6.2/§6.4: out-of-workspace file: → <globalStorage>/sidecars/<sha256(uri)>.json
(INV-19/24); untitled: → in-memory only (F6 degrade). update() carries the INV-16
newer-major throw + anchor prune; consumeSelfWrite is a no-op (outside the .threads
watcher). Mirrors src/baselineStore.ts; vscode-free, unit-tested.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:06:08 -07:00