Add community skills, agents, system prompts from 22+ sources
Community Skills (32): - jat: jat-start, jat-verify, jat-complete - pi-mono: codex-cli, codex-5.3-prompting, interactive-shell - picoclaw: github, weather, tmux, summarize, skill-creator - dyad: 18 skills (swarm-to-plan, multi-pr-review, fix-issue, lint, etc.) - dexter: dcf valuation skill Agents (23): - pi-mono subagents: scout, planner, reviewer, worker - toad: 19 agent configs (Claude, Codex, Gemini, Copilot, OpenCode, etc.) System Prompts (91): - Anthropic: 15 Claude prompts (opus-4.6, code, cowork, etc.) - OpenAI: 49 GPT prompts (gpt-5 series, o3, o4-mini, tools) - Google: 13 Gemini prompts (2.5-pro, 3-pro, workspace, cli) - xAI: 5 Grok prompts - Other: 9 misc prompts (Notion, Raycast, Warp, Kagi, etc.) Hooks (9): - JAT hooks for session management, signal tracking, activity logging Prompts (6): - pi-mono templates for PR review, issue analysis, changelog audit Sources analyzed: jat, ralph-desktop, toad, pi-mono, cmux, pi-interactive-shell, craft-agents-oss, dexter, picoclaw, dyad, system_prompts_leaks, Prometheus, zed, clawdbot, OS-Copilot, and more
This commit is contained in:
139
hooks/community/jat/user-prompt-signal.sh
Executable file
139
hooks/community/jat/user-prompt-signal.sh
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# user-prompt-signal.sh - UserPromptSubmit hook for tracking user messages
|
||||
#
|
||||
# Fires when user submits a prompt to Claude Code.
|
||||
# Writes user_input event to timeline for IDE visibility.
|
||||
#
|
||||
# Input: JSON via stdin with format: {"session_id": "...", "prompt": "...", ...}
|
||||
# Output: Appends to /tmp/jat-timeline-{tmux-session}.jsonl
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Read JSON input from stdin
|
||||
HOOK_INPUT=$(cat)
|
||||
|
||||
# Skip empty input
|
||||
if [[ -z "$HOOK_INPUT" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Parse session_id and prompt from the JSON input
|
||||
SESSION_ID=$(echo "$HOOK_INPUT" | jq -r '.session_id // ""' 2>/dev/null || echo "")
|
||||
USER_PROMPT=$(echo "$HOOK_INPUT" | jq -r '.prompt // ""' 2>/dev/null || echo "")
|
||||
|
||||
# Skip empty prompts or missing session_id
|
||||
if [[ -z "$USER_PROMPT" ]] || [[ -z "$SESSION_ID" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Skip /jat:start commands - these cause a race condition where the event gets
|
||||
# written to the OLD agent's timeline before /jat:start updates the agent file.
|
||||
# The /jat:start command emits its own "starting" signal which is the proper
|
||||
# event for the new session.
|
||||
if [[ "$USER_PROMPT" =~ ^/jat:start ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get tmux session name by looking up agent file from session_id
|
||||
# (Cannot use tmux display-message in subprocess - no TMUX env var)
|
||||
TMUX_SESSION=""
|
||||
|
||||
# Build list of directories to search: current dir + configured projects
|
||||
SEARCH_DIRS="."
|
||||
JAT_CONFIG="$HOME/.config/jat/projects.json"
|
||||
if [[ -f "$JAT_CONFIG" ]]; then
|
||||
PROJECT_PATHS=$(jq -r '.projects[].path // empty' "$JAT_CONFIG" 2>/dev/null | sed "s|^~|$HOME|g")
|
||||
for PROJECT_PATH in $PROJECT_PATHS; do
|
||||
if [[ -d "${PROJECT_PATH}/.claude" ]]; then
|
||||
SEARCH_DIRS="$SEARCH_DIRS $PROJECT_PATH"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
for BASE_DIR in $SEARCH_DIRS; do
|
||||
for SUBDIR in "sessions" ""; do
|
||||
if [[ -n "$SUBDIR" ]]; then
|
||||
AGENT_FILE="${BASE_DIR}/.claude/${SUBDIR}/agent-${SESSION_ID}.txt"
|
||||
else
|
||||
AGENT_FILE="${BASE_DIR}/.claude/agent-${SESSION_ID}.txt"
|
||||
fi
|
||||
if [[ -f "$AGENT_FILE" ]]; then
|
||||
AGENT_NAME=$(cat "$AGENT_FILE" 2>/dev/null | tr -d '\n')
|
||||
if [[ -n "$AGENT_NAME" ]]; then
|
||||
TMUX_SESSION="jat-${AGENT_NAME}"
|
||||
break 2
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
if [[ -z "$TMUX_SESSION" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Detect if the prompt contains an image (by checking for common image paths/patterns)
|
||||
# Image paths typically match: /path/to/file.(png|jpg|jpeg|gif|webp|svg)
|
||||
# Also check for task-images directory and upload patterns
|
||||
HAS_IMAGE="false"
|
||||
if [[ "$USER_PROMPT" =~ \.(png|jpg|jpeg|gif|webp|svg|PNG|JPG|JPEG|GIF|WEBP|SVG)($|[[:space:]]) ]] || \
|
||||
[[ "$USER_PROMPT" =~ task-images/ ]] || \
|
||||
[[ "$USER_PROMPT" =~ upload-.*\.(png|jpg|jpeg|gif|webp|svg) ]] || \
|
||||
[[ "$USER_PROMPT" =~ /tmp/.*\.(png|jpg|jpeg|gif|webp|svg) ]]; then
|
||||
HAS_IMAGE="true"
|
||||
fi
|
||||
|
||||
# Truncate long prompts for timeline display (keep first 500 chars)
|
||||
PROMPT_PREVIEW="${USER_PROMPT:0:500}"
|
||||
if [[ ${#USER_PROMPT} -gt 500 ]]; then
|
||||
PROMPT_PREVIEW="${PROMPT_PREVIEW}..."
|
||||
fi
|
||||
|
||||
# REMOVED: Task ID lookup from signal file
|
||||
# Previously we read task_id from /tmp/jat-signal-tmux-{session}.json, but this caused
|
||||
# signal leaking when a user started a new task - the user_input event would inherit
|
||||
# the OLD task_id from the previous signal file.
|
||||
#
|
||||
# User input events should not be associated with a specific task since they represent
|
||||
# what the user typed, which may be switching to a new task entirely (e.g., /jat:start).
|
||||
# The task context is better represented by subsequent agent signals that actually
|
||||
# emit the new task ID.
|
||||
TASK_ID=""
|
||||
|
||||
# Build event JSON
|
||||
EVENT_JSON=$(jq -c -n \
|
||||
--arg type "user_input" \
|
||||
--arg session "$SESSION_ID" \
|
||||
--arg tmux "$TMUX_SESSION" \
|
||||
--arg task "$TASK_ID" \
|
||||
--arg prompt "$PROMPT_PREVIEW" \
|
||||
--argjson hasImage "$HAS_IMAGE" \
|
||||
'{
|
||||
type: $type,
|
||||
session_id: $session,
|
||||
tmux_session: $tmux,
|
||||
task_id: $task,
|
||||
timestamp: (now | todate),
|
||||
data: {
|
||||
prompt: $prompt,
|
||||
hasImage: $hasImage
|
||||
}
|
||||
}' 2>/dev/null || echo "{}")
|
||||
|
||||
# Append to timeline log (JSONL format - preserves history)
|
||||
TIMELINE_FILE="/tmp/jat-timeline-${TMUX_SESSION}.jsonl"
|
||||
echo "$EVENT_JSON" >> "$TIMELINE_FILE" 2>/dev/null || true
|
||||
|
||||
# Start output monitor for real-time activity detection (shimmer effect)
|
||||
# Kill any existing monitor for this session first
|
||||
PID_FILE="/tmp/jat-monitor-${TMUX_SESSION}.pid"
|
||||
if [[ -f "$PID_FILE" ]]; then
|
||||
kill "$(cat "$PID_FILE")" 2>/dev/null || true
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
|
||||
# Start new monitor in background
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
nohup "$SCRIPT_DIR/monitor-output.sh" "$TMUX_SESSION" &>/dev/null &
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user