Skip to content

Commit 9d120e8

Browse files
nsheapsclaude
andcommitted
feat: add self-terminate plugin for graceful session exit
Adds a plugin that enables Claude to terminate its own session by sending SIGINT to its process. Includes: - Executable script (bin/self-terminate.sh) - Skill documentation explaining manual and automated methods - Safety verification to ensure parent is actually Claude Co-Authored-By: Claude Code (~/.ai.worktrees/subagent-via-tmux) <noreply@anthropic.com>
1 parent af2c7c9 commit 9d120e8

4 files changed

Lines changed: 173 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "self-terminate",
3+
"version": "1.0.0",
4+
"description": "Allows Claude to gracefully terminate itself using SIGINT",
5+
"author": {
6+
"name": "Nathan Heaps",
7+
"email": "nsheaps@gmail.com",
8+
"url": "https://github.com/nsheaps"
9+
},
10+
"homepage": "https://github.com/nsheaps/.ai/tree/main/plugins/self-terminate",
11+
"repository": "https://github.com/nsheaps/.ai",
12+
"keywords": ["terminate", "exit", "sigint", "process", "self-destruct"]
13+
}

plugins/self-terminate/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Self-Terminate Plugin
2+
3+
A Claude Code plugin that enables Claude to gracefully terminate its own session.
4+
5+
## Installation
6+
7+
This plugin is part of the nsheaps/.ai plugin collection. Install via:
8+
9+
```bash
10+
claude plugins install github:nsheaps/.ai/plugins/self-terminate
11+
```
12+
13+
## Usage
14+
15+
### Via Script (Recommended)
16+
17+
Claude can simply execute the provided script:
18+
19+
```bash
20+
~/.claude/plugins/self-terminate/bin/self-terminate.sh
21+
```
22+
23+
### Via Skill
24+
25+
The skill provides detailed instructions for manual termination if needed.
26+
27+
## How It Works
28+
29+
Claude Code runs as a process that spawns subshells for Bash commands. The script:
30+
31+
1. Identifies the parent process (Claude) via `$PPID`
32+
2. Verifies it's actually a Claude process
33+
3. Sends `SIGINT` for graceful termination
34+
35+
## Why SIGINT?
36+
37+
- **SIGINT (2)**: Graceful interrupt, allows cleanup
38+
- **SIGTERM (15)**: Also graceful, but SIGINT is more conventional for user-initiated stops
39+
- **SIGKILL (9)**: Force kill, no cleanup - avoid unless necessary
40+
41+
## Files
42+
43+
- `bin/self-terminate.sh` - Executable script for termination
44+
- `skills/self-terminate/SKILL.md` - Detailed skill documentation
45+
46+
## License
47+
48+
MIT
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
# Self-terminate script for Claude Code
3+
# Sends SIGINT to the Claude process that spawned this shell
4+
5+
set -euo pipefail
6+
7+
# Get the parent PID (Claude process)
8+
CLAUDE_PID="$PPID"
9+
10+
# Verify it's actually a claude process
11+
PROCESS_NAME=$(ps -o comm= -p "$CLAUDE_PID" 2>/dev/null || echo "unknown")
12+
13+
if [[ "$PROCESS_NAME" != *"claude"* ]]; then
14+
echo "Error: Parent process ($CLAUDE_PID) is not Claude (found: $PROCESS_NAME)" >&2
15+
exit 1
16+
fi
17+
18+
echo "Sending SIGINT to Claude process (PID: $CLAUDE_PID)..."
19+
kill -INT "$CLAUDE_PID"
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
name: self-terminate
3+
description: Gracefully terminate the Claude Code session by sending SIGINT to the Claude process
4+
---
5+
6+
# Self-Terminate Skill
7+
8+
This skill enables Claude to gracefully terminate its own session by sending a SIGINT signal to its process.
9+
10+
## When to Use This Skill
11+
12+
- When the user explicitly asks Claude to exit or terminate
13+
- When Claude needs to restart with a fresh session
14+
- When testing process management or signal handling
15+
16+
## How It Works
17+
18+
Claude runs as a process that spawns shell subprocesses for Bash commands. The parent PID (`$PPID`) of any spawned shell is the Claude process itself.
19+
20+
Sending `SIGINT` (signal 2) to the Claude process triggers a graceful shutdown, similar to pressing `Ctrl+C`.
21+
22+
## Quick Method: Use the Script
23+
24+
The easiest way is to execute the provided script:
25+
26+
```bash
27+
/path/to/plugins/self-terminate/bin/self-terminate.sh
28+
```
29+
30+
Or if the plugin is installed:
31+
32+
```bash
33+
~/.claude/plugins/self-terminate/bin/self-terminate.sh
34+
```
35+
36+
## Manual Method
37+
38+
If the script is unavailable, Claude can terminate itself manually:
39+
40+
### Step 1: Identify the Claude Process
41+
42+
```bash
43+
echo "Shell PID: $$"
44+
echo "Claude PID (parent): $PPID"
45+
ps -o pid,ppid,comm -p $$ -p $PPID
46+
```
47+
48+
### Step 2: Verify It's Claude
49+
50+
```bash
51+
ps -o comm= -p $PPID
52+
```
53+
54+
This should output `claude` or similar.
55+
56+
### Step 3: Send SIGINT
57+
58+
```bash
59+
kill -INT $PPID
60+
```
61+
62+
## Process Tree Context
63+
64+
A typical Claude Code process tree looks like:
65+
66+
```
67+
iTerm/Terminal
68+
└── shell (user's interactive shell)
69+
└── claude (PID: XXXXX) ← Target this
70+
└── /bin/zsh (spawned for Bash commands)
71+
└── (your command)
72+
```
73+
74+
## Safety Notes
75+
76+
- **SIGINT** causes graceful termination - Claude can clean up
77+
- **SIGTERM** also works for graceful shutdown
78+
- **SIGKILL** (-9) should be avoided - no cleanup opportunity
79+
- The script verifies the parent is actually Claude before sending the signal
80+
81+
## What Happens After
82+
83+
After termination:
84+
1. The Claude session ends immediately
85+
2. Any in-progress work is interrupted
86+
3. The user returns to their shell
87+
4. A new session can be started with `claude`
88+
89+
## Troubleshooting
90+
91+
**Script says parent is not Claude**: You may be running in a nested shell or different environment. Check `pstree -p $$` to see the full process tree.
92+
93+
**Signal ignored**: Some environments may mask signals. Try `kill -TERM $PPID` as an alternative.

0 commit comments

Comments
 (0)