feat(web,mobile): per-project default base branch for new worktrees - #21
Conversation
- Add defaultThreadBaseBranch project override, editable in source control settings - Automatic worktree drafts prefer the override, then the repo default, then the current branch - Mobile settings gains the field and honors it in the new task flow
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b7c4f413e1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if ( | ||
| target.projectId === null || | ||
| target.environment.serverConfig.environment.capabilities.projectSettingsOverrides !== true | ||
| ) |
There was a problem hiding this comment.
Gate default-branch writes on a versioned capability
When an updated mobile or web client connects to a pre-change server, that server still advertises the generic projectSettingsOverrides capability even though its nested settings schema does not know defaultThreadBaseBranch. These writes therefore appear supported and successful, but the old decoder strips the new field, so the value immediately disappears; mixed-version environments can also save it on only some machines without reporting a partial failure. Add a capability specifically covering this field and hide or disable the control unless every write target advertises it.
AGENTS.md reference: AGENTS.md:L74-L74
Useful? React with 👍 / 👎.
| const defaultThreadBaseBranch = isProjectScope | ||
| ? (target?.overrides.defaultThreadBaseBranch ?? "") | ||
| : ""; |
There was a problem hiding this comment.
Represent mixed base-branch overrides in the web control
For a logical project present on multiple connected environments with different overrides, this derives the field solely from the representative target, so the web UI presents one branch as though it applied everywhere. This is especially problematic because DraftInput does not commit an unchanged value: if the representative says dev and another machine says release, entering dev cannot fan that choice out, and if the representative is unset the reset action is also absent. Derive and display a mixed state from all targets, as the adjacent scoped settings do.
AGENTS.md reference: AGENTS.md:L74-L74
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
🟡 Changes recommended
The web settings row mishandles mixed project overrides and remains editable when no connected target can accept the write.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds a project-only default base branch for new worktree threads across web and mobile, including persistence, UI, fallback behavior, tests, and documentation.
Changes:
- Extends project override contracts and preservation logic.
- Applies the setting to web/mobile worktree draft creation and branch selection.
- Adds web/mobile settings controls and documentation.
File summaries
| File | Description |
|---|---|
packages/shared/src/projectSettings.ts |
Supports clearing project-only overrides. |
packages/shared/src/projectSettings.test.ts |
Tests persistence and clearing. |
packages/contracts/src/settings.ts |
Adds the override schema field. |
packages/contracts/src/settings.test.ts |
Tests validation and round-tripping. |
docs/user/project-settings.md |
Documents the setting. |
apps/web/src/hooks/useHandleNewThread.ts |
Applies the branch default to drafts. |
apps/web/src/hooks/useHandleNewThread.test.ts |
Tests default and explicit branch precedence. |
apps/web/src/components/settings/useScopedSettings.ts |
Adds the project branch update hook. |
apps/web/src/components/settings/scopedSettings.ts |
Plans merged project override writes. |
apps/web/src/components/settings/scopedSettings.test.ts |
Tests sibling preservation. |
apps/web/src/components/settings/ProjectDefaultsSettings.tsx |
Adds the web settings row. |
apps/web/src/components/BranchToolbarBranchSelector.tsx |
Uses the project branch candidate. |
apps/web/src/components/BranchToolbar.logic.ts |
Defines branch fallback precedence. |
apps/web/src/components/BranchToolbar.logic.test.ts |
Tests branch precedence and missing refs. |
apps/mobile/src/features/threads/new-task-flow-provider.tsx |
Applies the mobile branch default. |
apps/mobile/src/features/threads/new-task-branch-default.ts |
Resolves configured and fallback branches. |
apps/mobile/src/features/threads/new-task-branch-default.test.ts |
Tests mobile branch resolution. |
apps/mobile/src/features/settings/SettingsServerControlsRouteScreen.tsx |
Adds mobile editing and clearing UI. |
apps/mobile/src/features/settings/settings-scoped-server.ts |
Plans mobile override writes. |
apps/mobile/src/features/settings/settings-scoped-server.test.ts |
Tests mobile preservation and clearing. |
Review details
Suppressed comments (1)
apps/web/src/components/settings/ProjectDefaultsSettings.tsx:365
- When a project is selected but none of its environments is connected,
targetis null and the planner cannot produce a write, yet this input remains editable because it is not marked unavailable. Blurring it only discards the value after showing a warning, unlike the other server-backed rows; disable the control whileunavailable(or route it through the same inert-control handling).
<DraftInput
size="sm"
className="w-44 font-mono"
aria-label="Default base branch"
placeholder="Repository default"
- Files reviewed: 20/20 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const defaultThreadBaseBranch = isProjectScope | ||
| ? (target?.overrides.defaultThreadBaseBranch ?? "") | ||
| : ""; |
What Changed
Adds a project-only
defaultThreadBaseBranchsetting that controls the base branch used for automatic new worktree threads.packages/contracts: extends project settings overrides withdefaultThreadBaseBranch.docs/user/project-settings.mddocuments the new setting.Why
Teams work from different base branches per project (e.g.
develop), but new worktree threads always started from the repository's default branch or the current checkout. A per-project override lets each project declare its base once, while keeping the existing git-default → current-checkout fallback when unset.The setting is project-only by design: it is not an inheritable environment default, and writes merge into the project's existing overrides so sibling keys are never dropped.
UI Changes
Screenshots/video to be attached.
Checklist