Feature Request: PreSessionEnd Hook

Status Closed — not planned
Maintainer reply None cached
Activity 11 comments · opened Jan 8, 2026 · closed May 5, 2026

Feature Request: PreSessionEnd Hook

Repository: https://github.com/anthropics/claude-code/issues

---

Summary

Request for a PreSessionEnd hook that fires when the user signals exit, but before Claude terminates — enabling Claude-dependent operations as part of the exit flow.

The Problem

The current SessionEnd hook runs after Claude has already exited. Any operation requiring Claude's participation is impossible at that point.

Current flow:

User: /exit or Ctrl-D
  → Claude exits immediately
  → SessionEnd hook fires (Claude is gone)
  → Hook can only run shell commands — Claude cannot participate

Desired flow:

User: /exit or Ctrl-D
  → PreSessionEnd hook fires (Claude still active)
  → Claude executes any configured prompt/operation
  → Claude exits
  → SessionEnd hook fires for post-exit tasks

The Architectural Gap

The hooks system currently covers:

  • SessionStart — before Claude is ready (injection)
  • PostToolUse — during session (validation, logging)
  • SessionEnd — after Claude exits (cleanup)

What's missing: a hook at the moment the user signals "I'm done" but Claude is still active. This is the only point where Claude can participate in exit-related operations.

Use Case

I've built a custom context persistence system:

  • SessionStart hook: Decrypts and injects saved context
  • SessionEnd hook: Encrypts context file for storage
  • Custom /save-context skill: Claude summarises session → writes to .claude/context.md

The gap: The encryption hook runs after Claude exits, but the context generation requires Claude to be active. Currently I must manually run /save-context before exiting. If I forget, there's nothing to encrypt.

This isn't specific to my workflow — it's the general pattern: any exit operation requiring Claude's participation has no trigger point.

Proposed Solution

A PreSessionEnd hook that fires when the user signals exit (/exit, Ctrl-D twice, etc.) but before Claude terminates.

{
  "hooks": {
    "PreSessionEnd": [{
      "hooks": [{
        "type": "prompt",
        "prompt": "Summarise this session and save context to .claude/context.md"
      }]
    }]
  }
}

Hook Types

  • type: "prompt" — Inject a prompt for Claude to execute before exit. This is the key capability: Claude can summarise, clean up, confirm, or run any skill.
  • type: "command" — Run a shell command (consistent with other hooks, though less useful here since the point is Claude participation).

Behaviour

  • Hook fires once per exit signal
  • Claude processes the prompt normally
  • After completion, exit proceeds
  • If hook fails or times out, exit proceeds anyway (graceful degradation)

Workaround

I've created an /exit-save command that chains my save operation with /exit. It works, but requires discipline to use the right exit command — easy to forget and just Ctrl-D.

Impact

This fills the one timing gap in the hooks system. Users could:

  • Auto-generate session summaries on exit
  • Run cleanup prompts before termination
  • Trigger any Claude-dependent operation as part of the exit flow
  • Build more robust context persistence without manual steps

The hooks architecture is already excellent. This adds the missing lifecycle event.

---

Environment: Claude Code CLI
Related: SessionStart, SessionEnd, PostToolUse hooks

View original on GitHub ↗

11 Comments

github-actions[bot] · 7 months ago

Found 2 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/12755
  2. https://github.com/anthropics/claude-code/issues/13239

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

paullaudeman · 7 months ago

Not a duplicate — distinct capability request

#12755 requests a PreSessionEnd hook with type: "command" — an external shell script that can block exit based on external state (e.g., git status).

This request is for type: "prompt"Claude participates in the exit flow with full session context.

The architectural distinction:

| Capability | External command | Prompt injection |
|------------|------------------|------------------|
| Access to session context | ❌ None | ✅ Full |
| Can summarise conversation | ❌ No | ✅ Yes |
| Can generate context files | ❌ No | ✅ Yes |
| Can block exit | ✅ Yes (exit code) | ⚪ Optional |

Why this matters:

The use case in #12755 (uncommitted git changes) can be solved with an external command — git status doesn't need session awareness.

Context persistence cannot be solved externally. Only Claude knows what happened in the session. Generating a meaningful summary requires Claude to participate with full conversation context.

These are complementary capabilities under the same PreSessionEnd hook, but type: "prompt" is architecturally distinct from type: "command".

---

Happy to merge if the maintainers see these as the same request, but wanted to clarify the distinction.

multipletwigs · 7 months ago

@paullaudeman i'd love for this to be included as well, i have a use case here where i'd want to trigger external compilations of chat history before /exit finishes, following this thread! hope they add it in.

odysseus0 · 6 months ago

wanted the same thing. should be an easy add for them. literally same functionality as stop hook

