Skip to content

Commit e56424d

Browse files
committed
refactor: enhance adapter management and command structure
- Introduced a new adapter loading infrastructure in `lib/adapters.sh`, consolidating editor and AI adapter definitions into registries for improved maintainability. - Updated the `bin/gtr` script to source command handlers dynamically, streamlining command execution. - Added new commands for listing available adapters and starting AI tools, enhancing user interaction and functionality. - Removed outdated individual adapter scripts, transitioning to a registry-based approach for standard adapters, which simplifies the addition of new tools. - Improved documentation in various instruction files to clarify when to use registry entries versus custom adapter files.
1 parent 98858e3 commit e56424d

43 files changed

Lines changed: 2368 additions & 2279 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/instructions/ai.instructions.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,26 @@
22
applyTo: adapters/ai/**/*.sh
33
---
44

5-
# AI Instructions
5+
# AI Adapter Instructions
66

7-
## Adding Features
7+
## When to Use a File vs Registry
88

9-
### New AI Tool Adapter (`adapters/ai/<name>.sh`)
9+
Most AI tools are defined as **registry entries** in `lib/adapters.sh` — no adapter file needed.
10+
Only create an adapter file in `adapters/ai/` for tools that need **custom behavior** beyond the standard builder (see `claude.sh` or `cursor.sh` for examples).
11+
12+
## Adding a Standard AI Tool (Registry)
13+
14+
Add a line to `_AI_REGISTRY` in `lib/adapters.sh`:
15+
16+
```
17+
yourname|yourcmd|ToolName not found. Install with: ...|Extra info;More info
18+
```
19+
20+
Format: `name|cmd|err_msg|info_lines` (info lines are semicolon-separated)
21+
22+
## Adding a Custom AI Tool (File Override)
23+
24+
Create `adapters/ai/<name>.sh` implementing:
1025

1126
```bash
1227
#!/usr/bin/env bash
@@ -27,7 +42,9 @@ ai_start() {
2742
}
2843
```
2944

30-
**Also update**: Same as editor adapters (README, completions, help text)
45+
File-based adapters take precedence over registry entries of the same name.
46+
47+
**Also update**: README, completions (bash/zsh/fish), help text in `lib/commands/help.sh`
3148

3249
## Contract & Guidelines
3350

