Feature: Expose background task state to SessionEnd hooks
Problem
SessionEnd hooks (triggered by /clear) cannot reliably detect whether background tasks are still running. This creates a risk of clearing a session while work is in progress.
Why shell hooks can't see background tasks
- Process tree walking fails:
run_in_backgroundtasks are reparented to PID 1, so they're not in the Claude process tree. Acommandhook walkingpgrep -Pwill never find them. - No filesystem state: Claude tracks background tasks in-memory only. There's no
.pidfile, status file, or lock file in the task output directory (/tmp/claude-*/tasks/) that a shell script could check. prompthooks are advisory: Aprompthook onSessionEndcan ask Claude to checkTaskList, but it may not get a full execution turn before teardown completes — making it unreliable as a gate.
Current workaround (two-layer, partial coverage)
- A
commandhook that walks the Claude process tree for child processes (catches MCP servers, direct children — but notrun_in_backgroundtasks) - A
prompthook asking Claude to checkTaskList(advisory only, not a hard gate)
Neither layer reliably catches the common case: a Bash(run_in_background: true) command or a background Agent that hasn't completed yet.
Proposed Solution
One or both of:
Option A: Task-aware hook type
A new hook type (e.g., "type": "task_gate") that automatically blocks the session action if any tasks are in in_progress or pending state. No shell script needed — the runtime checks its own internal state.
{
"type": "task_gate",
"blockMessage": "Background tasks are still running. Wait for them to complete or stop them before clearing."
}
Option B: Expose task state to filesystem
Write a .status JSON file alongside each task's .output file (or a single tasks.json summary) that command hooks can read:
{
"tasks": [
{"id": "bgz6y9hwq", "status": "completed", "pid": null},
{"id": "bzt73iz7p", "status": "running", "pid": 12345}
]
}
This would let shell hooks do what they're good at — reading files and making exit-code decisions.
Environment
- Claude Code 2.1.149
- macOS (Darwin 25.5.0)
- Hook config:
SessionEndwithmatcher: "clear"
Context
This came up while building a SessionEnd hook system to ensure clean session teardowns. The guard script works well for OS-level processes but has a fundamental blind spot for Claude's internal task management.
---
Filed by illartech
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