# pi-fancy-editor

A [pi](https://github.com/earendil-works/pi) coding agent extension that replaces
the input editor with a compact **status-border editor** and matching footer.
It uses the active pi theme only — no bundled theme, no custom color tokens, no
separate theme setup. Because apparently one editor border can still need a
package. Naturally.

## Install

Install from npm:

```sh
pi install npm:@furbyhaxx/pi-fancy-editor
```

Install from GitHub:

```sh
pi install git:https://github.com/furbyhaxx/pi-fancy-editor
```

Or clone the repo and install from the local checkout:

```sh
git clone https://github.com/furbyhaxx/pi-fancy-editor
pi install path/to/cloned/repo
```

Or load directly without installing:

```sh
pi -e path/to/cloned/repo/extensions/fancy-editor/index.ts
```

## What it changes

- Top editor border shows working state and context usage.
- Bottom editor border shows the active role when another extension publishes one, plus the active model and thinking level.
- Bash input (`!command`) switches the border to pi's `bashMode` theme color and
  labels the editor as `Shell Exec`.
- Footer shows cwd, optional git branch, optional pie environment, session title,
  and extension statuses.
- Narrow terminals automatically collapse cwd/session placement.
- Multi-line paste handling keeps pasted newlines inside the editor instead of
  accidentally submitting half a paste. Revolutionary stuff.
- Submitted prompts, slash commands, and bash commands are persisted per cwd so
  arrow-up still has something useful after restarting pi.

## Compatibility notes

Pi exposes the editor and footer as singleton replacement surfaces. This
extension owns both when enabled, so it is intentionally mutually exclusive with
other extensions that also call `ctx.ui.setEditorComponent()` or
`ctx.ui.setFooter()`. Extensions that use commands, input events, statuses,
widgets, or `ctx.ui.setEditorText()` keep working with the fancy editor.

## Role integration

`pi-fancy-editor` can show the active role in the bottom editor border when
another extension publishes it over pi's shared event bus.

Event name:

```text
pi-agent-roles:active-role
```

Payload shape:

```ts
{
  name: string;
  label: string;
  color?: string; // pi theme token or #rrggbb
}
```

Send `null` to clear the role display.

When the fancy editor is enabled it also emits this readiness signal so
`pi-agent-roles` can suppress its fallback widget instead of duplicating the
role label below the editor:

```text
pi-fancy-editor:role-display-ready
```

Payload:

```ts
true | false
```

This is intended for integration with `pi-agent-roles`, but any extension can
emit the same event if it wants to drive the role segment.

## Wireframe

Wide terminal:

```text
╭────────────────────────────────────────────────────────────────────────────╮
│ chat output                                                                │
╰────────────────────────────────────────────────────────────────────────────╯
─ ⠋ Working.. ───────────────────────────── ctx ▪▪▪▪▫▫▫▫▫▫ 43% (34.2K/80K) ─
> refactor the auth module and run tests
─ Reviewer ─ anthropic/claude-sonnet-4-5:medium ─────────────────────────────
~/work/example (main) · env:auto                                  ✎ auth cleanup
```

Narrow terminal:

```text
─ ⠋ ───────────── ▪▪▫▫▫ 43% (34.2K/80K) ─
> fix the flaky test
─ Reviewer ─ claude-sonnet-4-5:medium ───
~/w/example (main) · env:auto
✎ auth cleanup
```

Bash mode:

```text
─ Shell Exec ─────────────────────────────── ctx ▪▫▫▫▫▫▫▫▫▫ 8% (6.1K/80K) ─
> !cargo test
─────────────────────────────────────────────────────────────────────────────
```

## Configuration

Configuration lives in pi's regular `settings.json` files:

- Global: `${PI_CODING_AGENT_DIR:-~/.pi/agent}/settings.json`
- Project: `.pi/settings.json`

The extension deep-merges both scopes the same way pi does: project settings win
over global settings. `PI_CODING_AGENT_DIR` is respected for the global file.

Minimal default configuration:

```json
{
  "editorPaddingX": 0,
  "fancyEditor": {
    "enabled": true,
    "workingMessage": "Working..",
    "contextBar": {
      "width": 10,
      "normalColor": "success",
      "normalPercent": 50,
      "warningColor": "warning",
      "warningPercent": 75,
      "criticalColor": "error",
      "criticalPercent": 95,
      "prefix": "ctx"
    },
    "showSessionId": false,
    "footer": {
      "enabled": true,
      "showCwd": true,
      "showGitBranch": true,
      "showSessionName": true,
      "sessionNameOwnLine": true,
      "showEnvironment": true,
      "showExtensionStatuses": true
    }
  }
}
```

### Options

| Setting | Default | Description |
|---|---:|---|
| `editorPaddingX` | `0` | Native pi editor padding setting, reused by this editor. |
| `fancyEditor.enabled` | `true` | Enable or disable the editor replacement. |
| `fancyEditor.workingMessage` | `"Working.."` | Text shown while pi is streaming on wide terminals. |
| `fancyEditor.contextBar.width` | `10` | Width of the context usage bar (`1`-`30`). |
| `fancyEditor.contextBar.normalColor` | `"success"` | Color used through `normalPercent`; built-in theme token or `#rrggbb`. |
| `fancyEditor.contextBar.normalPercent` | `50` | Percent where the gradient starts. Below this, `normalColor` is used unchanged. |
| `fancyEditor.contextBar.warningColor` | `"warning"` | Midpoint color for the context gradient; built-in theme token or `#rrggbb`. |
| `fancyEditor.contextBar.warningPercent` | `75` | Percent where the gradient reaches pure warning color. |
| `fancyEditor.contextBar.criticalColor` | `"error"` | Critical color for the context gradient; built-in theme token or `#rrggbb`. |
| `fancyEditor.contextBar.criticalPercent` | `95` | Percent where the gradient reaches pure critical color. |
| `fancyEditor.contextBar.prefix` | `"ctx"` | Prefix shown before the context usage bar on wide terminals. |
| `fancyEditor.showSessionId` | `false` | Add a short session id next to the session title. |
| `fancyEditor.footer.enabled` | `true` | Replace pi's footer with the compact footer. |
| `fancyEditor.footer.showCwd` | `true` | Show current cwd in the footer. |
| `fancyEditor.footer.showGitBranch` | `true` | Append the current git branch to cwd. |
| `fancyEditor.footer.showSessionName` | `true` | Show the current session title in the footer. |
| `fancyEditor.footer.sessionNameOwnLine` | `true` | Put the session title on its own first footer line, above cwd. |
| `fancyEditor.footer.showEnvironment` | `true` | Show `env:<name>` in the footer when pie environment metadata is available. |
| `fancyEditor.footer.showExtensionStatuses` | `true` | Include statuses published by extensions via `ctx.ui.setStatus()`. |

The extension uses built-in pi theme tokens such as `success`, `warning`,
`error`, `muted`, `dim`, `text`, `borderMuted`, and `bashMode`; context bar
colors may also be hex colors. Change the active pi theme with pi's normal
`theme` setting or `/settings`; this editor follows it.

The context bar color stays at `normalColor` through `normalPercent`, then is
generated in 5% increments from `normalColor` → `warningColor` →
`criticalColor`. The same gradient is applied to filled bar segments, the
percent value, and the currently used token count.

## Build and test

Pi loads the TypeScript source directly through its extension loader; no emitted
build artifacts are required.

```sh
npm install
npm test
```

## License

MIT
