Skip to content

Pi Coding Agent -- Sandbox Analysis Report

Analysis Date: 2026-02-12 Repository: https://github.com/badlogic/pi-monoGit Commit: 34878e7cc8074f42edff6c2cdcc9828aa9b6afdeLatest Version: 0.52.9 License: MIT Source Availability: Open source


1. Overview

Pi (published as @mariozechner/pi-coding-agent) is an interactive coding agent CLI built in TypeScript/Node.js. It is a monorepo (pi-mono) by Mario Zechner. The agent provides read, bash, edit, write, grep, find, and ls tools to an LLM, with support for many providers (Anthropic, OpenAI, Google, AWS Bedrock, Groq, Cerebras, xAI, OpenRouter, Mistral, GitHub Copilot, and more).

The monorepo contains these packages:

Packagenpm NameDescription
packages/ai@mariozechner/pi-aiUnified multi-provider LLM API
packages/agent@mariozechner/pi-agent-coreAgent runtime with tool calling
packages/coding-agent@mariozechner/pi-coding-agentMain CLI -- the coding agent
packages/tui@mariozechner/pi-tuiCustom terminal UI library
packages/web-ui@mariozechner/pi-web-uiWeb components for chat (not used by CLI)
packages/mom@mariozechner/pi-momSlack bot delegating to pi agent
packages/pods@mariozechner/pivLLM GPU pod management CLI

2. UI & Execution Modes

Custom TUI (NOT Ink/React)

Pi uses its own custom terminal UI library (@mariozechner/pi-tui) with differential rendering -- it is NOT based on Ink, React-Ink, blessed, or any other TUI framework. The TUI renders directly to stdout using ANSI escape codes and manages its own component tree.

typescript
// packages/tui/src/tui.ts
/**
 * Minimal TUI implementation with differential rendering
 */
export interface Component {
    render(width: number): string[];
    handleInput?(data: string): void;
    invalidate(): void;
}

Key TUI features:

  • Direct ANSI escape code rendering to stdout
  • Differential rendering (only re-renders changed lines)
  • Supports Kitty keyboard protocol for key release events
  • Terminal image support (Kitty protocol, iTerm2 inline images)
  • OSC 8 hyperlink support
  • Custom editor component with full input handling
  • Overlay/modal system

No Web UI in CLI Mode

The packages/web-ui package exists but is separate -- it provides web components (using lit / mini-lit) for embedding in web pages, not used by the CLI. The CLI is purely terminal-based.

Three Execution Modes

  1. Interactive mode (default) -- full TUI with editor, footer, conversation display
  2. Print mode (-p or piped stdin) -- non-interactive, outputs to stdout
  3. RPC mode (--rpc) -- headless JSON protocol on stdin/stdout for embedding in other applications

3. Authentication & Credentials

3.1 Credential Storage

All credentials are stored in a plain JSON file at ~/.pi/agent/auth.json, with file permissions set to 0o600:

typescript
// packages/coding-agent/src/core/auth-storage.ts
private save(): void {
    const dir = dirname(this.authPath);
    if (!existsSync(dir)) {
        mkdirSync(dir, { recursive: true, mode: 0o700 });
    }
    writeFileSync(this.authPath, JSON.stringify(this.data, null, 2), "utf-8");
    chmodSync(this.authPath, 0o600);
}

The auth file stores two types of credentials:

  • API keys (plain text in JSON)
  • OAuth tokens (access token, refresh token, expiry timestamp)

File locking via proper-lockfile prevents race conditions when multiple pi instances refresh tokens simultaneously.

Pi does NOT use macOS Keychain, keytar, keyring, or any OS-level credential store.

3.2 API Key Sources and Priority Order

Priority: runtime override > auth.json > env var > fallback resolver.

typescript
// packages/ai/src/env-api-keys.ts
const envMap: Record<string, string> = {
    openai: "OPENAI_API_KEY",
    "azure-openai-responses": "AZURE_OPENAI_API_KEY",
    google: "GEMINI_API_KEY",
    groq: "GROQ_API_KEY",
    cerebras: "CEREBRAS_API_KEY",
    xai: "XAI_API_KEY",
    openrouter: "OPENROUTER_API_KEY",
    "vercel-ai-gateway": "AI_GATEWAY_API_KEY",
    zai: "ZAI_API_KEY",
    mistral: "MISTRAL_API_KEY",
    minimax: "MINIMAX_API_KEY",
    "minimax-cn": "MINIMAX_CN_API_KEY",
    huggingface: "HF_TOKEN",
    opencode: "OPENCODE_API_KEY",
    "kimi-coding": "KIMI_API_KEY",
};

Additional provider-specific environment variables:

  • ANTHROPIC_API_KEY, ANTHROPIC_OAUTH_TOKEN
  • COPILOT_GITHUB_TOKEN, GH_TOKEN, GITHUB_TOKEN
  • AWS_PROFILE, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_BEARER_TOKEN_BEDROCK, AWS_REGION, AWS_DEFAULT_REGION, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_*
  • GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_CLOUD_PROJECT, GCLOUD_PROJECT, GOOGLE_CLOUD_LOCATION
  • AZURE_OPENAI_BASE_URL, AZURE_OPENAI_RESOURCE_NAME, AZURE_OPENAI_API_VERSION, AZURE_OPENAI_DEPLOYMENT_NAME_MAP

3.3 OAuth Flows

Pi supports 5 OAuth providers, each with its own flow:

ProviderFlow TypeLocal HTTP Server PortEndpoints
AnthropicPKCE auth code (manual paste)Noneclaude.ai/oauth/authorize, console.anthropic.com/v1/oauth/token
GitHub CopilotDevice code flow (polling)Nonegithub.com/login/device/code, github.com/login/oauth/access_token
Google AntigravityPKCE auth code + local callback127.0.0.1:51121accounts.google.com/o/oauth2/v2/auth, oauth2.googleapis.com/token
Google Gemini CLIPKCE auth code + local callback127.0.0.1:8085accounts.google.com/o/oauth2/v2/auth, oauth2.googleapis.com/token
OpenAI CodexPKCE auth code + local callback127.0.0.1:1455auth.openai.com/oauth/authorize, auth.openai.com/oauth/token

During OAuth login, pi opens the user's browser using platform-specific commands:

typescript
// packages/coding-agent/src/modes/interactive/components/login-dialog.ts
const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
exec(`${openCmd} "${url}"`);

3.4 Credential File Locations and Formats

PathPurpose
~/.pi/agent/auth.jsonAll API keys and OAuth tokens (JSON, mode 0o600)
~/.config/gcloud/application_default_credentials.jsonGoogle ADC check (for Vertex AI)
~/.aws/credentials, ~/.aws/configAWS credential chain (via SDK, for Bedrock)

4. Configuration & Filesystem

4.1 User-Level Config Paths

The default global config directory is ~/.pi/agent/, configurable via the PI_CODING_AGENT_DIR environment variable.

typescript
// packages/coding-agent/src/config.ts
export const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || ".pi";
export function getAgentDir(): string {
    const envDir = process.env[ENV_AGENT_DIR];
    if (envDir) { /* ... */ }
    return join(homedir(), CONFIG_DIR_NAME, "agent");
}
PathPurpose
~/.pi/agent/auth.jsonAPI keys and OAuth tokens
~/.pi/agent/settings.jsonUser settings (default provider, theme, compaction, etc.)
~/.pi/agent/models.jsonCustom model definitions
~/.pi/agent/pi-debug.logDebug log output
~/.pi/agent/sessions/Session history storage
~/.pi/agent/sessions/<encoded-cwd>/Per-project session files
~/.pi/agent/sessions/<encoded-cwd>/session.jsonlSession data (JSONL format)
~/.pi/agent/themes/User custom themes
~/.pi/agent/bin/Managed tool binaries (fd, rg)
~/.pi/agent/tools/Tools directory
~/.pi/agent/prompts/User prompt templates
~/.pi/agent/git/Git-based package installs
~/.pi/agent/npm/(via global npm root)
~/.pi/agent/extensions/Global extensions
~/.pi/agent/sandbox.jsonSandbox extension config (optional)

