{"_id":"@burneikis/pi-sticky","name":"@burneikis/pi-sticky","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@burneikis/pi-sticky","version":"1.0.0","description":"Keeps the chat input and footer pinned to the bottom of the terminal while you scroll — works alongside pi-vim, pi-status, and any other extensions","type":"module","license":"MIT","author":{"name":"burneikis"},"repository":{"type":"git","url":"git+https://github.com/burneikis/pi-sticky.git"},"keywords":["pi-package"],"pi":{"extensions":["./index.ts"]},"scripts":{"test":"tsx --test tests/*.test.ts"},"peerDependencies":{"@mariozechner/pi-coding-agent":"*","@mariozechner/pi-tui":"*"},"devDependencies":{"tsx":"^4.21.0"},"gitHead":"808c5ce4c644a072480bb97bdf1646f8b71211e9","_id":"@burneikis/pi-sticky@1.0.0","bugs":{"url":"https://github.com/burneikis/pi-sticky/issues"},"homepage":"https://github.com/burneikis/pi-sticky#readme","_nodeVersion":"22.22.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-Lu0rsvKr4xw6yutKwsBeEKr4cRx3asdqTWbcIfIjLwKbvFAiXbyaAonT7gtLaWjQ8pjaoOO5N8wyqKHTpeIYHA==","shasum":"8424a24acaaaf6784fb18c23ac65e1187b311f32","tarball":"https://registry.npmjs.org/@burneikis/pi-sticky/-/pi-sticky-1.0.0.tgz","fileCount":7,"unpackedSize":58252,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCoBAYhpZmtCmoaihCt8GVGtcCtHBfxw0x+83bELnwlNwIhAIYQECibN6IgAMdxNS7tYzqWagtmAzLLuvbOKJM6Vv7y"}]},"_npmUser":{"name":"burneikis","email":"alexburneikis@gmail.com"},"directories":{},"maintainers":[{"name":"burneikis","email":"alexburneikis@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-sticky_1.0.0_1778794795610_0.038955447004059174"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-14T21:39:55.538Z","1.0.0":"2026-05-14T21:39:55.975Z","modified":"2026-05-14T21:39:56.162Z"},"maintainers":[{"name":"burneikis","email":"alexburneikis@gmail.com"}],"description":"Keeps the chat input and footer pinned to the bottom of the terminal while you scroll — works alongside pi-vim, pi-status, and any other extensions","homepage":"https://github.com/burneikis/pi-sticky#readme","keywords":["pi-package"],"repository":{"type":"git","url":"git+https://github.com/burneikis/pi-sticky.git"},"author":{"name":"burneikis"},"bugs":{"url":"https://github.com/burneikis/pi-sticky/issues"},"license":"MIT","readme":"# pi-sticky\n\n> **Fully vibe-coded.** Might break. Works for me.\n\nKeeps the chat input and footer pinned to the bottom of the terminal while you scroll through chat history.\n\nWorks alongside your other extensions — it does not replace the editor or footer, it pins whatever is already registered.\n\n## What it does\n\nUses a terminal scroll-region technique (vendored from `pi-powerline-footer`) to split the terminal into two zones:\n\n- **Scrollable zone** — chat history\n- **Pinned zone** — status indicator, editor (e.g. from pi-vim), widgets, footer (e.g. from pi-status)\n\nMouse scroll and `super+up` / `super+down` (or Page Up / Page Down) move through chat history without the input area disappearing.\n\n## Installation\n\n```\npi install https://github.com/burneikis/pi-sticky\n```\n\nThen add to your `~/.pi/agent/settings.json`:\n\n```json\n{\n  \"extensions\": [\n    \"~/.pi/agent/extensions/pi-sticky\",\n    \"~/.pi/agent/extensions/pi-vim\",\n    \"~/.pi/agent/extensions/pi-status\"\n  ]\n}\n```\n\n### Load order is required\n\n**pi-sticky must be listed first.** It wraps `ctx.ui.setEditorComponent` and `ctx.ui.setFooter` before other extensions call them. If pi-vim or pi-status loads first, their registrations will not be intercepted and the sticky behavior will not work.\n\n## Compatibility\n\n| Extension | Works? | Notes |\n|---|---|---|\n| pi-vim | Yes | Editor is pinned as-is, vim modes fully preserved |\n| pi-status | Yes | Footer is pinned at the very bottom |\n| pi-powerline-footer | No | Both extensions patch the same terminal primitives; use one or the other |\n| Any `setWidget` extension | Yes | Widgets above/below editor are pinned alongside the editor |\n\n## Configuration\n\nNo configuration required. The extension works with sensible defaults:\n\n- Mouse scroll enabled\n- Keyboard scroll: `super+up` / `super+down`, `PageUp` / `PageDown`, `ctrl+shift+up` / `ctrl+shift+down`\n- Mouse text selection and copy-to-clipboard on release\n\n## Credits\n\nThe `fixed-editor/` directory is vendored from [pi-powerline-footer](https://github.com/nicobailon/pi-powerline-footer) by Nico Bailon (MIT licensed).\n\n## How it works (technical)\n\nAll extensions registered in the same session share a single `ctx` object (the extension runner creates it once and passes it to every `session_start` handler). pi-sticky uses this to intercept `ctx.ui.setEditorComponent` and `ctx.ui.setFooter` in its own `session_start` before other extensions run theirs.\n\nThe interception wraps each factory to capture:\n- The `tui` reference (the TUI instance, from the factory's first argument)\n- The editor renderable (the object returned by the editor factory)\n\nCompositor installation is deferred via `setTimeout(0)` so it runs after **all** extensions' `session_start` handlers complete. This ensures the footer (registered by pi-status) is already in `tui.children` when the compositor searches for it positionally.\n\nThe pinned layout from top to bottom:\n\n```\nstatusContainer     (loading / thinking animation)\nwidgetContainerAbove (extensions using setWidget \"aboveEditor\")\neditorContainer     (the chat input)\nwidgetContainerBelow (extensions using setWidget \"belowEditor\")\nfooter              (pi-status or built-in footer)\n```\n\nThese elements are hidden from the scrollable TUI render and re-rendered explicitly in the pinned cluster on every frame.\n","readmeFilename":"README.md","_rev":"1-aae9c1cc0dd9ead658e9c50dbef78577"}