@luan.sh/pi-side

Independent side conversations for Pi

Packages

Package details

extension

Install @luan.sh/pi-side from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@luan.sh/pi-side
Package
@luan.sh/pi-side
Version
0.3.3
Published
Sep 12, 2026
Downloads
not available
Author
cfcluan
License
MIT
Types
extension
Size
25.6 MB
Dependencies
2 dependencies · 3 peers
Pi manifest JSON
{
  "image": "https://pi.luan.sh/media/previews/pi-side-8c1a712df319.png",
  "video": "https://pi.luan.sh/media/previews/pi-side-21f6936fdecf.mp4",
  "extensions": [
    "./src/extension.ts",
    "./node_modules/@luan.sh/pi-libtui/src/extension.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@luan.sh/pi-side  

@luan.sh/pi-side opens independent, interactive Pi sessions next to the one you are working in. Each side chat is a real child pi process running in a PTY. It starts with a copy of the parent session's model-visible history, followed by a hidden boundary message that tells the model the inherited history is reference only. Use it to ask questions or explore without disturbing the main thread.

It is a Pi extension, not a model-facing tool. It registers one command (/side), one action (panels.chat.new), and a side-panel provider.

Preview

Independent side conversation beside the main Pi session.

@luan.sh/pi-side in Bootty

Watch the demo.

Install

pi install npm:@luan.sh/pi-side

The package requires Pi's interactive TUI. In print or non-UI mode the /side command reports that side chat is unavailable.

Optional companion: pi install npm:@luan.sh/pi-panels hosts each side chat as a tab in a side panel; without it, side chats open in a fullscreen overlay instead (see below).

Native binary: terminal-bridge

Side chats are driven by the native terminal-bridge binary. Requires a Rust toolchain (https://rustup.rs). The terminal-bridge binary builds itself on first use under Pi's agent directory (native/terminal-bridge/<version>/). Set PI_TERMINAL_BRIDGE_BINARY to use a prebuilt binary.

Use it

Input Effect
/side Start a new side chat
/side <prompt> Start a new side chat and send <prompt> as its first message
/side close Close the active side-chat tab (side-panel host only)
action panels.chat.new Same as /side with no prompt

Every side chat is new. The command never resumes an existing chat by name. Each child gets a fresh UUID session id and a label of the form Side N, where N increments for the life of the parent session.

The child runs pi --tui-mode fullscreen with the parent's current model and thinking level, and a theme variation derived from the parent's theme so the two surfaces are distinguishable. The environment variable PI_EMBEDDED_SIDE_CHAT=1 is set on the child process.

Child sessions are stored in side-chats/<uuid>/ under the parent's session directory, together with the generated theme file side-chat-<uuid>.json. When the parent runs without a session file (--no-session), they go under @luan.sh/pi-side/<parent-session-id>/ in the OS temporary directory instead.

Inherited history

When a side chat is created, every entry of the parent's current branch that contributes to the model context is copied into the child session, followed by a hidden custom message (pi-side-boundary). The boundary tells the model that everything before it is reference context, that it should answer questions and do lightweight non-mutating exploration, that sub-agents are off-limits, and that it must not modify files or state unless the user explicitly asks after the boundary. The child session records the parent session file as its parent.

With and without @luan.sh/pi-panels

The package registers a side-panel provider. When a side-panel host is present, each chat appears as a tab labelled Side N with a 󱐒 icon, and the panel's empty state gains a "Side chat" action. Restored tabs are added without starting their child processes until they are shown.

When no host is present, the same PTY pane opens in a fullscreen overlay instead. Only one restored chat can be shown this way: on session start the newest persisted chat is reopened in the overlay. Multiple simultaneous restored chats need the tabbed panel. /side close has no effect in overlay mode; leave the overlay or exit the child pi instead.

Lifecycle

Open chats are recorded as a custom session entry (side-chat:tabs-v1) in the parent session, so they survive /reload and session restore. On /reload the live child processes are handed to the reloaded extension intact, including any unsent editor text. Switching session or quitting Pi terminates the children. A child exiting on its own removes its tab.

Settings

The package declares no settings. It reads model, thinking level, theme, and session location from the parent Pi context.

Keybindings

The panels.chat.new action has no default key. To bind one, add it to keybindings.json in Pi's agent directory (normally ~/.pi/agent/keybindings.json). Each property name is an action ID and each value is a key ID string or an array of them:

{
  "panels.chat.new": "ctrl+shift+n"
}

Key IDs are a base key optionally preceded by ctrl, shift, alt, or super, joined with +. The file is read on load, so reload extensions after editing. Bindings only take effect when a shortcut host is installed (pi install npm:@luan.sh/pi-xsettings provides one). /side works without any binding.

Layout

Responsibility File
/side command, panels.chat.new action, side-panel provider, session hooks src/extension.ts
Child session creation, inherited history, boundary message, pi command line src/session.ts
PTY processes, panel tabs, overlay fallback, close and dispose src/manager.ts
Persisted tab state (side-chat:tabs-v1) and validation src/state.ts
Handing live PTYs across extension reload src/process-registry.ts
Public exports (createSideChatCommand, prepareSideChatSession, latestSideChatState, ...) src/index.ts

Develop

Source: https://github.com/luan/agents, directory harnesses/pi/agent/packages/pi-side. Run bun run typecheck and bun test test in that directory.