# pi-btw-cc

[![npm](https://img.shields.io/npm/v/pi-btw-cc?color=8abeb7)](https://www.npmjs.com/package/pi-btw-cc)
[![CI](https://github.com/Nouvelle-Lune/pi-btw-cc/actions/workflows/ci.yml/badge.svg)](https://github.com/Nouvelle-Lune/pi-btw-cc/actions/workflows/ci.yml)
[![license](https://img.shields.io/npm/l/pi-btw-cc)](LICENSE)

`/btw` side questions for [pi](https://pi.dev): ask about the work in progress without derailing it. The answer lands in a floating overlay instead of the main conversation, and only reaches it if you promote it with `f`.

```
/btw what does the retry wrapper do on a 429?
```

<img src="docs/btw-overlay.png" alt="The /btw overlay showing a side question, its answer, the side thread and the key hints" width="880">

## Install

```bash
pi install npm:pi-btw-cc
pi install git:github.com/Nouvelle-Lune/pi-btw-cc   # or from GitHub
```

Needs Node >= 22.19 and pi 0.85.x.

## Usage

| Command | |
| --- | --- |
| `/btw <question>` | Ask a side question — opens the overlay and starts the request right away |
| `/btw` | Reopen the overlay on the existing side thread (no model call) |

| Key | |
| --- | --- |
| `↑` `↓` | Scroll the answer |
| `⇧←` `⇧→` | Browse the side thread |
| `e` | Expand or fold a long side question |
| `c` | Copy the selected answer |
| `f` | Promote the selected exchange into the main conversation |
| `x` | Delete the selected side question |
| `Esc` `Enter` | Close |

The selected exchange is the one expanded in the body and the one `⇧←/⇧→`, `e`, `c`, `f` and `x` act on. The thread list under it marks the selection with `❯`, and the footer shows the position as `2/3`.

A question that wraps to more than three rows is folded to its first line plus a `… N more lines (e to show)` marker, so it does not push the answer — or the spinner while the request runs — out of the body. `e` unfolds the selected question; opening the overlay again starts folded.

<img src="docs/btw-browse.png" alt="Browsing to an older side question: the thread list marks the selection and the footer shows 1/3" width="880">

`f` adds the selected exchange to the main conversation, and the main agent answers it on its next turn:

<img src="docs/btw-promote.png" alt="The promoted exchange in the main transcript" width="880">

## Notes

- A side request sees the session's conversation (compaction-aware) but has **no tools**: it answers from context only, in one response, and cannot read files or run commands.
- Side questions stay in the session, so the thread continues across restarts, `/reload`, `/resume` and `/tree` branches.
- Promotion only appends, so the main conversation's cached prompt prefix stays valid. While a side request is still running, `f` waits instead of aborting it.
- Side requests don't share the main conversation's prompt cache, so their input tokens are billed in full.
- On narrow terminals the key hints wrap onto more rows and the answer area shrinks to keep them visible.
- Depending on the fold, a state change reveals what changed: a folded question keeps the top of the exchange in view, an unfolded one scrolls to the answer (or to the error) below the question. On a terminal too short to show both, the answer or status row wins over the question top.

## Development

```bash
npm install
npm run typecheck
npm test
npm run docs:images   # regenerate docs/*.svg + docs/*.png (needs rsvg-convert)
```

## License

MIT