gerard-wr · 6 months ago

+1 on this. We have an almost identical workflow — a per-user growth feedback system where Claude writes session observations to .claude/growth-notes/{user}.md during the conversation.

Our current hook coverage:

  • PreCompact — timestamps compaction events ✅
  • SessionEnd (clear) — timestamps /clear events, but context is already gone ⚠️
  • Custom /wr-bye command — AI-driven growth summary before exit ✅

The gap is exactly what you describe: any exit path (/clear, /exit, Ctrl-D) that bypasses our custom command loses unwritten AI observations.

One request: Please ensure /clear is included as a trigger alongside /exit and Ctrl-D. Currently /clear doesn't fire SessionEnd reliably in all cases, and it's the most common "accidental" exit path that skips custom cleanup commands.

The type: "prompt" proposal is especially valuable — shell-only hooks can only write timestamps, but a prompt hook would let Claude generate a proper session summary before context is destroyed.

Related: #21578 (PreClear specifically), #25009 (our issue, closing as duplicate of this + #21578)

CTJaeger · 6 months ago

+1 for this feature. I'm using Claude Code in VS Code and urgently need session lifecycle hooks.

My use case: Session chaos with multiple projects

I work on 5-8 projects simultaneously. Right now I have to keep dozens of Claude Code tabs open in VS Code just to preserve context — there's no way to browse, search or reopen past sessions per project.

A PreSessionEnd hook would allow me to automatically export a session summary to a project-specific _chatcontext/ directory. This would let me:

  • Close tabs without losing context
  • Resume work in a new session by reading the exported summary
  • Search past sessions per project via simple file search
  • Share session context with teammates

What I'd love to see

{
  "hooks": {
    "PreSessionEnd": [
      {
        "command": "cp $SESSION_TRANSCRIPT $PROJECT_DIR/_chatcontext/"
      }
    ]
  }
}

Currently, the only workaround is manually instructing Claude via CLAUDE.md to write a summary — but that's fragile and easy to forget.

This is a real daily pain point. Would make Claude Code significantly more usable for multi-project workflows.

CTJaeger · 6 months ago

+1 for this feature. I'm using Claude Code in VS Code and urgently need session lifecycle hooks.

My use case: Session chaos with multiple projects

I work on 5-8 projects simultaneously. Right now I have to keep dozens of Claude Code tabs open in VS Code just to preserve context — there is no way to browse, search or reopen past sessions per project.

A PreSessionEnd hook would allow me to automatically export a session summary to a project-specific _chatcontext/ directory. This would let me:

  • Close tabs without losing context
  • Resume work in a new session by reading the exported summary
  • Search past sessions per project via simple file search
  • Share session context with teammates

Currently, the only workaround is manually instructing Claude via CLAUDE.md to write a summary — but that is fragile and easy to forget.

This is a real daily pain point. Would make Claude Code significantly more usable for multi-project workflows.

spectator81-png · 5 months ago

Adding our use case: We built a relational memory plugin that needs Claude to analyze the conversation at session end — extracting 7 relational signal dimensions via LLM-as-judge, then updating an EMA vector.

We tried every workaround:

  • Stop hook (command, block/approve): Fires after every turn, not at exit. Creates infinite loops or fires mid-session.
  • Stop hook (prompt): JSON validation failed error — prompt-type hooks don't seem to work on Stop events.
  • Marker file pattern: Prevents loops but triggers mid-session at turn N, losing signals from later turns.

The core issue: there's no way to distinguish "agent finished a turn" from "user is closing the session." A PreSessionEnd hook that fires once at actual exit, with time for Claude to do work, would solve this completely.

Our plugin currently works as context-loader only (SessionStart injects relationship vector + layers). Signal extraction requires manual /memory-save. Filed as #34954 before finding this issue.

chriscoey · 5 months ago

+1 — I have a concrete use case for this.

I use a knowledge management system (Hindsight) that distills session learnings into a persistent memory graph. The distillation requires Claude to be active — it reviews the conversation, filters for non-obvious insights, and retains them via API. This can't happen in a SessionEnd shell hook because Claude is already gone.

Currently I work around this with:

  • A PreCompact hook that reminds Claude to run the distillation skill before context is lost
  • Manual invocation before /exit

Both are unreliable. PreCompact rarely fires with 1M context windows, and manual invocation means forgetting = losing the session's learnings.

A BeforeSessionEnd hook with systemMessage injection (as proposed in #39392) would solve this cleanly — Claude sees the message, runs the distillation, then exits. The key requirement is that Claude can still execute tool calls (API requests) during this window, not just receive a notification.

github-actions[bot] · 3 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

github-actions[bot] · 2 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.