Experimental: Add Antigravity and Claude code Hooks for nudging the agent toward the correct flutter-app-runtime behavior - #225
Conversation
…gent toward the correct flutter-app-runtime behavior
There was a problem hiding this comment.
Code Review
This pull request introduces pre-invocation and post-tool-use hooks for both Unix and Windows environments to detect Dart file edits and inject reminders to use the flutter-app-runtime skill for hot reloading. The review feedback highlights several critical issues: the Claude Code settings matcher needs to include str_replace_editor and its corresponding post-tool-use hook must look for the path argument instead of file_path to work correctly. Additionally, the temporary directory fallback logic needs to be consistent across scripts to prevent missing flag files, and the regex matching for Dart edits should be made case-insensitive and more robust.
| "hooks": { | ||
| "PostToolUse": [ | ||
| { | ||
| "matcher": "Edit|Write", |
There was a problem hiding this comment.
Claude Code's primary file editing tool is str_replace_editor. The current matcher only matches Edit|Write, which means this hook will never trigger when Claude Code edits files. Please add str_replace_editor to the matcher.
| "matcher": "Edit|Write", | |
| "matcher": "str_replace_editor|Edit|Write", |
| set -uo pipefail | ||
| INPUT="$(cat 2>/dev/null || true)" | ||
|
|
||
| if printf '%s' "$INPUT" | grep -Eq '"file_path"[^,]*[.]dart'; then |
There was a problem hiding this comment.
Claude Code's str_replace_editor tool uses the argument path rather than file_path to specify the file being edited. The current regex looking for "file_path" will never match, causing the hook to silently fail to detect Dart edits. Additionally, using case-insensitive matching (-i) ensures robustness against any casing variations in the JSON keys.
if printf '%s' "$INPUT" | grep -Eiq '"(file_path|path)"[^,]*[.]dart'; then
| CONV="$(printf '%s' "$INPUT" \ | ||
| | grep -o '"conversationId"[[:space:]]*:[[:space:]]*"[^"]*"' \ | ||
| | sed 's/.*"\([^"]*\)"$/\1/')" | ||
| FLAG="${TMPDIR:-/tmp}/flutter-app-runtime.${CONV:-default}.pending" |
There was a problem hiding this comment.
The temporary directory fallback logic here is inconsistent with .agents/hooks/flag-dart-edit (which uses ${TMPDIR:-${TEMP:-${TMP:-/tmp}}}). If TMPDIR is unset but TEMP or TMP is set, the two scripts will look in different directories, causing the flag file to not be found. Please make them consistent.
TEMP_DIR="${TMPDIR:-${TEMP:-${TMP:-/tmp}}}"
FLAG="${TEMP_DIR}/flutter-app-runtime.${CONV:-default}.pending"
| TEMP_DIR="${TMPDIR:-${TEMP:-${TMP:-/tmp}}}" | ||
| FLAG="${TEMP_DIR}/flutter-app-runtime.${CONV:-default}.pending" | ||
|
|
||
| if printf '%s' "$INPUT" | grep -Eq '"(TargetFile|AbsolutePath)"[^,]*[.]dart'; then |
There was a problem hiding this comment.
Using case-insensitive matching (-i) is safer and more robust against different casing (e.g., camelCase targetFile or absolutePath vs PascalCase TargetFile or AbsolutePath). Adding path as a fallback also ensures compatibility with other potential tool schemas.
if printf '%s' "$INPUT" | grep -Eiq '"(TargetFile|AbsolutePath|path)"[^,]*[.]dart'; then
Experimental PR, do not land.