npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@clapecho233/pi-smart-fold

v0.2.3

Published

pi coding-agent extension: collapse tool output at startup and fold thinking blocks to a live last line

Readme

pi-smart-fold

A pi coding-agent extension that keeps the session transcript compact — without losing key information.

| Without smart-fold | With smart-fold | | --- | --- | | Long thinking walls, verbose tool output, full file previews | One-line Thought for 12.4s summaries, folded tool output, write src/index.ts +12 -3 headers |

Features

1. Thinking fold + live timer (smart mode, default)

While the model thinks, the block shows a bold Thinking… (8s) header line, followed by the scrolling tail of the thinking text (like tail -f). One click toggles directly to the full text so far (the ticking Thinking… (8s) line stays pinned at the bottom and keeps updating); one more click toggles back to the scrolling tail. There is no intermediate label state — a single click always switches between scrolling tail ↔ full view:

Scrolling tail (default)          Full view (after one click)
Thinking… (8s)                    …earlier thinking text…
…latest line of thinking          …thinking still streaming…
                                  Thinking… (9s)   ← pinned at the bottom, live-updating

After the thinking run finishes, the block collapses to a single bold Thought for 12.4s line (measured duration). If the block was in full view at that moment, it transitions smoothly to the pinned duration footer first.

Single-click expand/collapse per block: finished thinking starts hidden (seeded by a prototype patch). One click → that block expands to its full text (with the bold duration line kept at the bottom); one more click → collapses back. No intermediate states, and only the clicked block is affected — other thinking runs in the same message are untouched. The same one-click toggle works for a run that already finished while its message is still streaming (e.g. thinking done, answer text or a tool call still coming): the folded Thought for … line expands directly — never through pi's bare Thought… label middle state.

  • Fully takes over native folding: pi's built-in hidden-thinking label (Thinking...) is replaced with per-message Thought for … labels generated by this extension. What you see after clicks or ctrl+t is always our text, never the native one. (In smart mode ctrl+t has no extra effect — use clicks or /fold expand instead.)
  • Exact click detection: an idempotent prototype patch on pi's publicly exported AssistantMessageComponent seeds the hidden state of finished thinking runs and observes writes to the component's internal visibility map (distinguishing ctrl+t's clear operation). Clicks on runs of a still-streaming message — the live run as well as already-finished ones — are redirected so the native two-state toggle's hidden middle state never appears. Global re-renders — theme changes, window resizes, layout redraws — are never mistaken for clicks. If a future pi version can't be patched, the extension degrades gracefully to pi's native display (with /fold expand as a fallback).
  • Persistent durations: each thinking run's duration is recorded in the session file keyed by content hash (a smart-fold-thinking custom entry, never sent to the LLM context), so durations still show after /resume. Multiple thinking runs within one message (between tool calls) are timed individually.
  • Code-block safe: while a code fence streams through the thinking text, structural fence lines are skipped in the collapsed tail — the block never flashes fully open for a frame. In the expanded view an unclosed code fence is closed automatically so the Thinking…/Thought for … footer renders below it as bold text, never swallowed into the code block as literal **asterisks**.
  • Truncation is measured in terminal display columns (CJK characters / emoji count as 2), keeping the line ending with an … prefix when over-wide.
  • Folding is display-only: the session file and the context sent to the model are never modified.

Other modes: tail (always one line — the text tail with a bold duration prefix), full (show full text after the run ends, with the duration footer), off (disable and restore pi's default thinking display).

Fallback: /fold expand on|off (or "Expand all thinking" in the settings panel) temporarily expands/collapses all finished thinking blocks. Daily usage only needs single clicks on individual blocks; new sessions always start fully folded.

2. Tool output folding

On every session_start (startup, /reload, /new, /resume, /fork) the extension calls ctx.ui.setToolsExpanded(false) so tool output stays collapsed; press ctrl+o to expand manually.

3. Tool call line truncation + write/edit diff stats

  • Long call lines are truncated: bash / read / grep / find / ls call lines collapse to a single line, cut to the terminal width with a trailing … (pi's ANSI-aware truncateToWidth). An extra … marker is appended when the command has more lines. Click or ctrl+o to expand and see everything.
  • write / edit line-diff stats:
    • write: reads the original file content before the write executes and computes a line-level diff (common prefix/suffix trimming + LCS). The header line gains a green +added / red -removed suffix, e.g. write src/index.ts +12 -3; new files show +N -0. Files larger than 8 MB are skipped. Stats are persisted with the tool result in the session file, so they still show in restored sessions (writes made before this version have no record and show nothing).
    • edit: diffs each edits[] entry's oldText → newText directly and sums the result, e.g. edit src/app.ts +2 -1 (updates live while arguments stream in).
  • write/edit collapse to a header-only line by default (writeCollapsed: header): collapsed rows show just the one-line header — no code content or diff preview (not natively possible in pi; implemented by wrapping both renderCall and renderResult — the result area renders an empty component while collapsed, and error messages remain visible). Click / ctrl+o expands to the full diff / syntax-highlighted content. The +N -M stat stays in the header line in both states (edit's native full-width background bar is preserved; the stat is injected into the trailing padding without changing the line width). Switch to preview in settings to restore pi's native preview.
  • Implemented as rendering wrappers around pi's built-in tools (execution logic is fully reused from each create*ToolDefinition).

Settings

/fold        Open a /config-style interactive settings list (Enter/Space to change, Esc to close)

Or change values directly (with autocompletion):

/fold thinking smart|tail|full|off   # on=smart, off=off accepted for compatibility
/fold tools on|off                   # fold tool output at session start
/fold writestat on|off               # write/edit diff stats toggle
/fold writecollapsed header|preview  # write rows: header-only / keep preview when collapsed

Config file smart-fold.config.json (next to the extension entry; the legacy boolean thinkingFold is migrated automatically):

{
  "toolsFold": true,
  "thinking": "smart",
  "writeStat": true,
  "writeCollapsed": "header"
}

Installation

Any one of these:

# Option A: clone into pi's global extension auto-discovery directory
git clone <this-repo> ~/.pi/agent/extensions/smart-fold

# Option B: install via the pi package manager
pi install git:<repo-url>

# Option B2: install from npm
pi install @clapecho233/pi-smart-fold

# Option C: add to settings.json
# ~/.pi/agent/settings.json → { "extensions": ["/path/to/pi-smart-fold"] }

# Try it temporarily
pi -e /path/to/pi-smart-fold/index.ts

The extension has no npm dependencies — pi loads the TypeScript directly via jiti.

Development

npm install        # dev deps only — the package ships no install scripts (npm ≥11 warns / npm 12 blocks them)
npm run link:pi    # link the installed pi runtime into node_modules (after clone; re-run after a pi upgrade)
npm run typecheck  # strict tsc against the installed pi's .d.ts (no emit)
npm run check      # link + typecheck + jiti load-check + unit tests + click simulation
npm test           # unit tests for the pure functions (native TS type stripping, Node ≥ 22.18, no build step)
npm run test:sim   # click-cycle simulation against the real pi AssistantMessageComponent

The extension itself has no npm dependencies — pi loads the TypeScript directly via jiti. typescript / @types/node are dev-only, and node_modules/@earendil-works/* are symlinks into the pi installation that loads the extension (created by scripts/link-pi.mjs, dev-only — at runtime pi's jiti loader resolves @earendil-works/* imports itself, which is why the package ships no install script), so typecheck always runs against the exact pi version installed on the machine.

Project layout:

index.ts                Extension entry (transformer / events / write render wrappers / /fold settings UI)
lib/fold.ts             Pure functions: display width, tail truncation, duration formatting, line diff
lib/thinking.ts         Thinking timer state machine (per-run durations keyed by content hash)
lib/config.ts           Config load/save (with legacy migration; falls back to defaults when missing/corrupt)
scripts/link-pi.mjs     Symlink the installed pi runtime into node_modules (version-following)
scripts/load-check.mjs  Smoke test: load the extension via pi's jiti and exercise registration
test/fold.test.mjs      Unit tests
test/click-sim.mjs      Click-cycle simulation (real pi component + simulated clicks, verifies tail ↔ full toggling)

Known limitations

  • Single-click toggling of thinking runs in a live message depends on the prototype patch's redirect; without the patch it degrades to pi's native two-state toggle (two clicks to expand).
  • Expand state is runtime-only: new sessions/reloads start folded again. Window resizes never collapse blocks you've expanded.
  • write diff stats only apply to writes executed in the current session (restored older sessions have no pre-execution snapshot to diff against).
  • When stacked with pi's native "Hide thinking blocks" (ctrl+t toggle): if thinking is hidden that way, the live scrolling line won't show — keep the native display at its default and let this extension handle folding.

Compatibility

Built and verified against pi 1.0.0 public extension APIs: registerMarkdownTransformer, ctx.ui.setToolsExpanded / setHiddenThinkingLabel, create*ToolDefinition (and friends), registerTool (renderCall / renderResult + ToolRenderContext), registerCommand, appendEntry, SettingsList, and the AssistantMessageComponent click-internals patch (updateContent, thinkingVisibilityOverrides, hiddenThinkingLabel).

After upgrading pi, run npm run link:pi && npm run check — the links follow the newly installed version automatically, and the check verifies types, jiti loading, and behavior against it.