pi-prompt-enhance

Pi extension: rewrite a sloppy draft prompt into a sharper one using the current conversation as context, ask you the choices it refuses to guess as multiple-choice dialogs, and put the result back in the editor.

Packages

Package details

extension

Install pi-prompt-enhance from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-prompt-enhance
Package
pi-prompt-enhance
Version
0.2.0
Published
Nov 5, 2026
Downloads
373/mo · 373/wk
Author
zeroicey
License
MIT
Types
extension
Size
23.8 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./src/extension.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-prompt-enhance

A Pi extension that rewrites the draft you are about to send into a sharper prompt — fixing dictation typos, dropping filler, tightening the structure — using the conversation you are already in as context, and then puts the result back in the editor. Nothing is sent for you.

git clone https://github.com/zeroicey/pi-prompt-enhance ~/src/pi-prompt-enhance
pi install ~/src/pi-prompt-enhance

Then /reload, or restart Pi.


Why

Voice input is fast and lossy: homophone errors, half-finished clauses, "那个就是那个", and a request that only covers the part you happened to think of. Sending that as-is makes the model guess, and you end up correcting it three turns later.

The usual fix — opening a second chat to "写得好一点" — fails for the obvious reason: that chat has no idea what you have been talking about.

So the enhancer runs inside the current session: same model, same context, one extra completion, result returned to your editor.

Usage

Entry How What it enhances
Shortcut ctrl+shift+e or alt+e whatever is in the editor
Command /enhance <draft> the argument

Both end in ctx.ui.setEditorText(result): you read it, edit it if you want, then press enter. esc during the spinner cancels and leaves the draft untouched.

Two bindings because some terminals and tmux configurations swallow ctrl+shift+… combinations; alt+e is the fallback that almost always lands.

One limitation worth knowing: a slash command consumes the editor line you typed it on, so /enhance cannot read a multi-line draft you already wrote — the draft has to be its argument, on one line. The shortcut path is the one that reads the real editor content, which is why it is the primary entry point.

Asking instead of guessing

When the rewrite depends on a choice only you can make, the enhancer does not make it for you. It returns up to three questions and they are asked as real dialogs — pick with ↑↓/enter, or take the ✏️ 自己输入… row and type your own answer (multi-line, enter to submit).

 部署方式:这个 komari 容器是用哪种方式跑起来的?
 → Docker Compose 编排启动
   docker run 单容器启动
   由 systemd 单元管理的容器
   ✏️ 自己输入…

 ↑↓ navigate  enter select  escape/ctrl+c cancel
  • A ★ prefix marks the option the enhancer would have picked.
  • Multi-select questions re-open after each pick and show ✓ 选完了(已选 N).
  • esc stops the queue and keeps whatever you already answered — and esc on the very first question means "ask nothing", so there is always a fast path.
  • The answers are folded into the prompt as a trailing 【已确认的取舍】 block, then the whole thing lands in the editor. Questions are never injected as guesses, and nothing is sent.

No dialogs available (RPC/print mode)? The questions are appended to the prompt as 【待确认】 text with their options, so a headless run loses nothing.

How it works

ctrl+shift+e / alt+e            /enhance <draft>
        │                       │
        └──────────┬────────────┘
                   ▼
   transcript = current branch messages
   (text only: tool results and thinking are skipped,
    head dropped past 24k chars)
                   ▼
   one completion · ctx.model (the model you are already using)
   system: rewrite rules + JSON contract
   user:   <对话上下文/> + <待增强的提示词/>
                   ▼
   parse { prompt, questions }
       │ malformed / plain text → whole reply is the prompt, no questions
       ▼
   questions? → ask them (select + free text) → fold answers in
                   ▼
            setEditorText → you review, then send

No new session, no subagent, no tool access: a single request whose context is a plain-text transcript of the current branch.

The rewrite rules

Encoded in SYSTEM_PROMPT (src/prompt.ts), and deliberately conservative:

  1. Keep the meaning and the language. No invented requirements, no invented constraints, no picking a tech stack for you.
  2. Fix typos and terminology — especially homophones from dictation — and normalise technical casing (hpcore, Debian, Docker, Postgres).
  3. Drop filler (那个, 就是, 反正), merge fragments, reorder into logic; add structure (goal / constraints / acceptance) only from information you actually provided.
  4. Ask instead of guessing. When a rewrite would require a subjective call, the enhancer emits a multiple-choice question instead of picking — up to three, each with 2–5 concrete, mutually exclusive options. It must not ask about anything you already said.
  5. Stay close in length — at most 1.5× the original. No preamble, no commentary, no code fence.
  6. Output one JSON object: { prompt, questions }. Nothing else.

Rule 4 is the interesting one: an enhancer that silently fills gaps is worse than no enhancer, because you accept its invention and then have to debug it. Asking costs one keystroke; a wrong guess costs a whole turn.

Tuning

Knob Where Default Effect
MAX_CONTEXT_CHARS src/prompt.ts 24_000 how much history is handed to the enhancer; raise it if it "forgets" earlier decisions
SYSTEM_PROMPT src/prompt.ts see above the rewrite contract
MAX_QUESTIONS / MAX_OPTIONS src/prompt.ts 3 / 8 caps applied when sanitising the model's reply
SHORTCUTS src/extension.ts ctrl+shift+e, alt+e bindings are literal key strings here, not keybindings.json entries

Dev

bun install
bun test          # 28 unit tests over the pure logic
bun run typecheck # tsc --noEmit, strict

src/prompt.ts is runtime-free (no Pi imports) so it is testable in isolation; src/extension.ts is the thin Pi-facing layer.

License

MIT