Getting Started

Overview

ctx preserves Claude Code session context across compactions — automatically.

When Claude Code hits its context window limit, it compacts the conversation. This is necessary, but lossy: your current goal, technical decisions, the file you were editing, what to do next — all of it can get diluted or lost. After two or three compactions, Claude may forget what you were building, repeat work, or contradict decisions you already made together.

ctx hooks into Claude Code’s PreCompact, PostCompact, and SessionStart events to capture and restore a structured snapshot of your working context, every time. Snapshots are scoped per branch, so parallel sessions on different branches never collide.

Vision

Every Claude Code session starts exactly where you left off.

Mission

Capture the minimum context needed to resume work, automatically, at the right moment.

Philosophy

The most recent state is the only state that matters. Compaction is not loss — it’s a checkpoint. One snapshot per branch, always current, never accumulated. If it’s in the code, git has it. If it’s not, it shouldn’t survive anyway.

ctx is not a memory tool. It doesn’t accumulate knowledge across sessions, index conversations, or build a searchable history. It solves one specific problem: keeping the current session coherent when context gets compacted.

Getting Started

How It Works

ctx hooks into three Claude Code lifecycle events:

HookWhenWhat ctx does
PreCompactBefore compaction firesReads transcript + git state, calls claude -p, writes snapshot
PostCompactAfter compaction completesRe-injects the snapshot into the compacted session
SessionStartEvery new sessionFinds snapshot for project + branch, prints it as context

The Flow

┌──────────────────────────────────────────────────────────────┐
│ Claude Code session                                          │
│                                                              │
│  /compact triggered                                          │
│       │                                                      │
│       ▼                                                      │
│  PreCompact hook → ctx reads transcript + git state          │
│                  → calls claude -p to extract semantics      │
│                  → writes snapshot (scoped to branch)        │
│                                                              │
│  PostCompact hook → ctx reads the snapshot just written      │
│                   → prints it to stdout                      │
│                   → Claude Code re-injects it immediately    │
│                                                              │
│  New session on same branch                                  │
│       │                                                      │
│       ▼                                                      │
│  SessionStart hook → ctx finds snapshot for project+branch   │
│                    → prints it to stdout                     │
│                    → Claude Code injects it as context       │
└──────────────────────────────────────────────────────────────┘

Why PostCompact Re-Injection Matters

After compaction, the context is summarized. PostCompact runs immediately after — ctx prints the snapshot back, so Claude re-enters the session with structured context intact. No information gap between pre-compaction and post-compaction state.

Branch Scoping

Snapshots are stored per project per branch:

~/.local/share/ctx/{sha256(project_path)}/{branch}/snapshot.md

Two sessions on different branches in the same repo never overwrite each other. Non-git directories and detached HEAD use _ as the branch name.

What ctx Does NOT Do

  • Does not keep a history of previous snapshots
  • Does not sync between machines
  • Does not require git
  • Does not auto-expire snapshots
  • Does not read chop’s SQLite database
  • Does not handle subagent transcripts (everything relevant is already in the orchestrator’s transcript)
Getting Started

Quick Start

Get ctx running in under a minute.

Install

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/AgusRdz/ctx/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/AgusRdz/ctx/main/install.ps1 | iex

Register Hooks

ctx init

This registers three hooks in ~/.claude/settings.json: PreCompact, PostCompact, and SessionStart.

Verify

ctx init --status

Expected output:

hooks: installed
  PreCompact  · auto    ✓
  PreCompact  · manual  ✓
  PostCompact · auto    ✓
  PostCompact · manual  ✓
  SessionStart          ✓

Try It

  1. Open a Claude Code session and do some work
  2. Run /compact to trigger compaction
  3. Check the snapshot: ctx show
  4. Open a new session — ctx automatically injects the snapshot

That’s it. ctx works silently from this point forward.

Getting Started

Installation

Install Script

macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/AgusRdz/ctx/main/install.sh | sh

Windows (PowerShell):

irm https://raw.githubusercontent.com/AgusRdz/ctx/main/install.ps1 | iex

Homebrew

brew install AgusRdz/tap/ctx

Go Toolchain

go install github.com/AgusRdz/ctx@latest

Binary Location

PlatformPath
macOS / Linux~/.local/bin/ctx
Windows%LOCALAPPDATA%\Programs\ctx\ctx.exe

Register Hooks

After installing, register ctx with Claude Code:

ctx init

To remove hooks:

ctx init --remove

Verify Attestations

All release binaries include build provenance attestations verifiable with the GitHub CLI:

gh attestation verify <binary> --repo AgusRdz/ctx

Update

ctx updates itself automatically in the background — once every 24 hours it checks for a new release and applies it silently on the next invocation.

ctx update       # update immediately
ctx changelog    # see what changed
Reference

Commands

Setup

ctx init                   Register PreCompact, PostCompact, and SessionStart hooks
ctx init --remove          Remove ctx hooks
ctx init --status          Check hook installation status
ctx init --local           Create local project config (.ctx/config.yml)

Session

ctx show                   Print snapshot for current branch
ctx show --project <path>  Print snapshot for a specific project
ctx state                  Capture and print current project state
ctx clear                  Delete snapshot for current branch
ctx clear --all            Delete all branch snapshots for this project
ctx list                   List all projects and branches with snapshots

Configuration

ctx config                 Show effective configuration with sources
ctx config --global        Show only global config file
ctx config --local         Show only local config file
ctx config --debug true    Enable verbose hook logging

Diagnostics

