@timmyjl12/pi-btw

Session-persistent isolated BTW chat with a split overlay and tabbed settings

Packages

Package details

extension

Install @timmyjl12/pi-btw from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@timmyjl12/pi-btw
Package
@timmyjl12/pi-btw
Version
0.2.0
Published
Nov 8, 2026
Downloads
265/mo · 17/wk
Author
timmyjl12
License
MIT
Types
extension
Size
82.4 KB
Dependencies
0 dependencies · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ]
}

Security note

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

README

@timmyjl12/pi-btw

An isolated, multi-turn BTW chat for Pi 1.0.1+. A split overlay puts this session's side-conversation history on the left, the current chat on the right, and Threads · Settings · Help in a keyboard-driven tab track.

The main agent keeps running. BTW has no tools and never automatically sends a message to the main agent.

Install / safe cutover

This replaces, rather than runs alongside, another /btw extension. In particular, disable @narumitw/pi-btw in your Pi package configuration before enabling this one. Installation does not migrate upstream memory-only threads, change global settings, or uninstall anything.

pi install npm:@timmyjl12/pi-btw
/reload

For an isolated trial, use a fresh PI_CODING_AGENT_DIR, configure a test model, and load just this extension:

$env:PI_CODING_AGENT_DIR = "C:\temp\pi-btw-trial"
pi -e npm:@timmyjl12/pi-btw

Run the trial in a separate terminal; do not overwrite your normal agent directory. Remove the temporary environment override when done. Non-TUI RPC/JSON/print invocation reports that interactive mode is required, without making a model call.

Usage

  • /btw opens or refocuses the workspace and resumes the selected thread.
  • /btw question… starts a new contextual thread and submits the first question.
  • Ctrl+Shift+B opens BTW from the main editor.
  • Alt+/ moves focus between the overlay and main editor. The overlay remains visible; the main editor and agent are usable underneath it. /btw refocuses the existing overlay, not a second instance.

Each contextual thread freezes a one-time bounded excerpt of the active main branch's user/assistant text. Later main activity does not update it. Create a new thread to capture newer context, or a contextless tangent to start fresh. This is Q&A, not a cloned coding agent: no tools, file access, tool results, images, system prompt, or private thinking are inherited.

Each send inherits the main model and thinking level at that moment. In-flight requests keep their original selection. Errors and cancelled partial answers remain visible; retries are manual. Empty final replies are retryable errors, not completed answers; they never enter completed follow-up context or last-answer handoff. A nonempty token-truncated reply remains completed with a visible warning. A busy send leaves the draft intact instead of creating hidden queued requests.

Reading, copying and export

Long answers are read through a sticky viewport: Alt+↑/Alt+↓ (or Shift+↑/Shift+↓) move one rendered line, the mouse wheel moves by its reported line count, and PgUp/PgDn move a page with a two-line overlap so no line is skipped. When the conversation is longer than the pane, the overlay shows how many lines sit above and below the window and draws a thumb in the pane separator. Scrolling away from the newest line keeps the reader's place while an answer keeps streaming; Ctrl+End returns to the end.

Alt+C opens a copy selector over the composer: Last answer (raw Markdown of the most recent completed reply), Whole thread, Visible lines (exactly the transcript lines on screen), and All threads (newest first). ←/→ or ↑/↓ chooses, Enter copies through Pi's clipboard service and Esc cancels. Copied text is stripped of terminal styling/control sequences and capped at 72,000 characters without splitting an emoji or CJK character (a retained thread still copies in full). In SSH/Mosh sessions (SSH_CONNECTION, SSH_CLIENT, MOSH_CONNECTION or PI_CLIPBOARD_OSC52), a payload over 75,000 UTF-8 bytes is trimmed to that byte budget before the write, because Pi's OSC 52 path otherwise skips it silently; native desktop clipboards keep the character-capped text. If a copy is nonetheless rejected for exceeding the OSC 52 limit, the overlay retries once with a trimmed prefix. Both trims are disclosed in the notice, and any other clipboard failure leaves the overlay open — Ctrl+B/Ctrl+Shift+B remain the path that stages text in the main editor.

Alt+M exports the selected thread to a Markdown file under .pi/btw/ in the project (<title-slug>-<YYYYMMDD-HHMMSS>.md), switches to the Threads tab and reports the relative path. The document has the title, export time, context kind, exchange count, and each question/answer with its status and model; a pending answer is exported with the text streamed so far. The frozen main-branch excerpt is not included. Existing files are never overwritten — a same-second export gets -2, -3, and so on — and the file is created with owner-only permissions on POSIX. Ctrl+R remains retry.

Claude bridge compatibility

With pi-claude-bridge, BTW uses the bridge's isolated, tool-less, nonpersistent call path (cacheRetention: "none"), not the main agent's captured prompt/session. Follow-ups carry the same bounded completed BTW history as reference data in BTW's own prompt; failed/cancelled answers are not replayed. No main system prompt, tools, skills, or live history are inherited.

This path was checked against bridge 0.9.3. It disables provider prompt caching and may deliver text only when the answer finishes; repeated follow-ups can cost more. Other providers retain their normal message replay and cache policy. Local BTW history still persists in the parent Pi session as described below.

Keyboard

