From 172d1e3e4f969a2304aa4b0b69b7d10695f38a11 Mon Sep 17 00:00:00 2001 From: Nathan Gendron Date: Thu, 13 Nov 2025 18:18:55 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Add=20prompts=20for=20GitHub=20C?= =?UTF-8?q?opilot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/copilot-instructions.md | 83 +++++++++++ .github/instructions/ai.instructions.md | 42 ++++++ .../instructions/completions.instructions.md | 133 ++++++++++++++++++ .github/instructions/editor.instructions.md | 45 ++++++ .github/instructions/lib.instructions.md | 28 ++++ .github/instructions/sh.instructions.md | 47 +++++++ .github/instructions/testing.instructions.md | 95 +++++++++++++ 7 files changed, 473 insertions(+) create mode 100644 .github/copilot-instructions.md create mode 100644 .github/instructions/ai.instructions.md create mode 100644 .github/instructions/completions.instructions.md create mode 100644 .github/instructions/editor.instructions.md create mode 100644 .github/instructions/lib.instructions.md create mode 100644 .github/instructions/sh.instructions.md create mode 100644 .github/instructions/testing.instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..efd8f3e --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,83 @@ +# Copilot Instructions + +## Architecture & Flow + +`bin/gtr` (961 lines) dispatches to `cmd_*` functions (case block lines 36‑77). Libraries sourced at startup: + +- `lib/core.sh` - create/list/remove/resolve worktrees +- `lib/config.sh` - git config wrapper with precedence +- `lib/ui.sh` - log_error/log_info/prompts +- `lib/copy.sh` - glob pattern file copying +- `lib/hooks.sh` - postCreate/postRemove execution +- `lib/platform.sh` - OS detection + GUI helpers + +Adapters in `adapters/{editor,ai}` each implement two functions with strict contracts (see below). + +## Key Concepts + +- Special ID `1` = main repo (usable in `open`, `go`, `ai`). +- Folder naming = sanitized branch (`feature/auth` → `feature-auth`). +- Base dir resolution (`resolve_base_dir`): config `gtr.worktrees.dir` → env → default `-worktrees`; relative paths resolved from repo root; tilde expanded; warns if inside repo unignored. +- Target resolution (`resolve_target`): ID `1` → current → sanitized path → scan directories; returns TSV: `is_main\tpath\tbranch`. +- Config precedence (`cfg_default`): git config (local→global→system) → env → fallback. Multi-value keys merged & deduped (`cfg_get_all`). + +## Adapter Contract + +Editor: `editor_can_open`, `editor_open `; AI: `ai_can_start`, `ai_start [args...]`. Must check tool availability (`command -v`), emit errors via `log_error`, never silently fail, and avoid side effects outside the target directory (AI uses subshell `(cd ...)`). Update README, help (`cmd_help`), completions. + +## Manual Testing (Essential Subset) + +```bash +./bin/gtr new feature/x # creates folder feature-x +./bin/gtr open feature/x # loads configured editor +./bin/gtr ai feature/x # starts configured AI tool +./bin/gtr list # lists main + worktrees +./bin/gtr rm feature/x # removes worktree +./bin/gtr go feature/x # prints path (use in cd) +``` + +Advanced: `--force --name backend` (same branch multi-worktree); `git config --add gtr.copy.include "**/.env.example"`; hooks: `git config --add gtr.hook.postCreate "npm install"`. +Full matrix: see `.github/instructions/testing.instructions.md`. + +## Common Changes + +**Add command**: new `cmd_()` function in `bin/gtr` + case entry (lines 36‑77) + help text in `cmd_help` + all three completions (bash/zsh/fish) + README docs. + +**Add adapter**: two functions (see contract below), `log_error` with install instructions, quote all paths, check `command -v`. Update: README, help text (`cmd_help`), completions (all three). + +**Modify core (`lib/*.sh`)**: keep backwards compatibility, always quote variables `"$var"`, support Git <2.22 fallback (`branch --show-current` → `rev-parse --abbrev-ref HEAD`), test manually across macOS/Linux. + +## Patterns & Gotchas + +- Always quote paths (spaces). Avoid unguarded globbing. +- `set -e` active: ensure non-critical failures are guarded (`command || true`). +- Multi-value config keys require `git config --add` (do not overwrite entire list unintentionally). +- If placing worktrees inside repo (relative path), add directory to `.gitignore` to prevent accidental commits. + +## Debugging + +Trace: `bash -x ./bin/gtr new test`; scoped: `set -x` / `set +x`; list function: `declare -f resolve_target`; inspect var: `echo "DEBUG=$var" >&2`; adapter sourcing: `bash -c 'source adapters/ai/claude.sh && ai_can_start && echo OK'`. + +## Troubleshooting Quick + +Permission: `chmod +x bin/gtr`. Missing adapter: `gtr adapter`. Install check: `./bin/gtr doctor`. Config issues: `git config --list | grep gtr`. Worktree confusion: inspect `resolve_target` logic & naming. Symlink problems: ensure `/usr/local/bin` exists then `ln -s "$(pwd)/bin/gtr" /usr/local/bin/gtr`. + +## Version + +Update `GTR_VERSION` (line 8 `bin/gtr`) when releasing; affects `gtr version` / `--version`. + +## Documentation Structure + +- **`.github/copilot-instructions.md`** (this file) - High-level guide for AI agents +- **`.github/instructions/*.instructions.md`** - Specific guidance by file pattern: + - `testing.instructions.md` - Manual testing checklist (applies to: `bin/gtr`, `lib/**/*.sh`, `adapters/**/*.sh`) + - `sh.instructions.md` - Shell scripting conventions (applies to: `**/*.sh`, `**/*.bash`, `**/*.fish`) + - `lib.instructions.md` - Core library modification guidelines (applies to: `lib/**/*.sh`) + - `editor.instructions.md` - Editor adapter contract (applies to: `adapters/editor/**/*.sh`) + - `ai.instructions.md` - AI tool adapter contract (applies to: `adapters/ai/**/*.sh`) + - `completions.instructions.md` - Shell completion updates (applies to: `completions/*`) +- **`README.md`** - User-facing documentation +- **`CONTRIBUTING.md`** - Contribution guidelines +- **`CLAUDE.md`** - Extended development guide for Claude Code + +Feedback: Ask if more detail needed on copy patterns, hooks, or multi-worktree `--force` safety. diff --git a/.github/instructions/ai.instructions.md b/.github/instructions/ai.instructions.md new file mode 100644 index 0000000..bde7500 --- /dev/null +++ b/.github/instructions/ai.instructions.md @@ -0,0 +1,42 @@ +--- +applyTo: adapters/ai/**/*.sh +--- + +# AI Instructions + +## Adding Features + +### New AI Tool Adapter (`adapters/ai/.sh`) + +```bash +#!/usr/bin/env bash +# ToolName adapter + +ai_can_start() { + command -v tool-cli >/dev/null 2>&1 +} + +ai_start() { + local path="$1" + shift + if ! ai_can_start; then + log_error "ToolName not found. Install with: ..." + return 1 + fi + (cd "$path" && tool-cli "$@") # Note: subshell for directory change +} +``` + +**Also update**: Same as editor adapters (README, completions, help text) + +## Contract & Guidelines + +- Must define: `ai_can_start` (0 = available), `ai_start [args...]` (runs in subshell `(cd ...)`). +- Always quote: `"$path"` and arguments; never assume current working directory. +- Use `log_error` + helpful install hint; never silent fail. +- Keep side effects confined to worktree directory; do not modify repo root unintentionally. +- Accept extra args after `--`: preserve ordering (`ai_start` receives already-shifted args). +- Prefer fast startup; heavy initialization belongs in hooks (`postCreate`), not adapters. +- When adding adapter: update `cmd_help`, README tool list, and completions (bash/zsh/fish). +- Test manually: `bash -c 'source adapters/ai/.sh && ai_can_start && echo OK'`. +- Inspect function definition if needed: `declare -f ai_start`. diff --git a/.github/instructions/completions.instructions.md b/.github/instructions/completions.instructions.md new file mode 100644 index 0000000..f682181 --- /dev/null +++ b/.github/instructions/completions.instructions.md @@ -0,0 +1,133 @@ +--- +applyTo: completions/gtr.bash, completions/_gtr, completions/gtr.fish +--- + +# Completions Instructions + +## Overview + +Shell completions provide tab-completion for `gtr` commands, flags, branches, and adapter names across Bash, Zsh, and Fish shells. + +## When to Update Completions + +**Always update all three completion files** when: + +- Adding new commands (e.g., `gtr new-command`) +- Adding new flags to existing commands (e.g., `--new-flag`) +- Adding editor or AI adapters (completion must list available adapters) +- Changing command names or flag names + +## File Responsibilities + +- **`completions/gtr.bash`** - Bash completion (requires bash-completion v2+) +- **`completions/_gtr`** - Zsh completion (uses Zsh completion system) +- **`completions/gtr.fish`** - Fish shell completion + +## Implementation Pattern + +Each completion file implements: + +1. **Command completion** - Top-level commands (`new`, `rm`, `open`, `ai`, `list`, etc.) +2. **Flag completion** - Command-specific flags (e.g., `--from`, `--force`, `--editor`) +3. **Branch completion** - Dynamic completion of existing worktree branches (via `gtr list --porcelain`) +4. **Adapter completion** - Editor names (`cursor`, `vscode`, `zed`) and AI tool names (`aider`, `claude`, `codex`) + +## Testing Completions + +**Manual testing** (no automated tests): + +```bash +# Bash - source the completion file +source completions/gtr.bash +gtr # Should show commands +gtr new # Should show flags +gtr open # Should show branches +gtr open --editor # Should show editor names + +# Zsh - fpath must include completions directory +fpath=(completions $fpath) +autoload -U compinit && compinit +gtr + +# Fish - symlink to ~/.config/fish/completions/ +ln -s "$(pwd)/completions/gtr.fish" ~/.config/fish/completions/ +gtr +``` + +## Branch Completion Logic + +All three completions dynamically fetch current worktree branches: + +- Parse output of `gtr list --porcelain` (tab-separated: `path\tbranch\tstatus`) +- Extract branch column (second field) +- Exclude the special ID `1` (main repo) if needed + +## Adapter Name Updates + +When adding an editor or AI adapter: + +**Bash** (`completions/gtr.bash`): + +- Update `_gtr_editors` array or case statement +- Update flag completion for `--editor` in `open` command + +**Zsh** (`completions/_gtr`): + +- Update `_arguments` completion specs for `--editor` or `--ai` +- Use `_values` or `_alternative` for adapter names + +**Fish** (`completions/gtr.fish`): + +- Update `complete -c gtr` lines for editor/AI flags +- List adapter names explicitly or parse from `gtr adapter` output + +## Keep in Sync + +The three completion files must stay synchronized: + +- Same commands supported +- Same flags for each command +- Same adapter names +- Same branch completion behavior + +## Examples + +**Adding a new command `gtr status`**: + +1. Add `status` to main command list in all three files +2. Add flag completion if the command has flags +3. Test tab completion works + +**Adding a new editor `sublime`**: + +1. Create `adapters/editor/sublime.sh` with contract functions +2. Add `sublime` to editor list in all three completion files +3. Update help text in `bin/gtr` (`cmd_help` function) +4. Update README with installation instructions +5. Test `gtr open --editor s` completes to `sublime` + +## Common Pitfalls + +- **Forgetting to update all three files** - Always update Bash, Zsh, AND Fish +- **Hardcoding adapter names** - Keep adapter lists in sync with actual files in `adapters/{editor,ai}/` +- **Not testing** - Source/reload completions and test with `` key +- **Case sensitivity** - Command and flag names must match exactly (case-sensitive) + +## Bash-Specific Notes + +- Requires `bash-completion` v2+ package +- Use `COMPREPLY` array to return completions +- Use `compgen` to filter based on current word (`$cur`) +- Check `$COMP_CWORD` for argument position + +## Zsh-Specific Notes + +- Uses `_arguments` completion framework +- Supports more sophisticated completion logic (descriptions, grouping) +- Use `_describe` for simple lists, `_arguments` for complex commands + +## Fish-Specific Notes + +- Uses declarative `complete -c gtr` syntax +- Conditions can check previous arguments with `__fish_seen_subcommand_from` +- Can call external commands for dynamic completion diff --git a/.github/instructions/editor.instructions.md b/.github/instructions/editor.instructions.md new file mode 100644 index 0000000..228ba86 --- /dev/null +++ b/.github/instructions/editor.instructions.md @@ -0,0 +1,45 @@ +--- +applyTo: adapters/editor/**/*.sh +--- + +# Editor Instructions + +## Adding Features + +### New Editor Adapter (`adapters/editor/.sh`) + +```bash +#!/usr/bin/env bash +# EditorName adapter + +editor_can_open() { + command -v editor-cli >/dev/null 2>&1 +} + +editor_open() { + local path="$1" + if ! editor_can_open; then + log_error "EditorName not found. Install from https://..." + return 1 + fi + editor-cli "$path" +} +``` + +**Also update**: + +- README.md (setup instructions) +- All three completion files: `completions/gtr.bash`, `completions/_gtr`, `completions/gtr.fish` +- Help text in `bin/gtr` (`cmd_help` function) + +## Contract & Guidelines + +- Required functions: `editor_can_open` (probe via `command -v`), `editor_open `. +- Quote all paths; support spaces. Avoid changing PWD globally—no subshell needed (editor opens path). +- Use `log_error` with actionable install guidance if command missing. +- Keep adapter lean: no project scans, no blocking prompts. +- Naming: file name = tool name (`zed.sh` → `zed` flag). Avoid uppercase. +- Update: README editor list, completions (bash/zsh/fish), help (`Available editors:`), optional screenshots. +- Manual test: `bash -c 'source adapters/editor/.sh && editor_can_open && editor_open . || echo fail'`. +- Fallback behavior: if editor absent, fail clearly; do NOT silently defer to file browser. +- Inspect function definition if needed: `declare -f editor_open`. diff --git a/.github/instructions/lib.instructions.md b/.github/instructions/lib.instructions.md new file mode 100644 index 0000000..d44ed19 --- /dev/null +++ b/.github/instructions/lib.instructions.md @@ -0,0 +1,28 @@ +--- +applyTo: lib/**/*.sh +--- + +# Lib Instructions + +## Modifying Core (`lib/*.sh`) + +- **Maintain backwards compatibility** with existing configs +- **Quote all paths**: Support spaces in directory names +- **Use `log_error` / `log_info`** from `lib/ui.sh` for user messages +- **Git version fallbacks**: Check `lib/core.sh:97-100` for example (Git 2.22+ `--show-current` vs older `rev-parse`) + +## Key Functions & Responsibilities + +- `resolve_base_dir`: config/env/default selection; warn if inside repo & not ignored. +- `resolve_target`: ID `1` + branch/current + sanitized path scan; returns TSV. +- `create_worktree`: decides remote/local/new; respects `--force` + `--name` safety. +- `cfg_default`: precedence local→global→system→env→fallback (do not reorder). +- `cfg_get_all`: merge multi-value keys; preserves order; deduplicates. + +## Change Guidelines + +- Preserve adapter contracts; do not rename exported functions used by `bin/gtr`. +- Add new config keys with `gtr.` prefix; avoid collisions. +- For performance-sensitive loops (e.g. directory scans) prefer built-ins (`find`, `grep`) with minimal subshells. +- Any new Git command: add fallback for older versions or guard with detection. +- Manual test after changes (subset): `new`, `open`, `ai`, `rm`, `list --porcelain`, `config set/get/unset`, `go 1`, hooks run once. diff --git a/.github/instructions/sh.instructions.md b/.github/instructions/sh.instructions.md new file mode 100644 index 0000000..99d0d0b --- /dev/null +++ b/.github/instructions/sh.instructions.md @@ -0,0 +1,47 @@ +--- +applyTo: **/*.bash, **/*.fish, **/*.sh +--- + +# Shell Instructions + +## Architecture + +**Key Pattern**: Everything is sourced at startup (`set -e` enabled). Functions call each other directly. No subshells except for hooks and AI tools. + +## Code Conventions + +### Shell Script Style + +- **Bash 3.2+ compatible** (macOS default), but 4.0+ features allowed where appropriate +- **Always quote variables**: `"$var"` not `$var` +- **Function-scoped vars**: Use `local var="value"` +- **Error handling**: Check return codes; functions return 1 on failure +- **Naming**: `snake_case` for functions/vars, `UPPER_CASE` for constants + +### Strict Mode & Safety + +- Global `set -e` in `bin/gtr`: guard non-critical commands with `|| true`. +- Prefer `[ ]` over `[[ ]]` for POSIX portability (use `[[` only when needed). +- Always quote glob inputs; disable unintended globbing (`set -f` temporarily if required). + +### Portability + +- Target Bash 3.2+: avoid associative arrays; use simple string/loop constructs. +- Avoid `readarray` and process substitution unsupported in older Bash. + +### Debugging + +- Quick trace: `bash -x ./bin/gtr `. +- Inline: wrap suspicious block with `set -x` / `set +x`. +- Function presence: `declare -f create_worktree` or `declare -f resolve_target`. +- Variable inspection: `echo "DEBUG var=$var" >&2` (stderr keeps stdout clean for command substitution). + +### External Commands + +- Keep dependencies minimal: only `git`, `sed`, `awk`, `find`, `grep` (avoid jq/curl unless justified). +- Check availability before use if adding new tools. + +### Quoting & Paths + +- Use `"${var}"`; for loop over lines: `while IFS= read -r line; do ... done` to preserve spaces. +- Sanitize branch names via `sanitize_branch_name` (do NOT duplicate logic elsewhere). diff --git a/.github/instructions/testing.instructions.md b/.github/instructions/testing.instructions.md new file mode 100644 index 0000000..018e062 --- /dev/null +++ b/.github/instructions/testing.instructions.md @@ -0,0 +1,95 @@ +--- +applyTo: bin/gtr, lib/**/*.sh, adapters/**/*.sh +--- + +# Testing Instructions + +Run after core or adapter changes; all manual (no automated tests). + +```bash +# Basic create/remove +./bin/gtr new test-feature # folder test-feature +./bin/gtr rm test-feature # removed + +# Branch sanitization +./bin/gtr new feature/auth # folder feature-auth + +# Remote branch (if exists) +./bin/gtr new existing-remote-branch # checks out tracking branch + +# Local existing branch +./bin/gtr new existing-local-branch # reuses local branch + +# New branch creation +./bin/gtr new brand-new-feature # creates branch + worktree + +# Force multiple worktrees same branch +./bin/gtr new test-feature --force --name backend # test-feature-backend + +# Editor + AI adapters +./bin/gtr config set gtr.editor.default cursor +./bin/gtr open test-feature +./bin/gtr config set gtr.ai.default claude +./bin/gtr ai test-feature + +# Listing +./bin/gtr list # human table +./bin/gtr list --porcelain # path\tbranch\tstatus + +# Navigation +cd "$(./bin/gtr go 1)" # repo root +cd "$(./bin/gtr go test-feature)" # worktree path + +# Config commands +./bin/gtr config set gtr.editor.default cursor +./bin/gtr config get gtr.editor.default +./bin/gtr config set gtr.editor.default vscode --global +./bin/gtr config unset gtr.editor.default + +# Copy patterns +git config --add gtr.copy.include "**/.env.example" +git config --add gtr.copy.exclude "**/.env" +./bin/gtr new test-copy # copies example, not real env + +# Hooks +git config --add gtr.hook.postCreate "echo 'Created!' > /tmp/gtr-test" +./bin/gtr new test-hooks # /tmp/gtr-test exists +git config --add gtr.hook.postRemove "echo 'Removed!' > /tmp/gtr-removed" +./bin/gtr rm test-hooks # /tmp/gtr-removed exists +``` + +## Installation & Environment Verification + +```bash +git --version +./bin/gtr doctor # checks repo, adapters, platform +./bin/gtr adapter # lists editors + AI tools +``` + +## Adapter Sourcing Checks + +```bash +bash -c 'source adapters/editor/cursor.sh && editor_can_open && echo OK' +bash -c 'source adapters/ai/claude.sh && ai_can_start && echo OK' +``` + +## Debugging Toolkit + +```bash +bash -x ./bin/gtr new test-feature # global trace +set -x; create_worktree ...; set +x # scoped trace inside function +declare -f resolve_target # confirm function loaded +echo "DEBUG worktree_path=$worktree_path" >&2 # variable inspection +``` + +## Success Criteria + +- All commands exit 0 (except intentional failures) and produce expected side-effects. +- No unquoted path errors; spaces handled. +- Hooks run only once per creation/removal. +- `list --porcelain` stable for scripting. + +## When Adding Features + +- Extend this matrix minimally (keep concise). +- Prefer adding under relevant section (e.g. new flag under create/remove).