proper-base
Baseline Pi behavior for session naming, history, prompt editing, fullscreen navigation, and footer styling
Package details
Install proper-base from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:proper-base- Package
proper-base- Version
0.8.0- Published
- Oct 5, 2026
- Downloads
- 852/mo · 55/wk
- Author
- sharafn
- License
- MIT
- Types
- extension
- Size
- 382.3 KB
- Dependencies
- 1 dependency · 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
proper-base
Baseline Pi behavior for quieter transcripts, automatic
session titles, model-preserving /clear, project prompt history, prompt
editing, fullscreen navigation, image handling, cancellation, autocomplete,
footer layout, context-window and Fast-mode control, commit message checks,
proactive subagent delegation, and deferred automatic updates.
User-facing features
Sessions and transcript
- Completed tools and errors collapse into separate one-line rows once later
output appears, or when the run settles. In fullscreen mode, click a row to
expand it and its
collapsecontrol to close it. Pi's tool-output shortcut, Ctrl+O by default, expands or collapses every row, and every row returns to collapsed when a run settles. Thoughts, tool-calling text, direct replies, and agent status updates remain fully visible and in their original order. - A fresh unnamed session gets a hidden 3 to 7 word title from the first successful assistant response. Existing, resumed, and already-named sessions keep their names.
/clearstarts an empty session but preserves the current provider, model, thinking level, session Fast setting, and session context window. Global Fast and the global context window stay unchanged. No messages, name, or branch state carry over.- The model you pick with
/modelor Ctrl+P and the level you pick with/thinking, Shift+Tab, or/model <model> <level>become Pi's startup defaults, so the next session opens on them. Pi otherwise saves those only when you press Ctrl+S in the picker, and because Pi re-derives the thinking level from the saved default on every model switch, an unsaved level is otherwise lost mid-session at the next/modelor Ctrl+P. Automatic model-switch clamps do not redefine that choice, and the router'sllm-router/autoplaceholder persists neither itself nor its forcedoff. Resuming a session does not redefine the model. Set"stickyDefaults": falsein~/.pi/agent/proper-base.jsonto turn this off. - Prompt-template expansions remain model-facing, while the transcript shows
the slash command you typed, such as
/implement-ready epic-1 4. /resumebuilds its session list from a raw byte scan of each session file instead of parsing every message, then loads message text in the background. Search matches session names, IDs, and working directories at once, and message text as it arrives.- CLIProxyAPI
empty_streamfailures andSelected model is at capacityoverload errors become normal retryable network errors, so Pi applies its existing retry budget and backoff. /tokens maxraises an OpenAI model's context window from its 272K default to the backend's 922K input cap for this session, throughopenai-codex, CLIProxyAPI, or theopenaiAPI./tokens defaultreturns to the default. Appendglobalto set it for every session (saved ascontextTokensin~/.pi/agent/proper-base.json); a session choice overrides the global one. Bare/tokensshows the current window. Tab onmaxordefaultopens the scope menu, whereglobalis one arrow away. Auto-compaction then triggers at the new window minus yourreserveTokens, including per-modelcompaction.modelOverrides. Input above 272K bills at the long-context rate.
Fast mode
With the CLIProxyAPI provider (@router-for-me/pi-cliproxyapi-provider),
proper-base takes over its /fast command and splits the priority-tier Fast
mode into two scopes:
/fasttoggles Fast for the current session only. proper-base never saves it, so new, resumed, and reloaded sessions start with it off;/clearkeeps it./fast-globaltoggles Fast for every session by saving the provider'sfastkey in~/.pi/agent/cliproxyapi.json. Running sessions pick up the change on their next request.
Fast applies when either scope is on, and only to models the provider's
catalog marks as Fast-capable. Turning one scope off tells you when the other
still keeps Fast on, and turning Fast on warns when the current model cannot
use it. While CLIPROXYAPI_FAST is set, /fast-global refuses to change the
saved setting and reports the environment value. The footer shows the fast
tag whenever Fast applies to the current model.
Automatic updates
- Pi's native background checks record available updates. proper-base installs them on the next supported launch, with live progress and safe restart.
- No recorded updates means no additional update checks or inventory at startup.
/settings→ Automatic updates persists enable/disable.--no-auto-updateandPROPER_UPDATER_OFF=1still override it for a launch.- Automatic updating requires npm Pi on Linux/macOS with Node 22.19+; automation and unsupported installations are skipped. No separate package is needed.
See update behavior, safety limits, and migration.
Prompt editing and cancellation
| Input | Behavior |
|---|---|
| Alt+Enter | Insert a newline instead of queuing a follow-up. Pi's own Shift+Enter and Ctrl+J stay intact. |
| Home | Move to the current visible-row start, then the full prompt start. |
| End | Move to the current logical-line end, then the full prompt end. |
| Ctrl+C with text | Clear the prompt without arming exit. |
| Ctrl+C on an empty prompt | Show Press Ctrl+C again to exit; repeat within 500 ms to quit. |
| Esc before assistant work starts | Restore the submitted prompt and remove that turn from the active branch. |
| Esc after assistant work starts | Keep Pi's normal abort behavior. |
Dismissing an ask_user_question dialog with Esc aborts the run instead of
spending another model turn acknowledging the dismissal. Tool or host failures
still reach the model so it can ask in plain text.
Project prompt history
proper-base records eligible editor submissions on a best-effort basis, not transformed Pi session messages. History uses an encoded key derived from the current working directory.
- Up and Down recall prompts from previous sessions in the same project. Up recalls only from an empty prompt; with a draft it only moves the cursor, so Home then Up can no longer replace what you typed.
- Ctrl+R starts case-sensitive reverse substring search. Press Ctrl+R again for an older match, Backspace or Shift+Backspace to broaden the query, Enter to submit, Esc to keep the match for editing, or Ctrl+G to restore the original draft.
- Prompt templates and skills remain in their submitted slash form.
- Built-in and extension UI commands such as
/model,/new, and/llm-router-configare not recallable. - Duplicate prompts keep their newest timestamp. The editor receives at most 200 entries.
History lives under ~/.pi/agent/proper-history/. One private JSONL file is
created per encoded working-directory key. Unusual paths that produce the same
hyphen encoding can share a file. Prompts over 4096 characters are skipped
rather than truncated. Startup reads only the newest 512 KiB; stores above
2 MiB compact to the newest 2000 valid entries. A concurrent append during that
rare compaction can lose one entry. Delete one file to forget one key, or the
directory to forget all proper-base history.
Autocomplete
- The selected autocomplete description appears in a non-capturing bordered panel above the prompt without moving the editor, list, or footer.
- Slash-command completion works after whitespace and on later prompt lines. It replaces only the active slash segment and ignores slashes inside paths and URLs.
- Accepting a slash command completion opens that command's argument menu
right away, such as the model list after
/model. - Word and line deletes (Alt+Backspace, Ctrl+W, Ctrl+U, Ctrl+K) refresh an open menu instead of leaving suggestions for text that no longer exists.
/modelresults sort by displayed model ID in descending numeric-aware order. Typed terms must all match when strict matches exist./modeltakes an optional thinking level after the model name, as in/model anthropic/claude-opus-4 high. Once the model name carries a provider slash, the next word completes against Pi's thinking levels; a word naming no level keeps searching models.- Tab-completing a model name submits nothing. It leaves the name, a trailing space, and an open level menu led by the level already in effect, so you can type a level straight away or press Enter to keep the current one.
- Tab or Enter on a level completion switches immediately: the level is
the last argument, so
/model gp<Tab>lo<Tab>picks the model andlowwithout a further Enter. Either key switches only when the complete prompt is a single-line/model ...command.
Fullscreen navigation and selection
Enable Pi's native fullscreen mode with /settings or:
{
"tuiMode": "fullscreen"
}
Pi keeps the prompt, queued messages, status, and footer pinned while the transcript scrolls above them. Submitting a prompt scrolls the transcript back to the newest output.
| Input | Behavior in fullscreen mode |
|---|---|
| Home, End, PageUp, PageDown | Stay assigned to the prompt editor. |
| Ctrl+Shift+Home or End | Jump the transcript to its top or bottom. |
| Ctrl+Shift+PageUp or PageDown | Scroll the transcript by one page. |
| Mouse wheel | Scroll three lines per notch instead of Pi's one. |
| Double-click | Select a complete one-line URL, path, flag, qualified identifier, or quoted value when possible. |
Set PROPER_WHEEL_SCROLL_LINES to a positive integer to change the wheel step,
for example 1 in a terminal that already sends one report per scrolled line.
Wheel and transcript scroll keys keep working while an ask_user_question
questionnaire or other overlay has focus, so earlier context stays reachable.
Typing or pasting clears a mouse selection, so a stale highlight never sits over changing text. The copy shortcut leaves the selection in place, so it can still be copied.
Copying fullscreen Markdown paragraphs and blockquotes removes display margins, quote borders, and screen-width line breaks. Real newlines, paragraph boundaries, and code indentation stay intact. Works with copy-on-select and Pi's configured copy shortcut. Lists, tables, and unmatched custom output keep native copying.
Scrolling away from current output adds a ↓ jump to bottom row above the
prompt. Clicking it returns to the newest output without disabling scrollbar
dragging.
Extension widgets that Pi would pin above the prompt (for example the pi-subagents async-agents card) render at the end of the transcript instead, so they scroll with the session and shrink as their content does rather than holding rows they no longer need.
The transcript's top-right corner carries muted ↑ and ↓ arrows that walk
the viewport between your own prompts. Clicking ↓ past the last prompt scrolls
to the bottom. While you are scrolled up, a dimmer position/total reading sits
centred under the arrows and counts the prompts in the session; it disappears
once the viewport is following output again.
A column of colored symbols along the transcript's right edge marks each
prompt, reply, and tool call in session order, newest at the bottom. › marks
your prompts, ‹ replies, and × failures. Tools show / for search, ≡
for reads, ± for edits, + for writes, $ for shell commands, @ for web
requests, & for agents, and · for anything else. Click a symbol to scroll
to that action. The action the viewport sits in shows in inverse video. At
rest the rail is faint and gives way to transcript text in its column, and
hovering it brings it to full strength with each action's name. Under a
terminal multiplexer, where Pi receives no hover events, it stays fully lit.
Pi 0.85.0 moves the prompt cursor to wherever you click in the prompt. If you
click the prompt area to focus the terminal or to select text, turn off
Prompt mouse clicks in /settings: clicks on the prompt text then leave the
cursor alone while drag-to-select keeps working. The same menu holds the
Session action rail toggle. Both persist in ~/.pi/agent/proper-base.json
as editorMouse and sessionRail.
Clipboard and model image context
Ctrl+V and Ctrl+Shift+V both use Pi's image-or-text clipboard action. Readable
clipboard image paths appear as short [image N] markers. Image-capable
terminals render compact previews; text-only terminals show marker source paths.
Source metadata and bytes are read asynchronously; oversized sources become
pixel-bounded PNG thumbnails through sharp instead of blocking the editor or
transmitting the full image for a tiny preview. sharp ships prebuilt macOS arm64/x64 and Linux binaries, so
no external image command is required. Pi's accent braille loader animates while conversion runs; the
marker and path appear only if conversion is unavailable or fails. When terminal
focus returns, active Kitty previews are retransmitted so a lost terminal-side
scene cannot remain blank behind Pi's upload cache. Left and Right treat each
intact [image N] marker as one cursor token. When the cursor lands on it, Pi
inverse-highlights the complete marker; Backspace removes the whole highlighted
token. On submit, each marker expands back to the original path the agent can
read.
Images remain in model context for every tool loop in the turn that introduced them. A later user message replaces older image blocks only in the outbound context copy, so saved sessions, exports, resumes, and branches retain the originals.
Under TERM_PROGRAM=Scribe, proper-base enables Kitty images and OSC 8
hyperlinks before Pi's renderer starts, so previews render and Ctrl+click on
any row of a wrapped link opens the full URL. Other terminals keep Pi's
detected capabilities. Every row of a wrapped link carries the same OSC 8 id,
so terminals that group links by id highlight and open it as one link.
On Linux, proper-base reads clipboard text through wl-paste, xclip, or
xsel, the tools Pi already uses to copy, instead of Pi's native clipboard
addon. That addon leaks two X connections on every read, and a long session
eventually hits the X server's client limit, after which paste silently stops
working. Image paste is unchanged, and macOS and Windows keep the addon.
Skill context
Load several skills before one request:
/skill:security /skill:testing fix the login flow
Only complete /skill:name tokens matching Pi's discovered catalog activate
skills. Matching is exact and case-sensitive; duplicate selections load once.
The first unknown or malformed token starts the literal request, with all
remaining text preserved. URLs, paths, queries, fragments, filename suffixes and
punctuation do not partially match names. Ambiguous, unreadable or malformed
registered selections reject the whole request. Explicit /skill-context load
and model-tool loads still report unknown names.
Use -- after the command chain when the request itself starts with a literal
/skill: example. Inline, quoted, escaped, and fenced mentions are not commands.
Pi autocomplete completes partial input to /skill:name; submitted /name,
$name, /skill name and / skill:name are not Pi skill aliases and remain
untouched. Other registered commands keep their own behavior. Pi's explicit
expansion opt-out remains respected, including RPC and queued prompts.
Each expanded skill appears as a collapsible section in terminal history,
including skills loaded through skill_context. Use Pi's tool-expansion shortcut
or click an individual section in fullscreen mode to view its instructions.
The request stays visible; the model still receives the full skill bodies.
Each selected skill retains a full snapshot and SHA-256 identity. Unchanged instructions appear once in outbound context; repeating a workflow command still submits its new request. Explicit reinvocation or refresh loads the current file and supersedes older instructions. Compaction restores the selected snapshots, never silently rereads changed files, and never replays the original request. Normal task progress determines which workflow steps remain to do.
Manage the working set without starting a model turn:
/skill-context
/skill-context load security testing
/skill-context remove testing
/skill-context refresh security
/skill-context clear
The list shows selected and removed snapshots, their version hashes, source paths, changes on disk, character count, and confirmation threshold. Selections follow the current session branch through resume, forks, context edits, and repeated compaction. New sessions start empty. There is no guessed task expiry: reference instructions apply only where relevant, and removal explicitly ends a selection. Removing a skill omits its instruction blocks from future managed requests without deleting historical user requests or the saved transcript. Conflicts are reported rather than resolved by mention order; loading never grants extra tool permissions.
The model can use skill_context to list or load the smallest relevant set from
Pi's catalog. Explicit-only skills require the user's /skill: invocation.
Ordinary file reads remain available but do not automatically pin every skill
file inspected. Supporting resources load on demand; their files are not
snapshotted or version-pinned by this feature.
Selected instructions above 200,000 characters trigger a confirmation dialog. Continue to keep every skill, or cancel to leave new selections unloaded. Approval is remembered for the unchanged selection during the session, including compaction. Changing the selection or reloading can require another confirmation. There is no hard character cap or model-scaled limit; Pi and provider context limits still apply. This count includes skill markup and separators, not tokens.
Restored selections are checked before reaching the model. Cancelling that check
stops the run; use /skill-context remove <name> or /skill-context clear to
reduce the selection, or retry and confirm. Runs without an interactive or RPC
confirmation UI stop with an explanation. No skill is silently truncated or
dropped.
Skill context management in /settings enables or disables the feature.
The preference is enabled by default and saved as "skillContext" in
~/.pi/agent/proper-base.json. /skill-context on and /skill-context off
provide a fallback when the native menu adapter is unavailable. Changes apply
to the next agent run. Disabled mode restores Pi's normal expansion and context
behavior; it does not erase instructions already delivered. Malformed or
unreadable configuration disables skill management until repaired.
Native menu integration and multi-command expansion use guarded Pi compatibility
adapters. /skill-context load remains available if expansion internals change.
The rest uses public command, tool, context, and session APIs. No new dependencies
or external registry are required.
Commit message guard
proper-base checks each git commit the agent runs through the bash or
quill_execute tool, and blocks the call unless all of these hold:
- The command is one direct
git commitcall. Chains (&&,||,;,|), wrappers such assh -c,env,sudo, ortimeout, variable-assignment prefixes, and dynamic text ($(...), backticks,$VAR) are rejected. - The message comes only from literal
-mor--messagetext.-F,-e,-c,-C,-t,-s,--fixup,--squash,--trailer,--cleanup,--allow-empty-message, and--no-verifyare rejected. - The subject and every body line fit in 72 columns, the second line is blank,
and no line carries a
Co-Authored-By,noreply@anthropic, orGenerated with Claudeattribution. A final block ofKey: valuetrailers may exceed the length limit.
A blocked call lists every problem at once, so the agent can fix the whole
message in one retry. Commands that do not contain both git and commit skip
the check, and a commit command the guard cannot parse is blocked. There is no
setting to turn the guard off.
Proactive delegation
When pi-subagents' subagent tool or its subagents_enable loader is active,
proper-base replaces its rule to delegate only when needed with a proactive
multi-agent mode. The agent hands independent work that is large enough to
justify a fresh context to subagents without waiting to be asked. It keeps sequential steps, small tasks, and edits
to the same area in the main session, and writes the final answer itself. Your
own instructions still take priority.
If the session has scoped models (from --models, enabledModels, or
/scoped-models), the prompt names them as the only models subagents may use
and asks the agent to pick one per task by difficulty and cost. The
llm-router/auto placeholder is left out. Sessions without either tool keep
their system prompt unchanged. Set "proactiveDelegation": false in
~/.pi/agent/proper-base.json to keep pi-subagents' ask-first policy.
Footer
The built-in footer keeps path, branch, cumulative input, output, cache, cost,
context use, model, and thinking effort visible in two compact rows. Stable
colors separate the metrics; context changes color above 70% and 90%.
Supported max and router-provided ultra effort levels use a slow rainbow
highlight. Custom replacement footers are not changed.
Install
Node 22.19 or newer is required. The package is tested against Pi 1.0.1.
From npm:
pi install npm:proper-base
From a local checkout:
pi install /path/to/proper-pi-extensions/proper-base
Pi supplies the core @earendil-works/pi-coding-agent and
@earendil-works/pi-tui peer packages. sharp is a runtime dependency for
image previews. Run npm install for a local checkout; it also prepares the
development checks below. There is no build step or install-time npm script.
This package replaces the former local proper-customs identity. Keep only one
registration. Existing data under the legacy proper-history path remains
compatible.
Configuration
proper-base needs no configuration. Optional settings live in
~/.pi/agent/proper-base.json, and a missing or unreadable file keeps every
default.
| Key | Default | Effect |
|---|---|---|
stickyDefaults |
true |
false stops model and thinking choices from becoming Pi's startup defaults. |
contextTokens |
unset | Global /tokens window, "max" or "default". /tokens <mode> global writes it. |
sessionRail |
true |
Shows the session action rail. Toggle it with Session action rail in /settings. |
editorMouse |
true |
Lets prompt clicks move the cursor. Toggle it with Prompt mouse clicks in /settings. |
proactiveDelegation |
true |
false keeps pi-subagents' ask-first delegation policy. |
The Automatic updates entry in /settings is stored separately, as
described in UPDATES.md.
| Environment variable | Effect |
|---|---|
PROPER_WHEEL_SCROLL_LINES |
Lines per mouse-wheel notch in fullscreen mode. Default 3. |
PROPER_UPDATER_OFF=1 |
Skips automatic updates for one launch, like --no-auto-update. |
CLIPROXYAPI_FAST |
The provider's Fast override. While it is set, /fast-global refuses to write. |
CLIPROXYAPI_PROVIDER_ID |
Provider ID that Fast mode and /tokens treat as CLIProxyAPI. Otherwise providerId from cliproxyapi.json, then cliproxyapi. |
TERM_PROGRAM=Scribe |
Set by the Scribe terminal. Enables Kitty image previews and OSC 8 links. |
Compatibility
Restart Pi once when upgrading from releases with permanent host patches. Those releases did not retain original methods or bindings for restoration. New installations restore owned patches on unload and support reload takeover.
- Fullscreen behavior uses Pi's native
tuiMode: "fullscreen"renderer. - Questionnaire cancellation activates only when
ask_user_questionis installed. - Editor and footer wrappers compose with existing providers when their Pi interfaces are compatible. Private Pi TUI changes or custom renderers may disable individual enhancements; later-loaded replacements still win.
- Ctrl+Shift fullscreen keys require a terminal that reports modifiers distinctly.
- Slash commands beginning with
__proper-are reserved for internal session recovery.
Development
npm install
npm test
npm run typecheck
npm run test:coverage
npm pack --dry-run
npm publish --dry-run
prepack runs tests and strict type checking before a tarball or publish. Tests
use Node's built-in runner. There is no build step.
License
MIT