| name | session-goal-replay |
|---|---|
| description | Replays a prior Claude Code session's turn sequence toward a newly-determined goal by resuming the actual session and live-synthesizing each prompt from the agent's real response. Falls back to a lower-fidelity subagent-based mode when isolation from the live session/environment is required. Use when you have a historical session transcript and want to redirect its procedural pattern toward a different objective than the one it originally pursued. |
Both modes operate in the same running environment (same filesystem, same working directory) — mode choice is about session mechanics, not environment isolation.
Resume mode (default). Drives the actual claude CLI via Bash,
appending real turns to a real session via --resume <session-id>.
Genuine conversational replay: full history and tool state are
restored by the CLI itself, not reconstructed by you.
Subagent mode (opt-in). Dispatches via the Task tool instead of
--resume. Pick this only when you specifically don't want the
retargeted run to create or extend any session JSONL at all — it's a
stateless one-shot dispatch with no session identity, not a lighter or
more isolated version of resume mode. Fidelity is lower by
construction (see caveats below), independent of environment.
- Locate the transcript. Session history is JSONL under
~/.claude/projects/<project-hash>/<session-id>.jsonl. Use Bash +jqto extract the ordered list of user-authored turns (filter out assistant/tool-result entries) along with the targetsession_id. - Extract per-turn intent and goal_span, same as before:
intent: what this turn was trying to get the agent to do, stated goal-agnostically.goal_span: the substring(s) carrying the original objective — these get replaced, never reused verbatim.
- State the new goal explicitly as a standing reference to restate internally at every turn — don't let it rely on surviving implicitly in the resumed context, since the resumed session's own history still contains the original goal framing (that's expected and fine — you're appending new turns pointed at a new goal onto a history that pursued a different one, not erasing the history).
For turn index t = 1..N:
-
Compose the prompt from
historical_turn[t].intent+ the new goal + (if t>1) the agent's actual last response. Write it fresh — the historical turn tells you what this step was for, not what words to send. -
Send it, guarding the resume-dialog trap:
echo "1" | claude -p --resume "$SESSION_ID" "$PROMPT_TEXT" --output-format jsonUse explicit
--resume <id>, not bare--continue— the latter only works on a finished session and is ambiguous if there's more than one candidate. Parsesession_idandresultfrom the JSON output; confirm the returnedsession_idmatches what you sent — silent mismatches mean you've drifted onto a different session. -
Score divergence against
historical_turn[t]'s original response:- Scope match (same kind of work, new goal) → low
- Unprompted branch (clarifying question, error, new consideration) → medium
- Contradiction / dead end / scripted next step no longer makes sense → high
-
Decide next-turn strategy:
- Low → synthesize turn t+1 from
historical_turn[t+1].intentas planned. - Medium → address what the agent just raised first, then fold in
historical_turn[t+1].intentas a secondary beat, still pointed at the new goal. - High → drop the script from here; coordinate freely toward the new goal, using remaining historical intents only as loose pacing reference. Log this as a script exit at turn t.
- Low → synthesize turn t+1 from
-
State/environment drift caveat. Even with true conversational history restored, tool calls (Read/Grep/Bash) inside the resumed session act on current filesystem/git state, not historical state. If files have changed since the original session, expect divergence from that alone, independent of the goal change — don't attribute all divergence to the retargeting.
-
Log every turn: index, divergence score, strategy, composed prompt, response summary, script-exit point if any. This is the only audit trail for reconstructing why the retargeted run ended up where it did.
- Goal leakage. Composing turn t+1 from the agent's actual last response risks re-importing old-goal framing if that response quoted or referenced the original objective. Check composed prompts before sending.
- Over-steering. If every turn scores "high," the original session isn't structurally similar enough to the new goal to be worth replaying at all — say so rather than forcing continued turns.
- Reconstruct a single prompt that inlines the prior turns as plain-text context (since there's no real history to inherit), followed by the new-goal-retargeted instruction for the current step.
- Dispatch via Task tool. Treat the response as a bounded worker result, not a conversational turn — there is no "next turn" to this subagent in the way resume mode has one; each dispatch is independent unless you manually carry forward a growing context string.
- Apply the same divergence scoring as resume mode if you're doing multiple dispatches in sequence, but expect systematically higher divergence rates than resume mode — the subagent has no memory of "being" the agent from the original session, only of the text you handed it.