rhachet-roles-ehmpathy 1.15.1 → 1.15.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.
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = safe find-and-replace across git-tracked files only
|
|
4
|
+
#
|
|
5
|
+
# .why = enables bulk text replacement without:
|
|
6
|
+
# - touching files outside the repo
|
|
7
|
+
# - modifying untracked files
|
|
8
|
+
# - accidental command chaining attacks
|
|
9
|
+
#
|
|
10
|
+
# this is a controlled alternative to raw sed, which is
|
|
11
|
+
# denied in permissions due to security risks.
|
|
12
|
+
#
|
|
13
|
+
# usage:
|
|
14
|
+
# sedreplace.sh --old "pattern" --new "replacement" # dry-run
|
|
15
|
+
# sedreplace.sh --old "pattern" --new "replacement" --execute # apply
|
|
16
|
+
# sedreplace.sh --old "pattern" --new "replacement" --glob "*.ts" # filter
|
|
17
|
+
#
|
|
18
|
+
# guarantee:
|
|
19
|
+
# - only operates on git-tracked files (git ls-files)
|
|
20
|
+
# - dry-run by default (shows diff, no changes)
|
|
21
|
+
# - requires --execute to apply changes
|
|
22
|
+
# - fail-fast on errors
|
|
23
|
+
######################################################################
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
# parse named arguments
|
|
27
|
+
OLD_PATTERN=""
|
|
28
|
+
NEW_PATTERN=""
|
|
29
|
+
GLOB_FILTER=""
|
|
30
|
+
EXECUTE=false
|
|
31
|
+
|
|
32
|
+
while [[ $# -gt 0 ]]; do
|
|
33
|
+
case $1 in
|
|
34
|
+
--old)
|
|
35
|
+
OLD_PATTERN="$2"
|
|
36
|
+
shift 2
|
|
37
|
+
;;
|
|
38
|
+
--new)
|
|
39
|
+
NEW_PATTERN="$2"
|
|
40
|
+
shift 2
|
|
41
|
+
;;
|
|
42
|
+
--glob)
|
|
43
|
+
GLOB_FILTER="$2"
|
|
44
|
+
shift 2
|
|
45
|
+
;;
|
|
46
|
+
--execute)
|
|
47
|
+
EXECUTE=true
|
|
48
|
+
shift
|
|
49
|
+
;;
|
|
50
|
+
*)
|
|
51
|
+
echo "unknown argument: $1"
|
|
52
|
+
echo "usage: sedreplace.sh --old 'pattern' --new 'replacement' [--glob '*.ts'] [--execute]"
|
|
53
|
+
exit 1
|
|
54
|
+
;;
|
|
55
|
+
esac
|
|
56
|
+
done
|
|
57
|
+
|
|
58
|
+
# validate required args
|
|
59
|
+
if [[ -z "$OLD_PATTERN" ]]; then
|
|
60
|
+
echo "error: --old pattern is required"
|
|
61
|
+
exit 1
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
if [[ -z "$NEW_PATTERN" ]]; then
|
|
65
|
+
echo "error: --new replacement is required"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# ensure we're in a git repo
|
|
70
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
71
|
+
echo "error: not in a git repository"
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# get git-tracked files, optionally filtered by glob
|
|
76
|
+
if [[ -n "$GLOB_FILTER" ]]; then
|
|
77
|
+
FILES=$(git ls-files "$GLOB_FILTER")
|
|
78
|
+
else
|
|
79
|
+
FILES=$(git ls-files)
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
if [[ -z "$FILES" ]]; then
|
|
83
|
+
echo "no files match the criteria"
|
|
84
|
+
exit 0
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# find files containing the pattern
|
|
88
|
+
MATCHING_FILES=$(echo "$FILES" | xargs grep -l "$OLD_PATTERN" 2>/dev/null || true)
|
|
89
|
+
|
|
90
|
+
if [[ -z "$MATCHING_FILES" ]]; then
|
|
91
|
+
echo "no files contain pattern: $OLD_PATTERN"
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# count matches
|
|
96
|
+
MATCH_COUNT=$(echo "$MATCHING_FILES" | wc -l)
|
|
97
|
+
echo "found $MATCH_COUNT file(s) containing pattern"
|
|
98
|
+
echo ""
|
|
99
|
+
|
|
100
|
+
if [[ "$EXECUTE" == "false" ]]; then
|
|
101
|
+
# dry-run: show what would change
|
|
102
|
+
echo "=== DRY RUN (use --execute to apply) ==="
|
|
103
|
+
echo ""
|
|
104
|
+
|
|
105
|
+
for file in $MATCHING_FILES; do
|
|
106
|
+
echo "--- $file ---"
|
|
107
|
+
# show the diff that would result
|
|
108
|
+
sed "s|$OLD_PATTERN|$NEW_PATTERN|g" "$file" | diff -u "$file" - || true
|
|
109
|
+
echo ""
|
|
110
|
+
done
|
|
111
|
+
|
|
112
|
+
echo "=== END DRY RUN ==="
|
|
113
|
+
echo ""
|
|
114
|
+
echo "to apply changes, run with --execute flag"
|
|
115
|
+
else
|
|
116
|
+
# execute: apply changes
|
|
117
|
+
echo "=== APPLYING CHANGES ==="
|
|
118
|
+
echo ""
|
|
119
|
+
|
|
120
|
+
for file in $MATCHING_FILES; do
|
|
121
|
+
echo "updating: $file"
|
|
122
|
+
# use sed -i for in-place editing
|
|
123
|
+
# note: macOS sed requires -i '' but linux sed uses -i
|
|
124
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
125
|
+
sed -i '' "s|$OLD_PATTERN|$NEW_PATTERN|g" "$file"
|
|
126
|
+
else
|
|
127
|
+
sed -i "s|$OLD_PATTERN|$NEW_PATTERN|g" "$file"
|
|
128
|
+
fi
|
|
129
|
+
done
|
|
130
|
+
|
|
131
|
+
echo ""
|
|
132
|
+
echo "=== DONE: updated $MATCH_COUNT file(s) ==="
|
|
133
|
+
echo ""
|
|
134
|
+
echo "to undo: git checkout ."
|
|
135
|
+
fi
|
|
@@ -139,6 +139,9 @@
|
|
|
139
139
|
"Bash(git mv:*)",
|
|
140
140
|
"Bash(git rm:*)",
|
|
141
141
|
|
|
142
|
+
// sedreplace - safe bulk find-and-replace on git-tracked files only
|
|
143
|
+
"Bash(bash .agent/repo=ehmpathy/role=mechanic/skills/.skills/claude.tools/sedreplace.sh:*)",
|
|
144
|
+
|
|
142
145
|
// npm read operations
|
|
143
146
|
"Bash(npm view:*)",
|
|
144
147
|
"Bash(npm list:*)",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "rhachet-roles-ehmpathy",
|
|
3
3
|
"author": "ehmpathy",
|
|
4
4
|
"description": "empathetic software construction roles and skills, via rhachet",
|
|
5
|
-
"version": "1.15.
|
|
5
|
+
"version": "1.15.2",
|
|
6
6
|
"repository": "ehmpathy/rhachet-roles-ehmpathy",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet-roles-ehmpathy",
|
|
8
8
|
"keywords": [
|