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

@hheei/pi-python-eval

v0.8.0

Published

Persistent session-scoped Python eval for Pi, with nested tool calls through the Pi host.

Readme

@hheei/pi-python-eval

Persistent, session-scoped Python for Pi. One python_eval tool runs trusted local Python in a kernel that keeps its namespace across cells, and lets a cell call other installed tools through the Pi host.

Install @hheei/pi-settings separately for the Settings UI. @hheei/pi-ext-core is a production dependency, not a separately loaded Pi extension.

Tool

python_eval({ code, reset?, timeout_ms? })

  • code is non-empty trusted source, at most 1 MiB. This is not a sandbox.
  • reset: true discards the kernel and its scope before the cell runs.
  • timeout_ms is a hard wall-clock deadline for the whole cell, defaulting to 180000 ms (180 seconds). Set it explicitly to override the default. Nested tool calls count toward it.
  • exposure: "model-only", defaultActive: false: enable it with --tools or defaultTools.

Each cell reports its namespace, so names that survived are visible instead of assumed. print and console go to the transcript, display() keeps a JSON-safe value, and the last expression is the cell result. A restart is reported explicitly, because a kernel that died lost its names.

Nested tools

A cell reaches exactly read, grep, find, bash, edit, write, and apply_patch, and only while that tool is active in the session. Every call goes through the Pi host's context.executeTool(), so the host's own validation, hooks, and permission checks apply and the host's reported outcome decides whether the call failed. The package holds no tool definitions and no fallback dispatch, so a missing tool or a blocked call surfaces as a tool failure.

Nested calls return the tool's text, or its structuredContent when it declares one (for example bash). Each call is recorded as a trace row with its arguments, text, duration, and error.

Tool calls are synchronous Python: result = tools.apply_patch({"patch": patch}). Do not use await; top-level await is unsupported. A compile-time SyntaxError prevents the entire cell from running, so earlier assignments in that cell do not create names. Fix and re-run the whole cell, including those assignments. Runtime errors can leave earlier assignments intact; check the reported namespace before retrying.

Kernel lifecycle

One kernel per extension instance, at most one cell at a time: a concurrent cell fails immediately rather than queueing. Cancellation interrupts the cell (SIGINT) and escalates to SIGKILL after about 5 seconds; session shutdown kills the kernel. Names never survive into another session.

The kernel runs src/kernel/child.py (packed beside the built host) over NDJSON on a private pipe, so the child's stdout reaches the transcript instead of the protocol. Environment variables that look like credentials (*_API_KEY, *_TOKEN, *_SECRET, *_PASSWORD) are not inherited. Python 3.9+ is required.

Settings

Group eval in the global ext_settings.json, provider pi-python-eval.eval:

| Field | Default | Meaning | | --- | --- | --- | | pythonBin | (auto) | Interpreter for the kernel. Empty uses python3 or python on PATH. |

Changes apply on reload or in a new session.

Details

Results carry format: "pi-ext-tools-python-eval" and bounded rows (200 rows, 4,000 characters per row, 12,000 characters of model-visible transcript).

Rendering

createPythonEvalPresentation in this package owns the cell's rendering facts: container status, summary ((reset), (timeout 2s), call stats, duration), the highlighted Python input section, transcript sections (muted namespace report, display:/result: prefixes, one header row per nested call), collapsed nested rows, and copy text. registerPythonEvalTool publishes it through ext-core's optional renderer point, so an installed UI package draws the frame and this package's native renderer shows the plain transcript when none is installed. No UI package is a dependency.