Skip to content

Commit 0e9636f

Browse files
committed
centralize hook structure
1 parent daf3622 commit 0e9636f

4 files changed

Lines changed: 53 additions & 52 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
# Builds a structured JSON notification payload for warp://cli-agent.
3+
#
4+
# Usage: source this file, then call build_payload with event-specific fields.
5+
#
6+
# Example:
7+
# source "$(dirname "${BASH_SOURCE[0]}")/build-payload.sh"
8+
# BODY=$(build_payload "$INPUT" "stop" \
9+
# --arg query "$QUERY" \
10+
# --arg response "$RESPONSE" \
11+
# --arg transcript_path "$TRANSCRIPT_PATH")
12+
#
13+
# The function extracts common fields (session_id, cwd, project) from the
14+
# hook's stdin JSON (passed as $1), then merges any extra jq args you pass.
15+
16+
build_payload() {
17+
local input="$1"
18+
local event="$2"
19+
shift 2
20+
21+
# Extract common fields from the hook input
22+
local session_id cwd project
23+
session_id=$(echo "$input" | jq -r '.session_id // empty' 2>/dev/null)
24+
cwd=$(echo "$input" | jq -r '.cwd // empty' 2>/dev/null)
25+
project=""
26+
if [ -n "$cwd" ]; then
27+
project=$(basename "$cwd")
28+
fi
29+
30+
# Build the payload: common fields + any extra args passed by the caller.
31+
# Extra args should be jq flag pairs like: --arg key "value" or --argjson key '{"a":1}'
32+
jq -nc \
33+
--arg agent "claude" \
34+
--arg event "$event" \
35+
--arg session_id "$session_id" \
36+
--arg cwd "$cwd" \
37+
--arg project "$project" \
38+
"$@" \
39+
'{v:1, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project} + $ARGS.named'
40+
}

plugins/warp/scripts/on-notification.sh

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,17 @@
33
# Sends a structured Warp notification when Claude has been idle
44

55
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
source "$SCRIPT_DIR/build-payload.sh"
67

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

10-
# Extract metadata from the hook input
11+
# Extract notification-specific fields
1112
NOTIF_TYPE=$(echo "$INPUT" | jq -r '.notification_type // "unknown"' 2>/dev/null)
12-
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
1313
MSG=$(echo "$INPUT" | jq -r '.message // "Input needed"' 2>/dev/null)
1414
[ -z "$MSG" ] && MSG="Input needed"
15-
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
16-
PROJECT=""
17-
if [ -n "$CWD" ]; then
18-
PROJECT=$(basename "$CWD")
19-
fi
2015

21-
# Build structured JSON payload
22-
BODY=$(jq -nc \
23-
--arg agent "claude" \
24-
--arg event "$NOTIF_TYPE" \
25-
--arg session_id "$SESSION_ID" \
26-
--arg cwd "$CWD" \
27-
--arg project "$PROJECT" \
28-
--arg summary "$MSG" \
29-
'{v:1, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, summary:$summary}')
16+
BODY=$(build_payload "$INPUT" "$NOTIF_TYPE" \
17+
--arg summary "$MSG")
3018

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

plugins/warp/scripts/on-permission-request.sh

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,18 @@
33
# Sends a structured Warp notification when Claude needs permission to run a tool
44

55
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
source "$SCRIPT_DIR/build-payload.sh"
67

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

10-
# Extract metadata from the hook input
11-
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
11+
# Extract permission-request-specific fields
1212
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"' 2>/dev/null)
1313
TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // {}' 2>/dev/null)
1414
# Fallback to empty object if jq failed or returned empty
1515
[ -z "$TOOL_INPUT" ] && TOOL_INPUT='{}'
16-
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
17-
PROJECT=""
18-
if [ -n "$CWD" ]; then
19-
PROJECT=$(basename "$CWD")
20-
fi
2116

22-
# Build a human-readable summary for the notification body
17+
# Build a human-readable summary
2318
TOOL_PREVIEW=$(echo "$INPUT" | jq -r '.tool_input | if .command then .command elif .file_path then .file_path else (tostring | .[0:80]) end // ""' 2>/dev/null)
2419
SUMMARY="Wants to run $TOOL_NAME"
2520
if [ -n "$TOOL_PREVIEW" ]; then
@@ -29,17 +24,9 @@ if [ -n "$TOOL_PREVIEW" ]; then
2924
SUMMARY="$SUMMARY: $TOOL_PREVIEW"
3025
fi
3126

32-
# Build structured JSON payload
33-
# tool_input is passed as raw JSON (not a string) so Warp can inspect it directly
34-
BODY=$(jq -nc \
35-
--arg agent "claude" \
36-
--arg event "permission_request" \
37-
--arg session_id "$SESSION_ID" \
38-
--arg cwd "$CWD" \
39-
--arg project "$PROJECT" \
27+
BODY=$(build_payload "$INPUT" "permission_request" \
4028
--arg summary "$SUMMARY" \
4129
--arg tool_name "$TOOL_NAME" \
42-
--argjson tool_input "$TOOL_INPUT" \
43-
'{v:1, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, summary:$summary, tool_name:$tool_name, tool_input:$tool_input}')
30+
--argjson tool_input "$TOOL_INPUT")
4431

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

plugins/warp/scripts/on-stop.sh

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Sends a structured Warp notification when Claude completes a task
44

55
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
source "$SCRIPT_DIR/build-payload.sh"
67

78
# Read hook input from stdin
89
INPUT=$(cat)
@@ -13,18 +14,10 @@ if [ "$STOP_HOOK_ACTIVE" = "true" ]; then
1314
exit 0
1415
fi
1516

16-
# Extract metadata from the hook input
17-
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
18-
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
19-
CWD=$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null)
20-
PROJECT=""
21-
if [ -n "$CWD" ]; then
22-
PROJECT=$(basename "$CWD")
23-
fi
24-
2517
# Extract the last user prompt and assistant response from the transcript.
2618
# Small delay to allow Claude Code to flush the current turn to the transcript file.
2719
# The Stop hook fires before the transcript is fully written.
20+
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
2821
sleep 0.3
2922
QUERY=""
3023
RESPONSE=""
@@ -54,16 +47,9 @@ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
5447
fi
5548
fi
5649

57-
# Build structured JSON payload
58-
BODY=$(jq -nc \
59-
--arg agent "claude" \
60-
--arg event "stop" \
61-
--arg session_id "$SESSION_ID" \
62-
--arg cwd "$CWD" \
63-
--arg project "$PROJECT" \
50+
BODY=$(build_payload "$INPUT" "stop" \
6451
--arg query "$QUERY" \
6552
--arg response "$RESPONSE" \
66-
--arg transcript_path "$TRANSCRIPT_PATH" \
67-
'{v:1, agent:$agent, event:$event, session_id:$session_id, cwd:$cwd, project:$project, query:$query, response:$response, transcript_path:$transcript_path}')
53+
--arg transcript_path "$TRANSCRIPT_PATH")
6854

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

0 commit comments

Comments
 (0)