4.2 Project-Level Config Paths

PathPurpose
<cwd>/.pi/settings.jsonProject-local settings
<cwd>/.pi/extensions/Project-local extensions
<cwd>/.pi/sandbox.jsonProject-local sandbox config
<cwd>/.pi/npm/Project-local npm packages
<cwd>/.pi/git/Project-local git packages

4.3 System/Enterprise Config Paths

N/A

4.4 Data & State Directories

PathPurpose
~/.pi/agent/sessions/Session history storage root
~/.pi/agent/sessions/<encoded-cwd>/session.jsonlPer-project session data
~/.pi/agent/pi-debug.logDebug log output

4.5 Workspace Files Read

FilePurpose
AGENTS.mdAgent instructions (loaded from cwd and parent dirs)
CLAUDE.mdAlternative agent instructions file
.gitignoreUsed by find/grep tools to respect ignore patterns
.ignoreAdditional ignore patterns
.fdignorefd-specific ignore patterns
<cwd>/.git/HEADGit branch detection (with worktree support)

4.6 Temp Directory Usage

Pi uses os.tmpdir() (which reads the TMPDIR environment variable on macOS) for temporary files:

typescript
// packages/coding-agent/src/core/tools/bash.ts
import { tmpdir } from "node:os";
function getTempFilePath(): string {
    const id = randomBytes(8).toString("hex");
    return join(tmpdir(), `pi-bash-${id}.log`);
}

Temporary file patterns:

PatternPurposeCleanup
$TMPDIR/pi-bash-<hex>.logBash output overflow (>30KB output)No automatic cleanup
$TMPDIR/pi-editor-<timestamp>.pi.mdExternal editor temp fileCleaned after editor closes
$TMPDIR/pi-extensions/npm/<hash>/Temporary npm package installsNo automatic cleanup
$TMPDIR/pi-extensions/git-<host>/<hash>/Temporary git package installsNo automatic cleanup
$TMPDIR/mom-bash-<id>.logMom (Slack bot) bash outputNo automatic cleanup

5. Tools Available to the LLM

Pi provides the following tools to the LLM:

  • read -- File reading (any file the LLM requests in the working directory tree)
  • bash -- Shell command execution (arbitrary commands via configured shell)
  • edit -- File editing (diff-based, uses diff npm package)
  • write -- File creation/writing
  • grep -- Content search (uses rg / ripgrep, streaming)
  • find -- File pattern matching (uses fd)
  • ls -- Directory listing

The bash tool runs commands directly on the host system with the user's full permissions. Shell resolution order: user shellPath in settings > /bin/bash > bash on PATH > sh.

Pi auto-downloads fd and rg (ripgrep) binaries if not found on PATH, installing them to ~/.pi/agent/bin/:

typescript
// packages/coding-agent/src/utils/tools-manager.ts
// Downloads from GitHub releases:
// https://github.com/sharkdp/fd/releases/...
// https://github.com/BurntSushi/ripgrep/releases/...

Extensions can register additional custom tools (including replacing the bash tool).


6. Host System Interactions

6.1 Subprocess Execution

Shell Execution (bash tool -- primary agent capability)

typescript
// packages/coding-agent/src/core/tools/bash.ts
const child = spawn(shell, [...args, command], {
    cwd,
    detached: true,
    env: env ?? getShellEnv(),
    stdio: ["ignore", "pipe", "pipe"],
});
  • Runs arbitrary commands via bash (or configured shell)
  • Shell resolution: user shellPath in settings > /bin/bash > bash on PATH > sh
  • Process groups are used (detached: true) for tree killing
  • SIGKILL sent to process group on cancellation
  • The agent's ~/.pi/agent/bin/ directory is prepended to PATH

Tool Binary Management

Pi auto-downloads fd and rg (ripgrep) if not found on PATH:

  • spawnSync("fd", [...]) for file autocomplete
  • spawn("rg", [...]) for grep tool (ripgrep streaming)
  • spawnSync("tar", ["xzf", ...]) for extracting downloaded archives
  • spawnSync("which", ["bash"]) or spawnSync("where", ["bash.exe"]) for shell detection

Clipboard Operations

typescript
// packages/coding-agent/src/utils/clipboard.ts (macOS)
execSync("pbcopy", { input: text, timeout: 5000 });

// Also emits OSC 52 escape sequence to stdout for terminal clipboard:
process.stdout.write(`\x1b]52;c;${encoded}\x07`);

On macOS: pbcopy for text, @mariozechner/clipboard (optional native dependency) for image clipboard.

External Editor

typescript
// packages/coding-agent/src/modes/interactive/interactive-mode.ts
const editorCmd = process.env.VISUAL || process.env.EDITOR;
const result = spawnSync(editor, [...editorArgs, tmpFile], {
    stdio: "inherit",
});
  • Spawns $VISUAL or $EDITOR for the /editor command
  • Uses a temp file in $TMPDIR

GitHub CLI

typescript
// Session sharing via /share command:
spawnSync("gh", ["auth", "status"], { encoding: "utf-8" });
spawn("gh", ["gist", "create", "--public=false", tmpFile]);

Browser Opening

typescript
// During OAuth login:
exec(`open "${url}"`);     // macOS
exec(`start "${url}"`);    // Windows
exec(`xdg-open "${url}"`); // Linux

Package Management

typescript
// packages/coding-agent/src/core/package-manager.ts
const child = spawn(command, args, { cwd: installRoot, ... });
// Runs: npm install, npm root -g, git clone, etc.
  • npm install <package> -- for installing npm extension packages
  • npm root -g -- to find global npm root
  • git clone <url> -- for git-based package installs
  • git fetch, git checkout -- for git package updates

Process Tree Killing

typescript
// packages/coding-agent/src/utils/shell.ts
// Unix:
process.kill(-pid, "SIGKILL");  // Kill entire process group
// Windows fallback:
spawn("taskkill", ["/F", "/T", "/PID", String(pid)]);

6.2 Network Requests

LLM API Calls

ProviderEndpoint Pattern
Anthropichttps://api.anthropic.com/v1/messages (via @anthropic-ai/sdk)
OpenAIhttps://api.openai.com/v1/... (via openai SDK)
Google Geminihttps://generativelanguage.googleapis.com/... (via @google/genai)
Google Vertexhttps://<location>-aiplatform.googleapis.com/...
AWS Bedrockhttps://bedrock-runtime.<region>.amazonaws.com
Azure OpenAIhttps://<resource>.openai.azure.com/openai/...
Groqhttps://api.groq.com/...
GitHub Copilothttps://api.individual.githubcopilot.com/...
MistralVia @mistralai/mistralai SDK
OthersVarious OpenAI-compatible endpoints

Other Network Requests

URLPurpose
https://registry.npmjs.org/@mariozechner/pi-coding-agent/latestVersion check on startup
https://registry.npmjs.org/<pkg>/latestnpm package version checks
https://api.github.com/repos/<repo>/releases/latestfd/rg binary download version check
https://github.com/<repo>/releases/download/...fd/rg binary downloads
https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssistAntigravity project discovery
https://www.googleapis.com/oauth2/v1/userinfoGoogle user email lookup
OAuth token endpoints (see Section 3)Token exchange and refresh

HTTP Proxy Support

