bash-classify 0.1.0__tar.gz → 0.1.1__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.
Files changed (169) hide show
  1. {bash_classify-0.1.0 → bash_classify-0.1.1}/PKG-INFO +30 -28
  2. {bash_classify-0.1.0 → bash_classify-0.1.1}/README.md +29 -27
  3. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/cli.py +26 -0
  4. {bash_classify-0.1.0 → bash_classify-0.1.1}/.claude/rules/command-database.md +0 -0
  5. {bash_classify-0.1.0 → bash_classify-0.1.1}/.claude-plugin/marketplace.json +0 -0
  6. {bash_classify-0.1.0 → bash_classify-0.1.1}/.editorconfig +0 -0
  7. {bash_classify-0.1.0 → bash_classify-0.1.1}/.github/workflows/ci.yml +0 -0
  8. {bash_classify-0.1.0 → bash_classify-0.1.1}/.github/workflows/publish.yml +0 -0
  9. {bash_classify-0.1.0 → bash_classify-0.1.1}/.gitignore +0 -0
  10. {bash_classify-0.1.0 → bash_classify-0.1.1}/.python-version +0 -0
  11. {bash_classify-0.1.0 → bash_classify-0.1.1}/CLAUDE.md +0 -0
  12. {bash_classify-0.1.0 → bash_classify-0.1.1}/LICENSE +0 -0
  13. {bash_classify-0.1.0 → bash_classify-0.1.1}/SPEC.md +0 -0
  14. {bash_classify-0.1.0 → bash_classify-0.1.1}/coding-agent-plugins/claude-code/.claude-plugin/plugin.json +0 -0
  15. {bash_classify-0.1.0 → bash_classify-0.1.1}/coding-agent-plugins/claude-code/hooks/classify-bash.sh +0 -0
  16. {bash_classify-0.1.0 → bash_classify-0.1.1}/coding-agent-plugins/claude-code/hooks/hooks.json +0 -0
  17. {bash_classify-0.1.0 → bash_classify-0.1.1}/docs/classification-guidance.md +0 -0
  18. {bash_classify-0.1.0 → bash_classify-0.1.1}/pyproject.toml +0 -0
  19. {bash_classify-0.1.0 → bash_classify-0.1.1}/ruff.toml +0 -0
  20. {bash_classify-0.1.0 → bash_classify-0.1.1}/schemas/command.schema.json +0 -0
  21. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/__init__.py +0 -0
  22. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/__main__.py +0 -0
  23. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/classifier.py +0 -0
  24. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/apt.yaml +0 -0
  25. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/awk.yaml +0 -0
  26. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/basename.yaml +0 -0
  27. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/bash.yaml +0 -0
  28. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/brew.yaml +0 -0
  29. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/builtin.yaml +0 -0
  30. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/cargo.yaml +0 -0
  31. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/cat.yaml +0 -0
  32. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/chgrp.yaml +0 -0
  33. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/chmod.yaml +0 -0
  34. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/chown.yaml +0 -0
  35. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/column.yaml +0 -0
  36. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/comm.yaml +0 -0
  37. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/command.yaml +0 -0
  38. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/cp.yaml +0 -0
  39. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/curl.yaml +0 -0
  40. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/cut.yaml +0 -0
  41. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/date.yaml +0 -0
  42. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/df.yaml +0 -0
  43. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/diff.yaml +0 -0
  44. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/dig.yaml +0 -0
  45. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/dirname.yaml +0 -0
  46. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/docker.yaml +0 -0
  47. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/du.yaml +0 -0
  48. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/echo.yaml +0 -0
  49. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/env.yaml +0 -0
  50. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/expand.yaml +0 -0
  51. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/false.yaml +0 -0
  52. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/file.yaml +0 -0
  53. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/find.yaml +0 -0
  54. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/fmt.yaml +0 -0
  55. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/fold.yaml +0 -0
  56. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/free.yaml +0 -0
  57. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/gawk.yaml +0 -0
  58. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/git.yaml +0 -0
  59. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/go.yaml +0 -0
  60. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/grep.yaml +0 -0
  61. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/groups.yaml +0 -0
  62. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/gunzip.yaml +0 -0
  63. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/gzip.yaml +0 -0
  64. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/head.yaml +0 -0
  65. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/helm.yaml +0 -0
  66. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/hostname.yaml +0 -0
  67. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/id.yaml +0 -0
  68. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/install.yaml +0 -0
  69. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/join.yaml +0 -0
  70. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/journalctl.yaml +0 -0
  71. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/jq.yaml +0 -0
  72. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/kill.yaml +0 -0
  73. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/killall.yaml +0 -0
  74. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/kubectl.yaml +0 -0
  75. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/less.yaml +0 -0
  76. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/ln.yaml +0 -0
  77. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/ls.yaml +0 -0
  78. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/make.yaml +0 -0
  79. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/md5sum.yaml +0 -0
  80. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/mkdir.yaml +0 -0
  81. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/more.yaml +0 -0
  82. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/mv.yaml +0 -0
  83. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/netstat.yaml +0 -0
  84. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/nice.yaml +0 -0
  85. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/nl.yaml +0 -0
  86. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/node.yaml +0 -0
  87. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/nohup.yaml +0 -0
  88. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/npm.yaml +0 -0
  89. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/nslookup.yaml +0 -0
  90. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/paste.yaml +0 -0
  91. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/ping.yaml +0 -0
  92. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/pip.yaml +0 -0
  93. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/pip3.yaml +0 -0
  94. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/pkill.yaml +0 -0
  95. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/poetry.yaml +0 -0
  96. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/printenv.yaml +0 -0
  97. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/printf.yaml +0 -0
  98. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/ps.yaml +0 -0
  99. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/pwd.yaml +0 -0
  100. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/python.yaml +0 -0
  101. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/python3.yaml +0 -0
  102. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/read.yaml +0 -0
  103. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/readlink.yaml +0 -0
  104. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/realpath.yaml +0 -0
  105. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/rev.yaml +0 -0
  106. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/rm.yaml +0 -0
  107. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/rsync.yaml +0 -0
  108. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/scp.yaml +0 -0
  109. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/sed.yaml +0 -0
  110. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/seq.yaml +0 -0
  111. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/sh.yaml +0 -0
  112. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/sha1sum.yaml +0 -0
  113. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/sha256sum.yaml +0 -0
  114. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/sort.yaml +0 -0
  115. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/ss.yaml +0 -0
  116. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/ssh.yaml +0 -0
  117. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/stat.yaml +0 -0
  118. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/strace.yaml +0 -0
  119. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/sudo.yaml +0 -0
  120. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/systemctl.yaml +0 -0
  121. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/tac.yaml +0 -0
  122. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/tail.yaml +0 -0
  123. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/tar.yaml +0 -0
  124. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/tee.yaml +0 -0
  125. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/terraform.yaml +0 -0
  126. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/test.yaml +0 -0
  127. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/time.yaml +0 -0
  128. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/timeout.yaml +0 -0
  129. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/top.yaml +0 -0
  130. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/touch.yaml +0 -0
  131. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/tr.yaml +0 -0
  132. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/traceroute.yaml +0 -0
  133. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/true.yaml +0 -0
  134. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/type.yaml +0 -0
  135. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/uname.yaml +0 -0
  136. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/unexpand.yaml +0 -0
  137. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/uniq.yaml +0 -0
  138. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/unzip.yaml +0 -0
  139. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/uptime.yaml +0 -0
  140. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/uv.yaml +0 -0
  141. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/wc.yaml +0 -0
  142. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/wget.yaml +0 -0
  143. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/whereis.yaml +0 -0
  144. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/which.yaml +0 -0
  145. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/whoami.yaml +0 -0
  146. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/xargs.yaml +0 -0
  147. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/xmllint.yaml +0 -0
  148. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/yes.yaml +0 -0
  149. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/yq.yaml +0 -0
  150. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/zip.yaml +0 -0
  151. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/commands/zsh.yaml +0 -0
  152. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/database.py +0 -0
  153. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/matcher.py +0 -0
  154. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/models.py +0 -0
  155. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/parser.py +0 -0
  156. {bash_classify-0.1.0 → bash_classify-0.1.1}/src/bash_classify/py.typed +0 -0
  157. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/__init__.py +0 -0
  158. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/conftest.py +0 -0
  159. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_classifier.py +0 -0
  160. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_cli.py +0 -0
  161. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_cli_serialization.py +0 -0
  162. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_database.py +0 -0
  163. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_matcher.py +0 -0
  164. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_models.py +0 -0
  165. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_parser.py +0 -0
  166. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_real_world.py +0 -0
  167. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_schema.py +0 -0
  168. {bash_classify-0.1.0 → bash_classify-0.1.1}/tests/test_smoke.py +0 -0
  169. {bash_classify-0.1.0 → bash_classify-0.1.1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bash-classify
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Classify bash commands as READONLY, WRITE, DANGEROUS, or UNKNOWN
5
5
  Project-URL: Homepage, https://github.com/fprochazka/bash-classify
6
6
  Project-URL: Repository, https://github.com/fprochazka/bash-classify
@@ -61,35 +61,26 @@ $ echo 'find . -name "*.pyc" -delete' | bash-classify | jq '.classification'
61
61
  "DANGEROUS"
62
62
  ```
63
63
 
64
- ## Claude Code hook
65
-
66
- Install as a Claude Code hook to auto-allow read-only commands and require approval for everything else:
67
-
68
- ```json
69
- {
70
- "hooks": {
71
- "PreToolUse": [
72
- {
73
- "matcher": "Bash",
74
- "hooks": [
75
- {
76
- "type": "command",
77
- "command": "echo \"$CLAUDE_TOOL_INPUT\" | jq -r '.command' | bash-classify",
78
- "timeout": 5000,
79
- "on_output": [
80
- {
81
- "matcher": "\"classification\": \"READONLY\"",
82
- "action": "approve"
83
- }
84
- ]
85
- }
86
- ]
87
- }
88
- ]
89
- }
90
- }
64
+ ## Claude Code plugin
65
+
66
+ The repo includes a Claude Code plugin that auto-allows readonly bash commands via a `PreToolUse` hook. Install it as a marketplace:
67
+
68
+ ```bash
69
+ # First, install the bash-classify CLI
70
+ uv tool install bash-classify
71
+
72
+ # Then install the plugin marketplace
73
+ claude plugin add /path/to/bash-classify
74
+ ```
75
+
76
+ Or from GitHub directly:
77
+
78
+ ```bash
79
+ claude plugin add https://github.com/fprochazka/bash-classify
91
80
  ```
92
81
 
82
+ Once installed, any Bash tool call classified as `READONLY` is auto-approved — no permission prompt. Everything else (WRITE, DANGEROUS, UNKNOWN) still requires confirmation.
83
+
93
84
  ## Command database
94
85
 
95
86
  The classification database includes 120+ command definitions covering common Unix utilities, package managers, container tools, cloud CLIs, and more.
@@ -142,6 +133,17 @@ uv run pytest
142
133
 
143
134
  To add or modify command definitions, see [docs/classification-guidance.md](docs/classification-guidance.md). All YAML files in `src/bash_classify/commands/` are validated against a [JSON Schema](schemas/command.schema.json) — your IDE will provide autocomplete if it supports the `# $schema:` comment.
144
135
 
136
+ ## Releasing
137
+
138
+ Version is derived automatically from git tags via `hatch-vcs` — no manual version bumping needed.
139
+
140
+ ```bash
141
+ git tag v<version>
142
+ git push origin v<version>
143
+ ```
144
+
145
+ The `publish.yml` GitHub Action builds and publishes to PyPI automatically via trusted publishing.
146
+
145
147
  ## License
146
148
 
147
149
  [MIT](LICENSE)
@@ -32,35 +32,26 @@ $ echo 'find . -name "*.pyc" -delete' | bash-classify | jq '.classification'
32
32
  "DANGEROUS"
33
33
  ```
34
34
 
35
- ## Claude Code hook
36
-
37
- Install as a Claude Code hook to auto-allow read-only commands and require approval for everything else:
38
-
39
- ```json
40
- {
41
- "hooks": {
42
- "PreToolUse": [
43
- {
44
- "matcher": "Bash",
45
- "hooks": [
46
- {
47
- "type": "command",
48
- "command": "echo \"$CLAUDE_TOOL_INPUT\" | jq -r '.command' | bash-classify",
49
- "timeout": 5000,
50
- "on_output": [
51
- {
52
- "matcher": "\"classification\": \"READONLY\"",
53
- "action": "approve"
54
- }
55
- ]
56
- }
57
- ]
58
- }
59
- ]
60
- }
61
- }
35
+ ## Claude Code plugin
36
+
37
+ The repo includes a Claude Code plugin that auto-allows readonly bash commands via a `PreToolUse` hook. Install it as a marketplace:
38
+
39
+ ```bash
40
+ # First, install the bash-classify CLI
41
+ uv tool install bash-classify
42
+
43
+ # Then install the plugin marketplace
44
+ claude plugin add /path/to/bash-classify
45
+ ```
46
+
47
+ Or from GitHub directly:
48
+
49
+ ```bash
50
+ claude plugin add https://github.com/fprochazka/bash-classify
62
51
  ```
63
52
 
53
+ Once installed, any Bash tool call classified as `READONLY` is auto-approved — no permission prompt. Everything else (WRITE, DANGEROUS, UNKNOWN) still requires confirmation.
54
+
64
55
  ## Command database
65
56
 
66
57
  The classification database includes 120+ command definitions covering common Unix utilities, package managers, container tools, cloud CLIs, and more.
@@ -113,6 +104,17 @@ uv run pytest
113
104
 
114
105
  To add or modify command definitions, see [docs/classification-guidance.md](docs/classification-guidance.md). All YAML files in `src/bash_classify/commands/` are validated against a [JSON Schema](schemas/command.schema.json) — your IDE will provide autocomplete if it supports the `# $schema:` comment.
115
106
 
107
+ ## Releasing
108
+
109
+ Version is derived automatically from git tags via `hatch-vcs` — no manual version bumping needed.
110
+
111
+ ```bash
112
+ git tag v<version>
113
+ git push origin v<version>
114
+ ```
115
+
116
+ The `publish.yml` GitHub Action builds and publishes to PyPI automatically via trusted publishing.
117
+
116
118
  ## License
117
119
 
118
120
  [MIT](LICENSE)
@@ -95,7 +95,33 @@ def main() -> None:
95
95
  1 - parse error (invalid bash syntax)
96
96
  2 - internal error
97
97
  """
98
+ if len(sys.argv) > 1 and sys.argv[1] in ("-h", "--help"):
99
+ print("Usage: bash-classify < command")
100
+ print(" echo 'ls -la' | bash-classify")
101
+ print()
102
+ print("Reads a bash expression from stdin, classifies it, and outputs JSON.")
103
+ print()
104
+ print("Exit codes:")
105
+ print(" 0 successfully classified")
106
+ print(" 1 empty input")
107
+ print(" 2 internal error")
108
+ sys.exit(0)
109
+
110
+ if len(sys.argv) > 1 and sys.argv[1] in ("-v", "--version"):
111
+ from importlib.metadata import version
112
+
113
+ print(f"bash-classify {version('bash-classify')}")
114
+ sys.exit(0)
115
+
98
116
  try:
117
+ import select
118
+
119
+ # Timeout if no data arrives within 5 seconds
120
+ ready, _, _ = select.select([sys.stdin], [], [], 5.0)
121
+ if not ready:
122
+ print("bash-classify: timed out waiting for input on stdin (use --help for usage)", file=sys.stderr)
123
+ sys.exit(1)
124
+
99
125
  expression = sys.stdin.read().strip()
100
126
  if not expression:
101
127
  sys.exit(1)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes