# What Is `navigate_tree` for In-Session Branches in Pi Web?

> Discover how navigate_tree in Pi Web switches in-session branches, updating the server leaf pointer for read-only navigation without rewriting session files. Explore conversation trees efficiently.

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

---

**The `navigate_tree` command switches the active in-session branch by updating the server-side leaf pointer without rewriting the session file, enabling read-only navigation within the existing conversation tree.**

The `navigate_tree` command is a core mechanism in the [agegr/pi-web](https://github.com/agegr/pi-web) repository that controls how users move between different conversation branches during an active **AgentSession**. When you interact with the Branch Navigator or click **Continue** in the UI, this command tells the server exactly which entry in the current session file should be displayed.

## How `navigate_tree` Controls In-Session Navigation

According to the architecture documented in [`AGENTS.md`](https://github.com/agegr/pi-web/blob/main/AGENTS.md), **in-session branches** (or tree branches) represent different paths within a single `.jsonl` session file. The `navigate_tree` command serves as the internal signaling mechanism that changes which branch is currently active in the UI.

Unlike a **fork** operation, which creates an entirely new session file, `navigate_tree` performs a read-only operation. It simply moves the cursor to a different leaf node while preserving the original parent/child relationships stored on disk. This distinction is critical for understanding the session lifecycle: navigation explores existing history, while forking creates new persistent branches.

## Client-Side Implementation: Dispatching the Command

On the client, the `navigate_tree` command is dispatched through the hook responsible for agent session communication. When a user selects a leaf in the Branch Navigator, the UI captures the target entry ID and sends it to the server.

```ts
// hooks/useAgentSession.ts – triggering branch navigation
const leafId = entryId; // ID of the target message entry

sendAgentCommand(sessionId, { 
  type: "navigate_tree", 
  targetId: leafId 
})
  .catch(() => {});

```

This `sendAgentCommand` function transmits the command object to the server-side RPC manager, initiating the branch switch.

## Server-Side Handling in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts)

The server receives the command in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts), where a command dispatcher handles the `navigate_tree` case. The implementation extracts the `targetId`, updates the session's current leaf pointer, and returns the refreshed state to the client.

```ts
// lib/rpc-manager.ts – command dispatch logic
case "navigate_tree": {
  const { targetId } = cmd;
  
  // Update the AgentSession’s current leaf to the requested entry
  session.setCurrentLeaf(targetId);
  
  // Return the updated session state to the client
  return { 
    type: "session_state", 
    state: session.getState() 
  };
}

```

The **`session.setCurrentLeaf()`** method performs the actual pointer update. Because this only modifies the in-memory session state and not the underlying `.jsonl` file, the operation is lightweight and immediate.

## `navigate_tree` vs. Forking: Understanding the Difference

It is essential to distinguish `navigate_tree` from session forking:

- **`navigate_tree`**: Changes the active view within the **same session file**. No new files are created; the operation only affects which messages are rendered in the UI.
- **Forking**: Creates a **new `.jsonl` file** with its own session ID, generating a distinct conversation branch that persists independently of the original session.

As implemented in `agegr/pi-web`, `navigate_tree` keeps you within the original conversation tree, allowing you to explore alternative response paths that already exist, while forking is used to spawn new, divergent conversation lines.

## Summary

- **`navigate_tree`** is the internal command that switches the active in-session branch without persisting changes to disk.
- The server-side implementation in **[`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts)** uses `session.setCurrentLeaf(targetId)` to update the current pointer.
- Client-side code in **[`hooks/useAgentSession.ts`](https://github.com/agegr/pi-web/blob/main/hooks/useAgentSession.ts)** dispatches the command via `sendAgentCommand()` when users interact with the Branch Navigator.
- This mechanism is **read-only** and distinct from forking, which creates new `.jsonl` session files.
- The command enables efficient exploration of existing conversation trees by updating only the in-memory view state.

## Frequently Asked Questions

### What happens to the session file when `navigate_tree` is called?

Nothing is written to disk. The `navigate_tree` command only updates the in-memory pointer via `session.setCurrentLeaf()`, making it a read-only operation that affects only what is displayed in the UI.

### How does `navigate_tree` differ from creating a new branch?

`navigate_tree` navigates existing branches within the current `.jsonl` file, while forking creates a brand new session file with a unique ID. Navigation preserves the original session history; forking spawns an independent conversation line.

### Where is the `navigate_tree` command handled on the server?

The command is handled in **[`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts)** within the command dispatcher switch statement. This file receives the `targetId`, updates the `AgentSession` state, and returns the updated session object to the client.

### Can `navigate_tree` create new conversation branches?

No, `navigate_tree` cannot create new branches. It only allows navigation to existing leaf nodes that are already present in the session tree. Creating new branches requires different commands that modify the session structure or initiate a fork operation.