omp packages

pi-copy-message4.0.0

Pi extension with a searchable TUI picker for copying raw session messages

fitchmultz Published 18 days ago MIT ~784 downloads/mo

Untested on omp

This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi copy-message extension

A pi extension that adds /copy-message: a keyboard-first picker for copying raw session message text without terminal wrapping, padding, or rendered TUI artifacts. It also adds /copy-user as a direct shortcut for the most recent user message.

pi-copy-message supersedes pi-copy-user-message, which only copied the most recent user message.

What it does

  • Adds /copy-message
  • Adds /copy-user for copying the most recent user message directly
  • Copies raw stored session message text, not rendered terminal lines
  • Shows messages in chat order: oldest at top, newest at bottom
  • Selects the newest visible message by default
  • Supports role filters for user, assistant, tool/bash, and custom messages
  • Hides tool/bash messages by default
  • Supports type-to-filter search across role and message text, with time:<term> for timestamp search
  • Supports Home/End jumps for oldest/newest visible messages
  • Uses Pi's configured selection bindings for navigation, copy, and cancel
  • Keeps Pi's platform clipboard writes and OSC 52 fallback, but reports success only after local text readback
  • Includes fast paths: /copy-message latest, /copy-message last, and /copy-message newest, using Pi's canonical active context
  • Supports direct numbered copies like /copy-message 3
  • Supports metadata copies with --with-meta, --with-metadata, or --with-role

Install

Install it from npm with pi:

pi install npm:pi-copy-message

Or install it directly from GitHub with pi:

pi install https://github.com/fitchmultz/pi-copy-message

Use /reload after updating extension code on current official Pi and the maintained fork. Restart Pi after changing dependencies or the host runtime.

If you prefer to load it directly from a local checkout during development:

pi -e ./extensions/copy-message.ts

Usage

Open the picker:

/copy-message

Copy the most recent user message directly:

/copy-user

Copy the latest visible default message directly:

/copy-message latest

Aliases:

/copy-message last
/copy-message newest

Copy the 3rd default-visible message directly, matching the picker's 1-based oldest-to-newest numbering:

/copy-message 3

Copy with role and timestamp metadata instead of raw text only:

/copy-message latest --with-meta
/copy-message 3 --with-role
/copy-user --with-meta

Keyboard controls

Key Action
Configured tui.select.up (default: ↑) Move to older visible message
Configured tui.select.down (default: ↓) Move to newer visible message
Configured tui.select.pageUp / tui.select.pageDown (default: PageUp / PageDown) Move by one visible page in regular mode
Ctrl+PageUp / Ctrl+PageDown Move by one visible page in fullscreen mode
Home / End Jump to oldest/newest visible message in regular mode
Ctrl+Home / Ctrl+End Jump to oldest/newest visible message in fullscreen mode
Type or paste text Filter visible messages; pasted line breaks and tabs become spaces
time:<term> Search timestamps
Backspace Delete one search character
Ctrl+U Toggle user messages
Ctrl+A Toggle assistant messages
Ctrl+T Toggle tool/bash messages
Alt+C Toggle custom messages
Tab Toggle a wrapped preview of the selected message
Alt+M Toggle raw vs metadata copy format
Configured tui.select.confirm (default: Enter) Copy selected message text
Configured tui.select.cancel (default: Esc/Ctrl+C) Cancel

Behavior notes

  • Entry IDs are hidden from the picker.
  • Mouse wheel navigates; clicking a message copies it and returns keyboard focus to the unchanged draft.
  • Session replacement, tree navigation, shutdown and reload cancel pending pickers without stale-context notifications.
  • The picker caps visible rows and scrolls instead of filling the screen.
  • Search preserves your original selected message and restores it when the search is cleared.
  • General search does not match timestamps; use time:<term> when you want to search by displayed time.
  • Picker previews and copy notifications remove terminal control characters; the copied text stays raw.
  • Filter labels honor the active pi theme.
  • Selection key hints show the active Pi bindings. Configured selection actions take precedence if they collide with the picker's filter, preview, or format shortcuts.
  • Only custom messages with display: true can appear or be copied from current custom_message entries or legacy message-wrapped entries; visible ones can be toggled with Alt+C.
  • A verified local copy notification includes the role and a short preview. Unavailable, empty or mismatched readback warns instead of claiming success; rejected writes report an error. Remote terminal delivery via OSC 52 cannot be verified, even when the remote machine's local clipboard matches.
  • Native clipboard reads are preferred where available. Bounded platform readers preserve exact text, including newlines; the extension never replaces Pi's working write fallback chain.
  • latest uses Pi's canonical session projection, honoring context edits, omissions and compaction. Numbered selectors, the picker and /copy-user retain raw active-branch history, including older pre-compaction messages.
  • /copy-message latest and numbered selectors include user, assistant, and visible custom messages by default while hiding tool/bash messages. Alt+C only affects the picker. If only hidden messages exist, latest falls back to the newest message so the command still does something useful.
  • /copy-message with no direct selector requires interactive TUI mode because the picker is a custom TUI component.
  • Direct commands such as /copy-user, /copy-message latest, and /copy-message 3 do not require TUI mode, though non-UI modes may not display notifications.

Compatibility

  • Requires Pi 1.0.0 or later. Development and standalone/packed qualification use the official 1.0.0 cohort; a maintained fork must be qualified at its actual supported revision, not by version-string equivalence.
  • The picker coalesces legacy in-progress assistant snapshots within their context-window boundaries so each response appears once. Current official Pi and the maintained fork no longer write those legacy boundaries.
  • Android/Termux clipboard writes use Pi's normal fallback chain, including OSC 52 when native clipboard commands are unavailable.
  • Pi includes Ctrl+X for copying the latest assistant response; this extension remains useful for searchable history, other roles, metadata, and direct selectors.
  • Node.js >=24.15.0. .nvmrc pins Node 24.21.0 for local development.

This package keeps pi core packages as wildcard peers (*) per pi package guidance. Pi aliases these imports to its own bundled copies when loading the extension, so the package never bundles or shadows pi core. Local development uses @earendil-works/pi-coding-agent and @earendil-works/pi-tui as dev dependencies for typechecking and tests.

Development

npm ci
npm run check # node --test + tsc --noEmit + pack dry-run

No production build or prepare is required. Tests run TypeScript directly with Node's type stripping, so source must stay erasable (erasableSyntaxOnly). Qualification uses the selected host installed in this checkout's dependency graph. The tests cover formatting, native command execution, canonical context and branch selection, both TUI modes, pointer focus and pending-picker disposal. Native addon interception and an isolated command PATH keep test clipboard writes in temporary fixture files, never the operator clipboard. Actual Android/Termux, Windows/WSL and remote terminal delivery still require platform qualification.

package-lock.json must only reference registry.npmjs.org; a test fails on private-registry URLs. Behind a registry proxy that rewrites tarball URLs, refresh the lock from public metadata and install through the proxy:

npm install --package-lock-only --ignore-scripts --registry=https://registry.npmjs.org/
npm ci

Key files:

  • extensions/copy-message.ts — publishable extension implementation
  • tests/copy-message.test.ts — regression tests for command wiring, filtering, search, navigation, and copy formatting