Pi respects HTTP_PROXY, HTTPS_PROXY, http_proxy, https_proxy, no_proxy, NO_PROXY environment variables via undici's EnvHttpProxyAgent:

typescript
// packages/ai/src/utils/http-proxy.ts
import("undici").then((m) => {
    const { EnvHttpProxyAgent, setGlobalDispatcher } = m;
    setGlobalDispatcher(new EnvHttpProxyAgent());
});

6.3 Port Binding

Pi binds local HTTP servers during OAuth flows:

PortProviderBind Address
51121Google Antigravity127.0.0.1
8085Google Gemini CLI127.0.0.1
1455OpenAI Codex127.0.0.1

These servers are temporary -- they start when login begins and close when the callback is received or login completes.

6.4 Browser Launching

During OAuth login, pi opens the user's browser using platform-specific commands:

  • macOS: open "<url>"
  • Windows: start "<url>"
  • Linux: xdg-open "<url>"

6.5 Clipboard Access

Text clipboard (write-only):

  • macOS: pbcopy via execSync
  • Also emits OSC 52 escape sequence (works over SSH)

Image clipboard (read-only, for pasting images into conversations):

  • macOS/Windows: @mariozechner/clipboard native module (optional dependency)
  • Linux/Wayland: wl-paste --list-types, wl-paste --type <mime>
  • Linux/X11: xclip -selection clipboard -t <mime> -o

6.6 File System Watchers

Pi sets up fs.watch() watchers on:

  1. Git HEAD file (<cwd>/.git/HEAD) -- monitors for branch changes, displayed in the footer
  2. Theme file -- watches for live theme reloading when custom themes change
typescript
// packages/coding-agent/src/core/footer-data-provider.ts
private gitWatcher: FSWatcher | null = null;
// Watches .git/HEAD for branch changes

// packages/coding-agent/src/modes/interactive/theme/theme.ts
themeWatcher = fs.watch(themeFile, (eventType) => { ... });

6.7 Other

  • RPC Mode: When run with --rpc, pi operates as a headless JSON-over-stdio service. Reads JSON commands from stdin, writes JSON events/responses to stdout. The RpcClient class can spawn a pi subprocess in RPC mode.
  • Docker/Container Interaction: The mom (Slack bot) package supports Docker execution (docker exec <container> sh -c <command>). This is only relevant to the Slack bot, not the main CLI.
  • Session Sharing: The /share command creates GitHub Gists via gh gist create for sharing session transcripts.

7. Extension Points

7.1 Hook/Lifecycle System

None identified (no hook/lifecycle events system).

7.2 Plugin/Extension Architecture

Extensions can:

  • Register custom tools (including replacing the bash tool)
  • Register custom commands
  • Hook into session events
  • Spawn subprocesses
  • Access the filesystem
  • Make network requests

Extensions are loaded from:

  1. CLI flag: pi -e ./my-extension.ts
  2. Settings: extensions array in settings.json
  3. Project-local: <cwd>/.pi/extensions/
  4. Packages: npm or git packages with pi.extensions in their package.json

Extensions are loaded via jiti (TypeScript-in-Node.js runtime).

7.3 MCP Integration

None identified. Pi uses its own extension system rather than MCP.

7.4 Custom Commands/Skills/Agents

  • Custom prompt templates: ~/.pi/agent/prompts/
  • Custom model definitions: ~/.pi/agent/models.json

7.5 SDK/API Surface

  • RPC mode (--rpc): Headless JSON-over-stdio protocol for embedding in other applications
  • RpcClient class: Can spawn a pi subprocess in RPC mode for programmatic control

8. Sandbox & Security Model

8.1 Built-in Sandboxing

Pi does NOT sandbox tool execution by default. The bash tool runs commands directly on the host system with the user's full permissions.

However, there is an optional sandbox extension at packages/coding-agent/examples/extensions/sandbox/ that uses @anthropic-ai/sandbox-runtime to enforce OS-level restrictions:

