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

> Understand the key differences between Fork and Continue (in-session branch) in pi-web. Learn how each method manages session files and history for independent workflows.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: deep-dive
- Published: 2026-08-18

---

**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`](https://github.com/agegr/pi-web/blob/main/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`

```typescript
// 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`](https://github.com/agegr/pi-web/blob/main/rpc-manager.ts) (lines 85-92) forwards this to `AgentSession.navigateTree`, which updates the `leafId` pointer:

```typescript
// 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`](https://github.com/agegr/pi-web/blob/main/rpc-manager.ts) | `AgentSession.navigateTree` |

## UI Implementation Details

The interface wires these differently:

**Fork button** — [`components/MessageView.tsx`](https://github.com/agegr/pi-web/blob/main/components/MessageView.tsx) (lines 249-258):

```tsx
// 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`](https://github.com/agegr/pi-web/blob/main/hooks/useAgentSession.ts) (lines 1443-1455):

```tsx
// 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`](https://github.com/agegr/pi-web/blob/main/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`](https://github.com/agegr/pi-web/blob/main/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.