Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ SESSION_STATE.md
.test-results/
.workflow-state.json
specs/
build/
dist/
*.egg-info/
51 changes: 45 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@

Launch a new Claude Code session in any project. When a session's context window fills up, this script seamlessly transfers work to a fresh Claude instance in a new terminal tab — no human intervention needed. Also supports switching to a different project entirely.

## Quick start

```bash
# 1. Install (Python 3.8+, no other dependencies)
pip install git+https://github.com/grobomo/context-reset

# 2. Add a stop hook to ~/.claude/settings.json
```

Add this to your Claude Code settings (`~/.claude/settings.json`):

```json
{
"hooks": {
"Stop": [
{
"type": "command",
"command": "new-session --project-dir $CLAUDE_PROJECT_DIR"
}
]
}
}
```

That's it. Claude will automatically reset to a fresh session when context gets heavy, carrying over TODO.md and a readable summary of the conversation.

If you already have stop hooks, just add the entry to your existing `Stop` array.

## How it works

1. Reads the last 500 JSONL lines from the transcript (efficient reverse-read, no full file load)
Expand Down Expand Up @@ -59,16 +87,27 @@ Each new tab gets:

## Integration with Claude Code hooks

Add to a [stop hook](https://docs.anthropic.com/en/docs/claude-code/hooks) module to let Claude trigger resets autonomously when context gets heavy:

```
python C:/path/to/context-reset/new_session.py --project-dir $CLAUDE_PROJECT_DIR
Add to a [stop hook](https://docs.anthropic.com/en/docs/claude-code/hooks) in `~/.claude/settings.json` to let Claude trigger resets autonomously when context gets heavy:

```json
{
"hooks": {
"Stop": [
{
"type": "command",
"command": "new-session --project-dir $CLAUDE_PROJECT_DIR"
}
]
}
}
```

The script reads `$CLAUDE_PROJECT_DIR` by default, so from a hook you can simply:
The script reads `$CLAUDE_PROJECT_DIR` by default, so from a hook you can simply use `new-session`.

If you prefer to run from source instead of pip install:

```
python C:/path/to/context-reset/new_session.py
python /path/to/context-reset/new_session.py --project-dir $CLAUDE_PROJECT_DIR
```

## Session continuity
Expand Down
18 changes: 18 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[build-system]
requires = ["setuptools>=64"]
build-backend = "setuptools.build_meta"

[project]
name = "claude-context-reset"
version = "1.0.0"
description = "Launch new Claude Code sessions with automatic state handoff"
readme = "README.md"
license = "MIT"
requires-python = ">=3.8"

[project.scripts]
new-session = "new_session:main"
context-reset = "new_session:main"

[tool.setuptools]
py-modules = ["new_session", "context_reset", "task_claims"]
117 changes: 117 additions & 0 deletions scripts/bootstrap.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# bootstrap.ps1 - Set up Claude Code with context-reset on a fresh Windows machine
# Run: iwr -useb https://raw.githubusercontent.com/grobomo/context-reset/main/scripts/bootstrap.ps1 | iex
#
# What it does:
# 1. Checks prerequisites (Python 3.8+, Node.js, Windows Terminal)
# 2. Installs Claude Code CLI (npm)
# 3. Installs context-reset (pip)
# 4. Configures the stop hook in ~/.claude/settings.json
#
# Safe to re-run -- skips already-installed components.

$ErrorActionPreference = "Stop"

function Write-Step($msg) { Write-Host "`n=> $msg" -ForegroundColor Cyan }
function Write-Ok($msg) { Write-Host " OK: $msg" -ForegroundColor Green }
function Write-Skip($msg) { Write-Host " SKIP: $msg" -ForegroundColor Yellow }
function Write-Fail($msg) { Write-Host " FAIL: $msg" -ForegroundColor Red }

# --- Prerequisites ---

Write-Step "Checking Python"
try {
$pyVer = python --version 2>&1
if ($pyVer -match 'Python (\d+)\.(\d+)') {
$major = [int]$Matches[1]; $minor = [int]$Matches[2]
if ($major -ge 3 -and $minor -ge 8) {
Write-Ok $pyVer
} else {
Write-Fail "$pyVer -- need Python 3.8+. Install from https://python.org"
exit 1
}
}
} catch {
Write-Fail "Python not found. Install from https://python.org"
exit 1
}

Write-Step "Checking Node.js"
try {
$nodeVer = node --version 2>&1
Write-Ok "Node $nodeVer"
} catch {
Write-Fail "Node.js not found. Install from https://nodejs.org"
exit 1
}

Write-Step "Checking Windows Terminal"
$wt = Get-Command wt -ErrorAction SilentlyContinue
if ($wt) {
Write-Ok "Windows Terminal found"
} else {
Write-Skip "Windows Terminal not found -- context-reset tab features will not work"
Write-Host " Install from Microsoft Store or winget install Microsoft.WindowsTerminal"
}

# --- Claude Code CLI ---

Write-Step "Checking Claude Code CLI"
$claude = Get-Command claude -ErrorAction SilentlyContinue
if ($claude) {
Write-Skip "Claude Code already installed"
} else {
Write-Host " Installing Claude Code..."
npm install -g @anthropic-ai/claude-code
Write-Ok "Claude Code installed"
}

# --- context-reset ---

Write-Step "Installing context-reset"
$ErrorActionPreference = "Continue"
$existing = pip show claude-context-reset 2>&1
if ("$existing" -match "Name: claude-context-reset") {
Write-Host " Upgrading..."
pip install --upgrade git+https://github.com/grobomo/context-reset 2>&1 | Out-Null
Write-Ok "context-reset upgraded"
} else {
pip install git+https://github.com/grobomo/context-reset 2>&1 | Out-Null
Write-Ok "context-reset installed"
}
$ErrorActionPreference = "Stop"

# Verify CLI entry point
try {
$help = new-session --help 2>&1
Write-Ok "new-session CLI works"
} catch {
Write-Fail "new-session CLI not found in PATH - check pip Scripts directory"
exit 1
}

# --- Configure stop hook (uses Python to avoid PowerShell JSON/encoding quirks) ---

Write-Step "Configuring Claude Code stop hook"
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$result = python (Join-Path $scriptDir "configure_hook.py") 2>&1

if ($result -eq "SKIP") {
Write-Skip "Stop hook already configured"
} elseif ($result -eq "ADDED") {
Write-Ok "Stop hook added to existing settings.json"
} elseif ($result -eq "CREATED") {
Write-Ok "Created settings.json with stop hook"
} else {
Write-Fail "Failed to configure stop hook"
}

# --- Done ---

Write-Host ""
Write-Host "Setup complete!" -ForegroundColor Green
Write-Host ""
Write-Host "Next steps:" -ForegroundColor White
Write-Host " 1. Run 'claude' in any project directory to start a session"
Write-Host " 2. When context fills up, Claude will automatically reset to a fresh tab"
Write-Host " 3. TODO.md and SESSION_STATE.md carry context between sessions"
Write-Host ""
26 changes: 26 additions & 0 deletions scripts/configure_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3
"""Add the context-reset stop hook to Claude Code settings.json."""
import json
import os
import sys

settings_file = os.path.join(os.path.expanduser("~"), ".claude", "settings.json")
os.makedirs(os.path.dirname(settings_file), exist_ok=True)

hook = {"type": "command", "command": "new-session --project-dir $CLAUDE_PROJECT_DIR"}

if os.path.exists(settings_file):
with open(settings_file, "r", encoding="utf-8-sig") as f:
settings = json.load(f)
stops = settings.get("hooks", {}).get("Stop", [])
if any("new-session" in h.get("command", "") for h in stops):
print("SKIP")
sys.exit(0)
settings.setdefault("hooks", {}).setdefault("Stop", []).append(hook)
print("ADDED")
else:
settings = {"hooks": {"Stop": [hook]}}
print("CREATED")

with open(settings_file, "w", encoding="utf-8") as f:
json.dump(settings, f, indent=2)
Loading