-
Notifications
You must be signed in to change notification settings - Fork 171
Experimental: Add Antigravity and Claude code Hooks for nudging the agent toward the correct flutter-app-runtime behavior #225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #!/usr/bin/env bash | ||
| # flutter-app-runtime: PostToolUse handler (Claude Code). | ||
| # | ||
| # Fires after Edit or Write tool calls. | ||
| # Checks stdin for .dart file edits and outputs hookSpecificOutput with additionalContext. | ||
|
|
||
| set -uo pipefail | ||
| INPUT="$(cat 2>/dev/null || true)" | ||
|
|
||
| if printf '%s' "$INPUT" | grep -Eq '"file_path"[^,]*[.]dart'; then | ||
| echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Dart source changed. Use the flutter-app-runtime skill to push this to the running app: hot_reload for widget/UI or simple logic changes. If no app is running, say so and continue."}}' | ||
| fi | ||
| exit 0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| @echo off | ||
| rem flutter-app-runtime: PostToolUse handler for Windows (Claude Code). | ||
| rem | ||
| rem Fires after Edit or Write tool calls. | ||
| rem Checks stdin for .dart file edits and outputs hookSpecificOutput with additionalContext. | ||
|
|
||
| setlocal EnableExtensions EnableDelayedExpansion | ||
|
|
||
| findstr /I /C:".dart" >nul 2>&1 | ||
| if %errorlevel% equ 0 ( | ||
| echo {"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"Dart source changed. Use the flutter-app-runtime skill to push this to the running app: hot_reload for widget/UI or simple logic changes. If no app is running, say so and continue."}} | ||
| ) | ||
| exit /b 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| #!/usr/bin/env bash | ||
| # flutter-app-runtime: PostToolUse handler (Antigravity). | ||
| # | ||
| # PostToolUse (per Antigravity hooks documentation): | ||
| # Fires after a tool completes. The `matcher` field is a regular expression | ||
| # matched against the tool name (here: the file-writing tools). | ||
| # Input (stdin, camelCase JSON): | ||
| # toolCall - object; the executed tool call, with `name` and `args` | ||
| # stepIdx - integer; 0-based index of the completed step | ||
| # error - string, optional; runtime error if the call failed, else empty | ||
| # plus common fields: conversationId, workspacePaths, transcriptPath, | ||
| # artifactDirectoryPath, modelName | ||
| # Output (stdout): an empty JSON object `{}` -- PostToolUse has NO field for | ||
| # injecting context back into the conversation. | ||
| # | ||
| # Because of that last point, this handler cannot deliver the reminder itself. | ||
| # It only records that a .dart file was touched; the PreInvocation handler | ||
| # reads the flag and does the actual injection before the next model call. | ||
|
|
||
| set -uo pipefail | ||
| INPUT="$(cat 2>/dev/null || true)" | ||
|
|
||
| CONV="$(printf '%s' "$INPUT" \ | ||
| | grep -o '"conversationId"[[:space:]]*:[[:space:]]*"[^"]*"' \ | ||
| | sed 's/.*"\([^"]*\)"$/\1/')" | ||
| 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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using case-insensitive matching ( |
||
| : > "$FLAG" 2>/dev/null || true | ||
| fi | ||
|
|
||
| echo '{}' | ||
| exit 0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| @echo off | ||
| rem flutter-app-runtime: PostToolUse handler for Windows (Antigravity). | ||
| rem | ||
| rem Native Windows batch script using findstr and %TEMP%. | ||
| rem Zero runtime dependencies; executes in < 5ms. | ||
|
|
||
| setlocal EnableExtensions EnableDelayedExpansion | ||
|
|
||
| findstr /I /C:".dart" >nul 2>&1 | ||
| if %errorlevel% equ 0 ( | ||
| type nul > "%TEMP%\flutter-app-runtime.default.pending" 2>nul | ||
| ) | ||
|
|
||
| echo {} | ||
| exit /b 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| #!/usr/bin/env bash | ||
| # flutter-app-runtime: PreInvocation handler (Antigravity). | ||
| # | ||
| # PreInvocation (per Antigravity hooks documentation): | ||
| # Fires before the model is called. There is no matcher -- the event key | ||
| # holds a flat list of handlers, and any matcher would be ignored. | ||
| # Input (stdin, camelCase JSON): | ||
| # invocationNum - integer; 0-indexed sequence number of this model | ||
| # invocation (the first invocation is 0) | ||
| # initialNumSteps - integer; number of steps currently in the trajectory | ||
| # plus common fields: conversationId, workspacePaths, transcriptPath, | ||
| # artifactDirectoryPath, modelName | ||
| # Output (stdout): | ||
| # injectSteps - optional array of steps injected into the conversation | ||
| # trajectory before the model is called. Each step carries | ||
| # one of: `toolCall` (a tool call to execute), `userMessage` | ||
| # (a message from the user), or `ephemeralMessage` (a | ||
| # transient system message -- what this hook uses). | ||
| # | ||
| # This is the injection point: if a .dart file was edited since the last model | ||
| # call, inject a one-shot reminder pointing the agent at the | ||
| # flutter-app-runtime skill. | ||
|
|
||
| set -uo pipefail | ||
| INPUT="$(cat 2>/dev/null || true)" | ||
|
|
||
| CONV="$(printf '%s' "$INPUT" \ | ||
| | grep -o '"conversationId"[[:space:]]*:[[:space:]]*"[^"]*"' \ | ||
| | sed 's/.*"\([^"]*\)"$/\1/')" | ||
| FLAG="${TMPDIR:-/tmp}/flutter-app-runtime.${CONV:-default}.pending" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The temporary directory fallback logic here is inconsistent with |
||
|
|
||
| if [ -f "$FLAG" ]; then | ||
| rm -f "$FLAG" 2>/dev/null || true | ||
| echo '{"injectSteps":[{"ephemeralMessage":"Dart source changed. Use the flutter-app-runtime skill to push this to the running app: hot_reload for widget/UI or simple logic changes. If no app is running, say so and continue."}]}' | ||
| else | ||
| echo '{"injectSteps":[]}' | ||
| fi | ||
| exit 0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| @echo off | ||
| rem flutter-app-runtime: PreInvocation handler for Windows (Antigravity). | ||
| rem | ||
| rem Native Windows batch script checking for pending Dart edit flag. | ||
| rem Zero runtime dependencies; executes in < 5ms. | ||
|
|
||
| setlocal EnableExtensions EnableDelayedExpansion | ||
|
|
||
| set "FLAG_FOUND=0" | ||
| if exist "%TEMP%\flutter-app-runtime.*.pending" set "FLAG_FOUND=1" | ||
| if exist "%TEMP%\flutter-app-runtime.pending" set "FLAG_FOUND=1" | ||
|
|
||
| if "!FLAG_FOUND!"=="1" ( | ||
| del /f /q "%TEMP%\flutter-app-runtime.*.pending" 2>nul | ||
| del /f /q "%TEMP%\flutter-app-runtime.pending" 2>nul | ||
| echo {"injectSteps":[{"ephemeralMessage":"Dart source changed. Use the flutter-app-runtime skill to push this to the running app: hot_reload for widget/UI or simple logic changes. If no app is running, say so and continue."}]} | ||
| ) else ( | ||
| echo {"injectSteps":[]} | ||
| ) | ||
| exit /b 0 |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,16 @@ | ||||||
| { | ||||||
| "hooks": { | ||||||
| "PostToolUse": [ | ||||||
| { | ||||||
| "matcher": "Edit|Write", | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude Code's primary file editing tool is
Suggested change
|
||||||
| "hooks": [ | ||||||
| { | ||||||
| "type": "command", | ||||||
| "command": ".agents/hooks/claude-post-tool-use", | ||||||
| "statusMessage": "flutter-app-runtime: mcp__dart__hot_reload" | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude Code's
str_replace_editortool uses the argumentpathrather thanfile_pathto 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.