carson 3.13.2 → 3.14.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d49ac2582d874ea7b4a25a9d71401fd8424b33ef8740ef8c9d1588d81616b00a
4
- data.tar.gz: 37d5ba4ebe4c7455eb1751a55cff6724f073bcce37463080fa3324db86c42fac
3
+ metadata.gz: a6187204d01b1fc7f62657f451451a0124e039b265d83379ce8c23e9ba62a346
4
+ data.tar.gz: d5b11033558afc8847386858bc62d9ba19816636dece60dfe4a5f1708528a50f
5
5
  SHA512:
6
- metadata.gz: 33498b92e55ab4caab2ddb9935ca1ce2b1965e61f03898849720cedbd24e878d981662fa1acad7312addb08d7bb90e83ab72e2f55658087f2af2c3f3d9c37f2c
7
- data.tar.gz: 01ee3460c17e00db79f9216592bda4171cc135ceb90ff88d3c83fa8925653f50ad1b3b8ea98e1f6ef37bce1a4f0f2e868d06968d7788e466f54d7d21e99b842b
6
+ metadata.gz: 005575df223f30f900794447f012d29bfa3c6a939433870da80dd54cdbcb43dd9099413357a049232ffdcd7d7c502996e3d4279a40f310fde576fe991c8659a0
7
+ data.tar.gz: 9c4c5023488bce12162fbcb0c4746db515c72e2b28618ca35682a3076ec2b3c1c67513af7712cb4238dc76a2fd389f9abf75385baf6d63ea10970be960d949e9
data/MANUAL.md CHANGED
@@ -142,6 +142,36 @@ carson prune
142
142
 
143
143
  After squash or rebase merge, the content matches main — removal proceeds without `--force`.
144
144
 
145
+ ### Carson vs Claude Code EnterWorktree
146
+
147
+ Claude Code has a built-in `EnterWorktree` tool. Both create a git worktree under `.claude/worktrees/` with a new branch — but they solve different problems and have different trade-offs.
148
+
149
+ **What Carson adds over EnterWorktree:**
150
+
151
+ | Concern | EnterWorktree | Carson |
152
+ |---|---|---|
153
+ | Auto-sync main before branching | No — branches from current HEAD, which may be stale | Yes — `git pull --ff-only` before branch creation |
154
+ | CWD guard on removal | No | Yes — blocks if shell is inside the worktree |
155
+ | Unpushed-commits guard | No | Yes — blocks if work hasn't been pushed |
156
+ | Content-aware squash/rebase detection | No | Yes — compares tree content, not SHAs |
157
+ | Branch cleanup (local + remote) | No | Yes — one command removes worktree, local branch, and remote branch |
158
+ | `.git/info/exclude` management | No | Yes — prevents `.claude/` appearing as untracked |
159
+ | Recovery-aware errors | No | Yes — every error includes a concrete recovery command |
160
+ | `--json` output | No | Yes — machine-readable for agent consumption |
161
+
162
+ **What EnterWorktree does that Carson does not:**
163
+
164
+ - **Automatic session CWD switch.** After creating the worktree, Claude Code moves the agent's working directory into it — no manual `cd` required. This is genuine friction that Carson should learn from.
165
+
166
+ **What EnterWorktree gets wrong:**
167
+
168
+ - **Session-exit cleanup prompt.** On session exit, Claude Code asks the user whether to keep or remove each worktree. In an agent workflow this is pure friction — the user cannot verify the state of bot-created worktrees and is forced to choose "keep" every time. Carson's approach is better: deferred deletion by default, with safety guards when you do choose to clean up.
169
+ - **Random names.** Without a name argument, EnterWorktree generates a random string. `git branch` output becomes unreadable. Carson requires a meaningful name that doubles as the branch name.
170
+
171
+ **Relationship — complementary, not competing:**
172
+
173
+ The two tools serve different layers. EnterWorktree owns the session (CWD switch); Carson owns the git lifecycle (sync, safety, cleanup). The ideal integration is Claude Code's `WorktreeCreate`/`WorktreeRemove` hook mechanism — Carson registers as the hook handler, so `EnterWorktree` delegates creation to `carson worktree create` and gets both Carson's safety and Claude Code's automatic CWD switch.
174
+
145
175
  ## Daily Operations