@@ -38,5 +55,4 @@ ai_start() {
3855
- Accept extra args after `--`: preserve ordering (`ai_start` receives already-shifted args).
3956
- Prefer fast startup; heavy initialization belongs in hooks (`postCreate`), not adapters.
4057
- When adding adapter: update `cmd_help`, README tool list, and completions (bash/zsh/fish).
41-
- Test manually: `bash -c 'source adapters/ai/<tool>.sh && ai_can_start && echo OK'`.
4258
- Inspect function definition if needed: `declare -f ai_start`.

.github/instructions/editor.instructions.md

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,28 @@
22
applyTo: adapters/editor/**/*.sh
33
---
44

5-
# Editor Instructions
5+
# Editor Adapter Instructions
66

7-
## Adding Features
7+
## When to Use a File vs Registry
88

9-
### New Editor Adapter (`adapters/editor/<name>.sh`)
9+
Most editors are defined as **registry entries** in `lib/adapters.sh` — no adapter file needed.
10+
Only create an adapter file in `adapters/editor/` for editors that need **custom behavior** beyond what the standard/terminal builders provide (see `nano.sh` for an example).
11+
12+
## Adding a Standard Editor (Registry)
13+
14+
Add a line to `_EDITOR_REGISTRY` in `lib/adapters.sh`:
15+
16+
```
17+
yourname|yourcmd|standard|EditorName not found. Install from https://...|flags
18+
```
19+
20+
Format: `name|cmd|type|err_msg|flags`
21+
- `type`: `standard` (GUI app) or `terminal` (runs in terminal)
22+
- `flags`: comma-separated — `workspace` (supports .code-workspace), `background` (terminal bg)
23+
24+
## Adding a Custom Editor (File Override)
25+
26+
Create `adapters/editor/<name>.sh` implementing:
1027

1128
```bash
1229
#!/usr/bin/env bash
@@ -26,20 +43,21 @@ editor_open() {
2643
}
2744
```
2845

46+
File-based adapters take precedence over registry entries of the same name.
47+
2948
**Also update**:
3049

3150
- README.md (setup instructions)
3251
- All three completion files: `completions/gtr.bash`, `completions/_git-gtr`, `completions/gtr.fish`
33-
- Help text in `bin/gtr` (`cmd_help` function)
52+
- Help text in `lib/commands/help.sh` (`cmd_help` function)
3453

3554
## Contract & Guidelines
3655

3756
- Required functions: `editor_can_open` (probe via `command -v`), `editor_open <path>`.
3857
- Quote all paths; support spaces. Avoid changing PWD globally—no subshell needed (editor opens path).
3958
- Use `log_error` with actionable install guidance if command missing.
4059
- Keep adapter lean: no project scans, no blocking prompts.
41-
- Naming: file name = tool name (`zed.sh``zed` flag). Avoid uppercase.
60+
- Naming: file/registry name = tool name (`zed``zed` flag). Avoid uppercase.
4261
- Update: README editor list, completions (bash/zsh/fish), help (`Available editors:`), optional screenshots.
43-
- Manual test: `bash -c 'source adapters/editor/<tool>.sh && editor_can_open && editor_open . || echo fail'`.
4462
- Fallback behavior: if editor absent, fail clearly; do NOT silently defer to file browser.
4563
- Inspect function definition if needed: `declare -f editor_open`.

.github/instructions/lib.instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ applyTo: lib/**/*.sh
2121

2222
## Change Guidelines
2323

24-
- Preserve adapter contracts; do not rename exported functions used by `bin/gtr`.
24+
- Preserve adapter contracts; do not rename exported functions used by command handlers in `lib/commands/`.
2525
- Add new config keys with `gtr.<name>` prefix; avoid collisions.
2626
- For performance-sensitive loops (e.g. directory scans) prefer built-ins (`find`, `grep`) with minimal subshells.
2727
- Any new Git command: add fallback for older versions or guard with detection.

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
- name: Run ShellCheck
2020
run: |
21-
shellcheck bin/gtr bin/git-gtr lib/*.sh adapters/editor/*.sh adapters/ai/*.sh
21+
shellcheck bin/gtr bin/git-gtr lib/*.sh lib/commands/*.sh adapters/editor/*.sh adapters/ai/*.sh
2222
2323
test:
2424
name: Tests

CLAUDE.md

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,30 @@ mkdir -p /tmp/gtr-test && cd /tmp/gtr-test && git init && git commit --allow-emp
3939
### Binary Structure
4040

4141
- `bin/git-gtr` — Thin wrapper enabling `git gtr` subcommand invocation
42-
- `bin/gtr`Main script (~1960 lines), contains `main()` dispatcher + all `cmd_*` handlers
42+
- `bin/gtr`Entry point (~105 lines): sources libraries and commands, contains `main()` dispatcher
4343

4444
### Module Structure
4545

46-
| File | Purpose |
47-
| ----------------- | ----------------------------------------------------------------------------------------------------------- |
48-
| `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` |
49-
| `lib/config.sh` | Git config wrapper with precedence: `cfg_get`, `cfg_default`, `cfg_get_all` |
50-
| `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` |
51-
| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove |
52-
| `lib/ui.sh` | Logging (`log_error`, `log_info`, `log_warn`), prompts, formatting |
53-
| `lib/platform.sh` | OS detection, GUI helpers |
46+
| File | Purpose |
47+
| ------------------ | ----------------------------------------------------------------------------------------------------------- |
48+
| `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` |
49+
| `lib/config.sh` | Git config wrapper with precedence: `cfg_get`, `cfg_default`, `cfg_get_all` |
50+
| `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` |
51+
| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove |
52+
| `lib/ui.sh` | Logging (`log_error`, `log_info`, `log_warn`), prompts, formatting |
53+
| `lib/platform.sh` | OS detection, GUI helpers |
54+
| `lib/adapters.sh` | Adapter registry, builder functions, generic fallbacks, loader functions |
55+
| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, etc. (16 files) |
5456

5557
### Adapters
5658

57-
Editor adapters in `adapters/editor/` and AI adapters in `adapters/ai/` are dynamically sourced via `load_editor_adapter()` and `load_ai_adapter()` in `bin/gtr`.
59+
Most adapters are defined declaratively in the **adapter registry** (`lib/adapters.sh`) using pipe-delimited entries. Custom adapters that need special logic remain as override files in `adapters/editor/` and `adapters/ai/`.
5860

59-
**Editor adapters** (atom, cursor, emacs, idea, nano, nvim, pycharm, sublime, vim, vscode, webstorm, zed): implement `editor_can_open()` + `editor_open(path)`.
61+
**Registry-defined adapters**: atom, cursor, emacs, idea, nvim, pycharm, sublime, vim, vscode, webstorm, zed (editors) and aider, auggie, codex, continue, copilot, gemini, opencode (AI).
6062

61-
**AI adapters** (aider, auggie, claude, codex, continue, copilot, cursor, gemini, opencode): implement `ai_can_start()` + `ai_start(path, args...)`.
63+
**Custom adapter files**: `adapters/editor/nano.sh`, `adapters/ai/claude.sh`, `adapters/ai/cursor.sh` — these implement `editor_can_open()`/`editor_open()` or `ai_can_start()`/`ai_start()` directly.
6264

63-
**Generic fallback**: `GTR_EDITOR_CMD` / `GTR_AI_CMD` env vars allow custom tools without adapter files.
65+
**Loading order**: file override → registry → generic PATH fallback. `GTR_EDITOR_CMD` / `GTR_AI_CMD` env vars allow custom tools without adapters.
6466

6567
### Command Flow
6668

@@ -106,15 +108,17 @@ cmd_editor() → resolve_target() → load_editor_adapter() → editor_open()
106108

107109
### Adding a New Command
108110

109-
1. Add `cmd_<name>()` function in `bin/gtr`
110-
2. Add case entry in `main()` dispatcher (around line 71)
111-
3. Add help text in `cmd_help()`
111+
1. Create `lib/commands/<name>.sh` with `cmd_<name>()` function
112+
2. Add case entry in `main()` dispatcher in `bin/gtr`
113+
3. Add help text in `lib/commands/help.sh`
112114
4. Update all three completion files: `completions/gtr.bash`, `completions/_git-gtr`, `completions/git-gtr.fish`
113115
5. Update README.md
114116

115117
### Adding an Adapter
116118

117-
Create `adapters/{editor,ai}/<name>.sh` implementing the two required functions (see existing adapters for patterns). Then update: help text in `cmd_help()` and `load_*_adapter()`, all three completions, README.md.
119+
**Standard adapters** (just a command name + error message): Add an entry to `_EDITOR_REGISTRY` or `_AI_REGISTRY` in `lib/adapters.sh`. Then update: help text in `lib/commands/help.sh`, all three completions, README.md.
120+
121+
**Custom adapters** (special logic needed): Create `adapters/{editor,ai}/<name>.sh` implementing the two required functions (see `adapters/ai/claude.sh` for an example). File-based adapters take priority over registry entries.
118122

119123
### Updating the Version
120124

CONTRIBUTING.md

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,25 @@ We welcome feature suggestions! Please:
3232

3333
```
3434
git-worktree-runner/
35-
├── bin/gtr # Main executable dispatcher
35+
├── bin/gtr # Main executable (~105 lines: sources libs, dispatches commands)
3636
├── lib/ # Core functionality
37-
│ ├── core.sh # Git worktree operations
37+
│ ├── ui.sh # User interface (logging, prompts)
3838
│ ├── config.sh # Configuration (git-config wrapper)
3939
│ ├── platform.sh # OS-specific utilities
40-
│ ├── ui.sh # User interface (logging, prompts)
40+
│ ├── core.sh # Git worktree operations
4141
│ ├── copy.sh # File copying logic
42-
│ └── hooks.sh # Hook execution
43-
├── adapters/ # Pluggable integrations
44-
│ ├── editor/ # Editor adapters (cursor, vscode, zed)
45-
│ └── ai/ # AI tool adapters (aider)
42+
│ ├── hooks.sh # Hook execution
43+
│ ├── provider.sh # GitHub/GitLab provider detection
44+
│ ├── adapters.sh # Adapter registries, builders, and loaders
45+
│ └── commands/ # Command handlers (one file per command)
46+
│ ├── create.sh # cmd_create + helpers
47+
│ ├── remove.sh # cmd_remove
48+
│ ├── rename.sh # cmd_rename
49+
│ ├── ... # (16 files total, one per command)
50+
│ └── help.sh # cmd_help
51+
├── adapters/ # Custom adapter overrides (non-registry)
52+
│ ├── editor/nano.sh # nano (custom terminal behavior)
53+
│ └── ai/ # claude.sh, cursor.sh (custom logic)
4654
├── completions/ # Shell completions (bash, zsh, fish)
4755
└── templates/ # Example configs and scripts
4856
```
@@ -92,60 +100,43 @@ do_something() {
92100

93101
#### Adding an Editor Adapter
94102

95-
1. Create `adapters/editor/yourname.sh`:
103+
Most editors follow a standard pattern and can be added as a **registry entry** in `lib/adapters.sh` (no separate file needed).
96104

97-
```bash
98-
#!/usr/bin/env bash
99-
# YourEditor adapter
105+
**Option A: Registry entry** (preferred for standard editors)
100106

101-
editor_can_open() {
102-
command -v yourcommand >/dev/null 2>&1
103-
}
107+
Add a line to `_EDITOR_REGISTRY` in `lib/adapters.sh`:
104108

105-
editor_open() {
106-
local path="$1"
109+
```
110+
yourname|yourcmd|standard|YourEditor not found. Install from https://...|flags
111+
```
107112

108-
if ! editor_can_open; then
109-
log_error "YourEditor not found. Install from https://..."
110-
return 1
111-
fi
113+
Format: `name|cmd|type|err_msg|flags` where:
114+
- `type`: `standard` (GUI app) or `terminal` (runs in current terminal)
115+
- `flags`: comma-separated — `workspace` (supports .code-workspace files), `background` (run in background)
112116

113-
yourcommand "$path"
114-
}
115-
```
117+
**Option B: Custom adapter file** (for editors with non-standard behavior)
118+
119+
Create `adapters/editor/yourname.sh` implementing `editor_can_open()` and `editor_open()`. See `adapters/editor/nano.sh` for an example.
116120

117-
2. Update README.md with setup instructions
118-
3. Update completions to include new editor
119-
4. Test on macOS, Linux, and Windows if possible
121+
**Also update**: README.md, all three completion files, help text in `lib/commands/help.sh`.
120122

121123
#### Adding an AI Tool Adapter
122124

123-
1. Create `adapters/ai/yourtool.sh`:
125+
**Option A: Registry entry** (preferred for standard CLI tools)
124126

125-
```bash
126-
#!/usr/bin/env bash
127-
# YourTool AI adapter
127+
Add a line to `_AI_REGISTRY` in `lib/adapters.sh`:
128128

129-
ai_can_start() {
130-
command -v yourtool >/dev/null 2>&1
131-
}
129+
```
130+
yourname|yourcmd|YourTool not found. Install with: ...|Extra info line 1;Extra info line 2
131+
```
132132

133-
ai_start() {
134-
local path="$1"
135-
shift
133+
Format: `name|cmd|err_msg|info_lines` (info lines are semicolon-separated).
136134

137-
if ! ai_can_start; then
138-
log_error "YourTool not found. Install with: ..."
139-
return 1
140-
fi
135+
**Option B: Custom adapter file** (for tools with non-standard behavior)
141136

142-
(cd "$path" && yourtool "$@")
143-
}
144-
```
137+
Create `adapters/ai/yourname.sh` implementing `ai_can_start()` and `ai_start()`. See `adapters/ai/claude.sh` for an example.
145138

146-
2. Update README.md
147-
3. Update completions
148-
4. Add example usage
139+
**Also update**: README.md, completions, help text.
149140

150141
#### Adding Core Features
151142

adapters/ai/aider.sh

Lines changed: 0 additions & 7 deletions
This file was deleted.

adapters/ai/auggie.sh

Lines changed: 0 additions & 7 deletions
This file was deleted.

adapters/ai/codex.sh

Lines changed: 0 additions & 10 deletions
This file was deleted.

adapters/ai/continue.sh

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)