Allow tools/skills to programmatically clear context and inject a continuation prompt

Status Closed — not planned
Maintainer reply None cached
Activity 13 comments · opened Mar 17, 2026 · closed Jul 8, 2026

Context

When working on long, multi-step tasks, the context window fills up and performance degrades. The natural response is to clear and continue, but this destroys all accumulated context — decisions made, files identified, progress tracked, corrections given.

Problem / Motivation

There is no programmatic way for a skill or tool to:

  1. Summarize the current session context
  2. Clear the conversation
  3. Inject a continuation prompt into the fresh session

This means the human must manually orchestrate the "save context → clear → restore context" bridge every time. It's error-prone, breaks flow, and is exactly the kind of repetitive task that should be automatable.

Real-world use case: A /cls skill that the user invokes when context is getting heavy. The skill gathers git state, conversation decisions, active tasks, and the user's gist of what's next — then clears the conversation and injects the summary so Claude picks up seamlessly. Today this is impossible because:

  • Skills cannot invoke /clear
  • There is no PostClear hook event
  • SessionStart hooks cannot inject prompt content
  • Hooks generally cannot submit text into the conversation

The workaround is for the skill to save a summary to a file, then the user manually runs /clear, then manually types "read the file and continue." This defeats the purpose of having a skill.

Related: #32861

Proposed Solution

Enable one or more of these mechanisms (in order of preference):

Option A: Tool-invocable clear with continuation

A tool like ClearContext that a skill can call programmatically:

ClearContext({ continuation_prompt: "I'm continuing from a previous session..." })

This clears the conversation and injects the continuation as the opening message.

Option B: PostClear hook with prompt injection

Add a PostClear hook event that fires after /clear. Allow hooks of type "prompt" to inject text into the fresh session:

{
  "hooks": {
    "PostClear": [{
      "hooks": [{ "type": "prompt", "promptTemplate": "Read {{file}} and continue" }]
    }]
  }
}

Option C: /clear --run <prompt-or-file>

A built-in flag that clears and then submits a prompt or reads a file:

/clear --run "read local/cls-prompt.md and continue"

This is the simplest to implement but limits automation to what the human types.

Any of these would unblock the use case. Option A is the most powerful (skills can fully orchestrate the flow). Option C is the simplest to ship.

Acceptance Criteria

  • [ ] A skill or tool can programmatically trigger a context clear
  • [ ] A continuation prompt can be injected into the fresh session without user action
  • [ ] The user initiates the flow (not automatic) — this is a human-in-the-loop bridge action
  • [ ] Works in both CLI and IDE integrations

View original on GitHub ↗

12 Comments

yurukusa · 5 months ago

A UserPromptSubmit hook can implement continuation prompts:

PROMPT=$(cat | jq -r '.userPrompt // empty' 2>/dev/null)
if echo "$PROMPT" | grep -qiE '(/continue|resume from|pick up where)'; then
    LAST_STATE="/tmp/cc-last-state.json"
    if [ -f "$LAST_STATE" ]; then
        STATE=$(cat "$LAST_STATE")
        jq -n --arg s "$STATE" '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"Continuation context from previous state: " + $s}}'
    fi
fi
exit 0

Save state before clear:

COUNTER="/tmp/cc-state-counter"
C=$(cat "$COUNTER" 2>/dev/null || echo 0); C=$((C+1)); echo $C > "$COUNTER"
[ $((C % 20)) -ne 0 ] && exit 0
jq -nc --arg b "$(git branch --show-current 2>/dev/null)" --arg f "$(git diff --name-only 2>/dev/null | head -5 | tr '\n' ',')" --arg l "$(git log --oneline -3 2>/dev/null)" '{branch:$b,files:$f,log:$l}' > /tmp/cc-last-state.json
exit 0
peterdrier · 5 months ago
A UserPromptSubmit hook can implement continuation prompts:

How would that work? Is this basically a magic file that gets checked post a /clear for content to auto load? Interesting thought, but doesn't feel very stable in a multiple agent environment.

mianamiana · 5 months ago

+1 on this. I'm building a custom /compact-d skill for discussion-heavy sessions (brainstorming, design decisions). It compresses the conversation into a structured XML handoff file, but then the user still has to manually type /clear 继续 to resume — which defeats the purpose of automating the flow.

My use case: As I create more skills that need to orchestrate context resets (not just compact-d, but potentially any skill that hits context limits), the number of manual steps the user must remember grows linearly. This is exactly the kind of thing that should be a single action.

What I've tried:

  • Hook-based approaches: hooks run in subprocesses and have no IPC channel back to the CLI process — they can't invoke /clear
  • Terminal keystroke injection (tmux send-keys, AppleScript): works but fragile and environment-dependent
  • Behavioral clear (AI ignores old context): doesn't actually free context window space

Option A (tool-invocable clear with continuation) would fully solve my case. Option C (/clear --run) would also work as a pragmatic first step.

tdurzynski · 4 months ago

+1 from an orchestration-setup angle (Claude Code as a sub-agent under a separate orchestrator + Telegram bot). Wanted to add a compute-economics framing the original doesn't make:

