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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bashgate
3
- Version: 0.1.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 (`bashgate.default.json`) 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.
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 (`bashgate.default.json`) 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.
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.1.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 (`bashgate.default.json`) 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.
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
@@ -1,7 +1,8 @@
1
1
  LICENSE
2
2
  README.md
3
- bashgate.py
4
3
  pyproject.toml
4
+ bashgate/__init__.py
5
+ bashgate/bashgate.default.json
5
6
  bashgate.egg-info/PKG-INFO
6
7
  bashgate.egg-info/SOURCES.txt
7
8
  bashgate.egg-info/dependency_links.txt
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "bashgate"
7
- version = "0.1.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
- py-modules = ["bashgate"]
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