Add Claude Code hook integration for command suggestions#9
Merged
Conversation
Adds a new `aifr hook` parent command with a `check-command` sub-command designed for use as a Claude Code PreToolUse hook. When configured for the Bash tool matcher, it reads the hook payload from stdin, analyzes the shell command, and denies it with an aifr alternative suggestion when the operation can be safely handled by aifr. Recognized commands: cat, head, tail, grep/rg, find, ls, wc, stat, diff, sed -n, sha256sum/md5sum/sha1sum, hexdump/xxd, git log, git diff. Complex commands (pipes, chains, subshells) are passed through silently. The `hook` parent command is extensible for future hook integrations. https://claude.ai/code/session_017inmawi6PUgMy9zSu6EXKv
Verifies that a piped command (git log --oneline | head -n 10) passes through CheckCommand without generating a suggestion, confirming the full wiring from JSON input through shell operator detection. https://claude.ai/code/session_017inmawi6PUgMy9zSu6EXKv
Pipelines ending in | head -n N or | tail -n N are now recognized and mapped to the appropriate aifr limit parameter per command: - cat file | head -n N → aifr read --lines=1:N file - git log | head -n N → aifr log --max-count=N - grep pat . | head -N → aifr search --max-matches=N pat . - find/ls | head -N → --limit=N Suggestions now carry MCP tool metadata (tool name + args). When --mcp is set or an aifr MCP server is detected in .mcp.json / $AIFR_MCP, the deny reason references the MCP tool call instead of a CLI command. https://claude.ai/code/session_017inmawi6PUgMy9zSu6EXKv
Use a proper shell parser (mvdan/sh) instead of hand-rolled tokenize, splitPipeline, and hasShellOperators functions. The AST-based approach correctly handles all quoting variants, redirections (excluded from args automatically), environment variable prefixes (in CallExpr.Assigns), and pipeline detection via BinaryCmd nodes. https://claude.ai/code/session_017inmawi6PUgMy9zSu6EXKv
The end-to-end pipeline test now checks that the deny reason actually mentions "aifr log" / "aifr_log" and "max-count" / "max_count", matching what the comment promised. https://claude.ai/code/session_017inmawi6PUgMy9zSu6EXKv
Pipelines ending in sed -n 'N,Mp' or sed -n 'Np' are now recognized as pipeline modifiers. For cat, this maps directly to aifr read --lines: cat file | sed -n '50,100p' → aifr read --lines=50:100 file cat file | sed -n '42p' → aifr read --lines=42:42 file When the sed range starts at line 1, it normalizes to HeadLines so commands with head-style limits (find --limit, search --max-matches, log --max-count) also benefit. https://claude.ai/code/session_017inmawi6PUgMy9zSu6EXKv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a new
aifr hook check-commandsubcommand that integrates with Claude Code's PreToolUse hook system. It analyzes shell commands and suggests aifr alternatives when applicable, allowing users to leverage aifr's access controls instead of running raw shell commands.Key Changes
hookcommand group (cmd/aifr/cmd_hook.go): Top-level command for AI agent integrationshook check-commandsubcommand (cmd/aifr/cmd_hook_checkcommand.go): Reads Claude Code hook payloads from stdin and outputs hook responsesinternal/hookcmd/suggest.go): Analyzes shell commands and generates aifr suggestions for:cat,head,tail,ls,find,stat,diffgrep,egrep,fgrep,rgwc,hexdump,xxd,odsha256sum,sha1sum,md5sum,shasum,sha384sum,sha512sumsed -n(read-only patterns)git log,git diffinternal/hookcmd/shellparse.go): Robust tokenization and operator detection that handles:internal/hookcmd/hookcmd.go): Parses Claude Code hook payloads and generates compliant responsesImplementation Details
sed 's/foo/bar/'are not suggestedhttps://claude.ai/code/session_017inmawi6PUgMy9zSu6EXKv