Skip to content
claudemods

ctx-handoff Claude Code mod: make Claude Code long sessions easier

Keeps the prompt cache warm, writes project notes from what you teach Claude, and can hand off a full context.

Permissions

  • Reads filesCan read files and list directories on your machine ($.fs.read / list / stat / exists).
  • Writes filesCan create or overwrite files on your machine ($.fs.write).
  • Calls the model (uses your quota)Can send its own requests to Claude, which count against your plan's usage ($.model.* / $.agent.spawn).
  • Intercepts tool callsSees every tool call Claude makes (tool.call / tool.check) and could block or change it.
  • Reads your promptsCan see what you type and the conversation transcript (prompt.* / session.append / session.messages).
  • Changes the UIDraws into the Claude Code interface: bands, panes, status text, toasts (ui.render / $.ui.*).
  • Adds commands/toolsRegisters new slash commands or tools that you or Claude can invoke ($.command.register / $.tool.register).
  • Stores dataKeeps data between sessions in the plugin's private store ($.store.*).
tested with
v2.1.303
last tested
requires
Claude Code ≥ 2.1.287
surfaces
above-prompt, status, toast

Install inside Claude Code:

/plugin install ctx-handoff --marketplace cablate/ctx-handoff-mod
All install options ↓

What does this mod do?

ctx-handoff is a community mod by CabLate (cablate) for Claude Code long sessions. It bundles several chores that come up when a conversation runs for hours: it sends a tiny request while you are away so the prompt cache does not expire, it turns your repeated instructions into per-project notes that are loaded into new conversations, and it nudges Claude when it retries a failing tool or says "done" without running a check.

Two bigger features are less automatic. An optional handoff writes a summary of the work, clears the conversation and continues in a fresh one when the context reaches a threshold; it is off by default. Guards are tool-call checks the mod drafts from rules you keep repeating, and they only apply after you approve them. A panel above the prompt (/handoff panel) lists guards, memories, rules, the latest notes update and every setting.

The author's README targets Claude subscriptions and long, large-context sessions. On an API key, Bedrock or Vertex the cache lasts five minutes, so the author suggests /handoff refresh off.

Demo

The recording starts Claude Code with the mod loaded in the small demo project. The footer immediately shows ctx-handoff: 30 more messages until notes update, the countdown to the next background notes update. The clip then runs /handoff guard, which prints Guards: none with the conditions under which guards get drafted, and /handoff refresh, which prints Currently on. Usage: /handoff refresh on|off. No model request is made in the clip, and it does not open the panel because the panel shows the full path of the notes file.

Install

Use any of the methods in the install block; they install straight from the author's own marketplace. Start a new session and run /handoff. The footer countdown appears once the session starts.

$ install ctx-handoff

Requires Claude Code ≥ 2.1.287

Installs from the author's own marketplace: cablate/ctx-handoff-mod

  1. 1.One line, inside Claude Code

    /plugin install ctx-handoff --marketplace cablate/ctx-handoff-mod

    Paste into a running session (v2.1.275+). Claude Code asks to add the marketplace first.

  2. 2.From your shell

    claude plugin marketplace add cablate/ctx-handoff-mod
    claude plugin install ctx-handoff@ctx-handoff-mod

    Then run /reload-plugins in any session that is already open.

  3. 3.Try it without installing

    git clone https://github.com/cablate/ctx-handoff-mod
    claude --plugin-dir ./ctx-handoff-mod

    Loads the mod for one session only. Nothing is added to your settings.

How it works

Everything is registered from one module, hooks/register.ts. Each finished turn restarts an idle timer. When it fires, and the context is above min_tokens, the mod sends a minimal fork request to read the cached conversation and then schedules the next one. This is the scheduling function, from hooks/register.ts:

async function schedule($: EngineInterface, delay = cfg.idleMs) {
  rt.idle?.cancel()
  if (await awayPaused($)) { rt.idle = undefined; await update($, idleState, () => null); return }
  rt.idle = $.clock.after(delay, () => void onIdle($))
  const due = (await $.clock.now()) + delay
  await update($, idleState, () => ({ due, refreshes: rt.refreshes }))
}

By default the idle time is 50 minutes and at most 3 refreshes run, after which an away handoff is saved without clearing. Every 30 user messages, or before a handoff, a separate request without history sends only the new part of the conversation to a notes model (claude-sonnet-5-5, low effort). Its JSON actions are validated in code, user quotes must be found in your actual messages, and lines that look like secrets are dropped before anything is written. The notes are injected into new conversations through prompt.context.

Customize it

The mod declares no userConfig. Settings live on the panel's Settings tab (/handoff panel, then key 5), and the mod also reads pluginConfigs["ctx-handoff@<marketplace>"].options from settings.json; the panel value wins. The settings include auto_handoff (default off), threshold (600000 tokens), idle_minutes (50), max_refresh (3), min_tokens (30000), distill_every (30), notes_model, retry_nudge, done_check, reply_language and language. Slash commands cover the rest: /handoff now, dry, distill on|off, refresh on|off, away pause|resume, guard, resume, continue and resend.

Permissions & safety

We read the manifest, hooks/hooks.json, hooks/register.ts in full, and the modules for settings, notes, handoff, guards, loops, language, promotion and the distill prompt. The remaining files, mostly the i18n strings, the panel view and small record helpers, were checked for side effects with searches rather than read line by line. The repo has no package.json, install script, binary or minified code. tools/ holds author-side scripts that the plugin does not load, and we did not run them. There are no hidden Unicode characters.

