Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ wt <command> [options] [args]
| `create` | Create a new worktree with branch |
| `remove` | Remove a worktree and its branch (auto-detects if inside worktree) |
| `list` | List all worktrees |
| `gha` | Monitor GitHub Actions status for current branch's PR |
| `completion` | Generate shell completion script (bash, zsh, fish) |

### Options
Expand All @@ -138,7 +137,6 @@ wt create --hook setup.sh feat # Create worktree, run setup.sh as hook
wt remove my-feature # Remove worktree and branch
wt remove # Remove current worktree (when inside one)
wt list # List all worktrees
wt gha # Monitor GitHub Actions for current branch's PR
wt completion bash # Generate bash completion script
```

Expand All @@ -160,16 +158,6 @@ Each worktree has its own working directory, so you can have different branches

If your repository has a `.claude/` directory (used by [Claude Code](https://claude.ai/code) for settings and context), `wt` automatically creates a symlink to it in each new worktree. This keeps your Claude configuration in sync across all worktrees without needing to copy or merge changes.

## GitHub Actions Monitoring

The `wt gha` command monitors the CI status for the current branch's pull request:

- Polls GitHub Actions status every 30 seconds
- Displays real-time progress (checks passed/failed/pending)
- Exits with code 0 when all checks pass
- Exits with code 1 if any checks fail, timeout occurs (60 min), or no PR exists
- Requires the [GitHub CLI](https://cli.github.com/) (`gh`) to be installed and authenticated

## Shell Completion

`wt` supports tab completion for bash, zsh, and fish shells. Completions include command names, flags, and dynamic worktree name completion for `wt jump` and `wt remove`.
Expand Down
4 changes: 1 addition & 3 deletions completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func bashCompletion(w io.Writer) error {
local cur prev words cword
_init_completion || return

local commands="jump create remove list gha completion"
local commands="jump create remove list completion"

case "${prev}" in
wt)
Expand Down Expand Up @@ -121,7 +121,6 @@ _wt() {
'create:Create a new worktree with branch'
'remove:Remove a worktree and its branch'
'list:List all worktrees'
'gha:Monitor GitHub Actions status for current branch PR'
'completion:Generate shell completion script'
)

Expand Down Expand Up @@ -178,7 +177,6 @@ complete -c wt -n "__fish_use_subcommand" -a "jump" -d "Jump to a worktree or re
complete -c wt -n "__fish_use_subcommand" -a "create" -d "Create a new worktree with branch"
complete -c wt -n "__fish_use_subcommand" -a "remove" -d "Remove a worktree and its branch"
complete -c wt -n "__fish_use_subcommand" -a "list" -d "List all worktrees"
complete -c wt -n "__fish_use_subcommand" -a "gha" -d "Monitor GitHub Actions status"
complete -c wt -n "__fish_use_subcommand" -a "completion" -d "Generate shell completion script"

# Options
Expand Down
34 changes: 0 additions & 34 deletions config.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,8 @@
package main

import "time"

// Directory structure constants
const (
WorktreesDir = ".worktrees"
ClaudeDir = ".claude"
DefaultHook = ".worktree-hook"
)

// GitHub Actions check statuses
const (
CheckStatusQueued = "QUEUED"
CheckStatusInProgress = "IN_PROGRESS"
CheckStatusCompleted = "COMPLETED"
)

// GitHub Actions check conclusions
const (
CheckConclusionSuccess = "SUCCESS"
CheckConclusionNeutral = "NEUTRAL"
CheckConclusionSkipped = "SKIPPED"
CheckConclusionFailure = "FAILURE"
CheckConclusionCancelled = "CANCELLED"
)

// Check detail markers
const (
MarkerSuccess = "+"
MarkerFailure = "x"
MarkerPending = " "
)

// GitHub Actions polling configuration
const (
DefaultPollInterval = 30 * time.Second
DefaultGHATimeout = 60 * time.Minute
)

// GHATimeout is the timeout for GitHub Actions monitoring (configurable for testing)
var GHATimeout = DefaultGHATimeout
68 changes: 0 additions & 68 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"testing"
"time"
)

func TestConstants(t *testing.T) {
Expand All @@ -18,71 +17,4 @@ func TestConstants(t *testing.T) {
t.Errorf("DefaultHook = %q, want %q", DefaultHook, ".worktree-hook")
}
})

// Test check status constants
t.Run("check status constants", func(t *testing.T) {
if CheckStatusQueued != "QUEUED" {
t.Errorf("CheckStatusQueued = %q, want %q", CheckStatusQueued, "QUEUED")
}
if CheckStatusInProgress != "IN_PROGRESS" {
t.Errorf("CheckStatusInProgress = %q, want %q", CheckStatusInProgress, "IN_PROGRESS")
}
if CheckStatusCompleted != "COMPLETED" {
t.Errorf("CheckStatusCompleted = %q, want %q", CheckStatusCompleted, "COMPLETED")
}
})

// Test check conclusion constants
t.Run("check conclusion constants", func(t *testing.T) {
if CheckConclusionSuccess != "SUCCESS" {
t.Errorf("CheckConclusionSuccess = %q, want %q", CheckConclusionSuccess, "SUCCESS")
}
if CheckConclusionNeutral != "NEUTRAL" {
t.Errorf("CheckConclusionNeutral = %q, want %q", CheckConclusionNeutral, "NEUTRAL")
}
if CheckConclusionSkipped != "SKIPPED" {
t.Errorf("CheckConclusionSkipped = %q, want %q", CheckConclusionSkipped, "SKIPPED")
}
if CheckConclusionFailure != "FAILURE" {
t.Errorf("CheckConclusionFailure = %q, want %q", CheckConclusionFailure, "FAILURE")
}
if CheckConclusionCancelled != "CANCELLED" {
t.Errorf("CheckConclusionCancelled = %q, want %q", CheckConclusionCancelled, "CANCELLED")
}
})

// Test marker constants
t.Run("marker constants", func(t *testing.T) {
if MarkerSuccess != "+" {
t.Errorf("MarkerSuccess = %q, want %q", MarkerSuccess, "+")
}
if MarkerFailure != "x" {
t.Errorf("MarkerFailure = %q, want %q", MarkerFailure, "x")
}
if MarkerPending != " " {
t.Errorf("MarkerPending = %q, want %q", MarkerPending, " ")
}
})

// Test timing constants
t.Run("timing constants", func(t *testing.T) {
if DefaultPollInterval != 30*time.Second {
t.Errorf("DefaultPollInterval = %v, want %v", DefaultPollInterval, 30*time.Second)
}
if DefaultGHATimeout != 60*time.Minute {
t.Errorf("DefaultGHATimeout = %v, want %v", DefaultGHATimeout, 60*time.Minute)
}
})

// Test that GHATimeout defaults to DefaultGHATimeout
t.Run("GHATimeout default", func(t *testing.T) {
// Reset to default if modified
origTimeout := GHATimeout
defer func() { GHATimeout = origTimeout }()

GHATimeout = DefaultGHATimeout
if GHATimeout != DefaultGHATimeout {
t.Errorf("GHATimeout = %v, want %v", GHATimeout, DefaultGHATimeout)
}
})
}
207 changes: 0 additions & 207 deletions gha.go

This file was deleted.

Loading
Loading