feat(editor): support opening .code-workspace files for VS Code/Cursor#78
Conversation
- Add resolve_workspace_file() helper to detect workspace files - Update cursor.sh and vscode.sh adapters to accept optional workspace arg - Auto-detect *.code-workspace files in worktree root - Add gtr.editor.workspace config option (or defaults.workspace in .gtrconfig) - Support 'none' value to disable workspace lookup entirely - Update documentation (configuration.md, .gtrconfig.example, CLAUDE.md)
WalkthroughAdds workspace-file support for VS Code/Cursor: new config key Changes
Sequence DiagramsequenceDiagram
participant User
participant gtr as bin/gtr
participant FS as Filesystem
participant Adapter as Editor Adapter
participant Editor as VS Code/Cursor
User->>gtr: gtr editor / gtr create --editor
gtr->>gtr: resolve_workspace_file(worktree_path)
gtr->>FS: Read config gtr.editor.workspace / .gtrconfig editor.workspace
alt Config == "none"
gtr->>gtr: skip workspace lookup
else Config specifies path
gtr->>FS: check configured workspace file exists
else (no config)
gtr->>FS: auto-detect *.code-workspace at worktree root
end
gtr->>Adapter: editor_open(path, workspace_file?)
alt workspace_file present and valid
Adapter->>Editor: open workspace_file
else
Adapter->>Editor: open folder path
end
Editor-->>User: editor ready
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (2)
🧰 Additional context used📓 Path-based instructions (7)bin/gtr📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
{bin/gtr,lib/**/*.sh,adapters/**/*.sh}📄 CodeRabbit inference engine (.github/instructions/testing.instructions.md)
Files:
lib/**/*.sh📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.sh📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
lib/config.sh📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{bash,fish,sh}📄 CodeRabbit inference engine (.github/instructions/sh.instructions.md)
Files:
README.md📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (1)📚 Learning: 2025-12-29T18:46:36.983ZApplied to files:
🔇 Additional comments (10)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @bin/gtr:
- Around line 1319-1321: Add the new configuration option description to the
cmd_help output under the CONFIGURATION OPTIONS section so users can discover
it; update the help text string in the cmd_help function to include an entry for
"gtr.editor.workspace" with a short description like: "gtr.editor.workspace
VS Code/Cursor workspace file path (relative to worktree root, or \"none\" to
disable)" so it appears alongside the other options in the help output.
🧹 Nitpick comments (1)
bin/gtr (1)
1341-1346: Non-deterministic ordering when multiple workspace files exist.The
find | head -1returns the first file found, but filesystem ordering is not guaranteed. If users have multiple.code-workspacefiles, results may vary across runs or systems.Consider sorting for deterministic behavior:
🔧 Proposed fix for deterministic ordering
# Auto-detect: find first .code-workspace in worktree root local ws_file - ws_file=$(find "$worktree_path" -maxdepth 1 -name "*.code-workspace" -type f 2>/dev/null | head -1) + ws_file=$(find "$worktree_path" -maxdepth 1 -name "*.code-workspace" -type f 2>/dev/null | LC_ALL=C sort | head -1) if [ -n "$ws_file" ]; then echo "$ws_file" fi
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
CLAUDE.mdadapters/editor/cursor.shadapters/editor/vscode.shbin/gtrdocs/configuration.mdtemplates/.gtrconfig.example
🧰 Additional context used
📓 Path-based instructions (9)
adapters/{editor,ai}/**/*.sh
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
adapters/{editor,ai}/**/*.sh: Adapters inadapters/{editor,ai}must each implement two functions with strict contracts: Editor requireseditor_can_openandeditor_open <path>; AI requiresai_can_startandai_start <path> [args...]
Adapter functions must check tool availability usingcommand -v, emit errors vialog_error, never silently fail, and avoid side effects outside the target directory
Files:
adapters/editor/vscode.shadapters/editor/cursor.sh
**/*.sh
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.sh: Always quote paths to handle spaces and special characters; avoid unguarded globbing
Keepset -eactive in shell scripts; ensure non-critical failures are guarded withcommand || true
**/*.sh: Use shebang#!/usr/bin/env bash(not/bin/bashor/bin/sh) for Bash scripts
Use snake_case naming for functions in Bash scripts
Use snake_case for local variables and UPPER_CASE for constants/environment variables in Bash scripts
Use 2-space indentation (no tabs) in Bash scripts
Always quote variables and paths in Bash scripts to prevent word splitting and globbing issues
Check return codes and use|| exit 1or|| return 1for error handling in Bash scripts
Useset -efor error handling in Bash scripts
Uselocalkeyword for function-scoped variables in Bash scripts
Files:
adapters/editor/vscode.shadapters/editor/cursor.sh
adapters/editor/**/*.sh
📄 CodeRabbit inference engine (.github/instructions/editor.instructions.md)
adapters/editor/**/*.sh: Editor adapter must implementeditor_can_open()function that probes for command availability usingcommand -voperator
Editor adapter must implementeditor_open <path>function that opens the given path in the editor
Quote all paths in shell commands to support spaces and special characters
Uselog_errorfunction with actionable installation guidance when the editor command is not found
Do not change PWD globally in editor adapters; avoid using subshells when opening editors
Keep adapter implementations lean: avoid project scans, blocking prompts, and unnecessary logic
Name editor adapter files using lowercase tool name (e.g.,zed.shfor the Zed editor, not uppercase)
If editor command is missing, fail clearly with an error message; do not silently defer to a file browser fallback
Files:
adapters/editor/vscode.shadapters/editor/cursor.sh
**/*.{bash,fish,sh}
📄 CodeRabbit inference engine (.github/instructions/sh.instructions.md)
**/*.{bash,fish,sh}: Bash 3.2+ compatible (macOS default), but 4.0+ features allowed where appropriate
Always quote variables: use"$var"not$var
Use function-scoped variables:local var="value"
Check return codes; functions return 1 on failure
Usesnake_casefor functions and variables,UPPER_CASEfor constants
Prefer[ ]over[[ ]]for POSIX portability; use[[only when needed
Always quote glob inputs; disable unintended globbing withset -ftemporarily if required
Avoid associative arrays in shell scripts; use simple string/loop constructs for Bash 3.2+ compatibility
Avoidreadarrayand process substitution unsupported in older Bash
Debug withbash -x ./bin/gtr <cmd>or wrap suspicious blocks withset -x/set +x
Check function presence withdeclare -f create_worktreeordeclare -f resolve_target
Use stderr for variable inspection:echo "DEBUG var=$var" >&2to keep stdout clean for command substitution
Keep dependencies minimal: only usegit,sed,awk,find,grep; avoid jq/curl unless justified
Check availability of external commands before use when adding new tools
Use"${var}"for variable expansion; for line loops usewhile IFS= read -r line; do ... doneto preserve spaces
Sanitize branch names viasanitize_branch_namefunction; do NOT duplicate logic elsewhere
Everything is sourced at startup withset -eenabled; functions call each other directly; no subshells except for hooks and AI tools
Files:
adapters/editor/vscode.shadapters/editor/cursor.sh
{bin/gtr,lib/**/*.sh,adapters/**/*.sh}
📄 CodeRabbit inference engine (.github/instructions/testing.instructions.md)
{bin/gtr,lib/**/*.sh,adapters/**/*.sh}: All commands must exit 0 (except intentional failures) and produce expected side-effects
No unquoted path errors; spaces must be handled in file paths
Hooks must run only once per creation/removal event
Files:
adapters/editor/vscode.shadapters/editor/cursor.shbin/gtr
adapters/**/*.sh
📄 CodeRabbit inference engine (.github/instructions/testing.instructions.md)
Adapter sourcing must be verifiable with function existence checks like
editor_can_openandai_can_start
Files:
adapters/editor/vscode.shadapters/editor/cursor.sh
adapters/editor/*.sh
📄 CodeRabbit inference engine (CLAUDE.md)
adapters/editor/*.sh: Editor adapters must implementeditor_can_open()function that returns 0 if the editor is available and non-zero otherwise
Editor adapters must implementeditor_open(path)function that opens the editor at the specified path
Editor adapter files must be placed inadapters/editor/directory and follow the naming patternadapters/editor/<name>.sh
Files:
adapters/editor/vscode.shadapters/editor/cursor.sh
adapters/{editor,ai}/*.sh
📄 CodeRabbit inference engine (CLAUDE.md)
Editor and AI adapters should use
log_errorfromlib/ui.shfor user-facing error messages
Files:
adapters/editor/vscode.shadapters/editor/cursor.sh
bin/gtr
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
bin/gtr: Dispatch commands throughcmd_*functions inbin/gtr(case block lines 36‑77)
UpdateGTR_VERSIONon line 8 ofbin/gtrwhen releasing; this affectsgtr version/--versionoutputGlobal
set -einbin/gtr: guard non-critical commands with|| true
list --porcelainoutput must remain stable for scripting purposes
bin/gtr: Updatebin/gtrversion constant (GTR_VERSION) when releasing a new version
Update help text inbin/gtrby searching for 'Available editors:' incmd_helpfunction andload_editor_adapterfunction when adding a new editor adapter
Update help text inbin/gtrby searching for 'Available AI tools:' incmd_helpfunction andload_ai_adapterfunction when adding a new AI tool adapter
Files:
bin/gtr
🧠 Learnings (1)
📚 Learning: 2025-12-29T18:46:36.983Z
Learnt from: helizaga
Repo: coderabbitai/git-worktree-runner PR: 64
File: bin/gtr:746-750
Timestamp: 2025-12-29T18:46:36.983Z
Learning: When error messages reference missing CLI tools (such as gh for GitHub CLI), use platform-agnostic installation guidance by directing users to the official website (e.g., https://cli.github.com/) instead of platform-specific package managers (brew, apt, choco) to ensure the guidance works across all operating systems. Apply this messaging to the bin/gtr script where applicable.
Applied to files:
bin/gtr
🧬 Code graph analysis (1)
adapters/editor/cursor.sh (2)
adapters/editor/vim.sh (1)
editor_can_open(5-7)lib/ui.sh (1)
log_error(12-14)
🔇 Additional comments (10)
CLAUDE.md (2)
446-446: LGTM!The new
gtr.editor.workspaceconfiguration key is well-documented with clear description of its purpose and auto-detection behavior.
463-474: LGTM!The .gtrconfig key mapping table is properly updated with the new
gtr.editor.workspace→defaults.workspacemapping, maintaining consistent formatting with existing entries.templates/.gtrconfig.example (1)
57-62: LGTM!The workspace configuration documentation is clear and comprehensive. It properly explains:
- Explicit workspace file path configuration
- Auto-detection fallback behavior
- The
nonevalue to disable workspace lookupThe commented examples follow the established template pattern.
adapters/editor/cursor.sh (1)
9-25: LGTM!The implementation correctly:
- Accepts an optional
workspace_fileparameter with proper default- Uses properly quoted variables throughout
- Falls back to directory opening when workspace is not provided or doesn't exist
- Follows the adapter contract and coding guidelines
adapters/editor/vscode.sh (1)
9-25: LGTM!The implementation is consistent with the cursor.sh adapter:
- Optional workspace parameter with safe default
- Proper variable quoting
- Correct fallback behavior when workspace file is missing
docs/configuration.md (2)
109-114: LGTM!The new
gtr.editor.workspaceconfiguration option is well-documented with clear comments explaining the behavior and default auto-detection.
123-131: LGTM!The "Workspace files" section provides clear documentation of the workspace resolution behavior:
- Explicit configuration takes precedence
nonedisables lookup- Auto-detection of
*.code-workspacefiles- Fallback to folder opening
This matches the implementation described in the PR and provides users with actionable guidance.
bin/gtr (3)
38-51: LGTM!The function correctly handles the optional workspace parameter with proper fallback behavior. The
targetvariable approach cleanly separates the decision logic from the command execution, and quoting is correct for paths with spaces.
314-317: LGTM!Correct integration of workspace resolution into the create workflow. The workspace file is resolved after loading the adapter, allowing adapters to potentially provide their own
resolve_workspace_fileoverride if needed.
715-718: LGTM!Consistent implementation matching the
cmd_createpattern.
- Add missing config key mapping in lib/config.sh for gtr.editor.workspace - Fix .gtrconfig key naming: defaults.workspace → editor.workspace for consistency - Fix bug: explicit config now takes precedence (no auto-detect fallback when file missing) - Update README examples to use claude instead of aider
550c774 to
02dff6c
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
1 similar comment
✅ Actions performedReview triggered.
|
Pull Request
Description
Add support for opening .code-workspace files when launching editors from gtr.
This introduces a small helper to resolve workspace files, updates the VS Code and Cursor editor adapters to optionally open a workspace instead of a folder, and adds configuration to control this behavior.
Motivation
Many projects rely on .code-workspace files to define multi-root setups, editor settings, and recommended extensions. Currently, gtr always opens the worktree directory, even when a workspace file is present, requiring users to manually open it afterward.
This change makes gtr respect workspace files when available, improving the editor workflow while keeping existing behavior as a fallback.
Fixes #77
Type of Change
Testing
Manual Testing Checklist
Tested on:
Core functionality tested:
git gtr new <branch>- Create worktreegit gtr go <branch>- Navigate to worktreegit gtr editor <branch>- Open in editor (if applicable)git gtr ai <branch>- Start AI tool (if applicable)git gtr rm <branch>- Remove worktreegit gtr list- List worktreesgit gtr config- Configuration commands (if applicable)Test Steps
.code-workspacefile in the rootgit gtr editor <branch>and verify the workspace file is openedgtr.editor.workspaceto a specific file and verify it is respectednoneand verify the editor opens the folder insteadExpected behavior:
Actual behavior:
Breaking Changes
Checklist
Before submitting this PR, please check:
git gtr(production) and./bin/gtr(development)Additional Context
This change is intentionally opt-in and conservative:
License Acknowledgment
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache License 2.0.
Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.