Automating Claude Code Sessions with Custom Hooks

jj-claude-hooks.png

I recently set up two hooks for Claude Code that have transformed my development workflow. Here's how I configured automatic version control checkpoints and real-time notifications for my coding sessions.

The Setup

My hook configuration lives in .claude/settings.json and consists of two main components:

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "/Users/dimitri.missoh/.claude/create-jj-checkpoint.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Bash|Edit|MultiEdit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '\"\\(.tool_input.command // \"\") - \\(.tool_input.description // \"\") - \\(.tool_response.stdout // \"\") - \\(.tool_response.content // \"\")\"' | /Users/dimitri.missoh/.claude/notification.sh"
          }
        ]
      }
    ]
  }
}

1. Automatic Jujutsu Checkpoints on Session Stop

When I end a Claude Code session, the Stop hook automatically creates a Jujutsu (jj) checkpoint of my work. This ensures I never lose changes between sessions.

The hook triggers create-jj-checkpoint.sh, which performs these steps:

# Get working directory from Claude environment or fallback to PWD
WORK_DIR="${CLAUDE_WORKING_DIRECTORY:-${PWD:-$(pwd)}}"

# Check if jj is installed and we're in a jj repository
if ! command -v jj >/dev/null 2>&1; then
    echo "Warning: jj (Jujutsu) is not installed. Skipping checkpoint."
    exit 0
fi

# Check for changes using jj diff and status
JJ_DIFF=$(jj diff --stat 2>&1)
JJ_STATUS=$(jj status --no-pager 2>&1)

# Skip if working copy is clean
if echo "$JJ_STATUS" | grep -q "working copy is clean"; then
    echo "No changes detected. Skipping checkpoint."
    exit 0
fi

# Create checkpoint with timestamp and session ID
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
DESCRIPTION="Code checkpoint - $TIMESTAMP (session: ${CLAUDE_SESSION_ID:-unknown})"
jj new
jj describe -m "$DESCRIPTION"

Key features:

2. Real-Time Notifications for Tool Operations

The PostToolUse hook fires after specific tool operations (Bash, Edit, MultiEdit, Write) and sends Mac notifications about completed tasks.

The notification pipeline:

  1. Captures tool input/output to a temporary file
  2. Extracts command details, descriptions, and results using jq
  3. Sends a notification via terminal-notifier with a fun frog sound

The notification script (notification.sh) is simple but effective:

#!/bin/bash
MESSAGE=$1

# Show Mac notifications using terminal-notifier
echo "${MESSAGE}" | terminal-notifier -title "Assisted Job Done!" -sound frog

This keeps me informed about what Claude is doing, especially during long-running operations or when I'm multitasking.

Prerequisites

To use this setup, you'll need to install:

  1. Jujutsu (jj) - A Git-compatible version control system

  2. terminal-notifier - Command-line tool for macOS notifications

Why This Works

The combination creates a seamless development experience:

The hooks respect my workflow - they only checkpoint when there are actual changes and handle edge cases gracefully. The notification system keeps me in the loop without being intrusive.

This setup has become an essential part of my Claude Code workflow, providing both safety nets and real-time awareness of AI-assisted development progress.


Dimitri Missoh | 2025-07-27

logo-small-transparent 2.png