rhachet-roles-ehmpathy 1.15.15 → 1.15.16
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.
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"deny": [
|
|
12
12
|
// git write operations - require explicit user request for audit trail
|
|
13
13
|
"Bash(git commit:*)",
|
|
14
|
-
"Bash(git add
|
|
14
|
+
"Bash(git add .)",
|
|
15
|
+
"Bash(git add -A:*)",
|
|
16
|
+
"Bash(git add --all:*)",
|
|
15
17
|
"Bash(git stash:*)",
|
|
16
18
|
"Bash(git checkout:*)",
|
|
17
19
|
"Bash(git branch -d:*)",
|
|
@@ -24,6 +26,10 @@
|
|
|
24
26
|
"Bash(git reflog delete:*)",
|
|
25
27
|
"Bash(git config:*)",
|
|
26
28
|
|
|
29
|
+
// git mv/rm - use mvsafe.sh and rmsafe.sh instead (repo-constrained)
|
|
30
|
+
"Bash(git mv:*)",
|
|
31
|
+
"Bash(git rm:*)",
|
|
32
|
+
|
|
27
33
|
// "anywrite" commands - CRITICAL SECURITY RISK
|
|
28
34
|
//
|
|
29
35
|
// unlike Claude's native Edit/Write tools which are scoped to the repo,
|
|
@@ -141,10 +147,6 @@
|
|
|
141
147
|
"Bash(mkdir:*)",
|
|
142
148
|
"Bash(pwd)",
|
|
143
149
|
|
|
144
|
-
// git mv/rm are safe - constrained to repo, all changes revertable
|
|
145
|
-
"Bash(git mv:*)",
|
|
146
|
-
"Bash(git rm:*)",
|
|
147
|
-
|
|
148
150
|
// git read-only - all have no write variants
|
|
149
151
|
"Bash(git log:*)",
|
|
150
152
|
"Bash(git status:*)",
|
|
@@ -162,6 +164,12 @@
|
|
|
162
164
|
// cpsafe - safe file copy within git repo (source must be git-tracked)
|
|
163
165
|
"Bash(.agent/repo=ehmpathy/role=mechanic/skills/.skills/claude.tools/cpsafe.sh:*)",
|
|
164
166
|
|
|
167
|
+
// mvsafe - safe file move within git repo
|
|
168
|
+
"Bash(.agent/repo=ehmpathy/role=mechanic/skills/.skills/claude.tools/mvsafe.sh:*)",
|
|
169
|
+
|
|
170
|
+
// rmsafe - safe file removal within git repo
|
|
171
|
+
"Bash(.agent/repo=ehmpathy/role=mechanic/skills/.skills/claude.tools/rmsafe.sh:*)",
|
|
172
|
+
|
|
165
173
|
// npm read operations
|
|
166
174
|
"Bash(npm view:*)",
|
|
167
175
|
"Bash(npm list:*)",
|
|
@@ -209,6 +217,9 @@
|
|
|
209
217
|
"Bash(RESNAP=true THOROUGH=true npm run test:integration:*)",
|
|
210
218
|
"Bash(RESNAP=true THOROUGH=true npm run test:acceptance:*)",
|
|
211
219
|
|
|
220
|
+
// test list operation
|
|
221
|
+
"Bash(npx jest --listTests:*)",
|
|
222
|
+
|
|
212
223
|
// fix operations
|
|
213
224
|
"Bash(npm run fix:*)",
|
|
214
225
|
"Bash(npm run fix:format:*)",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = safe file move within git repo
|
|
4
|
+
#
|
|
5
|
+
# .why = enables file moving without:
|
|
6
|
+
# - touching files outside the repo
|
|
7
|
+
# - accidental path traversal attacks
|
|
8
|
+
#
|
|
9
|
+
# this is a controlled alternative to raw mv, which is
|
|
10
|
+
# denied in permissions due to security risks.
|
|
11
|
+
#
|
|
12
|
+
# usage:
|
|
13
|
+
# mvsafe.sh --src "path/to/source" --dest "path/to/dest"
|
|
14
|
+
#
|
|
15
|
+
# guarantee:
|
|
16
|
+
# - source must be within repo
|
|
17
|
+
# - dest must be within repo
|
|
18
|
+
# - creates parent directories if needed
|
|
19
|
+
# - fail-fast on errors
|
|
20
|
+
######################################################################
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
# parse named arguments
|
|
24
|
+
SRC=""
|
|
25
|
+
DEST=""
|
|
26
|
+
|
|
27
|
+
while [[ $# -gt 0 ]]; do
|
|
28
|
+
case $1 in
|
|
29
|
+
--src)
|
|
30
|
+
SRC="$2"
|
|
31
|
+
shift 2
|
|
32
|
+
;;
|
|
33
|
+
--dest)
|
|
34
|
+
DEST="$2"
|
|
35
|
+
shift 2
|
|
36
|
+
;;
|
|
37
|
+
*)
|
|
38
|
+
echo "unknown argument: $1"
|
|
39
|
+
echo "usage: mvsafe.sh --src 'source' --dest 'destination'"
|
|
40
|
+
exit 1
|
|
41
|
+
;;
|
|
42
|
+
esac
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
# validate required args
|
|
46
|
+
if [[ -z "$SRC" ]]; then
|
|
47
|
+
echo "error: --src is required"
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
if [[ -z "$DEST" ]]; then
|
|
52
|
+
echo "error: --dest is required"
|
|
53
|
+
exit 1
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# ensure we're in a git repo
|
|
57
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
58
|
+
echo "error: not in a git repository"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# get repo root
|
|
63
|
+
REPO_ROOT=$(git rev-parse --show-toplevel)
|
|
64
|
+
|
|
65
|
+
# resolve absolute paths
|
|
66
|
+
SRC_ABS=$(realpath -m "$SRC")
|
|
67
|
+
DEST_ABS=$(realpath -m "$DEST")
|
|
68
|
+
|
|
69
|
+
# validate source is within repo
|
|
70
|
+
if [[ "$SRC_ABS" != "$REPO_ROOT"* ]]; then
|
|
71
|
+
echo "error: source must be within the git repository"
|
|
72
|
+
echo " repo root: $REPO_ROOT"
|
|
73
|
+
echo " source: $SRC_ABS"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# validate dest is within repo
|
|
78
|
+
if [[ "$DEST_ABS" != "$REPO_ROOT"* ]]; then
|
|
79
|
+
echo "error: destination must be within the git repository"
|
|
80
|
+
echo " repo root: $REPO_ROOT"
|
|
81
|
+
echo " dest: $DEST_ABS"
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# validate source exists
|
|
86
|
+
if [[ ! -e "$SRC_ABS" ]]; then
|
|
87
|
+
echo "error: source does not exist: $SRC"
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# create parent directories if needed
|
|
92
|
+
DEST_DIR=$(dirname "$DEST_ABS")
|
|
93
|
+
if [[ ! -d "$DEST_DIR" ]]; then
|
|
94
|
+
echo "creating directory: $DEST_DIR"
|
|
95
|
+
mkdir -p "$DEST_DIR"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# perform the move
|
|
99
|
+
mv "$SRC_ABS" "$DEST_ABS"
|
|
100
|
+
|
|
101
|
+
SRC_REL="${SRC_ABS#$REPO_ROOT/}"
|
|
102
|
+
DEST_REL="${DEST_ABS#$REPO_ROOT/}"
|
|
103
|
+
echo "moved: $SRC_REL -> $DEST_REL"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
######################################################################
|
|
3
|
+
# .what = safe file removal within git repo
|
|
4
|
+
#
|
|
5
|
+
# .why = enables file deletion without:
|
|
6
|
+
# - touching files outside the repo
|
|
7
|
+
# - accidental path traversal attacks
|
|
8
|
+
#
|
|
9
|
+
# this is a controlled alternative to raw rm, which is
|
|
10
|
+
# denied in permissions due to security risks.
|
|
11
|
+
#
|
|
12
|
+
# usage:
|
|
13
|
+
# rmsafe.sh --path "path/to/file"
|
|
14
|
+
# rmsafe.sh --path "path/to/dir" --recursive
|
|
15
|
+
#
|
|
16
|
+
# guarantee:
|
|
17
|
+
# - path must be within repo
|
|
18
|
+
# - requires --recursive for directories
|
|
19
|
+
# - fail-fast on errors
|
|
20
|
+
######################################################################
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
# parse named arguments
|
|
24
|
+
TARGET=""
|
|
25
|
+
RECURSIVE=false
|
|
26
|
+
|
|
27
|
+
while [[ $# -gt 0 ]]; do
|
|
28
|
+
case $1 in
|
|
29
|
+
--path)
|
|
30
|
+
TARGET="$2"
|
|
31
|
+
shift 2
|
|
32
|
+
;;
|
|
33
|
+
--recursive|-r)
|
|
34
|
+
RECURSIVE=true
|
|
35
|
+
shift
|
|
36
|
+
;;
|
|
37
|
+
*)
|
|
38
|
+
echo "unknown argument: $1"
|
|
39
|
+
echo "usage: rmsafe.sh --path 'target' [--recursive]"
|
|
40
|
+
exit 1
|
|
41
|
+
;;
|
|
42
|
+
esac
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
# validate required args
|
|
46
|
+
if [[ -z "$TARGET" ]]; then
|
|
47
|
+
echo "error: --path is required"
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# ensure we're in a git repo
|
|
52
|
+
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
53
|
+
echo "error: not in a git repository"
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# get repo root
|
|
58
|
+
REPO_ROOT=$(git rev-parse --show-toplevel)
|
|
59
|
+
|
|
60
|
+
# resolve absolute path
|
|
61
|
+
TARGET_ABS=$(realpath -m "$TARGET")
|
|
62
|
+
|
|
63
|
+
# validate target is within repo
|
|
64
|
+
if [[ "$TARGET_ABS" != "$REPO_ROOT"* ]]; then
|
|
65
|
+
echo "error: path must be within the git repository"
|
|
66
|
+
echo " repo root: $REPO_ROOT"
|
|
67
|
+
echo " path: $TARGET_ABS"
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# prevent deleting repo root itself
|
|
72
|
+
if [[ "$TARGET_ABS" == "$REPO_ROOT" ]]; then
|
|
73
|
+
echo "error: cannot delete the repository root"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# validate target exists
|
|
78
|
+
if [[ ! -e "$TARGET_ABS" ]]; then
|
|
79
|
+
echo "error: path does not exist: $TARGET"
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# check if directory and require --recursive
|
|
84
|
+
if [[ -d "$TARGET_ABS" ]] && [[ "$RECURSIVE" != true ]]; then
|
|
85
|
+
echo "error: target is a directory, use --recursive to delete"
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# perform the removal
|
|
90
|
+
if [[ "$RECURSIVE" == true ]]; then
|
|
91
|
+
rm -rf "$TARGET_ABS"
|
|
92
|
+
else
|
|
93
|
+
rm "$TARGET_ABS"
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
TARGET_REL="${TARGET_ABS#$REPO_ROOT/}"
|
|
97
|
+
echo "removed: $TARGET_REL"
|
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.16",
|
|
6
6
|
"repository": "ehmpathy/rhachet-roles-ehmpathy",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet-roles-ehmpathy",
|
|
8
8
|
"keywords": [
|