146
176
 
147
177
  **Start of work:**
@@ -170,6 +200,13 @@ carson template apply
170
200
  carson review gate
171
201
  ```
172
202
 
203
+ **Portfolio overview:**
204
+
205
+ ```bash
206
+ carson repos # list all governed repositories
207
+ carson repos --json # machine-readable output
208
+ ```
209
+
173
210
  **Periodic maintenance:**
174
211
 
175
212
  ```bash
data/README.md CHANGED
@@ -29,6 +29,8 @@ Carson is an autonomous governance runtime that lives on your workstation and in
29
29
 
30
30
  This separation is Carson's defining trait — the **outsider boundary**: no Carson scripts, config files, or governance payloads are ever placed inside a governed repository.
31
31
 
32
+ **Agent workspace management** — `carson worktree create` and `carson worktree remove` give coding agents safe, isolated workspaces. Unlike Claude Code's built-in `EnterWorktree`, Carson auto-syncs main before branching, guards against removing worktrees with unpushed work or an active shell inside, detects squash/rebase merges so removal doesn't falsely block, and cleans up the local and remote branch in one step. The two tools are complementary — see `MANUAL.md § Carson vs Claude Code EnterWorktree` for the full comparison.
33
+
32
34
  ### The Governance Loop
33
35
 
34
36
  Carson orchestrates a closed governance loop across two layers:
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.14.0
9
+
10
+ ### What changed
11
+
12
+ - **`carson repos` command** — lists all governed repositories from Carson's global config. Shows which repos Carson is serving at a glance. Supports `--json` for machine-readable output. Portfolio-level command — works from any directory.
13
+
14
+ ### UX improvement
15
+
16
+ - Bots and humans can now verify which repos Carson oversees with a single command instead of reading raw config JSON.
17
+
8
18
  ## 3.13.2
9
19
 
10
20
  ### What changed
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.13.2
1
+ 3.14.0
data/lib/carson/cli.rb CHANGED
@@ -12,7 +12,7 @@ module Carson
12
12
  return Runtime::EXIT_OK
13
13
  end
14
14
 
15
- if %w[refresh:all prune:all].include?( command )
15
+ if %w[repos refresh:all prune:all].include?( command )
16
16
  verbose = parsed.fetch( :verbose, false )
17
17
  runtime = Runtime.new( repo_root: repo_root, tool_root: tool_root, out: out, err: err, verbose: verbose )
18
18
  return dispatch( parsed: parsed, runtime: runtime )
@@ -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|remove <name>|onboard|refresh [--all]|offboard|template check|apply|review gate|sweep|govern [--dry-run] [--json] [--loop SECONDS]|version]"
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>|repos [--json]|onboard|refresh [--all]|offboard|template check|apply|review gate|sweep|govern [--dry-run] [--json] [--loop SECONDS]|version]"
57
57
  end
58
58
  end
59
59
 
@@ -86,6 +86,8 @@ module Carson
86
86
  parse_prune_command( argv: argv, parser: parser, err: err )
87
87
  when "worktree"
88
88
  parse_worktree_subcommand( argv: argv, parser: parser, err: err )
89
+ when "repos"
90
+ parse_repos_command( argv: argv, err: err )
89
91
  when "review"
90
92
  parse_named_subcommand( command: command, usage: "gate|sweep", argv: argv, parser: parser, err: err )
91
93
  when "audit"
@@ -299,6 +301,15 @@ module Carson
299
301
  { command: :invalid }
300
302
  end
301
303
 
304
+ def self.parse_repos_command( argv:, err: )
305
+ json_flag = argv.delete( "--json" ) ? true : false
306
+ unless argv.empty?
307
+ err.puts "#{BADGE} Unexpected arguments for repos: #{argv.join( ' ' )}"
308
+ return { command: :invalid }
309
+ end
310
+ { command: "repos", json: json_flag }
311
+ end
312
+
302
313
  def self.parse_govern_subcommand( argv:, err: )
