bashgate 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- {bashgate-0.1.0 → bashgate-0.2.0}/PKG-INFO +12 -2
- {bashgate-0.1.0 → bashgate-0.2.0}/README.md +11 -1
- bashgate-0.1.0/bashgate.py → bashgate-0.2.0/bashgate/__init__.py +58 -0
- bashgate-0.2.0/bashgate/bashgate.default.json +236 -0
- {bashgate-0.1.0 → bashgate-0.2.0}/bashgate.egg-info/PKG-INFO +12 -2
- {bashgate-0.1.0 → bashgate-0.2.0}/bashgate.egg-info/SOURCES.txt +2 -1
- {bashgate-0.1.0 → bashgate-0.2.0}/pyproject.toml +6 -3
- {bashgate-0.1.0 → bashgate-0.2.0}/LICENSE +0 -0
- {bashgate-0.1.0 → bashgate-0.2.0}/bashgate.egg-info/dependency_links.txt +0 -0
- {bashgate-0.1.0 → bashgate-0.2.0}/bashgate.egg-info/entry_points.txt +0 -0
- {bashgate-0.1.0 → bashgate-0.2.0}/bashgate.egg-info/requires.txt +0 -0
- {bashgate-0.1.0 → bashgate-0.2.0}/bashgate.egg-info/top_level.txt +0 -0
- {bashgate-0.1.0 → bashgate-0.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bashgate
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Claude Code PreToolUse hook that screens bash commands with path validation
|
|
5
5
|
Author: Mog Nesbitt
|
|
6
6
|
License-Expression: MIT
|
|
@@ -64,7 +64,9 @@ If you don't want local configs to be able to weaken or disable your global rule
|
|
|
64
64
|
|
|
65
65
|
### Quick start
|
|
66
66
|
|
|
67
|
-
The default config
|
|
67
|
+
The default config ships with sensible rules for common commands. After `bashgate install`, you'll have a working setup that auto-approves things like `git status`, `ls`, `cat`, and `rg` while still prompting for destructive operations.
|
|
68
|
+
|
|
69
|
+
It's recommended you review the config and change it for your needs.
|
|
68
70
|
|
|
69
71
|
### Config format
|
|
70
72
|
|
|
@@ -151,6 +153,14 @@ bashgate validate --config path/to/config.json
|
|
|
151
153
|
|
|
152
154
|
This checks for structural errors, unknown keys, and invalid regex patterns.
|
|
153
155
|
|
|
156
|
+
## Uninstalling
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
bashgate uninstall
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
This removes the hook entry from `~/.claude/settings.json`. If `~/.claude/bashgate.json` exists, it will alert you but won't delete it — remove it manually if you no longer need it.
|
|
163
|
+
|
|
154
164
|
## `find` considered annoying
|
|
155
165
|
|
|
156
166
|
You'll find bashgate trips up on `find` quite a bit because of its awkward syntax. I'd suggest
|
|
@@ -45,7 +45,9 @@ If you don't want local configs to be able to weaken or disable your global rule
|
|
|
45
45
|
|
|
46
46
|
### Quick start
|
|
47
47
|
|
|
48
|
-
The default config
|
|
48
|
+
The default config ships with sensible rules for common commands. After `bashgate install`, you'll have a working setup that auto-approves things like `git status`, `ls`, `cat`, and `rg` while still prompting for destructive operations.
|
|
49
|
+
|
|
50
|
+
It's recommended you review the config and change it for your needs.
|
|
49
51
|
|
|
50
52
|
### Config format
|
|
51
53
|
|
|
@@ -132,6 +134,14 @@ bashgate validate --config path/to/config.json
|
|
|
132
134
|
|
|
133
135
|
This checks for structural errors, unknown keys, and invalid regex patterns.
|
|
134
136
|
|
|
137
|
+
## Uninstalling
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
bashgate uninstall
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
This removes the hook entry from `~/.claude/settings.json`. If `~/.claude/bashgate.json` exists, it will alert you but won't delete it — remove it manually if you no longer need it.
|
|
144
|
+
|
|
135
145
|
## `find` considered annoying
|
|
136
146
|
|
|
137
147
|
You'll find bashgate trips up on `find` quite a bit because of its awkward syntax. I'd suggest
|
|
@@ -965,6 +965,61 @@ def cmd_install():
|
|
|
965
965
|
print("Create one to define allowed commands. Without it, all commands fall through.")
|
|
966
966
|
|
|
967
967
|
|
|
968
|
+
def cmd_uninstall():
|
|
969
|
+
"""Remove bashgate hook from ~/.claude/settings.json."""
|
|
970
|
+
settings_path = _settings_path()
|
|
971
|
+
|
|
972
|
+
# Load existing settings
|
|
973
|
+
try:
|
|
974
|
+
with open(settings_path) as f:
|
|
975
|
+
settings = json.load(f)
|
|
976
|
+
except FileNotFoundError:
|
|
977
|
+
print(f"No settings file found at {settings_path}")
|
|
978
|
+
return
|
|
979
|
+
except (json.JSONDecodeError, OSError) as e:
|
|
980
|
+
print(f"Error reading {settings_path}: {e}", file=sys.stderr)
|
|
981
|
+
sys.exit(1)
|
|
982
|
+
|
|
983
|
+
hooks = settings.get("hooks", {})
|
|
984
|
+
pre_tool_use = hooks.get("PreToolUse", [])
|
|
985
|
+
|
|
986
|
+
# Find and remove bashgate entries
|
|
987
|
+
found = False
|
|
988
|
+
new_pre_tool_use = []
|
|
989
|
+
for entry in pre_tool_use:
|
|
990
|
+
if entry.get("matcher") != "Bash":
|
|
991
|
+
new_pre_tool_use.append(entry)
|
|
992
|
+
continue
|
|
993
|
+
original_hooks = entry.get("hooks", [])
|
|
994
|
+
remaining_hooks = [
|
|
995
|
+
h for h in original_hooks
|
|
996
|
+
if "bashgate" not in h.get("command", "")
|
|
997
|
+
]
|
|
998
|
+
if len(remaining_hooks) < len(original_hooks):
|
|
999
|
+
found = True
|
|
1000
|
+
if remaining_hooks:
|
|
1001
|
+
entry["hooks"] = remaining_hooks
|
|
1002
|
+
new_pre_tool_use.append(entry)
|
|
1003
|
+
|
|
1004
|
+
if not found:
|
|
1005
|
+
print(f"No bashgate hook found in {settings_path}")
|
|
1006
|
+
else:
|
|
1007
|
+
if new_pre_tool_use:
|
|
1008
|
+
hooks["PreToolUse"] = new_pre_tool_use
|
|
1009
|
+
else:
|
|
1010
|
+
hooks.pop("PreToolUse", None)
|
|
1011
|
+
if not hooks:
|
|
1012
|
+
settings.pop("hooks", None)
|
|
1013
|
+
_write_settings(settings_path, settings)
|
|
1014
|
+
print(f"Removed bashgate hook from {settings_path}")
|
|
1015
|
+
|
|
1016
|
+
# Alert about config file
|
|
1017
|
+
config_path = os.path.expanduser("~/.claude/bashgate.json")
|
|
1018
|
+
if os.path.isfile(config_path):
|
|
1019
|
+
print(f"\nNote: Config file still exists at {config_path}")
|
|
1020
|
+
print("You may want to remove it manually if no longer needed.")
|
|
1021
|
+
|
|
1022
|
+
|
|
968
1023
|
def _write_settings(path, settings):
|
|
969
1024
|
"""Write settings JSON to the given path."""
|
|
970
1025
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
@@ -983,6 +1038,7 @@ def cmd_help():
|
|
|
983
1038
|
print("Commands:")
|
|
984
1039
|
print(" bashgate hook [options] Run as a Claude Code PreToolUse hook (reads JSON from stdin)")
|
|
985
1040
|
print(" bashgate install Install hook into ~/.claude/settings.json")
|
|
1041
|
+
print(" bashgate uninstall Remove hook from ~/.claude/settings.json")
|
|
986
1042
|
print(" bashgate validate Validate a config file")
|
|
987
1043
|
print()
|
|
988
1044
|
print("Hook options:")
|
|
@@ -1173,6 +1229,8 @@ def main():
|
|
|
1173
1229
|
cmd_hook(rest)
|
|
1174
1230
|
elif subcommand == "install":
|
|
1175
1231
|
cmd_install()
|
|
1232
|
+
elif subcommand == "uninstall":
|
|
1233
|
+
cmd_uninstall()
|
|
1176
1234
|
elif subcommand == "validate":
|
|
1177
1235
|
cmd_validate(rest)
|
|
1178
1236
|
else:
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
{
|
|
2
|
+
"commands": [
|
|
3
|
+
"base64",
|
|
4
|
+
"basename",
|
|
5
|
+
"cat",
|
|
6
|
+
"cd",
|
|
7
|
+
"column",
|
|
8
|
+
"comm",
|
|
9
|
+
"cut",
|
|
10
|
+
"date",
|
|
11
|
+
"df",
|
|
12
|
+
"diff",
|
|
13
|
+
"diffstat",
|
|
14
|
+
"dirname",
|
|
15
|
+
"du",
|
|
16
|
+
"echo",
|
|
17
|
+
{
|
|
18
|
+
"command": "fd",
|
|
19
|
+
"ask": {
|
|
20
|
+
"flags": [
|
|
21
|
+
"-x",
|
|
22
|
+
"--exec",
|
|
23
|
+
"-X",
|
|
24
|
+
"--exec-batch"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"file",
|
|
29
|
+
{
|
|
30
|
+
"command": "find",
|
|
31
|
+
"ask": {
|
|
32
|
+
"flags": [
|
|
33
|
+
"-exec",
|
|
34
|
+
"-execdir",
|
|
35
|
+
"-ok",
|
|
36
|
+
"-okdir",
|
|
37
|
+
"-delete",
|
|
38
|
+
"-fls",
|
|
39
|
+
"-fprint",
|
|
40
|
+
"-fprint0",
|
|
41
|
+
"-fprintf"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"command": "gh",
|
|
47
|
+
"allow": {
|
|
48
|
+
"subcommands": [
|
|
49
|
+
{
|
|
50
|
+
"subcommand": "api",
|
|
51
|
+
"allow": {
|
|
52
|
+
"any_path": true
|
|
53
|
+
},
|
|
54
|
+
"ask": {
|
|
55
|
+
"flags": [
|
|
56
|
+
"-f",
|
|
57
|
+
"--field",
|
|
58
|
+
"--raw-field",
|
|
59
|
+
"--input"
|
|
60
|
+
],
|
|
61
|
+
"arg_regex": "(?i)-(X|-method)[= ]?(POST|PUT|PATCH|DELETE)"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"cache list",
|
|
65
|
+
"issue list",
|
|
66
|
+
"issue view",
|
|
67
|
+
"pr checks",
|
|
68
|
+
"pr create",
|
|
69
|
+
"pr diff",
|
|
70
|
+
"pr list",
|
|
71
|
+
"pr view",
|
|
72
|
+
"repo view",
|
|
73
|
+
"release list",
|
|
74
|
+
"release view",
|
|
75
|
+
"run list",
|
|
76
|
+
"run view",
|
|
77
|
+
"search issues"
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"command": "git",
|
|
83
|
+
"flags_with_args": [
|
|
84
|
+
"-C",
|
|
85
|
+
"-c",
|
|
86
|
+
"--git-dir",
|
|
87
|
+
"--work-tree",
|
|
88
|
+
"--namespace",
|
|
89
|
+
"--exec-path"
|
|
90
|
+
],
|
|
91
|
+
"allow": {
|
|
92
|
+
"subcommands": [
|
|
93
|
+
"add",
|
|
94
|
+
"blame",
|
|
95
|
+
{
|
|
96
|
+
"subcommand": "branch",
|
|
97
|
+
"ask": {
|
|
98
|
+
"flags": [
|
|
99
|
+
"-d",
|
|
100
|
+
"-D",
|
|
101
|
+
"--delete",
|
|
102
|
+
"-f",
|
|
103
|
+
"--force",
|
|
104
|
+
"-C",
|
|
105
|
+
"-M"
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"checkout -b",
|
|
110
|
+
{
|
|
111
|
+
"subcommand": "commit",
|
|
112
|
+
"ask": {
|
|
113
|
+
"flags": [
|
|
114
|
+
"--amend"
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"diff",
|
|
119
|
+
"fetch",
|
|
120
|
+
"log",
|
|
121
|
+
"ls-files",
|
|
122
|
+
"ls-tree",
|
|
123
|
+
{
|
|
124
|
+
"subcommand": "push",
|
|
125
|
+
"ask": {
|
|
126
|
+
"flags": [
|
|
127
|
+
"--force",
|
|
128
|
+
"-f",
|
|
129
|
+
"--force-with-lease",
|
|
130
|
+
"--force-if-includes",
|
|
131
|
+
"--delete",
|
|
132
|
+
"-d",
|
|
133
|
+
"--mirror",
|
|
134
|
+
"--all",
|
|
135
|
+
"--prune",
|
|
136
|
+
"--no-verify"
|
|
137
|
+
],
|
|
138
|
+
"arg_regex": ":[^\\s]+"
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"reflog",
|
|
142
|
+
"rev-parse",
|
|
143
|
+
"show",
|
|
144
|
+
"status",
|
|
145
|
+
"tag"
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"command": "go",
|
|
151
|
+
"allow": {
|
|
152
|
+
"subcommands": [
|
|
153
|
+
"build",
|
|
154
|
+
"doc",
|
|
155
|
+
"env",
|
|
156
|
+
"fmt",
|
|
157
|
+
"list",
|
|
158
|
+
"mod download",
|
|
159
|
+
"mod graph",
|
|
160
|
+
"mod tidy",
|
|
161
|
+
"mod verify",
|
|
162
|
+
"mod why",
|
|
163
|
+
"test",
|
|
164
|
+
"version",
|
|
165
|
+
"vet"
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"command": "grep",
|
|
171
|
+
"allow": {
|
|
172
|
+
"any_path": {
|
|
173
|
+
"position": 1
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
"head",
|
|
178
|
+
"jq",
|
|
179
|
+
"ls",
|
|
180
|
+
"md5",
|
|
181
|
+
"mise exec -- bundle exec rspec",
|
|
182
|
+
"mkdir",
|
|
183
|
+
{
|
|
184
|
+
"command": "mix",
|
|
185
|
+
"allow": {
|
|
186
|
+
"subcommands": [
|
|
187
|
+
"clean",
|
|
188
|
+
"compile",
|
|
189
|
+
"credo",
|
|
190
|
+
"deps",
|
|
191
|
+
"deps.compile",
|
|
192
|
+
"deps.get",
|
|
193
|
+
"dialyzer",
|
|
194
|
+
"format",
|
|
195
|
+
"test"
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
"nl",
|
|
200
|
+
"od",
|
|
201
|
+
"paste",
|
|
202
|
+
"pbcopy",
|
|
203
|
+
"printf",
|
|
204
|
+
"pwd",
|
|
205
|
+
"realpath",
|
|
206
|
+
"rev",
|
|
207
|
+
"rg",
|
|
208
|
+
{
|
|
209
|
+
"command": "sed",
|
|
210
|
+
"allow": {
|
|
211
|
+
"any_path": {
|
|
212
|
+
"position": 1
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
"ask": {
|
|
216
|
+
"arg_regex": "(?:-i\\S*|--in-place)"
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
"seq",
|
|
220
|
+
"shasum",
|
|
221
|
+
"sleep",
|
|
222
|
+
"sort",
|
|
223
|
+
"stat",
|
|
224
|
+
"strings",
|
|
225
|
+
"tail",
|
|
226
|
+
"test",
|
|
227
|
+
"tr",
|
|
228
|
+
"tree",
|
|
229
|
+
"uname",
|
|
230
|
+
"uniq",
|
|
231
|
+
"wc",
|
|
232
|
+
"which",
|
|
233
|
+
"whoami",
|
|
234
|
+
"xxd"
|
|
235
|
+
]
|
|
236
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bashgate
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Claude Code PreToolUse hook that screens bash commands with path validation
|
|
5
5
|
Author: Mog Nesbitt
|
|
6
6
|
License-Expression: MIT
|
|
@@ -64,7 +64,9 @@ If you don't want local configs to be able to weaken or disable your global rule
|
|
|
64
64
|
|
|
65
65
|
### Quick start
|
|
66
66
|
|
|
67
|
-
The default config
|
|
67
|
+
The default config ships with sensible rules for common commands. After `bashgate install`, you'll have a working setup that auto-approves things like `git status`, `ls`, `cat`, and `rg` while still prompting for destructive operations.
|
|
68
|
+
|
|
69
|
+
It's recommended you review the config and change it for your needs.
|
|
68
70
|
|
|
69
71
|
### Config format
|
|
70
72
|
|
|
@@ -151,6 +153,14 @@ bashgate validate --config path/to/config.json
|
|
|
151
153
|
|
|
152
154
|
This checks for structural errors, unknown keys, and invalid regex patterns.
|
|
153
155
|
|
|
156
|
+
## Uninstalling
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
bashgate uninstall
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
This removes the hook entry from `~/.claude/settings.json`. If `~/.claude/bashgate.json` exists, it will alert you but won't delete it — remove it manually if you no longer need it.
|
|
163
|
+
|
|
154
164
|
## `find` considered annoying
|
|
155
165
|
|
|
156
166
|
You'll find bashgate trips up on `find` quite a bit because of its awkward syntax. I'd suggest
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "bashgate"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.2.0"
|
|
8
8
|
description = "Claude Code PreToolUse hook that screens bash commands with path validation"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -27,8 +27,11 @@ dev = ["pytest"]
|
|
|
27
27
|
[project.scripts]
|
|
28
28
|
bashgate = "bashgate:main"
|
|
29
29
|
|
|
30
|
-
[tool.setuptools]
|
|
31
|
-
|
|
30
|
+
[tool.setuptools.packages.find]
|
|
31
|
+
include = ["bashgate"]
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.package-data]
|
|
34
|
+
bashgate = ["bashgate.default.json"]
|
|
32
35
|
|
|
33
36
|
[tool.pytest.ini_options]
|
|
34
37
|
testpaths = ["."]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|