@estebanforge/pi-tool-display1.3.1
Compact tool call rendering, diff visualization, and output truncation extension for Pi coding agent. Hides, collapses, and truncates verbose tool output for cleaner TUI display. (fork of MasuRii extension)
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.
Reports 0
No reports yet.
Readme
@estebanforge/pi-tool-display
OpenCode-style tool rendering for the Pi coding agent.
Origin: this extension is a fork of pi-tool-display by MasuRii (MIT). Upstream went inactive, so this fork lives on inside the @estebanforge monorepo and is maintained here. All credit for the original design and implementation goes to MasuRii.
pi-tool-display keeps tool calls compact by default, adds richer diff rendering for file edits, and improves a few core chat UI details such as thinking labels and the native user prompt box.
Built-in tool calls render as tidy cards: a one-line header with an icon, tool name, and target, plus a one-line result summary. Cards stay collapsed; Ctrl+O expands one to the full output or diff using Pi's native expansion.
Features
- Tidy tool cards (on by default) for
read,grep,find,ls,bash,edit, andwrite: icon + target header, one-line result summary, collapsed by default, and full output onCtrl+O - Compact built-in tool rendering for
read,grep,find,ls,bash,edit, andwritewhen tidy cards are off - MCP-aware rendering with hidden, summary, and preview modes
- Opt-in custom tool overrides for noisy extension tools, defaulting to generic rendering unless
kind: "mcp"is selected - Adaptive edit/write diffs with split or unified layouts, syntax highlighting, inline emphasis, and narrow-pane width clamping
- Workspace-scoped projected pending edit/write previews that show
pending edit,pending overwrite, andpending creatediffs while partial tool calls are still streaming - Progressive collapsed diff hints that shorten automatically on small terminal widths instead of overflowing
- Hashline-anchor diff gutters that preserve
LINE#HASHlabels from anchored read/edit output when those lines are rendered in diffs - Three presets:
opencode,balanced, andverbose - Thinking labels during streaming and final message rendering, with context sanitization to avoid leaking presentation labels back into future model turns
- Optional native user message box with markdown-aware rendering and safer ANSI/background handling
- Per-tool ownership toggles so this extension can coexist with other renderer extensions
- Capability-aware settings that keep MCP and RTK-specific controls aligned with the current environment
- Adapter API for renderer consumers through the
pi-tool-display/tool-display-api-consumersubpath export
Installation
Local extension folder
Place this folder in one of Pi's auto-discovery locations:
# Global default (when PI_CODING_AGENT_DIR is unset)
~/.pi/agent/extensions/pi-tool-display
# Project-specific
.pi/extensions/pi-tool-display
npm package
pi install npm:@estebanforge/pi-tool-display
Usage
Interactive settings
Open the settings modal:
/tool-display
The modal exposes the day-to-day controls most people change regularly:
- preset profile
- tidy tool cards
- read output mode
- grep/find/ls output mode
- MCP output mode (when MCP is available)
- preview line count
- bash collapsed line count
- diff layout mode
- native user message box toggle
Advanced options remain in config.json.
Direct commands
/tool-display show # Show the effective config summary
/tool-display reset # Reset to the default opencode preset
/tool-display preset opencode # Apply opencode preset
/tool-display preset balanced # Apply balanced preset
/tool-display preset verbose # Apply verbose preset
Tool display adapter API
Other extensions can opt into pi-tool-display rendering without directly depending on its load order by importing the consumer helper:
import { decorateToolForDisplay, decorateMcpToolForDisplay } from "@estebanforge/pi-tool-display/tool-display-api-consumer";
decorateToolForDisplay(tool, adapter) applies the runtime decoration immediately when pi-tool-display is loaded, or queues the decoration until the API becomes available. Use adapter options such as kind: "read" | "edit" | "mcp" | "generic" to select the renderer family; decorateMcpToolForDisplay(tool) is the shortcut for MCP-style tools.
Presets
| Preset | Read Output | Search Output | MCP Output | Bash Output | Preview Lines | Bash Lines |
|---|---|---|---|---|---|---|
opencode |
hidden | hidden | hidden | opencode | 8 | 10 |
balanced |
summary | count | summary | summary | 8 | 10 |
verbose |
preview | preview | preview | preview | 12 | 20 |
opencode(default): minimal inline-only display; tool results stay collapsedbalanced: compact summaries with line counts and match totals; bash shows line count onlyverbose: larger previews for read/search/MCP/bash output
Bash Output Modes
| Mode | Behavior |
|---|---|
opencode |
Classic collapsed output using bashCollapsedLines limit with expansion hint |
summary |
Shows only line count (e.g., "โณ 3 lines returned") โ no output displayed |
preview |
Shows actual output lines using previewLines limit |
Configuration
Runtime configuration is stored at:
Default global path: ~/.pi/agent/extensions/pi-tool-display/config.json
Actual global path: $PI_CODING_AGENT_DIR/extensions/pi-tool-display/config.json when PI_CODING_AGENT_DIR is set
A starter template is included at config/config.example.json.
Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
debug |
boolean | false |
Opt-in file logging for extension diagnostics; missing values are treated as false |
tidyCards |
boolean | true |
Render built-in tool calls as compact collapsed cards; Ctrl+O expands to full output. Turn off to fall back to the classic header + output-mode rendering |
registerToolOverrides |
object | all true |
Built-in tool ownership flags |
customToolOverrides |
object | {} |
Explicit opt-in rendering rules for non-built-in extension tools |
enableNativeUserMessageBox |
boolean | true |
Enable bordered user prompt rendering |
readOutputMode |
string | "hidden" |
hidden, summary, or preview |
searchOutputMode |
string | "hidden" |
hidden, count, or preview |
mcpOutputMode |
string | "hidden" |
hidden, summary, or preview |
previewLines |
number | 8 |
Lines shown in collapsed preview mode |
expandedPreviewMaxLines |
number | 4000 |
Max preview lines when fully expanded |
bashOutputMode |
string | "opencode" |
opencode (collapse), summary (line count), or preview (show lines) |
bashCollapsedLines |
number | 10 |
Lines shown for collapsed bash output (opencode mode) |
diffViewMode |
string | "auto" |
auto, split, or unified |
diffIndicatorMode |
string | "bars" |
bars (vertical indicators), classic (+/- markers), or none |
diffSplitMinWidth |
number | 120 |
Minimum width before auto mode prefers split diffs |
diffCollapsedLines |
number | 24 |
Diff lines shown before collapsing |
diffWordWrap |
boolean | true |
Wrap long diff lines when needed |
allowExternalDiffPreviews |
boolean | false |
Allow pending edit/write diff previews for target paths outside workspace |
showTruncationHints |
boolean | false |
Show truncation indicators for compacted output |
showRtkCompactionHints |
boolean | false |
Show RTK compaction hints when RTK metadata exists |
Tool ownership
Use registerToolOverrides to control which built-in tools this extension owns:
{
"registerToolOverrides": {
"read": true,
"grep": true,
"find": true,
"ls": true,
"bash": true,
"edit": true,
"write": true
}
}
Subagent note: child sessions spawned by subagent extensions re-wrap tool definitions and can lose the display renderers attached at registration time. This extension detects that case at render time and rebuilds its renderers from the tool name, so owned built-ins keep their display in child sessions. If you still see plain rendering there, check the flags above.
Set any entry to false if another extension should handle that tool instead.
Changes to tool ownership take effect after
/reload.
Custom tool overrides
Use customToolOverrides when another extension registers a noisy top-level tool and you want pi-tool-display to render that tool's call/result output. Custom overrides are explicit opt-in only: unlisted or disabled tools keep their original renderers.
{
"customToolOverrides": {
"ide_find_symbol": {
"enabled": true,
"kind": "generic",
"outputMode": "summary"
},
"custom_mcp_gateway": {
"enabled": true,
"kind": "mcp",
"outputMode": "preview"
}
}
}
Each entry supports:
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Whether pi-tool-display should decorate this custom tool |
kind |
string | "generic" |
generic for plain compact output, or mcp for MCP-style call labels and result handling |
outputMode |
string | "summary" |
hidden, summary, or preview for this custom tool's result output |
Boolean shorthand is also accepted:
{
"customToolOverrides": {
"ide_find_symbol": true,
"noisy_tool_to_leave_alone": false
}
}
Notes:
- Built-in tool names (
read,grep,find,ls,bash,edit,write) are ignored here; useregisterToolOverridesfor those. genericcall rendering shows the tool name and argument count, then compacts the result according tooutputMode.mcpcall rendering understands MCP proxy-style arguments such astool,server,search,describe, andconnect.- Changes for already-registered tools take effect after
/reload; tools registered later can be decorated as they register.
Example config
{
"debug": false,
"tidyCards": true,
"registerToolOverrides": {
"read": true,
"grep": true,
"find": true,
"ls": true,
"bash": true,
"edit": true,
"write": true
},
"customToolOverrides": {
"ide_find_symbol": {
"enabled": true,
"kind": "generic",
"outputMode": "summary"
},
"custom_mcp_gateway": {
"enabled": true,
"kind": "mcp",
"outputMode": "preview"
}
},
"enableNativeUserMessageBox": true,
"readOutputMode": "summary",
"searchOutputMode": "count",
"mcpOutputMode": "summary",
"previewLines": 12,
"expandedPreviewMaxLines": 4000,
"bashOutputMode": "opencode",
"bashCollapsedLines": 15,
"diffViewMode": "auto",
"diffIndicatorMode": "bars",
"diffSplitMinWidth": 120,
"diffCollapsedLines": 24,
"diffWordWrap": true,
"allowExternalDiffPreviews": false,
"showTruncationHints": false,
"showRtkCompactionHints": false
}
Debug logging
Debug logging is disabled by default. Set debug to true in the extension root config.json only when collecting diagnostics; missing or non-true values are treated as false. When enabled, diagnostics are appended to debug/debug.log under a runtime-created debug/ directory, and no debug output is written to the terminal.
Rendering notes
Tidy tool cards
With tidyCards on (the default), owned built-in tools render as two-line cards:
๐ read src/auth.ts
โ 8 lines
โก (bash keeps its native `$ command` line with the live spinner)
โ 3 lines
โ๏ธ edit src/auth.ts (1 line)
โ +1/-1
The first line is the icon, tool name, and argument target; the second line is a short result summary colored by outcome (green counts, red failures, +adds/-dels for edits). bash keeps its native $ command header with the live spinner, so only its result line becomes a card. Cards are collapsed by default; Ctrl+O expands the card in place โ reads, searches, and bash show the full output, edits and writes show the full diff renderer. Errors collapse to โ failed: <first error line> and expand to the full error output.
Tidy mode replaces the collapsed presentation only: output modes, bash live output while a command streams, pending edit/write previews, RTK and truncation hints, and MCP/custom tool rendering all still apply. Setting tidyCards: false restores the classic header + output-mode rendering exactly; no other feature changes. Unlike pi-tidy-tools, no extra model-facing parameter is injected โ the card target comes from the tool's own arguments.
Edit and write diffs
edit and write results use the same diff renderer. In auto mode the extension chooses split or unified layout based on available width. On narrow panes it clamps rendered lines and shortens collapsed hint text so the diff stays readable instead of spilling past the terminal width.
While tool arguments are still streaming, partial edit and write calls can show projected pending previews. Deterministic edits render as pending edit diffs against current file contents, writes render as pending overwrite or pending create, and unresolved projections show a clear preview notice instead of guessing. Preview file reads are scoped to the active workspace so pending previews avoid reading paths outside the current project.
When diff input includes Pi anchored read lines such as 12#AB:content, the renderer treats the anchor as line metadata and displays the LINE#HASH label in the gutter while keeping the content aligned for split, unified, and compact diff layouts.
Write summaries
When content is available, write call summaries include line count and byte size information inline so you can quickly see the size of the pending write before expanding the result.
Thinking labels
Thinking blocks are labeled during streaming and on final messages. Before the next model turn, the extension sanitizes those presentation labels out of the stored assistant context so they do not accumulate or pollute future prompts.
Native user message box
When enabled, user prompts render inside a bordered box using Pi's native user message component. The renderer preserves markdown content more safely and normalizes ANSI/background handling to avoid odd nested background artifacts.
Capability detection
The extension checks the current Pi environment and adjusts behavior automatically:
- MCP tooling unavailable at startup: MCP settings can be hidden from the modal, but the configured MCP output mode is preserved because MCP tools may register later
- RTK optimizer unavailable: RTK hint settings are hidden and RTK compaction hints are disabled
This keeps the UI aligned with the current environment while still allowing dynamically registered MCP tools to be styled when they appear.
Troubleshooting
Reload safety
/reload is fully supported. On reload, the extension cleans up all tool overrides, prototype patches, timers, and event handlers through its built-in disposal registry, then re-registers everything on the next session lifecycle event. No manual cleanup is needed.
Tool ownership conflicts
If another extension is already rendering one of the built-in tools:
- Set
registerToolOverrides.<tool>tofalse - Run
/reload - Use
/tool-display showto confirm the effective ownership state
Built-in tool overrides (including bash) are registered with deferred ownership discovery โ the extension discovers which tools it owns via pi.getAllTools() during before_agent_start before overriding, preventing conflicts with other extensions that also register overrides.
Config not loading
If your settings are not being applied:
- Check that the global Pi tool-display config exists (default:
~/.pi/agent/extensions/pi-tool-display/config.json, respectsPI_CODING_AGENT_DIR) - Make sure the JSON is valid
- Run
/tool-display showto inspect the effective config summary
MCP or custom tool rendering not appearing
MCP tools are decorated via pi.registerTool interception, so they are captured as soon as they register regardless of lifecycle event ordering. If MCP tools still appear unstyled, check that the tool's name or parameter schema matches one of the supported MCP detection heuristics (names containing mcp, server:, ctx_, or parameter schemas with mcpServer/serverUrl/server_name).
For non-MCP extension tools, or MCP-like tools that do not match the heuristics, add the exact tool name under customToolOverrides and run /reload. Use kind: "generic" for ordinary tools and kind: "mcp" for MCP proxy-style arguments.
MCP or RTK settings missing
Those controls only appear when the corresponding capability is available in the current Pi environment.
Project structure
pi-tool-display/
โโโ index.ts # Extension entrypoint for Pi auto-discovery
โโโ src/
โ โโโ index.ts # Bootstrap and extension registration
โ โโโ capabilities.ts # MCP/RTK capability detection
โ โโโ config-modal.ts # /tool-display settings UI and command handling
โ โโโ config-store.ts # Config load/save and normalization
โ โโโ disposable.ts # Reload-safe cleanup registry for tool overrides, patches, and timers
โ โโโ diff-renderer.ts # Edit/write diff rendering engine
โ โโโ line-width-safety.ts # Width clamping helpers for narrow panes
โ โโโ pending-diff-preview.ts # Partial edit/write preview projection helpers
โ โโโ presets.ts # Preset definitions and matching
โ โโโ render-utils.ts # Shared rendering helpers
โ โโโ thinking-label.ts # Thinking label formatting and context sanitization
โ โโโ tool-overrides.ts # Built-in, MCP, and opt-in custom renderer overrides
โ โโโ types.ts # Shared config and type definitions
โ โโโ user-message-box-markdown.ts # Markdown extraction for user message rendering
โ โโโ user-message-box-native.ts # Native user message box registration
โ โโโ user-message-box-patch.ts # Safe native render patching helpers
โ โโโ user-message-box-renderer.ts # User message border renderer
โ โโโ user-message-box-utils.ts # ANSI/background normalization helpers
โ โโโ write-display-utils.ts # Write summary helpers
โ โโโ config-modal.ts # /tool-display settings dialog on @estebanforge/pi-tui-dialogs
โโโ config/
โ โโโ config.example.json # Starter config template
โโโ tests/
โโโ ansi-utils.test.ts # ANSI utility tests including foreground RGB preservation
โโโ bash-display.test.ts # Bash display and spinner tests
โโโ capabilities-edge.test.ts # Capability detection edge cases
โโโ config-modal.test.ts # Config modal tests
โโโ custom-tool-overrides.test.ts # Opt-in custom tool override tests
โโโ debug-logger-edge.test.ts # Debug logger edge cases
โโโ diff-renderer-ansi.test.ts # ANSI/background handling tests for diff rendering
โโโ diff-renderer-edge.test.ts # Diff renderer edge case tests
โโโ diff-renderer-width.test.ts # Width and background coverage tests for diff rendering
โโโ index-integration.test.ts # Integration tests for extension lifecycle
โโโ presets-edge.test.ts # Preset edge case tests
โโโ reload-behavior.test.ts # Reload-safe cleanup and re-registration tests
โโโ tool-overrides-config.test.ts # Tool override config tests
โโโ tool-overrides-registration.test.ts # Tool override registration tests
โโโ tool-ui-utils.test.ts # Utility tests for user message and diff helpers
Development
# Type check
npm run build
# Run tests
npm run test
# Full verification
npm run check
Related Pi Extensions
- pi-image-tools โ Image attachment and inline preview for the Pi TUI
- pi-hide-messages โ Hide older chat messages without losing context
- pi-startup-redraw-fix โ Fix terminal redraw glitches on startup
- pi-permission-system โ Permission enforcement for tool and command access