bash-classify 0.5.0__tar.gz → 0.7.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.
- {bash_classify-0.5.0 → bash_classify-0.7.0}/.claude-plugin/marketplace.json +1 -1
- {bash_classify-0.5.0 → bash_classify-0.7.0}/PKG-INFO +9 -5
- {bash_classify-0.5.0 → bash_classify-0.7.0}/README.md +8 -4
- {bash_classify-0.5.0 → bash_classify-0.7.0}/coding-agent-plugins/claude-code/.claude-plugin/plugin.json +1 -1
- bash_classify-0.7.0/coding-agent-plugins/claude-code/hooks/hook-permission-request.sh +37 -0
- bash_classify-0.7.0/coding-agent-plugins/claude-code/hooks/hooks.json +31 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/docs/classification-guidance.md +8 -2
- {bash_classify-0.5.0 → bash_classify-0.7.0}/schemas/command.schema.json +26 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/env.yaml +0 -1
- bash_classify-0.7.0/src/bash_classify/commands/gog.yaml +983 -0
- bash_classify-0.7.0/src/bash_classify/commands/gws.yaml +211 -0
- bash_classify-0.7.0/src/bash_classify/commands/mise.yaml +579 -0
- bash_classify-0.7.0/src/bash_classify/commands/pnpm.yaml +343 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/pup.yaml +272 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/xargs.yaml +0 -1
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/database.py +24 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/matcher.py +11 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/models.py +1 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_classifier.py +57 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_database.py +39 -0
- bash_classify-0.5.0/coding-agent-plugins/claude-code/hooks/hooks.json +0 -18
- {bash_classify-0.5.0 → bash_classify-0.7.0}/.claude/rules/command-database.md +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/.editorconfig +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/.github/workflows/ci.yml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/.github/workflows/publish.yml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/.gitignore +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/.python-version +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/CLAUDE.md +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/LICENSE +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/SPEC.md +0 -0
- /bash_classify-0.5.0/coding-agent-plugins/claude-code/hooks/classify-bash.sh → /bash_classify-0.7.0/coding-agent-plugins/claude-code/hooks/hook-pre-tool-use.sh +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/pyproject.toml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/ruff.toml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/__init__.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/__main__.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/classifier.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/cli.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/agent-browser.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/apt.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/awk.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/basename.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/bash-classify.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/bash.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/black.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/brew.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/builtin.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/cargo.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/cat.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/chgrp.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/chmod.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/chown.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/column.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/comm.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/command.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/cp.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/curl.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/cut.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/date.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/df.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/diff.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/dig.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/dirname.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/docker.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/du.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/echo.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/eslint.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/expand.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/false.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/file.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/find.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/fmt.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/fold.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/free.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/gawk.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/gcloud.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/gh.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/git.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/glab-discussion.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/glab.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/go.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/gradle.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/gradlew.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/grep.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/groups.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/gunzip.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/gzip.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/hadolint.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/head.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/helm.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/hostname.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/id.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/install.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/isort.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/java.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/javac.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/join.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/journalctl.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/jq.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/kill.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/killall.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/kubectl.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/less.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/ln.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/ls.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/make.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/md5sum.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/mkdir.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/more.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/mv.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/mvn.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/mvnw.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/mypy.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/netstat.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/nice.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/nl.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/node.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/nohup.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/npm.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/npx.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/nslookup.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/paste.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/ping.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/pip.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/pip3.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/pipx.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/pkill.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/poetry.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/prettier.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/printenv.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/printf.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/ps.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/pwd.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/pytest.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/python.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/python3.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/read.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/readlink.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/realpath.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/rev.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/rg.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/rm.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/rsync.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/ruff.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/scp.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/sed.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/seq.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/sh.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/sha1sum.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/sha256sum.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/shellcheck.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/sort.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/ss.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/ssh.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/stat.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/strace.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/sudo.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/systemctl.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/tac.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/tail.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/tar.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/tee.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/terraform.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/test.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/time.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/timeout.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/top.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/touch.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/tr.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/traceroute.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/true.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/tsc.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/type.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/uname.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/unexpand.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/uniq.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/unzip.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/uptime.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/uv.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/wc.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/wget.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/whereis.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/which.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/whoami.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/xmllint.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/yarn.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/yes.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/yq.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/zip.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/commands/zsh.yaml +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/parser.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/src/bash_classify/py.typed +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/__init__.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/conftest.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_cli.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_cli_serialization.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_matcher.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_models.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_parser.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_real_world.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_schema.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/tests/test_smoke.py +0 -0
- {bash_classify-0.5.0 → bash_classify-0.7.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bash-classify
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
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
|
|
@@ -33,7 +33,7 @@ Classify bash commands by their side-effect risk level.
|
|
|
33
33
|
|
|
34
34
|
## What it does
|
|
35
35
|
|
|
36
|
-
bash-classify parses bash expressions using tree-sitter, classifies each command against a database of
|
|
36
|
+
bash-classify parses bash expressions using tree-sitter, classifies each command against a database of 150+ known commands, and outputs a structured JSON verdict. Commands are classified along two axes: **classification** (`READONLY`, `LOCAL_EFFECTS`, `EXTERNAL_EFFECTS`, `DANGEROUS`, `UNKNOWN`) describing what kind of effects a command has, and **risk** (`LOW`, `MEDIUM`, `HIGH`) describing how worried you should be.
|
|
37
37
|
|
|
38
38
|
Designed primarily as a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) hook to automatically allow low-risk commands while flagging risky ones for human review.
|
|
39
39
|
|
|
@@ -86,10 +86,12 @@ Once installed, any Bash tool call with `risk: LOW` is auto-approved — no perm
|
|
|
86
86
|
|
|
87
87
|
## Command database
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
bash-classify loads command definitions from two locations:
|
|
90
90
|
|
|
91
|
-
-
|
|
92
|
-
-
|
|
91
|
+
- **Built-in database** — 150+ command definitions bundled with the package, covering common Unix utilities, package managers, container tools, cloud CLIs, and more. Lives in `src/bash_classify/commands/*.yaml`.
|
|
92
|
+
- **User database** — your own command definitions at `~/.config/bash-classify/commands/*.yaml` (override the location with the `BASH_CLASSIFY_CONFIG_DIR` env var, which resolves to `$BASH_CLASSIFY_CONFIG_DIR/commands/`). User files with the same name as a built-in override it completely, so you can customize classifications for internal tools, company-specific wrappers, or personal CLIs without forking the repo.
|
|
93
|
+
|
|
94
|
+
Both directories use the same YAML format. See [docs/classification-guidance.md](docs/classification-guidance.md) for how to add new commands. YAML definitions are validated against a [JSON Schema](schemas/command.schema.json) for IDE autocomplete and CI checks.
|
|
93
95
|
|
|
94
96
|
## Classification levels
|
|
95
97
|
|
|
@@ -118,7 +120,9 @@ Risk defaults are derived from classification (`READONLY`→LOW, `LOCAL_EFFECTS`
|
|
|
118
120
|
- **Tree-sitter parsing** -- bash expressions are parsed into an AST for accurate command extraction, handling pipes, subshells, and command substitution
|
|
119
121
|
- **YAML command database** -- each command has classification rules with subcommand and option matching
|
|
120
122
|
- **Subcommand matching** -- `kubectl get` and `kubectl delete` can have different classifications
|
|
123
|
+
- **Multi-goal build tools** -- `subcommand_mode: match_all` handles commands like `mvn clean install` and `gradle clean build test` where multiple goals can be combined in any order
|
|
121
124
|
- **Delegation for wrappers** -- commands like `xargs`, `sudo`, and `env` delegate classification to the inner command
|
|
125
|
+
- **File path detection** -- redirect operators (`>`, `>>`, `<`) are parsed into `write_paths`/`read_paths` in the output; writes to `/tmp` and `/var/tmp` stay at LOW risk
|
|
122
126
|
|
|
123
127
|
## Python API
|
|
124
128
|
|
|
@@ -4,7 +4,7 @@ Classify bash commands by their side-effect risk level.
|
|
|
4
4
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
|
-
bash-classify parses bash expressions using tree-sitter, classifies each command against a database of
|
|
7
|
+
bash-classify parses bash expressions using tree-sitter, classifies each command against a database of 150+ known commands, and outputs a structured JSON verdict. Commands are classified along two axes: **classification** (`READONLY`, `LOCAL_EFFECTS`, `EXTERNAL_EFFECTS`, `DANGEROUS`, `UNKNOWN`) describing what kind of effects a command has, and **risk** (`LOW`, `MEDIUM`, `HIGH`) describing how worried you should be.
|
|
8
8
|
|
|
9
9
|
Designed primarily as a [Claude Code](https://docs.anthropic.com/en/docs/claude-code) hook to automatically allow low-risk commands while flagging risky ones for human review.
|
|
10
10
|
|
|
@@ -57,10 +57,12 @@ Once installed, any Bash tool call with `risk: LOW` is auto-approved — no perm
|
|
|
57
57
|
|
|
58
58
|
## Command database
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
bash-classify loads command definitions from two locations:
|
|
61
61
|
|
|
62
|
-
-
|
|
63
|
-
-
|
|
62
|
+
- **Built-in database** — 150+ command definitions bundled with the package, covering common Unix utilities, package managers, container tools, cloud CLIs, and more. Lives in `src/bash_classify/commands/*.yaml`.
|
|
63
|
+
- **User database** — your own command definitions at `~/.config/bash-classify/commands/*.yaml` (override the location with the `BASH_CLASSIFY_CONFIG_DIR` env var, which resolves to `$BASH_CLASSIFY_CONFIG_DIR/commands/`). User files with the same name as a built-in override it completely, so you can customize classifications for internal tools, company-specific wrappers, or personal CLIs without forking the repo.
|
|
64
|
+
|
|
65
|
+
Both directories use the same YAML format. See [docs/classification-guidance.md](docs/classification-guidance.md) for how to add new commands. YAML definitions are validated against a [JSON Schema](schemas/command.schema.json) for IDE autocomplete and CI checks.
|
|
64
66
|
|
|
65
67
|
## Classification levels
|
|
66
68
|
|
|
@@ -89,7 +91,9 @@ Risk defaults are derived from classification (`READONLY`→LOW, `LOCAL_EFFECTS`
|
|
|
89
91
|
- **Tree-sitter parsing** -- bash expressions are parsed into an AST for accurate command extraction, handling pipes, subshells, and command substitution
|
|
90
92
|
- **YAML command database** -- each command has classification rules with subcommand and option matching
|
|
91
93
|
- **Subcommand matching** -- `kubectl get` and `kubectl delete` can have different classifications
|
|
94
|
+
- **Multi-goal build tools** -- `subcommand_mode: match_all` handles commands like `mvn clean install` and `gradle clean build test` where multiple goals can be combined in any order
|
|
92
95
|
- **Delegation for wrappers** -- commands like `xargs`, `sudo`, and `env` delegate classification to the inner command
|
|
96
|
+
- **File path detection** -- redirect operators (`>`, `>>`, `<`) are parsed into `write_paths`/`read_paths` in the output; writes to `/tmp` and `/var/tmp` stay at LOW risk
|
|
93
97
|
|
|
94
98
|
## Python API
|
|
95
99
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Fallback hook: PreToolUse isn't consistently fired from subagents, so we
|
|
5
|
+
# also classify on PermissionRequest (just before the user sees the dialog)
|
|
6
|
+
# and auto-allow low-risk commands there.
|
|
7
|
+
|
|
8
|
+
BASH_CLASSIFY=""
|
|
9
|
+
if command -v bash-classify &>/dev/null; then
|
|
10
|
+
BASH_CLASSIFY="bash-classify"
|
|
11
|
+
elif [[ -x "$HOME/.local/bin/bash-classify" ]]; then
|
|
12
|
+
BASH_CLASSIFY="$HOME/.local/bin/bash-classify"
|
|
13
|
+
else
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
input=$(cat)
|
|
18
|
+
|
|
19
|
+
command=$(echo "$input" | jq -r '.tool_input.command // empty')
|
|
20
|
+
|
|
21
|
+
if [[ -z "$command" ]]; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
classification_output=$(echo "$command" | "$BASH_CLASSIFY" 2>/dev/null) || true
|
|
26
|
+
|
|
27
|
+
if [[ -z "$classification_output" ]]; then
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
risk=$(echo "$classification_output" | jq -r '.risk // empty')
|
|
32
|
+
|
|
33
|
+
if [[ "$risk" == "LOW" ]]; then
|
|
34
|
+
echo '{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow"}}}'
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
exit 0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Auto-allow low-risk bash commands using bash-classify",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "Bash",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/hook-pre-tool-use.sh",
|
|
11
|
+
"timeout": 10,
|
|
12
|
+
"statusMessage": "Classifying bash command..."
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"PermissionRequest": [
|
|
18
|
+
{
|
|
19
|
+
"matcher": "Bash",
|
|
20
|
+
"hooks": [
|
|
21
|
+
{
|
|
22
|
+
"type": "command",
|
|
23
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/hook-permission-request.sh",
|
|
24
|
+
"timeout": 10,
|
|
25
|
+
"statusMessage": "Classifying bash command..."
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -236,6 +236,12 @@ subcommands:
|
|
|
236
236
|
|
|
237
237
|
Some commands do not do work themselves -- they delegate to an inner command. bash-classify models this with `delegates_to`, which tells the matcher how to extract the inner command's argv and classify it recursively.
|
|
238
238
|
|
|
239
|
+
### Pure-wrapper rule of thumb
|
|
240
|
+
|
|
241
|
+
For commands that are pure passthroughs -- they do nothing themselves beyond running the inner command (e.g. `env`, `xargs`, `mise exec`, `pnpm exec`) -- **omit `classification`**. The missing base defaults to `READONLY`, which is the identity element for severity-max against the delegated inner: the inner command's classification is what surfaces. Writing `classification: READONLY` explicitly on a pure wrapper is misleading -- it reads as "this command is safe" when the real intent is "inherit from whatever I wrap."
|
|
242
|
+
|
|
243
|
+
Only set a non-`READONLY` base when the wrapper itself contributes risk regardless of the inner (e.g. `sudo` is `EXTERNAL_EFFECTS` because it elevates privileges) or when the wrapper also has a meaningful standalone behavior that isn't READONLY.
|
|
244
|
+
|
|
239
245
|
### `rest_are_argv`
|
|
240
246
|
|
|
241
247
|
All remaining positional args (after the wrapper's own options) form the inner command.
|
|
@@ -244,7 +250,7 @@ All remaining positional args (after the wrapper's own options) form the inner c
|
|
|
244
250
|
|
|
245
251
|
```yaml
|
|
246
252
|
command: xargs
|
|
247
|
-
classification
|
|
253
|
+
# classification omitted -- pure passthrough, inherits from inner
|
|
248
254
|
delegates_to:
|
|
249
255
|
mode: rest_are_argv
|
|
250
256
|
options:
|
|
@@ -267,7 +273,7 @@ delegates_to:
|
|
|
267
273
|
|
|
268
274
|
```yaml
|
|
269
275
|
command: env
|
|
270
|
-
classification
|
|
276
|
+
# classification omitted -- pure passthrough
|
|
271
277
|
delegates_to:
|
|
272
278
|
mode: rest_are_argv
|
|
273
279
|
strip_assignments: true # strip leading KEY=VALUE tokens
|
|
@@ -6,6 +6,28 @@
|
|
|
6
6
|
"type": "object",
|
|
7
7
|
"required": ["command"],
|
|
8
8
|
"additionalProperties": false,
|
|
9
|
+
"oneOf": [
|
|
10
|
+
{
|
|
11
|
+
"description": "Alias file: points at another command, mutually exclusive with classification-bearing fields",
|
|
12
|
+
"required": ["alias_of"],
|
|
13
|
+
"not": {
|
|
14
|
+
"anyOf": [
|
|
15
|
+
{"required": ["classification"]},
|
|
16
|
+
{"required": ["risk"]},
|
|
17
|
+
{"required": ["subcommands"]},
|
|
18
|
+
{"required": ["options"]},
|
|
19
|
+
{"required": ["global_options"]},
|
|
20
|
+
{"required": ["subcommand_mode"]},
|
|
21
|
+
{"required": ["delegates_to"]},
|
|
22
|
+
{"required": ["strict"]}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"description": "Regular command definition",
|
|
28
|
+
"not": {"required": ["alias_of"]}
|
|
29
|
+
}
|
|
30
|
+
],
|
|
9
31
|
"properties": {
|
|
10
32
|
"command": {
|
|
11
33
|
"type": "string",
|
|
@@ -15,6 +37,10 @@
|
|
|
15
37
|
"type": "string",
|
|
16
38
|
"description": "Short description of the tool"
|
|
17
39
|
},
|
|
40
|
+
"alias_of": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Name of another command in the database whose definition should be used verbatim. Mutually exclusive with classification/risk/subcommands/options/global_options/subcommand_mode/delegates_to/strict."
|
|
43
|
+
},
|
|
18
44
|
"classification": {
|
|
19
45
|
"$ref": "#/$defs/Classification"
|
|
20
46
|
},
|