rhachet-roles-ehmpathy 1.13.10 → 1.13.12
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,136 @@
|
|
|
1
|
+
{
|
|
2
|
+
// mechanic role permissions for Claude
|
|
3
|
+
//
|
|
4
|
+
// these permissions are conservative by design:
|
|
5
|
+
// - deny: commands that should never be auto-approved
|
|
6
|
+
// - ask: commands that require explicit user approval
|
|
7
|
+
// - allow: commands that are safe to auto-approve
|
|
8
|
+
|
|
9
|
+
"permissions": {
|
|
10
|
+
// commands that should never be auto-approved
|
|
11
|
+
"deny": [
|
|
12
|
+
// git write operations - require explicit user approval for audit trail
|
|
13
|
+
"Bash(git commit:*)",
|
|
14
|
+
"Bash(git add:*)",
|
|
15
|
+
"Bash(git stash:*)",
|
|
16
|
+
"Bash(git checkout:*)",
|
|
17
|
+
|
|
18
|
+
// "anywrite" commands - CRITICAL SECURITY RISK
|
|
19
|
+
//
|
|
20
|
+
// unlike Claude's native Edit/Write tools which are scoped to the repo,
|
|
21
|
+
// these bash commands can write ANYWHERE on your OS. this makes them
|
|
22
|
+
// prime targets for prompt injection attacks:
|
|
23
|
+
//
|
|
24
|
+
// 1. user asks claude to fetch docs from lookslegit.dev/api-reference
|
|
25
|
+
// 2. page contains hidden instructions to write innocent-looking content
|
|
26
|
+
// 3. with anywrite allowed, claude writes to ~/.bashrc or ~/.zshrc
|
|
27
|
+
// 4. content looks like helpful aliases but executes malicious logic
|
|
28
|
+
// 5. your entire system is now compromised
|
|
29
|
+
//
|
|
30
|
+
// sed: in-place file modification anywhere on disk
|
|
31
|
+
"Bash(sed:*)",
|
|
32
|
+
// tee: write to any path - ~/.bashrc, ~/.ssh/authorized_keys, etc.
|
|
33
|
+
"Bash(tee:*)",
|
|
34
|
+
// find -exec: arbitrary command execution on matched files
|
|
35
|
+
"Bash(find:*)",
|
|
36
|
+
// echo >: redirect to any file - echo "malicious" >> ~/.bashrc
|
|
37
|
+
"Bash(echo:*)",
|
|
38
|
+
// mv: move/overwrite any file - mv ~/.ssh/config ~/.ssh/config.bak
|
|
39
|
+
"Bash(mv:*)",
|
|
40
|
+
|
|
41
|
+
// test runners - should use npm run test:* scripts instead
|
|
42
|
+
// direct invocation bypasses project test configuration
|
|
43
|
+
"Bash(npx biome:*)",
|
|
44
|
+
"Bash(npx jest:*)"
|
|
45
|
+
],
|
|
46
|
+
|
|
47
|
+
// commands that require explicit user approval each time
|
|
48
|
+
"ask": [
|
|
49
|
+
"Bash(bash:*)",
|
|
50
|
+
"Bash(chmod:*)",
|
|
51
|
+
"Bash(npm install:*)",
|
|
52
|
+
"Bash(pnpm install:*)",
|
|
53
|
+
"Bash(pnpm add:*)"
|
|
54
|
+
],
|
|
55
|
+
|
|
56
|
+
// commands that are safe to auto-approve
|
|
57
|
+
"allow": [
|
|
58
|
+
// ide integrations
|
|
59
|
+
"mcp__ide__getDiagnostics",
|
|
60
|
+
|
|
61
|
+
// web access
|
|
62
|
+
"WebSearch",
|
|
63
|
+
"WebFetch(domain:github.com)",
|
|
64
|
+
"WebFetch(domain:www.npmjs.com)",
|
|
65
|
+
"WebFetch(domain:hub.docker.com)",
|
|
66
|
+
"WebFetch(domain:raw.githubusercontent.com)",
|
|
67
|
+
"WebFetch(domain:biomejs.dev)",
|
|
68
|
+
|
|
69
|
+
// git read-only
|
|
70
|
+
"Bash(git log:*)",
|
|
71
|
+
|
|
72
|
+
// filesystem read operations
|
|
73
|
+
"Bash(ls:*)",
|
|
74
|
+
"Bash(tree:*)",
|
|
75
|
+
"Bash(cat:*)",
|
|
76
|
+
"Bash(head:*)",
|
|
77
|
+
"Bash(tail:*)",
|
|
78
|
+
"Bash(grep:*)",
|
|
79
|
+
"Bash(wc:*)",
|
|
80
|
+
"Bash(diff:*)",
|
|
81
|
+
"Bash(which:*)",
|
|
82
|
+
"Bash(file:*)",
|
|
83
|
+
"Bash(mkdir:*)",
|
|
84
|
+
"Bash(pwd)",
|
|
85
|
+
|
|
86
|
+
// safe custom tools
|
|
87
|
+
"Bash(bash src/logic/roles/mechanic/.skills/claude.tools/mvsafe.sh:*)",
|
|
88
|
+
|
|
89
|
+
// npm read operations
|
|
90
|
+
"Bash(npm view:*)",
|
|
91
|
+
"Bash(npm list:*)",
|
|
92
|
+
"Bash(npm remove:*)",
|
|
93
|
+
|
|
94
|
+
// rhachet operations
|
|
95
|
+
"Bash(npx rhachet roles boot --repo ehmpathy --role mechanic)",
|
|
96
|
+
|
|
97
|
+
// self execution of packages
|
|
98
|
+
"Bash(npx tsx ./bin/run:*)",
|
|
99
|
+
|
|
100
|
+
// build operations
|
|
101
|
+
"Bash(npm run build:*)",
|
|
102
|
+
"Bash(npm run build:compile)",
|
|
103
|
+
"Bash(npm run start:testdb:*)",
|
|
104
|
+
|
|
105
|
+
// test operations
|
|
106
|
+
"Bash(npm run test:*)",
|
|
107
|
+
"Bash(npm run test:types:*)",
|
|
108
|
+
"Bash(npm run test:format:*)",
|
|
109
|
+
"Bash(npm run test:lint:*)",
|
|
110
|
+
"Bash(npm run test:unit:*)",
|
|
111
|
+
"Bash(npm run test:integration:*)",
|
|
112
|
+
"Bash(npm run test:acceptance:*)",
|
|
113
|
+
|
|
114
|
+
// thorough test operations
|
|
115
|
+
"Bash(THOROUGH=true npm run test:*)",
|
|
116
|
+
"Bash(THOROUGH=true npm run test:types:*)",
|
|
117
|
+
"Bash(THOROUGH=true npm run test:format:*)",
|
|
118
|
+
"Bash(THOROUGH=true npm run test:lint:*)",
|
|
119
|
+
"Bash(THOROUGH=true npm run test:unit:*)",
|
|
120
|
+
"Bash(THOROUGH=true npm run test:integration:*)",
|
|
121
|
+
"Bash(THOROUGH=true npm run test:acceptance:*)",
|
|
122
|
+
|
|
123
|
+
// fix operations
|
|
124
|
+
"Bash(npm run fix:*)",
|
|
125
|
+
"Bash(npm run fix:format:*)",
|
|
126
|
+
"Bash(npm run fix:lint:*)",
|
|
127
|
+
|
|
128
|
+
// github cli read operations
|
|
129
|
+
"Bash(gh pr checks:*)",
|
|
130
|
+
"Bash(gh pr status:*)",
|
|
131
|
+
|
|
132
|
+
// skill sourcing
|
|
133
|
+
"Bash(source .agent/repo=.this/skills/*)"
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
# • extends asks by appending new entries (conservative)
|
|
12
12
|
# • idempotent: safe to rerun
|
|
13
13
|
#
|
|
14
|
-
# .how =
|
|
15
|
-
#
|
|
14
|
+
# .how = loads permissions from init.claude.permissions.jsonc
|
|
15
|
+
# and uses jq to merge them into .claude/settings.local.json
|
|
16
16
|
#
|
|
17
17
|
# guarantee:
|
|
18
18
|
# ✔ creates .claude/settings.local.json if missing
|
|
@@ -29,95 +29,19 @@ set -euo pipefail
|
|
|
29
29
|
PROJECT_ROOT="$PWD"
|
|
30
30
|
SETTINGS_FILE="$PROJECT_ROOT/.claude/settings.local.json"
|
|
31
31
|
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"Bash(git add:*)",
|
|
46
|
-
"Bash(git stash:*)",
|
|
47
|
-
"Bash(git checkout:*)"
|
|
48
|
-
],
|
|
49
|
-
"ask": [
|
|
50
|
-
"Bash(bash:*)",
|
|
51
|
-
"Bash(chmod:*)",
|
|
52
|
-
"Bash(npm install:*)",
|
|
53
|
-
"Bash(pnpm install:*)",
|
|
54
|
-
"Bash(pnpm add:*)"
|
|
55
|
-
],
|
|
56
|
-
"allow": [
|
|
57
|
-
"mcp__ide__getDiagnostics",
|
|
58
|
-
|
|
59
|
-
"WebSearch",
|
|
60
|
-
"WebFetch(domain:github.com)",
|
|
61
|
-
"WebFetch(domain:www.npmjs.com)",
|
|
62
|
-
"WebFetch(domain:hub.docker.com)",
|
|
63
|
-
"WebFetch(domain:raw.githubusercontent.com)",
|
|
64
|
-
"WebFetch(domain:biomejs.dev)",
|
|
65
|
-
"Bash(git log:*),
|
|
66
|
-
|
|
67
|
-
"Bash(ls:*)",
|
|
68
|
-
"Bash(tree:*)",
|
|
69
|
-
"Bash(cat:*)",
|
|
70
|
-
"Bash(head:*)",
|
|
71
|
-
"Bash(tail:*)",
|
|
72
|
-
"Bash(grep:*)",
|
|
73
|
-
"Bash(wc:*)",
|
|
74
|
-
"Bash(diff:*)",
|
|
75
|
-
"Bash(which:*)",
|
|
76
|
-
"Bash(file:*)",
|
|
77
|
-
"Bash(mkdir:*)",
|
|
78
|
-
"Bash(pwd)",
|
|
79
|
-
"Bash(bash src/logic/roles/mechanic/.skills/claude.tools/mvsafe.sh:*)",
|
|
80
|
-
"Bash(npm view:*)",
|
|
81
|
-
"Bash(npm list:*)",
|
|
82
|
-
"Bash(npm remove:*)",
|
|
83
|
-
|
|
84
|
-
"Bash(npx rhachet roles boot --repo ehmpathy --role mechanic)",
|
|
85
|
-
"Bash(npx tsx ./bin/run:*)",
|
|
86
|
-
|
|
87
|
-
"Bash(npm run build:*)",
|
|
88
|
-
"Bash(npm run build:compile)",
|
|
89
|
-
"Bash(npm run start:testdb:*)",
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
"Bash(npm run test:*)",
|
|
93
|
-
"Bash(npm run test:types:*)",
|
|
94
|
-
"Bash(npm run test:format:*)",
|
|
95
|
-
"Bash(npm run test:lint:*)",
|
|
96
|
-
"Bash(npm run test:unit:*)",
|
|
97
|
-
"Bash(npm run test:integration:*)",
|
|
98
|
-
"Bash(npm run test:acceptance:*)",
|
|
99
|
-
|
|
100
|
-
"Bash(THOROUGH=true npm run test:*)",
|
|
101
|
-
"Bash(THOROUGH=true npm run test:types:*)",
|
|
102
|
-
"Bash(THOROUGH=true npm run test:format:*)",
|
|
103
|
-
"Bash(THOROUGH=true npm run test:lint:*)",
|
|
104
|
-
"Bash(THOROUGH=true npm run test:unit:*)",
|
|
105
|
-
"Bash(THOROUGH=true npm run test:integration:*)",
|
|
106
|
-
"Bash(THOROUGH=true npm run test:acceptance:*)",
|
|
107
|
-
|
|
108
|
-
"Bash(npm run fix:*)",
|
|
109
|
-
"Bash(npm run fix:format:*)",
|
|
110
|
-
"Bash(npm run fix:lint:*)",
|
|
111
|
-
|
|
112
|
-
"Bash(gh pr checks:*)",
|
|
113
|
-
"Bash(gh pr status:*)",
|
|
114
|
-
|
|
115
|
-
"Bash(source .agent/repo=.this/skills/*)"
|
|
116
|
-
]
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
EOF
|
|
120
|
-
)
|
|
32
|
+
# resolve the permissions config file (relative to this script)
|
|
33
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
34
|
+
PERMISSIONS_FILE="$SCRIPT_DIR/init.claude.permissions.jsonc"
|
|
35
|
+
|
|
36
|
+
# verify permissions file exists
|
|
37
|
+
if [[ ! -f "$PERMISSIONS_FILE" ]]; then
|
|
38
|
+
echo "❌ permissions config not found: $PERMISSIONS_FILE" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# load and parse JSONC (strip comments before parsing)
|
|
43
|
+
# - removes // line comments (both standalone and trailing)
|
|
44
|
+
PERMISSIONS_CONFIG=$(grep -v '^\s*//' "$PERMISSIONS_FILE" | sed 's|//.*||' | jq -c '.')
|
|
121
45
|
|
|
122
46
|
# ensure .claude directory exists
|
|
123
47
|
mkdir -p "$(dirname "$SETTINGS_FILE")"
|
|
@@ -145,19 +69,26 @@ jq --argjson perms "$PERMISSIONS_CONFIG" '
|
|
|
145
69
|
.permissions.ask = ((.permissions.ask // []) + $perms.permissions.ask | unique)
|
|
146
70
|
' "$SETTINGS_FILE" > "$SETTINGS_FILE.tmp"
|
|
147
71
|
|
|
148
|
-
|
|
149
|
-
|
|
72
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
|
|
73
|
+
BACKUP_FILE="${SETTINGS_FILE%.local.json}.${TIMESTAMP}.bak.local.json"
|
|
74
|
+
|
|
75
|
+
# check if any changes were made (use jq for semantic JSON comparison)
|
|
76
|
+
if jq -e --slurpfile before "$SETTINGS_FILE" --slurpfile after "$SETTINGS_FILE.tmp" -n '$before[0].permissions == $after[0].permissions' >/dev/null 2>&1; then
|
|
150
77
|
rm "$SETTINGS_FILE.tmp"
|
|
151
78
|
echo "👌 mechanic permissions already configured"
|
|
152
|
-
echo " $SETTINGS_FILE"
|
|
79
|
+
echo " ${SETTINGS_FILE#"$PROJECT_ROOT/"}"
|
|
153
80
|
exit 0
|
|
154
81
|
fi
|
|
155
82
|
|
|
83
|
+
# create backup before applying changes (guards against partial failures)
|
|
84
|
+
cp "$SETTINGS_FILE" "$BACKUP_FILE"
|
|
85
|
+
|
|
156
86
|
# atomic replace
|
|
157
87
|
mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE"
|
|
158
88
|
|
|
159
89
|
echo "🔐 mechanic permissions configured successfully!"
|
|
160
|
-
echo " $SETTINGS_FILE"
|
|
90
|
+
echo " ${SETTINGS_FILE#"$PROJECT_ROOT/"}"
|
|
91
|
+
echo " ${BACKUP_FILE#"$PROJECT_ROOT/"}"
|
|
161
92
|
echo ""
|
|
162
93
|
echo "✨ permissions applied:"
|
|
163
94
|
echo " • allow: replaced entirely"
|
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.13.
|
|
5
|
+
"version": "1.13.12",
|
|
6
6
|
"repository": "ehmpathy/rhachet-roles-ehmpathy",
|
|
7
7
|
"homepage": "https://github.com/ehmpathy/rhachet-roles-ehmpathy",
|
|
8
8
|
"keywords": [
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"fix": "npm run fix:format && npm run fix:lint",
|
|
28
28
|
"build:clean": "rm dist/ -rf",
|
|
29
29
|
"build:compile": "tsc -p ./tsconfig.build.json && tsc-alias -p ./tsconfig.build.json",
|
|
30
|
-
"build:complete": "rsync -a --prune-empty-dirs --include='*/' --exclude='**/.route/**' --exclude='**/.scratch/**' --exclude='**/.behavior/**' --exclude='**/*.test.sh' --include='**/*.template.md' --include='**/.briefs/**/*.md' --include='**/.briefs/*.md' --include='**/.skills/**/*.sh' --include='**/.skills/*.sh' --exclude='*' src/ dist/",
|
|
30
|
+
"build:complete": "rsync -a --prune-empty-dirs --include='*/' --exclude='**/.route/**' --exclude='**/.scratch/**' --exclude='**/.behavior/**' --exclude='**/*.test.sh' --include='**/*.template.md' --include='**/.briefs/**/*.md' --include='**/.briefs/*.md' --include='**/.skills/**/*.sh' --include='**/.skills/*.sh' --include='**/.skills/**/*.jsonc' --include='**/.skills/*.jsonc' --exclude='*' src/ dist/",
|
|
31
31
|
"build": "npm run build:clean && npm run build:compile && npm run build:complete --if-present",
|
|
32
32
|
"test:commits": "LAST_TAG=$(git describe --tags --abbrev=0 @^ 2> /dev/null || git rev-list --max-parents=0 HEAD) && npx commitlint --from $LAST_TAG --to HEAD --verbose",
|
|
33
33
|
"test:types": "tsc -p ./tsconfig.json --noEmit",
|