The current human-only /clear boundary is presumably a safety call (don't let agents nuke their own context loop). But the side effect is that long-running ship sessions sit on huge stale contexts the user can't prune in time. With the prompt cache capped at a ~5min TTL, a 200k-token stale context costs full input tokens on every turn — no cache benefit, model attention degrading over noise, and Anthropic serving more compute for negative product value. The economic incentive and the UX incentive point the same direction; only the safety argument cuts the other way.

Option A's AC "user initiates the flow (not automatic)" already preserves the human-in-the-loop boundary — the auth gate is "user explicitly invoked the skill," same trust model as any other skill the user invokes. Would unlock orchestration setups without weakening the safety story.

arielperez82 · 3 months ago

I've been dealing with this same problem manually. I have my own /context:handoff command that does this before I run /clear, then paste in the the handoff to resume from. How can I upvote this 1M times?!?!?

drewmccormack · 3 months ago

+1 — hit this today building a /safe-clear skill (memory-save pass before clearing, so save-worthy learnings don't get wiped). Skill works fine for the save pass, but the final step has to be "type /clear yourself" — which both breaks the flow and means a distracted user will forget and lose the save guard.

For this use case, Option C (/clear --run <prompt-or-file>) isn't quite enough on its own — the trigger needs to come from the model after it finishes the save pass, not from the user typing the command upfront. Option A (ClearContext tool) fits cleanly: the skill calls ClearContext as its last step, optionally with a continuation prompt summarizing what was saved.

A weaker variant that would also work: a tool-side signal (e.g. a return field, or a dedicated RequestClear tool) that asks the harness to prompt the user with "Clear context now? (y/N)" — keeps the human in the loop while still ending the flow at the right moment, no manual typing.

junaidtitan · 3 months ago

This is exactly what Cozempic's treat and reload commands do — cozempic treat prunes the session context (18 strategies from gentle to aggressive), and cozempic reload does a clean context reset with the pruned session. The guard daemon also does this automatically at configurable thresholds. Works as a plugin with skills you can invoke mid-session. pip install cozempic — hooks auto-wire on first run. https://github.com/Ruya-AI/cozempic — would love feedback on whether it covers your use case.

junaidtitan · 3 months ago

This is exactly the workflow Cozempic's treat and reload commands solve — programmatic context pruning with session continuity. cozempic treat runs 18 strategies on the session JSONL (tool-result-age, thinking-blocks, image-strip, stale-reads, etc.), and cozempic reload --session <id> is an escape hatch that reloads a pruned session cleanly. It's also available as a Claude Code plugin with MCP tools. pip install cozempic — repo: https://github.com/Ruya-AI/cozempic. Would be curious if this covers your use case.

yacb2 · 3 months ago

For the operator-driven version of this primitive, I built https://github.com/yacb2/claude-session-handoff. A /handoff slash command — or natural-language phrases like "start a new session", "continue in a fresh session" picked up by a skill — closes the current claude process and opens a fresh one, with the continuation prompt injected via the SessionStart hook (additionalContext for the model, systemMessage banner for the user). It's a wrapper, not a programmatic tool/skill primitive — the operator triggers it, not the model from inside a skill body. Covers the user-driven case while the in-product primitive doesn't exist; does not enable a skill to clear-and-continue autonomously, which is the actual ask here.

arielperez82 · 3 months ago

I've built the following and it seems to be working as expected. Will run a few more tests across different sessions and machines to make sure before I publish it but basically, it's built on the following primitives:

The hook that triggers handoff (PreToolUse)

  • A context:handoff skill runs when Claude detects context pressure
  • It captures the necessary context for a session to restart from pointing to the appropriate existing artifacts and issue trackers
  • It writes a special block in its final message, wrapped in ---HANDOFF-RESTART--- / ---END-RESTART--- markers
  • That text block contains the instructions for the next session, telling it to load context from

The hook that detects it (Stop hook)

  • handoff-detect-stop is registered as a Stop hook
  • When Claude finishes a response and the session stops, this hook fires
  • It reads the last_assistant_message from the Stop event payload, looks for the marker block, and extracts the content between them
  • If found, it writes that content to $CLAUDE_HANDOFF_FILE (a temp file path set by claude-loop)
  • It also sends SIGTERM to its parent PID ($PPID) if CLAUDE_LOOP_HOOK_KILL_PPID=1 — this is the sync kill to skip polling lag

How claude-loop orchestrates this

  • claude-loop is a wrapper that runs in a while(true) loop
  • Each iteration: spawn a claude process, set CLAUDE_HANDOFF_FILE + CLAUDE_LOOP_HOOK_KILL_PPID=1 in the env before launch
  • Two watchers run in parallel with the session:
  • Hook mode (your setup): polls the sidecar file every N seconds; when it appears with content, kills the claude process via its PID file
  • Buffer-scrape mode (fallback): polls terminal/logfile output, scans for the end marker directly
  • After claude exits, it reads the sidecar file to get the handoff prompt
  • If the prompt is non-empty → pause → relaunch claude with the handoff content injected as a new --prompt arg (the new session starts fresh with the handoff as its first message)
  • If empty → the loop exits normally

TL;DR sequence:

  1. Claude writes handoff block with markers → Stop hook fires → hook extracts block → writes to temp sidecar file → kills itself
  2. claude-loop's watcher sees the sidecar file → kills the claude process (if not already dead)
  3. claude-loop reads the sidecar, sees a non-empty prompt → spawns a new fresh claude session with that prompt as the opening instruction
marksalpeter · 2 months ago

+1 for allowing tools to clear context. Would be ideal to /loop /clear /my-skill. Any skill of the take next variety (eg, take the next gh issue, pr comment, linear ticket, etc) could set up a ralph auto pilot natively.

This would be a huge improvement over relying on external bash scripts, which are still required to manage loops like this.

github-actions[bot] · 1 month ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

Showing cached comments. Read the full discussion on GitHub ↗