typescript
// Uses sandbox-exec on macOS, bubblewrap on Linux
await SandboxManager.initialize({
    network: config.network,
    filesystem: config.filesystem,
});
const wrappedCommand = await SandboxManager.wrapWithSandbox(command);

This is opt-in and must be explicitly enabled by the user via pi -e ./sandbox.

8.2 Permission System

None. All tools run with the user's full permissions by default.

8.3 Safety Mechanisms

  • Credential file permissions set to 0o600 (owner read/write only)
  • Config directory created with 0o700 permissions
  • File locking via proper-lockfile for auth.json

8.4 Known Vulnerabilities

None identified.

8.5 Enterprise/Managed Security Controls

N/A


9. Key Dependencies

DependencyPackageImpact
@anthropic-ai/sdkaiHTTP to Anthropic API
openaiaiHTTP to OpenAI-compatible APIs
@google/genaiaiHTTP to Google Gemini API
@aws-sdk/client-bedrock-runtimeaiHTTP to AWS Bedrock
@mistralai/mistralaiaiHTTP to Mistral API
undiciaiHTTP proxy agent setup (modifies global fetch)
proxy-agentaiHTTP proxy for AWS SDK
proper-lockfilecoding-agentFile-level locking for auth.json
globcoding-agentFilesystem globbing
@mariozechner/clipboardcoding-agent (optional)Native clipboard access (image read)
@silvia-odwyer/photon-nodecoding-agentWASM-based image processing (BMP-to-PNG)
@mariozechner/jiticoding-agentRuntime TypeScript loading for extensions
chalkcoding-agentTerminal color output
diffcoding-agentDiff generation for edit tool
file-typecoding-agentFile MIME type detection
ignorecoding-agent.gitignore pattern matching
hosted-git-infocoding-agentGit URL parsing for package manager
yamlcoding-agentYAML parsing
markedcoding-agent, tuiMarkdown parsing
@slack/socket-mode, @slack/web-apimomSlack WebSocket and API (bot only)
@anthropic-ai/sandbox-runtimesandbox example, momOS-level sandboxing (optional)

10. Environment Variables

Pi-Specific

VariablePurpose
PI_CODING_AGENT_DIROverride global config directory (default: ~/.pi/agent)
PI_PACKAGE_DIROverride package asset directory
PI_SHARE_VIEWER_URLOverride share viewer URL
PI_SKIP_VERSION_CHECKSkip npm version check on startup
PI_AI_ANTIGRAVITY_VERSIONOverride Antigravity User-Agent version
PI_TIMINGEnable timing instrumentation (1)
PI_CLEAR_ON_SHRINKClear empty rows when content shrinks (1)
PI_HARDWARE_CURSOREnable hardware cursor (1)
PI_CACHE_RETENTIONCache retention setting (long)

Provider API Keys

VariableProvider
OPENAI_API_KEYOpenAI
AZURE_OPENAI_API_KEYAzure OpenAI
GEMINI_API_KEYGoogle Gemini
GROQ_API_KEYGroq
CEREBRAS_API_KEYCerebras
XAI_API_KEYxAI
OPENROUTER_API_KEYOpenRouter
AI_GATEWAY_API_KEYVercel AI Gateway
ZAI_API_KEYZAI
MISTRAL_API_KEYMistral
MINIMAX_API_KEYMiniMax
MINIMAX_CN_API_KEYMiniMax CN
HF_TOKENHuggingFace
OPENCODE_API_KEYOpenCode
KIMI_API_KEYKimi Coding
ANTHROPIC_API_KEYAnthropic
ANTHROPIC_OAUTH_TOKENAnthropic OAuth
COPILOT_GITHUB_TOKENGitHub Copilot
GH_TOKEN / GITHUB_TOKENGitHub
AWS_PROFILE, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, etc.AWS Bedrock
GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_CLOUD_PROJECT, etc.Google Vertex AI
AZURE_OPENAI_BASE_URL, AZURE_OPENAI_RESOURCE_NAME, etc.Azure OpenAI

