carson 3.10.5 → 3.11.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/RELEASE.md +22 -0
- data/VERSION +1 -1
- data/lib/carson/cli.rb +3 -8
- data/lib/carson/runtime/deliver.rb +1 -1
- data/lib/carson/runtime/local/worktree.rb +5 -62
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d6a7526cb4973b9f911b8fd28d151ca719cbb53be7d42beb29e676d0d9354f4
|
|
4
|
+
data.tar.gz: 4b116460df0e2e9397edf0f60432abb907d7b81f1e28a4d7e8bceda47e030db7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 807185f0bbeb5c2762b89c8a59aed681006a1589a66024f2cf546972416bde79ad858be69cceb685a6b762a8594d95efa41607323f1d5469f3d70709b64a57f1
|
|
7
|
+
data.tar.gz: 7d7c6a06a7bf4b75428a57afa891f04dadf1ca402ac35cfee2d968658963e180b8b2ed27a1aa2a8c78c057456d319977ddfce6d022f945281081c9d7b936a7ff
|
data/RELEASE.md
CHANGED
|
@@ -5,6 +5,16 @@ Release-note scope rule:
|
|
|
5
5
|
- `RELEASE.md` records only version deltas, breaking changes, and migration actions.
|
|
6
6
|
- Operational usage guides live in `MANUAL.md` and `API.md`.
|
|
7
7
|
|
|
8
|
+
## 3.11.0
|
|
9
|
+
|
|
10
|
+
### What changed
|
|
11
|
+
|
|
12
|
+
- **Drop `worktree done`** — removed the `worktree done` subcommand entirely. `worktree remove` now handles everything: CWD safety guard, unpushed-commits guard, session state cleanup, branch and remote deletion. Two operations (create, remove) instead of three. Simpler, safer, less to remember.
|
|
13
|
+
|
|
14
|
+
### Breaking changes
|
|
15
|
+
|
|
16
|
+
- `carson worktree done <name>` no longer exists. Use `carson worktree remove <name>` instead. Add `--force` to override safety guards.
|
|
17
|
+
|
|
8
18
|
## 3.10.5
|
|
9
19
|
|
|
10
20
|
### What changed
|
|
@@ -16,6 +26,18 @@ Release-note scope rule:
|
|
|
16
26
|
|
|
17
27
|
- No breaking changes. New safety guard — previously git-protected operations now fail earlier with clearer diagnostics.
|
|
18
28
|
|
|
29
|
+
## 3.10.4
|
|
30
|
+
|
|
31
|
+
### What changed
|
|
32
|
+
|
|
33
|
+
- **Worktree remove guards unpushed commits** — `carson worktree remove` now checks for unpushed commits before deleting a worktree. Blocks with recovery guidance (push command or `--force` to override). Prevents accidental destruction of work that exists only locally.
|
|
34
|
+
- **Shared unpushed-commits check** — extracted `check_unpushed_commits` method used by `worktree remove`, eliminating code duplication.
|
|
35
|
+
- **Fix resolve path from inside worktrees** — `resolve_worktree_path` now uses `main_worktree_root` instead of `repo_root` for bare-name resolution. Previously, calling `carson worktree remove <name>` from inside a worktree would look in the wrong directory.
|
|
36
|
+
|
|
37
|
+
### Migration
|
|
38
|
+
|
|
39
|
+
- No breaking changes. `--force` overrides the new unpushed-commits guard.
|
|
40
|
+
|
|
19
41
|
## 3.10.3
|
|
20
42
|
|
|
21
43
|
### What changed
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.11.0
|
data/lib/carson/cli.rb
CHANGED
|
@@ -53,7 +53,7 @@ module Carson
|
|
|
53
53
|
|
|
54
54
|
def self.build_parser
|
|
55
55
|
OptionParser.new do |opts|
|
|
56
|
-
opts.banner = "Usage: carson [status [--json]|setup|audit [--json]|sync [--json]|deliver [--merge] [--json] [--title T] [--body-file F]|prune [--all] [--json]|worktree [--json] create|
|
|
56
|
+
opts.banner = "Usage: carson [status [--json]|setup|audit [--json]|sync [--json]|deliver [--merge] [--json] [--title T] [--body-file F]|prune [--all] [--json]|worktree [--json] create|remove <name>|onboard|refresh [--all]|offboard|template check|apply|review gate|sweep|govern [--dry-run] [--json] [--loop SECONDS]|session [--json] [--task T]|session clear [--json]|version]"
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -180,7 +180,7 @@ module Carson
|
|
|
180
180
|
json_flag = argv.delete( "--json" ) ? true : false
|
|
181
181
|
action = argv.shift
|
|
182
182
|
if action.to_s.strip.empty?
|
|
183
|
-
err.puts "#{BADGE} Missing subcommand for worktree. Use: carson worktree create|
|
|
183
|
+
err.puts "#{BADGE} Missing subcommand for worktree. Use: carson worktree create|remove <name>"
|
|
184
184
|
err.puts parser
|
|
185
185
|
return { command: :invalid }
|
|
186
186
|
end
|
|
@@ -193,9 +193,6 @@ module Carson
|
|
|
193
193
|
return { command: :invalid }
|
|
194
194
|
end
|
|
195
195
|
{ command: "worktree:create", worktree_name: name, json: json_flag }
|
|
196
|
-
when "done"
|
|
197
|
-
name = argv.shift
|
|
198
|
-
{ command: "worktree:done", worktree_name: name, json: json_flag }
|
|
199
196
|
when "remove"
|
|
200
197
|
force = argv.delete( "--force" ) ? true : false
|
|
201
198
|
worktree_path = argv.shift
|
|
@@ -205,7 +202,7 @@ module Carson
|
|
|
205
202
|
end
|
|
206
203
|
{ command: "worktree:remove", worktree_path: worktree_path, force: force, json: json_flag }
|
|
207
204
|
else
|
|
208
|
-
err.puts "#{BADGE} Unknown worktree subcommand: #{action}. Use: carson worktree create|
|
|
205
|
+
err.puts "#{BADGE} Unknown worktree subcommand: #{action}. Use: carson worktree create|remove <name>"
|
|
209
206
|
{ command: :invalid }
|
|
210
207
|
end
|
|
211
208
|
end
|
|
@@ -379,8 +376,6 @@ module Carson
|
|
|
379
376
|
runtime.prune_all!
|
|
380
377
|
when "worktree:create"
|
|
381
378
|
runtime.worktree_create!( name: parsed.fetch( :worktree_name ), json_output: parsed.fetch( :json, false ) )
|
|
382
|
-
when "worktree:done"
|
|
383
|
-
runtime.worktree_done!( name: parsed.fetch( :worktree_name, nil ), json_output: parsed.fetch( :json, false ) )
|
|
384
379
|
when "worktree:remove"
|
|
385
380
|
runtime.worktree_remove!( worktree_path: parsed.fetch( :worktree_path ), force: parsed.fetch( :force, false ), json_output: parsed.fetch( :json, false ) )
|
|
386
381
|
when "onboard"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Safe worktree lifecycle management for coding agents.
|
|
2
|
-
#
|
|
3
|
-
#
|
|
2
|
+
# Two operations: create and remove. Remove is safe by default — guards against
|
|
3
|
+
# CWD-inside-worktree and unpushed commits. Use --force to override.
|
|
4
4
|
# Supports --json for machine-readable structured output with recovery commands.
|
|
5
5
|
module Carson
|
|
6
6
|
class Runtime
|
|
@@ -50,62 +50,6 @@ module Carson
|
|
|
50
50
|
)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
# Marks a worktree as completed without deleting it.
|
|
54
|
-
# Verifies all changes are committed. Deferred deletion — cleanup happens later.
|
|
55
|
-
def worktree_done!( name: nil, json_output: false )
|
|
56
|
-
if name.to_s.strip.empty?
|
|
57
|
-
return worktree_finish(
|
|
58
|
-
result: { command: "worktree done", status: "error",
|
|
59
|
-
error: "missing worktree name",
|
|
60
|
-
recovery: "carson worktree done <name>" },
|
|
61
|
-
exit_code: EXIT_ERROR, json_output: json_output
|
|
62
|
-
)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
resolved_path = resolve_worktree_path( worktree_path: name )
|
|
66
|
-
|
|
67
|
-
unless worktree_registered?( path: resolved_path )
|
|
68
|
-
return worktree_finish(
|
|
69
|
-
result: { command: "worktree done", status: "error", name: name,
|
|
70
|
-
error: "#{name} is not a registered worktree",
|
|
71
|
-
recovery: "git worktree list" },
|
|
72
|
-
exit_code: EXIT_ERROR, json_output: json_output
|
|
73
|
-
)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Check for uncommitted changes in the worktree.
|
|
77
|
-
wt_status, _, status_result, = Open3.capture3( "git", "status", "--porcelain", chdir: resolved_path )
|
|
78
|
-
if status_result.success? && !wt_status.strip.empty?
|
|
79
|
-
return worktree_finish(
|
|
80
|
-
result: { command: "worktree done", status: "block", name: name,
|
|
81
|
-
error: "worktree has uncommitted changes",
|
|
82
|
-
recovery: "git -C #{resolved_path} add -A && git -C #{resolved_path} commit, then carson worktree done #{name}" },
|
|
83
|
-
exit_code: EXIT_BLOCK, json_output: json_output
|
|
84
|
-
)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Check for unpushed commits using shared guard.
|
|
88
|
-
branch = worktree_branch( path: resolved_path )
|
|
89
|
-
unpushed = check_unpushed_commits( branch: branch, worktree_path: resolved_path )
|
|
90
|
-
if unpushed
|
|
91
|
-
return worktree_finish(
|
|
92
|
-
result: { command: "worktree done", status: "block", name: name, branch: branch,
|
|
93
|
-
error: unpushed[ :error ],
|
|
94
|
-
recovery: unpushed[ :recovery ] },
|
|
95
|
-
exit_code: EXIT_BLOCK, json_output: json_output
|
|
96
|
-
)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Clear worktree from session state.
|
|
100
|
-
update_session( worktree: :clear )
|
|
101
|
-
|
|
102
|
-
worktree_finish(
|
|
103
|
-
result: { command: "worktree done", status: "ok", name: name, branch: branch || "(detached)",
|
|
104
|
-
next_step: "carson worktree remove #{name}" },
|
|
105
|
-
exit_code: EXIT_OK, json_output: json_output
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
53
|
# Removes a worktree: directory, git registration, and branch.
|
|
110
54
|
# Never forces removal — if the worktree has uncommitted changes, refuses unless
|
|
111
55
|
# the user explicitly passes force: true via CLI --force flag.
|
|
@@ -211,6 +155,9 @@ module Carson
|
|
|
211
155
|
end
|
|
212
156
|
end
|
|
213
157
|
|
|
158
|
+
# Clear worktree from session state.
|
|
159
|
+
update_session( worktree: :clear )
|
|
160
|
+
|
|
214
161
|
worktree_finish(
|
|
215
162
|
result: { command: "worktree remove", status: "ok", name: File.basename( resolved_path ),
|
|
216
163
|
branch: branch, branch_deleted: branch_deleted, remote_deleted: remote_deleted },
|
|
@@ -245,10 +192,6 @@ module Carson
|
|
|
245
192
|
puts_line "Worktree created: #{result[ :name ]}"
|
|
246
193
|
puts_line " Path: #{result[ :path ]}"
|
|
247
194
|
puts_line " Branch: #{result[ :branch ]}"
|
|
248
|
-
when "worktree done"
|
|
249
|
-
puts_line "Worktree done: #{result[ :name ]}"
|
|
250
|
-
puts_line " Branch: #{result[ :branch ]}"
|
|
251
|
-
puts_line " Cleanup later with `#{result[ :next_step ]}` or `carson housekeep`."
|
|
252
195
|
when "worktree remove"
|
|
253
196
|
unless verbose?
|
|
254
197
|
puts_line "Worktree removed: #{result[ :name ]}"
|