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 +4 -4
- data/MANUAL.md +3 -3
- data/RELEASE.md +23 -0
- data/VERSION +1 -1
- data/hooks/command-guard +27 -4
- data/lib/carson/runtime/deliver.rb +7 -8
- 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: 3d81e341c8b680889a883ac964de779e488168c08b692b4bc550d18309a2cd79
|
|
4
|
+
data.tar.gz: 59334525ce9d1b7952917e1a69dee01f4056900c0bfde09da191c1246ed0a087
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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.
|
|
74
|
-
carson_version: "3.
|
|
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.
|
|
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
|
|
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 ] = "
|
|
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 "
|
|
812
|
+
return "refresh this branch onto #{remote_ref}, then carson deliver" if freshness.fetch( :status ) == :behind
|
|
813
813
|
|
|
814
|
-
|
|
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: "
|
|
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 ] = "
|
|
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 ] = "
|
|
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 ] = "
|
|
1276
|
+
result[ :recovery ] = "carson deliver"
|
|
1278
1277
|
EXIT_ERROR
|
|
1279
1278
|
end
|
|
1280
1279
|
end
|