SessionEnd Hook

SessionEnd

SessionEnd is triggered when a Hawa Code session terminates. Suitable for performing cleanup tasks, logging session statistics, or saving session state.

Note: Since SessionEnd is triggered when the session ends, it cannot block session termination and only supports type: "command" hooks.


Key Features

Property Description
Trigger Timing When the session ends
Can Block No - Cannot prevent session termination
Supported Hook Types Only supports command
Decision Control None - Only for side effects (logging, cleanup, etc.)

Matcher Support

SessionEnd supports using matchers to filter by session end reason:

Matcher Trigger Timing
clear When clearing the session using the /clear command
other Other exit reasons (normal exit, abnormal exit, etc.)
* Match all end reasons

Input Parameters

Field Type Description
session_id string Session unique identifier
transcript_path string Full path to the conversation JSON file
cwd string Current working directory
permission_mode string Current permission mode
hook_event_name string Fixed as "SessionEnd"
reason string Session end reason: "clear" or "other"

Input Example:

{
"session_id": "abc123",
"transcript_path": "/Users/.../.hcode/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "SessionEnd",
"reason": "other"
}

Output Parameters

SessionEnd hook has no specific output requirements. The script’s standard output and error output will be logged but will not affect the session termination process.


Configuration Examples

Basic Cleanup Hook (matches all end reasons)

{
"hooks": {
"SessionEnd": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "node ./hooks/session-end.js"
}
]
}
]
}
}

Script Example (./hooks/session-end.js):

const fs = require('fs');

// Read parameters from stdin
const input = fs.readFileSync(0, 'utf-8');
const params = JSON.parse(input);

const sessionId = params.session_id;
const reason = params.reason;

// Log session statistics
const stats = {
sessionId: sessionId,
endTime: new Date().toISOString(),
reason: reason,
transcriptPath: params.transcript_path
};

// Write statistics to log file
fs.appendFileSync(
'./logs/session-stats.log',
JSON.stringify(stats) + '\n'
);

console.error(`[SessionEnd] Session ${sessionId} has ended, reason: ${reason}`);
process.exit(0);

Match Specific Exit Reason (only execute on /clear)

{
"hooks": {
"SessionEnd": [
{
"matcher": "clear",
"hooks": [
{
"type": "command",
"command": "rm -f /tmp/claude-scratch-*.txt"
}
]
}
]
}
}

Multi-Matcher Configuration

{
"hooks": {
"SessionEnd": [
{
"matcher": "clear",
"hooks": [
{
"type": "command",
"command": "echo 'Session cleared' >> ./logs/cleanup.log"
}
]
},
{
"matcher": "other",
"hooks": [
{
"type": "command",
"command": "node ./hooks/normal-exit.js"
}
]
}
]
}
}