feat(projects): add Global Defaults for the three project settings fields - #81
Conversation
…elds Projects settings gains a Global Defaults section above the project selector holding the same three fields the per-project card already owns: worktree command, ticket key, and Beads directory. A project keeps winning whenever its own value is non-empty; only an empty project value consults the global. Empty already meant "fall back" for all three fields, so this adds a link to an existing chain rather than changing what any stored value means. Every global ships empty, which reproduces the exact previous resolution for every project. A project field taking its value from a global shows an Inherited badge next to the field name and renders the global as its input placeholder, so the effective value is visible without leaving the page. The badge tracks the live draft text, so it clears as soon as an override is typed and returns when the field is emptied again. Resolution lands only in behavioral consumers; the settings projections keep exposing each project's own stored value so the badge can tell the two apart. gxserver owns the cascade for the Beads workspace directory and the worktree setup command, and the two early-return gates that guard that command consult the global too, since either would otherwise skip the executor for a project that inherits. The native sidebar resolves the ticket key between the legacy gitConfig key and the project-name fallback. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (9)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Adds a Global Defaults section at the top of the Projects settings page, per the discussion in feedback-and-ideas. It holds the same three fields the per-project card already owns — worktree command, ticket key, and Beads directory — and each applies to every project that does not set its own value.
Why this is safe to land
Empty already meant "fall back" for all three fields ("Leave blank to use the project root"). So this adds a link to an existing chain rather than changing what any stored value means. Every global ships empty, which reproduces the exact previous resolution for every project. Nobody's setup moves unless they fill something in.
Inherited indicator
A project field taking its value from a global shows a small Inherited badge next to the field name, and renders the global value as its input placeholder so the effective value is visible without leaving the page.
The badge tracks the live draft text, not the saved value — it clears the moment an override is typed and returns when the field is emptied again.
Where the cascade lands
Resolution goes only into behavioral consumers. The settings projections deliberately keep exposing each project's own stored value, otherwise the badge could not tell "set to X" from "inheriting X".
typed_operations.rs— Beads cwdtyped_operations.rsexecutor, plus theserver.rsandgxserver-runtime.tsgatesnative-sidebar.tsx— between the legacygitConfigkey and the project-name fallbackBoth worktree gates matter: each early-returns when nothing is configured, so either one would otherwise skip the executor for a project that inherits its command.
global_project_defaults.rssplits the one filesystem read from the decision, the waysession_lifecycle.rssplits its settings gate, so the cascade is unit-testable without a settings file on disk.Validation
tsc --noEmit— cleancargo test— 662 existing pass, plus 6 new covering project-wins / empty-falls-back / empty-global-preserves-old-behaviorvitest run --config vitest.release.config.ts— 1279 pass. The 2 failures inshared/sidebar-commands.test.ts(showOnProjectRow) reproduce identically on a clean checkout ofmainat f057528 and are unrelated to this change.sidebar-settings-modal--projects): setting a global ticket key and clearing the project's own key shows the Inherited badge with the global as placeholder, while a sibling field that has its own value shows no badge; typing an override dismisses it.One thing worth flagging separately
GPUI's Kanban currently passes the project display name as
beadsDisplayKeyregardless of the configured key (gpui/src/main.rs), so the per-project ticket key only takes effect in the native sidebar today. That is pre-existing onmainand untouched here, but it means the ticket-key half of this feature inherits that same limitation.🤖 Generated with Claude Code