Skip to main content
hooksSource-backedReview first Safety Privacy

Session Metrics Collector - Hooks

Collects and reports detailed metrics about the coding session when Claude stops.

by JSONbored·added 2025-09-19·
HarnessClaude Code
Trigger:Stop
Review first review before installing

Open the source and read safety notes before installing.

Citation facts

Source-backed facts for citing this resource, derived directly from the registry — also available as plain text for AI assistants.

Source URLs
https://code.claude.com/docs/en/hooks, https://github.com/JSONbored/awesome-claude/blob/main/content/hooks/session-metrics-collector.mdx
Safety notes
Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling.
Privacy notes
Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output.
Author
JSONbored
Claim status
unclaimed
Last verified
2025-09-19

Decision playbook

Review trust signals before you adopt

Signals are present but mixed. Use the checklist below to confirm the source and operational safety for your environment.

Compare context
Selected

0

Current score

78

Baseline

Delta

No baseline selected

No major trust-signal divergence detected in the current selection.

Source and provenance checks

Complete

Confirm ownership and provenance before trusting install instructions.

  • Source link availableRequired

    Open the canonical repository and verify ownership.

    Done
  • Source provenance statusRequired

    Marked as source-backed.

    Done
  • Metadata reviewed

    Registry metadata indicates a reviewed listing.

    Done

Safety and privacy checks

Complete

Validate risk disclosures before installation or API wiring.

  • Safety notes presentRequired

    Review the listed safety guidance before running commands.

    Done
  • Privacy notes presentRequired

    Review data handling notes before connecting accounts or secrets.

    Done
  • Trust level risk gateRequired

    Trust level does not block evaluation.

    Done

Package and install checks

Needs review

Check package metadata and artifact integrity signals.

  • Install payload available

    Install or copy payload is available for review.

    Done
  • Package verification flag

    No package verification flag provided.

    Pending
  • Checksum metadata

    No checksum provided for downloaded artifact.

    Pending

Compare-driven decision checks

Needs review

Use compare context to validate trade-offs before adoption.

  • Compare tray has multiple entries

    Add at least one more entry to compare trust differences.

    Pending
  • Baseline comparison available

    No baseline peer selected yet.

    Pending
  • Diverging trust signals identified

    No major trust-signal divergence found.

    Pending

Setup at a glance

CLI install

Copy-ready — paste the snippet to get started.

Install command

Provided

Config snippet

Provided

Copy snippet

Provided

Prerequisites

None

Platforms

1 listed

Difficulty

0/100

Adoption plan

Balanced adoption plan

Current risk score 16/100. Use staged verification before broader rollout.

Risk 16

Pre-adoption checks

Validate source and review signals before any execution.

  • Confirm source provenanceRequired

    Source URL/provenance metadata is present.

    Done
  • Confirm metadata review state

    Listing has review metadata.

    Done
  • Verify install payload

    Install/config payload exists and can be inspected.

    Done

Security checks

Confirm safety, privacy, and package integrity signals.

  • Review safety notesRequired

    Safety notes are present.

    Done
  • Review privacy notesRequired

    Privacy notes are present.

    Done
  • Verify package integrity metadata

    No package verification/checksum metadata.

    Pending

Rollout

Adopt in controlled steps based on the selected plan.

  • Run in isolated sandbox firstRequired

    Use a constrained sandbox and observe behavior across multiple tasks.

    Pending
  • Roll out graduallyRequired

    Roll out to a small cohort before wider usage.

    Pending
  • Set monitoring and fallback

    Define rollback path and monitor errors after adoption.

    Pending

Evidence readiness

Evidence readiness matrix · balanced

Required evidence gates are covered (5/6 signals complete).

Risk 15

Source provenance

Present

Source repository/provenance is listed.

Required in this preset

Metadata review

Present

Review metadata is present.

Required in this preset

Safety notes

Present

Safety notes are present.

Required in this preset

Privacy notes

Present

Privacy notes are present.

Optional in this preset

Package integrity

Missing

Package integrity metadata is missing.

Optional in this preset

Install payload

Present

Install payload is available.

Required in this preset

Required evidence gates are covered for this preset.

Decision timeline

Decision timeline · balanced

5/6 steps complete with no blocking gaps for this preset.

Risk 14

triage

Confirm source provenanceRequired

Source/provenance metadata is available.

Done

triage

Check metadata review statusRequired

Review metadata is available.

Done

verify

Review safety notesRequired

Safety notes are available.

Done

verify

Review privacy notes

Privacy notes are available.

Done

verify

Validate package integrity metadata

Package integrity metadata is missing.

Pending

rollout

Verify install payload and commandsRequired

Install payload is available.

Done

No required blockers for this timeline preset.

Safety & privacy surface

