Skip to content

Add multi-repository context support#6

Merged
guodong-sq merged 9 commits intomainfrom
feature/multi-repo-context
Feb 9, 2026
Merged

Add multi-repository context support#6
guodong-sq merged 9 commits intomainfrom
feature/multi-repo-context

Conversation

@guodong-sq
Copy link
Copy Markdown
Collaborator

Summary

  • Adds wt context command for managing multiple repository configurations
  • Adds wt context add subcommand that runs full setup flow (same as install.sh)
  • Shows context banner on all commands to indicate active repository
  • Extracts shared setup logic into lib/wt-context-setup for reuse

Changes

New files:

  • lib/wt-context - Core context management library
  • lib/wt-context-setup - Shared setup flow for install.sh and wt context add
  • bin/wt-context - Context list/switch/add command

Modified files:

  • lib/wt-common - Loads context config on init
  • install.sh - Simplified to use shared setup library
  • wt.sh - Added context command
  • All bin/wt-* scripts - Added context banner
  • Shell completions - Added context command completion
  • lib/wt-help - Updated help text

User Experience

# Interactive context selection
wt context

# Direct switch
wt context java

# List all contexts
wt context --list

# Add new repository context (full setup flow)
wt context add
wt context add ~/repo
wt context add myname ~/repo

# All commands show context banner
wt list
# Output:
#   [Context: java] (wt context to switch)
#   ...

Test plan

  • Fresh install with install.sh
  • Add second context with wt context add
  • Switch contexts with wt context
  • Verify context banner appears on all commands
  • Verify shell completions work

🤖 Generated with Claude Code

@guodong-sq guodong-sq force-pushed the feature/multi-repo-context branch from 4b865f5 to 5d2c6ca Compare January 29, 2026 22:02
@bezhermoso
Copy link
Copy Markdown
Contributor

bezhermoso commented Feb 7, 2026

Have you considered using git config as config source of vault directory path, worktree base path, etc.? That way, wt would largely "work" depending on which repo you're on i.e. context-switching is either (a) cding to another repo, or (b) an --repo path argument you pass down to git -C

Base automatically changed from expand-project-metadata-support to main February 9, 2026 03:32
guodong-sq and others added 5 commits February 8, 2026 22:39
Replace hardcoded java-monorepo defaults with a user-centric flow that:
  - Asks which repository to manage first
  - Auto-detects default branch from origin/HEAD or main/master
  - Derives all paths from repo location (e.g., myrepo -> myrepo-master, myrepo-worktrees)
  - Shows derived config and allows customization
Expand beyond .ijwb to support multiple IDE/editor metadata patterns:
- Add WT_METADATA_PATTERNS config variable (space-separated list)
- Add WT_KNOWN_METADATA array with 16 known patterns:
  - JetBrains: .idea, .run, .fleet
  - Bazel: .ijwb, .aswb, .clwb, .bazelbsp, .bsp
  - Xcode/iOS: .swiftpm, xcuserdata
  - VS Code: .vscode
  - Scala: .metals, .bloop
  - Eclipse: .settings, .project, .classpath

New scripts:
- bin/wt-metadata-export: Export all configured patterns to vault
- bin/wt-metadata-import: Import all configured patterns to worktree

Install flow changes:
- Scan repo for existing metadata directories
- Interactive checkbox selection (all detected selected by default)
- Save selection to WT_METADATA_PATTERNS

Updated:
- wt-add uses wt-metadata-import
- wt.sh adds metadata-export/import commands (keeps ijwb-* as aliases)
- All find commands use -L to follow symlinks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Detection now finds top-level metadata dirs only
  (e.g., .idea inside .ijwb is not listed separately)
- Export deduplicates by sorting paths and skipping nested ones
- Add tilde expansion for paths containing ~/

Algorithm: sort all found paths, keep only those not inside another kept path

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement context-based switching to manage multiple git repositories with
separate configurations. Each context stores its own worktree paths, metadata
vault location, and default branch.

New commands:
- `wt context` - Interactive context selection
- `wt context <name>` - Switch to named context
- `wt context --list` - List all contexts
- `wt context add` - Full setup flow for new repository

Key changes:
- Add lib/wt-context for context management functions
- Add lib/wt-context-setup for shared setup flow
- Add bin/wt-context command
- Update all commands to show context banner when contexts are configured
- Simplify install.sh to use shared setup library
- Add shell completions for context command

Storage structure:
  ~/.config/wt/repos/<name>.conf  - Per-context configuration
  ~/.config/wt/current            - Current active context name
  ~/.config/wt/idea-files/<name>/ - Per-context metadata vault

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use ${arr[@]+"${arr[@]}"} idiom to safely expand potentially empty
arrays when running with set -u (nounset). This prevents "unbound
variable" errors in _wt_detect_metadata_patterns and
_wt_select_metadata_patterns functions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@guodong-sq guodong-sq force-pushed the feature/multi-repo-context branch from 5d2c6ca to 4ca6b99 Compare February 9, 2026 03:50
@guodong-sq
Copy link
Copy Markdown
Collaborator Author

guodong-sq commented Feb 9, 2026

Have you considered using git config as config source of vault directory path, worktree base path, etc.? That way, wt would largely "work" depending on which repo you're on i.e. context-switching is either (a) cding to another repo, or (b) an --repo path argument you pass down to git -C

Thanks for the suggestion! I think with git config alone there's a challenge with the "run wt from anywhere" use case. Even with git config storing per-repo settings, we'd still need something to answer: "which repo should wt list query when I run it from user root?"

Options would be:

  1. Require being in a repo, can't run wt list, wt cd or wt switch from anywhere
  2. Always pass --repo, wt --repo ~/Development/java list works, but adds friction to every command
  3. Store "current context" somewhere, which brings us back to needing ~/.wt/current or similar

