From 87436e122c09dc490570eecc31901154023c28a9 Mon Sep 17 00:00:00 2001 From: grobomo Date: Fri, 17 Apr 2026 19:46:34 -0500 Subject: [PATCH 1/2] Add pip packaging for team distribution pyproject.toml with CLI entry points (new-session, context-reset). README Quick Start section: pip install + hook snippet. Teammates install with one command, wire up with one JSON block. --- .gitignore | 3 +++ README.md | 51 ++++++++++++++++++++++++++++++++++++++++++++------ pyproject.toml | 18 ++++++++++++++++++ 3 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore index 86763a3..90b00f8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ SESSION_STATE.md .test-results/ .workflow-state.json specs/ +build/ +dist/ +*.egg-info/ diff --git a/README.md b/README.md index b49fa27..51039e9 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d1964d9 --- /dev/null +++ b/pyproject.toml @@ -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"] From 2e9ca2b51032c25942dd4dc896e2bf2607844639 Mon Sep 17 00:00:00 2001 From: grobomo Date: Sat, 18 Apr 2026 04:50:45 -0500 Subject: [PATCH 2/2] Add bootstrap script for team onboarding PowerShell bootstrap.ps1 checks prereqs (Python, Node, Windows Terminal), installs Claude Code + context-reset, configures the stop hook. Idempotent, BOM-free JSON writes, works in constrained language mode. Teammate runs one command to get full context-reset setup. --- scripts/bootstrap.ps1 | 117 ++++++++++++++++++++++++++++++++++++++ scripts/configure_hook.py | 26 +++++++++ 2 files changed, 143 insertions(+) create mode 100644 scripts/bootstrap.ps1 create mode 100644 scripts/configure_hook.py diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1 new file mode 100644 index 0000000..dc40767 --- /dev/null +++ b/scripts/bootstrap.ps1 @@ -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 "" diff --git a/scripts/configure_hook.py b/scripts/configure_hook.py new file mode 100644 index 0000000..8a9fe50 --- /dev/null +++ b/scripts/configure_hook.py @@ -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)