Safety & privacy surface

1 safety and 1 privacy notes across 2 risk areas. Review closely: credentials & tokens, permissions & scopes.

2 areas
  • SafetyPermissions & scopesRuns automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling.
  • PrivacyCredentials & tokensReceives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output.

Safety notes

  • Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling.

Privacy notes

  • Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output.

Schema details

Install type
cli
Reading time
4 min
Difficulty score
0
Troubleshooting
Yes
Breaking changes
No
Skill and platform metadata
Retrieval sources
https://code.claude.com/docs/en/hooks
Runtime and command metadata
Trigger
Stop
Script language
bash
Script body
#!/bin/bash

echo "📊 Session Metrics Collector - Gathering session analytics..."
echo "⏱️ Session ended: $(date)"

# Create metrics directory
mkdir -p .metrics

# Session metadata
SESSION_ID="$(date +%Y%m%d_%H%M%S)"
METRICS_FILE=".metrics/session-${SESSION_ID}.json"
END_TIME=$(date)
END_TIMESTAMP=$(date +%s)

echo "💾 Collecting session metrics..."

# Get session start time (approximate from oldest .claude file or fallback)
if [ -d ".claude" ] && [ "$(find .claude -type f 2>/dev/null | wc -l)" -gt 0 ]; then
    START_TIMESTAMP=$(stat -f %B .claude/*.log 2>/dev/null | head -1 || echo $((END_TIMESTAMP - 3600)))
else
    # Fallback: assume 1 hour session
    START_TIMESTAMP=$((END_TIMESTAMP - 3600))
fi

SESSION_DURATION=$((END_TIMESTAMP - START_TIMESTAMP))
SESSION_HOURS=$((SESSION_DURATION / 3600))
SESSION_MINUTES=$(((SESSION_DURATION % 3600) / 60))

echo "⏱️ Session Duration: ${SESSION_HOURS}h ${SESSION_MINUTES}m"

# File statistics
echo "📁 Analyzing file changes..."

# Git-based analysis (preferred)
if git rev-parse --git-dir >/dev/null 2>&1; then
    FILES_MODIFIED=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
    FILES_ADDED=$(git diff --name-status 2>/dev/null | grep '^A' | wc -l | tr -d ' ')
    FILES_DELETED=$(git diff --name-status 2>/dev/null | grep '^D' | wc -l | tr -d ' ')
    
    # Line statistics
    LINE_STATS=$(git diff --shortstat 2>/dev/null || echo "0 files changed")
    LINES_ADDED=$(echo "$LINE_STATS" | grep -o '[0-9]\+ insertion' | grep -o '[0-9]\+' || echo 0)
    LINES_DELETED=$(echo "$LINE_STATS" | grep -o '[0-9]\+ deletion' | grep -o '[0-9]\+' || echo 0)
    
    # Languages used
    LANGUAGES=$(git diff --name-only 2>/dev/null | sed 's/.*\.//' | sort | uniq -c | sort -nr | head -5)
else
    # Fallback: recent file changes
    FILES_MODIFIED=$(find . -type f -newer .metrics 2>/dev/null | wc -l | tr -d ' ' || echo "0")
    FILES_ADDED="unknown"
    FILES_DELETED="unknown"
    LINES_ADDED="unknown"
    LINES_DELETED="unknown"
    LANGUAGES="unknown"
fi

echo "📊 File Statistics:"
echo "  • Files Modified: $FILES_MODIFIED"
echo "  • Files Added: $FILES_ADDED"
echo "  • Files Deleted: $FILES_DELETED"
echo "  • Lines Added: $LINES_ADDED"
echo "  • Lines Deleted: $LINES_DELETED"

# Repository analysis
if git rev-parse --git-dir >/dev/null 2>&1; then
    REPO_NAME=$(basename "$(git rev-parse --show-toplevel)" 2>/dev/null || echo "unknown")
    CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
    COMMIT_COUNT=$(git rev-list --count HEAD 2>/dev/null || echo "unknown")
    
    echo "📂 Repository Info:"
    echo "  • Repository: $REPO_NAME"
    echo "  • Branch: $CURRENT_BRANCH"
    echo "  • Total Commits: $COMMIT_COUNT"
fi

# System information
CWD=$(pwd)
USER=$(whoami 2>/dev/null || echo "unknown")
HOST=$(hostname 2>/dev/null || echo "unknown")

echo "🖥️ Environment:"
echo "  • User: $USER"
echo "  • Host: $HOST"
echo "  • Directory: $(basename "$CWD")"

# Activity analysis from .claude logs
if [ -d ".claude" ]; then
    ACTIVITY_COUNT=$(find .claude -name "*.log" -exec cat {} \; 2>/dev/null | wc -l | tr -d ' ')
    echo "📈 Activity: $ACTIVITY_COUNT logged actions"
fi

# Generate JSON metrics
echo "💾 Saving detailed metrics to: $METRICS_FILE"

cat > "$METRICS_FILE" << EOF
{
  "session": {
    "id": "$SESSION_ID",
    "start_time": "$(date -r $START_TIMESTAMP 2>/dev/null || echo 'unknown')",
    "end_time": "$END_TIME",
    "duration_seconds": $SESSION_DURATION,
    "duration_formatted": "${SESSION_HOURS}h ${SESSION_MINUTES}m"
  },
  "files": {
    "modified": $FILES_MODIFIED,
    "added": $FILES_ADDED,
    "deleted": $FILES_DELETED
  },
  "lines": {
    "added": $LINES_ADDED,
    "deleted": $LINES_DELETED
  },
  "repository": {
    "name": "$REPO_NAME",
    "branch": "$CURRENT_BRANCH",
    "total_commits": $COMMIT_COUNT
  },
  "environment": {
    "user": "$USER",
    "host": "$HOST",
    "working_directory": "$CWD"
  },
  "productivity": {
    "files_per_hour": $(echo "scale=2; $FILES_MODIFIED * 3600 / $SESSION_DURATION" | bc -l 2>/dev/null || echo 0),
    "lines_per_hour": $(echo "scale=2; ($LINES_ADDED + $LINES_DELETED) * 3600 / $SESSION_DURATION" | bc -l 2>/dev/null || echo 0)
  }
}
EOF

# Summary statistics
echo ""
echo "📊 Session Summary:"
echo "  • Duration: ${SESSION_HOURS}h ${SESSION_MINUTES}m"
echo "  • Productivity: $(echo "scale=1; $FILES_MODIFIED * 3600 / $SESSION_DURATION" | bc -l 2>/dev/null || echo '0') files/hour"
echo "  • Total Changes: $((LINES_ADDED + LINES_DELETED)) lines"

# Historical comparison
if [ "$(find .metrics -name 'session-*.json' 2>/dev/null | wc -l)" -gt 1 ]; then
    PREV_SESSION=$(find .metrics -name 'session-*.json' | sort | tail -2 | head -1)
    if [ -f "$PREV_SESSION" ]; then
        echo "📈 Compared to last session:"
        echo "  • Previous session available for comparison"
    fi
fi

# Cleanup old metrics (keep last 30 sessions)
find .metrics -name 'session-*.json' | sort | head -n -30 | xargs rm -f 2>/dev/null

echo ""
echo "💡 Productivity Tips:"
echo "  • Review metrics regularly to identify patterns"
echo "  • Set productivity goals for future sessions"
echo "  • Use metrics to optimize development workflow"
echo "  • Compare sessions to track improvement"

echo ""
echo "🎯 Session metrics collection complete!"
echo "📄 Full report saved to: $METRICS_FILE"

exit 0
Full copyable content
{
  "hooks": {
    "stop": {
      "script": "./.claude/hooks/session-metrics-collector.sh",
      "matchers": [
        "*"
      ]
    }
  }
}

About this resource

Features

  • Comprehensive session analytics including session analytics integration (session metrics collection on session stop, detailed session reporting with comprehensive reports, session data aggregation with data aggregation, session analytics visualization with analytics visualization), analytics optimization (analytics performance with fast collection, analytics accuracy with accurate metrics, analytics efficiency with efficient processing, analytics coverage with comprehensive metrics), analytics validation (session data validation with data verification, analytics accuracy validation with accuracy checking, analytics completeness validation with completeness checking, analytics consistency validation with consistency checking), and analytics reporting (session analytics reporting with analytics results, session metrics reporting with metrics details, session statistics reporting with statistics, session insights reporting with insights)
  • File modification tracking including file tracking (file modification detection with change detection, file change tracking with change tracking, file activity monitoring with activity monitoring, file modification analysis with modification analysis), file statistics (file modification statistics with modification counts, file addition statistics with addition counts, file deletion statistics with deletion counts, file change statistics with change metrics), file analysis (file change analysis with change analysis, file pattern analysis with pattern detection, file type analysis with type detection, file activity analysis with activity analysis), and file reporting (file modification reporting with modification details, file statistics reporting with statistics, file analysis reporting with analysis results, file insights reporting with insights)
  • Language usage statistics including language detection (programming language detection with language identification, language usage tracking with usage tracking, language distribution analysis with distribution analysis, language trend analysis with trend analysis), language statistics (language file statistics with file counts, language line statistics with line counts, language change statistics with change metrics, language activity statistics with activity metrics), language analysis (language usage analysis with usage analysis, language pattern analysis with pattern detection, language preference analysis with preference detection, language productivity analysis with productivity analysis), and language reporting (language usage reporting with usage details, language statistics reporting with statistics, language analysis reporting with analysis results, language insights reporting with insights)
  • Productivity metrics collection including productivity tracking (productivity metric collection with metric collection, productivity measurement with productivity measurement, productivity analysis with productivity analysis, productivity optimization with optimization), productivity metrics (files per hour metrics with file productivity, lines per hour metrics with line productivity, session efficiency metrics with efficiency measurement, productivity trend metrics with trend tracking), productivity analysis (productivity pattern analysis with pattern detection, productivity trend analysis with trend analysis, productivity comparison analysis with comparison analysis, productivity optimization analysis with optimization suggestions), and productivity reporting (productivity metrics reporting with metrics details, productivity analysis reporting with analysis results, productivity insights reporting with insights, productivity recommendations reporting with recommendations)
  • Session duration measurement including duration tracking (session duration measurement with duration tracking, session time tracking with time tracking, session interval analysis with interval analysis, session timing analysis with timing analysis), duration statistics (session duration statistics with duration metrics, session time statistics with time metrics, session interval statistics with interval metrics, session timing statistics with timing metrics), duration analysis (session duration analysis with duration analysis, session time analysis with time analysis, session pattern analysis with pattern detection, session efficiency analysis with efficiency analysis), and duration reporting (session duration reporting with duration details, session time reporting with time details, session analysis reporting with analysis results, session insights reporting with insights)
  • Git integration for change tracking including Git integration (Git repository detection with repository detection, Git change tracking with change tracking, Git commit analysis with commit analysis, Git branch analysis with branch analysis), Git statistics (Git file statistics with file metrics, Git line statistics with line metrics, Git commit statistics with commit metrics, Git branch statistics with branch metrics), Git analysis (Git change analysis with change analysis, Git activity analysis with activity analysis, Git workflow analysis with workflow analysis, Git productivity analysis with productivity analysis), and Git reporting (Git integration reporting with integration status, Git statistics reporting with statistics, Git analysis reporting with analysis results, Git insights reporting with insights)
  • Historical session comparison and trend analysis including historical analysis (session history tracking with history tracking, session comparison analysis with comparison analysis, session trend analysis with trend analysis, session pattern analysis with pattern detection), trend metrics (productivity trend metrics with trend tracking, session duration trend metrics with duration trends, file activity trend metrics with activity trends, language usage trend metrics with language trends), trend reporting (historical comparison reporting with comparison results, trend analysis reporting with trend results, pattern analysis reporting with pattern results, trend insights reporting with insights), and trend optimization (trend-based recommendations with recommendations, trend-based optimization with optimization, trend-based insights with insights, trend-based planning with planning)
  • Development workflow integration including continuous analytics (real-time session metrics collection on session stop, immediate analytics reporting on session end, automatic metrics collection on session completion, seamless analytics integration with development workflow), workflow automation (automated session analytics without manual intervention, analytics automation with automatic collection, reporting automation with automatic reporting), and workflow optimization (session metrics tracking with metrics tracking, analytics optimization with optimization, session consistency maintenance with consistency checks)

Use Cases

  • Track coding session productivity automatically collecting session metrics, calculating productivity rates, and providing productivity insights
  • Analyze development patterns automatically tracking file modifications, language usage, and development activities to identify patterns
  • Measure session effectiveness automatically measuring session duration, productivity metrics, and session efficiency
  • Generate development reports automatically generating detailed JSON reports with session metrics, statistics, and insights
  • Monitor coding habits over time automatically tracking historical sessions, comparing sessions, and analyzing trends
  • Development workflow integration seamlessly integrating session metrics collection into development workflows without manual analytics or reporting

Installation

  1. Create hooks directory: mkdir -p .claude/hooks
  2. Create hook file: touch .claude/hooks/session-metrics-collector.sh
  3. Make executable: chmod +x .claude/hooks/session-metrics-collector.sh
  4. Add configuration from Hook Configuration section above to .claude/settings.json or ~/.claude/settings.json
  5. Alternative: Use the interactive /hooks command in Claude Code

Config paths

  • Local (not committed): .claude/settings.local.json
  • User settings (global): ~/.claude/settings.json
  • Project-wide (committed): .claude/settings.json

Requirements

  • Claude Code CLI installed
  • Project directory initialized
  • Bash shell available
  • Git installed (optional, for Git-based statistics)
  • jq (optional, for JSON generation and parsing)
  • bc or awk (optional, for calculations)
  • stat command (for timestamp extraction)

Hook Configuration

{
  "hooks": {
    "stop": {
      "script": "./.claude/hooks/session-metrics-collector.sh",
      "matchers": ["*"]
    }
  }
}

Hook Script

#!/bin/bash

echo "📊 Session Metrics Collector - Gathering session analytics..."
echo "⏱️ Session ended: $(date)"

# Create metrics directory
mkdir -p .metrics

# Session metadata
SESSION_ID="$(date +%Y%m%d_%H%M%S)"
METRICS_FILE=".metrics/session-${SESSION_ID}.json"
END_TIME=$(date)
END_TIMESTAMP=$(date +%s)

echo "💾 Collecting session metrics..."

# Get session start time (approximate from oldest .claude file or fallback)
if [ -d ".claude" ] && [ "$(find .claude -type f 2>/dev/null | wc -l)" -gt 0 ]; then
    START_TIMESTAMP=$(stat -f %B .claude/*.log 2>/dev/null | head -1 || echo $((END_TIMESTAMP - 3600)))
else
    # Fallback: assume 1 hour session
    START_TIMESTAMP=$((END_TIMESTAMP - 3600))
fi

SESSION_DURATION=$((END_TIMESTAMP - START_TIMESTAMP))
SESSION_HOURS=$((SESSION_DURATION / 3600))
SESSION_MINUTES=$(((SESSION_DURATION % 3600) / 60))

echo "⏱️ Session Duration: ${SESSION_HOURS}h ${SESSION_MINUTES}m"

# File statistics
echo "📁 Analyzing file changes..."

# Git-based analysis (preferred)
if git rev-parse --git-dir >/dev/null 2>&1; then
    FILES_MODIFIED=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
    FILES_ADDED=$(git diff --name-status 2>/dev/null | grep '^A' | wc -l | tr -d ' ')
    FILES_DELETED=$(git diff --name-status 2>/dev/null | grep '^D' | wc -l | tr -d ' ')

    # Line statistics
    LINE_STATS=$(git diff --shortstat 2>/dev/null || echo "0 files changed")
    LINES_ADDED=$(echo "$LINE_STATS" | grep -o '[0-9]\+ insertion' | grep -o '[0-9]\+' || echo 0)
    LINES_DELETED=$(echo "$LINE_STATS" | grep -o '[0-9]\+ deletion' | grep -o '[0-9]\+' || echo 0)

    # Languages used
    LANGUAGES=$(git diff --name-only 2>/dev/null | sed 's/.*\.//' | sort | uniq -c | sort -nr | head -5)
else
    # Fallback: recent file changes
    FILES_MODIFIED=$(find . -type f -newer .metrics 2>/dev/null | wc -l | tr -d ' ' || echo "0")
    FILES_ADDED="unknown"
    FILES_DELETED="unknown"
    LINES_ADDED="unknown"
    LINES_DELETED="unknown"
    LANGUAGES="unknown"
fi

echo "📊 File Statistics:"
echo "  • Files Modified: $FILES_MODIFIED"
echo "  • Files Added: $FILES_ADDED"
echo "  • Files Deleted: $FILES_DELETED"
echo "  • Lines Added: $LINES_ADDED"
echo "  • Lines Deleted: $LINES_DELETED"

# Repository analysis
if git rev-parse --git-dir >/dev/null 2>&1; then
    REPO_NAME=$(basename "$(git rev-parse --show-toplevel)" 2>/dev/null || echo "unknown")
    CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
    COMMIT_COUNT=$(git rev-list --count HEAD 2>/dev/null || echo "unknown")

    echo "📂 Repository Info:"
    echo "  • Repository: $REPO_NAME"
    echo "  • Branch: $CURRENT_BRANCH"
    echo "  • Total Commits: $COMMIT_COUNT"
fi

# System information
CWD=$(pwd)
USER=$(whoami 2>/dev/null || echo "unknown")
HOST=$(hostname 2>/dev/null || echo "unknown")

echo "🖥️ Environment:"
echo "  • User: $USER"
echo "  • Host: $HOST"
echo "  • Directory: $(basename "$CWD")"

# Activity analysis from .claude logs
if [ -d ".claude" ]; then
    ACTIVITY_COUNT=$(find .claude -name "*.log" -exec cat {} \; 2>/dev/null | wc -l | tr -d ' ')
    echo "📈 Activity: $ACTIVITY_COUNT logged actions"
fi

# Generate JSON metrics
echo "💾 Saving detailed metrics to: $METRICS_FILE"

cat > "$METRICS_FILE" << EOF
{
  "session": {
    "id": "$SESSION_ID",
    "start_time": "$(date -r $START_TIMESTAMP 2>/dev/null || echo 'unknown')",
    "end_time": "$END_TIME",
    "duration_seconds": $SESSION_DURATION,
    "duration_formatted": "${SESSION_HOURS}h ${SESSION_MINUTES}m"
  },
  "files": {
    "modified": $FILES_MODIFIED,
    "added": $FILES_ADDED,
    "deleted": $FILES_DELETED
  },
  "lines": {
    "added": $LINES_ADDED,
    "deleted": $LINES_DELETED
  },
  "repository": {
    "name": "$REPO_NAME",
    "branch": "$CURRENT_BRANCH",
    "total_commits": $COMMIT_COUNT
  },
  "environment": {
    "user": "$USER",
    "host": "$HOST",
    "working_directory": "$CWD"
  },
  "productivity": {
    "files_per_hour": $(echo "scale=2; $FILES_MODIFIED * 3600 / $SESSION_DURATION" | bc -l 2>/dev/null || echo 0),
    "lines_per_hour": $(echo "scale=2; ($LINES_ADDED + $LINES_DELETED) * 3600 / $SESSION_DURATION" | bc -l 2>/dev/null || echo 0)
  }
}
EOF

# Summary statistics
echo ""
echo "📊 Session Summary:"
echo "  • Duration: ${SESSION_HOURS}h ${SESSION_MINUTES}m"
echo "  • Productivity: $(echo "scale=1; $FILES_MODIFIED * 3600 / $SESSION_DURATION" | bc -l 2>/dev/null || echo '0') files/hour"
echo "  • Total Changes: $((LINES_ADDED + LINES_DELETED)) lines"

# Historical comparison
if [ "$(find .metrics -name 'session-*.json' 2>/dev/null | wc -l)" -gt 1 ]; then
    PREV_SESSION=$(find .metrics -name 'session-*.json' | sort | tail -2 | head -1)
    if [ -f "$PREV_SESSION" ]; then
        echo "📈 Compared to last session:"
        echo "  • Previous session available for comparison"
    fi
fi

# Cleanup old metrics (keep last 30 sessions)
find .metrics -name 'session-*.json' | sort | head -n -30 | xargs rm -f 2>/dev/null

echo ""
echo "💡 Productivity Tips:"
echo "  • Review metrics regularly to identify patterns"
echo "  • Set productivity goals for future sessions"
echo "  • Use metrics to optimize development workflow"
echo "  • Compare sessions to track improvement"

echo ""
echo "🎯 Session metrics collection complete!"
echo "📄 Full report saved to: $METRICS_FILE"

exit 0

Examples

Session Metrics Collector Hook Script

Complete hook script that collects session metrics on session stop

#!/bin/bash
echo "📊 Session Metrics Collector - Gathering session analytics..."
echo "⏱️ Session ended: $(date)"
mkdir -p .metrics
SESSION_ID="$(date +%Y%m%d_%H%M%S)"
METRICS_FILE=".metrics/session-${SESSION_ID}.json"
END_TIMESTAMP=$(date +%s)
START_TIMESTAMP=$((END_TIMESTAMP - 3600))
SESSION_DURATION=$((END_TIMESTAMP - START_TIMESTAMP))
if git rev-parse --git-dir >/dev/null 2>&1; then
  FILES_MODIFIED=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
  LINES_ADDED=$(git diff --shortstat 2>/dev/null | grep -o '[0-9]\+ insertion' | grep -o '[0-9]\+' || echo 0)
else
  FILES_MODIFIED=0
  LINES_ADDED=0
fi
cat > "$METRICS_FILE" << EOF
{
  "session": {
    "id": "$SESSION_ID",
    "duration_seconds": $SESSION_DURATION
  },
  "files": {
    "modified": $FILES_MODIFIED
  },
  "lines": {
    "added": $LINES_ADDED
  }
}
EOF
echo "📄 Metrics saved to: $METRICS_FILE"
exit 0

Hook Configuration

Complete hook configuration for .claude/settings.json to enable session metrics collection

{
  "hooks": {
    "stop": {
      "script": "./.claude/hooks/session-metrics-collector.sh",
      "matchers": ["*"]
    }
  }
}

Enhanced Metrics Collection with jq

Enhanced hook script using jq for safe JSON generation and Git diff HEAD for all uncommitted changes

#!/bin/bash
SESSION_ID="$(date +%Y%m%d_%H%M%S)"
METRICS_FILE=".metrics/session-${SESSION_ID}.json"
END_TIMESTAMP=$(date +%s)
START_TIMESTAMP=$(stat -c %Y .claude 2>/dev/null || echo $((END_TIMESTAMP - 3600)))
SESSION_DURATION=$((END_TIMESTAMP - START_TIMESTAMP))
if [ "$SESSION_DURATION" -lt 60 ]; then
  SESSION_DURATION=60
fi
if git rev-parse --git-dir >/dev/null 2>&1; then
  FILES_MODIFIED=$(git diff HEAD --name-only 2>/dev/null | wc -l | tr -d ' ')
  LINES_ADDED=$(git diff HEAD --shortstat 2>/dev/null | grep -o '[0-9]\+ insertion' | grep -o '[0-9]\+' || echo 0)
  LINES_DELETED=$(git diff HEAD --shortstat 2>/dev/null | grep -o '[0-9]\+ deletion' | grep -o '[0-9]\+' || echo 0)
else
  FILES_MODIFIED=0
  LINES_ADDED=0
  LINES_DELETED=0
fi
PRODUCTIVITY=$(awk "BEGIN {printf \"%.2f\", $FILES_MODIFIED * 3600 / $SESSION_DURATION}")
jq -n --arg id "$SESSION_ID" --argjson duration $SESSION_DURATION --argjson files $FILES_MODIFIED --argjson added $LINES_ADDED --argjson deleted $LINES_DELETED --argjson productivity $PRODUCTIVITY '{session: {id: $id, duration_seconds: $duration}, files: {modified: $files}, lines: {added: $added, deleted: $deleted}, productivity: {files_per_hour: $productivity}}' > "$METRICS_FILE"
exit 0

Session Comparison and Language Analysis

Enhanced hook script with historical session comparison and language usage analysis

#!/bin/bash
SESSION_ID="$(date +%Y%m%d_%H%M%S)"
METRICS_FILE=".metrics/session-${SESSION_ID}.json"
if [ -d ".metrics" ] && [ "$(find .metrics -name 'session-*.json' 2>/dev/null | wc -l)" -gt 0 ]; then
  PREV_SESSION=$(find .metrics -name 'session-*.json' | sort | tail -1)
  if [ -f "$PREV_SESSION" ]; then
    PREV_FILES=$(jq -r '.files.modified // 0' "$PREV_SESSION" 2>/dev/null || echo 0)
    PREV_DURATION=$(jq -r '.session.duration_seconds // 0' "$PREV_SESSION" 2>/dev/null || echo 0)
    echo "📈 Previous session: $PREV_FILES files, ${PREV_DURATION}s"
  fi
fi
if git rev-parse --git-dir >/dev/null 2>&1; then
  FILES_MODIFIED=$(git diff HEAD --name-only 2>/dev/null | wc -l | tr -d ' ')
  LANGUAGES=$(git diff HEAD --name-only 2>/dev/null | sed 's/.*\.//' | sort | uniq -c | sort -nr | head -5 | awk '{print $2":"$1}' | tr '\n' ',' | sed 's/,$//')
else
  FILES_MODIFIED=0
  LANGUAGES=""
fi
jq -n --arg id "$SESSION_ID" --argjson files $FILES_MODIFIED --arg langs "$LANGUAGES" '{session: {id: $id}, files: {modified: $files}, languages: $langs}' > "$METRICS_FILE"
exit 0

Session Metrics Configuration Example

Example session metrics configuration for customizing metrics collection

{
  "session_metrics": {
    "metrics_directory": ".metrics",
    "retention_days": 30,
    "include_git_stats": true,
    "include_language_stats": true,
    "include_productivity_stats": true,
    "compare_with_previous": true
  }
}

Troubleshooting

Session metrics show 'unknown' duration or incorrect timing data

Hook relies on .claude directory timestamps. Ensure .claude exists before sessions. On Linux use 'stat -c %Y' instead of macOS 'stat -f %B' for timestamp extraction compatibility. Verify timestamp extraction. Test with various timestamp formats.

Git-based statistics return zero despite file modifications

Run 'git add .' before stopping to stage changes. Hook uses 'git diff' showing only unstaged. Modify script to use 'git diff HEAD' for all uncommitted changes instead. Verify Git status. Test with various Git states.

bc command errors: 'command not found' during metrics calculation

Install bc: 'brew install bc' (macOS) or 'apt-get install bc' (Linux). Or replace with awk: 'awk "BEGIN {printf "%.2f", $FILES_MODIFIED * 3600 / $SESSION_DURATION}"'. Verify calculation tools. Test with various calculation methods.

JSON metrics file has invalid format breaking parsers

Script appends without validation. Variables with special chars break JSON. Escape values: use jq for generation: 'jq -n --arg id "$SESSION_ID" '{session: {id: $id}}' > "$METRICS_FILE"'. Verify JSON format. Test with various data values.

Productivity calculations show zero or negative values

Division by zero when SESSION_DURATION=0. Add check: 'if [ "$SESSION_DURATION" -lt 60 ]; then SESSION_DURATION=60; fi' setting minimum 1-minute before calculations. Verify duration calculation. Test with various session durations.

Language statistics are incomplete or missing

Language detection relies on file extensions. Files without extensions or with uncommon extensions may not be detected. Use more sophisticated language detection or manual language mapping. Verify language detection. Test with various file types.

Historical session comparison fails or shows incorrect data

Previous session file may be missing or corrupted. Add file existence check: 'if [ -f "$PREV_SESSION" ]; then ...'. Verify file paths. Test with various session history scenarios.

Metrics directory grows too large with old session files

Add cleanup logic: 'find .metrics -name 'session-.json' -mtime +30 -delete' to remove files older than 30 days. Or limit retention: 'find .metrics -name 'session-.json' | sort | head -n -30 | xargs rm -f'. Verify cleanup logic. Test with various retention policies.

Source citations

Add this badge to your README

Show that Session Metrics Collector - Hooks is listed on HeyClaude. Paste this Markdown into your README — it renders the badge and links back to this page.

Listed on HeyClaude
[![Listed on HeyClaude](https://heyclau.de/badge/hooks/session-metrics-collector.svg)](https://heyclau.de/entry/hooks/session-metrics-collector)

How it compares

Session Metrics Collector - Hooks side by side with 3 alternatives on trust, install, platform support, and disclosed safety notes — all from reviewed registry metadata.

Field

Collects and reports detailed metrics about the coding session when Claude stops.

Open dossier

A Stop hook that syncs your changed files to cloud storage when a Claude Code session ends, using rclone to push to S3, Google Cloud Storage, or any of its 70+ supported backends.

Open dossier

Analyzes and reports final bundle sizes when the development session ends.

Open dossier

Detects unused CSS selectors when stylesheets are modified to keep CSS lean using PurgeCSS, PostCSS, and content analysis. This hook runs on CSS/SCSS file write/edit operations and analyzes stylesheets to identify unused selectors, generate optimized output, and report before/after size metrics.

Open dossier
Next steps
Trust
Review statusReviewedMaintainer reviewedReviewedMaintainer reviewedReviewedMaintainer reviewedReviewedMaintainer reviewed
Package trustPackage not verifiedPackage not verifiedPackage not verifiedPackage not verified
Source provenanceSource-backedSource-backedSource-backedSource-backed
Submitter
Install riskReview firstReview firstReview firstReview first
Notes Safety Privacy Safety Privacy Safety Privacy Safety Privacy
BrandAWS logoAWS
Categoryhookshookshookshooks
Sourcesource-backedsource-backedsource-backedsource-backed
AuthorJSONboredJSONboredJSONboredJSONbored
Added2025-09-192025-09-192025-09-192025-09-19
Platforms
Claude Code
Claude Code
Claude Code
Claude Code
Source repo
Safety notesRuns automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling.Runs automatically at session end and can create compressed archives of modified git files. Uploads backups through AWS CLI, Google Cloud SDK, or rclone when those tools and bucket variables are configured. Writes a temporary archive under /tmp when using the rclone fallback and removes it after the copy attempt.Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling.Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling.
Privacy notesReceives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output.Sends modified file contents to the configured cloud storage destination. Uses locally configured cloud credentials and bucket environment variables but does not define or manage them. Backup archives may include source code, docs, generated files, and any unignored local changes listed by git diff.Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output.Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output.
Prerequisites— none listed— none listed— none listed— none listed
Install
mkdir -p .claude/hooks && touch .claude/hooks/session-metrics-collector.sh && chmod +x .claude/hooks/session-metrics-collector.sh
mkdir -p .claude/hooks && touch .claude/hooks/cloud-backup-on-session-stop.sh && chmod +x .claude/hooks/cloud-backup-on-session-stop.sh
mkdir -p .claude/hooks && touch .claude/hooks/final-bundle-size-reporter.sh && chmod +x .claude/hooks/final-bundle-size-reporter.sh
mkdir -p .claude/hooks && touch .claude/hooks/css-unused-selector-detector.sh && chmod +x .claude/hooks/css-unused-selector-detector.sh
Config
{
  "hooks": {
    "stop": {
      "script": "./.claude/hooks/session-metrics-collector.sh",
      "matchers": [
        "*"
      ]
    }
  }
}
{
  "hooks": {
    "stop": {
      "script": "./.claude/hooks/cloud-backup-on-session-stop.sh"
    }
  }
}
{
  "hooks": {
    "stop": {
      "script": "./.claude/hooks/final-bundle-size-reporter.sh"
    }
  }
}
{
  "hooks": {
    "postToolUse": {
      "script": "./.claude/hooks/css-unused-selector-detector.sh",
      "matchers": [
        "write",
        "edit"
      ]
    }
  }
}
Citations
ClaimUnclaimedUnclaimedUnclaimedUnclaimed
Open 4 picks in the interactive comparison tool

Related guides

Signals

Loading live community signals…

More like this, weekly

A short, calm digest of reviewed Claude resources. Unsubscribe any time.