Skip to content

feat(projects): add Global Defaults for the three project settings fields - #81

Merged
maddada merged 1 commit into
maddada:mainfrom
banozz0:feat/global-project-defaults
Aug 2, 2026
Merged

feat(projects): add Global Defaults for the three project settings fields#81
maddada merged 1 commit into
maddada:mainfrom
banozz0:feat/global-project-defaults

Conversation

@banozz0

@banozz0 banozz0 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

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".

Field Behavioral site
Beads directory typed_operations.rs — Beads cwd
Worktree command typed_operations.rs executor, plus the server.rs and gxserver-runtime.ts gates
Ticket key native-sidebar.tsx — between the legacy gitConfig key and the project-name fallback

Both 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.rs splits the one filesystem read from the decision, the way session_lifecycle.rs splits its settings gate, so the cascade is unit-testable without a settings file on disk.

Validation

  • tsc --noEmit — clean
  • cargo test — 662 existing pass, plus 6 new covering project-wins / empty-falls-back / empty-global-preserves-old-behavior
  • vitest run --config vitest.release.config.ts — 1279 pass. The 2 failures in shared/sidebar-commands.test.ts (showOnProjectRow) reproduce identically on a clean checkout of main at f057528 and are unrelated to this change.
  • Verified in Storybook (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 beadsDisplayKey regardless 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 on main and untouched here, but it means the ticket-key half of this feature inherits that same limitation.

🤖 Generated with Claude Code

…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>
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@banozz0, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 33 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0957514f-1f5d-4b95-aabe-1147220fd6f1

📥 Commits

Reviewing files that changed from the base of the PR and between f057528 and 0369850.

📒 Files selected for processing (9)
  • gpui/sidebar/gxserver-runtime.ts
  • gxserver-rs/src/global_project_defaults.rs
  • gxserver-rs/src/lib.rs
  • gxserver-rs/src/server.rs
  • gxserver-rs/src/typed_operations.rs
  • native/sidebar/native-sidebar.tsx
  • shared/ghostex-settings.ts
  • sidebar/settings-modal.tsx
  • sidebar/styles/modals.css

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@maddada
maddada merged commit b50c9b2 into maddada:main Aug 2, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants