Fork vs In-Session Branch (Continue) in pi-web: Key Differences Explained

In pi-web, Fork creates a brand-new .jsonl session file with full history independence, while Continue (in-session branch) keeps the same file and only moves the cursor to a different leaf.

The pi-web conversational AI interface offers two distinct ways to branch from an existing conversation. Understanding when to use each can prevent data duplication and unexpected behavior in your agent sessions. This guide breaks down the architectural differences, implementation details, and practical use cases based on the actual source code.

What Fork Does in pi-web

Fork creates a completely independent session file.

When you click the Fork button on any user message, the UI sends a fork command to the server. In lib/rpc-manager.ts (lines 48-84), this command triggers one of two outcomes:

  • Empty fork: Creates a fresh session linked to the original (used when forking before any messages)
  • History fork: Copies all conversation history up to the selected entry via createBranchedSession
// lib/rpc-manager.ts – fork command handling (L48-L84)
case "fork": {
  const { entryId } = payload;
  // Creates new .jsonl file, either empty or with copied history
  const newSession = await createBranchedSession(sessionId, entryId);
  // Current wrapper shuts down, UI switches to new session
  return { sessionId: newSession.id };
}

The original session remains untouched. You get:

  • A new file at ~/.pi/agent/sessions/[UUID].jsonl
  • A parentSession header pointing to the original
  • Sidebar visualization as a child node under the parent

Use Fork when: you want to preserve the original conversation exactly as-is while exploring a completely different direction with full isolation.

What In-Session Branch (Continue) Does

Continue — also called in-session branch — navigates within the existing file without duplication.

Triggered by the Continue button or BranchNavigator component, this sends a navigate_tree command. The rpc-manager.ts (lines 85-92) forwards this to AgentSession.navigateTree, which updates the leafId pointer:

// lib/rpc-manager.ts – navigate_tree handling (L85-L92)
case "navigate_tree": {
  const { targetId } = payload;
  // Moves cursor within SAME file; no new file created
  await this.inner.navigateTree(targetId);
  return { leafId: targetId };
}

Key characteristics:

  • The same .jsonl file is reused
  • Only the leafId (current message pointer) changes
  • All conversation history remains in one place
  • UI updates to show the selected branch as active

Use Continue when: you want to revisit or extend an earlier point in the same conversation without fragmenting your session history across multiple files.

Fork vs In-Session Branch: Side-by-Side Comparison

Aspect Fork In-Session Branch (Continue)
Command type fork navigate_tree
File outcome New .jsonl created Same file reused
Storage impact Duplicates history (up to fork point) Zero duplication
Original session Unchanged, preserved Continues from new leaf
Sidebar display Child node under parent Same session, different branch
Implementation createBranchedSession in rpc-manager.ts AgentSession.navigateTree

UI Implementation Details

The interface wires these differently:

Fork button — components/MessageView.tsx (lines 249-258):

// components/MessageView.tsx – Fork button rendering
<MessageView
  entryId={entry.id}
  forking={isForking}
  onFork={(entryId) => {
    // Dispatches fork command to rpc-manager
    sendAgentCommand(sessionId, { type: "fork", entryId });
  }}
/>

Continue navigation — hooks/useAgentSession.ts (lines 1443-1455):

// hooks/useAgentSession.ts – Branch navigation
const handleNavigate = (leafId: string) => {
  sendAgentCommand(sessionId, { 
    type: "navigate_tree", 
    targetId: leafId 
  });
};

Architectural Rationale

The AGENTS.md documentation explicitly warns against confusing these two modes under "Two kinds of branching — don't confuse them":

A fork creates a new independent session file, while an in-session branch (navigate_tree) rewrites the view within the same file.

This distinction exists because:

  • Fork enables true parallel experimentation where branches never interfere
  • In-session branch keeps related exploration contained, reducing file sprawl and preserving context

Choose based on whether you need isolation (Fork) or continuity (Continue).

Summary

  • Fork generates an independent .jsonl session file via createBranchedSession — best for divergent experiments requiring full isolation
  • In-session branch (Continue) updates the leafId cursor within the same file via navigate_tree — best for exploring alternatives without fragmentation
  • Both commands route through lib/rpc-manager.ts but invoke fundamentally different session management paths
  • The UI surfaces Fork on individual messages and Continue through the branch navigator

Frequently Asked Questions

Can I convert a Continue branch into a Fork later?

No direct conversion exists in the current pi-web implementation. If you need file independence after using Continue, you must manually Fork from your desired point, which will create the new .jsonl file at that moment.

Does Forking preserve the full conversation history?

Partially. When you Fork at a specific message, pi-web copies history up to that entry point into the new file. Messages after the fork point are not included. This is implemented in createBranchedSession called from rpc-manager.ts.

Will in-session branches affect other users or shared sessions?

In-session branches (navigate_tree) only affect your current session view. Since no new file is created, other concurrent access to the same session file would see the same underlying data — though leafId is typically session-specific.

Which branching method should I use for A/B testing prompts?

Use Fork. Creating independent .jsonl files ensures your prompt variants remain cleanly separated with no risk of cross-contamination, and you can compare results across fully isolated session histories.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →