Skip to content

Commit e0e18e1

Browse files
authored
Add StopFailure hook (#73)
1 parent 58c823d commit e0e18e1

4 files changed

Lines changed: 65 additions & 2 deletions

File tree

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"name": "warp",
1111
"description": "Native Warp notifications when Claude completes tasks or needs input",
1212
"source": "./plugins/warp",
13-
"version": "2.1.0",
13+
"version": "2.2.0",
1414
"category": "productivity",
1515
"tags": ["notifications", "terminal", "warp"]
1616
},

plugins/warp/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "warp",
33
"description": "Warp terminal integration for Claude Code - native notifications, and more to come",
4-
"version": "2.1.0",
4+
"version": "2.2.0",
55
"author": {
66
"name": "Warp",
77
"url": "https://warp.dev"

plugins/warp/hooks/hooks.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@
6262
}
6363
]
6464
}
65+
],
66+
"StopFailure": [
67+
{
68+
"hooks": [
69+
{
70+
"type": "command",
71+
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/on-stop-failure.sh"
72+
}
73+
]
74+
}
6575
]
6676
}
6777
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash
2+
# Hook script for Claude Code StopFailure event
3+
# Sends a structured Warp notification when Claude's turn ends due to an API error
4+
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
source "$SCRIPT_DIR/should-use-structured.sh"
7+
8+
# Legacy Warp clients that don't support structured events don't get a
9+
# stop_failure notification — they have no UI to act on it.
10+
if ! should_use_structured; then
11+
exit 0
12+
fi
13+
14+
source "$SCRIPT_DIR/build-payload.sh"
15+
16+
# Read hook input from stdin
17+
INPUT=$(cat)
18+
19+
# Extract the error type (e.g. "rate_limit") and human-readable message.
20+
ERROR_TYPE=$(echo "$INPUT" | jq -r '.error // empty' 2>/dev/null)
21+
ERROR_MESSAGE=$(echo "$INPUT" | jq -r '.last_assistant_message // empty' 2>/dev/null)
22+
23+
# Also try to extract the last user query from the transcript so Warp can
24+
# show it as the notification title, matching the Stop hook behaviour.
25+
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
26+
QUERY=""
27+
if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
28+
QUERY=$(jq -rs '
29+
[
30+
.[] | select(.type == "user") |
31+
if .message.content | type == "string" then .
32+
elif [.message.content[] | select(.type == "text")] | length > 0 then .
33+
else empty
34+
end
35+
] | last |
36+
if .message.content | type == "array"
37+
then [.message.content[] | select(.type == "text") | .text] | join(" ")
38+
else .message.content // empty
39+
end
40+
' "$TRANSCRIPT_PATH" 2>/dev/null)
41+
42+
if [ -n "$QUERY" ] && [ ${#QUERY} -gt 200 ]; then
43+
QUERY="${QUERY:0:197}..."
44+
fi
45+
fi
46+
47+
BODY=$(build_payload "$INPUT" "stop_failure" \
48+
--arg query "$QUERY" \
49+
--arg response "$ERROR_MESSAGE" \
50+
--arg error_type "$ERROR_TYPE" \
51+
--arg transcript_path "$TRANSCRIPT_PATH")
52+
53+
"$SCRIPT_DIR/warp-notify.sh" "warp://cli-agent" "$BODY"

0 commit comments

Comments
 (0)