Skip to content
Productivity
Hook

Hooks

What claude-journal runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
claude-journal
63 skills1 agent6 commands1 hook

Claude Code

> /plugin marketplace add chrismbryant/claude-journal-mcp
> /plugin install claude-journal@claude-journal-dev

What fires, and when

UserPromptSubmit

Fires before Claude sees each prompt you send. A plugin can use it to inject context, so the same instruction reaches the model every turn instead of only at session start.

  • Matches*node ${CLAUDE_PLUGIN_ROOT}/hooks/journal-auto-capture.js
Read hooks/hooks.json

Where it lives

  • hooks/journal-auto-capture.jsRunsGitHub
    Read the script
    #!/usr/bin/env node
    
    /**
     * Auto-capture hook for Claude Journal MCP
     *
     * Triggers auto-capture every 30 minutes if activity occurred.
     *
     * Installation:
     *   1. Copy to ~/.claude/hooks/journal-auto-capture.js
     *   2. Make executable: chmod +x ~/.claude/hooks/journal-auto-capture.js
     *   3. Add to ~/.claude/hooks/config.json (see README.md)
     */
    
    const fs = require('fs');
    const path = require('path');
    const os = require('os');
    
    // Configuration
    const CAPTURE_INTERVAL = 30 * 60 * 1000; // 30 minutes in milliseconds
    const MIN_ACTIVITY_THRESHOLD = 3; // Minimum messages since last capture
    const STATE_FILE = path.join(os.homedir(), '.claude', 'journal-capture-state.json');
    
    // Load or initialize state
    function loadState() {
      try {
        if (fs.existsSync(STATE_FILE)) {
          const data = fs.readFileSync(STATE_FILE, 'utf8');
          return JSON.parse(data);
        }
      } catch (error) {
        console.error(`⚠️  Failed to load state: ${error.message}`);
        console.error(`   State file: ${STATE_FILE}`);
        console.error(`   Initializing with default state...`);
      }
    
      return {
        lastCapture: 0,
        messageCount: 0,
        lastProject: null
      };
    }
    
    // Save state
    function saveState(state) {
      try {
        // Ensure directory exists
        const dir = path.dirname(STATE_FILE);
        if (!fs.existsSync(dir)) {
          fs.mkdirSync(dir, { recursive: true });
        }
    
        fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2), 'utf8');
        return true;
      } catch (error) {
        console.error(`⚠️  Failed to save state: ${error.message}`);
        console.error(`   State file: ${STATE_FILE}`);
        return false;
      }
    }
    
    // Get current working directory (project detection)
    function getCurrentProject() {
      try {
        const cwd = process.cwd();
        const parts = cwd.split(path.sep);
        // Return last directory name as project
        return parts[parts.length - 1];
      } catch {
        return null;
      }
    }
    
    // Main logic
    function main() {
      const state = loadState();
      const now = Date.now();
      const elapsed = now - state.lastCapture;
    
      // Log hook execution (for debugging)
      console.log('📊 Journal auto-capture hook running');
    
      // Increment message count
      state.messageCount++;
    
      // Update current project
      const currentProject = getCurrentProject();
      if (currentProject) {
        state.lastProject = currentProject;
      }
    
      // Check if we should trigger auto-capture
      const shouldCapture = (
        elapsed > CAPTURE_INTERVAL ||
        state.messageCount >= MIN_ACTIVITY_THRESHOLD
      );
    
      if (shouldCapture) {
        console.log('');
        console.log('🕐 Journal auto-capture triggered');
        console.log(`   ${state.messageCount} messages exchanged since last capture`);
        if (state.lastProject) {
          console.log(`   Project: ${state.lastProject}`);
        }
        console.log('');
        console.log('📝 Please capture this session to the journal:');
        console.log('   - Summarize the goal (what we were trying to do)');
        console.log('   - Summarize what was accomplished');
        console.log('   - Use journal_auto_capture with a brief summary');
        console.log('');
        console.log('⚠️  Claude: You MUST respond to this trigger, even if you decide not to capture.');
        console.log('   Either create a journal entry OR explain why you\'re not capturing.');
        console.log('');
    
        // Reset state
        state.lastCapture = now;
        state.messageCount = 0;
      }
    
      // Save updated state
      const saved = saveState(state);
      if (!saved) {
        console.error('⚠️  Failed to save auto-capture state. Next trigger may be incorrect.');
      }
    }
    
    // Run
    main();
    

Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.

@chrismbryant
Ships withclaude-journal

A lightweight journal/memory system for Claude Code with no ML dependencies. Uses simple SQLite for fast, local storage. This is a full-featured Claude Code plugin with slash commands, skills, an agent, and auto-capture hooks.

63 skills1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
6
Star history of chrismbryant/claude-journal-mcp on GitHub, a chart by star-history.com

More plugins that ship hooks.

i-have-adhd

i-have-adhd

A skill that shapes Claude Code's output for readers with ADHD: it leads with the next action, numbers multi-step work, restates state across turns, drops tangents, gives specific time estimates, and makes progress visible. Invoke it with /i-h.

1 skill1 hook60k
@ayghri@ayghri
Install Plugin
pua

pua

A Claude Code plugin that makes the assistant work harder when it stalls or repeats failures. It adds pressure-style coaching, plus skills for workplace reminders and senior engineer, CTO and team-lead modes for planning and execution.

12 skills+320k
@tanweai@tanweai
Install Plugin
claude-obsidian

claude-obsidian

Turns the sources you read, such as papers, articles and transcripts, into a linked wiki of Markdown notes in Obsidian. Claude keeps sources and citations so every summary can be traced back to its origin.

15 skills+216k
@agricidaniel@agricidaniel
Install Plugin
obsidian-second-brain

obsidian-second-brain

Gives Claude Code a persistent second brain stored as plain markdown in an Obsidian vault. Notes rewrite themselves as new sources arrive, and scheduled agents handle research synthesis and note capture.

1 skill+25.3k
@eugeniughelbur@eugeniughelbur
Install Plugin
arscontexta

arscontexta

A Claude Code plugin that builds a personal knowledge system through conversation, with skills for adding knowledge domains, checking vault health, getting methodology guidance, and evolving the system over time.

10 skills+23.5k
@agenticnotetaking@agenticnotetaking
Install Plugin
pro-workflow

pro-workflow

A Claude Code workflow plugin that learns from your corrections and keeps a self-correcting memory across sessions. It adds skills for agent teams, parallel worktree batch changes, bug capture as GitHub issues, project auto-setup and context compaction.

41 skills+32.9k
@rohitg00@rohitg00
Install Plugin
engram

engram

Helps you learn any topic with a first-principles curriculum, guided tutoring, and spaced review that schedules free-recall practice. Includes coaching for retention stats and study strategy.

3 skills+21.5k
@nagisanzenin@nagisanzenin
Install Plugin
hey

hey

A command line tool for HEY that lets you read and send email, manage contacts, labels, calendars, todos, habits, time tracking and journal entries from the terminal or from your coding agent.

1 skill1 hook423
@basecamp@basecamp
Install Plugin

Questions about the hooks in claude-journal.

Which coding agents can use the hooks in claude-journal?
The hooks in claude-journal install in Claude Code and Cursor: each runs Claude Code hooks from .claude/settings.json, so copy the hooks there.