Four built-in tools leave the workflow open to extension
Pi starts a model with read, write, edit, and bash. It can run interactively, print or emit JSON, expose an RPC process, or sit inside another application through its SDK. Sessions persist as branching JSONL trees, and long conversations can be compacted while the original history remains available. The terminal shows model, tokens, cache use, cost, and context. This is enough for real repository work without deciding how every team should plan or delegate.
The omissions are deliberate. Pi does not ship plan mode or subagents as fixed product features. TypeScript extensions can add tools, commands, UI, provider hooks, and custom behavior. Skills, prompt templates, themes, and packages cover lighter changes. That freedom is Pi's appeal, and also its main adoption cost: two developers can both say they use Pi while running meaningfully different agents with different safety and review behavior.
Provider choice is wide, but compatibility work remains visible
Pi supports subscription login for Anthropic, OpenAI, and GitHub Copilot, plus API-key access to more than 20 named services. It can also connect to llama.cpp and lets users describe compatible custom models. Model and thinking selectors work inside the terminal, while provider catalogs refresh separately. Developers comparing price, context, or reasoning behavior can keep one interface instead of learning another agent for each account.
A shared interface cannot erase provider differences. Open issue 8610 reports that v0.84.3 fails immediately when Google Vertex runs through HTTP proxy variables. Issue 8643 describes image tool results rejected by OpenAI models on Bedrock. Issue 6996 reports missing thought signatures on Gemini 3.x tool calls. These are specific integrations, not a blanket failure. They show why teams should keep a small provider acceptance suite before changing the default model.
What happened when we ran it
Our sandbox installed 352 npm packages in 54 seconds, occupying 422 MB. The repository at commit a1f955e contained 1,394 files, roughly 272,558 source lines, and an 18.1 MB checkout. Its build succeeded in 31 seconds. The monorepo had 10 CI workflow files and no Dockerfile or top-level tests directory. Npm audit reported 0 known vulnerabilities across the installed dependency tree.
The complete test step exited 1 after 322 seconds. A node:test portion reported 5 passed and 0 failed. The failing tail came from the @earendil-works/pi-session-backend-sqlite-node workspace: Vitest showed 10 test files passed and 1 failed, with 86 tests passed and 1 failed out of 87. The supplied log does not identify the assertion or cause, so the defensible finding ends there. Pi built cleanly, but commit a1f955e did not pass every configured test in our fresh container.
Isolation is an operator choice, not a default permission prompt
The README is unusually direct: Pi has no built-in permission system restricting files, processes, networking, or credentials. It runs with the rights of the user who launched it. That is acceptable on a disposable development machine only if the user accepts the model invoking shell commands and editing reachable files. A production team should make the boundary part of installation, rather than relying on every developer to remember a special command.
The docs give 3 isolation patterns. Plain Docker places the whole process and provider keys in a container, with a mounted project directory still writing through to the host. OpenShell can enforce filesystem, network, credential, and inference policy through a gateway. Gondolin keeps Pi and provider auth on the host but routes built-in tools into a Linux micro-VM. Extensions still run wherever the Pi process runs, so an added tool can bypass a tool-routing boundary unless it delegates too.
Project trust can execute local packages and extensions
Interactive startup asks before loading project-local settings and resources from an untrusted folder. Once trusted, Pi can load .pi settings, install missing project packages, and execute project extensions. Context files load before that decision, while local executable extensions wait. The distinction reduces surprise, but trust remains a code-execution decision. Inspect the project package list and extensions just as you would inspect a build script from a new repository.
Pi's own dependency policy is stricter than the average npm CLI. Direct external dependencies are pinned, new releases have a 2-day minimum age, CI uses npm ci --ignore-scripts, and the published coding-agent package carries a shrinkwrap file. Release checks create isolated npm and Bun installations. Those controls do not audit every third-party Pi package, but they are useful evidence that maintainers understand the supply-chain risk of an extensible agent.
Version 0.84.3 is active while extension regressions are being reported
GitHub showed 97,937 stars and 139 combined open issues and pull requests on August 27, 2026. The last push was August 26, and v0.84.3 had shipped 2 days earlier. Its release added native PowerShell execution, safer managed updates, thinking controls, and many provider fixes. Current issue 8620 also reports that global extensions importing Pi packages fail under that bundled CLI release.
Pi is worth trying when customization is the requirement, not a hobby attached to it. The 54-second install, moderate 422 MB footprint, provider range, and detailed extension API make experimentation cheap. The failed SQLite test, current adapter reports, and explicit lack of built-in permissions mean a team rollout needs pinned versions, provider checks, reviewed extensions, and mandatory isolation. Without those policies, Pi's flexibility turns into each developer operating a different security model.

