feat(protocol): thread/list, thread/fork and thread/archive - #231
Merged
Conversation
Finding F15 in docs/THREE_WAY_REVIEW.md. The protocol could start, read and resume a thread but not enumerate one, so every client that wanted a thread picker read the session directory itself — the desktop through a Tauri command, which is a second reader of the same data with its own idea of what a row is. Adds the three methods behind a `threadManagement` capability. ThreadStore gains optional list/archive; a store without them leaves the capability off and the runtime rejects the calls rather than letting an empty list pass for the truth. The canonical store lists snapshots first and then projects any legacy session that has no snapshot yet, so a listing shows everything a user has, not just what the app-server has touched since 0.2.0. Fork copies a thread into a new one and leaves the original untouched. An in-progress turn is copied as `interrupted`: nothing is executing the fork, and carrying `in_progress` across would leave it permanently unable to start a turn. The desktop sidebar now lists through the protocol, falling back to the Tauri reader only when the sidecar is too old to serve it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Finding F15 in
docs/THREE_WAY_REVIEW.md— the last open item from the review.The protocol could start, read and resume a thread but not enumerate one. So every client that wanted a thread picker read the session directory itself: the desktop through a Tauri command, with its own row shape, its own ordering and its own idea of a title. Two readers of the same data.
The three methods
thread/listthread/forkthread/archiveBehind a
threadManagementcapability.ThreadStoregains optionallist/archive: a store without them leaves the capability off and the runtime rejects the calls, rather than letting an empty list pass for the truth.listThreads()returnsnullto the desktop client in that case, so "the server can't tell me" and "there are no threads" stay distinguishable.The canonical store lists snapshots first, then projects any legacy session that has no snapshot yet — a listing shows everything a user has, not just what the app-server has touched since 0.2.0. Legacy rows are projected lazily and not written back.
Fork copies an in-progress turn as
interrupted. Nothing is executing the fork, andstartTurnrefuses a thread that already has an in-progress turn — so carrying the status across would produce a fork that could never be used. There's a test that forks mid-turn and then starts a turn on the result.Wired, not just declared
The desktop sidebar lists through the protocol now, falling back to the Tauri reader only when the sidecar is too old. A capability nothing consumes is the failure mode this whole review batch has been about.
Verification
7 new runtime tests (ordering, title derivation, no title for an empty thread, archive removing a row, archiving a nonexistent thread, fork isolation, in-progress fork, and a store that can't do any of it). The preview fixture serves
thread/listandthread/archive, so the existing Playwright journey — which picks sessions by title out of the sidebar — is now exercising the protocol-backed listing end to end.pnpm typecheck·lint·format:checkclean; protocol 31 · core 750/16 skipped · desktop 101 · server 41 · cli 208 · vscode 12 · lsp 13 · scripts 21;playwright test→ 7 passed.Follow-up: archive and delete in the sidebar still go through Tauri;
thread/archiveis served but not yet the path the button takes. That's the remaining half of removing the second reader.🤖 Generated with Claude Code