Editor/Shell

VariablePurpose
VISUALPreferred editor for /editor command
EDITORFallback editor for /editor command
SHELL(not used -- pi finds bash independently)

Terminal Detection

VariablePurpose
COLORTERMTrue color detection
TERMTerminal type detection
TERM_PROGRAMTerminal program detection (Apple_Terminal)
WT_SESSIONWindows Terminal detection
COLORFGBGDark/light mode detection
DISPLAYX11 display for clipboard
WAYLAND_DISPLAYWayland display for clipboard
XDG_SESSION_TYPESession type for Wayland detection
TERMUX_VERSIONTermux environment detection

Proxy

VariablePurpose
HTTP_PROXY / http_proxyHTTP proxy
HTTPS_PROXY / https_proxyHTTPS proxy
NO_PROXY / no_proxyProxy bypass list

11. Summary Tables

11.1 All Filesystem Paths Accessed

PathAccessPurposeCreated by Agent?
~/.pi/agent/R/WGlobal config rootYes
~/.pi/agent/auth.jsonR/WCredentials (API keys + OAuth)Yes
~/.pi/agent/settings.jsonR/WUser settingsYes
~/.pi/agent/models.jsonRCustom model definitionsNo (user-created)
~/.pi/agent/pi-debug.logWDebug outputYes
~/.pi/agent/sessions/R/WSession storage rootYes
~/.pi/agent/sessions/<encoded-cwd>/session.jsonlR/WSession conversation historyYes
~/.pi/agent/themes/RCustom themesNo (user-created)
~/.pi/agent/bin/R/WManaged binaries (fd, rg)Yes
~/.pi/agent/bin/fdR/Wfd binaryYes (downloaded)
~/.pi/agent/bin/rgR/Wrg (ripgrep) binaryYes (downloaded)
~/.pi/agent/tools/R/WTools directoryYes
~/.pi/agent/prompts/RPrompt templatesNo (user-created)
~/.pi/agent/git/<host>/<path>/R/WGit package installsYes
~/.pi/agent/extensions/RGlobal extensionsNo (user-created)
~/.pi/agent/sandbox.jsonRSandbox config (optional ext)No (user-created)
<cwd>/.pi/settings.jsonR/WProject settingsYes
<cwd>/.pi/extensions/RProject extensionsNo (user-created)
<cwd>/.pi/npm/R/WProject npm packagesYes
<cwd>/.pi/git/R/WProject git packagesYes
<cwd>/.pi/sandbox.jsonRProject sandbox configNo (user-created)
<cwd>/.git/HEADRGit branch detectionNo
<cwd>/AGENTS.mdRAgent instructionsNo
<cwd>/CLAUDE.mdRAgent instructions (alt)No
<cwd>/.gitignoreRIgnore patternsNo
$TMPDIR/pi-bash-<hex>.logR/WBash output overflowYes
$TMPDIR/pi-editor-<ts>.pi.mdR/WExternal editor tempYes
$TMPDIR/pi-extensions/R/WTemp package installsYes
~/.config/gcloud/application_default_credentials.jsonRGoogle ADC checkNo
~/.aws/credentials, ~/.aws/configRAWS credentials (via SDK)No
Any file in <cwd> treeR/WAgent read/write/edit toolsVaries

11.2 All Network Endpoints

