claude-worktree 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -0
- data/lib/claude/worktree/version.rb +1 -1
- data/lib/cwt/repository.rb +10 -5
- data/lib/cwt/view.rb +27 -17
- data/lib/cwt/worktree.rb +17 -3
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f68f3cf3d0c293ec2a023f465bc7cd2a9dd4115011e93fb027c9ca0a94ced718
|
|
4
|
+
data.tar.gz: ebfaeb8f5ef8a443dc03b5565c682ee11300f2749a7659935ac15cf620bb51ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56b6b1e6f4990a10834095b1ffcea614a999c3463668fb9191ee51ac0f4fd30c9a4790b1c2757c4a84b69eb7e2c714ba424297682c19d5dd04e713dde2b27533
|
|
7
|
+
data.tar.gz: 0fad5b624dbe7ee5084dcd792c01fe6b7a8e1caafe09a1e7e09d88f8997d0b72d27c1ba7bf511e0742b5543b185966e3293fc5cd821f74458ddf98a063dd171a
|
data/README.md
CHANGED
|
@@ -69,6 +69,14 @@ npm ci
|
|
|
69
69
|
echo "Ready to rock!"
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
+
### Base Branch
|
|
73
|
+
|
|
74
|
+
By default, new worktrees branch off of `HEAD`. To always branch from a specific starting point (e.g., `main`), set the `CWT_START_POINT` environment variable:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
export CWT_START_POINT=main
|
|
78
|
+
```
|
|
79
|
+
|
|
72
80
|
## 🎮 Usage
|
|
73
81
|
|
|
74
82
|
Run `cwt` in the root of any Git repository.
|
data/lib/cwt/repository.rb
CHANGED
|
@@ -80,7 +80,7 @@ module Cwt
|
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
worktrees.find do |wt|
|
|
83
|
-
wt.name == name_or_path || wt.path == normalized_path
|
|
83
|
+
wt.name == name_or_path || wt.branch == name_or_path || wt.path == normalized_path
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
@@ -89,16 +89,21 @@ module Cwt
|
|
|
89
89
|
def create_worktree(name)
|
|
90
90
|
require_relative 'worktree'
|
|
91
91
|
|
|
92
|
-
# Sanitize name
|
|
93
|
-
safe_name = name.strip
|
|
92
|
+
# Sanitize name (allow / for branch name hierarchy)
|
|
93
|
+
safe_name = name.strip
|
|
94
|
+
.gsub(%r{[^a-zA-Z0-9_\-/]}, '_')
|
|
95
|
+
.gsub(%r{/+}, '/')
|
|
96
|
+
.gsub(%r{^/|/$}, '')
|
|
94
97
|
path = File.join(worktrees_dir, safe_name)
|
|
95
98
|
absolute_path = File.join(@root, WORKTREE_DIR, safe_name)
|
|
96
99
|
|
|
97
|
-
# Ensure .worktrees
|
|
98
|
-
FileUtils.mkdir_p(
|
|
100
|
+
# Ensure parent directories exist (e.g. .worktrees/feat/ for feat/my-feature)
|
|
101
|
+
FileUtils.mkdir_p(File.dirname(path))
|
|
99
102
|
|
|
100
103
|
# Create worktree with new branch
|
|
101
104
|
cmd = ["git", "-C", @root, "worktree", "add", "-b", safe_name, path]
|
|
105
|
+
base_branch = ENV["CWT_START_POINT"]
|
|
106
|
+
cmd << base_branch if base_branch && !base_branch.strip.empty?
|
|
102
107
|
_stdout, stderr, status = Open3.capture3(*cmd)
|
|
103
108
|
|
|
104
109
|
unless status.success?
|
data/lib/cwt/view.rb
CHANGED
|
@@ -40,7 +40,7 @@ module Cwt
|
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
draw_header(tui, frame, header_area)
|
|
43
|
-
|
|
43
|
+
draw_table(model, tui, frame, list_area)
|
|
44
44
|
draw_footer(model, tui, frame, footer_area)
|
|
45
45
|
|
|
46
46
|
return unless model.mode == :creating
|
|
@@ -72,23 +72,32 @@ module Cwt
|
|
|
72
72
|
frame.render_widget(title, area)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
def self.
|
|
76
|
-
|
|
77
|
-
# Status Icons
|
|
75
|
+
def self.draw_table(model, tui, frame, area)
|
|
76
|
+
rows = model.visible_worktrees.map do |wt|
|
|
78
77
|
status_icon = wt.dirty ? '●' : ' '
|
|
79
78
|
status_style = wt.dirty ? tui.style(**THEME[:dirty]) : tui.style(**THEME[:clean])
|
|
80
79
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
tui.
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
tui.row(cells: [
|
|
81
|
+
tui.table_cell(content: " #{status_icon} ", style: status_style),
|
|
82
|
+
tui.table_cell(
|
|
83
|
+
content: tui.text_span(content: wt.name, style: tui.style(modifiers: [:bold]))
|
|
84
|
+
),
|
|
85
|
+
tui.table_cell(
|
|
86
|
+
content: tui.text_span(content: wt.branch || 'HEAD', style: tui.style(**THEME[:dim]))
|
|
87
|
+
),
|
|
88
|
+
tui.table_cell(
|
|
89
|
+
content: tui.text_span(content: (wt.last_commit || ''), style: tui.style(**THEME[:accent]))
|
|
90
|
+
)
|
|
89
91
|
])
|
|
90
92
|
end
|
|
91
93
|
|
|
94
|
+
widths = [
|
|
95
|
+
tui.constraint_length(3),
|
|
96
|
+
tui.constraint_fill(1),
|
|
97
|
+
tui.constraint_fill(1),
|
|
98
|
+
tui.constraint_length(15)
|
|
99
|
+
]
|
|
100
|
+
|
|
92
101
|
# Dynamic Title based on context
|
|
93
102
|
title_content = if model.mode == :filtering
|
|
94
103
|
tui.text_line(spans: [
|
|
@@ -102,10 +111,11 @@ module Cwt
|
|
|
102
111
|
tui.text_line(spans: [tui.text_span(content: ' SESSIONS ', style: tui.style(**THEME[:dim]))])
|
|
103
112
|
end
|
|
104
113
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
table = tui.table(
|
|
115
|
+
rows: rows,
|
|
116
|
+
widths: widths,
|
|
117
|
+
selected_row: model.selection_index,
|
|
118
|
+
row_highlight_style: tui.style(**THEME[:selection]),
|
|
109
119
|
highlight_symbol: '▎',
|
|
110
120
|
block: tui.block(
|
|
111
121
|
titles: [{ content: title_content }],
|
|
@@ -114,7 +124,7 @@ module Cwt
|
|
|
114
124
|
)
|
|
115
125
|
)
|
|
116
126
|
|
|
117
|
-
frame.render_widget(
|
|
127
|
+
frame.render_widget(table, area)
|
|
118
128
|
end
|
|
119
129
|
|
|
120
130
|
def self.draw_footer(model, tui, frame, area)
|
data/lib/cwt/worktree.rb
CHANGED
|
@@ -21,7 +21,8 @@ module Cwt
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def name
|
|
24
|
-
File.
|
|
24
|
+
resolve = ->(p) { File.realpath(p) rescue File.expand_path(p) }
|
|
25
|
+
resolve.call(@path).delete_prefix("#{resolve.call(@repository.worktrees_dir)}/")
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def exists?
|
|
@@ -94,7 +95,10 @@ module Cwt
|
|
|
94
95
|
end
|
|
95
96
|
end
|
|
96
97
|
|
|
97
|
-
# Step 3:
|
|
98
|
+
# Step 3: Clean up empty parent directories under .worktrees/
|
|
99
|
+
cleanup_empty_parents
|
|
100
|
+
|
|
101
|
+
# Step 4: Delete Branch
|
|
98
102
|
delete_branch(force: force)
|
|
99
103
|
end
|
|
100
104
|
|
|
@@ -173,10 +177,20 @@ module Cwt
|
|
|
173
177
|
end
|
|
174
178
|
end
|
|
175
179
|
|
|
180
|
+
def cleanup_empty_parents
|
|
181
|
+
worktrees_dir = @repository.worktrees_dir
|
|
182
|
+
dir = File.dirname(@path)
|
|
183
|
+
while dir != worktrees_dir && dir.start_with?(worktrees_dir)
|
|
184
|
+
break unless Dir.exist?(dir) && (Dir.entries(dir) - %w[. ..]).empty?
|
|
185
|
+
Dir.rmdir(dir)
|
|
186
|
+
dir = File.dirname(dir)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
176
190
|
def delete_branch(force: false)
|
|
177
191
|
branch_flag = force ? "-D" : "-d"
|
|
178
192
|
_stdout, stderr, status = Open3.capture3(
|
|
179
|
-
"git", "-C", @repository.root, "branch", branch_flag,
|
|
193
|
+
"git", "-C", @repository.root, "branch", branch_flag, @branch
|
|
180
194
|
)
|
|
181
195
|
|
|
182
196
|
if status.success?
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: claude-worktree
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ben Garcia
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-02-23 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: ratatui_ruby
|
|
@@ -54,6 +55,7 @@ metadata:
|
|
|
54
55
|
homepage_uri: https://github.com/bucket-robotics/claude-worktree
|
|
55
56
|
source_code_uri: https://github.com/bucket-robotics/claude-worktree
|
|
56
57
|
changelog_uri: https://github.com/bucket-robotics/claude-worktree/blob/main/CHANGELOG.md
|
|
58
|
+
post_install_message:
|
|
57
59
|
rdoc_options: []
|
|
58
60
|
require_paths:
|
|
59
61
|
- lib
|
|
@@ -68,7 +70,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
68
70
|
- !ruby/object:Gem::Version
|
|
69
71
|
version: '0'
|
|
70
72
|
requirements: []
|
|
71
|
-
rubygems_version: 3.
|
|
73
|
+
rubygems_version: 3.5.22
|
|
74
|
+
signing_key:
|
|
72
75
|
specification_version: 4
|
|
73
76
|
summary: A TUI tool to manage Git Worktrees for AI coding agents.
|
|
74
77
|
test_files: []
|