Connect sessions across projects, and report what a review is using - #9
Open
tdwd wants to merge 4 commits into
Open
Connect sessions across projects, and report what a review is using#9tdwd wants to merge 4 commits into
tdwd wants to merge 4 commits into
Conversation
The sidebar worked out what a session is called by hand: the title, or the generated name when the title is empty. Two callers are about to want the same answer — the connect picker, and the notices that name a session on another project — and each would have written its own copy. The author of a second copy is the last person who ever compares them. format.go is named for the category rather than its first occupant. What a project is called, and how a figure is abbreviated to sit beside these, belong in it too.
Sessions on one project already see each other. The case scope cannot express
is the opposite one: an API changing in one repository while its consumer
changes in another. So a connection is an escape from the project, never a
subdivision of it.
Four decisions worth keeping.
A pair, not a named set. store.Connection{A, B}. The motivating case is exactly
two sessions, and a set would need a name, a member editor and a rule for the
last member leaving. Connecting A to B and A to C lets A see both without
making B and C visible to each other.
Claims deliberately do not widen. Every other scoping test became sees; Claim
kept ProjectID. A claim is a repo-relative path, so two sessions in different
repositories both claiming internal/api/client.go would be reported as
colliding over a file they do not share, and an agent that meets one false
conflict stops trusting the mechanism. This is the exception most likely to be
tidied away by a later reader, which is why it has a test named for it.
The read widens, the write does not. A note still goes to the writer's own
project log. A reader gets that merged with what connected sessions wrote in
theirs, filtered to those sessions — handing over the far project's whole log
would publish the notes of every session there.
The coordinator is told the whole set, never a delta. SetConnections replaces.
The store owns the document and the coordinator holds a copy; a copy updated by
deltas is free to drift the first time an update is missed, and the drift is
invisible.
Register, Registered and Unregister move to registry.go, leaving coord.go the
type and its lifecycle. Two documentation catch-ups ride along because they
touch the same table and paragraph: the README gains the `e` row it never had,
and the architecture tool list names the five tools added since it was written.
The badge could only show a cost, and a cost arrives once, in the result event. So a review in flight showed $0.00 for its whole run and read as free. The run now uses --output-format stream-json --verbose --include-partial-messages, and agent.RunClaude takes a callback that fires on every event carrying usage. What a captured stream showed, and what the design follows from: only the output count moves. The first event of a turn already carries the final input, cache-read and cache-write figures — in one measured run, 15,888 read and 7,954 written were known before a single word was generated. And cost is not in any event but the last, so a run in flight can report what it is using and not what it will cost. The sidebar therefore shows tokens while a review runs and dollars once it lands. One format, not two. The non-live path could have kept --output-format json, but a second parser is a second place for claude's field names to drift, and the totals are the thing least affordable to get quietly wrong. It also closed a gap the old code's own doc comment denied. RunClaude promised to return an error "only when there is no accounting at all", while cmd.Output turned any non-zero exit into an error and discarded the result envelope with it. Reading stdout to the end before waiting means a result that arrived is returned whatever the process does afterwards. The backlog's open entry 11 asked for exactly this, so it goes; the struck-out entry above it is the record now.
Not every session wants an agent. Reaching a server, running a migration or watching a log is work that belongs beside the agents rather than in a separate terminal, and almost all of it already works: agent.Start runs whatever store.Session.Agent names, coordArgs gives no coordination flags to a program it does not know, and willResume refuses --continue to anything but claude. What is missing is the menu entry and three decisions around it, which the entry states. No code changes.
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.
Four commits, each reviewable on its own.
sessionLabelout of the sidebar intointernal/ui/format.go, so the two callers that follow do not each write their own copy. No behaviour change.store.Connection{A, B},coord.sees, theckey and its picker. A connection widens what a session can read and never narrows a project. Claims deliberately do not widen, and there is a test named for that exception.--output-format stream-jsonand a usage callback onagent.RunClaude. The badge shows tokens during a run and dollars after, because the CLI reports cost only in the result event.go test ./...andmake racepass on the final commit. Each commit was built and tested on its own before the next was made.The follow-up branch adds a focus guard so
xandccannot act on a session the keyboard is not driving.