Skip to content

Commit 0b55be0

Browse files
committed
aihook: rename stop to shell
1 parent 0d8f3a8 commit 0b55be0

3 files changed

Lines changed: 32 additions & 18 deletions

File tree

aihook/AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ go test ./aihook/...
3636
go build ./aihook
3737

3838
# Run
39-
./aihook stop < script.sh
39+
./aihook shell < script.sh
4040
```
4141

4242
### Code Structure

aihook/README.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,19 @@ go build ./aihook
3434

3535
## Usage
3636

37-
### Stop Hook
37+
### Shell Hook
3838

39-
The `stop` subcommand validates shell scripts and ensures all `cd` commands are executed within subshells:
39+
The `shell` subcommand validates shell scripts and ensures all `cd` commands are executed within subshells:
4040

4141
```bash
4242
# Check a shell script from stdin
43-
echo 'cd /tmp' | aihook stop
43+
echo 'cd /tmp' | aihook shell
4444

4545
# With Claude Code hook format output
46-
echo 'cd /tmp' | aihook stop --claude
46+
echo 'cd /tmp' | aihook shell --claude
47+
48+
# Block execution when cd violations are found
49+
echo 'cd /tmp' | aihook shell --claude --block-on-cd
4750
```
4851

4952
### Examples
@@ -58,10 +61,15 @@ cd /tmp && ls
5861
(cd /tmp && ls)
5962
```
6063

64+
### Flags
65+
66+
- `--claude`: Output in JSON format compatible with Claude Code hooks
67+
- `--block-on-cd`: When set, returns exit code 2 for violations (blocks execution). Without this flag, violations are reported but execution is not blocked (exit code 0)
68+
6169
### Exit Codes
6270

63-
- `0`: No violations found
64-
- `2`: Violations detected (cd commands outside subshells)
71+
- `0`: No violations found (or violations found but `--block-on-cd` not set)
72+
- `2`: Violations detected and `--block-on-cd` flag is set
6573
- `1`: Parse error or other failure
6674

6775
### Output Formats
@@ -97,7 +105,7 @@ To use `aihook` as a Claude Code PreToolUse hook that validates Bash commands, a
97105
"hooks": [
98106
{
99107
"type": "command",
100-
"command": "aihook stop --claude"
108+
"command": "aihook shell --claude --block-on-cd"
101109
}
102110
]
103111
}
@@ -110,7 +118,8 @@ The hook will:
110118
- Match any Bash tool invocation (via the `"Bash"` matcher)
111119
- Receive the bash command script on stdin
112120
- Validate that all `cd` commands are in subshells
113-
- Return exit code 0 to allow, or exit code 2 to block with error message
121+
- With `--block-on-cd`: Return exit code 2 to block execution when violations are found
122+
- Without `--block-on-cd`: Report violations but allow execution (exit code 0)
114123
- Use `--claude` flag to output in the expected JSON format
115124

116125
For more flexible matching, you can use regex patterns like `"Bash.*cd"` to only check Bash commands containing `cd`.

aihook/main.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,22 @@ var rootCmd = &cobra.Command{
1717
Long: `aihook validates shell commands and code patterns for Claude Code hooks.`,
1818
}
1919

20-
var stopCmd = &cobra.Command{
21-
Use: "stop",
22-
Short: "Stop hook that validates shell commands",
23-
Long: `Stop hook that parses shell syntax and forbids 'cd' invocations outside subshells.`,
24-
RunE: runStop,
20+
var shellCmd = &cobra.Command{
21+
Use: "shell",
22+
Short: "Shell hook that validates shell commands",
23+
Long: `Shell hook that parses shell syntax and forbids 'cd' invocations outside subshells.`,
24+
RunE: runShell,
2525
}
2626

2727
var claudeFlag bool
28+
var blockOnCdFlag bool
2829

2930
func init() {
30-
rootCmd.AddCommand(stopCmd)
31+
rootCmd.AddCommand(shellCmd)
3132
rootCmd.AddCommand(version.NewVersionCommand("aihook"))
3233

33-
stopCmd.Flags().BoolVar(&claudeFlag, "claude", false, "Output in Claude Code hook format")
34+
shellCmd.Flags().BoolVar(&claudeFlag, "claude", false, "Output in Claude Code hook format")
35+
shellCmd.Flags().BoolVar(&blockOnCdFlag, "block-on-cd", false, "Block when cd commands are found outside subshells")
3436
}
3537

3638
func main() {
@@ -40,7 +42,7 @@ func main() {
4042
}
4143
}
4244

43-
func runStop(cmd *cobra.Command, args []string) error {
45+
func runShell(cmd *cobra.Command, args []string) error {
4446
v := validator.New()
4547
violations, err := v.ValidateScript(os.Stdin)
4648
if err != nil {
@@ -49,7 +51,10 @@ func runStop(cmd *cobra.Command, args []string) error {
4951

5052
if len(violations) > 0 {
5153
msg := validator.FormatViolations(violations)
52-
return formatOutput(msg, 2)
54+
if blockOnCdFlag {
55+
return formatOutput(msg, 2)
56+
}
57+
return formatOutput(msg, 0)
5358
}
5459

5560
return formatOutput("No violations found", 0)

0 commit comments

Comments
 (0)