pi-fast-tree

extensionmaintained

Fast session tree navigator for pi — slim in-memory projection instead of walking full message payloads

by — · v0.1.2 · published 5d ago

$ pi install npm:pi-fast-tree
downloads/mo
477
stars
1
last push
5d ago
open issues
0

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

507 downloads · last 12 weeks (weekly)

README

⚡ pi-fast-tree

Instant session-tree navigator for Pi

Same /tree. Same keys. A slim projection so fat sessions don't freeze the picker.

pi-fast-tree: a session tree lighting up from a slim scan while the full-payload blob stays dark

npm version checks pi extension license

Built-in /tree freezes on fat sessions because the picker keeps every SessionEntry — tool arguments, images, whole assistant bodies — on the nodes it flattens, filters, and searches. pi-fast-tree hijacks /tree and paints from a slim projection: ids, topology, a 200-character preview, and a precomputed search haystack.

Selecting a node still calls Pi's navigateTree. Branch summarization, leaf movement, and the transcript rebuild are unchanged.

Why this is not pi-fast-resume

pi-fast-resumepi-fast-tree
Command/resume/tree
Datathousands of JSONL filesone already-loaded session
Winskip bytes on diskskip work on in-memory payloads
First paintstream top-N file headersproject the id/parentId skeleton once

Partial JSONL reads do not help /tree. The current session is already parsed. The freeze is CPU: getTree() copies every entry, flattenTree() stashes every toolCall including arguments, and extractContent does extractFullContent(content).slice(0, 200) on every node, every search keystroke.

Install

pi install npm:pi-fast-tree
Other install methods

From GitHub:

pi install git:github.com/monotykamary/pi-fast-tree

From a local checkout:

bun install
pi install /absolute/path/to/pi-fast-tree

Then /reload.

Hijack mode is on by default — /tree, double-escape, and app.session.tree open the fast navigator.

Usage

/tree                 Open fast navigator (hijack mode)
/fast-tree            Open fast navigator (only when hijackTree is false)

Picker controls

Identical to built-in /tree:

KeyAction
↑ / ↓Navigate visible entries
← / →Page up/down
Ctrl+← / Ctrl+→ or Alt+← / Alt+→Fold/unfold or jump between branch segments
Shift+LSet or clear a label
Shift+TToggle label timestamps
Ctrl+XCopy the selected message
EnterJump to that point
EscapeCancel (clears search first)
Ctrl+OCycle filter mode
typingFilter by precomputed preview + label + role

Filter modes: default, no-tools, user-only, labeled-only, and all. Default comes from treeFilterMode in settings.

Config

All options go in ~/.pi/agent/extensions/pi-fast-tree.json:

KeyTypeDefaultDescription
hijackTreebooleantrueWhen true, /tree and app.session.tree open the fast navigator. Set false to keep built-in /tree and register /fast-tree as a separate command.
shortcutstring(none)Standalone keybinding for the fast navigator. Works regardless of hijackTree. Example: "ctrl+shift+t".
{
  "hijackTree": false,
  "shortcut": "ctrl+shift+t"
}

Reload with /reload after changing config.

How hijack works

On load, the extension patches InteractiveMode.prototype.showTreeSelector. Built-in /tree returns early inside interactive onSubmit before extension commands run, so this is the same approach as pi-fast-resume. On session_shutdown the prototype is restored. If showTreeSelector is missing, it falls back to the original.

Known limitations

AreaBuilt-in /treepi-fast-treeImpact
Search depthMatches against extracted message text (still capped at 200 after a full concat)Matches the capped preview + label + role computed onceA token that only appears after the first 200 characters of a message will not match.
Unknown tool argsJSON.stringify(args).slice(0, 40)Same 40-char snippet, but only from shallow scalars (nested objects become ...)Custom tool rows still show [name: {…}]. Megabyte nested payloads are not stringified.
Abort-during-summaryRe-opens /tree on summarization abortCancelled navigateTree notifies and returnsEscape-during-summary uses pi's navigation result; the picker does not auto-reopen on abort.

Copy (Ctrl+X) reads the full selected entry via sessionManager.getEntry, so it is not capped.

Development

bun install
bun run check        # typecheck + vitest + knip

License

MIT.