EndpointPurposeWhen Triggered
api.anthropic.comLLM inferenceWhen Anthropic provider selected
api.openai.comLLM inferenceWhen OpenAI provider selected
generativelanguage.googleapis.comLLM inferenceWhen Gemini provider selected
<loc>-aiplatform.googleapis.comLLM inferenceWhen Vertex AI configured
bedrock-runtime.<region>.amazonaws.comLLM inferenceWhen Bedrock configured
<resource>.openai.azure.comLLM inferenceWhen Azure OpenAI configured
api.individual.githubcopilot.comLLM inferenceWhen GitHub Copilot configured
api.groq.comLLM inferenceWhen Groq configured
Various OpenAI-compatible endpointsLLM inferenceWhen other providers configured
registry.npmjs.orgVersion check, package installsStartup, extension install
api.github.comfd/rg release checksTool binary updates
github.comfd/rg downloads, git clonesTool binary downloads, git packages
claude.aiAnthropic OAuthDuring Anthropic login
console.anthropic.comAnthropic OAuth tokenDuring Anthropic login
github.com/login/*GitHub OAuthDuring GitHub Copilot login
accounts.google.comGoogle OAuthDuring Google login
oauth2.googleapis.comGoogle token exchangeDuring Google login
cloudcode-pa.googleapis.comAntigravity project discoveryDuring Antigravity setup
auth.openai.comOpenAI Codex OAuthDuring OpenAI login
www.googleapis.comGoogle user infoDuring Google login
pi.dev/session/Session share viewerWhen sharing sessions
127.0.0.1:51121Antigravity OAuth callbackDuring Antigravity login
127.0.0.1:8085Gemini CLI OAuth callbackDuring Gemini login
127.0.0.1:1455OpenAI Codex OAuth callbackDuring OpenAI login

11.3 All System Interactions

TypeMechanismDetails
Shell executionspawn() via configured shellAgent bash tool -- runs arbitrary commands
File read/write/editNode.js fs moduleAgent tools -- reads/writes project files
Clipboard write (text)pbcopy (macOS), OSC 52Copy to clipboard
Clipboard read (image)@mariozechner/clipboard native modulePaste images into conversation
Browser launchexec("open") / exec("xdg-open")OAuth login flows
HTTP port bindinghttp.createServerOAuth callback servers (temporary)
Tool binary downloadfetch() to GitHub releasesfd/rg auto-install
Package managementnpm install, git cloneExtension installation
External editorspawnSync($VISUAL/$EDITOR)/editor command
GitHub CLIspawnSync("gh")Session sharing
File watchingfs.watch()Git HEAD, theme files
Process group killprocess.kill(-pid, "SIGKILL")Bash tool cancellation
Archive extractionspawnSync("tar")fd/rg install

12. Sandboxing Recommendations

Critical restrictions needed:

  1. Shell execution -- The bash tool runs arbitrary commands with full user permissions. This is the primary attack surface.
  2. File system access -- The agent reads/writes files anywhere accessible to the user. No built-in path restrictions.
  3. Network access -- Unrestricted outbound network to LLM providers, npm registry, GitHub, and any URL the agent shell commands access.

What to allow:

  • Network access to configured LLM provider endpoints
  • Read/write access to the working directory (scoped)
  • Read/write access to ~/.pi/agent/ for config/state
  • Read access to ~/.config/gcloud/ and ~/.aws/ for cloud credentials
  • Localhost port binding on ports 51121, 8085, 1455 for OAuth callbacks
  • $TMPDIR access for temporary files

Known gaps:

  • No built-in sandboxing by default -- all tools run with full user permissions
  • Optional sandbox extension exists (@anthropic-ai/sandbox-runtime) but must be explicitly enabled
  • Extensions can register arbitrary tools, spawn processes, access filesystem, and make network requests
  • Package manager can npm install and git clone arbitrary packages
  • Auto-downloads binaries from GitHub (fd, rg) without verification beyond HTTPS

Recommended isolation strategy:

  • Use the built-in optional sandbox extension (pi -e ./sandbox) for basic OS-level restrictions
  • Container-based isolation for stronger guarantees
  • Network egress filtering to restrict to configured LLM endpoints
  • Restrict the ~/.pi/agent/auth.json file to prevent credential exfiltration

Open source under the Apache 2.0 License.