they are all valid options, and UX preferences, I went with "run from anywhere" since I often run wt list or wt cd from random directories.

I can see a place where we use a hybrid approach, where the current context is stored globally (e.g., in ~/.wt/current), then per-repo configurations and shell variables stored in git config. I went with single location for simplicity and put all config in one place. But git config has the advantage of config traveling with the repo. No strong preference either way honestly!

@guodong-sq guodong-sq marked this pull request as ready for review February 9, 2026 05:07
@guodong-sq guodong-sq merged commit 24c24a1 into main Feb 9, 2026
1 check passed
guodong-sq added a commit that referenced this pull request Feb 9, 2026
@guodong-sq guodong-sq deleted the feature/multi-repo-context branch February 9, 2026 05:07
@bezhermoso
Copy link
Copy Markdown
Contributor

bezhermoso commented Feb 10, 2026

Thanks for the suggestion! I think with git config alone there's a challenge with the "run wt from anywhere" use case. Even with git config storing per-repo settings, we'd still need something to answer: "which repo should wt list query when I run it from user root?"

IMO to support multi-repo, wt being context-aware when run within a repo would be the least surprising behavior to most people. I get the need for it to function "globally"/absence of immediate, local context, but I don't believe these two things are necessarily mutually exclusive.

Somewhat tangential, but making "local context" primary and "global context" secondary can even simplify other things e.g. less reliance on sessions/login-shell/interactivity (e.g. no need for source wt.sh), easier installation (e.g. just add to $PATH), etc.

IMO having the core of wt be local-context-first can likely simplify the implementation because of the tighter scope, the session-awareness & other interactivity stuff can easily be a layer above. This split offers a great benefit of minimizing where we have to be POSIX-compliant as we can separate the UX layer & offer shell-specific niceties. This is not an uncommon design pattern in CLI tools.

@guodong-sq
Copy link
Copy Markdown
Collaborator Author

guodong-sq commented Feb 10, 2026

Thanks for the suggestion! I think with git config alone there's a challenge with the "run wt from anywhere" use case. Even with git config storing per-repo settings, we'd still need something to answer: "which repo should wt list query when I run it from user root?"

IMO to support multi-repo, wt being context-aware when run within a repo would be the least surprising behavior to most people. I get the need for it to function "globally"/absence of immediate, local context, but I don't believe these two things are necessarily mutually exclusive.

Somewhat tangential, but making "local context" primary and "global context" secondary can even simplify other things e.g. less reliance on sessions/login-shell/interactivity (e.g. no need for source wt.sh), easier installation (e.g. just add to $PATH), etc.

IMO having the core of wt be local-context-first can likely simplify the implementation because of the tighter scope, the session-awareness & other interactivity stuff can easily be a layer above. This split offers a great benefit of minimizing where we have to be POSIX-compliant as we can separate the UX layer & offer shell-specific niceties. This is not an uncommon design pattern in CLI tools.

Thought about this a little bit more, here are my thoughts

local vs global context priority

I think the real tension is that wt has two kinds of commands with opposite needs: sub commands like wt add, wt metadata-* operates inside a repo, while wt list or wt cd can navigate across repo.
"Local-context-first" optimizes for "work on what I'm in." whereas "Global-context-first" optimizes for "jump to where I want to be.". However this concern is workflow-dependent, I find it beneficial and use navigation commands a lot, but for someone with external tools that help with the navigation, the commands that matter (wt add, wt remove, wt switch, wt metadata-*) are all "operate on the repo I'm in" operations that work better with local detection.
And the multi-session problem is a real correctness issue: two tmux panes running wt context concurrently stomp on each other's state via a shared ~/.wt/current file, potentially creating worktrees in the wrong repo.

the layering / POSIX point

I want to understand this better, were you referring to literally targeting POSIX sh, or more about the principle of keeping shell-specific concerns out of the core? Currently the architecture is:

  • wt.sh must be sourced
  • All bin/wt-* scripts are standalone bash executables
  • Completions are already split into wt.bash and wt.zsh

The only reason sourcing is required today is the wt() dispatcher function and wt cd (can't change the shell's cwd from a subprocess). Every other command already works as a standalone executable. Also the bin/wt-* scripts are all #!/usr/bin/env bash and use bash-isms structurally (arrays, process substitution, [[ ]] throughout). Getting to POSIX sh would be a significant rewrite, and since bash+zsh covers the entire target audience, I'm not sure the payoff is there.

changes required to make local context take precedence

If I understand the suggestion correctly, the split would be:

  • Core layer (pure executables, bash, no sourcing):

    • wt-add, wt-remove, wt-list, wt-switch, wt-metadata-*, wt-context
    • Detect context from cwd. Accept --repo/--context override.
    • takes all input via arguments, non-interactive.
  • UX/Integration layer (interaction, session-aware)

    • interactive menus, confirmation prompts, wt cd, completions, fzf, context banners
    • shell-specific

@bezhermoso Does the above resonate with you?

@bezhermoso
Copy link
Copy Markdown
Contributor

bezhermoso commented Feb 10, 2026

Getting to POSIX sh would be a significant rewrite, and since bash+zsh covers the entire target audience, I'm not sure the payoff is there.

@guodong-sq Ahh yes, I admit I did not dig into the true state of POSIX-compatibility, but simply assumed it was partly the goal given the use of cd ... && pwd common POSIX-compliant method of resolving paths in lieu of non-POSIX realpath. I agree targeting Zsh/Bash is already sufficient.

That resonates. I agree with your analysis of the tension here. Your analysis on what the required changes are for separating core functionality from shell integration is spot-on, and IMO would lead to more correct (or at least least-suprising) behavior, predictability & composability that makes it more attractive to adopt & slot into people's varying workflows.

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