composer: let the repository picker check out zero, one, or many repos - #105
Merged
Conversation
The Repository row's toggle was already multi-select, but its resting state lied: an empty selection MEANT "let the server resolve it" while RENDERING as [x] on the detected repo. Checking a second repo therefore produced a set of one, silently dropping the repo that looked selected, and unchecking everything was indistinguishable from the default. The selection is now null when untouched, and the first toggle seeds from the detected repo, so the checkboxes on screen are the checkout you get. The row reads "none" for the no-checkout sandbox. Two related bugs, either of which would have made that fix invisible: The override key was dead. The backend renamed sandbox: to environment: and the config model forbids extra keys, so every repo pick was rejected at validation. The same stale key sat behind --repo/--cpu/--memory/--timeout on 'session start'. The context repo overrode the selection. The server merges the request's `repository` into the checkout unconditionally, even under an explicit config, so an empty set could never hold; it is dropped when the selection excludes it. Request building moves to applyComposerChoices so the three cases are testable without mounting the pane. The public skill documented the old sandbox: schema (and github: under it, now top-level permissions:), which would have generated configs the API rejects.
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.
Summary
The new-session composer's Repository row (
agent, then ↑ past "Agent") only ever produced a one-repo checkout, though sandboxes take zero, one, or many. Three separate bugs, the latter two of which would have made fixing the first one invisible.The resting state lied. The toggle logic was already multi-select, but an empty selection meant "let the server resolve it" while rendering as
[x]on the detected repo. So checking a second repo produced a set of one, silently dropping the repo that looked selected, and unchecking everything was indistinguishable from the default. The selection is nownullwhen untouched, and the first toggle seeds from the detected repo, so the checkboxes on screen are the checkout you get. The row readsnonefor the no-checkout sandbox.The override key was dead.
sandbox:was renamed toenvironment:in ellipsis#6162, andStrictConfigModelisextra="forbid". Verified against the real Pydantic model:So every repo pick from this picker had been rejected at validation. The same stale key sat behind
--repo/--cpu/--memory/--timeoutonagent session start, which was silently broken too.The context repo overrode the selection. The server merges the request's
repositoryinto the checkout unconditionally, even under an explicit config (run_agent_session.py: "even under an explicit --config,agentin a repo always has that repo"). An empty or api-less selection could therefore never hold, so it is dropped when the selection excludes it — which also moves default-config resolution off that repo's rung, the honest reading of "not this one".Request building moves out of the
startSessioncallback intoapplyComposerChoicesinlib/sessions.ts, so the three cases are testable without mounting the pane.The public skill documented the old
sandbox:schema (withgithub:nested under it, now top-levelpermissions:), which would have had agents generate configs the API rejects.Test plan
tsc --noEmitclean, on a worktree branched fromorigin/mainapplyComposerChoicestests: untouched sends no repo override; many repos; empty set; context repo dropped when excluded;environmentnotsandbox; no mutation of the input requestacme/webyields[x] acme/api [x] acme/web— previously this droppedacme/api. Three checked submits all three withrepositoryretained; unchecking all submitsenvironment.repositories: []withrepositorydropped. Closed row readsacme/api, acme/web, acme/infraandnonerespectively.SKILL.mdvalidated against the realAgentConfig/CodeReviewConfigmodelsWorth a second opinion on: dropping
req.repositorywhen the selection excludes it also changes which rung of the defaults ladder resolves the agent. That seemed right — if you uncheck this repo, you probably don't want its repo-default agent either — but it is a behavior change beyond the checkout set.