feat(settings): add branch prefix for inferred branch names#873
Conversation
Add a "Branch prefix" text field to the General settings panel. When a repo is added without an explicit branch name — so the branch name is inferred from the project name — the prefix is prepended with a `/` separator, unless the prefix already ends in `/`. The preference is stored under the `branch-prefix` key in preferences.json and read directly by the backend (same pattern as `recent-agents`) in all three inference paths: add_project_repo_impl, the create_project Tauri command, and the web server's create_project handler. Explicit branch names and the workspace-name fallback are unaffected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
The branch prefix from preferences was spliced raw into inferred branch names, so values like "Matt Toohey", "/mtoohey", "foo//", or ones containing ".."/"~"/".lock" flowed into `git worktree add -b` and failed later as opaque git errors. Normalize the prefix at usage time with the same rules infer_branch_name applies to project names, applied per /-separated segment so multi-level prefixes like "team/mtoohey" keep their hierarchy. Empty segments are dropped, which also removes the trailing-slash special case in apply_branch_prefix: a normalized prefix never starts or ends with "/", so it always joins with a single separator. Prefixes with nothing valid left after normalization are treated as unset. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 08b6e6fe5f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| */ | ||
| export function setBranchPrefix(prefix: string): void { | ||
| preferences.branchPrefix = prefix; | ||
| setStoreValue(BRANCH_PREFIX_STORE_KEY, prefix.trim()); |
There was a problem hiding this comment.
Persist branch prefix for web clients
When the app is running via the web server (isTauri === false), initPersistentStore leaves backend null, so this new setter only changes the local Svelte state and setStoreValue returns without writing preferences.json; however the web create_project path now calls infer_prefixed_branch_name, which reads that server-side file. In that environment, setting Branch prefix in General settings and then adding/creating a repo without an explicit branch still produces the unprefixed branch name, so the setting appears to work in the UI but has no effect.
Useful? React with 👍 / 👎.
When the app runs via the web server (isTauri === false), the persistent store had no backend: setStoreValue was a silent no-op, so setting Branch prefix in General settings only updated local Svelte state while the server-side create_project path read the untouched preferences.json — the setting appeared to work but had no effect (and every other preference silently reset between web sessions). Give web mode a real backend that proxies get/set/delete to new get_preference / set_preference / delete_preference commands on the web server. The server opens ~/.staged/preferences.json through the tauri-plugin-store Rust API, which returns the desktop frontend's already-loaded instance when one exists, so concurrent desktop and web clients share one in-memory store instead of clobbering each other's writes. Mutations are saved to disk immediately so the backend paths that read the file directly (branch-prefix, recent-agents) observe web writes right away. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
The Branch prefix placeholder in General settings was hardcoded to "e.g. mtoohey" — it looked like it might be derived from the current user's name, but it was just a literal. Replace it with a neutral "e.g. alice", and sweep the same personal name out of the normalize_branch_prefix doc comment and test fixtures so it doesn't appear anywhere in the codebase. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
The empty-state description under Branch prefix read "Prepended (with a / separator) to branch names…", which is stilted and buries the separator detail in a parenthetical. Reword it to "This prefix will be added to branch names along with a slash separator when a repo is added without choosing a branch." Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
…ription The previous reword kept "when a repo is added without choosing a branch" from the old copy, but the requested text ended at the slash separator. The description now reads just "This prefix will be added to branch names along with a slash separator." Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Matt Toohey <contact@matttoohey.com>
Summary
Adds a Branch prefix setting (Settings → General) that is prepended to branch names inferred from project names — e.g. with prefix
mtoohey, adding a repo to project "My Project" without picking a branch yieldsmtoohey/my-project.Changes
preferences.svelte.ts,GeneralSettingsPanel.svelte): newbranch-prefixpreference with a text input in General settings, including a live example of the resulting branch name.branches.rs): newinfer_prefixed_branch_namereads the prefix from the preferences store and joins it onto the inferred name with a/. The prefix is sanitized per/-separated segment using the same normalization rules as project names, so multi-level prefixes liketeam/mtooheykeep their hierarchy while invalid characters, empty segments, and stray slashes can't produce an invalid ref.create_projectinlib.rs,add_project_repo_implinproject_commands.rs, and the web server dispatch) now use the prefixed inference. Theresolve_project_workspace_namefallback stays on the unprefixedinfer_branch_nameso existing workspace identities are unaffected.Testing
Unit tests cover prefix joining, sanitization, multi-level prefixes, empty-segment handling, and fully-invalid prefixes.