carson 3.30.0 → 3.30.2

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: 5156cb5207a0ee95cad65c30d494a24ddcee97c90f2aab6861b34f9ec8e92069
4
- data.tar.gz: 182a83aaa84ec1d9c0a548bdaf98e421b4eab9e4ab1248b0d67db58e42a7c5ae
3
+ metadata.gz: 3d81e341c8b680889a883ac964de779e488168c08b692b4bc550d18309a2cd79
4
+ data.tar.gz: 59334525ce9d1b7952917e1a69dee01f4056900c0bfde09da191c1246ed0a087
5
5
  SHA512:
6
- metadata.gz: 3e42b39fad6ca26a05bd914f7653c9cd4e7bb4227c9eb03ba5288b5e54d30f87f4b8e69991236caab797964d293ec1e6b01c4ec6a8853b24f80f7a7bb1670cfe
7
- data.tar.gz: fd147d7b1941670279ad3261b0cca81639d72043b3e429a1f0290aff4a9deb53000971c5bb5953d7f36b4b574a1c5b03547f9cf33fdb3bcc16bbe4f30e5b770a
6
+ metadata.gz: 56ef060de2589540f6f87425fd49e147ee40577f9f6b8539152f06028100539c19b68d318e6dccb2376dc4666b05b3273b3989025b17510aeeb5866e2f32785e
7
+ data.tar.gz: 064f48a6b0b8db74484dd8584bcfa1b352caca8c68bb0662106ef235362486da602e654f5e1377495b7612df7a362ed00221e0737326224fd67aa0d514ca4b6f
data/MANUAL.md CHANGED
@@ -66,12 +66,12 @@ on:
66
66
 
67
67
  jobs:
68
68
  governance:
69
- uses: wanghailei/carson/.github/workflows/carson_policy.yml@v3.29.0
69
+ uses: wanghailei/carson/.github/workflows/carson_policy.yml@v3.30.0
70
70
  secrets:
71
71
  CARSON_READ_TOKEN: ${{ secrets.CARSON_READ_TOKEN }}
72
72
  with:
73
- carson_ref: "v3.29.0"
74
- carson_version: "3.29.0"
73
+ carson_ref: "v3.30.0"
74
+ carson_version: "3.30.0"
75
75
  rubocop_version: "1.81.0"