303
314
  options = {
304
315
  dry_run: false,
@@ -376,6 +387,8 @@ module Carson
376
387
  runtime.review_gate!
377
388
  when "review:sweep"
378
389
  runtime.review_sweep!
390
+ when "repos"
391
+ runtime.repos!( json_output: parsed.fetch( :json, false ) )
379
392
  when "govern"
380
393
  runtime.govern!(
381
394
  dry_run: parsed.fetch( :dry_run, false ),
@@ -229,11 +229,7 @@ module Carson
229
229
  puts_line ""
230
230
  puts_line "Carson at your service."
231
231
 
232
- if self.in.respond_to?( :tty? ) && self.in.tty?
233
- prompt_govern_registration!
234
- else
235
- puts_line "To register for portfolio governance: carson onboard (in a TTY)"
236
- end
232
+ auto_register_govern!
237
233
 
238
234
  puts_line ""
239
235
  puts_line "Your repository is set up. Carson has placed files in your"
@@ -1,6 +1,7 @@
1
1
  # Safe worktree lifecycle management for coding agents.
2
- # Two operations: create and remove. Remove is safe by default — guards against
3
- # CWD-inside-worktree and unpushed commits. Use --force to override.
2
+ # Two operations: create and remove. Create auto-syncs main before branching.
3
+ # Remove is safe by default — guards against CWD-inside-worktree and unpushed
4
+ # commits. Content-aware: allows removal after squash/rebase merge without --force.
4
5
  # Supports --json for machine-readable structured output with recovery commands.
5
6
  module Carson
6
7
  class Runtime
@@ -0,0 +1,29 @@
1
+ # Lists governed repositories from Carson's global config.
2
+ # Portfolio-level query — not scoped to any single repository.
3
+ require "json"
4
+
5
+ module Carson
6
+ class Runtime
7
+ module Repos
8
+ def repos!( json_output: false )
9
+ repos = config.govern_repos
10
+
11
+ if json_output
12
+ out.puts JSON.pretty_generate( { command: "repos", repos: repos } )
13
+ else
14
+ if repos.empty?
15
+ puts_line "No governed repositories."
16
+ puts_line " Run carson onboard in a repo to register it."
17
+ else
18
+ puts_line "Governed repositories (#{repos.length}):"
19
+ repos.each { |path| puts_line " #{path}" }
20
+ end
21
+ end
22
+
23
+ EXIT_OK
24
+ end
25
+ end
26
+
27
+ include Repos
28
+ end
29
+ end
@@ -368,24 +368,16 @@ module Carson
368
368
  !path.empty? && File.file?( path )
369
369
  end
370
370
 
371
- # After onboard succeeds, offer to register the repo for portfolio governance.
372
- def prompt_govern_registration!
371
+ # Automatically registers the repo for portfolio governance during onboard.
372
+ def auto_register_govern!
373
373
  expanded = File.expand_path( repo_root )
374
374
  if config.govern_repos.include?( expanded )
375
375
  puts_verbose "govern_registration: already registered #{expanded}"
376
376
  return
377
377
  end
378
378
 
379
- puts_line ""
380
- puts_line "Portfolio governance"
381
- puts_line " Register this repo so carson refresh --all and carson govern include it?"
382
- accepted = prompt_yes_no( default: true )
383
- if accepted
384
- append_govern_repo!( repo_path: expanded )
385
- puts_line "Registered. Run carson refresh --all to keep all repos in sync."
386
- else
387
- puts_line "Skipped. Run carson onboard here again to register later."
388
- end
379
+ append_govern_repo!( repo_path: expanded )
380
+ puts_line "Registered for portfolio governance."
389
381
  end
390
382
 
391
383
  # Reusable Y/n prompt following existing prompt_choice conventions.
@@ -217,6 +217,7 @@ end
217
217
 
218
218
  require_relative "runtime/local"
219
219
  require_relative "runtime/audit"
220
+ require_relative "runtime/repos"
220
221
  require_relative "runtime/review"
221
222
  require_relative "runtime/govern"
222
223
  require_relative "runtime/setup"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carson
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.2
4
+ version: 3.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hailei Wang
@@ -61,6 +61,7 @@ files:
61
61
  - lib/carson/runtime/local/sync.rb
62
62
  - lib/carson/runtime/local/template.rb
63
63
  - lib/carson/runtime/local/worktree.rb
64
+ - lib/carson/runtime/repos.rb
64
65
  - lib/carson/runtime/review.rb
65
66
  - lib/carson/runtime/review/data_access.rb
66
67
  - lib/carson/runtime/review/gate_support.rb