ctx doctor                 Check hooks, binary path, claude availability
ctx logs                   Show last 20 hook log entries
ctx logs -n <N>            Show last N entries
ctx logs --all             Show all entries

Maintenance

ctx update                 Update to the latest version
ctx uninstall              Remove ctx completely (hooks, data, binary)
ctx version                Show version
ctx changelog              Show changes in the current version
ctx changelog --full       Show full changelog history
Reference

Configuration

ctx uses two config layers that merge field-by-field. Local values win over global.

Global Config

Location: ~/.config/ctx/config.yml (Windows: %APPDATA%\ctx\config.yml)

core:
  debug: false
  claude_timeout: 30     # seconds; default 30

Local Config

Location: {project}/.ctx/config.yml (optional, project-level overrides)

Create with:

ctx init --local

.ctx/ is automatically added to .gitignore — local config is a developer preference, not a team setting.

Project State Config

Controls what ctx captures at compaction time:

project_state:
  enabled: true
  git: true
  typecheck:
    enabled: true
    timeout_seconds: 20
    command: ""          # custom command overrides auto-detection
  tests:
    enabled: false       # opt-in — can be slow
    timeout_seconds: 60
    max_failed_names: 5
    command: ""          # custom command overrides auto-detection
  max_dirty_files: 10
  max_errors: 5

Auto-detection for typecheck covers tsc (tsconfig.json) and go build (go.mod). For everything else, set a custom command:

# dotnet build (C#)
project_state:
  typecheck:
    enabled: true
    command: "dotnet build --no-restore -v minimal"

# mypy (Python)
project_state:
  typecheck:
    enabled: true
    command: "mypy src --no-error-summary"

# clippy (Rust)
project_state:
  typecheck:
    enabled: true
    command: "cargo clippy --quiet 2>&1"

View Effective Config

ctx config

Output:

effective configuration
───────────────────────────────────────
core.debug              false      [default]
core.claude_timeout     30         [default]

global:  ~/.config/ctx/config.yml
local:   /home/agus/projects/myapp/.ctx/config.yml

Docker-based projects: ctx runs typecheck commands on the host. If your build runs inside Docker, disable typecheck in your local config:

project_state:
  typecheck:
    enabled: false
Reference

Snapshot Format

The snapshot is a structured markdown document with four fields, capped at 300 tokens.

Structure

# Session Context

_Captured: 2026-03-09T14:32Z_

## Goal
Building the authentication middleware

## Decisions
- Using JWT with RS256 for token signing
- Middleware applied at router level, not per-handler

## In Progress
 auth/middleware.go | 45 +++++++++
 auth/jwt.go       | 32 ++++++
 2 files changed, 77 insertions(+)

## Next
Add token refresh endpoint and write integration tests

Fields

FieldWhat it captures
GoalWhat you’re building right now
DecisionsTechnical choices made this session
In ProgressFiles being modified (git diff –stat)
NextWhat to do when context resumes

Storage Location

PlatformPath
Linux/macOS~/.local/share/ctx/{project-hash}/{branch}/snapshot.md
Windows%LOCALAPPDATA%\ctx\{project-hash}\{branch}\snapshot.md

The project hash is sha256(abs_project_path). One snapshot per project per branch. path.txt at the hash-dir level stores the original path for ctx list reverse lookup.

View Your Snapshot

ctx show

Delete Your Snapshot

ctx clear          # current branch only
ctx clear --all    # all branches for this project
Reference

Debugging

Doctor Command

ctx doctor

Checks hooks registration, binary path, and claude CLI availability. Run this first when something doesn’t work.

Log File

All hook executions write to a single log file:

PlatformPath
Linux/macOS~/.local/share/ctx/debug.log
Windows%LOCALAPPDATA%\ctx\debug.log

Format:

[2026-03-08T14:32:00Z] precompact | trigger=auto | project=/home/agus/myapp | duration=3.2s | status=ok
[2026-03-08T14:32:00Z] session    | project=/home/agus/myapp | snapshot=found | tokens=187

Errors append with full detail:

[2026-03-08T14:32:00Z] precompact | ERROR: claude -p exited with code 1: ...

Log Commands

ctx logs              # last 20 entries
ctx logs -n 50        # last 50 entries
ctx logs --all        # all entries

Enable Verbose Logging

ctx config --debug true

Shows context sizes, timings, and detailed error traces.

Manual Test Procedure

Step 1 — Verify the hook fires

Open a Claude Code session, run a few commands, then type /compact. Check the log:

tail -5 ~/.local/share/ctx/debug.log
# Windows: tail -5 "$LOCALAPPDATA/ctx/debug.log"

Expected: a precompact | status=ok entry.

Step 2 — Verify the snapshot

ctx show

Expected: structured snapshot with goal, decisions, in_progress, next.

Step 3 — Verify Claude receives context

Close the session and open a new one. Ask Claude:

What do you know about what we were working on?

Expected: Claude describes the snapshot content without you mentioning it.

Fallback Behavior

  • No git: snapshot generates using filesystem data only
  • claude unavailable: snapshot falls back to deterministic-only content, logs a warning, does not crash
Reference

Updates

Automatic Updates

ctx updates itself automatically in the background. Once every 24 hours it checks for a new release, downloads it silently, and applies it on the next invocation. You’ll see a one-line notification when it does.

Manual Update

ctx update

Changelog

ctx changelog        # current version changes
ctx changelog --full # full history

Uninstall

ctx uninstall

Removes hooks from ~/.claude/settings.json, deletes all snapshot data, and removes the binary.

To only remove hooks without uninstalling:

ctx init --remove