Skip to content

Resume, fork, and reset a Pi session

Yesterday you were three files deep into stash’s readability extractor, chasing why it mangles certain sites, when you had to stop. Pi didn’t lose any of that - every session is a plain JSONL file on disk under ~/.pi/agent/sessions/, organized by project, one entry per turn, tool call, and model switch. Nothing about it is hidden from you; you’re just not looking at it yet. Reopening yesterday is a matter of pointing Pi at the right file instead of re-explaining what you already worked out.

From the shell, the fast path is pi --continue - continue the most recent session for the directory you’re standing in:

Terminal window
cd stash
pi --continue

That’s the one you’ll reach for most mornings. When the most recent session isn’t the one you want - you did a quick README tidy after the extractor work, and the latest thread is that, not the bug - open the session picker instead and reach past it. From inside a running session, /resume does this (check pi --help for the shell-level equivalent in your version):

> /resume
Select a session:
stash · README tidy yesterday 19:05
❯ stash · extractor mangles some sites yesterday 16:40
stash · feed-date CSV fix 6 days ago

That last entry is real - the picker reaches back across every session Pi has ever run in this repo, not just the last one.

Once you’re back in, ask directly instead of assuming:

> where did we leave the extractor bug?
You'd traced it to two sites specifically: one strips article text down to
a single sentence because the readability heuristic picks the wrong <div>,
the other keeps the nav bar because it lacks the semantic markup the
heuristic depends on. You hadn't picked a fix yet.

That’s not Pi re-deriving anything - it’s reading the restored conversation straight back to you. The investigation you closed yesterday stays closed.

Today’s actual work is a different bug: stash’s full-text search misses accented characters, so searching “café” doesn’t find an article that mentions “café.” There are two legitimate fixes, and you can’t tell which is better without trying it:

  1. Normalize incoming text at write time - strip diacritics before it ever reaches the search index.
  2. Reconfigure the FTS5 virtual table’s tokenizer to ignore diacritics itself, and rebuild the index.

Betting on one before you’ve seen either in practice would be guessing. Instead, fork the session at the point where you asked about the bug, so both attempts start from the same understanding without polluting each other:

/fork

/fork branches a new session from any earlier message in the current thread - you pick the point, Pi copies everything up to it into a fresh session file, and the original thread keeps existing untouched. Run it once from “where you asked about the accent bug,” try the tokenizer approach in the new branch, then /fork again from the same point for the normalize-at-write approach in a second branch. Now you have two live attempts, each with the full context of the bug report and neither one contaminated by the other’s dead ends.

This is the same command doing two different jobs, and it’s worth naming both:

  • Explore two options that share a starting point. That’s what you just did - fork twice from the same message, run both approaches, and compare real results instead of arguing about it in the abstract.
  • Undo a wrong turn. If Pi goes deep into a bad approach - say it spends ten turns rewriting the tokenizer config in a way that breaks unrelated queries - you don’t have to re-prompt through the whole mistake to undo it. Fork from the message right before the agent went sideways, and continue from there instead. The bad branch isn’t deleted; it’s still sitting on disk if you ever want to see what went wrong. It’s just not the thread you’re continuing in.

To see the branches you’ve made, use /tree (or double-Esc) - it visualizes the whole session as a tree, so you can find the fork point again, rename a branch, or jump between the two accent-fix attempts without losing your place.

You try the tokenizer reconfiguration first, and it works - unicode61 remove_diacritics=2 on the FTS5 table, plus a one-time reindex. You keep that branch, and the normalize-at-write branch sits unused in the tree; you don’t need to delete it, it’s just not where you’re working.

Resuming is cheap enough that it’s tempting to reach for it out of habit - drag yesterday’s extractor investigation into a task that has nothing to do with it, just because the session is right there. That’s not continuity, that’s clutter: Pi will happily keep talking about the extractor while you’re actually trying to add a new tag-filter to the CLI, and the accumulated context does you no favors.

When the next thing genuinely doesn’t follow from the last one, start clean instead - check pi --help or /help for the exact fresh-session command in your installed version; we’ll call it /new here:

/new

That clears to a blank session - no accent-bug history, no extractor trace, nothing to accidentally carry forward. The rule of thumb: resume or fork when you’re continuing something, start clean when you’re not. Getting this wrong in either direction costs you - dragging in unrelated history muddies a fresh task, and starting clean when you were continuing throws away context you’ll just have to rebuild by hand.

That judgment is easier to feel than to memorize, so here it is playing out - a session with its context window x-rayed beside the terminal, pausing at exactly this fork. The command names are generic; in Pi, read “clear” as starting a fresh session, and the compact branch as a preview of what the next lesson does about a full window:

One session, played back with its context window x-rayed. Watch what the work costs on the right; when the playback pauses, you decide what the session does next - then replay the other choices.

0k / 200k
Fixed overheadRulesConversationFile readsTool outputSummaries
agent session - billing-app
agent cli · new session · repo: billing-app
the window, x-rayed

    Every number is an illustrative order of magnitude, and the commands answer to different names across tools - /compact, /compress, or /summarize; /clear, /new, or a fresh chat. The trade is the same everywhere: a reset is coming, and choosing its moment - and what survives it - is yours to keep.

    You’ve got the accent-search fix landed by forking instead of gambling, and a habit for picking up tomorrow morning without losing today’s decisions. But the next piece of stash work - rewriting the extractor properly - is going to run long enough to fill the window outright. Next: what happens when the thread runs out of room.