Key Action
Tab / Shift+Tab Threads / Settings / Help
Enter Send; select thread; accept inline action; cycle preference
Shift+Enter Newline (native Pi editor bindings also apply)
Alt+H Toggle history/composer focus (also reaches history on narrow terminals)
Up / Down in history Select thread
Ctrl+N / Ctrl+T New contextual thread / contextless tangent
Ctrl+F Search thread titles
Ctrl+E Rename selected thread
Ctrl+D Archive with inline confirmation; no session-file deletion
Ctrl+R Retry most recent failed/cancelled question
Alt+↑ / Alt+↓ (or Shift+↑ / Shift+↓) Scroll the conversation one rendered line
PgUp / PgDn Scroll one page with a two-line overlap
Mouse wheel Scroll the conversation (Pi fullscreen mode)
Ctrl+Home / Ctrl+End Beginning / end of conversation
Alt+C Copy: last answer, whole thread, visible lines or all threads
Alt+M Export the selected thread as Markdown to .pi/btw/
Ctrl+B / Ctrl+Shift+B Stage last completed answer / retained transcript in main editor
Alt+/ Switch focus to main editor; use again to return
Esc Cancel active request; close when idle; cancel inline actions
Ctrl+C Close immediately and cancel work

Handoff closes the overlay and stages a draft, preserving any existing main draft. Review before sending. It does not automatically inject, summarize, or start a main turn.

Settings are session-local: Markdown, timestamps, and initial focus. There is no independent model picker or global settings file. Narrow terminals switch to one pane, with history still keyboard-accessible; extremely small terminals show a clipped compact view and retain close/cancel controls. In compact widths Alt+C shows the selected copy target as Copy 2/4: Whole thread so every target stays reachable without horizontal room.

History and privacy

Threads, frozen context excerpts, questions, answers and preferences persist as versioned custom entries in the parent Pi session JSONL. They survive reload/resume and remain browseable across branches of that session. They do not participate in Pi's main LLM context. Forking into a different session only carries entries Pi copies to that session.

Host persistence caveat: Pi defers writing a brand-new session until it contains a main user/assistant message. BTW-only activity before your first main prompt stays in memory; the overlay warns about this. --no-session sessions are also memory-only. Once Pi saves the parent conversation, it includes the earlier BTW custom entries. This extension does not force a save by injecting fake main messages or editing JSONL files.

Custom entries still advance the session leaf and are present in session files/backups/exports. Treat BTW content as sensitive session data, not a private ephemeral channel. Archiving adds a tombstone; it does not erase previous records. Rollback is disabling this extension and re-enabling your previous /btw owner; no session data needs deleting. Unknown future-version or malformed records are ignored. Interrupted pending turns recover as cancelled and can be retried. A failed save keeps the result in memory with an explicit warning; that unsaved result may be lost on close/restart.

Resource / lifecycle safeguards

  • Registration-only entrypoint; UI/model modules load on first open. No eager history scan, filesystem settings, process, watcher or timer.
  • One history array copy per open, cooperative reconstruction every 250 entries; never scan session files or rebuild history from render.
  • Up to 50 recently created threads materialized; oldest entries remain on disk. Up to 40 exchanges and 64,000 text characters retained per thread. A limit notice discloses windowing.
  • Frozen branch text: 12,000 characters, at most 500 entries / 60 text blocks inspected. Follow-ups include at most 20 completed exchanges within 24,000 text characters plus the frozen excerpt/current question.
  • Question: 8,000 characters. Answer: 32,000 characters. Requested output ceiling: 4,096 tokens, or 32,768 when the model supports reasoning and inherited thinking is enabled, capped to a positive model maximum. Token-based Pi adapters may add their own thinking allowance (up to 16,384 by default in Pi 1.0.1), also under the model cap. Higher thinking may cost more; the extension inherits the thinking level, not custom main-session token budgets. Unknown/zero model limits use the bounded extension ceiling.
  • One model request at a time; independent cancellation; a 120-second deadline; streaming repaints coalesced at 80 ms; settled-turn rendering is reused until layout/view/theme or turn content changes. No main-agent abort/idle wait, network auto-retry loop, terminal mouse capture or alternate-screen patching. The overlay handles normalized wheel events when Pi forwards them but never enables mouse reporting itself, so terminal selection keeps working in regular mode.
  • Clipboard writes go through Pi's public copyToClipboard helper (native helper first, platform commands, then OSC 52 for remote/headless sessions). Copied payloads are capped at 72,000 characters and stripped of ANSI/control sequences, and a byte cut never splits a UTF-8 code point. Remote sessions trim a payload over 75,000 UTF-8 bytes up front (Pi's OSC 52 path can skip an oversized copy silently after a native write), and any other OSC 52 size rejection gets one automatic byte-bounded retry; both disclose the trim. Native desktop clipboards keep the full character-capped text. The overlay is not blocked by a slow clipboard: the write resolves into a notice, and a failure never closes it or drops the draft.
  • Markdown export is explicit (Alt+M), never automatic. One file is written per invocation below <cwd>/.pi/btw/, only the selected thread's conversation is included (never the frozen main-branch excerpt), existing files are never overwritten, and the path is shown in the overlay. A failed write (read-only checkout, invalid .pi) is reported as a notice and leaves the draft and thread untouched.
  • Close, tree navigation, reload, shutdown and session replacement abort work and suppress late writes/repaints. A process-wide worker budget, preserved across extension reloads, blocks additional calls if a custom provider ignores abort, rather than accumulating abandoned requests. The host/provider owns network teardown; this extension cannot forcibly terminate an uncooperative provider.

Bounds prevent extension-owned state/request/render growth; they are not a guarantee about all Pi/providers/terminals.

Development

npm install
npm run check
npm pack --dry-run

Pi loads TypeScript directly; there is no build/bundle step. Tests use Node's built-in runner. The runtime imports only Pi host peers and Node standard library. See CHANGELOG.md for release notes.

Inspiration

Informed by narumiruna/pi-btw, dbachelder/pi-btw, rpiv-btw, pi-better-btw-plus, and the overlay/tab grammar of @timmyjl12/pi-model-picker. This implementation deliberately stays tool-less and uses public Pi APIs rather than copying their coding-agent/terminal ownership internals.