76
76
  ```
77
77
 
data/RELEASE.md CHANGED
@@ -5,6 +5,29 @@ 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.30.2
9
+
10
+ ### What changed
11
+
12
+ - **Recovery hints re-enter through Carson, not blocked raw commands** — Delivery error recovery messages no longer suggest raw `gh pr create`, `gh pr merge`, or `git rebase` commands. All recovery paths now guide the user back through Carson. Freshness blocks say "refresh this branch onto the target, then `carson deliver`" instead of teaching raw git recipes.
13
+ - **Fast PR indentation guard restored** — The Ruby indentation guard in CI now correctly handles access modifier detection, fixing false positives that blocked PRs.
14
+
15
+ ### No migration required
16
+
17
+ - Existing workflows continue to work unchanged.
18
+
19
+ ## 3.30.1
20
+
21
+ ### What changed
22
+
23
+ - **MANUAL.md CI example updated to v3.30.0** — The CI workflow reference, `carson_ref`, and `carson_version` in the setup example were still pinned to v3.29.0. Now aligned with the current release.
24
+ - **CI split into fast PR gate and full smoke on main** — PR checks run the unit test suite only; the full smoke script runs on main after merge. Reduces PR feedback time.
25
+ - **Command guard respects leading `cd` in Bash commands** — `cd /path && gh pr create` is now correctly detected as a governed command.
26
+
27
+ ### No migration required
28
+
29
+ - Existing workflows continue to work unchanged.
30
+
8
31
  ## 3.30.0
9
32
 
10
33
  ### What changed
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.30.0
1
+ 3.30.2
data/hooks/command-guard CHANGED
@@ -31,6 +31,28 @@ block_command() {
31
31
  exit 2
32
32
  }
33
33
 
34
+ resolve_command_pwd() {
35
+ local command_text="$1"
36
+ local base_pwd
37
+ local raw_cd_target
38
+ local cd_target
39
+ local resolved_pwd
40
+
41
+ base_pwd="$(pwd -P)"
42
+ if [[ ! "$command_text" =~ ^[[:space:]]*cd[[:space:]]+([^;&|]+)[[:space:]]*(&&|;) ]]; then
43
+ echo "$base_pwd"
44
+ return
45
+ fi
46
+
47
+ raw_cd_target="${BASH_REMATCH[1]}"
48
+ cd_target="$(printf '%s' "$raw_cd_target" | sed -E "s/^[[:space:]]+//; s/[[:space:]]+$//; s/^'(.*)'$/\\1/; s/^\"(.*)\"$/\\1/")"
49
+ if resolved_pwd="$(cd "$base_pwd" && cd "$cd_target" 2>/dev/null && pwd -P)"; then
50
+ echo "$resolved_pwd"
51
+ else
52
+ echo "$base_pwd"
53
+ fi
54
+ }
55
+
34
56
  # Read the tool call JSON from stdin.
35
57
  input="$(cat)"
36
58
 
@@ -40,16 +62,17 @@ tool_name="$(echo "$input" | jq -r '.tool_name // empty' 2>/dev/null)"
40
62
 
41
63
  command_text="$(echo "$input" | jq -r '.tool_input.command // empty' 2>/dev/null)"
42
64
  [ -n "$command_text" ] || exit 0
65
+ command_pwd="$(resolve_command_pwd "$command_text")"
43
66
 
44
67
  # Check if the current directory is inside a governed repository.
45
68
  config_file="${HOME}/.carson/config.json"
46
69
  [ -f "$config_file" ] || exit 0
47
70
 
48
- repo_root="$(git rev-parse --show-toplevel 2>/dev/null || echo "")"
71
+ repo_root="$(git -C "$command_pwd" rev-parse --show-toplevel 2>/dev/null || echo "")"
49
72
  [ -n "$repo_root" ] || exit 0
50
73
 
51
74
  current_root="$(cd "$repo_root" && pwd -P)"
52
- common_dir="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null || echo "")"
75
+ common_dir="$(git -C "$command_pwd" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || echo "")"
53
76
  if [ -n "$common_dir" ]; then
54
77
  governed_root="$(cd "$(dirname "$common_dir")" && pwd -P)"
55
78
  else
@@ -62,7 +85,7 @@ fi
62
85
 
63
86
  main_branch="$(jq -r '.git.main_branch // "main"' "$config_file" 2>/dev/null || echo "main")"
64
87
  [ -n "$main_branch" ] || main_branch="main"
65
- current_branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")"
88
+ current_branch="$(git -C "$command_pwd" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")"
66
89
  on_main_worktree=false
67
90
  on_main_branch=false
68
91
  [ "$current_root" = "$governed_root" ] && on_main_worktree=true
@@ -96,7 +119,7 @@ fi
96
119
  if [ "$on_main_worktree" = true ] && [ "$on_main_branch" = true ] && grep -qE "$main_mutation_pattern" <<<"$command_text"; then
97
120
  block_command \
98
121
  "Main working tree is read-only in this Carson-governed repo." \
99
- "Use \`carson worktree create <name>\` first, then run \`git add\` or \`git commit\` inside that worktree."
122
+ "Use \`carson worktree create <name>\` first, then commit inside that worktree or let Carson do it with \`carson deliver --commit \"...\"\`."
100
123
  fi
101
124
 
102
125
  exit 0
@@ -288,7 +288,7 @@ module Carson
288
288
  when :blocked
289
289
  result[ :outcome ] = "blocked"
290
290
  result[ :waited_seconds ] = elapsed_settle_seconds( started_at: started_at )
291
- result[ :recovery ] = "git rebase #{config.git_remote}/#{main} && carson deliver" if evaluation[ :cause ] == "freshness"
291
+ result[ :recovery ] = "refresh this branch onto #{config.git_remote}/#{main}, then carson deliver" if evaluation[ :cause ] == "freshness"
292
292
  apply_handoff!(
293
293
  result: result,
294
294
  reason: evaluation.fetch( :reason ),
@@ -809,10 +809,9 @@ module Carson
809
809
 
810
810
  def freshness_recovery( freshness: )
811
811
  remote_ref = freshness.fetch( :remote_ref )
812
- return "git rebase #{remote_ref} && carson deliver" if freshness.fetch( :status ) == :behind
812
+ return "refresh this branch onto #{remote_ref}, then carson deliver" if freshness.fetch( :status ) == :behind
813
813
 
814
- remote, main = remote_ref.split( "/", 2 )
815
- "git fetch #{remote} #{main} && carson deliver"
814
+ "carson deliver (once #{remote_ref} is reachable)"
816
815
  end
817
816
 
818
817
  def deliver_merge_attempt_cap
@@ -898,7 +897,7 @@ module Carson
898
897
  reason: "freshness_behind",
899
898
  cause: "freshness",
900
899
  summary: "branch is behind #{remote_main}",
901
- recovery: "git rebase #{remote_main} && carson deliver"
900
+ recovery: "refresh this branch onto #{remote_main}, then carson deliver"
902
901
  } if merge_state == "BEHIND"
903
902
 
904
903
  return {
@@ -1127,7 +1126,7 @@ module Carson
1127
1126
 
1128
1127
  if lease_stderr.to_s.include?( "stale info" )
1129
1128
  result[ :error ] = "force-with-lease rejected — another push landed on #{branch} since your last fetch"
1130
- result[ :recovery ] = "git fetch #{remote} #{branch} && carson deliver"
1129
+ result[ :recovery ] = "inspect newer commits on #{branch}, reconcile, then carson deliver"
1131
1130
  else
1132
1131
  error_text = lease_stderr.to_s.strip
1133
1132
  error_text = "push failed (force-with-lease)" if error_text.empty?
@@ -1175,7 +1174,7 @@ module Carson
1175
1174
  error_text = stderr.to_s.strip
1176
1175
  error_text = "pr create failed" if error_text.empty?
1177
1176
  result[ :error ] = error_text
1178
- result[ :recovery ] = "gh pr create --title '#{pr_title}' --head #{branch}"
1177
+ result[ :recovery ] = "carson deliver"
1179
1178
  return [ nil, nil ]
1180
1179
  end
1181
1180
 
@@ -1274,7 +1273,7 @@ module Carson
1274
1273
  error_text = stderr.to_s.strip
1275
1274
  error_text = "merge failed" if error_text.empty?
1276
1275
  result[ :error ] = error_text
1277
- result[ :recovery ] = "gh pr merge #{number} --#{method}"
1276
+ result[ :recovery ] = "carson deliver"
1278
1277
  EXIT_ERROR
1279
1278
  end
1280
1279
  end
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.30.0
4
+ version: 3.30.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hailei Wang