@nicknisi/pi-pin-last-prompt

Sticky header pinning the owning user prompt while scrolling the transcript

Packages

Package details

extension

Install @nicknisi/pi-pin-last-prompt from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@nicknisi/pi-pin-last-prompt
Package
@nicknisi/pi-pin-last-prompt
Version
0.1.2
Published
Aug 7, 2026
Downloads
443/mo · 443/wk
Author
nicknisi
License
MIT
Types
extension
Size
20.5 KB
Dependencies
0 dependencies · 2 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

@nicknisi/pi-pin-last-prompt

Sticky header that pins the owning user prompt to the top of the screen while scrolling back through the transcript in fullscreen TUI mode. When you scroll up, a full-width bar appears showing the prompt that "owns" the content at the top of the viewport, updating as you scroll across exchanges (sticky-section-header behavior, a la Claude Code). It disappears when you return to the live tail.

What it adds

  • Widget pin-last-prompt — renders nothing itself; exists only as a per-frame hook so the overlay can track scroll state (pi calls widget render() every frame, which is where scroll state is observable).
  • Overlay — a full-width bar anchored top-left at row: 0, col: 0, width: "100%", shown only while scrolled back in fullscreen mode. Rendered with the theme's selectedBg background and an accent-colored \uf007 icon, with the prompt text collapsed to a single line and truncated with .
  • Event hooks: before_agent_start (records the last prompt), session_start (installs the widget), session_shutdown (clears widget and state).

No slash commands, tools, keybindings, or custom entry types.

Requirements

  • pi >= 0.84 — the pinned bar relies on the fullscreen transcript renderer (TuiAltScreen) and its isFollowingOutput / getPrimaryScrollView internals, which only exist in fullscreen mode. In inline mode the extension loads but never shows anything.

Usage

No configuration or interaction. Install it, run pi in fullscreen mode (default), scroll up — the bar appears and tracks which prompt's section you're in.

Example of what the bar renders:

  <prompt text collapsed to one line, truncated to terminal width>…

Configuration

None. No config files, options, or environment variables.

Install

pi install /Users/nicknisi/Developer/pi-extensions/packages/pin-last-prompt

Dependencies

Peer deps (provided by the pi runtime):

  • @earendil-works/pi-coding-agentExtensionAPI, event hooks, ctx.ui.setWidget.
  • @earendil-works/pi-tuiTUI type, OverlayHandle, truncateToWidth, visibleWidth for width-correct padding/truncation.

No npm runtime dependencies, no workspace deps.

Implementation notes

The prompt offsets are computed by walking pi's transcript component tree: it recurses into Container children (pure concatenation of rendered lines) and records the document line offset of each UserMessageComponent leaf. The sticky prompt is the last entry whose start <= scrollTop, clamped to the first entry when scrolled above it. Offsets are cached and invalidated when the transcript width or contentHeight changes (streaming, tool expand/collapse, resize), plus on widget invalidate().

The overlay is nonCapturing so it never intercepts input. Overlay stack mutations are deferred to a microtask because syncTopBar runs inside the render pass; text updates land in the same frame since the overlay composites after the dock renders.

The bar must not linger at the live tail: any live overlay blocks pi's runtime TUI-mode switching, so it is hidden as soon as isFollowingOutput returns to true.

Caveats

  • Leans on pi internals, may break across pi versions. The sticky lookup depends on internal class names (UserMessageComponent, Container) and TUI internals (isFollowingOutput, getPrimaryScrollView, scroll view child/contentHeight/getContentWidth). If a pi update renames or restructures these, the extension degrades gracefully: the bar falls back to showing the last prompt sent this session instead of per-section tracking.
  • Fullscreen only. No effect in inline mode or non-TUI contexts.
  • Single-line prompts. Prompt text is whitespace-collapsed and truncated to the terminal width; multi-line prompts show only what fits on one line.
  • The blank line above the editor is stock pi (a hardcoded Spacer in the widget container, present even with no extensions). This extension neither adds nor removes it — the widget renders zero lines.