### Setup Gondolin Extension Source: https://pi.dev/docs/latest/containerization Copies and installs the Gondolin example extension. Ensure Node.js is installed. ```bash cp -R packages/coding-agent/examples/extensions/gondolin ~/.pi/agent/extensions/gondolin cd ~/.pi/agent/extensions/gondolin npm install --ignore-scripts ``` -------------------------------- ### Complete Agent Session Creation Example Source: https://pi.dev/docs/latest/sdk A comprehensive example demonstrating the setup and creation of an agent session. It includes configuring authentication, model registry, tools, resource loading, and session management. This example shows how to override settings, define custom tools, and subscribe to session events. ```typescript import { getModel } from "@earendil-works/pi-ai"; import { Type } from "typebox"; import { AuthStorage, createAgentSession, DefaultResourceLoader, defineTool, ModelRegistry, SessionManager, SettingsManager, } from "@earendil-works/pi-coding-agent"; // Set up auth storage (custom location) const authStorage = AuthStorage.create("/custom/agent/auth.json"); // Runtime API key override (not persisted) if (process.env.MY_KEY) { authStorage.setRuntimeApiKey("anthropic", process.env.MY_KEY); } // Model registry (no custom models.json) const modelRegistry = ModelRegistry.create(authStorage); // Inline tool const statusTool = defineTool({ name: "status", label: "Status", description: "Get system status", parameters: Type.Object({}), execute: async () => ({ content: [{ type: "text", text: `Uptime: ${process.uptime()}s` }], details: {}, }), }); const model = getModel("anthropic", "claude-opus-4-5"); if (!model) throw new Error("Model not found"); // In-memory settings with overrides const settingsManager = SettingsManager.inMemory({ compaction: { enabled: false }, retry: { enabled: true, maxRetries: 2 }, }); const loader = new DefaultResourceLoader({ cwd: process.cwd(), agentDir: "/custom/agent", settingsManager, systemPromptOverride: () => "You are a minimal assistant. Be concise.", }); await loader.reload(); const { session } = await createAgentSession({ cwd: process.cwd(), agentDir: "/custom/agent", model, thinkingLevel: "off", authStorage, modelRegistry, tools: ["read", "bash", "status"], customTools: [statusTool], resourceLoader: loader, sessionManager: SessionManager.inMemory(), settingsManager, }); session.subscribe((event) => { if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") { process.stdout.write(event.assistantMessageEvent.delta); } }); await session.prompt("Get status and list files."); ``` -------------------------------- ### Quick Start: Create and Use an Agent Session Source: https://pi.dev/docs/latest/sdk This snippet demonstrates how to set up credential storage and a model registry, create an agent session, subscribe to session events, and send a prompt to the agent. It's useful for getting started with basic agent interaction. ```typescript import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@earendil-works/pi-coding-agent"; // Set up credential storage and model registry const authStorage = AuthStorage.create(); const modelRegistry = ModelRegistry.create(authStorage); const { session } = await createAgentSession({ sessionManager: SessionManager.inMemory(), authStorage, modelRegistry, }); session.subscribe((event) => { if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") { process.stdout.write(event.assistantMessageEvent.delta); } }); await session.prompt("What files are in the current directory?"); ``` -------------------------------- ### Clone and Build Pi Project Source: https://pi.dev/docs/latest/development Clone the Pi monorepo, install dependencies, and build the project. This is the initial setup step for development. ```bash git clone https://github.com/earendil-works/pi-mono cd pi-mono npm install npm run build ``` -------------------------------- ### Start Pi in Project Directory Source: https://pi.dev/docs/latest/quickstart Navigate to your project directory and start Pi to begin working on your project. ```bash cd /path/to/project pi ``` -------------------------------- ### Install Pi using PowerShell Source: https://pi.dev Installs Pi using a PowerShell command to download and execute the installation script. ```powershell irm https://pi.dev/install.ps1 | iex ``` -------------------------------- ### Install Pi Coding Agent SDK Source: https://pi.dev/docs/latest/sdk Install the SDK using npm. The SDK is included in the main package, so no separate installation is needed. ```bash npm install @earendil-works/pi-coding-agent ``` -------------------------------- ### Install Pi using curl Source: https://pi.dev Installs Pi using a curl command to download and execute the installation script. ```bash curl -fsSL https://pi.dev/install.sh | sh ``` -------------------------------- ### Full Example Configuration Source: https://pi.dev/docs/latest/settings A comprehensive example demonstrating various settings including default provider, model, theme, compaction, retry, enabled models, warnings, and package loading. ```json { "defaultProvider": "anthropic", "defaultModel": "claude-sonnet-4-20250514", "defaultThinkingLevel": "medium", "theme": "dark", "compaction": { "enabled": true, "reserveTokens": 16384, "keepRecentTokens": 20000 }, "retry": { "enabled": true, "maxRetries": 3 }, "enabledModels": ["claude-*", "gpt-4o"], "warnings": { "anthropicExtraUsage": true }, "packages": ["pi-skills"] } ``` -------------------------------- ### Install a Pi Package Source: https://pi.dev/docs/latest/usage Installs a package from a specified source. Use the -l flag to install it locally to the project. ```bash pi install [-l] ``` -------------------------------- ### Prompt Template Usage Examples Source: https://pi.dev/docs/latest/prompt-templates Demonstrates how to invoke prompt templates from the editor using a slash command, with examples for basic invocation and templates with arguments. ```text /review # Expands review.md /component Button # Expands with argument /component Button "click handler" # Multiple arguments ``` -------------------------------- ### Description Best Practices Example Source: https://pi.dev/docs/latest/skills Provides examples of good and poor descriptions for agent skills. ```yaml description: Extracts text and tables from PDF files, fills PDF forms, and merges multiple PDFs. Use when working with PDF documents. ``` ```yaml description: Helps with PDFs. ``` -------------------------------- ### Install Pi coding agent using bun Source: https://pi.dev Installs the Pi coding agent package globally using bun. ```bash bun add -g --ignore-scripts @earendil-works/pi-coding-agent ``` -------------------------------- ### Install Brave Search Dependencies Source: https://pi.dev/docs/latest/skills Install the necessary dependencies for the Brave Search project. Navigate to the project directory before running this command. ```bash cd /path/to/brave-search && npm install ``` -------------------------------- ### Install Pi Package from npm Source: https://pi.dev Installs a Pi extension package from npm. Ensure you have npm installed and configured. ```bash $ pi install npm:@foo/pi-tools ``` -------------------------------- ### Brave Search Skill Example Source: https://pi.dev/docs/latest/skills Example of a SKILL.md file for a Brave Search skill, including name and description. ```markdown --- name: brave-search description: Web search and content extraction via Brave Search API. Use for searching documentation, facts, or any web content. --- ``` -------------------------------- ### Agent Start and End Event Handlers Source: https://pi.dev/docs/latest/extensions Fired once per user prompt. Use agent_start for initial setup and agent_end to process messages after the agent has completed its turn. ```typescript pi.on("agent_start", async (_event, ctx) => {}); ``` ```typescript pi.on("agent_end", async (event, ctx) => { // event.messages - messages from this prompt }); ``` -------------------------------- ### Response for get_commands Source: https://pi.dev/docs/latest/rpc Example response for `get_commands`, detailing available commands with their names, descriptions, sources, and locations. ```json { "type": "response", "command": "get_commands", "success": true, "data": { "commands": [ {"name": "session-name", "description": "Set or clear session name", "source": "extension", "path": "/home/user/.pi/agent/extensions/session.ts"}, {"name": "fix-tests", "description": "Fix failing tests", "source": "prompt", "location": "project", "path": "/home/user/myproject/.pi/agent/prompts/fix-tests.md"}, {"name": "skill:brave-search", "description": "Web search via Brave API", "source": "skill", "location": "user", "path": "/home/user/.pi/agent/skills/brave-search/SKILL.md"} ] } } ``` -------------------------------- ### Install Pi on Termux Source: https://pi.dev/docs/latest/termux Installs Node.js, Termux-API, Git, and the Pi coding agent globally. Creates a configuration directory and runs Pi. ```bash # Update packages pkg update && pkg upgrade # Install dependencies pkg install nodejs termux-api git # Install pi npm install -g --ignore-scripts @earendil-works/pi-coding-agent # Create config directory mkdir -p ~/.pi/agent # Run pi pi ``` -------------------------------- ### Tool Usage Example Source: https://pi.dev/docs/latest/usage Enable specific tools for the agent using the `--tools` flag. ```bash # Read-only mode pi --tools read,grep,find,ls -p "Review the code" ``` -------------------------------- ### Install Git Package with Version Ref Source: https://pi.dev/docs/latest/packages Installs a Git package specifying a version reference (tag or commit) using the 'git:' prefix and SSH shorthand. ```bash pi install git:git@github.com:user/repo@v1.0.0 ``` -------------------------------- ### Install Pi Packages Source: https://pi.dev/docs/latest/packages Commands to install Pi packages from npm, git, raw URLs, or local paths. Use -l for project settings instead of user settings. ```bash pi install npm:@foo/bar@1.0.0 pi install git:github.com/user/repo@v1 pi install https://github.com/user/repo # raw URLs work too pi install /absolute/path/to/package pi install ./relative/path/to/package ``` -------------------------------- ### Install Pi Source: https://pi.dev/docs/latest/quickstart Install Pi globally using npm. The --ignore-scripts flag prevents execution of dependency lifecycle scripts. ```bash npm install -g --ignore-scripts @earendil-works/pi-coding-agent ``` -------------------------------- ### Install Pi coding agent using npm Source: https://pi.dev Installs the Pi coding agent package globally using npm. ```bash npm install -g --ignore-scripts @earendil-works/pi-coding-agent ``` -------------------------------- ### Model with Provider Prefix Example Source: https://pi.dev/docs/latest/usage Specify the model directly with its provider prefix. ```bash # Model with provider prefix pi --model openai/gpt-4o "Help me refactor" ``` -------------------------------- ### List Installed Pi Packages Source: https://pi.dev/docs/latest/packages Command to display currently installed Pi packages from settings. ```bash pi list ``` -------------------------------- ### Install Pi coding agent using pnpm Source: https://pi.dev Installs the Pi coding agent package globally using pnpm. ```bash pnpm add -g --ignore-scripts @earendil-works/pi-coding-agent ``` -------------------------------- ### Install Pi Package from Git Source: https://pi.dev Installs a Pi extension package directly from a Git repository. This is useful for installing packages not yet published to npm. ```bash $ pi install git:github.com/badlogic/pi-doom ``` -------------------------------- ### Specify Model Example Source: https://pi.dev/docs/latest/usage Use the `--provider` and `--model` flags to select a specific AI model. ```bash # Different model pi --provider openai --model gpt-4o "Help me refactor" ``` -------------------------------- ### Skill Name Rules Example Source: https://pi.dev/docs/latest/skills Illustrates valid and invalid naming conventions for agent skills. ```text Valid: `pdf-processing`, `data-analysis`, `code-review` Invalid: `PDF-Processing`, `-pdf`, `pdf--processing` ``` -------------------------------- ### Install Git Package using SSH Protocol Source: https://pi.dev/docs/latest/packages Installs a Git package using the standard SSH protocol URL format. ```bash pi install ssh://git@github.com/user/repo ``` -------------------------------- ### Install Git Package using SSH Shorthand Source: https://pi.dev/docs/latest/packages Installs a Git package using the 'git:' prefix with an SSH shorthand format. This requires the 'git:' prefix for shorthand recognition. ```bash pi install git:git@github.com:user/repo ``` -------------------------------- ### Include Files in Prompt Source: https://pi.dev/docs/latest/usage Examples of how to include local files as part of the prompt message to the CLI. ```bash pi @prompt.md "Answer this" ``` ```bash pi -p @screenshot.png "What's in this image?" ``` ```bash pi @code.ts @test.ts "Review these files" ``` -------------------------------- ### Temporarily Use Pi Packages Source: https://pi.dev/docs/latest/packages Use the -e or --extension flag to try a package without installing it. This installs to a temporary directory for the current run only. ```bash pi -e npm:@foo/bar pi -e git:github.com/user/repo ``` -------------------------------- ### Start RPC Mode Source: https://pi.dev/docs/latest/rpc This command starts the Pi coding agent in RPC mode. Common options include setting the LLM provider, model, session name, and session persistence. ```bash pi --mode rpc [options] ``` -------------------------------- ### Install Termux API CLI tools Source: https://pi.dev/docs/latest/termux Installs the command-line interface tools for Termux:API, which are necessary for using device integrations like clipboard and notifications. ```bash pkg install termux-api ``` -------------------------------- ### Interactive Prompt Example Source: https://pi.dev/docs/latest/usage Use the `pi` command with a direct prompt for interactive use. ```bash # Interactive with initial prompt pi "List all .ts files in src/" ``` -------------------------------- ### Named Session Example Source: https://pi.dev/docs/latest/usage Create a named session for persistent context using the `--name` flag. ```bash # Named one-shot session pi --name "release audit" -p "Audit this repository" ``` -------------------------------- ### Tool Execution Start Event Source: https://pi.dev/docs/latest/rpc Emitted when a tool begins execution. Includes the tool's ID, name, and arguments. ```json { "type": "tool_execution_start", "toolCallId": "call_abc123", "toolName": "bash", "args": {"command": "ls -la"} } ``` -------------------------------- ### InteractiveMode Example Source: https://pi.dev/docs/latest/sdk Use InteractiveMode for a full TUI interactive experience with an editor, chat history, and built-in commands. Requires setup of the runtime environment. ```typescript import { type CreateAgentSessionRuntimeFactory, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, InteractiveMode, SessionManager, } from "@earendil-works/pi-coding-agent"; const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => { const services = await createAgentSessionServices({ cwd }); return { ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })), services, diagnostics: services.diagnostics, }; }; const runtime = await createAgentSessionRuntime(createRuntime, { cwd: process.cwd(), agentDir: getAgentDir(), sessionManager: SessionManager.create(process.cwd()), }); const mode = new InteractiveMode(runtime, { migratedProviders: [], modelFallbackMessage: undefined, initialMessage: "Hello", initialImages: [], initialMessages: [], }); await mode.run(); ``` -------------------------------- ### session_start Source: https://pi.dev/docs/latest/extensions Fired when a session is started, loaded, or reloaded. This is useful for initializing extension state or resources tied to a specific session. ```APIDOC ## session_start ### Description Fired when a session is started, loaded, or reloaded. ### Event Payload - `event.reason` (string) - Indicates the reason for the session start: "startup", "reload", "new", "resume", or "fork". - `event.previousSessionFile` (string) - Present for "new", "resume", and "fork" reasons, indicating the path to the previous session file. ### Context - `ctx.ui.notify` (function) - Displays a notification to the user. - `ctx.sessionManager.getSessionFile` (function) - Returns the current session file path. ### Example ```javascript pi.on("session_start", async (event, ctx) => { // event.reason - "startup" | "reload" | "new" | "resume" | "fork" // event.previousSessionFile - present for "new", "resume", and "fork" ctx.ui.notify(`Session: ${ctx.sessionManager.getSessionFile() ?? "ephemeral"}`, "info"); }); ``` ``` -------------------------------- ### Project Instructions File Source: https://pi.dev/docs/latest/quickstart Create an AGENTS.md file in your project root to provide specific instructions for Pi's operation within that project. ```markdown # Project Instructions - Run `npm run check` after code changes. - Do not run production migrations locally. - Keep responses concise. ``` -------------------------------- ### runPrintMode Example Source: https://pi.dev/docs/latest/sdk Utilize runPrintMode for single-shot interactions where you send prompts, receive a result, and then exit. This mode is suitable for straightforward, non-interactive tasks. Requires runtime setup. ```typescript import { type CreateAgentSessionRuntimeFactory, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, runPrintMode, SessionManager, } from "@earendil-works/pi-coding-agent"; const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => { const services = await createAgentSessionServices({ cwd }); return { ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })), services, diagnostics: services.diagnostics, }; }; const runtime = await createAgentSessionRuntime(createRuntime, { cwd: process.cwd(), agentDir: getAgentDir(), sessionManager: SessionManager.create(process.cwd()), }); await runPrintMode(runtime, { mode: "text", initialMessage: "Hello", initialImages: [], messages: ["Follow up"], }); ``` -------------------------------- ### runRpcMode Example Source: https://pi.dev/docs/latest/sdk Employ runRpcMode for JSON-RPC mode, ideal for integrating with subprocesses. This mode facilitates communication between different processes using a defined JSON protocol. Requires runtime setup. ```typescript import { type CreateAgentSessionRuntimeFactory, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, runRpcMode, SessionManager, } from "@earendil-works/pi-coding-agent"; const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => { const services = await createAgentSessionServices({ cwd }); return { ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent })), services, diagnostics: services.diagnostics, }; }; const runtime = await createAgentSessionRuntime(createRuntime, { cwd: process.cwd(), agentDir: getAgentDir(), sessionManager: SessionManager.create(process.cwd()), }); await runRpcMode(runtime); ``` -------------------------------- ### SKILL.md Frontmatter and Instructions Source: https://pi.dev/docs/latest/skills The SKILL.md file contains frontmatter with the skill's name and description, followed by instructions for setup and usage. ```markdown --- name: my-skill description: What this skill does and when to use it. Be specific. --- # My Skill ## Setup Run once before first use: ```bash cd /path/to/skill && npm install ``` ``` -------------------------------- ### Basic Extension Structure Source: https://pi.dev/docs/latest/extensions This snippet shows the basic structure of a Pi Coding Agent extension. It demonstrates how to import necessary types, define the main extension function, and register event handlers for session start and tool calls. It also includes examples of registering a custom tool and a command. ```typescript import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { Type } from "typebox"; export default function (pi: ExtensionAPI) { // React to events pi.on("session_start", async (_event, ctx) => { ctx.ui.notify("Extension loaded!", "info"); }); pi.on("tool_call", async (event, ctx) => { if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) { const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?"); if (!ok) return { block: true, reason: "Blocked by user" }; } }); // Register a custom tool pi.registerTool({ name: "greet", label: "Greet", description: "Greet someone by name", parameters: Type.Object({ name: Type.String({ description: "Name to greet" }), }), async execute(toolCallId, params, signal, onUpdate, ctx) { return { content: [{ type: "text", text: `Hello, ${params.name}!` }], details: {}, }; }, }); // Register a command pi.registerCommand("hello", { description: "Say hello", handler: async (args, ctx) => { ctx.ui.notify(`Hello ${args || "world"}!`, "info"); }, }); } ``` -------------------------------- ### Run Gondolin Extension Source: https://pi.dev/docs/latest/containerization Launches Pi with the Gondolin extension, mounting the current directory into the VM. ```bash cd /path/to/project pi -e ~/.pi/agent/extensions/gondolin ``` -------------------------------- ### Package.json for Extension with Dependencies Source: https://pi.dev/docs/latest/extensions This `package.json` example shows how to declare dependencies like `zod` and `chalk`, and specify the extension entry point using the `pi.extensions` field. ```json { "name": "my-extension", "dependencies": { "zod": "^3.0.0", "chalk": "^5.0.0" }, "pi": { "extensions": ["./src/index.ts"] } } ``` -------------------------------- ### Create and Manage Agent Sessions Source: https://pi.dev/docs/latest/sdk Demonstrates creating in-memory, persistent, and continued sessions. Also shows how to open specific session files and list available sessions. ```typescript import { type CreateAgentSessionRuntimeFactory, createAgentSession, createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices, getAgentDir, SessionManager, } from "@earendil-works/pi-coding-agent"; // In-memory (no persistence) const { session } = await createAgentSession({ sessionManager: SessionManager.inMemory(), }); // New persistent session const { session: persisted } = await createAgentSession({ sessionManager: SessionManager.create(process.cwd()), }); // Continue most recent const { session: continued, modelFallbackMessage } = await createAgentSession({ sessionManager: SessionManager.continueRecent(process.cwd()), }); if (modelFallbackMessage) { console.log("Note:", modelFallbackMessage); } // Open specific file const { session: opened } = await createAgentSession({ sessionManager: SessionManager.open("/path/to/session.jsonl"), }); // List sessions const currentProjectSessions = await SessionManager.list(process.cwd()); const allSessions = await SessionManager.listAll(process.cwd()); ``` ```typescript // Session replacement API for /new, /resume, /fork, /clone, and import flows. const createRuntime: CreateAgentSessionRuntimeFactory = async ({ cwd, sessionManager, sessionStartEvent }) => { const services = await createAgentSessionServices({ cwd }); return { ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent, })), services, diagnostics: services.diagnostics, }; }; const runtime = await createAgentSessionRuntime(createRuntime, { cwd: process.cwd(), agentDir: getAgentDir(), sessionManager: SessionManager.create(process.cwd()), }); // Replace the active session with a fresh one await runtime.newSession(); // Replace the active session with another saved session await runtime.switchSession("/path/to/session.jsonl"); // Replace the active session with a fork from a specific user entry await runtime.fork("entry-id"); // Clone the active path through a specific entry await runtime.fork("entry-id", { position: "at" }); ``` -------------------------------- ### Handle Session Start Event Source: https://pi.dev/docs/latest/extensions Fired when a session is started, loaded, or reloaded. Use to initialize session-specific state. ```javascript pi.on("session_start", async (event, ctx) => { // event.reason - "startup" | "reload" | "new" | "resume" | "fork" // event.previousSessionFile - present for "new", "resume", and "fork" ctx.ui.notify(`Session: ${ctx.sessionManager.getSessionFile() ?? "ephemeral"}`, "info"); }); ``` -------------------------------- ### Create Custom Keybindings Source: https://pi.dev/docs/latest/keybindings Create a `~/.pi/agent/keybindings.json` file to define custom keybindings. Each action can be bound to a single key or an array of keys. User configurations override default bindings. ```json { "tui.editor.cursorUp": ["up", "ctrl+p"], "tui.editor.cursorDown": ["down", "ctrl+n"], "tui.editor.deleteWordBackward": ["ctrl+w", "alt+backspace"] } ``` -------------------------------- ### Project Settings Override Example Source: https://pi.dev/docs/latest/settings Demonstrates how project settings merge with global settings. The project-specific `reserveTokens` value overrides the global one, while `theme` and `enabled` are inherited. ```json // ~/.pi/agent/settings.json (global) { "theme": "dark", "compaction": { "enabled": true, "reserveTokens": 16384 } } // .pi/settings.json (project) { "compaction": { "reserveTokens": 8192 } } // Result { "theme": "dark", "compaction": { "enabled": true, "reserveTokens": 8192 } } ``` -------------------------------- ### Configure Context Files Source: https://pi.dev/docs/latest/usage Pi loads context files like AGENTS.md or CLAUDE.md at startup to configure project behavior. Disable loading with `--no-context-files` or `-nc`. ```bash pi --no-context-files ``` ```bash pi -nc ``` -------------------------------- ### Launch Pi in OpenShell Sandbox Source: https://pi.dev/docs/latest/containerization Creates and launches a Pi sandbox using OpenShell. The `-- pi` at the end passes arguments to the Pi process. ```bash openshell sandbox create --name pi-sandbox --from pi -- pi ``` -------------------------------- ### Start New Session with Parent Tracking Source: https://pi.dev/docs/latest/rpc Start a new session while optionally tracking a parent session using the 'parentSession' field. This allows for hierarchical session management. ```json {"type": "new_session", "parentSession": "/path/to/parent-session.jsonl"} ``` -------------------------------- ### Initialize and Use DefaultResourceLoader Source: https://pi.dev/docs/latest/sdk Demonstrates how to initialize `DefaultResourceLoader` to discover extensions, skills, prompts, themes, and context files. Ensure `cwd` and `agentDir` are correctly set. ```typescript import { DefaultResourceLoader, getAgentDir, } from "@earendil-works/pi-coding-agent"; const loader = new DefaultResourceLoader({ cwd, agentDir: getAgentDir(), }); await loader.reload(); const extensions = loader.getExtensions(); const skills = loader.getSkills(); const prompts = loader.getPrompts(); const themes = loader.getThemes(); const contextFiles = loader.getAgentsFiles().agentsFiles; ``` -------------------------------- ### Autocomplete Dropdown Example Source: https://pi.dev/docs/latest/prompt-templates Illustrates how prompt templates with argument hints appear in the autocomplete dropdown, showing commands, expected arguments, and descriptions. ```text → pr — Review PRs from URLs with structured issue and code analysis is — Analyze GitHub issues (bugs or feature requests) wr [instructions] — Finish the current task end-to-end cl — Audit changelog entries before release ``` -------------------------------- ### Start Pi Without Built-in Tools Source: https://pi.dev/docs/latest/extensions Initiate the Pi agent using only extension-provided tools, disabling all default built-in tools. This is useful for creating a completely custom environment or for security-sensitive applications. ```bash pi --no-builtin-tools -e ./my-extension.ts ``` -------------------------------- ### Get all session entries Source: https://pi.dev/docs/latest/rpc Retrieves all session entries in append order. Pass the last entry ID seen as `since` to get only entries strictly after it. Includes pre-compaction history and abandoned branches. ```json {"type": "get_entries"} ``` ```json {"type": "get_entries", "since": "abc123"} ``` -------------------------------- ### Termux Agent Environment Configuration Source: https://pi.dev/docs/latest/termux Example AGENTS.md file for Termux on Android, detailing OS, home/prefix paths, and providing examples for opening URLs, files, clipboard operations, notifications, device info, and sharing. ```bash # Agent Environment: Termux on Android ## Location - **OS**: Android (Termux terminal emulator) - **Home**: `/data/data/com.termux/files/home` - **Prefix**: `/data/data/com.termux/files/usr` - **Shared storage**: `/storage/emulated/0` (Downloads, Documents, etc.) ## Opening URLs ```bash termux-open-url "https://example.com" ``` ## Opening Files ```bash termux-open file.pdf # Opens with default app termux-open --chooser image.jpg # Choose app ``` ## Clipboard ```bash termux-clipboard-set "text" # Copy termux-clipboard-get # Paste ``` ## Notifications ```bash termux-notification -t "Title" -c "Content" ``` ## Device Info ```bash termux-battery-status # Battery info termux-wifi-connectioninfo # WiFi info termux-telephony-deviceinfo # Device info ``` ## Sharing ```bash termux-share -a send file.txt # Share file ``` ## Other Useful Commands ```bash termux-toast "message" # Quick toast popup termux-vibrate # Vibrate device termux-tts-speak "hello" # Text to speech termux-camera-photo out.jpg # Take photo ``` ## Notes - Termux:API app must be installed for `termux-*` commands - Use `pkg install termux-api` for the command-line tools - Storage permission needed for `/storage/emulated/0` access ``` -------------------------------- ### Create Agent Session with Directory Options Source: https://pi.dev/docs/latest/sdk Configure the working directory (`cwd`) and agent directory (`agentDir`) for resource discovery when creating an agent session. `cwd` defaults to `process.cwd()` and `agentDir` defaults to `~/.pi/agent`. ```javascript const { session } = await createAgentSession({ // Working directory for DefaultResourceLoader discovery cwd: process.cwd(), // default // Global config directory agentDir: "~/.pi/agent", // default (expands ~) }); ``` -------------------------------- ### get_fork_messages Source: https://pi.dev/docs/latest/rpc Get user messages available for forking. ```APIDOC ## get_fork_messages ### Description Get user messages available for forking. ### Command ```json {"type": "get_fork_messages"} ``` ### Response #### Success Response ```json { "type": "response", "command": "get_fork_messages", "success": true, "data": { "messages": [ {"entryId": "abc123", "text": "First prompt..."}, {"entryId": "def456", "text": "Second prompt..."} ] } } ``` ``` -------------------------------- ### Static Creation Methods Source: https://pi.dev/docs/latest/session-format Methods for creating new sessions or opening existing ones. ```APIDOC ## SessionManager.create ### Description Creates a new session. ### Method Static ### Parameters - **cwd** (string) - Required - The current working directory. - **sessionDir** (string?) - Optional - The directory to store the session. ``` ```APIDOC ## SessionManager.open ### Description Opens an existing session file. ### Method Static ### Parameters - **path** (string) - Required - The path to the session file. - **sessionDir** (string?) - Optional - The directory where the session is stored. ``` ```APIDOC ## SessionManager.continueRecent ### Description Continues the most recent session or creates a new one if none exists. ### Method Static ### Parameters - **cwd** (string) - Required - The current working directory. - **sessionDir** (string?) - Optional - The directory to store the session. ``` ```APIDOC ## SessionManager.inMemory ### Description Creates a session that does not persist to a file. ### Method Static ### Parameters - **cwd** (string?) - Optional - The current working directory. ``` ```APIDOC ## SessionManager.forkFrom ### Description Forks a new session from another project's session file. ### Method Static ### Parameters - **sourcePath** (string) - Required - The path to the source session file. - **targetCwd** (string) - Required - The current working directory for the new session. - **sessionDir** (string?) - Optional - The directory to store the new session. ``` -------------------------------- ### Editor text Source: https://pi.dev/docs/latest/extensions Get or set the text content of the editor. ```APIDOC ## setEditorText ### Description Sets the text content of the editor. ### Method ctx.ui.setEditorText(text: string) ### Parameters - **text** (string) - Required - The text to set in the editor. ### Request Example ```javascript ctx.ui.setEditorText("Prefill text"); ``` ## getEditorText ### Description Retrieves the current text content of the editor. ### Method ctx.ui.getEditorText(): string ### Request Example ```javascript const current = ctx.ui.getEditorText(); ``` ``` -------------------------------- ### Create Agent Session with Default Settings Source: https://pi.dev/docs/latest/sdk Loads settings from default file locations (global and project) and creates an agent session. No special setup is required. ```typescript import { createAgentSession, SettingsManager, SessionManager } from "@earendil-works/pi-coding-agent"; // Default: loads from files (global + project merged) const { session } = await createAgentSession({ settingsManager: SettingsManager.create(), }); ``` -------------------------------- ### Remove Pi Packages Source: https://pi.dev/docs/latest/packages Command to remove an installed Pi package. ```bash pi remove npm:@foo/bar ``` -------------------------------- ### Instance Methods - Tree Navigation Source: https://pi.dev/docs/latest/session-format Methods for navigating and querying the session's entry tree structure. ```APIDOC ## Session.getLeafId ### Description Gets the ID of the current leaf entry. ### Method Instance ``` ```APIDOC ## Session.getLeafEntry ### Description Gets the current leaf entry object. ### Method Instance ``` ```APIDOC ## Session.getEntry ### Description Retrieves an entry by its ID. ### Method Instance ### Parameters - **id** (string) - Required - The ID of the entry to retrieve. ``` ```APIDOC ## Session.getBranch ### Description Walks from a given entry up to the root of the session tree. ### Method Instance ### Parameters - **fromId** (string?) - Optional - The ID of the entry to start from. If not provided, starts from the current leaf. ``` ```APIDOC ## Session.getTree ### Description Retrieves the entire session tree structure. ### Method Instance ``` ```APIDOC ## Session.getChildren ### Description Gets the direct children of a given parent entry. ### Method Instance ### Parameters - **parentId** (string) - Required - The ID of the parent entry. ``` ```APIDOC ## Session.getLabel ### Description Gets the label associated with a specific entry. ### Method Instance ### Parameters - **id** (string) - Required - The ID of the entry. ``` ```APIDOC ## Session.branch ### Description Moves the current leaf to an earlier entry in the session tree. ### Method Instance ### Parameters - **entryId** (string) - Required - The ID of the entry to branch to. ``` ```APIDOC ## Session.resetLeaf ### Description Resets the current leaf to null, effectively before any entries have been made. ### Method Instance ``` ```APIDOC ## Session.branchWithSummary ### Description Branches the session at a specific entry and includes a summary. ### Method Instance ### Parameters - **entryId** (string) - Required - The ID of the entry to branch at. - **summary** (string) - Required - A summary of the branch. - **details** (any?) - Optional - Additional details about the branch. - **fromHook** (boolean?) - Optional - Indicates if this branch was triggered by a hook. ``` -------------------------------- ### Piped Input Example Source: https://pi.dev/docs/latest/usage Pipe content from stdin to the `pi` command for processing. ```bash # Non-interactive with piped stdin cat README.md | pi -p "Summarize this text" ``` -------------------------------- ### Interactive RPC Client (Node.js) Source: https://pi.dev/docs/latest/rpc This Node.js example shows how to create an interactive RPC client. It uses `child_process.spawn` to run the agent and handles JSON lines from stdout. It also includes basic SIGINT handling for graceful abortion. ```javascript const { spawn } = require("child_process"); const { StringDecoder } = require("string_decoder"); const agent = spawn("pi", ["--mode", "rpc", "--no-session"]); function attachJsonlReader(stream, onLine) { const decoder = new StringDecoder("utf8"); let buffer = ""; stream.on("data", (chunk) => { buffer += typeof chunk === "string" ? chunk : decoder.write(chunk); while (true) { const newlineIndex = buffer.indexOf("\n"); if (newlineIndex === -1) break; let line = buffer.slice(0, newlineIndex); buffer = buffer.slice(newlineIndex + 1); if (line.endsWith("\r")) line = line.slice(0, -1); onLine(line); } }); stream.on("end", () => { buffer += decoder.end(); if (buffer.length > 0) { onLine(buffer.endsWith("\r") ? buffer.slice(0, -1) : buffer); } }); } attachJsonlReader(agent.stdout, (line) => { const event = JSON.parse(line); if (event.type === "message_update") { const { assistantMessageEvent } = event; if (assistantMessageEvent.type === "text_delta") { process.stdout.write(assistantMessageEvent.delta); } } }); // Send prompt agent.stdin.write(JSON.stringify({ type: "prompt", message: "Hello" }) + "\n"); // Abort on Ctrl+C process.on("SIGINT", () => { agent.stdin.write(JSON.stringify({ type: "abort" }) + "\n"); }); ``` -------------------------------- ### Non-Interactive Prompt Example Source: https://pi.dev/docs/latest/usage Use the `-p` flag for non-interactive execution of a prompt. ```bash # Non-interactive pi -p "Summarize this codebase" ``` -------------------------------- ### Load All Resources from a Package Source: https://pi.dev/docs/latest/settings Use the string form to load all resources from a specified npm or git package. ```json { "packages": ["pi-skills", "@org/my-extension"] } ``` -------------------------------- ### new_session Source: https://pi.dev/docs/latest/rpc Start a fresh session. Can be cancelled by a `session_before_switch` extension event handler. ```APIDOC ## new_session ### Description Start a fresh session. Can be cancelled by a `session_before_switch` extension event handler. ### Method `new_session` ### Request Body - **parentSession** (string) - Optional - The path to the parent session for tracking purposes. ### Request Example (Simple) ```json {"type": "new_session"} ``` ### Request Example (With parent session) ```json {"type": "new_session", "parentSession": "/path/to/parent-session.jsonl"} ``` ### Response #### Success Response - **type** (string) - Indicates the response type, should be `"response"`. - **command** (string) - The command that was processed, should be `"new_session"`. - **success** (boolean) - `true` if the new session command was processed successfully. - **data** (object) - Contains information about the session status. - **cancelled** (boolean) - `true` if the session was cancelled by an extension, `false` otherwise. #### Response Example (Not cancelled) ```json {"type": "response", "command": "new_session", "success": true, "data": {"cancelled": false}} ``` #### Response Example (Cancelled) ```json {"type": "response", "command": "new_session", "success": true, "data": {"cancelled": true}} ``` ``` -------------------------------- ### Limit Model Cycling Example Source: https://pi.dev/docs/latest/usage Control which models the agent can cycle through using a pattern. ```bash # Limit model cycling pi --models "claude-*,gpt-4o" ``` -------------------------------- ### Create New Session - Pi Extension Source: https://pi.dev/docs/latest/extensions Initiate a new session, optionally linking it to a parent session and defining setup logic or actions to perform within the new session context. ```javascript const parentSession = ctx.sessionManager.getSessionFile(); const kickoff = "Continue in the replacement session"; const result = await ctx.newSession({ parentSession, setup: async (sm) => { sm.appendMessage({ role: "user", content: [{ type: "text", text: "Context from previous session..." }], timestamp: Date.now(), }); }, withSession: async (ctx) => { // Use only the replacement-session ctx here. await ctx.sendUserMessage(kickoff); }, }); if (result.cancelled) { // An extension cancelled the new session } ``` -------------------------------- ### Model Thinking Level Example Source: https://pi.dev/docs/latest/usage Use shorthand to specify the thinking level for a model. ```bash # Model with thinking level shorthand pi --model sonnet:high "Solve this complex problem" ``` -------------------------------- ### Pi Event Lifecycle Overview Source: https://pi.dev/docs/latest/extensions Visual representation of the Pi event flow from startup to user interaction and session management. ```text pi starts │ ├─► project_trust (user/global and CLI extensions only, before project resources load) ├─► session_start { reason: "startup" } └─► resources_discover { reason: "startup" } │ ▼ user sends prompt ─────────────────────────────────────────┐ │ │ ├─► (extension commands checked first, bypass if found) │ ├─► input (can intercept, transform, or handle) │ ├─► (skill/template expansion if not handled) │ ├─► before_agent_start (can inject message, modify system prompt) ├─► agent_start │ ├─► message_start / message_update / message_end │ │ │ │ ┌─── turn (repeats while LLM calls tools) ───┐ │ │ │ │ │ │ ├─► turn_start │ │ │ ├─► context (can modify messages) │ │ │ ├─► before_provider_request (can inspect or replace payload) │ ├─► after_provider_response (status + headers, before stream consume) │ │ │ │ │ │ LLM responds, may call tools: │ │ │ │ ├─► tool_execution_start │ │ │ │ ├─► tool_call (can block) │ │ │ │ ├─► tool_execution_update │ │ │ │ ├─► tool_result (can modify) │ │ │ │ └─► tool_execution_end │ │ │ │ │ │ │ └─► turn_end │ │ │ │ └─► agent_end │ │ user sends another prompt ◄────────────────────────────────┘ /new (new session) or /resume (switch session) ├─► session_before_switch (can cancel) ├─► session_shutdown ├─► session_start { reason: "new" | "resume", previousSessionFile? } └─► resources_discover { reason: "startup" } /fork or /clone ├─► session_before_fork (can cancel) ├─► session_shutdown ├─► session_start { reason: "fork", previousSessionFile } └─► resources_discover { reason: "startup" } /name or pi.setSessionName() └─► session_info_changed /compact or auto-compaction ├─► session_before_compact (can cancel or customize) └─► session_compact /tree navigation ├─► session_before_tree (can cancel or customize) └─► session_tree /model or Ctrl+P (model selection/cycling) ├─► thinking_level_select (if model change changes/clamps thinking level) └─► model_select thinking level changes (settings, keybinding, pi.setThinkingLevel()) └─► thinking_level_select exit (Ctrl+C, Ctrl+D, SIGHUP, SIGTERM) └─► session_shutdown ```