Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"name": "warp",
"description": "Native Warp notifications when Claude completes tasks or needs input",
"source": "./plugins/warp",
"version": "2.1.0",
"version": "2.2.0",
"category": "productivity",
"tags": ["notifications", "terminal", "warp"]
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/warp/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "warp",
"description": "Warp terminal integration for Claude Code - native notifications, and more to come",
"version": "2.1.0",
"version": "2.2.0",
"author": {
"name": "Warp",
"url": "https://warp.dev"
Expand Down
10 changes: 10 additions & 0 deletions plugins/warp/hooks/hooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@
}
]
}
],
"StopFailure": [
{
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/on-stop-failure.sh"
}
]
}
]
}
}
53 changes: 53 additions & 0 deletions plugins/warp/scripts/on-stop-failure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash
# Hook script for Claude Code StopFailure event
# Sends a structured Warp notification when Claude's turn ends due to an API error

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/should-use-structured.sh"

# Legacy Warp clients that don't support structured events don't get a
# stop_failure notification — they have no UI to act on it.
if ! should_use_structured; then
exit 0
fi

source "$SCRIPT_DIR/build-payload.sh"

# Read hook input from stdin
INPUT=$(cat)

# Extract the error type (e.g. "rate_limit") and human-readable message.
ERROR_TYPE=$(echo "$INPUT" | jq -r '.error // empty' 2>/dev/null)
ERROR_MESSAGE=$(echo "$INPUT" | jq -r '.last_assistant_message // empty' 2>/dev/null)

# Also try to extract the last user query from the transcript so Warp can
# show it as the notification title, matching the Stop hook behaviour.
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
QUERY=""
if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
QUERY=$(jq -rs '
[
.[] | select(.type == "user") |
if .message.content | type == "string" then .
elif [.message.content[] | select(.type == "text")] | length > 0 then .
else empty
end
] | last |
if .message.content | type == "array"
then [.message.content[] | select(.type == "text") | .text] | join(" ")
else .message.content // empty
end
' "$TRANSCRIPT_PATH" 2>/dev/null)

if [ -n "$QUERY" ] && [ ${#QUERY} -gt 200 ]; then
QUERY="${QUERY:0:197}..."
fi
fi

BODY=$(build_payload "$INPUT" "stop_failure" \
--arg query "$QUERY" \
--arg response "$ERROR_MESSAGE" \
--arg error_type "$ERROR_TYPE" \
--arg transcript_path "$TRANSCRIPT_PATH")

"$SCRIPT_DIR/warp-notify.sh" "warp://cli-agent" "$BODY"
Loading