Findings you should know about:

  • Model requests, no other network. There is no fetch, process call or network code. The mod calls $.model.fork and $.model.complete, which use your Claude quota. Conversation text is sent for notes and handoff summaries, the same way the conversation itself is.
  • Writes outside its own store. $.fs.write creates and updates <claude config dir>/projects/<workspace>/memory/ctx-handoff.md, and writes a backup in .ctx-handoff-backup/ before deleting a note from the panel. Background notes updates are on by default, but they are skipped when the session starts in your home folder. It does not touch settings.json, shell files or LaunchAgents, and it reads HOME, USERPROFILE and CLAUDE_CONFIG_DIR.
  • It injects text into the model. prompt.context adds your notes, an optional progress memo and guard questions to new conversations, tagged [ctx-handoff]. Tool results can carry nudges. Once a rule has been repeated 3 times in a git repo, the injected text tells Claude to write it into the repo (CLAUDE.md, .claude/skills, hooks) without asking first, but not to commit. The notes are model-written summaries of your conversations, so check the file now and then.
  • Gating hooks. tool.call can deny a call only for a guard you approved. classic.Stop can block one "done" answer per turn when files were edited and no check ran (done_check, on by default). prompt.submit holds your messages while a handoff is running. If you turn auto handoff on, the mod runs /clear and submits the summary itself.
  • No daemon, no telemetry. Timers live only in the Claude Code process. Usage statistics stay in the plugin's store.
  • Managed setups. claude plugin validate notes that prompt.context and classic.Stop hooks do not run in a user-installed plugin where an organization manages Claude Code.
  • License. MIT, with a LICENSE file.

claude plugin validate reported no errors. Its only warning is that the CLAUDE.md at the repo root is not loaded as plugin context. The author's 290 tests across 15 files passed on Claude Code 2.1.303.

Reads files
Can read files and list directories on your machine ($.fs.read / list / stat / exists).
Writes files
Can create or overwrite files on your machine ($.fs.write).
Calls the model (uses your quota)
Can send its own requests to Claude, which count against your plan's usage ($.model.* / $.agent.spawn).
Intercepts tool calls
Sees every tool call Claude makes (tool.call / tool.check) and could block or change it.
Reads your prompts
Can see what you type and the conversation transcript (prompt.* / session.append / session.messages).
Changes the UI
Draws into the Claude Code interface: bands, panes, status text, toasts (ui.render / $.ui.*).
Adds commands/tools
Registers new slash commands or tools that you or Claude can invoke ($.command.register / $.tool.register).
Stores data
Keeps data between sessions in the plugin's private store ($.store.*).

Compatibility & troubleshooting

Checked with Claude Code 2.1.303 on macOS (validate, tests and the recording). The author's README requires 2.1.287 or later. If /handoff does nothing:

  • claude --version is 2.1.287 or later, and you started a new session after installing.
  • Another /handoff command may exist; the mod then registers /ctx-handoff instead.
  • The footer countdown is absent when notes updates are off or when you started Claude Code in your home folder.
  • Cache refreshes help only where the cache lasts an hour, so turn them off with /handoff refresh off on API keys.
  • Run /handoff for the current state, including the latest failure and the path of the notes file.

FAQ

Does ctx-handoff use my Claude quota?
Yes. It has no servers of its own, but it makes model requests through your Claude Code sign-in. A cache refresh is a tiny request, and a notes update sends only the new part of the conversation to Sonnet 5.5 at low effort. A full handoff is one request.
Where does it write files?
Project notes go to ctx-handoff.md in the memory folder under ~/.claude/projects/ (or CLAUDE_CONFIG_DIR) for the workspace. Everything else lives in the plugin's own store. Deleting a note from the panel backs up the old file first.
Will it clear my conversation by itself?
Only if you turn on auto_handoff, which is off by default. With it off, Claude Code's own compact handles a full context. Away handoffs are saved without clearing, and you choose whether to resume from them.
Can it block Claude's tool calls?
Only through guards. The mod drafts them from rules you keep repeating, and nothing applies until you approve a guard. Separately, a default-on check can hold back a "done" answer once if files were edited and nothing was tested.
How do I turn the background parts off?
Run /handoff distill off for notes, /handoff refresh off for cache refreshes, or open /handoff panel and use the Settings tab for the nudges and the reply-language reminder.
Project Sentinel running in Claude CodeFeatured

Project Sentinel

A status band, context handoff, prompt cache tracking and permission rules for long Claude Code runs.

  • above-prompt
  • pane
  • spinner
  • status
  • toast
  • Reads files
  • Runs commands
  • Calls the model (uses your quota)
  • Intercepts tool calls
  • Reads your prompts
  • Changes the UI
  • Adds commands/tools
  • Stores data

tested with v2.1.296

Cache Clock running in Claude CodeFeatured

Cache Clock

A prompt-cache line under your Claude Code status line: time left while warm, hit rate, and tokens re-cached once cold.

  • status
  • Reads files
  • Writes files
  • Runs commands
  • Adds commands/tools

tested with v2.1.296

Where Am I running in Claude CodeFeatured

Where Am I

A recap above the Claude Code prompt: the session goal, what is happening now, what waits on you and the next step.

  • above-prompt
  • Reads files
  • Calls the model (uses your quota)
  • Intercepts tool calls
  • Reads your prompts
  • Changes the UI
  • Adds commands/tools

tested with v2.1.303

More in Timers, todos, standups, Context, quota, cost.